diff --git a/.idea/misc.xml b/.idea/misc.xml index 2f2e6a16..9cf50334 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -29,7 +29,7 @@ - + diff --git a/app/src/main/java/jp/juggler/subwaytooter/Column.kt b/app/src/main/java/jp/juggler/subwaytooter/Column.kt index cab9bccc..ebed5f2d 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/Column.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/Column.kt @@ -151,6 +151,7 @@ class Column( private const val KEY_INSTANCE_LOCAL = "instance_local" 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_REGEX_TEXT = "regex_text" @@ -518,7 +519,8 @@ class Column( internal var system_notification_not_related : Boolean = false internal var instance_local : Boolean = false - var enable_speech : Boolean = false + internal var enable_speech : Boolean = false + internal var use_old_api = false internal var regex_text : String = "" @@ -718,6 +720,7 @@ class Column( instance_local = src.optBoolean(KEY_INSTANCE_LOCAL) enable_speech = src.optBoolean(KEY_ENABLE_SPEECH) + use_old_api = src.optBoolean(KEY_USE_OLD_API) last_viewing_item_id = EntityId.from(src, KEY_LAST_VIEWING_ITEM) regex_text = src.parseString(KEY_REGEX_TEXT) ?: "" @@ -766,28 +769,34 @@ class Column( } } + private fun JSONObject.putIfTrue(key:String,value:Boolean){ + if(value) put( key,true) + } + @Throws(JSONException::class) fun encodeJSON(dst : JSONObject, old_index : Int) { dst.put(KEY_ACCOUNT_ROW_ID, access_info.db_id) dst.put(KEY_TYPE, column_type) dst.put(KEY_COLUMN_ID, column_id) - dst.put(KEY_DONT_CLOSE, dont_close) - dst.put(KEY_WITH_ATTACHMENT, with_attachment) - dst.put(KEY_WITH_HIGHLIGHT, with_highlight) - dst.put(KEY_DONT_SHOW_BOOST, dont_show_boost) - dst.put(KEY_DONT_SHOW_FOLLOW, dont_show_follow) - dst.put(KEY_DONT_SHOW_FAVOURITE, dont_show_favourite) - dst.put(KEY_DONT_SHOW_REPLY, dont_show_reply) - dst.put(KEY_DONT_SHOW_REACTION, dont_show_reaction) - dst.put(KEY_DONT_SHOW_VOTE, dont_show_vote) - dst.put(KEY_DONT_SHOW_NORMAL_TOOT, dont_show_normal_toot) - dst.put(KEY_DONT_STREAMING, dont_streaming) - dst.put(KEY_DONT_AUTO_REFRESH, dont_auto_refresh) - dst.put(KEY_HIDE_MEDIA_DEFAULT, hide_media_default) - dst.put(KEY_SYSTEM_NOTIFICATION_NOT_RELATED, system_notification_not_related) - dst.put(KEY_INSTANCE_LOCAL, instance_local) - dst.put(KEY_ENABLE_SPEECH, enable_speech) + dst.putIfTrue(KEY_DONT_CLOSE, dont_close) + dst.putIfTrue(KEY_WITH_ATTACHMENT, with_attachment) + dst.putIfTrue(KEY_WITH_HIGHLIGHT, with_highlight) + dst.putIfTrue(KEY_DONT_SHOW_BOOST, dont_show_boost) + dst.putIfTrue(KEY_DONT_SHOW_FOLLOW, dont_show_follow) + dst.putIfTrue(KEY_DONT_SHOW_FAVOURITE, dont_show_favourite) + dst.putIfTrue(KEY_DONT_SHOW_REPLY, dont_show_reply) + dst.putIfTrue(KEY_DONT_SHOW_REACTION, dont_show_reaction) + dst.putIfTrue(KEY_DONT_SHOW_VOTE, dont_show_vote) + dst.putIfTrue(KEY_DONT_SHOW_NORMAL_TOOT, dont_show_normal_toot) + dst.putIfTrue(KEY_DONT_STREAMING, dont_streaming) + dst.putIfTrue(KEY_DONT_AUTO_REFRESH, dont_auto_refresh) + dst.putIfTrue(KEY_HIDE_MEDIA_DEFAULT, hide_media_default) + dst.putIfTrue(KEY_SYSTEM_NOTIFICATION_NOT_RELATED, system_notification_not_related) + dst.putIfTrue(KEY_INSTANCE_LOCAL, instance_local) + dst.putIfTrue(KEY_ENABLE_SPEECH, enable_speech) + dst.putIfTrue(KEY_USE_OLD_API, use_old_api) + last_viewing_item_id?.putTo(dst, KEY_LAST_VIEWING_ITEM) dst.put(KEY_REGEX_TEXT, regex_text) @@ -1745,7 +1754,11 @@ class Column( env.update(client, parser) } - private var useConversationSummarys = false + // DMカラム更新時に新APIの利用に成功したなら真 + internal var useConversationSummarys = false + + // DMカラムのストリーミングイベントで新形式のイベントを利用できたなら真 + internal var useConversationSummaryStreaming = false internal fun startLoading() { cancelLastTask() @@ -2418,24 +2431,26 @@ class Column( TYPE_DIRECT_MESSAGES -> { - // try 2.6.0 new API https://github.com/tootsuite/mastodon/pull/8832 - val result = getConversationSummary(client, PATH_DIRECT_MESSAGES2) - return when { - - // cancelled - result == null -> null - - // not error - result.error.isNullOrBlank() -> { - useConversationSummarys = true - result - } - - else -> { - // fallback to old api - getStatuses(client, PATH_DIRECT_MESSAGES) + useConversationSummarys = false + if(! use_old_api){ + + // try 2.6.0 new API https://github.com/tootsuite/mastodon/pull/8832 + val result = getConversationSummary(client, PATH_DIRECT_MESSAGES2) + + when{ + // cancelled + result == null -> return null + + // not error + result.error.isNullOrBlank() -> { + useConversationSummarys = true + return result + } } } + + // fallback to old api + return getStatuses(client, PATH_DIRECT_MESSAGES) } TYPE_LOCAL -> return getStatuses(client, makePublicLocalUrl()) @@ -6002,18 +6017,27 @@ class Column( } } + override fun onTimelineItem(item : TimelineItem) { if(is_dispose.get()) return if(item is TootConversationSummary) { if(column_type != TYPE_DIRECT_MESSAGES) return if(isFiltered(item.last_status)) return + if( use_old_api ){ + useConversationSummaryStreaming = false + return + }else{ + useConversationSummaryStreaming = true + } }else if(item is TootNotification) { if(column_type != TYPE_NOTIFICATIONS) return if(isFiltered(item)) return } else if(item is TootStatus) { if(column_type == TYPE_NOTIFICATIONS) return - if(useConversationSummarys) return + + // マストドン2.6.0形式のDMカラム用イベントを利用したならば、その直後に発生する普通の投稿イベントを無視する + if( useConversationSummaryStreaming ) return if(column_type == TYPE_LOCAL && ! isMisskey && item.account.acct.indexOf('@') != - 1) return if(isFiltered(item)) return diff --git a/app/src/main/java/jp/juggler/subwaytooter/ColumnViewHolder.kt b/app/src/main/java/jp/juggler/subwaytooter/ColumnViewHolder.kt index bde7a275..718837c8 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ColumnViewHolder.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ColumnViewHolder.kt @@ -104,6 +104,7 @@ class ColumnViewHolder( private val cbHideMediaDefault : CheckBox private val cbSystemNotificationNotRelated : CheckBox private val cbEnableSpeech : CheckBox + private val cbOldApi : CheckBox private val llRegexFilter : View private val btnDeleteNotification : Button @@ -194,7 +195,7 @@ class ColumnViewHolder( listView = viewRoot.findViewById(R.id.listView) if(Pref.bpShareViewPool(activity.pref)) { - listView.setRecycledViewPool( activity.viewPool) + listView.setRecycledViewPool(activity.viewPool) } listView.itemAnimator = null // @@ -241,6 +242,7 @@ class ColumnViewHolder( cbHideMediaDefault = viewRoot.findViewById(R.id.cbHideMediaDefault) cbSystemNotificationNotRelated = viewRoot.findViewById(R.id.cbSystemNotificationNotRelated) cbEnableSpeech = viewRoot.findViewById(R.id.cbEnableSpeech) + cbOldApi = viewRoot.findViewById(R.id.cbOldApi) etRegexFilter = viewRoot.findViewById(R.id.etRegexFilter) llRegexFilter = viewRoot.findViewById(R.id.llRegexFilter) tvRegexFilterError = viewRoot.findViewById(R.id.tvRegexFilterError) @@ -276,6 +278,7 @@ class ColumnViewHolder( cbHideMediaDefault.setOnCheckedChangeListener(this) cbSystemNotificationNotRelated.setOnCheckedChangeListener(this) cbEnableSpeech.setOnCheckedChangeListener(this) + cbOldApi.setOnCheckedChangeListener(this) // 入力の追跡 etRegexFilter.addTextChangedListener(object : TextWatcher { @@ -355,25 +358,25 @@ class ColumnViewHolder( //復元後にもここを通るがこれは正常である val sp = column.scroll_save - if(sp==null) { -// val lvi = column.last_viewing_item_id -// if( lvi != null ){ -// column.last_viewing_item_id = null -// val listIndex = column.findListIndexByTimelineId(lvi) -// if( listIndex != null){ -// log.d( -// "restoreScrollPosition [$page_idx] %s , restore from last_viewing_item_id %d" -// , column.getColumnName( true ) -// ,listIndex -// ) -// ScrollPosition(column.toAdapterIndex(listIndex),0).restore(this@ColumnViewHolder) -// return -// } -// } - + if(sp == null) { + // val lvi = column.last_viewing_item_id + // if( lvi != null ){ + // column.last_viewing_item_id = null + // val listIndex = column.findListIndexByTimelineId(lvi) + // if( listIndex != null){ + // log.d( + // "restoreScrollPosition [$page_idx] %s , restore from last_viewing_item_id %d" + // , column.getColumnName( true ) + // ,listIndex + // ) + // ScrollPosition(column.toAdapterIndex(listIndex),0).restore(this@ColumnViewHolder) + // return + // } + // } + log.d( "restoreScrollPosition [$page_idx] %s , column has no saved scroll position." - , column.getColumnName( true ) + , column.getColumnName(true) ) return } @@ -383,17 +386,17 @@ class ColumnViewHolder( if(listView.visibility != View.VISIBLE) { log.d( "restoreScrollPosition [$page_idx] %s , listView is not visible. saved position %s,%s is dropped." - ,column.getColumnName(true) - ,sp.adapterIndex - ,sp.offset + , column.getColumnName(true) + , sp.adapterIndex + , sp.offset ) } else { log.d( "restoreScrollPosition [%d] %s , listView is visible. resume %s,%s" - ,page_idx - ,column.getColumnName(true) - ,sp.adapterIndex - ,sp.offset + , page_idx + , column.getColumnName(true) + , sp.adapterIndex + , sp.offset ) sp.restore(this@ColumnViewHolder) } @@ -462,6 +465,7 @@ class ColumnViewHolder( cbHideMediaDefault.isChecked = column.hide_media_default cbSystemNotificationNotRelated.isChecked = column.system_notification_not_related cbEnableSpeech.isChecked = column.enable_speech + cbOldApi.isChecked = column.use_old_api etRegexFilter.setText(column.regex_text) etSearch.setText(column.search_query) @@ -488,6 +492,8 @@ class ColumnViewHolder( vg(cbHideMediaDefault, column.canNSFWDefault()) vg(cbSystemNotificationNotRelated, column.column_type == Column.TYPE_NOTIFICATIONS) vg(cbEnableSpeech, column.canSpeech()) + vg(cbOldApi, column.column_type == Column.TYPE_DIRECT_MESSAGES) + vg(btnDeleteNotification, column.column_type == Column.TYPE_NOTIFICATIONS) vg(llSearch, column.isSearchColumn) @@ -503,11 +509,11 @@ class ColumnViewHolder( val canRefreshBottom = column.canRefreshBottomBySwipe() refreshLayout.isEnabled = canRefreshTop || canRefreshBottom - refreshLayout.direction = if( canRefreshTop && canRefreshBottom) { + refreshLayout.direction = if(canRefreshTop && canRefreshBottom) { SwipyRefreshLayoutDirection.BOTH - }else if( canRefreshTop){ + } else if(canRefreshTop) { SwipyRefreshLayoutDirection.TOP - }else{ + } else { SwipyRefreshLayoutDirection.BOTTOM } @@ -760,7 +766,7 @@ class ColumnViewHolder( return } - column.startRefresh(false, direction == SwipyRefreshLayoutDirection.BOTTOM ) + column.startRefresh(false, direction == SwipyRefreshLayoutDirection.BOTTOM) } override fun onCheckedChanged(view : CompoundButton, isChecked : Boolean) { @@ -803,19 +809,19 @@ class ColumnViewHolder( activity.app_state.saveColumnList() column.startLoading() } - + R.id.cbDontShowReaction -> { column.dont_show_reaction = isChecked activity.app_state.saveColumnList() column.startLoading() } - + R.id.cbDontShowVote -> { column.dont_show_vote = isChecked activity.app_state.saveColumnList() column.startLoading() } - + R.id.cbDontShowNormalToot -> { column.dont_show_normal_toot = isChecked activity.app_state.saveColumnList() @@ -870,6 +876,12 @@ class ColumnViewHolder( column.enable_speech = isChecked activity.app_state.saveColumnList() } + + R.id.cbOldApi -> { + column.use_old_api = isChecked + activity.app_state.saveColumnList() + column.startLoading() + } } } @@ -883,7 +895,7 @@ class ColumnViewHolder( column.addColumnViewHolder(this) when(v.id) { - R.id.btnColumnClose -> activity.closeColumn(column ) + R.id.btnColumnClose -> activity.closeColumn(column) R.id.btnColumnReload -> { App1.custom_emoji_cache.clearErrorCache() @@ -1083,7 +1095,7 @@ class ColumnViewHolder( showToast(activity, true, refreshError) } - fun saveScrollPosition() :Boolean{ + fun saveScrollPosition() : Boolean { val column = this.column when { column == null -> log.d("saveScrollPosition [%d] , column==null", page_idx) diff --git a/app/src/main/res/layout/page_column.xml b/app/src/main/res/layout/page_column.xml index c0680995..503d3908 100644 --- a/app/src/main/res/layout/page_column.xml +++ b/app/src/main/res/layout/page_column.xml @@ -262,6 +262,13 @@ android:text="@string/enable_speech" /> + + …周辺のアカウントTL %1$s周辺のアカウントTL 検証時刻 + 古いAPIを使う diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 083c36a0..c2fe51c6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -793,5 +793,6 @@ Account timeline around … Account timeline around %1$s verified at + Use old API