feat: Refactor Android share handling to dynamically load Capacitor core and improve plugin registration

This commit is contained in:
2026-05-17 16:53:40 +10:00
parent c2fc71ddca
commit ba31d65568
2 changed files with 21 additions and 22 deletions

View File

@@ -9,30 +9,13 @@
"xmr.se"
],
"allowCustomHomeservers": true,
"calling": {
"livekitServiceUrl": "https://b.ruv.wtf/matrix-rtc/livekit/jwt"
},
"featuredCommunities": {
"openAsDefault": false,
"spaces": [
"#cinny-space:matrix.org",
"#community:matrix.org",
"#space:envs.net",
"#science-space:matrix.org",
"#libregaming-games:tchncs.de",
"#mathematics-on:matrix.org"
],
"rooms": [
"#cinny:matrix.org",
"#freesoftware:matrix.org",
"#pcapdroid:matrix.org",
"#gentoo:matrix.org",
"#PrivSec.dev:arcticfoxes.net",
"#disroot:aria-net.org"
],
"servers": ["envs.net", "matrix.org", "monero.social", "mozilla.org"]
"servers": []
},
"hashRouter": {

View File

@@ -1,4 +1,11 @@
import { Capacitor, registerPlugin, type PluginListenerHandle } from '@capacitor/core';
import type { PluginListenerHandle } from '@capacitor/core';
const CAPACITOR_CORE_MODULE_ID = '@capacitor/core';
type CapacitorCoreModule = typeof import('@capacitor/core');
const loadCapacitorCore = async (): Promise<CapacitorCoreModule> =>
import(/* @vite-ignore */ CAPACITOR_CORE_MODULE_ID);
/** Metadata for a file received from an Android share intent. */
export type AndroidSharedFile = {
@@ -27,15 +34,21 @@ interface AndroidShareHandlerPlugin {
): Promise<PluginListenerHandle>;
}
const AndroidShareHandler = registerPlugin<AndroidShareHandlerPlugin>('AndroidShareHandler');
const getAndroidShareHandler = async (): Promise<AndroidShareHandlerPlugin> => {
const { registerPlugin } = await loadCapacitorCore();
return registerPlugin<AndroidShareHandlerPlugin>('AndroidShareHandler');
};
/** Returns true when the Android share bridge is available. */
export const isAndroidShareSupported = (): boolean =>
Capacitor.isNativePlatform() && Capacitor.getPlatform() === 'android';
export const isAndroidShareSupported = (): boolean => {
const capacitor = (window as typeof window & { Capacitor?: CapacitorCoreModule['Capacitor'] }).Capacitor;
return 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 AndroidShareHandler = await getAndroidShareHandler();
const result = await AndroidShareHandler.getPendingShare();
return result.share;
};
@@ -43,6 +56,7 @@ export const getPendingAndroidShare = async (): Promise<AndroidSharePayload | nu
/** Clears the native pending share payload. */
export const clearPendingAndroidShare = async (): Promise<void> => {
if (!isAndroidShareSupported()) return;
const AndroidShareHandler = await getAndroidShareHandler();
await AndroidShareHandler.clearPendingShare();
};
@@ -51,6 +65,7 @@ export const listenForAndroidShares = async (
listener: (payload: AndroidSharePayload) => void
): Promise<PluginListenerHandle | undefined> => {
if (!isAndroidShareSupported()) return undefined;
const AndroidShareHandler = await getAndroidShareHandler();
return AndroidShareHandler.addListener('shareReceived', listener);
};
@@ -59,6 +74,7 @@ export const materializeSharedFile = async (
sharedFile: AndroidSharedFile,
receivedAt: number
): Promise<File> => {
const { Capacitor } = await loadCapacitorCore();
const fileUrl = Capacitor.convertFileSrc(sharedFile.path);
const response = await fetch(fileUrl);
if (!response.ok) {