feat: track, album, playlist template variables

This commit is contained in:
Roberto Tonino 2021-01-31 22:30:06 +01:00
parent b59fbcf533
commit 337ca3c04e
8 changed files with 293 additions and 148 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
<template functional> <template functional>
<details :class="[data.staticClass, { 'with-arrow': props.withArrow }]"> <details :class="[data.staticClass, { 'with-arrow': props.withArrow }]" :style="data.staticStyle">
<summary class="cursor-pointer"> <summary class="cursor-pointer">
<slot name="title">Setting</slot> <slot name="title">Setting</slot>
</summary> </summary>
@ -17,7 +17,7 @@ details > summary::-webkit-details-marker {
details.with-arrow > summary::-webkit-details-marker { details.with-arrow > summary::-webkit-details-marker {
display: initial; display: initial;
vertical-align: super; vertical-align: var(--arrow-v-align, super);
} }
</style> </style>

View File

@ -2,13 +2,13 @@
<div class="fixed-footer"> <div class="fixed-footer">
<h1 class="mb-8 text-5xl">{{ $t('settings.title') }}</h1> <h1 class="mb-8 text-5xl">{{ $t('settings.title') }}</h1>
<div id="logged_in_info" v-if="isLoggedIn" ref="loggedInInfo"> <div v-if="isLoggedIn" id="logged_in_info" ref="loggedInInfo">
<img <img
id="settings_picture" id="settings_picture"
class="w-32 h-32 rounded-full" ref="userpicture"
:src="pictureHref" :src="pictureHref"
alt="Profile Picture" alt="Profile Picture"
ref="userpicture" class="w-32 h-32 rounded-full"
/> />
<i18n path="settings.login.loggedIn" tag="p"> <i18n path="settings.login.loggedIn" tag="p">
@ -34,12 +34,12 @@
<div class="my-5 space-y-5"> <div class="my-5 space-y-5">
<div class="flex items-center"> <div class="flex items-center">
<input <input
autocomplete="off"
type="password"
:value="arl"
id="login_input_arl" id="login_input_arl"
ref="loginInput" ref="loginInput"
:value="arl"
autocomplete="off"
placeholder="ARL" placeholder="ARL"
type="password"
/> />
<button class="ml-2 btn btn-primary btn-only-icon" @click="copyARLtoClipboard"> <button class="ml-2 btn btn-primary btn-only-icon" @click="copyARLtoClipboard">
<i class="material-icons">assignment</i> <i class="material-icons">assignment</i>
@ -50,11 +50,11 @@
{{ $t('settings.login.arl.question') }} {{ $t('settings.login.arl.question') }}
</RouterLink> </RouterLink>
<a v-if="clientMode" href="#" class="block" @click="appLogin"> <a v-if="clientMode" class="block" href="#" @click="appLogin">
{{ $t('settings.login.login') }} {{ $t('settings.login.login') }}
</a> </a>
<button class="btn btn-primary" @click="login" style="width: 100%"> <button class="btn btn-primary" style="width: 100%" @click="login">
{{ $t('settings.login.arl.update') }} {{ $t('settings.login.arl.update') }}
</button> </button>
</div> </div>
@ -67,11 +67,11 @@
<li <li
v-for="locale in locales" v-for="locale in locales"
:key="locale" :key="locale"
class="inline-flex items-center locale-flag"
:class="{ 'locale-flag--current': currentLocale === locale }" :class="{ 'locale-flag--current': currentLocale === locale }"
:title="locale"
class="inline-flex items-center locale-flag"
@click="changeLocale(locale)" @click="changeLocale(locale)"
v-html="flags[locale]" v-html="flags[locale]"
:title="locale"
/> />
</ul> </ul>
</div> </div>
@ -85,11 +85,11 @@
</template> </template>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="modelSlimDownloads" /> <input v-model="modelSlimDownloads" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.appearance.slimDownloadTab') }}</span> <span class="checkbox-text">{{ $t('settings.appearance.slimDownloadTab') }}</span>
</label> </label>
<label class="mb-4 with-checkbox"> <label class="mb-4 with-checkbox">
<input type="checkbox" v-model="modelSlimSidebar" /> <input v-model="modelSlimSidebar" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.appearance.slimSidebar') }}</span> <span class="checkbox-text">{{ $t('settings.appearance.slimSidebar') }}</span>
</label> </label>
</BaseAccordion> </BaseAccordion>
@ -102,7 +102,7 @@
</template> </template>
<div class="flex items-center"> <div class="flex items-center">
<input autocomplete="off" type="text" v-model="settings.downloadLocation" /> <input v-model="settings.downloadLocation" autocomplete="off" type="text" />
<button v-if="clientMode" class="ml-2 btn btn-primary btn-only-icon" @click="selectDownloadFolder"> <button v-if="clientMode" class="ml-2 btn btn-primary btn-only-icon" @click="selectDownloadFolder">
<i class="material-icons">folder</i> <i class="material-icons">folder</i>
</button> </button>
@ -117,13 +117,29 @@
</template> </template>
<p>{{ $t('settings.templates.tracknameTemplate') }}</p> <p>{{ $t('settings.templates.tracknameTemplate') }}</p>
<input type="text" v-model="settings.tracknameTemplate" /> <input v-model="settings.tracknameTemplate" type="text" />
<TemplateVariablesList :template-variables="trackTemplateVariables" @variable-click="onTemplateVariableClick">
<template #title>
{{ $t('settings.templates.tracknameAvailableVariables') }}
</template>
</TemplateVariablesList>
<p>{{ $t('settings.templates.albumTracknameTemplate') }}</p> <p>{{ $t('settings.templates.albumTracknameTemplate') }}</p>
<input type="text" v-model="settings.albumTracknameTemplate" /> <input v-model="settings.albumTracknameTemplate" type="text" />
<TemplateVariablesList :template-variables="trackTemplateVariables" @variable-click="onTemplateVariableClick">
<template #title>
{{ $t('settings.templates.albumTracknameAvailableVariables') }}
</template>
</TemplateVariablesList>
<p>{{ $t('settings.templates.playlistTracknameTemplate') }}</p> <p>{{ $t('settings.templates.playlistTracknameTemplate') }}</p>
<input type="text" v-model="settings.playlistTracknameTemplate" /> <input v-model="settings.playlistTracknameTemplate" type="text" />
<TemplateVariablesList :template-variables="trackTemplateVariables" @variable-click="onTemplateVariableClick">
<template #title>
{{ $t('settings.templates.playlistTracknameAvailableVariables') }}
</template>
</TemplateVariablesList>
</BaseAccordion> </BaseAccordion>
<BaseAccordion class="settings-group"> <BaseAccordion class="settings-group">
@ -136,50 +152,50 @@
<div class="space-x-5 settings-container"> <div class="space-x-5 settings-container">
<div class="settings-container__third"> <div class="settings-container__third">
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.createPlaylistFolder" /> <input v-model="settings.createPlaylistFolder" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.folders.createPlaylistFolder') }}</span> <span class="checkbox-text">{{ $t('settings.folders.createPlaylistFolder') }}</span>
</label> </label>
<div class="input-group" v-if="settings.createPlaylistFolder"> <div v-if="settings.createPlaylistFolder" class="input-group">
<p class="input-group-text">{{ $t('settings.folders.playlistNameTemplate') }}</p> <p class="input-group-text">{{ $t('settings.folders.playlistNameTemplate') }}</p>
<input type="text" v-model="settings.playlistNameTemplate" /> <input v-model="settings.playlistNameTemplate" type="text" />
</div> </div>
</div> </div>
<div class="settings-container__third"> <div class="settings-container__third">
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.createArtistFolder" /> <input v-model="settings.createArtistFolder" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.folders.createArtistFolder') }}</span> <span class="checkbox-text">{{ $t('settings.folders.createArtistFolder') }}</span>
</label> </label>
<div class="input-group" v-if="settings.createArtistFolder"> <div v-if="settings.createArtistFolder" class="input-group">
<p class="input-group-text">{{ $t('settings.folders.artistNameTemplate') }}</p> <p class="input-group-text">{{ $t('settings.folders.artistNameTemplate') }}</p>
<input type="text" v-model="settings.artistNameTemplate" /> <input v-model="settings.artistNameTemplate" type="text" />
</div> </div>
</div> </div>
<div class="settings-container__third"> <div class="settings-container__third">
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.createAlbumFolder" /> <input v-model="settings.createAlbumFolder" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.folders.createAlbumFolder') }}</span> <span class="checkbox-text">{{ $t('settings.folders.createAlbumFolder') }}</span>
</label> </label>
<div class="input-group" v-if="settings.createAlbumFolder"> <div v-if="settings.createAlbumFolder" class="input-group">
<p class="input-group-text">{{ $t('settings.folders.albumNameTemplate') }}</p> <p class="input-group-text">{{ $t('settings.folders.albumNameTemplate') }}</p>
<input type="text" v-model="settings.albumNameTemplate" /> <input v-model="settings.albumNameTemplate" type="text" />
</div> </div>
</div> </div>
</div> </div>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.createCDFolder" /> <input v-model="settings.createCDFolder" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.folders.createCDFolder') }}</span> <span class="checkbox-text">{{ $t('settings.folders.createCDFolder') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.createStructurePlaylist" /> <input v-model="settings.createStructurePlaylist" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.folders.createStructurePlaylist') }}</span> <span class="checkbox-text">{{ $t('settings.folders.createStructurePlaylist') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.createSingleFolder" /> <input v-model="settings.createSingleFolder" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.folders.createSingleFolder') }}</span> <span class="checkbox-text">{{ $t('settings.folders.createSingleFolder') }}</span>
</label> </label>
</BaseAccordion> </BaseAccordion>
@ -194,20 +210,20 @@
<div class="space-x-5 settings-container"> <div class="space-x-5 settings-container">
<div class="settings-container__third settings-container__third--only-checkbox"> <div class="settings-container__third settings-container__third--only-checkbox">
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.padTracks" /> <input v-model="settings.padTracks" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.trackTitles.padTracks') }}</span> <span class="checkbox-text">{{ $t('settings.trackTitles.padTracks') }}</span>
</label> </label>
</div> </div>
<div class="settings-container__third"> <div class="settings-container__third">
<div class="input-group"> <div class="input-group">
<p class="input-group-text">{{ $t('settings.trackTitles.paddingSize') }}</p> <p class="input-group-text">{{ $t('settings.trackTitles.paddingSize') }}</p>
<input max="10" type="number" v-model="settings.paddingSize" /> <input v-model="settings.paddingSize" max="10" type="number" />
</div> </div>
</div> </div>
<div class="settings-container__third"> <div class="settings-container__third">
<div class="input-group"> <div class="input-group">
<p class="input-group-text">{{ $t('settings.trackTitles.illegalCharacterReplacer') }}</p> <p class="input-group-text">{{ $t('settings.trackTitles.illegalCharacterReplacer') }}</p>
<input type="text" v-model="settings.illegalCharacterReplacer" /> <input v-model="settings.illegalCharacterReplacer" type="text" />
</div> </div>
</div> </div>
</div> </div>
@ -219,28 +235,28 @@
</template> </template>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.saveArtwork" /> <input v-model="settings.saveArtwork" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.covers.saveArtwork') }}</span> <span class="checkbox-text">{{ $t('settings.covers.saveArtwork') }}</span>
</label> </label>
<div class="input-group" v-if="settings.saveArtwork"> <div v-if="settings.saveArtwork" class="input-group">
<p class="input-group-text">{{ $t('settings.covers.coverImageTemplate') }}</p> <p class="input-group-text">{{ $t('settings.covers.coverImageTemplate') }}</p>
<input type="text" v-model="settings.coverImageTemplate" /> <input v-model="settings.coverImageTemplate" type="text" />
</div> </div>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.saveArtworkArtist" /> <input v-model="settings.saveArtworkArtist" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.covers.saveArtworkArtist') }}</span> <span class="checkbox-text">{{ $t('settings.covers.saveArtworkArtist') }}</span>
</label> </label>
<div class="input-group" v-if="settings.saveArtworkArtist"> <div v-if="settings.saveArtworkArtist" class="input-group">
<p class="input-group-text">{{ $t('settings.covers.artistImageTemplate') }}</p> <p class="input-group-text">{{ $t('settings.covers.artistImageTemplate') }}</p>
<input type="text" v-model="settings.artistImageTemplate" /> <input v-model="settings.artistImageTemplate" type="text" />
</div> </div>
<div class="input-group"> <div class="input-group">
<p class="input-group-text">{{ $t('settings.covers.localArtworkSize') }}</p> <p class="input-group-text">{{ $t('settings.covers.localArtworkSize') }}</p>
<input type="number" min="100" max="10000" step="100" v-model.number="settings.localArtworkSize" /> <input v-model.number="settings.localArtworkSize" max="10000" min="100" step="100" type="number" />
<p v-if="settings.localArtworkSize > 1200" class="input-group-text" style="opacity: 0.75; color: #ffcc22"> <p v-if="settings.localArtworkSize > 1200" class="input-group-text" style="opacity: 0.75; color: #ffcc22">
{{ $t('settings.covers.imageSizeWarning') }} {{ $t('settings.covers.imageSizeWarning') }}
</p> </p>
@ -248,7 +264,7 @@
<div class="input-group"> <div class="input-group">
<p class="input-group-text">{{ $t('settings.covers.embeddedArtworkSize') }}</p> <p class="input-group-text">{{ $t('settings.covers.embeddedArtworkSize') }}</p>
<input type="number" min="100" max="10000" step="100" v-model.number="settings.embeddedArtworkSize" /> <input v-model.number="settings.embeddedArtworkSize" max="10000" min="100" step="100" type="number" />
<p v-if="settings.embeddedArtworkSize > 1200" class="input-group-text" style="opacity: 0.75; color: #ffcc22"> <p v-if="settings.embeddedArtworkSize > 1200" class="input-group-text" style="opacity: 0.75; color: #ffcc22">
{{ $t('settings.covers.imageSizeWarning') }} {{ $t('settings.covers.imageSizeWarning') }}
</p> </p>
@ -264,7 +280,7 @@
</div> </div>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.embeddedArtworkPNG" /> <input v-model="settings.embeddedArtworkPNG" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.covers.embeddedArtworkPNG') }}</span> <span class="checkbox-text">{{ $t('settings.covers.embeddedArtworkPNG') }}</span>
</label> </label>
<p v-if="settings.embeddedArtworkPNG" style="opacity: 0.75; color: #ffcc22"> <p v-if="settings.embeddedArtworkPNG" style="opacity: 0.75; color: #ffcc22">
@ -272,13 +288,13 @@
</p> </p>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.coverDescriptionUTF8" /> <input v-model="settings.tags.coverDescriptionUTF8" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.covers.coverDescriptionUTF8') }}</span> <span class="checkbox-text">{{ $t('settings.covers.coverDescriptionUTF8') }}</span>
</label> </label>
<div class="input-group"> <div class="input-group">
<p class="input-group-text">{{ $t('settings.covers.jpegImageQuality') }}</p> <p class="input-group-text">{{ $t('settings.covers.jpegImageQuality') }}</p>
<input type="number" min="1" max="100" v-model.number="settings.jpegImageQuality" /> <input v-model.number="settings.jpegImageQuality" max="100" min="1" type="number" />
</div> </div>
</BaseAccordion> </BaseAccordion>
@ -292,106 +308,106 @@
<div class="space-x-5 settings-container"> <div class="space-x-5 settings-container">
<div class="settings-container__half"> <div class="settings-container__half">
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.title" /> <input v-model="settings.tags.title" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.title') }}</span> <span class="checkbox-text">{{ $t('settings.tags.title') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.artist" /> <input v-model="settings.tags.artist" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.artist') }}</span> <span class="checkbox-text">{{ $t('settings.tags.artist') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.album" /> <input v-model="settings.tags.album" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.album') }}</span> <span class="checkbox-text">{{ $t('settings.tags.album') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.cover" /> <input v-model="settings.tags.cover" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.cover') }}</span> <span class="checkbox-text">{{ $t('settings.tags.cover') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.trackNumber" /> <input v-model="settings.tags.trackNumber" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.trackNumber') }}</span> <span class="checkbox-text">{{ $t('settings.tags.trackNumber') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.trackTotal" /> <input v-model="settings.tags.trackTotal" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.trackTotal') }}</span> <span class="checkbox-text">{{ $t('settings.tags.trackTotal') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.discNumber" /> <input v-model="settings.tags.discNumber" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.discNumber') }}</span> <span class="checkbox-text">{{ $t('settings.tags.discNumber') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.discTotal" /> <input v-model="settings.tags.discTotal" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.discTotal') }}</span> <span class="checkbox-text">{{ $t('settings.tags.discTotal') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.albumArtist" /> <input v-model="settings.tags.albumArtist" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.albumArtist') }}</span> <span class="checkbox-text">{{ $t('settings.tags.albumArtist') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.genre" /> <input v-model="settings.tags.genre" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.genre') }}</span> <span class="checkbox-text">{{ $t('settings.tags.genre') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.year" /> <input v-model="settings.tags.year" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.year') }}</span> <span class="checkbox-text">{{ $t('settings.tags.year') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.date" /> <input v-model="settings.tags.date" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.date') }}</span> <span class="checkbox-text">{{ $t('settings.tags.date') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.explicit" /> <input v-model="settings.tags.explicit" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.explicit') }}</span> <span class="checkbox-text">{{ $t('settings.tags.explicit') }}</span>
</label> </label>
</div> </div>
<div class="settings-container__half"> <div class="settings-container__half">
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.isrc" /> <input v-model="settings.tags.isrc" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.isrc') }}</span> <span class="checkbox-text">{{ $t('settings.tags.isrc') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.length" /> <input v-model="settings.tags.length" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.length') }}</span> <span class="checkbox-text">{{ $t('settings.tags.length') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.barcode" /> <input v-model="settings.tags.barcode" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.barcode') }}</span> <span class="checkbox-text">{{ $t('settings.tags.barcode') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.bpm" /> <input v-model="settings.tags.bpm" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.bpm') }}</span> <span class="checkbox-text">{{ $t('settings.tags.bpm') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.replayGain" /> <input v-model="settings.tags.replayGain" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.replayGain') }}</span> <span class="checkbox-text">{{ $t('settings.tags.replayGain') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.label" /> <input v-model="settings.tags.label" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.label') }}</span> <span class="checkbox-text">{{ $t('settings.tags.label') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.lyrics" /> <input v-model="settings.tags.lyrics" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.lyrics') }}</span> <span class="checkbox-text">{{ $t('settings.tags.lyrics') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.syncedLyrics" /> <input v-model="settings.tags.syncedLyrics" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.syncedLyrics') }}</span> <span class="checkbox-text">{{ $t('settings.tags.syncedLyrics') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.copyright" /> <input v-model="settings.tags.copyright" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.copyright') }}</span> <span class="checkbox-text">{{ $t('settings.tags.copyright') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.composer" /> <input v-model="settings.tags.composer" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.composer') }}</span> <span class="checkbox-text">{{ $t('settings.tags.composer') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.involvedPeople" /> <input v-model="settings.tags.involvedPeople" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.involvedPeople') }}</span> <span class="checkbox-text">{{ $t('settings.tags.involvedPeople') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.source" /> <input v-model="settings.tags.source" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.tags.source') }}</span> <span class="checkbox-text">{{ $t('settings.tags.source') }}</span>
</label> </label>
</div> </div>
@ -407,7 +423,7 @@
<div class="input-group"> <div class="input-group">
<p class="input-group-text">{{ $t('settings.downloads.queueConcurrency') }}</p> <p class="input-group-text">{{ $t('settings.downloads.queueConcurrency') }}</p>
<input type="number" min="1" v-model.number="settings.queueConcurrency" /> <input v-model.number="settings.queueConcurrency" min="1" type="number" />
</div> </div>
<div class="input-group"> <div class="input-group">
@ -433,46 +449,46 @@
<div class="space-x-5 settings-container"> <div class="space-x-5 settings-container">
<div class="settings-container__third settings-container__third--only-checkbox"> <div class="settings-container__third settings-container__third--only-checkbox">
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.fallbackBitrate" /> <input v-model="settings.fallbackBitrate" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.downloads.fallbackBitrate') }}</span> <span class="checkbox-text">{{ $t('settings.downloads.fallbackBitrate') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.fallbackSearch" /> <input v-model="settings.fallbackSearch" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.downloads.fallbackSearch') }}</span> <span class="checkbox-text">{{ $t('settings.downloads.fallbackSearch') }}</span>
</label> </label>
</div> </div>
<div class="settings-container__third settings-container__third--only-checkbox"> <div class="settings-container__third settings-container__third--only-checkbox">
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.logErrors" /> <input v-model="settings.logErrors" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.downloads.logErrors') }}</span> <span class="checkbox-text">{{ $t('settings.downloads.logErrors') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.logSearched" /> <input v-model="settings.logSearched" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.downloads.logSearched') }}</span> <span class="checkbox-text">{{ $t('settings.downloads.logSearched') }}</span>
</label> </label>
</div> </div>
<div class="settings-container__third settings-container__third--only-checkbox"> <div class="settings-container__third settings-container__third--only-checkbox">
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.syncedLyrics" /> <input v-model="settings.syncedLyrics" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.downloads.syncedLyrics') }}</span> <span class="checkbox-text">{{ $t('settings.downloads.syncedLyrics') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.createM3U8File" /> <input v-model="settings.createM3U8File" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.downloads.createM3U8File') }}</span> <span class="checkbox-text">{{ $t('settings.downloads.createM3U8File') }}</span>
</label> </label>
</div> </div>
</div> </div>
<div class="input-group" v-if="settings.createM3U8File"> <div v-if="settings.createM3U8File" class="input-group">
<p class="input-group-text">{{ $t('settings.downloads.playlistFilenameTemplate') }}</p> <p class="input-group-text">{{ $t('settings.downloads.playlistFilenameTemplate') }}</p>
<input type="text" v-model="settings.playlistFilenameTemplate" /> <input v-model="settings.playlistFilenameTemplate" type="text" />
</div> </div>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.saveDownloadQueue" /> <input v-model="settings.saveDownloadQueue" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.downloads.saveDownloadQueue') }}</span> <span class="checkbox-text">{{ $t('settings.downloads.saveDownloadQueue') }}</span>
</label> </label>
</BaseAccordion> </BaseAccordion>
@ -483,17 +499,17 @@
</template> </template>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.savePlaylistAsCompilation" /> <input v-model="settings.tags.savePlaylistAsCompilation" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.other.savePlaylistAsCompilation') }}</span> <span class="checkbox-text">{{ $t('settings.other.savePlaylistAsCompilation') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.useNullSeparator" /> <input v-model="settings.tags.useNullSeparator" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.other.useNullSeparator') }}</span> <span class="checkbox-text">{{ $t('settings.other.useNullSeparator') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.saveID3v1" /> <input v-model="settings.tags.saveID3v1" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.other.saveID3v1') }}</span> <span class="checkbox-text">{{ $t('settings.other.saveID3v1') }}</span>
</label> </label>
@ -514,22 +530,22 @@
</div> </div>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.tags.singleAlbumArtist" /> <input v-model="settings.tags.singleAlbumArtist" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.other.singleAlbumArtist') }}</span> <span class="checkbox-text">{{ $t('settings.other.singleAlbumArtist') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.albumVariousArtists" /> <input v-model="settings.albumVariousArtists" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.other.albumVariousArtists') }}</span> <span class="checkbox-text">{{ $t('settings.other.albumVariousArtists') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.removeAlbumVersion" /> <input v-model="settings.removeAlbumVersion" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.other.removeAlbumVersion') }}</span> <span class="checkbox-text">{{ $t('settings.other.removeAlbumVersion') }}</span>
</label> </label>
<label class="with-checkbox"> <label class="with-checkbox">
<input type="checkbox" v-model="settings.removeDuplicateArtists" /> <input v-model="settings.removeDuplicateArtists" type="checkbox" />
<span class="checkbox-text">{{ $t('settings.other.removeDuplicateArtists') }}</span> <span class="checkbox-text">{{ $t('settings.other.removeDuplicateArtists') }}</span>
</label> </label>
@ -602,14 +618,14 @@
<div class="input-group"> <div class="input-group">
<p class="input-group-text">{{ $t('settings.other.previewVolume') }}</p> <p class="input-group-text">{{ $t('settings.other.previewVolume') }}</p>
<input type="range" min="0" max="100" step="1" class="slider" v-model.number="modelVolume" /> <input v-model.number="modelVolume" class="slider" max="100" min="0" step="1" type="range" />
<span>{{ previewVolume }}%</span> <span>{{ previewVolume }}%</span>
</div> </div>
<div class="input-group"> <div class="input-group">
<p class="input-group-text">{{ $t('settings.other.executeCommand.title') }}</p> <p class="input-group-text">{{ $t('settings.other.executeCommand.title') }}</p>
<p class="secondary-text">{{ $t('settings.other.executeCommand.description') }}</p> <p class="secondary-text">{{ $t('settings.other.executeCommand.description') }}</p>
<input type="text" v-model="settings.executeCommand" /> <input v-model="settings.executeCommand" type="text" />
</div> </div>
</BaseAccordion> </BaseAccordion>
@ -617,9 +633,9 @@
<template #title> <template #title>
<h3 class="settings-group__header"> <h3 class="settings-group__header">
<svg <svg
class="w-6 h-6 mr-4" class="mr-4 w-6 h-6"
style="fill: #1db954"
enable-background="new 0 0 24 24" enable-background="new 0 0 24 24"
style="fill: #1db954"
viewBox="0 0 24 24" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
@ -637,17 +653,17 @@
<div class="input-group"> <div class="input-group">
<p class="input-group-text">{{ $t('settings.spotify.clientID') }}</p> <p class="input-group-text">{{ $t('settings.spotify.clientID') }}</p>
<input type="text" v-model="spotifyFeatures.clientId" /> <input v-model="spotifyFeatures.clientId" type="text" />
</div> </div>
<div class="input-group"> <div class="input-group">
<p class="input-group-text">{{ $t('settings.spotify.clientSecret') }}</p> <p class="input-group-text">{{ $t('settings.spotify.clientSecret') }}</p>
<input type="password" v-model="spotifyFeatures.clientSecret" /> <input v-model="spotifyFeatures.clientSecret" type="password" />
</div> </div>
<div class="input-group"> <div class="input-group">
<p class="input-group-text">{{ $t('settings.spotify.username') }}</p> <p class="input-group-text">{{ $t('settings.spotify.username') }}</p>
<input type="text" v-model="spotifyUser" /> <input v-model="spotifyUser" type="text" />
</div> </div>
</BaseAccordion> </BaseAccordion>
@ -660,17 +676,17 @@
<style lang="scss" scoped> <style lang="scss" scoped>
#logged_in_info { #logged_in_info {
height: 250px;
display: flex; display: flex;
align-items: center;
flex-direction: column; flex-direction: column;
justify-content: space-evenly; justify-content: space-evenly;
align-items: center; height: 250px;
} }
.locale-flag { .locale-flag {
width: 60px;
justify-content: center; justify-content: center;
cursor: pointer; cursor: pointer;
width: 60px;
&:not(:last-child) { &:not(:last-child) {
margin-right: 10px; margin-right: 10px;
@ -718,8 +734,8 @@
&--only-checkbox { &--only-checkbox {
display: flex; display: flex;
flex-direction: column;
align-items: start; align-items: start;
flex-direction: column;
justify-content: center; justify-content: center;
} }
} }
@ -758,16 +774,20 @@ import { mapActions, mapGetters } from 'vuex'
import { debounce } from 'lodash-es' import { debounce } from 'lodash-es'
import { getSettingsData } from '@/data/settings' import { getSettingsData } from '@/data/settings'
import { trackTemplateVariables } from '@/data/file-templates'
import { toast } from '@/utils/toasts' import { toast } from '@/utils/toasts'
import { socket } from '@/utils/socket' import { socket } from '@/utils/socket'
import { flags } from '@/utils/flags' import { flags } from '@/utils/flags'
import { copyToClipboard } from '@/utils/utils'
import BaseAccordion from '@/components/globals/BaseAccordion.vue' import BaseAccordion from '@/components/globals/BaseAccordion.vue'
import TemplateVariablesList from '@components/settings/TemplateVariablesList.vue'
export default { export default {
components: { components: {
BaseAccordion BaseAccordion,
TemplateVariablesList
}, },
data() { data() {
return { return {
@ -784,7 +804,8 @@ export default {
lastUser: '', lastUser: '',
spotifyUser: '', spotifyUser: '',
accountNum: 0, accountNum: 0,
accounts: [] accounts: [],
trackTemplateVariables
} }
}, },
computed: { computed: {
@ -872,6 +893,10 @@ export default {
setSlimDownloads: 'setSlimDownloads', setSlimDownloads: 'setSlimDownloads',
setSlimSidebar: 'setSlimSidebar' setSlimSidebar: 'setSlimSidebar'
}), }),
onTemplateVariableClick(templateName) {
copyToClipboard(templateName)
toast(`Copied ${templateName} to clipboard!`)
},
revertSettings() { revertSettings() {
this.settings = JSON.parse(JSON.stringify(this.lastSettings)) this.settings = JSON.parse(JSON.stringify(this.lastSettings))
}, },
@ -944,7 +969,9 @@ export default {
}, },
accountChanged(user, accountNum) { accountChanged(user, accountNum) {
this.$refs.username.innerText = user.name this.$refs.username.innerText = user.name
this.$refs.userpicture.src = `https://e-cdns-images.dzcdn.net/images/user/${user.picture}/125x125-000000-80-0-0.jpg` this.$refs.userpicture.src = `https://e-cdns-images.dzcdn.net/images/user/${
user.picture
}/125x125-000000-80-0-0.jpg`
this.accountNum = accountNum this.accountNum = accountNum
localStorage.setItem('accountNum', this.accountNum) localStorage.setItem('accountNum', this.accountNum)

View File

@ -0,0 +1,31 @@
<template>
<BaseAccordion style="--arrow-v-align: baseline; margin-bottom: 3rem;">
<template #title>
<slot name="title"></slot>
</template>
<div class="flex flex-wrap p-4 space-x-2 rounded-2xl bg-background-secondary">
<span
v-for="templateVariable in templateVariables"
class="inline-block p-2 mt-2 tracking-wider rounded cursor-pointer bg-panels-bg first:ml-2 hover:shadow-outline"
@click="$emit('variable-click', templateVariable)"
>
{{ templateVariable }}
</span>
</div>
</BaseAccordion>
</template>
<script>
import BaseAccordion from '@components/globals/BaseAccordion.vue'
export default {
components: { BaseAccordion },
props: {
templateVariables: {
type: Array,
required: true
}
}
}
</script>

View File

@ -0,0 +1,62 @@
// TODO: Use JSON
export const trackTemplateVariables = [
'%title%',
'%artist%',
'%artists%',
'%allartists%',
'%mainartists%',
'%featartists%',
'%album%',
'%albumartist%',
'%tracknumber%',
'%tracktotal%',
'%discnumber%',
'%disctotal%',
'%genre%',
'%year%',
'%date%',
'%bpm%',
'%label%',
'%isrc%',
'%upc%',
'%explicit%',
'%track_id%',
'%album_id%',
'%artist_id%',
'%playlist_id%',
'%position%'
]
export const albumFolderTemplateVariables = [
'%album_id%',
'%genre%',
'%album%',
'%artist%',
'%artist_id%',
'%root_artist%',
'%root_artist_id%',
'%tracktotal%',
'%disctotal%',
'%type%',
'%upc%',
'%explicit%',
'%label%',
'%year%',
'%date%',
'%bitrate%'
]
export const artistFolderTemplateVariables = ['%artist%', '%artist_id%', '%root_artist%', '%root_artist_id%']
export const playlistFolderTemplateVariables = [
'%playlist%',
'%playlist_id%',
'%owner%',
'%owner_id%',
'%year%',
'%date%',
'%explicit%'
]
export const playlistFilenameTemplateVariables = ['%title%', '%artist%', '%size%', '%type%', '%id%', '%bitrate%']

View File

@ -229,8 +229,11 @@ const en = {
templates: { templates: {
title: 'Templates', title: 'Templates',
tracknameTemplate: 'Trackname template', tracknameTemplate: 'Trackname template',
tracknameAvailableVariables: 'Available trackname variables',
albumTracknameTemplate: 'Album track template', albumTracknameTemplate: 'Album track template',
playlistTracknameTemplate: 'Playlist track template' albumTracknameAvailableVariables: 'Available album track variables',
playlistTracknameTemplate: 'Playlist track template',
playlistTracknameAvailableVariables: 'Available playlist track variables'
}, },
folders: { folders: {
title: 'Folders', title: 'Folders',

View File

@ -231,8 +231,11 @@ const it = {
templates: { templates: {
title: 'Template', title: 'Template',
tracknameTemplate: 'Template nome brano', tracknameTemplate: 'Template nome brano',
tracknameAvailableVariables: 'Variabili nome brano disponibili',
albumTracknameTemplate: 'Template nome brano negli Album', albumTracknameTemplate: 'Template nome brano negli Album',
playlistTracknameTemplate: 'Template nome brano nelle Playlist' albumTracknameAvailableVariables: 'Variabili nome brano negli Album disponibili',
playlistTracknameTemplate: 'Template nome brano nelle Playlist',
playlistTracknameAvailableVariables: 'Variabili nome brano nelle Playlist disponibili'
}, },
folders: { folders: {
title: 'Cartelle', title: 'Cartelle',

View File

@ -53,40 +53,12 @@ module.exports = {
}, },
variants: { variants: {
textColor: ({ after }) => after(['group-hover']), textColor: ({ after }) => after(['group-hover']),
margin: ({ before }) => before(['first']),
borderWidth: ['responsive', 'first', 'hover', 'focus'], borderWidth: ['responsive', 'first', 'hover', 'focus'],
cursor: ['responsive', 'hover'] cursor: ['responsive', 'hover']
}, },
corePlugins: { corePlugins: {
preflight: false preflight: false
}, },
plugins: [outlinesPlugin()] plugins: []
}
function outlinesPlugin() {
return ({ addUtilities, theme }) => {
// https://github.com/tailwindlabs/discuss/issues/196
let newUtilities = {}
const boxShadowPrefix = '0 0 0 3px'
const colors = theme('colors')
Object.keys(colors).forEach(color => {
const colorData = colors[color]
if (typeof colorData === 'string') {
newUtilities[`.outline-${color}`] = {
boxShadow: `${boxShadowPrefix} ${colorData}`
}
} else {
Object.keys(colorData).forEach(colorVariation => {
newUtilities[`.outline-${color}-${colorVariation}`] = {
boxShadow: `${boxShadowPrefix} ${colorData[colorVariation]}`
}
})
}
})
addUtilities(newUtilities, {
variants: ['focus']
})
}
} }