base admin
This commit is contained in:
@@ -226,6 +226,36 @@ const BookPage = forwardRef<HTMLDivElement, BookPageProps>(
|
||||
/>
|
||||
);
|
||||
|
||||
case 'audio':
|
||||
return (
|
||||
<audio
|
||||
key={obj.id || index}
|
||||
src={obj.audioUrl || ''}
|
||||
controls
|
||||
preload="metadata"
|
||||
style={withEntrance(
|
||||
{
|
||||
...baseStyle,
|
||||
width: obj.width ? `${obj.width * scale}px` : `${320 * scale}px`,
|
||||
height: obj.height ? `${obj.height * scale}px` : `${56 * scale}px`,
|
||||
zIndex: index,
|
||||
pointerEvents: 'auto',
|
||||
},
|
||||
obj,
|
||||
index,
|
||||
)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
onMouseDown={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
onTouchStart={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
case 'link': {
|
||||
const isInternalLink = obj.linkUrl?.startsWith('page://');
|
||||
const linkStyle = {
|
||||
|
||||
@@ -38,6 +38,7 @@ type ViewerDataPage = {
|
||||
borderRadius?: number;
|
||||
imageUrl?: string;
|
||||
videoUrl?: string;
|
||||
audioUrl?: string;
|
||||
linkUrl?: string;
|
||||
rotation?: number;
|
||||
opacity?: number;
|
||||
@@ -129,6 +130,10 @@ export function transformViewerDataToPages(data: ViewerData): PageData[] {
|
||||
baseObject.videoUrl = obj.videoUrl;
|
||||
}
|
||||
|
||||
if (obj.type === "audio" && obj.audioUrl) {
|
||||
baseObject.audioUrl = obj.audioUrl;
|
||||
}
|
||||
|
||||
if (obj.type === "link" && obj.linkUrl) {
|
||||
baseObject.linkUrl = obj.linkUrl;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ export const INITIAL_PAGES_PRELOAD_COUNT = 5;
|
||||
|
||||
type MediaAsset = {
|
||||
url: string;
|
||||
kind: 'image' | 'video';
|
||||
kind: 'image' | 'video' | 'audio';
|
||||
};
|
||||
|
||||
const MEDIA_LOAD_TIMEOUT_MS = 15_000;
|
||||
@@ -20,6 +20,11 @@ function addVideoUrl(urls: Map<string, MediaAsset>, url?: string) {
|
||||
urls.set(url, { url, kind: 'video' });
|
||||
}
|
||||
|
||||
function addAudioUrl(urls: Map<string, MediaAsset>, url?: string) {
|
||||
if (!url) return;
|
||||
urls.set(url, { url, kind: 'audio' });
|
||||
}
|
||||
|
||||
export function extractPageMediaAssets(
|
||||
pages: PageData[],
|
||||
documentSettings?: Partial<DocumentSettings>,
|
||||
@@ -38,6 +43,8 @@ export function extractPageMediaAssets(
|
||||
addImageUrl(assets, element.imageUrl);
|
||||
} else if (element.type === 'video') {
|
||||
addVideoUrl(assets, element.videoUrl);
|
||||
} else if (element.type === 'audio') {
|
||||
addAudioUrl(assets, element.audioUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,6 +90,25 @@ function preloadVideo(url: string): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
function preloadAudio(url: string): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
const audio = document.createElement('audio');
|
||||
audio.preload = 'auto';
|
||||
|
||||
const finish = () => {
|
||||
audio.onloadeddata = null;
|
||||
audio.onerror = null;
|
||||
audio.removeAttribute('src');
|
||||
audio.load();
|
||||
resolve();
|
||||
};
|
||||
|
||||
audio.onloadeddata = finish;
|
||||
audio.onerror = finish;
|
||||
audio.src = url;
|
||||
});
|
||||
}
|
||||
|
||||
function withTimeout(promise: Promise<void>, ms: number): Promise<void> {
|
||||
return Promise.race([
|
||||
promise,
|
||||
@@ -94,7 +120,11 @@ function withTimeout(promise: Promise<void>, ms: number): Promise<void> {
|
||||
|
||||
export function preloadMediaAsset(asset: MediaAsset): Promise<void> {
|
||||
const load =
|
||||
asset.kind === 'video' ? preloadVideo(asset.url) : preloadImage(asset.url);
|
||||
asset.kind === 'video'
|
||||
? preloadVideo(asset.url)
|
||||
: asset.kind === 'audio'
|
||||
? preloadAudio(asset.url)
|
||||
: preloadImage(asset.url);
|
||||
return withTimeout(load, MEDIA_LOAD_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user