perf(chats): make ChannelNewMessageViewModel.init idempotent across recompositions

Every channel composer screen (NIP-28 public chat, NIP-29 relay group, NIP-53
live activity, ephemeral and geohash chats) calls `init(accountViewModel)`
directly from its composable body, so it ran on the main thread on every
recomposition of that body — re-allocating UserSuggestionState,
EmojiSuggestionState and a fresh ChatFileUploadState each time. Besides the
wasted main-thread allocations, blindly re-initializing `uploadState` would
reset an in-progress upload.

Guard the setup so it only (re)runs when the account actually changes, matching
the pattern the sibling ConcordNewMessageViewModel already uses. Repeated calls
with the same account are now cheap no-ops, so leaving the call in the composable
body stays correct while dropping the per-recomposition work.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CDK63toGbE7DQxKxrQnhMU
This commit is contained in:
Claude
2026-07-18 01:25:52 +00:00
parent 9d8e07fbee
commit 7dcf2afa0f
@@ -213,6 +213,13 @@ open class ChannelNewMessageViewModel :
fun user(): User = account.userProfile()
open fun init(accountVM: AccountViewModel) {
// The channel screens call this straight from their composable body, so it runs on the main
// thread on every recomposition of that body. Guard against re-running the allocating setup
// (new UserSuggestionState/EmojiSuggestionState/ChatFileUploadState) when nothing changed:
// only (re)initialize when the account actually differs. Beyond the wasted allocations, a
// blind re-init would also reset `uploadState` mid-upload, discarding in-flight progress.
if (::accountViewModel.isInitialized && this.accountViewModel === accountVM) return
this.accountViewModel = accountVM
this.account = accountVM.account
this.canAddInvoice = hasLnAddress()