lunes, 26 de mayo de 2025

Fixing ZTopInc WiFi Driver Compilation on Ubuntu 24.04 LTS

UPDATE 2026: Fix for new linux kernel versions (6.17+) in this branch: https://codeberg.org/anlijudavid/driver_wifi_ztopinc/src/branch/linux-kernel-6-17 

__________________________________________ 

If you're struggling to get your ZTopInc 802.11n NIC (USB ID: 350b:9101) working on Ubuntu 24.04, you're not alone. The driver available in most repositories fails to compile on modern Linux kernels due to outdated code that hasn't been updated for recent kernel changes.

The Problem

When trying to compile the ZTopInc Wi-Fi driver on Ubuntu 24.04 with kernel 6.11, you'll encounter these compilation errors:

/src/os/linux/hif/usb.c:1114:2: error: invalid preprocessing directive #elseif; did you mean #else?
/src/os/linux/hif/usb.c:1115:6: error: 'struct usb_driver' has no member named 'drvwrap'

The driver was written for much older kernel versions and uses deprecated structures and incorrect preprocessor syntax.

The Root Cause

Two main issues prevent compilation:

  1. Invalid preprocessor directive: The code uses #elseif instead of the correct #elif
  2. Obsolete kernel structure: The drvwrap.driver.shutdown field no longer exists in modern kernel versions

The problematic code looked like this:

#elseif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) && (LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0))
    .drvwrap.driver.shutdown = zt_usb_shutdown,

The Solution

The fix is straightforward but essential for modern kernel compatibility:

#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19))
    .shutdown = zt_usb_shutdown,

Getting the Fixed Driver

I've created a pull request with the fix to the original repository, and also maintain a fork with the working code:

Installation

To use the fixed driver on Ubuntu 24.04:

# Clone the working fork
git clone https://codeberg.org/anlijudavid/driver_wifi_ztopinc.git cd driver_wifi_ztopinc/src 

# Compile
make 
 
 # Install
sudo insmod ./zt9101_ztopmac_usb.ko cfg=./wifi.cfg

Verified Working Environment

This fix has been tested and confirmed working on:

  • OS: Ubuntu 24.04 LTS
  • Kernel: 6.11.0-26-generic
  • Device: ZTopInc 802.11n NIC (idVendor=350b, idProduct=9101)
  • Compiler: gcc-13

Why This Matters

These kinds of compatibility issues are common with older drivers as the Linux kernel evolves. Small syntax errors and deprecated structures can completely break compilation, leaving users unable to use their hardware on modern systems.

By maintaining updated forks and contributing fixes back to original repositories, we can keep older hardware working with current Linux distributions.

If you have this WiFi adapter and have been struggling to get it working on recent Ubuntu versions, give the fixed driver a try!

The end ...

jueves, 16 de enero de 2025

[Story] La arepa de huevo en la vitrina

La arepa de huevo, que no solo tiene huevo, sino también pollo, la vende la vecina del frente. Todos los días saca a la vitrina unas cuantas para vender; también vende papa rellena. La pequeña vitrina, que de pequeña solo tiene el nombre, hace que las arepas de huevo en el segundo piso se colapsen unas sobre otras, al igual que las papas rellenas, haciendo que entren muchas.

Las arepas de huevo son diferentes: la masa de maíz amarillo crocante y gruesa, y por dentro, pollo desmechado que se combina con el huevo para hacer un relleno muy sabroso. Se siente la grasa, que aparenta ser reciente y no parecería provenir de los aceites de las arepas de huevo de hace quince días; el pollo junto al huevo hacen una perfecta combinación de sabores.

La pequeña vitrina, a diferencia de otras que vienen acompañadas de un pequeño vigilante volador negro, por suerte la vitrina protagonista no cuenta con este diminuto insecto; de lo contrario, nunca se escribiría ninguna historia sobre ella y su contenido. En ocasiones, mientras camino por la calle, veo otras vitrinas que sí cuentan con la presencia de aquellos insectos negros, algunas veces encima de algún pan, otras sobre alguna empanada, y también sobre alguna que otra morcilla negra mientras se ahúma. Por suerte, mi vecina no cuenta con la desagradable compañía de aquel animal de alas redondas, lo que provoca en mí esa sensación de pulcritud, y más cuando la señora que me atiende lleva puesto su delantal blanco y visualmente limpio.

Un día más, las arepas de huevo están ausentes de la vitrina. Por alguna razón, es la comida más popular del lugar; no sé por qué se vendería más una arepa de huevo que una papa rellena. Quizás sea una particularidad del sector donde abunda el alcohol; la sequía, el mareo y el hambre de comer algo con grasa y delicioso de aquellos personajes deambulantes nocturnos hace que ruja alguna que otra tripa.

La noche se desarrolla; al ojo de buen cubero, habrá unas tres arepas de huevo restantes. No durarán mucho, pues alguna tripa rugiente hará que su huésped vaya, sin dudarlo, a comprar una de esas preparaciones de maíz crujiente.

[Sueño] El mundo virtual a través de un monitor 4D

Hoy 26 de noviembre de 2024 tuve un sueño muy extraño pero interesante. El sueño arrancó en primera persona, no es tan común este tipo de sueños en mí porque suelo estar en ellos en una forma omnisciente, donde puedo estar viendo todos los sucesos del sueño desde arriba o algún lado sin que nadie sepa de mi existencia, ni siquiera me contaría como un ser orgánico, la sensación que tengo en esa forma es inmaterial y quizás la palabra “astral” aplique aquí. Luego están los otros sueños, donde puedo estar en primera persona, donde experimento todo de primera mano, dolor, susto, felicidad, etc. No solo emociones, sino sentir a través de mis sentidos físicos como tacto y la presión que hago sobre los objetos que toco.

Aparecí de repente en una feria de tecnología, fue como abrir los ojos y estar rodeado de gente en un lugar donde se encontraban varios productos tecnológicos en exhibición. Di unos pocos pasos y me he topado con un expositor al que le hablé en un mal inglés porque se me trabó la lengua, él de alguna forma supo que hablaba español (quizás por mi acento) por lo que me respondió en este idioma. Me invitó a probar una demo que tenía en su stand de exposición, que inicialmente era muy simple: una computadora portátil sobre una mesa. La computadora no era como las de Apple, delgadas y diseño afinado, esta era diferente porque era todo lo contrario: gruesa y rústica. Así como las computadoras todoterreno que usan los militares en las películas (seguramente de aquí mi mente inconsciente tomo la referencia).


Me acerqué a la computadora y observé su pantalla. Mostraba lo que parecía ser un edificio en 3 dimensiones, representado solo por sus aristas y terminaciones, sin detalles adicionales ni objetos cotidianos. El expositor intervino para mostrarme más y comenzó a navegar por el mundo tridimensional como si fuera un videojuego, usando un periférico externo. Luego tomó un objeto de la mesa junto al computador: una cajita negra rectangular del tamaño de dos palmas de mano. Me recordaba a esas cajas donde vienen las gafas de sol nuevas, aunque no creo que contuviera unas gafas. En realidad, su contenido no era lo importante, sino lo que el expositor estaba a punto de hacer con ella...

Tomó la cajita negra y la introdujo en la pantalla de la computadora. Fue algo extraordinario, pues jamás había visto un objeto físico atravesar una pantalla digital como si fuera un portal. El expositor metió toda su mano, traspasando la pantalla mientras manipulaba la caja dentro del mundo virtual. La caja quedó ubicada dentro del edificio que, aunque inicialmente parecía ser solo un modelo tridimensional, resultó ser una representación de un edificio físico real que podía explorarse a través de la pantalla.

En este punto, el expositor retiró su mano de la pantalla, dejando la cajita negra del otro lado. La caja había quedado físicamente ubicada en alguna parte del edificio real.

Era mi turno. El expositor me invitó a buscar la caja por mí mismo, introduciendo la mano a través de la pantalla. Sentía cierto temor al intentarlo, consciente de estar probando una tecnología experimental. Me armé de valor y toqué la pantalla suavemente, sin ejercer presión—se sentía como cualquier pantalla normal. El expositor me animó a intentarlo nuevamente, esta vez presionando con más fuerza.


Esta vez, al ejercer más presión, la sensación fue diferente: una fuerte corriente eléctrica y presión en la punta de mis dedos (lo único que había logrado traspasar hasta ese momento). Sentía un leve dolor que bordeaba el umbral de lo tolerable—pensé que si aumentaba tan solo un poco más, se volvería insoportable. Me movía muy lentamente, considerando que era la velocidad más segura para probar esta tecnología. Finalmente, logré introducir toda la mano y desplazarme a través del espacio mostrado en la pantalla. El dolor pasó a segundo plano; mi mente lo procesaba inconscientemente mientras me concentraba en los movimientos de mi mano al otro lado de la pantalla. Después de unos minutos, encontré la caja, la agarré y la saqué de la pantalla.


