From 43f1a1dd1b44065663a797603012394c52a9baea Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 13 May 2023 13:31:58 -0300 Subject: use ESM module syntax & update tui-lib Exciting update! This doesn't make any substantial changes exactly but does update the most quickly-archaic parts of older Node code. --- ui.js | 131 +++++++++++++++++++++++++++--------------------------------------- 1 file changed, 53 insertions(+), 78 deletions(-) (limited to 'ui.js') diff --git a/ui.js b/ui.js index dc9dab9..f006a70 100644 --- a/ui.js +++ b/ui.js @@ -1,20 +1,35 @@ // The UI in MTUI! Interfaces with the backend to form the complete mtui app. -'use strict' +import {spawn} from 'node:child_process' +import {readFile, writeFile} from 'node:fs/promises' +import path from 'node:path' +import url from 'node:url' -const { getAllCrawlersForArg } = require('./crawlers') -const processSmartPlaylist = require('./smart-playlist') -const UndoManager = require('./undo-manager') +import {orderBy} from 'natural-orderby' +import open from 'open' -const { +import {Button, Form, ListScrollForm, TextInput} from 'tui-lib/ui/controls' +import {Dialog} from 'tui-lib/ui/dialogs' +import {Label, Pane, WrapLabel} from 'tui-lib/ui/presentation' +import {DisplayElement, FocusElement} from 'tui-lib/ui/primitives' + +import * as ansi from 'tui-lib/util/ansi' +import telc from 'tui-lib/util/telchars' +import unic from 'tui-lib/util/unichars' + +import {getAllCrawlersForArg} from './crawlers.js' +import processSmartPlaylist from './smart-playlist.js' +import UndoManager from './undo-manager.js' + +import { commandExists, getSecFromTimestamp, getTimeStringsFromSec, promisifyProcess, - shuffleArray -} = require('./general-util') + shuffleArray, +} from './general-util.js' -const { +import { cloneGrouplike, collapseGrouplike, countTotalTracks, @@ -30,46 +45,14 @@ const { parentSymbol, reverseOrderOfGroups, searchForItem, - shuffleOrderOfGroups -} = require('./playlist-utils') - -const { - ui: { - Dialog, - DisplayElement, - Label, - Pane, - WrapLabel, - form: { - Button, - FocusElement, - Form, - ListScrollForm, - TextInput, - } - }, - util: { - ansi, - telchars: telc, - unichars: unic, - } -} = require('tui-lib') + shuffleOrderOfGroups, +} from './playlist-utils.js' /* text editor features disabled because theyre very much incomplete and havent * gotten much use from me or anyonea afaik! const TuiTextEditor = require('tui-text-editor') */ -const { promisify } = require('util') -const { spawn } = require('child_process') -const { orderBy } = require('natural-orderby') -const fs = require('fs') -const open = require('open') -const path = require('path') -const url = require('url') -const readFile = promisify(fs.readFile) -const writeFile = promisify(fs.writeFile) - const input = {} const keyBindings = [ @@ -186,7 +169,7 @@ telc.isRight = input.isRight telc.isSelect = input.isSelect telc.isBackspace = input.isBackspace -class AppElement extends FocusElement { +export default class AppElement extends FocusElement { constructor(backend, config = {}) { super() @@ -269,7 +252,7 @@ class AppElement extends FocusElement { this.queueTimeLabel = new Label('') this.queuePane.addChild(this.queueTimeLabel) - this.queueListingElement.on('select', item => this.updateQueueLengthLabel()) + this.queueListingElement.on('select', _item => this.updateQueueLengthLabel()) this.queueListingElement.on('open', item => this.openSpecialOrThroughSystem(item)) this.queueListingElement.on('queue', item => this.play(item)) this.queueListingElement.on('remove', item => this.unqueue(item)) @@ -441,7 +424,7 @@ class AppElement extends FocusElement { this.autoDJControl = new ToggleControl('Enable Auto-DJ?', { setValue: val => (this.enableAutoDJ = val), - getValue: val => this.enableAutoDJ, + getValue: () => this.enableAutoDJ, getEnabled: () => this.config.canControlPlayback }) @@ -1374,9 +1357,9 @@ class AppElement extends FocusElement { } showMenuForItemElement(el, listing) { - const { editMode } = this + // const { editMode } = this const { canControlQueue, canProcessMetadata } = this.config - const anyMarked = editMode && this.markGrouplike.items.length > 0 + // const anyMarked = editMode && this.markGrouplike.items.length > 0 const generatePageForItem = item => { const emitControls = play => () => { @@ -1387,7 +1370,7 @@ class AppElement extends FocusElement { }) } - const hasNotesFile = !!getCorrespondingFileForItem(item, '.txt') + // const hasNotesFile = !!getCorrespondingFileForItem(item, '.txt') const timestampsItem = this.hasTimestampsFile(item) && (this.timestampsExpanded(item, listing) ? {label: 'Collapse saved timestamps', action: () => this.collapseTimestamps(item, listing)} : {label: 'Expand saved timestamps', action: () => this.expandTimestamps(item, listing)} @@ -1431,13 +1414,12 @@ class AppElement extends FocusElement { // to move the "mark"/"paste" (etc) code into separate functions, // instead of just defining their behavior inside the listing event // handlers. - /* - editMode && {label: isMarked ? 'Unmark' : 'Mark', action: () => el.emit('mark')}, - anyMarked && {label: 'Paste (above)', action: () => el.emit('paste', {where: 'above'})}, - anyMarked && {label: 'Paste (below)', action: () => el.emit('paste', {where: 'below'})}, + + // editMode && {label: isMarked ? 'Unmark' : 'Mark', action: () => el.emit('mark')}, + // anyMarked && {label: 'Paste (above)', action: () => el.emit('paste', {where: 'above'})}, + // anyMarked && {label: 'Paste (below)', action: () => el.emit('paste', {where: 'below'})}, // anyMarked && !this.isReal && {label: 'Paste', action: () => this.emit('paste')}, // No "above" or "elow" in the label because the "fake" item/row will be replaced (it'll disappear, since there'll be an item in the group) - {divider: true}, - */ + // {divider: true}, canControlQueue && isPlayable(item) && {element: this.whereControl}, canControlQueue && isGroup(item) && {element: this.orderControl}, @@ -1450,10 +1432,8 @@ class AppElement extends FocusElement { canProcessMetadata && isTrack(item) && {label: 'Process metadata', action: () => setTimeout(() => this.processMetadata(item, true))}, isOpenable(item) && item.url.endsWith('.json') && {label: 'Open (JSON Playlist)', action: () => this.openSpecialOrThroughSystem(item)}, isOpenable(item) && {label: 'Open (System)', action: () => this.openThroughSystem(item)}, - /* - !hasNotesFile && isPlayable(item) && {label: 'Create notes file', action: () => this.editNotesFile(item, true)}, - hasNotesFile && isPlayable(item) && {label: 'Edit notes file', action: () => this.editNotesFile(item, true)}, - */ + // !hasNotesFile && isPlayable(item) && {label: 'Create notes file', action: () => this.editNotesFile(item, true)}, + // hasNotesFile && isPlayable(item) && {label: 'Edit notes file', action: () => this.editNotesFile(item, true)}, canControlQueue && isPlayable(item) && {label: 'Remove from queue', action: () => this.unqueue(item)}, isTrack(item) && isQueued && {label: 'Reveal in queue', action: () => this.revealInQueue(item)}, {divider: true}, @@ -1475,7 +1455,7 @@ class AppElement extends FocusElement { ].filter(Boolean) // TODO: Implement this! :P - const isMarked = false + // const isMarked = false this.showContextMenu({ x: el.absLeft, @@ -2250,7 +2230,7 @@ class AppElement extends FocusElement { } get selectedQueuePlayer() { return this.getDep('selectedQueuePlayer') } - set selectedQueuePlayer(v) { return this.setDep('selectedQueuePlayer', v) } + set selectedQueuePlayer(v) { this.setDep('selectedQueuePlayer', v) } } class GrouplikeListingElement extends Form { @@ -2745,6 +2725,7 @@ class GrouplikeListingElement extends Form { // Just to make the selected-track-info bar fill right away (if it wasn't // already filled by a previous this.curIndex set). + /* eslint-disable-next-line no-self-assign */ form.curIndex = form.curIndex this.fixAllLayout() @@ -2916,7 +2897,6 @@ class GrouplikeListingForm extends ListScrollForm { set curIndex(newIndex) { this.setDep('curIndex', newIndex) this.emit('select', this.inputs[this.curIndex]) - return newIndex } get curIndex() { @@ -3007,7 +2987,6 @@ class GrouplikeListingForm extends ListScrollForm { } dragLeftRange(item) { - const { items } = this.app.markGrouplike if (this.selectMode === 'select') { if (!this.oldMarkedItems.includes(item)) { this.app.unmarkItem(item) @@ -3331,8 +3310,8 @@ class InlineListPickerElement extends FocusElement { this.showContextMenu({ x: this.absLeft + ansi.measureColumns(this.labelText) + 1, y: this.absTop + 1, - items: this.options.map(({ value, label }, index) => ({ - label: label, + items: this.options.map(({ label }, index) => ({ + label, action: () => { this.curIndex = index }, @@ -3378,7 +3357,7 @@ class InlineListPickerElement extends FocusElement { } get curIndex() { return this.getDep('curIndex') } - set curIndex(v) { return this.setDep('curIndex', v) } + set curIndex(v) { this.setDep('curIndex', v) } } // Quite hacky, but ATM I can't think of any way to neatly tie getDep/setDep @@ -3860,7 +3839,7 @@ class InteractiveGrouplikeItemElement extends BasicGrouplikeItemElement { } else if (!this.isPlayable) { writable.write('F') } else if (record.downloading) { - writable.write(braille[Math.floor(Date.now() / 250) % 6]) + writable.write(brailleChar) } else if (this.app.SQP.playingTrack === this.item) { writable.write('\u25B6') } else if (this.app.hasTimestampsFile(this.item)) { @@ -3905,7 +3884,6 @@ class TimestampGrouplikeItemElement extends BasicGrouplikeItemElement { || last.timestampEnd !== Infinity && last.timestampEnd || last.timestamp) const strings = getTimeStringsFromSec(data.timestamp, duration) - const stringsEnd = getTimeStringsFromSec(data.timestampEnd, duration) this.text = ( /* @@ -4319,7 +4297,6 @@ class PlaybackInfoElement extends FocusElement { this.app.backend.queuePlayers.length > 1 && { label: 'Delete', action: () => { - const { parent } = this this.app.removeQueuePlayer(this.queuePlayer) } } @@ -4414,17 +4391,17 @@ class PlaybackInfoElement extends FocusElement { } get curSecTotal() { return this.getDep('curSecTotal') } - set curSecTotal(v) { return this.setDep('curSecTotal', v) } + set curSecTotal(v) { this.setDep('curSecTotal', v) } get lenSecTotal() { return this.getDep('lenSecTotal') } - set lenSecTotal(v) { return this.setDep('lenSecTotal', v) } + set lenSecTotal(v) { this.setDep('lenSecTotal', v) } get volume() { return this.getDep('volume') } - set volume(v) { return this.setDep('volume', v) } + set volume(v) { this.setDep('volume', v) } get isLooping() { return this.getDep('isLooping') } - set isLooping(v) { return this.setDep('isLooping', v) } + set isLooping(v) { this.setDep('isLooping', v) } get isPaused() { return this.getDep('isPaused') } - set isPaused(v) { return this.setDep('isPaused', v) } + set isPaused(v) { this.setDep('isPaused', v) } get currentTrack() { return this.getDep('currentTrack') } - set currentTrack(v) { return this.setDep('currentTrack', v) } + set currentTrack(v) { this.setDep('currentTrack', v) } } class OpenPlaylistDialog extends Dialog { @@ -5259,9 +5236,9 @@ class Menubar extends ListScrollForm { } get color() { return this.getDep('color') } - set color(v) { return this.setDep('color', v) } + set color(v) { this.setDep('color', v) } get attribute() { return this.getDep('attribute') } - set attribute(v) { return this.setDep('attribute', v) } + set attribute(v) { this.setDep('attribute', v) } } class PartyBanner extends DisplayElement { @@ -5396,5 +5373,3 @@ class NotesTextEditor extends TuiTextEditor { } } */ - -module.exports = AppElement -- cgit 1.3.0-6-gf8a5