explorerUrl() hardcoded both the seed ("iris.radicle.network") and
the explorer base ("https://radicle.network"), so every "Copy Link"
and "Open in …" action ignored the user's config and could point at
a host that does not replicate the repo.
Expose publicExplorer and preferredSeeds on the Config type (both
already carried by radicle::profile::Config) and thread config
through to every explorerUrl() call site. URLs are now built from
the publicExplorer template, filling $host from the first preferred
seed (falling back to rosa only when none are configured), and link
labels show the configured explorer's host.
Co-authored-by: Rūdolfs Ošiņš <rudolfs@osins.org>
Exclude target/, node_modules/, releases/ and .git/ from the
build context. Dockerfile.release COPYs nothing, so podman was
tarring the entire 32G target/ dir into the build context,
exhausting the machine's temp disk with "no space left on
device".
rustup is packaged in Ubuntu noble (universe), so install it via
apt instead of piping the rustup-init script from sh.rustup.rs.
Removes one remote connection from the docker build.
add build-arg: RUST_VERSION=1.90
PatchTeaser requests diff_stats per row, and each call re-opened the
whole repo through libgit2-surf, so a list of patches serialized into
tens of seconds on a large repo. Shell out to `git diff --numstat`,
which opens and diffs in one fast pass, falling back to the surf diff
when git is unavailable.
repo_blob and repo_readme resolved the blob through radicle-surf, which
also walks history to find the last commit that touched the path.
libgit2 ignores the commit-graph and diffs every commit, so opening a
file last changed long ago took a long time and varied by how far back
the file changed, not by its size.
Resolve the content with a direct tree lookup and the last commit via
`git rev-list -1`, falling back to the libgit2 walk when git is
unavailable.
libgit2's revwalk ignores the pack bitmap and commit-graph, so counting
walks every commit. Shell out to `git rev-list --count --use-bitmap-index`,
which uses those indexes, and fall back to the revwalk if git is
missing, too old, or errors, so the result is unchanged, just faster on
maintained storage.
The file tree was the one list left un-virtualized, so wide directories
mounted every entry and re-rendered all rows on selection. Render
entries through VirtualList like the other lists.
Navigating away from a list and back via history (the sidebar
back/forward buttons) returns to the same scroll position with the
previously loaded pages intact, instead of refetching only the first
page at the top.
A reusable windowing wrapper that mounts virtua's Virtualizer against
the existing OverlayScrollbars viewport, so the app-wide custom
scrollbar is preserved.
list_issues previously read through heartwood's id-ordered issue cache,
forcing it to load and sort every issue in memory on each page. Mirror
the patch path instead: a domain/issue Service backed by an IssueStorage
adapter that queries the issues table directly.
The issues list shipped each issue's full root comment (body) over IPC,
but the teaser never renders it, only the detail view does. Make
Issue.body optional and add an Issue::summary constructor that skips it;
list_issues now builds summaries while issue_by_id keeps the full body.
The patches list paged through everything without scrolling: ScrollArea
fired its load-more check on every `updated` DOM event, and the list's
min-height made the bottom threshold always true, so each appended page
triggered the next. Move it to InfiniteScrollSentinel like the commits
list.
The settings footer showed "Up to date" whenever no new version was
known — including when the update checker was disabled or the version
fetch had silently failed. Derive an explicit upToDate state that is
only true when a check succeeded and found no newer version, so a
failed or disabled check no longer claims the app is current.
The version check fetched latest.json without any cache directive.
The server sends no Cache-Control header, so WebKit applied heuristic
caching (RFC 9111 4.2.2): the response is considered fresh for 10% of
the time since Last-Modified, which can be hours to days between
releases. Apps checking for updates right after a release were served
a stale latest.json from disk cache and concluded they were up to
date. Dev builds use a separate cache, which is why the bug only
appeared in release builds.
Fetch with cache: "no-store" so every check hits the server.
On Linux, Tauri derives the deb/rpm package name from productName with
no way to set them independently. We override productName to
radicle-desktop so the package is named correctly, which would otherwise
also force the launcher entry to read radicle-desktop.
Add a custom .desktop template that hardcodes Name=Radicle while keeping
the package name unchanged.
Make sure docker and podman are up and running as they're necessary for
the arch packaging and artifact building.
This also shows what commands would have been run when a phase fails.