add video embed to description pane
This commit is contained in:
parent
c93f65153c
commit
5e01e56dec
3 changed files with 48 additions and 11 deletions
|
|
@ -52,7 +52,7 @@
|
|||
import Button from '$lib/components/ui/Button.svelte'
|
||||
import Icon from '$lib/components/Icon.svelte'
|
||||
import DescriptionRenderer from '$lib/components/DescriptionRenderer.svelte'
|
||||
import { openDescriptionSidebar } from '$lib/features/description/openDescriptionSidebar.svelte'
|
||||
import { openDescriptionPane } from '$lib/features/description/openDescriptionPane.svelte'
|
||||
import {
|
||||
openPartyEditSidebar,
|
||||
type PartyEditValues
|
||||
|
|
@ -407,9 +407,10 @@
|
|||
let deleting = $state(false)
|
||||
|
||||
function openDescriptionPanel() {
|
||||
openDescriptionSidebar({
|
||||
openDescriptionPane({
|
||||
title: party.name || '(untitled party)',
|
||||
description: party.description,
|
||||
videoUrl: party.videoUrl,
|
||||
canEdit: canEdit(),
|
||||
partyId: party.id,
|
||||
partyShortcode: party.shortcode,
|
||||
|
|
|
|||
|
|
@ -7,13 +7,24 @@
|
|||
|
||||
interface Props {
|
||||
description?: string
|
||||
videoUrl?: string
|
||||
canEdit?: boolean
|
||||
partyId?: string
|
||||
partyShortcode?: string
|
||||
onSave?: (description: string) => Promise<void>
|
||||
}
|
||||
|
||||
let { description, canEdit = false, partyId, partyShortcode, onSave }: Props = $props()
|
||||
let { description, videoUrl, canEdit = false, partyId, partyShortcode, onSave }: Props = $props()
|
||||
|
||||
/** Extract YouTube video ID from various URL formats */
|
||||
function extractVideoId(url?: string): string | null {
|
||||
if (!url) return null
|
||||
// Match youtube.com/watch?v=ID, youtu.be/ID, youtube.com/embed/ID
|
||||
const match = url.match(/(?:youtube\.com\/(?:watch\?v=|embed\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/)
|
||||
return match?.[1] ?? null
|
||||
}
|
||||
|
||||
const videoId = $derived(extractVideoId(videoUrl))
|
||||
|
||||
const paneStack = usePaneStack()
|
||||
|
||||
|
|
@ -43,9 +54,20 @@
|
|||
})
|
||||
</script>
|
||||
|
||||
<div class="description-sidebar">
|
||||
<div class="description-pane">
|
||||
<div class="content-section">
|
||||
<div class="content-inner">
|
||||
{#if videoId}
|
||||
<div class="video-embed">
|
||||
<iframe
|
||||
src="https://www.youtube.com/embed/{videoId}"
|
||||
title="YouTube video"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen
|
||||
></iframe>
|
||||
</div>
|
||||
{/if}
|
||||
{#if description}
|
||||
<div class="description-content">
|
||||
<DescriptionRenderer content={description} truncate={false} />
|
||||
|
|
@ -65,13 +87,25 @@
|
|||
@use '$src/themes/typography' as *;
|
||||
@use '$src/themes/effects' as *;
|
||||
|
||||
.description-sidebar {
|
||||
.description-pane {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.video-embed {
|
||||
margin-bottom: $unit-2x;
|
||||
border-radius: $unit;
|
||||
overflow: hidden;
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.content-section {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
|
|
|
|||
|
|
@ -1,20 +1,22 @@
|
|||
import { sidebar } from '$lib/stores/sidebar.svelte'
|
||||
import DescriptionSidebar from '$lib/components/sidebar/DescriptionSidebar.svelte'
|
||||
import DescriptionPane from '$lib/components/sidebar/DescriptionPane.svelte'
|
||||
|
||||
interface DescriptionSidebarOptions {
|
||||
interface DescriptionPaneOptions {
|
||||
title?: string | undefined
|
||||
description?: string | undefined
|
||||
videoUrl?: string | undefined
|
||||
canEdit?: boolean | undefined
|
||||
partyId?: string | undefined
|
||||
partyShortcode?: string | undefined
|
||||
onSave?: ((description: string) => Promise<void>) | undefined
|
||||
}
|
||||
|
||||
export function openDescriptionSidebar(options: DescriptionSidebarOptions) {
|
||||
const { title, description, canEdit, partyId, partyShortcode, onSave } = options
|
||||
export function openDescriptionPane(options: DescriptionPaneOptions) {
|
||||
const { title, description, videoUrl, canEdit, partyId, partyShortcode, onSave } = options
|
||||
|
||||
sidebar.openWithComponent(title ?? '', DescriptionSidebar, {
|
||||
sidebar.openWithComponent(title ?? '', DescriptionPane, {
|
||||
description,
|
||||
videoUrl,
|
||||
canEdit,
|
||||
partyId,
|
||||
partyShortcode,
|
||||
|
|
@ -22,6 +24,6 @@ export function openDescriptionSidebar(options: DescriptionSidebarOptions) {
|
|||
})
|
||||
}
|
||||
|
||||
export function closeDescriptionSidebar() {
|
||||
export function closeDescriptionPane() {
|
||||
sidebar.close()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue