Skip to content

ryostore: rework the Apps catalogue as a marketplace - #634

Closed
dodo986 wants to merge 101 commits into
Ryoku-dev:mainfrom
dodo986:feat/ryostore-apps-marketplace
Closed

dodo986 wants to merge 101 commits into
Ryoku-dev:mainfrom
dodo986:feat/ryostore-apps-marketplace

Conversation

@dodo986

@dodo986 dodo986 commented Oct 28, 2026

Copy link
Copy Markdown
Member

What changed

Apps already shipped; this is a design rework of how its catalogue is presented, not a new category.

  • The Apps page no longer uses the oversized artwork cards. It opens with a featured shelf, a Trending / Popular / New / Updated strip, and compact icon and text tiles, two to four per row.
  • The strip is backed by real data. The Flathub provider used to fetch only the popular collection, so any other ordering would have been cosmetic. It now merges popular, trending, recently added and recently updated into one cached snapshot and passes the trending score, monthly installs and update date through item metadata.
  • One browse grid serves Apps and every other category. The hero and strip sit above it and the grid switches to compact tiles when Apps or a Flathub search is in scope. The earlier shape mounted a second grid behind the Apps page, which built artwork delegates for every app while hidden.
  • Search keeps Flathub's relevance order. A partial fetch still serves the collections that answered and leaves the complete cache in place.
  • Every other category, the detail page and install logic are unchanged.

Area

ryoku

How it was tested

  • go test ./... in ryostore/backend: collection merge, partial failure keeping the cache, ranking metadata.
  • node --test quickshell/lib/store.test.mjs: all four sorts, name tiebreak, featured picks and rotation, source left unmutated.
  • tests/ui/ryostore-apps-probe.sh: routes to Apps, checks hero, strip and compact grid, asserts the default Trending order, picks Popular, checks the reorder and selection, opens the detail with Enter, Esc restores sort and selection.
  • tests/ui/ryostore-flow-probe.sh: install, detail, search and context restoration still pass.
  • Ran against live Flathub data at 1180x760 and at a narrow width.
  • qmllint is clean on the new components. App.qml trips this Qt build's legacy syntax verifier on unstable-dev as well, so that is not a regression.

Checklist

  • One logical change, with a clear [area] scope: summary commit subject.
  • Matching CHANGELOG.md updated in the area I touched.
  • The git hooks pass locally; I did not use --no-verify.
  • Lua parses (luac -p), shell scripts pass bash -n, and QML passes qmllint where applicable.
  • No duplicated config, no dead code, no commented-out code, no em-dash.
  • Docs updated if behavior or layout changed.

github-actions Bot and others added 30 commits October 26, 2026 03:01
Orpheus, Shima and most visualizers paused whenever playback detection missed a stream.

Note: Fixed: Music-reactive bars and visualizers always react in Performance mode.
With Easy Effects or another filter sink, the analyser heard only the silent default output.

Note: Fixed: Orpheus, Shima and visualizers react to music played through Easy Effects.
niri parses proportion and window/layer-rule opacity as float scalars and
rejects an integer literal, failing the whole config. kdlNum printed a stored
1 as "1", so a default column width of 1 produced
"default-column-width { proportion 1; }" and an invalid settings.kdl.
Format those values with kdlFloat, as the spring damping-ratio already is.

Change-Id: I17aaffdae2fa9fbce56b047e7938e8e1b8172984
Update now always ran plain `ryoku update --gui`, so taking the distribution
packages meant a terminal and `ryoku update --system`. Add an INCLUDE SYSTEM
switch beside Update now, saved as `update_system` in the Hub config and off
by default. When on, Update now runs `ryoku update --gui --system`.

Note: New: Update now can include the system packages with one switch in Updates.
Ryostore had no way to install ordinary applications. A new flatpak
provider lists the 300 most popular Flathub desktop applications from the
Flathub collection API, joined with `flatpak list` so an installed
application outside that ranking stays listed and removable.

Flathub is a third-party source that does not pass through the ryostore
registry or its screening, so each item carries Flathub's own verified or
unverified state and a link to its Flathub page, and the category
description says the store does not review it.

Install adds the user flathub remote when missing and installs into the
user installation, so no privileged prompt is needed. Installing an
application that is already installed updates it in the installation that
holds it, which is what the UPDATE button runs. Remove targets whichever
installation holds the application, keeps its data, and for the user
installation also uninstalls the runtimes nothing uses any more. Update
state comes from `flatpak remote-ls --updates` per installation, best
effort and bounded.

`ryostore search <category> <query>` is new: a provider whose source is
larger than its catalogue implements it, and flatpak searches all of
Flathub live. A search started from the Apps category asks it after a
short debounce, so an application outside the ranking is found. The
ranking is cached on disk and served flagged offline when Flathub is
unreachable; icons load lazily like the Omarchy marketplace's media.