Aquí el sueño termina.

miércoles, 8 de noviembre de 2023

Amplitude: Entendiendo los tipos de medición en User Composition

El gráfico Composición de usuarios (User Composition) en Amplitude muestra el desglose de usuarios activos en función de una única propiedad de usuario. Este tipo de graficos en Amplitude proporciona información sobre quiénes son sus usuarios y qué propiedades comparten.

En la secciòn "Measured as" disponemos de 3 opciones para efectuar la medicion de la composicion "Most Recent Value", "All Values" y "Cross Property Values":

  1. Most Recent Value (Valor más reciente):
    Este enfoque considera únicamente el valor más reciente de una propiedad para cada usuario.

    - El valor se extrae del evento más reciente en el que el usuario participó.
    - Cada usuario aparecerá en solo un grupo en función de su valor más reciente.
    - Por ejemplo, si estás analizando la propiedad "País" y un usuario cambió su país de residencia, solo se considerará el país más reciente en el gráfico.
    - Otro ejemplo, si tienes una propiedad de usuario llamada “Plan de Suscripción” y un usuario cambia de un plan gratuito a uno de pago, el valor más reciente de esa propiedad reflejará el plan de pago.

  2. All Values (Todos los valores):
    Aquí se incluyen todos los valores que tus usuarios activos han tenido para la propiedad en cuestión durante el período de análisis.
    - Ten en cuenta que el gráfico de User Composition solo incluye usuarios activos, por lo que los valores de propiedades relacionados con eventos inactivos no se tendrán en cuenta.
    - Si un usuario ha tenido varios valores para una propiedad a lo largo del tiempo, todos esos valores se considerarán en este enfoque.

  3. Cross Property Values (Valores cruzados de propiedades):
    Este enfoque muestra conjuntos de propiedades que los usuarios activos han tenido dentro del rango de tiempo seleccionado.
    - Los grupos son mutuamente excluyentes, lo que significa que un usuario solo puede caer en un grupo.
    - Por ejemplo, si estás analizando las propiedades "Género" y "Edad", los usuarios se agruparán según combinaciones específicas de género y edad.

viernes, 13 de octubre de 2023

Enmascarar email con Javascript

Cuando se trata de proteger la privacidad en línea, ocultar direcciones de correo electrónico es una práctica común. En este breve artículo, exploraremos el uso de expresiones regulares (regex) en un ejemplo de código React para lograr este propósito. Vamos a analizar el siguiente código:
import { useState } from "react";

const email = "my.custom.email@domain.com";
const regex = /(\w{3}).*/g;

export function App() {
  const [hide, setHide] = useState(false);
  const renderEmail = hide
    ? email.replace(regex, "$1********@********")
    : email;

  return (
    <div>
      {renderEmail}
      <br />
      <button
        type="button"
        onClick={() => {
          setHide((prev) => !prev);
        }}
      >
        {hide ? "Show email" : "Hide email"}
      </button>
    </div>
  );
}

Desglose del Regex:

En este código, se utiliza la expresión regular /(\w{3}).*/g para ocultar parte de la dirección de correo electrónico. Desglosemos cada parte:
  • /: Delimita el inicio y el final de la expresión regular.
  • (\w{3}): Captura los primeros tres caracteres de la dirección de correo electrónico y los almacena en el grupo de captura $1.
  • .*: Coincide con el resto de la dirección de correo electrónico.

Desventajas y solución:

Aunque esta técnica puede ser efectiva, presenta algunas desventajas:
  • Dependencia del lado del cliente: Este enfoque depende del código ejecutándose en el lado del cliente, lo que significa que no proporciona una solución integral de seguridad. Recuerda que la seguridad es un tema complejo, y estas soluciones deben usarse con precaución y en combinación con otras medidas de seguridad.
  • Limitado a direcciones específicas: Este regex asume que las direcciones de correo electrónico siempre tendrán al menos tres caracteres antes del símbolo '@', lo cual puede no ser cierto en todos los casos. Aquí propongo dinamizar la captura de los elementos con regex de la siguiente manera:
