Skip to content

unified warning panel for all screens - #6587

Draft
mahibi wants to merge 8 commits into
masterfrom
maintenaceModeWarnings
Draft

unified warning panel for all screens#6587
mahibi wants to merge 8 commits into
masterfrom
maintenaceModeWarnings

Conversation

@mahibi

@mahibi mahibi commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Warnings like the maintenance mode should be shown on all screens* as a warning panel without duplicated code.

*= all compose screens. Old XML screens should migrate to compose to make use of the new warning panel.

🖼️ Screenshots

🏚️ Before 🏡 After
B A

🚧 TODO

  • ...

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not needed
  • 🔖 Capability is checked 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

mahibi added 8 commits August 26, 2026 16:59
Detects HTTP 503 responses carrying the X-Nextcloud-Maintenance-Mode
header during chat message polling and surfaces a red banner in the
message input area, mirroring the "Connection lost" banner and the
maintenance-mode banner already shown in the conversation list.

Assisted-by: Claude Code:claude-sonnet-5

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
getRoomsFromServer() caught and only logged exceptions from the
background room-list sync, so GetRoomsErrorState was never produced
by the current getRooms() path (roomListFlow only observes the local
database, not the network call). This made handleHttpExceptions
unreachable, silently breaking the unauthorized/outdated-client
dialogs and the maintenance-mode banner.

Adds a getRoomsErrorFlow that the repository emits into instead of
swallowing the exception, collected by the view model into the
existing GetRoomsErrorState.

Assisted-by: Claude Code:claude-sonnet-5

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
…in a shared interceptor

Chat and conversation list each had their own bespoke detection of
server maintenance mode (HTTP 503 + X-Nextcloud-Maintenance-Mode
header), each only covering their own network call. Replaces both
with a single OkHttpClient interceptor that sees every request for
every screen and account, and publishes status changes (maintenance
mode, unauthorized, client-update-required) via EventBus for any
screen to react to — mirroring how the iOS app's
NCAPISessionManager.checkStatusCode works.

Assisted-by: Claude Code:claude-sonnet-5

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
…t observing late

HttpStatusInterceptor only posts a ServerStatusEvent on a status
transition, so a screen that starts observing after the transition
already happened never learns the current status. In practice, the
conversation list is usually first to detect maintenance mode; by the
time a chat is opened, no new transition occurs since the account is
already flagged, so the chat banner never appeared even though the
server was still in maintenance mode.

Adds HttpStatusInterceptor.currentStatus(accountId) so ChatActivity
and ConversationsListActivity can seed their state as soon as the
account is known, in addition to reacting to future transitions.

Assisted-by: Claude Code:claude-sonnet-5

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
…seActivity

Centralizes maintenance-mode/offline detection into BaseActivity
(account resolution, EventBus subscription, HttpStatusInterceptor
seeding) instead of each screen wiring its own state, and adds the
shared StatusBannerRow (moved to components/, self-padding for the
status bar only when visible) to the conversation list plus the 12
other screens that are fully written in Compose.

ChatActivity keeps its existing XML-based banner untouched, since it
mixes XML and Compose rather than being fully Compose.

Assisted-by: Claude Code:claude-sonnet-5

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
…ntWithStatusBanner

Each fully-Compose screen repeated the same isOnline/isMaintenanceMode
state collection and Column-wrapping to show the shared status banner.
Adds BaseActivity.setContentWithStatusBanner(content), a drop-in
replacement for setContent that collects the state once and renders
StatusBannerRow above content, and switches all 12 screens to use it
instead of duplicating the wiring.

ConversationsListActivity is unchanged: its banner is embedded inside
its own Scaffold's topBar alongside the conversation list's top bar,
not the generic "wrap everything" shape the helper assumes.

Assisted-by: Claude Code:claude-sonnet-5

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
ConversationListTopBar always applied statusBarsPadding regardless of
whether StatusBannerRow above it was already visible and self-padding
for the status bar, producing a visible gap between the banner and the
search/top bar. Only pad the top bar when the banner is hidden.

Assisted-by: Claude Code:claude-sonnet-5

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Several screens apply their own statusBarsPadding()/Scaffold inset
(ThreadsOverviewActivity, DiagnosisActivity, LogsActivity,
ConversationCreationActivity, ContactsScreen, LocationPickerScreen)
assuming they sit at the true top of the window. Once
StatusBannerRow is visible it already claims that inset for itself,
so those screens' own padding added a second, redundant gap on top
of it (e.g. an oversized app bar in "new conversation").

setContentWithStatusBanner now marks the status-bar inset consumed
for content() whenever the banner is showing, so screens' existing
statusBarsPadding() calls add nothing extra in that case. Fixed once
centrally since some of the affected composables (ContactsScreen,
LocationPickerScreen) have no access to the banner state to guard
against it themselves.

Assisted-by: Claude Code:claude-sonnet-5

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
@mahibi mahibi self-assigned this Aug 26, 2026
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.

1 participant