1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
|
TODO: A way to see the path of the currently selected item in any grouplike
element. Each item in the path should be a button that, when pressed,
makes the MAIN grouplike view navigate there.
(Done!)
TODO: A "shuffle queue" button!
TODO: A "clear queue" button.
(Done! Press S or C, or choose the option from the menubar.)
TODO: A way to jump to an item with a particular name. Probably press "/".
It'd be nice if the closest match got highlighted while you were typing.
(Done!)
TODO: "Queue to play next"... maybe also a cursor in the queue list, which
would tell after what track to place newly-queued items?
(Done!)
TODO: Scroll to the selected track once it starts playing when selected from
the queue.
TODO: process.on('SIGWINCH', () => ...) -- detect terminal resize!!
(Done!)
TODO: Pressing enter in the queue seems to not be doing the right thing?
It should NOT move the selected item anywhere in the queue; it should
just select and play that track.
(Done!)
TODO: iTunes downloader - test this.
TODO: Warn if no mkfifo (means controls won't work).
TODO: file:// support for crawl-local.
(Done!)
TODO: Pass YouTube playlist or http://.../playlist.json-like URLs to use them
as playlists (crawl automatically).
(Done!)
TODO: There's some weird glitch where, if downloaderArg is missing (=== ""),
it'll play.. something by Jake Chudnow?? -- Okay, looks like it's using
~/.mtui/downloads/<locallink, etc>/ as the directory for where it would
put the download file (because it's .../localink/ + encode(dlArg) and
dlArg is empty). The way the cache works is that it checks if there is
already a file in that directory, and there IS: a directory for another
track download! But the cache doesn't know this; it just thinks that
directory is the MP3 file (or whatever). So it returns it. MPV works fine
if you pass it a directory that contains music files, so in my case,
72_food (by Jake Chudnow) plays. (That's the first thing returned by
readdir, I suppose.)
(Done!)
TODO: Mouse support, obviously.
TODO: Ctrl-O'ing a playlist sets the left-pane's selected index to the second
item, for some reason. (Regardless of what you had selected before..)
TODO: "Open in new tab" in the Open prompt.
TODO: Inspect the inevitable memory issues that are absolutely 100% sure to
become a problem with opening playlists on the fly.
TODO: Cancelling the "enter a playlist source" dialog shouldn't also stop the
current song.
(Done!)
TODO: Move TabberElement to tui-lib, at some point.
TODO: Make PathElements selectable (again).
(Done!)
TODO: Make the tabber UI show handy information, like what tab you've got
selected, how many tabs there are, the usual (same way a browser tabber
works).
(Done!)
TODO: A "bookmarked playlists" list in the UI, so you can quickly load up
playlists you often use. (Let anything go here, like YT playlist URLs,
file paths, etc.)
TODO: Get rid of "WARNING: unable to extract uploader nickname", which comes
from youtube-dl.
(Done!)
TODO: Fix crashes related to the window resizing while a download is occurring
(i.e. the braille "download spinner" is showing). Very weird!
TODO: Investigate performance issues with very very long ListScrollForms.
(Done!)
TODO: At some point, putting mtui downloads in ~/.mtui - but preferrably with
a more humanish structure - would be quite nice..!
(Done! Yeeeeeeees!!!!!!!!)
TODO: Press "M" to show a context menu. (Done!)
TODO: Figure out a keybinding for Mark (in edit mode) - probably Ctrl-M.
(I prefer Ctrl to be used for functions that will open a dialog of some
sort, though..)
TODO: Only show scrollbars if the form is actually scrollable. (This would make
context menus look better.)
TODO: "Play" (now), in the context menu, should act like a queue-up-next, not a
queue-at-end. (Done!)
TODO: Make the queue code more sane.
(Done!)
TODO: Figure out when the "queue" context menu options should immediately play
the track. Currently, they don't ever initiate playing (besides the
"Play now" option).
(Done! Sorta. There are now just "play" and "queue" buttons. These use
the options chosen ("where" and "order"). Previously, combinations of
those made up menu options, e.g. "queue at end". Now they're separate
controls and the play/queue button you pick decides whether they play
right away or not.)
TODO: A "remove from queue" option for tracks and groups, which removes them
and their children from the queue.
(Done!)
TODO: After the end of a shuffled queue, the next song from the group of the
last track is played (and so on, until the group is empty). This seems
definitely wrong.
(Done! At the end of a shuffle queue, it just stops now.)
TODO: Show a preview of where "Jump to" will go while typing.
(Done!)
TODO: Cancelling "Jump to" should return the selected index to whatever it was
before.
(Done!)
TODO: Entering more than one key "at once" into a text input element will only
move the cursor right by one character, not by the length of the inputted
text. (This is an issue when pasting or spamming the keyboard.) Should be
fixed in tui-lib.
(Done!)
TODO: Pressing space while an "Up (to <group>)" button is selected both
activates the button and pauses music (because the app detects that the
space key is pressed). This is definitely wrong (it should do one or the
other - I'm not too sure which, yet, but probably the latter). (Done!)
TODO: If a track's file is a symlink, the "From:" label should show where it
links to.
TODO: The "Up (to <group>)" and "(This group has no items)" elements are not
quite buttons nor grouplike items. They should be more consistent with
actual grouplike items (i.e. same behavior and appearance), and should
be less buggy.
(Done!)
TODO: "Distribute" options in play/queue menu -- "don't distribute", "spread
(across queue?) evenly", "spread randomly".
(Done!)
TODO: Investigate how to make "distribute" options work better when the
currently-playing song is contained in the group to be distributed.
TODO: The "distribute" options shouldn't show up when you've only got a track
selected! But imagine you already had a "distribute" option selected when
you open up the menu on a track. Is there a way to not mutate the index
of the whereControl in that case (until the user changes the option)?
Like the DS home screen.
TODO: If you remove tracks from the queue that are above the currently selected
track of the queue, the selection index won't change -- so the actual
selected track will become something different. No good!
(Done!)
TODO: Arbitrary queue! I.e, you specify the downloadURL, then it queues that
item.
TODO: A "distribute children" option (with better wording)! Like manually
queueing each child group to be distributed evenly one by one, but
automatic.
More on that thought...I don't think I want to have "clumps" of like,
one of a song from EVERY album right at the start and the end, when we
do that. (Well maybe not the end, but definitely at the start.) If we
pretend there's "fake" items at the start of the group before we
distribute it, I think we'll get better results - that fake item will be
placed at the start, letting the rest of the group get distributed in
better order. (Of course, the fake item is just an offset in the math.
It isn't an actual item that will get added to the queue.)
TODO: Remove ALL children before queueing, THEN queue them - including any math
for distribution. Might give interesting results...or maybe it wouldn't
be any different. Worth investigating!
TODO: A "play later" option for songs in the queue, identical to distributing
randomly the single track; if the track is already playing, it should
skip to the next song before shuffling.
(Done!)
TODO: Loop one song!
(Done!)
TODO: Volume controls!
(Done!)
TODO: Metadata, in memory.
(Done!)
TODO: Load metadata from storage.
(Done!)
TODO: Restore metadata, if it's recognized as similar to an old path.
(Basically: How do we deal with moving files around? We'll also want some
sort of a manager to get rid of unused metadata, if wanted..... on the
one hand, it'll be saving precious kilobytes, but on the other, people
might not want to keep a record of moved or deleted tracks at all, so it
could actually be useful.)
TODO: Don't store duplicate metadata entries (prereq for tags, custom metadata,
etc) for the same track. Do it symlink-style -- map downloader arg to
actual key used for metadata (downloaded file path).
(Done!)
TODO: Metadata process status bar.
(Done!)
TODO: Add Vim arrow keys. Please forgive me.
(Done!)
TODO: Use some other key for toggling loop (besides L), so we can make full use
of HJKL arrow keys.
TODO: In the queue, remove the track number, if possible! Search if all tracks
(or a majority?? maybe later if it becomes a problem...) follow the same
track number format (i.e. start with a number), and if so, remove from
the displayed name. Otherwise, the number is probably just part of the
track's actual name and shouldn't be removed.
(Done!)
TODO: An indicator for the number of tracks in the queue!
(Done!)
TODO: "Reveal" option in queue listing context menu.
(Done!)
TODO: A menubar!
(Done!)
TODO: Make pressing the de-focus menubar key restore the selection even if you
selected the menubar by clicking on it.
TODO: Make the queue length element react to being very squished.
TODO: Don't close the menubar menus when an option is chosen!
Instead, reload that menu to reflect the changes. Handy so that you can
easily press a specific action (e.g. "play later") several times in
succession.
TODO: Color theme picker!! Make sure to save the choice in ~/.mtui, of course!
TODO: An "interweaved" option in the "order" picker - works like putting every
sub-group into a new queue, each time distributing evenly, then using
that as the group to queue according to the "where" picker.
TODO: A "reverse" option in the order picker! Also a "reverse order of groups"
or something, cuz why not yo.
(Done!)
TODO: The context menu crashes when the input spans across the screen! Need to
figure out some kind of "fix layout according to max dimensions" code in
general - it'd be useful here.
TODO: Work out frame rate shenanigans. :) This is a huge task, though (to get
it exactly right) - to begin, just make it so telnet and ordinary clients
get different framerates.
(Done!)
TODO: Remember the scroll position of each group. This should probably be done
per-listing, but make sure the data disappears when the listing is
destroyed (e.g. tab closed)! Have maps on the listings instead of the
grouplikes themselves.
(Done!)
TODO: Apparently shift-up/down selecting doesn't keep the selected item within
the scroll view. Fix that.
(Done!)
TODO: When you queue a song which is already before the current song / insert
index in the queue, it ends up being placed one index closer to the end
than intended. Fix this!
(Done!)
TODO: A "clear after this track" option. Maybe also a corresponding "clear
up to this track" option?
(Done!)
TODO: Maybe also a "pause after this track" option. Worth considering!
TODO: Pay closer attention to the ordering of queue items' context menu...
I like how it is right now for accessibility to specific menu items
(play sooner/later immediately under the start position, remove from
queue one "above" the start pos = at the bottom) -- but it might make
more logical sense to group 'play sooner', 'play next', and 'remove
from queue' all into one section.
TODO: Figure out duplicates in the selection system! Right now, it's possible
to have both a group and its children selected at the same time, which
actually treats them as separate items in the selection grouplike.
This /might/ be good for performing an action on a group as well as its
children, but that seems like a rare case (only relevant to labelling as
far as I can imagine), and it doesn't seem super intuitive UI-wise right
now.
Maybe we could make it so if you have a grouplike selected, then browse
within it to see its children (or subchildren, etc), those child items
would be highlighted, but only dimly? The idea is that no highlight = not
selected; dim highlight = a parent is selected and so actions like
queuing will apply to this item; full highlight = this item itself is
selected, so actions that only apply to individual items, like labelling,
will apply. It's not entirely obvious what this means, but I think it
more or less makes sense.
BTW: we'll need a new function, removeDuplicates, for said actions. One
of those "actions" is actually called just by opening the context menu --
the tally numbers showing the total tracks selected and the sum duration
of all of those tracks. Make sure to call removeDuplicates after
flattenGrouplike. (I considered putting that new behavior of rD into fG,
but it doesn't seem worth it - better to keep them separate and let us
explicitly decide when we do or don't want to consider duplicates.)
TODO: Default to 'after selected track' in context menu, and make pressing Q
(the shorthand for queuing the selection) act as though that's the
selected option, instead of queuing at the end of the queue (which is
really only useful when you're building a queue at the start, assuming
you don't start by shuffling your entire queue anyway).
(Done!)
TODO: When grouplike listings are fixLayout'd (e.g. the window is resized),
make sure the selected input is still visible!
(Done!)
TODO: If you press any key which should select a particular element of the UI
(e.g. the menubar) while a context menu is open, currently the context
menu will close and then restore selection to the element which was
selected when the menu was opened. This seems to happen after the target
element is selected; the effect is that any key which is meant to focus
specific UI parts instead closes the context menu while one is open.
We already have a key for doing just that (the cancel key, i.e. esc or
period), so fix this!
(Done!)
TODO: g/G should work for navigation in context menus! And probably all
ListScrollForms, tbh, but I'm kinda weary of introducing new behavior
like that to tui-lib.
(Done!)
TODO: PageUp/PageDown support is complicated to implement (I've tried) and
should come eventually, but for now just make Home/End work as aliases
for g/G. ~~This means making it possible for the keybinding system to let
a single input function return true for multiple different keys!~~
Actually, we already had that part implemented. :P
(Done!)
TODO: Work out the BIGGER framerate shenanigans. Specifically: down with the
render interval! Or, more literally, get rid of it altogether. Only
render when we know the on-screen text is going to have changed.
(Done - Huzzah! We use 0% CPU when not actively updating the screen now.)
TODO: Be more sneaky about how we decide what text to update on the screen,
in a way which saves us performance. Instead of going through the whole
ansi.interpret process, predict which regions of the screen are going to
have updated, and only process those spaces. We can guess reasonably by
looking at which elements caused the screen to update (keep track of this
in the Root, through the shouldRenderTo function).
TODO: Create a basic Element class, which DisplayElement extends. We have a lot
of code related to scheduling displaying stuff on the screen, and it'd be
nice to keep it more separate from all the basic element logic.
(Done!)
TODO: toString functions for elements! Handy for debugging.
TODO: Revealing a track shouldn't forcibly position it at the bottom of the
screen (in grouplike listings that span more than a screen). Don't scroll
if the item is already visible, and if it's above the current scroll
area, make it appear at the top of the listing view instead of the
bottom.
(Done!)
TODO: Text file support. Yes. Heck yes. Heck hecking yes.
Read text files contained in your music library folders. If there is a
file which has the same basename as a track (or group), show a mark on
the item in grouplike listings, and let it be viewed through an action
on the context menu. Maybe, just MAYBE, implement editing support too.
(Done!!! Still some WIP stuff in the text editor library, but this is
definitely functional as of now.)
TODO: Make 'after selected song' the default in the context menu, too. I miight
go back on this decision, but I think it's just more convenient in
general, and if you prefer 'after current song', that option isn't hard
to discover and select.
(Done!)
TODO: Investigate why reveal() has distinct support for grouplikes as well as
tracks - you can't append actual groups to the queue (only their
flattened children) after all. But if you could -- I think reveal should
work the same for groups as it does for tracks, i.e. opening the parent
and then selecting the item.
TODO: Make the menubar work like context menus for keyboard selection, e.g.
pressing P should select 'Playback' (not bubble to the app element and
rewind to the previous track).
(Done!)
TODO: Implement a UI in the playback info pane that shows when multiple players
exist at once. Make sure it's mouse-interactive, too!
(Done! Will probably be tweaked / expanded in the future.)
TODO: Add a menu for controlling the multiple-players code through the menubar.
(Done! Oh gosh this was such a hack.)
TODO: Investigate menubar UX - now that it uses KeyboardSelector, it's very
comparable in interaction to ContextMenus. To match context menus,
should we make its selection index reset to zero (i.e. the 'mtui' option)
whenever it's selected (via the keyboard)?
(Done! Decided yes.)
TODO: When a telnet client disconnects, the music stops. This shouldn't happen!
TODO: Creating a new music player should base its details (volume, looping
status) on the player which was selected when it was created.
TODO: Show the number of new entries in the "process (new entries)" label.
Probably don't show that menu option if there aren't any new entries.
(Also change it to "new tracks" instead of "new entries"?)
TODO: A "play (in new player)" option in the play menu. It'd be nice to have
this in the queue's context menu, too.
TODO: "Shuffle queue", "shuffle these tracks" options in the queue's
context menu?
TODO: It looks like you can't move the currently playing track by re-queuing
it? Investigate this.
TODO: Fix mtui crashing when you interact with it before the main listing has
loaded its contents.
TODO: Specific config permissions to view and edit text files.
TODO: I lied when I said I finished text editor stuff. Still to-do:
Don't show text files which are adjacent (same filename, but .txt) to
a playable. Instead, show a mark on the listing item. Have a context menu
option for focusing the text editor.
TODO: Have a context menu option for creating a text file for notes on a
playable, when there is no existing adjacent file.
(Done!)
TODO: Delete notes files which are totally empty (or just a single line break).
TODO: Only count *consistently* formatted text, across all tracks in a group,
as track numbering. See '19 3 In The Morning (Pianokind)' for example -
it is the only track in the group which is formatted '## # <text>'.
It does follow the formatting '## <text>' as all other tracks do, so only
the first digits, and following whitespace, should be removed.
TODO: Related to the above - always keep at least one word. See CANSLP's new
release "untitled folder", with tracks named "01 1", "02 2", etc.
TODO: Update to work with IPC server mpv (and socat).
(Done!)
TODO: Look into testing ^that on Windows. Remove mkfifo, since it's probably
no longer necessary!
TODO: Expand selection context menu by pressing the heading button! It should
show a list of the tracks contained within the selection. Selecting any
item should reveal that item in the main listing pane.
TODO: Opening the selection contxt menu should show an option to either add or
remove the cursor-focused item from the selection - this would make
selection accessible when a keyboard or the shift key is inaccessible.
TODO: Integrate the rest of the stuff that handles argv into parseOptions.
TODO: Figure out looping not always working consistently. I've tried to deal
with this before, but it's been broken since switching to socat. Maybe we
aren't receiving time data as consistently, or aren't re-applying loop
when we're supposed to?
TODO: Show how many tracks remain in a queue player's queue, ala "+1" floated
to the right, behind the playback position/duration indicator.
(Done!)
TODO: "Lock scroll to cursor" option in queue listing. Will make the listing
automatically scroll so that the selected element is at the same visual
Y-position - even when the cursor is moved *not* by the user, e.g. the
enxt track playing while the current track is selected. This will allow
the user to reveal a certain number of tracks ahead/behind the current
track according to their liking. (Keep in mind ends of the listing, where
the scroll can't be adjusted to match because that would mean scrolling
past the ends... maybe put a dim background behind the element currently
occupying the locked position, scrolling such that the selected element
is at that position whenever doing so doesn't go out of bounds?)
(Done! This was less work than expected. Dim background not implemented
because (1) it's more work and (2) I don't want to overcomplicate the
user interface.)
TODO: Revisit labels and notes features! They're commented out for now :P
TODO: Pressing "Reveal" should focus the main listing. This is prrrrobably a
case of context menu selection-restoring being a pain.
(Done!)
TODO: When a track besides the currently playing one is selected in the queue
listing, display the time either *until the track starts* or *since the
track ended* appropriately, ala "+03:45" or "-1:32:17", in the queue
time label (which is positioned at the bottom of the queue listing).
(Done!)
TODO: In that regard, also change the queue length label (just above the time
label) to indicate which track is selected --- RELATIVE to the current
track, ala "40 (+5) / 1032" or "5 (-1) / 10".
(Done!)
TODO: Deselecting a grouplike listing (e.g. by clicking elsewhere) should hide
its "jump to" element.
TODO: A "before selected item" option for in the queue menu!
TODO: The sorting for library3/C418 seems to be weird???? Could be pointing to
some bug!
TODO: Selecting a group from the path listing at the bottom of listings should
make it so the child of that group matching with the path is selected.
For example: selecting X in W/X/Y/Z would open the directory X and
select item Y; selecting Z would open the directory Z and select the
track (or group) which the path element is active on in the first place.
TODO: UI to change the directory from which mtui reads music by default!
TODO: file/folder browse-select UI 0_0
|