const regex = /(.*)@.*/g;
const renderEmail = hide
    ? email.replace(regex, (match, group1) => {
        const usernameLength = group1.length;
        return `${group1.substring(0, usernameLength / 2)}${'*'.repeat(usernameLength / 2)}@${'*'.repeat(6)}`
})
    : email;
    • Se define una expresión regular (/(.*)@.*/g) que busca una cadena que tenga algún texto antes y después del símbolo '@' en una dirección de correo electrónico.
    • Luego, el reemplazo se realiza tomando el texto antes del símbolo '@' y reemplazando la segunda mitad de ese texto con asteriscos. También se reemplaza la parte después del '@' con asteriscos.

Configurar correo Gmail corporativo con Thunderbird

Thunderbird
Thunderbird

Thunderbird, el cliente de correo electrónico libre y de código abierto, está de vuelta con un nuevo enfoque. La nueva versión de Thunderbird, que se lanzó en octubre de 2023, presenta un nuevo diseño, nuevas funciones y un nuevo enfoque en la privacidad y la seguridad.

Cómo agregar una cuenta de Gmail corporativo a Thunderbird

Agregar una cuenta de Gmail corporativo a Thunderbird es un proceso relativamente sencillo. Sigue estos pasos:

1. Asegúrate de que tu cuenta de Gmail corporativo esté habilitada para IMAP. Para activar IMAP en la consola de administración, ve a https://gmail.com/ y haz clic en Settings (icono de engranaje ubicado en la parte superior derecha)See all settingsForwarding and POP/IMAP. Asegúrate que IMAP está activado (IMAP is enabled). Activar en caso de que no lo esté.

Activar IMAP en Gmail


2. Abre Thunderbird.

3. En Thunderbird, haz clic en Settings > Account Actions > Add Mail Account.


Agregar cuenta de correo en Thunderbird

4. Introduce el Nombre de tu empresa, tu dirección de correo electrónico de Gmail corporativo, (la contraseña aún no):

Llenar formulario inicial de agregar cuenta en Thunderbird

5. La misma contraseña para correos corporativos no puede ser usada para iniciar sesión en Thunderbird, en este caso, debemos usar una contraseña alterna que debemos crear a continuación. Para ello, usaremos la guía oficial que ofrece Google:

|. Ve a tu Google Account.

2.  Seleccionar Seguridad (o "Security"). 

3. Debajo de la sección "Signing in to Google," selecciona "2-Step Verification" (y proceder con la autenticación que Google solicite)

Verificación de dos pasos 

 4. Al final de la pagina, seleccionar "App passwords" o "Contraseñas de aplicaciones".

Botón final de contraseñas de aplicaciones

5. Ingrese un nombre que te ayude a recordar la contrasña de la aplicacion.
6. Seleccionar Generar. 
7. Copia la contraseña que aparece en tu pantalla. La contraseña tendrá 16 caracteres y no debe ser compartida jamás.
Contraseña de aplicación generada (demo)

6. Volviendo a Thunderbird, necesitaremos pegar la contraseña de aplicación generada anteriormente en el campo de Contraseña o Password.

Pegando contraseña de aplicación de Google en Thunderbird

7. Configurar manualmente los parámetros restantes siguiendo las instrucciones de soporte de Google:

Incoming Mail (POP) Server

pop.gmail.com

Requires SSL: Yes

Port: 995

Outgoing Mail (SMTP) Server

smtp.gmail.com

Requires SSL: Yes

Requires TLS: Yes (if available)

Requires Authentication: Yes

Port for TLS/STARTTLS: 587

If you use Gmail with your work or school account, check with your administrator for the correct SMTP configuration.


Configuración manual de los protocolos para Incoming & Outgoing Server


8. Clic en Re-test y luego en Done, Thunderbird se conectará a tu cuenta de Gmail corporativo y sincronizará tus correos electrónicos, contactos y calendario.

viernes, 15 de septiembre de 2023

No pude hacer pan de trigo pero si pan de yuca

¡He conseguido hacer exitosamente pan de yuca, este es mi pan favorito! Me encanta demasiado este pan y tenía que aprender a prepararlo, pero antes de preparar este pan tuvieron que pasar varios días y 3 intentos fallidos para hacer pan. El primer intento hice la masa con su respectiva levadura, queso, harina de trigo, sal y azúcar, la amasé un par de minutos y la dejé en reposo para que la levadura se activara. 1 hora después la masa seguía igual y no había crecido ni un milímetro, sabía que algo andaba mal, pero como era mi primer pan decidí meterlo al horno, después de 60 minutos había hecho un desastre, por fuera se miraba fenomenal, pero por dentro la masa estaba dura y fea. Ese día con mucho dolor tuve que tirar a la basura todo el resultado, nadie comería ese pan.

