mirror of
https://github.com/status-im/status-app.git
synced 2026-08-27 15:11:20 +00:00
754276d8533f879c03cdeee7964b8de276cae69f
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
68eb973c84 |
perf(chat): lazy, async member loading for user list and mention suggstions (#21920)
* perf(chat): lazy, async member loading for user list and mention suggestions The members panel builds on first show only (latched), asynchronously behind MembersListSkeleton — it must never delay a chat switch. Once built, UserListPanel binds its users model only while the right panel is actually visible, and it adopts the shared MembersPanelHeader introduced with the skeletons. The mention suggestions adaptor stays detached from the members model until the first mention entry (short wire delay, loading skeleton in the suggestion box meanwhile; the latch drops on usersModel swap so chat switches never pay for sorting the members model). Together these were ~1.5s of the chat-switch freeze on large communities. * fixup! perf(chat): lazy, async member loading for user list and mention suggestions The members panel is shared across the section's chats, so once built it stayed visible through a chat switch: it showed the previous chat's members while sorting the incoming model on the switch frame. A latch drops it back behind MembersListSkeleton on every active-chat change and re-arms on a short delay, the same shape as the mention suggestions wiring. rightPanelReady now follows the loader it was named after. * fixup! perf(chat): lazy, async member loading for user list and mention suggestions Keying the latch on the active chat id dropped it on every switch, but a community channel without permissions hands the view the *same* members model object — so the panel was torn down and fully re-sorted for nothing, on the dominant path. Key it on the model identity instead: same object, same members, no work; different object, the protection the latch is for. rightPanelReady must fold the latch in, or the chrome retires its members skeleton exactly while the panel is showing one. membersWireDelay moves into `d` (tests reach it through the view's private object), and the panel's own skeleton is released like the others rather than kept alive and hidden. The switch test now targets the permissioned channel, whose model really differs, and a new test pins that the shared-model switch costs nothing. * fixup! perf(chat): lazy, async member loading for user list and mention suggestions Extract the fully-wired CommunityChatLoader test harness (mock stack, loader wiring, type-prefix finders) into a shared helpers component. The members-skeleton suite is the first consumer; the community section suite above adopts it at the next stack rebase, removing ~90 duplicated lines per suite. * chore: update translations * perf: sorted users_model and PR comments * perf: Avoid swapping skeleton for the real view when swipeview animations are running * chore: update translations * chore: update translations |
||
|
|
4483d7eb2d |
fix(ios): pause/resume services with the app lifecycle and re-point media URLs on rebind (#21687)
* fix(media): re-point cached media URLs when the media server restarts (#47) iOS suspends the app and kills status-go's local media server; on resume it rebinds on a NEW ephemeral port and emits mediaserver.started, which the Nim side never handled — every cached https://localhost:<oldport>/ image URL (chat images, avatars, stickers, link previews, community icons) went permanently stale. Key decisions: - New MediaServerStartedSignal decoded in signals_manager (the enum member already existed, so the cheap-triage scan needs no change); null-event envelopes decode to port 0 and every rewrite helper treats port <= 0 as a no-op. - One shared helper, withMediaServerPort (app_service/common/ media_server_url.nim): rewrites the port ONLY for http(s):// localhost|127.0.0.1|0.0.0.0:<port> URLs, splicing around the authority so path/query stay byte-identical; everything else (remote URLs, data URIs, qrc/file paths, port-less URLs) passes through untouched, so callers apply it blindly. Desktop stays a no-op: the signal never fires there, and an unchanged port rewrites nothing. - Subscribers rewrite in place + notify: message models (chat + pinned) re-emit image-carrying roles via dataChanged; link-preview thumbnails are QObjects and emit urlChanged directly; section model refreshes community image/banner/icon; contacts service rewrites its ContactDetails cache and re-emits SIGNAL_CONTACT_UPDATED per changed contact, plus the user-profile singleton's own avatar (its setters already no-op on equal values). - Dropped the contacts service's imageServerUrl field: it was write-only dead code (fetched once, never read). Files: src/app/core/signals/{signals_manager,types}.nim, src/app/core/signals/remote_signals/mediaserver.nim (new), src/app_service/common/media_server_url.nim (new), src/app_service/service/contacts/service.nim, src/app_service/service/message/dto/{link_preview,link_preview_thumbnail}.nim, src/app/modules/shared_models/{message_item,message_model,link_preview_model,section_model}.nim, chat_section chat_content + messages + main module/controller/io_interface wiring, test/nim/{media_server_url_test (new),message_model_test, signals_manager_test}.nim Verified: media_server_url_test 9/9 OK, signals_manager_test 6/6 OK (incl. 2 new mediaserver.started tests) via make nim-test-run USE_SYSTEM_NIM=1. message_model_test does NOT link in this arm64 container — pre-existing nimqml/LTO link failure, reproduced identically on clean HEAD with a fresh nimcache; the 3 new model tests compile but need CI/another host to run. Device repro (background 10+ min, resume, images reload) remains for the human pass. * fix(build): normalize two 'import Nimqml' casings to the module's real name discord_message_item and message_transaction_parameters_item imported Nimqml (capital N) while the vendored module file is nimqml.nim. On a case-insensitive checkout (Docker-on-Mac bind mount) Nim treats the two spellings as distinct modules whose nimcache artifacts collide on one file, so any test pulling in these items (e.g. message_model_test) fails to link with undefined nimqml symbols. Found while verifying #47. * refactor(media): deduplicate the media-URL refresh template and drop dead code Review follow-up to ca5e5c92c, no behavior change: - Extract the thrice-duplicated compare-rewrite-flag template into refreshMediaServerUrl in media_server_url.nim; message_item, section_model and contacts/service now share one definition. - Drop the why-comment copy-pasted verbatim into three controllers; the explanation lives on MediaServerStartedSignal and the helper module. - Remove backend getImageServerURL, dead since its only caller (setImageServerUrl) was deleted on this branch. - Whitespace: trailing newline in signals/types.nim, blank line before the appended suite in message_model_test.nim. Verified: media_server_url_test, message_model_test and signals_manager_test all pass (nim-test-run recipe); app wiring compile-checked via app/modules/main/module + contacts service + section_model with --compileOnly. * fix(ios): drive PauseServices/ResumeServices from the app lifecycle (#51) On iOS status-go runs in-process and nothing drove the pausable-services lifecycle: services never paused on backgrounding (battery cost) and never resumed on foregrounding, so the media server's listening socket iOS kills during suspension stayed dead and every cached localhost media URL failed until app restart (device-confirmed: post-resume image loads get Connection refused while in-process RPC still works). Resuming now re-runs the full recovery chain: ResumeServices -> ServiceRegistry -> mediaserver ToForeground() rebind -> mediaserver.started -> #47/#49's URL refresh. Key decisions: - Lifecycle source is StatusQ's UrlSchemeEvent applicationStateChanged watcher (already the iOS foreground seam): new appBackgrounded signal emitted ONLY on Qt::ApplicationSuspended — Inactive dips from share sheets/system alerts never pause; appForegrounded fires on every return to Active, so ServicesPauseBridge latches (`paused`) and resumes only when it actually paused. Connections are synchronous (AutoConnection, same thread): iOS freezes the process right after the state change, a queued pause slot might never run. - Bridge wired only under `when defined(ios)`: Android's service process already drives pause/resume from binder visibility (UI process must not double-drive), desktop is never suspended. - Same contract as StatusGoService.java: fetch the service list from PausableServices() at each transition (late-registered services picked up; empty list — node not running, e.g. login screen — drives nothing), then PauseServices/ResumeServices with the JSON name array. The three libstatus C exports are bound in new backend/pausable_services.nim (vendor/nim-status-go doesn't cover them); errors logged, not fatal. - Backend calls injected into the bridge as a seam (PausableServicesCalls), so the Nim test drives the real StatusQ signal emitters against recorders. Files: src/app/core/services_pause_bridge.nim (new), src/backend/pausable_services.nim (new), src/nim_status_client.nim, src/statusq_bridge.nim, ui/StatusQ/{include/StatusQ/urlschemeevent.h, src/{urlschemeevent,externc}.cpp}, Makefile (test target), test/nim/services_pause_bridge_test.nim (new) Verified: services_pause_bridge_test 15/15 OK; full tests-nim-linux 464 OK / 0 failed (chat_section_model_test fails to compile identically on the clean base — pre-existing, unrelated); nim_status_client Linux path compile-checked (--compileOnly, exit 0); StatusQ recompiles clean; libstatus.so exports PausableServices/PauseServices/ResumeServices (linked by the test). Device criteria (iPhone: photo -> background 10+ min -> resume -> images recover; Android S21: exactly one service-driven pause/resume, no duplicates) remain for the human pass — iOS paths can't run in this container. * fix(tests): reset the fetch counter per case in services_pause_bridge unittest setup vars are module-scope globals; the int's constant initializer runs once, so fetches leaked across cases and the two absolute-count assertions saw the running total. * fix: Potential fix for pull request finding * fix(statusq): handle the full application-state enum in watchApplicationState Inactive is an expected transient dip and stays a no-op; anything else unhandled now logs a qWarning. * fix(tests): empty pausable set no longer latches paused, so foregrounding skips the fetch |
||
|
|
5487b67d71 |
fix(wallet): stable per-key nested token submodels
The 'tokens' role of token_groups_model and token_lists_model created a new TokensModel on every data() read, overwriting a single slot shared by all rows and consumers. Each read dropped the previously handed-out submodel while QML still referenced it, and the data source captured the row index, so a surviving submodel could read another row's tokens after rows shifted. Cache one submodel per group key and resolve the row by key on demand. The submodel follows its row's lifetime: reset when its content changes, deleted after the parent's remove/reset signals when its row is gone. |
||
|
|
716de1e2f5 |
test(bench): trim size sweeps to assert-relevant sizes on CI
The bench execution alone runs ~13 minutes on CI. BENCH_QUICK=1 (set by tests-nim-linux) keeps only the sizes the gates actually reference: benches whose asserts pin a size keep that size, benches with purely structural (size-independent) gates keep the smallest. Local runs keep the full sweeps. |
||
|
|
ba0eb3a223 |
test(bench): make wall-clock perf gates report-only on CI
Shared CI executors are too noisy for frame-budget and relative-timing assertions (e.g. open_seed maxStall 33.87ms vs the 32ms budget). Route them through perfAssert, downgraded to report-only when BENCH_ASSERTS=0 -- which tests-nim-linux now sets. Structural gates (resets, row churn, counts, instantiation errors) stay hard doAsserts, so the benches keep protecting against rot on CI. |
||
|
|
9a3d1c3a6c |
chore: organise nim test targets
- move the nim test targets to a dedicated nim-tests.mk file - split tests and benchmarks in two different targets, but keep the benchmarks as part of the nim-tests-run so that it doesn't rot over time - group tests/benchmarks that will need statusQ or QT_MODEL_SPY |