mirror of
https://codeberg.org/Hyperpipe/Hyperpipe
synced 2025-06-28 21:18:01 +02:00
Merge pull request 'main' (#1) from Hyperpipe/Hyperpipe:main into main
Reviewed-on: https://codeberg.org/HexagonCDN/Hyperpipe/pulls/1
This commit is contained in:
commit
197d16cd00
41 changed files with 1000 additions and 840 deletions
|
@ -1,5 +1,9 @@
|
||||||
.git
|
.git
|
||||||
|
.gitea
|
||||||
.gitignore
|
.gitignore
|
||||||
.dockerignore
|
.dockerignore
|
||||||
|
.prettierignore
|
||||||
|
.prettierrc.json
|
||||||
|
.woodpecker.yml
|
||||||
*.md
|
*.md
|
||||||
*.txt
|
*.txt
|
39
.woodpecker.yml
Normal file
39
.woodpecker.yml
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
pipeline:
|
||||||
|
build:
|
||||||
|
image: node:alpine
|
||||||
|
commands:
|
||||||
|
- npm install
|
||||||
|
- npm run build
|
||||||
|
when:
|
||||||
|
path:
|
||||||
|
exclude: [ '*.md', '.gitea/*' ]
|
||||||
|
event: ['push', 'pull_request']
|
||||||
|
|
||||||
|
docker:
|
||||||
|
image: woodpeckerci/plugin-docker-buildx
|
||||||
|
settings:
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
repo: codeberg.org/hyperpipe/hyperpipe
|
||||||
|
registry: codeberg.org
|
||||||
|
tags: latest
|
||||||
|
username: snematoda
|
||||||
|
password:
|
||||||
|
from_secret: cb_token
|
||||||
|
when:
|
||||||
|
branch: main
|
||||||
|
path:
|
||||||
|
exclude: [ '*.md', '.gitea/*' ]
|
||||||
|
event: ['push']
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
image: node:alpine
|
||||||
|
commands:
|
||||||
|
- npm install surge
|
||||||
|
- cp dist/index.html dist/200.html
|
||||||
|
- npx surge ./dist hyperpipe.surge.sh
|
||||||
|
secrets: [surge_login, surge_token]
|
||||||
|
when:
|
||||||
|
branch: main
|
||||||
|
path:
|
||||||
|
exclude: [ '*.md', '.gitea/*' ]
|
||||||
|
event: ['push']
|
|
@ -1,19 +0,0 @@
|
||||||
pipeline:
|
|
||||||
build:
|
|
||||||
image: node:alpine
|
|
||||||
commands:
|
|
||||||
- npm install
|
|
||||||
- npm run build
|
|
||||||
when:
|
|
||||||
event: [push, pull_request]
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
image: node:alpine
|
|
||||||
commands:
|
|
||||||
- npm install surge
|
|
||||||
- cp dist/index.html dist/200.html
|
|
||||||
- npx surge ./dist hyperpipe.surge.sh
|
|
||||||
secrets: [surge_login, surge_token]
|
|
||||||
when:
|
|
||||||
branch: main
|
|
||||||
event: push
|
|
15
Dockerfile
15
Dockerfile
|
@ -1,20 +1,15 @@
|
||||||
FROM node:alpine AS build
|
FROM --platform=$BUILDPLATFORM node:lts AS build
|
||||||
|
|
||||||
ARG api
|
|
||||||
ARG pipedapi
|
|
||||||
|
|
||||||
WORKDIR /app/
|
WORKDIR /app/
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
RUN sed -i "s/hyperpipeapi.onrender.com/$api/g" index.html src/scripts/fetch.js
|
RUN --mount=type=cache,target=/root/.cache/node \
|
||||||
|
--mount=type=cache,target=/app/node_modules \
|
||||||
RUN sed -i "s/pipedapi.kavin.rocks/$pipedapi/g" index.html src/scripts/fetch.js
|
npm install --prefer-offline && \
|
||||||
|
|
||||||
RUN npm install && \
|
|
||||||
npm run build
|
npm run build
|
||||||
|
|
||||||
FROM nginx:alpine
|
FROM --platform=$BUILDPLATFORM nginx:stable
|
||||||
|
|
||||||
COPY --from=build /app/dist/ /usr/share/nginx/html/
|
COPY --from=build /app/dist/ /usr/share/nginx/html/
|
||||||
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
|
@ -119,7 +119,7 @@ You can reach out to me personally on:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*YouTube Music is a trademark of Google LLC.*
|
*Hyperpipe does not host any content. All content on Hyperpipe is from YouTube Music. YouTube and YouTube Music are trademarks of Google LLC. Hyperpipe is not affiliated with YouTube or YouTube Music.*
|
||||||
|
|
||||||
[hypipe]: https://hyperpipe.surge.sh
|
[hypipe]: https://hyperpipe.surge.sh
|
||||||
[piped]: https://piped.kavin.rocks
|
[piped]: https://piped.kavin.rocks
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
version: '3'
|
|
||||||
|
|
||||||
services:
|
|
||||||
hyperpipe-frontend:
|
|
||||||
image: hyperpipe-frontend
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
args:
|
|
||||||
pipedapi: pipedapi.kavin.rocks
|
|
||||||
api: hyperpipeapi.onrender.com
|
|
||||||
container_name: hyperpipe-frontend
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- '8080:80'
|
|
|
@ -9,7 +9,6 @@
|
||||||
<link rel="icon" href="/favicon.svg" />
|
<link rel="icon" href="/favicon.svg" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||||
<meta name="msapplication-TileColor" content="#181818" />
|
<meta name="msapplication-TileColor" content="#181818" />
|
||||||
<link rel="preconnect" href="https://cdn.jsdelivr.net" />
|
|
||||||
<link rel="preconnect" href="https://hyperpipeapi.onrender.com" />
|
<link rel="preconnect" href="https://hyperpipeapi.onrender.com" />
|
||||||
<link rel="dns-prefetch" href="https://pipedapi.kavin.rocks" />
|
<link rel="dns-prefetch" href="https://pipedapi.kavin.rocks" />
|
||||||
<link rel="dns-prefetch" href="https://hyperpipe-proxy.onrender.com" />
|
<link rel="dns-prefetch" href="https://hyperpipe-proxy.onrender.com" />
|
||||||
|
@ -29,7 +28,10 @@
|
||||||
<title>Hyperpipe</title>
|
<title>Hyperpipe</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>Kind Sir, Please Give Me JavaScript</noscript>
|
<noscript
|
||||||
|
>JavaScript is required for this site to function. Please enable it in
|
||||||
|
your browser or browser extension settings.</noscript
|
||||||
|
>
|
||||||
|
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|
||||||
|
|
1174
package-lock.json
generated
1174
package-lock.json
generated
File diff suppressed because it is too large
Load diff
10
package.json
10
package.json
|
@ -15,15 +15,15 @@
|
||||||
"dompurify": "^2.4.1",
|
"dompurify": "^2.4.1",
|
||||||
"mux.js": "^6.2.0",
|
"mux.js": "^6.2.0",
|
||||||
"peerjs": "^1.4.7",
|
"peerjs": "^1.4.7",
|
||||||
"pinia": "^2.0.26",
|
"pinia": "^2.0.28",
|
||||||
"shaka-player": "^4.3.0",
|
"shaka-player": "^4.3.1",
|
||||||
"stream-browserify": "^3.0.0",
|
"stream-browserify": "^3.0.0",
|
||||||
"vue": "^3.2.38",
|
"vue": "^3.2.38",
|
||||||
"xml-js": "^1.6.11"
|
"xml-js": "^1.6.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^3.2.0",
|
"@vitejs/plugin-vue": "^4.0.0",
|
||||||
"prettier": "^2.8.0",
|
"prettier": "^2.8.1",
|
||||||
"vite": "^3.2.4"
|
"vite": "^4.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,7 +150,7 @@ onMounted(() => {
|
||||||
v-if="data.state.art"
|
v-if="data.state.art"
|
||||||
class="art"
|
class="art"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
:src="data.state.art" />
|
:src="data.state.art.replaceAll('&', '&')" />
|
||||||
|
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<NowPlaying @get-artist="artist.getArtist" />
|
<NowPlaying @get-artist="artist.getArtist" />
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
{
|
{
|
||||||
"date": "2022-11-30"
|
"date": "2022-12-13"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { useRand } from '@/scripts/colors.js';
|
||||||
|
|
||||||
const rand = useRand();
|
const rand = useRand();
|
||||||
|
|
||||||
const props = defineProps({
|
defineProps({
|
||||||
name: String,
|
name: String,
|
||||||
author: {
|
author: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onUpdated } from 'vue';
|
import { ref } from 'vue';
|
||||||
import Btn from './Btn.vue';
|
import Btn from './Btn.vue';
|
||||||
|
|
||||||
import { useStore } from '@/scripts/util.js';
|
import { useStore } from '@/scripts/util.js';
|
||||||
|
|
|
@ -51,7 +51,9 @@ onMounted(() => {
|
||||||
<template>
|
<template>
|
||||||
<template v-if="data.options.length > 0">
|
<template v-if="data.options.length > 0">
|
||||||
<select :value="id" class="input" @input="id = $event.target.value">
|
<select :value="id" class="input" @input="id = $event.target.value">
|
||||||
<option v-for="i in data.options" :value="i.id">{{ i.title }}</option>
|
<option v-for="i in data.options" :value="i.id" :key="i.id">
|
||||||
|
{{ i.title }}
|
||||||
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -60,6 +62,7 @@ onMounted(() => {
|
||||||
<div class="grid-3 circle">
|
<div class="grid-3 circle">
|
||||||
<AlbumItem
|
<AlbumItem
|
||||||
v-for="i in data.artists"
|
v-for="i in data.artists"
|
||||||
|
:key="i.id"
|
||||||
:name="i.title"
|
:name="i.title"
|
||||||
:author="i.subtitle"
|
:author="i.subtitle"
|
||||||
:art="i.thumbnails[1].url"
|
:art="i.thumbnails[1].url"
|
||||||
|
@ -72,6 +75,7 @@ onMounted(() => {
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<SongItem
|
<SongItem
|
||||||
v-for="i in data.songs"
|
v-for="i in data.songs"
|
||||||
|
:key="i.id"
|
||||||
:title="i.title"
|
:title="i.title"
|
||||||
:author="i.subtitle"
|
:author="i.subtitle"
|
||||||
:channel="'/channel/' + i.subId"
|
:channel="'/channel/' + i.subId"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, ref, onMounted, onUnmounted } from 'vue';
|
import { reactive, onMounted } from 'vue';
|
||||||
|
|
||||||
import { useResults } from '@/stores/results.js';
|
import { useResults } from '@/stores/results.js';
|
||||||
|
|
||||||
|
@ -62,19 +62,21 @@ onMounted(get);
|
||||||
|
|
||||||
<h2 class="head">{{ data.title }}</h2>
|
<h2 class="head">{{ data.title }}</h2>
|
||||||
|
|
||||||
<template v-for="type in ['featured', 'spotlight', 'community']">
|
<template
|
||||||
|
v-for="type in ['featured', 'spotlight', 'community']"
|
||||||
|
:key="type">
|
||||||
<h3 class="head">{{ t('title.' + type) }}</h3>
|
<h3 class="head">{{ t('title.' + type) }}</h3>
|
||||||
<div class="grid-3">
|
<div class="grid-3">
|
||||||
<template v-for="i in data[type]">
|
<AlbumItem
|
||||||
<AlbumItem
|
v-for="i in data[type]"
|
||||||
:name="i.title"
|
:key="i.id"
|
||||||
:author="i.subtitle"
|
:name="i.title"
|
||||||
:art="i.thumbnails[0].url"
|
:author="i.subtitle"
|
||||||
@open-album="
|
:art="i.thumbnails[0].url"
|
||||||
getAlbum('/playlist?list=' + i.id);
|
@open-album="
|
||||||
nav.state.page = 'home';
|
getAlbum('/playlist?list=' + i.id);
|
||||||
" />
|
nav.state.page = 'home';
|
||||||
</template>
|
" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -86,6 +88,7 @@ onMounted(get);
|
||||||
<button
|
<button
|
||||||
v-for="i in btns.moods"
|
v-for="i in btns.moods"
|
||||||
class="btn"
|
class="btn"
|
||||||
|
:key="i.id"
|
||||||
:style="`--btn-color: ${i.subtitle};`"
|
:style="`--btn-color: ${i.subtitle};`"
|
||||||
@click="get(i.id)">
|
@click="get(i.id)">
|
||||||
{{ i.title }}
|
{{ i.title }}
|
||||||
|
@ -98,6 +101,7 @@ onMounted(get);
|
||||||
<button
|
<button
|
||||||
v-for="i in btns.genres"
|
v-for="i in btns.genres"
|
||||||
class="btn"
|
class="btn"
|
||||||
|
:key="i.id"
|
||||||
:style="`--btn-color: ${i.subtitle};`"
|
:style="`--btn-color: ${i.subtitle};`"
|
||||||
@click="get(i.id)">
|
@click="get(i.id)">
|
||||||
{{ i.title }}
|
{{ i.title }}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive } from 'vue';
|
|
||||||
|
|
||||||
import SearchBar from '@/components/SearchBar.vue';
|
import SearchBar from '@/components/SearchBar.vue';
|
||||||
import IcoHyp from '@/assets/icons/IcoHyp.vue';
|
import IcoHyp from '@/assets/icons/IcoHyp.vue';
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,9 @@ const { t } = useI18n(),
|
||||||
results = useResults(),
|
results = useResults(),
|
||||||
nav = useNav();
|
nav = useNav();
|
||||||
|
|
||||||
const emit = defineEmits(['play-urls', 'open-playlist']),
|
defineEmits(['play-urls', 'open-playlist']);
|
||||||
list = ref([]),
|
|
||||||
|
const list = ref([]),
|
||||||
show = reactive({
|
show = reactive({
|
||||||
new: false,
|
new: false,
|
||||||
sync: false,
|
sync: false,
|
||||||
|
@ -137,7 +138,7 @@ const Login = async () => {
|
||||||
},
|
},
|
||||||
createPlaylist = async () => {
|
createPlaylist = async () => {
|
||||||
if (text.value) {
|
if (text.value) {
|
||||||
const res = await useAuthCreatePlaylist(text.value);
|
await useAuthCreatePlaylist(text.value);
|
||||||
|
|
||||||
getPlaylists();
|
getPlaylists();
|
||||||
show.new = false;
|
show.new = false;
|
||||||
|
@ -312,24 +313,24 @@ onMounted(async () => {
|
||||||
<h2 v-if="list.length > 0">{{ t('playlist.local') }}</h2>
|
<h2 v-if="list.length > 0">{{ t('playlist.local') }}</h2>
|
||||||
|
|
||||||
<div class="grid-3">
|
<div class="grid-3">
|
||||||
<template v-for="i in list">
|
<AlbumItem
|
||||||
<AlbumItem
|
v-for="i in list"
|
||||||
:name="i.name"
|
:key="i.name"
|
||||||
:author="t('title.songs') + ' • ' + i.urls.length"
|
:name="i.name"
|
||||||
:grad="useRand()"
|
:author="t('title.songs') + ' • ' + i.urls.length"
|
||||||
@open-album="Open(i.name)" />
|
:grad="useRand()"
|
||||||
</template>
|
@open-album="Open(i.name)" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 class="login-h">{{ t('playlist.remote') }}</h2>
|
<h2 class="login-h">{{ t('playlist.remote') }}</h2>
|
||||||
|
|
||||||
<div v-if="auth" class="grid-3">
|
<div v-if="auth" class="grid-3">
|
||||||
<template v-for="i in user.playlists">
|
<AlbumItem
|
||||||
<AlbumItem
|
v-for="i in user.playlists"
|
||||||
:name="i.name.replace('Playlist - ', '')"
|
:key="i.id"
|
||||||
:art="pathname(i.thumbnail) != '/' ? i.thumbnail : undefined"
|
:name="i.name.replace('Playlist - ', '')"
|
||||||
@open-album="$emit('open-playlist', '/playlists?list=' + i.id)" />
|
:art="pathname(i.thumbnail) != '/' ? i.thumbnail : undefined"
|
||||||
</template>
|
@open-album="$emit('open-playlist', '/playlists?list=' + i.id)" />
|
||||||
</div>
|
</div>
|
||||||
<form v-else class="login" @submit.prevent>
|
<form v-else class="login" @submit.prevent>
|
||||||
<input
|
<input
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import { ref, watch, onMounted, onBeforeUnmount, onUnmounted } from 'vue';
|
||||||
ref,
|
|
||||||
watch,
|
|
||||||
onMounted,
|
|
||||||
onUpdated,
|
|
||||||
onBeforeUnmount,
|
|
||||||
onUnmounted,
|
|
||||||
} from 'vue';
|
|
||||||
|
|
||||||
import muxjs from 'mux.js';
|
import muxjs from 'mux.js';
|
||||||
window.muxjs = muxjs;
|
window.muxjs = muxjs;
|
||||||
|
@ -64,7 +57,7 @@ async function Stream() {
|
||||||
if (shaka.Player.isBrowserSupported) {
|
if (shaka.Player.isBrowserSupported) {
|
||||||
const audioPlayer = new shaka.Player(audio.value);
|
const audioPlayer = new shaka.Player(audio.value);
|
||||||
|
|
||||||
const codecs = useStore().getItem('codec');
|
const codecs = store.getItem('codec');
|
||||||
|
|
||||||
audioPlayer
|
audioPlayer
|
||||||
.getNetworkingEngine()
|
.getNetworkingEngine()
|
||||||
|
@ -94,7 +87,7 @@ async function Stream() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const quality = useStore().getItem('quality');
|
const quality = store.getItem('quality');
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
window.audioPlayer
|
window.audioPlayer
|
||||||
|
|
|
@ -12,26 +12,28 @@ defineEmits(['playthis']);
|
||||||
<template>
|
<template>
|
||||||
<Transition name="fade">
|
<Transition name="fade">
|
||||||
<div class="pl-modal placeholder" :data-placeholder="t('playlist.add')">
|
<div class="pl-modal placeholder" :data-placeholder="t('playlist.add')">
|
||||||
<template v-for="plurl in data.state.urls">
|
<div
|
||||||
<div class="pl-item" @click="$emit('playthis', plurl)">
|
v-for="plurl in data.state.urls"
|
||||||
<span
|
class="pl-item"
|
||||||
v-if="data.state.url == plurl.url"
|
:key="plurl.url"
|
||||||
class="bars-wrap"
|
@click="$emit('playthis', plurl)">
|
||||||
:class="player.state.status">
|
<span
|
||||||
<div class="bars"></div>
|
v-if="data.state.url == plurl.url"
|
||||||
<div class="bars"></div>
|
class="bars-wrap"
|
||||||
<div class="bars"></div>
|
:class="player.state.status">
|
||||||
</span>
|
<div class="bars"></div>
|
||||||
<div v-else-if="plurl.thumbnails" class="pl-img">
|
<div class="bars"></div>
|
||||||
<img
|
<div class="bars"></div>
|
||||||
:src="plurl.thumbnails[0].url"
|
</span>
|
||||||
:height="plurl.thumbnails[0].height"
|
<div v-else-if="plurl.thumbnails" class="pl-img">
|
||||||
:width="plurl.thumbnails[0].width"
|
<img
|
||||||
loading="lazy" />
|
:src="plurl.thumbnails[0].url"
|
||||||
</div>
|
:height="plurl.thumbnails[0].height"
|
||||||
<span class="pl-main caps">{{ plurl.title }}</span>
|
:width="plurl.thumbnails[0].width"
|
||||||
|
loading="lazy" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<span class="pl-main caps">{{ plurl.title }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -107,7 +107,9 @@ onMounted(() => {
|
||||||
class="input"
|
class="input"
|
||||||
:value="getStore('locale') || 'en'"
|
:value="getStore('locale') || 'en'"
|
||||||
@change="setLang($event.target.value)">
|
@change="setLang($event.target.value)">
|
||||||
<option v-for="i in SUPPORTED_LOCALES" :value="i.code">{{ i.name }}</option>
|
<option v-for="i in SUPPORTED_LOCALES" :value="i.code" :key="i.code">
|
||||||
|
{{ i.name }}
|
||||||
|
</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<h2>{{ t('pref.tab') }}</h2>
|
<h2>{{ t('pref.tab') }}</h2>
|
||||||
|
@ -205,7 +207,7 @@ onMounted(() => {
|
||||||
<th>{{ t('instances.loc') }}</th>
|
<th>{{ t('instances.loc') }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody v-for="i in hypInstances">
|
<tbody v-for="i in hypInstances" :key="i.name">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{{ i.name }}
|
{{ i.name }}
|
||||||
|
@ -273,7 +275,7 @@ onMounted(() => {
|
||||||
<th>{{ t('instances.version') }}</th>
|
<th>{{ t('instances.version') }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody v-for="i in instances">
|
<tbody v-for="i in instances" :key="i.name">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{{ i.name.replace('Official', 'Default') }}
|
{{ i.name.replace('Official', 'Default') }}
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import { ref, watch, onActivated, onUpdated, onDeactivated } from 'vue';
|
||||||
ref,
|
|
||||||
reactive,
|
|
||||||
watch,
|
|
||||||
onActivated,
|
|
||||||
onUpdated,
|
|
||||||
onDeactivated,
|
|
||||||
} from 'vue';
|
|
||||||
|
|
||||||
import Btn from './Btn.vue';
|
import Btn from './Btn.vue';
|
||||||
import SongItem from './SongItem.vue';
|
import SongItem from './SongItem.vue';
|
||||||
|
@ -241,11 +234,12 @@ onDeactivated(() => {
|
||||||
<button
|
<button
|
||||||
v-for="f in filters"
|
v-for="f in filters"
|
||||||
class="filter caps"
|
class="filter caps"
|
||||||
|
:key="f"
|
||||||
|
:data-active="f == filter"
|
||||||
@click="
|
@click="
|
||||||
filter = f;
|
filter = f;
|
||||||
getSearch(nav.state.search);
|
getSearch(nav.state.search);
|
||||||
"
|
">
|
||||||
:data-active="f == filter">
|
|
||||||
{{ t('title.' + f.split('_')[1]) }}
|
{{ t('title.' + f.split('_')[1]) }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -255,35 +249,35 @@ onDeactivated(() => {
|
||||||
class="search-wrap">
|
class="search-wrap">
|
||||||
<h2 v-if="!isSearch">{{ t('title.songs') }}</h2>
|
<h2 v-if="!isSearch">{{ t('title.songs') }}</h2>
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<template v-for="(song, index) in results.items.songs.items">
|
<SongItem
|
||||||
<SongItem
|
v-for="(song, index) in results.items.songs.items"
|
||||||
:index="index"
|
:key="song.url || song.id"
|
||||||
:playlistId="song.playlistId"
|
:index="index"
|
||||||
:author="song.uploaderName || song.subtitle"
|
:playlistId="song.playlistId"
|
||||||
:title="song.title || song.name"
|
:author="song.uploaderName || song.subtitle"
|
||||||
:channel="song.uploaderUrl || '/channel/' + song.subId"
|
:title="song.title || song.name"
|
||||||
:play="song.url || '/watch?v=' + song.id"
|
:channel="song.uploaderUrl || '/channel/' + song.subId"
|
||||||
:art="
|
:play="song.url || '/watch?v=' + song.id"
|
||||||
song.thumbnail || song.thumbnails[1]?.url || song.thumbnails[0]?.url
|
:art="
|
||||||
"
|
song.thumbnail || song.thumbnails[1]?.url || song.thumbnails[0]?.url
|
||||||
@remove="removeSong"
|
"
|
||||||
@open-song="
|
@remove="removeSong"
|
||||||
$emit('play-urls', [
|
@open-song="
|
||||||
{
|
$emit('play-urls', [
|
||||||
url: song.url || '/watch?v=' + song.id,
|
{
|
||||||
title: song.title || song.name,
|
url: song.url || '/watch?v=' + song.id,
|
||||||
thumbnails: [
|
title: song.title || song.name,
|
||||||
{
|
thumbnails: [
|
||||||
url:
|
{
|
||||||
song.thumbnail ||
|
url:
|
||||||
song.thumbnails[1]?.url ||
|
song.thumbnail ||
|
||||||
song.thumbnails[0]?.url,
|
song.thumbnails[1]?.url ||
|
||||||
},
|
song.thumbnails[0]?.url,
|
||||||
],
|
},
|
||||||
},
|
],
|
||||||
])
|
},
|
||||||
" />
|
])
|
||||||
</template>
|
" />
|
||||||
</div>
|
</div>
|
||||||
<a
|
<a
|
||||||
v-if="artist.state.playlistId"
|
v-if="artist.state.playlistId"
|
||||||
|
@ -301,15 +295,15 @@ onDeactivated(() => {
|
||||||
class="search-wrap">
|
class="search-wrap">
|
||||||
<h2 v-if="!isSearch">{{ t('title.albums') }}</h2>
|
<h2 v-if="!isSearch">{{ t('title.albums') }}</h2>
|
||||||
<div class="grid-3">
|
<div class="grid-3">
|
||||||
<template v-for="album in results.items.albums.items">
|
<AlbumItem
|
||||||
<AlbumItem
|
v-for="album in results.items.albums.items"
|
||||||
:author="album.uploaderName || album.subtitle"
|
:key="album.url || album.id"
|
||||||
:name="album.name || album.title"
|
:author="album.uploaderName || album.subtitle"
|
||||||
:art="album.thumbnail || album.thumbnails[0].url"
|
:name="album.name || album.title"
|
||||||
@open-album="
|
:art="album.thumbnail || album.thumbnails[0].url"
|
||||||
results.getAlbum(album.url || '/playlist?list=' + album.id)
|
@open-album="
|
||||||
" />
|
results.getAlbum(album.url || '/playlist?list=' + album.id)
|
||||||
</template>
|
" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -320,6 +314,7 @@ onDeactivated(() => {
|
||||||
<div class="grid-3">
|
<div class="grid-3">
|
||||||
<AlbumItem
|
<AlbumItem
|
||||||
v-for="pl in results.items.playlists.items"
|
v-for="pl in results.items.playlists.items"
|
||||||
|
:key="pl.url"
|
||||||
:author="pl.videos + ' Songs • ' + pl.uploaderName"
|
:author="pl.videos + ' Songs • ' + pl.uploaderName"
|
||||||
:name="pl.name"
|
:name="pl.name"
|
||||||
:art="pl.thumbnail"
|
:art="pl.thumbnail"
|
||||||
|
@ -332,13 +327,13 @@ onDeactivated(() => {
|
||||||
class="search-wrap">
|
class="search-wrap">
|
||||||
<h2>{{ t('title.singles') }}</h2>
|
<h2>{{ t('title.singles') }}</h2>
|
||||||
<div class="grid-3">
|
<div class="grid-3">
|
||||||
<template v-for="single in results.items.singles.items">
|
<AlbumItem
|
||||||
<AlbumItem
|
v-for="single in results.items.singles.items"
|
||||||
:author="single.subtitle"
|
:key="single.id"
|
||||||
:name="single.title"
|
:author="single.subtitle"
|
||||||
:art="single.thumbnails[0].url"
|
:name="single.title"
|
||||||
@open-album="results.getAlbum('/playlist?list=' + single.id)" />
|
:art="single.thumbnails[0].url"
|
||||||
</template>
|
@open-album="results.getAlbum('/playlist?list=' + single.id)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -355,18 +350,17 @@ onDeactivated(() => {
|
||||||
}}
|
}}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="grid-3 circle">
|
<div class="grid-3 circle">
|
||||||
<template
|
<AlbumItem
|
||||||
v-for="a in results.items.artists
|
v-for="a in results.items.artists
|
||||||
? results.items.artists.items
|
? results.items.artists.items
|
||||||
: results.items.recommendedArtists.items">
|
: results.items.recommendedArtists.items"
|
||||||
<AlbumItem
|
:key="a.id || a.url"
|
||||||
:author="a.subtitle"
|
:author="a.subtitle"
|
||||||
:name="a.name || a.title"
|
:name="a.name || a.title"
|
||||||
:art="a.thumbnail || a.thumbnails[0].url"
|
:art="a.thumbnail || a.thumbnails[0].url"
|
||||||
@open-album="
|
@open-album="
|
||||||
artist.getArtist(a.id || a.url.replace('/channel/', ''))
|
artist.getArtist(a.id || a.url.replace('/channel/', ''))
|
||||||
" />
|
" />
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -5,6 +5,12 @@ import { useNav, useI18n } from '@/stores/misc.js';
|
||||||
const { t } = useI18n(),
|
const { t } = useI18n(),
|
||||||
show = ref(false),
|
show = ref(false),
|
||||||
nav = useNav();
|
nav = useNav();
|
||||||
|
|
||||||
|
function search(e) {
|
||||||
|
nav.state.search = e.target.value;
|
||||||
|
nav.state.page = 'home';
|
||||||
|
e.target.blur();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -19,11 +25,8 @@ const { t } = useI18n(),
|
||||||
type="search"
|
type="search"
|
||||||
aria-label="Search Input"
|
aria-label="Search Input"
|
||||||
:placeholder="t('title.search') + '...'"
|
:placeholder="t('title.search') + '...'"
|
||||||
@change="
|
@change="search"
|
||||||
nav.state.search = $event.target.value;
|
@keyup.enter="search"
|
||||||
nav.state.page = 'home';
|
|
||||||
$event.target.blur();
|
|
||||||
"
|
|
||||||
:value="nav.state.search" />
|
:value="nav.state.search" />
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { getJsonAuth } from '@/scripts/fetch.js';
|
||||||
import { useRand } from '@/scripts/colors.js';
|
import { useRand } from '@/scripts/colors.js';
|
||||||
import { useStore } from '@/scripts/util.js';
|
import { useStore } from '@/scripts/util.js';
|
||||||
|
|
||||||
import { useArtist, useResults } from '@/stores/results.js';
|
import { useArtist } from '@/stores/results.js';
|
||||||
import { useData, usePlayer } from '@/stores/player.js';
|
import { useData, usePlayer } from '@/stores/player.js';
|
||||||
|
|
||||||
const rand = useRand(),
|
const rand = useRand(),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, watch } from 'vue';
|
import { ref, reactive } from 'vue';
|
||||||
|
|
||||||
import Modal from './Modal.vue';
|
import Modal from './Modal.vue';
|
||||||
|
|
||||||
|
@ -19,8 +19,9 @@ const { t } = useI18n(),
|
||||||
player = usePlayer(),
|
player = usePlayer(),
|
||||||
store = useStore();
|
store = useStore();
|
||||||
|
|
||||||
const emit = defineEmits(['save']),
|
defineEmits(['save']);
|
||||||
showme = reactive({
|
|
||||||
|
const showme = reactive({
|
||||||
menu: false,
|
menu: false,
|
||||||
pl: false,
|
pl: false,
|
||||||
vol: false,
|
vol: false,
|
||||||
|
@ -112,29 +113,29 @@ async function Like() {
|
||||||
}
|
}
|
||||||
">
|
">
|
||||||
<template #content>
|
<template #content>
|
||||||
<template v-for="i in list">
|
<div
|
||||||
<div
|
v-for="i in list"
|
||||||
class="flex item"
|
:key="i.name"
|
||||||
@click="
|
class="flex item"
|
||||||
pl = i.name;
|
@click="
|
||||||
plRemote = false;
|
pl = i.name;
|
||||||
"
|
plRemote = false;
|
||||||
:data-active="pl == i.name && plRemote == false">
|
"
|
||||||
<span>{{ i.name }}</span
|
:data-active="pl == i.name && plRemote == false">
|
||||||
><span class="ml-auto">{{ i.urls.length || '' }}</span>
|
<span>{{ i.name }}</span
|
||||||
</div>
|
><span class="ml-auto">{{ i.urls.length || '' }}</span>
|
||||||
</template>
|
</div>
|
||||||
<template v-for="i in remote">
|
<div
|
||||||
<div
|
v-for="i in remote"
|
||||||
class="flex item"
|
:key="i.id"
|
||||||
@click="
|
class="flex item"
|
||||||
pl = i.id;
|
@click="
|
||||||
plRemote = true;
|
pl = i.id;
|
||||||
"
|
plRemote = true;
|
||||||
:data-active="pl == i.id && plRemote == true">
|
"
|
||||||
<span>{{ i.name }}</span>
|
:data-active="pl == i.id && plRemote == true">
|
||||||
</div>
|
<span>{{ i.name }}</span>
|
||||||
</template>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #buttons>
|
<template #buttons>
|
||||||
<button aria-label="Cancel" @click="showme.pl = false">
|
<button aria-label="Cancel" @click="showme.pl = false">
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
"dark": "Mračno (Zadano)",
|
"dark": "Mračno (Zadano)",
|
||||||
"dracula": "Drakula",
|
"dracula": "Drakula",
|
||||||
"nord": "Nord",
|
"nord": "Nord",
|
||||||
"blur": "Zamućenje",
|
"blur": "Zamagljeno",
|
||||||
"blur_light": "Zamućenje (Svjetlo)",
|
"blur_light": "Zamućenje (Svjetlo)",
|
||||||
"light": "Svjetlo"
|
"light": "Svjetlo"
|
||||||
},
|
},
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
"tab": "Výchozí karta",
|
"tab": "Výchozí karta",
|
||||||
"dark": "Tmavý (výchozí)",
|
"dark": "Tmavý (výchozí)",
|
||||||
"light": "Světlý",
|
"light": "Světlý",
|
||||||
"blur": "Rozmazaný",
|
"blur": "Rozmazání",
|
||||||
"blur_light": "Rozmazaný (světlý)",
|
"blur_light": "Rozmazaný (světlý)",
|
||||||
"dracula": "Drákula",
|
"dracula": "Drákula",
|
||||||
"nord": "Nord"
|
"nord": "Nord"
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
},
|
},
|
||||||
"lyrics": {
|
"lyrics": {
|
||||||
"load": "Načítání textů",
|
"load": "Načítání textů",
|
||||||
"void": "Žádné texty"
|
"void": "Texty nenalezeny"
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"back": "Zpět",
|
"back": "Zpět",
|
||||||
|
|
|
@ -46,9 +46,9 @@
|
||||||
"best": "am Besten",
|
"best": "am Besten",
|
||||||
"tab": "Standard-Registerkarte",
|
"tab": "Standard-Registerkarte",
|
||||||
"dark": "Dunkel (Standard)",
|
"dark": "Dunkel (Standard)",
|
||||||
"light": "Licht",
|
"light": "Hell",
|
||||||
"blur": "Unschärfe",
|
"blur": "Unschärfe",
|
||||||
"blur_light": "Unschärfe (Licht)",
|
"blur_light": "Unschärfe (hell)",
|
||||||
"dracula": "Dracula",
|
"dracula": "Dracula",
|
||||||
"nord": "Nord"
|
"nord": "Nord"
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
"local": "Regional",
|
"local": "Regional",
|
||||||
"remote": "Remoto",
|
"remote": "Remoto",
|
||||||
"search": "Búsqueda",
|
"search": "Búsqueda",
|
||||||
"playlists": "Listas de reproducción"
|
"playlists": "Listas de reproducción",
|
||||||
|
"feeds": "Fuentes"
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"back": "Atrás",
|
"back": "Atrás",
|
||||||
|
@ -43,7 +44,13 @@
|
||||||
"auto_queue": "Canciones en la cola de reproducción automáticamente",
|
"auto_queue": "Canciones en la cola de reproducción automáticamente",
|
||||||
"worst": "La peor",
|
"worst": "La peor",
|
||||||
"best": "La mejor",
|
"best": "La mejor",
|
||||||
"tab": "Ficha predeterminada"
|
"tab": "Ficha predeterminada",
|
||||||
|
"dark": "Oscuro (Por defecto)",
|
||||||
|
"blur": "Desenfocar",
|
||||||
|
"light": "Claro",
|
||||||
|
"blur_light": "Desenfoque (Luz)",
|
||||||
|
"dracula": "Drácula",
|
||||||
|
"nord": "Nord"
|
||||||
},
|
},
|
||||||
"info": {
|
"info": {
|
||||||
"see_all": "Ver todo",
|
"see_all": "Ver todo",
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
"remote": "À distance",
|
"remote": "À distance",
|
||||||
"community": "Communauté",
|
"community": "Communauté",
|
||||||
"search": "Recherche",
|
"search": "Recherche",
|
||||||
"playlists": "Listes de lecture"
|
"playlists": "Listes de lecture",
|
||||||
|
"feeds": "Flux"
|
||||||
},
|
},
|
||||||
"playlist": {
|
"playlist": {
|
||||||
"local": "Listes de lecture locales",
|
"local": "Listes de lecture locales",
|
||||||
|
@ -35,7 +36,13 @@
|
||||||
"player": "Lecteur audio",
|
"player": "Lecteur audio",
|
||||||
"auto_queue": "Mettre automatiquement les chansons en file d'attente",
|
"auto_queue": "Mettre automatiquement les chansons en file d'attente",
|
||||||
"codec": "Codec",
|
"codec": "Codec",
|
||||||
"tab": "Onglet par défaut"
|
"tab": "Onglet par défaut",
|
||||||
|
"dark": "Sombre (par défaut)",
|
||||||
|
"light": "Clair",
|
||||||
|
"blur": "Flou",
|
||||||
|
"blur_light": "Flou (clair)",
|
||||||
|
"dracula": "Dracula",
|
||||||
|
"nord": "Nord"
|
||||||
},
|
},
|
||||||
"info": {
|
"info": {
|
||||||
"see_all": "Voir tout",
|
"see_all": "Voir tout",
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
{
|
{
|
||||||
"title": {
|
"title": {
|
||||||
"songs": "Cancións",
|
"songs": "Cancións",
|
||||||
"albums": "Álbums",
|
"albums": "Álbums",
|
||||||
"singles": "Singles",
|
"singles": "Singles",
|
||||||
"artists": "Artistas",
|
"artists": "Artistas",
|
||||||
"similar_artists": "Artistas similares",
|
"similar_artists": "Artistas similares",
|
||||||
"moods": "Estado de ánimo",
|
"moods": "Estado de ánimo",
|
||||||
"genres": "Xéneros",
|
"genres": "Xéneros",
|
||||||
"featured": "Destacado"
|
"featured": "Destacado"
|
||||||
}
|
},
|
||||||
|
"pref": {
|
||||||
|
"blur": "Desenfoque"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,13 @@
|
||||||
"quality": "Qualità",
|
"quality": "Qualità",
|
||||||
"auto": "automatica",
|
"auto": "automatica",
|
||||||
"worst": "la peggia",
|
"worst": "la peggia",
|
||||||
"tab": "Scheda predefinita"
|
"tab": "Scheda predefinita",
|
||||||
|
"dark": "Scuro (predefinito)",
|
||||||
|
"light": "Chiaro",
|
||||||
|
"blur": "Sfocatura",
|
||||||
|
"blur_light": "Sfocatura (chiaro)",
|
||||||
|
"dracula": "Dracula",
|
||||||
|
"nord": "Nord"
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"albums": "Album",
|
"albums": "Album",
|
||||||
|
@ -25,7 +31,8 @@
|
||||||
"local": "Locale",
|
"local": "Locale",
|
||||||
"search": "Ricerca",
|
"search": "Ricerca",
|
||||||
"featured": "In primo piano",
|
"featured": "In primo piano",
|
||||||
"playlists": "Playlist"
|
"playlists": "Playlist",
|
||||||
|
"feeds": "Flussi"
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"add": "Aggiungi",
|
"add": "Aggiungi",
|
||||||
|
|
74
src/locales/pt_br.json
Normal file
74
src/locales/pt_br.json
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
{
|
||||||
|
"title": {
|
||||||
|
"songs": "Músicas",
|
||||||
|
"albums": "Álbuns",
|
||||||
|
"singles": "Singles",
|
||||||
|
"artists": "Artistas",
|
||||||
|
"similar_artists": "Artistas Similares",
|
||||||
|
"playlists": "Playlists",
|
||||||
|
"moods": "Humores",
|
||||||
|
"genres": "Gêneros",
|
||||||
|
"featured": "Destaques",
|
||||||
|
"spotlight": "Foco",
|
||||||
|
"community": "Comunidade",
|
||||||
|
"login": "Entrar",
|
||||||
|
"local": "Local",
|
||||||
|
"remote": "Remoto",
|
||||||
|
"search": "Pesquisar",
|
||||||
|
"feeds": "Feeds"
|
||||||
|
},
|
||||||
|
"action": {
|
||||||
|
"back": "Voltar",
|
||||||
|
"add": "Adicionar",
|
||||||
|
"create": "Criar",
|
||||||
|
"cancel": "Cancelar",
|
||||||
|
"send": "Enviar",
|
||||||
|
"receive": "Receber"
|
||||||
|
},
|
||||||
|
"playlist": {
|
||||||
|
"local": "Playlists Locais",
|
||||||
|
"remote": "Playlists Remotas",
|
||||||
|
"name": "Nome da Playlist",
|
||||||
|
"add": "Adicionar Músicas à Playlist",
|
||||||
|
"create": "Criar uma nova Playlist",
|
||||||
|
"sync": "Sincronizar playlists",
|
||||||
|
"select": "Selecione a Playlist para Adicionar"
|
||||||
|
},
|
||||||
|
"pref": {
|
||||||
|
"theme": "Tema",
|
||||||
|
"dark": "Escuro (padrão)",
|
||||||
|
"light": "Claro",
|
||||||
|
"blur": "Desfocado",
|
||||||
|
"blur_light": "Desfocado (Claro)",
|
||||||
|
"dracula": "Dracula",
|
||||||
|
"nord": "Nord",
|
||||||
|
"tab": "Aba Padrão",
|
||||||
|
"player": "Reprodutor de Áudio",
|
||||||
|
"auto_queue": "Enfileirar músicas automaticamente",
|
||||||
|
"codec": "Codec",
|
||||||
|
"quality": "Qualidade",
|
||||||
|
"auto": "automática",
|
||||||
|
"best": "melhor",
|
||||||
|
"worst": "pior",
|
||||||
|
"volume": "Volume Padrão"
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"see_all": "Ver Tudo",
|
||||||
|
"search": "Comece a pesquisar",
|
||||||
|
"no_info": "Nenhuma Informação Disponível"
|
||||||
|
},
|
||||||
|
"instances": {
|
||||||
|
"hyp": "Instância do Hyperpipe",
|
||||||
|
"piped": "Instância do Piped",
|
||||||
|
"auth": "Instância de Autenticação",
|
||||||
|
"name": "Nome",
|
||||||
|
"loc": "Localizações",
|
||||||
|
"cdn": "CDN",
|
||||||
|
"up_to_date": "Atualizado",
|
||||||
|
"version": "Versão"
|
||||||
|
},
|
||||||
|
"lyrics": {
|
||||||
|
"load": "Buscando Letras",
|
||||||
|
"void": "Sem Letras"
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,8 @@
|
||||||
"login": "Autentificare",
|
"login": "Autentificare",
|
||||||
"search": "Căutare",
|
"search": "Căutare",
|
||||||
"local": "Local",
|
"local": "Local",
|
||||||
"songs": "Melodii"
|
"songs": "Melodii",
|
||||||
|
"feeds": "Fluxuri"
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"back": "Înapoi",
|
"back": "Înapoi",
|
||||||
|
@ -43,7 +44,13 @@
|
||||||
"best": "cel mai bun",
|
"best": "cel mai bun",
|
||||||
"auto": "auto",
|
"auto": "auto",
|
||||||
"worst": "cel mai rău",
|
"worst": "cel mai rău",
|
||||||
"volume": "Volum implicit"
|
"volume": "Volum implicit",
|
||||||
|
"blur": "Blur",
|
||||||
|
"dark": "Întunecat (implicit)",
|
||||||
|
"light": "Luminat",
|
||||||
|
"blur_light": "Blur (Lumină)",
|
||||||
|
"dracula": "Dracula",
|
||||||
|
"nord": "Nord"
|
||||||
},
|
},
|
||||||
"instances": {
|
"instances": {
|
||||||
"cdn": "CDN",
|
"cdn": "CDN",
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
"remote": "Удалённый",
|
"remote": "Удалённый",
|
||||||
"albums": "Альбомы",
|
"albums": "Альбомы",
|
||||||
"spotlight": "Поиск",
|
"spotlight": "Поиск",
|
||||||
"playlists": "Плейлисты"
|
"playlists": "Плейлисты",
|
||||||
|
"feeds": "Фиды"
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"back": "Назад",
|
"back": "Назад",
|
||||||
|
@ -43,7 +44,13 @@
|
||||||
"volume": "Громкость по умолчанию",
|
"volume": "Громкость по умолчанию",
|
||||||
"quality": "Качество",
|
"quality": "Качество",
|
||||||
"best": "лучшее",
|
"best": "лучшее",
|
||||||
"tab": "Вкладка по умолчанию"
|
"tab": "Вкладка по умолчанию",
|
||||||
|
"dark": "Темный (по умолчанию)",
|
||||||
|
"light": "Светлый",
|
||||||
|
"blur": "Размытый",
|
||||||
|
"blur_light": "Размытый (светлый)",
|
||||||
|
"dracula": "Дракула",
|
||||||
|
"nord": "Норд"
|
||||||
},
|
},
|
||||||
"instances": {
|
"instances": {
|
||||||
"piped": "Инстанс Piped",
|
"piped": "Инстанс Piped",
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
"volume": "Подразумевана јачина звука",
|
"volume": "Подразумевана јачина звука",
|
||||||
"tab": "Подразумевана Картица",
|
"tab": "Подразумевана Картица",
|
||||||
"light": "Светло",
|
"light": "Светло",
|
||||||
"blur": "Замућење",
|
"blur": "Замагљено",
|
||||||
"dracula": "Дракула",
|
"dracula": "Дракула",
|
||||||
"nord": "Норд",
|
"nord": "Норд",
|
||||||
"dark": "Мрачно (Подразумевано)",
|
"dark": "Мрачно (Подразумевано)",
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
"genres": "Türler",
|
"genres": "Türler",
|
||||||
"moods": "Ruh hâli",
|
"moods": "Ruh hâli",
|
||||||
"spotlight": "Spot ışıkları",
|
"spotlight": "Spot ışıkları",
|
||||||
"remote": "Uzak"
|
"remote": "Uzak",
|
||||||
|
"feeds": "Akışlar"
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"back": "Geri",
|
"back": "Geri",
|
||||||
|
@ -38,12 +39,18 @@
|
||||||
"player": "Ses Çalar",
|
"player": "Ses Çalar",
|
||||||
"auto_queue": "Şarkıları Otomatik Olarak Sırala",
|
"auto_queue": "Şarkıları Otomatik Olarak Sırala",
|
||||||
"codec": "Codec",
|
"codec": "Codec",
|
||||||
"tab": "Varsayılan Sekme",
|
"tab": "Öntanımlı Sekme",
|
||||||
"quality": "Kalite",
|
"quality": "Kalite",
|
||||||
"auto": "otomatik",
|
"auto": "otomatik",
|
||||||
"best": "en iyi",
|
"best": "en iyi",
|
||||||
"worst": "en kötü",
|
"worst": "en kötü",
|
||||||
"volume": "Varsayılan Ses Düzeyi"
|
"volume": "Öntanımlı Ses Düzeyi",
|
||||||
|
"dark": "Koyu (Öntanımlı)",
|
||||||
|
"light": "Açık",
|
||||||
|
"blur": "Bulanıklaştır",
|
||||||
|
"blur_light": "Bulanıklaştır (Açık)",
|
||||||
|
"dracula": "Dracula",
|
||||||
|
"nord": "Nord"
|
||||||
},
|
},
|
||||||
"info": {
|
"info": {
|
||||||
"see_all": "Hepsini Gör",
|
"see_all": "Hepsini Gör",
|
||||||
|
|
|
@ -10,7 +10,9 @@
|
||||||
"singles": "Các đĩa đơn",
|
"singles": "Các đĩa đơn",
|
||||||
"login": "Đăng nhập",
|
"login": "Đăng nhập",
|
||||||
"moods": "Chủ đề",
|
"moods": "Chủ đề",
|
||||||
"playlists": "Các danh sách phát"
|
"playlists": "Các danh sách phát",
|
||||||
|
"featured": "Nổi bật",
|
||||||
|
"feeds": "Nguồn cấp dữ liệu"
|
||||||
},
|
},
|
||||||
"pref": {
|
"pref": {
|
||||||
"auto": "tự động",
|
"auto": "tự động",
|
||||||
|
@ -20,28 +22,45 @@
|
||||||
"best": "cao nhất",
|
"best": "cao nhất",
|
||||||
"worst": "thấp nhất",
|
"worst": "thấp nhất",
|
||||||
"quality": "Chất lượng",
|
"quality": "Chất lượng",
|
||||||
"theme": "Giao diện"
|
"theme": "Giao diện",
|
||||||
|
"dark": "Tối (Mặc định)",
|
||||||
|
"light": "Sáng",
|
||||||
|
"blur": "Mờ",
|
||||||
|
"blur_light": "Mờ (Sáng)",
|
||||||
|
"nord": "Nord",
|
||||||
|
"dracula": "Dracula",
|
||||||
|
"auto_queue": "Tự động xếp hàng các bài hát",
|
||||||
|
"tab": "Thẻ mặc định"
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"cancel": "Hủy",
|
"cancel": "Hủy",
|
||||||
"create": "Tạo",
|
"create": "Tạo",
|
||||||
"add": "Thêm",
|
"add": "Thêm",
|
||||||
"back": "Quay lại",
|
"back": "Quay lại",
|
||||||
"receive": "Nhận"
|
"receive": "Nhận",
|
||||||
|
"send": "Gửi"
|
||||||
},
|
},
|
||||||
"instances": {
|
"instances": {
|
||||||
"version": "Phiên bản",
|
"version": "Phiên bản",
|
||||||
"name": "Tên",
|
"name": "Tên",
|
||||||
"cdn": "CDN",
|
"cdn": "CDN",
|
||||||
"loc": "Các vị trí",
|
"loc": "Các vị trí",
|
||||||
"up_to_date": "Phiên bản mới nhất"
|
"up_to_date": "Phiên bản mới nhất",
|
||||||
|
"auth": "Instance xác thực"
|
||||||
},
|
},
|
||||||
"playlist": {
|
"playlist": {
|
||||||
"create": "Tạo một danh sách phát mới",
|
"create": "Tạo một danh sách phát mới",
|
||||||
"name": "Tên danh sách phát",
|
"name": "Tên danh sách phát",
|
||||||
"add": "Thêm bài hát vào danh sách phát"
|
"add": "Thêm bài hát vào danh sách phát",
|
||||||
|
"sync": "Đồng bộ hóa các danh sách phát",
|
||||||
|
"select": "Lựa chọn danh sách phát để thêm"
|
||||||
},
|
},
|
||||||
"info": {
|
"info": {
|
||||||
"search": "Bắt đầu tìm kiếm"
|
"search": "Bắt đầu tìm kiếm",
|
||||||
|
"see_all": "Xem tất cả"
|
||||||
|
},
|
||||||
|
"lyrics": {
|
||||||
|
"load": "Tìm lời bài hát",
|
||||||
|
"void": "Không có lời bài hát"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
"songs": "歌曲",
|
"songs": "歌曲",
|
||||||
"albums": "专辑",
|
"albums": "专辑",
|
||||||
"login": "登录",
|
"login": "登录",
|
||||||
"playlists": "播放列表"
|
"playlists": "播放列表",
|
||||||
|
"feeds": "订阅源"
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"add": "添加",
|
"add": "添加",
|
||||||
|
@ -43,7 +44,13 @@
|
||||||
"worst": "最差",
|
"worst": "最差",
|
||||||
"volume": "默认音量",
|
"volume": "默认音量",
|
||||||
"theme": "主题",
|
"theme": "主题",
|
||||||
"tab": "默认标签页"
|
"tab": "默认标签页",
|
||||||
|
"blur": "模糊",
|
||||||
|
"dark": "深色(默认)",
|
||||||
|
"light": "亮色",
|
||||||
|
"blur_light": "模糊(亮色)",
|
||||||
|
"dracula": "Dracula",
|
||||||
|
"nord": "Nord"
|
||||||
},
|
},
|
||||||
"info": {
|
"info": {
|
||||||
"see_all": "显示全部",
|
"see_all": "显示全部",
|
||||||
|
|
|
@ -92,6 +92,10 @@ export const SUPPORTED_LOCALES = [
|
||||||
code: 'zh_Hans',
|
code: 'zh_Hans',
|
||||||
name: '中文 (简体)',
|
name: '中文 (简体)',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
code: 'pt_br',
|
||||||
|
name: 'Português Brasileiro',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const useNav = defineStore('nav', () => {
|
export const useNav = defineStore('nav', () => {
|
||||||
|
|
|
@ -29,7 +29,7 @@ export const useData = defineStore('data', () => {
|
||||||
|
|
||||||
console.log(json);
|
console.log(json);
|
||||||
|
|
||||||
state.art = json.thumbnailUrl;
|
state.art = json.thumbnailUrl.replaceAll('&', '&');
|
||||||
state.description = json.description;
|
state.description = json.description;
|
||||||
state.title = json.title.replaceAll('&', '&');
|
state.title = json.title.replaceAll('&', '&');
|
||||||
state.artist = json.uploader
|
state.artist = json.uploader
|
||||||
|
|
|
@ -68,7 +68,7 @@ export const useResults = defineStore('results', () => {
|
||||||
useNav().state.page = 'home';
|
useNav().state.page = 'home';
|
||||||
|
|
||||||
next.value =
|
next.value =
|
||||||
json.nextpage || json.nextpage != 'null'
|
json.nextpage && json.nextpage != 'null'
|
||||||
? hash + '?nextpage=' + encodeURIComponent(json.nextpage)
|
? hash + '?nextpage=' + encodeURIComponent(json.nextpage)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue