feat: implement lazy loading for MediaLibraryPage and optimize video rendering
Some checks failed
Deploy Development / deploy (push) Successful in 35s
Test Suite / pytest-backend (push) Successful in 25s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 7s
Test Suite / playwright-tests (push) Failing after 1m43s
Some checks failed
Deploy Development / deploy (push) Successful in 35s
Test Suite / pytest-backend (push) Successful in 25s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 7s
Test Suite / playwright-tests (push) Failing after 1m43s
- Refactored MediaLibraryPage to use React's lazy loading and Suspense for improved performance during page load. - Updated video rendering logic to utilize createElement for better flexibility and maintainability. - Enhanced loading state with a spinner to improve user experience while media content is being fetched.
This commit is contained in:
parent
bebcf5af73
commit
c1d1c2d7e0
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react'
|
||||
import React, { lazy, Suspense } from 'react'
|
||||
import {
|
||||
BrowserRouter as Router,
|
||||
Routes,
|
||||
|
|
@ -32,10 +32,11 @@ import AdminMaturityModelsPage from './pages/AdminMaturityModelsPage'
|
|||
import TrainerContextsPage from './pages/TrainerContextsPage'
|
||||
import MediaWikiImportPage from './pages/MediaWikiImportPage'
|
||||
import AdminUsersPage from './pages/AdminUsersPage'
|
||||
import MediaLibraryPage from './pages/MediaLibraryPage'
|
||||
import ActiveClubSwitcher from './components/ActiveClubSwitcher'
|
||||
import './app.css'
|
||||
|
||||
const MediaLibraryPage = lazy(() => import('./pages/MediaLibraryPage'))
|
||||
|
||||
// Bottom Navigation (Mobile)
|
||||
function Nav({ isAdmin }) {
|
||||
const items = getMainNavItems(isAdmin)
|
||||
|
|
@ -159,7 +160,28 @@ function AppRoutes() {
|
|||
<Route path="profile" element={<Navigate to="/settings" replace />} />
|
||||
<Route path="settings" element={<AccountSettingsPage />} />
|
||||
<Route path="settings/system" element={<SettingsSystemInfoPage />} />
|
||||
<Route path="media" element={<MediaLibraryPage />} />
|
||||
<Route
|
||||
path="media"
|
||||
element={
|
||||
<Suspense
|
||||
fallback={
|
||||
<div
|
||||
style={{
|
||||
minHeight: '50vh',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
background: 'var(--bg)',
|
||||
}}
|
||||
>
|
||||
<div className="spinner" />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<MediaLibraryPage />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
<Route path="exercises">
|
||||
<Route index element={<ExercisesListPage />} />
|
||||
<Route path="new" element={<ExerciseFormPage />} />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useState, useCallback, useRef } from 'react'
|
||||
import { useEffect, useState, useCallback, useRef, createElement } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import {
|
||||
LayoutGrid,
|
||||
|
|
@ -162,24 +162,22 @@ function MediaThumb({ mediaId, mimeType }) {
|
|||
return <div className="media-library__thumb-ph">HEIC</div>
|
||||
}
|
||||
if (mime.startsWith('video/')) {
|
||||
return (
|
||||
<video
|
||||
className="media-library__thumb-video"
|
||||
src={url}
|
||||
muted
|
||||
playsInline
|
||||
preload="metadata"
|
||||
onLoadedMetadata={(e) => {
|
||||
const el = e.target
|
||||
try {
|
||||
const d = el.duration
|
||||
el.currentTime = Number.isFinite(d) && d > 0 ? Math.min(0.05, d * 0.01) : 0.05
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
return createElement('video', {
|
||||
className: 'media-library__thumb-video',
|
||||
src: url,
|
||||
muted: true,
|
||||
playsInline: true,
|
||||
preload: 'metadata',
|
||||
onLoadedMetadata: (e) => {
|
||||
const el = e.target
|
||||
try {
|
||||
const d = el.duration
|
||||
el.currentTime = Number.isFinite(d) && d > 0 ? Math.min(0.05, d * 0.01) : 0.05
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
if (mime.startsWith('image/')) {
|
||||
return (
|
||||
|
|
@ -907,17 +905,17 @@ export default function MediaLibraryPage() {
|
|||
)
|
||||
}
|
||||
if (kind === 'video') {
|
||||
return (
|
||||
<video
|
||||
key={preview.id}
|
||||
className="media-library__preview-video"
|
||||
src={url}
|
||||
controls
|
||||
playsInline
|
||||
preload="metadata"
|
||||
>
|
||||
Wiedergabe nicht unterstützt.
|
||||
</video>
|
||||
return createElement(
|
||||
'video',
|
||||
{
|
||||
key: preview.id,
|
||||
className: 'media-library__preview-video',
|
||||
src: url,
|
||||
controls: true,
|
||||
playsInline: true,
|
||||
preload: 'metadata',
|
||||
},
|
||||
'Wiedergabe nicht unterstützt.',
|
||||
)
|
||||
}
|
||||
if (kind === 'pdf') {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user