mirror of
https://github.com/jeffvli/feishin.git
synced 2024-11-20 06:27:09 +01:00
* feat: Discord Rich Presence album art via Last.fm * fix: securely fetch album art
This commit is contained in:
parent
61d7e7c390
commit
21f4a78dd7
@ -582,6 +582,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))",
|
||||||
|
"lastfmApiKey": "{{lastfm}} API key",
|
||||||
|
"lastfmApiKey_description": "the API key for {{lastfm}}. required for cover art",
|
||||||
"lyricFetch": "fetch lyrics from the internet",
|
"lyricFetch": "fetch lyrics from the internet",
|
||||||
"lyricFetch_description": "fetch lyrics from various internet sources",
|
"lyricFetch_description": "fetch lyrics from various internet sources",
|
||||||
"lyricFetchProvider": "providers to fetch lyrics from",
|
"lyricFetchProvider": "providers to fetch lyrics from",
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
useCurrentSong,
|
useCurrentSong,
|
||||||
useCurrentStatus,
|
useCurrentStatus,
|
||||||
useDiscordSetttings,
|
useDiscordSetttings,
|
||||||
|
useGeneralSettings,
|
||||||
usePlayerStore,
|
usePlayerStore,
|
||||||
} from '/@/renderer/store';
|
} from '/@/renderer/store';
|
||||||
import { SetActivity } from '@xhayper/discord-rpc';
|
import { SetActivity } from '@xhayper/discord-rpc';
|
||||||
@ -16,6 +17,7 @@ const discordRpc = isElectron() ? window.electron.discordRpc : null;
|
|||||||
export const useDiscordRpc = () => {
|
export const useDiscordRpc = () => {
|
||||||
const intervalRef = useRef(0);
|
const intervalRef = useRef(0);
|
||||||
const discordSettings = useDiscordSetttings();
|
const discordSettings = useDiscordSetttings();
|
||||||
|
const generalSettings = useGeneralSettings();
|
||||||
const currentSong = useCurrentSong();
|
const currentSong = useCurrentSong();
|
||||||
const currentStatus = useCurrentStatus();
|
const currentStatus = useCurrentStatus();
|
||||||
|
|
||||||
@ -67,6 +69,19 @@ export const useDiscordRpc = () => {
|
|||||||
activity.largeImageKey = song?.imageUrl;
|
activity.largeImageKey = song?.imageUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (generalSettings.lastfmApiKey && song?.album && song?.artists.length) {
|
||||||
|
console.log('Fetching album info for', song.album, song.artists[0].name);
|
||||||
|
const albumInfo = await fetch(
|
||||||
|
`https://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=${generalSettings.lastfmApiKey}&artist=${encodeURIComponent(song.artistName)}&album=${encodeURIComponent(song.album)}&format=json`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const albumInfoJson = await albumInfo.json();
|
||||||
|
|
||||||
|
if (albumInfoJson.album?.image?.[3]['#text']) {
|
||||||
|
activity.largeImageKey = albumInfoJson.album.image[3]['#text'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fall back to default icon if not set
|
// Fall back to default icon if not set
|
||||||
if (!activity.largeImageKey) {
|
if (!activity.largeImageKey) {
|
||||||
activity.largeImageKey = 'icon';
|
activity.largeImageKey = 'icon';
|
||||||
@ -79,6 +94,7 @@ export const useDiscordRpc = () => {
|
|||||||
discordSettings.enableIdle,
|
discordSettings.enableIdle,
|
||||||
discordSettings.showAsListening,
|
discordSettings.showAsListening,
|
||||||
discordSettings.showServerImage,
|
discordSettings.showServerImage,
|
||||||
|
generalSettings.lastfmApiKey,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -4,12 +4,17 @@ import {
|
|||||||
SettingOption,
|
SettingOption,
|
||||||
SettingsSection,
|
SettingsSection,
|
||||||
} from '/@/renderer/features/settings/components/settings-section';
|
} from '/@/renderer/features/settings/components/settings-section';
|
||||||
import { useDiscordSetttings, useSettingsStoreActions } from '/@/renderer/store';
|
import {
|
||||||
|
useDiscordSetttings,
|
||||||
|
useSettingsStoreActions,
|
||||||
|
useGeneralSettings,
|
||||||
|
} from '/@/renderer/store';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const DiscordSettings = () => {
|
export const DiscordSettings = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const settings = useDiscordSetttings();
|
const settings = useDiscordSetttings();
|
||||||
|
const generalSettings = useGeneralSettings();
|
||||||
const { setSettings } = useSettingsStoreActions();
|
const { setSettings } = useSettingsStoreActions();
|
||||||
|
|
||||||
const discordOptions: SettingOption[] = [
|
const discordOptions: SettingOption[] = [
|
||||||
@ -142,6 +147,31 @@ export const DiscordSettings = () => {
|
|||||||
postProcess: 'sentenceCase',
|
postProcess: 'sentenceCase',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
control: (
|
||||||
|
<TextInput
|
||||||
|
defaultValue={generalSettings.lastfmApiKey}
|
||||||
|
onBlur={(e) => {
|
||||||
|
setSettings({
|
||||||
|
general: {
|
||||||
|
...generalSettings,
|
||||||
|
lastfmApiKey: e.currentTarget.value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
description: t('setting.lastfmApiKey', {
|
||||||
|
context: 'description',
|
||||||
|
lastfm: 'Last.fm',
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
}),
|
||||||
|
isHidden: !isElectron(),
|
||||||
|
title: t('setting.lastfmApiKey', {
|
||||||
|
lastfm: 'Last.fm',
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
}),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return <SettingsSection options={discordOptions} />;
|
return <SettingsSection options={discordOptions} />;
|
||||||
|
@ -232,6 +232,7 @@ export interface SettingsState {
|
|||||||
homeFeature: boolean;
|
homeFeature: boolean;
|
||||||
homeItems: SortableItem<HomeItem>[];
|
homeItems: SortableItem<HomeItem>[];
|
||||||
language: string;
|
language: string;
|
||||||
|
lastfmApiKey: string;
|
||||||
nativeAspectRatio: boolean;
|
nativeAspectRatio: boolean;
|
||||||
passwordStore?: string;
|
passwordStore?: string;
|
||||||
playButtonBehavior: Play;
|
playButtonBehavior: Play;
|
||||||
@ -377,6 +378,7 @@ const initialState: SettingsState = {
|
|||||||
homeFeature: true,
|
homeFeature: true,
|
||||||
homeItems,
|
homeItems,
|
||||||
language: 'en',
|
language: 'en',
|
||||||
|
lastfmApiKey: '',
|
||||||
nativeAspectRatio: false,
|
nativeAspectRatio: false,
|
||||||
passwordStore: undefined,
|
passwordStore: undefined,
|
||||||
playButtonBehavior: Play.NOW,
|
playButtonBehavior: Play.NOW,
|
||||||
|
Loading…
Reference in New Issue
Block a user