Compare commits

...

2 Commits

Author SHA1 Message Date
Michael B
451d594f23 feat(website): wire English subtitle tracks for learning tutorials 2026-06-08 12:55:41 -04:00
Michael B
9ffdcd17b6 fix: show featured workflow video before copy on mobile 2026-06-08 12:11:54 -04:00
5 changed files with 102 additions and 26 deletions

View File

@@ -13,15 +13,9 @@ import { computed, shallowRef, useTemplateRef, watch } from 'vue'
import { t } from '../../i18n/translations'
import type { Locale } from '../../i18n/translations'
import type { VideoTrack } from '../../types/video'
import PlayPauseButton from './PlayPauseButton.vue'
type VideoTrack = {
src: string
kind: 'subtitles' | 'captions' | 'descriptions'
srclang: string
label: string
}
const {
locale = 'en',
src,
@@ -285,7 +279,7 @@ function toggleFullscreen() {
@click="toggleFullscreen"
>
<svg
class="text-primary-comfy-ink size-3.5 lg:size-4"
class="size-3.5 text-primary-comfy-ink lg:size-4"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
@@ -331,7 +325,7 @@ function toggleFullscreen() {
<!-- Muted icon -->
<svg
v-if="muted"
class="text-primary-comfy-ink size-3.5 lg:size-4"
class="size-3.5 text-primary-comfy-ink lg:size-4"
viewBox="0 0 24 24"
fill="currentColor"
stroke="currentColor"
@@ -349,7 +343,7 @@ function toggleFullscreen() {
<!-- Unmuted icon -->
<svg
v-else
class="text-primary-comfy-ink size-3.5 lg:size-4"
class="size-3.5 text-primary-comfy-ink lg:size-4"
viewBox="0 0 24 24"
fill="currentColor"
stroke="currentColor"

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import type { Locale } from '../../i18n/translations'
import type { VideoTrack } from '../../types/video'
import { t } from '../../i18n/translations'
import Badge from '../common/Badge.vue'
@@ -13,15 +14,23 @@ const demoVideoSrc =
'https://media.comfy.org/website/learning/skyreplacement_smaller_v06.mp4'
const demoVideoPoster =
'https://media.comfy.org/website/learning/skyreplacement_smaller_v06_thumbnail.jpg'
const demoVideoTracks: VideoTrack[] = [
{
src: 'https://media.comfy.org/website/learning/skyreplacement_smaller_v06_vtt.en.vtt',
kind: 'subtitles',
srclang: 'en',
label: 'English'
}
]
</script>
<template>
<section class="max-w-9xl mx-auto px-6 py-16 lg:py-24">
<div class="grid grid-cols-1 items-center gap-12 lg:grid-cols-2 lg:gap-16">
<div class="flex flex-col gap-8">
<div class="order-last flex flex-col gap-8 lg:order-0">
<div>
<h2
class="text-primary-comfy-canvas text-4xl font-light tracking-tight lg:text-6xl"
class="text-4xl font-light tracking-tight text-primary-comfy-canvas lg:text-6xl"
>
{{ t('learning.featured.title', locale) }}
</h2>
@@ -31,7 +40,7 @@ const demoVideoPoster =
</div>
<p
class="text-primary-comfy-canvas max-w-md text-sm/relaxed lg:text-base"
class="max-w-md text-sm/relaxed text-primary-comfy-canvas lg:text-base"
>
{{ t('learning.featured.description', locale) }}
</p>
@@ -54,11 +63,14 @@ const demoVideoPoster =
</ul>
</div>
<div class="border-primary-warm-gray rounded-4.5xl border p-4">
<div
class="border-primary-warm-gray rounded-4.5xl order-first border p-4 lg:order-0"
>
<VideoPlayer
:locale
:src="demoVideoSrc"
:poster="demoVideoPoster"
:tracks="demoVideoTracks"
minimal
/>
</div>

View File

@@ -62,31 +62,41 @@ onUnmounted(() => {
>
<button
:aria-label="t('gallery.detail.close', locale)"
class="border-primary-comfy-yellow bg-primary-comfy-ink hover:bg-primary-comfy-yellow group absolute top-8 right-10 z-10 flex size-10 cursor-pointer items-center justify-center rounded-2xl border-2 transition-colors lg:right-26"
class="border-primary-comfy-yellow hover:bg-primary-comfy-yellow group absolute top-8 right-10 z-10 flex size-10 cursor-pointer items-center justify-center rounded-2xl border-2 bg-primary-comfy-ink transition-colors lg:right-26"
@click="emit('close')"
>
<span
class="bg-primary-comfy-yellow group-hover:bg-primary-comfy-ink size-5 transition-colors"
class="bg-primary-comfy-yellow size-5 transition-colors group-hover:bg-primary-comfy-ink"
style="mask: url('/icons/close.svg') center / contain no-repeat"
/>
</button>
<div
class="border-primary-comfy-yellow bg-primary-comfy-ink rounded-5xl flex w-full max-w-7xl items-center justify-center overflow-hidden border-2 p-3 lg:p-4"
class="border-primary-comfy-yellow rounded-5xl flex w-full max-w-7xl items-center justify-center overflow-hidden border-2 bg-primary-comfy-ink p-3 lg:p-4"
>
<video
ref="videoRef"
:src="tutorial.videoSrc"
:poster="tutorial.poster"
class="aspect-video w-full rounded-3xl object-contain lg:rounded-4xl"
crossorigin="anonymous"
controls
autoplay
playsinline
></video>
>
<track
v-for="track in tutorial.tracks ?? []"
:key="track.src"
:src="track.src"
:kind="track.kind"
:srclang="track.srclang"
:label="track.label"
/>
</video>
</div>
<h2
class="text-primary-comfy-canvas mt-6 text-center text-lg font-medium lg:text-xl"
class="mt-6 text-center text-lg font-medium text-primary-comfy-canvas lg:text-xl"
>
{{ t('learning.tutorials.titlePrefix', locale) }}
{{ tutorial.title[locale] }}

View File

@@ -1,4 +1,9 @@
import type { LocalizedText, TranslationKey } from '../i18n/translations'
import type {
Locale,
LocalizedText,
TranslationKey
} from '../i18n/translations'
import type { VideoTrack } from '../types/video'
export interface LearningTutorial {
id: string
@@ -8,6 +13,7 @@ export interface LearningTutorial {
href?: string
poster?: string
posterTime?: number
tracks?: readonly VideoTrack[]
}
const DEFAULT_POSTER_TIME_SECONDS = 1
@@ -20,6 +26,18 @@ export const getTutorialPosterSrc = (tutorial: LearningTutorial): string =>
? tutorial.poster
: `${tutorial.videoSrc}#t=${tutorial.posterTime ?? DEFAULT_POSTER_TIME_SECONDS}`
const SUBTITLE_LABELS: Record<Locale, string> = {
en: 'English',
'zh-CN': '简体中文'
}
const subtitleTrack = (src: string, locale: Locale): VideoTrack => ({
src,
kind: 'subtitles',
srclang: locale,
label: SUBTITLE_LABELS[locale]
})
export const learningTutorials: readonly LearningTutorial[] = [
{
id: 'cleanplate_walkthrough_v03',
@@ -29,7 +47,13 @@ export const learningTutorials: readonly LearningTutorial[] = [
poster:
'https://media.comfy.org/website/learning/cleanplate_walkthrough_v03_thumbnail.jpg',
// href: '#',
tags: [partnerNodesTag, imageToVideoTag]
tags: [partnerNodesTag, imageToVideoTag],
tracks: [
subtitleTrack(
'https://media.comfy.org/website/learning/cleanplate_walkthrough_v03_vtt.en.vtt',
'en'
)
]
},
{
id: 'deaging_workflow_v03',
@@ -39,7 +63,13 @@ export const learningTutorials: readonly LearningTutorial[] = [
poster:
'https://media.comfy.org/website/learning/deaging_workflow_v03_thumbnail.jpg',
href: 'https://cloud.comfy.org/?share=93f286fbc2c8',
tags: [partnerNodesTag, imageToVideoTag]
tags: [partnerNodesTag, imageToVideoTag],
tracks: [
subtitleTrack(
'https://media.comfy.org/website/learning/deaging_workflow_v03_vtt.en.vtt',
'en'
)
]
},
{
id: 'frame_adjustments_demo_v03',
@@ -49,7 +79,13 @@ export const learningTutorials: readonly LearningTutorial[] = [
poster:
'https://media.comfy.org/website/learning/frame_adjustments_demo_v03_thumbnail.jpg',
href: 'https://cloud.comfy.org/?share=7dca0438edf4',
tags: [partnerNodesTag, imageToVideoTag]
tags: [partnerNodesTag, imageToVideoTag],
tracks: [
subtitleTrack(
'https://media.comfy.org/website/learning/frame_adjustments_demo_v03_vtt.en.vtt',
'en'
)
]
},
{
id: 'mattes_and_utilities_v03',
@@ -59,7 +95,13 @@ export const learningTutorials: readonly LearningTutorial[] = [
poster:
'https://media.comfy.org/website/learning/mattes_and_utilities_v03_thumbnail.jpg',
href: 'https://cloud.comfy.org/?share=be0889296f65',
tags: [partnerNodesTag, imageToVideoTag]
tags: [partnerNodesTag, imageToVideoTag],
tracks: [
subtitleTrack(
'https://media.comfy.org/website/learning/mattes_and_utilities_v03_vtt.en.vtt',
'en'
)
]
},
{
id: 'seedance_demo_comfyui_v03',
@@ -69,7 +111,13 @@ export const learningTutorials: readonly LearningTutorial[] = [
poster:
'https://media.comfy.org/website/learning/seedance seedance_demo_comfyui_v03_thumbnail.jpg',
href: 'https://cloud.comfy.org/?share=ef543bd4a773',
tags: [partnerNodesTag, imageToVideoTag]
tags: [partnerNodesTag, imageToVideoTag],
tracks: [
subtitleTrack(
'https://media.comfy.org/website/learning/seedance_demo_comfyui_v03_vtt.en.vtt',
'en'
)
]
},
{
id: 'skyreplacement_smaller_v06',
@@ -79,6 +127,12 @@ export const learningTutorials: readonly LearningTutorial[] = [
poster:
'https://media.comfy.org/website/learning/skyreplacement_smaller_v06_thumbnail.jpg',
href: 'https://comfy.org/workflows/537cf7f1f745-537cf7f1f745/',
tags: [partnerNodesTag, imageToVideoTag]
tags: [partnerNodesTag, imageToVideoTag],
tracks: [
subtitleTrack(
'https://media.comfy.org/website/learning/skyreplacement_smaller_v06_vtt.en.vtt',
'en'
)
]
}
] as const

View File

@@ -0,0 +1,6 @@
export interface VideoTrack {
src: string
kind: 'subtitles' | 'captions' | 'descriptions'
srclang: string
label: string
}