diff --git a/src/components/dialog/DialogAudioBible.vue b/src/components/dialog/DialogAudioBible.vue index d38844e4d..d15198dd5 100644 --- a/src/components/dialog/DialogAudioBible.vue +++ b/src/components/dialog/DialogAudioBible.vue @@ -210,6 +210,7 @@ import { } from 'src/helpers/jw-media'; import { useCurrentStateStore } from 'src/stores/current-state'; import { useJwStore } from 'src/stores/jw'; +import { timeToSeconds } from 'src/utils/time'; import { computed, ref, watch } from 'vue'; // Stores @@ -336,11 +337,6 @@ const addSelectedVerses = async () => { const startVerseNumber = chosenVerses.value[0]; const endVerseNumber = chosenVerses.value[1] || startVerseNumber; - const timeToSeconds = (time: string) => { - const [h, m, s] = time.split(':').map(parseFloat); - return h * 3600 + m * 60 + s; - }; - const min = timeToSeconds( selectedChapterMedia.value.map((item) => item.markers.markers.find( diff --git a/src/components/media/MediaItem.vue b/src/components/media/MediaItem.vue index 0a06f24fb..8199344c0 100644 --- a/src/components/media/MediaItem.vue +++ b/src/components/media/MediaItem.vue @@ -76,26 +76,48 @@
- {{ formatTime(0) }} +
-
+
- {{ formatTime(media.duration) }} +
@@ -290,31 +312,53 @@ " class="absolute duration-slider" > - +
+
+ +
+
+ {{ + '-' + + formatTime( + Math.max( + (customDurationMax || 0) - + (mediaPlayingCurrentPosition || 0), + 0, + ), + ) + }} +
+
@@ -671,7 +715,7 @@ import { useObsStateStore } from 'src/stores/obs-state'; import { isFileUrl } from 'src/utils/fs'; import { isAudio, isImage, isVideo } from 'src/utils/media'; import { sendObsSceneEvent } from 'src/utils/obs'; -import { formatTime } from 'src/utils/time'; +import { formatTime, timeToSeconds } from 'src/utils/time'; import { computed, onMounted, @@ -802,6 +846,17 @@ const customDurationMin = computed(() => { ); }); +const customDurationMinUserInput = ref(formatTime(customDurationMin.value)); + +watch(customDurationMinUserInput, (val) => { + const duration = + customDurations.value?.[currentCongregation.value]?.[selectedDate.value]?.[ + props.media.uniqueId + ]; + if (!duration) return; + duration.min = timeToSeconds(val); +}); + const customDurationMax = computed(() => { return ( customDurations.value[currentCongregation.value]?.[selectedDate.value]?.[ @@ -810,6 +865,17 @@ const customDurationMax = computed(() => { ); }); +const customDurationMaxUserInput = ref(formatTime(customDurationMax.value)); + +watch(customDurationMaxUserInput, (val) => { + const duration = + customDurations.value?.[currentCongregation.value]?.[selectedDate.value]?.[ + props.media.uniqueId + ]; + if (!duration) return; + duration.max = timeToSeconds(val); +}); + const setMediaPlaying = async ( media: DynamicMediaObject, signLanguage = false, diff --git a/src/css/app.scss b/src/css/app.scss index 5899d2f60..5cd380364 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -417,8 +417,8 @@ body.body--dark { } .duration-slider { - width: calc(100% - 207px); - bottom: -8px; + width: calc(100% - 198px); + bottom: 0px; right: 16px; } diff --git a/src/utils/time.ts b/src/utils/time.ts index 33a0542eb..3c0f91a8b 100644 --- a/src/utils/time.ts +++ b/src/utils/time.ts @@ -25,3 +25,25 @@ export const formatTime = (time: number) => { return '..:..'; } }; + +export const timeToSeconds = (time: string) => { + try { + const parts = time.split(':').map(parseFloat); + if (parts.length === 3) { + // Format: hh:mm:ss + const [h, m, s] = parts; + return h * 3600 + m * 60 + s; + } else if (parts.length === 2) { + // Format: mm:ss + const [m, s] = parts; + // Convert minutes to hours and calculate seconds + const h = Math.floor(m / 60); + const remainingMinutes = m % 60; + return h * 3600 + remainingMinutes * 60 + s; + } + return 0; + } catch (error) { + errorCatcher(error); + return 0; + } +};