Skip to content

Commit

Permalink
feat: add long press mixin (#545)
Browse files Browse the repository at this point in the history
* longpress with some new props

* simple longpress without once handler

* working with once pattern

* updated tests and cleanup private props

* update prop executeonce to be ContinuousExecution

* lowercase ms

* fix: add $longPressEnd fireAncestor call

* fix: rename field in test

* fix: update docs

---------

Co-authored-by: David Richards, Jr. <dbarichardsjr@gmail.com>
  • Loading branch information
che-effe and ImCoolNowRight authored Oct 23, 2024
1 parent 55e8d4c commit 11d2368
Show file tree
Hide file tree
Showing 7 changed files with 617 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ function keyPress(elm, key) {
[`_handle${keyEvt.key}`, '_handleKey'],
{
...pressEvent,
timeStamp: Date.now(),
type: 'keydown',
...keyEvt
}
Expand All @@ -71,7 +72,12 @@ function keyRelease(elm, key) {
) {
elm.stage.application.focusBottomUpEvent(
[`_handle${keyEvt.key}Release`, '_handleKeyRelease'],
{ ...pressEvent, type: 'keyup', ...keyEvt }
{
...pressEvent,
timeStamp: Date.now(),
type: 'keyup',
...keyEvt
}
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`withLongPress renders 1`] = `
{
"Component": {
"Background": {
"active": false,
"alpha": 1,
"attached": true,
"boundsMargin": null,
"clipping": false,
"color": 4294967295,
"enabled": true,
"flex": false,
"flexItem": false,
"h": 0,
"isComponent": undefined,
"mount": 0,
"mountX": 0,
"mountY": 0,
"pivot": 0.5,
"pivotX": 0.5,
"pivotY": 0.5,
"ref": "Background",
"renderOfScreen": undefined,
"renderToTexture": false,
"scale": 1,
"scaleX": 1,
"scaleY": 1,
"state": undefined,
"tag": [Function],
"tags": [
"Background",
],
"texture": {
"type": "StaticCanvasTexture",
},
"visible": true,
"w": 0,
"x": 0,
"y": 0,
"zIndex": 0,
},
"Tile": {
"active": false,
"alpha": 1,
"attached": true,
"boundsMargin": null,
"children": {
"Artwork": {
"active": false,
"alpha": 0.001,
"attached": true,
"boundsMargin": null,
"children": {
"Image": {
"active": false,
"alpha": 1,
"attached": true,
"boundsMargin": null,
"clipping": false,
"color": 4294967295,
"enabled": true,
"flex": false,
"flexItem": false,
"h": 180,
"isComponent": undefined,
"mount": 0,
"mountX": 0,
"mountY": 0,
"pivot": 0.5,
"pivotX": 0.5,
"pivotY": 0.5,
"ref": "Image",
"renderOfScreen": undefined,
"renderToTexture": false,
"scale": 1,
"scaleX": 1,
"scaleY": 1,
"state": undefined,
"tag": [Function],
"tags": [
"Image",
],
"texture": {
"src": "https://image.tmdb.org/t/p/w500/zHdQ6yaqDf3OQO5uhr0auAgwK6O.jpg",
"type": "CustomImageTexture",
},
"visible": true,
"w": 320,
"x": 0,
"y": 0,
"zIndex": 1,
},
},
"clipping": false,
"color": 4294967295,
"enabled": true,
"flex": false,
"flexItem": false,
"h": 180,
"hasFinalFocus": false,
"hasFocus": false,
"isComponent": true,
"mount": 0.5,
"mountX": 0.5,
"mountY": 0.5,
"pivot": 0.5,
"pivotX": 0.5,
"pivotY": 0.5,
"ref": "Artwork",
"renderOfScreen": undefined,
"renderToTexture": true,
"scale": 1,
"scaleX": 1,
"scaleY": 1,
"state": "",
"tag": [Function],
"tags": [
"Artwork",
],
"type": "Artwork",
"visible": true,
"w": 320,
"x": 160,
"y": 90,
"zIndex": 0,
},
"Content": {
"active": false,
"alpha": 1,
"attached": true,
"boundsMargin": null,
"clipping": false,
"color": 4294967295,
"enabled": true,
"flex": false,
"flexItem": false,
"h": 180,
"isComponent": undefined,
"mount": 0.5,
"mountX": 0.5,
"mountY": 0.5,
"pivot": 0.5,
"pivotX": 0.5,
"pivotY": 0.5,
"ref": "Content",
"renderOfScreen": undefined,
"renderToTexture": false,
"scale": 1,
"scaleX": 1,
"scaleY": 1,
"state": undefined,
"tag": [Function],
"tags": [
"Content",
],
"visible": true,
"w": 320,
"x": 160,
"y": 90,
"zIndex": 0,
},
},
"clipping": false,
"color": 4294967295,
"enabled": true,
"flex": false,
"flexItem": false,
"h": 0,
"isComponent": undefined,
"mount": 0,
"mountX": 0,
"mountY": 0,
"pivot": 0.5,
"pivotX": 0.5,
"pivotY": 0.5,
"ref": "Tile",
"renderOfScreen": undefined,
"renderToTexture": false,
"scale": 1,
"scaleX": 1,
"scaleY": 1,
"state": undefined,
"tag": [Function],
"tags": [
"Tile",
],
"visible": true,
"w": 0,
"x": 0,
"y": 0,
"zIndex": 0,
},
},
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright 2023 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/

import lng from '@lightningjs/core';

export type WithLongPressConstructor<BaseType extends typeof lng.Component> =
BaseType & {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
new (...args: any[]): BaseType;
};

export default function withLongPress<BaseType extends typeof lng.Component>(
base: BaseType
): WithLongPressConstructor<BaseType>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* Copyright 2023 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/

export default function withLongPress(Base) {
return class extends Base {
static get name() {
return Base.name;
}

set threshold(value) {
this._threshold = value;
}

get threshold() {
return this._threshold;
}

set continuousExecution(val) {
this._continuousExecution = val;
}

_construct() {
this._pressedTimeStart = null;
this._hasExecuted = false;
this._threshold = 2000;
super._construct();
}

/**
* this will handle only key down events
* it will grab a reference start time stamp and compare it to any subsequent key down events' timestamp values
* when we meet the set threshold time in seconds, we will execute a supplied callback method
* */
_handleKey(keyEvent) {
// capture the key event time stamp the first time through to use as a reference.
if (!this._firstPressed) {
this._firstPressed = this._pressedTimeStart = keyEvent.timeStamp;
super._handleKey(keyEvent);
}
// check latest keyEvent time stamp against the start time stamp and see if the difference
// is greater than the threshold
if (
// eslint-disable-next-line no-constant-condition
this._pressedTimeStart &&
keyEvent.timeStamp - this._pressedTimeStart >= this.threshold
) {
// short circuit here if we only want to execute once before a key up event
if (!this._continuousExecution && this._hasExecuted) {
return;
}
this.fireAncestors('$longPressHit', keyEvent.key);
if (this._continuousExecution) {
this._pressedTimeStart += this.threshold;
} else {
this._hasExecuted = true;
this._pressedTimeStart = null;
}
}
}

/**
* this will handle only key up events
* */
_handleKeyRelease(keyEvent) {
if (keyEvent.timeStamp - this._firstPressed >= this.threshold) {
this.fireAncestors('$longPressEnd', keyEvent.key);
}
this._firstPressed = null;
this._pressedTimeStart = null;
this._hasExecuted = false;
super._handleKeyRelease(keyEvent);
}
};
}
Loading

0 comments on commit 11d2368

Please sign in to comment.