Remove the old `var message by mutableStateOf(TextFieldValue(""))` properties
from all ViewModels, making `TextFieldState` the single source of truth.
Key changes:
- Add TextFieldState extension functions (updateText, insertUrlAtCursor,
replaceCurrentWord, currentWord) to TextFieldValueExtensions.kt
- Update PreviewState to accept String instead of TextFieldValue
- Add TextFieldState overload to UserSuggestionState.replaceCurrentWord
- Remove forwardZapToEditting and updateZapForwardTo from IZapField interface
- Migrate all 8 ViewModels: EditPostViewModel, ShortNotePostViewModel,
ChatNewMessageViewModel, NewPublicMessageViewModel, CommentPostViewModel,
LongFormPostViewModel, NewProductViewModel, ChannelNewMessageViewModel
- Update all Screen composables that referenced removed properties
https://claude.ai/code/session_01VminH5nD1jbzncbgTaqXEK
2. ShortNotePostViewModel.kt — Added messageState/forwardZapToEdittingState fields and removed stale override keywords to match updated IMessageField/IZapField interfaces
3. ChatNewMessageViewModel.kt — Same pattern: added messageState, forwardZapToEdittingState, toUsersState, subjectState fields and removed stale override keywords
Migrate from the old BasicTextField (TextFieldValue/onValueChange) to the new
BasicTextField (TextFieldState) which properly sets EditorInfo.contentMimeTypes
when contentReceiver modifier is present, enabling GIF keyboard support.
Core changes:
- ThinPaddingTextField: uses new BasicTextField with TextFieldState,
OutputTransformation, TextFieldDecorator, TextFieldLineLimits
- UrlUserTagTransformation: converted from VisualTransformation to
OutputTransformation using TextFieldBuffer.addStyle/replace
- IMessageField: simplified to val messageState: TextFieldState
- MessageField: uses contentReceiver + new ThinPaddingTextField
- RichContentTextField: deleted (no longer needed)
- ViewModels: added messageState (TextFieldState) to IMessageField impls
WIP: call sites still need updating to new ThinPaddingTextField API
https://claude.ai/code/session_014FZPV258VfdeE1mcyeU7wU
The Compose contentReceiver modifier doesn't set EditorInfo.contentMimeTypes
on the old BasicTextField, so Android keyboards never enable the GIF button.
Replace with an AndroidView wrapping EditText that uses
ViewCompat.setOnReceiveContentListener() to properly declare supported
MIME types to the IME, enabling the GIF/sticker button on keyboards
like Gboard.
https://claude.ai/code/session_014FZPV258VfdeE1mcyeU7wU
Add contentReceiver modifier to MessageField to receive images/GIFs
directly from Android's keyboard. When a GIF is selected from the
keyboard, its URI is passed to the post ViewModel's selectImage flow
for upload handling.
https://claude.ai/code/session_014FZPV258VfdeE1mcyeU7wU
Change the action lambda to `suspend (EventStore) -> Unit` so callers
can use suspend functions directly. Remove the now-unnecessary
runBlocking wrapper around delay() in ExpirationTest.
https://claude.ai/code/session_01TQRzVTAXBVWRGstcsapA5F
Each EventStore uses an independent in-memory SQLite database, so tests
can safely run concurrently. This launches all 16 DB configurations in
parallel via coroutines on Dispatchers.Default instead of running them
sequentially.
https://claude.ai/code/session_01TQRzVTAXBVWRGstcsapA5F
Add full compliance with NIP-85 by implementing all four assertion event
kinds and their associated tag types in the nip85TrustedAssertions package:
- Kind 30382 (User Assertions): Add all 15 missing tag parsers and
builders (first_created_at, post_cnt, reply_cnt, reactions_cnt, all
zap/report/topic/active_hours tags) to ContactCardEvent
- Kind 30383 (Event Assertions): New EventAssertionEvent with rank,
comment_cnt, quote_cnt, repost_cnt, reaction_cnt, zap_cnt, zap_amount
- Kind 30384 (Addressable Event Assertions): New
AddressableAssertionEvent with same tags as 30383
- Kind 30385 (External ID Assertions): New ExternalIdAssertionEvent
with rank, comment_cnt, reaction_cnt
- Add ProviderTypes for all new assertion kinds (30383/30384/30385)
- Register all new event kinds in EventFactory
- Add comprehensive tests for all assertion event types
https://claude.ai/code/session_01XZQsSnkHJ6tFiPS7fRLzPJ
Add a dedicated Polls-only feed screen (NIP-88 kind 1068, non-zap polls)
accessible from the left navigation drawer. The screen includes the
standard top nav filter bar for Global/Follows/etc filtering, reusing
the Discovery follow list settings.
New files:
- PollsFeedFilter: filters LocalCache for PollEvent only
- PollsFilterAssembler + PollsSubAssembler: relay subscriptions
- PollsScreen: main screen with pull-to-refresh feed
- PollsTopBar: top bar with Global/Follows filter spinner
- Relay filter subassemblies for authors, follows, global, hashtag
Wiring:
- Route.Polls added to navigation
- Polls entry in left drawer with ic_poll icon
- pollsFeed added to AccountFeedContentStates
- PollsFilterAssembler added to RelaySubscriptionsCoordinator
https://claude.ai/code/session_013JWrsYpQczmZtpW3WwRRfK
- Add KindTag to LnZapRequestEvent.create() when zapping events, as required
by NIP-A4 ("NIP-57 zaps MUST include the k tag to 24")
- Enforce e tag prohibition in all PublicMessageEvent.build() methods by
stripping any e tags from the tag builder output (NIP-A4: "e tags must not
be used")
- Add comprehensive tests for both changes
https://claude.ai/code/session_019JsSsTTXivnNWiAtE5DE1R