Refactor notifications to Kotlin & paging (#4026)
This refactors the NotificationsFragment and related classes to Kotlin & paging. While trying to preserve as much of the original behavior as possible, this adds the following improvements as well: - The "show notifications filter" preference was added again - The "load more" button now has a background ripple effect when clicked - The "legal" report category of Mastodon 4.2 is now supported in report notifications - Unknown notifications now display "unknown notification type" instead of an empty line Other code quality improvements: - All views from xml layouts are now referenced via ViewBindings - the classes responsible for showing system notifications were moved to a new package `systemnotifications` while the classes from this refactoring are in `notifications` - the id of the local Tusky account is now called `tuskyAccountId` in all places I could find closes https://github.com/tuskyapp/Tusky/issues/3429 --------- Co-authored-by: Zongle Wang <wangzongler@gmail.com>
This commit is contained in:
parent
3bbf96b057
commit
b2c0b18c8e
121 changed files with 6992 additions and 4654 deletions
|
|
@ -27,6 +27,21 @@ import androidx.sqlite.db.SupportSQLiteDatabase;
|
|||
|
||||
import com.keylesspalace.tusky.TabDataKt;
|
||||
import com.keylesspalace.tusky.components.conversation.ConversationEntity;
|
||||
import com.keylesspalace.tusky.db.dao.AccountDao;
|
||||
import com.keylesspalace.tusky.db.dao.DraftDao;
|
||||
import com.keylesspalace.tusky.db.dao.InstanceDao;
|
||||
import com.keylesspalace.tusky.db.dao.NotificationsDao;
|
||||
import com.keylesspalace.tusky.db.dao.TimelineAccountDao;
|
||||
import com.keylesspalace.tusky.db.dao.TimelineDao;
|
||||
import com.keylesspalace.tusky.db.dao.TimelineStatusDao;
|
||||
import com.keylesspalace.tusky.db.entity.AccountEntity;
|
||||
import com.keylesspalace.tusky.db.entity.DraftEntity;
|
||||
import com.keylesspalace.tusky.db.entity.HomeTimelineEntity;
|
||||
import com.keylesspalace.tusky.db.entity.InstanceEntity;
|
||||
import com.keylesspalace.tusky.db.entity.NotificationEntity;
|
||||
import com.keylesspalace.tusky.db.entity.NotificationReportEntity;
|
||||
import com.keylesspalace.tusky.db.entity.TimelineAccountEntity;
|
||||
import com.keylesspalace.tusky.db.entity.TimelineStatusEntity;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
|
@ -40,11 +55,14 @@ import java.io.File;
|
|||
InstanceEntity.class,
|
||||
TimelineStatusEntity.class,
|
||||
TimelineAccountEntity.class,
|
||||
ConversationEntity.class
|
||||
ConversationEntity.class,
|
||||
NotificationEntity.class,
|
||||
NotificationReportEntity.class,
|
||||
HomeTimelineEntity.class
|
||||
},
|
||||
// Note: Starting with version 54, database versions in Tusky are always even.
|
||||
// This is to reserve odd version numbers for use by forks.
|
||||
version = 58,
|
||||
version = 60,
|
||||
autoMigrations = {
|
||||
@AutoMigration(from = 48, to = 49),
|
||||
@AutoMigration(from = 49, to = 50, spec = AppDatabase.MIGRATION_49_50.class),
|
||||
|
|
@ -61,6 +79,9 @@ public abstract class AppDatabase extends RoomDatabase {
|
|||
@NonNull public abstract ConversationsDao conversationDao();
|
||||
@NonNull public abstract TimelineDao timelineDao();
|
||||
@NonNull public abstract DraftDao draftDao();
|
||||
@NonNull public abstract NotificationsDao notificationsDao();
|
||||
@NonNull public abstract TimelineStatusDao timelineStatusDao();
|
||||
@NonNull public abstract TimelineAccountDao timelineAccountDao();
|
||||
|
||||
public static final Migration MIGRATION_2_3 = new Migration(2, 3) {
|
||||
@Override
|
||||
|
|
@ -698,4 +719,126 @@ public abstract class AppDatabase extends RoomDatabase {
|
|||
database.execSQL("ALTER TABLE `AccountEntity` ADD COLUMN `isShowHomeSelfBoosts` INTEGER NOT NULL DEFAULT 1");
|
||||
}
|
||||
};
|
||||
|
||||
public static final Migration MIGRATION_58_60 = new Migration(58, 60) {
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase database) {
|
||||
// drop the old tables - they are only caches anyway
|
||||
database.execSQL("DROP TABLE `TimelineStatusEntity`");
|
||||
database.execSQL("DROP TABLE `TimelineAccountEntity`");
|
||||
|
||||
// create the new tables
|
||||
database.execSQL("""
|
||||
CREATE TABLE IF NOT EXISTS `TimelineAccountEntity` (
|
||||
`serverId` TEXT NOT NULL,
|
||||
`tuskyAccountId` 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`, `tuskyAccountId`)
|
||||
)"""
|
||||
);
|
||||
database.execSQL("""
|
||||
CREATE TABLE IF NOT EXISTS `TimelineStatusEntity` (
|
||||
`serverId` TEXT NOT NULL,
|
||||
`url` TEXT,
|
||||
`tuskyAccountId` INTEGER NOT NULL,
|
||||
`authorServerId` TEXT NOT NULL,
|
||||
`inReplyToId` TEXT,
|
||||
`inReplyToAccountId` TEXT,
|
||||
`content` TEXT NOT NULL,
|
||||
`createdAt` INTEGER NOT NULL,
|
||||
`editedAt` INTEGER,
|
||||
`emojis` TEXT NOT NULL,
|
||||
`reblogsCount` INTEGER NOT NULL,
|
||||
`favouritesCount` INTEGER NOT NULL,
|
||||
`repliesCount` INTEGER NOT NULL,
|
||||
`reblogged` INTEGER NOT NULL,
|
||||
`bookmarked` INTEGER NOT NULL,
|
||||
`favourited` INTEGER NOT NULL,
|
||||
`sensitive` INTEGER NOT NULL,
|
||||
`spoilerText` TEXT NOT NULL,
|
||||
`visibility` INTEGER NOT NULL,
|
||||
`attachments` TEXT NOT NULL,
|
||||
`mentions` TEXT NOT NULL,
|
||||
`tags` TEXT NOT NULL,
|
||||
`application` TEXT,
|
||||
`poll` TEXT,
|
||||
`muted` INTEGER NOT NULL,
|
||||
`expanded` INTEGER NOT NULL,
|
||||
`contentCollapsed` INTEGER NOT NULL,
|
||||
`contentShowing` INTEGER NOT NULL,
|
||||
`pinned` INTEGER NOT NULL,
|
||||
`card` TEXT, `language` TEXT,
|
||||
`filtered` TEXT NOT NULL,
|
||||
PRIMARY KEY(`serverId`, `tuskyAccountId`),
|
||||
FOREIGN KEY(`authorServerId`, `tuskyAccountId`) REFERENCES `TimelineAccountEntity`(`serverId`, `tuskyAccountId`) ON UPDATE NO ACTION ON DELETE NO ACTION
|
||||
)"""
|
||||
);
|
||||
database.execSQL(
|
||||
"CREATE INDEX IF NOT EXISTS `index_TimelineStatusEntity_authorServerId_tuskyAccountId` ON `TimelineStatusEntity` (`authorServerId`, `tuskyAccountId`)"
|
||||
);
|
||||
database.execSQL("""
|
||||
CREATE TABLE IF NOT EXISTS `HomeTimelineEntity` (
|
||||
`tuskyAccountId` INTEGER NOT NULL,
|
||||
`id` TEXT NOT NULL,
|
||||
`statusId` TEXT,
|
||||
`reblogAccountId` TEXT,
|
||||
`loading` INTEGER NOT NULL,
|
||||
PRIMARY KEY(`id`, `tuskyAccountId`),
|
||||
FOREIGN KEY(`statusId`, `tuskyAccountId`) REFERENCES `TimelineStatusEntity`(`serverId`, `tuskyAccountId`) ON UPDATE NO ACTION ON DELETE NO ACTION,
|
||||
FOREIGN KEY(`reblogAccountId`, `tuskyAccountId`) REFERENCES `TimelineAccountEntity`(`serverId`, `tuskyAccountId`) ON UPDATE NO ACTION ON DELETE NO ACTION
|
||||
)"""
|
||||
);
|
||||
database.execSQL(
|
||||
"CREATE INDEX IF NOT EXISTS `index_HomeTimelineEntity_statusId_tuskyAccountId` ON `HomeTimelineEntity` (`statusId`, `tuskyAccountId`)"
|
||||
);
|
||||
database.execSQL(
|
||||
"CREATE INDEX IF NOT EXISTS `index_HomeTimelineEntity_reblogAccountId_tuskyAccountId` ON `HomeTimelineEntity` (`reblogAccountId`, `tuskyAccountId`)"
|
||||
);
|
||||
database.execSQL("""
|
||||
CREATE TABLE IF NOT EXISTS `NotificationReportEntity`(
|
||||
`tuskyAccountId` INTEGER NOT NULL,
|
||||
`serverId` TEXT NOT NULL,
|
||||
`category` TEXT NOT NULL,
|
||||
`statusIds` TEXT,
|
||||
`createdAt` INTEGER NOT NULL,
|
||||
`targetAccountId` TEXT,
|
||||
PRIMARY KEY(`serverId`, `tuskyAccountId`),
|
||||
FOREIGN KEY(`targetAccountId`, `tuskyAccountId`) REFERENCES `TimelineAccountEntity`(`serverId`, `tuskyAccountId`) ON UPDATE NO ACTION ON DELETE NO ACTION
|
||||
)"""
|
||||
);
|
||||
database.execSQL(
|
||||
"CREATE INDEX IF NOT EXISTS `index_NotificationReportEntity_targetAccountId_tuskyAccountId` ON `NotificationReportEntity` (`targetAccountId`, `tuskyAccountId`)"
|
||||
);
|
||||
database.execSQL("""
|
||||
CREATE TABLE IF NOT EXISTS `NotificationEntity` (
|
||||
`tuskyAccountId` INTEGER NOT NULL,
|
||||
`type` TEXT,
|
||||
`id` TEXT NOT NULL,
|
||||
`accountId` TEXT,
|
||||
`statusId` TEXT,
|
||||
`reportId` TEXT,
|
||||
`loading` INTEGER NOT NULL,
|
||||
PRIMARY KEY(`id`, `tuskyAccountId`),
|
||||
FOREIGN KEY(`accountId`, `tuskyAccountId`) REFERENCES `TimelineAccountEntity`(`serverId`, `tuskyAccountId`) ON UPDATE NO ACTION ON DELETE NO ACTION,
|
||||
FOREIGN KEY(`statusId`, `tuskyAccountId`) REFERENCES `TimelineStatusEntity`(`serverId`, `tuskyAccountId`) ON UPDATE NO ACTION ON DELETE NO ACTION,
|
||||
FOREIGN KEY(`reportId`, `tuskyAccountId`) REFERENCES `NotificationReportEntity`(`serverId`, `tuskyAccountId`) ON UPDATE NO ACTION ON DELETE NO ACTION
|
||||
)"""
|
||||
);
|
||||
database.execSQL(
|
||||
"CREATE INDEX IF NOT EXISTS `index_NotificationEntity_accountId_tuskyAccountId` ON `NotificationEntity` (`accountId`, `tuskyAccountId`)"
|
||||
);
|
||||
database.execSQL(
|
||||
"CREATE INDEX IF NOT EXISTS `index_NotificationEntity_statusId_tuskyAccountId` ON `NotificationEntity` (`statusId`, `tuskyAccountId`)"
|
||||
);
|
||||
database.execSQL(
|
||||
"CREATE INDEX IF NOT EXISTS `index_NotificationEntity_reportId_tuskyAccountId` ON `NotificationEntity` (`reportId`, `tuskyAccountId`)"
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue