feat: rename Deck to Library and implement tap-to-preview for cards in Deck Builder on touch devices.
This commit is contained in:
@@ -96,3 +96,4 @@
|
||||
- [Create Favicon](./devlog/2025-12-18-005739_create_favicon.md): Completed. Generated and integrated a new application favicon.
|
||||
- [Mobile Touch Preview](./devlog/2025-12-18-012500_mobile_touch_preview.md): Completed. Updated card preview logic to disable hover and enable long-press on touch devices, improving usability on tablets and mobile.
|
||||
- [Minimize Slider Defaults](./devlog/2025-12-18-013000_minimize_slider_defaults.md): Completed. Set default card size settings to their minimum values across Cube Manager, Draft View, and Deck Builder.
|
||||
- [Deck Builder Touch Interaction](./devlog/2025-12-18-014500_deck_builder_touch.md): Completed. Renamed "Deck" to "Library" and implemented tap-to-preview logic on touch devices, disabling tap-to-move.
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Work Plan - Deck Builder Touch Interaction Updates
|
||||
|
||||
## Request
|
||||
1. Change "Deck" zone name to "Library" in the UI.
|
||||
2. Update touch interaction logic in Deck Builder:
|
||||
- Tap (1 finger) should NOT move the card (add/remove).
|
||||
- Tap (1 finger) should show the Card Preview (like in Draft Pick).
|
||||
- Drag and Drop remains the method to move cards on touch devices.
|
||||
|
||||
## Changes
|
||||
- **DeckBuilderView.tsx**:
|
||||
- Replaced display text "Deck" with "Library" in headers and empty state messages.
|
||||
- Updated `ListItem`, `DeckCardItem`, and `StackView` `onClick` handlers.
|
||||
- Implemented `window.matchMedia('(pointer: coarse)')` check to toggle behavior:
|
||||
- **Touch**: Tap -> `onHover(card)` (Preview)
|
||||
- **Mouse**: Click -> `onCardClick(card)` (Add/Remove)
|
||||
|
||||
## Verification
|
||||
- Verified code changes apply to all view modes (List, Grid, Stack).
|
||||
- Verified drag-and-drop mechanics were not altered (handled by dnd-kit wrappers).
|
||||
@@ -91,7 +91,13 @@ const ListItem: React.FC<{ card: DraftCard; onClick?: () => void; onHover?: (c:
|
||||
}
|
||||
};
|
||||
|
||||
const { onTouchStart, onTouchEnd, onTouchMove, onClick: handleTouchClick } = useCardTouch(onHover || (() => { }), onClick || (() => { }), card);
|
||||
const { onTouchStart, onTouchEnd, onTouchMove, onClick: handleTouchClick } = useCardTouch(onHover || (() => { }), () => {
|
||||
if (window.matchMedia('(pointer: coarse)').matches) {
|
||||
if (onHover) onHover(card);
|
||||
} else {
|
||||
if (onClick) onClick();
|
||||
}
|
||||
}, card);
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -159,7 +165,13 @@ const CardsDisplay: React.FC<{
|
||||
<StackView
|
||||
cards={cards.map(normalizeCard)}
|
||||
cardWidth={cardWidth}
|
||||
onCardClick={(c) => onCardClick(c)}
|
||||
onCardClick={(c) => {
|
||||
if (window.matchMedia('(pointer: coarse)').matches) {
|
||||
onHover(c);
|
||||
} else {
|
||||
onCardClick(c);
|
||||
}
|
||||
}}
|
||||
onHover={(c) => onHover(c)}
|
||||
disableHoverPreview={true}
|
||||
/>
|
||||
@@ -564,10 +576,10 @@ export const DeckBuilderView: React.FC<DeckBuilderViewProps> = ({ initialPool, a
|
||||
{/* Deck Column */}
|
||||
<DroppableZone id="deck-zone" className="flex-1 flex flex-col min-w-0 bg-slate-900/50">
|
||||
<div className="p-3 border-b border-slate-800 font-bold text-slate-400 uppercase text-xs flex justify-between">
|
||||
<span>Deck ({deck.length})</span>
|
||||
<span>Library ({deck.length})</span>
|
||||
</div>
|
||||
<div className="flex-1 overflow-auto p-2 custom-scrollbar">
|
||||
<CardsDisplay cards={deck} viewMode={viewMode} cardWidth={cardWidth} onCardClick={removeFromDeck} onHover={setHoveredCard} emptyMessage="Your Deck is Empty" source="deck" />
|
||||
<CardsDisplay cards={deck} viewMode={viewMode} cardWidth={cardWidth} onCardClick={removeFromDeck} onHover={setHoveredCard} emptyMessage="Your Library is Empty" source="deck" />
|
||||
</div>
|
||||
</DroppableZone>
|
||||
</div>
|
||||
@@ -586,10 +598,10 @@ export const DeckBuilderView: React.FC<DeckBuilderViewProps> = ({ initialPool, a
|
||||
{/* Bottom: Deck */}
|
||||
<DroppableZone id="deck-zone" className="h-[40%] flex flex-col min-h-0 bg-slate-900/50">
|
||||
<div className="p-2 border-b border-slate-800 font-bold text-slate-400 uppercase text-xs flex justify-between shrink-0">
|
||||
<span>Deck ({deck.length})</span>
|
||||
<span>Library ({deck.length})</span>
|
||||
</div>
|
||||
<div className="flex-1 overflow-auto p-2 custom-scrollbar">
|
||||
<CardsDisplay cards={deck} viewMode={viewMode} cardWidth={cardWidth} onCardClick={removeFromDeck} onHover={setHoveredCard} emptyMessage="Your Deck is Empty" source="deck" />
|
||||
<CardsDisplay cards={deck} viewMode={viewMode} cardWidth={cardWidth} onCardClick={removeFromDeck} onHover={setHoveredCard} emptyMessage="Your Library is Empty" source="deck" />
|
||||
</div>
|
||||
</DroppableZone>
|
||||
</div>
|
||||
@@ -613,7 +625,13 @@ export const DeckBuilderView: React.FC<DeckBuilderViewProps> = ({ initialPool, a
|
||||
|
||||
const DeckCardItem = ({ card, useArtCrop, isFoil, onCardClick, onHover }: any) => {
|
||||
const displayImage = useArtCrop ? card.imageArtCrop : card.image;
|
||||
const { onTouchStart, onTouchEnd, onTouchMove, onClick } = useCardTouch(onHover, () => onCardClick(card), card);
|
||||
const { onTouchStart, onTouchEnd, onTouchMove, onClick } = useCardTouch(onHover, () => {
|
||||
if (window.matchMedia('(pointer: coarse)').matches) {
|
||||
onHover(card);
|
||||
} else {
|
||||
onCardClick(card);
|
||||
}
|
||||
}, card);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user