diff --git a/.gitignore b/.gitignore index ae1c70561b..48dc3058ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ npm-debug.log +/.idea + /build /appconfig.*.json diff --git a/src/chessground/Chessground.ts b/src/chessground/Chessground.ts index c9e9f4ef4f..008e9eef59 100644 --- a/src/chessground/Chessground.ts +++ b/src/chessground/Chessground.ts @@ -69,7 +69,11 @@ export default class Chessground { if (!isViewOnly) { board.addEventListener('touchstart', (e: TouchEvent) => drag.start(this, e)) board.addEventListener('touchmove', (e: TouchEvent) => drag.move(this, e)) - board.addEventListener('touchend', (e: TouchEvent) => drag.end(this, e)) + board.addEventListener('touchend', (e: TouchEvent) => { + const { clientX, clientY } = e.changedTouches[0] + drag.placePieceInHand(this, [clientX, clientY], bounds) + drag.end(this, e) + }) board.addEventListener('touchcancel', () => drag.cancel(this)) } diff --git a/src/chessground/board.ts b/src/chessground/board.ts index 45673627a3..644680506e 100644 --- a/src/chessground/board.ts +++ b/src/chessground/board.ts @@ -66,8 +66,8 @@ export function apiMove(state: State, orig: Key, dest: Key): boolean { return baseMove(state, orig, dest) } -export function apiNewPiece(state: State, piece: Piece, key: Key): boolean { - return baseNewPiece(state, piece, key) +export function apiNewPiece(state: State, piece: Piece, key: Key, force = false): boolean { + return baseNewPiece(state, piece, key, force) } export function userMove(state: State, orig: Key, dest: Key): boolean { @@ -136,6 +136,10 @@ export function unselect(state: State): void { state.premovable.dests = null } +export function setPieceInHand(state: State, piece: Piece | null, force = false): void { + state.pieceInHand = piece ? { ...piece, force } : null +} + export function isMovable(state: State, orig: Key): boolean { const piece = state.pieces.get(orig) return !!piece && ( diff --git a/src/chessground/drag.ts b/src/chessground/drag.ts index b401d3d6be..7942c9cd21 100644 --- a/src/chessground/drag.ts +++ b/src/chessground/drag.ts @@ -5,6 +5,7 @@ import Chessground from './Chessground' import * as board from './board' import * as util from './util' import { anim } from './anim' +import {apiNewPiece} from './board' export interface DragCurrent { orig: Key // orig key of dragging piece @@ -207,6 +208,22 @@ export function cancel(ctrl: Chessground) { } } +export function placePieceInHand(ctrl: Chessground, position: NumberPair, bounds: ClientRect) { + const state = ctrl.state + + if (state.pieceInHand) { + const [x, y] = position + const key = getKeyAtDomPos(state, [x, y], bounds) + + if (key) { + apiNewPiece(state, state.pieceInHand, key, state.pieceInHand.force) + } + state.pieceInHand = null + + ctrl.redraw() + } +} + function getKeyAtDomPos(state: State, pos: NumberPair, bounds: ClientRect): Key | null { if (typeof bounds !== 'object') { throw new Error('function getKeyAtDomPos require bounds object arg') diff --git a/src/chessground/state.ts b/src/chessground/state.ts index d0e789a8ba..e562ccf3d5 100644 --- a/src/chessground/state.ts +++ b/src/chessground/state.ts @@ -4,6 +4,7 @@ import { DragCurrent } from './drag' export interface State { pieces: cg.Pieces + pieceInHand: Piece & { force: boolean } | null orientation: Color // board orientation. white | black turnColor: Color // turn to play. white | black check: Key | null // square currently in check "a2" @@ -85,6 +86,7 @@ export interface State { export function makeDefaults(): State { return { pieces: new Map(), + pieceInHand: null, orientation: 'white' as Color, turnColor: 'white' as Color, check: null, diff --git a/src/ui/editor/EditorCtrl.ts b/src/ui/editor/EditorCtrl.ts index c4cf1dd680..ad234a783b 100644 --- a/src/ui/editor/EditorCtrl.ts +++ b/src/ui/editor/EditorCtrl.ts @@ -18,6 +18,7 @@ import continuePopup, { Controller as ContinuePopupCtrl } from '../shared/contin import i18n from '../../i18n' import drag from './drag' import { EditorState, BoardPosition, BoardPositionCategory, CastlingToggle, CastlingToggles, CASTLING_TOGGLES } from './interfaces' +import {setPieceInHand} from '../../chessground/board' export default class EditorCtrl { public menu: MenuInterface @@ -121,8 +122,29 @@ export default class EditorCtrl { redraw() } - public onstart = (e: TouchEvent): void => drag(this, e) + + private pickUp = (e: TouchEvent) => { + if (e.touches && e.touches.length > 1) return // support one finger touch only + const role = (e.target as HTMLElement).getAttribute('data-role'), + color = (e.target as HTMLElement).getAttribute('data-color') + if (!role || !color) return + e.stopPropagation() + e.preventDefault() + + const piece = { + role: (role as Role), + color: (color as Color) + } + + setPieceInHand(this.chessground.state, piece, true) + } + + public onstart = (e: TouchEvent): void => { + this.pickUp(e) + drag(this, e) + } public onmove = (e: TouchEvent): void => cgDrag.move(this.chessground, e) + public onend = (e: TouchEvent): void => cgDrag.end(this.chessground, e) public editorOnCreate = (vn: Mithril.VnodeDOM): void => {