config option for listenbrainz/lastfm links

This commit is contained in:
Kendall Garner 2025-06-07 20:36:41 -07:00
parent 636c227a83
commit 9b79502022
No known key found for this signature in database
GPG key ID: 9355F387FE765C94
5 changed files with 99 additions and 42 deletions

View file

@ -587,6 +587,8 @@
"imageAspectRatio_description": "if enabled, cover art will be shown using their native aspect ratio. for art that is not 1:1, the remaining space will be empty", "imageAspectRatio_description": "if enabled, cover art will be shown using their native aspect ratio. for art that is not 1:1, the remaining space will be empty",
"language": "language", "language": "language",
"language_description": "sets the language for the application ($t(common.restartRequired))", "language_description": "sets the language for the application ($t(common.restartRequired))",
"lastfm": "show last.fm links",
"lastfm_description": "show links to last.fm on artist/album pages",
"lastfmApiKey": "{{lastfm}} API key", "lastfmApiKey": "{{lastfm}} API key",
"lastfmApiKey_description": "the API key for {{lastfm}}. required for cover art", "lastfmApiKey_description": "the API key for {{lastfm}}. required for cover art",
"lyricFetch": "fetch lyrics from the internet", "lyricFetch": "fetch lyrics from the internet",
@ -605,6 +607,8 @@
"mpvExecutablePath_description": "sets the path to the mpv executable. if left empty, the default path will be used", "mpvExecutablePath_description": "sets the path to the mpv executable. if left empty, the default path will be used",
"mpvExtraParameters": "mpv parameters", "mpvExtraParameters": "mpv parameters",
"mpvExtraParameters_help": "one per line", "mpvExtraParameters_help": "one per line",
"musicbrainz": "show musicbrainz links",
"musicbrainz_description": "show links to musicbrainz on artist/album pages, where mbid exists",
"passwordStore": "passwords/secret store", "passwordStore": "passwords/secret store",
"passwordStore_description": "what password/secret store to use. change this if you are having issues storing passwords.", "passwordStore_description": "what password/secret store to use. change this if you are having issues storing passwords.",
"playbackStyle": "playback style", "playbackStyle": "playback style",

View file

