Add eslint rules for i18n
This commit is contained in:
parent
ebea32faf9
commit
edfbf94313
|
@ -2,9 +2,20 @@
|
||||||
"python.defaultInterpreterPath": "/workspace/funkwhale/api/.venv/bin/python",
|
"python.defaultInterpreterPath": "/workspace/funkwhale/api/.venv/bin/python",
|
||||||
"python.testing.cwd": "/workspace/funkwhale/api",
|
"python.testing.cwd": "/workspace/funkwhale/api",
|
||||||
"python.envFile": "/workspace/funkwhale/.gitpod/.env",
|
"python.envFile": "/workspace/funkwhale/.gitpod/.env",
|
||||||
"python.testing.pytestArgs": ["--cov=funkwhale_api", "tests/"],
|
"python.testing.pytestArgs": [
|
||||||
|
"--cov=funkwhale_api",
|
||||||
|
"tests/"
|
||||||
|
],
|
||||||
"python.testing.unittestEnabled": false,
|
"python.testing.unittestEnabled": false,
|
||||||
"python.testing.pytestEnabled": true,
|
"python.testing.pytestEnabled": true,
|
||||||
"vitest.enable": true,
|
"vitest.enable": true,
|
||||||
"vitest.commandLine": "yarn vitest"
|
"vitest.commandLine": "yarn vitest",
|
||||||
|
"i18n-ally.localesPaths": [
|
||||||
|
"front/src/locales"
|
||||||
|
],
|
||||||
|
"i18n-ally.pathMatcher": "*.json",
|
||||||
|
"i18n-ally.enabledFrameworks": [
|
||||||
|
"vue"
|
||||||
|
],
|
||||||
|
"i18n-ally.keystyle": "nested"
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
extends: [
|
extends: [
|
||||||
'plugin:vue/vue3-recommended',
|
'plugin:vue/vue3-recommended',
|
||||||
|
'plugin:@intlify/vue-i18n/recommended',
|
||||||
'@vue/typescript/recommended',
|
'@vue/typescript/recommended',
|
||||||
'@vue/standard'
|
'@vue/standard'
|
||||||
],
|
],
|
||||||
|
@ -32,6 +33,11 @@ module.exports = {
|
||||||
'no-redeclare': 'off',
|
'no-redeclare': 'off',
|
||||||
'no-undef': 'off',
|
'no-undef': 'off',
|
||||||
|
|
||||||
|
// NOTE: i18n
|
||||||
|
'@intlify/vue-i18n/valid-message-syntax': 'error',
|
||||||
|
'@intlify/vue-i18n/no-missing-keys': 'error',
|
||||||
|
'@intlify/vue-i18n/no-dynamic-keys': 'error',
|
||||||
|
|
||||||
// TODO (wvffle): Remove after VUI and #1618
|
// TODO (wvffle): Remove after VUI and #1618
|
||||||
'vue/multi-word-component-names': 'off',
|
'vue/multi-word-component-names': 'off',
|
||||||
'import/extensions': 'off',
|
'import/extensions': 'off',
|
||||||
|
@ -51,5 +57,11 @@ module.exports = {
|
||||||
'vue/comment-directive': 'off'
|
'vue/comment-directive': 'off'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
settings: {
|
||||||
|
'vue-i18n': {
|
||||||
|
localeDir: 'src/locales/*.{json,json5,yaml,yml}',
|
||||||
|
messageSyntaxVersion: '^9.0.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -58,6 +58,8 @@
|
||||||
"vuex-router-sync": "5.0.0"
|
"vuex-router-sync": "5.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@intlify/eslint-plugin-vue-i18n": "^2.0.0",
|
||||||
|
"@intlify/vite-plugin-vue-i18n": "^6.0.1",
|
||||||
"@types/diff": "5.0.2",
|
"@types/diff": "5.0.2",
|
||||||
"@types/dompurify": "2.4.0",
|
"@types/dompurify": "2.4.0",
|
||||||
"@types/howler": "2.2.7",
|
"@types/howler": "2.2.7",
|
||||||
|
|
|
@ -67,14 +67,10 @@ const headerStyle = computed(() => {
|
||||||
<div class="column" />
|
<div class="column" />
|
||||||
</div>
|
</div>
|
||||||
<h2 class="header">
|
<h2 class="header">
|
||||||
<translate >
|
A social platform to enjoy and share music
|
||||||
A social platform to enjoy and share music
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Funkwhale is a community-driven project that lets you listen and share music and audio within a decentralized, open network.
|
||||||
Funkwhale is a community-driven project that lets you listen and share music and audio within a decentralized, open network.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -88,23 +84,14 @@ const headerStyle = computed(() => {
|
||||||
class="signup-form content"
|
class="signup-form content"
|
||||||
>
|
>
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate >
|
Sign up
|
||||||
Sign up
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<template v-if="openRegistrations">
|
<template v-if="openRegistrations">
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Sign up now to keep a track of your favorites, create playlists, discover new content and much more!
|
||||||
Sign up now to keep a track of your favorites, create playlists, discover new content and much more!
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<p v-if="defaultUploadQuota">
|
<p v-if="defaultUploadQuota">
|
||||||
<translate
|
Users on this pod also get %{ quota } of free storage to upload their own content!
|
||||||
|
|
||||||
:translate-params="{quota: defaultUploadQuota}"
|
|
||||||
>
|
|
||||||
Users on this pod also get %{ quota } of free storage to upload their own content!
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<signup-form
|
<signup-form
|
||||||
button-classes="success"
|
button-classes="success"
|
||||||
|
@ -112,7 +99,7 @@ const headerStyle = computed(() => {
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<p >
|
<p>
|
||||||
Registrations are closed on this pod. You can signup on another pod using the link below.
|
Registrations are closed on this pod. You can signup on another pod using the link below.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -121,7 +108,7 @@ const headerStyle = computed(() => {
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
href="https://funkwhale.audio/#get-started"
|
href="https://funkwhale.audio/#get-started"
|
||||||
>
|
>
|
||||||
<translate >Find another pod</translate>
|
Find another pod
|
||||||
<i class="external alternate icon" />
|
<i class="external alternate icon" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -131,19 +118,13 @@ const headerStyle = computed(() => {
|
||||||
class="signup-form content"
|
class="signup-form content"
|
||||||
>
|
>
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate >
|
Sign up
|
||||||
Sign up
|
|
||||||
</translate>
|
|
||||||
<div class="ui positive message">
|
<div class="ui positive message">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<translate >
|
You're already signed in!
|
||||||
You're already signed in!
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
<translate translate-contect="Content/About/Hello">
|
Hello {{ $store.state.auth.username }}
|
||||||
Hello
|
|
||||||
</translate> {{ $store.state.auth.username }}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</h3>
|
</h3>
|
||||||
|
@ -164,9 +145,7 @@ const headerStyle = computed(() => {
|
||||||
id="description"
|
id="description"
|
||||||
class="ui header"
|
class="ui header"
|
||||||
>
|
>
|
||||||
<translate >
|
About this pod
|
||||||
About this pod
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div
|
<div
|
||||||
v-if="shortDescription"
|
v-if="shortDescription"
|
||||||
|
@ -175,9 +154,7 @@ const headerStyle = computed(() => {
|
||||||
{{ shortDescription }}
|
{{ shortDescription }}
|
||||||
</div>
|
</div>
|
||||||
<p v-else>
|
<p v-else>
|
||||||
<translate >
|
No description available.
|
||||||
No description available.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<template v-if="stats">
|
<template v-if="stats">
|
||||||
|
@ -187,22 +164,14 @@ const headerStyle = computed(() => {
|
||||||
<span class="statistics-figure ui text">
|
<span class="statistics-figure ui text">
|
||||||
<span class="ui big text"><strong>{{ stats.users.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
<span class="ui big text"><strong>{{ stats.users.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
||||||
<br>
|
<br>
|
||||||
<translate
|
{{ $t('active user | active users', stats.users) }}
|
||||||
|
|
||||||
:translate-n="stats.users"
|
|
||||||
translate-plural="active users"
|
|
||||||
>active user</translate>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<span class="statistics-figure ui text">
|
<span class="statistics-figure ui text">
|
||||||
<span class="ui big text"><strong>{{ stats.hours.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
<span class="ui big text"><strong>{{ stats.hours.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
||||||
<br>
|
<br>
|
||||||
<translate
|
{{ $t('hour of music | hours of music', stats.hours) }}
|
||||||
translate-context="Content/About/*"
|
|
||||||
:translate-n="stats.hours"
|
|
||||||
translate-plural="hours of music"
|
|
||||||
>hour of music</translate>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -213,9 +182,7 @@ const headerStyle = computed(() => {
|
||||||
to="/about/pod"
|
to="/about/pod"
|
||||||
class="ui fluid basic secondary button"
|
class="ui fluid basic secondary button"
|
||||||
>
|
>
|
||||||
<translate >
|
Learn More
|
||||||
Learn More
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -234,14 +201,10 @@ const headerStyle = computed(() => {
|
||||||
id="description"
|
id="description"
|
||||||
class="ui header"
|
class="ui header"
|
||||||
>
|
>
|
||||||
<translate >
|
Browse public content
|
||||||
Browse public content
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Listen to public albums and playlists shared on this pod.
|
||||||
Listen to public albums and playlists shared on this pod.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -255,11 +218,11 @@ const headerStyle = computed(() => {
|
||||||
id="description"
|
id="description"
|
||||||
class="ui header"
|
class="ui header"
|
||||||
>
|
>
|
||||||
<translate >Find another pod</translate>
|
Find another pod
|
||||||
<i class="external alternate icon" />
|
<i class="external alternate icon" />
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
<translate >Listen to public albums and playlists shared on this pod.</translate>
|
Listen to public albums and playlists shared on this pod.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -273,11 +236,11 @@ const headerStyle = computed(() => {
|
||||||
id="description"
|
id="description"
|
||||||
class="ui header"
|
class="ui header"
|
||||||
>
|
>
|
||||||
<translate >Find an app</translate>
|
Find an app
|
||||||
<i class="external alternate icon" />
|
<i class="external alternate icon" />
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
<translate >Use Funkwhale on other devices with our apps.</translate>
|
Use Funkwhale on other devices with our apps.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -287,9 +250,7 @@ const headerStyle = computed(() => {
|
||||||
to="/about/pod"
|
to="/about/pod"
|
||||||
class="ui right floated basic secondary button"
|
class="ui right floated basic secondary button"
|
||||||
>
|
>
|
||||||
<translate >
|
About this pod
|
||||||
About this pod
|
|
||||||
</translate>
|
|
||||||
<i class="icon arrow right" />
|
<i class="icon arrow right" />
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -99,42 +99,32 @@ const headerStyle = computed(() => {
|
||||||
to="/about/pod"
|
to="/about/pod"
|
||||||
class="item"
|
class="item"
|
||||||
>
|
>
|
||||||
<translate >
|
About this pod
|
||||||
About this pod
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
to="/about/pod#rules"
|
to="/about/pod#rules"
|
||||||
class="item"
|
class="item"
|
||||||
>
|
>
|
||||||
<translate >
|
Rules
|
||||||
Rules
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
to="/about/pod#terms"
|
to="/about/pod#terms"
|
||||||
class="item"
|
class="item"
|
||||||
>
|
>
|
||||||
<translate >
|
Terms and privacy policy
|
||||||
Terms and privacy policy
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
to="/about/pod#features"
|
to="/about/pod#features"
|
||||||
class="item"
|
class="item"
|
||||||
>
|
>
|
||||||
<translate >
|
Features
|
||||||
Features
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="stats"
|
v-if="stats"
|
||||||
to="/about/pod#statistics"
|
to="/about/pod#statistics"
|
||||||
class="item"
|
class="item"
|
||||||
>
|
>
|
||||||
<translate >
|
Statistics
|
||||||
Statistics
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -144,63 +134,49 @@ const headerStyle = computed(() => {
|
||||||
id="description about-this-pod"
|
id="description about-this-pod"
|
||||||
class="ui header"
|
class="ui header"
|
||||||
>
|
>
|
||||||
<translate >
|
About this pod
|
||||||
About this pod
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<sanitized-html
|
<sanitized-html
|
||||||
v-if="longDescription"
|
v-if="longDescription"
|
||||||
:html="longDescription"
|
:html="longDescription"
|
||||||
/>
|
/>
|
||||||
<p v-else>
|
<p v-else>
|
||||||
<translate >
|
No description available.
|
||||||
No description available.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3
|
<h3
|
||||||
id="rules"
|
id="rules"
|
||||||
class="ui header"
|
class="ui header"
|
||||||
>
|
>
|
||||||
<translate >
|
Rules
|
||||||
Rules
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<sanitized-html
|
<sanitized-html
|
||||||
v-if="rules"
|
v-if="rules"
|
||||||
:html="rules"
|
:html="rules"
|
||||||
/>
|
/>
|
||||||
<p v-else>
|
<p v-else>
|
||||||
<translate >
|
No rules available.
|
||||||
No rules available.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3
|
<h3
|
||||||
id="terms"
|
id="terms"
|
||||||
class="ui header"
|
class="ui header"
|
||||||
>
|
>
|
||||||
<translate >
|
Terms and privacy policy
|
||||||
Terms and privacy policy
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<sanitized-html
|
<sanitized-html
|
||||||
v-if="terms"
|
v-if="terms"
|
||||||
:html="terms"
|
:html="terms"
|
||||||
/>
|
/>
|
||||||
<p v-else>
|
<p v-else>
|
||||||
<translate >
|
No terms available.
|
||||||
No terms available.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3
|
<h3
|
||||||
id="features"
|
id="features"
|
||||||
class="header"
|
class="header"
|
||||||
>
|
>
|
||||||
<translate >
|
Features
|
||||||
Features
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div class="features-container ui two column stackable grid">
|
<div class="features-container ui two column stackable grid">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
|
@ -208,9 +184,7 @@ const headerStyle = computed(() => {
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<translate >
|
Funkwhale version
|
||||||
Funkwhale version
|
|
||||||
</translate>
|
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
v-if="version"
|
v-if="version"
|
||||||
|
@ -225,15 +199,13 @@ const headerStyle = computed(() => {
|
||||||
class="right aligned"
|
class="right aligned"
|
||||||
>
|
>
|
||||||
<span class="features-status ui text">
|
<span class="features-status ui text">
|
||||||
<translate >N/A</translate>
|
N/A
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<translate >
|
Federation
|
||||||
Federation
|
|
||||||
</translate>
|
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
v-if="federationEnabled"
|
v-if="federationEnabled"
|
||||||
|
@ -241,7 +213,7 @@ const headerStyle = computed(() => {
|
||||||
>
|
>
|
||||||
<span class="features-status ui text">
|
<span class="features-status ui text">
|
||||||
<i class="check icon" />
|
<i class="check icon" />
|
||||||
<translate >Enabled</translate>
|
Enabled
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
|
@ -250,15 +222,13 @@ const headerStyle = computed(() => {
|
||||||
>
|
>
|
||||||
<span class="features-status ui text">
|
<span class="features-status ui text">
|
||||||
<i class="x icon" />
|
<i class="x icon" />
|
||||||
<translate >Disabled</translate>
|
Disabled
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<translate >
|
Allow-list
|
||||||
Allow-list
|
|
||||||
</translate>
|
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
v-if="allowListEnabled"
|
v-if="allowListEnabled"
|
||||||
|
@ -266,7 +236,7 @@ const headerStyle = computed(() => {
|
||||||
>
|
>
|
||||||
<span class="features-status ui text">
|
<span class="features-status ui text">
|
||||||
<i class="check icon" />
|
<i class="check icon" />
|
||||||
<translate >Enabled</translate>
|
Enabled
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
|
@ -275,7 +245,7 @@ const headerStyle = computed(() => {
|
||||||
>
|
>
|
||||||
<span class="features-status ui text">
|
<span class="features-status ui text">
|
||||||
<i class="x icon" />
|
<i class="x icon" />
|
||||||
<translate >Disabled</translate>
|
Disabled
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -287,9 +257,7 @@ const headerStyle = computed(() => {
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<translate >
|
Anonymous access
|
||||||
Anonymous access
|
|
||||||
</translate>
|
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
v-if="anonymousCanListen"
|
v-if="anonymousCanListen"
|
||||||
|
@ -297,7 +265,7 @@ const headerStyle = computed(() => {
|
||||||
>
|
>
|
||||||
<span class="features-status ui text">
|
<span class="features-status ui text">
|
||||||
<i class="check icon" />
|
<i class="check icon" />
|
||||||
<translate >Enabled</translate>
|
Enabled
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
|
@ -306,15 +274,13 @@ const headerStyle = computed(() => {
|
||||||
>
|
>
|
||||||
<span class="features-status ui text">
|
<span class="features-status ui text">
|
||||||
<i class="x icon" />
|
<i class="x icon" />
|
||||||
<translate >Disabled</translate>
|
Disabled
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<translate >
|
Registrations
|
||||||
Registrations
|
|
||||||
</translate>
|
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
v-if="openRegistrations"
|
v-if="openRegistrations"
|
||||||
|
@ -322,7 +288,7 @@ const headerStyle = computed(() => {
|
||||||
>
|
>
|
||||||
<span class="features-status ui text">
|
<span class="features-status ui text">
|
||||||
<i class="check icon" />
|
<i class="check icon" />
|
||||||
<translate >Open</translate>
|
Open
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
|
@ -331,15 +297,13 @@ const headerStyle = computed(() => {
|
||||||
>
|
>
|
||||||
<span class="features-status ui text">
|
<span class="features-status ui text">
|
||||||
<i class="x icon" />
|
<i class="x icon" />
|
||||||
<translate >Closed</translate>
|
Closed
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<translate >
|
Upload quota
|
||||||
Upload quota
|
|
||||||
</translate>
|
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
v-if="defaultUploadQuota"
|
v-if="defaultUploadQuota"
|
||||||
|
@ -354,7 +318,7 @@ const headerStyle = computed(() => {
|
||||||
class="right aligned"
|
class="right aligned"
|
||||||
>
|
>
|
||||||
<span class="features-status ui text">
|
<span class="features-status ui text">
|
||||||
<translate >N/A</translate>
|
N/A
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -368,9 +332,7 @@ const headerStyle = computed(() => {
|
||||||
id="statistics"
|
id="statistics"
|
||||||
class="header"
|
class="header"
|
||||||
>
|
>
|
||||||
<translate >
|
Statistics
|
||||||
Statistics
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div class="statistics-container">
|
<div class="statistics-container">
|
||||||
<div
|
<div
|
||||||
|
@ -380,11 +342,7 @@ const headerStyle = computed(() => {
|
||||||
<span class="statistics-figure ui text">
|
<span class="statistics-figure ui text">
|
||||||
<span class="ui big text"><strong>{{ stats.hours.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
<span class="ui big text"><strong>{{ stats.hours.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
||||||
<br>
|
<br>
|
||||||
<translate
|
{{ $t('hour of music | hours of music', stats.hours) }}
|
||||||
translate-context="Content/About/*"
|
|
||||||
:translate-n="stats.hours"
|
|
||||||
translate-plural="hours of music"
|
|
||||||
>hour of music</translate>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -394,11 +352,7 @@ const headerStyle = computed(() => {
|
||||||
<span class="statistics-figure ui text">
|
<span class="statistics-figure ui text">
|
||||||
<span class="ui big text"><strong>{{ stats.artists.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
<span class="ui big text"><strong>{{ stats.artists.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
||||||
<br>
|
<br>
|
||||||
<translate
|
{{ $t('artist | artists', stats.artists) }}
|
||||||
|
|
||||||
:translate-n="stats.artists"
|
|
||||||
translate-plural="artists"
|
|
||||||
>artist</translate>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -408,11 +362,7 @@ const headerStyle = computed(() => {
|
||||||
<span class="statistics-figure ui text">
|
<span class="statistics-figure ui text">
|
||||||
<span class="ui big text"><strong>{{ stats.albums.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
<span class="ui big text"><strong>{{ stats.albums.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
||||||
<br>
|
<br>
|
||||||
<translate
|
{{ $t('album | albums', stats.albums) }}
|
||||||
|
|
||||||
:translate-n="stats.albums"
|
|
||||||
translate-plural="albums"
|
|
||||||
>album</translate>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -422,11 +372,7 @@ const headerStyle = computed(() => {
|
||||||
<span class="statistics-figure ui text">
|
<span class="statistics-figure ui text">
|
||||||
<span class="ui big text"><strong>{{ stats.tracks.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
<span class="ui big text"><strong>{{ stats.tracks.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
||||||
<br>
|
<br>
|
||||||
<translate
|
{{ $t('track | tracks', stats.tracks) }}
|
||||||
|
|
||||||
:translate-n="stats.tracks"
|
|
||||||
translate-plural="tracks"
|
|
||||||
>track</translate>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -436,11 +382,7 @@ const headerStyle = computed(() => {
|
||||||
<span class="statistics-figure ui text">
|
<span class="statistics-figure ui text">
|
||||||
<span class="ui big text"><strong>{{ stats.users.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
<span class="ui big text"><strong>{{ stats.users.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
||||||
<br>
|
<br>
|
||||||
<translate
|
{{ $t('active user | active users', stats.users) }}
|
||||||
|
|
||||||
:translate-n="stats.users"
|
|
||||||
translate-plural="active users"
|
|
||||||
>active user</translate>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -450,11 +392,7 @@ const headerStyle = computed(() => {
|
||||||
<span class="statistics-figure ui text">
|
<span class="statistics-figure ui text">
|
||||||
<span class="ui big text"><strong>{{ stats.listenings.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
<span class="ui big text"><strong>{{ stats.listenings.toLocaleString($store.state.ui.momentLocale) }}</strong></span>
|
||||||
<br>
|
<br>
|
||||||
<translate
|
{{ $t('listening | listenings', stats.listenings) }}
|
||||||
|
|
||||||
:translate-n="stats.listenings"
|
|
||||||
translate-plural="listenings"
|
|
||||||
>listening</translate>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -465,18 +403,13 @@ const headerStyle = computed(() => {
|
||||||
id="contact"
|
id="contact"
|
||||||
class="ui header"
|
class="ui header"
|
||||||
>
|
>
|
||||||
<translate >
|
Contact
|
||||||
Contact
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<a
|
<a
|
||||||
v-if="contactEmail"
|
v-if="contactEmail"
|
||||||
:href="`mailto:${contactEmail}`"
|
:href="`mailto:${contactEmail}`"
|
||||||
>
|
>
|
||||||
<translate
|
{{ $t('Send us an email: %{ contactEmail }', { contactEmail }) }}
|
||||||
|
|
||||||
:translate-params="{ email: contactEmail }"
|
|
||||||
>Send us an email: {{ contactEmail }}</translate>
|
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -487,9 +420,7 @@ const headerStyle = computed(() => {
|
||||||
class="ui left floated basic secondary button"
|
class="ui left floated basic secondary button"
|
||||||
>
|
>
|
||||||
<i class="icon arrow left" />
|
<i class="icon arrow left" />
|
||||||
<translate >
|
Introduction
|
||||||
Introduction
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -70,12 +70,9 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
>
|
>
|
||||||
<div class="segment-content">
|
<div class="segment-content">
|
||||||
<h1 class="ui center aligned large header">
|
<h1 class="ui center aligned large header">
|
||||||
<translate
|
<span>
|
||||||
:translate-params="{podName: podName}"
|
{{ $t('Welcome to %{ podName }!', { podName }) }}
|
||||||
tag="span"
|
</span>
|
||||||
>
|
|
||||||
Welcome to %{ podName }!
|
|
||||||
</translate>
|
|
||||||
<div
|
<div
|
||||||
v-if="shortDescription"
|
v-if="shortDescription"
|
||||||
class="sub header"
|
class="sub header"
|
||||||
|
@ -89,9 +86,7 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
<div class="ui stackable grid">
|
<div class="ui stackable grid">
|
||||||
<div class="ten wide column">
|
<div class="ten wide column">
|
||||||
<h2 class="header">
|
<h2 class="header">
|
||||||
<translate >
|
About this Funkwhale pod
|
||||||
About this Funkwhale pod
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<div
|
<div
|
||||||
id="pod"
|
id="pod"
|
||||||
|
@ -100,9 +95,7 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
<div class="ui stackable grid">
|
<div class="ui stackable grid">
|
||||||
<div class="eight wide column">
|
<div class="eight wide column">
|
||||||
<p v-if="!longDescription">
|
<p v-if="!longDescription">
|
||||||
<translate >
|
No description available.
|
||||||
No description available.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<template v-if="longDescription || rules">
|
<template v-if="longDescription || rules">
|
||||||
<sanitized-html
|
<sanitized-html
|
||||||
|
@ -125,9 +118,7 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
class="ui link"
|
class="ui link"
|
||||||
:to="{name: 'about'}"
|
:to="{name: 'about'}"
|
||||||
>
|
>
|
||||||
<translate >
|
Learn more
|
||||||
Learn more
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -142,9 +133,7 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
class="ui link"
|
class="ui link"
|
||||||
:to="{name: 'about', hash: '#rules'}"
|
:to="{name: 'about', hash: '#rules'}"
|
||||||
>
|
>
|
||||||
<translate >
|
Server rules
|
||||||
Server rules
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -154,36 +143,20 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
<div class="eight wide column">
|
<div class="eight wide column">
|
||||||
<template v-if="stats">
|
<template v-if="stats">
|
||||||
<h3 class="sub header">
|
<h3 class="sub header">
|
||||||
<translate >
|
Statistics
|
||||||
Statistics
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
<i class="user icon" /><translate
|
<i class="user icon" />
|
||||||
|
{{ $t('%{ users } active user | %{ users } active users', stats, stats.users) }}
|
||||||
:translate-params="{count: stats.users.toLocaleString($store.state.ui.momentLocale) }"
|
|
||||||
:translate-n="stats.users"
|
|
||||||
translate-plural="%{ count } active users"
|
|
||||||
>
|
|
||||||
%{ count } active user
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<i class="music icon" /><translate
|
<i class="music icon" />
|
||||||
translate-context="Content/Home/Stat"
|
{{ $t('%{ hours } hour of music | %{ hours } hours of music', stats, stats.hours) }}
|
||||||
:translate-params="{count: stats.hours.toLocaleString($store.state.ui.momentLocale)}"
|
|
||||||
:translate-n="stats.hours"
|
|
||||||
translate-plural="%{ count } hours of music"
|
|
||||||
>
|
|
||||||
%{ count } hour of music
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="contactEmail">
|
<template v-if="contactEmail">
|
||||||
<h3 class="sub header">
|
<h3 class="sub header">
|
||||||
<translate >
|
Contact
|
||||||
Contact
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<i class="at icon" />
|
<i class="at icon" />
|
||||||
<a :href="`mailto:${contactEmail}`">{{ contactEmail }}</a>
|
<a :href="`mailto:${contactEmail}`">{{ contactEmail }}</a>
|
||||||
|
@ -206,30 +179,26 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
<div class="ui stackable grid">
|
<div class="ui stackable grid">
|
||||||
<div class="four wide column">
|
<div class="four wide column">
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate >
|
About Funkwhale
|
||||||
About Funkwhale
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<translate tag="p">
|
<p>
|
||||||
This pod runs Funkwhale, a community-driven project that lets you listen and share music and audio within a decentralized, open network.
|
This pod runs Funkwhale, a community-driven project that lets you listen and share music and audio within a decentralized, open network.
|
||||||
</translate>
|
</p>
|
||||||
<translate tag="p">
|
<p>
|
||||||
Funkwhale is free and developed by a friendly community of volunteers.
|
Funkwhale is free and developed by a friendly community of volunteers.
|
||||||
</translate>
|
</p>
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
href="https://funkwhale.audio"
|
href="https://funkwhale.audio"
|
||||||
>
|
>
|
||||||
<i class="external alternate icon" />
|
<i class="external alternate icon" />
|
||||||
<translate >Visit funkwhale.audio</translate>
|
Visit funkwhale.audio
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="four wide column">
|
<div class="four wide column">
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate >
|
Log In
|
||||||
Log In
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<login-form
|
<login-form
|
||||||
button-classes="success"
|
button-classes="success"
|
||||||
|
@ -239,23 +208,14 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
</div>
|
</div>
|
||||||
<div class="four wide column">
|
<div class="four wide column">
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate >
|
Sign up
|
||||||
Sign up
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<template v-if="openRegistrations">
|
<template v-if="openRegistrations">
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Sign up now to keep track of your favorites, create playlists, discover new content and much more!
|
||||||
Sign up now to keep track of your favorites, create playlists, discover new content and much more!
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<p v-if="defaultUploadQuota">
|
<p v-if="defaultUploadQuota">
|
||||||
<translate
|
{{ $t('Users on this pod also get %{ quota } of free storage to upload their own content!', { quota: humanSize(defaultUploadQuota * 1000 * 1000) }) }}
|
||||||
|
|
||||||
:translate-params="{quota: humanSize(defaultUploadQuota * 1000 * 1000)}"
|
|
||||||
>
|
|
||||||
Users on this pod also get %{ quota } of free storage to upload their own content!
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<signup-form
|
<signup-form
|
||||||
button-classes="success"
|
button-classes="success"
|
||||||
|
@ -263,7 +223,7 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<p >
|
<p>
|
||||||
Registrations are closed on this pod. You can signup on another pod using the link below.
|
Registrations are closed on this pod. You can signup on another pod using the link below.
|
||||||
</p>
|
</p>
|
||||||
<a
|
<a
|
||||||
|
@ -272,16 +232,14 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
href="https://funkwhale.audio/#get-started"
|
href="https://funkwhale.audio/#get-started"
|
||||||
>
|
>
|
||||||
<i class="external alternate icon" />
|
<i class="external alternate icon" />
|
||||||
<translate >Find another pod</translate>
|
Find another pod
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="four wide column">
|
<div class="four wide column">
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate >
|
Useful links
|
||||||
Useful links
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div class="ui relaxed list">
|
<div class="ui relaxed list">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
|
@ -292,14 +250,10 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
class="header"
|
class="header"
|
||||||
to="/library"
|
to="/library"
|
||||||
>
|
>
|
||||||
<translate >
|
Browse public content
|
||||||
Browse public content
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<translate >
|
Listen to public albums and playlists shared on this pod
|
||||||
Listen to public albums and playlists shared on this pod
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -312,12 +266,10 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
>
|
>
|
||||||
<translate >Mobile apps</translate>
|
Mobile apps
|
||||||
</a>
|
</a>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<translate >
|
Use Funkwhale on other devices with our apps
|
||||||
Use Funkwhale on other devices with our apps
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -330,12 +282,10 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
>
|
>
|
||||||
<translate >User guides</translate>
|
User guides
|
||||||
</a>
|
</a>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<translate >
|
Discover everything you need to know about Funkwhale and its features
|
||||||
Discover everything you need to know about Funkwhale and its features
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -352,22 +302,16 @@ whenever(() => store.state.auth.authenticated, () => {
|
||||||
:limit="10"
|
:limit="10"
|
||||||
>
|
>
|
||||||
<template #title>
|
<template #title>
|
||||||
<translate >
|
Recently added albums
|
||||||
Recently added albums
|
|
||||||
</translate>
|
|
||||||
</template>
|
</template>
|
||||||
<router-link to="/library">
|
<router-link to="/library">
|
||||||
<translate >
|
View more…
|
||||||
View more…
|
|
||||||
</translate>
|
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
</router-link>
|
</router-link>
|
||||||
</album-widget>
|
</album-widget>
|
||||||
<div class="ui hidden section divider" />
|
<div class="ui hidden section divider" />
|
||||||
<h3 class="ui header">
|
<h3 class="ui header">
|
||||||
<translate >
|
New channels
|
||||||
New channels
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<channels-widget
|
<channels-widget
|
||||||
:show-modification-date="true"
|
:show-modification-date="true"
|
||||||
|
|
|
@ -20,15 +20,11 @@ const labels = computed(() => ({
|
||||||
<h1 class="ui huge header">
|
<h1 class="ui huge header">
|
||||||
<i class="warning icon" />
|
<i class="warning icon" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<translate >
|
Page not found!
|
||||||
Page not found!
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</h1>
|
</h1>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Sorry, the page you asked for does not exist:
|
||||||
Sorry, the page you asked for does not exist:
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<a :href="path">{{ path }}</a>
|
<a :href="path">{{ path }}</a>
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
|
@ -36,9 +32,7 @@ const labels = computed(() => ({
|
||||||
class="ui icon labeled right button"
|
class="ui icon labeled right button"
|
||||||
to="/"
|
to="/"
|
||||||
>
|
>
|
||||||
<translate >
|
Go to home page
|
||||||
Go to home page
|
|
||||||
</translate>
|
|
||||||
<i class="right arrow icon" />
|
<i class="right arrow icon" />
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { whenever, watchDebounced, useCurrentElement, useScrollLock, useFullscre
|
||||||
import { nextTick, ref, computed, watchEffect, onMounted } from 'vue'
|
import { nextTick, ref, computed, watchEffect, onMounted } from 'vue'
|
||||||
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
|
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useStore } from '~/store'
|
import { useStore } from '~/store'
|
||||||
|
|
||||||
import { usePlayer } from '~/composables/audio/player'
|
import { usePlayer } from '~/composables/audio/player'
|
||||||
|
@ -17,10 +18,6 @@ import TrackFavoriteIcon from '~/components/favorites/TrackFavoriteIcon.vue'
|
||||||
import TrackPlaylistIcon from '~/components/playlists/TrackPlaylistIcon.vue'
|
import TrackPlaylistIcon from '~/components/playlists/TrackPlaylistIcon.vue'
|
||||||
import PlayerControls from '~/components/audio/PlayerControls.vue'
|
import PlayerControls from '~/components/audio/PlayerControls.vue'
|
||||||
import MilkDrop from '~/components/audio/visualizer/MilkDrop.vue'
|
import MilkDrop from '~/components/audio/visualizer/MilkDrop.vue'
|
||||||
import { whenever, watchDebounced, useCurrentElement, useScrollLock } from '@vueuse/core'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import useQueue from '~/composables/audio/useQueue'
|
|
||||||
import usePlayer from '~/composables/audio/usePlayer'
|
|
||||||
|
|
||||||
import VirtualList from '~/components/vui/list/VirtualList.vue'
|
import VirtualList from '~/components/vui/list/VirtualList.vue'
|
||||||
import QueueItem from '~/components/QueueItem.vue'
|
import QueueItem from '~/components/QueueItem.vue'
|
||||||
|
@ -301,20 +298,14 @@ const coverType = useStorage('queue:cover-type', CoverType.COVER_ART)
|
||||||
class="ui small warning message"
|
class="ui small warning message"
|
||||||
>
|
>
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate >
|
The track cannot be loaded
|
||||||
The track cannot be loaded
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<p v-if="hasNext && isPlaying">
|
<p v-if="hasNext && isPlaying">
|
||||||
<translate >
|
The next track will play automatically in a few seconds…
|
||||||
The next track will play automatically in a few seconds…
|
|
||||||
</translate>
|
|
||||||
<i class="loading spinner icon" />
|
<i class="loading spinner icon" />
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
You may have a connectivity issue.
|
||||||
You may have a connectivity issue.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -413,17 +404,13 @@ const coverType = useStorage('queue:cover-type', CoverType.COVER_ART)
|
||||||
class="ui right floated basic button"
|
class="ui right floated basic button"
|
||||||
@click="$store.commit('ui/queueFocused', null)"
|
@click="$store.commit('ui/queueFocused', null)"
|
||||||
>
|
>
|
||||||
<translate >
|
Close
|
||||||
Close
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="ui right floated basic button danger"
|
class="ui right floated basic button danger"
|
||||||
@click="clear"
|
@click="clear"
|
||||||
>
|
>
|
||||||
<translate >
|
Clear
|
||||||
Clear
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
{{ labels.queue }}
|
{{ labels.queue }}
|
||||||
<div class="sub header">
|
<div class="sub header">
|
||||||
|
@ -477,22 +464,17 @@ const coverType = useStorage('queue:cover-type', CoverType.COVER_ART)
|
||||||
>
|
>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<i class="feed icon" /> <translate >
|
<i class="feed icon" />
|
||||||
You have a radio playing
|
You have a radio playing
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
New tracks will be appended here automatically.
|
||||||
New tracks will be appended here automatically.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
class="ui basic primary button"
|
class="ui basic primary button"
|
||||||
@click="$store.dispatch('radios/stop')"
|
@click="$store.dispatch('radios/stop')"
|
||||||
>
|
>
|
||||||
<translate >
|
Stop radio
|
||||||
Stop radio
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -172,9 +172,7 @@ watch(() => props.initialId, () => {
|
||||||
@click.prevent="type = 'rss'"
|
@click.prevent="type = 'rss'"
|
||||||
>
|
>
|
||||||
<i class="feed icon" />
|
<i class="feed icon" />
|
||||||
<translate >
|
RSS
|
||||||
RSS
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<div class="or" />
|
<div class="or" />
|
||||||
<button
|
<button
|
||||||
|
@ -182,9 +180,7 @@ watch(() => props.initialId, () => {
|
||||||
@click.prevent="type = 'artists'"
|
@click.prevent="type = 'artists'"
|
||||||
>
|
>
|
||||||
<i class="globe icon" />
|
<i class="globe icon" />
|
||||||
<translate >
|
Fediverse
|
||||||
Fediverse
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
|
@ -199,9 +195,7 @@ watch(() => props.initialId, () => {
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate >
|
Error while fetching object
|
||||||
Error while fetching object
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -217,14 +211,10 @@ watch(() => props.initialId, () => {
|
||||||
{{ labels.fieldLabel }}
|
{{ labels.fieldLabel }}
|
||||||
</label>
|
</label>
|
||||||
<p v-if="type === 'rss'">
|
<p v-if="type === 'rss'">
|
||||||
<translate >
|
Use this form to subscribe to an RSS feed from its URL.
|
||||||
Use this form to subscribe to an RSS feed from its URL.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<p v-else-if="type === 'artists'">
|
<p v-else-if="type === 'artists'">
|
||||||
<translate >
|
Use this form to subscribe to a channel hosted somewhere else on the Fediverse.
|
||||||
Use this form to subscribe to a channel hosted somewhere else on the Fediverse.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<input
|
<input
|
||||||
id="object-id"
|
id="object-id"
|
||||||
|
@ -241,9 +231,7 @@ watch(() => props.initialId, () => {
|
||||||
:class="['ui', 'primary', {loading: isLoading}, 'button']"
|
:class="['ui', 'primary', {loading: isLoading}, 'button']"
|
||||||
:disabled="isLoading || !id || id.length === 0"
|
:disabled="isLoading || !id || id.length === 0"
|
||||||
>
|
>
|
||||||
<translate >
|
Search
|
||||||
Search
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<div
|
<div
|
||||||
|
@ -252,9 +240,7 @@ watch(() => props.initialId, () => {
|
||||||
class="ui warning message"
|
class="ui warning message"
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
This kind of object isn't supported yet
|
||||||
This kind of object isn't supported yet
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -71,9 +71,7 @@ const checkAndSwitch = async (url: string) => {
|
||||||
@update:show="isError = false"
|
@update:show="isError = false"
|
||||||
>
|
>
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate >
|
Choose your instance
|
||||||
Choose your instance
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div class="scrolling content">
|
<div class="scrolling content">
|
||||||
<div
|
<div
|
||||||
|
@ -82,20 +80,14 @@ const checkAndSwitch = async (url: string) => {
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
It is not possible to connect to the given URL
|
||||||
It is not possible to connect to the given URL
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li>
|
<li>
|
||||||
<translate >
|
The server might be down
|
||||||
The server might be down
|
|
||||||
</translate>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<translate >
|
The given address is not a Funkwhale server
|
||||||
The given address is not a Funkwhale server
|
|
||||||
</translate>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -107,7 +99,6 @@ const checkAndSwitch = async (url: string) => {
|
||||||
v-if="$store.state.instance.instanceUrl"
|
v-if="$store.state.instance.instanceUrl"
|
||||||
v-translate="{url: $store.state.instance.instanceUrl, hostname: $store.getters['instance/domain'] }"
|
v-translate="{url: $store.state.instance.instanceUrl, hostname: $store.getters['instance/domain'] }"
|
||||||
class="description"
|
class="description"
|
||||||
|
|
||||||
>
|
>
|
||||||
You are currently connected to <a
|
You are currently connected to <a
|
||||||
href="%{ url }"
|
href="%{ url }"
|
||||||
|
@ -115,12 +106,10 @@ const checkAndSwitch = async (url: string) => {
|
||||||
>%{ hostname } <i class="external icon" /></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted.
|
>%{ hostname } <i class="external icon" /></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted.
|
||||||
</p>
|
</p>
|
||||||
<p v-else>
|
<p v-else>
|
||||||
<translate >
|
To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices.
|
||||||
To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="instance-picker"><translate >Instance URL</translate></label>
|
<label for="instance-picker">Instance URL</label>
|
||||||
<div class="ui action input">
|
<div class="ui action input">
|
||||||
<input
|
<input
|
||||||
id="instance-picker"
|
id="instance-picker"
|
||||||
|
@ -132,9 +121,7 @@ const checkAndSwitch = async (url: string) => {
|
||||||
type="submit"
|
type="submit"
|
||||||
:class="['ui', 'icon', {loading: isLoading}, 'button']"
|
:class="['ui', 'icon', {loading: isLoading}, 'button']"
|
||||||
>
|
>
|
||||||
<translate >
|
Submit
|
||||||
Submit
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -146,9 +133,7 @@ const checkAndSwitch = async (url: string) => {
|
||||||
>
|
>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<h4>
|
<h4>
|
||||||
<translate >
|
Suggested choices
|
||||||
Suggested choices
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<button
|
<button
|
||||||
v-for="(url, key) in suggestedInstances"
|
v-for="(url, key) in suggestedInstances"
|
||||||
|
@ -163,9 +148,7 @@ const checkAndSwitch = async (url: string) => {
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="ui basic cancel button">
|
<button class="ui basic cancel button">
|
||||||
<translate >
|
Cancel
|
||||||
Cancel
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</semantic-modal>
|
</semantic-modal>
|
||||||
|
|
|
@ -110,9 +110,7 @@ const player = computed(() => [
|
||||||
<template>
|
<template>
|
||||||
<semantic-modal v-model:show="showRef">
|
<semantic-modal v-model:show="showRef">
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<translate >
|
Keyboard shortcuts
|
||||||
Keyboard shortcuts
|
|
||||||
</translate>
|
|
||||||
</header>
|
</header>
|
||||||
<section class="scrolling content">
|
<section class="scrolling content">
|
||||||
<div class="ui stackable two column grid">
|
<div class="ui stackable two column grid">
|
||||||
|
@ -156,9 +154,7 @@ const player = computed(() => [
|
||||||
</section>
|
</section>
|
||||||
<footer class="actions">
|
<footer class="actions">
|
||||||
<button class="ui basic cancel button">
|
<button class="ui basic cancel button">
|
||||||
<translate >
|
Close
|
||||||
Close
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</footer>
|
</footer>
|
||||||
</semantic-modal>
|
</semantic-modal>
|
||||||
|
|
|
@ -149,9 +149,7 @@ onMounted(() => {
|
||||||
</div>
|
</div>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate >
|
Administration
|
||||||
Administration
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div class="divider" />
|
<div class="divider" />
|
||||||
<router-link
|
<router-link
|
||||||
|
@ -166,9 +164,7 @@ onMounted(() => {
|
||||||
>
|
>
|
||||||
{{ $store.state.ui.notifications.pendingReviewEdits }}
|
{{ $store.state.ui.notifications.pendingReviewEdits }}
|
||||||
</div>
|
</div>
|
||||||
<translate >
|
Library
|
||||||
Library
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="$store.state.auth.availablePermissions['moderation']"
|
v-if="$store.state.auth.availablePermissions['moderation']"
|
||||||
|
@ -182,27 +178,21 @@ onMounted(() => {
|
||||||
>
|
>
|
||||||
{{ $store.state.ui.notifications.pendingReviewReports + $store.state.ui.notifications.pendingReviewRequests }}
|
{{ $store.state.ui.notifications.pendingReviewReports + $store.state.ui.notifications.pendingReviewRequests }}
|
||||||
</div>
|
</div>
|
||||||
<translate >
|
Moderation
|
||||||
Moderation
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="$store.state.auth.availablePermissions['settings']"
|
v-if="$store.state.auth.availablePermissions['settings']"
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'manage.users.users.list'}"
|
:to="{name: 'manage.users.users.list'}"
|
||||||
>
|
>
|
||||||
<translate >
|
Users
|
||||||
Users
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="$store.state.auth.availablePermissions['settings']"
|
v-if="$store.state.auth.availablePermissions['settings']"
|
||||||
class="item"
|
class="item"
|
||||||
:to="{path: '/manage/settings'}"
|
:to="{path: '/manage/settings'}"
|
||||||
>
|
>
|
||||||
<translate >
|
Settings
|
||||||
Settings
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -327,17 +317,17 @@ onMounted(() => {
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<fieldset
|
<fieldset
|
||||||
v-for="t in themes"
|
v-for="th in themes"
|
||||||
:key="t.key"
|
:key="th.key"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
:id="t.key"
|
:id="th.key"
|
||||||
v-model="theme"
|
v-model="theme"
|
||||||
type="radio"
|
type="radio"
|
||||||
name="theme"
|
name="theme"
|
||||||
:value="t.key"
|
:value="th.key"
|
||||||
>
|
>
|
||||||
<label :for="t.key">{{ t.name }}</label>
|
<label :for="th.key">{{ th.name }}</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
</semantic-modal>
|
</semantic-modal>
|
||||||
|
@ -362,18 +352,14 @@ onMounted(() => {
|
||||||
class="ui fluid tiny primary button"
|
class="ui fluid tiny primary button"
|
||||||
:to="{name: 'login'}"
|
:to="{name: 'login'}"
|
||||||
>
|
>
|
||||||
<translate >
|
Login
|
||||||
Login
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="ui small hidden divider" />
|
<div class="ui small hidden divider" />
|
||||||
<router-link
|
<router-link
|
||||||
class="ui fluid tiny button"
|
class="ui fluid tiny button"
|
||||||
:to="{path: '/signup'}"
|
:to="{path: '/signup'}"
|
||||||
>
|
>
|
||||||
<translate >
|
Create an account
|
||||||
Create an account
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<nav
|
<nav
|
||||||
|
@ -385,9 +371,7 @@ onMounted(() => {
|
||||||
id="navigation-label"
|
id="navigation-label"
|
||||||
class="visually-hidden"
|
class="visually-hidden"
|
||||||
>
|
>
|
||||||
<translate >
|
Main navigation
|
||||||
Main navigation
|
|
||||||
</translate>
|
|
||||||
</h1>
|
</h1>
|
||||||
<div class="ui small hidden divider" />
|
<div class="ui small hidden divider" />
|
||||||
<section
|
<section
|
||||||
|
@ -407,9 +391,7 @@ onMounted(() => {
|
||||||
@click="expanded = 'explore'"
|
@click="expanded = 'explore'"
|
||||||
@focus="expanded = 'explore'"
|
@focus="expanded = 'explore'"
|
||||||
>
|
>
|
||||||
<translate >
|
Explore
|
||||||
Explore
|
|
||||||
</translate>
|
|
||||||
<i
|
<i
|
||||||
v-if="expanded !== 'explore'"
|
v-if="expanded !== 'explore'"
|
||||||
class="angle right icon"
|
class="angle right icon"
|
||||||
|
@ -420,58 +402,44 @@ onMounted(() => {
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'search'}"
|
:to="{name: 'search'}"
|
||||||
>
|
>
|
||||||
<i class="search icon" /><translate >
|
<i class="search icon" /> Search
|
||||||
Search
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'library.index'}"
|
:to="{name: 'library.index'}"
|
||||||
active-class="_active"
|
active-class="_active"
|
||||||
>
|
>
|
||||||
<i class="music icon" /><translate >
|
<i class="music icon" /> Browse
|
||||||
Browse
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'library.podcasts.browse'}"
|
:to="{name: 'library.podcasts.browse'}"
|
||||||
>
|
>
|
||||||
<i class="podcast icon" /><translate >
|
<i class="podcast icon" /> Podcasts
|
||||||
Podcasts
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'library.albums.browse'}"
|
:to="{name: 'library.albums.browse'}"
|
||||||
>
|
>
|
||||||
<i class="compact disc icon" /><translate >
|
<i class="compact disc icon" /> Albums
|
||||||
Albums
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'library.artists.browse'}"
|
:to="{name: 'library.artists.browse'}"
|
||||||
>
|
>
|
||||||
<i class="user icon" /><translate >
|
<i class="user icon" /> Artists
|
||||||
Artists
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'library.playlists.browse'}"
|
:to="{name: 'library.playlists.browse'}"
|
||||||
>
|
>
|
||||||
<i class="list icon" /><translate >
|
<i class="list icon" /> Playlists
|
||||||
Playlists
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'library.radios.browse'}"
|
:to="{name: 'library.radios.browse'}"
|
||||||
>
|
>
|
||||||
<i class="feed icon" /><translate >
|
<i class="feed icon" /> Radios
|
||||||
Radios
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -486,9 +454,7 @@ onMounted(() => {
|
||||||
@click="expanded = 'myLibrary'"
|
@click="expanded = 'myLibrary'"
|
||||||
@focus="expanded = 'myLibrary'"
|
@focus="expanded = 'myLibrary'"
|
||||||
>
|
>
|
||||||
<translate >
|
My Library
|
||||||
My Library
|
|
||||||
</translate>
|
|
||||||
<i
|
<i
|
||||||
v-if="expanded !== 'myLibrary'"
|
v-if="expanded !== 'myLibrary'"
|
||||||
class="angle right icon"
|
class="angle right icon"
|
||||||
|
@ -499,49 +465,37 @@ onMounted(() => {
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'library.me'}"
|
:to="{name: 'library.me'}"
|
||||||
>
|
>
|
||||||
<i class="music icon" /><translate >
|
<i class="music icon" /> Browse
|
||||||
Browse
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'library.albums.me'}"
|
:to="{name: 'library.albums.me'}"
|
||||||
>
|
>
|
||||||
<i class="compact disc icon" /><translate >
|
<i class="compact disc icon" /> Albums
|
||||||
Albums
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'library.artists.me'}"
|
:to="{name: 'library.artists.me'}"
|
||||||
>
|
>
|
||||||
<i class="user icon" /><translate >
|
<i class="user icon" /> Artists
|
||||||
Artists
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'library.playlists.me'}"
|
:to="{name: 'library.playlists.me'}"
|
||||||
>
|
>
|
||||||
<i class="list icon" /><translate >
|
<i class="list icon" /> Playlists
|
||||||
Playlists
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'library.radios.me'}"
|
:to="{name: 'library.radios.me'}"
|
||||||
>
|
>
|
||||||
<i class="feed icon" /><translate >
|
<i class="feed icon" /> Radios
|
||||||
Radios
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
class="item"
|
class="item"
|
||||||
:to="{name: 'favorites'}"
|
:to="{name: 'favorites'}"
|
||||||
>
|
>
|
||||||
<i class="heart icon" /><translate >
|
<i class="heart icon" /> Favorites
|
||||||
Favorites
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -550,15 +504,11 @@ onMounted(() => {
|
||||||
class="header item"
|
class="header item"
|
||||||
:to="{name: 'subscriptions'}"
|
:to="{name: 'subscriptions'}"
|
||||||
>
|
>
|
||||||
<translate >
|
Channels
|
||||||
Channels
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate >
|
More
|
||||||
More
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
<router-link
|
<router-link
|
||||||
|
@ -566,9 +516,7 @@ onMounted(() => {
|
||||||
to="/about"
|
to="/about"
|
||||||
active-class="router-link-exact-active active"
|
active-class="router-link-exact-active active"
|
||||||
>
|
>
|
||||||
<i class="info icon" /><translate >
|
<i class="info icon" /> About this pod
|
||||||
About this pod
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -110,9 +110,7 @@ const save = async () => {
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Error while saving settings
|
||||||
Error while saving settings
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -127,9 +125,7 @@ const save = async () => {
|
||||||
v-if="result"
|
v-if="result"
|
||||||
class="ui positive message"
|
class="ui positive message"
|
||||||
>
|
>
|
||||||
<translate >
|
Settings updated successfully.
|
||||||
Settings updated successfully.
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-for="(setting, key) in settings"
|
v-for="(setting, key) in settings"
|
||||||
|
@ -229,9 +225,7 @@ const save = async () => {
|
||||||
<div v-if="values[setting.identifier]">
|
<div v-if="values[setting.identifier]">
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
<h3 class="ui header">
|
<h3 class="ui header">
|
||||||
<translate >
|
Current image
|
||||||
Current image
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<img
|
<img
|
||||||
v-if="values[setting.identifier]"
|
v-if="values[setting.identifier]"
|
||||||
|
@ -246,9 +240,7 @@ const save = async () => {
|
||||||
type="submit"
|
type="submit"
|
||||||
:class="['ui', {'loading': isLoading}, 'right', 'floated', 'success', 'button']"
|
:class="['ui', {'loading': isLoading}, 'right', 'floated', 'success', 'button']"
|
||||||
>
|
>
|
||||||
<translate >
|
Save
|
||||||
Save
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -69,17 +69,13 @@ const move = (idx: number, increment: number) => {
|
||||||
:class="[{active: !isPreviewing}, 'item']"
|
:class="[{active: !isPreviewing}, 'item']"
|
||||||
@click.stop.prevent="isPreviewing = false"
|
@click.stop.prevent="isPreviewing = false"
|
||||||
>
|
>
|
||||||
<translate >
|
Edit form
|
||||||
Edit form
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
:class="[{active: isPreviewing}, 'item']"
|
:class="[{active: isPreviewing}, 'item']"
|
||||||
@click.stop.prevent="isPreviewing = true"
|
@click.stop.prevent="isPreviewing = true"
|
||||||
>
|
>
|
||||||
<translate >
|
Preview form
|
||||||
Preview form
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -99,12 +95,10 @@ const move = (idx: number, increment: number) => {
|
||||||
>
|
>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="help-text">
|
<label for="help-text">
|
||||||
<translate >Help text</translate>
|
Help text
|
||||||
</label>
|
</label>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
An optional text to be displayed at the start of the sign-up form.
|
||||||
An optional text to be displayed at the start of the sign-up form.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<content-form
|
<content-form
|
||||||
v-if="value.help_text"
|
v-if="value.help_text"
|
||||||
|
@ -115,32 +109,24 @@ const move = (idx: number, increment: number) => {
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>
|
<label>
|
||||||
<translate >Additional fields</translate>
|
Additional fields
|
||||||
</label>
|
</label>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Additional form fields to be displayed in the form. Only shown if manual sign-up validation is enabled.
|
||||||
Additional form fields to be displayed in the form. Only shown if manual sign-up validation is enabled.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<table v-if="value.fields?.length > 0">
|
<table v-if="value.fields?.length > 0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<translate >
|
Field label
|
||||||
Field label
|
|
||||||
</translate>
|
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<translate >
|
Field type
|
||||||
Field type
|
|
||||||
</translate>
|
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<translate >
|
Required
|
||||||
Required
|
|
||||||
</translate>
|
|
||||||
</th>
|
</th>
|
||||||
<th><span class="visually-hidden"><translate >Actions</translate></span></th>
|
<th><span class="visually-hidden">Actions</span></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -158,28 +144,20 @@ const move = (idx: number, increment: number) => {
|
||||||
<td>
|
<td>
|
||||||
<select v-model="field.input_type">
|
<select v-model="field.input_type">
|
||||||
<option value="short_text">
|
<option value="short_text">
|
||||||
<translate >
|
Short text
|
||||||
Short text
|
|
||||||
</translate>
|
|
||||||
</option>
|
</option>
|
||||||
<option value="long_text">
|
<option value="long_text">
|
||||||
<translate >
|
Long text
|
||||||
Long text
|
|
||||||
</translate>
|
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select v-model="field.required">
|
<select v-model="field.required">
|
||||||
<option :value="true">
|
<option :value="true">
|
||||||
<translate >
|
Yes
|
||||||
Yes
|
|
||||||
</translate>
|
|
||||||
</option>
|
</option>
|
||||||
<option :value="false">
|
<option :value="false">
|
||||||
<translate >
|
No
|
||||||
No
|
|
||||||
</translate>
|
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
|
@ -214,9 +192,7 @@ const move = (idx: number, increment: number) => {
|
||||||
class="ui basic button"
|
class="ui basic button"
|
||||||
@click.stop.prevent="addField"
|
@click.stop.prevent="addField"
|
||||||
>
|
>
|
||||||
<translate >
|
Add a new field
|
||||||
Add a new field
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -103,9 +103,7 @@ watch(page, fetchData, { immediate: true })
|
||||||
@refresh="fetchData()"
|
@refresh="fetchData()"
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
You may need to subscribe to this channel to see its content.
|
||||||
You may need to subscribe to this channel to see its content.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</empty-state>
|
</empty-state>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -165,9 +165,7 @@ defineExpose({
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Error while saving channel
|
||||||
Error while saving channel
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -184,9 +182,7 @@ defineExpose({
|
||||||
class="ui grouped channel-type required field"
|
class="ui grouped channel-type required field"
|
||||||
>
|
>
|
||||||
<legend>
|
<legend>
|
||||||
<translate >
|
What will this channel be used for?
|
||||||
What will this channel be used for?
|
|
||||||
</translate>
|
|
||||||
</legend>
|
</legend>
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
@ -214,7 +210,7 @@ defineExpose({
|
||||||
<template v-if="!creating || step === 2">
|
<template v-if="!creating || step === 2">
|
||||||
<div class="ui required field">
|
<div class="ui required field">
|
||||||
<label for="channel-name">
|
<label for="channel-name">
|
||||||
<translate >Name</translate>
|
Name
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
v-model="newValues.name"
|
v-model="newValues.name"
|
||||||
|
@ -225,7 +221,7 @@ defineExpose({
|
||||||
</div>
|
</div>
|
||||||
<div class="ui required field">
|
<div class="ui required field">
|
||||||
<label for="channel-username">
|
<label for="channel-username">
|
||||||
<translate >Fediverse handle</translate>
|
Fediverse handle
|
||||||
</label>
|
</label>
|
||||||
<div class="ui left labeled input">
|
<div class="ui left labeled input">
|
||||||
<div class="ui basic label">
|
<div class="ui basic label">
|
||||||
|
@ -242,9 +238,7 @@ defineExpose({
|
||||||
<template v-if="creating">
|
<template v-if="creating">
|
||||||
<div class="ui small hidden divider" />
|
<div class="ui small hidden divider" />
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Used in URLs and to follow this channel in the Fediverse. It cannot be changed later.
|
||||||
Used in URLs and to follow this channel in the Fediverse. It cannot be changed later.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
@ -254,9 +248,7 @@ defineExpose({
|
||||||
:image-class="newValues.content_category === 'podcast' ? '' : 'circular'"
|
:image-class="newValues.content_category === 'podcast' ? '' : 'circular'"
|
||||||
@delete="newValues.cover = null"
|
@delete="newValues.cover = null"
|
||||||
>
|
>
|
||||||
<translate >
|
Channel Picture
|
||||||
Channel Picture
|
|
||||||
</translate>
|
|
||||||
</attachment-input>
|
</attachment-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui small hidden divider" />
|
<div class="ui small hidden divider" />
|
||||||
|
@ -264,7 +256,7 @@ defineExpose({
|
||||||
<div class="ten wide column">
|
<div class="ten wide column">
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<label for="channel-tags">
|
<label for="channel-tags">
|
||||||
<translate >Tags</translate>
|
Tags
|
||||||
</label>
|
</label>
|
||||||
<tags-selector
|
<tags-selector
|
||||||
id="channel-tags"
|
id="channel-tags"
|
||||||
|
@ -279,7 +271,7 @@ defineExpose({
|
||||||
>
|
>
|
||||||
<div class="ui required field">
|
<div class="ui required field">
|
||||||
<label for="channel-language">
|
<label for="channel-language">
|
||||||
<translate >Language</translate>
|
Language
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="channel-language"
|
id="channel-language"
|
||||||
|
@ -302,7 +294,7 @@ defineExpose({
|
||||||
<div class="ui small hidden divider" />
|
<div class="ui small hidden divider" />
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<label for="channel-name">
|
<label for="channel-name">
|
||||||
<translate >Description</translate>
|
Description
|
||||||
</label>
|
</label>
|
||||||
<content-form v-model="newValues.description" />
|
<content-form v-model="newValues.description" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -312,7 +304,7 @@ defineExpose({
|
||||||
>
|
>
|
||||||
<div class="ui required field">
|
<div class="ui required field">
|
||||||
<label for="channel-itunes-category">
|
<label for="channel-itunes-category">
|
||||||
<translate >Category</translate>
|
Category
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="itunes-category"
|
id="itunes-category"
|
||||||
|
@ -332,7 +324,7 @@ defineExpose({
|
||||||
</div>
|
</div>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<label for="channel-itunes-category">
|
<label for="channel-itunes-category">
|
||||||
<translate >Subcategory</translate>
|
Subcategory
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="itunes-category"
|
id="itunes-category"
|
||||||
|
@ -357,7 +349,7 @@ defineExpose({
|
||||||
>
|
>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<label for="channel-itunes-email">
|
<label for="channel-itunes-email">
|
||||||
<translate >Owner e-mail address</translate>
|
Owner e-mail address
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
id="channel-itunes-email"
|
id="channel-itunes-email"
|
||||||
|
@ -368,7 +360,7 @@ defineExpose({
|
||||||
</div>
|
</div>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<label for="channel-itunes-name">
|
<label for="channel-itunes-name">
|
||||||
<translate >Owner name</translate>
|
Owner name
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
id="channel-itunes-name"
|
id="channel-itunes-name"
|
||||||
|
@ -379,9 +371,7 @@ defineExpose({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Used for the itunes:email and itunes:name field required by certain platforms such as Spotify or iTunes.
|
||||||
Used for the itunes:email and itunes:name field required by certain platforms such as Spotify or iTunes.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -390,9 +380,7 @@ defineExpose({
|
||||||
class="ui active inverted dimmer"
|
class="ui active inverted dimmer"
|
||||||
>
|
>
|
||||||
<div class="ui text loader">
|
<div class="ui text loader">
|
||||||
<translate >
|
Loading
|
||||||
Loading
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -84,9 +84,7 @@ fetchData()
|
||||||
:class="['ui', 'basic', 'button']"
|
:class="['ui', 'basic', 'button']"
|
||||||
@click="fetchData(nextPage)"
|
@click="fetchData(nextPage)"
|
||||||
>
|
>
|
||||||
<translate >
|
Show more
|
||||||
Show more
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="!isLoading && albums.length === 0">
|
<template v-if="!isLoading && albums.length === 0">
|
||||||
|
@ -95,9 +93,7 @@ fetchData()
|
||||||
@refresh="fetchData()"
|
@refresh="fetchData()"
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
You may need to subscribe to this channel to see its contents.
|
||||||
You may need to subscribe to this channel to see its contents.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</empty-state>
|
</empty-state>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -77,9 +77,7 @@ fetchData()
|
||||||
:class="['ui', 'basic', 'button']"
|
:class="['ui', 'basic', 'button']"
|
||||||
@click="fetchData(nextPage)"
|
@click="fetchData(nextPage)"
|
||||||
>
|
>
|
||||||
<translate >
|
Show more
|
||||||
Show more
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="!isLoading && channels.length === 0">
|
<template v-if="!isLoading && channels.length === 0">
|
||||||
|
|
|
@ -52,24 +52,20 @@ const { copy, copied } = useClipboard({ source: textarea })
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
<strong>
|
<strong>
|
||||||
<translate >Sharing will not work because this pod doesn't allow anonymous users to access content.</translate>
|
Sharing will not work because this pod doesn't allow anonymous users to access content.
|
||||||
</strong>
|
</strong>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Please contact your admins and ask them to update the corresponding setting.
|
||||||
Please contact your admins and ask them to update the corresponding setting.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui form">
|
<div class="ui form">
|
||||||
<div class="two fields">
|
<div class="two fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="embed-width"><translate >Widget width</translate></label>
|
<label for="embed-width">Widget width</label>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Leave empty for a responsive widget
|
||||||
Leave empty for a responsive widget
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<input
|
<input
|
||||||
id="embed-width"
|
id="embed-width"
|
||||||
|
@ -82,7 +78,7 @@ const { copy, copied } = useClipboard({ source: textarea })
|
||||||
<template v-if="type != 'track'">
|
<template v-if="type != 'track'">
|
||||||
<br>
|
<br>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="embed-height"><translate >Widget height</translate></label>
|
<label for="embed-height">Widget height</label>
|
||||||
<input
|
<input
|
||||||
id="embed-height"
|
id="embed-height"
|
||||||
v-model="height"
|
v-model="height"
|
||||||
|
@ -99,15 +95,11 @@ const { copy, copied } = useClipboard({ source: textarea })
|
||||||
class="ui right accent labeled icon floated button"
|
class="ui right accent labeled icon floated button"
|
||||||
@click="copy()"
|
@click="copy()"
|
||||||
>
|
>
|
||||||
<i class="copy icon" /><translate >
|
<i class="copy icon" /> Copy
|
||||||
Copy
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<label for="embed-width"><translate >Embed code</translate></label>
|
<label for="embed-width">Embed code</label>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Copy/paste this code in your website HTML
|
||||||
Copy/paste this code in your website HTML
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<textarea
|
<textarea
|
||||||
ref="textarea"
|
ref="textarea"
|
||||||
|
@ -120,9 +112,7 @@ const { copy, copied } = useClipboard({ source: textarea })
|
||||||
v-if="copied"
|
v-if="copied"
|
||||||
class="message"
|
class="message"
|
||||||
>
|
>
|
||||||
<translate >
|
Text copied to clipboard!
|
||||||
Text copied to clipboard!
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -134,7 +124,7 @@ const { copy, copied } = useClipboard({ source: textarea })
|
||||||
:href="iframeSrc"
|
:href="iframeSrc"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<translate >Preview</translate>
|
Preview
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
<iframe
|
<iframe
|
||||||
|
|
|
@ -40,19 +40,16 @@ const toggle = () => {
|
||||||
<i class="heart icon" />
|
<i class="heart icon" />
|
||||||
<translate
|
<translate
|
||||||
v-if="isApproved"
|
v-if="isApproved"
|
||||||
|
|
||||||
>
|
>
|
||||||
Unfollow
|
Unfollow
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else-if="isPending"
|
v-else-if="isPending"
|
||||||
|
|
||||||
>
|
>
|
||||||
Cancel follow request
|
Cancel follow request
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else
|
v-else
|
||||||
|
|
||||||
>
|
>
|
||||||
Follow
|
Follow
|
||||||
</translate>
|
</translate>
|
||||||
|
|
|
@ -138,7 +138,7 @@ const openMenu = () => {
|
||||||
v-else
|
v-else
|
||||||
:class="[playIconClass, 'icon']"
|
:class="[playIconClass, 'icon']"
|
||||||
/>
|
/>
|
||||||
<template v-if="!discrete && !iconOnly"> <slot><translate >Play</translate></slot></template>
|
<template v-if="!discrete && !iconOnly"> <slot>Play</slot></template>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="!discrete && !iconOnly"
|
v-if="!discrete && !iconOnly"
|
||||||
|
@ -156,7 +156,7 @@ const openMenu = () => {
|
||||||
:title="labels.addToQueue"
|
:title="labels.addToQueue"
|
||||||
@click.stop.prevent="enqueue"
|
@click.stop.prevent="enqueue"
|
||||||
>
|
>
|
||||||
<i class="plus icon" /><translate >Add to queue</translate>
|
<i class="plus icon" />Add to queue
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="item basic"
|
class="item basic"
|
||||||
|
@ -181,7 +181,7 @@ const openMenu = () => {
|
||||||
:title="labels.startRadio"
|
:title="labels.startRadio"
|
||||||
@click.stop.prevent="$store.dispatch('radios/start', {type: 'similar', objectId: track?.id})"
|
@click.stop.prevent="$store.dispatch('radios/start', {type: 'similar', objectId: track?.id})"
|
||||||
>
|
>
|
||||||
<i class="feed icon" /><translate >Play radio</translate>
|
<i class="feed icon" />Play radio
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="track"
|
v-if="track"
|
||||||
|
@ -190,7 +190,7 @@ const openMenu = () => {
|
||||||
@click.stop="$store.commit('playlists/chooseTrack', track)"
|
@click.stop="$store.commit('playlists/chooseTrack', track)"
|
||||||
>
|
>
|
||||||
<i class="list icon" />
|
<i class="list icon" />
|
||||||
<translate >Add to playlist…</translate>
|
Add to playlist…
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="track && $route.name !== 'library.tracks.detail'"
|
v-if="track && $route.name !== 'library.tracks.detail'"
|
||||||
|
@ -200,11 +200,9 @@ const openMenu = () => {
|
||||||
<i class="info icon" />
|
<i class="info icon" />
|
||||||
<translate
|
<translate
|
||||||
v-if="track.artist?.content_category === 'podcast'"
|
v-if="track.artist?.content_category === 'podcast'"
|
||||||
|
|
||||||
>Episode details</translate>
|
>Episode details</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else
|
v-else
|
||||||
|
|
||||||
>Track details</translate>
|
>Track details</translate>
|
||||||
</button>
|
</button>
|
||||||
<div class="divider" />
|
<div class="divider" />
|
||||||
|
|
|
@ -133,9 +133,7 @@ const hideArtist = () => {
|
||||||
id="player-label"
|
id="player-label"
|
||||||
class="visually-hidden"
|
class="visually-hidden"
|
||||||
>
|
>
|
||||||
<translate >
|
Audio player and controls
|
||||||
Audio player and controls
|
|
||||||
</translate>
|
|
||||||
</h1>
|
</h1>
|
||||||
<div
|
<div
|
||||||
class="ui inverted segment fixed-controls"
|
class="ui inverted segment fixed-controls"
|
||||||
|
|
|
@ -73,9 +73,7 @@ const labels = computed(() => ({
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<h2>
|
<h2>
|
||||||
<translate >
|
Search for some music
|
||||||
Search for some music
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<div :class="['ui', {'loading': isLoading }, 'search']">
|
<div :class="['ui', {'loading': isLoading }, 'search']">
|
||||||
<div class="ui icon big input">
|
<div class="ui icon big input">
|
||||||
|
@ -91,9 +89,7 @@ const labels = computed(() => ({
|
||||||
</div>
|
</div>
|
||||||
<template v-if="query.length > 0">
|
<template v-if="query.length > 0">
|
||||||
<h3 class="ui title">
|
<h3 class="ui title">
|
||||||
<translate >
|
Artists
|
||||||
Artists
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div v-if="results.artists.length > 0">
|
<div v-if="results.artists.length > 0">
|
||||||
<div class="ui cards">
|
<div class="ui cards">
|
||||||
|
@ -105,16 +101,12 @@ const labels = computed(() => ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p v-else>
|
<p v-else>
|
||||||
<translate >
|
No artist matched your query
|
||||||
No artist matched your query
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="query.length > 0">
|
<template v-if="query.length > 0">
|
||||||
<h3 class="ui title">
|
<h3 class="ui title">
|
||||||
<translate >
|
Albums
|
||||||
Albums
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div
|
<div
|
||||||
v-if="results.albums.length > 0"
|
v-if="results.albums.length > 0"
|
||||||
|
@ -132,9 +124,7 @@ const labels = computed(() => ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p v-else>
|
<p v-else>
|
||||||
<translate >
|
No album matched your query
|
||||||
No album matched your query
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -112,9 +112,7 @@ watch(
|
||||||
:class="['ui', 'basic', 'button']"
|
:class="['ui', 'basic', 'button']"
|
||||||
@click="fetchData(nextPage)"
|
@click="fetchData(nextPage)"
|
||||||
>
|
>
|
||||||
<translate >
|
Show more
|
||||||
Show more
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -108,9 +108,7 @@ watch(
|
||||||
:class="['ui', 'basic', 'button']"
|
:class="['ui', 'basic', 'button']"
|
||||||
@click="fetchData(nextPage)"
|
@click="fetchData(nextPage)"
|
||||||
>
|
>
|
||||||
<translate >
|
Show more
|
||||||
Show more
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -200,9 +200,7 @@ watch(() => props.websocketHandlers.includes('Listen'), (to) => {
|
||||||
>
|
>
|
||||||
<div class="ui icon header">
|
<div class="ui icon header">
|
||||||
<i class="music icon" />
|
<i class="music icon" />
|
||||||
<translate >
|
Nothing found
|
||||||
Nothing found
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="isLoading"
|
v-if="isLoading"
|
||||||
|
@ -217,9 +215,7 @@ watch(() => props.websocketHandlers.includes('Listen'), (to) => {
|
||||||
:class="['ui', 'basic', 'button']"
|
:class="['ui', 'basic', 'button']"
|
||||||
@click="fetchData(nextPage as string)"
|
@click="fetchData(nextPage as string)"
|
||||||
>
|
>
|
||||||
<translate >
|
Show more
|
||||||
Show more
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -72,23 +72,17 @@ store.state.auth.applicationSecret = undefined
|
||||||
</div>
|
</div>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<router-link :to="{name: 'settings'}">
|
<router-link :to="{name: 'settings'}">
|
||||||
<translate >
|
Back to settings
|
||||||
Back to settings
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<translate >
|
Application details
|
||||||
Application details
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<div class="ui form">
|
<div class="ui form">
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else.
|
||||||
Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="copy-id"><translate >Application ID</translate></label>
|
<label for="copy-id">Application ID</label>
|
||||||
<copy-input
|
<copy-input
|
||||||
id="copy-id"
|
id="copy-id"
|
||||||
:value="application.client_id"
|
:value="application.client_id"
|
||||||
|
@ -100,18 +94,14 @@ store.state.auth.applicationSecret = undefined
|
||||||
>
|
>
|
||||||
<div class="ui small warning message">
|
<div class="ui small warning message">
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate >
|
Keep a copy of this token in a safe place
|
||||||
Keep a copy of this token in a safe place
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
You won't be able to see it again once you leave this screen.
|
||||||
You won't be able to see it again once you leave this screen.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label for="copy-secret"><translate >Application secret</translate></label>
|
<label for="copy-secret">Application secret</label>
|
||||||
<copy-input
|
<copy-input
|
||||||
id="copy-secret"
|
id="copy-secret"
|
||||||
:value="secret"
|
:value="secret"
|
||||||
|
@ -121,7 +111,7 @@ store.state.auth.applicationSecret = undefined
|
||||||
v-if="application.token != undefined"
|
v-if="application.token != undefined"
|
||||||
class="field"
|
class="field"
|
||||||
>
|
>
|
||||||
<label for="copy-secret"><translate >Access token</translate></label>
|
<label for="copy-secret">Access token</label>
|
||||||
<copy-input
|
<copy-input
|
||||||
id="copy-secret"
|
id="copy-secret"
|
||||||
:value="application.token"
|
:value="application.token"
|
||||||
|
@ -131,14 +121,12 @@ store.state.auth.applicationSecret = undefined
|
||||||
@click.prevent="refreshToken"
|
@click.prevent="refreshToken"
|
||||||
>
|
>
|
||||||
<i class="refresh icon" />
|
<i class="refresh icon" />
|
||||||
<translate >Regenerate token</translate>
|
Regenerate token
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<translate >
|
Edit application
|
||||||
Edit application
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<application-form
|
<application-form
|
||||||
:app="application"
|
:app="application"
|
||||||
|
|
|
@ -120,9 +120,7 @@ const allScopes = computed(() => {
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
We cannot save your changes
|
||||||
We cannot save your changes
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -134,7 +132,7 @@ const allScopes = computed(() => {
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<label for="application-name"><translate >Name</translate></label>
|
<label for="application-name">Name</label>
|
||||||
<input
|
<input
|
||||||
id="application-name"
|
id="application-name"
|
||||||
v-model="fields.name"
|
v-model="fields.name"
|
||||||
|
@ -144,7 +142,7 @@ const allScopes = computed(() => {
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<label for="redirect-uris"><translate >Redirect URI</translate></label>
|
<label for="redirect-uris">Redirect URI</label>
|
||||||
<input
|
<input
|
||||||
id="redirect-uris"
|
id="redirect-uris"
|
||||||
v-model="fields.redirect_uris"
|
v-model="fields.redirect_uris"
|
||||||
|
@ -152,17 +150,13 @@ const allScopes = computed(() => {
|
||||||
type="text"
|
type="text"
|
||||||
>
|
>
|
||||||
<p class="help">
|
<p class="help">
|
||||||
<translate >
|
Use "urn:ietf:wg:oauth:2.0:oob" as a redirect URI if your application is not served on the web.
|
||||||
Use "urn:ietf:wg:oauth:2.0:oob" as a redirect URI if your application is not served on the web.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<label><translate >Scopes</translate></label>
|
<label>Scopes</label>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Checking the parent "Read" or "Write" scopes implies access to all the corresponding children scopes.
|
||||||
Checking the parent "Read" or "Write" scopes implies access to all the corresponding children scopes.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<div class="ui stackable two column grid">
|
<div class="ui stackable two column grid">
|
||||||
<div
|
<div
|
||||||
|
@ -210,13 +204,11 @@ const allScopes = computed(() => {
|
||||||
>
|
>
|
||||||
<translate
|
<translate
|
||||||
v-if="app !== null"
|
v-if="app !== null"
|
||||||
|
|
||||||
>
|
>
|
||||||
Update application
|
Update application
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else
|
v-else
|
||||||
|
|
||||||
>
|
>
|
||||||
Create application
|
Create application
|
||||||
</translate>
|
</translate>
|
||||||
|
|
|
@ -55,14 +55,10 @@ const created = (application: Application) => {
|
||||||
<div class="ui vertical stripe segment">
|
<div class="ui vertical stripe segment">
|
||||||
<section class="ui text container">
|
<section class="ui text container">
|
||||||
<router-link :to="{name: 'settings'}">
|
<router-link :to="{name: 'settings'}">
|
||||||
<translate >
|
Back to settings
|
||||||
Back to settings
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<translate >
|
Create a new application
|
||||||
Create a new application
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<application-form
|
<application-form
|
||||||
:defaults="defaults"
|
:defaults="defaults"
|
||||||
|
|
|
@ -119,9 +119,7 @@ whenever(() => props.clientId, fetchApplication, { immediate: true })
|
||||||
<section class="ui vertical stripe segment">
|
<section class="ui vertical stripe segment">
|
||||||
<div class="ui small text container">
|
<div class="ui small text container">
|
||||||
<h2>
|
<h2>
|
||||||
<i class="lock open icon" /><translate >
|
<i class="lock open icon" /> Authorize third-party app
|
||||||
Authorize third-party app
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<div
|
<div
|
||||||
v-if="errors.length > 0"
|
v-if="errors.length > 0"
|
||||||
|
@ -132,17 +130,13 @@ whenever(() => props.clientId, fetchApplication, { immediate: true })
|
||||||
v-if="application"
|
v-if="application"
|
||||||
class="header"
|
class="header"
|
||||||
>
|
>
|
||||||
<translate >
|
Error while authorizing application
|
||||||
Error while authorizing application
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<h4
|
<h4
|
||||||
v-else
|
v-else
|
||||||
class="header"
|
class="header"
|
||||||
>
|
>
|
||||||
<translate >
|
Error while fetching application data
|
||||||
Error while fetching application data
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -183,20 +177,20 @@ whenever(() => props.clientId, fetchApplication, { immediate: true })
|
||||||
:class="['ui', 'basic', 'right floated', 'tiny', 'vertically-spaced component-label label']"
|
:class="['ui', 'basic', 'right floated', 'tiny', 'vertically-spaced component-label label']"
|
||||||
>
|
>
|
||||||
<i class="pencil icon" />
|
<i class="pencil icon" />
|
||||||
<translate >Write-only</translate>
|
Write-only
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
v-else-if="!topic.write && topic.read"
|
v-else-if="!topic.write && topic.read"
|
||||||
:class="['ui', 'basic', 'right floated', 'tiny', 'vertically-spaced component-label label']"
|
:class="['ui', 'basic', 'right floated', 'tiny', 'vertically-spaced component-label label']"
|
||||||
>
|
>
|
||||||
<translate >Read-only</translate>
|
Read-only
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
v-else-if="topic.write && topic.read"
|
v-else-if="topic.write && topic.read"
|
||||||
:class="['ui', 'basic', 'right floated', 'tiny', 'vertically-spaced component-label label']"
|
:class="['ui', 'basic', 'right floated', 'tiny', 'vertically-spaced component-label label']"
|
||||||
>
|
>
|
||||||
<i class="pencil icon" />
|
<i class="pencil icon" />
|
||||||
<translate >Full access</translate>
|
Full access
|
||||||
</span>
|
</span>
|
||||||
<i :class="[topic.icon, 'icon']" />
|
<i :class="[topic.icon, 'icon']" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@ -207,7 +201,7 @@ whenever(() => props.clientId, fetchApplication, { immediate: true })
|
||||||
</div>
|
</div>
|
||||||
</h4>
|
</h4>
|
||||||
<div v-if="unknownRequestedScopes.length > 0">
|
<div v-if="unknownRequestedScopes.length > 0">
|
||||||
<p><strong><translate >The application is also requesting the following unknown permissions:</translate></strong></p>
|
<p><strong>The application is also requesting the following unknown permissions:</strong></p>
|
||||||
<ul
|
<ul
|
||||||
v-for="(unknownscope, key) in unknownRequestedScopes"
|
v-for="(unknownscope, key) in unknownRequestedScopes"
|
||||||
:key="key"
|
:key="key"
|
||||||
|
@ -230,7 +224,6 @@ whenever(() => props.clientId, fetchApplication, { immediate: true })
|
||||||
<p
|
<p
|
||||||
v-if="redirectUri === 'urn:ietf:wg:oauth:2.0:oob'"
|
v-if="redirectUri === 'urn:ietf:wg:oauth:2.0:oob'"
|
||||||
v-translate
|
v-translate
|
||||||
|
|
||||||
>
|
>
|
||||||
You will be shown a code to copy-paste in the application.
|
You will be shown a code to copy-paste in the application.
|
||||||
</p>
|
</p>
|
||||||
|
@ -244,7 +237,7 @@ whenever(() => props.clientId, fetchApplication, { immediate: true })
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
<div v-else-if="code">
|
<div v-else-if="code">
|
||||||
<p><strong><translate >Copy-paste the following code in the application:</translate></strong></p>
|
<p><strong>Copy-paste the following code in the application:</strong></p>
|
||||||
<copy-input :value="code" />
|
<copy-input :value="code" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -75,20 +75,14 @@ const submit = async () => {
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
We cannot log you in
|
||||||
We cannot log you in
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li v-if="errors[0] == 'invalid_credentials' && $store.state.instance.settings.moderation.signup_approval_enabled.value">
|
<li v-if="errors[0] == 'invalid_credentials' && $store.state.instance.settings.moderation.signup_approval_enabled.value">
|
||||||
<translate >
|
If you signed-up recently, you may need to wait before our moderation team review your account, or verify your e-mail address.
|
||||||
If you signed-up recently, you may need to wait before our moderation team review your account, or verify your e-mail address.
|
|
||||||
</translate>
|
|
||||||
</li>
|
</li>
|
||||||
<li v-else-if="errors[0] == 'invalid_credentials'">
|
<li v-else-if="errors[0] == 'invalid_credentials'">
|
||||||
<translate >
|
Please double-check that your username and password combination is correct and make sure you verified your e-mail address.
|
||||||
Please double-check that your username and password combination is correct and make sure you verified your e-mail address.
|
|
||||||
</translate>
|
|
||||||
</li>
|
</li>
|
||||||
<li v-else>
|
<li v-else>
|
||||||
{{ errors[0] }}
|
{{ errors[0] }}
|
||||||
|
@ -98,11 +92,11 @@ const submit = async () => {
|
||||||
<template v-if="domain === $store.getters['instance/domain']">
|
<template v-if="domain === $store.getters['instance/domain']">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="username-field">
|
<label for="username-field">
|
||||||
<translate >Username or e-mail address</translate>
|
Username or e-mail address
|
||||||
<template v-if="showSignup">
|
<template v-if="showSignup">
|
||||||
|
|
|
|
||||||
<router-link :to="{path: '/signup'}">
|
<router-link :to="{path: '/signup'}">
|
||||||
<translate >Create an account</translate>
|
Create an account
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
</label>
|
</label>
|
||||||
|
@ -119,12 +113,12 @@ const submit = async () => {
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="password-field">
|
<label for="password-field">
|
||||||
<translate >Password</translate> |
|
Password |
|
||||||
<router-link
|
<router-link
|
||||||
tabindex="1"
|
tabindex="1"
|
||||||
:to="{name: 'auth.password-reset', query: {email: credentials.username}}"
|
:to="{name: 'auth.password-reset', query: {email: credentials.username}}"
|
||||||
>
|
>
|
||||||
<translate >Reset your password</translate>
|
Reset your password
|
||||||
</router-link>
|
</router-link>
|
||||||
</label>
|
</label>
|
||||||
<password-input
|
<password-input
|
||||||
|
@ -147,9 +141,7 @@ const submit = async () => {
|
||||||
:class="['ui', {'loading': isLoading}, 'right', 'floated', buttonClasses, 'button']"
|
:class="['ui', {'loading': isLoading}, 'right', 'floated', buttonClasses, 'button']"
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<translate >
|
Login
|
||||||
Login
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -19,13 +19,10 @@ const labels = computed(() => ({
|
||||||
class="ui small text container"
|
class="ui small text container"
|
||||||
>
|
>
|
||||||
<h2>
|
<h2>
|
||||||
<translate >
|
Are you sure you want to log out?
|
||||||
Are you sure you want to log out?
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<p
|
<p
|
||||||
v-translate="{username: $store.state.auth.username}"
|
v-translate="{username: $store.state.auth.username}"
|
||||||
|
|
||||||
>
|
>
|
||||||
You are currently logged in as %{ username }
|
You are currently logged in as %{ username }
|
||||||
</p>
|
</p>
|
||||||
|
@ -33,9 +30,7 @@ const labels = computed(() => ({
|
||||||
class="ui button"
|
class="ui button"
|
||||||
@click="$store.dispatch('auth/logout')"
|
@click="$store.dispatch('auth/logout')"
|
||||||
>
|
>
|
||||||
<translate >
|
Yes, log me out!
|
||||||
Yes, log me out!
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -43,17 +38,13 @@ const labels = computed(() => ({
|
||||||
class="ui small text container"
|
class="ui small text container"
|
||||||
>
|
>
|
||||||
<h2>
|
<h2>
|
||||||
<translate >
|
You aren't currently logged in
|
||||||
You aren't currently logged in
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<router-link
|
<router-link
|
||||||
to="/login"
|
to="/login"
|
||||||
class="ui button"
|
class="ui button"
|
||||||
>
|
>
|
||||||
<translate >
|
Log in!
|
||||||
Log in!
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -69,7 +69,7 @@ const submitAndScan = async () => {
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<i class="external icon" />
|
<i class="external icon" />
|
||||||
<translate >Documentation</translate>
|
Documentation
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
<div class="ui clearing hidden divider" />
|
<div class="ui clearing hidden divider" />
|
||||||
|
@ -79,9 +79,7 @@ const submitAndScan = async () => {
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Error while saving plugin
|
||||||
Error while saving plugin
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -99,7 +97,7 @@ const submitAndScan = async () => {
|
||||||
v-model="enabled"
|
v-model="enabled"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
>
|
>
|
||||||
<label :for="`${plugin.name}-enabled`"><translate >Enabled</translate></label>
|
<label :for="`${plugin.name}-enabled`">Enabled</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui clearing hidden divider" />
|
<div class="ui clearing hidden divider" />
|
||||||
|
@ -107,7 +105,7 @@ const submitAndScan = async () => {
|
||||||
v-if="plugin.source"
|
v-if="plugin.source"
|
||||||
class="field"
|
class="field"
|
||||||
>
|
>
|
||||||
<label for="plugin-library"><translate >Library</translate></label>
|
<label for="plugin-library">Library</label>
|
||||||
<select
|
<select
|
||||||
id="plugin-library"
|
id="plugin-library"
|
||||||
v-model="values['library']"
|
v-model="values['library']"
|
||||||
|
@ -121,9 +119,7 @@ const submitAndScan = async () => {
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<div>
|
<div>
|
||||||
<translate >
|
Library where files should be imported.
|
||||||
Library where files should be imported.
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="(plugin.conf?.length ?? 0) > 0">
|
<template v-if="(plugin.conf?.length ?? 0) > 0">
|
||||||
|
@ -198,18 +194,14 @@ const submitAndScan = async () => {
|
||||||
type="submit"
|
type="submit"
|
||||||
:class="['ui', {'loading': isLoading}, 'right', 'floated', 'button']"
|
:class="['ui', {'loading': isLoading}, 'right', 'floated', 'button']"
|
||||||
>
|
>
|
||||||
<translate >
|
Save
|
||||||
Save
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="plugin.source"
|
v-if="plugin.source"
|
||||||
:class="['ui', {'loading': isLoading}, 'right', 'floated', 'button']"
|
:class="['ui', {'loading': isLoading}, 'right', 'floated', 'button']"
|
||||||
@click.prevent="submitAndScan"
|
@click.prevent="submitAndScan"
|
||||||
>
|
>
|
||||||
<translate >
|
Scan
|
||||||
Scan
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<div class="ui clearing hidden divider" />
|
<div class="ui clearing hidden divider" />
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -276,9 +276,7 @@ fetchOwnedApps()
|
||||||
<div class="ui vertical stripe segment">
|
<div class="ui vertical stripe segment">
|
||||||
<section class="ui text container">
|
<section class="ui text container">
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<translate >
|
Account settings
|
||||||
Account settings
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<form
|
<form
|
||||||
class="ui form"
|
class="ui form"
|
||||||
|
@ -289,9 +287,7 @@ fetchOwnedApps()
|
||||||
class="ui positive message"
|
class="ui positive message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Settings updated
|
||||||
Settings updated
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -300,9 +296,7 @@ fetchOwnedApps()
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Your settings can't be updated
|
||||||
Your settings can't be updated
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -346,18 +340,14 @@ fetchOwnedApps()
|
||||||
:class="['ui', { loading: isLoading }, 'button']"
|
:class="['ui', { loading: isLoading }, 'button']"
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<translate >
|
Update settings
|
||||||
Update settings
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
<section class="ui text container">
|
<section class="ui text container">
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<translate >
|
Avatar
|
||||||
Avatar
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<div class="ui form">
|
<div class="ui form">
|
||||||
<div
|
<div
|
||||||
|
@ -366,9 +356,7 @@ fetchOwnedApps()
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Your avatar cannot be saved
|
||||||
Your avatar cannot be saved
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -385,9 +373,7 @@ fetchOwnedApps()
|
||||||
@update:model-value="submitAvatar($event)"
|
@update:model-value="submitAvatar($event)"
|
||||||
@delete="avatar = {uuid: null}"
|
@delete="avatar = {uuid: null}"
|
||||||
>
|
>
|
||||||
<translate >
|
Avatar
|
||||||
Avatar
|
|
||||||
</translate>
|
|
||||||
</attachment-input>
|
</attachment-input>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -395,16 +381,10 @@ fetchOwnedApps()
|
||||||
<section class="ui text container">
|
<section class="ui text container">
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<translate >
|
Change my password
|
||||||
Change my password
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<div class="ui message">
|
<div class="ui message">
|
||||||
<translate >
|
Changing your password will also change your Subsonic API password if you have requested one. You will have to update your password on your clients that use this password.
|
||||||
Changing your password will also change your Subsonic API password if you have requested one.
|
|
||||||
</translate> <translate >
|
|
||||||
You will have to update your password on your clients that use this password.
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
<form
|
<form
|
||||||
class="ui form"
|
class="ui form"
|
||||||
|
@ -416,20 +396,16 @@ fetchOwnedApps()
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Your password cannot be changed
|
||||||
Your password cannot be changed
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li v-if="passwordError == 'invalid_credentials'">
|
<li v-if="passwordError == 'invalid_credentials'">
|
||||||
<translate >
|
Please double-check your password is correct
|
||||||
Please double-check your password is correct
|
|
||||||
</translate>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="old-password-field"><translate >Current password</translate></label>
|
<label for="old-password-field">Current password</label>
|
||||||
<password-input
|
<password-input
|
||||||
v-model="credentials.oldPassword"
|
v-model="credentials.oldPassword"
|
||||||
field-id="old-password-field"
|
field-id="old-password-field"
|
||||||
|
@ -437,7 +413,7 @@ fetchOwnedApps()
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="new-password-field"><translate >New password</translate></label>
|
<label for="new-password-field">New password</label>
|
||||||
<password-input
|
<password-input
|
||||||
v-model="credentials.newPassword"
|
v-model="credentials.newPassword"
|
||||||
field-id="new-password-field"
|
field-id="new-password-field"
|
||||||
|
@ -448,42 +424,30 @@ fetchOwnedApps()
|
||||||
:class="['ui', {'loading': isLoadingPassword}, {disabled: !credentials.newPassword || !credentials.oldPassword}, 'warning', 'button']"
|
:class="['ui', {'loading': isLoadingPassword}, {disabled: !credentials.newPassword || !credentials.oldPassword}, 'warning', 'button']"
|
||||||
:action="submitPassword"
|
:action="submitPassword"
|
||||||
>
|
>
|
||||||
<translate >
|
Change password
|
||||||
Change password
|
|
||||||
</translate>
|
|
||||||
<template #modal-header>
|
<template #modal-header>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Change your password?
|
||||||
Change your password?
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-content>
|
<template #modal-content>
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Changing your password will have the following consequences:
|
||||||
Changing your password will have the following consequences:
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<translate >
|
You will be logged out from this session and have to log in with the new one
|
||||||
You will be logged out from this session and have to log in with the new one
|
|
||||||
</translate>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<translate >
|
Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password
|
||||||
Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password
|
|
||||||
</translate>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-confirm>
|
<template #modal-confirm>
|
||||||
<div>
|
<div>
|
||||||
<translate >
|
Disable access
|
||||||
Disable access
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</dangerous-button>
|
</dangerous-button>
|
||||||
|
@ -500,15 +464,11 @@ fetchOwnedApps()
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<i class="eye slash outline icon" />
|
<i class="eye slash outline icon" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<translate >
|
Content filters
|
||||||
Content filters
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Content filters help you hide content you don't want to see on the service.
|
||||||
Content filters help you hide content you don't want to see on the service.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
@ -516,27 +476,19 @@ fetchOwnedApps()
|
||||||
@click="$store.dispatch('moderation/fetchContentFilters')"
|
@click="$store.dispatch('moderation/fetchContentFilters')"
|
||||||
>
|
>
|
||||||
<i class="refresh icon" />
|
<i class="refresh icon" />
|
||||||
<translate >
|
Refresh
|
||||||
Refresh
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<h3 class="ui header">
|
<h3 class="ui header">
|
||||||
<translate >
|
Hidden artists
|
||||||
Hidden artists
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<table class="ui compact very basic unstackable table">
|
<table class="ui compact very basic unstackable table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<translate >
|
Name
|
||||||
Name
|
|
||||||
</translate>
|
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<translate >
|
Creation date
|
||||||
Creation date
|
|
||||||
</translate>
|
|
||||||
</th>
|
</th>
|
||||||
<th />
|
<th />
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -559,9 +511,7 @@ fetchOwnedApps()
|
||||||
class="ui basic tiny button"
|
class="ui basic tiny button"
|
||||||
@click="$store.dispatch('moderation/deleteContentFilter', filter.uuid)"
|
@click="$store.dispatch('moderation/deleteContentFilter', filter.uuid)"
|
||||||
>
|
>
|
||||||
<translate >
|
Delete
|
||||||
Delete
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -576,24 +526,18 @@ fetchOwnedApps()
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<i class="open lock icon" />
|
<i class="open lock icon" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<translate >
|
Authorized apps
|
||||||
Authorized apps
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
This is the list of applications that have access to your account data.
|
||||||
This is the list of applications that have access to your account data.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
:class="['ui', 'icon', { loading: isLoadingApps }, 'button']"
|
:class="['ui', 'icon', { loading: isLoadingApps }, 'button']"
|
||||||
@click="fetchApps()"
|
@click="fetchApps()"
|
||||||
>
|
>
|
||||||
<i class="refresh icon" />
|
<i class="refresh icon" />
|
||||||
<translate >
|
Refresh
|
||||||
Refresh
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<table
|
<table
|
||||||
v-if="apps.length > 0"
|
v-if="apps.length > 0"
|
||||||
|
@ -602,14 +546,10 @@ fetchOwnedApps()
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<translate >
|
Application
|
||||||
Application
|
|
||||||
</translate>
|
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<translate >
|
Permissions
|
||||||
Permissions
|
|
||||||
</translate>
|
|
||||||
</th>
|
</th>
|
||||||
<th />
|
<th />
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -630,29 +570,22 @@ fetchOwnedApps()
|
||||||
:class="['ui', 'tiny', 'danger', { loading: isRevoking.has(app.client_id) }, 'button']"
|
:class="['ui', 'tiny', 'danger', { loading: isRevoking.has(app.client_id) }, 'button']"
|
||||||
@confirm="revokeApp(app.client_id)"
|
@confirm="revokeApp(app.client_id)"
|
||||||
>
|
>
|
||||||
<translate >
|
Revoke
|
||||||
Revoke
|
|
||||||
</translate>
|
|
||||||
<template #modal-header>
|
<template #modal-header>
|
||||||
<p
|
<p
|
||||||
v-translate="{application: app.name}"
|
v-translate="{application: app.name}"
|
||||||
|
|
||||||
>
|
>
|
||||||
Revoke access for application "%{ application }"?
|
Revoke access for application "%{ application }"?
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-content>
|
<template #modal-content>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
This will prevent this application from accessing the service on your behalf.
|
||||||
This will prevent this application from accessing the service on your behalf.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-confirm>
|
<template #modal-confirm>
|
||||||
<div>
|
<div>
|
||||||
<translate >
|
Revoke access
|
||||||
Revoke access
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</dangerous-button>
|
</dangerous-button>
|
||||||
|
@ -662,13 +595,9 @@ fetchOwnedApps()
|
||||||
</table>
|
</table>
|
||||||
<empty-state v-else>
|
<empty-state v-else>
|
||||||
<template #title>
|
<template #title>
|
||||||
<translate >
|
You don't have any application connected with your account.
|
||||||
You don't have any application connected with your account.
|
|
||||||
</translate>
|
|
||||||
</template>
|
</template>
|
||||||
<translate >
|
If you authorize third-party applications to access your data, those applications will be listed here.
|
||||||
If you authorize third-party applications to access your data, those applications will be listed here.
|
|
||||||
</translate>
|
|
||||||
</empty-state>
|
</empty-state>
|
||||||
</section>
|
</section>
|
||||||
<section
|
<section
|
||||||
|
@ -679,23 +608,17 @@ fetchOwnedApps()
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<i class="code icon" />
|
<i class="code icon" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<translate >
|
Your applications
|
||||||
Your applications
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
This is the list of applications that you have registered.
|
||||||
This is the list of applications that you have registered.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<router-link
|
<router-link
|
||||||
class="ui success button"
|
class="ui success button"
|
||||||
:to="{name: 'settings.applications.new'}"
|
:to="{name: 'settings.applications.new'}"
|
||||||
>
|
>
|
||||||
<translate >
|
Register a new application
|
||||||
Register a new application
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<table
|
<table
|
||||||
v-if="ownedApps.length > 0"
|
v-if="ownedApps.length > 0"
|
||||||
|
@ -704,19 +627,13 @@ fetchOwnedApps()
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<translate >
|
Application
|
||||||
Application
|
|
||||||
</translate>
|
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<translate >
|
Scopes
|
||||||
Scopes
|
|
||||||
</translate>
|
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<translate >
|
Creation date
|
||||||
Creation date
|
|
||||||
</translate>
|
|
||||||
</th>
|
</th>
|
||||||
<th />
|
<th />
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -742,37 +659,28 @@ fetchOwnedApps()
|
||||||
class="ui tiny success button"
|
class="ui tiny success button"
|
||||||
:to="{name: 'settings.applications.edit', params: {id: app.client_id}}"
|
:to="{name: 'settings.applications.edit', params: {id: app.client_id}}"
|
||||||
>
|
>
|
||||||
<translate >
|
Edit
|
||||||
Edit
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<dangerous-button
|
<dangerous-button
|
||||||
:class="['ui', 'tiny', 'danger', { loading: isDeleting.has(app.client_id) }, 'button']"
|
:class="['ui', 'tiny', 'danger', { loading: isDeleting.has(app.client_id) }, 'button']"
|
||||||
@confirm="deleteApp(app.client_id)"
|
@confirm="deleteApp(app.client_id)"
|
||||||
>
|
>
|
||||||
<translate >
|
Remove
|
||||||
Remove
|
|
||||||
</translate>
|
|
||||||
<template #modal-header>
|
<template #modal-header>
|
||||||
<p
|
<p
|
||||||
v-translate="{application: app.name}"
|
v-translate="{application: app.name}"
|
||||||
|
|
||||||
>
|
>
|
||||||
Remove application "%{ application }"?
|
Remove application "%{ application }"?
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-content>
|
<template #modal-content>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
This will permanently remove the application and all the associated tokens.
|
||||||
This will permanently remove the application and all the associated tokens.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-confirm>
|
<template #modal-confirm>
|
||||||
<div>
|
<div>
|
||||||
<translate >
|
Remove application
|
||||||
Remove application
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</dangerous-button>
|
</dangerous-button>
|
||||||
|
@ -782,13 +690,9 @@ fetchOwnedApps()
|
||||||
</table>
|
</table>
|
||||||
<empty-state v-else>
|
<empty-state v-else>
|
||||||
<template #title>
|
<template #title>
|
||||||
<translate >
|
You don't have registered any application yet.
|
||||||
You don't have registered any application yet.
|
|
||||||
</translate>
|
|
||||||
</template>
|
</template>
|
||||||
<translate >
|
Register one to integrate Funkwhale with third-party applications.
|
||||||
Register one to integrate Funkwhale with third-party applications.
|
|
||||||
</translate>
|
|
||||||
</empty-state>
|
</empty-state>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -800,23 +704,17 @@ fetchOwnedApps()
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<i class="code icon" />
|
<i class="code icon" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<translate >
|
Plugins
|
||||||
Plugins
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Use plugins to extend Funkwhale and get additional features.
|
||||||
Use plugins to extend Funkwhale and get additional features.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<router-link
|
<router-link
|
||||||
class="ui success button"
|
class="ui success button"
|
||||||
:to="{name: 'settings.plugins'}"
|
:to="{name: 'settings.plugins'}"
|
||||||
>
|
>
|
||||||
<translate >
|
Manage plugins
|
||||||
Manage plugins
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</section>
|
</section>
|
||||||
<section class="ui text container">
|
<section class="ui text container">
|
||||||
|
@ -824,20 +722,15 @@ fetchOwnedApps()
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<i class="comment icon" />
|
<i class="comment icon" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<translate >
|
Change my e-mail address
|
||||||
Change my e-mail address
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Change the e-mail address associated with your account. We will send a confirmation to the new address.
|
||||||
Change the e-mail address associated with your account. We will send a confirmation to the new address.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<translate
|
<translate
|
||||||
:translate-params="{email: $store.state.auth.profile?.email}"
|
:translate-params="{email: $store.state.auth.profile?.email}"
|
||||||
|
|
||||||
>
|
>
|
||||||
Your current e-mail address is %{ email }.
|
Your current e-mail address is %{ email }.
|
||||||
</translate>
|
</translate>
|
||||||
|
@ -852,9 +745,7 @@ fetchOwnedApps()
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
We cannot change your e-mail address
|
||||||
We cannot change your e-mail address
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -866,7 +757,7 @@ fetchOwnedApps()
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="new-email"><translate >New e-mail address</translate></label>
|
<label for="new-email">New e-mail address</label>
|
||||||
<input
|
<input
|
||||||
id="new-email"
|
id="new-email"
|
||||||
v-model="newEmail"
|
v-model="newEmail"
|
||||||
|
@ -875,7 +766,7 @@ fetchOwnedApps()
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="current-password-field-email"><translate >Password</translate></label>
|
<label for="current-password-field-email">Password</label>
|
||||||
<password-input
|
<password-input
|
||||||
v-model="emailPassword"
|
v-model="emailPassword"
|
||||||
field-id="current-password-field-email"
|
field-id="current-password-field-email"
|
||||||
|
@ -886,9 +777,7 @@ fetchOwnedApps()
|
||||||
type="submit"
|
type="submit"
|
||||||
class="ui button"
|
class="ui button"
|
||||||
>
|
>
|
||||||
<translate >
|
Update
|
||||||
Update
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
@ -897,23 +786,17 @@ fetchOwnedApps()
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<i class="trash icon" />
|
<i class="trash icon" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<translate >
|
Delete my account
|
||||||
Delete my account
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
You can permanently and irreversibly delete your account and all the associated data using the form below. You will be asked for confirmation.
|
||||||
You can permanently and irreversibly delete your account and all the associated data using the form below. You will be asked for confirmation.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<div
|
<div
|
||||||
role="alert"
|
role="alert"
|
||||||
class="ui warning message"
|
class="ui warning message"
|
||||||
>
|
>
|
||||||
<translate >
|
Your account will be deleted from our servers within a few minutes. We will also notify other servers who may have a copy of some of your data so they can proceed to deletion. Please note that some of these servers may be offline or unwilling to comply though.
|
||||||
Your account will be deleted from our servers within a few minutes. We will also notify other servers who may have a copy of some of your data so they can proceed to deletion. Please note that some of these servers may be offline or unwilling to comply though.
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="ui form">
|
<div class="ui form">
|
||||||
<div
|
<div
|
||||||
|
@ -922,9 +805,7 @@ fetchOwnedApps()
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
We cannot delete your account
|
||||||
We cannot delete your account
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -936,7 +817,7 @@ fetchOwnedApps()
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="current-password-field"><translate >Password</translate></label>
|
<label for="current-password-field">Password</label>
|
||||||
<password-input
|
<password-input
|
||||||
v-model="deleteAccountPassword"
|
v-model="deleteAccountPassword"
|
||||||
field-id="current-password-field"
|
field-id="current-password-field"
|
||||||
|
@ -947,30 +828,22 @@ fetchOwnedApps()
|
||||||
:class="['ui', {'loading': isDeletingAccount}, {disabled: !deleteAccountPassword}, {danger: deleteAccountPassword}, 'button']"
|
:class="['ui', {'loading': isDeletingAccount}, {disabled: !deleteAccountPassword}, {danger: deleteAccountPassword}, 'button']"
|
||||||
:action="deleteAccount"
|
:action="deleteAccount"
|
||||||
>
|
>
|
||||||
<translate >
|
Delete my account…
|
||||||
Delete my account…
|
|
||||||
</translate>
|
|
||||||
<template #modal-header>
|
<template #modal-header>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Do you want to delete your account?
|
||||||
Do you want to delete your account?
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-content>
|
<template #modal-content>
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
This is irreversible and will permanently remove your data from our servers. You will we immediately logged out.
|
||||||
This is irreversible and will permanently remove your data from our servers. You will we immediately logged out.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-confirm>
|
<template #modal-confirm>
|
||||||
<div>
|
<div>
|
||||||
<translate >
|
Delete my account
|
||||||
Delete my account
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</dangerous-button>
|
</dangerous-button>
|
||||||
|
|
|
@ -88,20 +88,14 @@ fetchInstanceSettings()
|
||||||
<div v-if="submitted">
|
<div v-if="submitted">
|
||||||
<div class="ui success message">
|
<div class="ui success message">
|
||||||
<p v-if="signupRequiresApproval">
|
<p v-if="signupRequiresApproval">
|
||||||
<translate >
|
Your account request was successfully submitted. You will be notified by e-mail when our moderation team has reviewed your request.
|
||||||
Your account request was successfully submitted. You will be notified by e-mail when our moderation team has reviewed your request.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<p v-else>
|
<p v-else>
|
||||||
<translate >
|
Your account was successfully created. Please verify your e-mail address before trying to login.
|
||||||
Your account was successfully created. Please verify your e-mail address before trying to login.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<h2>
|
<h2>
|
||||||
<translate >
|
Log in to your Funkwhale account
|
||||||
Log in to your Funkwhale account
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<login-form
|
<login-form
|
||||||
button-classes="basic success"
|
button-classes="basic success"
|
||||||
|
@ -117,17 +111,13 @@ fetchInstanceSettings()
|
||||||
v-if="!$store.state.instance.settings.users.registration_enabled.value"
|
v-if="!$store.state.instance.settings.users.registration_enabled.value"
|
||||||
class="ui message"
|
class="ui message"
|
||||||
>
|
>
|
||||||
<translate >
|
Public registrations are not possible on this instance. You will need an invitation code to sign up.
|
||||||
Public registrations are not possible on this instance. You will need an invitation code to sign up.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
v-else-if="signupRequiresApproval"
|
v-else-if="signupRequiresApproval"
|
||||||
class="ui message"
|
class="ui message"
|
||||||
>
|
>
|
||||||
<translate >
|
Registrations on this pod are open, but reviewed by moderators before approval.
|
||||||
Registrations on this pod are open, but reviewed by moderators before approval.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<template v-if="formCustomization?.help_text">
|
<template v-if="formCustomization?.help_text">
|
||||||
<rendered-description
|
<rendered-description
|
||||||
|
@ -143,9 +133,7 @@ fetchInstanceSettings()
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Your account cannot be created.
|
||||||
Your account cannot be created.
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -157,7 +145,7 @@ fetchInstanceSettings()
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="required field">
|
<div class="required field">
|
||||||
<label for="username-field"><translate >Username</translate></label>
|
<label for="username-field">Username</label>
|
||||||
<input
|
<input
|
||||||
id="username-field"
|
id="username-field"
|
||||||
ref="username"
|
ref="username"
|
||||||
|
@ -170,7 +158,7 @@ fetchInstanceSettings()
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="required field">
|
<div class="required field">
|
||||||
<label for="email-field"><translate >E-mail address</translate></label>
|
<label for="email-field">E-mail address</label>
|
||||||
<input
|
<input
|
||||||
id="email-field"
|
id="email-field"
|
||||||
ref="email"
|
ref="email"
|
||||||
|
@ -182,7 +170,7 @@ fetchInstanceSettings()
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="required field">
|
<div class="required field">
|
||||||
<label for="password-field"><translate >Password</translate></label>
|
<label for="password-field">Password</label>
|
||||||
<password-input
|
<password-input
|
||||||
v-model="payload.password1"
|
v-model="payload.password1"
|
||||||
field-id="password-field"
|
field-id="password-field"
|
||||||
|
@ -192,7 +180,7 @@ fetchInstanceSettings()
|
||||||
v-if="!$store.state.instance.settings.users.registration_enabled.value"
|
v-if="!$store.state.instance.settings.users.registration_enabled.value"
|
||||||
class="required field"
|
class="required field"
|
||||||
>
|
>
|
||||||
<label for="invitation-code"><translate >Invitation code</translate></label>
|
<label for="invitation-code">Invitation code</label>
|
||||||
<input
|
<input
|
||||||
id="invitation-code"
|
id="invitation-code"
|
||||||
v-model="payload.invitation"
|
v-model="payload.invitation"
|
||||||
|
@ -229,9 +217,7 @@ fetchInstanceSettings()
|
||||||
:class="['ui', buttonClasses, {'loading': isLoading}, ' right floated button']"
|
:class="['ui', buttonClasses, {'loading': isLoading}, ' right floated button']"
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<translate >
|
Create my account
|
||||||
Create my account
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -82,36 +82,26 @@ fetchToken()
|
||||||
@submit.prevent="requestNewToken()"
|
@submit.prevent="requestNewToken()"
|
||||||
>
|
>
|
||||||
<h2>
|
<h2>
|
||||||
<translate >
|
Subsonic API password
|
||||||
Subsonic API password
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<p
|
<p
|
||||||
v-if="!subsonicEnabled"
|
v-if="!subsonicEnabled"
|
||||||
class="ui message"
|
class="ui message"
|
||||||
>
|
>
|
||||||
<translate >
|
The Subsonic API is not available on this Funkwhale instance.
|
||||||
The Subsonic API is not available on this Funkwhale instance.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Funkwhale is compatible with other music players that support the Subsonic API. You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance.
|
||||||
Funkwhale is compatible with other music players that support the Subsonic API.
|
|
||||||
</translate> <translate >
|
|
||||||
You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
However, accessing Funkwhale from those clients requires a separate password you can set below.
|
||||||
However, accessing Funkwhale from those clients requires a separate password you can set below.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
href="https://docs.funkwhale.audio/users/apps.html#subsonic-compatible-clients"
|
href="https://docs.funkwhale.audio/users/apps.html#subsonic-compatible-clients"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<translate >Discover how to use Funkwhale from other apps</translate>
|
Discover how to use Funkwhale from other apps
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<div
|
<div
|
||||||
|
@ -128,9 +118,7 @@ fetchToken()
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Error
|
||||||
Error
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -164,28 +152,20 @@ fetchToken()
|
||||||
:class="['ui', {'loading': isLoading}, 'button']"
|
:class="['ui', {'loading': isLoading}, 'button']"
|
||||||
:action="requestNewToken"
|
:action="requestNewToken"
|
||||||
>
|
>
|
||||||
<translate >
|
Request a new password
|
||||||
Request a new password
|
|
||||||
</translate>
|
|
||||||
<template #modal-header>
|
<template #modal-header>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Request a new Subsonic API password?
|
||||||
Request a new Subsonic API password?
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-content>
|
<template #modal-content>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
This will log you out from existing devices that use the current password.
|
||||||
This will log you out from existing devices that use the current password.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-confirm>
|
<template #modal-confirm>
|
||||||
<div>
|
<div>
|
||||||
<translate >
|
Request a new password
|
||||||
Request a new password
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</dangerous-button>
|
</dangerous-button>
|
||||||
|
@ -195,37 +175,27 @@ fetchToken()
|
||||||
:class="['ui', {'loading': isLoading}, 'button']"
|
:class="['ui', {'loading': isLoading}, 'button']"
|
||||||
@click="requestNewToken"
|
@click="requestNewToken"
|
||||||
>
|
>
|
||||||
<translate >
|
Request a password
|
||||||
Request a password
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<dangerous-button
|
<dangerous-button
|
||||||
v-if="token"
|
v-if="token"
|
||||||
:class="['ui', {'loading': isLoading}, 'warning', 'button']"
|
:class="['ui', {'loading': isLoading}, 'warning', 'button']"
|
||||||
:action="disable"
|
:action="disable"
|
||||||
>
|
>
|
||||||
<translate >
|
Disable Subsonic access
|
||||||
Disable Subsonic access
|
|
||||||
</translate>
|
|
||||||
<template #modal-header>
|
<template #modal-header>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Disable Subsonic API access?
|
||||||
Disable Subsonic API access?
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-content>
|
<template #modal-content>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
This will completely disable access to the Subsonic API using from account.
|
||||||
This will completely disable access to the Subsonic API using from account.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-confirm>
|
<template #modal-confirm>
|
||||||
<div>
|
<div>
|
||||||
<translate >
|
Disable access
|
||||||
Disable access
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</dangerous-button>
|
</dangerous-button>
|
||||||
|
|
|
@ -59,9 +59,7 @@ defineExpose({
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Error while creating
|
||||||
Error while creating
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -74,7 +72,7 @@ defineExpose({
|
||||||
</div>
|
</div>
|
||||||
<div class="ui required field">
|
<div class="ui required field">
|
||||||
<label for="album-title">
|
<label for="album-title">
|
||||||
<translate >Title</translate>
|
Title
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
v-model="title"
|
v-model="title"
|
||||||
|
|
|
@ -35,13 +35,11 @@ const albumForm = ref()
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate
|
<translate
|
||||||
v-if="channel.content_category === 'podcast'"
|
v-if="channel.content_category === 'podcast'"
|
||||||
|
|
||||||
>
|
>
|
||||||
New series
|
New series
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else
|
v-else
|
||||||
|
|
||||||
>
|
>
|
||||||
New album
|
New album
|
||||||
</translate>
|
</translate>
|
||||||
|
@ -57,18 +55,14 @@ const albumForm = ref()
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="ui basic cancel button">
|
<button class="ui basic cancel button">
|
||||||
<translate >
|
Cancel
|
||||||
Cancel
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
:class="['ui', 'primary', {loading: isLoading}, 'button']"
|
:class="['ui', 'primary', {loading: isLoading}, 'button']"
|
||||||
:disabled="!submittable"
|
:disabled="!submittable"
|
||||||
@click.stop.prevent="albumForm.submit()"
|
@click.stop.prevent="albumForm.submit()"
|
||||||
>
|
>
|
||||||
<translate >
|
Create
|
||||||
Create
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</semantic-modal>
|
</semantic-modal>
|
||||||
|
|
|
@ -49,11 +49,9 @@ watch(() => props.channel, fetchData, { immediate: true })
|
||||||
<label for="album-dropdown">
|
<label for="album-dropdown">
|
||||||
<translate
|
<translate
|
||||||
v-if="channel && channel.artist && channel.artist.content_category === 'podcast'"
|
v-if="channel && channel.artist && channel.artist.content_category === 'podcast'"
|
||||||
|
|
||||||
>Series</translate>
|
>Series</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else
|
v-else
|
||||||
|
|
||||||
>Album</translate>
|
>Album</translate>
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
|
@ -62,9 +60,7 @@ watch(() => props.channel, fetchData, { immediate: true })
|
||||||
class="ui search normal dropdown"
|
class="ui search normal dropdown"
|
||||||
>
|
>
|
||||||
<option value="">
|
<option value="">
|
||||||
<translate >
|
None
|
||||||
None
|
|
||||||
</translate>
|
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
v-for="album in albums"
|
v-for="album in albums"
|
||||||
|
|
|
@ -55,7 +55,7 @@ fetchLicenses()
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<label for="license-dropdown">
|
<label for="license-dropdown">
|
||||||
<translate >License</translate>
|
License
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="license-dropdown"
|
id="license-dropdown"
|
||||||
|
@ -63,9 +63,7 @@ fetchLicenses()
|
||||||
class="ui search normal dropdown"
|
class="ui search normal dropdown"
|
||||||
>
|
>
|
||||||
<option value="">
|
<option value="">
|
||||||
<translate >
|
None
|
||||||
None
|
|
||||||
</translate>
|
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
v-for="l in featuredLicenses"
|
v-for="l in featuredLicenses"
|
||||||
|
@ -86,7 +84,7 @@ fetchLicenses()
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer noopener"
|
rel="noreferrer noopener"
|
||||||
>
|
>
|
||||||
<translate >About this license</translate>
|
About this license
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -411,9 +411,7 @@ const labels = computed(() => ({
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Error while publishing
|
||||||
Error while publishing
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -426,7 +424,7 @@ const labels = computed(() => ({
|
||||||
</div>
|
</div>
|
||||||
<div :class="['ui', 'required', {hidden: step > 1}, 'field']">
|
<div :class="['ui', 'required', {hidden: step > 1}, 'field']">
|
||||||
<label for="channel-dropdown">
|
<label for="channel-dropdown">
|
||||||
<translate >Channel</translate>
|
Channel
|
||||||
</label>
|
</label>
|
||||||
<div
|
<div
|
||||||
id="channel-dropdown"
|
id="channel-dropdown"
|
||||||
|
@ -449,9 +447,7 @@ const labels = computed(() => ({
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<p>
|
<p>
|
||||||
<i class="copyright icon" />
|
<i class="copyright icon" />
|
||||||
<translate >
|
Add a license to your upload to ensure some freedoms to your public.
|
||||||
Add a license to your upload to ensure some freedoms to your public.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -464,9 +460,7 @@ const labels = computed(() => ({
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<p>
|
<p>
|
||||||
<i class="warning icon" />
|
<i class="warning icon" />
|
||||||
<translate >
|
You don't have any space left to upload your files. Please contact the moderators.
|
||||||
You don't have any space left to upload your files. Please contact the moderators.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -477,25 +471,19 @@ const labels = computed(() => ({
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
<i class="redo icon" />
|
<i class="redo icon" />
|
||||||
<translate >
|
You have some draft uploads pending publication.
|
||||||
You have some draft uploads pending publication.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
class="ui basic button"
|
class="ui basic button"
|
||||||
@click.stop.prevent="includeDraftUploads = false"
|
@click.stop.prevent="includeDraftUploads = false"
|
||||||
>
|
>
|
||||||
<translate >
|
Ignore
|
||||||
Ignore
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="ui basic button"
|
class="ui basic button"
|
||||||
@click.stop.prevent="includeDraftUploads = true"
|
@click.stop.prevent="includeDraftUploads = true"
|
||||||
>
|
>
|
||||||
<translate >
|
Resume
|
||||||
Resume
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -547,19 +535,16 @@ const labels = computed(() => ({
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<translate
|
<translate
|
||||||
v-if="file.active"
|
v-if="file.active"
|
||||||
|
|
||||||
>
|
>
|
||||||
Uploading
|
Uploading
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else-if="file.error"
|
v-else-if="file.error"
|
||||||
|
|
||||||
>
|
>
|
||||||
Errored
|
Errored
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else
|
v-else
|
||||||
|
|
||||||
>
|
>
|
||||||
Pending
|
Pending
|
||||||
</translate>
|
</translate>
|
||||||
|
@ -567,12 +552,12 @@ const labels = computed(() => ({
|
||||||
· {{ parseFloat(file.progress ?? '0') }}%
|
· {{ parseFloat(file.progress ?? '0') }}%
|
||||||
</template>
|
</template>
|
||||||
· <a @click.stop.prevent="remove(file)">
|
· <a @click.stop.prevent="remove(file)">
|
||||||
<translate >Remove</translate>
|
Remove
|
||||||
</a>
|
</a>
|
||||||
<template v-if="file.error">
|
<template v-if="file.error">
|
||||||
·
|
·
|
||||||
<a @click.stop.prevent="retry(file)">
|
<a @click.stop.prevent="retry(file)">
|
||||||
<translate >Retry</translate>
|
Retry
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
@ -615,15 +600,11 @@ const labels = computed(() => ({
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<i class="upload icon" />
|
<i class="upload icon" />
|
||||||
<translate >
|
Drag and drop your files here or open the browser to upload your files
|
||||||
Drag and drop your files here or open the browser to upload your files
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="ui very small divider" />
|
<div class="ui very small divider" />
|
||||||
<div>
|
<div>
|
||||||
<translate >
|
Browse…
|
||||||
Browse…
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</file-upload-widget>
|
</file-upload-widget>
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
|
|
|
@ -33,7 +33,7 @@ watch(newValues, (values) => emit('update:values', values), { immediate: true })
|
||||||
<div :class="['ui', {loading: isLoading}, 'form']">
|
<div :class="['ui', {loading: isLoading}, 'form']">
|
||||||
<div class="ui required field">
|
<div class="ui required field">
|
||||||
<label for="upload-title">
|
<label for="upload-title">
|
||||||
<translate >Title</translate>
|
Title
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
v-model="newValues.title"
|
v-model="newValues.title"
|
||||||
|
@ -44,15 +44,13 @@ watch(newValues, (values) => emit('update:values', values), { immediate: true })
|
||||||
v-model="newValues.cover"
|
v-model="newValues.cover"
|
||||||
@delete="newValues.cover = ''"
|
@delete="newValues.cover = ''"
|
||||||
>
|
>
|
||||||
<translate >
|
Track Picture
|
||||||
Track Picture
|
|
||||||
</translate>
|
|
||||||
</attachment-input>
|
</attachment-input>
|
||||||
<div class="ui small hidden divider" />
|
<div class="ui small hidden divider" />
|
||||||
<div class="ui two fields">
|
<div class="ui two fields">
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<label for="upload-tags">
|
<label for="upload-tags">
|
||||||
<translate >Tags</translate>
|
Tags
|
||||||
</label>
|
</label>
|
||||||
<tags-selector
|
<tags-selector
|
||||||
id="upload-tags"
|
id="upload-tags"
|
||||||
|
@ -62,7 +60,7 @@ watch(newValues, (values) => emit('update:values', values), { immediate: true })
|
||||||
</div>
|
</div>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<label for="upload-position">
|
<label for="upload-position">
|
||||||
<translate >Position</translate>
|
Position
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
v-model="newValues.position"
|
v-model="newValues.position"
|
||||||
|
@ -74,7 +72,7 @@ watch(newValues, (values) => emit('update:values', values), { immediate: true })
|
||||||
</div>
|
</div>
|
||||||
<div class="ui field">
|
<div class="ui field">
|
||||||
<label for="upload-description">
|
<label for="upload-description">
|
||||||
<translate >Description</translate>
|
Description
|
||||||
</label>
|
</label>
|
||||||
<content-form
|
<content-form
|
||||||
v-model="newValues.description"
|
v-model="newValues.description"
|
||||||
|
|
|
@ -56,25 +56,21 @@ const isLoading = ref(false)
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate
|
<translate
|
||||||
v-if="step === 1"
|
v-if="step === 1"
|
||||||
|
|
||||||
>
|
>
|
||||||
Publish audio
|
Publish audio
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else-if="step === 2"
|
v-else-if="step === 2"
|
||||||
|
|
||||||
>
|
>
|
||||||
Files to upload
|
Files to upload
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else-if="step === 3"
|
v-else-if="step === 3"
|
||||||
|
|
||||||
>
|
>
|
||||||
Upload details
|
Upload details
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else-if="step === 4"
|
v-else-if="step === 4"
|
||||||
|
|
||||||
>
|
>
|
||||||
Processing uploads
|
Processing uploads
|
||||||
</translate>
|
</translate>
|
||||||
|
@ -95,9 +91,7 @@ const isLoading = ref(false)
|
||||||
</template>
|
</template>
|
||||||
<div class="ui very small hidden divider" />
|
<div class="ui very small hidden divider" />
|
||||||
<template v-if="statusData && statusData.quotaStatus">
|
<template v-if="statusData && statusData.quotaStatus">
|
||||||
<translate >
|
Remaining storage space:
|
||||||
Remaining storage space:
|
|
||||||
</translate>
|
|
||||||
{{ humanSize((statusData.quotaStatus.remaining - statusData.uploadedSize) * 1000 * 1000) }}
|
{{ humanSize((statusData.quotaStatus.remaining - statusData.uploadedSize) * 1000 * 1000) }}
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
@ -106,36 +100,28 @@ const isLoading = ref(false)
|
||||||
v-if="step === 1"
|
v-if="step === 1"
|
||||||
class="ui basic cancel button"
|
class="ui basic cancel button"
|
||||||
>
|
>
|
||||||
<translate >
|
Cancel
|
||||||
Cancel
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-else-if="step < 3"
|
v-else-if="step < 3"
|
||||||
class="ui basic button"
|
class="ui basic button"
|
||||||
@click.stop.prevent="uploadForm.step -= 1"
|
@click.stop.prevent="uploadForm.step -= 1"
|
||||||
>
|
>
|
||||||
<translate >
|
Previous step
|
||||||
Previous step
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-else-if="step === 3"
|
v-else-if="step === 3"
|
||||||
class="ui basic button"
|
class="ui basic button"
|
||||||
@click.stop.prevent="uploadForm.step -= 1"
|
@click.stop.prevent="uploadForm.step -= 1"
|
||||||
>
|
>
|
||||||
<translate >
|
Update
|
||||||
Update
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="step === 1"
|
v-if="step === 1"
|
||||||
class="ui primary button"
|
class="ui primary button"
|
||||||
@click.stop.prevent="uploadForm.step += 1"
|
@click.stop.prevent="uploadForm.step += 1"
|
||||||
>
|
>
|
||||||
<translate >
|
Next step
|
||||||
Next step
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<div
|
<div
|
||||||
v-if="step === 2"
|
v-if="step === 2"
|
||||||
|
@ -147,9 +133,7 @@ const isLoading = ref(false)
|
||||||
:disabled="!statusData?.canSubmit || undefined"
|
:disabled="!statusData?.canSubmit || undefined"
|
||||||
@click.prevent.stop="uploadForm.publish"
|
@click.prevent.stop="uploadForm.publish"
|
||||||
>
|
>
|
||||||
<translate >
|
Publish
|
||||||
Publish
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
ref="dropdown"
|
ref="dropdown"
|
||||||
|
@ -164,9 +148,7 @@ const isLoading = ref(false)
|
||||||
class="basic item"
|
class="basic item"
|
||||||
@click="update(false)"
|
@click="update(false)"
|
||||||
>
|
>
|
||||||
<translate >
|
Finish later
|
||||||
Finish later
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
@ -176,9 +158,7 @@ const isLoading = ref(false)
|
||||||
class="ui basic cancel button"
|
class="ui basic cancel button"
|
||||||
@click="update(false)"
|
@click="update(false)"
|
||||||
>
|
>
|
||||||
<translate >
|
Close
|
||||||
Close
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</semantic-modal>
|
</semantic-modal>
|
||||||
|
|
|
@ -167,7 +167,7 @@ const launchAction = async () => {
|
||||||
class="right floated"
|
class="right floated"
|
||||||
>
|
>
|
||||||
<span v-if="needsRefresh">
|
<span v-if="needsRefresh">
|
||||||
<translate >Content has been updated, click refresh to see up-to-date content</translate>
|
Content has been updated, click refresh to see up-to-date content
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
class="ui basic icon button"
|
class="ui basic icon button"
|
||||||
|
@ -185,7 +185,7 @@ const launchAction = async () => {
|
||||||
>
|
>
|
||||||
<div class="ui inline fields">
|
<div class="ui inline fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="actions-select"><translate >Actions</translate></label>
|
<label for="actions-select">Actions</label>
|
||||||
<select
|
<select
|
||||||
id="actions-select"
|
id="actions-select"
|
||||||
v-model="currentActionName"
|
v-model="currentActionName"
|
||||||
|
@ -208,9 +208,7 @@ const launchAction = async () => {
|
||||||
:aria-label="labels.performAction"
|
:aria-label="labels.performAction"
|
||||||
@confirm="launchAction"
|
@confirm="launchAction"
|
||||||
>
|
>
|
||||||
<translate >
|
Go
|
||||||
Go
|
|
||||||
</translate>
|
|
||||||
<template #modal-header>
|
<template #modal-header>
|
||||||
<p>
|
<p>
|
||||||
<translate
|
<translate
|
||||||
|
@ -231,7 +229,6 @@ const launchAction = async () => {
|
||||||
</template>
|
</template>
|
||||||
<translate
|
<translate
|
||||||
v-else
|
v-else
|
||||||
|
|
||||||
>
|
>
|
||||||
This may affect a lot of elements or have irreversible consequences, please double check this is really what you want.
|
This may affect a lot of elements or have irreversible consequences, please double check this is really what you want.
|
||||||
</translate>
|
</translate>
|
||||||
|
@ -239,9 +236,7 @@ const launchAction = async () => {
|
||||||
</template>
|
</template>
|
||||||
<template #modal-confirm>
|
<template #modal-confirm>
|
||||||
<div :aria-label="labels.performAction">
|
<div :aria-label="labels.performAction">
|
||||||
<translate >
|
Launch
|
||||||
Launch
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</dangerous-button>
|
</dangerous-button>
|
||||||
|
@ -252,9 +247,7 @@ const launchAction = async () => {
|
||||||
:class="['ui', {disabled: checked.length === 0}, {'loading': isLoading}, 'button']"
|
:class="['ui', {disabled: checked.length === 0}, {'loading': isLoading}, 'button']"
|
||||||
@click="launchAction"
|
@click="launchAction"
|
||||||
>
|
>
|
||||||
<translate >
|
Go
|
||||||
Go
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="count field">
|
<div class="count field">
|
||||||
|
@ -301,7 +294,6 @@ const launchAction = async () => {
|
||||||
>
|
>
|
||||||
<translate
|
<translate
|
||||||
key="4"
|
key="4"
|
||||||
|
|
||||||
>Select only current page</translate>
|
>Select only current page</translate>
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
|
@ -313,9 +305,7 @@ const launchAction = async () => {
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Error while applying action
|
||||||
Error while applying action
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
|
|
@ -107,9 +107,7 @@ const getAttachmentUrl = (uuid: string) => {
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Your attachment cannot be saved
|
||||||
Your attachment cannot be saved
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -146,7 +144,7 @@ const getAttachmentUrl = (uuid: string) => {
|
||||||
<div class="eleven wide column">
|
<div class="eleven wide column">
|
||||||
<div class="file-input">
|
<div class="file-input">
|
||||||
<label :for="attachmentId">
|
<label :for="attachmentId">
|
||||||
<translate >Upload New Picture…</translate>
|
Upload New Picture…
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
:id="attachmentId"
|
:id="attachmentId"
|
||||||
|
@ -161,27 +159,21 @@ const getAttachmentUrl = (uuid: string) => {
|
||||||
</div>
|
</div>
|
||||||
<div class="ui very small hidden divider" />
|
<div class="ui very small hidden divider" />
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
PNG or JPG. Dimensions should be between 1400x1400px and 3000x3000px. Maximum file size allowed is 5MB.
|
||||||
PNG or JPG. Dimensions should be between 1400x1400px and 3000x3000px. Maximum file size allowed is 5MB.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
v-if="value"
|
v-if="value"
|
||||||
class="ui basic tiny button"
|
class="ui basic tiny button"
|
||||||
@click.stop.prevent="remove(value as string)"
|
@click.stop.prevent="remove(value as string)"
|
||||||
>
|
>
|
||||||
<translate >
|
Remove
|
||||||
Remove
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<div
|
<div
|
||||||
v-if="isLoading"
|
v-if="isLoading"
|
||||||
class="ui active inverted dimmer"
|
class="ui active inverted dimmer"
|
||||||
>
|
>
|
||||||
<div class="ui indeterminate text loader">
|
<div class="ui indeterminate text loader">
|
||||||
<translate >
|
Uploading file…
|
||||||
Uploading file…
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,13 +22,11 @@ const value = useVModel(props, 'modelValue', emit)
|
||||||
>
|
>
|
||||||
<translate
|
<translate
|
||||||
v-if="value"
|
v-if="value"
|
||||||
|
|
||||||
>
|
>
|
||||||
Expand
|
Expand
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else
|
v-else
|
||||||
|
|
||||||
>
|
>
|
||||||
Collapse
|
Collapse
|
||||||
</translate>
|
</translate>
|
||||||
|
|
|
@ -86,17 +86,13 @@ onMounted(async () => {
|
||||||
:class="[{active: !isPreviewing}, 'item']"
|
:class="[{active: !isPreviewing}, 'item']"
|
||||||
@click.prevent="isPreviewing = false"
|
@click.prevent="isPreviewing = false"
|
||||||
>
|
>
|
||||||
<translate >
|
Write
|
||||||
Write
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
:class="[{active: isPreviewing}, 'item']"
|
:class="[{active: isPreviewing}, 'item']"
|
||||||
@click.prevent="isPreviewing = true"
|
@click.prevent="isPreviewing = true"
|
||||||
>
|
>
|
||||||
<translate >
|
Preview
|
||||||
Preview
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="isPreviewing">
|
<template v-if="isPreviewing">
|
||||||
|
@ -112,9 +108,7 @@ onMounted(async () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p v-else-if="!preview">
|
<p v-else-if="!preview">
|
||||||
<translate >
|
Nothing to preview.
|
||||||
Nothing to preview.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<sanitized-html
|
<sanitized-html
|
||||||
v-else
|
v-else
|
||||||
|
@ -141,9 +135,7 @@ onMounted(async () => {
|
||||||
{{ remainingChars }}
|
{{ remainingChars }}
|
||||||
</span>
|
</span>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Markdown syntax is supported.
|
||||||
Markdown syntax is supported.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,9 +22,7 @@ const { copy, isSupported: canCopy, copied } = useClipboard({ source: value, cop
|
||||||
v-if="copied"
|
v-if="copied"
|
||||||
class="message"
|
class="message"
|
||||||
>
|
>
|
||||||
<translate >
|
Text copied to clipboard!
|
||||||
Text copied to clipboard!
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<input
|
<input
|
||||||
:id="id"
|
:id="id"
|
||||||
|
@ -39,9 +37,7 @@ const { copy, isSupported: canCopy, copied } = useClipboard({ source: value, cop
|
||||||
@click="copy()"
|
@click="copy()"
|
||||||
>
|
>
|
||||||
<i class="copy icon" />
|
<i class="copy icon" />
|
||||||
<translate >
|
Copy
|
||||||
Copy
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -42,9 +42,7 @@ const confirm = () => {
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<slot name="modal-header">
|
<slot name="modal-header">
|
||||||
<translate >
|
Do you want to confirm this action?
|
||||||
Do you want to confirm this action?
|
|
||||||
</translate>
|
|
||||||
</slot>
|
</slot>
|
||||||
</h4>
|
</h4>
|
||||||
<div class="scrolling content">
|
<div class="scrolling content">
|
||||||
|
@ -54,18 +52,14 @@ const confirm = () => {
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="ui basic cancel button">
|
<button class="ui basic cancel button">
|
||||||
<translate >
|
Cancel
|
||||||
Cancel
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
:class="['ui', 'confirm', confirmColor, 'button']"
|
:class="['ui', 'confirm', confirmColor, 'button']"
|
||||||
@click="confirm"
|
@click="confirm"
|
||||||
>
|
>
|
||||||
<slot name="modal-confirm">
|
<slot name="modal-confirm">
|
||||||
<translate >
|
Confirm
|
||||||
Confirm
|
|
||||||
</translate>
|
|
||||||
</slot>
|
</slot>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -19,9 +19,7 @@ withDefaults(defineProps<Props>(), {
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<slot name="title">
|
<slot name="title">
|
||||||
<i class="search icon" />
|
<i class="search icon" />
|
||||||
<translate >
|
No results were found.
|
||||||
No results were found.
|
|
||||||
</translate>
|
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
</h4>
|
</h4>
|
||||||
|
@ -32,9 +30,7 @@ withDefaults(defineProps<Props>(), {
|
||||||
class="ui button"
|
class="ui button"
|
||||||
@click="emit('refresh')"
|
@click="emit('refresh')"
|
||||||
>
|
>
|
||||||
<translate >
|
Refresh
|
||||||
Refresh
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -28,11 +28,9 @@ const truncated = computed(() => props.content.slice(0, props.length))
|
||||||
<br>
|
<br>
|
||||||
<translate
|
<translate
|
||||||
v-if="expanded"
|
v-if="expanded"
|
||||||
|
|
||||||
>Show less</translate>
|
>Show less</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else
|
v-else
|
||||||
|
|
||||||
>Show more</translate>
|
>Show more</translate>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -42,7 +42,7 @@ const search = () => {
|
||||||
for="search-query"
|
for="search-query"
|
||||||
class="hidden"
|
class="hidden"
|
||||||
>
|
>
|
||||||
<translate >Search</translate>
|
Search
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
id="search-query"
|
id="search-query"
|
||||||
|
|
|
@ -91,21 +91,19 @@ const submit = async () => {
|
||||||
href=""
|
href=""
|
||||||
@click.stop.prevent="showMore = true"
|
@click.stop.prevent="showMore = true"
|
||||||
>
|
>
|
||||||
<translate >Show more</translate>
|
Show more
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
v-else
|
v-else
|
||||||
href=""
|
href=""
|
||||||
@click.stop.prevent="showMore = false"
|
@click.stop.prevent="showMore = false"
|
||||||
>
|
>
|
||||||
<translate >Show less</translate>
|
Show less
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<p v-else-if="!isUpdating">
|
<p v-else-if="!isUpdating">
|
||||||
<translate >
|
No description available
|
||||||
No description available
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<template v-if="!isUpdating && canUpdate && updateUrl">
|
<template v-if="!isUpdating && canUpdate && updateUrl">
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
|
@ -114,7 +112,7 @@ const submit = async () => {
|
||||||
@click="isUpdating = true"
|
@click="isUpdating = true"
|
||||||
>
|
>
|
||||||
<i class="pencil icon" />
|
<i class="pencil icon" />
|
||||||
<translate >Edit</translate>
|
Edit
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<form
|
<form
|
||||||
|
@ -128,9 +126,7 @@ const submit = async () => {
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Error while updating description
|
||||||
Error while updating description
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -149,16 +145,14 @@ const submit = async () => {
|
||||||
class="left floated"
|
class="left floated"
|
||||||
@click.prevent="isUpdating = false"
|
@click.prevent="isUpdating = false"
|
||||||
>
|
>
|
||||||
<translate >Cancel</translate>
|
Cancel
|
||||||
</a>
|
</a>
|
||||||
<button
|
<button
|
||||||
:class="['ui', {'loading': isLoading}, 'right', 'floated', 'button']"
|
:class="['ui', {'loading': isLoading}, 'right', 'floated', 'button']"
|
||||||
type="submit"
|
type="submit"
|
||||||
:disabled="isLoading"
|
:disabled="isLoading"
|
||||||
>
|
>
|
||||||
<translate >
|
Update description
|
||||||
Update description
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<div class="ui clearing hidden divider" />
|
<div class="ui clearing hidden divider" />
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -63,13 +63,13 @@ const labels = computed(() => ({
|
||||||
class="menu"
|
class="menu"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
v-for="t in themes"
|
v-for="th in themes"
|
||||||
:key="t.key"
|
:key="th.key"
|
||||||
:class="[{'active': theme === t.key}, 'item']"
|
:class="[{'active': theme === th.key}, 'item']"
|
||||||
:value="t.key"
|
:value="th.key"
|
||||||
@click="theme = t.key"
|
@click="theme = th.key"
|
||||||
>
|
>
|
||||||
<i :class="t.icon" />
|
<i :class="th.icon" />
|
||||||
{{ t.name }}
|
{{ t.name }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -166,7 +166,7 @@ const labels = computed(() => ({
|
||||||
<div class="divider" />
|
<div class="divider" />
|
||||||
<router-link
|
<router-link
|
||||||
class="item"
|
class="item"
|
||||||
style="color: var(--danger-color)!important;"
|
style="color: var(--danger-color) !important;"
|
||||||
:to="{ name: 'logout' }"
|
:to="{ name: 'logout' }"
|
||||||
>
|
>
|
||||||
<i class="sign out alternate icon" />
|
<i class="sign out alternate icon" />
|
||||||
|
|
|
@ -112,9 +112,7 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
|
||||||
<section class="ui vertical center aligned stripe segment">
|
<section class="ui vertical center aligned stripe segment">
|
||||||
<div :class="['ui', { 'active': isLoading }, 'inverted', 'dimmer']">
|
<div :class="['ui', { 'active': isLoading }, 'inverted', 'dimmer']">
|
||||||
<div class="ui text loader">
|
<div class="ui text loader">
|
||||||
<translate >
|
Loading your favorites…
|
||||||
Loading your favorites…
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2
|
<h2
|
||||||
|
@ -126,7 +124,6 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
|
||||||
translate-plural="%{ count } favorites"
|
translate-plural="%{ count } favorites"
|
||||||
:translate-n="$store.state.favorites.count"
|
:translate-n="$store.state.favorites.count"
|
||||||
:translate-params="{ count }"
|
:translate-params="{ count }"
|
||||||
|
|
||||||
>
|
>
|
||||||
%{ count } favorite
|
%{ count } favorite
|
||||||
</translate>
|
</translate>
|
||||||
|
@ -144,7 +141,7 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
|
||||||
<div class="fields">
|
<div class="fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="favorites-ordering">
|
<label for="favorites-ordering">
|
||||||
<translate >Ordering</translate>
|
Ordering
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="favorites-ordering"
|
id="favorites-ordering"
|
||||||
|
@ -162,7 +159,7 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="favorites-ordering-direction">
|
<label for="favorites-ordering-direction">
|
||||||
<translate >Order</translate>
|
Order
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="favorites-ordering-direction"
|
id="favorites-ordering-direction"
|
||||||
|
@ -170,20 +167,16 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
|
||||||
class="ui dropdown"
|
class="ui dropdown"
|
||||||
>
|
>
|
||||||
<option value="+">
|
<option value="+">
|
||||||
<translate >
|
Ascending
|
||||||
Ascending
|
|
||||||
</translate>
|
|
||||||
</option>
|
</option>
|
||||||
<option value="-">
|
<option value="-">
|
||||||
<translate >
|
Descending
|
||||||
Descending
|
|
||||||
</translate>
|
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="favorites-results">
|
<label for="favorites-results">
|
||||||
<translate >Results per page</translate>
|
Results per page
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="favorites-results"
|
id="favorites-results"
|
||||||
|
@ -222,20 +215,14 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
|
||||||
>
|
>
|
||||||
<div class="ui icon header">
|
<div class="ui icon header">
|
||||||
<i class="broken heart icon" />
|
<i class="broken heart icon" />
|
||||||
<translate
|
No tracks have been added to your favorites yet
|
||||||
|
|
||||||
>
|
|
||||||
No tracks have been added to your favorites yet
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
<router-link
|
<router-link
|
||||||
:to="'/library'"
|
:to="'/library'"
|
||||||
class="ui success labeled icon button"
|
class="ui success labeled icon button"
|
||||||
>
|
>
|
||||||
<i class="headphones icon" />
|
<i class="headphones icon" />
|
||||||
<translate >
|
Browse the library
|
||||||
Browse the library
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -37,13 +37,11 @@ const title = computed(() => isFavorite.value
|
||||||
<i class="heart icon" />
|
<i class="heart icon" />
|
||||||
<translate
|
<translate
|
||||||
v-if="isFavorite"
|
v-if="isFavorite"
|
||||||
|
|
||||||
>
|
>
|
||||||
In favorites
|
In favorites
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else
|
v-else
|
||||||
|
|
||||||
>
|
>
|
||||||
Add to favorites
|
Add to favorites
|
||||||
</translate>
|
</translate>
|
||||||
|
|
|
@ -80,9 +80,7 @@ const { start: startPolling } = useTimeoutFn(poll, 1000, { immediate: false })
|
||||||
class="small"
|
class="small"
|
||||||
>
|
>
|
||||||
<h3 class="header">
|
<h3 class="header">
|
||||||
<translate >
|
Refreshing object from remote server…
|
||||||
Refreshing object from remote server…
|
|
||||||
</translate>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div class="scrolling content">
|
<div class="scrolling content">
|
||||||
<template v-if="data && data.status != 'pending'">
|
<template v-if="data && data.status != 'pending'">
|
||||||
|
@ -91,14 +89,10 @@ const { start: startPolling } = useTimeoutFn(poll, 1000, { immediate: false })
|
||||||
class="ui message"
|
class="ui message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Refresh was skipped
|
||||||
Refresh was skipped
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
The remote server answered, but returned data was unsupported by Funkwhale.
|
||||||
The remote server answered, but returned data was unsupported by Funkwhale.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -106,14 +100,10 @@ const { start: startPolling } = useTimeoutFn(poll, 1000, { immediate: false })
|
||||||
class="ui success message"
|
class="ui success message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Refresh successful
|
||||||
Refresh successful
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
Data was refreshed successfully from remote server.
|
||||||
Data was refreshed successfully from remote server.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -121,22 +111,16 @@ const { start: startPolling } = useTimeoutFn(poll, 1000, { immediate: false })
|
||||||
class="ui error message"
|
class="ui error message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Refresh error
|
||||||
Refresh error
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
An error occurred while trying to refresh data:
|
||||||
An error occurred while trying to refresh data:
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<table class="ui very basic collapsing celled table">
|
<table class="ui very basic collapsing celled table">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<translate >
|
Error type
|
||||||
Error type
|
|
||||||
</translate>
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ data.detail.error_code }}
|
{{ data.detail.error_code }}
|
||||||
|
@ -144,57 +128,47 @@ const { start: startPolling } = useTimeoutFn(poll, 1000, { immediate: false })
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<translate >
|
Error detail
|
||||||
Error detail
|
|
||||||
</translate>
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<translate
|
<translate
|
||||||
v-if="data.detail.error_code === 'http' && data.detail.status_code"
|
v-if="data.detail.error_code === 'http' && data.detail.status_code"
|
||||||
:translate-params="{status: data.detail.status_code}"
|
:translate-params="{status: data.detail.status_code}"
|
||||||
|
|
||||||
>
|
>
|
||||||
The remote server answered with HTTP %{ status }
|
The remote server answered with HTTP %{ status }
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else-if="['http', 'request'].indexOf(data.detail.error_code) > -1"
|
v-else-if="['http', 'request'].indexOf(data.detail.error_code) > -1"
|
||||||
|
|
||||||
>
|
>
|
||||||
An HTTP error occurred while contacting the remote server
|
An HTTP error occurred while contacting the remote server
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else-if="data.detail.error_code === 'timeout'"
|
v-else-if="data.detail.error_code === 'timeout'"
|
||||||
|
|
||||||
>
|
>
|
||||||
The remote server didn't respond quickly enough
|
The remote server didn't respond quickly enough
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else-if="data.detail.error_code === 'connection'"
|
v-else-if="data.detail.error_code === 'connection'"
|
||||||
|
|
||||||
>
|
>
|
||||||
Impossible to connect to the remote server
|
Impossible to connect to the remote server
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else-if="['invalid_json', 'invalid_jsonld', 'missing_jsonld_type'].indexOf(data.detail.error_code) > -1"
|
v-else-if="['invalid_json', 'invalid_jsonld', 'missing_jsonld_type'].indexOf(data.detail.error_code) > -1"
|
||||||
|
|
||||||
>
|
>
|
||||||
The remote server returned invalid JSON or JSON-LD data
|
The remote server returned invalid JSON or JSON-LD data
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else-if="data.detail.error_code === 'validation'"
|
v-else-if="data.detail.error_code === 'validation'"
|
||||||
|
|
||||||
>
|
>
|
||||||
Data returned by the remote server had invalid or missing attributes
|
Data returned by the remote server had invalid or missing attributes
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else-if="data.detail.error_code === 'unhandled'"
|
v-else-if="data.detail.error_code === 'unhandled'"
|
||||||
|
|
||||||
>
|
>
|
||||||
Unknown error
|
Unknown error
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else
|
v-else
|
||||||
|
|
||||||
>
|
>
|
||||||
Unknown error
|
Unknown error
|
||||||
</translate>
|
</translate>
|
||||||
|
@ -209,9 +183,7 @@ const { start: startPolling } = useTimeoutFn(poll, 1000, { immediate: false })
|
||||||
class="ui active inverted dimmer"
|
class="ui active inverted dimmer"
|
||||||
>
|
>
|
||||||
<div class="ui text loader">
|
<div class="ui text loader">
|
||||||
<translate >
|
Requesting a fetch…
|
||||||
Requesting a fetch…
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -219,9 +191,7 @@ const { start: startPolling } = useTimeoutFn(poll, 1000, { immediate: false })
|
||||||
class="ui active inverted dimmer"
|
class="ui active inverted dimmer"
|
||||||
>
|
>
|
||||||
<div class="ui text loader">
|
<div class="ui text loader">
|
||||||
<translate >
|
Waiting for result…
|
||||||
Waiting for result…
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -230,9 +200,7 @@ const { start: startPolling } = useTimeoutFn(poll, 1000, { immediate: false })
|
||||||
class="ui negative message"
|
class="ui negative message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Error while saving settings
|
||||||
Error while saving settings
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
<li
|
<li
|
||||||
|
@ -249,31 +217,23 @@ const { start: startPolling } = useTimeoutFn(poll, 1000, { immediate: false })
|
||||||
class="ui warning message"
|
class="ui warning message"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Refresh pending
|
||||||
Refresh pending
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
The refresh request hasn't been processed in time by our server. It will be processed later.
|
||||||
The refresh request hasn't been processed in time by our server. It will be processed later.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="ui basic cancel button">
|
<button class="ui basic cancel button">
|
||||||
<translate >
|
Close
|
||||||
Close
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="data && data.status === 'finished'"
|
v-if="data && data.status === 'finished'"
|
||||||
class="ui confirm success button"
|
class="ui confirm success button"
|
||||||
@click.prevent="showModal = false; emit('refresh')"
|
@click.prevent="showModal = false; emit('refresh')"
|
||||||
>
|
>
|
||||||
<translate >
|
Close and reload page
|
||||||
Close and reload page
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</semantic-modal>
|
</semantic-modal>
|
||||||
|
|
|
@ -64,9 +64,7 @@ fetchData()
|
||||||
v-if="!isLoading && libraries.length === 0"
|
v-if="!isLoading && libraries.length === 0"
|
||||||
class="ui subtitle"
|
class="ui subtitle"
|
||||||
>
|
>
|
||||||
<translate >
|
No matching library.
|
||||||
No matching library.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
<div class="ui cards">
|
<div class="ui cards">
|
||||||
|
@ -92,9 +90,7 @@ fetchData()
|
||||||
:class="['ui', 'basic', 'button']"
|
:class="['ui', 'basic', 'button']"
|
||||||
@click="fetchData(nextPage)"
|
@click="fetchData(nextPage)"
|
||||||
>
|
>
|
||||||
<translate >
|
Show more
|
||||||
Show more
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -323,9 +323,7 @@ const remove = async () => {
|
||||||
:to="{name: 'library.albums.edit', params: {id: object.id }}"
|
:to="{name: 'library.albums.edit', params: {id: object.id }}"
|
||||||
>
|
>
|
||||||
<i class="pencil icon" />
|
<i class="pencil icon" />
|
||||||
<translate >
|
Add a description…
|
||||||
Add a description…
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -341,9 +339,7 @@ const remove = async () => {
|
||||||
:to="{name: 'library.albums.edit', params: {id: object.id }}"
|
:to="{name: 'library.albums.edit', params: {id: object.id }}"
|
||||||
>
|
>
|
||||||
<i class="pencil icon" />
|
<i class="pencil icon" />
|
||||||
<translate >
|
Add a description…
|
||||||
Add a description…
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -62,13 +62,11 @@ const paginatedDiscs = computed(() => props.object.tracks.slice(props.paginateBy
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<translate
|
<translate
|
||||||
v-if="isSerie"
|
v-if="isSerie"
|
||||||
|
|
||||||
>
|
>
|
||||||
Episodes
|
Episodes
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else
|
v-else
|
||||||
|
|
||||||
>
|
>
|
||||||
Tracks
|
Tracks
|
||||||
</translate>
|
</translate>
|
||||||
|
@ -137,17 +135,13 @@ const paginatedDiscs = computed(() => props.object.tracks.slice(props.paginateBy
|
||||||
|
|
||||||
<template v-if="!artist.channel && !isSerie">
|
<template v-if="!artist.channel && !isSerie">
|
||||||
<h2>
|
<h2>
|
||||||
<translate >
|
User libraries
|
||||||
User libraries
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<library-widget
|
<library-widget
|
||||||
:url="'albums/' + object.id + '/libraries/'"
|
:url="'albums/' + object.id + '/libraries/'"
|
||||||
@loaded="emit('libraries-loaded', $event)"
|
@loaded="emit('libraries-loaded', $event)"
|
||||||
>
|
>
|
||||||
<translate >
|
This album is present in the following libraries:
|
||||||
This album is present in the following libraries:
|
|
||||||
</translate>
|
|
||||||
</library-widget>
|
</library-widget>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -53,7 +53,7 @@ const remove = () => emit('remove')
|
||||||
v-model:show="showEmbedModal"
|
v-model:show="showEmbedModal"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >Embed this album on your website</translate>
|
Embed this album on your website
|
||||||
</h4>
|
</h4>
|
||||||
<div class="scrolling content">
|
<div class="scrolling content">
|
||||||
<div class="description">
|
<div class="description">
|
||||||
|
@ -66,7 +66,7 @@ const remove = () => emit('remove')
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="ui basic deny button">
|
<button class="ui basic deny button">
|
||||||
<translate >Cancel</translate>
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</semantic-modal>
|
</semantic-modal>
|
||||||
|
@ -86,7 +86,6 @@ const remove = () => emit('remove')
|
||||||
<i class="external icon" />
|
<i class="external icon" />
|
||||||
<translate
|
<translate
|
||||||
:translate-params="{domain: domain}"
|
:translate-params="{domain: domain}"
|
||||||
|
|
||||||
>View on %{ domain }</translate>
|
>View on %{ domain }</translate>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
@ -97,7 +96,7 @@ const remove = () => emit('remove')
|
||||||
@click="showEmbedModal = !showEmbedModal"
|
@click="showEmbedModal = !showEmbedModal"
|
||||||
>
|
>
|
||||||
<i class="code icon" />
|
<i class="code icon" />
|
||||||
<translate >Embed</translate>
|
Embed
|
||||||
</div>
|
</div>
|
||||||
<a
|
<a
|
||||||
v-if="isAlbum && musicbrainzUrl"
|
v-if="isAlbum && musicbrainzUrl"
|
||||||
|
@ -107,7 +106,7 @@ const remove = () => emit('remove')
|
||||||
class="basic item"
|
class="basic item"
|
||||||
>
|
>
|
||||||
<i class="external icon" />
|
<i class="external icon" />
|
||||||
<translate >View on MusicBrainz</translate>
|
View on MusicBrainz
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
v-if="!isChannel && isAlbum"
|
v-if="!isChannel && isAlbum"
|
||||||
|
@ -117,7 +116,7 @@ const remove = () => emit('remove')
|
||||||
class="basic item"
|
class="basic item"
|
||||||
>
|
>
|
||||||
<i class="external icon" />
|
<i class="external icon" />
|
||||||
<translate >Search on Discogs</translate>
|
Search on Discogs
|
||||||
</a>
|
</a>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="object.is_local"
|
v-if="object.is_local"
|
||||||
|
@ -125,7 +124,7 @@ const remove = () => emit('remove')
|
||||||
class="basic item"
|
class="basic item"
|
||||||
>
|
>
|
||||||
<i class="edit icon" />
|
<i class="edit icon" />
|
||||||
<translate >Edit</translate>
|
Edit
|
||||||
</router-link>
|
</router-link>
|
||||||
<dangerous-button
|
<dangerous-button
|
||||||
v-if="artist && $store.state.auth.authenticated && artist.channel && artist.attributed_to.full_username === $store.state.auth.fullUsername"
|
v-if="artist && $store.state.auth.authenticated && artist.channel && artist.attributed_to.full_username === $store.state.auth.fullUsername"
|
||||||
|
@ -133,24 +132,22 @@ const remove = () => emit('remove')
|
||||||
@confirm="remove()"
|
@confirm="remove()"
|
||||||
>
|
>
|
||||||
<i class="ui trash icon" />
|
<i class="ui trash icon" />
|
||||||
<translate >Delete…</translate>
|
Delete…
|
||||||
<template #modal-header>
|
<template #modal-header>
|
||||||
<p>
|
<p>
|
||||||
<translate >Delete this album?</translate>
|
Delete this album?
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-content>
|
<template #modal-content>
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
The album will be deleted, as well as any related files and data. This action is irreversible.
|
||||||
The album will be deleted, as well as any related files and data. This action is irreversible.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #modal-confirm>
|
<template #modal-confirm>
|
||||||
<p>
|
<p>
|
||||||
<translate >Delete</translate>
|
Delete
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
</dangerous-button>
|
</dangerous-button>
|
||||||
|
@ -171,7 +168,7 @@ const remove = () => emit('remove')
|
||||||
:to="{name: 'manage.library.albums.detail', params: {id: object.id}}"
|
:to="{name: 'manage.library.albums.detail', params: {id: object.id}}"
|
||||||
>
|
>
|
||||||
<i class="wrench icon" />
|
<i class="wrench icon" />
|
||||||
<translate >Open in moderation interface</translate>
|
Open in moderation interface
|
||||||
</router-link>
|
</router-link>
|
||||||
<a
|
<a
|
||||||
v-if="$store.state.auth.profile && $store.state.auth.profile?.is_superuser"
|
v-if="$store.state.auth.profile && $store.state.auth.profile?.is_superuser"
|
||||||
|
@ -181,7 +178,7 @@ const remove = () => emit('remove')
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
<i class="wrench icon" />
|
<i class="wrench icon" />
|
||||||
<translate >View in Django's admin</translate>
|
View in Django's admin
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -24,13 +24,11 @@ const canEdit = store.state.auth.availablePermissions.library
|
||||||
<h2>
|
<h2>
|
||||||
<translate
|
<translate
|
||||||
v-if="canEdit"
|
v-if="canEdit"
|
||||||
|
|
||||||
>
|
>
|
||||||
Edit this album
|
Edit this album
|
||||||
</translate>
|
</translate>
|
||||||
<translate
|
<translate
|
||||||
v-else
|
v-else
|
||||||
|
|
||||||
>
|
>
|
||||||
Suggest an edit on this album
|
Suggest an edit on this album
|
||||||
</translate>
|
</translate>
|
||||||
|
@ -39,9 +37,7 @@ const canEdit = store.state.auth.availablePermissions.library
|
||||||
v-if="!object.is_local"
|
v-if="!object.is_local"
|
||||||
class="ui message"
|
class="ui message"
|
||||||
>
|
>
|
||||||
<translate >
|
This object is managed by another server, you cannot edit it.
|
||||||
This object is managed by another server, you cannot edit it.
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
<edit-form
|
<edit-form
|
||||||
v-else
|
v-else
|
||||||
|
|
|
@ -121,9 +121,7 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
|
||||||
<main v-title="labels.title">
|
<main v-title="labels.title">
|
||||||
<section class="ui vertical stripe segment">
|
<section class="ui vertical stripe segment">
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<translate >
|
Browsing albums
|
||||||
Browsing albums
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<form
|
<form
|
||||||
:class="['ui', {'loading': isLoading}, 'form']"
|
:class="['ui', {'loading': isLoading}, 'form']"
|
||||||
|
@ -132,7 +130,7 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
|
||||||
<div class="fields">
|
<div class="fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="albums-search">
|
<label for="albums-search">
|
||||||
<translate >Search</translate>
|
Search
|
||||||
</label>
|
</label>
|
||||||
<div class="ui action input">
|
<div class="ui action input">
|
||||||
<input
|
<input
|
||||||
|
@ -152,11 +150,11 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="tags-search"><translate >Tags</translate></label>
|
<label for="tags-search">Tags</label>
|
||||||
<tags-selector v-model="tags" />
|
<tags-selector v-model="tags" />
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="album-ordering"><translate >Ordering</translate></label>
|
<label for="album-ordering">Ordering</label>
|
||||||
<select
|
<select
|
||||||
id="album-ordering"
|
id="album-ordering"
|
||||||
v-model="ordering"
|
v-model="ordering"
|
||||||
|
@ -172,26 +170,22 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="album-ordering-direction"><translate >Ordering direction</translate></label>
|
<label for="album-ordering-direction">Ordering direction</label>
|
||||||
<select
|
<select
|
||||||
id="album-ordering-direction"
|
id="album-ordering-direction"
|
||||||
v-model="orderingDirection"
|
v-model="orderingDirection"
|
||||||
class="ui dropdown"
|
class="ui dropdown"
|
||||||
>
|
>
|
||||||
<option value="+">
|
<option value="+">
|
||||||
<translate >
|
Ascending
|
||||||
Ascending
|
|
||||||
</translate>
|
|
||||||
</option>
|
</option>
|
||||||
<option value="-">
|
<option value="-">
|
||||||
<translate >
|
Descending
|
||||||
Descending
|
|
||||||
</translate>
|
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="album-results"><translate >Results per page</translate></label>
|
<label for="album-results">Results per page</label>
|
||||||
<select
|
<select
|
||||||
id="album-results"
|
id="album-results"
|
||||||
v-model="paginateBy"
|
v-model="paginateBy"
|
||||||
|
@ -234,9 +228,7 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
|
||||||
>
|
>
|
||||||
<div class="ui icon header">
|
<div class="ui icon header">
|
||||||
<i class="compact disc icon" />
|
<i class="compact disc icon" />
|
||||||
<translate >
|
No results matching your query
|
||||||
No results matching your query
|
|
||||||
</translate>
|
|
||||||
</div>
|
</div>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="$store.state.auth.authenticated"
|
v-if="$store.state.auth.authenticated"
|
||||||
|
@ -244,9 +236,7 @@ const paginateOptions = computed(() => sortedUniq([12, 25, 50, paginateBy.value]
|
||||||
class="ui success button labeled icon"
|
class="ui success button labeled icon"
|
||||||
>
|
>
|
||||||
<i class="upload icon" />
|
<i class="upload icon" />
|
||||||
<translate >
|
Add some music
|
||||||
Add some music
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -147,9 +147,7 @@ watch(() => props.id, fetchData, { immediate: true })
|
||||||
class="vibrant"
|
class="vibrant"
|
||||||
:artist="object"
|
:artist="object"
|
||||||
>
|
>
|
||||||
<translate >
|
Play all albums
|
||||||
Play all albums
|
|
||||||
</translate>
|
|
||||||
</play-button>
|
</play-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -158,9 +156,7 @@ watch(() => props.id, fetchData, { immediate: true })
|
||||||
v-model:show="showEmbedModal"
|
v-model:show="showEmbedModal"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<translate >
|
Embed this artist work on your website
|
||||||
Embed this artist work on your website
|
|
||||||
</translate>
|
|
||||||
</h4>
|
</h4>
|
||||||
<div class="scrolling content">
|
<div class="scrolling content">
|
||||||
<div class="description">
|
<div class="description">
|
||||||
|
@ -172,9 +168,7 @@ watch(() => props.id, fetchData, { immediate: true })
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="ui deny button">
|
<button class="ui deny button">
|
||||||
<translate >
|
Cancel
|
||||||
Cancel
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</semantic-modal>
|
</semantic-modal>
|
||||||
|
@ -183,9 +177,7 @@ watch(() => props.id, fetchData, { immediate: true })
|
||||||
class="ui button"
|
class="ui button"
|
||||||
@click="dropdown.click()"
|
@click="dropdown.click()"
|
||||||
>
|
>
|
||||||
<translate >
|
More…
|
||||||
More…
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
ref="dropdown"
|
ref="dropdown"
|
||||||
|
@ -203,7 +195,6 @@ watch(() => props.id, fetchData, { immediate: true })
|
||||||
<i class="external icon" />
|
<i class="external icon" />
|
||||||
<translate
|
<translate
|
||||||
:translate-params="{domain: domain}"
|
:translate-params="{domain: domain}"
|
||||||
|
|
||||||
>View on %{ domain }</translate>
|
>View on %{ domain }</translate>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
@ -214,9 +205,7 @@ watch(() => props.id, fetchData, { immediate: true })
|
||||||
@click.prevent="showEmbedModal = !showEmbedModal"
|
@click.prevent="showEmbedModal = !showEmbedModal"
|
||||||
>
|
>
|
||||||
<i class="code icon" />
|
<i class="code icon" />
|
||||||
<translate >
|
Embed
|
||||||
Embed
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
<a
|
<a
|
||||||
:href="wikipediaUrl"
|
:href="wikipediaUrl"
|
||||||
|
@ -225,7 +214,7 @@ watch(() => props.id, fetchData, { immediate: true })
|
||||||
class="basic item"
|
class="basic item"
|
||||||
>
|
>
|
||||||
<i class="wikipedia w icon" />
|
<i class="wikipedia w icon" />
|
||||||
<translate >Search on Wikipedia</translate>
|
Search on Wikipedia
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
v-if="musicbrainzUrl"
|
v-if="musicbrainzUrl"
|
||||||
|
@ -235,7 +224,7 @@ watch(() => props.id, fetchData, { immediate: true })
|
||||||
class="basic item"
|
class="basic item"
|
||||||
>
|
>
|
||||||
<i class="external icon" />
|
<i class="external icon" />
|
||||||
<translate >View on MusicBrainz</translate>
|
View on MusicBrainz
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
:href="discogsUrl"
|
:href="discogsUrl"
|
||||||
|
@ -244,7 +233,7 @@ watch(() => props.id, fetchData, { immediate: true })
|
||||||
class="basic item"
|
class="basic item"
|
||||||
>
|
>
|
||||||
<i class="external icon" />
|
<i class="external icon" />
|
||||||
<translate >Search on Discogs</translate>
|
Search on Discogs
|
||||||
</a>
|
</a>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="object.is_local"
|
v-if="object.is_local"
|
||||||
|
@ -252,9 +241,7 @@ watch(() => props.id, fetchData, { immediate: true })
|
||||||
class="basic item"
|
class="basic item"
|
||||||
>
|
>
|
||||||
<i class="edit icon" />
|
<i class="edit icon" />
|
||||||
<translate >
|
Edit
|
||||||
Edit
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="divider" />
|
<div class="divider" />
|
||||||
<div
|
<div
|
||||||
|
@ -274,9 +261,7 @@ watch(() => props.id, fetchData, { immediate: true })
|
||||||
:to="{name: 'manage.library.artists.detail', params: {id: object.id}}"
|
:to="{name: 'manage.library.artists.detail', params: {id: object.id}}"
|
||||||
>
|
>
|
||||||
<i class="wrench icon" />
|
<i class="wrench icon" />
|
||||||
<translate >
|
Open in moderation interface
|
||||||
Open in moderation interface
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<a
|
<a
|
||||||
v-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
|
v-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
|
||||||
|
@ -286,7 +271,7 @@ watch(() => props.id, fetchData, { immediate: true })
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
<i class="wrench icon" />
|
<i class="wrench icon" />
|
||||||
<translate >View in Django's admin</translate>
|
View in Django's admin
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -65,25 +65,19 @@ const loadMoreAlbums = async () => {
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
<div class="ui message">
|
<div class="ui message">
|
||||||
<p>
|
<p>
|
||||||
<translate >
|
You are currently hiding content related to this artist.
|
||||||
You are currently hiding content related to this artist.
|
|
||||||
</translate>
|
|
||||||
</p>
|
</p>
|
||||||
<router-link
|
<router-link
|
||||||
class="right floated"
|
class="right floated"
|
||||||
:to="{name: 'settings'}"
|
:to="{name: 'settings'}"
|
||||||
>
|
>
|
||||||
<translate >
|
Review my filters
|
||||||
Review my filters
|
|
||||||
</translate>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<button
|
<button
|
||||||
class="ui basic tiny button"
|
class="ui basic tiny button"
|
||||||
@click="$store.dispatch('moderation/deleteContentFilter', contentFilter.uuid)"
|
@click="$store.dispatch('moderation/deleteContentFilter', contentFilter.uuid)"
|
||||||
>
|
>
|
||||||
<translate >
|
Remove filter
|
||||||
Remove filter
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -98,9 +92,7 @@ const loadMoreAlbums = async () => {
|
||||||
class="ui vertical stripe segment"
|
class="ui vertical stripe segment"
|
||||||
>
|
>
|
||||||
<h2>
|
<h2>
|
||||||
<translate >
|
Albums by this artist
|
||||||
Albums by this artist
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<div class="ui cards app-cards">
|
<div class="ui cards app-cards">
|
||||||
<album-card
|
<album-card
|
||||||
|
@ -115,9 +107,7 @@ const loadMoreAlbums = async () => {
|
||||||
:class="['ui', {loading: isLoadingMoreAlbums}, 'button']"
|
:class="['ui', {loading: isLoadingMoreAlbums}, 'button']"
|
||||||
@click="loadMoreAlbums()"
|
@click="loadMoreAlbums()"
|
||||||
>
|
>
|
||||||
<translate >
|
Load more…
|
||||||
Load more…
|
|
||||||
</translate>
|
|
||||||
</button>
|
</button>
|
||||||
</section>
|
</section>
|
||||||
<section
|
<section
|
||||||
|
@ -132,9 +122,7 @@ const loadMoreAlbums = async () => {
|
||||||
>
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
<h2>
|
<h2>
|
||||||
<translate >
|
New tracks by this artist
|
||||||
New tracks by this artist
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -142,17 +130,13 @@ const loadMoreAlbums = async () => {
|
||||||
</section>
|
</section>
|
||||||
<section class="ui vertical stripe segment">
|
<section class="ui vertical stripe segment">
|
||||||
<h2>
|
<h2>
|
||||||
<translate >
|
User libraries
|
||||||
User libraries
|
|
||||||
</translate>
|
|
||||||
</h2>
|
</h2>
|
||||||
<library-widget
|
<library-widget
|
||||||
:url="'artists/' + object.id + '/libraries/'"
|
:url="'artists/' + object.id + '/libraries/'"
|
||||||
@loaded="emit('libraries-loaded', $event)"
|
@loaded="emit('libraries-loaded', $event)"
|
||||||
>
|
>
|
||||||
<translate >
|
This artist is present in the following libraries:
|
||||||
This artist is present in the following libraries:
|
|
||||||
</translate>
|
|
||||||
</library-widget>
|
</library-widget>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue