Commits at 0839a4abb10a3f192fa092eb51a92b06a31a16bf
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
4570e084macos: Disconnect menu items
In GTK-Adwaita, it's easy thanks to "gsettings" CLI application. In
macOS, however, there seems to no way to clear an application's
"@AppStorage" data.
Shota FUJI
authored at
Shota FUJI
comitted at
cf516079macos: Accept Xcode project settings recommendation
It has been showing a warning and it was annoying.
Shota FUJI
authored at
Shota FUJI
comitted at
1dd7aab4macos: Change non-modified variable to immutable
Addressed a Xcode warning.
Shota FUJI
authored at
Shota FUJI
comitted at
afb2d6b4macos: Merge server discovery and main window
The former is (most of the case) shown once.
The reason I changed the payload of ".found" case is, without that, the
only reference will be "ConnectedView" and every updates to the View
would release then re-create a connection.
Shota FUJI
authored at
Shota FUJI
comitted at
d53ccec3macos: Save connected server ID and reconnect on launch
The current UX is not complete, as there is no way to disconnect.
Considering the usecase of connecting to more than one Roon server is
rare, the discovery window should be integrated into the main window.
Then it can conditionally render server discovery or connected view
without going to discovery view first.
Shota FUJI
authored at
Shota FUJI
comitted at
37c16ed0core: Allow clients to set custom extension ID/name/version
It has been pain to manage authorization tokens in Roon settings page.
Shota FUJI
authored at
Shota FUJI
comitted at
dfc4cec0macos: Display loading UI during extension authorization
It has been unclear what it's doing and what a user should do.
Shota FUJI
authored at
Shota FUJI
comitted at