Skip to content

Commit 2c4b51f

Browse files
committed
feat: font size slider for subtitles
1 parent 51f5296 commit 2c4b51f

4 files changed

Lines changed: 45 additions & 9 deletions

File tree

resources/js/components/video/VideoPlayer.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ function resetControlsTimeout() {
791791
}
792792
793793
function handleControlsTimeout() {
794-
if (isPaused.value || popover.value?.popoverOpen) return;
794+
if (isPaused.value || popover.value?.popoverOpen || playerSubtitles.value?.subtitlesPopover?.popoverOpen) return;
795795
if (controlsHideTimeout.value) clearTimeout(controlsHideTimeout.value);
796796
797797
isShowingControls.value = false;
@@ -1137,7 +1137,7 @@ defineExpose({
11371137
width="100%"
11381138
type="video/mp4"
11391139
ref="player"
1140-
:style="{ 'z-index': 3 }"
1140+
:style="{ 'z-index': 3, '--subtitle-font-multiplier': playerSubtitles?.subtitleSizeMultiplier ?? 1 }"
11411141
preload="metadata"
11421142
:class="
11431143
cn(
@@ -1383,7 +1383,7 @@ defineExpose({
13831383
<ProiconsSettings class="size-4 transition-transform duration-500 ease-in-out hover:rotate-180" />
13841384
</template>
13851385
<template #content>
1386-
<section class="scrollbar-minimal xs:h-28 flex h-14 flex-col overflow-y-auto transition-transform md:h-fit">
1386+
<section class="scrollbar-minimal xs:h-28 flex h-14 flex-col overflow-y-auto pe-0.5 transition-transform md:h-fit md:pe-0">
13871387
<VideoPopoverItem v-for="(item, index) in videoPopoverItems" :key="index" v-bind="item" />
13881388
<VideoPopoverSlider
13891389
v-model="currentSpeed"
@@ -1647,7 +1647,7 @@ video::cue {
16471647
font-family: var(--font-figtree);
16481648
text-shadow: 0px 0px 7px #000 !important;
16491649
/* Font size here for firefox */
1650-
font-size: var(--subtitle-cue-size, 1rem);
1650+
font-size: calc(var(--subtitle-cue-size, 1rem) * var(--subtitle-font-multiplier, 1));
16511651
}
16521652
16531653
/* Incompatible with Firefox */

resources/js/components/video/VideoPopoverItem.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const props = withDefaults(defineProps<PopoverItem>(), {});
1010
:title="title ?? 'Popover Item'"
1111
:class="
1212
cn(
13-
'disabled:button-disabled transition-input relative flex w-full cursor-pointer items-center rounded-sm px-2 py-1.5 text-xs outline-hidden ease-in-out select-none hover:bg-neutral-900',
13+
'disabled:button-disabled transition-input relative flex w-full cursor-pointer items-center rounded-md px-2 py-1.5 text-xs outline-hidden ease-in-out select-none hover:bg-neutral-900',
1414
{ selectedStyle: selected },
1515
{ hidden: disabled },
1616
style,

resources/js/components/video/VideoPopoverSlider.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const model = defineModel();
88
<section
99
:disabled="disabled"
1010
:title="title ?? 'Popover Slider'"
11-
:class="`relative flex w-full flex-wrap items-center gap-y-2 rounded-sm px-2 py-1.5 text-xs outline-hidden transition-colors hover:bg-neutral-900 data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 ${style ?? ''}`"
11+
:class="`relative flex w-full flex-wrap items-center gap-y-2 rounded-md px-2 py-1.5 text-xs outline-hidden transition-colors hover:bg-neutral-900 data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 ${style ?? ''}`"
1212
@wheel="wheelAction"
1313
v-show="!hidden"
1414
>

resources/js/components/video/subtitles/PlayerSubtitles.vue

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
<script setup lang="ts">
22
import type { SubtitleResource } from '@/types/resources';
3-
import { cn, type PopoverItem } from '@aminnausin/cedar-ui';
3+
import type { PopoverItem } from '@aminnausin/cedar-ui';
44
import type { Ref } from 'vue';
55
66
import { computed, inject, ref, useTemplateRef } from 'vue';
77
import { useContentStore } from '@/stores/ContentStore';
88
import { storeToRefs } from 'pinia';
9+
import { round } from 'lodash-es';
10+
import { cn } from '@aminnausin/cedar-ui';
911
12+
import VideoPopoverSlider from '@/components/video/VideoPopoverSlider.vue';
1013
import VideoPopoverItem from '@/components/video/VideoPopoverItem.vue';
1114
import VideoPopover from '@/components/video/VideoPopover.vue';
1215
16+
import ProiconsTextFontSize from '~icons/proicons/text-font-size';
1317
import ProiconsCheckmark from '~icons/proicons/checkmark';
1418
import LucideCaptionsOff from '~icons/lucide/captions-off';
1519
import LucideCaptions from '~icons/lucide/captions';
@@ -28,6 +32,10 @@ const props = defineProps<PlayerSubtitlesProps>();
2832
//#region Local State
2933
const currentSubtitleTrack = ref<SubtitleResource>();
3034
const isShowingSubtitles = ref(false);
35+
const subtitleSizeMultiplier = ref(1);
36+
const subtitleSizeMin = 0.5;
37+
const subtitleSizeMax = 2;
38+
const subtitleSizeDelta = 0.1;
3139
3240
const subtitlesPopover = useTemplateRef('subtitles-popover');
3341
const playerSubtitleItems = computed(() => {
@@ -70,6 +78,19 @@ const defaultSubtitleTrack = computed<SubtitleResource | undefined>(() => {
7078
7179
return subtitles.find((s) => s.is_default) ?? subtitles[0];
7280
});
81+
82+
const handleSizeChange = (_: Event, dir: number = 0) => {
83+
if (dir) {
84+
subtitleSizeMultiplier.value = round(Math.max(Math.min(parseFloat(`${subtitleSizeMultiplier.value}`) + subtitleSizeDelta * dir, subtitleSizeMax), subtitleSizeMin), 2);
85+
}
86+
};
87+
88+
const handleSizeWheel = (event: WheelEvent) => {
89+
event.preventDefault();
90+
91+
handleSizeChange(new Event('SizeChange'), event.deltaY < 0 ? 1 : -1);
92+
};
93+
7394
//#endregion
7495
7596
//#region Functions
@@ -116,14 +137,16 @@ defineExpose({
116137
isShowingSubtitles,
117138
currentSubtitleTrack,
118139
defaultSubtitleTrack,
140+
subtitleSizeMultiplier,
141+
subtitlesPopover,
119142
});
120143
</script>
121144
<template>
122145
<VideoPopover
123146
ref="subtitles-popover"
124147
:margin="80"
125148
:player="player"
126-
:popoverClass="cn('max-w-40! rounded-lg md:h-fit', { 'h-18 ': playerSubtitleItems.length > 1 }, { 'right-0!': usingPlayerModernUI })"
149+
:popoverClass="cn('max-w-40! rounded-lg md:h-fit', { 'h-28 ': playerSubtitleItems.length > 1 }, { 'right-0!': usingPlayerModernUI })"
127150
:button-attributes="{
128151
'target-element': player,
129152
'use-tooltip': true,
@@ -136,7 +159,20 @@ defineExpose({
136159
<LucideCaptionsOff v-else class="size-4" />
137160
</template>
138161
<template #content>
139-
<section :class="['scrollbar-minimal flex max-h-28 flex-col overflow-y-auto transition-transform md:h-fit', { 'h-14': playerSubtitleItems.length > 1 }]">
162+
<section :class="['scrollbar-minimal flex max-h-32 flex-col overflow-y-auto transition-transform md:h-fit', { 'h-25 pe-0.5': playerSubtitleItems.length > 1 }]">
163+
<VideoPopoverSlider
164+
v-if="playerSubtitleItems.length > 1"
165+
v-model="subtitleSizeMultiplier"
166+
:text="`Font Size`"
167+
:shortcut="`${Math.round(subtitleSizeMultiplier * 100)}%`"
168+
:icon="ProiconsTextFontSize"
169+
:min="0.5"
170+
:max="2"
171+
:step="0.1"
172+
:action="handleSizeChange"
173+
:wheel-action="handleSizeWheel"
174+
:title="'Change Subtitle Font Size'"
175+
/>
140176
<VideoPopoverItem v-for="(item, index) in playerSubtitleItems" :key="index" v-bind="item" class="capitalize" />
141177
</section>
142178
</template>

0 commit comments

Comments
 (0)