60 lines
1.5 KiB
TypeScript
60 lines
1.5 KiB
TypeScript
import { createPhotoShareLink } from '../services/photosApi';
|
|
|
|
type ShareOptions = {
|
|
token: string;
|
|
photoId: number;
|
|
title?: string;
|
|
text?: string;
|
|
};
|
|
|
|
async function copyToClipboard(text: string): Promise<boolean> {
|
|
try {
|
|
if (navigator.clipboard && window.isSecureContext) {
|
|
await navigator.clipboard.writeText(text);
|
|
return true;
|
|
}
|
|
} catch {
|
|
// ignore and fallback
|
|
}
|
|
|
|
try {
|
|
const input = document.createElement('input');
|
|
input.value = text;
|
|
document.body.appendChild(input);
|
|
input.select();
|
|
document.execCommand('copy');
|
|
document.body.removeChild(input);
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export async function sharePhotoLink(options: ShareOptions): Promise<{ url: string; method: 'native' | 'clipboard' | 'manual' }>
|
|
{
|
|
const payload = await createPhotoShareLink(options.token, options.photoId);
|
|
const shareData: ShareData = {
|
|
title: options.title ?? 'Fotospiel Moment',
|
|
text: options.text ?? '',
|
|
url: payload.url,
|
|
};
|
|
|
|
if (navigator.share && (!navigator.canShare || navigator.canShare(shareData))) {
|
|
try {
|
|
await navigator.share(shareData);
|
|
return { url: payload.url, method: 'native' };
|
|
} catch (error: any) {
|
|
if (error?.name === 'AbortError') {
|
|
return { url: payload.url, method: 'native' };
|
|
}
|
|
// fall through to clipboard
|
|
}
|
|
}
|
|
|
|
if (await copyToClipboard(payload.url)) {
|
|
return { url: payload.url, method: 'clipboard' };
|
|
}
|
|
|
|
return { url: payload.url, method: 'manual' };
|
|
}
|