Note: New: Ryostore has an Apps section for installing, updating and removing Flathub applications, with search across all of Flathub.
deviceOfType returned the first NetworkManager device of a type in
GetAllDevices order. On a machine with two ethernet ports, an unplugged
onboard port listed ahead of the connected one made the network topic
report wired as Disconnected, and the bar showed the offline icon.
Setting the idle port unmanaged does not help, since GetAllDevices still
returns it. A second Wi-Fi adapter hit the same path for the status frame
and the scan, connect and disconnect intents.

deviceOfType now ranks every device of the type: Connected, then
Connecting, then disconnected but usable, keeping service order on a tie,
so a single-device machine is unchanged.

Note: Fixed: the bar shows your wired or Wi-Fi connection on machines with more than one network adapter
…ortions

[ryoku] niri: write whole proportions and opacities as floats
[ryoku] shell daemon: report the live network device
[ryoku] ryostore: add an Apps category for Flathub applications
Reject option-shaped ids, keep unrelated runtimes, and install only through

a verified Flathub remote, preferring the system one the doctor sets up.

Note: New: RyoStore lists Flathub apps in a new Apps category.
…ystem

[ryoku] hub: add an include-system switch to Update now
Keep Update now available independently of the Ryoku update count.
Open the correct RyoStore sections and offer installation for missing bundle parts.
Refresh stale catalogue snapshots so new bundles appear on first open.

Note: Fixed: Updates, add-on installation and new bundles work from the Hub.
Voice apps adjust input gain while typing, and every bar treated it as input.
Only deliberate mic level edits now raise the popup; mute keys still show.
Keep speaker controls visible regardless of which client changed them.
Note: Fixed: Microphone gain no longer interrupts typing with popups.
The wallpaper preview only painted the background, leaving the shell on its old palette.
Share the cached candidate palette with shell surfaces in a session-only file.
Cancel restores committed colours; apply keeps the normal theme update.
Note: Fixed: The shell follows the wallpaper being previewed without changing application themes.
The Controls overview grew beyond the panel on shorter displays.
Keep its header fixed and let the content scroll to the bottom.

Note: Fixed: All Controls options remain reachable on smaller screens.
A separate bottom-layer window could sit behind the wallpaper after re-add.
Paint the plain look in the desktop and keep audio capture independent
of the optional overlay window.

Note: Fixed: Removed visualizers show again when added back.
The spectrum painter was clipped to a rectangle while Shima drew a rounded card.
Loud peaks could show beyond its lower corners, especially at small sizes.
Follow the card radius in the painter without reducing normal playback levels.

Note: Fixed: Shima's visualizer bars stay inside the widget card.
The smooth ring containers fell behind the password pill when the clock
stopped positioning every number as a direct child of the clock scene.
Restore the old depth order without changing ring motion or the 12-hour setting.

Note: Fixed: Orbital's dial and numbers cross the password pill again.
An imported shell setting hid the desktop editor's own placement settings.
Restore the right setting, resolve apps and let folder renaming take focus.
Translate the desktop menu in every language and fix Spanish notifications.
Note: Fixed: Apps and folders work on the desktop, with a readable Spanish menu.
neur0map and others added 28 commits October 27, 2026 16:34
Closing the sidebar destroyed its whole controls tree 48 ms after the
exit animation, so every Super+Escape rebuilt meters, connections,
levels, the plugin host and two layer surfaces (15 to 150 ms on the GUI
thread) and reran plugin discovery. The tree now stays loaded for 15 s
after closing with its probes stopped, and discovery reruns only when
the plugin files change.

Note: Fixed: Super+Escape opens and closes without the stutter of rebuilding the controls each time
Island backgrounds resolved their ends through Repeater.itemAt() before
the delegates existed and never retried until the app list changed, so a
restarted shell drew a transparent dock until an app opened or closed.
An auto-hidden dock also sat on the bottom layer, where any open window
covered its edge strip and swallowed the reveal hover.

Note: Fixed: The dock shows its background right after the shell restarts
Note: Fixed: An auto-hiding dock reveals on edge hover even with windows open
The window and music previews used one 300 ms close grace for both the
trip from the icon into the preview and the exit afterwards, and the
preview is a separate surface, so a normal-speed crossing of the gap
closed it before its own hover took over. The first arrival now gets a
longer grace; once reached, the preview closes as promptly as before.

Note: Fixed: Hover previews on bar and dock icons stay open while you move the pointer into them
The music-sink fix handed cava the bare sink name, which cava cannot
open, so the visualizers fell silent whenever music played; 1.0.5 read
only the default sink, which stays silent when apps play to another
sink such as Easy Effects. Both feeds now open the sink's monitor and
Line follows the same sink. Fixed sensitivity, a hard noise gate and
gain that skipped Aura meant quiet playback barely moved the looks; the
feeds now normalise with autosens and the gain drives every look.

