Add input module
This commit is contained in:
parent
814d6741a2
commit
b9af38f49d
15
index.html
15
index.html
@ -107,18 +107,9 @@
|
|||||||
</svg>
|
</svg>
|
||||||
<nav>
|
<nav>
|
||||||
|
|
||||||
<button class="left player">Previous</button>
|
<button id="left">Previous</button>
|
||||||
<button class="center player playing">Paused</button>
|
<button id="center">Paused</button>
|
||||||
<button class="center player paused">Play</button>
|
<button id="right">Next</button>
|
||||||
<button class="right player">Next</button>
|
|
||||||
|
|
||||||
<button class="left queue">Up</button>
|
|
||||||
<button class="center queue">Jump</button>
|
|
||||||
<button class="right queue">Down</button>
|
|
||||||
|
|
||||||
<button class="left browser">Queue All</button>
|
|
||||||
<button class="center browser">Queue</button>
|
|
||||||
<button class="right browser">Play Track</button>
|
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ import List from "./list.js"
|
|||||||
import * as entry from "./entry.js"
|
import * as entry from "./entry.js"
|
||||||
import * as mode from "./mode.js"
|
import * as mode from "./mode.js"
|
||||||
import * as device from "device"
|
import * as device from "device"
|
||||||
import { OnEntryListKeydown } from "./util.js"
|
|
||||||
|
|
||||||
const app = window.app ??= {}
|
const app = window.app ??= {}
|
||||||
const view = window.view ??= {}
|
const view = window.view ??= {}
|
||||||
@ -26,10 +25,9 @@ export const Init = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const View = async () => {
|
export const View = async () => {
|
||||||
list = new List(
|
list = new List(view.browser = {
|
||||||
view.browser = {},
|
element: document.getElementById('browser')
|
||||||
document.getElementById('browser')
|
})
|
||||||
)
|
|
||||||
Render()
|
Render()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,44 +61,7 @@ export const Open = () => {
|
|||||||
mode.Display('browser')
|
mode.Display('browser')
|
||||||
}
|
}
|
||||||
|
|
||||||
export const OnKeydown = (event) => {
|
export const Back = () => {
|
||||||
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 = () => {
|
|
||||||
let e = app.browser.current
|
let e = app.browser.current
|
||||||
if(e.root) {
|
if(e.root) {
|
||||||
return
|
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) {
|
if(entry.entries) {
|
||||||
app.browser.current = entry
|
app.browser.current = entry
|
||||||
Render()
|
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 = () => {
|
export const Focused = () => {
|
||||||
return app.browser.view[view.browser.cursor]
|
return app.browser.view[view.browser.cursor]
|
||||||
|
@ -4,6 +4,7 @@ import * as queue from './queue.js'
|
|||||||
import * as entry from './entry.js'
|
import * as entry from './entry.js'
|
||||||
import * as mode from './mode.js'
|
import * as mode from './mode.js'
|
||||||
import * as player from './player.js'
|
import * as player from './player.js'
|
||||||
|
import * as input from './input.js'
|
||||||
import * as device from 'device'
|
import * as device from 'device'
|
||||||
|
|
||||||
window.device = device
|
window.device = device
|
||||||
@ -12,6 +13,7 @@ window.queue = queue
|
|||||||
window.entry = entry
|
window.entry = entry
|
||||||
window.mode = mode
|
window.mode = mode
|
||||||
window.player = player
|
window.player = player
|
||||||
|
window.input = input
|
||||||
window.main = main
|
window.main = main
|
||||||
|
|
||||||
document.addEventListener('load', main.Start())
|
document.addEventListener('load', main.Start())
|
210
src/input.js
Normal file
210
src/input.js
Normal file
@ -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)
|
||||||
|
}
|
18
src/list.js
18
src/list.js
@ -1,6 +1,5 @@
|
|||||||
export default function List(view, element) {
|
export default function List(view) {
|
||||||
|
|
||||||
view.element = element
|
|
||||||
view.cursor = 0
|
view.cursor = 0
|
||||||
|
|
||||||
const Render = this.Render = (entries, iResetCursorTo = view.cursor) => {
|
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
|
return this
|
||||||
}
|
}
|
@ -6,6 +6,7 @@ import * as device from 'device'
|
|||||||
import * as browser from './browser.js'
|
import * as browser from './browser.js'
|
||||||
import * as entry from './entry.js'
|
import * as entry from './entry.js'
|
||||||
import * as mode from './mode.js'
|
import * as mode from './mode.js'
|
||||||
|
import * as input from './input.js'
|
||||||
|
|
||||||
export let store
|
export let store
|
||||||
export let saveTimeout
|
export let saveTimeout
|
||||||
@ -47,8 +48,7 @@ export const View = async () => {
|
|||||||
await queue.View()
|
await queue.View()
|
||||||
await player.View()
|
await player.View()
|
||||||
mode.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' })
|
// player.Render({ name: 'Timeland, Smoke & Mirrors, The Land Before Timeland, & Hypertension', artist: 'King Gizzard & The Lizard Wizard' })
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ const view = window.view ??= {}
|
|||||||
import * as browser from './browser.js'
|
import * as browser from './browser.js'
|
||||||
import * as player from './player.js'
|
import * as player from './player.js'
|
||||||
import * as queue from './queue.js'
|
import * as queue from './queue.js'
|
||||||
|
import * as input from './input.js'
|
||||||
|
|
||||||
export let modules
|
export let modules
|
||||||
export const states = {
|
export const states = {
|
||||||
@ -27,6 +28,7 @@ export const View = () => {
|
|||||||
modules[app.mode].Open()
|
modules[app.mode].Open()
|
||||||
|
|
||||||
Render()
|
Render()
|
||||||
|
input.Actions()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Display = (name) => {
|
export const Display = (name) => {
|
||||||
|
@ -61,7 +61,14 @@ export const textContainer = (eElement, sText) => {
|
|||||||
|
|
||||||
export const Open = () => {
|
export const Open = () => {
|
||||||
mode.Display('player')
|
mode.Display('player')
|
||||||
document.body.classList.add('paused')
|
}
|
||||||
|
|
||||||
|
export const TogglePausePlay = () => {
|
||||||
|
if(State() === states.PLAYING) {
|
||||||
|
Pause()
|
||||||
|
} else {
|
||||||
|
Play()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const OnKeydown = (event) => {
|
export const OnKeydown = (event) => {
|
||||||
|
55
src/queue.js
55
src/queue.js
@ -2,22 +2,19 @@ import List from "./list.js"
|
|||||||
|
|
||||||
import * as mode from "./mode.js"
|
import * as mode from "./mode.js"
|
||||||
import * as player from "./player.js"
|
import * as player from "./player.js"
|
||||||
import { OnEntryListKeydown } from "./util.js"
|
|
||||||
|
|
||||||
const app = window.app ??= {}
|
const app = window.app ??= {}
|
||||||
const view = window.view ??= {}
|
const view = window.view ??= {}
|
||||||
|
|
||||||
export let list
|
export let list = new List(view.queue = {
|
||||||
|
element: document.getElementById('queue'),
|
||||||
|
})
|
||||||
|
|
||||||
export const Init = async () => {
|
export const Init = async () => {
|
||||||
app.queue = []
|
app.queue = []
|
||||||
}
|
}
|
||||||
|
|
||||||
export const View = async () => {
|
export const View = async () => {
|
||||||
list = new List(
|
|
||||||
view.queue = {},
|
|
||||||
document.getElementById('queue')
|
|
||||||
)
|
|
||||||
Render()
|
Render()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,36 +22,7 @@ export const Render = async () => {
|
|||||||
list.Render(app.queue)
|
list.Render(app.queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const OnKeydown = (event) => {
|
export const Move = (offset, eTrack = Focused()) => {
|
||||||
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) => {
|
|
||||||
let i = view.queue.cursor + offset
|
let i = view.queue.cursor + offset
|
||||||
if(i == app.queue.length || i < 0) {
|
if(i == app.queue.length || i < 0) {
|
||||||
return
|
return
|
||||||
@ -70,17 +38,30 @@ export const Open = () => {
|
|||||||
mode.Display('queue')
|
mode.Display('queue')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const Focused = () => {
|
export const Focused = () => {
|
||||||
return app.queue[view.queue.cursor]
|
return app.queue[view.queue.cursor]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Add = (eTrack) => {
|
export const Add = (eTrack) => {
|
||||||
// TODO: solid way to determine if something is playable
|
// TODO: solid way to determine if something is playable
|
||||||
|
if(eTrack.entries) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
app.queue.push(eTrack)
|
app.queue.push(eTrack)
|
||||||
if(app.queue.length == 1 && player.State() === player.states.EMPTY) {
|
if(app.queue.length == 1 && player.State() === player.states.EMPTY) {
|
||||||
player.Next()
|
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 = () => {
|
export const Shift = () => {
|
||||||
|
13
src/util.js
13
src/util.js
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user