feat(pwa): add web share target for text and images with offline queue
This commit is contained in:
1 parent
c181ffea54
commit
86d2cd0138
9 files changed
+360
-2
No files matched your search
@@ -67,6 +67,7 @@ import { UserAvatar } from './components/UserAvatar';
|
||||
import { CommandPalette } from './components/CommandPalette';
|
||||
import { AppFooter } from './components/AppFooter';
|
||||
import { AboutModal } from './components/AboutModal';
|
||||
import { consumePendingShares, formatSharedThought } from './lib/shareTarget';
|
||||
import { APP_VERSION } from './version';
|
||||
|
||||
type ActiveTab =
|
||||
@@ -555,6 +556,46 @@ export const App: React.FC = () => {
|
||||
);
|
||||
}, [authStatus.demoMode, authStatus.demoResetInSeconds]);
|
||||
|
||||
// Web Share Target: import shared thoughts from external apps
|
||||
useEffect(() => {
|
||||
if (!user) return;
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const hasPendingShare = params.get('shared') === 'pending';
|
||||
|
||||
const processShares = async () => {
|
||||
try {
|
||||
const shares = await consumePendingShares();
|
||||
if (shares.length === 0) return;
|
||||
|
||||
let importedCount = 0;
|
||||
for (const share of shares) {
|
||||
const content = formatSharedThought(share);
|
||||
if (content) {
|
||||
await api.captureThought(content, 'normal', 'manual', '', { target: 'inbox' });
|
||||
importedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (importedCount > 0) {
|
||||
triggerHaptic(15);
|
||||
setDemoNotice('Erfolgreich im Quick Dump abgelegt');
|
||||
setTimeout(() => setDemoNotice(null), 4000);
|
||||
refreshAll();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Fehler beim Import geteilter Daten:', err);
|
||||
} finally {
|
||||
if (hasPendingShare) {
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.delete('shared');
|
||||
window.history.replaceState({}, '', url.pathname + (url.search ? url.search : '') + url.hash);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
processShares();
|
||||
}, [user, refreshAll]);
|
||||
|
||||
// The demo database was reset: drop cached answers of the old data, remount the views (they load
|
||||
// fresh data), refresh counters and the countdown. Sessions stay valid (fixed demo account IDs).
|
||||
const handleDemoReset = useCallback(() => {
|
||||
|
||||
Reference in new issue
Block a user