feat(chat): support message recall within 30 days - #6551
Conversation
There was a problem hiding this comment.
Pull request overview
Adds 30-day message recall with expanded participant/admin permissions and recalling-user attribution.
Changes:
- Extends recall eligibility and adds tests.
- Persists and transfers recall attribution.
- Displays the recalling user in the primary chat placeholder.
Reviewed changes
Copilot reviewed 26 out of 27 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
MessageRecallTest.kt |
Tests recall eligibility. |
values/strings.xml |
Adds English attribution text. |
values-zh-rTW/strings.xml |
Adds Traditional Chinese text. |
values-zh-rCN/strings.xml |
Adds Simplified Chinese text. |
RecallMessage.kt |
Defines recall attribution entity. |
MessageItem.kt |
Adds attribution and eligibility logic. |
TransferDataType.kt |
Adds recall transfer type. |
TransferServer.kt |
Exports recall records. |
TransferInserter.kt |
Imports recall records. |
TransferClient.kt |
Processes recall transfer data. |
RecallHolder.kt |
Shows recalling user in chat. |
ConversationFragment.kt |
Applies expanded recall permissions. |
SendMessageJob.kt |
Records local recall actor. |
Injector.kt |
Injects recall DAO. |
DecryptMessage.kt |
Records remote recall actor. |
BaseJob.kt |
Exposes recall DAO to jobs. |
TimeExtension.kt |
Adds 30-day age check. |
BaseDbModule.kt |
Provides recall DAO. |
RecallMessageDao.kt |
Implements recall persistence queries. |
DataConverter.kt |
Maps recall attribution fields. |
MixinDatabaseMigrations.kt |
Creates recall table. |
MixinDatabase.kt |
Registers entity, DAO, and migration. |
MessageDao.kt |
Joins recall attribution. |
MessageFetcher.kt |
Fetches recall attribution. |
DaoExtension.kt |
Cleans associated recall records. |
Constants.kt |
Increments database version. |
72.json |
Records Room schema version 72. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
5eba75a to
4284d15
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 35 out of 36 changed files in this pull request and generated no new comments.
Suppressed comments (5)
app/src/main/java/one/mixin/android/db/MixinDatabaseMigrations.kt:617
- This migration leaves all pre-upgrade
MESSAGE_RECALLrows without recaller metadata, so existing placeholders cannot show a name and device transfer also omits that attribution. Before this feature, recall was sender-only, so backfill these rows from the original message'suser_idwhile migrating.
db.execSQL("CREATE TABLE IF NOT EXISTS `recall_messages` (`message_id` TEXT NOT NULL, `user_id` TEXT NOT NULL, PRIMARY KEY(`message_id`))")
app/src/main/java/one/mixin/android/widget/QuoteView.kt:101
- Persisted
quote_contentcreated by older versions has norecallUserId, so a legacy message recalled by the current user now falls through to “This message was deleted”; the previous code identified it viauserId. Preserve that sender fallback only when the new recaller ID is absent.
app/src/main/java/one/mixin/android/ui/home/ConversationListFragment.kt:996 - Older databases and transfers do not have a
recall_messagesentry, so existing self-recalled conversation previews now lose the previous “You deleted” text. Fall back to the original sender only whenrecallUserIdis unavailable.
conversationItem.recallUserId == id -> {
binding.msgTv.setText(R.string.You_deleted_this_message)
}
app/src/main/java/one/mixin/android/ui/conversation/holder/RecallHolder.kt:37
- Recall rows created before this metadata table existed have no
recallUserId; this changes the current user's old self-recalled messages from “You deleted” to the generic placeholder. Retain the existingisMeinference when the new ID is absent.
messageItem.recallUserId == meId -> ctx.getString(R.string.You_deleted_this_message) + " "
app/src/main/java/one/mixin/android/ui/conversation/chathistory/holder/RecallHolder.kt:36
- Transferred or historical recall items can lack the new metadata, causing legacy self-recalled entries in chat history to regress to the generic placeholder. Use the existing
isMevalue as the fallback only whenrecallUserIdis null.
messageItem.recallUserId == meId -> ctx.getString(R.string.You_deleted_this_message) + " "
d2e449b to
c46c680
Compare
Reuse messages.participant_id for who recalled a message instead of a new recall_messages table. Recalled text/image/contact messages never wrote this column.
Summary
recall_messages.Validation
./gradlew :app:compileGooglePlayDebugKotlin