Note: Fixed: Visualizers react to desktop audio again, including audio routed through Easy Effects
Note: Fixed: Every visualizer look reacts at normal listening volume and follows the gain setting
Visualizer instances were addressed by list position: new ones returned
their index, the active pointer was an index, and the Stage grips,
outlines and labels keyed on "visualizer:" + index. Adding or removing
one renumbered the rest, so selection, settings and drags landed on the
wrong instance and one could hide another. Each instance now carries a
persisted id, the active pointer names that id, and existing configs
are migrated on load.

Note: Fixed: Adding a third visualizer no longer replaces the first; each keeps its own place, settings and selection
Follow-up to the send-to-phone action: drop the stray lines that broke
Icon.qml and ShortcutSheet.qml, keep the capture in a private 0700
runtime dir with a 0600 file instead of a predictable /tmp name, pass
the path and device to kdeconnect-cli as plain arguments, clean up on
every path, probe devices only when the toolbar opens, let the user pick
a device when several are paired, and list kdeconnect as an optional
dependency.

Note: New: Send an annotated screenshot to a paired phone with KDE Connect from the ryoshot toolbar (Ctrl+K), contributed by Ronin-CK
Materialize copies each packaged Quickshell config into ~/.config one
file at a time, and every instance kept Quickshell's file watching on,
so a change landing while shell.qml was briefly absent reloaded a half
laid tree and left "File not found" on screen. Configs running from
~/.config/quickshell no longer hot reload from that churn; ryoku reload
and source-path runs still reload as before.

Note: Fixed: Updates no longer leave a "Failed to load configuration" error on the desktop or in Ryoku Settings
The desktop's folder dialogs and app picker went through the Stage's own
translator, which read a private catalogue directory Ryoku never ships,
so they stayed in English in every language. It now forwards to the
shared Ryoku catalogue. The desktop menu also gains New application,
which reuses the installed-app picker and shortcut store, and desktop
icons can open on a single or a double click.

Note: Fixed: Desktop folder menus and dialogs follow the system language
Note: New: Right-click the desktop and pick New application to place an app icon there, opening on one or two clicks
Completes the Global page switch from Ryoku-dev#619, which only hid the Hub rail
glosses. The preference is now a typed daemon setting, read live by a
shared Ryoku.Ui singleton, so the kana beside setting cards, Marginalia,
page watermarks, the 力 brand mark, workspace numerals and decorative
text in the shell, Hub, Ryogami, RyoStore and RyoVM all follow it, and
the generated Fastfetch config drops the kanji from its greeting.
Default stays on, so the existing look is unchanged.

Note: New: A Japanese glosses switch in Ryoku Settings > Global hides the Japanese characters across the desktop and in the terminal greeting
An image notification grows when its thumbnail finishes loading. The
card eased that growth like an expand, and the popup list kept its first
delegate measurement, so the layer often stayed at the pre-image height
and cut the toast off under its title. Non-user height changes now snap
to the measured height, the surface sizes from the card's target height
and relays out when a delegate grows; expand and collapse still ease.

Note: Fixed: Notifications with an image show their full text and buttons instead of being cut off under the title
The Python bar kept its own Do Not Disturb and sound keys and played its
own file with pw-play, so its controls and Ryoku Settings disagreed and
the sound skipped Ryoku's volume, critical cue and suppress-sound
policy. Its visualizers also ignored the main colour and gain. The
controls now drive Flags.dnd and the shell's sound settings, cues go
through ryoku-shell sound, sound state is read from the shell's Config
service, and the visualizers follow the active colour and gain.

Note: Fixed: Notification style, sound and visualizer settings take effect in the Python bar style
niri repeats a bind while its key is held, so a press that lasted a
little too long on the mic-mute key muted and unmuted the microphone
(or the speaker mute and play keys flipped back). Toggle media keys now
emit repeat=false, matching Hyprland and Wayfire.

Note: Fixed: On niri, holding the mic-mute, mute or play key no longer flips it back
Arch's xdg-desktop-portal-hyprland 1.4.1 drops its frame callback during
DMA-BUF renegotiation, so hardware-encoded shares die within a second,
and Start then waits forever on an invalid PipeWire node until the
portal is restarted. The -git package needs the -git Hyprland stack.
[ryoku] now builds upstream 167adef (both fixes) against the stable
libraries as 1.4.1.r10.g167adef, which sorts above Arch's build and
gives way once Arch ships a newer release.

