From c89c5a975a92081baf9c1f2828dcba63b81eb19d Mon Sep 17 00:00:00 2001 From: KRTirtho Date: Wed, 21 Apr 2021 14:00:40 +0600 Subject: [PATCH] Fixed shortcuts & replaced with pure QShortcut --- README.md | 13 ++++---- src/app.tsx | 92 +++++++++++++++++++++++++++++++++-------------------- 2 files changed, 65 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 68a467ac..1694ebff 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Following are the features that currently spotube offers: - Playback control is on user's machine instead of server based - Small size & less data hungry - No spotify or youtube ads since it uses all public & free APIs (But it's recommended to support the creators by watching/liking/subscribing to the artists youtube channel or add as favourite track in spotify. Mostly buying spotify premium is the best way to support their valuable creations) -- Lyric Seek (WIP) +- Lyric Seek ## Requirements @@ -149,11 +149,12 @@ $ npm start There will be some glitches, lags & stuck motions because of the library Spotube is currently using under the hood. It has some issues with layouts thus sometime some contents aren't shown or overflows out of the window. But resizing the window would fix this issue. Soon there will be some updates fixing this sort of layout related problems ## TODO: - -- Compile, Debug & Build for **MacOS** -- Add seek Lyric for currently playing track -- Support for playing/streaming podcasts/shows -- Easy installation procedure/mechanism for simplicity +- [ ] Compile, Debug & Build for **MacOS** +- [x] Compile, Debug & Build for **Windows** +- [x] Add seek Lyric for currently playing track +- [ ] Support for playing/streaming podcasts/shows +- [ ] Easy installation procedure/mechanism for simplicity in Windows +- [ ] Artist, User & Album pages ## Things that don't work - Shows & Podcasts aren't supported as it'd require premium anyway diff --git a/src/app.tsx b/src/app.tsx index 3130da7b..3e5c6928 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect, useRef } from "react"; -import { Window, hot, View, useEventHandler } from "@nodegui/react-nodegui"; -import { QIcon, QKeyEvent, QMainWindow, QMainWindowSignals, WidgetEventTypes, WindowState } from "@nodegui/nodegui"; +import { Window, hot, View } from "@nodegui/react-nodegui"; +import { QIcon, QMainWindow, WidgetEventTypes, WindowState, QShortcut, QKeySequence } from "@nodegui/nodegui"; import { MemoryRouter } from "react-router"; import Routes from "./routes"; import { LocalStorage } from "node-localstorage"; @@ -22,7 +22,7 @@ export enum LocalStorageKeys { credentials = "credentials", refresh_token = "refresh_token", preferences = "user-preferences", - volume = "volume" + volume = "volume", } export interface Credentials { @@ -54,36 +54,6 @@ const initialCredentials: Credentials = { clientId: "", clientSecret: "" }; function RootApp() { const windowRef = useRef(); const [currentTrack, setCurrentTrack] = useState(); - - const windowEvents = useEventHandler( - { - async KeyRelease(nativeEv) { - try { - if (nativeEv) { - const event = new QKeyEvent(nativeEv); - const eventKey = event.key(); - if (audioPlayer.isRunning() && currentTrack) - switch (eventKey) { - case 32: //space - (await audioPlayer.isPaused()) ? await audioPlayer.play() : await audioPlayer.pause(); - break; - case 16777236: //arrow-right - (await audioPlayer.isSeekable()) && (await audioPlayer.seek(+5)); - break; - case 16777234: //arrow-left - (await audioPlayer.isSeekable()) && (await audioPlayer.seek(-5)); - break; - default: - break; - } - } - } catch (error) { - console.error("Error in window events: ", error); - } - }, - }, - [currentTrack] - ); // cache const cachedPreferences = localStorage.getItem(LocalStorageKeys.preferences); const cachedCredentials = localStorage.getItem(LocalStorageKeys.credentials); @@ -160,13 +130,67 @@ function RootApp() { }; windowRef.current?.addEventListener(WidgetEventTypes.Close, onWindowClose); + return () => { windowRef.current?.removeEventListener(WidgetEventTypes.Close, onWindowClose); }; }); + let spaceShortcut: QShortcut | null; + let rightShortcut: QShortcut | null; + let leftShortcut: QShortcut | null; + // short cut effect + useEffect(() => { + if (windowRef.current) { + spaceShortcut = new QShortcut(windowRef.current); + rightShortcut = new QShortcut(windowRef.current); + leftShortcut = new QShortcut(windowRef.current); + + spaceShortcut.setKey(new QKeySequence("SPACE")); + rightShortcut.setKey(new QKeySequence("RIGHT")); + leftShortcut.setKey(new QKeySequence("LEFT")); + + async function spaceAction() { + try { + currentTrack && audioPlayer.isRunning() && (await audioPlayer.isPaused()) ? await audioPlayer.play() : await audioPlayer.pause(); + console.log("You pressed SPACE"); + } catch (error) { + showError(error, "[Failed to play/pause audioPlayer]: "); + } + } + async function rightAction() { + try { + currentTrack && audioPlayer.isRunning() && (await audioPlayer.isSeekable()) && (await audioPlayer.seek(+5)); + console.log("You pressed RIGHT"); + } catch (error) { + showError(error, "[Failed to seek audioPlayer]: "); + } + } + async function leftAction() { + try { + currentTrack && audioPlayer.isRunning() && (await audioPlayer.isSeekable()) && (await audioPlayer.seek(-5)); + console.log("You pressed LEFT"); + } catch (error) { + showError(error, "[Failed to seek audioPlayer]: "); + } + } + + spaceShortcut.addEventListener("activated", spaceAction); + rightShortcut.addEventListener("activated", rightAction); + leftShortcut.addEventListener("activated", leftAction); + + return () => { + spaceShortcut?.removeEventListener("activated", spaceAction); + rightShortcut?.removeEventListener("activated", rightAction); + leftShortcut?.removeEventListener("activated", leftAction); + spaceShortcut = null; + rightShortcut = null; + leftShortcut = null; + }; + } + }); return ( - +