forked from BRETT/BRETT
Media attachment cards with popover players and shared volume
- Audio/video attachments render as media cards (cover or icon, title/artist/size) instead of plain file chips; image attachments use 3:2 thumbnails matching the audio card height - Players open in a Popover (autoplay on open) with a dimming overlay; AudioPlayerDialog/VideoPlayerDialog removed - New useMediaVolume composable shares volume/mute between all audio players and Plyr via the 4brett-player storage key - Player buttons and Plyr controls follow the theme border radius - Portrait videos: aspect is applied even when metadata loaded before hydration, and the raw video is height-capped pre-JS Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { useMediaControls } from '@vueuse/core'
|
||||
|
||||
// Derselbe localStorage-Key wie Plyr im VideoPlayer — so teilen sich Video- und
|
||||
// Audio-Player eine gemerkte Lautstärke (in beide Richtungen)
|
||||
const STORAGE_KEY = '4brett-player'
|
||||
|
||||
interface StoredPrefs {
|
||||
volume?: number
|
||||
muted?: boolean
|
||||
}
|
||||
|
||||
function readPrefs(): StoredPrefs {
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY)
|
||||
return raw ? JSON.parse(raw) as StoredPrefs : {}
|
||||
}
|
||||
catch {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
export function useMediaVolume(target: Parameters<typeof useMediaControls>[0]) {
|
||||
const controls = useMediaControls(target)
|
||||
|
||||
if (import.meta.client) {
|
||||
const applyStored = () => {
|
||||
const prefs = readPrefs()
|
||||
if (typeof prefs.volume === 'number' && controls.volume.value !== prefs.volume) {
|
||||
controls.volume.value = prefs.volume
|
||||
}
|
||||
if (typeof prefs.muted === 'boolean' && controls.muted.value !== prefs.muted) {
|
||||
controls.muted.value = prefs.muted
|
||||
}
|
||||
}
|
||||
|
||||
watch(toRef(target), (el) => {
|
||||
if (el) applyStored()
|
||||
}, { immediate: true })
|
||||
|
||||
watch([controls.volume, controls.muted], ([v, m]) => {
|
||||
const prefs = readPrefs()
|
||||
if (prefs.volume === v && prefs.muted === m) return
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify({ ...prefs, volume: v, muted: m }))
|
||||
}
|
||||
catch { /* Storage deaktiviert/voll */ }
|
||||
})
|
||||
}
|
||||
|
||||
return controls
|
||||
}
|
||||
Reference in New Issue
Block a user