Supe que en ese primer intento mi error fue no dejar activar la levadura, así que para el segundo intento usé los mismos ingredientes, pero esta vez amase por mucho más tiempo y usé otra levadura porque quizás la que tenía en casa estaba dañada, también recurrí a un método que encontré en internet que consiste en dejar que la levadura se active por separado en un mínimo de harina de trigo con agua tibia, luego este se revuelve con el resto de la masa y esperé que la levadura se activara, 2 horas después noté que la levadura había hecho efecto, pero era muy mínimo e insuficiente, aun así decidí continuar y hornear. El resultado fue otro desastre, aunque no tanto como el 1.er intento, esta vez pude comer pan, pero solo las partes que quedaron parcialmente bien, el resto tuve que botarlo, intenté darlo a las aves a través de la ventana de mi casa y ni las palomas quisieron comerlo.

Mis dos intentos anteriores siempre los hice en la tarde, pensé que quizás si empezaba desde temprano a preparar la masa podría dar el tiempo suficiente para activar la levadura, para este momento recién había aprendido que la levadura se activa dependiendo de la temperatura ambiente y que en zonas de frío es muy difícil, así entendí que por esta razón fallaba mi proceso, pues donde estoy la temperatura por lo general está bajo los 16 grados centígrados. Sabiendo esto, decidí hacer un tercer intento, esta vez amasando la masa por mucho tiempo y dejando la masa esperando que la levadura se activara durante muchas horas, también intenté replicar un ambiente húmedo y temperatura ideal para la levadura poniendo el horno a una temperatura de 25 grados más o menos y con agua en el fondo del horno en otro recipiente para intentar humedecer el interior del horno. En la tarde noche decidí hornear lo que sería el 3.er desastre.

Frustrado de no poder hacer pan, pero sabiendo que principalmente la falla fue activar la levadura, decidí parar mis intentos de hacer pan de trigo. Tuve una charla con una amiga que sabe hacer pan y le he comentado todos los problemas que tuve, ella me ha sugerido hacer pan de yuca porque no requiere activar la levadura, cuando escuché eso mi cerebro se iluminó y rápidamente recuperé mis esperanzas de hacer pan. Al siguiente día fui a la tienda y compré 1 libra de almidón de yuca, 500 gramos de queso campesino y 1 litro de leche entera para luego comenzar a preparar el pan, lo amase con otros ingredientes que ya tenía en casa y deje un rato que la levadura se activara, obviamente sabía que no lo lograría, pero había que intentarlo una última vez. Como imaginarán, ningún hongo de levadura se movió, todo siguió igual, la masa no había crecido ni cambiado de color, pero esto no me importaba en absoluto porque sabía que para este pan eso no era muy relevante. Hice las bolitas de pan con las manos, y lo dejé sobre la bandeja de latón que previamente había preparado con mantequilla en la superficie para evitar que se pegara el pan. Después de 20 minutos de horneado ya había logrado hacer por primera vez pan de yuca, quedó esponjoso y muy delicioso, todo perfecto, excepto que durante el horneado el pan creció tanto que se pegaron los unos con los otros. Tengo pendiente hacer una segunda versión mejorada, esta vez con las bolitas de pan más pequeñas y más separadas para evitar que se peguen.

miércoles, 16 de agosto de 2023

Tras la huella del Error: Cómo Solucioné un Problema de Render en React

Ayer, miércoles 16 de agosto, desde el equipo de QA me llegó un reporte de un error en uno de los desarrollos que había realizado, un error atípico y difícil de diagnosticar. Estuve en la mañana colocando Logs y debuggers por todos lados, los componentes afectados en los últimos cambios aparentemente no mostraban inconsistencias y renderizaciones fuera de lo normal. Pude replicar el error, pues sucedía al desplazarme por una serie de Tabs y el contenido correspondiente a cada Tab provocaba bloqueos en el sitio web. Usar la extensión React Devtools era imposible, pues al tener un error de bloqueo total de la pagina no era posible navegar, inspeccionar y usar extensiones de Chrome durante el crash.

