Remove Matrix Widget API connection and logging
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 20s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 20s
This commit is contained in:
26
package-lock.json
generated
26
package-lock.json
generated
@@ -13,7 +13,6 @@
|
||||
"express": "^5.2.1",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lucide-react": "^0.562.0",
|
||||
"matrix-widget-api": "^1.16.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0"
|
||||
},
|
||||
@@ -1425,12 +1424,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/events": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.3.tgz",
|
||||
"integrity": "sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
||||
@@ -2547,15 +2540,6 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/events": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8.x"
|
||||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
|
||||
@@ -3232,16 +3216,6 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/matrix-widget-api": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/matrix-widget-api/-/matrix-widget-api-1.16.0.tgz",
|
||||
"integrity": "sha512-OCsCzEN54jWamvWkBa7PqcKdlOhLA+nJbUyqsATHvzb4/NMcjdUZWSDurZxyNE5eYlNwxClA6Hw20mzJEKJbvg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/events": "^3.0.0",
|
||||
"events": "^3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/media-typer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
"express": "^5.2.1",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lucide-react": "^0.562.0",
|
||||
"matrix-widget-api": "^1.16.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0"
|
||||
},
|
||||
|
||||
108
src/App.tsx
108
src/App.tsx
@@ -9,14 +9,7 @@ import { GifGrid } from './components/GifGrid';
|
||||
import './styles/global.css';
|
||||
|
||||
function App() {
|
||||
const [logs, setLogs] = useState<string[]>([]);
|
||||
|
||||
const addLog = (msg: string) => {
|
||||
setLogs(prev => [`[${new Date().toLocaleTimeString()}] ${msg}`, ...prev].slice(0, 5));
|
||||
console.log(msg);
|
||||
};
|
||||
|
||||
const { theme, sendGif, ready, refreshPermissions } = useMatrixWidget(addLog);
|
||||
const { theme, sendGif } = useMatrixWidget();
|
||||
const { favorites, toggleFavorite, isFavorite } = useFavorites();
|
||||
|
||||
const [categories, setCategories] = useState<string[]>([]);
|
||||
@@ -26,8 +19,6 @@ function App() {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [sendingState, setSendingState] = useState<{ id: string, status: 'sending' | 'sent' | 'error', errorMsg?: string } | null>(null);
|
||||
|
||||
// Apply theme
|
||||
|
||||
// Apply theme
|
||||
useEffect(() => {
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
@@ -36,7 +27,6 @@ function App() {
|
||||
// Load categories on mount
|
||||
useEffect(() => {
|
||||
gifService.getCategories().then(setCategories);
|
||||
addLog("App mounted, waiting for Matrix...");
|
||||
}, []);
|
||||
|
||||
// Fetch GIFs
|
||||
@@ -60,7 +50,7 @@ function App() {
|
||||
}
|
||||
setGifs(results);
|
||||
} catch (error: any) {
|
||||
addLog(`Fetch error: ${error.message}`);
|
||||
console.error(`Fetch error: ${error.message}`);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -84,22 +74,15 @@ function App() {
|
||||
};
|
||||
|
||||
const handleGifSelect = async (gif: GifObject) => {
|
||||
if (!ready) {
|
||||
addLog("⚠️ Widget not ready, trying direct send...");
|
||||
}
|
||||
|
||||
setSendingState({ id: gif.id, status: 'sending' });
|
||||
addLog(`Sending GIF: ${gif.id}`);
|
||||
|
||||
try {
|
||||
await sendGif(gif);
|
||||
setSendingState({ id: gif.id, status: 'sent' });
|
||||
addLog("Send success!");
|
||||
setTimeout(() => setSendingState(null), 2000);
|
||||
} catch (e: any) {
|
||||
const msg = e.message || JSON.stringify(e);
|
||||
setSendingState({ id: gif.id, status: 'error', errorMsg: msg });
|
||||
addLog(`Send Failed: ${msg}`);
|
||||
setTimeout(() => setSendingState(null), 5000);
|
||||
}
|
||||
};
|
||||
@@ -108,81 +91,26 @@ function App() {
|
||||
|
||||
return (
|
||||
<div className="app-container">
|
||||
<div style={{
|
||||
padding: '8px 12px',
|
||||
fontSize: '12px',
|
||||
color: ready ? '#4ECDC4' : '#FF6B6B',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<span>Status: {ready ? 'Connected' : 'Connecting...'}</span>
|
||||
{sendingState && (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
<span style={{
|
||||
fontWeight: 'bold',
|
||||
color: sendingState.status === 'error' ? '#FF6B6B' : '#FFEEAD'
|
||||
}}>
|
||||
{sendingState.status === 'sending' && 'Sending...'}
|
||||
{sendingState.status === 'sent' && 'Sent!'}
|
||||
{sendingState.status === 'error' && 'Failed'}
|
||||
</span>
|
||||
{sendingState.status === 'error' && (
|
||||
<div style={{ display: 'flex', gap: '4px' }}>
|
||||
<button
|
||||
onClick={() => {
|
||||
const id = prompt("Please paste the Widget ID from the logs (looks like !abc...):");
|
||||
if (id) {
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.set('widgetId', id);
|
||||
window.location.href = url.toString();
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
background: '#2F3136', border: '1px solid #555', borderRadius: '4px',
|
||||
color: 'white', padding: '2px 6px', fontSize: '10px', cursor: 'pointer'
|
||||
}}
|
||||
>
|
||||
Set ID
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
addLog("Requesting permissions...");
|
||||
refreshPermissions();
|
||||
}}
|
||||
style={{
|
||||
background: '#5865F2', border: 'none', borderRadius: '4px',
|
||||
color: 'white', padding: '2px 6px', fontSize: '10px', cursor: 'pointer'
|
||||
}}
|
||||
>
|
||||
Fix Permissions
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Debug Log Box - Always visible */}
|
||||
<div style={{
|
||||
fontSize: '11px',
|
||||
color: '#ccc',
|
||||
padding: '8px 12px',
|
||||
marginBottom: '8px',
|
||||
fontFamily: 'monospace',
|
||||
maxHeight: '120px',
|
||||
minHeight: '60px',
|
||||
overflowY: 'auto',
|
||||
backgroundColor: 'rgba(0,0,0,0.3)',
|
||||
borderRadius: '4px',
|
||||
border: '1px solid rgba(255,255,255,0.1)'
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
zIndex: 1000,
|
||||
background: sendingState.status === 'error' ? '#FF6B6B' : '#4ECDC4',
|
||||
color: '#1A1B1E',
|
||||
padding: '8px',
|
||||
textAlign: 'center',
|
||||
fontWeight: 'bold',
|
||||
fontSize: '14px',
|
||||
boxShadow: '0 2px 4px rgba(0,0,0,0.2)'
|
||||
}}>
|
||||
{logs.length === 0 ? (
|
||||
<div style={{ color: '#666' }}>Waiting for logs...</div>
|
||||
) : (
|
||||
logs.map((log, i) => <div key={i}>{log}</div>)
|
||||
)}
|
||||
{sendingState.status === 'sending' && 'Sending GIF...'}
|
||||
{sendingState.status === 'sent' && 'GIF Sent!'}
|
||||
{sendingState.status === 'error' && `Error: ${sendingState.errorMsg || 'Failed to send'}`}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<SearchBar onSearch={handleSearch} />
|
||||
|
||||
|
||||
@@ -1,94 +1,16 @@
|
||||
import { useEffect, useState, useRef } from 'react';
|
||||
import { WidgetApi } from 'matrix-widget-api';
|
||||
import { useState } from 'react';
|
||||
import type { GifObject } from '../types';
|
||||
|
||||
export const useMatrixWidget = (onLog?: (msg: string) => void) => {
|
||||
const widgetApiRef = useRef<WidgetApi | null>(null);
|
||||
export const useMatrixWidget = () => {
|
||||
const [theme] = useState<'light' | 'dark'>(() => {
|
||||
const themeParam = new URLSearchParams(window.location.search).get('theme');
|
||||
return (themeParam === 'light' || themeParam === 'dark') ? themeParam : 'dark';
|
||||
});
|
||||
const [ready, setReady] = useState(false);
|
||||
const initialized = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (initialized.current) return;
|
||||
initialized.current = true;
|
||||
|
||||
const log = (msg: string) => {
|
||||
console.log(`[Widget] ${msg}`);
|
||||
onLog?.(msg);
|
||||
};
|
||||
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
const hashParams = new URLSearchParams(window.location.hash.substring(1));
|
||||
|
||||
log(`URL Search: ${window.location.search}`);
|
||||
log(`URL Hash: ${window.location.hash}`);
|
||||
|
||||
const widgetId = searchParams.get('widgetId') || hashParams.get('widgetId');
|
||||
// Decode the ID in case it was double-encoded or raw from URL
|
||||
const finalId = widgetId ? decodeURIComponent(widgetId) : 'my-widget-id';
|
||||
|
||||
log(`Widget ID: ${finalId}`);
|
||||
|
||||
try {
|
||||
const api = new WidgetApi(finalId);
|
||||
|
||||
log("Requesting capabilities...");
|
||||
api.requestCapabilities([
|
||||
'm.send_event:m.room.message',
|
||||
'm.sticker',
|
||||
'm.send_event:m.sticker',
|
||||
]);
|
||||
|
||||
log("Starting Widget API...");
|
||||
api.start();
|
||||
|
||||
api.on("ready", () => {
|
||||
log("Widget API Ready!");
|
||||
setReady(true);
|
||||
});
|
||||
|
||||
api.on("error", (err: Error) => {
|
||||
log(`Widget Error: ${err.message}`);
|
||||
});
|
||||
|
||||
widgetApiRef.current = api;
|
||||
|
||||
// Set a timeout to warn if not ready after 5 seconds
|
||||
setTimeout(() => {
|
||||
if (!ready) {
|
||||
log("⚠️ Still not ready after 5s. Are you running inside a Matrix widget?");
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
} catch (error: any) {
|
||||
log(`Init Error: ${error.message}`);
|
||||
}
|
||||
}, [onLog]);
|
||||
|
||||
const refreshPermissions = async () => {
|
||||
if (!widgetApiRef.current) return;
|
||||
onLog?.("Manual permission refresh triggered...");
|
||||
try {
|
||||
await widgetApiRef.current.requestCapabilities([
|
||||
'm.sticker',
|
||||
'm.send_event:m.sticker',
|
||||
'm.send_event:m.room.message',
|
||||
]);
|
||||
onLog?.("Capabilities request sent.");
|
||||
} catch (e) {
|
||||
onLog?.(`Cap Request Error: ${e}`);
|
||||
}
|
||||
};
|
||||
|
||||
const sendGif = async (gif: GifObject) => {
|
||||
const { tinygif } = gif.media_formats;
|
||||
const title = gif.title || "GIF";
|
||||
|
||||
onLog?.(`Sending: ${title}`);
|
||||
|
||||
try {
|
||||
// Get Matrix homeserver and access token from URL params
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
@@ -103,8 +25,6 @@ export const useMatrixWidget = (onLog?: (msg: string) => void) => {
|
||||
// Use tinygif for smaller size
|
||||
const gifUrl = tinygif.url;
|
||||
|
||||
onLog?.('Uploading to Matrix...');
|
||||
|
||||
// Upload GIF through our proxy
|
||||
const uploadResponse = await fetch(
|
||||
`/api/gif-upload?url=${encodeURIComponent(gifUrl)}&homeserver=${encodeURIComponent(homeserver)}&accessToken=${encodeURIComponent(accessToken)}`
|
||||
@@ -117,8 +37,6 @@ export const useMatrixWidget = (onLog?: (msg: string) => void) => {
|
||||
|
||||
const { mxcUrl, size } = await uploadResponse.json();
|
||||
|
||||
onLog?.(`Uploaded ${(size / 1024).toFixed(1)}KB, sending...`);
|
||||
|
||||
// Send directly via Matrix Client-Server API
|
||||
const txnId = `m${Date.now()}.${Math.random()}`;
|
||||
const sendUrl = `${homeserver}/_matrix/client/v3/rooms/${encodeURIComponent(roomId)}/send/m.sticker/${txnId}`;
|
||||
@@ -146,12 +64,11 @@ export const useMatrixWidget = (onLog?: (msg: string) => void) => {
|
||||
throw new Error(error.error || 'Send failed');
|
||||
}
|
||||
|
||||
onLog?.('✓ GIF sent!');
|
||||
} catch (error: any) {
|
||||
onLog?.(`✗ Failed: ${error.message}`);
|
||||
console.error(`Failed to send GIF: ${error.message}`);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
return { theme, sendGif, ready, refreshPermissions };
|
||||
return { theme, sendGif };
|
||||
};
|
||||
Reference in New Issue
Block a user