Skip to content

Commit

Permalink
fix: groundwork to allow time entry for custom durations
Browse files Browse the repository at this point in the history
  • Loading branch information
sircharlo committed Dec 6, 2024
1 parent 623aead commit c369cd2
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 40 deletions.
6 changes: 1 addition & 5 deletions src/components/dialog/DialogAudioBible.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down
132 changes: 99 additions & 33 deletions src/components/media/MediaItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,26 +76,48 @@
</div>
<div class="row items-center q-mt-lg">
<div class="col-shrink q-pr-md time-duration">
{{ formatTime(0) }}
<q-input
v-model="customDurationMinUserInput"
class="text-center q-pa-none"
dense
hide-bottom-space
item-aligned
:max="customDurationMax"
min="0"
outlined
style="width: 70px"
/>
</div>
<div class="col">
<div class="col flex">
<q-range
v-model="
customDurations[currentCongregation]![selectedDate]![
media.uniqueId
]
"
label
label-always
:left-label-value="formatTime(customDurationMin)"
:max="media.duration"
:min="0"
:right-label-value="formatTime(customDurationMax)"
:step="0.1"
@update:model-value="
customDurationMinUserInput =
formatTime(customDurationMin);
customDurationMaxUserInput =
formatTime(customDurationMax);
"
/>
</div>
<div class="col-shrink q-pl-md time-duration">
{{ formatTime(media.duration) }}
<q-input
v-model="customDurationMaxUserInput"
class="text-center q-pa-none"
dense
hide-bottom-space
item-aligned
:max="media.duration"
:min="customDurationMin"
outlined
style="width: 70px"
/>
</div>
</div>
</q-card-section>
Expand Down Expand Up @@ -290,31 +312,53 @@
"
class="absolute duration-slider"
>
<q-slider
v-model="mediaPlayingCurrentPosition"
:color="
mediaPlayingAction === 'pause' ? 'primary' : 'accent-400'
"
:inner-max="customDurationMax"
:inner-min="customDurationMin"
inner-track-color="accent-400"
label
:label-always="mediaPlayingAction === 'pause'"
:label-color="
mediaPlayingAction === 'pause' ? undefined : 'accent-400'
"
:label-value="
mediaPlayingAction === 'pause'
? formatTime(mediaPlayingCurrentPosition)
: $t('pause-to-adjust-time')
"
:max="media.duration"
:min="0"
:readonly="mediaPlayingAction !== 'pause'"
:step="0.1"
track-color="negative"
@update:model-value="seekTo"
/>
<div class="row flex-center">
<div class="col" style="height: 28px">
<q-slider
v-model="mediaPlayingCurrentPosition"
:color="
mediaPlayingAction === 'pause'
? 'primary'
: 'accent-400'
"
:inner-max="customDurationMax"
:inner-min="customDurationMin"
inner-track-color="accent-400"
label
:label-color="
mediaPlayingAction === 'pause'
? undefined
: 'accent-400'
"
:label-value="
mediaPlayingAction === 'pause'
? formatTime(mediaPlayingCurrentPosition)
: $t('pause-to-adjust-time')
"
:max="media.duration"
:min="0"
:readonly="mediaPlayingAction !== 'pause'"
:step="0.1"
track-color="negative"
@update:model-value="seekTo"
/>
</div>
<div
class="col-shrink text-caption q-mx-sm text-right"
style="min-width: 40px"
>
{{
'-' +
formatTime(
Math.max(
(customDurationMax || 0) -
(mediaPlayingCurrentPosition || 0),
0,
),
)
}}
</div>
</div>
</div>
</transition>
</div>
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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]?.[
Expand All @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions src/css/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -417,8 +417,8 @@ body.body--dark {
}

.duration-slider {
width: calc(100% - 207px);
bottom: -8px;
width: calc(100% - 198px);
bottom: 0px;
right: 16px;
}

Expand Down
22 changes: 22 additions & 0 deletions src/utils/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
};

0 comments on commit c369cd2

Please sign in to comment.