Al tener un bloqueo de la pagina web es común pensar en una serie de excepciones que van rompiendo todo, también es cierto que en un contexto de desarrollo web puede tratarse de iteraciones indefinidas de un mismo elemento, componente o función, por eso, al llegar a la conclusión de que el problema debía ser un renderizado incontrolado de algún componente de React esta debía ser la sospecha #1.

Primer intento

Revisión superficial del problema y diagnostico inicial. Los nuevos cambios involucraban llamados a diferentes Queries de Grahpql y renderizado de componentes nuevos, por ello fue necesario validar los siguientes puntos:
  • Peticiones: Desde el navegador web, abrir el inspeccionador de elementos e ir hasta el Tab "Red" (o "Network" en Inglés) para validar que no existan llamados recurrentes e innecesarios de los queries de Graphql.
    • Resultado: Todo a la normalidad.
  • Errores en consola: Revisar que no se tengan errores o advertencias en la consola del navegador (Tab "Consola").
    • Resultado: Todo a la normalidad.
  • Profiling: Intentar hacer Profiling de los componentes de React usando la extension React Devtools.
    • Resultado: No se pudo realizar profiling debido al bloqueo de la pagina al momento de activar la opción cuando el bug se había presentado.
  • Error Boundary: Agregar como padre uno de los componentes custom llamado ErrorBoundary que sirve par capturar errores en los componentes hijos.
    • Resultado: No hubo errores, por lo tanto ErrorBoundary estaba puesto en vano.

Segundo intento

Lo primero que debía hacer era descartar que se trataba de un error en los componentes principales, por eso, el segundo intento para detectar el problema fue abrir el inspeccionador de elementos de Google Chrome y desde la opción de "Fuentes" (o "Sources" en Inglés) activar la casilla "Detenerse cuando se detecten excepciones". Una vez activada la detección de excepciones se procede a navegar en el sitio web para desencadenar todo tipo de excepciones sea cual sea que ocurran durante la navegación, así cuando el Bug se presente lo podremos ver en cuestión (siempre y cuando arroje una excepción).

Un par de horas después, había realizado el proceso de depuración de varios errores, encontrando y solucionando algunos problemas mínimos con la ayuda del step-by-step del inspecionador del navegador web. Este primer intento se consolida al detectar varios errores provocados por la carga Lazy Load de algunos componentes de React, sin embargo, tenia que intentar esta opción a pesar que no sirva para detectar errores de renderizado infinito en React. En conclusión, este segundo intento me sirvió para encontrar puntos de mejora y validaciones extra, pero no para hallar el problema real.

Tercer intento

Después de despejar la mente, almorzar y caminar un rato por la calle, volví a casa, hice masa de pan y la puse en un recipiente para que la levadura se activara y la masa creciera, luego abrí el sitio web de Mercado Libre (o MELI) para buscar algunos productos de intereses, y al cabo de unos minutos no había comprado nada pero si me encontraba inspeccionando el sitio web con la extension de React Devtools, encontré que algunos componentes de MELI se están renderizando de forma innecesaria con solo hacer unas pocas acciones como un hover, también vi que usan servicios Graphql y las traducciones de los productos vienen desde Backend.

En fin, durante esta inspección he terminado descubriendo de forma accidental y activando la casilla "Highlight updates when components render" ubicada en "React Developer Tools > View Settings > General > Highlight updates when components render". Activar la visualización de cambios me permitió ver cada update en los componentes de MELI, esta característica resultó ser muy útil para identificar qué componentes se están actualizando durante la navegación en el sitio web.


Una vez encontrada y activada esta característica, seguí indagando sobre el problema inicial. Durante el primer diagnostico, al intentar hacer Profiling durante la replicación del problema no se lograba iniciar y procesar debido al bloqueo de la pagina, provocando un colapso de todo el sitio web e impidiendo realizar cualquier acción, la única salida era el cierre forzado de la pestaña del navegador, sin embargo, una vez dejando activada la visualización de cambios podía navegar por el sitio web y luego replicar el problema para poder observar segundos antes del colapso qué componentes se estaban renderizando de manera descontrolada. Y así fue que logré identificar el componente a corregir.

