Add CLEAR and FILTER buttons to notifications (#1168)
* Issue tuskyapp#762 add clear notifications button to the top of the Notifications adapter * Issue tuskyapp#764 add the notifications filter * Update notifications top bar buttons * Replace PopupMenu with PopupWindow. Save notifications filter to the account table * Disable hide top bar on empty content at the notification screen * Add app bar behavior to the sw640 notification layout * Fix issue with click on top notification tabmain
parent
1555b025e1
commit
83f1d7aaf1
@ -0,0 +1,662 @@ |
||||
{ |
||||
"formatVersion": 1, |
||||
"database": { |
||||
"version": 14, |
||||
"identityHash": "b9ca62605345d229ced2bb0c1f2db79b", |
||||
"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)", |
||||
"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 |
||||
} |
||||
], |
||||
"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, `notificationsMentioned` INTEGER NOT NULL, `notificationsFollowed` INTEGER NOT NULL, `notificationsReblogged` INTEGER NOT NULL, `notificationsFavorited` 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, `mediaPreviewEnabled` INTEGER NOT NULL, `lastNotificationId` TEXT NOT NULL, `activeNotifications` TEXT NOT NULL, `emojis` TEXT NOT NULL, `tabPreferences` TEXT NOT NULL, `notificationsFilter` 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": "notificationsMentioned", |
||||
"columnName": "notificationsMentioned", |
||||
"affinity": "INTEGER", |
||||
"notNull": true |
||||
}, |
||||
{ |
||||
"fieldPath": "notificationsFollowed", |
||||
"columnName": "notificationsFollowed", |
||||
"affinity": "INTEGER", |
||||
"notNull": true |
||||
}, |
||||
{ |
||||
"fieldPath": "notificationsReblogged", |
||||
"columnName": "notificationsReblogged", |
||||
"affinity": "INTEGER", |
||||
"notNull": true |
||||
}, |
||||
{ |
||||
"fieldPath": "notificationsFavorited", |
||||
"columnName": "notificationsFavorited", |
||||
"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": "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 |
||||
} |
||||
], |
||||
"primaryKey": { |
||||
"columnNames": [ |
||||
"id" |
||||
], |
||||
"autoGenerate": true |
||||
}, |
||||
"indices": [ |
||||
{ |
||||
"name": "index_AccountEntity_domain_accountId", |
||||
"unique": true, |
||||
"columnNames": [ |
||||
"domain", |
||||
"accountId" |
||||
], |
||||
"createSql": "CREATE UNIQUE INDEX `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, 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 |
||||
} |
||||
], |
||||
"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, `favourited` INTEGER NOT NULL, `sensitive` INTEGER NOT NULL, `spoilerText` TEXT, `visibility` INTEGER, `attachments` TEXT, `mentions` TEXT, `application` TEXT, `reblogServerId` TEXT, `reblogAccountId` 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": "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 |
||||
} |
||||
], |
||||
"primaryKey": { |
||||
"columnNames": [ |
||||
"serverId", |
||||
"timelineUserId" |
||||
], |
||||
"autoGenerate": false |
||||
}, |
||||
"indices": [ |
||||
{ |
||||
"name": "index_TimelineStatusEntity_authorServerId_timelineUserId", |
||||
"unique": false, |
||||
"columnNames": [ |
||||
"authorServerId", |
||||
"timelineUserId" |
||||
], |
||||
"createSql": "CREATE INDEX `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, 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 |
||||
} |
||||
], |
||||
"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_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, 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.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 |
||||
} |
||||
], |
||||
"primaryKey": { |
||||
"columnNames": [ |
||||
"id", |
||||
"accountId" |
||||
], |
||||
"autoGenerate": false |
||||
}, |
||||
"indices": [], |
||||
"foreignKeys": [] |
||||
} |
||||
], |
||||
"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, \"b9ca62605345d229ced2bb0c1f2db79b\")" |
||||
] |
||||
} |
||||
} |
@ -0,0 +1,74 @@ |
||||
/* Copyright 2019 Joel Pyska |
||||
* |
||||
* This file is a part of Tusky. |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the |
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even |
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
||||
* Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License along with Tusky; if not, |
||||
* see <http://www.gnu.org/licenses>. */ |
||||
|
||||
package com.keylesspalace.tusky.util |
||||
|
||||
import android.content.Context |
||||
import android.util.AttributeSet |
||||
import android.view.MotionEvent |
||||
import com.google.android.material.appbar.AppBarLayout |
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout |
||||
import android.view.View |
||||
import android.view.ViewGroup |
||||
import androidx.recyclerview.widget.RecyclerView |
||||
|
||||
|
||||
/** |
||||
* Disable AppBar scroll if content view empty or don't need to scroll |
||||
*/ |
||||
class AppBarLayoutNoEmptyScrollBehavior : AppBarLayout.Behavior { |
||||
|
||||
constructor() : super() |
||||
|
||||
constructor (context: Context, attrs: AttributeSet) : super(context, attrs) |
||||
|
||||
private fun isRecyclerViewScrollable(appBar: AppBarLayout, recyclerView: RecyclerView?): Boolean { |
||||
if (recyclerView == null) |
||||
return false |
||||
var recyclerViewHeight = recyclerView.height // Height includes RecyclerView plus AppBarLayout at same level |
||||
val appCompatHeight = appBar.height |
||||
recyclerViewHeight -= appCompatHeight |
||||
|
||||
return recyclerView.computeVerticalScrollRange() > recyclerViewHeight |
||||
} |
||||
|
||||
override fun onStartNestedScroll(parent: CoordinatorLayout, child: AppBarLayout, directTargetChild: View, target: View, nestedScrollAxes: Int, type: Int): Boolean { |
||||
return if (isRecyclerViewScrollable(child, getRecyclerView(parent))) { |
||||
super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes, type) |
||||
} else false |
||||
} |
||||
|
||||
override fun onTouchEvent(parent: CoordinatorLayout, child: AppBarLayout, ev: MotionEvent): Boolean { |
||||
//Prevent scroll on app bar drag |
||||
return if (child.isShown && !isRecyclerViewScrollable(child, getRecyclerView(parent))) |
||||
true |
||||
else |
||||
super.onTouchEvent(parent, child, ev) |
||||
} |
||||
|
||||
private fun getRecyclerView(parent: ViewGroup): RecyclerView? { |
||||
for (i in 0 until parent.childCount) { |
||||
val child = parent.getChildAt(i) |
||||
if (child is RecyclerView) |
||||
return child |
||||
else if (child is ViewGroup) { |
||||
val childRecyclerView = getRecyclerView(child) |
||||
if (childRecyclerView is RecyclerView) |
||||
return childRecyclerView |
||||
} |
||||
} |
||||
return null |
||||
} |
||||
} |
@ -0,0 +1,45 @@ |
||||
/* Copyright 2019 Joel Pyska |
||||
* |
||||
* This file is a part of Tusky. |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the |
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the |
||||
* License, or (at your option) any later version. |
||||
* |
||||
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even |
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
||||
* Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License along with Tusky; if not, |
||||
* see <http://www.gnu.org/licenses>. */ |
||||
|
||||
package com.keylesspalace.tusky.util |
||||
|
||||
import com.keylesspalace.tusky.entity.Notification |
||||
import org.json.JSONArray |
||||
|
||||
/** |
||||
* Serialize to string array and deserialize notifications type |
||||
*/ |
||||
|
||||
fun serialize(data: Set<Notification.Type>?): String { |
||||
val array = JSONArray() |
||||
data?.forEach { |
||||
array.put(it.presentation) |
||||
} |
||||
return array.toString() |
||||
} |
||||
|
||||
fun deserialize(data: String?): Set<Notification.Type> { |
||||
val ret = HashSet<Notification.Type>() |
||||
data?.let { |
||||
val array = JSONArray(data) |
||||
for (i in 0..(array.length() - 1)) { |
||||
val item = array.getString(i) |
||||
val type = Notification.Type.byString(item) |
||||
if (type != Notification.Type.UNKNOWN) |
||||
ret.add(type) |
||||
} |
||||
} |
||||
return ret |
||||
} |
@ -0,0 +1,107 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:background="?attr/tab_page_margin_drawable"> |
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout |
||||
android:layout_width="640dp" |
||||
android:layout_height="match_parent" |
||||
android:layout_gravity="center_horizontal" |
||||
android:background="?attr/window_background"> |
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
|
||||
<com.google.android.material.appbar.AppBarLayout |
||||
android:id="@+id/appBarOptions" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
app:layout_behavior="com.keylesspalace.tusky.util.AppBarLayoutNoEmptyScrollBehavior" |
||||
app:elevation="0dp"> |
||||
|
||||
<androidx.appcompat.widget.Toolbar |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:background="?android:colorBackground" |
||||
app:contentInsetEnd="0dp" |
||||
app:contentInsetLeft="0dp" |
||||
app:contentInsetRight="0dp" |
||||
app:contentInsetStart="0dp" |
||||
app:layout_scrollFlags="scroll|enterAlways"> |
||||
|
||||
<LinearLayout |
||||
android:id="@+id/topButtonsLayout" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="horizontal"> |
||||
|
||||
<Button |
||||
android:id="@+id/buttonClear" |
||||
style="@style/TuskyButton.TextButton" |
||||
android:layout_width="0dp" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:text="@string/notifications_clear" |
||||
android:textSize="?attr/status_text_medium" /> |
||||
|
||||
<Button |
||||
android:id="@+id/buttonFilter" |
||||
style="@style/TuskyButton.TextButton" |
||||
android:layout_width="0dp" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:text="@string/notifications_apply_filter" |
||||
android:textSize="?attr/status_text_medium" /> |
||||
|
||||
</LinearLayout> |
||||
</androidx.appcompat.widget.Toolbar> |
||||
|
||||
<View |
||||
android:layout_width="match_parent" |
||||
android:layout_height="1dp" |
||||
android:layout_gravity="bottom" |
||||
android:background="?android:attr/listDivider" /> |
||||
|
||||
</com.google.android.material.appbar.AppBarLayout> |
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout |
||||
android:id="@+id/swipeRefreshLayout" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"> |
||||
|
||||
<androidx.recyclerview.widget.RecyclerView |
||||
android:id="@+id/recyclerView" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" /> |
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> |
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout> |
||||
|
||||
<ProgressBar |
||||
android:id="@+id/progressBar" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
app:layout_constraintBottom_toBottomOf="parent" |
||||
app:layout_constraintLeft_toLeftOf="parent" |
||||
app:layout_constraintRight_toRightOf="parent" |
||||
app:layout_constraintTop_toTopOf="parent" /> |
||||
|
||||
<com.keylesspalace.tusky.view.BackgroundMessageView |
||||
android:id="@+id/statusView" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:src="@android:color/transparent" |
||||
android:visibility="gone" |
||||
app:layout_constraintBottom_toBottomOf="parent" |
||||
app:layout_constraintLeft_toLeftOf="parent" |
||||
app:layout_constraintRight_toRightOf="parent" |
||||
app:layout_constraintTop_toTopOf="parent" |
||||
tools:src="@drawable/elephant_error" |
||||
tools:visibility="visible" /> |
||||
</androidx.constraintlayout.widget.ConstraintLayout> |
||||
</FrameLayout> |
@ -0,0 +1,102 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
|
||||
<com.google.android.material.appbar.AppBarLayout |
||||
android:id="@+id/appBarOptions" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
app:elevation="0dp" |
||||
app:layout_behavior="com.keylesspalace.tusky.util.AppBarLayoutNoEmptyScrollBehavior"> |
||||
|
||||
<androidx.appcompat.widget.Toolbar |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:background="?android:colorBackground" |
||||
app:contentInsetStart="0dp" |
||||
app:contentInsetLeft="0dp" |
||||
app:contentInsetEnd="0dp" |
||||
app:contentInsetRight="0dp" |
||||
app:layout_scrollFlags="scroll|enterAlways"> |
||||
|
||||
<LinearLayout |
||||
android:id="@+id/topButtonsLayout" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="horizontal"> |
||||
|
||||
<Button |
||||
android:id="@+id/buttonClear" |
||||
style="@style/TuskyButton.TextButton" |
||||
android:layout_width="0dp" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:text="@string/notifications_clear" |
||||
android:textSize="?attr/status_text_medium" /> |
||||
|
||||
<Button |
||||
android:id="@+id/buttonFilter" |
||||
style="@style/TuskyButton.TextButton" |
||||
android:layout_width="0dp" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:text="@string/notifications_apply_filter" |
||||
android:textSize="?attr/status_text_medium" /> |
||||
|
||||
</LinearLayout> |
||||
</androidx.appcompat.widget.Toolbar> |
||||
<View |
||||
android:layout_width="match_parent" |
||||
android:layout_height="1dp" |
||||
android:background="?android:attr/listDivider" |
||||
android:layout_gravity="bottom"/> |
||||
|
||||
</com.google.android.material.appbar.AppBarLayout> |
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout |
||||
android:id="@+id/swipeRefreshLayout" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" |
||||
> |
||||
|
||||
<androidx.recyclerview.widget.RecyclerView |
||||
android:id="@+id/recyclerView" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
/> |
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> |
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout> |
||||
|
||||
<ProgressBar |
||||
android:id="@+id/progressBar" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
app:layout_constraintBottom_toBottomOf="parent" |
||||
app:layout_constraintLeft_toLeftOf="parent" |
||||
app:layout_constraintRight_toRightOf="parent" |
||||
app:layout_constraintTop_toTopOf="parent" /> |
||||
|
||||
<com.keylesspalace.tusky.view.BackgroundMessageView |
||||
android:id="@+id/statusView" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:src="@android:color/transparent" |
||||
android:visibility="gone" |
||||
app:layout_constraintBottom_toBottomOf="parent" |
||||
app:layout_constraintLeft_toLeftOf="parent" |
||||
app:layout_constraintRight_toRightOf="parent" |
||||
app:layout_constraintTop_toTopOf="parent" |
||||
tools:src="@drawable/elephant_error" |
||||
tools:visibility="visible" /> |
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout> |
@ -0,0 +1,17 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:orientation="vertical" android:layout_width="200dp" |
||||
android:layout_height="wrap_content" |
||||
android:background="?attr/window_background"> |
||||
<ListView |
||||
android:id="@+id/listView" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content"/> |
||||
<Button |
||||
android:id="@+id/buttonApply" |
||||
style="@style/TuskyButton.TextButton" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:text="@string/filter_apply" |
||||
android:textSize="?attr/status_text_medium" /> |
||||
</LinearLayout> |
@ -0,0 +1,27 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
|
||||
<item |
||||
android:id="@+id/filter_favourites" |
||||
android:checkable="true" |
||||
android:checked="true" |
||||
android:title="@string/filter_favorites" /> |
||||
<item |
||||
android:id="@+id/filter_boosts" |
||||
android:checkable="true" |
||||
android:checked="true" |
||||
android:title="@string/filter_boosts" /> |
||||
<item |
||||
android:id="@+id/filter_follows" |
||||
android:checkable="true" |
||||
android:checked="true" |
||||
android:title="@string/filter_follows" /> |
||||
<item |
||||
android:id="@+id/filter_mentions" |
||||
android:checkable="true" |
||||
android:checked="true" |
||||
android:title="@string/filter_mentions" /> |
||||
<item |
||||
android:id="@+id/filter_apply" |
||||
android:title="@string/filter_apply" /> |
||||
</menu> |
Loading…
Reference in new issue