Skip to content

Commit

Permalink
feat(full-screen): add mousetrap record poc
Browse files Browse the repository at this point in the history
  • Loading branch information
daksh2k committed Jun 28, 2024
1 parent 3dfaeb8 commit f78c04e
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 47 deletions.
97 changes: 50 additions & 47 deletions Extensions/full-screen/dist/fullScreen.js

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions Extensions/full-screen/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { Config, Settings } from "./types/fullscreen";
import WebAPI from "./services/web-api";
import showWhatsNew from "./services/whats-new";
import { getHtmlContent } from "./services/html-creator";
import { initMoustrapRecord } from "./services/mousetrap-record";

import SeekableProgressBar from "./ui/components/ProgressBar/ProgressBar";
import SeekableVolumeBar from "./ui/components/VolumeBar/VolumeBar";
Expand All @@ -47,6 +48,7 @@ async function main() {

// Start from here
showWhatsNew();
initMoustrapRecord(Spicetify.Mousetrap);

if (CFM.getGlobal("activationTypes") !== "btns") {
if (CFM.getGlobal("keyActivation") !== "def") Spicetify.Mousetrap.bind("t", openwithTV);
Expand Down Expand Up @@ -259,6 +261,12 @@ async function main() {
}
}

function recordSequence() {
Spicetify.Mousetrap.record(function (sequence) {
// sequence is an array like ['ctrl+k', 'c']
console.log("You pressed: " + sequence.join(" "));
});
}
// Set the timeout to show upnext or hide when song ends
let upnextTimer: NodeJS.Timeout,
upNextShown = false;
Expand Down
199 changes: 199 additions & 0 deletions Extensions/full-screen/src/services/mousetrap-record.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/**
* This extension allows you to record a sequence using Mousetrap.
*
* @author Dan Tao <[email protected]>
*/
export function initMoustrapRecord(Mousetrap) {
/**
* the sequence currently being recorded
*
* @type {Array}
*/
var _recordedSequence = [],
/**
* a callback to invoke after recording a sequence
*
* @type {Function|null}
*/
_recordedSequenceCallback = null,
/**
* a list of all of the keys currently held down
*
* @type {Array}
*/
_currentRecordedKeys = [],
/**
* temporary state where we remember if we've already captured a
* character key in the current combo
*
* @type {boolean}
*/
_recordedCharacterKey = false,
/**
* a handle for the timer of the current recording
*
* @type {null|number}
*/
_recordTimer = null,
/**
* the original handleKey method to override when Mousetrap.record() is
* called
*
* @type {Function}
*/
_origHandleKey = Mousetrap.prototype.handleKey;

/**
* handles a character key event
*
* @param {string} character
* @param {Array} modifiers
* @param {Event} e
* @returns void
*/
function _handleKey(character, modifiers, e) {
var self = this;

if (!self.recording) {
_origHandleKey.apply(self, arguments);
return;
}

// remember this character if we're currently recording a sequence
if (e.type == "keydown") {
if (character.length === 1 && _recordedCharacterKey) {
_recordCurrentCombo();
}

for (i = 0; i < modifiers.length; ++i) {
_recordKey(modifiers[i]);
}
_recordKey(character);

// once a key is released, all keys that were held down at the time
// count as a keypress
} else if (e.type == "keyup" && _currentRecordedKeys.length > 0) {
_recordCurrentCombo();
}
}

/**
* marks a character key as held down while recording a sequence
*
* @param {string} key
* @returns void
*/
function _recordKey(key) {
var i;

// one-off implementation of Array.indexOf, since IE6-9 don't support it
for (i = 0; i < _currentRecordedKeys.length; ++i) {
if (_currentRecordedKeys[i] === key) {
return;
}
}

_currentRecordedKeys.push(key);

if (key.length === 1) {
_recordedCharacterKey = true;
}
}

/**
* marks whatever key combination that's been recorded so far as finished
* and gets ready for the next combo
*
* @returns void
*/
function _recordCurrentCombo() {
_recordedSequence.push(_currentRecordedKeys);
_currentRecordedKeys = [];
_recordedCharacterKey = false;
_restartRecordTimer();
}

/**
* ensures each combo in a sequence is in a predictable order and formats
* key combos to be '+'-delimited
*
* modifies the sequence in-place
*
* @param {Array} sequence
* @returns void
*/
function _normalizeSequence(sequence) {
var i;

for (i = 0; i < sequence.length; ++i) {
sequence[i].sort(function (x, y) {
// modifier keys always come first, in alphabetical order
if (x.length > 1 && y.length === 1) {
return -1;
} else if (x.length === 1 && y.length > 1) {
return 1;
}

// character keys come next (list should contain no duplicates,
// so no need for equality check)
return x > y ? 1 : -1;
});

sequence[i] = sequence[i].join("+");
}
}

/**
* finishes the current recording, passes the recorded sequence to the stored
* callback, and sets Mousetrap.handleKey back to its original function
*
* @returns void
*/
function _finishRecording() {
if (_recordedSequenceCallback) {
_normalizeSequence(_recordedSequence);
_recordedSequenceCallback(_recordedSequence);
}

// reset all recorded state
_recordedSequence = [];
_recordedSequenceCallback = null;
_currentRecordedKeys = [];
}

/**
* called to set a 1 second timeout on the current recording
*
* this is so after each key press in the sequence the recording will wait for
* 1 more second before executing the callback
*
* @returns void
*/
function _restartRecordTimer() {
clearTimeout(_recordTimer);
_recordTimer = setTimeout(_finishRecording, 1000);
}

/**
* records the next sequence and passes it to a callback once it's
* completed
*
* @param {Function} callback
* @returns void
*/
Mousetrap.prototype.record = function (callback) {
var self = this;
self.recording = true;
_recordedSequenceCallback = function () {
self.recording = false;
callback.apply(self, arguments);
};
};

Mousetrap.prototype.handleKey = function () {
var self = this;
_handleKey.apply(self, arguments);
};

Mousetrap.init();
}
1 change: 1 addition & 0 deletions shared/types/spicetify.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,7 @@ declare namespace Spicetify {
* so new extension should use this library instead.
*/
const Mousetrap: {
record(arg0: (sequence: any) => void): unknown;
bind: (
keys: string | string[],
callback: (event: KeyboardEvent, combo: string) => void,
Expand Down

0 comments on commit f78c04e

Please sign in to comment.