2326738b84
Tapping reply on a Marmot/MLS (kind:445) message in the Notifications screen previously fell through routeReplyTo()'s `else` branch and opened the generic public-comment composer (Route.GenericCommentPost). Sending it would publish a plaintext kind:1111 that references the encrypted inner event id, leaking that the user has decrypted that group message. Mirror the NIP-17 pattern (Route.Room carries replyId, draftId, draftMessage; the same chat screen renders the "replying to" quote above the input) for MLS: - routeReplyTo() now detects MarmotGroupChatroom in note.inGatherers, matching how routeFor() at line 67 already finds the parent group, and returns Route.MarmotGroupChat(groupId, replyId = note.idHex). - Route.MarmotGroupChat gains message/replyId/draftId fields. - MarmotGroupChatView resolves the replyId into a Note, shows DisplayReplyingToNote above the composer, wires onWantsToReply for in-chat replies, and threads the parent inner event through AccountViewModel.sendMarmotGroupMessage into MarmotManager.buildTextMessage, which now adds a NIP-18 q-tag on the inner kind:9 (the same convention ChatEvent.reply() uses). Push notifications: notifyGroupMessage previously passed chatroomMembers=null, so the inline Reply action was never attached for MLS group notifications. Add a parallel MARMOT_REPLY_ACTION wired with the group id + parent inner event id; NotificationReplyReceiver loads the account, rebuilds the parent inner event from LocalCache (or sends unthreaded if the cache was pruned), and publishes the reply through the same MarmotManager path — so the inline notification reply stays encrypted inside the group instead of taking the NIP-17 PTag fallback.