@samitouri / QOSami-HFS / commits / 551d95c2

parse mp3 file names

Massimo Melina committed Oct 25, 2024 at 15:38 UTC 551d95c2f9454c9d298b68c0bfca2b6c8d4a0df0
3 files changed +13 -3
admin/src/CustomHtmlPage.ts
+2 -2
@@ -4,7 +4,7 @@ import { createElement as h, Fragment, useEffect, useMemo, useState } from 'reac
4 import { Field, SelectField } from '@hfs/mui-grid-form'
5 import { apiCall, useApiEx } from './api'
6 import { Alert, Box } from '@mui/material'
7 -import { Dict, HTTP_MESSAGES, isCtrlKey, prefix, md } from './misc';
7 +import { Dict, HTTP_MESSAGES, isCtrlKey, prefix, md, isNumeric } from './misc';
8 import { IconBtn, reloadBtn, wikiLink } from './mui';
9 import { Save } from '@mui/icons-material'
10 import _ from 'lodash'
@@ -25,7 +25,7 @@ export default function CustomHtmlPage() {
25 useEffect(() => data && setSaved(data?.sections), [data])
26 useEffect(() => setAll(saved), [saved])
27 const options = useMemo(() => {
28 - const keys = _.sortBy(Object.keys(all), x => !isNaN(+x)) // http codes at the bottom
28 + const keys = _.sortBy(Object.keys(all), isNumeric) // http codes at the bottom
29 if (keys.length && !keys.includes(section))
30 state.customHtmlSection = _.findKey(all, Boolean) || keys?.[0] || '' // prefer any key with content
31 return keys.map(x => ({
frontend/src/show.ts
+7 -1
@@ -2,6 +2,7 @@ import { DirEntry, DirList, ext2type, state, useSnapState } from './state'
2 import { createElement as h, Fragment, useEffect, useMemo, useRef, useState } from 'react'
3 import {
4 basename, dirname, domOn, hfsEvent, hIcon, isMac, newDialog, pathEncode, restartAnimation, useStateMounted,
5 + isNumeric,
6 } from './misc'
7 import { useEventListener, useWindowSize } from 'usehooks-ts'
8 import { EntryDetails, useMidnight } from './BrowseFiles'
@@ -189,7 +190,12 @@ export function fileShow(entry: DirEntry, { startPlaying=false } = {}) {
190 }
191 const m = window.MediaMetadata && (navigator.mediaSession.metadata = new MediaMetadata(meta))
192 if (cur.ext === 'mp3') {
192 - setTags(Object.assign(meta, await getId3Tags(location.pathname + cur.n).catch(() => {})))
193 + const arr = cur.name.split(' - ') // "artist - title" is quite common for mp3s
194 + setTags(Object.assign(meta, {
195 + title: arr.at(-1)?.slice(0, -4), // last part, without extension
196 + artist: arr.filter(x => !isNumeric(x)).at(-2), // previous part, if any and not numeric
197 + ...await getId3Tags(location.pathname + cur.n).catch(() => {})
198 + }))
199 if (m) Object.assign(m, meta)
200 }
201 hfsEvent('showPlay', {
src/cross.ts
+4
@@ -353,6 +353,10 @@ export function formatTimestamp(x: number | string | Date) {
353 return !x ? '' : (x instanceof Date ? x : new Date(x)).toLocaleString()
354 }
355
356 +export function isNumeric(x: unknown) {
357 + return _.isNumber(x) || _.isString(x) && !isNaN(Number(x))
358 +}
359 +
360 export function isPrimitive(x: unknown): x is boolean | string | number | undefined | null {
361 return !x || Object(x) !== x
362 }