Todo se resumió a un problema, regeneración de referencias de objetos que pasan como props a otros componentes. Los componentes recibían estos props y realizaban una acción con un useEffect, este luego realizaba otra acción que cambiaba la referencia de una de sus dependencias, y así sucesivamente hasta el final de los tiempos. Esto provocaba una cantidad de iteraciones indefinidas en el ciclo de ejecución de un componente, haciendo que a su vez los componentes hijos también sufrieran un re-renderizado. En fin, todo esto ocurrió al trabajar en la versión "16" de React, en las versiones posteriores también deben haber problemas de infinite loops en useEffects pero se deberían controlan mejor para evitar crashes en el sitio web.

Conclusiones

  • La Persistencia en la Depuración: A pesar de la complejidad y frustración inicial, aprendí la importancia de persistir en la depuración y no rendirte ante problemas difíciles de diagnosticar.
  • Enfoque Iterativo: Descubrí que abordar un problema técnico de manera iterativa, probando diferentes enfoques y herramientas, puede llevar finalmente a la identificación y resolución del problema.
  • Exploración de Herramientas de Desarrollo: Mi experiencia mostró la utilidad de aprovechar al máximo las herramientas de desarrollo disponibles, como el inspector de elementos y las extensiones como React Devtools, para analizar y entender el comportamiento de tus componentes.
  • Descubrimiento Casual: A veces, los descubrimientos más valiosos pueden surgir de manera casual. El hallazgo accidental de la opción "Highlight updates when components render" ilustra cómo explorar diversas características puede revelar soluciones inesperadas.
  • Control de Referencias y Ciclos de Vida: Aprendí sobre la importancia de controlar las referencias y las actualizaciones en los componentes de React, especialmente al trabajar con efectos en el ciclo de vida de los componentes.

viernes, 4 de agosto de 2023

Un viaje como Frontend Developer

¡Bienvenidos a mi nuevo blog! Mi blog anterior fue construido usando Gatsby y publicado desde Netlify, sin embargo, estoy buscando una forma mucho más rápida y Low Code para mantener mi blog. Por cierto, mi primer blog estaba en Médium, escribí muchos post de todo tipo, sueños, tutoriales y otras cosas personales.

Hoy quiero compartir con ustedes un poco más acerca de quién soy y cómo me he convertido en un Frontend Developer. Mi nombre es Julian, y mi pasión por la tecnología y la programación ha sido el motor que me ha impulsado en este fascinante camino.

A mediados del 2010 y 2011, desde una edad temprana, siempre me sentí atraído por el mundo de la informática. Recuerdo con cariño mis primeros días jugando con las computadoras de la escuela, tratando de entender cómo funcionaban y cómo podía interactuar con ellas. Mi curiosidad me llevó a profundizar en los conceptos básicos de programación, y pronto me encontré desarrollando mis primeros proyectos simples, pero emocionantes. Emocionantes porque mis primeros códigos fueron escritos en Bash y comúnmente escribía sentencias peligrosas para eliminar el System32, abrir cientos de ventanas de Paint hasta bloquear la computadora, y otros Scripts delicados. En varios casos estos archivos Bash venían con un icono personalizado de una carpeta con el nombre de "P0xN0", las personas que miraban esta "carpeta" con aquel supuesto contenido videográfico terminaban dando doble click y por ende dando muerte a la computadora, adiós System32.

A medida que crecía, mi fascinación por la tecnología solo aumentaba, y mi objetivo se volvía más claro: quería convertirme en un profesional de la programación y ayudar a crear aplicaciones y sitios web innovadores que impactaran la vida de las personas de manera positiva.

Mi camino hacia convertirme en Frontend Developer no fue fácil, pero cada desafío que enfrenté fue una oportunidad para aprender y mejorar mis habilidades. Estudié arduamente y me sumergí en una amplia gama de tecnologías, desde los fundamentos como HTML, CSS y JavaScript, hasta frameworks y librerías más avanzadas como React y Angular. Amo profundamente programar en TypeScript, así que todo lo que escribo suele venir bien tipado, odio usar los "any" excepto donde no hay escapatoria para no usarlo.

A lo largo de mi carrera, he enfrentado desafíos en el diseño y desarrollo de interfaces de usuario altamente interactivas, garantizando que la experiencia del usuario sea fluida y atractiva. También he tenido la oportunidad de colaborar con diseñadores, analistas y otros desarrolladores para comprender las necesidades del usuario y traducirlas en productos finales que superen sus expectativas.

