diff --git a/app/schemas/com.keylesspalace.tusky.db.AppDatabase/26.json b/app/schemas/com.keylesspalace.tusky.db.AppDatabase/26.json
new file mode 100644
index 00000000..ed54aecf
--- /dev/null
+++ b/app/schemas/com.keylesspalace.tusky.db.AppDatabase/26.json
@@ -0,0 +1,909 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 26,
+ "identityHash": "f6370dbef6f97c3b6de019eb14c7c461",
+ "entities": [
+ {
+ "tableName": "TootEntity",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `text` TEXT, `urls` TEXT, `descriptions` TEXT, `contentWarning` TEXT, `inReplyToId` TEXT, `inReplyToText` TEXT, `inReplyToUsername` TEXT, `visibility` INTEGER, `poll` TEXT, `formattingSyntax` TEXT NOT NULL, `markdownMode` INTEGER)",
+ "fields": [
+ {
+ "fieldPath": "uid",
+ "columnName": "uid",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "text",
+ "columnName": "text",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "urls",
+ "columnName": "urls",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "descriptions",
+ "columnName": "descriptions",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "contentWarning",
+ "columnName": "contentWarning",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "inReplyToId",
+ "columnName": "inReplyToId",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "inReplyToText",
+ "columnName": "inReplyToText",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "inReplyToUsername",
+ "columnName": "inReplyToUsername",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "visibility",
+ "columnName": "visibility",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "poll",
+ "columnName": "poll",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "formattingSyntax",
+ "columnName": "formattingSyntax",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "markdownMode",
+ "columnName": "markdownMode",
+ "affinity": "INTEGER",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "uid"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "AccountEntity",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `domain` TEXT NOT NULL, `accessToken` TEXT NOT NULL, `isActive` INTEGER NOT NULL, `accountId` TEXT NOT NULL, `username` TEXT NOT NULL, `displayName` TEXT NOT NULL, `profilePictureUrl` TEXT NOT NULL, `notificationsEnabled` INTEGER NOT NULL, `notificationsStreamingEnabled` INTEGER NOT NULL, `notificationsMentioned` INTEGER NOT NULL, `notificationsFollowed` INTEGER NOT NULL, `notificationsFollowRequested` INTEGER NOT NULL, `notificationsReblogged` INTEGER NOT NULL, `notificationsFavorited` INTEGER NOT NULL, `notificationsPolls` INTEGER NOT NULL, `notificationsEmojiReactions` INTEGER NOT NULL, `notificationsChatMessages` INTEGER NOT NULL, `notificationsSubscriptions` INTEGER NOT NULL, `notificationsMove` INTEGER NOT NULL, `notificationSound` INTEGER NOT NULL, `notificationVibration` INTEGER NOT NULL, `notificationLight` INTEGER NOT NULL, `defaultPostPrivacy` INTEGER NOT NULL, `defaultMediaSensitivity` INTEGER NOT NULL, `alwaysShowSensitiveMedia` INTEGER NOT NULL, `alwaysOpenSpoiler` INTEGER NOT NULL, `mediaPreviewEnabled` INTEGER NOT NULL, `lastNotificationId` TEXT NOT NULL, `activeNotifications` TEXT NOT NULL, `emojis` TEXT NOT NULL, `tabPreferences` TEXT NOT NULL, `notificationsFilter` TEXT NOT NULL, `defaultFormattingSyntax` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "domain",
+ "columnName": "domain",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "accessToken",
+ "columnName": "accessToken",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isActive",
+ "columnName": "isActive",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "accountId",
+ "columnName": "accountId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "username",
+ "columnName": "username",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "displayName",
+ "columnName": "displayName",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "profilePictureUrl",
+ "columnName": "profilePictureUrl",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationsEnabled",
+ "columnName": "notificationsEnabled",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationsStreamingEnabled",
+ "columnName": "notificationsStreamingEnabled",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationsMentioned",
+ "columnName": "notificationsMentioned",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationsFollowed",
+ "columnName": "notificationsFollowed",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationsFollowRequested",
+ "columnName": "notificationsFollowRequested",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationsReblogged",
+ "columnName": "notificationsReblogged",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationsFavorited",
+ "columnName": "notificationsFavorited",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationsPolls",
+ "columnName": "notificationsPolls",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationsEmojiReactions",
+ "columnName": "notificationsEmojiReactions",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationsChatMessages",
+ "columnName": "notificationsChatMessages",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationsSubscriptions",
+ "columnName": "notificationsSubscriptions",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationsMove",
+ "columnName": "notificationsMove",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationSound",
+ "columnName": "notificationSound",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationVibration",
+ "columnName": "notificationVibration",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationLight",
+ "columnName": "notificationLight",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "defaultPostPrivacy",
+ "columnName": "defaultPostPrivacy",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "defaultMediaSensitivity",
+ "columnName": "defaultMediaSensitivity",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "alwaysShowSensitiveMedia",
+ "columnName": "alwaysShowSensitiveMedia",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "alwaysOpenSpoiler",
+ "columnName": "alwaysOpenSpoiler",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "mediaPreviewEnabled",
+ "columnName": "mediaPreviewEnabled",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastNotificationId",
+ "columnName": "lastNotificationId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "activeNotifications",
+ "columnName": "activeNotifications",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "emojis",
+ "columnName": "emojis",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "tabPreferences",
+ "columnName": "tabPreferences",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notificationsFilter",
+ "columnName": "notificationsFilter",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "defaultFormattingSyntax",
+ "columnName": "defaultFormattingSyntax",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_AccountEntity_domain_accountId",
+ "unique": true,
+ "columnNames": [
+ "domain",
+ "accountId"
+ ],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_AccountEntity_domain_accountId` ON `${TABLE_NAME}` (`domain`, `accountId`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "InstanceEntity",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`instance` TEXT NOT NULL, `emojiList` TEXT, `maximumTootCharacters` INTEGER, `maxPollOptions` INTEGER, `maxPollOptionLength` INTEGER, `version` TEXT, `chatLimit` INTEGER, PRIMARY KEY(`instance`))",
+ "fields": [
+ {
+ "fieldPath": "instance",
+ "columnName": "instance",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "emojiList",
+ "columnName": "emojiList",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "maximumTootCharacters",
+ "columnName": "maximumTootCharacters",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "maxPollOptions",
+ "columnName": "maxPollOptions",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "maxPollOptionLength",
+ "columnName": "maxPollOptionLength",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "version",
+ "columnName": "version",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "chatLimit",
+ "columnName": "chatLimit",
+ "affinity": "INTEGER",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "instance"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "TimelineStatusEntity",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` TEXT NOT NULL, `url` TEXT, `timelineUserId` INTEGER NOT NULL, `authorServerId` TEXT, `inReplyToId` TEXT, `inReplyToAccountId` TEXT, `content` TEXT, `createdAt` INTEGER NOT NULL, `emojis` TEXT, `reblogsCount` INTEGER NOT NULL, `favouritesCount` INTEGER NOT NULL, `reblogged` INTEGER NOT NULL, `bookmarked` INTEGER NOT NULL, `favourited` INTEGER NOT NULL, `sensitive` INTEGER NOT NULL, `spoilerText` TEXT, `visibility` INTEGER, `attachments` TEXT, `mentions` TEXT, `application` TEXT, `reblogServerId` TEXT, `reblogAccountId` TEXT, `poll` TEXT, `pleroma` TEXT, PRIMARY KEY(`serverId`, `timelineUserId`), FOREIGN KEY(`authorServerId`, `timelineUserId`) REFERENCES `TimelineAccountEntity`(`serverId`, `timelineUserId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
+ "fields": [
+ {
+ "fieldPath": "serverId",
+ "columnName": "serverId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "url",
+ "columnName": "url",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "timelineUserId",
+ "columnName": "timelineUserId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "authorServerId",
+ "columnName": "authorServerId",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "inReplyToId",
+ "columnName": "inReplyToId",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "inReplyToAccountId",
+ "columnName": "inReplyToAccountId",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "content",
+ "columnName": "content",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "createdAt",
+ "columnName": "createdAt",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "emojis",
+ "columnName": "emojis",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "reblogsCount",
+ "columnName": "reblogsCount",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "favouritesCount",
+ "columnName": "favouritesCount",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "reblogged",
+ "columnName": "reblogged",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "bookmarked",
+ "columnName": "bookmarked",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "favourited",
+ "columnName": "favourited",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "sensitive",
+ "columnName": "sensitive",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "spoilerText",
+ "columnName": "spoilerText",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "visibility",
+ "columnName": "visibility",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "attachments",
+ "columnName": "attachments",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "mentions",
+ "columnName": "mentions",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "application",
+ "columnName": "application",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "reblogServerId",
+ "columnName": "reblogServerId",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "reblogAccountId",
+ "columnName": "reblogAccountId",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "poll",
+ "columnName": "poll",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "pleroma",
+ "columnName": "pleroma",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "serverId",
+ "timelineUserId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [
+ {
+ "name": "index_TimelineStatusEntity_authorServerId_timelineUserId",
+ "unique": false,
+ "columnNames": [
+ "authorServerId",
+ "timelineUserId"
+ ],
+ "createSql": "CREATE INDEX IF NOT EXISTS `index_TimelineStatusEntity_authorServerId_timelineUserId` ON `${TABLE_NAME}` (`authorServerId`, `timelineUserId`)"
+ }
+ ],
+ "foreignKeys": [
+ {
+ "table": "TimelineAccountEntity",
+ "onDelete": "NO ACTION",
+ "onUpdate": "NO ACTION",
+ "columns": [
+ "authorServerId",
+ "timelineUserId"
+ ],
+ "referencedColumns": [
+ "serverId",
+ "timelineUserId"
+ ]
+ }
+ ]
+ },
+ {
+ "tableName": "TimelineAccountEntity",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` TEXT NOT NULL, `timelineUserId` INTEGER NOT NULL, `localUsername` TEXT NOT NULL, `username` TEXT NOT NULL, `displayName` TEXT NOT NULL, `url` TEXT NOT NULL, `avatar` TEXT NOT NULL, `emojis` TEXT NOT NULL, `bot` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `timelineUserId`))",
+ "fields": [
+ {
+ "fieldPath": "serverId",
+ "columnName": "serverId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "timelineUserId",
+ "columnName": "timelineUserId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "localUsername",
+ "columnName": "localUsername",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "username",
+ "columnName": "username",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "displayName",
+ "columnName": "displayName",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "url",
+ "columnName": "url",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "avatar",
+ "columnName": "avatar",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "emojis",
+ "columnName": "emojis",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "bot",
+ "columnName": "bot",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "serverId",
+ "timelineUserId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "ConversationEntity",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`accountId` INTEGER NOT NULL, `id` TEXT NOT NULL, `accounts` TEXT NOT NULL, `unread` INTEGER NOT NULL, `s_id` TEXT NOT NULL, `s_url` TEXT, `s_inReplyToId` TEXT, `s_inReplyToAccountId` TEXT, `s_account` TEXT NOT NULL, `s_content` TEXT NOT NULL, `s_createdAt` INTEGER NOT NULL, `s_emojis` TEXT NOT NULL, `s_favouritesCount` INTEGER NOT NULL, `s_favourited` INTEGER NOT NULL, `s_bookmarked` INTEGER NOT NULL, `s_sensitive` INTEGER NOT NULL, `s_spoilerText` TEXT NOT NULL, `s_attachments` TEXT NOT NULL, `s_mentions` TEXT NOT NULL, `s_showingHiddenContent` INTEGER NOT NULL, `s_expanded` INTEGER NOT NULL, `s_collapsible` INTEGER NOT NULL, `s_collapsed` INTEGER NOT NULL, `s_poll` TEXT, PRIMARY KEY(`id`, `accountId`))",
+ "fields": [
+ {
+ "fieldPath": "accountId",
+ "columnName": "accountId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "accounts",
+ "columnName": "accounts",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "unread",
+ "columnName": "unread",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.id",
+ "columnName": "s_id",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.url",
+ "columnName": "s_url",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "lastStatus.inReplyToId",
+ "columnName": "s_inReplyToId",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "lastStatus.inReplyToAccountId",
+ "columnName": "s_inReplyToAccountId",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "lastStatus.account",
+ "columnName": "s_account",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.content",
+ "columnName": "s_content",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.createdAt",
+ "columnName": "s_createdAt",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.emojis",
+ "columnName": "s_emojis",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.favouritesCount",
+ "columnName": "s_favouritesCount",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.favourited",
+ "columnName": "s_favourited",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.bookmarked",
+ "columnName": "s_bookmarked",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.sensitive",
+ "columnName": "s_sensitive",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.spoilerText",
+ "columnName": "s_spoilerText",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.attachments",
+ "columnName": "s_attachments",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.mentions",
+ "columnName": "s_mentions",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.showingHiddenContent",
+ "columnName": "s_showingHiddenContent",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.expanded",
+ "columnName": "s_expanded",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.collapsible",
+ "columnName": "s_collapsible",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.collapsed",
+ "columnName": "s_collapsed",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastStatus.poll",
+ "columnName": "s_poll",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id",
+ "accountId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "ChatEntity",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localId` INTEGER NOT NULL, `chatId` TEXT NOT NULL, `accountId` TEXT NOT NULL, `unread` INTEGER NOT NULL, `updatedAt` INTEGER NOT NULL, `lastMessageId` TEXT, PRIMARY KEY(`localId`, `chatId`))",
+ "fields": [
+ {
+ "fieldPath": "localId",
+ "columnName": "localId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "chatId",
+ "columnName": "chatId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "accountId",
+ "columnName": "accountId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "unread",
+ "columnName": "unread",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "updatedAt",
+ "columnName": "updatedAt",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastMessageId",
+ "columnName": "lastMessageId",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "localId",
+ "chatId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "ChatMessageEntity",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localId` INTEGER NOT NULL, `messageId` TEXT NOT NULL, `content` TEXT, `chatId` TEXT NOT NULL, `accountId` TEXT NOT NULL, `createdAt` INTEGER NOT NULL, `attachment` TEXT, `emojis` TEXT NOT NULL, PRIMARY KEY(`localId`, `messageId`))",
+ "fields": [
+ {
+ "fieldPath": "localId",
+ "columnName": "localId",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "messageId",
+ "columnName": "messageId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "content",
+ "columnName": "content",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "chatId",
+ "columnName": "chatId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "accountId",
+ "columnName": "accountId",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "createdAt",
+ "columnName": "createdAt",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "attachment",
+ "columnName": "attachment",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "emojis",
+ "columnName": "emojis",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "localId",
+ "messageId"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ }
+ ],
+ "views": [],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f6370dbef6f97c3b6de019eb14c7c461')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/app/src/husky/res/values/strings.xml b/app/src/husky/res/values/strings.xml
index a03ac32c..4e6e95f1 100644
--- a/app/src/husky/res/values/strings.xml
+++ b/app/src/husky/res/values/strings.xml
@@ -37,6 +37,9 @@
%s published a new post
Subscriptions
Notifications when somebody you\'re subscribed to published a new post
+ %s migrated to
+ Move
+ Notifications when somebody you\'re following migrated to another profile
Other
Privacy
@@ -48,6 +51,7 @@
my posts are reacted with emojis
received a chat message
somebody I\'m subscribed to published a new post
+ somebody I\'m following migrated to another profile
Hide muted users
Enable bigger custom emojis
Enable experimental Pleroma-FE stickers(if available)
diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/NotificationsAdapter.java b/app/src/main/java/com/keylesspalace/tusky/adapter/NotificationsAdapter.java
index dc6f43e1..bfab9ff3 100644
--- a/app/src/main/java/com/keylesspalace/tusky/adapter/NotificationsAdapter.java
+++ b/app/src/main/java/com/keylesspalace/tusky/adapter/NotificationsAdapter.java
@@ -52,6 +52,7 @@ import com.keylesspalace.tusky.util.LinkHelper;
import com.keylesspalace.tusky.util.SmartLengthInputFilter;
import com.keylesspalace.tusky.util.StatusDisplayOptions;
import com.keylesspalace.tusky.util.StringUtils;
+import com.keylesspalace.tusky.util.ThemeUtils;
import com.keylesspalace.tusky.util.TimestampUtils;
import com.keylesspalace.tusky.viewdata.NotificationViewData;
import com.keylesspalace.tusky.viewdata.StatusViewData;
@@ -78,7 +79,8 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
private static final int VIEW_TYPE_PLACEHOLDER = 3;
private static final int VIEW_TYPE_MUTED_STATUS = 4;
private static final int VIEW_TYPE_FOLLOW_REQUEST = 5;
- private static final int VIEW_TYPE_UNKNOWN = 6;
+ private static final int VIEW_TYPE_MOVE = 6;
+ private static final int VIEW_TYPE_UNKNOWN = 7;
private static final InputFilter[] COLLAPSE_INPUT_FILTER = new InputFilter[]{SmartLengthInputFilter.INSTANCE};
private static final InputFilter[] NO_INPUT_FILTER = new InputFilter[0];
@@ -125,6 +127,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
.inflate(R.layout.item_status_notification, parent, false);
return new StatusNotificationViewHolder(view, statusDisplayOptions);
}
+ case VIEW_TYPE_MOVE:
case VIEW_TYPE_FOLLOW: {
View view = inflater
.inflate(R.layout.item_follow, parent, false);
@@ -233,7 +236,15 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
case VIEW_TYPE_FOLLOW: {
if (payloadForHolder == null) {
FollowViewHolder holder = (FollowViewHolder) viewHolder;
- holder.setMessage(concreteNotificaton.getAccount());
+ holder.setMessage(concreteNotificaton.getAccount(), null);
+ holder.setupButtons(notificationActionListener, concreteNotificaton.getAccount().getId());
+ }
+ break;
+ }
+ case VIEW_TYPE_MOVE: {
+ if (payloadForHolder == null) {
+ FollowViewHolder holder = (FollowViewHolder) viewHolder;
+ holder.setMessage(concreteNotificaton.getTarget(), concreteNotificaton.getAccount());
holder.setupButtons(notificationActionListener, concreteNotificaton.getAccount().getId());
}
break;
@@ -294,6 +305,9 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
case FOLLOW_REQUEST: {
return VIEW_TYPE_FOLLOW_REQUEST;
}
+ case MOVE: {
+ return VIEW_TYPE_MOVE;
+ }
default: {
return VIEW_TYPE_UNKNOWN;
}
@@ -340,13 +354,30 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
this.statusDisplayOptions = statusDisplayOptions;
}
- void setMessage(Account account) {
+ void setMessage(Account account, @Nullable Account from) {
Context context = message.getContext();
- String format = context.getString(R.string.notification_follow_format);
String wrappedDisplayName = StringUtils.unicodeWrap(account.getName());
- String wholeMessage = String.format(format, wrappedDisplayName);
- CharSequence emojifiedMessage = CustomEmojiHelper.emojify(wholeMessage, account.getEmojis(), message, true);
+ Drawable drawable;
+ CharSequence emojifiedMessage;
+
+ if(from != null) {
+ String format = context.getString(R.string.notification_move_format);
+ String wrappedFromName = StringUtils.unicodeWrap(from.getName());
+ String wholeMessage = String.format(format, wrappedFromName);
+ emojifiedMessage = CustomEmojiHelper.emojify(wholeMessage, from.getEmojis(), message, true);
+
+ drawable = ThemeUtils.getTintedDrawable(context, R.drawable.ic_reply_24dp, R.attr.colorPrimary);
+ } else {
+ String format = context.getString(R.string.notification_follow_format);
+ String wholeMessage = String.format(format, wrappedDisplayName);
+ emojifiedMessage = CustomEmojiHelper.emojify(wholeMessage, account.getEmojis(), message, true);
+
+ drawable = ThemeUtils.getTintedDrawable(context, R.drawable.ic_person_add_24dp, R.attr.colorPrimary);
+ }
+
+ message.setCompoundDrawablesRelativeWithIntrinsicBounds(drawable, null, null, null);
+
message.setText(emojifiedMessage);
String username = context.getString(R.string.status_username_format, account.getUsername());
diff --git a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationHelper.java b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationHelper.java
index 7cc029ff..82eab93d 100644
--- a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationHelper.java
+++ b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationHelper.java
@@ -129,6 +129,7 @@ public class NotificationHelper {
public static final String CHANNEL_EMOJI_REACTION = "CHANNEL_EMOJI_REACTION";
public static final String CHANNEL_CHAT_MESSAGES = "CHANNEL_CHAT_MESSAGES";
public static final String CHANNEL_SUBSCRIPTIONS = "CHANNEL_SUBSCRIPTIONS";
+ public static final String CHANNEL_MOVE = "CHANNEL_MOVE";
/**
* WorkManager Tag
@@ -401,7 +402,8 @@ public class NotificationHelper {
CHANNEL_POLL + account.getIdentifier(),
CHANNEL_EMOJI_REACTION + account.getIdentifier(),
CHANNEL_CHAT_MESSAGES + account.getIdentifier(),
- CHANNEL_SUBSCRIPTIONS + account.getIdentifier()
+ CHANNEL_SUBSCRIPTIONS + account.getIdentifier(),
+ CHANNEL_MOVE + account.getIdentifier()
};
int[] channelNames = {
R.string.notification_mention_name,
@@ -412,7 +414,8 @@ public class NotificationHelper {
R.string.notification_poll_name,
R.string.notification_emoji_name,
R.string.notification_chat_message_name,
- R.string.notification_subscription_name
+ R.string.notification_subscription_name,
+ R.string.notification_move_name
};
int[] channelDescriptions = {
R.string.notification_mention_descriptions,
@@ -423,7 +426,8 @@ public class NotificationHelper {
R.string.notification_poll_description,
R.string.notification_emoji_description,
R.string.notification_chat_message_description,
- R.string.notification_subscription_description
+ R.string.notification_subscription_description,
+ R.string.notification_move_description
};
List channels = new ArrayList<>(9);
@@ -585,6 +589,8 @@ public class NotificationHelper {
return account.getNotificationsEmojiReactions();
case CHAT_MESSAGE:
return account.getNotificationsChatMessages();
+ case MOVE:
+ return account.getNotificationsMove();
default:
return false;
}
@@ -611,6 +617,8 @@ public class NotificationHelper {
return CHANNEL_EMOJI_REACTION + account.getIdentifier();
case CHAT_MESSAGE:
return CHANNEL_CHAT_MESSAGES + account.getIdentifier();
+ case MOVE:
+ return CHANNEL_MOVE + account.getIdentifier();
default:
return null;
}
@@ -713,12 +721,17 @@ public class NotificationHelper {
case CHAT_MESSAGE:
return String.format(context.getString(R.string.notification_chat_message_format),
accountName);
+ case MOVE: {
+ return String.format(context.getString(R.string.notification_move_format), accountName);
+ }
}
return null;
}
private static String bodyForType(Notification notification, Context context) {
switch (notification.getType()) {
+ case MOVE:
+ return "@" + notification.getTarget().getUsername();
case FOLLOW:
case FOLLOW_REQUEST:
return "@" + notification.getAccount().getUsername();
diff --git a/app/src/main/java/com/keylesspalace/tusky/components/preference/NotificationPreferencesFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/preference/NotificationPreferencesFragment.kt
index a3310067..935c47e2 100644
--- a/app/src/main/java/com/keylesspalace/tusky/components/preference/NotificationPreferencesFragment.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/components/preference/NotificationPreferencesFragment.kt
@@ -144,6 +144,17 @@ class NotificationPreferencesFragment : PreferenceFragmentCompat(), Injectable {
true
}
}
+
+ switchPreference {
+ setTitle(R.string.pref_title_notification_filter_move)
+ key = PrefKeys.NOTIFICATION_FILTER_MOVE
+ isIconSpaceReserved = false
+ isChecked = activeAccount.notificationsMove
+ setOnPreferenceChangeListener { _, newValue ->
+ updateAccount { it.notificationsMove = newValue as Boolean }
+ true
+ }
+ }
}
preferenceCategory(R.string.pref_title_notification_alerts) { category ->
diff --git a/app/src/main/java/com/keylesspalace/tusky/db/AccountEntity.kt b/app/src/main/java/com/keylesspalace/tusky/db/AccountEntity.kt
index 6d1b415b..9064aaf4 100644
--- a/app/src/main/java/com/keylesspalace/tusky/db/AccountEntity.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/db/AccountEntity.kt
@@ -47,6 +47,7 @@ data class AccountEntity(@field:PrimaryKey(autoGenerate = true) var id: Long,
var notificationsEmojiReactions: Boolean = true,
var notificationsChatMessages: Boolean = true,
var notificationsSubscriptions: Boolean = true,
+ var notificationsMove: Boolean = true,
var notificationSound: Boolean = true,
var notificationVibration: Boolean = true,
var notificationLight: Boolean = true,
diff --git a/app/src/main/java/com/keylesspalace/tusky/db/AppDatabase.java b/app/src/main/java/com/keylesspalace/tusky/db/AppDatabase.java
index 51f90fd1..2e2ca574 100644
--- a/app/src/main/java/com/keylesspalace/tusky/db/AppDatabase.java
+++ b/app/src/main/java/com/keylesspalace/tusky/db/AppDatabase.java
@@ -381,6 +381,7 @@ public abstract class AppDatabase extends RoomDatabase {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE `AccountEntity` ADD COLUMN `notificationsSubscriptions` INTEGER NOT NULL DEFAULT 1");
+ database.execSQL("ALTER TABLE `AccountEntity` ADD COLUMN `notificationsMove` INTEGER NOT NULL DEFAULT 1");
}
};
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/entity/Notification.kt b/app/src/main/java/com/keylesspalace/tusky/entity/Notification.kt
index e057264c..a88a9b92 100644
--- a/app/src/main/java/com/keylesspalace/tusky/entity/Notification.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/entity/Notification.kt
@@ -32,7 +32,8 @@ data class Notification(
val pleroma: PleromaNotification? = null,
val emoji: String? = null,
@SerializedName("chat_message") val chatMessage: ChatMessage? = null,
- @SerializedName("created_at") val createdAt: Date? = null ) {
+ @SerializedName("created_at") val createdAt: Date? = null,
+ val target: Account? = null) {
@JsonAdapter(NotificationTypeAdapter::class)
enum class Type(val presentation: String) {
@@ -44,7 +45,8 @@ data class Notification(
POLL("poll"),
EMOJI_REACTION("pleroma:emoji_reaction"),
FOLLOW_REQUEST("follow_request"),
- CHAT_MESSAGE("pleroma:chat_mention");
+ CHAT_MESSAGE("pleroma:chat_mention"),
+ MOVE("move");
companion object {
@@ -56,7 +58,7 @@ data class Notification(
}
return UNKNOWN
}
- val asList = listOf(MENTION, REBLOG, FAVOURITE, FOLLOW, POLL, EMOJI_REACTION, FOLLOW_REQUEST, CHAT_MESSAGE)
+ val asList = listOf(MENTION, REBLOG, FAVOURITE, FOLLOW, POLL, EMOJI_REACTION, FOLLOW_REQUEST, CHAT_MESSAGE, MOVE)
val asStringList = asList.map { it.presentation }
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/fragment/NotificationsFragment.java b/app/src/main/java/com/keylesspalace/tusky/fragment/NotificationsFragment.java
index 307e7d19..0ee22c02 100644
--- a/app/src/main/java/com/keylesspalace/tusky/fragment/NotificationsFragment.java
+++ b/app/src/main/java/com/keylesspalace/tusky/fragment/NotificationsFragment.java
@@ -500,7 +500,7 @@ public class NotificationsFragment extends SFragment implements
NotificationViewData.Concrete newViewData = new NotificationViewData.Concrete(
viewdata.getType(), viewdata.getId(), viewdata.getAccount(),
- viewDataBuilder.createStatusViewData(), viewdata.getEmoji());
+ viewDataBuilder.createStatusViewData(), viewdata.getEmoji(), viewdata.getTarget());
notifications.setPairedItem(position, newViewData);
updateAdapter();
}
@@ -534,7 +534,7 @@ public class NotificationsFragment extends SFragment implements
NotificationViewData.Concrete newViewData = new NotificationViewData.Concrete(
viewdata.getType(), viewdata.getId(), viewdata.getAccount(),
- viewDataBuilder.createStatusViewData(), viewdata.getEmoji());
+ viewDataBuilder.createStatusViewData(), viewdata.getEmoji(), viewdata.getTarget());
notifications.setPairedItem(position, newViewData);
updateAdapter();
@@ -569,7 +569,7 @@ public class NotificationsFragment extends SFragment implements
NotificationViewData.Concrete newViewData = new NotificationViewData.Concrete(
viewdata.getType(), viewdata.getId(), viewdata.getAccount(),
- viewDataBuilder.createStatusViewData(), viewdata.getEmoji());
+ viewDataBuilder.createStatusViewData(), viewdata.getEmoji(), viewdata.getTarget());
notifications.setPairedItem(position, newViewData);
updateAdapter();
@@ -598,7 +598,7 @@ public class NotificationsFragment extends SFragment implements
NotificationViewData.Concrete newViewData = new NotificationViewData.Concrete(
viewdata.getType(), viewdata.getId(), viewdata.getAccount(),
- viewDataBuilder.createStatusViewData(), viewdata.getEmoji());
+ viewDataBuilder.createStatusViewData(), viewdata.getEmoji(), viewdata.getTarget());
notifications.setPairedItem(position, newViewData);
updateAdapter();
@@ -645,7 +645,7 @@ public class NotificationsFragment extends SFragment implements
.setIsExpanded(expanded)
.createStatusViewData();
NotificationViewData notificationViewData = new NotificationViewData.Concrete(old.getType(),
- old.getId(), old.getAccount(), statusViewData, old.getEmoji());
+ old.getId(), old.getAccount(), statusViewData, old.getEmoji(), old.getTarget());
notifications.setPairedItem(position, notificationViewData);
updateAdapter();
}
@@ -659,7 +659,7 @@ public class NotificationsFragment extends SFragment implements
.setIsShowingSensitiveContent(isShowing)
.createStatusViewData();
NotificationViewData notificationViewData = new NotificationViewData.Concrete(old.getType(),
- old.getId(), old.getAccount(), statusViewData, old.getEmoji());
+ old.getId(), old.getAccount(), statusViewData, old.getEmoji(), old.getTarget());
notifications.setPairedItem(position, notificationViewData);
updateAdapter();
}
@@ -673,7 +673,7 @@ public class NotificationsFragment extends SFragment implements
.setMuted(isMuted)
.createStatusViewData();
NotificationViewData notificationViewData = new NotificationViewData.Concrete(old.getType(),
- old.getId(), old.getAccount(), statusViewData, old.getEmoji());
+ old.getId(), old.getAccount(), statusViewData, old.getEmoji(), old.getTarget());
notifications.setPairedItem(position, notificationViewData);
updateAdapter();
}
@@ -689,7 +689,7 @@ public class NotificationsFragment extends SFragment implements
NotificationViewData.Concrete newViewData = new NotificationViewData.Concrete(
viewdata.getType(), viewdata.getId(), viewdata.getAccount(),
- viewDataBuilder.createStatusViewData(), viewdata.getEmoji());
+ viewDataBuilder.createStatusViewData(), viewdata.getEmoji(), viewdata.getTarget());
notifications.setPairedItem(position, newViewData);
}
@@ -745,7 +745,8 @@ public class NotificationsFragment extends SFragment implements
concreteNotification.getId(),
concreteNotification.getAccount(),
updatedStatus,
- concreteNotification.getEmoji()
+ concreteNotification.getEmoji(),
+ concreteNotification.getTarget()
);
notifications.setPairedItem(position, updatedNotification);
updateAdapter();
@@ -871,6 +872,8 @@ public class NotificationsFragment extends SFragment implements
return getString(R.string.notification_poll_name);
case EMOJI_REACTION:
return getString(R.string.notification_emoji_name);
+ case MOVE:
+ return getString(R.string.notification_move_name);
default:
return "Unknown";
}
@@ -1427,7 +1430,8 @@ public class NotificationsFragment extends SFragment implements
NotificationViewData.Concrete newViewData = new NotificationViewData.Concrete(
viewdata.getType(), viewdata.getId(), viewdata.getAccount(),
- ViewDataUtils.statusToViewData(newStatus, false, false), viewdata.getEmoji());
+ ViewDataUtils.statusToViewData(newStatus, false, false),
+ viewdata.getEmoji(), viewdata.getTarget());
notifications.setPairedItem(position, newViewData);
updateAdapter();
diff --git a/app/src/main/java/com/keylesspalace/tusky/settings/SettingsConstants.kt b/app/src/main/java/com/keylesspalace/tusky/settings/SettingsConstants.kt
index 1981b8e0..0e2ae997 100644
--- a/app/src/main/java/com/keylesspalace/tusky/settings/SettingsConstants.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/settings/SettingsConstants.kt
@@ -62,6 +62,7 @@ object PrefKeys {
const val NOTIFICATION_FILTER_FOLLOW_REQUESTS = "notificationFilterFollowRequests"
const val NOTIFICATION_FILTER_EMOJI_REACTIONS = "notificationFilterEmojis"
const val NOTIFICATION_FILTER_SUBSCRIPTIONS = "notificationFilterSubscriptions"
+ const val NOTIFICATION_FILTER_MOVE = "notificationFilterMove"
const val NOTIFICATIONS_FILTER_FOLLOWS = "notificationFilterFollows"
const val TAB_FILTER_HOME_REPLIES = "tabFilterHomeReplies"
diff --git a/app/src/main/java/com/keylesspalace/tusky/util/ViewDataUtils.java b/app/src/main/java/com/keylesspalace/tusky/util/ViewDataUtils.java
index c961d746..d9bd3584 100644
--- a/app/src/main/java/com/keylesspalace/tusky/util/ViewDataUtils.java
+++ b/app/src/main/java/com/keylesspalace/tusky/util/ViewDataUtils.java
@@ -92,7 +92,8 @@ public final class ViewDataUtils {
alwaysShowSensitiveData,
alwaysOpenSpoiler
),
- notification.getEmoji()
+ notification.getEmoji(),
+ notification.getTarget()
);
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/viewdata/NotificationViewData.java b/app/src/main/java/com/keylesspalace/tusky/viewdata/NotificationViewData.java
index 6d36b02d..845ecc2c 100644
--- a/app/src/main/java/com/keylesspalace/tusky/viewdata/NotificationViewData.java
+++ b/app/src/main/java/com/keylesspalace/tusky/viewdata/NotificationViewData.java
@@ -47,16 +47,20 @@ public abstract class NotificationViewData {
private final Account account;
@Nullable
private final StatusViewData.Concrete statusViewData;
+ @Nullable
private final String emoji;
+ @Nullable
+ private final Account target; // move notification
public Concrete(Notification.Type type, String id, Account account,
@Nullable StatusViewData.Concrete statusViewData,
- @Nullable String emoji) {
+ @Nullable String emoji, @Nullable Account target) {
this.type = type;
this.id = id;
this.account = account;
this.statusViewData = statusViewData;
this.emoji = emoji;
+ this.target = target;
}
public Notification.Type getType() {
@@ -81,6 +85,11 @@ public abstract class NotificationViewData {
return emoji;
}
+ @Nullable
+ public Account getTarget() {
+ return target;
+ }
+
@Override
public long getViewDataId() {
return id.hashCode();
@@ -95,6 +104,7 @@ public abstract class NotificationViewData {
Objects.equals(id, concrete.id) &&
account.getId().equals(concrete.account.getId()) &&
(emoji != null && concrete.emoji != null && emoji.equals(concrete.emoji)) &&
+ (target != null && concrete.target != null && target.getId().equals(concrete.target.getId())) &&
(statusViewData == concrete.statusViewData ||
statusViewData != null &&
statusViewData.deepEquals(concrete.statusViewData));
@@ -102,7 +112,6 @@ public abstract class NotificationViewData {
@Override
public int hashCode() {
-
return Objects.hash(type, id, account, statusViewData);
}
}