通知カラムにクイックフィルターを追加

This commit is contained in:
tateisu 2019-01-08 13:30:18 +09:00
parent 3da82e74cd
commit 3b74452c7e
6 changed files with 435 additions and 85 deletions

View File

@ -162,6 +162,7 @@ class Column(
private const val KEY_ENABLE_SPEECH = "enable_speech"
private const val KEY_USE_OLD_API = "use_old_api"
private const val KEY_LAST_VIEWING_ITEM = "lastViewingItem"
private const val KEY_QUICK_FILTER = "quickFilter"
private const val KEY_REGEX_TEXT = "regex_text"
@ -226,6 +227,14 @@ class Column(
internal var useInstanceTicker = false
internal const val QUICK_FILTER_ALL = 0
internal const val QUICK_FILTER_MENTION = 1
internal const val QUICK_FILTER_FAVOURITE = 2
internal const val QUICK_FILTER_BOOST = 3
internal const val QUICK_FILTER_FOLLOW = 4
internal const val QUICK_FILTER_REACTION = 5
internal const val QUICK_FILTER_VOTE = 6
@Suppress("UNCHECKED_CAST")
private inline fun <reified T> getParamAt(params : Array<out Any>, idx : Int) : T {
return params[idx] as T
@ -280,7 +289,7 @@ class Column(
TYPE_LIST_TL -> context.getString(R.string.list_timeline)
TYPE_DIRECT_MESSAGES -> context.getString(R.string.direct_messages)
TYPE_TREND_TAG -> context.getString(R.string.trend_tag)
TYPE_SCHEDULED_STATUS ->context.getString(R.string.scheduled_status)
TYPE_SCHEDULED_STATUS -> context.getString(R.string.scheduled_status)
else -> "?"
}
}
@ -576,12 +585,16 @@ class Column(
internal var with_highlight : Boolean = false
internal var dont_show_boost : Boolean = false
internal var dont_show_reply : Boolean = false
internal var dont_show_reaction : Boolean = false
internal var dont_show_vote : Boolean = false
internal var dont_show_normal_toot : Boolean = false
internal var dont_show_favourite : Boolean = false // 通知カラムのみ
internal var dont_show_follow : Boolean = false // 通知カラムのみ
internal var dont_show_reaction : Boolean = false // 通知カラムのみ
internal var dont_show_vote : Boolean = false // 通知カラムのみ
internal var quick_filter = QUICK_FILTER_ALL
internal var dont_streaming : Boolean = false
internal var dont_auto_refresh : Boolean = false
internal var hide_media_default : Boolean = false
@ -669,14 +682,15 @@ class Column(
private val isFilterEnabled : Boolean
get() = (with_attachment
|| with_highlight
|| regex_text.isNotEmpty()
|| dont_show_normal_toot
|| quick_filter != QUICK_FILTER_ALL
|| dont_show_boost
|| dont_show_favourite
|| dont_show_follow
|| dont_show_reply
|| dont_show_reaction
|| dont_show_vote
|| dont_show_normal_toot
|| regex_text.isNotEmpty()
)
@Volatile
@ -789,6 +803,7 @@ class Column(
hide_media_default = src.optBoolean(KEY_HIDE_MEDIA_DEFAULT)
system_notification_not_related = src.optBoolean(KEY_SYSTEM_NOTIFICATION_NOT_RELATED)
instance_local = src.optBoolean(KEY_INSTANCE_LOCAL)
quick_filter = src.optInt(KEY_QUICK_FILTER, 0)
enable_speech = src.optBoolean(KEY_ENABLE_SPEECH)
use_old_api = src.optBoolean(KEY_USE_OLD_API)
@ -867,6 +882,7 @@ class Column(
dst.putIfTrue(KEY_INSTANCE_LOCAL, instance_local)
dst.putIfTrue(KEY_ENABLE_SPEECH, enable_speech)
dst.putIfTrue(KEY_USE_OLD_API, use_old_api)
dst.put(KEY_QUICK_FILTER, quick_filter)
last_viewing_item_id?.putTo(dst, KEY_LAST_VIEWING_ITEM)
@ -1022,37 +1038,49 @@ class Column(
val sb = StringBuilder()
sb.append("(")
var n = 0
if(! dont_show_reply) {
if(n ++ > 0) sb.append(", ")
sb.append(context.getString(R.string.notification_type_mention))
when(quick_filter) {
QUICK_FILTER_ALL -> {
var n = 0
if(! dont_show_reply) {
if(n ++ > 0) sb.append(", ")
sb.append(context.getString(R.string.notification_type_mention))
}
if(! dont_show_follow) {
if(n ++ > 0) sb.append(", ")
sb.append(context.getString(R.string.notification_type_follow))
}
if(! dont_show_boost) {
if(n ++ > 0) sb.append(", ")
sb.append(context.getString(R.string.notification_type_boost))
}
if(! dont_show_favourite) {
if(n ++ > 0) sb.append(", ")
sb.append(context.getString(R.string.notification_type_favourite))
}
if(isMisskey && ! dont_show_reaction) {
if(n ++ > 0) sb.append(", ")
sb.append(context.getString(R.string.notification_type_reaction))
}
if(isMisskey && ! dont_show_vote) {
if(n ++ > 0) sb.append(", ")
sb.append(context.getString(R.string.notification_type_vote))
}
val n_max = if(isMisskey) {
6
} else {
4
}
if(n == 0 || n == n_max) return "" // 全部か皆無なら部分表記は要らない
}
QUICK_FILTER_MENTION -> sb.append(context.getString(R.string.notification_type_mention))
QUICK_FILTER_FAVOURITE -> sb.append(context.getString(R.string.notification_type_favourite))
QUICK_FILTER_BOOST -> sb.append(context.getString(R.string.notification_type_boost))
QUICK_FILTER_FOLLOW -> sb.append(context.getString(R.string.notification_type_follow))
QUICK_FILTER_REACTION -> sb.append(context.getString(R.string.notification_type_reaction))
QUICK_FILTER_VOTE -> sb.append(context.getString(R.string.notification_type_vote))
}
if(! dont_show_follow) {
if(n ++ > 0) sb.append(", ")
sb.append(context.getString(R.string.notification_type_follow))
}
if(! dont_show_boost) {
if(n ++ > 0) sb.append(", ")
sb.append(context.getString(R.string.notification_type_boost))
}
if(! dont_show_favourite) {
if(n ++ > 0) sb.append(", ")
sb.append(context.getString(R.string.notification_type_favourite))
}
if(isMisskey && ! dont_show_reaction) {
if(n ++ > 0) sb.append(", ")
sb.append(context.getString(R.string.notification_type_reaction))
}
if(isMisskey && ! dont_show_vote) {
if(n ++ > 0) sb.append(", ")
sb.append(context.getString(R.string.notification_type_vote))
}
val n_max = if(isMisskey) {
6
} else {
4
}
if(n == 0 || n == n_max) return "" // 全部か皆無なら部分表記は要らない
sb.append(")")
return sb.toString()
}
@ -1570,33 +1598,78 @@ class Column(
private fun isFiltered(item : TootNotification) : Boolean {
when(item.type) {
TootNotification.TYPE_FAVOURITE -> if(dont_show_favourite) {
log.d("isFiltered: favourite notification filtered.")
return true
when(quick_filter) {
QUICK_FILTER_ALL -> {
when(item.type) {
TootNotification.TYPE_FAVOURITE -> if(dont_show_favourite) {
log.d("isFiltered: favourite notification filtered.")
return true
}
TootNotification.TYPE_REBLOG,
TootNotification.TYPE_RENOTE,
TootNotification.TYPE_QUOTE -> if(dont_show_boost) {
log.d("isFiltered: reblog notification filtered.")
return true
}
TootNotification.TYPE_FOLLOW_REQUEST,
TootNotification.TYPE_FOLLOW -> if(dont_show_follow) {
log.d("isFiltered: follow notification filtered.")
return true
}
TootNotification.TYPE_MENTION,
TootNotification.TYPE_REPLY -> if(dont_show_reply) {
log.d("isFiltered: mention notification filtered.")
return true
}
TootNotification.TYPE_REACTION -> if(dont_show_reaction) {
log.d("isFiltered: reaction notification filtered.")
return true
}
TootNotification.TYPE_VOTE -> if(dont_show_vote) {
log.d("isFiltered: vote notification filtered.")
return true
}
}
}
TootNotification.TYPE_REBLOG,
TootNotification.TYPE_RENOTE,
TootNotification.TYPE_QUOTE -> if(dont_show_boost) {
log.d("isFiltered: reblog notification filtered.")
return true
}
TootNotification.TYPE_FOLLOW -> if(dont_show_follow) {
log.d("isFiltered: follow notification filtered.")
return true
}
TootNotification.TYPE_MENTION,
TootNotification.TYPE_REPLY -> if(dont_show_reply) {
log.d("isFiltered: mention notification filtered.")
return true
}
TootNotification.TYPE_REACTION -> if(dont_show_reaction) {
log.d("isFiltered: reaction notification filtered.")
return true
}
TootNotification.TYPE_VOTE -> if(dont_show_vote) {
log.d("isFiltered: vote notification filtered.")
return true
else -> {
when(item.type) {
TootNotification.TYPE_FAVOURITE -> if(quick_filter != QUICK_FILTER_FAVOURITE) {
log.d("isFiltered: ${item.type} notification filtered.")
return true
}
TootNotification.TYPE_REBLOG,
TootNotification.TYPE_RENOTE,
TootNotification.TYPE_QUOTE -> if(quick_filter != QUICK_FILTER_BOOST) {
log.d("isFiltered: ${item.type} notification filtered.")
return true
}
TootNotification.TYPE_FOLLOW_REQUEST,
TootNotification.TYPE_FOLLOW -> if(quick_filter != QUICK_FILTER_FOLLOW) {
log.d("isFiltered: ${item.type} notification filtered.")
return true
}
TootNotification.TYPE_MENTION,
TootNotification.TYPE_REPLY -> if(quick_filter != QUICK_FILTER_MENTION) {
log.d("isFiltered: ${item.type} notification filtered.")
return true
}
TootNotification.TYPE_REACTION -> if(quick_filter != QUICK_FILTER_REACTION) {
log.d("isFiltered: ${item.type} notification filtered.")
return true
}
TootNotification.TYPE_VOTE -> if(quick_filter != QUICK_FILTER_VOTE) {
log.d("isFiltered: ${item.type} notification filtered.")
return true
}
else -> {
log.d("isFiltered: ${item.type} notification filtered.")
return true
}
}
}
}
@ -2403,7 +2476,7 @@ class Column(
fun parseNotifications(client : TootApiClient) : TootApiResult? {
val params = makeMisskeyBaseParameter(parser)
val params = makeMisskeyBaseParameter(parser).addMisskeyNotificationFilter()
val path_base = makeNotificationUrl()
@ -2585,10 +2658,10 @@ class Column(
}
private fun getScheduledStatuses(client:TootApiClient):TootApiResult?{
private fun getScheduledStatuses(client : TootApiClient) : TootApiResult? {
val result = client.request("/api/v1/scheduled_statuses")
val src = parseList(::TootScheduled,parser,result?.jsonArray)
list_tmp = addAll(list_tmp,src)
val src = parseList(::TootScheduled, parser, result?.jsonArray)
list_tmp = addAll(list_tmp, src)
// ページングはないっぽい
idOld = null
@ -3940,7 +4013,7 @@ class Column(
val delimiter = if(- 1 != path_base.indexOf('?')) '&' else '?'
val last_since_id = idRecent
val params = makeMisskeyBaseParameter(parser)
val params = makeMisskeyBaseParameter(parser).addMisskeyNotificationFilter()
val time_start = SystemClock.elapsedRealtime()
@ -5375,7 +5448,7 @@ class Column(
fun getNotificationList(client : TootApiClient) : TootApiResult? {
val path_base = makeNotificationUrl()
val params = makeMisskeyBaseParameter(parser)
val params = makeMisskeyBaseParameter(parser).addMisskeyNotificationFilter()
val time_start = SystemClock.elapsedRealtime()
val delimiter = if(- 1 != path_base.indexOf('?')) '&' else '?'
@ -6377,11 +6450,13 @@ class Column(
s.increaseReaction(ev.reaction, byMe, "onNoteUpdated ${ev.userId}")
}
}
MisskeyNoteUpdate.Type.UNREACTION -> {
scanStatusAll { s ->
s.decreaseReaction(ev.reaction, byMe ,"onNoteUpdated ${ev.userId}")
s.decreaseReaction(ev.reaction, byMe, "onNoteUpdated ${ev.userId}")
}
}
MisskeyNoteUpdate.Type.VOTED -> {
scanStatusAll { s ->
s.enquete?.increaseVote(context, ev.choice, byMe) ?: false
@ -6394,7 +6469,7 @@ class Column(
}
}
else ->{
else -> {
log.d("onNoteUpdated: unknown type: ${ev.type}")
}
}
@ -6799,16 +6874,68 @@ class Column(
else -> {
val sb = StringBuilder(PATH_NOTIFICATIONS) // always contain "?limit=XX"
if(dont_show_favourite) sb.append("&exclude_types[]=favourite")
if(dont_show_boost) sb.append("&exclude_types[]=reblog")
if(dont_show_follow) sb.append("&exclude_types[]=follow")
if(dont_show_reply) sb.append("&exclude_types[]=mention")
when(quick_filter) {
QUICK_FILTER_ALL -> {
if(dont_show_favourite) sb.append("&exclude_types[]=favourite")
if(dont_show_boost) sb.append("&exclude_types[]=reblog")
if(dont_show_follow) sb.append("&exclude_types[]=follow")
if(dont_show_reply) sb.append("&exclude_types[]=mention")
}
else -> {
if(quick_filter != QUICK_FILTER_FAVOURITE) sb.append("&exclude_types[]=favourite")
if(quick_filter != QUICK_FILTER_BOOST) sb.append("&exclude_types[]=reblog")
if(quick_filter != QUICK_FILTER_FOLLOW) sb.append("&exclude_types[]=follow")
if(quick_filter != QUICK_FILTER_MENTION) sb.append("&exclude_types[]=mention")
}
}
// reaction,voteはmastodonにはない
sb.toString()
}
}
}
private fun JSONObject.addMisskeyNotificationFilter() : JSONObject {
when(quick_filter) {
QUICK_FILTER_ALL -> {
val excludeList = JSONArray()
// Misskeyのお気に入りは通知されない
// if(dont_show_favourite) ...
if(dont_show_boost) {
excludeList.put("renote")
excludeList.put("quote")
}
if(dont_show_follow) {
excludeList.put("follow")
excludeList.put("receiveFollowRequest")
}
if(dont_show_reply) {
excludeList.put("mention")
excludeList.put("reply")
}
if(dont_show_reaction) {
excludeList.put("reaction")
}
if(dont_show_vote) {
excludeList.put("poll_vote")
}
if(excludeList.length() > 0) put("excludeTypes", excludeList)
}
// QUICK_FILTER_FAVOURITE // misskeyはお気に入りの通知はない
QUICK_FILTER_BOOST -> put("includeTypes", jsonArray("renote", "quote"))
QUICK_FILTER_FOLLOW -> put("includeTypes", jsonArray("follow", "receiveFollowRequest"))
QUICK_FILTER_MENTION -> put("includeTypes", jsonArray("mention", "reply"))
QUICK_FILTER_REACTION -> put("includeTypes", jsonArray("reaction"))
QUICK_FILTER_VOTE -> put("includeTypes", jsonArray("poll_vote"))
}
return this
}
private fun makeListTlUrl() : String {
return if(isMisskey) {
"/api/notes/user-list-timeline"
@ -6922,7 +7049,7 @@ class Column(
fun onScheduleDeleted(item : TootScheduled) {
val tmp_list = ArrayList<TimelineItem>(list_data.size)
for(o in list_data) {
if(o === item ) continue
if(o === item) continue
tmp_list.add(o)
}
if(tmp_list.size != list_data.size) {
@ -6988,7 +7115,6 @@ class Column(
)
}
// fun findListIndexByTimelineId(orderId : EntityId) : Int? {
// list_data.forEachIndexed { i, v ->
// if(v.getOrderId() == orderId) return i
@ -7001,3 +7127,4 @@ class Column(
}
}

View File

@ -113,6 +113,15 @@ class ColumnViewHolder(
private val llRegexFilter : View
private val btnDeleteNotification : Button
private val svQuickFilter : HorizontalScrollView
private val btnQuickFilterAll : Button
private val btnQuickFilterMention : ImageButton
private val btnQuickFilterFavourite : ImageButton
private val btnQuickFilterBoost : ImageButton
private val btnQuickFilterFollow : ImageButton
private val btnQuickFilterReaction : ImageButton
private val btnQuickFilterVote : ImageButton
private val llRefreshError : FrameLayout
private val ivRefreshError : ImageView
private val tvRefreshError : TextView
@ -324,6 +333,25 @@ class ColumnViewHolder(
btnDeleteNotification = viewRoot.findViewById(R.id.btnDeleteNotification)
svQuickFilter = viewRoot.findViewById(R.id.svQuickFilter)
btnQuickFilterAll = viewRoot.findViewById(R.id.btnQuickFilterAll)
btnQuickFilterMention = viewRoot.findViewById(R.id.btnQuickFilterMention)
btnQuickFilterFavourite = viewRoot.findViewById(R.id.btnQuickFilterFavourite)
btnQuickFilterBoost = viewRoot.findViewById(R.id.btnQuickFilterBoost)
btnQuickFilterFollow = viewRoot.findViewById(R.id.btnQuickFilterFollow)
btnQuickFilterReaction = viewRoot.findViewById(R.id.btnQuickFilterReaction)
btnQuickFilterVote = viewRoot.findViewById(R.id.btnQuickFilterVote)
btnQuickFilterAll.setOnClickListener(this)
btnQuickFilterMention.setOnClickListener(this)
btnQuickFilterFavourite.setOnClickListener(this)
btnQuickFilterBoost.setOnClickListener(this)
btnQuickFilterFollow.setOnClickListener(this)
btnQuickFilterReaction.setOnClickListener(this)
btnQuickFilterVote.setOnClickListener(this)
llColumnHeader.setOnClickListener(this)
btnColumnSetting.setOnClickListener(this)
btnColumnReload.setOnClickListener(this)
@ -565,7 +593,7 @@ class ColumnViewHolder(
vg(cbDontShowNormalToot, column.canFilterNormalToot())
vg(cbDontShowReaction, isNotificationColumn && column.isMisskey)
vg(cbDontShowVote, isNotificationColumn && column.isMisskey)
vg(cbDontShowFavourite, isNotificationColumn)
vg(cbDontShowFavourite, isNotificationColumn && ! column.isMisskey)
vg(cbDontShowFollow, isNotificationColumn)
vg(cbInstanceLocal, column.column_type == Column.TYPE_HASHTAG)
@ -615,6 +643,8 @@ class ColumnViewHolder(
column.addColumnViewHolder(this)
showQuickFilter()
showColumnColor()
showContent(reason = "onPageCreate", reset = true)
@ -1005,6 +1035,15 @@ class ColumnViewHolder(
column.mRefreshLoadingErrorPopupState = 1 - column.mRefreshLoadingErrorPopupState
showRefreshError()
}
R.id.btnQuickFilterAll -> clickQuickFilter(Column.QUICK_FILTER_ALL)
R.id.btnQuickFilterMention -> clickQuickFilter(Column.QUICK_FILTER_MENTION)
R.id.btnQuickFilterFavourite -> clickQuickFilter(Column.QUICK_FILTER_FAVOURITE)
R.id.btnQuickFilterBoost -> clickQuickFilter(Column.QUICK_FILTER_BOOST)
R.id.btnQuickFilterFollow -> clickQuickFilter(Column.QUICK_FILTER_FOLLOW)
R.id.btnQuickFilterReaction -> clickQuickFilter(Column.QUICK_FILTER_REACTION)
R.id.btnQuickFilterVote -> clickQuickFilter(Column.QUICK_FILTER_VOTE)
}
}
@ -1397,4 +1436,91 @@ class ColumnViewHolder(
scrollToTop()
}
}
private fun clickQuickFilter(filter : Int) {
column?.quick_filter = filter
showQuickFilter()
activity.app_state.saveColumnList()
column?.startLoading()
}
private fun showQuickFilter() {
val column = this.column ?: return
val isNotificationColumn = column.column_type == Column.TYPE_NOTIFICATIONS
vg(svQuickFilter, isNotificationColumn)
if(! isNotificationColumn) return
vg(btnQuickFilterReaction, column.isMisskey)
vg(btnQuickFilterVote, column.isMisskey)
vg(btnQuickFilterFavourite, !column.isMisskey)
val colorBg = column.getHeaderBackgroundColor()
val colorFg = column.getHeaderNameColor()
val colorBgSelected = Color.rgb(
(Color.red(colorBg) *3 + Color.red(colorFg)) / 4,
(Color.green(colorBg)*3 + Color.green(colorFg)) / 4,
(Color.blue(colorBg)*3 + Color.blue(colorFg)) / 4
)
svQuickFilter.setBackgroundColor(colorBg)
fun showQuickFilterButton(btn : View, iconId : Int, selected : Boolean) {
ViewCompat.setBackground(
btn,
getAdaptiveRippleDrawable(
if(selected) colorBgSelected else colorBg,
colorFg
)
)
when(btn){
is ImageButton ->setIconDrawableId(activity,btn,iconId,colorFg)
is TextView -> btn.textColor = colorFg
}
}
showQuickFilterButton(
btnQuickFilterAll,
0,
column.quick_filter == Column.QUICK_FILTER_ALL
)
showQuickFilterButton(
btnQuickFilterMention,
R.drawable.btn_reply,
column.quick_filter == Column.QUICK_FILTER_MENTION
)
showQuickFilterButton(
btnQuickFilterFavourite,
R.drawable.btn_favourite,
column.quick_filter == Column.QUICK_FILTER_FAVOURITE
)
showQuickFilterButton(
btnQuickFilterBoost,
R.drawable.btn_boost,
column.quick_filter == Column.QUICK_FILTER_BOOST
)
showQuickFilterButton(
btnQuickFilterFollow,
R.drawable.ic_follow_plus,
column.quick_filter == Column.QUICK_FILTER_FOLLOW
)
showQuickFilterButton(
btnQuickFilterReaction,
R.drawable.ic_add,
column.quick_filter == Column.QUICK_FILTER_REACTION
)
showQuickFilterButton(
btnQuickFilterVote,
R.drawable.ic_vote,
column.quick_filter == Column.QUICK_FILTER_VOTE
)
}
}

View File

@ -193,3 +193,15 @@ fun jsonObject(initializer : JSONObject.() -> Unit) : JSONObject {
dst.initializer()
return dst
}
fun Array<String>.toJsonArray() : JSONArray = JSONArray().also{
for(s in this){
it.put(s)
}
}
fun jsonArray(vararg args:String) = JSONArray().also{
for(s in args){
it.put(s)
}
}

View File

@ -14,10 +14,10 @@
android:layout_height="wrap_content"
android:background="@drawable/bg_column_header"
android:orientation="vertical"
android:paddingBottom="3dp"
android:paddingEnd="12dp"
android:paddingStart="12dp"
android:paddingTop="3dp"
android:paddingEnd="12dp"
android:paddingBottom="3dp"
>
<LinearLayout
@ -33,8 +33,8 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end"
android:paddingEnd="4dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:textColor="?attr/colorColumnHeaderAcct"
android:textSize="12sp"
tools:text="tvColumnContext"
@ -138,10 +138,10 @@
android:layout_height="wrap_content"
android:background="?attr/colorColumnSettingBackground"
android:orientation="vertical"
android:paddingBottom="3dp"
android:paddingEnd="12dp"
android:paddingStart="12dp"
android:paddingTop="3dp"
android:paddingEnd="12dp"
android:paddingBottom="3dp"
>
<CheckBox
@ -322,10 +322,10 @@
android:layout_height="wrap_content"
android:background="?attr/colorSearchFormBackground"
android:orientation="vertical"
android:paddingBottom="3dp"
android:paddingEnd="12dp"
android:paddingStart="12dp"
android:paddingTop="3dp"
android:paddingEnd="12dp"
android:paddingBottom="3dp"
>
<LinearLayout
@ -375,10 +375,10 @@
android:baselineAligned="false"
android:gravity="center"
android:orientation="horizontal"
android:paddingBottom="3dp"
android:paddingEnd="12dp"
android:paddingStart="12dp"
android:paddingTop="3dp"
android:paddingEnd="12dp"
android:paddingBottom="3dp"
>
<EditText
@ -404,6 +404,89 @@
</LinearLayout>
<HorizontalScrollView
android:id="@+id/svQuickFilter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="40dp"
android:orientation="horizontal"
>
<Button
android:id="@+id/btnQuickFilterAll"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:background="@drawable/btn_bg_transparent"
android:minWidth="40dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:text="@string/all"
android:textAllCaps="false"
android:stateListAnimator="@null"
/>
<ImageButton
android:id="@+id/btnQuickFilterMention"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:background="@drawable/btn_bg_transparent"
android:contentDescription="@string/mention2"
/>
<ImageButton
android:id="@+id/btnQuickFilterFavourite"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:background="@drawable/btn_bg_transparent"
android:contentDescription="@string/favourite"
/>
<ImageButton
android:id="@+id/btnQuickFilterBoost"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:background="@drawable/btn_bg_transparent"
android:contentDescription="@string/boost"
/>
<ImageButton
android:id="@+id/btnQuickFilterFollow"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:background="@drawable/btn_bg_transparent"
android:contentDescription="@string/follow"
/>
<ImageButton
android:id="@+id/btnQuickFilterReaction"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:background="@drawable/btn_bg_transparent"
android:contentDescription="@string/reaction"
/>
<ImageButton
android:id="@+id/btnQuickFilterVote"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:background="@drawable/btn_bg_transparent"
android:contentDescription="@string/vote"
/>
</LinearLayout>
</HorizontalScrollView>
<FrameLayout
android:id="@+id/flColumnBackground"
android:layout_width="match_parent"

View File

@ -842,5 +842,6 @@
<string name="cant_change_account_when_editing_scheduled_status">予約した投稿の再編集ではアカウントを変更できません</string>
<string name="delete_scheduled_status_before_update">投稿する前に編集前の古い予約投稿を削除します。よろしいですか?</string>
<string name="reply_icon_size">返信アイコンの大きさ(単位:dp。デフォルト:24。アプリ再起動が必要)</string>
<string name="all">All</string>
</resources>

View File

@ -862,5 +862,6 @@
<string name="cant_change_account_when_editing_scheduled_status">Can\'t change account when editing scheduled status.</string>
<string name="delete_scheduled_status_before_update">Delete scheduled status before posting. Are you sure?</string>
<string name="reply_icon_size">Reply icon size(Unit:dp. default:24. app restart required)</string>
<string name="all">All</string>
</resources>