diff --git a/front/src/components/About.vue b/front/src/components/About.vue
index 72355ef58..6e2bf9815 100644
--- a/front/src/components/About.vue
+++ b/front/src/components/About.vue
@@ -21,7 +21,7 @@ const banner = computed(() => get(nodeinfo.value, 'metadata.banner'))
const shortDescription = computed(() => get(nodeinfo.value, 'metadata.shortDescription'))
const stats = computed(() => {
- const users = get(nodeinfo.value, 'usage.users.activeMonth', null)
+ const users = get(nodeinfo.value, 'usage.users.activeMonth', 0)
const hours = get(nodeinfo.value, 'metadata.library.music.hours', 0)
if (users === null) {
@@ -32,7 +32,7 @@ const stats = computed(() => {
})
const openRegistrations = computed(() => get(nodeinfo.value, 'openRegistrations'))
-const defaultUploadQuota = computed(() => humanSize(get(nodeinfo.value, 'metadata.defaultUploadQuota') * 1000 * 1000))
+const defaultUploadQuota = computed(() => humanSize(get(nodeinfo.value, 'metadata.defaultUploadQuota', 0) * 1000 * 1000))
const headerStyle = computed(() => {
if (!banner.value) {
@@ -196,11 +196,11 @@ const headerStyle = computed(() => {
- {{ parseInt(stats.hours).toLocaleString($store.state.ui.momentLocale) }}
+ {{ stats.hours.toLocaleString($store.state.ui.momentLocale) }}
hour of music
diff --git a/front/src/components/AboutPod.vue b/front/src/components/AboutPod.vue
index ae26a67b4..9a0eabb6a 100644
--- a/front/src/components/AboutPod.vue
+++ b/front/src/components/AboutPod.vue
@@ -8,6 +8,7 @@ import { computed } from 'vue'
import axios from 'axios'
import useMarkdown from '~/composables/useMarkdown'
+import type { NodeInfo } from '~/store/instance'
const store = useStore()
const nodeinfo = computed(() => store.state.instance.nodeinfo)
@@ -25,9 +26,9 @@ const labels = computed(() => ({
const podName = computed(() => get(nodeinfo.value, 'metadata.nodeName') || 'Funkwhale')
const banner = computed(() => get(nodeinfo.value, 'metadata.banner'))
-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 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(() => get(nodeinfo.value, 'metadata.library.anonymousCanListen'))
const allowListEnabled = computed(() => get(nodeinfo.value, 'metadata.allowList.enabled'))
@@ -39,17 +40,19 @@ const federationEnabled = computed(() => get(nodeinfo.value, 'metadata.library.f
const onDesktop = computed(() => window.innerWidth > 800)
const stats = computed(() => {
+ const info = nodeinfo.value ?? {} as NodeInfo
+
const data = {
- users: get(nodeinfo.value, 'usage.users.activeMonth', null),
- hours: get(nodeinfo.value, 'metadata.library.music.hours', null),
- artists: get(nodeinfo.value, 'metadata.library.artists.total', null),
- albums: get(nodeinfo.value, 'metadata.library.albums.total', null),
- tracks: get(nodeinfo.value, 'metadata.library.tracks.total', null),
- listenings: get(nodeinfo.value, 'metadata.usage.listenings.total', null)
+ users: get(info, 'usage.users.activeMonth', null),
+ hours: get(info, 'metadata.library.music.hours', null),
+ artists: get(info, 'metadata.library.artists.total', null),
+ albums: get(info, 'metadata.library.albums.total', null),
+ tracks: get(info, 'metadata.library.tracks.total', null),
+ listenings: get(info, 'metadata.usage.listenings.total', null)
}
if (data.users === null || data.artists === null) {
- return
+ return data
}
return data
@@ -375,11 +378,11 @@ const headerStyle = computed(() => {
class="statistics-statistic"
>
- {{ parseInt(stats.hours).toLocaleString($store.state.ui.momentLocale) }}
+ {{ stats.hours.toLocaleString($store.state.ui.momentLocale) }}
hour of music
diff --git a/front/src/components/Home.vue b/front/src/components/Home.vue
index a44619bbd..7db516aa3 100644
--- a/front/src/components/Home.vue
+++ b/front/src/components/Home.vue
@@ -23,7 +23,7 @@ const nodeinfo = computed(() => store.state.instance.nodeinfo)
const podName = computed(() => get(nodeinfo.value, 'metadata.nodeName') || 'Funkwhale')
const banner = computed(() => get(nodeinfo.value, 'metadata.banner'))
const shortDescription = computed(() => get(nodeinfo.value, 'metadata.shortDescription'))
-const longDescription = useMarkdown(() => get(nodeinfo.value, 'metadata.longDescription'))
+const longDescription = useMarkdown(() => get(nodeinfo.value, 'metadata.longDescription', ''))
const rules = computed(() => get(nodeinfo.value, 'metadata.rules'))
const contactEmail = computed(() => get(nodeinfo.value, 'metadata.contactEmail'))
const anonymousCanListen = computed(() => get(nodeinfo.value, 'metadata.library.anonymousCanListen'))
@@ -31,7 +31,7 @@ const openRegistrations = computed(() => get(nodeinfo.value, 'openRegistrations'
const defaultUploadQuota = computed(() => get(nodeinfo.value, 'metadata.defaultUploadQuota'))
const stats = computed(() => {
- const users = get(nodeinfo.value, 'usage.users.activeMonth', null)
+ const users = get(nodeinfo.value, 'usage.users.activeMonth', 0)
const hours = get(nodeinfo.value, 'metadata.library.music.hours', 0)
if (users === null) {
@@ -172,8 +172,8 @@ whenever(() => store.state.auth.authenticated, () => {
%{ count } hour of music
diff --git a/front/src/store/instance.ts b/front/src/store/instance.ts
index 72341bf5e..e446953b0 100644
--- a/front/src/store/instance.ts
+++ b/front/src/store/instance.ts
@@ -10,10 +10,77 @@ export interface State {
frontSettings: FrontendSettings
instanceUrl?: string
knownInstances: string[]
- nodeinfo: unknown | null
+ nodeinfo: NodeInfo | null
settings: Settings
}
+type TotalCount = {
+ total: number
+}
+
+export interface NodeInfo {
+ version: string;
+ software: {
+ name: string;
+ version: string;
+ }
+ protocols: any[];
+ services?: {
+ inbound?: string[];
+ outbound?: string[];
+ }
+ openRegistrations: boolean;
+ usage: {
+ users: {
+ total: number;
+ activeHalfyear: number;
+ activeMonth: number;
+ }
+ }
+ metadata: {
+ actorId: string
+ 'private': boolean
+ shortDescription: string
+ longDescription: string
+ rules: string
+ contactEmail: string
+ terms: string
+ nodeName: string
+ banner: string
+ defaultUploadQuota: number
+ library: {
+ federationEnabled: boolean
+ anonymousCanListen: boolean
+ tracks?: TotalCount
+ artists?: TotalCount
+ albums?: TotalCount
+ music?: { hours: number }
+ }
+ supportedUploadExtensions: string[]
+ allowList: {
+ enabled: boolean
+ domains: string[]
+ }
+ reportTypes: {
+ 'type': string
+ label: string
+ anonymous: boolean
+ }[]
+ funkwhaleSupportMessageEnabled: boolean
+ instanceSupportMessage: string
+ endpoints: {
+ knownNodes?: string
+ channels?: string
+ libraries?: string
+ }
+ usage: {
+ favorites: { tracks: TotalCount }
+ listenings: TotalCount
+ downloads: TotalCount
+ }
+ }
+}
+
interface FrontendSettings {
defaultServerUrl: string
additionalStylesheets: string[]