Skip to content

Xnt 111 drop pin freshness check - #17652

Closed
xeniacloud wants to merge 21 commits into
nextcloud:masterfrom
Krateos-BV:xnt-111-drop-pin-freshness-check
Closed

xeniacloud wants to merge 21 commits into
nextcloud:masterfrom
Krateos-BV:xnt-111-drop-pin-freshness-check

Conversation

@xeniacloud

Copy link
Copy Markdown

🖼️ Screenshots

🏚️ Before 🏡 After
B A

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not needed
  • 🔙 Backport requests are created or not needed: /backport to stable-xx.x
  • 📅 Milestone is set
  • 🌸 PR title is meaningful (if it should be in the changelog: is it meaningful to users?)

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI (N/A)

Vasilis Giannakopoulos and others added 21 commits September 7, 2026 11:38
Add XeniaCloud unsigned CI build workflow
Adapts the canonical Xenia navy gradient (nextcloud#1233/nextcloud#2266/nextcloud#3399) used
by the Desktop/Notes rebrands (XNT-44/45/46/34) in place of Nextcloud's
blue (#0082C9/#1CAFFF/#007cc2), applied to:
- adaptive icon foreground: the "files" glyph is the literal trademarked
  Nextcloud cloud logo (SPDX LicenseRef-NextcloudTrademarks) - replaced
  with the Xenia cloud glyph (from nextcloud-desktop's
  "Xenia Desktop-icon.svg", inkscape:label="files"), not just recolored
- adaptive icon background gradient
- legacy pre-API26 launcher PNGs (mdpi-xxxhdpi) + ic_launcher-web(-round).png,
  regenerated from the same shared-geometry SVG as the VectorDrawable so
  the raster and vector assets can't diverge
- splash screen logo (nextcloud_splash_logo.xml) - same glyph, rescaled
- splash screen background + primary/primary_dark/color_accent colors
  (setup.xml) - single-color picks from the 3-stop gradient, same
  convention as XNT-34's defaultBrand
- app_name (setup.xml) - this app has no app_name_long; app_name IS the
  launcher-visible string (AndroidManifest already references it via
  @string/app_name, no hardcoded label to change)

Deliberately NOT changed:
- applicationId / no resValue app_name pattern exists in build.gradle.kts
  to touch - changing applicationId would break account_type/authority
  provider identifiers elsewhere in setup.xml and has no precedent in the
  sibling notes-android/notes-ios rebrands
- qa/versionDev flavor icon overrides (separate source sets, not part of
  the CI-verified assembleGenericDebug build path)
- deeper "Nextcloud" strings (ecosystem app names, server product name,
  placeholders, interop URL schemes) - out of scope for this surface-level
  rebrand per the ticket

REUSE.toml: carved the touched main-flavor PNG paths out of the blanket
Nextcloud-trademark annotation into a new XeniaCloud-attributed block
(qa/versionDev stay covered by the original block, untouched). `reuse
lint` passes clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JCBWnbTpV5Cksc3s7ZLX1M
…ovider/account identifiers

Set applicationId to eu.xeniacloud.files (generic/gplay/huawei), plus
eu.xeniacloud.files.beta / .qa for the versionDev and qa flavors, so
Xenia Files installs alongside the upstream Nextcloud Files app.

applicationId alone is not sufficient for coexistence. The account type
and the five content-provider authorities are independent string
resources in setup.xml, not derived from applicationId. Left unchanged,
they would still collide with the upstream app: duplicate provider
authorities fail installation outright, and a duplicate accountType
breaks the account authenticator between differently-signed apps.
Renamed them following the same pattern upstream already uses to keep
its own qa/versionDev flavors installable side by side.

The manifest, authenticator.xml and syncadapter_files.xml reference all
of these via @string, so they follow automatically; no hardcoded
authority literals remain in code.

Deliberately unchanged:
- Java package com.nextcloud.client (1861 package/import decls) and
  org.nextcloud.providers.cursors -- source packages, unrelated to
  applicationId; the module namespace is com.owncloud.android.
- db_file/db_name/data_folder -- scoped to the app sandbox, cannot
  collide across packages.
- Store URLs in setup.xml, README/docs -- point at upstream listings;
  Xenia has no distribution channel yet.
- Deck/ecosystem package queries -- outbound refs to third-party apps.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GCJHcfUt8oBjcbG8cdKNSz
Follow-ups flagged in review of the xenia-rebrand branch.

Store/download links: the three strings are referenced from
SettingsActivity (Recommend share) and CommunityFragment (RC section),
so they cannot be deleted without breaking the build. Blanked instead,
and disabled the Recommend preference entirely (recommend_enabled=false)
so the share text does not render with empty URLs. Community RC buttons
become inert -- DisplayUtils.startLinkIntent no-ops on an empty string.

No Play Store listing or signed release exists yet, so pointing these at
xeniacloud.eu or an empty GitHub releases page was rejected in favour of
no link at all.

Root folder display name: main, versionDev and qa flavours all carried
the upstream name; all three updated.

README: dropped the Play Store / F-Droid / Obtainium download badges
pointing at com.nextcloud.client.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AHW2vejxtCEXHnzJ92tNSX
XNT-54: remove upstream store links and rebrand root folder display name
The workflow was pinned to the now-deleted xenia-rebrand branch, so no
CI build path existed. Trigger on push to master and on pull requests
targeting master instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UwrZnx9ZWDGKvVCkoz5J2n
The drawer's Talk and Notes tiles, and the file-list "open in Notes" button,
went through android-common's EcosystemManager, whose EcosystemApp enum
hardcodes com.nextcloud.talk2 and it.niedermann.owncloud.notes. All three
controls tried to launch upstream's clients, which a XeniaCloud user does not
have installed, so none of them did anything useful.

EcosystemApp is a plain enum with no string-resource seam, and neither it nor
openApp is open to subclass, so there is nothing to override. The sending half
of the logic is reimplemented app-side as XeniaEcosystemManager against a
XeniaEcosystemApp enum pointed at eu.xeniacloud.notes and eu.xeniacloud.talk.

Only the sending half. receiveAccount delegates to the library untouched: that
path carries no package names and no branding, it only reads the account name
out of an incoming intent. Keeping the delegate is also why
FileDisplayActivity's call site needed no change - only the field's type
changed, in its superclass.

The wire contract is deliberately unchanged. The intent action is still
com.nextcloud.intent.OPEN_ECOSYSTEM_APP and the extra key is still KEY_ACCOUNT,
matching the intent-filter already in this app's manifest. Both are opaque
identifiers the three apps have to agree on rather than branding, and renaming
either would force a synchronised three-app release for no user benefit.

A missing app no longer redirects to the Play Store, because XeniaCloud has no
store listings and that redirect would land the user on a "not found" page.
They get a snackbar instead. For the same reason the More tile is hidden rather
than pointed at a Play Store search - upstream searched it for publisher
"Nextcloud", so left alone it advertised upstream's apps from inside this one.

The three snackbar strings are defined app-side rather than reused from the
library, whose not-installed string reads "App not installed. Redirecting to
store…" and no longer describes what happens.

Assisted-by: ClaudeCode:claude-opus-5
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mfu9zFrWdUXig9E2SDMVD6
Export worked but showed the user nothing. exportFiles only queued
FilesExportWork, and the sole success signal was a notification on
NOTIFICATION_CHANNEL_DOWNLOAD, which is IMPORTANCE_LOW - no heads-up, no sound.
Nothing on screen changed, and the file lands in Download/, which the app never
navigates to, so a successful export was indistinguishable from a no-op.

exportFiles already took a Context and a View it never used. Those are now the
hook: it observes the export job and shows a snackbar when it finishes.

The counts come from the worker rather than being assumed. FilesExportWork
returns them in its Result, JobInfo carries a generic output map through from
WorkInfo, and the snackbar picks the same three plurals the summary
notification uses, so the two can never disagree - including the partial
failure case, where the worker still reports Result.success. The snackbar
offers the same "locate folder" action the notification does.

The job outlives the screen that started it. The observer is scoped to the host
activity, so the fragment's view can be detached by the time it fires and
Snackbar.make would fail to find a parent; that case is skipped and the
notification remains the only report, as before.

This is a deliberate divergence from upstream nextcloud/android, which has the
same silent behaviour.

Assisted-by: ClaudeCode:claude-opus-5
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mfu9zFrWdUXig9E2SDMVD6
XNT-91: open the Xenia companion apps, not upstream's
Five gaps from XNT-85, four of which turned out to have a different cause
than the ticket assumed.

Onboarding, account setup and deep-link login all drew @drawable/logo, which
was still the Nextcloud mark under LicenseRef-NextcloudTrademarks. Replaced
with the Xenia cloud, taken from ic_launcher_foreground.xml so the launcher
icon and every in-app logo are the one mark. Its 900x450 frame is kept, so
those three screens keep their footprint. This is also the likeliest answer to
the "app icon shows the Nextcloud icon somewhere" report: the launcher icon was
already correct, and the account-setup screen is the surface a user meets right
after it.

The User-Agent keeps its Nextcloud-android token. name_for_branded_user_agent
is not a replacement hook - MainApp.getUserAgent formats
"Nextcloud-android/%1$s%2$s" with version and branded name, so the branded name
can only ever be a suffix. The token is load-bearing: nextcloud/server matches
it with IRequest::USER_AGENT_CLIENT_ANDROID, which apps/dav Auth.php uses to
skip CSRF checks for official clients, and the regex allows a trailing suffix.
So the brand is appended rather than substituted.

The server URL is fixed via webview_login_url with show_server_url_input off,
upstream's own hook for a single-tenant branded client. Login now goes straight
to the Login Flow v2 WebView against portal.xeniacloud.eu and the host field is
gone, so no manual entry on first launch.

The drawer header showed the brand name twice because both halves come from the
server, not from the layout: updateHeader loads capability.getServerLogo, and
setDrawerHeaderLogo then drew capability.getServerName beside it. Upstream
assumes a themed instance supplies an icon-only mark that the name completes,
but XeniaCloud's theming logo is a full wordmark. The name is no longer drawn,
and its TextView is removed rather than left unreachable. The fallback used
when an instance supplies no theming logo was nextcloud_logo.xml, upstream's
wordmark; it becomes xenia_logo.xml.

The ecosystem tiles are relabelled Xenia Talk and Xenia Notes. XNT-91 pointed
them at eu.xeniacloud.talk and eu.xeniacloud.notes, which left them opening the
Xenia apps under upstream's names. ecosystem_apps_notes also feeds the
file-list header, "This folder is best viewed in ...".

Only values/strings.xml is touched; the values-* translations are left to the
translation pipeline.

Out of scope and untouched: the upstream project links in setup.xml
(privacy_url, license_url, help_link, sourcecode_url, translation_link,
contributing_link, dev_changelog), which are GPL-fork attribution.

Assisted-by: ClaudeCode:claude-opus-5
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mfu9zFrWdUXig9E2SDMVD6
XNT-85: close the remaining Xenia Files rebrand gaps
Onboarding offered two calls to action below "Log in" that both sent a
Xenia Files user to Nextcloud. "Sign up with provider" started
AuthenticatorActivity with EXTRA_USE_PROVIDER_AS_WEBLOGIN, and that branch
is evaluated before the webview_login_url branch, so it bypassed the
single-tenant login hook entirely and loaded provider_registration_server,
www.nextcloud.com/register. "Host your own server" opened
url_server_install, nextcloud.com/install.

The obvious fix does not work. Both buttons are gated on
MDMConfig.showIntro(), which reads show_provider_or_own_installation, but
that flag has four other call sites: OnboardingServiceImpl gates
launchFirstRunIfNeeded on it, so turning it off would stop FirstRunActivity
launching at all and make the onboarding screens dead code. It also decides
whether "add account" goes through onboarding (DrawerActivity,
UserListAdapter) and how the button area is sized.

So the two calls to action get their own flag,
show_onboarding_provider_options, defaulting to upstream's behaviour and
set to false here. showIntro and the onboarding flow are untouched.

Verified on a Pixel 8 emulator: onboarding still launches on first run and
still shows all four pages in portrait and landscape, both buttons are
gone, the button area lays out correctly with "Log in" alone, and "Log in"
still starts the login flow against portal.xeniacloud.eu.

Once both buttons are hidden, provider_registration_server and
url_server_install are unreachable from any surviving code path. Whether to
rebrand or delete those two strings is left as a separate decision.

Assisted-by: ClaudeCode:claude-opus-5
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
XNT-110: drop provider signup and self-hosting calls to action from onboarding
setDrawerHeaderLogo stopped drawing capability.getServerName() next to the
logo, which left createSVGLogoTarget taking an OCCapability it never reads.
SpotBugs flagged it as UP_UNUSED_PARAMETER and the fork's warning count went
373 to 374; removing the parameter and its now-unused import puts it back to
373. Verified locally by running spotbugsGplayDebug on the commit before
XNT-85, on master, and on this branch.

The caller still uses the capability for getServerBackground and
getServerLogo, so only the parameter goes.

Assisted-by: ClaudeCode:claude-opus-5
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
detectWrongSettings requires the pinned androidLibraryVersion to be within
the last 10 commits of nextcloud/android-library master. Ours had fallen to
position 13, so the check failed on every pull request. Nothing in our diffs
caused it; upstream's library repo simply moved.

Bumping the pin also needs its artifacts recorded in the dependency
verification metadata. Only the two android-library artifacts are added, by
hand. Running gradle's --write-verification-metadata generator instead wanted
to add 390 components across kotlin, bouncycastle, protobuf and others, which
is local resolution noise rather than anything this bump requires - the build
verifies with just these two.

Verified locally: assembleGenericDebug builds, detectWrongSettings.sh exits 0,
and the app installs and runs on a Pixel 8 emulator - onboarding renders and
the login flow reaches the portal.xeniacloud.eu grant page with no
NoSuchMethodError or NoClassDefFoundError in logcat, which is the risk when
the library moves 12 commits including a Kotlin bump.

Note this is a treadmill: the pin will fall out of the 10-commit window again
as soon as upstream pushes 10 more commits. A fork-appropriate fix for
detectWrongSettings is the durable answer.

Assisted-by: ClaudeCode:claude-opus-5
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Drop the capability parameter left unused by XNT-85
XNT-111: refresh the android-library pin to 8cbaa7e8
fix(export): confirm a finished export on screen
detectWrongSettings.sh asserted that the pinned androidLibraryVersion
appeared in the last 10 commits of nextcloud/android-library master.
That window measures upstream's commit cadence, not any property of
this repo, so the job turned red on unrelated PRs whenever upstream
merged 10 commits. The SNAPSHOT and is_beta assertions are unchanged.

Removing the check also drops the job's only external network call.

Refs: XNT-111
Assisted-by: ClaudeCode:claude-opus-5
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YEsWSCebAEpW3pMUkzmFVA
Signed-off-by: xeniacloud <infra@xeniacloud.eu>
@xeniacloud xeniacloud closed this Sep 15, 2026
@xeniacloud
xeniacloud deleted the xnt-111-drop-pin-freshness-check branch September 15, 2026 19:33
@xeniacloud
xeniacloud restored the xnt-111-drop-pin-freshness-check branch September 15, 2026 19:36
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.

2 participants