feat(about): merge about and about-this-pod pages
This commit is contained in:
parent
9a943d6c37
commit
4c2c2a6e4d
|
@ -7,6 +7,8 @@ import { computed } from 'vue'
|
|||
|
||||
import SignupForm from '~/components/auth/SignupForm.vue'
|
||||
import LogoText from '~/components/LogoText.vue'
|
||||
import type { NodeInfo } from '~/store/instance'
|
||||
import useMarkdown from '~/composables/useMarkdown'
|
||||
|
||||
const store = useStore()
|
||||
const nodeinfo = computed(() => store.state.instance.nodeinfo)
|
||||
|
@ -28,10 +30,22 @@ const stats = computed(() => {
|
|||
return null
|
||||
}
|
||||
|
||||
return { users, hours }
|
||||
const info = nodeinfo.value ?? {} as NodeInfo
|
||||
|
||||
const data = {
|
||||
users: get(info, 'usage.users.activeMonth', null),
|
||||
hours: get(info, 'metadata.content.local.hoursOfContent', null),
|
||||
artists: get(info, 'metadata.content.local.artists.total', null),
|
||||
albums: get(info, 'metadata.content.local.albums.total', null),
|
||||
tracks: get(info, 'metadata.content.local.tracks.total', null),
|
||||
listenings: get(info, 'metadata.usage.listenings.total', null)
|
||||
}
|
||||
|
||||
return { users, hours, data }
|
||||
})
|
||||
|
||||
const openRegistrations = computed(() => get(nodeinfo.value, 'openRegistrations'))
|
||||
|
||||
const defaultUploadQuota = computed(() => humanSize(get(nodeinfo.value, 'metadata.defaultUploadQuota', 0) * 1000 * 1000))
|
||||
|
||||
const headerStyle = computed(() => {
|
||||
|
@ -43,6 +57,25 @@ const headerStyle = computed(() => {
|
|||
backgroundImage: `url(${store.getters['instance/absoluteUrl'](banner.value)})`
|
||||
}
|
||||
})
|
||||
|
||||
const longDescription = useMarkdown(() => get(nodeinfo.value, 'metadata.longDescription', ''))
|
||||
const rules = useMarkdown(() => get(nodeinfo.value, 'metadata.rules', ''))
|
||||
const terms = useMarkdown(() => get(nodeinfo.value, 'metadata.terms', ''))
|
||||
const contactEmail = computed(() => get(nodeinfo.value, 'metadata.contactEmail'))
|
||||
const anonymousCanListen = computed(() => {
|
||||
const features = get(nodeinfo.value, 'metadata.metadata.feature', []) as string[]
|
||||
const hasAnonymousCanListen = features.includes('anonymousCanListen')
|
||||
return hasAnonymousCanListen
|
||||
})
|
||||
const allowListEnabled = computed(() => get(nodeinfo.value, 'metadata.allowList.enabled'))
|
||||
const version = computed(() => get(nodeinfo.value, 'software.version'))
|
||||
const federationEnabled = computed(() => {
|
||||
const features = get(nodeinfo.value, 'metadata.metadata.feature', []) as string[]
|
||||
const hasAnonymousCanListen = features.includes('federation')
|
||||
return hasAnonymousCanListen
|
||||
})
|
||||
|
||||
const onDesktop = computed(() => window.innerWidth > 800)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -162,16 +195,16 @@ const headerStyle = computed(() => {
|
|||
<div class="two column row">
|
||||
<div class="column">
|
||||
<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>
|
||||
{{ t('components.About.stat.activeUsers', stats.users) }}
|
||||
{{ stats.users ? t('components.About.stat.activeUsers', stats.users) : "—" }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="column">
|
||||
<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 ? stats.hours.toLocaleString(store.state.ui.momentLocale) : "—" }}</strong></span>
|
||||
<br>
|
||||
{{ t('components.About.stat.hoursOfMusic', stats.hours) }}
|
||||
{{ stats.hours ? t('components.About.stat.hoursOfMusic', stats.hours) : "—" }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -245,17 +278,353 @@ const headerStyle = computed(() => {
|
|||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="ui fluid horizontally fitted basic clearing segment container">
|
||||
<router-link
|
||||
to="/about/pod"
|
||||
class="ui right floated basic secondary button"
|
||||
>
|
||||
{{ t('components.About.header.aboutPod') }}
|
||||
<i class="icon arrow right" />
|
||||
</router-link>
|
||||
<div
|
||||
class="ui"
|
||||
:class="{ container: onDesktop}"
|
||||
>
|
||||
<div class="ui horizontally fitted stripe basic segment">
|
||||
<div class="ui basic vertically fitted stripe segment content">
|
||||
<section
|
||||
:class="['ui', 'head', {'with-background': banner}, 'vertical', 'center', 'aligned', 'stripe', 'segment']"
|
||||
:style="headerStyle"
|
||||
>
|
||||
<h1>
|
||||
<i class="music icon" />
|
||||
{{ podName }}
|
||||
</h1>
|
||||
</section>
|
||||
</div>
|
||||
<div class="ui basic vertically fitted stripe segment content">
|
||||
<!-- See layout in _about.scss -->
|
||||
<div class="about-pod-info-container">
|
||||
<div class="about-pod-info-toc">
|
||||
<div class="ui vertical pointing secondary menu">
|
||||
<router-link
|
||||
to="/about/pod"
|
||||
class="item"
|
||||
>
|
||||
{{ t('components.AboutPod.link.about') }}
|
||||
</router-link>
|
||||
<router-link
|
||||
to="/about/pod#rules"
|
||||
class="item"
|
||||
>
|
||||
{{ t('components.AboutPod.link.rules') }}
|
||||
</router-link>
|
||||
<router-link
|
||||
to="/about/pod#terms"
|
||||
class="item"
|
||||
>
|
||||
{{ t('components.AboutPod.link.terms') }}
|
||||
</router-link>
|
||||
<router-link
|
||||
to="/about/pod#features"
|
||||
class="item"
|
||||
>
|
||||
{{ t('components.AboutPod.link.features') }}
|
||||
</router-link>
|
||||
<router-link
|
||||
v-if="stats"
|
||||
to="/about/pod#statistics"
|
||||
class="item"
|
||||
>
|
||||
{{ t('components.AboutPod.link.statistics') }}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="about-pod-info">
|
||||
<h2
|
||||
id="description about-this-pod"
|
||||
class="ui header"
|
||||
>
|
||||
{{ t('components.AboutPod.header.about') }}
|
||||
</h2>
|
||||
<sanitized-html
|
||||
v-if="longDescription"
|
||||
:html="longDescription"
|
||||
/>
|
||||
<p v-else>
|
||||
{{ t('components.AboutPod.placeholder.noDescription') }}
|
||||
</p>
|
||||
|
||||
<h3
|
||||
id="rules"
|
||||
class="ui header"
|
||||
>
|
||||
{{ t('components.AboutPod.header.rules') }}
|
||||
</h3>
|
||||
<sanitized-html
|
||||
v-if="rules"
|
||||
:html="rules"
|
||||
/>
|
||||
<p v-else>
|
||||
{{ t('components.AboutPod.placeholder.noRules') }}
|
||||
</p>
|
||||
|
||||
<h3
|
||||
id="terms"
|
||||
class="ui header"
|
||||
>
|
||||
{{ t('components.AboutPod.header.terms') }}
|
||||
</h3>
|
||||
<sanitized-html
|
||||
v-if="terms"
|
||||
:html="terms"
|
||||
/>
|
||||
<p v-else>
|
||||
{{ t('components.AboutPod.placeholder.noTerms') }}
|
||||
</p>
|
||||
|
||||
<h3
|
||||
id="features"
|
||||
class="header"
|
||||
>
|
||||
{{ t('components.AboutPod.header.features') }}
|
||||
</h3>
|
||||
<div class="features-container ui two column stackable grid">
|
||||
<div class="column">
|
||||
<table class="ui very basic table unstackable">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
{{ t('components.AboutPod.feature.version') }}
|
||||
</td>
|
||||
<td
|
||||
v-if="version"
|
||||
class="right aligned"
|
||||
>
|
||||
<span class="features-status ui text">
|
||||
{{ version }}
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
v-else
|
||||
class="right aligned"
|
||||
>
|
||||
<span class="features-status ui text">
|
||||
{{ t('components.AboutPod.notApplicable') }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{{ t('components.AboutPod.feature.federation') }}
|
||||
</td>
|
||||
<td
|
||||
v-if="federationEnabled"
|
||||
class="right aligned"
|
||||
>
|
||||
<span class="features-status ui text">
|
||||
<i class="check icon" />
|
||||
{{ t('components.AboutPod.feature.status.enabled') }}
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
v-else
|
||||
class="right aligned"
|
||||
>
|
||||
<span class="features-status ui text">
|
||||
<i class="x icon" />
|
||||
{{ t('components.AboutPod.feature.status.disabled') }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{{ t('components.AboutPod.feature.allowList') }}
|
||||
</td>
|
||||
<td
|
||||
v-if="allowListEnabled"
|
||||
class="right aligned"
|
||||
>
|
||||
<span class="features-status ui text">
|
||||
<i class="check icon" />
|
||||
{{ t('components.AboutPod.feature.status.enabled') }}
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
v-else
|
||||
class="right aligned"
|
||||
>
|
||||
<span class="features-status ui text">
|
||||
<i class="x icon" />
|
||||
{{ t('components.AboutPod.feature.status.disabled') }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="column">
|
||||
<table class="ui very basic table unstackable">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
{{ t('components.AboutPod.feature.anonymousAccess') }}
|
||||
</td>
|
||||
<td
|
||||
v-if="anonymousCanListen"
|
||||
class="right aligned"
|
||||
>
|
||||
<span class="features-status ui text">
|
||||
<i class="check icon" />
|
||||
{{ t('components.AboutPod.feature.status.enabled') }}
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
v-else
|
||||
class="right aligned"
|
||||
>
|
||||
<span class="features-status ui text">
|
||||
<i class="x icon" />
|
||||
{{ t('components.AboutPod.feature.status.disabled') }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{{ t('components.AboutPod.feature.registrations') }}
|
||||
</td>
|
||||
<td
|
||||
v-if="openRegistrations"
|
||||
class="right aligned"
|
||||
>
|
||||
<span class="features-status ui text">
|
||||
<i class="check icon" />
|
||||
{{ t('components.AboutPod.feature.status.open') }}
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
v-else
|
||||
class="right aligned"
|
||||
>
|
||||
<span class="features-status ui text">
|
||||
<i class="x icon" />
|
||||
{{ t('components.AboutPod.feature.status.closed') }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{{ t('components.AboutPod.feature.quota') }}
|
||||
</td>
|
||||
<td
|
||||
v-if="defaultUploadQuota"
|
||||
class="right aligned"
|
||||
>
|
||||
<span class="features-status ui text">
|
||||
{{ defaultUploadQuota }}
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
v-else
|
||||
class="right aligned"
|
||||
>
|
||||
<span class="features-status ui text">
|
||||
{{ t('components.AboutPod.notApplicable') }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-if="stats">
|
||||
<h3
|
||||
id="statistics"
|
||||
class="header"
|
||||
>
|
||||
{{ t('components.AboutPod.header.statistics') }}
|
||||
</h3>
|
||||
<div class="statistics-container">
|
||||
<div
|
||||
v-if="stats.hours"
|
||||
class="statistics-statistic"
|
||||
>
|
||||
<span class="statistics-figure ui text">
|
||||
<span class="ui big text"><strong>{{ stats.hours.toLocaleString(store.state.ui.momentLocale) }}</strong></span>
|
||||
<br>
|
||||
{{ t('components.AboutPod.stat.hoursOfMusic', stats.hours) }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="stats.data.artists"
|
||||
class="statistics-statistic"
|
||||
>
|
||||
<span class="statistics-figure ui text">
|
||||
<span class="ui big text"><strong>{{ stats.data.artists.toLocaleString(store.state.ui.momentLocale) }}</strong></span>
|
||||
<br>
|
||||
{{ t('components.AboutPod.stat.artistsCount', stats.data.artists) }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="stats.data.albums"
|
||||
class="statistics-statistic"
|
||||
>
|
||||
<span class="statistics-figure ui text">
|
||||
<span class="ui big text"><strong>{{ stats.data.albums.toLocaleString(store.state.ui.momentLocale) }}</strong></span>
|
||||
<br>
|
||||
{{ t('components.AboutPod.stat.albumsCount', stats.data.albums) }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="stats.data.tracks"
|
||||
class="statistics-statistic"
|
||||
>
|
||||
<span class="statistics-figure ui text">
|
||||
<span class="ui big text"><strong>{{ stats.data.tracks.toLocaleString(store.state.ui.momentLocale) }}</strong></span>
|
||||
<br>
|
||||
{{ t('components.AboutPod.stat.tracksCount', stats.data.tracks) }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="stats.users"
|
||||
class="statistics-statistic"
|
||||
>
|
||||
<span class="statistics-figure ui text">
|
||||
<span class="ui big text"><strong>{{ stats.users.toLocaleString(store.state.ui.momentLocale) }}</strong></span>
|
||||
<br>
|
||||
{{ t('components.AboutPod.stat.activeUsers', stats.users) }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="stats.data.listenings"
|
||||
class="statistics-statistic"
|
||||
>
|
||||
<span class="statistics-figure ui text">
|
||||
<span class="ui big text"><strong>{{ stats.data.listenings.toLocaleString(store.state.ui.momentLocale) }}</strong></span>
|
||||
<br>
|
||||
{{ t('components.AboutPod.stat.listeningsCount', stats.data.listenings) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="contactEmail">
|
||||
<h3
|
||||
id="contact"
|
||||
class="ui header"
|
||||
>
|
||||
{{ t('components.AboutPod.header.contact') }}
|
||||
</h3>
|
||||
<a
|
||||
v-if="contactEmail"
|
||||
:href="`mailto:${contactEmail}`"
|
||||
>
|
||||
{{ t('components.AboutPod.message.contact', { contactEmail }) }}
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<div class="ui hidden divider" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
|
Loading…
Reference in New Issue