Files
cinny-mobile/overlay/src/app/utils/androidShare.ts
Max Litruv Boonzaayer c263b681d4 feat: add ShareRoomPicker component for selecting rooms to share Android content
- Implemented ShareRoomPicker component to allow users to pick a room for sharing content received from Android intents.
- Integrated search functionality to filter rooms and directs.
- Added virtualized list for efficient rendering of room options.
- Created utility functions for handling Android share payloads, including fetching and clearing pending shares.

Co-authored-by: Copilot <copilot@github.com>
2026-04-26 14:32:19 +10:00

73 lines
2.5 KiB
TypeScript

import { Capacitor, registerPlugin, type PluginListenerHandle } from '@capacitor/core';
/** Metadata for a file received from an Android share intent. */
export type AndroidSharedFile = {
path: string;
name: string;
mimeType: string;
size: number;
};
/** Payload persisted by the native Android share handler. */
export type AndroidSharePayload = {
text?: string;
subject?: string;
files: AndroidSharedFile[];
receivedAt: number;
};
interface AndroidShareHandlerPlugin {
/** Returns the last pending share payload, if one exists. */
getPendingShare(): Promise<{ share: AndroidSharePayload | null }>;
/** Clears the last pending share payload after it has been consumed. */
clearPendingShare(): Promise<void>;
addListener(
eventName: 'shareReceived',
listenerFunc: (payload: AndroidSharePayload) => void
): Promise<PluginListenerHandle>;
}
const AndroidShareHandler = registerPlugin<AndroidShareHandlerPlugin>('AndroidShareHandler');
/** Returns true when the Android share bridge is available. */
export const isAndroidShareSupported = (): boolean =>
Capacitor.isNativePlatform() && Capacitor.getPlatform() === 'android';
/** Fetches the current pending native share payload. */
export const getPendingAndroidShare = async (): Promise<AndroidSharePayload | null> => {
if (!isAndroidShareSupported()) return null;
const result = await AndroidShareHandler.getPendingShare();
return result.share;
};
/** Clears the native pending share payload. */
export const clearPendingAndroidShare = async (): Promise<void> => {
if (!isAndroidShareSupported()) return;
await AndroidShareHandler.clearPendingShare();
};
/** Subscribes to new incoming native share payloads. */
export const listenForAndroidShares = async (
listener: (payload: AndroidSharePayload) => void
): Promise<PluginListenerHandle | undefined> => {
if (!isAndroidShareSupported()) return undefined;
return AndroidShareHandler.addListener('shareReceived', listener);
};
/** Converts a cached native shared file into a browser File for upload. */
export const materializeSharedFile = async (
sharedFile: AndroidSharedFile,
receivedAt: number
): Promise<File> => {
const fileUrl = Capacitor.convertFileSrc(sharedFile.path);
const response = await fetch(fileUrl);
if (!response.ok) {
throw new Error(`Failed to read shared file: ${sharedFile.name}`);
}
const blob = await response.blob();
return new File([blob], sharedFile.name, {
type: sharedFile.mimeType || blob.type,
lastModified: receivedAt,
});
};