Why am I experiencing a charging issue with a Lenovo IdeaPad 3? [closed]Why am I experiencing a charging issue with a Lenovo IdeaPad 3? [closed]Why am I experiencing a charging issue with a Lenovo IdeaPad 3? [closed]
Category: javascript
Category Added in a WPeMatico Campaign
Why do I get “typeerror: _ is null” on a Javascript line with no underscores?
In a Vue-based JavaScript project that uses the autocomplete-js package, I am hitting the following error when I try to instantiate the autocomplete object:
TypeError: _ is null
However, there is no underscore on the line that shows up in the debugger:
invariant(containerElement.tagName !== 'INPUT', 'The `container` option does not support `input` elements. You need to change the container to a `div`.');
This code is inside a subpackage of autocomplete-js called invariant. The invariant function being called in that package also contains no underscores. Also, the containerElement is not an INPUT type, so that invariant line shouldn’t be doing anything anyway.
How is this error happening, and how might I get past it?
Secure User Registration System in PHP with Input Validation and MySQL Integration [closed]
You are tasked with developing a user registration system using PHP and MySQL. The system must collect a user’s full name, email, password, and contact number. Upon submission, the PHP script should validate the inputs (check if email is valid, password is at least 8 characters, and contact number is numeric and 10 digits). If validation passes, the data must be stored in a MySQL database with the password hashed using password_hash(). Additionally, if the email is already registered, the user should be shown an appropriate error message. Write a PHP script to handle the form submission, input validation, error handling, and successful data insertion into the database. Also, describe how you would prevent SQL injection in this scenario.
Add Prism highlight to peace of codes in a text
Hy guys. I am trying to apply code highlight to a question made by a user and I am not sure how to do.
For a better understanding, when the user post a question similar to stack overflow he can write text and also include code. If he include code it’s added inside the code block like: “`code here´´´ and the adding code part works fine as you can see in this first picture.
the plain text and code snippet
As you can see in the picture, I am able to highlight the code but is add everything inside the highlighted block, and I am able only to specify the first language, in this example the first block of code is HTML so it is applying the highlight, but at the bottom you can see that the java part is not working because I am not able to add two languages to be recognized and the API does not recognized the codes part automatically.
So, my real question is how could I get the code part that is in a text than I can use the tag selected by the user to add as the language and then insert the code found in the text inside my
<pre><code class=language-{{tags[0]}}></code></pre> then print the rest of the plain text and once another peace of code is identified I add again inside <pre><code class=language-{{tags[1]}}></code></pre> until the end of the text.
To make clear this tags new to the language will be selected when the user add a question so I use to highlight with the correct format.
Here is an example that I hard coded only so you can have an idea what I am trying to do, but will not work the way I did because it apply for all question made even if there is no code. I made only so you can understand what I am trying to accomplish.
So in this last picture you can see that I highlighted the code parts only with their respective languages tag.
He is the code but only to visualized how i did but I know it is not the correct way I am new in jinja2 and front end so I appreciate some help from you guys.
{% set question = post.Question.split('```') %}
<div>
<span class="text-dark">
{{question[0]}}
</span>
<pre class="row">
<code class="language-{{tags[0]}}">
{{question[1]}}
</code>
</pre>
<span class="text-dark">
{{question[2]}}
</span>
<pre class="row">
<code class="language-{{tags[2]}}">
{{question[3]}}
</code>
</pre>
</div>
So if anyone has any idea how I could to that in Jinja2 or JS would be very nice, thanks in advance for you all.
Javascript/Ajax question from a confluence macro
I’m trying to debug a confluence macro that stores the value of a checkbox when it is clicked – but can’t seem to get it to even react to user interaction.
Shown below is the code that is being executed on the page (from the dev tools elements tab).
<input class="checkbox dynCheckbox" type="checkbox" name="dynCheckboxone" id="dynCheckboxone" value="checked" resolved="">
<label for="dynCheckboxone">one</label>
//<![CDATA[
AJS.toInit(function(){
AJS.$('.dynCheckboxone').click(function(){
AJS.${d}.ajax({
type: 'GET',
data: {
submit: 'true',
checkbox: AJS.$(this).attr('id'),
value: AJS.$(this).is(':checked') ? 'checked' : ''
},
url: "/location/for/this/stuff",
success: function(data) {
console.log(data);
},
error: function() {
console.log(data);
}
});
});
});
//]]>
This page should initially load with the checkbox unticked, and then when ticked, store the value and if the page is reloaded (due to the nature of confluence) it should remain ticked
Ever need a function to check your random or alike functions for output statistics
Here is a function to check a random function for outputs over ‘n’ no.of iterations, this is a useful function to check you algo or luck based random function this returns the return value of your function over hundred’s or thousand’s of iterations and arrange the results statistically like if you have set of expected outputs it shows like 1 returned 10 times in 100 times execution, 2 returned 20 times in 100 times execution and it also lists two other :
- Unexpected outputs
- Expected but not resulted outputs
- The execution time taken by code using epoch ms differences(Date object)
This function is useful over sectors like data analysis like chatGPT said or any other
Code :
//entering time
enter = new Date().valueOf();
//No need to modify this
function formatMsg(count,obj){
let status=false;
console.log(" In "+count+" times execution of your function, ");
for(a of Object.entries(obj)){
console.log(""+a[0]+" "+a[1]);
status=true;
}
}
function randomCheck(func,values,count=1000)
{
let list=[];
let unknown=[];
let expect=false,expected=[];
for(let i=0;i<count;i++){
list.push(func());
}
let obj = {};
var sum,sum2=0;
for(let j of values){
sum=0;
list.forEach((a)=>{
if(j == a) sum++;
});
obj[""+j+" resulted"] = "" + sum + " times";
sum2+=sum;
}
obj[" Total : "]=sum2;
//for values which are not resulted but expected
values.forEach((a)=>{
if(!list.includes(a)){
expect = true;
expected.push(a);
}
});
if(expect){obj[" Values which are expected to occur but didn't occur over "+count]=" executions";
expected.forEach((a)=>{
obj[" "+a]="";
});
}
//for values which are not expected but resulted
if(sum2!=count){
list.forEach((a)=>{
if(!values.includes(a)){
unknown.push(a)
}
});
obj[" Unknown values occured, "]="";
if(!unknown.length==0){
let temp={};
unknown.forEach(a=>{
if(Object.keys(temp).includes(""+a)){
temp[a]+=1;
}else{
temp[a]=1;
}
});
for(let itr of Object.entries(temp)){
obj[""+itr[0]+" resulted"]=" "+itr[1]+" times";
}
}
}
formatMsg(count,obj);
}
// update myfunc with your function code
myfunc=()=>{
return (Math.floor(Math.random()*100 + 1))
}
//update outputs with your array of outputs
let Outputs = [];
for(let i=1;i<=100;i++)
Outputs.push(i);
randomCheck(myfunc,Outputs,100);
/*This is the function you have to modify with your function and output here i have taken 1 .. 100 as outputs and my func is adjusted random to get 1 to 100 values and you can also specify the no.of iterations through count or by default the count will be 1000 */
//exiting time
exit = new Date().valueOf();
console.log("Overall execution time taken is approximately : "+(exit-enter)+" milliseconds...");
In node.js and npm, how can I prevent environment configs being passed on to required files?
I have a series of JS files in my node application that both perform a function (in this case Cypress tests) and export an object that can be used in other JS files.
I want to send an environment config variable when I run each file, eg
npm run main-tests --test=home-banner
The idea is that I can run a whole suite of tests by running npm run main-tests or just one test that belongs to that suite by running npm run main-tests --test=test-name.
In my main-tests.js file I have something like:
//main-tests.js
const homePageTests = require('./homePage/homePageTests.js');
const prodPageTest = require('./prodPages/prodPageTest.js');
const files = {...homePageTests.files, ...prodPageTest.files}; // <-all .spec.js file paths from subtests
let specs = Object.values(files);
if (process.env.npm_config_test) {
const testSpec = files[process.env.npm_config_test];
if (testSpec) {
specs = testSpec;
}
else {
console.error(`Test specification "${process.env.npm_config_test}" not found.`);
process.exit(1);
}
}
// do the tests.....
Then in my ‘sub-test’ JS files, eg homePageTests.js I have something similar:
//homePageTests.js
const files = {
"home-banner":"./homeBanner.spec.js",
"home-menu":"./homeMenu.spec.js",
};
let specs = Object.values(files);
if (process.env.npm_config_test) {
const testSpec = files[process.env.npm_config_test];
if (testSpec) {
specs = testSpec;
}
else {
console.error(`Test specification "${process.env.npm_config_test}" not found.`);
process.exit(1);
}
}
// do the tests.....
module.exports = {files};
Now, this all works fine, but for one thing: if I run npm run main-tests --test=home-banner the home-page config variable is also sent to prodPageTest.js and nothing gets run as home-page does not exist in the files object in prodPageTest.js and the conditional fails, hitting process.exit(1);
Obviously, this is something to do with the way I am ‘requiring’ the files (const prodPageTest = require('./prodPages/prodPageTest.js');).
Is there a way I can just include the files object from the subtest files, without including or running the rest of the code on that file?
Cannot mute microphone on Twilio call
I’m implementing a screen to make calls from the Twilio service:
At the moment, calls connect and I can hang up. The problem is that I can’t mute the microphone or the call (the button does nothing), and the “Status (Estado)” text only updates from “Disconnected (Desconectado)” to “On Call (En llamada.)”. Here’s the front-end code:
<?php
include 'php/conexion.php';
/**Validacion de Session**/
session_start();
if(!isset($_SESSION['user']['ID_Usuario'])){
header("Location: ../");
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<?php include_once 'include/head.php';?>
<!--<script src="js/funciones.js"></script>-->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="js/toast.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>
<!-- <script src="https://media.twiliocdn.com/sdk/js/voice/releases/2.13.0/twilio-voice.min.js"></script> -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
<title>Llamadas en linea</title>
<style>
#contenido_cliente table td {
vertical-align: top;
padding: 0.25rem 0.5rem;
}
#contenido_cliente td {
padding: 4px 8px;
vertical-align: top;
}
</style>
</head>
<?php include_once 'include/navbar.php'; ?>
<!-- Modal de espera -->
<div class="container-fluid">
<div class="row">
<?php include_once 'include/slide.php'; ?>
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
<div
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2 fw-bold">
Llamadas en linea
</h1>
</div>
<div class="card mt-4">
<div class="card-header bg-info text-white">
<h5 class="mb-0">Llamadas Telefónicas</h5>
</div>
<div class="card-body">
<div class="row">
<!-- COLUMNA IZQUIERDA: Teléfono + Dialpad -->
<div class="col-md-4">
<!-- Input + Botones -->
<div class="mb-3">
<label for="numero_llamar" class="form-label">Número a llamar</label>
<input type="text" class="form-control" id="numero_llamar" placeholder="(000) 000 0000">
</div>
<div class="mb-3">
<button class="btn btn-success me-2" id="llamar" onclick="realizarLlamada()">Llamar</button>
<button class="btn btn-danger me-2" id="colgar" onclick="colgarLlamada()">Colgar</button>
<button class="btn btn-warning me-2" id="mute" onclick="toggleMute()">Silenciar</button>
</div>
<div class="mb-3">
<strong>Estado:</strong> <span id="estado_llamada">Desconectado</span><br>
<strong>Duración:</strong> <span id="duracion_llamada">00:00</span>
</div>
<!-- Dialpad -->
<div class="border rounded p-3 mt-4">
<div class="col-md-12 text-center">
<div class="d-grid gap-2 mb-2" style="max-width: 200px; margin: auto;">
<div class="row">
<div class="col"><button class="btn btn-outline-dark w-100" onclick="agregarNumero('1')">1</button></div>
<div class="col"><button class="btn btn-outline-dark w-100" onclick="agregarNumero('2')">2</button></div>
<div class="col"><button class="btn btn-outline-dark w-100" onclick="agregarNumero('3')">3</button></div>
</div>
<div class="row">
<div class="col"><button class="btn btn-outline-dark w-100" onclick="agregarNumero('4')">4</button></div>
<div class="col"><button class="btn btn-outline-dark w-100" onclick="agregarNumero('5')">5</button></div>
<div class="col"><button class="btn btn-outline-dark w-100" onclick="agregarNumero('6')">6</button></div>
</div>
<div class="row">
<div class="col"><button class="btn btn-outline-dark w-100" onclick="agregarNumero('7')">7</button></div>
<div class="col"><button class="btn btn-outline-dark w-100" onclick="agregarNumero('8')">8</button></div>
<div class="col"><button class="btn btn-outline-dark w-100" onclick="agregarNumero('9')">9</button></div>
</div>
<div class="row">
<div class="col"><button class="btn btn-outline-dark w-100" onclick="agregarNumero('*')">*</button></div>
<div class="col"><button class="btn btn-outline-dark w-100" onclick="agregarNumero('0')">0</button></div>
<div class="col"><button class="btn btn-outline-dark w-100" onclick="agregarNumero('#')">#</button></div>
</div>
<button class="btn btn-secondary mt-2" onclick="borrarUltimoDigito()">Borrar último</button>
<button class="btn btn-danger mt-1" onclick="borrarTodoNumero()">Borrar todo</button>
</div>
</div>
</div>
</div>
<!-- COLUMNA CENTRO: Agenda -->
<div class="col-md-4">
<div class="mb-2">
<input type="text" class="form-control" id="filtro_contactos" placeholder="Buscar contacto por nombre..." onkeyup="filtrarContactos()">
</div>
<div style="max-height: 560px; overflow-y: auto;">
<table class="table table-bordered table-hover mb-0">
<thead class="table-light sticky-top bg-white" style="top: 0; z-index: 1;">
<tr>
<th>Nombre</th>
<th>Celular</th>
<th>Estatus numero</th>
</tr>
</thead>
<tbody id="tabla_contactos">
<!-- Contactos aquí -->
</tbody>
</table>
</div>
</div>
<!-- COLUMNA DERECHA: Información del Cliente -->
<div class="col-md-4">
<div id="detalle_cliente" class="border rounded p-3 bg-light">
<h5 class="mb-3">Información del Cliente</h5>
<div id="contenido_cliente" style="max-height: 560px; overflow-y: auto;" class="text-muted">Seleccione un contacto para ver los detalles.</div>
</div>
</div>
</div>
</div>
</div>
<?php include_once 'include/footer.php';?>
</main>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/@twilio/[email protected]/dist/twilio.min.js"></script>
<script src="../js/llamadas.js"></script>
</html>
Here’s the script:
let device;
let currentConnection;
let isMuted = false;
let callStartTime;
let durationInterval;
function actualizarEstado(estado) {
document.getElementById("estado_llamada").textContent = estado;
}
function actualizarDuracion() {
if (!callStartTime) return;
const now = new Date();
const diff = Math.floor((now - callStartTime) / 1000);
const minutes = String(Math.floor(diff / 60)).padStart(2, '0');
const seconds = String(diff % 60).padStart(2, '0');
document.getElementById("duracion_llamada").textContent = `${minutes}:${seconds}`;
}
let listaContactos = [];
function cargarContactos() {
fetch('php/llamadas.php?accion=contactos')
.then(res => res.json())
.then(clientes => {
listaContactos = clientes; // Guardamos para filtrar después
renderizarContactos(clientes);
})
.catch(err => {
console.error("Error al cargar contactos:", err);
});
}
function renderizarContactos(clientes) {
const tabla = document.getElementById("tabla_contactos");
tabla.innerHTML = "";
const agrupado = {};
// Agrupar por ID_Cliente
clientes.forEach(c => {
if (!agrupado[c.ID_Cliente]) {
agrupado[c.ID_Cliente] = [];
}
agrupado[c.ID_Cliente].push(c);
});
// Dibujar por cada grupo
Object.values(agrupado).forEach(grupo => {
grupo.forEach(c => {
const fila = document.createElement("tr");
fila.style.cursor = "pointer";
let numero = '';
let etiqueta = '';
if (c.Estatus === "1") {
numero = c.Telefono;
etiqueta = 'Actual';
} else if (c.Estatus === "0") {
numero = c.Telefono;
etiqueta = 'Anterior';
} else {
numero = c.Celular;
etiqueta = ''; // Sin etiqueta visible
}
// Acción al hacer clic
fila.addEventListener("click", () => seleccionarNumero(numero));
fila.innerHTML = `
<td>${c.NombreCompleto}</td>
<td>${numero}</td>
<td>${etiqueta}</td>
`;
tabla.appendChild(fila);
});
});
if (tabla.innerHTML.trim() === "") {
const fila = document.createElement("tr");
fila.innerHTML = `<td colspan="3" class="text-center">Información del cliente no disponible</td>`;
tabla.appendChild(fila);
}
}
function filtrarContactos() {
const filtro = document.getElementById("filtro_contactos").value.toLowerCase();
const filtrados = listaContactos.filter(c =>
c.NombreCompleto.toLowerCase().includes(filtro)
);
renderizarContactos(filtrados);
}
function seleccionarNumero(numero) {
document.getElementById("numero_llamar").value = numero;
const contenedor = document.getElementById("contenido_cliente");
contenedor.innerHTML = `<div class="text-info">Cargando información del cliente...</div>`;
fetch(`php/llamadas.php?accion=reporte_contratos&telefono=${numero}`)
.then(res => res.json())
.then(data => {
if (!Array.isArray(data) || data.length === 0) {
contenedor.innerHTML = `<div class="text-warning">Información del cliente no disponible.</div>`;
return;
}
contenedor.innerHTML = ""; // Limpiar contenido
// Si hay más de un contrato, usar pestañas
if (data.length > 1) {
const navTabs = document.createElement("ul");
navTabs.classList.add("nav", "nav-tabs");
navTabs.role = "tablist";
const tabContent = document.createElement("div");
tabContent.classList.add("tab-content");
data.forEach((contrato, index) => {
const contratoId = contrato.ID_Contrato || `Contrato ${index + 1}`;
const tabId = `contrato-${index}`;
// Crear pestaña
const tab = document.createElement("li");
tab.classList.add("nav-item");
tab.innerHTML = `
<a class="nav-link ${index === 0 ? 'active' : ''}" data-bs-toggle="tab" href="#${tabId}" role="tab">${contratoId}</a>
`;
navTabs.appendChild(tab);
// Crear contenido de la pestaña
const tabPane = document.createElement("div");
tabPane.classList.add("tab-pane", "fade");
if (index === 0) {
tabPane.classList.add("show", "active");
}
tabPane.id = tabId;
tabPane.role = "tabpanel";
tabPane.appendChild(crearTablaCliente(contrato));
tabContent.appendChild(tabPane);
});
contenedor.appendChild(navTabs);
contenedor.appendChild(tabContent);
} else {
// Solo un contrato
contenedor.appendChild(crearTablaCliente(data[0]));
}
})
.catch(err => {
console.error("Error al obtener reporte del cliente:", err);
contenedor.innerHTML = `<div class="text-danger">Ocurrió un error al obtener la información del cliente.</div>`;
});
}
function crearTablaCliente(data) {
const tabla = document.createElement("table");
tabla.classList.add("table", "table-bordered", "table-sm", "mb-0", "w-100");
tabla.style.tableLayout = "fixed";
for (const [key, value] of Object.entries(data)) {
const fila = document.createElement("tr");
const celdaClave = document.createElement("td");
celdaClave.classList.add("fw-bold", "text-end", "bg-light");
celdaClave.style.width = "45%"; // Aumentamos para dejar más espacio
celdaClave.style.paddingRight = "1rem";
celdaClave.style.whiteSpace = "nowrap";
celdaClave.textContent = key;
const celdaValor = document.createElement("td");
celdaValor.classList.add("text-start");
celdaValor.style.width = "55%";
celdaValor.style.paddingLeft = "1rem";
celdaValor.textContent = formatearValor(key, value);
fila.appendChild(celdaClave);
fila.appendChild(celdaValor);
tabla.appendChild(fila);
}
return tabla;
}
function formatearValor(key, valor) {
if (!valor) return "";
// Fechas (YYYY-MM-DD)
if (/fecha/i.test(key) && /^d{4}-d{2}-d{2}/.test(valor)) {
const fecha = new Date(valor);
if (!isNaN(fecha)) {
return fecha.toLocaleDateString("es-MX", {
day: '2-digit',
month: 'long',
year: 'numeric'
}).replace(/^(d+)sdes(w+)sdes(d{4})$/, (_, d, m, y) => `${d}-${m.charAt(0).toUpperCase() + m.slice(1)}-${y}`);
}
}
// Monto / dinero
if (/monto|precio|cuota|total|costo|pago|importe/i.test(key)) {
const num = parseFloat(valor);
if (!isNaN(num)) {
return num.toLocaleString('es-MX', {
style: 'currency',
currency: 'MXN',
minimumFractionDigits: 2
});
}
}
return valor;
}
function inicializarTwilio() {
fetch('{Servidor}/Twilio/example/token.php')
.then(response => response.json())
.then(data => {
device = new Twilio.Device(data.token, { debug: true });
device.on('ready', () => {
actualizarEstado('Listo para llamar');
});
device.on('error', (error) => {
actualizarEstado(`Error: ${error.message}`);
});
device.on('connect', (conn) => {
currentConnection = conn;
conn.on('disconnect', () => currentConnection = null);
});
device.on('disconnect', () => currentConnection = null);
})
.catch(err => {
actualizarEstado('Error al obtener token');
console.error(err);
});
}
function realizarLlamada() {
const numero = document.getElementById("numero_llamar").value;
if (!device) {
alert("Dispositivo aún no inicializado.");
return;
}
fetch('{Servidor}/Twilio/example/voice.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `To=+52${encodeURIComponent(numero)}`
}).then(() => {
device.connect();
callStartTime = new Date();
durationInterval = setInterval(actualizarDuracion, 1000);
actualizarEstado('En llamada');
document.getElementById("llamar").disabled = true;
}).catch(err => {
console.error("Error al enviar número al backend:", err);
alert("No se pudo iniciar la llamada.");
});
}
function colgarLlamada() {
if (device) device.disconnectAll();
callStartTime = null;
clearInterval(durationInterval);
document.getElementById("duracion_llamada").textContent = '00:00';
actualizarEstado('Desconectado');
document.getElementById("llamar").disabled = false;
}
function toggleMute() {
if (!currentConnection) return;
const localStream = currentConnection.mediaStream?.stream;
if (localStream) {
const audioTrack = localStream.getAudioTracks()[0];
if (audioTrack) {
isMuted = !isMuted;
audioTrack.enabled = !isMuted;
actualizarEstado(isMuted ? "Silenciado (micrófono apagado)" : "En llamada");
}
}
}
function agregarNumero(digito) {
const input = document.getElementById("numero_llamar");
input.value += digito;
}
function borrarUltimoDigito() {
const input = document.getElementById("numero_llamar");
input.value = input.value.slice(0, -1);
}
function llenarNumero(numero) {
document.getElementById("numero_llamar").value = numero;
}
function borrarTodoNumero() {
document.getElementById("numero_llamar").value = '';
}
window.addEventListener('DOMContentLoaded', () => {
inicializarTwilio();
});
document.addEventListener("DOMContentLoaded", () => {
cargarContactos();
});
In the Twilio API section, I have two files configured. The first is “token.php,” where the connection is configured:
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header('Access-Control-Allow-Headers: Content-Type');
require(__DIR__.'/../src/Twilio/autoload.php');
// Cargar credenciales desde la ruta específica
$config = require 'C:\conf_twilio\config.php';
use TwilioJwtAccessToken;
use TwilioJwtGrantsVoiceGrant;
$identity = 'Isilisi'; // Puede ser dinámico (ej: $_SESSION['user_id'])
try {
$token = new AccessToken(
$config['TWILIO_ACCOUNT_SID'],
$config['TWILIO_API_KEY'],
$config['TWILIO_API_SECRET'],
3600,
$identity
);
$voiceGrant = new VoiceGrant();
$voiceGrant->setOutgoingApplicationSid($config['TWIML_APP_SID']);
$voiceGrant->setIncomingAllow(true);
$token->addGrant($voiceGrant);
echo json_encode([
'identity' => $identity,
'token' => $token->toJWT(),
'callerId' => $config['TWILIO_CALLER_ID']
]);
} catch (Exception $e) {
header('HTTP/1.1 500 Internal Server Error');
echo json_encode(['error' => 'Error al generar token: ' . $e->getMessage()]);
}
?>
And finally, “voice.php,” where the request to connect the call is made. Both files exist at the same API level:
<?php
header('Access-Control-Allow-Origin: *'); // Permite peticiones desde cualquier origen
header('Access-Control-Allow-Methods: GET, POST');
header('Access-Control-Allow-Headers: Content-Type');
// voice.php
header('Content-Type: text/xml');
$to = $_POST['To'] ?? null;
if ($to) {
// Guardar temporalmente en archivo
file_put_contents(__DIR__ . '/numero.txt', $to);
exit; // Terminar si solo estamos guardando
}
// Si no vino por POST, entonces Twilio está solicitando el TwiML
$numero = @file_get_contents(__DIR__ . '/numero.txt');
echo '<?xml version="1.0" encoding="UTF-8"?>';
?>
<Response>
<?php if ($numero): ?>
<Dial callerId="+523341711661">
<Number><?php echo htmlspecialchars($numero); ?></Number>
</Dial>
<?php else: ?>
<Say>No se proporcionó un número para llamar.</Say>
<?php endif; ?>
</Response>
The main thing I need to fix is the microphone not muting, but I’m open to any other code improvements you might suggest. Thanks a bunch for your help!
babel-plugin-require-context-hook error: __requireContext is not defined
I was trying to use babel-plugin-require-context-hook to make jest to digest require.context()
, and, as a result of that, my tests finally started running smoothly.
At the same time though, my expo app itself started failing with the below error:
Metro error: __requireContext is not defined
Call Stack
factory
node_modules/expo-router/_ctx-html.js
loadModuleImplementation
node_modules/metro-runtime/src/polyfills/require.js
guardedLoadModule
node_modules/metro-runtime/src/polyfills/require.js
require
node_modules/metro-runtime/src/polyfills/require.js
factory
node_modules/expo-router/build/static/getRootComponent.js
loadModuleImplementation
node_modules/metro-runtime/src/polyfills/require.js
guardedLoadModule
node_modules/metro-runtime/src/polyfills/require.js
require
node_modules/metro-runtime/src/polyfills/require.js
factory
node_modules/expo-router/build/static/renderStaticContent.js
loadModuleImplementation
node_modules/metro-runtime/src/polyfills/require.js
I have this line in my source js file where require.context() is:
require('babel-plugin-require-context-hook/register')()
Making it conditional, doesn’t help either:
if (process.env.NODE_ENV === 'test') {
require('babel-plugin-require-context-hook/register')();
}
Would appreciate any help.
babel.config.js:
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
"plugins": [
[
"@babel/plugin-proposal-optional-chaining-assign",
{
"version": "2023-07"
}
],
["require-context-hook"]
]
};
};
package.json
"dependencies": {
"babel-plugin-require-context-hook": "^1.0.0",
...
Why does “Rendered more hooks than during the previous render” occur when generating components inline in the return statement?
I have a component that renders 100 instances of another component which internally uses hooks.
When I use this logic inline inside the return statement, like this:
export const MyComponent: StoryFn<typeof ParentComponent> = () => (
<someAnotherComponent>
{Array.from({ length: 100 }).map((_, index) => (
<currentComponent.Reaction
counter={index}
mine={index % 3 !== 0}
/>
))}
</someAnotherComponent>
);
gives this:
Rendered more hooks than during the previous render.
But when I add key={index} it solves the issue:
export const MyComponent: StoryFn<typeof ParentComponent> = () => (
<someAnotherComponent>
{Array.from({ length: 100 }).map((_, index) => (
<currentComponent.Reaction
key={index}
counter={index}
mine={index % 3 !== 0}
/>
))}
</someAnotherComponent>
);
This doesn’t give the error. Can someone explain me why?
Web Audio API Question (Beginner programmer)
I’m trying to wrap my head around how to use the Web Audio API. I’m building a simple EQ Google Chrome extension to help EQ some bad-sounding audio I listen to on YouTube and elsewhere.
There’s a quirk about the API, I’m not fully understanding. I’ve read the documentation and still don’t understand something fundamental –
Why is that with the Gain Node, you can create an instance of it two ways- one, using the factory method on the audio context, and the other with the new GainNode() syntax.
Do other audio nodes have this option? Or just the Gain node? If so, why just the gain node, and not the EQ per se?
✅ const gain = window._audioCtx.createGain();
✅ const gainNode = audioContext.createGain();
Works!
❌ const EQ = window._audioCtx.createEQ();
✅ const EQ = new BiquadFilterNode(window._audioCtx);
How to disconnect MutationObserver when one of the elements undergoing mutation is no longer found
I have a MutationObserver to perform some logic as DOM elements are being added. At the end I need to disconnect the observer. That decision is itself based on whether a certain element exists or not. If the loadingElement no longer exists in the DOM, that’s when I need to disconnect the observer. But is it safe to do this inside the MutationObserver function?
const targetElement = document.querySelector('div.serviceRequest');
// Create a MutationObserver
const observer = new MutationObserver(function(mutationsList) {
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
updateSubmenuWhenScrolling();
}
// TODO: If a certain element is no longer found, need to disconnect
// let loadingElement = document.querySelector('div.loading');
// if (!loadingElement) {
// observer.disconnect(); // ???
// }
}
});
// Configure the observer to watch for child list changes in the subtree
const config = { childList: true, subtree: true };
// Start observing the target element
if (targetElement) {
observer.observe(targetElement, config);
}
why is the cube zooming out but is not moving to the top-right side of the screen? [closed]
I have a Three.js scene where I animate a Rubik’s-cube–style object by “zooming out” (scaling it down) and I’d also like it to drift toward the top-right corner of the viewport as it shrinks. Right now the scaling works perfectly, but any translation I apply to the scene or the camera has no visible effect.
Link to my code
https://github.com/Osman-bin-nasir/Portfolio
Tried translating the scene
Tried panning the camera by capturing its initial position and then updating each frame
updateAutonumericInput not updating certain things
I have a Shiny app where when one input is changed, I want other inputs to update. In the example I’ve provided below, I have a autonumericInput() with a starting value of 1. There’s also an actionButton(), and clicking on this button is supposed to update the autonumericInput() in 3 ways:
- Change the value from 1 to 10. (which works)
- Change the number of decimal places displayed from 2 (the default starting value) to 0. (also works)
- Change the color of the font from red to black. (doesn’t work!)
Upon clicking the actionButton, the value in the autonumericInput should go from 1.00 to 10, along with a text color change. But the color change not working makes me think that the style update isn’t being acknowledged for some reason. Any idea why?
Example code:
library(shiny)
library(shinyWidgets)
server = function(input, output) {
shiny::observeEvent(input$button, {
# This is where the update happens. The value and decimal places get updated,
# but not the text color.
shinyWidgets::updateAutonumericInput(
inputId = "test",
value = 10,
options = list(
decimalPlaces = 0,
style = "color: black;"
)
)
})
}
ui = function() {
# This is how the app loads, and all styling works just fine.
shiny::fluidPage(
shiny::actionButton(inputId = "button", label = "Press Me"),
shinyWidgets::autonumericInput(
inputId = "test",
label = NULL,
value = 1,
style = "color: red;"
)
)
}
shiny::shinyApp(ui = ui, server = server)
I’ve also messed around with font-size & various other style-related CSS options within the updateAutonumericInput() call, but none are applied when I click the actionButton().
How to customize return message of zod object schema, JS
In following schema:
const mySchema = z.object(
{
key1: z.string().nonempty(),
key2: z.record(z.unknown()).optional(),
key3: z.string().optional(),
},
{ error: (iss) => (Array.isArray(iss.input) ? 'custom message' : undefined) }
)
.strict();
When schema is given an array I would like to receive a custom message, and if it is not an array or not an object the standard error message, “expected object, received …”.
I do not understand why but when safe parsing a variable which holds an array the schema returns “expected error, received array” instead the custom message.
Any help would be much appreciated.