
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
tauri-plugin-buttonkit-api
Advanced tools
Tauri plugin for detecting physical button presses on mobile devices
Un plugin para aplicaciones Tauri que permite detectar pulsaciones de botones físicos en dispositivos móviles, como los botones de volumen en Android.
En tu archivo src-tauri/Cargo.toml, añade:
[dependencies]
tauri-plugin-buttonkit = "0.1.0"
O si prefieres usar la versión en desarrollo directamente desde GitHub:
[dependencies]
tauri-plugin-buttonkit = { git = "https://github.com/dovaldev/tauri-plugin-buttonkit" }
En tu archivo src-tauri/src/main.rs, añade el plugin al builder de Tauri:
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_buttonkit::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Como el paquete aún no está publicado en npm, hay dos opciones para usarlo:
En tu archivo package.json, añade:
"dependencies": {
"tauri-plugin-buttonkit-api": "github:dovaldev/tauri-plugin-buttonkit"
}
Y luego ejecuta:
# Usando npm
npm install
# Usando yarn
yarn
# Usando pnpm
pnpm install
Alternativamente, puedes copiar el código de la API JavaScript directamente de la carpeta guest-js a tu proyecto y crear tus propios archivos de interfaz.
El archivo principal está en guest-js/index.ts y defines la API para interactuar con el plugin desde tu código frontend.
import {
ping,
startListeningToButtons,
stopListeningToButtons,
onButtonPress
} from 'tauri-plugin-buttonkit-api';
// Ejemplo básico para verificar que el plugin funciona
ping("Hola desde la app!").then(response => {
console.log(response); // Debería mostrar el valor que enviaste
});
// Iniciar la escucha de botones
await startListeningToButtons();
// Registrar un callback para los eventos de botones
const unsubscribe = onButtonPress((event) => {
console.log(`Botón presionado: ${event.button}`);
// Realizar acciones según el botón presionado
if (event.button === 'VolumeUp') {
// Hacer algo cuando se presiona el botón de subir volumen
} else if (event.button === 'VolumeDown') {
// Hacer algo cuando se presiona el botón de bajar volumen
}
});
// Cuando quieras dejar de escuchar los eventos:
unsubscribe();
await stopListeningToButtons();
import React, { useState, useEffect } from 'react';
import {
ping,
onButtonPress,
startListeningToButtons,
stopListeningToButtons,
ButtonEvent
} from 'tauri-plugin-buttonkit-api';
// Definimos el tipo para los eventos de botones procesados
interface ProcessedButtonEvent {
button: string;
time: string;
}
const ButtonKitComponent: React.FC = () => {
const [buttonEvents, setButtonEvents] = useState<ProcessedButtonEvent[]>([]);
const [isListening, setIsListening] = useState<boolean>(false);
const [unsubscribeFunc, setUnsubscribeFunc] = useState<(() => Promise<void>) | null>(null);
// Función para manejar los eventos de botones
const handleButtonPress = (event: ButtonEvent) => {
const { button, timestamp } = event;
const newEvent = {
button,
time: new Date(timestamp).toLocaleTimeString()
};
setButtonEvents(prevEvents => {
// Mantener solo los últimos 10 eventos
const updatedEvents = [...prevEvents, newEvent];
if (updatedEvents.length > 10) {
return updatedEvents.slice(updatedEvents.length - 10);
}
return updatedEvents;
});
};
// Función para iniciar la escucha de botones
const startListening = async () => {
if (!isListening) {
try {
await startListeningToButtons();
const unsubscribe = onButtonPress(handleButtonPress);
setUnsubscribeFunc(() => unsubscribe);
setIsListening(true);
console.log("Escucha de botones iniciada");
} catch (error) {
console.error("Error al iniciar la escucha:", error);
}
}
};
// Función para detener la escucha de botones
const stopListening = async () => {
if (isListening && unsubscribeFunc) {
try {
await unsubscribeFunc();
await stopListeningToButtons();
setIsListening(false);
setUnsubscribeFunc(null);
console.log("Escucha de botones detenida");
} catch (error) {
console.error("Error al detener la escucha:", error);
}
}
};
// Efecto para iniciar automáticamente en dispositivos móviles
useEffect(() => {
const isMobileDevice = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
if (isMobileDevice) {
startListening();
}
// Limpiar al desmontar el componente
return () => {
if (isListening && unsubscribeFunc) {
unsubscribeFunc().then(() => {
stopListeningToButtons().catch(console.error);
}).catch(console.error);
}
};
}, []);
return (
<div>
<h2>Control de botones físicos</h2>
<div>
<button
onClick={startListening}
disabled={isListening}
>
Iniciar escucha
</button>
<button
onClick={stopListening}
disabled={!isListening}
>
Detener escucha
</button>
</div>
<div>
<h3>Eventos registrados:</h3>
{buttonEvents.length === 0 ? (
<p>No se han detectado eventos de botones físicos aún.</p>
) : (
<ul>
{buttonEvents.map((event, index) => (
<li key={index}>{event.time} - Botón: {event.button}</li>
))}
</ul>
)}
</div>
</div>
);
};
export default ButtonKitComponent;
ping(value: string): Promise<PingResponse>Función de prueba que devuelve el valor enviado. Útil para verificar que el plugin está funcionando correctamente.
startListeningToButtons(): Promise<void>Inicia la escucha de eventos de botones físicos en el dispositivo.
stopListeningToButtons(): Promise<void>Detiene la escucha de eventos de botones físicos.
onButtonPress(callback: (event: ButtonEvent) => void): () => Promise<void>Registra una función callback que será llamada cada vez que se presione un botón físico. Retorna una función para cancelar la suscripción.
interface ButtonEvent {
button: string; // Identificador del botón (ej: "VolumeUp", "VolumeDown")
timestamp: number; // Timestamp en milisegundos cuando ocurrió el evento
}
interface PingResponse {
value: string; // El valor enviado en la función ping
}
Actualmente, el plugin detecta los siguientes botones en Android:
VolumeUp: Botón de subir volumenVolumeDown: Botón de bajar volumensrc/: Código Rust del pluginguest-js/: Código TypeScript de la API del frontendandroid/: Implementación nativa para Androidios/: Implementación nativa para iOSexamples/: Aplicación de ejemplo que usa el plugincd examples/tauri-app
pnpm install
pnpm tauri android dev
Este proyecto está bajo la Licencia MIT.
Las contribuciones son bienvenidas. Por favor, abre un issue o envía un pull request en GitHub.
FAQs
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.