Tailwind V4 migration initial commit

This commit is contained in:
mikiher 2025-03-16 16:41:37 +02:00
parent d60ccff5e8
commit 30db5d50fb
186 changed files with 1858 additions and 1324 deletions

View file

@ -7,7 +7,7 @@
<button class="w-7 h-7 flex items-center justify-center mx-4 hover:scale-110 duration-100 transform text-gray-200 hover:text-white" @click="editItem">
<span class="material-symbols text-base">edit</span>
</button>
<div class="flex-grow hidden md:block" />
<div class="grow hidden md:block" />
<p class="text-base hidden md:block">{{ $strings.LabelDuration }}:</p>
<p class="text-base font-mono ml-4 hidden md:block">{{ $secondsToTimestamp(mediaDurationRounded) }}</p>
</div>
@ -17,18 +17,18 @@
<div class="flex items-center">
<div class="w-12 hidden lg:block" />
<p class="text-lg mb-4 font-semibold">{{ $strings.HeaderChapters }}</p>
<div class="flex-grow" />
<div class="grow" />
<ui-checkbox v-model="showSecondInputs" checkbox-bg="primary" small label-class="text-sm text-gray-200 pl-1" :label="$strings.LabelShowSeconds" class="mx-2" />
<div class="w-32 hidden lg:block" />
</div>
<div class="flex items-center mb-3 py-1 -mx-1">
<div class="w-12 hidden lg:block" />
<ui-btn v-if="chapters.length" color="primary" small class="mx-1" @click.stop="removeAllChaptersClick">{{ $strings.ButtonRemoveAll }}</ui-btn>
<ui-btn v-if="chapters.length" color="bg-primary" small class="mx-1" @click.stop="removeAllChaptersClick">{{ $strings.ButtonRemoveAll }}</ui-btn>
<ui-btn v-if="newChapters.length > 1" :color="showShiftTimes ? 'bg' : 'primary'" class="mx-1" small @click="showShiftTimes = !showShiftTimes">{{ $strings.ButtonShiftTimes }}</ui-btn>
<ui-btn color="primary" small :class="{ 'mx-1': newChapters.length > 1 }" @click="showFindChaptersModal = true">{{ $strings.ButtonLookup }}</ui-btn>
<div class="flex-grow" />
<ui-btn color="bg-primary" small :class="{ 'mx-1': newChapters.length > 1 }" @click="showFindChaptersModal = true">{{ $strings.ButtonLookup }}</ui-btn>
<div class="grow" />
<ui-btn v-if="hasChanges" small class="mx-1" @click.stop="resetChapters">{{ $strings.ButtonReset }}</ui-btn>
<ui-btn v-if="hasChanges" color="success" class="mx-1" :disabled="!hasChanges" small @click="saveChapters">{{ $strings.ButtonSave }}</ui-btn>
<ui-btn v-if="hasChanges" color="bg-success" class="mx-1" :disabled="!hasChanges" small @click="saveChapters">{{ $strings.ButtonSave }}</ui-btn>
<div class="w-32 hidden lg:block" />
</div>
@ -36,12 +36,12 @@
<transition name="slide">
<div v-if="showShiftTimes" class="flex mb-4">
<div class="w-12 hidden lg:block" />
<div class="flex-grow">
<div class="grow">
<div class="flex items-center">
<p class="text-sm mb-1 font-semibold pr-2">{{ $strings.LabelTimeToShift }}</p>
<ui-text-input v-model="shiftAmount" type="number" class="max-w-20" style="height: 30px" />
<ui-btn color="primary" class="mx-1" small @click="shiftChapterTimes">{{ $strings.ButtonAdd }}</ui-btn>
<div class="flex-grow" />
<ui-btn color="bg-primary" class="mx-1" small @click="shiftChapterTimes">{{ $strings.ButtonAdd }}</ui-btn>
<div class="grow" />
<span class="material-symbols text-gray-200 hover:text-white cursor-pointer" @click="showShiftTimes = false">expand_less</span>
</div>
<p class="text-xs py-1.5 text-gray-300 max-w-md">{{ $strings.NoteChapterEditorTimes }}</p>
@ -54,7 +54,7 @@
<div class="flex text-xs uppercase text-gray-300 font-semibold mb-2">
<div class="w-8 min-w-8 md:w-12 md:min-w-12"></div>
<div class="w-24 min-w-24 md:w-32 md:min-w-32 px-2">{{ $strings.LabelStart }}</div>
<div class="flex-grow px-2">{{ $strings.LabelTitle }}</div>
<div class="grow px-2">{{ $strings.LabelTitle }}</div>
<div class="w-32"></div>
</div>
<template v-for="chapter in newChapters">
@ -64,7 +64,7 @@
<ui-text-input v-if="showSecondInputs" v-model="chapter.start" type="number" class="text-xs" @change="checkChapters" />
<ui-time-picker v-else class="text-xs" v-model="chapter.start" :show-three-digit-hour="mediaDuration >= 360000" @change="checkChapters" />
</div>
<div class="flex-grow px-1">
<div class="grow px-1">
<ui-text-input v-model="chapter.title" @change="checkChapters" class="text-xs" />
</div>
<div class="w-32 min-w-32 px-2 py-1">
@ -103,20 +103,20 @@
<div class="w-full max-w-xl py-4 px-2">
<div class="flex items-center mb-4 py-1">
<p class="text-lg font-semibold">{{ $strings.HeaderAudioTracks }}</p>
<div class="flex-grow" />
<div class="grow" />
<ui-btn small @click="setChaptersFromTracks">{{ $strings.ButtonSetChaptersFromTracks }}</ui-btn>
<ui-tooltip :text="$strings.MessageSetChaptersFromTracksDescription" direction="top" class="flex items-center mx-1 cursor-default">
<span class="material-symbols text-xl text-gray-200">info</span>
</ui-tooltip>
</div>
<div class="flex text-xs uppercase text-gray-300 font-semibold mb-2">
<div class="flex-grow">{{ $strings.LabelFilename }}</div>
<div class="grow">{{ $strings.LabelFilename }}</div>
<div class="w-20">{{ $strings.LabelDuration }}</div>
<div class="w-20 hidden md:block text-center">{{ $strings.HeaderChapters }}</div>
</div>
<template v-for="track in audioTracks">
<div :key="track.ino" class="flex items-center py-2" :class="currentTrackIndex === track.index && isPlayingChapter ? 'bg-success bg-opacity-10' : ''">
<div class="flex-grow max-w-[calc(100%-80px)] pr-2">
<div :key="track.ino" class="flex items-center py-2" :class="currentTrackIndex === track.index && isPlayingChapter ? 'bg-success/10' : ''">
<div class="grow max-w-[calc(100%-80px)] pr-2">
<p class="text-xs truncate max-w-sm">{{ track.metadata.filename }}</p>
</div>
<div class="w-20" style="min-width: 80px">
@ -130,7 +130,7 @@
</div>
</div>
<div v-if="saving" class="w-full h-full absolute top-0 left-0 bottom-0 right-0 z-30 bg-black bg-opacity-25 flex items-center justify-center">
<div v-if="saving" class="w-full h-full absolute top-0 left-0 bottom-0 right-0 z-30 bg-black/25 flex items-center justify-center">
<ui-loading-indicator />
</div>
@ -144,7 +144,7 @@
<div v-if="!chapterData" class="flex p-20">
<ui-text-input-with-label v-model.trim="asinInput" label="ASIN" />
<ui-dropdown v-model="regionInput" :label="$strings.LabelRegion" small :items="audibleRegions" class="w-32 mx-1" />
<ui-btn small color="primary" class="mt-5" @click="findChapters">{{ $strings.ButtonSearch }}</ui-btn>
<ui-btn small color="bg-primary" class="mt-5" @click="findChapters">{{ $strings.ButtonSearch }}</ui-btn>
</div>
<div v-else class="w-full p-4">
<div class="flex justify-between mb-4">
@ -164,35 +164,35 @@
<div class="flex py-0.5 text-xs font-semibold uppercase text-gray-300 mb-1">
<div class="w-24 px-2">{{ $strings.LabelStart }}</div>
<div class="flex-grow px-2">{{ $strings.LabelTitle }}</div>
<div class="grow px-2">{{ $strings.LabelTitle }}</div>
</div>
<div class="w-full max-h-80 overflow-y-auto my-2">
<div v-for="(chapter, index) in chapterData.chapters" :key="index" class="flex py-0.5 text-xs" :class="chapter.startOffsetSec > mediaDuration ? 'bg-error bg-opacity-20' : chapter.startOffsetSec + chapter.lengthMs / 1000 > mediaDuration ? 'bg-warning bg-opacity-20' : index % 2 === 0 ? 'bg-primary bg-opacity-30' : ''">
<div v-for="(chapter, index) in chapterData.chapters" :key="index" class="flex py-0.5 text-xs" :class="chapter.startOffsetSec > mediaDuration ? 'bg-error/20' : chapter.startOffsetSec + chapter.lengthMs / 1000 > mediaDuration ? 'bg-warning/20' : index % 2 === 0 ? 'bg-primary/30' : ''">
<div class="w-24 min-w-24 px-2">
<p class="font-mono">{{ $secondsToTimestamp(chapter.startOffsetSec) }}</p>
</div>
<div class="flex-grow px-2">
<div class="grow px-2">
<p class="truncate max-w-sm">{{ chapter.title }}</p>
</div>
</div>
</div>
<div v-if="chapterData.runtimeLengthSec > mediaDurationRounded" class="w-full pt-2">
<div class="flex items-center">
<div class="w-2 h-2 bg-warning bg-opacity-50" />
<div class="w-2 h-2 bg-warning/50" />
<p class="pl-2">{{ $strings.MessageChapterEndIsAfter }}</p>
</div>
<div class="flex items-center">
<div class="w-2 h-2 bg-error bg-opacity-50" />
<div class="w-2 h-2 bg-error/50" />
<p class="pl-2">{{ $strings.MessageChapterStartIsAfter }}</p>
</div>
</div>
<div class="flex items-center pt-2">
<ui-btn small color="primary" class="mr-1" @click="applyChapterNamesOnly">{{ $strings.ButtonMapChapterTitles }}</ui-btn>
<ui-btn small color="bg-primary" class="mr-1" @click="applyChapterNamesOnly">{{ $strings.ButtonMapChapterTitles }}</ui-btn>
<ui-tooltip :text="$strings.MessageMapChapterTitles" direction="top" class="flex items-center">
<span class="material-symbols text-xl text-gray-200">info</span>
</ui-tooltip>
<div class="flex-grow" />
<ui-btn small color="success" @click="applyChapterData">{{ $strings.ButtonApplyChapters }}</ui-btn>
<div class="grow" />
<ui-btn small color="bg-success" @click="applyChapterData">{{ $strings.ButtonApplyChapters }}</ui-btn>
</div>
</div>
</div>