@ -90,7 +90,7 @@ export const AlbumDetailContent = ({ background, tableRef }: AlbumDetailContentP
const status = useCurrentStatus(); const status = useCurrentStatus();
const isFocused = useAppFocus(); const isFocused = useAppFocus();
const currentSong = useCurrentSong(); const currentSong = useCurrentSong();
const { externalLinks } = useGeneralSettings(); const { lastFM, musicBrainz } = useGeneralSettings();
const genreRoute = useGenreRoute(); const genreRoute = useGenreRoute();
const columnDefs = useMemo( const columnDefs = useMemo(
@ -407,27 +407,29 @@ export const AlbumDetailContent = ({ background, tableRef }: AlbumDetailContentP
</Group> </Group>
</Box> </Box>
)} )}
{externalLinks ? ( {lastFM || musicBrainz ? (
<Box component="section"> <Box component="section">
<Group spacing="sm"> <Group spacing="sm">
<Button {lastFM && (
compact <Button
component="a" compact
href={`https://www.last.fm/music/${encodeURIComponent( component="a"
detailQuery?.data?.albumArtist || '', href={`https://www.last.fm/music/${encodeURIComponent(
)}/${encodeURIComponent(detailQuery.data?.name || '')}`} detailQuery?.data?.albumArtist || '',
radius="md" )}/${encodeURIComponent(detailQuery.data?.name || '')}`}
rel="noopener noreferrer" radius="md"
size="md" rel="noopener noreferrer"
target="_blank" size="md"
tooltip={{ target="_blank"
label: t('action.openIn.lastfm'), tooltip={{
}} label: t('action.openIn.lastfm'),
variant="subtle" }}
> variant="subtle"
<FaLastfmSquare size={25} /> >
</Button> <FaLastfmSquare size={25} />
{mbzId ? ( </Button>
)}
{musicBrainz && mbzId ? (
<Button <Button
compact compact
component="a" component="a"

View file

@ -66,7 +66,7 @@ interface AlbumArtistDetailContentProps {
export const AlbumArtistDetailContent = ({ background }: AlbumArtistDetailContentProps) => { export const AlbumArtistDetailContent = ({ background }: AlbumArtistDetailContentProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { artistItems, externalLinks } = useGeneralSettings(); const { artistItems, lastFM, musicBrainz } = useGeneralSettings();
const { albumArtistId, artistId } = useParams() as { const { albumArtistId, artistId } = useParams() as {
albumArtistId?: string; albumArtistId?: string;
artistId?: string; artistId?: string;
@ -451,27 +451,29 @@ export const AlbumArtistDetailContent = ({ background }: AlbumArtistDetailConten
</Group> </Group>
</Box> </Box>
) : null} ) : null}
{externalLinks ? ( {lastFM || musicBrainz ? (
<Box component="section"> <Box component="section">
<Group spacing="sm"> <Group spacing="sm">
<Button {lastFM && (
compact <Button
component="a" compact
href={`https://www.last.fm/music/${encodeURIComponent( component="a"
detailQuery?.data?.name || '', href={`https://www.last.fm/music/${encodeURIComponent(
)}`} detailQuery?.data?.name || '',
radius="md" )}`}
rel="noopener noreferrer" radius="md"
size="md" rel="noopener noreferrer"
target="_blank" size="md"
tooltip={{ target="_blank"
label: t('action.openIn.lastfm'), tooltip={{
}} label: t('action.openIn.lastfm'),
variant="subtle" }}
> variant="subtle"
<FaLastfmSquare size={25} /> >
</Button> <FaLastfmSquare size={25} />
{mbzId ? ( </Button>
)}
{musicBrainz && mbzId ? (
<Button <Button
compact compact
component="a" component="a"

View file

@ -4,7 +4,10 @@ import isElectron from 'is-electron';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { NumberInput, Select, Slider, Switch, Tooltip } from '/@/renderer/components'; import { NumberInput, Select, Slider, Switch, Tooltip } from '/@/renderer/components';
import { SettingsSection } from '/@/renderer/features/settings/components/settings-section'; import {
SettingOption,
SettingsSection,
} from '/@/renderer/features/settings/components/settings-section';
import { import {
GenreTarget, GenreTarget,
SideQueueType, SideQueueType,
@ -37,7 +40,7 @@ export const ControlSettings = () => {
const settings = useGeneralSettings(); const settings = useGeneralSettings();
const { setSettings } = useSettingsStoreActions(); const { setSettings } = useSettingsStoreActions();
const controlOptions = [ const controlOptions: SettingOption[] = [
{ {
control: ( control: (
<NumberInput <NumberInput
@ -396,6 +399,48 @@ export const ControlSettings = () => {
}), }),
title: t('setting.externalLinks', { postProcess: 'sentenceCase' }), title: t('setting.externalLinks', { postProcess: 'sentenceCase' }),
}, },
{
control: (
<Switch
defaultChecked={settings.lastFM}
onChange={(e) => {
setSettings({
general: {
...settings,
lastFM: e.currentTarget.checked,
},
});
}}
/>
),
description: t('setting.lastfm', {
context: 'description',
postProcess: 'sentenceCase',
}),
isHidden: !settings.externalLinks,
title: t('setting.lastfm', { postProcess: 'sentenceCase' }),
},
{
control: (
<Switch
defaultChecked={settings.musicBrainz}
onChange={(e) => {
setSettings({
general: {
...settings,
musicBrainz: e.currentTarget.checked,
},
});
}}
/>
),
description: t('setting.musicbrainz', {
context: 'description',
postProcess: 'sentenceCase',
}),
isHidden: !settings.externalLinks,
title: t('setting.musicbrainz', { postProcess: 'sentenceCase' }),
},
{ {
control: ( control: (
<Select <Select

View file

@ -227,7 +227,9 @@ export interface SettingsState {
homeFeature: boolean; homeFeature: boolean;
homeItems: SortableItem<HomeItem>[]; homeItems: SortableItem<HomeItem>[];
language: string; language: string;
lastFM: boolean;
lastfmApiKey: string; lastfmApiKey: string;
musicBrainz: boolean;
nativeAspectRatio: boolean; nativeAspectRatio: boolean;
passwordStore?: string; passwordStore?: string;
playButtonBehavior: Play; playButtonBehavior: Play;
@ -376,7 +378,9 @@ const initialState: SettingsState = {
homeFeature: true, homeFeature: true,
homeItems, homeItems,
language: 'en', language: 'en',
lastFM: true,
lastfmApiKey: '', lastfmApiKey: '',
musicBrainz: true,
nativeAspectRatio: false, nativeAspectRatio: false,
passwordStore: undefined, passwordStore: undefined,
playButtonBehavior: Play.NOW, playButtonBehavior: Play.NOW,