[ryoku] sits after the official and CachyOS repos, so a same-named
package resolves from them on a fresh install. The ISO installer (online
and offline closure) and the script installer now align every installed
package that [ryoku] serves at a newer version, the same rule ryoku
update already applies to existing boxes.

Note: Fixed: Screen sharing from Discord, Vesktop and browsers on Hyprland no longer drops right after it starts or stops working until the portal restarts
The alignment test exec'd pacman's vercmp, which CI runners do not have,
and the install guard flagged the two in-chroot pacman queries for
lacking --noconfirm. The comparator is now a seam the test replaces, and
both queries pass --noconfirm.
The SDDM host never received the clock format, so a skin that defaults
to 24-hour (the stock Orbital one) showed 17:00 at the sign-in screen
whatever the user picked, and skins that read the clock from their own
config missed it in the session lock too. The installed greeter config
now records the choice, the host hands it and the locale to every skin,
and the session lock exposes it the same way. The sign-in screen picks
up a change when the skin is applied or Ryoku updates, so toggling the
format never asks for a password.

Note: Fixed: The lock and sign-in screen clocks follow the 12-hour or 24-hour setting in every language
The launcher's Audio Visualizer action ran the overlay mode, which puts
the visualizer on its own layer above windows and the dock, so a bar
style visualizer started from the launcher covered the dock icons. It
now starts the ordinary desktop visualizer; the overlay keeps its own
explicitly named shortcut.

Note: Fixed: The visualizer started from the launcher stays behind apps and the dock
Shima paints its dock body into a full-output chassis on the Top layer,
and the icon surfaces of the Shima and Python docks sat on the same
layer, so whichever loaded last won: after a restart, a relogin or a
dock switch the icons often hid behind the body, which looked like an
empty or unsaved dock. Both now sit above the chassis. The Python dock
also read its pinned app from roles the delegate never received, so a
click under the Shima bar launched nothing; it now uses the bound entry
and the shared launcher.

Note: Fixed: With the Shima bar, the Shima and Python docks keep their icons visible after a relogin and the icons open their apps
Any selected desktop icon held the desktop layer's exclusive keyboard
grab, and creating a folder or an app shortcut leaves the new icon
selected, so after the flow no window got keys (and on Hyprland, where
that grab also takes the pointer, no clicks either): the desktop looked
frozen. The folder dialog also lost its field's focus to the layer, and
on niri a bottom-layer exclusive request is ignored, so with a window
focused the typed name went into that window. Dialogs now lift the
desktop above windows for exactly as long as they need keys; a
selection takes the keyboard only while the pointer is over the icons,
Enter releases it before launching, and the app picker returns focus
when it closes.

Note: Fixed: Creating a desktop folder or app shortcut no longer leaves the desktop unresponsive, and the name field takes typing
New application, Open folder and Shima's Sleep stayed English in
Spanish: the first is new, the other two only ever held an English
value, and the translation workflow cannot run while its provider is
out of credit. They are now human overrides, and the catalogue is
re-extracted with the overrides applied, so they show in Spanish; the
remaining new strings keep English until the workflow runs again.

Note: Fixed: The desktop New application and Open folder entries and Shima's Sleep option appear in Spanish
Shima's clock control set the global 12/24-hour preference but also kept
its own copy, so a box could carry both: Shima's bar showed the old
12-hour choice while the lock followed the global 24-hour one. The
control now writes only the global preference, and a leftover Shima
copy is migrated into it once and removed.

Note: Fixed: With the Shima bar, the lock screen clock uses the same 12-hour or 24-hour format as the bar
The Apps catalogue drew the same oversized artwork cards as every other
category, so a page held a handful of apps and their icons read as
thumbnails. Apps now opens with a featured shelf, a Trending, Popular, New
and Updated strip, and compact icon and text tiles that fit several apps per
row; every other category keeps the artwork grid.

The strip needed data the provider never fetched, so the Flathub provider
now merges the popular, trending, recently added and recently updated
collections into one cached snapshot and passes the trending score, monthly
installs and update date through item metadata. A partial fetch still serves
the apps it got but does not replace the complete cache. Search keeps
Flathub's relevance order.

Note: New: the Apps catalogue is a marketplace page with sort tabs and compact tiles
Apps had its own page with a second ProductGrid, so the cover grid stayed
alive behind it and built a full set of artwork delegates for every app.
The hero and the sort strip now sit above the one grid, which switches to
compact tiles when Apps or the Flathub search is in scope, so the page
component, the surface alias and the overlay wrapper are gone.

Also drops the favourites count the provider fetched but nothing showed,
and folds the hero's three metadata labels into one chip component.
@dodo986 dodo986 closed this Oct 28, 2026
@dodo986

dodo986 commented Oct 28, 2026

Copy link
Copy Markdown
Member Author

wrong branch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants