49f88cc6macos: Support multi window browsing
This enables opening multiple zones in a dedicated windows at the same
time. I don't use multiple zones, though.
Shota FUJI
authored at
Shota FUJI
comitted at
825761acmacos: Workaround Xcode silently run the whole app in background
Shota FUJI
authored at
Shota FUJI
comitted at
cfc3edc0macos: Delete "Frameworks" directory
No longer used. It's empty.
Shota FUJI
authored at
Shota FUJI
comitted at
041b7f55macos: Fix suboptimal loading cancel experience
Resetting saved server connection (ID, host, port) and token is soooo
annoying. This also provides disconnection flow to error screen.
Shota FUJI
authored at
Shota FUJI
comitted at
4fa35277macos: Automatic reconnection
No retry over, but I think this is enough for this app.
Shota FUJI
authored at
Shota FUJI
comitted at
b9e19ee0macos: Select default hierarchy on visionOS
It displays as split view too. Tested on simulator.
Shota FUJI
authored at
Shota FUJI
comitted at
9881e13bmacos: Include OS name in extension name
I tested the app in various emulators but everything registered as
"Plac macOS" is sooooo confusing and unhelpful. Which should I delete?
Which one is of iOS simulator?
I should have renamed directory name ("macos") too, but it's rather big
task. I'm not gonna deal with it for the time being.
Shota FUJI
authored at
Shota FUJI
comitted at
15b90ff0macos: Remove redundant class property
The `address` is basically equivalent of the tuple in open state's
associated value. Noticed during reading of the code for state machine
redesign.
Shota FUJI
authored at
Shota FUJI
comitted at
0839a4abmacos: Group browse items by estimated item category
API does not return item kind. It does return "hint" property, but it's
useless for this purpose. For example, album items has "Play Album"
entry and song entries. Both "Play Album" and song entries have same
"action_list" hint thus they are (from program's perspective,) same.
This simple heuristic I wrote, at least for my usage, correctly group
items most of the time. I may tweak the logic in a future, but it's good
enough for now.
Shota FUJI
authored at
Shota FUJI
comitted at
7a551a5amacos: Fix junky title animation between navigations
iOS/iPad OS runs an animate when a navigation stack changes.
This is especially significant on iPad, which performs scale in addition
to translation. Previous to this patch, navigating to a page triggers
junky layout change (whole list moves upwards after 300ms or so.)
Shota FUJI
authored at
Shota FUJI
comitted at
44ff5579macos: Smoother browsing action
Previous experience was like,
1) Tap an action
2) Navigate to a new stack
3) Immediately navigate back to the previous stack
As most of the browse action do not lead to a new stack,
I added a dedicated logic to handle browse action.
Shota FUJI
authored at
Shota FUJI
comitted at
5e233c43macos: Browsing preview
Although action (server-side pop) behavior is strange, it's okay for now
as I'm going to tidy navigations up later.
Shota FUJI
authored at
Shota FUJI
comitted at
99342ff9macos: Refactor top-level files
Those files were obscure and one had to open the files in order to find
what's inside (view? helpers? models?)
Now, those are nicely organized so no need to open each files to figure
out the category of the file.
Shota FUJI
authored at
Shota FUJI
comitted at
b2454bafmacos: Seekbar
It's waaaaaaay better than GTK-Adwaita app, thanks to sane API design.
I mean, inclusion of events for start/end of edit.
Shota FUJI
authored at
Shota FUJI
comitted at
62d7639dmacos: Insert marker comments into large files
These service files defines Roon API types, therefore they tend to grow
larger and are difficult to decompose.
Shota FUJI
authored at
Shota FUJI
comitted at
dd6e1534macos: Reconfigure preview for PlaybackBar view
TIL "MARK:" comment support for Xcode.
Shota FUJI
authored at
Shota FUJI
comitted at
d8414c2emacos: Use protocols to untie IO from UI code
For testability.
Shota FUJI
authored at
Shota FUJI
comitted at
87a170f9macos: Implement core logic in Swift
Managing long-live object and handling IO in C API was mistake.
Every Zig/Swift nicities are eliminated at C API boundary. It must be
stupid make/free (or retain/release) function calls and they always have
to be heap allocoated using cAllocator. Everything has to be thread-safe
by using manual reference counting. Good practices in each languages are
no longer available due to C API barrier.
Although I had to duplicated Roon API handling logic, I believe this
work is worth the added code. IO and concurrent things are done in a
Swift-y way, avoiding small heap allocations are now easier (I guess
it's already less than the previous?), and most importantly, I have
deeper understandings of Swift and Apple frameworks than before.
UI layer code is way cleaner than the before. Especially watching
incoming message is very ergnomic--I can just iterate on `compactMap`-ed
async iterator, as you can see in "plac/DataModel/ZoneDataModel.swift".
As a bonus, every async task now handles cancellation (e.g. closing
window) perfectly.
In terms of performance, I don't think there is any regression.
Moreover, I feel this rewrite version performs better. Not profiled
(I've never profiled Plac macOS app...) but playback control actions are
instant without any UI stutter. Considering it now uses more high-level
API provided by Apple, this rewrite should improve stability and
portability.
Despite of these good things, there is one I'm not satisfied
with--message parsing (MOO / SOOD.) Swift does not have a good
reader/writer interface unlike Zig. The closest thing is SwiftNIO's
`ByteBuffer`, but I avoided it to keep dependence to third-party
libraries lower (the repository is in Apple org, though.) I've
considered using Zig code for that part or write a dedicated C module
using Wuffs but abandoned the ideas too, because of Xcode signing
gotchas (ugh.)
Speaking of Xcode signing, the app now works on iOS simulator. It
probably won't work on real device due to multicast entitlement, but
this is huge advancement. Some entry point tweaks are necessary, like UI
for entering IP/port of Roon server. Revising suspension and resume is
also necessary. Not ready to use, but this is great starting point.
Overall, I'm satisfied the result and enjoyed this whole learning process.
Shota FUJI
authored at
Shota FUJI
comitted at
92b7d54fcore: C API for getting image URL
SwiftUI has AsyncImage view, which takes a URL.
Shota FUJI
authored at
Shota FUJI
comitted at
4cafdb7fmacos: Use Environment for passing connection down
Future views such as artwork requires connection, but passing a
connection down to each view via initializer is tedious.
Shota FUJI
authored at
Shota FUJI
comitted at