Android CI build + delete-chat (self-only) + SFU copy refresh
- codemagic.yaml: add an Android workflow that builds an installable debug APK (Linux instance, no signing needed to test) — the Android equivalent of the iOS TestFlight loop. mobile/scripts/android-patch.js injects the camera/mic/notification permissions into the CI-generated manifest (android/ is gitignored, same as ios/). - Delete chat (self-only): new POST /api/messages/clear bulk-hides a whole DM (or group) for the requester via the existing per-user message_hidden mechanism — the other party keeps their copy entirely. "Delete chat" button added to the DM contact-info panel; chat-cleared synced to my other devices. Verified end-to-end on Postgres (A clears -> empty for A, B untouched). - Meetings copy: SFU is live, so drop the "coming soon" / "small group (mesh)" wording on the welcome card and the Meetings header. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -213,6 +213,24 @@ const messages = {
|
||||
markDeleted: (id) => db.prepare("UPDATE messages SET deleted=1, body='', attachment_id=NULL, poll_id=NULL WHERE id=?").run(id),
|
||||
// #18 Delete-for-me: hide a message from ONE user's view (the row + everyone else are untouched).
|
||||
hideForUser: (messageId, userId) => db.prepare('INSERT INTO message_hidden (message_id,user_id,hidden_at) VALUES (?,?,?) ON CONFLICT(message_id,user_id) DO NOTHING').run(messageId, userId, now()),
|
||||
// "Delete chat" (self-only): hide the ENTIRE DM thread with one peer from a single user's view. Bulk-inserts
|
||||
// message_hidden rows for every message of the pair, reusing the exact filters the thread + conversation list
|
||||
// already apply (they skip message_hidden), so the chat disappears for this user while the peer keeps their
|
||||
// copy. New messages afterwards start a fresh thread (they aren't hidden) — WhatsApp-style.
|
||||
hideThreadForUser: (teamId, userId, peerId) => db.prepare(
|
||||
`INSERT INTO message_hidden (message_id,user_id,hidden_at)
|
||||
SELECT id, ?, ? FROM messages
|
||||
WHERE team_id=? AND conversation_id IS NULL
|
||||
AND ((sender_id=? AND recipient_id=?) OR (sender_id=? AND recipient_id=?))
|
||||
ON CONFLICT (message_id,user_id) DO NOTHING`
|
||||
).run(userId, now(), teamId, userId, peerId, peerId, userId),
|
||||
// "Delete chat" (self-only) for a GROUP conversation: hide every message from one member's view (they stay a
|
||||
// member; new messages arrive as a fresh thread). The peer/other members are untouched.
|
||||
hideConversationForUser: (conversationId, userId) => db.prepare(
|
||||
`INSERT INTO message_hidden (message_id,user_id,hidden_at)
|
||||
SELECT id, ?, ? FROM messages WHERE conversation_id=?
|
||||
ON CONFLICT (message_id,user_id) DO NOTHING`
|
||||
).run(userId, now(), conversationId),
|
||||
hiddenForUser: async (userId) => (await db.prepare('SELECT message_id FROM message_hidden WHERE user_id=?').all(userId)).map((r) => r.message_id),
|
||||
// Last message in a group that THIS user hasn't hidden (so a "delete for me" on the last message
|
||||
// rolls the sidebar preview back to the previous one, instead of showing what they just removed).
|
||||
|
||||
Reference in New Issue
Block a user