normalize controls onto lists

This commit is contained in:
jeffvli
2025-11-08 14:28:22 -08:00
parent fb75717ae0
commit 3c996407d5
15 changed files with 401 additions and 347 deletions
@@ -1,102 +1,104 @@
import { MouseEvent } from 'react';
import { useMemo } from 'react';
import {
ItemListItem,
ItemListStateActions,
} from '/@/renderer/components/item-list/helpers/item-list-state';
import { LibraryItem } from '/@/shared/types/domain-types';
import { ItemListItem } from '/@/renderer/components/item-list/helpers/item-list-state';
import { DefaultItemControlProps, ItemControls } from '/@/renderer/components/item-list/types';
import { usePlayerContext } from '/@/renderer/features/player/context/player-context';
import { Play } from '/@/shared/types/types';
const handleItemClick = (
item: (ItemListItem & object) | undefined,
itemType: LibraryItem,
internalState: ItemListStateActions,
) => {
if (!item) {
return;
}
export const useDefaultItemListControls = () => {
const player = usePlayerContext();
const itemListItem: ItemListItem = {
id: item.id,
itemType,
serverId: item.serverId,
};
const controls: ItemControls = useMemo(() => {
return {
onClick: ({ internalState, item, itemType }: DefaultItemControlProps) => {
if (!item) {
return;
}
// Regular click - deselect all others and select only this item
// If this item is already the only selected item, deselect it
const selectedItems = internalState.getSelected();
const isOnlySelected = selectedItems.length === 1 && selectedItems[0].id === item.id;
const itemListItem: ItemListItem = {
_serverId: item._serverId,
id: item.id,
itemType,
};
if (isOnlySelected) {
internalState.clearSelected();
} else {
internalState.setSelected([itemListItem]);
}
};
const handleItemDoubleClick = (
item: (ItemListItem & object) | undefined,
itemType: LibraryItem,
internalState: ItemListStateActions,
) => {
console.log('handleItemDoubleClick', item, itemType, internalState);
};
const handleItemExpand = (
item: (ItemListItem & object) | undefined,
itemType: LibraryItem,
internalState: ItemListStateActions,
) => {
if (!item) {
return;
}
return internalState.toggleExpanded({
id: item.id,
itemType,
serverId: item.serverId,
});
};
const handleItemFavorite = (
item: (ItemListItem & object) | undefined,
itemType: LibraryItem,
internalState: ItemListStateActions,
) => {
console.log('handleItemFavorite', item, itemType, internalState);
};
const handleItemRating = (
item: (ItemListItem & object) | undefined,
itemType: LibraryItem,
internalState: ItemListStateActions,
) => {
console.log('handleItemRating', item, itemType, internalState);
};
const handleItemMore = (
item: (ItemListItem & object) | undefined,
itemType: LibraryItem,
internalState: ItemListStateActions,
) => {
console.log('handleItemMore', item, itemType, internalState);
};
const handleItemPlay = (
item: (ItemListItem & object) | undefined,
itemType: LibraryItem,
playType: Play,
internalState: ItemListStateActions,
) => {
console.log('handleItemPlay', item, itemType, playType, internalState);
};
export const itemListControls = {
handleItemClick,
handleItemDoubleClick,
handleItemExpand,
handleItemFavorite,
handleItemMore,
handleItemPlay,
handleItemRating,
// Regular click - deselect all others and select only this item
// If this item is already the only selected item, deselect it
const selectedItems = internalState.getSelected();
const isOnlySelected =
selectedItems.length === 1 && selectedItems[0].id === item.id;
if (isOnlySelected) {
internalState.clearSelected();
} else {
internalState.setSelected([itemListItem]);
}
},
onDoubleClick: ({ internalState, item, itemType }: DefaultItemControlProps) => {
console.log('onDoubleClick', item, itemType, internalState);
},
onExpand: ({ internalState, item, itemType }: DefaultItemControlProps) => {
if (!item || !internalState) {
return;
}
return internalState?.toggleExpanded({
_serverId: item._serverId,
id: item.id,
itemType,
});
},
onFavorite: ({
favorite,
item,
itemType,
}: DefaultItemControlProps & { favorite: boolean }) => {
if (!item) {
return;
}
player.setFavorite(item._serverId, [item.id], itemType, favorite);
},
onMore: ({ internalState, item, itemType }: DefaultItemControlProps) => {
console.log('handleItemMore', item, itemType, internalState);
},
onPlay: ({
item,
itemType,
playType,
}: DefaultItemControlProps & { playType: Play }) => {
if (!item) {
return;
}
player.addToQueueByFetch(item._serverId, [item.id], itemType, playType);
},
onRating: ({
item,
itemType,
rating,
}: DefaultItemControlProps & { rating: number }) => {
if (!item) {
return;
}
const previousRating = (item as { userRating: number }).userRating || 0;
let newRating = rating;
if (previousRating === rating) {
newRating = 0;
}
player.setRating(item._serverId, [item.id], itemType, newRating);
},
};
}, [player]);
return controls;
};
@@ -13,9 +13,9 @@ export type ItemListAction =
| { type: 'CLEAR_SELECTED' };
export interface ItemListItem {
_serverId: string;
id: string;
itemType: LibraryItem;
serverId: string;
}
export interface ItemListState {
@@ -81,6 +81,8 @@ export const itemListReducer = (state: ItemListState, action: ItemListAction): I
const newExpanded = new Set<string>();
const newExpandedItems = new Map<string, ItemListItem>();
console.log('SET_EXPANDED', action.payload);
if (action.payload.length > 0) {
const firstItem = action.payload[0];
newExpanded.add(firstItem.id);
@@ -158,9 +160,6 @@ export const itemListReducer = (state: ItemListState, action: ItemListAction): I
}
};
/**
* Initial state for item grid
*/
export const initialItemListState: ItemListState = {
expanded: new Set(),
expandedItems: new Map(),