Merge branch 'main' into ™

This commit is contained in:
HexagonCDN 2023-01-14 10:23:22 +00:00
commit 9d7033d728
14 changed files with 185 additions and 58 deletions

1
.gitignore vendored
View file

@ -6,6 +6,7 @@ yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
log.txt
node_modules
.DS_Store

View file

@ -1,4 +1,4 @@
FROM --platform=$BUILDPLATFORM node:lts AS build
FROM --platform=$BUILDPLATFORM node:lts-alpine AS build
WORKDIR /app/
@ -9,7 +9,7 @@ RUN --mount=type=cache,target=/root/.cache/node \
npm install --prefer-offline && \
npm run build
FROM --platform=$BUILDPLATFORM nginx:stable
FROM --platform=$BUILDPLATFORM nginx:stable-alpine
COPY --from=build /app/dist/ /usr/share/nginx/html/
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf

View file

@ -1,3 +1,3 @@
{
"date": "2022-12-31"
"date": "2023-01-13"
}

View file

@ -36,8 +36,11 @@ const list = ref([]),
show = reactive({
new: false,
sync: false,
import: false,
}),
text = ref(''),
isImport = ref(false),
importFile = ref(''),
sync = reactive({
type: 'send',
id: 'Please Wait...',
@ -82,6 +85,59 @@ const Open = key => {
});
}
},
Import = async (data = importFile.value) => {
if (data?.type == 'application/json')
data = await data.text().then(txt => JSON.parse(txt).local);
if (!data) {
alert('No data to import');
return;
}
List();
for (let i of data) {
const pl = list.value.filter(p => p.name == i.name)[0];
if (pl) {
for (let u of i.urls) {
if (!pl.urls.filter(r => r.url === u.url)[0]) {
useUpdatePlaylist(i.name, u, () => {
console.log('Added: ' + u.name);
});
}
}
} else {
useCreatePlaylist(i.name, i.urls);
}
List();
}
show.import = false;
},
Export = () => {
List();
const base = JSON.stringify(
{
format: 'Hyperpipe',
version: 0,
local: list.value,
playlists: [], // TODO?
},
null,
2,
),
file = new Blob([base], { type: 'application/json' }),
ele = document.createElement('a');
ele.href = URL.createObjectURL(file);
ele.download = 'hyperpipe.json';
ele.click();
ele.remove();
},
Send = () => {
const conn = sync.peer.connect(sync.to);
@ -183,30 +239,10 @@ watch(
if (sync.type == 'rec') {
console.log(data);
List();
Import(data);
for (let i of data) {
const pl = list.value.filter(p => p.name == i.name)[0];
if (pl) {
for (let u of i.urls) {
if (!pl.urls.filter(r => r.url === u.url)[0]) {
useUpdatePlaylist(i.name, u, () => {
console.log('Added: ' + u.name);
});
}
}
} else {
useCreatePlaylist(i.name, i.urls);
}
List();
if (data.indexOf(i) == data.length - 1) {
show.sync = false;
}
}
}
});
});
} else if (sync.peer) {
@ -300,6 +336,43 @@ onMounted(async () => {
</template>
</Modal>
<Modal
n="2"
:display="show.import"
:title="t('action.import')"
@show="
e => {
show.import = e;
}
">
<template #content>
<div class="tabs">
<button :data-active="isImport" @click="isImport = true">
{{ t('action.import') }}
</button>
<button :data-active="!isImport" @click="isImport = false">
{{ t('action.export') }}
</button>
</div>
<div v-if="isImport">
<input
type="file"
class="textbox"
name="import"
accept="application/json"
@change="importFile = $event.target.files[0]" />
</div>
</template>
<template #buttons>
<button @click="show.import = false">{{ t('action.cancel') }}</button>
<button @click="isImport ? Import() : Export()">
{{ isImport ? t('action.import') : t('action.export') }}
</button>
</template>
</Modal>
<div class="grid">
<div class="npl-box bi bi-plus-lg pop" @click="show.new = true"></div>
@ -308,6 +381,8 @@ onMounted(async () => {
@click="show.sync = true"></div>
<div class="npl-box bi bi-tag pop" @click="getFeeds"></div>
<div class="npl-box bi bi-arrow-up pop" @click="show.import = true"></div>
</div>
<h2 v-if="list.length > 0">{{ t('playlist.local') }}</h2>
@ -329,6 +404,7 @@ onMounted(async () => {
v-for="i in user.playlists"
:key="i.id"
:name="i.name.replace('Playlist - ', '')"
:author="t('title.songs') + ' • ' + i.videos"
:art="pathname(i.thumbnail) != '/' ? i.thumbnail : undefined"
@open-album="$emit('open-playlist', '/playlists?list=' + i.id)" />
</div>
@ -419,6 +495,20 @@ button.logout {
display: block;
background: linear-gradient(135deg, indianred, #bf616a);
}
input[type='file'] {
display: block;
}
input[type='file']::file-selector-button {
font-weight: bold;
appearance: inherit;
outline: inherit;
border: inherit;
border-radius: 0.25rem;
padding: 0.5rem;
margin: 0.1rem 0.5rem 0.1rem 0.1rem;
color: var(--color-background);
background: linear-gradient(135deg, cornflowerblue, #88c0d0);
}
.tabs button:first-child {
border-radius: 0.25rem 0 0 0.25rem;
}

View file

@ -119,10 +119,10 @@ onMounted(() => {
class="input"
:value="getStore('page') || 'home'"
@change="setStore('page', $event.target.value)">
<option value="home">Home</option>
<option value="explore">Explore</option>
<option value="charts">Charts</option>
<option value="library">Library</option>
<option value="home">{{ t('pref.home') }}</option>
<option value="explore">{{ t('pref.explore') }}</option>
<option value="charts">{{ t('pref.charts') }}</option>
<option value="library">{{ t('pref.library') }}</option>
</select>
<h2>{{ t('pref.player') }}</h2>

View file

@ -134,7 +134,8 @@ async function Like() {
plRemote = true;
"
:data-active="pl == i.id && plRemote == true">
<span>{{ i.name }}</span>
<span>{{ i.name }}</span
><span class="ml-auto">{{ i.videos }}</span>
</div>
</template>
<template #buttons>
@ -424,11 +425,6 @@ input[type='range']::-webkit-slider-thumb {
background-color: var(--color-foreground);
-webkit-appearance: none;
appearance: none;
opacity: 0;
transition: opacity 0.4s ease;
}
input[type='range']:hover::-webkit-slider-thumb,
#vol input[type='range']::-webkit-slider-thumb {
opacity: 1;
height: 1rem;
width: 1rem;
@ -447,13 +443,8 @@ input[type='range']::-webkit-slider-runnable-track {
input[type='range']::-moz-range-thumb {
-moz-appearance: none;
appearance: none;
opacity: 0;
border: none;
outline: none;
transition: opacity 0.4s ease;
}
input[type='range']:hover::-moz-range-thumb,
#vol input[type='range']::-moz-range-thumb {
background-color: var(--color-foreground);
opacity: 1;
height: 1rem;

View file

@ -33,7 +33,11 @@
"blur": "Rozmazání",
"blur_light": "Rozmazaný (světlý)",
"dracula": "Drákula",
"nord": "Nord"
"nord": "Nord",
"explore": "Procházet",
"charts": "Žebříčky",
"home": "Domů",
"library": "Knihovna"
},
"instances": {
"name": "Název",
@ -55,7 +59,9 @@
"add": "Přidat",
"cancel": "Zrušit",
"send": "Poslat",
"receive": "Obdržet"
"receive": "Obdržet",
"import": "Importovat",
"export": "Exportovat"
},
"playlist": {
"local": "Místní playlisty",

View file

@ -3,8 +3,8 @@
"moods": "Stimmungen",
"songs": "Lieder",
"albums": "Alben",
"genres": "Genres",
"singles": "Singles",
"genres": "Kategorien",
"singles": "Einzeltitel",
"artists": "Künstler/innen",
"similar_artists": "Ähnliche Künstler/innen",
"featured": "Ausgewählt",
@ -23,7 +23,9 @@
"create": "Erstellen",
"add": "Hinzufügen",
"cancel": "Abbrechen",
"receive": "Empfangen"
"receive": "Empfangen",
"import": "Importieren",
"export": "Exportieren"
},
"playlist": {
"local": "Lokale Wiedergabelisten",
@ -49,8 +51,12 @@
"light": "Hell",
"blur": "Unschärfe",
"blur_light": "Unschärfe (hell)",
"dracula": "Dracula",
"nord": "Nord"
"dracula": "Drakula",
"nord": "Nord",
"library": "Bibliothek",
"charts": "Diagramme",
"explore": "Erkunden",
"home": "Startseite"
},
"info": {
"no_info": "Keine Informationen verfügbar",

View file

@ -23,7 +23,9 @@
"create": "Create",
"cancel": "Cancel",
"send": "Send",
"receive": "Receive"
"receive": "Receive",
"import": "Import",
"export": "Export"
},
"playlist": {
"local": "Local Playlists",
@ -50,7 +52,11 @@
"auto": "auto",
"best": "best",
"worst": "worst",
"volume": "Default Volume"
"volume": "Default Volume",
"home": "Home",
"explore": "Explore",
"charts": "Charts",
"library": "Library"
},
"info": {
"see_all": "See All",

View file

@ -23,7 +23,9 @@
"create": "Crear",
"send": "Enviar",
"receive": "Recibir",
"cancel": "Cancelar"
"cancel": "Cancelar",
"import": "Importar",
"export": "Exportar"
},
"playlist": {
"local": "Listas de reproducción locales",
@ -50,7 +52,11 @@
"light": "Claro",
"blur_light": "Desenfoque (Luz)",
"dracula": "Drácula",
"nord": "Nord"
"nord": "Nord",
"home": "Inicio",
"library": "Biblioteca",
"charts": "Gráfica",
"explore": "Explorar"
},
"info": {
"see_all": "Ver todo",

View file

@ -42,7 +42,11 @@
"blur": "Flou",
"blur_light": "Flou (clair)",
"dracula": "Dracula",
"nord": "Nord"
"nord": "Nord",
"charts": "Graphiques",
"explore": "Explorer",
"home": "Accueil",
"library": "Bibliothèque"
},
"info": {
"see_all": "Voir tout",
@ -55,7 +59,9 @@
"add": "Ajouter",
"create": "Créer",
"cancel": "Annuler",
"receive": "Recevoir"
"receive": "Recevoir",
"import": "Importer",
"export": "Exporter"
},
"instances": {
"up_to_date": "À jour",

View file

@ -15,7 +15,11 @@
"blur": "Sfocatura",
"blur_light": "Sfocatura (chiaro)",
"dracula": "Dracula",
"nord": "Nord"
"nord": "Nord",
"library": "Raccolta",
"home": "Pagina principale",
"charts": "Grafici",
"explore": "Esplora"
},
"title": {
"albums": "Album",
@ -40,7 +44,9 @@
"back": "Indietro",
"create": "Crea",
"send": "Invia",
"cancel": "Annulla"
"cancel": "Annulla",
"import": "Importa",
"export": "Esporta"
},
"info": {
"see_all": "Vedi tutto",

View file

@ -23,7 +23,9 @@
"create": "Oluştur",
"cancel": "İptal",
"receive": "Al",
"send": "Gönder"
"send": "Gönder",
"export": "Dışa aktar",
"import": "İçe aktar"
},
"playlist": {
"local": "Yerel Oynatma Listeleri",
@ -50,7 +52,11 @@
"blur": "Bulanıklaştır",
"blur_light": "Bulanıklaştır (Açık)",
"dracula": "Dracula",
"nord": "Nord"
"nord": "Nord",
"charts": "Grafikler",
"library": "Kütüphane",
"explore": "Keşfet",
"home": "Ana sayfa"
},
"info": {
"see_all": "Hepsini Gör",

View file

@ -30,7 +30,10 @@
"nord": "Nord",
"dracula": "Dracula",
"auto_queue": "Tự động xếp hàng các bài hát",
"tab": "Thẻ mặc định"
"tab": "Thẻ mặc định",
"library": "Thư viện",
"explore": "Khám phá",
"home": "Trang chủ"
},
"action": {
"cancel": "Hủy",