From b9af38f49da79bbfc1c110d79352665f30597805 Mon Sep 17 00:00:00 2001 From: Dakedres Date: Fri, 29 Nov 2024 13:09:49 -0700 Subject: [PATCH] Add input module --- index.html | 15 +--- src/browser.js | 71 +++++++---------- src/in | 1 + src/index.js | 2 + src/input.js | 210 +++++++++++++++++++++++++++++++++++++++++++++++++ src/list.js | 18 +---- src/main.js | 4 +- src/mode.js | 2 + src/player.js | 9 ++- src/queue.js | 55 +++++-------- src/util.js | 13 --- 11 files changed, 274 insertions(+), 126 deletions(-) create mode 100644 src/in create mode 100644 src/input.js delete mode 100644 src/util.js diff --git a/index.html b/index.html index fb4f18f..0688342 100644 --- a/index.html +++ b/index.html @@ -107,18 +107,9 @@ diff --git a/src/browser.js b/src/browser.js index db3062f..a73a11e 100644 --- a/src/browser.js +++ b/src/browser.js @@ -7,7 +7,6 @@ import List from "./list.js" import * as entry from "./entry.js" import * as mode from "./mode.js" import * as device from "device" -import { OnEntryListKeydown } from "./util.js" const app = window.app ??= {} const view = window.view ??= {} @@ -26,10 +25,9 @@ export const Init = async () => { } export const View = async () => { - list = new List( - view.browser = {}, - document.getElementById('browser') - ) + list = new List(view.browser = { + element: document.getElementById('browser') + }) Render() } @@ -63,44 +61,7 @@ export const Open = () => { mode.Display('browser') } -export const OnKeydown = (event) => { - let e = Focused() - - switch(event.key) { - case 'SoftLeft': - // PlayTrack() - break - - case 'Escape': - case 'Backspace': - back() - break - - case ' ': - case 'Enter': - if(e.entries) { - Cd(e) - break - } - case 'q': - if(e.entries == null) { - queue.Add(e) - } - list.Scroll(1) - break; - - case 'r': - case '7': - app.browser.recursiveView = !app.browser.recursiveView - Render() - break - - default: - return OnEntryListKeydown(list, event, e) - } -} - -export const back = () => { +export const Back = () => { let e = app.browser.current if(e.root) { return @@ -112,7 +73,7 @@ export const back = () => { } } -export const Cd = (entry = app.browser.root) => { +export const Cd = (entry = Focused() || app.browser.root) => { if(entry.entries) { app.browser.current = entry Render() @@ -123,6 +84,28 @@ export const Cd = (entry = app.browser.root) => { } } +export const Queue = (entry = Focused()) => { + queue.Add(entry) + list.Scroll(1) +} + +export const QueueAllBelow = () => { + let e = app.browser.current.entries + + for(let i = app.cursor; i < e.length; i++) { + queue.Add(e) + } +} + +export const GoToDirectory = (entry = Focused()) => { + Cd(entry.parent) && + list.Focus(app.browser.view.indexOf(entry)) +} + +export const ToggleRecursiveView = () => { + app.browser.recursiveView = !app.browser.recursiveView + Render() +} export const Focused = () => { return app.browser.view[view.browser.cursor] diff --git a/src/in b/src/in new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/src/in @@ -0,0 +1 @@ +1 diff --git a/src/index.js b/src/index.js index 22e7642..7834397 100644 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,7 @@ import * as queue from './queue.js' import * as entry from './entry.js' import * as mode from './mode.js' import * as player from './player.js' +import * as input from './input.js' import * as device from 'device' window.device = device @@ -12,6 +13,7 @@ window.queue = queue window.entry = entry window.mode = mode window.player = player +window.input = input window.main = main document.addEventListener('load', main.Start()) \ No newline at end of file diff --git a/src/input.js b/src/input.js new file mode 100644 index 0000000..7b98530 --- /dev/null +++ b/src/input.js @@ -0,0 +1,210 @@ +const app = window.app ??= {} +const view = window.view ??= {} + +const holdIntervals = 3 +const holdIntervalLength = 200 + +import * as browser from './browser.js' +import * as player from './player.js' +import * as queue from './queue.js' + +export function Init() { +} + +export function View() { + view.c + + window.addEventListener('keydown', OnKeydown) + window.addEventListener('keyup', OnKeyup) + + Render() +} + +export function Render() { + Actions() +} + +export function Actions() { + let a = view.actions = {} + + a['ArrowRight'] = { + name: 'Next Panel', + up() { + mode.Scroll(1) + } + } + a['ArrowLeft'] = { + name: 'Prev Panel', + up() { + mode.Scroll(-1) + } + } + a['0'] = { + + } + + a['c'] = a.pausePlay = { + hint: 'Pause/Play', + up: player.TogglePausePlay + } + a['s'] = a.skip = { + hint: 'Next', + up: player.Next + } + a['+'] = a.volumeUp = { + hint: 'Volume Up', + down() { + navigator.volumeUp() + } + } + a['-'] = a.volumeDown = { + hint: 'Volume Down', + down() { + navigator.volumeDown() + } + } + + switch(app.mode) { + case mode.states.PLAYER: + a[' '] = a['Enter'] = player.State() == player.states.PLAYING ? + { + hint: 'Play', + up: player.Play + } : + { + hint: 'Pause', + up: player.Pause + } + a['ArrowUp'] = a.volumeUp + a['ArrowDown'] = a.volumeDown + a['SoftRight'] = a.skip + break + + case mode.states.BROWSER: + a['q'] = { + down: browser.Queue + } + a[' '] = a['Enter'] = { + hint: 'Queue', + press() { + browser.Cd() && browser.Queue() + }, + holdHint: 'Queue All', + hold: browser.QueueAllBelow + } + a['4'] = a['g'] = { + up: browser.GoToDirectory + } + a['Backspace'] = a['Escape'] = { + up: browser.Back + } + + listActions(browser.list) + break + + case mode.states.QUEUE: + listActions(queue.list) + + a[' '] = a['Enter'] = { + hint: 'Remove', + press: queue.Remove, + holdHint: 'Remove All', + hold: queue.RemoveAllBelow + } + a['SoftLeft'] = a['['] = a['ArrowUp'].shift = { + down() { + queue.Move(-1) + } + } + a['SoftRight'] = a[']'] = a['ArrowDown'].shift = { + down() { + queue.Move(1) + } + } + a['4'] = a['g'] = { + up() { + browser.GoToDirectory(queue.Focused()) + mode.Set(mode.states.BROWSER) + } + } + break + } +} + +function listActions(list) { + let a = view.actions + + a['ArrowUp'] = { + down() { + list.Scroll(-1) + } + } + a['ArrowDown'] = { + down() { + list.Scroll(1) + } + } +} + +export function OnKeydown(event) { + let a = view.actions[event.key] + if(a == null) return + + ActionDown(a.shift && event.shiftKey ? a.shift : a) + && event.preventDefault() +} + +export function ActionDown(action) { + if(action.holdTimeout != null) { + return true + } + + if(action.down) { + return action.down() + } + + if(action.hold) { + Hold(action) + } else if(action.press) { + return action.press() + } +} + +export function OnKeyup(event) { + let a = view.actions[event.key] + if(a == null) return + + ActionUp(a.shift && event.shiftKey ? a.shift : a) + && event.preventDefault() +} + +export function ActionUp(action) { + if(action.holdTimeout != null) { + clearTimeout(action.holdTimeout) + action.holdTimeout = null + } + + if(action.up) { + return action.up() + } + + if(action.heldCount > 0) { + return action.press() + } +} + +export function Hold(aAction) { + aAction.heldCount = holdIntervals + createHoldTimeout(aAction) +} + +export function createHoldTimeout(aAction) { + aAction.holdTimeout = setTimeout(() => { + aAction.heldCount-- + if(aAction.heldCount == 0) { + aAction.hold() + } else { + createHoldTimeout(aAction) + } + }, holdIntervalLength) +} diff --git a/src/list.js b/src/list.js index 8203fa7..53d8411 100644 --- a/src/list.js +++ b/src/list.js @@ -1,6 +1,5 @@ -export default function List(view, element) { +export default function List(view) { - view.element = element view.cursor = 0 const Render = this.Render = (entries, iResetCursorTo = view.cursor) => { @@ -89,20 +88,5 @@ export default function List(view, element) { } } - const OnKeydown = this.OnKeydown = (event) => { - switch(event.key) { - case 'ArrowDown': - Scroll(1) - break - - case 'ArrowUp': - Scroll(-1) - break - - default: - return true - } - } - return this } \ No newline at end of file diff --git a/src/main.js b/src/main.js index d51d66f..3748720 100644 --- a/src/main.js +++ b/src/main.js @@ -6,6 +6,7 @@ import * as device from 'device' import * as browser from './browser.js' import * as entry from './entry.js' import * as mode from './mode.js' +import * as input from './input.js' export let store export let saveTimeout @@ -47,9 +48,8 @@ export const View = async () => { await queue.View() await player.View() mode.View() + input.View() - window.addEventListener('keydown', OnKeydown) - // player.Render({ name: 'Timeland, Smoke & Mirrors, The Land Before Timeland, & Hypertension', artist: 'King Gizzard & The Lizard Wizard' }) } diff --git a/src/mode.js b/src/mode.js index 9cddff9..858b13a 100644 --- a/src/mode.js +++ b/src/mode.js @@ -4,6 +4,7 @@ const view = window.view ??= {} import * as browser from './browser.js' import * as player from './player.js' import * as queue from './queue.js' +import * as input from './input.js' export let modules export const states = { @@ -27,6 +28,7 @@ export const View = () => { modules[app.mode].Open() Render() + input.Actions() } export const Display = (name) => { diff --git a/src/player.js b/src/player.js index 40444d7..1ea3049 100644 --- a/src/player.js +++ b/src/player.js @@ -61,7 +61,14 @@ export const textContainer = (eElement, sText) => { export const Open = () => { mode.Display('player') - document.body.classList.add('paused') +} + +export const TogglePausePlay = () => { + if(State() === states.PLAYING) { + Pause() + } else { + Play() + } } export const OnKeydown = (event) => { diff --git a/src/queue.js b/src/queue.js index a79fe52..e28be4e 100644 --- a/src/queue.js +++ b/src/queue.js @@ -2,22 +2,19 @@ import List from "./list.js" import * as mode from "./mode.js" import * as player from "./player.js" -import { OnEntryListKeydown } from "./util.js" const app = window.app ??= {} const view = window.view ??= {} -export let list +export let list = new List(view.queue = { + element: document.getElementById('queue'), +}) export const Init = async () => { app.queue = [] } export const View = async () => { - list = new List( - view.queue = {}, - document.getElementById('queue') - ) Render() } @@ -25,36 +22,7 @@ export const Render = async () => { list.Render(app.queue) } -export const OnKeydown = (event) => { - let e = Focused() - - switch(event.key) { - // case 'ArrowLeft': - // back() - // break - - // case 'ArrowRight': - // cd(e) - // break - - case '[': - case 'SoftLeft': - // Move track up - Move(e, -1) - break - - case ']': - case 'SoftRight': - // Move track down - Move(e, 1) - break; - - default: - return OnEntryListKeydown(list, event, e) - } -} - -export const Move = (eTrack, offset) => { +export const Move = (offset, eTrack = Focused()) => { let i = view.queue.cursor + offset if(i == app.queue.length || i < 0) { return @@ -70,17 +38,30 @@ export const Open = () => { mode.Display('queue') } - export const Focused = () => { return app.queue[view.queue.cursor] } export const Add = (eTrack) => { // TODO: solid way to determine if something is playable + if(eTrack.entries) { + return false + } app.queue.push(eTrack) if(app.queue.length == 1 && player.State() === player.states.EMPTY) { player.Next() } + return true +} + +export const Remove = () => { + app.queue.splice(view.queue.cursor, 1) + Render() +} + +export const RemoveAllBelow = () => { + app.queue = app.queue.slice(0, view.queue.cursor) + Render() } export const Shift = () => { diff --git a/src/util.js b/src/util.js deleted file mode 100644 index 6faa0d6..0000000 --- a/src/util.js +++ /dev/null @@ -1,13 +0,0 @@ -export const OnEntryListKeydown = (list, event, e) => { - switch(event.key) { - case '4': - case 'g': - browser.Open() - browser.Cd(e.parent) && - list.Focus(app.browser.view.indexOf(e)) - break - - default: - return list.OnKeydown(event) - } -} \ No newline at end of file