View file

@ -6,27 +6,27 @@
<div class="w-full h-full overflow-y-auto p-8">
<div class="w-full flex justify-between items-center pb-6 pt-2">
<p class="text-lg">{{ $strings.MessageDragFilesIntoTrackOrder }}</p>
<ui-btn color="success" @click="saveTracklist">{{ $strings.ButtonSaveTracklist }}</ui-btn>
<ui-btn color="bg-success" @click="saveTracklist">{{ $strings.ButtonSaveTracklist }}</ui-btn>
</div>
<div class="w-full flex items-center text-sm py-4 bg-primary border-l border-r border-t border-gray-600">
<div class="text-center px-4 w-12">{{ $strings.LabelNew }}</div>
<div class="text-center px-4 w-24 flex items-center cursor-pointer text-white text-opacity-40 hover:text-opacity-100" @click="sortByCurrent" @mousedown.prevent>
<div class="text-center px-4 w-24 flex items-center cursor-pointer text-white//40 hover:text-white/100" @click="sortByCurrent" @mousedown.prevent>
<span class="text-white">{{ $strings.LabelCurrent }}</span>
<span class="material-symbols ml-1" :class="currentSort === 'current' ? 'text-white text-opacity-100 text-lg' : 'text-sm'">{{ currentSort === 'current' ? 'expand_more' : 'unfold_more' }}</span>
<span class="material-symbols ml-1" :class="currentSort === 'current' ? 'text-white/100 text-lg' : 'text-sm'">{{ currentSort === 'current' ? 'expand_more' : 'unfold_more' }}</span>
</div>
<div class="text-center px-4 w-32 flex items-center cursor-pointer text-white text-opacity-40 hover:text-opacity-100" @click="sortByFilenameTrack" @mousedown.prevent>
<div class="text-center px-4 w-32 flex items-center cursor-pointer text-white//40 hover:text-white/100" @click="sortByFilenameTrack" @mousedown.prevent>
<span class="text-white">{{ $strings.LabelTrackFromFilename }}</span>
<span class="material-symbols ml-1" :class="currentSort === 'track-filename' ? 'text-white text-opacity-100 text-lg' : 'text-sm'">{{ currentSort === 'track-filename' ? 'expand_more' : 'unfold_more' }}</span>
<span class="material-symbols ml-1" :class="currentSort === 'track-filename' ? 'text-white/100 text-lg' : 'text-sm'">{{ currentSort === 'track-filename' ? 'expand_more' : 'unfold_more' }}</span>
</div>
<div class="text-center px-4 w-32 flex items-center cursor-pointer text-white text-opacity-40 hover:text-opacity-100" @click="sortByMetadataTrack" @mousedown.prevent>
<div class="text-center px-4 w-32 flex items-center cursor-pointer text-white//40 hover:text-white/100" @click="sortByMetadataTrack" @mousedown.prevent>
<span class="text-white">{{ $strings.LabelTrackFromMetadata }}</span>
<span class="material-symbols ml-1" :class="currentSort === 'metadata' ? 'text-white text-opacity-100 text-lg' : 'text-sm'">{{ currentSort === 'metadata' ? 'expand_more' : 'unfold_more' }}</span>
<span class="material-symbols ml-1" :class="currentSort === 'metadata' ? 'text-white/100 text-lg' : 'text-sm'">{{ currentSort === 'metadata' ? 'expand_more' : 'unfold_more' }}</span>
</div>
<div class="w-20 text-center">{{ $strings.LabelDiscFromFilename }}</div>
<div class="w-20 text-center">{{ $strings.LabelDiscFromMetadata }}</div>
<div class="text-center px-4 flex-grow flex items-center cursor-pointer text-white text-opacity-40 hover:text-opacity-100" @click="sortByFilename" @mousedown.prevent>
<div class="text-center px-4 grow flex items-center cursor-pointer text-white//40 hover:text-white/100" @click="sortByFilename" @mousedown.prevent>
<span class="text-white">{{ $strings.LabelFilename }}</span>
<span class="material-symbols ml-1" :class="currentSort === 'filename' ? 'text-white text-opacity-100 text-lg' : 'text-sm'">{{ currentSort === 'filename' ? 'expand_more' : 'unfold_more' }}</span>
<span class="material-symbols ml-1" :class="currentSort === 'filename' ? 'text-white/100 text-lg' : 'text-sm'">{{ currentSort === 'filename' ? 'expand_more' : 'unfold_more' }}</span>
</div>
<div class="w-20 text-center">{{ $strings.LabelSize }}</div>
@ -53,7 +53,7 @@
<div class="truncate px-4 w-20 min-w-20">
{{ audio.discNumFromMeta }}
</div>
<div class="truncate px-4 flex-grow">
<div class="truncate px-4 grow">
{{ audio.metadata.filename }}
</div>

