Redesign sidebar / header and other misc. improvements (#24)

* Remove 1920px max width

* Fix position of list controls menu

* Match size and color of search input

* Adjust library header sizing

* Move app menu to sidebar

* Increase row buffer on play queue list

* Fix query builder styles

* Fix playerbar slider track bg

* Adjust titlebar styles

* Fix invalid modal prop

* Various adjustments to detail pages

* Fix sidebar height calculation

* Fix list null indicators, add filter indicator

* Adjust playqueue styles

* Fix jellyfin releaseYear normalization

* Suppress browser context menu on ag-grid

* Add radius to drawer queue -- normalize layout

* Add modal styles to provider theme

* Fix playlist song list pagination

* Add disc number to albums with more than one disc

* Fix query builder boolean values

* Adjust input placeholder color

* Properly handle rating/favorite from context menu on table

* Conform dropdown menu styles to context menu

* Increase sort type select width

* Fix drawer queue radius

* Change primary color

* Prevent volume wheel from invalid values

* Add icons to query builder dropdowns

* Update notification styles

* Update scrollbar thumb styles

* Remove "add to playlist" on smart playlists

* Fix "add to playlist" from context menu
This commit is contained in:
Jeff 2023-02-07 22:47:23 -08:00 committed by GitHub
parent d2c0d4c11f
commit 9f2e873366
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
80 changed files with 1427 additions and 1101 deletions

View file

@ -21,6 +21,16 @@ export const PLAYLIST_SONG_CONTEXT_MENU_ITEMS: SetContextMenuItems = [
{ children: true, disabled: false, id: 'setRating' },
];
export const SMART_PLAYLIST_SONG_CONTEXT_MENU_ITEMS: SetContextMenuItems = [
{ id: 'play' },
{ id: 'playLast' },
{ divider: true, id: 'playNext' },
{ divider: true, id: 'addToPlaylist' },
{ id: 'addToFavorites' },
{ divider: true, id: 'removeFromFavorites' },
{ children: true, disabled: false, id: 'setRating' },
];
export const ALBUM_CONTEXT_MENU_ITEMS: SetContextMenuItems = [
{ id: 'play' },
{ id: 'playLast' },

View file

@ -40,7 +40,7 @@ import { usePlayQueueAdd } from '/@/renderer/features/player';
import { useDeletePlaylist } from '/@/renderer/features/playlists';
import { useRemoveFromPlaylist } from '/@/renderer/features/playlists/mutations/remove-from-playlist-mutation';
import { useCreateFavorite, useDeleteFavorite, useUpdateRating } from '/@/renderer/features/shared';
import { useCurrentServer } from '/@/renderer/store';
import { useAuthStore, useCurrentServer } from '/@/renderer/store';
import { Play } from '/@/renderer/types';
type ContextMenuContextProps = {
@ -65,6 +65,10 @@ const ContextMenuContext = createContext<ContextMenuContextProps>({
},
});
const JELLYFIN_IGNORED_MENU_ITEMS: ContextMenuItemType[] = ['setRating'];
// const NAVIDROME_IGNORED_MENU_ITEMS: ContextMenuItemType[] = [];
// const SUBSONIC_IGNORED_MENU_ITEMS: ContextMenuItemType[] = [];
export interface ContextMenuProviderProps {
children: React.ReactNode;
}
@ -92,6 +96,13 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
const openContextMenu = (args: OpenContextMenuProps) => {
const { xPos, yPos, menuItems, data, type, tableRef, dataNodes, context } = args;
const serverType = data[0]?.serverType || useAuthStore.getState().currentServer?.type;
let validMenuItems = menuItems;
if (serverType === ServerType.JELLYFIN) {
validMenuItems = menuItems.filter((item) => !JELLYFIN_IGNORED_MENU_ITEMS.includes(item.id));
}
// If the context menu dimension can't be automatically calculated, calculate it manually
// This is a hacky way since resize observer may not automatically recalculate when not rendered
const menuHeight = menuRect.height || (menuItems.length + 1) * 50;
@ -107,7 +118,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
context,
data,
dataNodes,
menuItems,
menuItems: validMenuItems,
tableRef,
type,
xPos: calculatedXPos,
@ -187,8 +198,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
},
onSuccess: () => {
toast.success({
message: `${item.name} was successfully deleted`,
title: 'Playlist deleted',
message: `Playlist has been deleted`,
});
},
},
@ -269,9 +279,9 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
let nodesToUnfavorite: RowNode<any>[] = [];
if (ctx.dataNodes) {
nodesToUnfavorite = ctx.dataNodes.filter((item) => !item.data.userFavorite);
nodesToUnfavorite = ctx.dataNodes.filter((item) => item.data.userFavorite);
} else {
itemsToUnfavorite = ctx.data.filter((item) => !item.userFavorite);
itemsToUnfavorite = ctx.data.filter((item) => item.userFavorite);
}
const idsToUnfavorite = nodesToUnfavorite
@ -304,7 +314,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
if (ctx.dataNodes) {
for (const node of ctx.dataNodes) {
switch (node.data.type) {
switch (node.data.itemType) {
case LibraryItem.ALBUM:
albumId.push(node.data.id);
break;
@ -318,7 +328,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
}
} else {
for (const item of ctx.data) {
switch (item.type) {
switch (item.itemType) {
case LibraryItem.ALBUM:
albumId.push(item.id);
break;
@ -370,7 +380,6 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
onSuccess: () => {
toast.success({
message: `${songId.length} song(s) were removed from the playlist`,
title: 'Song(s) removed from playlist',
});
ctx.context?.tableRef?.current?.api?.refreshInfiniteCache();
closeAllModals();
@ -432,13 +441,24 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
items = ctx.data.filter((item) => item.serverId === serverId);
}
updateRatingMutation.mutate({
_serverId: serverId,
query: {
item: items,
rating,
updateRatingMutation.mutate(
{
_serverId: serverId,
query: {
item: items,
rating,
},
},
});
{
onSuccess: () => {
if (ctx.dataNodes) {
for (const node of ctx.dataNodes) {
node.setData({ ...node.data, userRating: rating });
}
}
},
},
);
}
},
[ctx.data, ctx.dataNodes, updateRatingMutation],
@ -625,17 +645,15 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
<HoverCard.Dropdown>
<Stack spacing={0}>
{contextMenuItems[item.id].children?.map((child) => (
<>
<ContextMenuButton
key={`sub-${child.id}`}
disabled={child.disabled}
leftIcon={child.leftIcon}
rightIcon={child.rightIcon}
onClick={child.onClick}
>
{child.label}
</ContextMenuButton>
</>
<ContextMenuButton
key={`sub-${child.id}`}
disabled={child.disabled}
leftIcon={child.leftIcon}
rightIcon={child.rightIcon}
onClick={child.onClick}
>
{child.label}
</ContextMenuButton>
))}
</Stack>
</HoverCard.Dropdown>