From 5516daab6ea11c22b6e7e3e10cf2d97ea059fd43 Mon Sep 17 00:00:00 2001
From: Kendall Garner <17521368+kgarner7@users.noreply.github.com>
Date: Mon, 15 Jan 2024 20:46:06 -0800
Subject: [PATCH] enable comments, safer note
---
.../api/jellyfin/jellyfin-normalize.ts | 1 +
.../api/navidrome/navidrome-normalize.ts | 1 +
src/renderer/api/navidrome/navidrome-types.ts | 1 +
.../api/subsonic/subsonic-normalize.ts | 1 +
src/renderer/api/types.ts | 1 +
.../virtual-table/cells/note-cell.tsx | 17 ++-------
.../components/album-detail-content.tsx | 16 +++++++-
src/renderer/utils/linkify.tsx | 38 +++++++++++++++++++
8 files changed, 62 insertions(+), 14 deletions(-)
create mode 100644 src/renderer/utils/linkify.tsx
diff --git a/src/renderer/api/jellyfin/jellyfin-normalize.ts b/src/renderer/api/jellyfin/jellyfin-normalize.ts
index 4d844174..ffef489a 100644
--- a/src/renderer/api/jellyfin/jellyfin-normalize.ts
+++ b/src/renderer/api/jellyfin/jellyfin-normalize.ts
@@ -214,6 +214,7 @@ const normalizeAlbum = (
name: entry.Name,
})),
backdropImageUrl: null,
+ comment: null,
createdAt: item.DateCreated,
duration: item.RunTimeTicks / 10000,
genres: item.GenreItems?.map((entry) => ({
diff --git a/src/renderer/api/navidrome/navidrome-normalize.ts b/src/renderer/api/navidrome/navidrome-normalize.ts
index 4aafb14e..717ba2ca 100644
--- a/src/renderer/api/navidrome/navidrome-normalize.ts
+++ b/src/renderer/api/navidrome/navidrome-normalize.ts
@@ -154,6 +154,7 @@ const normalizeAlbum = (
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) => ({
diff --git a/src/renderer/api/navidrome/navidrome-types.ts b/src/renderer/api/navidrome/navidrome-types.ts
index d01174f6..b63b5442 100644
--- a/src/renderer/api/navidrome/navidrome-types.ts
+++ b/src/renderer/api/navidrome/navidrome-types.ts
@@ -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
diff --git a/src/renderer/api/subsonic/subsonic-normalize.ts b/src/renderer/api/subsonic/subsonic-normalize.ts
index 881e7fef..31c2f6c8 100644
--- a/src/renderer/api/subsonic/subsonic-normalize.ts
+++ b/src/renderer/api/subsonic/subsonic-normalize.ts
@@ -155,6 +155,7 @@ const normalizeAlbum = (
: [],
artists: item.artistId ? [{ id: item.artistId, imageUrl: null, name: item.artist }] : [],
backdropImageUrl: null,
+ comment: null,
createdAt: item.created,
duration: item.duration,
genres: item.genre
diff --git a/src/renderer/api/types.ts b/src/renderer/api/types.ts
index 5165c7fb..3abf9f64 100644
--- a/src/renderer/api/types.ts
+++ b/src/renderer/api/types.ts
@@ -147,6 +147,7 @@ export type Album = {
albumArtists: RelatedArtist[];
artists: RelatedArtist[];
backdropImageUrl: string | null;
+ comment: string | null;
createdAt: string;
duration: number | null;
genres: Genre[];
diff --git a/src/renderer/components/virtual-table/cells/note-cell.tsx b/src/renderer/components/virtual-table/cells/note-cell.tsx
index 1191d597..eaa1b5f7 100644
--- a/src/renderer/components/virtual-table/cells/note-cell.tsx
+++ b/src/renderer/components/virtual-table/cells/note-cell.tsx
@@ -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) => `${url}`,
- );
-};
+import { replaceURLWithHTMLLinks } from '/@/renderer/utils/linkify';
export const NoteCell = ({ value }: ICellRendererParams) => {
const formattedValue = useMemo(() => {
@@ -39,9 +29,10 @@ export const NoteCell = ({ value }: ICellRendererParams) => {
+ >
+ {formattedValue}
+
);
};
diff --git a/src/renderer/features/albums/components/album-detail-content.tsx b/src/renderer/features/albums/components/album-detail-content.tsx
index d158d908..97addc46 100644
--- a/src/renderer/features/albums/components/album-detail-content.tsx
+++ b/src/renderer/features/albums/components/album-detail-content.tsx
@@ -1,7 +1,7 @@
import { MutableRefObject, useCallback, useMemo } from 'react';
import { RowDoubleClickedEvent, RowHeightParams, RowNode } from '@ag-grid-community/core';
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
-import { Box, Group, Stack } from '@mantine/core';
+import { Box, Group, Spoiler, Stack } from '@mantine/core';
import { useSetState } from '@mantine/hooks';
import { useTranslation } from 'react-i18next';
import { RiHeartFill, RiHeartLine, RiMoreFill, RiSettings2Fill } from 'react-icons/ri';
@@ -41,6 +41,7 @@ import {
useTableSettings,
} from '/@/renderer/store/settings.store';
import { Play } from '/@/renderer/types';
+import { replaceURLWithHTMLLinks } from '/@/renderer/utils/linkify';
const isFullWidthRow = (node: RowNode) => {
return node.id?.startsWith('disc-');
@@ -279,6 +280,7 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP
};
const showGenres = detailQuery?.data?.genres ? detailQuery?.data?.genres.length !== 0 : false;
+ const comment = detailQuery?.data?.comment;
const handleGeneralContextMenu = useHandleGeneralContextMenu(
LibraryItem.ALBUM,
@@ -395,6 +397,18 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP
)}
+ {comment && (
+
+
+ {replaceURLWithHTMLLinks(comment)}
+
+
+ )}
{
+ const urlRegex = new RegExp(URL_REGEX, 'g');
+ const matches = text.matchAll(urlRegex);
+ const elements = [];
+ let lastIndex = 0;
+
+ for (const match of matches) {
+ const position = match.index!;
+
+ if (position > lastIndex) {
+ elements.push(text.substring(lastIndex, position));
+ }
+
+ const link = match[0];
+ elements.push(
+
+ {link}
+ ,
+ );
+
+ lastIndex = position + link.length;
+ }
+
+ if (text.length > lastIndex) {
+ elements.push(text.substring(lastIndex));
+ }
+
+ return elements;
+};