View file

@ -19,14 +19,14 @@
</div>
<div class="flex justify-center flex-wrap">
<div class="w-full max-w-2xl border border-white border-opacity-10 bg-bg mx-2">
<div class="w-full max-w-2xl border border-white/10 bg-bg mx-2">
<div class="flex py-2 px-4">
<div class="w-1/3 text-xs font-semibold uppercase text-gray-200">{{ $strings.LabelMetaTag }}</div>
<div class="w-2/3 text-xs font-semibold uppercase text-gray-200">{{ $strings.LabelValue }}</div>
</div>
<div class="w-full max-h-72 overflow-auto">
<template v-for="(value, key, index) in metadataObject">
<div :key="key" class="flex py-1 px-4 text-sm" :class="index % 2 === 0 ? 'bg-primary bg-opacity-25' : ''">
<div :key="key" class="flex py-1 px-4 text-sm" :class="index % 2 === 0 ? 'bg-primary/25' : ''">
<div class="w-1/3 font-semibold">{{ key }}</div>
<div class="w-2/3">
{{ value }}
@ -35,17 +35,17 @@
</template>
</div>
</div>
<div class="w-full max-w-2xl border border-white border-opacity-10 bg-bg mx-2">
<div class="flex py-2 px-4 bg-primary bg-opacity-25">
<div class="flex-grow text-xs font-semibold uppercase text-gray-200">{{ $strings.LabelChapterTitle }}</div>
<div class="w-full max-w-2xl border border-white/10 bg-bg mx-2">
<div class="flex py-2 px-4 bg-primary/25">
<div class="grow text-xs font-semibold uppercase text-gray-200">{{ $strings.LabelChapterTitle }}</div>
<div class="w-24 text-xs font-semibold uppercase text-gray-200">{{ $strings.LabelStart }}</div>
<div class="w-24 text-xs font-semibold uppercase text-gray-200">{{ $strings.LabelEnd }}</div>
</div>
<div class="w-full max-h-72 overflow-auto">
<p v-if="!metadataChapters.length" class="py-5 text-center text-gray-200">{{ $strings.MessageNoChapters }}</p>
<template v-for="(chapter, index) in metadataChapters">
<div :key="index" class="flex py-1 px-4 text-sm" :class="index % 2 === 1 ? 'bg-primary bg-opacity-25' : ''">
<div class="flex-grow font-semibold">{{ chapter.title }}</div>
<div :key="index" class="flex py-1 px-4 text-sm" :class="index % 2 === 1 ? 'bg-primary/25' : ''">
<div class="grow font-semibold">{{ chapter.title }}</div>
<div class="w-24">
{{ $secondsToTimestamp(chapter.start) }}
</div>
@ -58,7 +58,7 @@
</div>
</div>
<div class="w-full h-px bg-white bg-opacity-10 my-8" />
<div class="w-full h-px bg-white/10 my-8" />
<div class="w-full max-w-4xl mx-auto">
<!-- queued alert -->
@ -69,9 +69,9 @@
<div v-else-if="isEmbedTool" class="w-full flex justify-end items-center mb-4">
<ui-checkbox v-if="!isTaskFinished" v-model="shouldBackupAudioFiles" :disabled="processing" :label="$strings.LabelBackupAudioFiles" medium checkbox-bg="bg" label-class="pl-2 text-base md:text-lg" @input="toggleBackupAudioFiles" />
<div class="flex-grow" />
<div class="grow" />
<ui-btn v-if="!isTaskFinished" color="primary" :loading="processing" :progress="progress" @click.stop="embedClick">{{ $strings.ButtonStartMetadataEmbed }}</ui-btn>
<ui-btn v-if="!isTaskFinished" color="bg-primary" :loading="processing" :progress="progress" @click.stop="embedClick">{{ $strings.ButtonStartMetadataEmbed }}</ui-btn>
<p v-else-if="taskFailed" class="text-error text-lg font-semibold">{{ $strings.MessageEmbedFailed }} {{ taskError }}</p>
<p v-else class="text-success text-lg font-semibold">{{ $strings.MessageEmbedFinished }}</p>
</div>
@ -81,10 +81,10 @@
<span class="material-symbols text-xl">{{ showEncodeOptions || usingCustomEncodeOptions ? 'check_box' : 'check_box_outline_blank' }}</span> <span class="pl-1">{{ $strings.LabelUseAdvancedOptions }}</span>
</button>
<div class="flex-grow" />
<div class="grow" />
<ui-btn v-if="!isTaskFinished && processing" color="error" :loading="isCancelingEncode" class="mr-2" @click.stop="cancelEncodeClick">{{ $strings.ButtonCancelEncode }}</ui-btn>
<ui-btn v-if="!isTaskFinished" color="primary" :loading="processing" :progress="progress" @click.stop="encodeM4bClick">{{ $strings.ButtonStartM4BEncode }}</ui-btn>
<ui-btn v-if="!isTaskFinished && processing" color="bg-error" :loading="isCancelingEncode" class="mr-2" @click.stop="cancelEncodeClick">{{ $strings.ButtonCancelEncode }}</ui-btn>
<ui-btn v-if="!isTaskFinished" color="bg-primary" :loading="processing" :progress="progress" @click.stop="encodeM4bClick">{{ $strings.ButtonStartM4BEncode }}</ui-btn>
<p v-else-if="taskFailed" class="text-error text-lg font-semibold">{{ $strings.MessageM4BFailed }} {{ taskError }}</p>
<p v-else class="text-success text-lg font-semibold">{{ $strings.MessageM4BFinished }}</p>
</div>
@ -142,17 +142,17 @@
<div class="w-full max-w-4xl mx-auto">
<p class="mb-2 font-semibold">{{ $strings.HeaderAudioTracks }}</p>
<div class="w-full mx-auto border border-white border-opacity-10 bg-bg">
<div class="flex py-2 px-4 bg-primary bg-opacity-25">
<div class="w-full mx-auto border border-white/10 bg-bg">
<div class="flex py-2 px-4 bg-primary/25">
<div class="w-10 text-xs font-semibold text-gray-200">#</div>
<div class="flex-grow text-xs font-semibold uppercase text-gray-200">{{ $strings.LabelFilename }}</div>
<div class="grow text-xs font-semibold uppercase text-gray-200">{{ $strings.LabelFilename }}</div>
<div class="w-16 text-xs font-semibold uppercase text-gray-200">{{ $strings.LabelSize }}</div>
<div class="w-24"></div>
</div>
<template v-for="file in audioFiles">
<div :key="file.index" class="flex py-2 px-4 text-sm" :class="file.index % 2 === 0 ? 'bg-primary bg-opacity-25' : ''">
<div :key="file.index" class="flex py-2 px-4 text-sm" :class="file.index % 2 === 0 ? 'bg-primary/25' : ''">
<div class="w-10">{{ file.index }}</div>
<div class="flex-grow">
<div class="grow">
{{ file.metadata.filename }}
</div>
<div class="w-16 font-mono text-gray-200">