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;
+ }
+};