La tecnología nunca deja de avanzar, y eso es lo que más me emociona de ser un Frontend Developer. Cada día hay algo nuevo que aprender, ya sea una nueva técnica de diseño, un framework emergente o una metodología de desarrollo. Mantenerme actualizado en este entorno en constante evolución es un desafío que abrazo con entusiasmo. Suelo usar Twitter, YouTube y charlas con amigos para mantenerme al día.

A través de mi trayectoria como Frontend Developer, he aprendido la importancia de la empatía y la comprensión del usuario. Al final del día, nuestro trabajo no solo se trata de escribir código, sino de resolver problemas y mejorar la vida de quienes interactúan con nuestras creaciones, por eso, todo lo que hago suele venir acompañado de buena accesibilidad Web, vivo enamorado de A11y.

Me siento bendecido de poder dedicar mi vida profesional a lo que amo, y estoy emocionado de seguir creciendo y evolucionando en este campo tan apasionante. En este blog, compartiré mis conocimientos, experiencias y consejos relacionados con el desarrollo frontend, con la esperanza de inspirar y ayudar a otros desarrolladores en su propio viaje.

Así que únanse a mí en este viaje, donde exploraremos juntos el fascinante mundo del desarrollo frontend y cómo podemos dar vida a nuestras ideas a través del código.

¡Gracias por leer! Si tienes alguna pregunta o tema que te gustaría que aborde en futuras publicaciones, no dudes en dejar un comentario. ¡Hagamos crecer esta comunidad de desarrolladores apasionados por la tecnología!

¡Nos vemos en la próxima entrada del blog!

viernes, 6 de enero de 2023

La noche es joven

La noche es joven. La luna se esconde sobre el cielo que irrumpe su luz azul, las nubes son negras y preparadas están, para liberar lágrimas sobre los techos que albergan seres durmientes. Aparece un segundo protagonista ante la fría noche, ella toca la puerta cuando al mismo tiempo se pregunta si habrá alguien al otro lado. Nadie abre aquella puerta de hierro oxidado con manijas de roble, tallada con el aire que roza su rostro. Piso de piedra rústica cubre aquel hogar de una mente perdida en la falsa realidad, una serie de pensamientos que ella quizás no comprenda. Él la desea tanto. Cree que ella es el camino al verdadero mundo, uno en donde todo se observa desde la misma perspectiva. Ella camina en sus sueños a lado de la distante presencia de aquel hombre, que deambula en el otro lado de la inmensa puerta negra.

martes, 6 de diciembre de 2022

Como criar un gato para que no sea loco y callejero

La mejor manera de criar un gato para que no sea loco y callejero es darle un buen comienzo en la vida. Esto incluye cosas como proporcionarle un ambiente seguro y estable, brindarle amor y atención adecuados, y asegurarse de que reciba una nutrición adecuada y un cuidado médico regular.

También es importante acostumbrar al gato a estar en casa y a interactuar con las personas de una manera positiva desde una edad temprana. Esto puede ayudar a que el gato se sienta cómodo y seguro en el hogar y tenga menos probabilidades de convertirse en un gato callejero.

Otras cosas que pueden ayudar a prevenir que un gato se vuelva loco y callejero incluyen:
  • Proporcionar al gato una variedad de juguetes y actividades para mantenerlo entretenido y estimulado.
  • Ofrecerle un espacio seguro y cómodo donde pueda dormir y descansar.
  • Evitar castigar al gato o tratarlo de manera cruel. Esto puede causar estrés y trauma en el gato y puede contribuir a que se vuelva agresivo o temeroso.
  • Asegurarse de que el gato esté desparasitado y vacunado regularmente. Esto ayudará a prevenir enfermedades y problemas de salud que pueden contribuir a comportamientos inapropiados en el gato.
  • Criar un gato para que sea un miembro feliz y saludable de la familia puede requerir tiempo y esfuerzo, pero puede ser muy gratificante. Con paciencia y amor, su gato puede crecer para ser un compañero leal y afectuoso.
Información dada por https://openai.com/blog/chatgpt/ ante la pregunta: "cómo criar un gato para que no sea loco y callejero".

Fixing ZTopInc WiFi Driver Compilation on Ubuntu 24.04 LTS

UPDATE 2026: Fix for new linux kernel versions (6.17+) in this branch: https://codeberg.org/anlijudavid/driver_wifi_ztopinc/src/branch/linux...