include lastfm/mbz links
This commit is contained in:
parent
5516daab6e
commit
ea67a18962
10 changed files with 146 additions and 3 deletions
|
@ -16,7 +16,11 @@
|
||||||
"removeFromQueue": "remove from queue",
|
"removeFromQueue": "remove from queue",
|
||||||
"setRating": "set rating",
|
"setRating": "set rating",
|
||||||
"toggleSmartPlaylistEditor": "toggle $t(entity.smartPlaylist) editor",
|
"toggleSmartPlaylistEditor": "toggle $t(entity.smartPlaylist) editor",
|
||||||
"viewPlaylists": "view $t(entity.playlist_other)"
|
"viewPlaylists": "view $t(entity.playlist_other)",
|
||||||
|
"openIn": {
|
||||||
|
"lastfm": "Open in Last.fm",
|
||||||
|
"musicbrainz": "Open in MusicBrainz"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"action_one": "action",
|
"action_one": "action",
|
||||||
|
@ -414,6 +418,8 @@
|
||||||
"discordUpdateInterval_description": "the time in seconds between each update (minimum 15 seconds)",
|
"discordUpdateInterval_description": "the time in seconds between each update (minimum 15 seconds)",
|
||||||
"enableRemote": "enable remote control server",
|
"enableRemote": "enable remote control server",
|
||||||
"enableRemote_description": "enables the remote control server to allow other devices to control the application",
|
"enableRemote_description": "enables the remote control server to allow other devices to control the application",
|
||||||
|
"externalLinks": "show external links",
|
||||||
|
"externalLinks_description": "enables showing external links (Last.fm, MusicBrainz) on artist/album pages",
|
||||||
"exitToTray": "exit to tray",
|
"exitToTray": "exit to tray",
|
||||||
"exitToTray_description": "exit the application to the system tray",
|
"exitToTray_description": "exit the application to the system tray",
|
||||||
"floatingQueueArea": "show floating queue hover area",
|
"floatingQueueArea": "show floating queue hover area",
|
||||||
|
|
|
@ -202,6 +202,7 @@ const normalizeAlbum = (
|
||||||
imageSize?: number,
|
imageSize?: number,
|
||||||
): Album => {
|
): Album => {
|
||||||
return {
|
return {
|
||||||
|
albumArtist: item.AlbumArtist,
|
||||||
albumArtists:
|
albumArtists:
|
||||||
item.AlbumArtists.map((entry) => ({
|
item.AlbumArtists.map((entry) => ({
|
||||||
id: entry.Id,
|
id: entry.Id,
|
||||||
|
@ -233,6 +234,7 @@ const normalizeAlbum = (
|
||||||
isCompilation: null,
|
isCompilation: null,
|
||||||
itemType: LibraryItem.ALBUM,
|
itemType: LibraryItem.ALBUM,
|
||||||
lastPlayedAt: null,
|
lastPlayedAt: null,
|
||||||
|
mbzId: item.ProviderIds?.MusicBrainzAlbum || null,
|
||||||
name: item.Name,
|
name: item.Name,
|
||||||
playCount: item.UserData?.PlayCount || 0,
|
playCount: item.UserData?.PlayCount || 0,
|
||||||
releaseDate: item.PremiereDate?.split('T')[0] || null,
|
releaseDate: item.PremiereDate?.split('T')[0] || null,
|
||||||
|
@ -288,6 +290,7 @@ const normalizeAlbumArtist = (
|
||||||
}),
|
}),
|
||||||
itemType: LibraryItem.ALBUM_ARTIST,
|
itemType: LibraryItem.ALBUM_ARTIST,
|
||||||
lastPlayedAt: null,
|
lastPlayedAt: null,
|
||||||
|
mbz: item.ProviderIds?.MusicBrainzArtist || null,
|
||||||
name: item.Name,
|
name: item.Name,
|
||||||
playCount: item.UserData?.PlayCount || 0,
|
playCount: item.UserData?.PlayCount || 0,
|
||||||
serverId: server?.id || '',
|
serverId: server?.id || '',
|
||||||
|
|
|
@ -422,6 +422,11 @@ const song = z.object({
|
||||||
UserData: userData.optional(),
|
UserData: userData.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const providerIds = z.object({
|
||||||
|
MusicBrainzAlbum: z.string().optional(),
|
||||||
|
MusicBrainzArtist: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
const albumArtist = z.object({
|
const albumArtist = z.object({
|
||||||
BackdropImageTags: z.array(z.string()),
|
BackdropImageTags: z.array(z.string()),
|
||||||
ChannelId: z.null(),
|
ChannelId: z.null(),
|
||||||
|
@ -435,6 +440,7 @@ const albumArtist = z.object({
|
||||||
LocationType: z.string(),
|
LocationType: z.string(),
|
||||||
Name: z.string(),
|
Name: z.string(),
|
||||||
Overview: z.string(),
|
Overview: z.string(),
|
||||||
|
ProviderIds: providerIds.optional(),
|
||||||
RunTimeTicks: z.number(),
|
RunTimeTicks: z.number(),
|
||||||
ServerId: z.string(),
|
ServerId: z.string(),
|
||||||
Type: z.string(),
|
Type: z.string(),
|
||||||
|
@ -466,6 +472,7 @@ const album = z.object({
|
||||||
ParentLogoItemId: z.string(),
|
ParentLogoItemId: z.string(),
|
||||||
PremiereDate: z.string().optional(),
|
PremiereDate: z.string().optional(),
|
||||||
ProductionYear: z.number(),
|
ProductionYear: z.number(),
|
||||||
|
ProviderIds: providerIds.optional(),
|
||||||
RunTimeTicks: z.number(),
|
RunTimeTicks: z.number(),
|
||||||
ServerId: z.string(),
|
ServerId: z.string(),
|
||||||
Songs: z.array(song).optional(), // This is not a native Jellyfin property -- this is used for combined album detail
|
Songs: z.array(song).optional(), // This is not a native Jellyfin property -- this is used for combined album detail
|
||||||
|
|
|
@ -151,6 +151,7 @@ const normalizeAlbum = (
|
||||||
const imageBackdropUrl = imageUrl?.replace(/size=\d+/, 'size=1000') || null;
|
const imageBackdropUrl = imageUrl?.replace(/size=\d+/, 'size=1000') || null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
albumArtist: item.albumArtist,
|
||||||
albumArtists: [{ id: item.albumArtistId, imageUrl: null, name: item.albumArtist }],
|
albumArtists: [{ id: item.albumArtistId, imageUrl: null, name: item.albumArtist }],
|
||||||
artists: [{ id: item.artistId, imageUrl: null, name: item.artist }],
|
artists: [{ id: item.artistId, imageUrl: null, name: item.artist }],
|
||||||
backdropImageUrl: imageBackdropUrl,
|
backdropImageUrl: imageBackdropUrl,
|
||||||
|
@ -169,6 +170,7 @@ const normalizeAlbum = (
|
||||||
isCompilation: item.compilation,
|
isCompilation: item.compilation,
|
||||||
itemType: LibraryItem.ALBUM,
|
itemType: LibraryItem.ALBUM,
|
||||||
lastPlayedAt: normalizePlayDate(item),
|
lastPlayedAt: normalizePlayDate(item),
|
||||||
|
mbzId: item.mbzAlbumId || null,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
playCount: item.playCount,
|
playCount: item.playCount,
|
||||||
releaseDate: new Date(item.minYear, 0, 1).toISOString(),
|
releaseDate: new Date(item.minYear, 0, 1).toISOString(),
|
||||||
|
@ -217,6 +219,7 @@ const normalizeAlbumArtist = (
|
||||||
imageUrl: imageUrl || null,
|
imageUrl: imageUrl || null,
|
||||||
itemType: LibraryItem.ALBUM_ARTIST,
|
itemType: LibraryItem.ALBUM_ARTIST,
|
||||||
lastPlayedAt: normalizePlayDate(item),
|
lastPlayedAt: normalizePlayDate(item),
|
||||||
|
mbz: item.mbzArtistId || null,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
playCount: item.playCount,
|
playCount: item.playCount,
|
||||||
serverId: server?.id || 'unknown',
|
serverId: server?.id || 'unknown',
|
||||||
|
|
|
@ -126,6 +126,7 @@ const normalizeAlbumArtist = (
|
||||||
imageUrl,
|
imageUrl,
|
||||||
itemType: LibraryItem.ALBUM_ARTIST,
|
itemType: LibraryItem.ALBUM_ARTIST,
|
||||||
lastPlayedAt: null,
|
lastPlayedAt: null,
|
||||||
|
mbz: null,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
playCount: null,
|
playCount: null,
|
||||||
serverId: server?.id || 'unknown',
|
serverId: server?.id || 'unknown',
|
||||||
|
@ -150,6 +151,7 @@ const normalizeAlbum = (
|
||||||
}) || null;
|
}) || null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
albumArtist: item.artist,
|
||||||
albumArtists: item.artistId
|
albumArtists: item.artistId
|
||||||
? [{ id: item.artistId, imageUrl: null, name: item.artist }]
|
? [{ id: item.artistId, imageUrl: null, name: item.artist }]
|
||||||
: [],
|
: [],
|
||||||
|
@ -174,6 +176,7 @@ const normalizeAlbum = (
|
||||||
isCompilation: null,
|
isCompilation: null,
|
||||||
itemType: LibraryItem.ALBUM,
|
itemType: LibraryItem.ALBUM,
|
||||||
lastPlayedAt: null,
|
lastPlayedAt: null,
|
||||||
|
mbzId: null,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
playCount: null,
|
playCount: null,
|
||||||
releaseDate: item.year ? new Date(item.year, 0, 1).toISOString() : null,
|
releaseDate: item.year ? new Date(item.year, 0, 1).toISOString() : null,
|
||||||
|
|
|
@ -144,6 +144,7 @@ export type Genre = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Album = {
|
export type Album = {
|
||||||
|
albumArtist: string;
|
||||||
albumArtists: RelatedArtist[];
|
albumArtists: RelatedArtist[];
|
||||||
artists: RelatedArtist[];
|
artists: RelatedArtist[];
|
||||||
backdropImageUrl: string | null;
|
backdropImageUrl: string | null;
|
||||||
|
@ -157,6 +158,7 @@ export type Album = {
|
||||||
isCompilation: boolean | null;
|
isCompilation: boolean | null;
|
||||||
itemType: LibraryItem.ALBUM;
|
itemType: LibraryItem.ALBUM;
|
||||||
lastPlayedAt: string | null;
|
lastPlayedAt: string | null;
|
||||||
|
mbzId: string | null;
|
||||||
name: string;
|
name: string;
|
||||||
playCount: number | null;
|
playCount: number | null;
|
||||||
releaseDate: string | null;
|
releaseDate: string | null;
|
||||||
|
@ -229,6 +231,7 @@ export type AlbumArtist = {
|
||||||
imageUrl: string | null;
|
imageUrl: string | null;
|
||||||
itemType: LibraryItem.ALBUM_ARTIST;
|
itemType: LibraryItem.ALBUM_ARTIST;
|
||||||
lastPlayedAt: string | null;
|
lastPlayedAt: string | null;
|
||||||
|
mbz: string | null;
|
||||||
name: string;
|
name: string;
|
||||||
playCount: number | null;
|
playCount: number | null;
|
||||||
serverId: string;
|
serverId: string;
|
||||||
|
|
|
@ -4,7 +4,9 @@ import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/li
|
||||||
import { Box, Group, Spoiler, Stack } from '@mantine/core';
|
import { Box, Group, Spoiler, Stack } from '@mantine/core';
|
||||||
import { useSetState } from '@mantine/hooks';
|
import { useSetState } from '@mantine/hooks';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { FaLastfmSquare } from 'react-icons/fa';
|
||||||
import { RiHeartFill, RiHeartLine, RiMoreFill, RiSettings2Fill } from 'react-icons/ri';
|
import { RiHeartFill, RiHeartLine, RiMoreFill, RiSettings2Fill } from 'react-icons/ri';
|
||||||
|
import { SiMusicbrainz } from 'react-icons/si';
|
||||||
import { generatePath, useParams } from 'react-router';
|
import { generatePath, useParams } from 'react-router';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
@ -36,6 +38,7 @@ import { useAppFocus, useContainerQuery } from '/@/renderer/hooks';
|
||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import { useCurrentServer, useCurrentSong, useCurrentStatus } from '/@/renderer/store';
|
import { useCurrentServer, useCurrentSong, useCurrentStatus } from '/@/renderer/store';
|
||||||
import {
|
import {
|
||||||
|
useGeneralSettings,
|
||||||
usePlayButtonBehavior,
|
usePlayButtonBehavior,
|
||||||
useSettingsStoreActions,
|
useSettingsStoreActions,
|
||||||
useTableSettings,
|
useTableSettings,
|
||||||
|
@ -76,6 +79,7 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP
|
||||||
const status = useCurrentStatus();
|
const status = useCurrentStatus();
|
||||||
const isFocused = useAppFocus();
|
const isFocused = useAppFocus();
|
||||||
const currentSong = useCurrentSong();
|
const currentSong = useCurrentSong();
|
||||||
|
const { externalLinks } = useGeneralSettings();
|
||||||
|
|
||||||
const columnDefs = useMemo(
|
const columnDefs = useMemo(
|
||||||
() => getColumnDefs(tableConfig.columns, false, 'albumDetail'),
|
() => getColumnDefs(tableConfig.columns, false, 'albumDetail'),
|
||||||
|
@ -315,6 +319,8 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP
|
||||||
|
|
||||||
const { rowClassRules } = useCurrentSongRowStyles({ tableRef });
|
const { rowClassRules } = useCurrentSongRowStyles({ tableRef });
|
||||||
|
|
||||||
|
const mbzId = detailQuery?.data?.mbzId;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContentContainer>
|
<ContentContainer>
|
||||||
<LibraryBackgroundOverlay $backgroundColor={background} />
|
<LibraryBackgroundOverlay $backgroundColor={background} />
|
||||||
|
@ -397,6 +403,46 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP
|
||||||
</Group>
|
</Group>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
{externalLinks ? (
|
||||||
|
<Box component="section">
|
||||||
|
<Group spacing="sm">
|
||||||
|
<Button
|
||||||
|
compact
|
||||||
|
component="a"
|
||||||
|
href={`https://www.last.fm/music/${encodeURIComponent(
|
||||||
|
detailQuery?.data?.albumArtist || '',
|
||||||
|
)}/${encodeURIComponent(detailQuery.data?.name || '')}`}
|
||||||
|
radius="md"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
size="md"
|
||||||
|
target="_blank"
|
||||||
|
tooltip={{
|
||||||
|
label: t('action.openIn.lastfm'),
|
||||||
|
}}
|
||||||
|
variant="subtle"
|
||||||
|
>
|
||||||
|
<FaLastfmSquare size={25} />
|
||||||
|
</Button>
|
||||||
|
{mbzId ? (
|
||||||
|
<Button
|
||||||
|
compact
|
||||||
|
component="a"
|
||||||
|
href={`https://musicbrainz.org/release/${mbzId}`}
|
||||||
|
radius="md"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
size="md"
|
||||||
|
target="_blank"
|
||||||
|
tooltip={{
|
||||||
|
label: t('action.openIn.musicbrainz'),
|
||||||
|
}}
|
||||||
|
variant="subtle"
|
||||||
|
>
|
||||||
|
<SiMusicbrainz size={25} />
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
</Group>
|
||||||
|
</Box>
|
||||||
|
) : null}
|
||||||
{comment && (
|
{comment && (
|
||||||
<Box component="section">
|
<Box component="section">
|
||||||
<Spoiler
|
<Spoiler
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
|
import { useMemo } from 'react';
|
||||||
import { ColDef, RowDoubleClickedEvent } from '@ag-grid-community/core';
|
import { ColDef, RowDoubleClickedEvent } from '@ag-grid-community/core';
|
||||||
import { Box, Group, Stack } from '@mantine/core';
|
import { Box, Group, Stack } from '@mantine/core';
|
||||||
import { useMemo } from 'react';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { FaLastfmSquare } from 'react-icons/fa';
|
||||||
import { RiHeartFill, RiHeartLine, RiMoreFill } from 'react-icons/ri';
|
import { RiHeartFill, RiHeartLine, RiMoreFill } from 'react-icons/ri';
|
||||||
|
import { SiMusicbrainz } from 'react-icons/si';
|
||||||
import { generatePath, useParams } from 'react-router';
|
import { generatePath, useParams } from 'react-router';
|
||||||
import { createSearchParams, Link } from 'react-router-dom';
|
import { createSearchParams, Link } from 'react-router-dom';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
@ -34,7 +37,7 @@ import { LibraryBackgroundOverlay } from '/@/renderer/features/shared/components
|
||||||
import { useContainerQuery } from '/@/renderer/hooks';
|
import { useContainerQuery } from '/@/renderer/hooks';
|
||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
import { useGeneralSettings, usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
||||||
import { CardRow, Play, TableColumn } from '/@/renderer/types';
|
import { CardRow, Play, TableColumn } from '/@/renderer/types';
|
||||||
|
|
||||||
const ContentContainer = styled.div`
|
const ContentContainer = styled.div`
|
||||||
|
@ -59,6 +62,8 @@ interface AlbumArtistDetailContentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AlbumArtistDetailContent = ({ background }: AlbumArtistDetailContentProps) => {
|
export const AlbumArtistDetailContent = ({ background }: AlbumArtistDetailContentProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { externalLinks } = useGeneralSettings();
|
||||||
const { albumArtistId } = useParams() as { albumArtistId: string };
|
const { albumArtistId } = useParams() as { albumArtistId: string };
|
||||||
const cq = useContainerQuery();
|
const cq = useContainerQuery();
|
||||||
const handlePlayQueueAdd = usePlayQueueAdd();
|
const handlePlayQueueAdd = usePlayQueueAdd();
|
||||||
|
@ -324,6 +329,7 @@ export const AlbumArtistDetailContent = ({ background }: AlbumArtistDetailConten
|
||||||
detailQuery?.data?.biography !== undefined && detailQuery?.data?.biography !== null;
|
detailQuery?.data?.biography !== undefined && detailQuery?.data?.biography !== null;
|
||||||
const showTopSongs = topSongsQuery?.data?.items?.length;
|
const showTopSongs = topSongsQuery?.data?.items?.length;
|
||||||
const showGenres = detailQuery?.data?.genres ? detailQuery?.data?.genres.length !== 0 : false;
|
const showGenres = detailQuery?.data?.genres ? detailQuery?.data?.genres.length !== 0 : false;
|
||||||
|
const mbzId = detailQuery?.data?.mbz;
|
||||||
|
|
||||||
const isLoading =
|
const isLoading =
|
||||||
detailQuery?.isLoading ||
|
detailQuery?.isLoading ||
|
||||||
|
@ -411,6 +417,50 @@ export const AlbumArtistDetailContent = ({ background }: AlbumArtistDetailConten
|
||||||
</Group>
|
</Group>
|
||||||
</Box>
|
</Box>
|
||||||
) : null}
|
) : null}
|
||||||
|
{externalLinks ? (
|
||||||
|
<Box
|
||||||
|
component="section"
|
||||||
|
mb={-20}
|
||||||
|
mt={-20}
|
||||||
|
>
|
||||||
|
<Group spacing="sm">
|
||||||
|
<Button
|
||||||
|
compact
|
||||||
|
component="a"
|
||||||
|
href={`https://www.last.fm/music/${encodeURIComponent(
|
||||||
|
detailQuery?.data?.name || '',
|
||||||
|
)}`}
|
||||||
|
radius="md"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
size="md"
|
||||||
|
target="_blank"
|
||||||
|
tooltip={{
|
||||||
|
label: t('action.openIn.lastfm'),
|
||||||
|
}}
|
||||||
|
variant="subtle"
|
||||||
|
>
|
||||||
|
<FaLastfmSquare size={25} />
|
||||||
|
</Button>
|
||||||
|
{mbzId ? (
|
||||||
|
<Button
|
||||||
|
compact
|
||||||
|
component="a"
|
||||||
|
href={`https://musicbrainz.org/artist/${mbzId}`}
|
||||||
|
radius="md"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
size="md"
|
||||||
|
target="_blank"
|
||||||
|
tooltip={{
|
||||||
|
label: t('action.openIn.musicbrainz'),
|
||||||
|
}}
|
||||||
|
variant="subtle"
|
||||||
|
>
|
||||||
|
<SiMusicbrainz size={25} />
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
</Group>
|
||||||
|
</Box>
|
||||||
|
) : null}
|
||||||
{showBiography ? (
|
{showBiography ? (
|
||||||
<Box
|
<Box
|
||||||
component="section"
|
component="section"
|
||||||
|
|
|
@ -268,6 +268,26 @@ export const ControlSettings = () => {
|
||||||
isHidden: false,
|
isHidden: false,
|
||||||
title: t('setting.skipPlaylistPage', { postProcess: 'sentenceCase' }),
|
title: t('setting.skipPlaylistPage', { postProcess: 'sentenceCase' }),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
control: (
|
||||||
|
<Switch
|
||||||
|
defaultChecked={settings.externalLinks}
|
||||||
|
onChange={(e) => {
|
||||||
|
setSettings({
|
||||||
|
general: {
|
||||||
|
...settings,
|
||||||
|
externalLinks: e.currentTarget.checked,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
description: t('setting.externalLinks', {
|
||||||
|
context: 'description',
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
}),
|
||||||
|
title: t('setting.externalLinks', { postProcess: 'sentenceCase' }),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return <SettingsSection options={controlOptions} />;
|
return <SettingsSection options={controlOptions} />;
|
||||||
|
|
|
@ -170,6 +170,7 @@ export interface SettingsState {
|
||||||
general: {
|
general: {
|
||||||
accent: string;
|
accent: string;
|
||||||
defaultFullPlaylist: boolean;
|
defaultFullPlaylist: boolean;
|
||||||
|
externalLinks: boolean;
|
||||||
followSystemTheme: boolean;
|
followSystemTheme: boolean;
|
||||||
language: string;
|
language: string;
|
||||||
playButtonBehavior: Play;
|
playButtonBehavior: Play;
|
||||||
|
@ -281,6 +282,7 @@ const initialState: SettingsState = {
|
||||||
general: {
|
general: {
|
||||||
accent: 'rgb(53, 116, 252)',
|
accent: 'rgb(53, 116, 252)',
|
||||||
defaultFullPlaylist: true,
|
defaultFullPlaylist: true,
|
||||||
|
externalLinks: false,
|
||||||
followSystemTheme: false,
|
followSystemTheme: false,
|
||||||
language: 'en',
|
language: 'en',
|
||||||
playButtonBehavior: Play.NOW,
|
playButtonBehavior: Play.NOW,
|
||||||
|
|
Reference in a new issue