Skip to content

Commit

Permalink
Merge pull request #450 from kgarner7/more-metadata
Browse files Browse the repository at this point in the history
[feature]: Show album comment, Last.fm/MusicBrainz links
  • Loading branch information
jeffvli authored Feb 2, 2024
2 parents efa0d9e + aca6826 commit ccb0e14
Show file tree
Hide file tree
Showing 18 changed files with 335 additions and 72 deletions.
8 changes: 7 additions & 1 deletion src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
"removeFromQueue": "remove from queue",
"setRating": "set rating",
"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": {
"action_one": "action",
Expand Down Expand Up @@ -419,6 +423,8 @@
"discordUpdateInterval_description": "the time in seconds between each update (minimum 15 seconds)",
"enableRemote": "enable remote control server",
"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_description": "exit the application to the system tray",
"floatingQueueArea": "show floating queue hover area",
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/api/jellyfin/jellyfin-normalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ const normalizeAlbum = (
imageSize?: number,
): Album => {
return {
albumArtist: item.AlbumArtist,
albumArtists:
item.AlbumArtists.map((entry) => ({
id: entry.Id,
Expand All @@ -214,6 +215,7 @@ const normalizeAlbum = (
name: entry.Name,
})),
backdropImageUrl: null,
comment: null,
createdAt: item.DateCreated,
duration: item.RunTimeTicks / 10000,
genres: item.GenreItems?.map((entry) => ({
Expand All @@ -232,6 +234,7 @@ const normalizeAlbum = (
isCompilation: null,
itemType: LibraryItem.ALBUM,
lastPlayedAt: null,
mbzId: item.ProviderIds?.MusicBrainzAlbum || null,
name: item.Name,
playCount: item.UserData?.PlayCount || 0,
releaseDate: item.PremiereDate?.split('T')[0] || null,
Expand Down Expand Up @@ -287,6 +290,7 @@ const normalizeAlbumArtist = (
}),
itemType: LibraryItem.ALBUM_ARTIST,
lastPlayedAt: null,
mbz: item.ProviderIds?.MusicBrainzArtist || null,
name: item.Name,
playCount: item.UserData?.PlayCount || 0,
serverId: server?.id || '',
Expand Down
7 changes: 7 additions & 0 deletions src/renderer/api/jellyfin/jellyfin-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,11 @@ const song = z.object({
UserData: userData.optional(),
});

const providerIds = z.object({
MusicBrainzAlbum: z.string().optional(),
MusicBrainzArtist: z.string().optional(),
});

const albumArtist = z.object({
BackdropImageTags: z.array(z.string()),
ChannelId: z.null(),
Expand All @@ -435,6 +440,7 @@ const albumArtist = z.object({
LocationType: z.string(),
Name: z.string(),
Overview: z.string(),
ProviderIds: providerIds.optional(),
RunTimeTicks: z.number(),
ServerId: z.string(),
Type: z.string(),
Expand Down Expand Up @@ -466,6 +472,7 @@ const album = z.object({
ParentLogoItemId: z.string(),
PremiereDate: z.string().optional(),
ProductionYear: z.number(),
ProviderIds: providerIds.optional(),
RunTimeTicks: z.number(),
ServerId: z.string(),
Songs: z.array(song).optional(), // This is not a native Jellyfin property -- this is used for combined album detail
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/api/navidrome/navidrome-normalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,11 @@ const normalizeAlbum = (
const imageBackdropUrl = imageUrl?.replace(/size=\d+/, 'size=1000') || null;

return {
albumArtist: item.albumArtist,
albumArtists: [{ id: item.albumArtistId, imageUrl: null, name: item.albumArtist }],
artists: [{ id: item.artistId, imageUrl: null, name: item.artist }],
backdropImageUrl: imageBackdropUrl,
comment: item.comment || null,
createdAt: item.createdAt.split('T')[0],
duration: item.duration * 1000 || null,
genres: item.genres?.map((genre) => ({
Expand All @@ -168,6 +170,7 @@ const normalizeAlbum = (
isCompilation: item.compilation,
itemType: LibraryItem.ALBUM,
lastPlayedAt: normalizePlayDate(item),
mbzId: item.mbzAlbumId || null,
name: item.name,
playCount: item.playCount,
releaseDate: new Date(item.minYear, 0, 1).toISOString(),
Expand Down Expand Up @@ -216,6 +219,7 @@ const normalizeAlbumArtist = (
imageUrl: imageUrl || null,
itemType: LibraryItem.ALBUM_ARTIST,
lastPlayedAt: normalizePlayDate(item),
mbz: item.mbzArtistId || null,
name: item.name,
playCount: item.playCount,
serverId: server?.id || 'unknown',
Expand Down
1 change: 1 addition & 0 deletions src/renderer/api/navidrome/navidrome-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const album = z.object({
allArtistIds: z.string(),
artist: z.string(),
artistId: z.string(),
comment: z.string().optional(),
compilation: z.boolean(),
coverArtId: z.string().optional(), // Removed after v0.48.0
coverArtPath: z.string().optional(), // Removed after v0.48.0
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/api/subsonic/subsonic-normalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ const normalizeAlbumArtist = (
imageUrl,
itemType: LibraryItem.ALBUM_ARTIST,
lastPlayedAt: null,
mbz: null,
name: item.name,
playCount: null,
serverId: server?.id || 'unknown',
Expand All @@ -150,11 +151,13 @@ const normalizeAlbum = (
}) || null;

return {
albumArtist: item.artist,
albumArtists: item.artistId
? [{ id: item.artistId, imageUrl: null, name: item.artist }]
: [],
artists: item.artistId ? [{ id: item.artistId, imageUrl: null, name: item.artist }] : [],
backdropImageUrl: null,
comment: null,
createdAt: item.created,
duration: item.duration,
genres: item.genre
Expand All @@ -173,6 +176,7 @@ const normalizeAlbum = (
isCompilation: null,
itemType: LibraryItem.ALBUM,
lastPlayedAt: null,
mbzId: null,
name: item.name,
playCount: null,
releaseDate: item.year ? new Date(item.year, 0, 1).toISOString() : null,
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,11 @@ export type Genre = {
};

export type Album = {
albumArtist: string;
albumArtists: RelatedArtist[];
artists: RelatedArtist[];
backdropImageUrl: string | null;
comment: string | null;
createdAt: string;
duration: number | null;
genres: Genre[];
Expand All @@ -156,6 +158,7 @@ export type Album = {
isCompilation: boolean | null;
itemType: LibraryItem.ALBUM;
lastPlayedAt: string | null;
mbzId: string | null;
name: string;
playCount: number | null;
releaseDate: string | null;
Expand Down Expand Up @@ -228,6 +231,7 @@ export type AlbumArtist = {
imageUrl: string | null;
itemType: LibraryItem.ALBUM_ARTIST;
lastPlayedAt: string | null;
mbz: string | null;
name: string;
playCount: number | null;
serverId: string;
Expand Down
1 change: 1 addition & 0 deletions src/renderer/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export * from './select';
export * from './skeleton';
export * from './slider';
export * from './spinner';
export * from './spoiler';
export * from './switch';
export * from './tabs';
export * from './text';
Expand Down
39 changes: 39 additions & 0 deletions src/renderer/components/spoiler/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import clsx from 'clsx';
import { HTMLAttributes, ReactNode, useRef, useState } from 'react';
import styles from './spoiler.module.scss';
import { useIsOverflow } from '/@/renderer/hooks';

interface SpoilerProps extends HTMLAttributes<HTMLDivElement> {
children?: ReactNode;
defaultOpened?: boolean;
maxHeight?: number;
}

export const Spoiler = ({ maxHeight, defaultOpened, children, ...props }: SpoilerProps) => {
const ref = useRef(null);
const isOverflow = useIsOverflow(ref);
const [isExpanded, setIsExpanded] = useState(!!defaultOpened);

const spoilerClassNames = clsx(styles.spoiler, {
[styles.canExpand]: isOverflow,
[styles.isExpanded]: isExpanded,
});

const handleToggleExpand = () => {
setIsExpanded((val) => !val);
};

return (
<div
ref={ref}
className={spoilerClassNames}
role="button"
style={{ maxHeight: maxHeight ?? '100px' }}
tabIndex={-1}
onClick={handleToggleExpand}
{...props}
>
{children}
</div>
);
};
31 changes: 31 additions & 0 deletions src/renderer/components/spoiler/spoiler.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.control:hover {
color: var(--btn-subtle-fg-hover);
text-decoration: none;
}

.spoiler {
position: relative;
text-align: justify;
width: 100%;
height: 100%;
overflow: hidden;
}

.spoiler:not(.is-expanded).can-expand:after {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 100%;
content: '';
background: linear-gradient(to top, var(--main-bg) 10%, transparent 60%);
pointer-events: none;
}

.spoiler.can-expand {
cursor: pointer;
}

.spoiler.is-expanded {
max-height: 2500px !important;
}
17 changes: 4 additions & 13 deletions src/renderer/components/virtual-table/cells/note-cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,7 @@ import { Skeleton } from '/@/renderer/components/skeleton';
import { CellContainer } from '/@/renderer/components/virtual-table/cells/generic-cell';
import { useMemo } from 'react';
import { Text } from '/@/renderer/components/text';

const URL_REGEX =
/((?:https?:\/\/)?(?:[\w-]{1,32}(?:\.[\w-]{1,32})+)(?:\/[\w\-./?%&=][^.|^\s]*)?)/g;

const replaceURLWithHTMLLinks = (text: string) => {
const urlRegex = new RegExp(URL_REGEX, 'g');
return text.replaceAll(
urlRegex,
(url) => `<a href="${url}" target="_blank" rel="noreferrer">${url}</a>`,
);
};
import { replaceURLWithHTMLLinks } from '/@/renderer/utils/linkify';

export const NoteCell = ({ value }: ICellRendererParams) => {
const formattedValue = useMemo(() => {
Expand All @@ -39,9 +29,10 @@ export const NoteCell = ({ value }: ICellRendererParams) => {
<CellContainer $position="left">
<Text
$secondary
dangerouslySetInnerHTML={{ __html: formattedValue }}
overflow="hidden"
/>
>
{formattedValue}
</Text>
</CellContainer>
);
};
Loading

0 comments on commit ccb0e14

Please sign in to comment.