diff --git a/src/lib/api/resources/grid.ts b/src/lib/api/resources/grid.ts index c9c20bef..00c93667 100644 --- a/src/lib/api/resources/grid.ts +++ b/src/lib/api/resources/grid.ts @@ -281,4 +281,98 @@ export async function removeCharacter( if (!res.ok) { throw new Error(`Failed to remove character: ${res.statusText}`) } +} + +// Uncap update methods - these use special endpoints +export async function updateCharacterUncap( + gridCharacterId: string, + uncapLevel?: number, + transcendenceStep?: number, + headers?: Record +): Promise { + const body = { + character: { + id: gridCharacterId, + ...(uncapLevel !== undefined && { uncap_level: uncapLevel }), + ...(transcendenceStep !== undefined && { transcendence_step: transcendenceStep }) + } + } + + const res = await fetch('/api/uncap/characters', { + method: 'POST', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + ...headers + }, + body: JSON.stringify(body) + }) + + if (!res.ok) { + throw new Error(`Failed to update character uncap: ${res.statusText}`) + } + + return res.json() +} + +export async function updateWeaponUncap( + gridWeaponId: string, + uncapLevel?: number, + transcendenceStep?: number, + headers?: Record +): Promise { + const body = { + weapon: { + id: gridWeaponId, + ...(uncapLevel !== undefined && { uncap_level: uncapLevel }), + ...(transcendenceStep !== undefined && { transcendence_step: transcendenceStep }) + } + } + + const res = await fetch('/api/uncap/weapons', { + method: 'POST', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + ...headers + }, + body: JSON.stringify(body) + }) + + if (!res.ok) { + throw new Error(`Failed to update weapon uncap: ${res.statusText}`) + } + + return res.json() +} + +export async function updateSummonUncap( + gridSummonId: string, + uncapLevel?: number, + transcendenceStep?: number, + headers?: Record +): Promise { + const body = { + summon: { + id: gridSummonId, + ...(uncapLevel !== undefined && { uncap_level: uncapLevel }), + ...(transcendenceStep !== undefined && { transcendence_step: transcendenceStep }) + } + } + + const res = await fetch('/api/uncap/summons', { + method: 'POST', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + ...headers + }, + body: JSON.stringify(body) + }) + + if (!res.ok) { + throw new Error(`Failed to update summon uncap: ${res.statusText}`) + } + + return res.json() } \ No newline at end of file diff --git a/src/lib/composables/drag-drop.svelte.ts b/src/lib/composables/drag-drop.svelte.ts index 7613ca55..ab978600 100644 --- a/src/lib/composables/drag-drop.svelte.ts +++ b/src/lib/composables/drag-drop.svelte.ts @@ -99,7 +99,10 @@ export function createDragDropContext(handlers: DragDropHandlers = {}) { if (e.pointerType === 'touch') { initiateTouchDrag(e, item, source, type) } else { - startDrag(item, { ...source, type }) + // For mouse, don't start drag immediately - wait for actual drag movement + // This prevents the dragging class from being applied on simple clicks + state.touchState.touchStartPos = { x: e.clientX, y: e.clientY } + state.touchState.currentTouch = { item, source, type } } } @@ -123,10 +126,20 @@ export function createDragDropContext(handlers: DragDropHandlers = {}) { Math.pow(e.clientY - state.touchState.touchStartPos.y, 2) ) - if (distance > state.touchState.touchThreshold && state.touchState.longPressTimer) { + // For touch events, cancel long press if moved too much + if (e.pointerType === 'touch' && distance > state.touchState.touchThreshold && state.touchState.longPressTimer) { clearTimeout(state.touchState.longPressTimer) state.touchState.longPressTimer = null } + + // For mouse events, start dragging after threshold movement + if (e.pointerType === 'mouse' && !state.isDragging && state.touchState.currentTouch) { + if (distance > state.touchState.touchThreshold) { + const { item, source, type } = state.touchState.currentTouch + startDrag(item, { ...source, type }) + state.touchState.currentTouch = null + } + } } function handlePointerUp() { @@ -135,6 +148,7 @@ export function createDragDropContext(handlers: DragDropHandlers = {}) { state.touchState.longPressTimer = null } state.touchState.touchStartPos = null + state.touchState.currentTouch = null } function startDrag(item: GridItem, source: DragSource) { diff --git a/src/lib/services/grid.service.ts b/src/lib/services/grid.service.ts index 0c9b218b..b7714630 100644 --- a/src/lib/services/grid.service.ts +++ b/src/lib/services/grid.service.ts @@ -1,5 +1,6 @@ import type { Party, GridWeapon, GridSummon, GridCharacter } from '$lib/types/api/party' import * as partiesApi from '$lib/api/resources/parties' +import * as gridApi from '$lib/api/resources/grid' import type { FetchLike } from '$lib/api/core' export interface GridOperation { @@ -171,27 +172,15 @@ export class GridService { } async updateWeaponUncap( - partyId: string, gridWeaponId: string, - uncapLevel: number, - transcendenceLevel: number, + uncapLevel?: number, + transcendenceStep?: number, editKey?: string - ): Promise { - const payload = { - id: gridWeaponId, + ): Promise { + return gridApi.updateWeaponUncap( + gridWeaponId, uncapLevel, - transcendenceLevel - } - - // Set uncap to 6 when transcending - if (transcendenceLevel > 0 && uncapLevel < 6) { - payload.uncapLevel = 6 - } - - return partiesApi.updateWeaponGrid( - this.fetch, - partyId, - payload, + transcendenceStep, this.buildHeaders(editKey) ) } @@ -281,27 +270,15 @@ export class GridService { } async updateSummonUncap( - partyId: string, gridSummonId: string, - uncapLevel: number, - transcendenceLevel: number, + uncapLevel?: number, + transcendenceStep?: number, editKey?: string - ): Promise { - const payload = { - id: gridSummonId, + ): Promise { + return gridApi.updateSummonUncap( + gridSummonId, uncapLevel, - transcendenceLevel - } - - // Set uncap to 6 when transcending - if (transcendenceLevel > 0 && uncapLevel < 6) { - payload.uncapLevel = 6 - } - - return partiesApi.updateSummonGrid( - this.fetch, - partyId, - payload, + transcendenceStep, this.buildHeaders(editKey) ) } @@ -413,24 +390,15 @@ export class GridService { } async updateCharacterUncap( - partyId: string, gridCharacterId: string, - uncapLevel: number, - transcendenceLevel: number, - perpetuity: boolean, + uncapLevel?: number, + transcendenceStep?: number, editKey?: string - ): Promise { - const payload = { - id: gridCharacterId, + ): Promise { + return gridApi.updateCharacterUncap( + gridCharacterId, uncapLevel, - transcendenceLevel, - perpetuity - } - - return partiesApi.updateCharacterGrid( - this.fetch, - partyId, - payload, + transcendenceStep, this.buildHeaders(editKey) ) }