mmmm everything
This commit is contained in:
92
old.src/view/List.js
Normal file
92
old.src/view/List.js
Normal file
@@ -0,0 +1,92 @@
|
||||
export default function List(view) {
|
||||
|
||||
view.cursor = 0
|
||||
|
||||
const Render = this.Render = (entries, iResetCursorTo = view.cursor) => {
|
||||
while (view.element.firstChild) {
|
||||
view.element.removeChild(view.element.lastChild)
|
||||
}
|
||||
entries.map(renderEntry).forEach(n => view.element.appendChild(n))
|
||||
Focus(iResetCursorTo)
|
||||
}
|
||||
|
||||
const renderEntry = (entry, i) => {
|
||||
let ele = document.createElement('li')
|
||||
|
||||
if(entry.entries) {
|
||||
populateListEntry(entry, ele, i)
|
||||
} else {
|
||||
populateTrackEntry(entry, ele, i)
|
||||
}
|
||||
|
||||
// ele.addEventListener('mouseenter', (event) => {
|
||||
// console.log(event)
|
||||
// if(event.movementX || event.movementY)
|
||||
// Focus(i, false)
|
||||
// })
|
||||
|
||||
return ele
|
||||
}
|
||||
|
||||
const populateListEntry = (entry, ele) => {
|
||||
let a = document.createElement('a')
|
||||
let header = document.createElement('header')
|
||||
|
||||
header.innerText = entry.name
|
||||
a.appendChild(header)
|
||||
ele.appendChild(a)
|
||||
}
|
||||
|
||||
const populateTrackEntry = (entry, ele) => {
|
||||
// TODO: fix button problem on kaios
|
||||
let sect = document.createElement('section')
|
||||
|
||||
let trackNumber = document.createElement('code')
|
||||
let title = document.createElement('b')
|
||||
let artist = document.createElement('cite')
|
||||
|
||||
trackNumber.innerText = formatTrackNumber(entry.trackNumber)
|
||||
title.innerText = entry.name
|
||||
artist.innerText = entry.artist
|
||||
|
||||
sect.appendChild(title)
|
||||
sect.appendChild(artist)
|
||||
|
||||
ele.appendChild(trackNumber)
|
||||
ele.appendChild(sect)
|
||||
}
|
||||
|
||||
const formatTrackNumber = trackNumber => {
|
||||
return trackNumber == Infinity ? '--' : trackNumber.toString().padStart(2, '0')
|
||||
}
|
||||
|
||||
const Scroll = this.Scroll = (distance) => {
|
||||
let children = Array.from(view.element.children)
|
||||
let i = view.cursor
|
||||
i += distance
|
||||
if(i >= children.length) {
|
||||
i = 0
|
||||
} else if(i < 0) {
|
||||
i = children.length - 1
|
||||
}
|
||||
|
||||
Focus(i)
|
||||
}
|
||||
|
||||
const Focus = this.Focus = (i, scroll = true) => {
|
||||
view.cursor = i
|
||||
if(view.element.children.length === 0) {
|
||||
return
|
||||
}
|
||||
if(view.focus) {
|
||||
view.focus.classList.remove('focus')
|
||||
}
|
||||
view.focus = view.element.children[view.cursor]
|
||||
view.focus.classList.add('focus')
|
||||
if(scroll) {
|
||||
view.element.children[Math.max(i - 4, 0)].scrollIntoView()
|
||||
}
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
109
old.src/view/browser.js
Normal file
109
old.src/view/browser.js
Normal file
@@ -0,0 +1,109 @@
|
||||
// entry - a track, directory, playlist, etc
|
||||
// - entries
|
||||
// - name
|
||||
// - length
|
||||
|
||||
import List from "./List.js"
|
||||
import * as panels from "./panels.js"
|
||||
|
||||
const app = window.app ??= {}
|
||||
const view = window.view ??= {}
|
||||
|
||||
export let list = new List(view.browser = {
|
||||
element: document.getElementById('browser')
|
||||
})
|
||||
|
||||
export const Init = async () => {
|
||||
app.browser = {}
|
||||
app.browser.root = {
|
||||
entries: app.index,
|
||||
root: true
|
||||
}
|
||||
app.browser.current = app.browser.root
|
||||
app.browser.recursiveView = false
|
||||
app.browser.view = []
|
||||
}
|
||||
|
||||
export const View = async () => {
|
||||
Render()
|
||||
}
|
||||
|
||||
export const Render = async () => {
|
||||
organizeView()
|
||||
list.Render(app.browser.view, 0)
|
||||
}
|
||||
|
||||
export const organizeView = () => {
|
||||
if(app.browser.recursiveView) {
|
||||
app.browser.view = []
|
||||
recurseView()
|
||||
} else {
|
||||
app.browser.view = app.browser.current.entries
|
||||
}
|
||||
app.browser.view.sort((a, b) => a.order - b.order)
|
||||
}
|
||||
|
||||
export const recurseView = (eaEntries = app.browser.current.entries, bIncludeDirectories = true) => {
|
||||
for(let e of eaEntries) {
|
||||
if(e.entries) {
|
||||
recurseView(e.entries, false)
|
||||
if(!bIncludeDirectories)
|
||||
continue
|
||||
}
|
||||
app.browser.view.push(e)
|
||||
}
|
||||
}
|
||||
|
||||
export const Open = () => {
|
||||
panels.Display('browser')
|
||||
}
|
||||
|
||||
export const Back = () => {
|
||||
let e = app.browser.current
|
||||
if(e.root) {
|
||||
return
|
||||
}
|
||||
let s = Cd(e.parent)
|
||||
|
||||
if(s) {
|
||||
list.Focus(app.browser.view.indexOf(e))
|
||||
}
|
||||
}
|
||||
|
||||
export const Cd = (entry = Focused() || app.browser.root) => {
|
||||
if(entry.entries) {
|
||||
app.browser.current = entry
|
||||
Render()
|
||||
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
19
old.src/view/index.js
Normal file
19
old.src/view/index.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import * as mode from './panels.js'
|
||||
import * as queue from './queue.js'
|
||||
import * as browser from './browser.js'
|
||||
import * as player from './player.js'
|
||||
import * as input from './input.js'
|
||||
import * as List from './List.js'
|
||||
|
||||
export {
|
||||
mode,
|
||||
queue,
|
||||
browser,
|
||||
player,
|
||||
input,
|
||||
List
|
||||
}
|
||||
|
||||
export function toggleHidden(element) {
|
||||
element.classList.toggle('hidden')
|
||||
}
|
||||
211
old.src/view/input.js
Normal file
211
old.src/view/input.js
Normal file
@@ -0,0 +1,211 @@
|
||||
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'
|
||||
import * as main from '../main.js'
|
||||
|
||||
{
|
||||
window.addEventListener('keydown', OnKeydown)
|
||||
window.addEventListener('keyup', OnKeyup)
|
||||
}
|
||||
|
||||
export function Render() {
|
||||
Actions()
|
||||
}
|
||||
|
||||
export function Actions() {
|
||||
let a = view.actions = {}
|
||||
|
||||
a['EndCall'] = {
|
||||
name: 'Close Hiss',
|
||||
up() {
|
||||
main.saveState().then(() => window.close())
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
75
old.src/view/panels.js
Normal file
75
old.src/view/panels.js
Normal file
@@ -0,0 +1,75 @@
|
||||
const app = window.app ??= {}
|
||||
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 = {
|
||||
PLAYER: 0,
|
||||
BROWSER: 1,
|
||||
QUEUE: 2
|
||||
}
|
||||
|
||||
export const Init = (name) => {
|
||||
app.mode = 1
|
||||
}
|
||||
|
||||
export const View = () => {
|
||||
view.tabIndicatorLine = document.getElementById('tab-indicator-line')
|
||||
|
||||
modules = new Array(3)
|
||||
modules[states.PLAYER] = player
|
||||
modules[states.BROWSER] = browser
|
||||
modules[states.QUEUE] = queue
|
||||
|
||||
modules[app.mode].Open()
|
||||
|
||||
Render()
|
||||
input.Actions()
|
||||
}
|
||||
|
||||
export const Display = (name) => {
|
||||
document.body.classList = [ name ]
|
||||
}
|
||||
|
||||
export const Render = () => {
|
||||
updateIndicator()
|
||||
}
|
||||
|
||||
export const indicatorMargin = 2
|
||||
export const updateIndicator = () => {
|
||||
let dashes = []
|
||||
let r = 100 - (indicatorMargin * (modules.length - 1))
|
||||
let pd = 60
|
||||
let sdc = modules.length - 1
|
||||
let sdr = r - pd
|
||||
let sd = parseInt(sdr / sdc)
|
||||
pd += sdr % sdc
|
||||
|
||||
for(let i = 0; i < modules.length; i++) {
|
||||
dashes.push(i === app.mode ? pd : sd)
|
||||
}
|
||||
|
||||
view.tabIndicatorLine.style.strokeDasharray = dashes
|
||||
.join(', ' + indicatorMargin + ', ')
|
||||
|
||||
}
|
||||
|
||||
export const Set = (iMode) => {
|
||||
app.mode = iMode
|
||||
View()
|
||||
}
|
||||
|
||||
export const Scroll = (distance) => {
|
||||
let i = distance + app.mode
|
||||
if(i < 0) i = modules.length - 1
|
||||
else if(i >= modules.length) i = 0
|
||||
Set(i)
|
||||
}
|
||||
|
||||
export const OnKeydown = (event) => {
|
||||
return modules[app.mode].OnKeydown(event)
|
||||
}
|
||||
226
old.src/view/player.js
Normal file
226
old.src/view/player.js
Normal file
@@ -0,0 +1,226 @@
|
||||
const view = window.view ??= {}
|
||||
const app = window.app ??= {}
|
||||
|
||||
import * as mode from "./panels.js"
|
||||
import * as queue from "./queue.js"
|
||||
import * as entry from "../entry.js"
|
||||
|
||||
export const states = {
|
||||
EMPTY: 0,
|
||||
PLAYING: 1,
|
||||
PAUSED: 2
|
||||
}
|
||||
|
||||
export const Init = () => {
|
||||
app.player = {
|
||||
currentTime: 0
|
||||
}
|
||||
}
|
||||
|
||||
export const View = async () => {
|
||||
view.player = {
|
||||
cover: document.getElementById('track-cover'),
|
||||
title: document.getElementById('track-title'),
|
||||
artist: document.getElementById('track-artist'),
|
||||
timestamp: document.getElementById('timestamp'),
|
||||
trackLength: document.getElementById('track-length'),
|
||||
progress: document.getElementById('playback-progress')
|
||||
}
|
||||
|
||||
if(app.player.current) {
|
||||
Switch(await Load(app.player.current, app.player.currentTime), app.player.current)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const Open = () => {
|
||||
mode.Display('player')
|
||||
}
|
||||
|
||||
export const TogglePausePlay = () => {
|
||||
if(State() === states.PLAYING) {
|
||||
Pause()
|
||||
} else {
|
||||
Play()
|
||||
}
|
||||
}
|
||||
|
||||
export const OnKeydown = (event) => {
|
||||
switch(event.key) {
|
||||
case 'ArrowUp':
|
||||
navigator.volumeManager?.requestUp()
|
||||
break
|
||||
|
||||
case 'ArrowDown':
|
||||
navigator.volumeManager?.requestDown()
|
||||
break
|
||||
|
||||
case ' ':
|
||||
case 'Enter':
|
||||
if(State() === states.PLAYING) {
|
||||
Pause()
|
||||
} else {
|
||||
Play()
|
||||
}
|
||||
break
|
||||
|
||||
case ']':
|
||||
case 'SoftRight':
|
||||
Next()
|
||||
break
|
||||
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export const Load = async (eTrack, fromTime) => {
|
||||
let f = await device.Open(eTrack.handle)
|
||||
let u = URL.createObjectURL(f)
|
||||
|
||||
// if(fromTime) {
|
||||
// u = new URL(u)
|
||||
// u.hash = '#t=' + fromTime
|
||||
// }
|
||||
let a = new Audio(u)
|
||||
if(fromTime) {
|
||||
a.currentTime = fromTime
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
export const Switch = (aTrack, eTrack) => {
|
||||
if(State() === states.PLAYING) {
|
||||
view.playback.pause()
|
||||
}
|
||||
|
||||
view.playback = aTrack
|
||||
app.player.current = eTrack
|
||||
attach()
|
||||
Render()
|
||||
}
|
||||
|
||||
export const attach = () => {
|
||||
let a = view.playback
|
||||
|
||||
a.addEventListener('playing', onStart)
|
||||
a.addEventListener('timeupdate', onTimeUpdate)
|
||||
a.addEventListener('ended', onEnded)
|
||||
|
||||
storeTime()
|
||||
}
|
||||
|
||||
export const onStart = () => {
|
||||
storeTime()
|
||||
renderDuration()
|
||||
onTimeUpdate()
|
||||
}
|
||||
|
||||
export const onTimeUpdate = () => {
|
||||
let s = parseInt(view.playback.currentTime)
|
||||
if(s > app.player.currentTime) {
|
||||
storeTime()
|
||||
renderTimestamp()
|
||||
}
|
||||
renderProgress()
|
||||
}
|
||||
|
||||
export const storeTime = () => {
|
||||
app.player.currentTime = view.playback ?
|
||||
parseInt(view.playback.currentTime) :
|
||||
0
|
||||
}
|
||||
|
||||
export const formatTime = currentTime => {
|
||||
let minutes = Math.floor(currentTime / 60).toString()
|
||||
let seconds = Math.floor(currentTime % 60).toString()
|
||||
|
||||
return minutes.padStart(2, '0') + ':' + seconds.padStart(2, '0')
|
||||
}
|
||||
|
||||
export const onEnded = () => {
|
||||
view.playback = null
|
||||
Next()
|
||||
}
|
||||
|
||||
/* Rendering */
|
||||
|
||||
export const Render = async () => {
|
||||
marqueeableText(view.player.title, app.player.current.name)
|
||||
marqueeableText(view.player.artist, app.player.current.artist)
|
||||
renderCover()
|
||||
renderTimestamp()
|
||||
renderDuration()
|
||||
}
|
||||
|
||||
export const marqueeableText = (eElement, sName) => {
|
||||
while(eElement.firstChild) {
|
||||
eElement.lastChild.remove()
|
||||
}
|
||||
eElement.classList = []
|
||||
let s = textContainer(eElement, sName)
|
||||
|
||||
if(s.offsetWidth > eElement.offsetWidth) {
|
||||
eElement.classList = [ 'marquee' ]
|
||||
textContainer(eElement, sName)
|
||||
}
|
||||
}
|
||||
|
||||
export const textContainer = (eElement, sText) => {
|
||||
let s = document.createElement('span')
|
||||
s.innerText = sText
|
||||
eElement.appendChild(s)
|
||||
return s
|
||||
}
|
||||
|
||||
export const renderProgress = () => {
|
||||
let t = view.playback.currentTime / view.playback.duration
|
||||
t = parseInt(t * 100)
|
||||
view.player.progress.style.strokeDasharray = `${t}, ${100 - t}`
|
||||
}
|
||||
|
||||
export const renderTimestamp = (iTimestamp = app.player.currentTime) => {
|
||||
view.player.timestamp.innerText = formatTime(iTimestamp)
|
||||
}
|
||||
|
||||
export const renderDuration = (iDuration = view.playback.duration) => {
|
||||
view.player.trackLength.innerText = formatTime(iDuration)
|
||||
}
|
||||
|
||||
export const renderCover = async () => {
|
||||
view.player.cover.src = app.player.current.coverId ?
|
||||
URL.createObjectURL(await entry.GetCover(app.player.current)):
|
||||
''
|
||||
}
|
||||
|
||||
/* Actions */
|
||||
|
||||
export const Play = async () => {
|
||||
if(view.playback) {
|
||||
view.playback.play()
|
||||
return
|
||||
}
|
||||
|
||||
await Next()
|
||||
}
|
||||
|
||||
export const Next = async () => {
|
||||
let e = queue.Shift()
|
||||
if(e) {
|
||||
Switch(await Load(e), e)
|
||||
view.playback.play()
|
||||
}
|
||||
}
|
||||
|
||||
export const Pause = () => {
|
||||
view.playback.pause()
|
||||
}
|
||||
|
||||
export const State = () => {
|
||||
if(view.playback == null) {
|
||||
return states.EMPTY
|
||||
} else {
|
||||
return view.playback.paused ? states.PAUSED : states.PLAYING
|
||||
}
|
||||
}
|
||||
75
old.src/view/queue.js
Normal file
75
old.src/view/queue.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import List from "./List.js"
|
||||
import * as mode from "./panels.js"
|
||||
import * as player from "./player.js"
|
||||
|
||||
const app = window.app ??= {}
|
||||
const view = window.view ??= {}
|
||||
|
||||
export let list = new List(view.queue = {
|
||||
element: document.getElementById('queue'),
|
||||
})
|
||||
|
||||
export const Init = async () => {
|
||||
app.queue = []
|
||||
}
|
||||
|
||||
export const View = async () => {
|
||||
Render()
|
||||
}
|
||||
|
||||
export const Render = async () => {
|
||||
list.Render(app.queue)
|
||||
}
|
||||
|
||||
export const Move = (offset, eTrack = Focused()) => {
|
||||
let i = view.queue.cursor + offset
|
||||
if(i == app.queue.length || i < 0) {
|
||||
return
|
||||
}
|
||||
let n = app.queue[i]
|
||||
app.queue[view.queue.cursor] = n
|
||||
app.queue[i] = eTrack
|
||||
list.Render(app.queue, i)
|
||||
}
|
||||
|
||||
export const Open = () => {
|
||||
Render()
|
||||
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 = () => {
|
||||
let e
|
||||
|
||||
if(app.queue.length > 0) {
|
||||
e = app.queue.shift()
|
||||
Render()
|
||||
return e
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user