From f482b3bff19e6532932fa3a8a094f773e31b1e78 Mon Sep 17 00:00:00 2001 From: tateisu Date: Thu, 6 Jun 2019 08:31:33 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF=E3=82=BF?= =?UTF-8?q?=E3=80=82=E3=81=82=E3=81=A8misskey=20v11=E3=81=A7=E3=83=9F?= =?UTF-8?q?=E3=83=A5=E3=83=BC=E3=83=88=E4=B8=80=E8=A6=A7=E3=82=92=E8=AA=AD?= =?UTF-8?q?=E3=82=81=E3=81=AA=E3=81=8B=E3=81=A3=E3=81=9F=E3=83=90=E3=82=B0?= =?UTF-8?q?=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jp/juggler/subwaytooter/ColumnTask.kt | 4 + .../jp/juggler/subwaytooter/ColumnTask_Gap.kt | 265 ++++---- .../subwaytooter/ColumnTask_Loading.kt | 193 +++--- .../subwaytooter/ColumnTask_Refresh.kt | 367 +++++------ .../jp/juggler/subwaytooter/ColumnTypeProc.kt | 619 +++++++++--------- .../jp/juggler/subwaytooter/ColumnUtil.kt | 20 +- 6 files changed, 745 insertions(+), 723 deletions(-) diff --git a/app/src/main/java/jp/juggler/subwaytooter/ColumnTask.kt b/app/src/main/java/jp/juggler/subwaytooter/ColumnTask.kt index 94e1d1b6..1cd5772f 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ColumnTask.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ColumnTask.kt @@ -23,6 +23,10 @@ abstract class ColumnTask( val ctType : ColumnTaskType ) : AsyncTask() { + override fun onCancelled(result : TootApiResult?) { + onPostExecute(null) + } + val ctStarted = AtomicBoolean(false) val ctClosed = AtomicBoolean(false) diff --git a/app/src/main/java/jp/juggler/subwaytooter/ColumnTask_Gap.kt b/app/src/main/java/jp/juggler/subwaytooter/ColumnTask_Gap.kt index e466c886..5f8e3d4c 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ColumnTask_Gap.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ColumnTask_Gap.kt @@ -19,12 +19,141 @@ class ColumnTask_Gap( ) : ColumnTask(columnArg, ColumnTaskType.GAP) { companion object { - private val log = LogCategory("CT_Gap") + internal val log = LogCategory("CT_Gap") } private var max_id : EntityId? = gap.max_id private var since_id : EntityId? = gap.since_id + override fun doInBackground(vararg unused : Void) : TootApiResult? { + ctStarted.set(true) + + val client = TootApiClient(context, callback = object : TootApiCallback { + override val isApiCancelled : Boolean + get() = isCancelled || column.is_dispose.get() + + override fun publishApiProgress(s : String) { + runOnMainLooper { + if(isCancelled) return@runOnMainLooper + column.task_progress = s + column.fireShowContent(reason = "gap progress", changeList = ArrayList()) + } + } + }) + + client.account = access_info + + try { + return (columnTypeProcMap[column.column_type] ?: columnTypeProcMap[Column.TYPE_HOME]) + .gap(this, client) + + } finally { + try { + column.updateRelation(client, list_tmp, column.who_account, parser) + } catch(ex : Throwable) { + log.trace(ex) + } + + ctClosed.set(true) + runOnMainLooperDelayed(333L) { + if(! isCancelled) column.fireShowColumnStatus() + } + } + } + + override fun onPostExecute(result : TootApiResult?) { + if(column.is_dispose.get()) return + + if(isCancelled || result == null) { + return + } + + try { + + column.lastTask = null + column.bRefreshLoading = false + + val error = result.error + if(error != null) { + column.mRefreshLoadingError = error + column.fireShowContent(reason = "gap error", changeList = ArrayList()) + return + } + + val list_tmp = this.list_tmp + if(list_tmp == null) { + column.fireShowContent(reason = "gap list_tmp is null", changeList = ArrayList()) + return + } + + val list_new = column.duplicate_map.filterDuplicate(list_tmp) + // 0個でもギャップを消すために以下の処理を続ける + + val changeList = ArrayList() + + column.replaceConversationSummary(changeList, list_new, column.list_data) + + val added = list_new.size // may 0 + + val position = column.list_data.indexOf(gap) + if(position == - 1) { + log.d("gap not found..") + column.fireShowContent(reason = "gap not found", changeList = ArrayList()) + return + } + + // idx番目の要素がListViewのtopから何ピクセル下にあるか + var restore_idx = position + 1 + var restore_y = 0 + val holder = column.viewHolder + if(holder != null) { + try { + restore_y = holder.getListItemOffset(restore_idx) + } catch(ex : IndexOutOfBoundsException) { + restore_idx = position + try { + restore_y = holder.getListItemOffset(restore_idx) + } catch(ex2 : IndexOutOfBoundsException) { + restore_idx = - 1 + } + } + } + + column.list_data.removeAt(position) + column.list_data.addAll(position, list_new) + + changeList.add(AdapterChange(AdapterChangeType.RangeRemove, position)) + if(added > 0) { + changeList.add( + AdapterChange( + AdapterChangeType.RangeInsert, + position, + added + ) + ) + } + column.fireShowContent(reason = "gap updated", changeList = changeList) + + if(holder != null) { + if(restore_idx >= 0) { + // ギャップが画面内にあるなら + holder.setListItemTop(restore_idx + added - 1, restore_y) + } else { + // ギャップが画面内にない場合、何もしない + } + } else { + val scroll_save = column.scroll_save + if(scroll_save != null) { + scroll_save.adapterIndex += added - 1 + } + } + + column.updateMisskeyCapture() + } finally { + column.fireShowColumnStatus() + } + } + internal fun getAccountList( client : TootApiClient, path_base : String, @@ -640,136 +769,4 @@ class ColumnTask_Gap( return result } - override fun doInBackground(vararg unused : Void) : TootApiResult? { - ctStarted.set(true) - - val client = TootApiClient(context, callback = object : TootApiCallback { - override val isApiCancelled : Boolean - get() = isCancelled || column.is_dispose.get() - - override fun publishApiProgress(s : String) { - runOnMainLooper { - if(isCancelled) return@runOnMainLooper - column.task_progress = s - column.fireShowContent(reason = "gap progress", changeList = ArrayList()) - } - } - }) - - client.account = access_info - - try { - return (columnTypeProcMap[column.column_type]?:columnTypeProcMap[Column.TYPE_HOME]) - .procGap(this,client) - - } finally { - try { - column.updateRelation(client, list_tmp, column.who_account, parser) - } catch(ex : Throwable) { - log.trace(ex) - } - - ctClosed.set(true) - runOnMainLooperDelayed(333L) { - if(! isCancelled) column.fireShowColumnStatus() - } - } - } - - override fun onCancelled(result : TootApiResult?) { - onPostExecute(null) - } - - override fun onPostExecute(result : TootApiResult?) { - if(column.is_dispose.get()) return - - if(isCancelled || result == null) { - return - } - - try { - - column.lastTask = null - column.bRefreshLoading = false - - val error = result.error - if(error != null) { - column.mRefreshLoadingError = error - column.fireShowContent(reason = "gap error", changeList = ArrayList()) - return - } - - val list_tmp = this.list_tmp - if(list_tmp == null) { - column.fireShowContent(reason = "gap list_tmp is null", changeList = ArrayList()) - return - } - - val list_new = column.duplicate_map.filterDuplicate(list_tmp) - // 0個でもギャップを消すために以下の処理を続ける - - val changeList = ArrayList() - - column.replaceConversationSummary(changeList, list_new, column.list_data) - - val added = list_new.size // may 0 - - val position = column.list_data.indexOf(gap) - if(position == - 1) { - log.d("gap not found..") - column.fireShowContent(reason = "gap not found", changeList = ArrayList()) - return - } - - // idx番目の要素がListViewのtopから何ピクセル下にあるか - var restore_idx = position + 1 - var restore_y = 0 - val holder = column.viewHolder - if(holder != null) { - try { - restore_y = holder.getListItemOffset(restore_idx) - } catch(ex : IndexOutOfBoundsException) { - restore_idx = position - try { - restore_y = holder.getListItemOffset(restore_idx) - } catch(ex2 : IndexOutOfBoundsException) { - restore_idx = - 1 - } - } - } - - column.list_data.removeAt(position) - column.list_data.addAll(position, list_new) - - changeList.add(AdapterChange(AdapterChangeType.RangeRemove, position)) - if(added > 0) { - changeList.add( - AdapterChange( - AdapterChangeType.RangeInsert, - position, - added - ) - ) - } - column.fireShowContent(reason = "gap updated", changeList = changeList) - - if(holder != null) { - if(restore_idx >= 0) { - // ギャップが画面内にあるなら - holder.setListItemTop(restore_idx + added - 1, restore_y) - } else { - // ギャップが画面内にない場合、何もしない - } - } else { - val scroll_save = column.scroll_save - if(scroll_save != null) { - scroll_save.adapterIndex += added - 1 - } - } - - column.updateMisskeyCapture() - } finally { - column.fireShowColumnStatus() - } - } -} \ No newline at end of file +} diff --git a/app/src/main/java/jp/juggler/subwaytooter/ColumnTask_Loading.kt b/app/src/main/java/jp/juggler/subwaytooter/ColumnTask_Loading.kt index 31fb8f7e..5f140054 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ColumnTask_Loading.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ColumnTask_Loading.kt @@ -1,8 +1,6 @@ package jp.juggler.subwaytooter -import android.annotation.SuppressLint import android.os.SystemClock -import android.view.Gravity import jp.juggler.subwaytooter.api.TootApiCallback import jp.juggler.subwaytooter.api.TootApiClient import jp.juggler.subwaytooter.api.TootApiResult @@ -15,19 +13,98 @@ import org.json.JSONObject import java.util.* import kotlin.collections.ArrayList -@SuppressLint("StaticFieldLeak") class ColumnTask_Loading( columnArg : Column ) : ColumnTask(columnArg, ColumnTaskType.LOADING) { companion object { - val log = LogCategory("CT_Loading") + internal val log = LogCategory("CT_Loading") } internal var instance_tmp : TootInstance? = null internal var list_pinned : ArrayList? = null + override fun doInBackground(vararg unused : Void) : TootApiResult? { + ctStarted.set(true) + + if(Pref.bpInstanceTicker(pref)) { + InstanceTicker.load() + } + + val client = TootApiClient(context, callback = object : TootApiCallback { + override val isApiCancelled : Boolean + get() = isCancelled || column.is_dispose.get() + + override fun publishApiProgress(s : String) { + runOnMainLooper { + if(isCancelled) return@runOnMainLooper + column.task_progress = s + column.fireShowContent(reason = "loading progress", changeList = ArrayList()) + } + } + }) + + client.account = access_info + + try { + val result : TootApiResult? = access_info.checkConfirmed(context, client) + if(result == null || result.error != null) return result + + column.muted_word2 = column.encodeFilterTree(column.loadFilter2(client)) + + return (columnTypeProcMap[column.column_type] ?: columnTypeProcMap[Column.TYPE_HOME]) + .loading(this, client) + + } finally { + try { + column.updateRelation(client, list_tmp, column.who_account, parser) + } catch(ex : Throwable) { + log.trace(ex) + } + ctClosed.set(true) + runOnMainLooperDelayed(333L) { + if(! isCancelled) column.fireShowColumnStatus() + } + } + } + + override fun onPostExecute(result : TootApiResult?) { + if(column.is_dispose.get()) return + + if(isCancelled || result == null) { + return + } + + column.bInitialLoading = false + column.lastTask = null + + if(result.error != null) { + column.mInitialLoadingError = result.error ?: "" + } else { + column.duplicate_map.clear() + column.list_data.clear() + val list_tmp = this.list_tmp + if(list_tmp != null) { + val list_pinned = this.list_pinned + if(list_pinned?.isNotEmpty() == true) { + val list_new = column.duplicate_map.filterDuplicate(list_pinned) + column.list_data.addAll(list_new) + } + val list_new = column.duplicate_map.filterDuplicate(list_tmp) + column.list_data.addAll(list_new) + } + + column.resumeStreaming(false) + } + column.fireShowContent(reason = "loading updated", reset = true) + + // 初期ロードの直後は先頭に移動する + column.viewHolder?.scrollToTop() + + column.updateMisskeyCapture() + } + internal fun getInstanceInformation( client : TootApiClient, instance_name : String? @@ -62,7 +139,7 @@ class ColumnTask_Loading( log.d("getStatusesPinned: list size=%s", list_pinned?.size ?: - 1) } - internal fun getStatuses( + internal fun getStatusList( client : TootApiClient, path_base : String?, aroundMin : Boolean = false, @@ -403,7 +480,7 @@ class ColumnTask_Loading( return result } - internal fun parseAccountList( + internal fun getAccountList( client : TootApiClient, path_base : String, emptyMessage : String? = null, @@ -480,7 +557,7 @@ class ColumnTask_Loading( return result } - internal fun parseDomainList( + internal fun getDomainList( client : TootApiClient, path_base : String ) : TootApiResult? { @@ -493,7 +570,7 @@ class ColumnTask_Loading( return result } - internal fun parseReports(client : TootApiClient, path_base : String) : TootApiResult? { + internal fun getReportList(client : TootApiClient, path_base : String) : TootApiResult? { val result = client.request(path_base) if(result != null) { val src = parseList(::TootReport, result.jsonArray) @@ -522,7 +599,7 @@ class ColumnTask_Loading( return result } - internal fun parseNotifications( + internal fun getNotificationList( client : TootApiClient, fromAcct : String? = null ) : TootApiResult? { @@ -606,7 +683,10 @@ class ColumnTask_Loading( return result } - internal fun getPublicAroundStatuses(client : TootApiClient, url : String) : TootApiResult? { + internal fun getPublicAroundStatuses( + client : TootApiClient, + url : String + ) : TootApiResult? { // (Mastodonのみ対応) var instance = access_info.instance @@ -633,14 +713,14 @@ class ColumnTask_Loading( var bInstanceTooOld = false if(instance?.versionGE(TootInstance.VERSION_2_6_0) == true) { // 指定より新しいトゥート - result = getStatuses(client, url, aroundMin = true) + result = getStatusList(client, url, aroundMin = true) if(result == null || result.error != null) return result } else { bInstanceTooOld = true } // 指定位置より古いトゥート - result = getStatuses(client, url, aroundMax = true) + result = getStatusList(client, url, aroundMax = true) if(result == null || result.error != null) return result list_tmp?.sortBy { it.getOrderId() } @@ -685,14 +765,14 @@ class ColumnTask_Loading( var bInstanceTooOld = false if(instance?.versionGE(TootInstance.VERSION_2_6_0) == true) { // 指定より新しいトゥート - result = getStatuses(client, path, aroundMin = true) + result = getStatusList(client, path, aroundMin = true) if(result == null || result.error != null) return result } else { bInstanceTooOld = true } // 指定位置より古いトゥート - result = getStatuses(client, path, aroundMax = true) + result = getStatusList(client, path, aroundMax = true) if(result == null || result.error != null) return result list_tmp?.sortBy { it.getOrderId() } @@ -718,88 +798,5 @@ class ColumnTask_Loading( return result } - override fun doInBackground(vararg unused : Void) : TootApiResult? { - ctStarted.set(true) - - if(Pref.bpInstanceTicker(pref)) { - InstanceTicker.load() - } - - val client = TootApiClient(context, callback = object : TootApiCallback { - override val isApiCancelled : Boolean - get() = isCancelled || column.is_dispose.get() - - override fun publishApiProgress(s : String) { - runOnMainLooper { - if(isCancelled) return@runOnMainLooper - column.task_progress = s - column.fireShowContent(reason = "loading progress", changeList = ArrayList()) - } - } - }) - - client.account = access_info - - - try { - val result : TootApiResult? = access_info.checkConfirmed(context, client) - if(result == null || result.error != null) return result - - column.muted_word2 = column.encodeFilterTree(column.loadFilter2(client)) - - return (columnTypeProcMap[column.column_type]?:columnTypeProcMap[Column.TYPE_HOME]) - .procLoading(this,client) - - } finally { - try { - column.updateRelation(client, list_tmp, column.who_account, parser) - } catch(ex : Throwable) { - log.trace(ex) - } - ctClosed.set(true) - runOnMainLooperDelayed(333L) { - if(! isCancelled) column.fireShowColumnStatus() - } - } - } - - override fun onCancelled(result : TootApiResult?) { - onPostExecute(null) - } - - override fun onPostExecute(result : TootApiResult?) { - if(column.is_dispose.get()) return - - if(isCancelled || result == null) { - return - } - - column.bInitialLoading = false - column.lastTask = null - - if(result.error != null) { - column.mInitialLoadingError = result.error ?: "" - } else { - column.duplicate_map.clear() - column.list_data.clear() - val list_tmp = this.list_tmp - if(list_tmp != null) { - val list_pinned = this.list_pinned - if(list_pinned?.isNotEmpty() == true) { - val list_new = column.duplicate_map.filterDuplicate(list_pinned) - column.list_data.addAll(list_new) - } - val list_new = column.duplicate_map.filterDuplicate(list_tmp) - column.list_data.addAll(list_new) - } - - column.resumeStreaming(false) - } - column.fireShowContent(reason = "loading updated", reset = true) - - // 初期ロードの直後は先頭に移動する - column.viewHolder?.scrollToTop() - - column.updateMisskeyCapture() - } } + diff --git a/app/src/main/java/jp/juggler/subwaytooter/ColumnTask_Refresh.kt b/app/src/main/java/jp/juggler/subwaytooter/ColumnTask_Refresh.kt index 60726a4f..9608661b 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ColumnTask_Refresh.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ColumnTask_Refresh.kt @@ -1,6 +1,5 @@ package jp.juggler.subwaytooter -import android.annotation.SuppressLint import android.os.SystemClock import jp.juggler.subwaytooter.api.TootApiCallback import jp.juggler.subwaytooter.api.TootApiClient @@ -12,10 +11,9 @@ import jp.juggler.util.* import org.json.JSONArray import org.json.JSONObject -@SuppressLint("StaticFieldLeak") class ColumnTask_Refresh( columnArg : Column, - internal val bSilent : Boolean, + private val bSilent : Boolean, internal val bBottom : Boolean, internal val posted_status_id : EntityId? = null, internal val refresh_after_toot : Int = - 1 @@ -25,7 +23,183 @@ class ColumnTask_Refresh( ) { companion object { - val log = LogCategory("CT_Refresh") + internal val log = LogCategory("CT_Refresh") + } + + private var filterUpdated = false + + override fun doInBackground(vararg unused : Void) : TootApiResult? { + ctStarted.set(true) + + val client = TootApiClient(context, callback = object : TootApiCallback { + override val isApiCancelled : Boolean + get() = isCancelled || column.is_dispose.get() + + override fun publishApiProgress(s : String) { + runOnMainLooper { + if(isCancelled) return@runOnMainLooper + column.task_progress = s + column.fireShowContent(reason = "refresh progress", changeList = ArrayList()) + } + } + }) + client.account = access_info + try { + + if(! bBottom) { + val filterList = column.loadFilter2(client) + if(filterList != null) { + column.muted_word2 = column.encodeFilterTree(filterList) + filterUpdated = true + } + } + + return (columnTypeProcMap[column.column_type] ?: columnTypeProcMap[Column.TYPE_HOME]) + .refresh(this, client) + } finally { + try { + column.updateRelation(client, list_tmp, column.who_account, parser) + } catch(ex : Throwable) { + log.trace(ex) + } + ctClosed.set(true) + runOnMainLooperDelayed(333L) { + if(! isCancelled) column.fireShowColumnStatus() + } + } + } + + override fun onPostExecute(result : TootApiResult?) { + if(column.is_dispose.get()) return + + if(isCancelled || result == null) { + return + } + try { + column.lastTask = null + column.bRefreshLoading = false + + if(filterUpdated) { + column.checkFiltersForListData(column.muted_word2) + } + + val error = result.error + if(error != null) { + column.mRefreshLoadingError = error + column.mRefreshLoadingErrorTime = SystemClock.elapsedRealtime() + column.fireShowContent(reason = "refresh error", changeList = ArrayList()) + return + } + + val list_new = column.duplicate_map.filterDuplicate(list_tmp) + if(list_new.isEmpty()) { + column.fireShowContent( + reason = "refresh list_new is empty", + changeList = ArrayList() + ) + return + } + + // 事前にスクロール位置を覚えておく + var sp : ScrollPosition? = null + val holder = column.viewHolder + if(holder != null) { + sp = holder.scrollPosition + } + + + + if(bBottom) { + val changeList = listOf( + AdapterChange( + AdapterChangeType.RangeInsert, + column.list_data.size, + list_new.size + ) + ) + column.list_data.addAll(list_new) + column.fireShowContent(reason = "refresh updated bottom", changeList = changeList) + + // 新着が少しだけ見えるようにスクロール位置を移動する + if(sp != null) { + holder?.setScrollPosition(sp, 20f) + } + } else { + + val changeList = ArrayList() + + if(column.list_data.isNotEmpty() && column.list_data[0] is TootGap) { + changeList.add(AdapterChange(AdapterChangeType.RangeRemove, 0, 1)) + column.list_data.removeAt(0) + } + + for(o in list_new) { + if(o is TootStatus) { + val highlight_sound = o.highlight_sound + if(highlight_sound != null) { + App1.sound(highlight_sound) + break + } + } + } + + column.replaceConversationSummary(changeList, list_new, column.list_data) + + val added = list_new.size // may 0 + + // 投稿後のリフレッシュなら当該投稿の位置を探す + var status_index = - 1 + for(i in 0 until added) { + val o = list_new[i] + if(o is TootStatus && o.id == posted_status_id) { + status_index = i + break + } + } + + changeList.add(AdapterChange(AdapterChangeType.RangeInsert, 0, added)) + column.list_data.addAll(0, list_new) + column.fireShowContent(reason = "refresh updated head", changeList = changeList) + + if(status_index >= 0 && refresh_after_toot == Pref.RAT_REFRESH_SCROLL) { + // 投稿後にその投稿にスクロールする + if(holder != null) { + holder.setScrollPosition( + ScrollPosition(column.toAdapterIndex(status_index)), + 0f + ) + } else { + column.scroll_save = ScrollPosition(column.toAdapterIndex(status_index)) + } + } else { + // + val scroll_save = column.scroll_save + when { + // ViewHolderがある場合は増加件数分+deltaの位置にスクロールする + sp != null -> { + sp.adapterIndex += added + val delta = if(bSilent) 0f else - 20f + holder?.setScrollPosition(sp, delta) + } + // ViewHolderがなくて保存中の位置がある場合、増加件数分ずらす。deltaは難しいので反映しない + scroll_save != null -> scroll_save.adapterIndex += added + // 保存中の位置がない場合、保存中の位置を新しく作る + else -> column.scroll_save = + ScrollPosition(column.toAdapterIndex(added)) + } + } + } + + column.updateMisskeyCapture() + + } finally { + column.fireShowColumnStatus() + + if(! bBottom) { + column.bRefreshingTop = false + column.resumeStreaming(false) + } + } } internal fun getAccountList( @@ -406,7 +580,7 @@ class ColumnTask_Refresh( var result = if(isMisskey) { client.request( path_base, - params.addRangeMisskey( bBottom).toPostRequestBuilder() + params.addRangeMisskey(bBottom).toPostRequestBuilder() ) } else { client.request(column.addRange(bBottom, path_base)) @@ -624,7 +798,7 @@ class ColumnTask_Refresh( var result = when { isMisskey -> client.request( path_base, - params.addRangeMisskey( bBottom).toPostRequestBuilder() + params.addRangeMisskey(bBottom).toPostRequestBuilder() ) aroundMin -> client.request(column.addRangeMin(path_base)) @@ -895,7 +1069,7 @@ class ColumnTask_Refresh( var result = when { isMisskey -> client.request( path_base, - params.addRangeMisskey( bBottom).toPostRequestBuilder() + params.addRangeMisskey(bBottom).toPostRequestBuilder() ) aroundMin -> client.request(column.addRangeMin(path_base)) @@ -1135,183 +1309,4 @@ class ColumnTask_Refresh( return firstResult } - private var filterUpdated = false - - override fun doInBackground(vararg unused : Void) : TootApiResult? { - ctStarted.set(true) - - val client = TootApiClient(context, callback = object : TootApiCallback { - override val isApiCancelled : Boolean - get() = isCancelled || column.is_dispose.get() - - override fun publishApiProgress(s : String) { - runOnMainLooper { - if(isCancelled) return@runOnMainLooper - column.task_progress = s - column.fireShowContent(reason = "refresh progress", changeList = ArrayList()) - } - } - }) - client.account = access_info - try { - - if(! bBottom) { - val filterList = column.loadFilter2(client) - if(filterList != null) { - column.muted_word2 = column.encodeFilterTree(filterList) - filterUpdated = true - } - } - - return (columnTypeProcMap[column.column_type]?:columnTypeProcMap[Column.TYPE_HOME]) - .procRefresh(this,client) - } finally { - try { - column.updateRelation(client, list_tmp, column.who_account, parser) - } catch(ex : Throwable) { - log.trace(ex) - } - ctClosed.set(true) - runOnMainLooperDelayed(333L) { - if(! isCancelled) column.fireShowColumnStatus() - } - } - } - - override fun onCancelled(result : TootApiResult?) { - onPostExecute(null) - } - - override fun onPostExecute(result : TootApiResult?) { - if(column.is_dispose.get()) return - - if(isCancelled || result == null) { - return - } - try { - column.lastTask = null - column.bRefreshLoading = false - - if(filterUpdated) { - column.checkFiltersForListData(column.muted_word2) - } - - val error = result.error - if(error != null) { - column.mRefreshLoadingError = error - column.mRefreshLoadingErrorTime = SystemClock.elapsedRealtime() - column.fireShowContent(reason = "refresh error", changeList = ArrayList()) - return - } - - val list_new = column.duplicate_map.filterDuplicate(list_tmp) - if(list_new.isEmpty()) { - column.fireShowContent( - reason = "refresh list_new is empty", - changeList = ArrayList() - ) - return - } - - // 事前にスクロール位置を覚えておく - var sp : ScrollPosition? = null - val holder = column.viewHolder - if(holder != null) { - sp = holder.scrollPosition - } - - - - if(bBottom) { - val changeList = listOf( - AdapterChange( - AdapterChangeType.RangeInsert, - column.list_data.size, - list_new.size - ) - ) - column.list_data.addAll(list_new) - column.fireShowContent(reason = "refresh updated bottom", changeList = changeList) - - // 新着が少しだけ見えるようにスクロール位置を移動する - if(sp != null) { - holder?.setScrollPosition(sp, 20f) - } - } else { - - val changeList = ArrayList() - - if(column.list_data.isNotEmpty() && column.list_data[0] is TootGap) { - changeList.add(AdapterChange(AdapterChangeType.RangeRemove, 0, 1)) - column.list_data.removeAt(0) - } - - for(o in list_new) { - if(o is TootStatus) { - val highlight_sound = o.highlight_sound - if(highlight_sound != null) { - App1.sound(highlight_sound) - break - } - } - } - - column.replaceConversationSummary(changeList, list_new, column.list_data) - - val added = list_new.size // may 0 - - // 投稿後のリフレッシュなら当該投稿の位置を探す - var status_index = - 1 - for(i in 0 until added) { - val o = list_new[i] - if(o is TootStatus && o.id == posted_status_id) { - status_index = i - break - } - } - - changeList.add(AdapterChange(AdapterChangeType.RangeInsert, 0, added)) - column.list_data.addAll(0, list_new) - column.fireShowContent(reason = "refresh updated head", changeList = changeList) - - if(status_index >= 0 && refresh_after_toot == Pref.RAT_REFRESH_SCROLL) { - // 投稿後にその投稿にスクロールする - if(holder != null) { - holder.setScrollPosition( - ScrollPosition(column.toAdapterIndex(status_index)), - 0f - ) - } else { - column.scroll_save = ScrollPosition(column.toAdapterIndex(status_index)) - } - } else { - // - val scroll_save = column.scroll_save - when { - // ViewHolderがある場合は増加件数分+deltaの位置にスクロールする - sp != null -> { - sp.adapterIndex += added - val delta = if(bSilent) 0f else - 20f - holder?.setScrollPosition(sp, delta) - } - // ViewHolderがなくて保存中の位置がある場合、増加件数分ずらす。deltaは難しいので反映しない - scroll_save != null -> scroll_save.adapterIndex += added - // 保存中の位置がない場合、保存中の位置を新しく作る - else -> column.scroll_save = - ScrollPosition(column.toAdapterIndex(added)) - } - } - } - - column.updateMisskeyCapture() - - } finally { - column.fireShowColumnStatus() - - if(! bBottom) { - column.bRefreshingTop = false - column.resumeStreaming(false) - } - } - } } diff --git a/app/src/main/java/jp/juggler/subwaytooter/ColumnTypeProc.kt b/app/src/main/java/jp/juggler/subwaytooter/ColumnTypeProc.kt index 5e7dc2f8..78aa741b 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ColumnTypeProc.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ColumnTypeProc.kt @@ -18,35 +18,33 @@ import java.util.* - Refresh : (始端/終端の)差分更新 - Gap : ギャップ部分の読み込み -procLoading,procRefresh,procGap はそれぞれ this の種類が異なるので注意 +loading,refresh,gap はそれぞれ this の種類が異なるので注意 同じ関数を呼び出してるように見えても実際には異なるクラスの異なる関数を呼び出している場合がある */ -private val unsupportedProcRefresh : ColumnTask_Refresh.(client : TootApiClient) -> TootApiResult? = +private val unsupportedRefresh : ColumnTask_Refresh.(client : TootApiClient) -> TootApiResult? = { TootApiResult("edge reading not supported.") } -private val unsupportedProcGap : ColumnTask_Gap.(client : TootApiClient) -> TootApiResult? = +private val unsupportedGap : ColumnTask_Gap.(client : TootApiClient) -> TootApiResult? = { TootApiResult("gap reading not supported.") } class ColumnTypeProc( - val procLoading : ColumnTask_Loading.(client : TootApiClient) -> TootApiResult?, - val procRefresh : ColumnTask_Refresh.(client : TootApiClient) -> TootApiResult? = unsupportedProcRefresh, - val procGap : ColumnTask_Gap.(client : TootApiClient) -> TootApiResult? = unsupportedProcGap + val loading : ColumnTask_Loading.(client : TootApiClient) -> TootApiResult?, + val refresh : ColumnTask_Refresh.(client : TootApiClient) -> TootApiResult? = unsupportedRefresh, + val gap : ColumnTask_Gap.(client : TootApiClient) -> TootApiResult? = unsupportedGap ) + private fun SparseArray.add( type : Int, - procLoading : ColumnTask_Loading.(client : TootApiClient) -> TootApiResult?, - procRefresh : ColumnTask_Refresh.(client : TootApiClient) -> TootApiResult? = unsupportedProcRefresh, - procGap : ColumnTask_Gap.(client : TootApiClient) -> TootApiResult? = unsupportedProcGap -) = put( - type, - ColumnTypeProc(procLoading, procRefresh, procGap) -) + loading : ColumnTask_Loading.(client : TootApiClient) -> TootApiResult?, + refresh : ColumnTask_Refresh.(client : TootApiClient) -> TootApiResult? = unsupportedRefresh, + gap : ColumnTask_Gap.(client : TootApiClient) -> TootApiResult? = unsupportedGap +) = put(type, ColumnTypeProc(loading, refresh, gap)) private val profileStatusMastodon = ColumnTypeProc( - procLoading = { client -> + loading = { client -> var instance = access_info.instance // まだ取得してない @@ -68,20 +66,15 @@ private val profileStatusMastodon = ColumnTypeProc( getStatusesPinned(client, "$path&pinned=true") } - getStatuses(client, path) + getStatusList(client, path) }, - procRefresh = { client -> - getStatusList(client, column.makeProfileStatusesUrl(column.profile_id)) - }, - - procGap = { client -> - getStatusList(client, column.makeProfileStatusesUrl(column.profile_id)) - } + refresh = { client -> getStatusList(client, column.makeProfileStatusesUrl(column.profile_id)) }, + gap = { client -> getStatusList(client, column.makeProfileStatusesUrl(column.profile_id)) } ) private val profileStatusMisskey = ColumnTypeProc( - procLoading = { client -> + loading = { client -> // 固定トゥートの取得 val pinnedNotes = column.who_account?.get()?.pinnedNotes if(pinnedNotes != null) { @@ -89,21 +82,21 @@ private val profileStatusMisskey = ColumnTypeProc( } // 通常トゥートの取得 - getStatuses( + getStatusList( client, Column.PATH_MISSKEY_PROFILE_STATUSES, misskeyParams = column.makeMisskeyParamsProfileStatuses(parser), initialUntilDate = true ) }, - procRefresh = { client -> + refresh = { client -> getStatusList( client, Column.PATH_MISSKEY_PROFILE_STATUSES, misskeyParams = column.makeMisskeyParamsProfileStatuses(parser) ) }, - procGap = { client -> + gap = { client -> getStatusList( client , Column.PATH_MISSKEY_PROFILE_STATUSES @@ -113,20 +106,20 @@ private val profileStatusMisskey = ColumnTypeProc( ) private val followingMastodon = ColumnTypeProc( - procLoading = { client -> - parseAccountList( + loading = { client -> + getAccountList( client, String.format(Locale.JAPAN, Column.PATH_ACCOUNT_FOLLOWING, column.profile_id), emptyMessage = context.getString(R.string.none_or_hidden_following) ) }, - procRefresh = { client -> + refresh = { client -> getAccountList( client, String.format(Locale.JAPAN, Column.PATH_ACCOUNT_FOLLOWING, column.profile_id) ) }, - procGap = { client -> + gap = { client -> getAccountList( client, String.format(Locale.JAPAN, Column.PATH_ACCOUNT_FOLLOWING, column.profile_id) @@ -135,7 +128,7 @@ private val followingMastodon = ColumnTypeProc( ) private val followingMastodonPseudo = ColumnTypeProc( - procLoading = { + loading = { column.idRecent = null column.idOld = null list_tmp = addOne( @@ -147,9 +140,9 @@ private val followingMastodonPseudo = ColumnTypeProc( ) private val followingMisskey10 = ColumnTypeProc( - procLoading = { client -> + loading = { client -> column.pagingType = ColumnPagingType.Cursor - parseAccountList( + getAccountList( client, Column.PATH_MISSKEY_PROFILE_FOLLOWING, emptyMessage = context.getString(R.string.none_or_hidden_following), @@ -157,7 +150,7 @@ private val followingMisskey10 = ColumnTypeProc( misskeyArrayFinder = misskeyArrayFinderUsers ) }, - procRefresh = { client -> + refresh = { client -> getAccountList( client, Column.PATH_MISSKEY_PROFILE_FOLLOWING, @@ -165,7 +158,7 @@ private val followingMisskey10 = ColumnTypeProc( misskeyArrayFinder = misskeyArrayFinderUsers ) }, - procGap = { client -> + gap = { client -> getAccountList( client, Column.PATH_MISSKEY_PROFILE_FOLLOWING, @@ -176,10 +169,10 @@ private val followingMisskey10 = ColumnTypeProc( ) private val followingMisskey11 = ColumnTypeProc( - procLoading = { client -> + loading = { client -> column.pagingType = ColumnPagingType.Default column.useDate = false - parseAccountList( + getAccountList( client, Column.PATH_MISSKEY_PROFILE_FOLLOWING, emptyMessage = context.getString(R.string.none_or_hidden_following), @@ -187,7 +180,7 @@ private val followingMisskey11 = ColumnTypeProc( misskeyCustomParser = misskeyFollowingParser ) }, - procRefresh = { client -> + refresh = { client -> column.useDate = false getAccountList( client, @@ -196,7 +189,7 @@ private val followingMisskey11 = ColumnTypeProc( misskeyCustomParser = misskeyFollowingParser ) }, - procGap = { client -> + gap = { client -> getAccountList( client, Column.PATH_MISSKEY_PROFILE_FOLLOWING, @@ -207,9 +200,9 @@ private val followingMisskey11 = ColumnTypeProc( ) private val followersMisskey11 = ColumnTypeProc( - procLoading = { client -> + loading = { client -> column.pagingType = ColumnPagingType.Default - parseAccountList( + getAccountList( client, Column.PATH_MISSKEY_PROFILE_FOLLOWERS, emptyMessage = context.getString(R.string.none_or_hidden_followers), @@ -218,7 +211,7 @@ private val followersMisskey11 = ColumnTypeProc( ) }, - procRefresh = { client -> + refresh = { client -> column.useDate = false getAccountList( client, @@ -227,7 +220,7 @@ private val followersMisskey11 = ColumnTypeProc( misskeyCustomParser = misskeyFollowersParser ) }, - procGap = { client -> + gap = { client -> getAccountList( client, Column.PATH_MISSKEY_PROFILE_FOLLOWING, @@ -238,9 +231,9 @@ private val followersMisskey11 = ColumnTypeProc( ) private val followersMisskey10 = ColumnTypeProc( - procLoading = { client -> + loading = { client -> column.pagingType = ColumnPagingType.Cursor - parseAccountList( + getAccountList( client, Column.PATH_MISSKEY_PROFILE_FOLLOWERS, emptyMessage = context.getString(R.string.none_or_hidden_followers), @@ -249,7 +242,7 @@ private val followersMisskey10 = ColumnTypeProc( ) }, - procRefresh = { client -> + refresh = { client -> getAccountList( client, Column.PATH_MISSKEY_PROFILE_FOLLOWERS, @@ -257,7 +250,7 @@ private val followersMisskey10 = ColumnTypeProc( misskeyArrayFinder = misskeyArrayFinderUsers ) }, - procGap = { client -> + gap = { client -> getAccountList( client , Column.PATH_MISSKEY_PROFILE_FOLLOWERS @@ -267,7 +260,7 @@ private val followersMisskey10 = ColumnTypeProc( ) private val followersMastodonPseudo = ColumnTypeProc( - procLoading = { + loading = { column.idRecent = null column.idOld = null list_tmp = addOne( @@ -279,21 +272,21 @@ private val followersMastodonPseudo = ColumnTypeProc( ) private val followersMastodon = ColumnTypeProc( - procLoading = { client -> - parseAccountList( + loading = { client -> + getAccountList( client, String.format(Locale.JAPAN, Column.PATH_ACCOUNT_FOLLOWERS, column.profile_id), emptyMessage = context.getString(R.string.none_or_hidden_followers) ) }, - procRefresh = { client -> + refresh = { client -> getAccountList( client, String.format(Locale.JAPAN, Column.PATH_ACCOUNT_FOLLOWERS, column.profile_id) ) }, - procGap = { client -> + gap = { client -> getAccountList( client, String.format(Locale.JAPAN, Column.PATH_ACCOUNT_FOLLOWERS, column.profile_id) @@ -305,52 +298,52 @@ private val profileTabProcMap = SparseArray().apply { add(Column.TAB_STATUS, - procLoading = { client -> + loading = { client -> when { - isMisskey -> profileStatusMisskey.procLoading(this, client) - else -> profileStatusMastodon.procLoading(this, client) + isMisskey -> profileStatusMisskey.loading(this, client) + else -> profileStatusMastodon.loading(this, client) } }, - procRefresh = { client -> + refresh = { client -> when { - isMisskey -> profileStatusMisskey.procRefresh(this, client) - else -> profileStatusMastodon.procRefresh(this, client) + isMisskey -> profileStatusMisskey.refresh(this, client) + else -> profileStatusMastodon.refresh(this, client) } }, - procGap = { client -> + gap = { client -> when { - isMisskey -> profileStatusMisskey.procGap(this, client) - else -> profileStatusMastodon.procGap(this, client) + isMisskey -> profileStatusMisskey.gap(this, client) + else -> profileStatusMastodon.gap(this, client) } } ) add(Column.TAB_FOLLOWING, - procLoading = { client -> + loading = { client -> when { - misskeyVersion >= 11 -> followingMisskey11.procLoading(this, client) - isMisskey -> followingMisskey10.procLoading(this, client) - access_info.isPseudo -> followingMastodonPseudo.procLoading(this, client) - else -> followingMastodon.procLoading(this, client) + misskeyVersion >= 11 -> followingMisskey11.loading(this, client) + isMisskey -> followingMisskey10.loading(this, client) + access_info.isPseudo -> followingMastodonPseudo.loading(this, client) + else -> followingMastodon.loading(this, client) } }, - procRefresh = { client -> + refresh = { client -> when { - misskeyVersion >= 11 -> followingMisskey11.procRefresh(this, client) - isMisskey -> followingMisskey10.procRefresh(this, client) - else -> followingMastodon.procRefresh(this, client) + misskeyVersion >= 11 -> followingMisskey11.refresh(this, client) + isMisskey -> followingMisskey10.refresh(this, client) + else -> followingMastodon.refresh(this, client) } }, - - procGap = { client -> + + gap = { client -> when { - misskeyVersion >= 11 -> followingMisskey11.procGap(this, client) - isMisskey -> followingMisskey10.procGap(this, client) - else -> followingMastodon.procGap(this, client) + misskeyVersion >= 11 -> followingMisskey11.gap(this, client) + isMisskey -> followingMisskey10.gap(this, client) + else -> followingMastodon.gap(this, client) } } ) @@ -358,30 +351,30 @@ private val profileTabProcMap = SparseArray().apply { add(Column.TAB_FOLLOWERS, - procLoading = { client -> + loading = { client -> when { - misskeyVersion >= 11 -> followersMisskey11.procLoading(this, client) - isMisskey -> followersMisskey10.procLoading(this, client) - access_info.isPseudo -> followersMastodonPseudo.procLoading(this, client) - else -> followersMastodon.procLoading(this, client) + misskeyVersion >= 11 -> followersMisskey11.loading(this, client) + isMisskey -> followersMisskey10.loading(this, client) + access_info.isPseudo -> followersMastodonPseudo.loading(this, client) + else -> followersMastodon.loading(this, client) } }, - procRefresh = { client -> + refresh = { client -> when { - misskeyVersion >= 11 -> followersMisskey11.procRefresh(this, client) - isMisskey -> followersMisskey10.procRefresh(this, client) - access_info.isPseudo -> followersMastodonPseudo.procRefresh(this, client) - else -> followersMastodon.procRefresh(this, client) + misskeyVersion >= 11 -> followersMisskey11.refresh(this, client) + isMisskey -> followersMisskey10.refresh(this, client) + access_info.isPseudo -> followersMastodonPseudo.refresh(this, client) + else -> followersMastodon.refresh(this, client) } }, - procGap = { client -> + gap = { client -> when { - misskeyVersion >= 11 -> followersMisskey11.procGap(this, client) - isMisskey -> followersMisskey10.procGap(this, client) - access_info.isPseudo -> followersMastodonPseudo.procGap(this, client) - else -> followersMastodon.procGap(this, client) + misskeyVersion >= 11 -> followersMisskey11.gap(this, client) + isMisskey -> followersMisskey10.gap(this, client) + access_info.isPseudo -> followersMastodonPseudo.gap(this, client) + else -> followersMastodon.gap(this, client) } } ) @@ -390,34 +383,32 @@ private val profileTabProcMap = SparseArray().apply { val columnTypeProcMap = SparseArray().apply { add(Column.TYPE_HOME, - procLoading = { client -> getStatuses(client, column.makeHomeTlUrl()) }, - procRefresh = { client -> getStatusList(client, column.makeHomeTlUrl()) }, - procGap = { client -> getStatusList(client, column.makeHomeTlUrl()) } + loading = { client -> getStatusList(client, column.makeHomeTlUrl()) }, + refresh = { client -> getStatusList(client, column.makeHomeTlUrl()) }, + gap = { client -> getStatusList(client, column.makeHomeTlUrl()) } ) add(Column.TYPE_LOCAL, - procLoading = { client -> getStatuses(client, column.makePublicLocalUrl()) }, - procRefresh = { client -> getStatusList(client, column.makePublicLocalUrl()) }, - procGap = { client -> getStatusList(client, column.makePublicLocalUrl()) } + loading = { client -> getStatusList(client, column.makePublicLocalUrl()) }, + refresh = { client -> getStatusList(client, column.makePublicLocalUrl()) }, + gap = { client -> getStatusList(client, column.makePublicLocalUrl()) } ) add(Column.TYPE_FEDERATE, - procLoading = { client -> getStatuses(client, column.makePublicFederateUrl()) }, - procRefresh = { client -> getStatusList(client, column.makePublicFederateUrl()) }, - procGap = { client -> getStatusList(client, column.makePublicFederateUrl()) } + loading = { client -> getStatusList(client, column.makePublicFederateUrl()) }, + refresh = { client -> getStatusList(client, column.makePublicFederateUrl()) }, + gap = { client -> getStatusList(client, column.makePublicFederateUrl()) } ) add(Column.TYPE_MISSKEY_HYBRID, - procLoading = { client -> getStatuses(client, column.makeMisskeyHybridTlUrl()) }, - procRefresh = { client -> getStatusList(client, column.makeMisskeyHybridTlUrl()) }, - procGap = { client -> getStatusList(client, column.makeMisskeyHybridTlUrl()) } + loading = { client -> getStatusList(client, column.makeMisskeyHybridTlUrl()) }, + refresh = { client -> getStatusList(client, column.makeMisskeyHybridTlUrl()) }, + gap = { client -> getStatusList(client, column.makeMisskeyHybridTlUrl()) } ) add(Column.TYPE_LOCAL_AROUND, - procLoading = { client -> - getPublicAroundStatuses(client, column.makePublicLocalUrl()) - }, - procRefresh = { client -> + loading = { client -> getPublicAroundStatuses(client, column.makePublicLocalUrl()) }, + refresh = { client -> if(bBottom) { getStatusList(client, column.makePublicLocalUrl()) } else { @@ -430,12 +421,8 @@ val columnTypeProcMap = SparseArray().apply { ) add(Column.TYPE_FEDERATED_AROUND, - - procLoading = { client -> - getPublicAroundStatuses(client, column.makePublicFederateUrl()) - }, - - procRefresh = { client -> + loading = { client -> getPublicAroundStatuses(client, column.makePublicFederateUrl()) }, + refresh = { client -> if(bBottom) { getStatusList(client, column.makePublicFederateUrl()) } else { @@ -449,42 +436,28 @@ val columnTypeProcMap = SparseArray().apply { add(Column.TYPE_PROFILE, - procLoading = { client -> + loading = { client -> val who_result = column.loadProfileAccount(client, parser, true) if(client.isApiCancelled || column.who_account == null) return@add who_result (profileTabProcMap[column.profile_tab] ?: profileTabProcMap[Column.TAB_STATUS]) - .procLoading(this, client) + .loading(this, client) }, - procRefresh = { client -> + refresh = { client -> column.loadProfileAccount(client, parser, false) (profileTabProcMap[column.profile_tab] ?: profileTabProcMap[Column.TAB_STATUS]) - .procRefresh(this, client) + .refresh(this, client) }, - procGap = { client -> + gap = { client -> (profileTabProcMap[column.profile_tab] ?: profileTabProcMap[Column.TAB_STATUS]) - .procGap(this, client) + .gap(this, client) } ) add(Column.TYPE_FAVOURITES, - procLoading = { client -> - if(isMisskey) { - column.useDate = false - getStatuses( - client - , Column.PATH_MISSKEY_FAVORITES - , misskeyParams = column.makeMisskeyTimelineParameter(parser) - , misskeyCustomParser = misskeyCustomParserFavorites - ) - } else { - getStatuses(client, Column.PATH_FAVOURITES) - } - }, - - procRefresh = { client -> + loading = { client -> if(isMisskey) { column.useDate = false getStatusList( @@ -498,7 +471,21 @@ val columnTypeProcMap = SparseArray().apply { } }, - procGap = { client -> + refresh = { client -> + if(isMisskey) { + column.useDate = false + getStatusList( + client + , Column.PATH_MISSKEY_FAVORITES + , misskeyParams = column.makeMisskeyTimelineParameter(parser) + , misskeyCustomParser = misskeyCustomParserFavorites + ) + } else { + getStatusList(client, Column.PATH_FAVOURITES) + } + }, + + gap = { client -> if(isMisskey) { column.useDate = false getStatusList( @@ -514,19 +501,19 @@ val columnTypeProcMap = SparseArray().apply { ) add(Column.TYPE_NOTIFICATIONS, - procLoading = { client -> parseNotifications(client) }, - procRefresh = { client -> getNotificationList(client) }, - procGap = { client -> getNotificationList(client) } + loading = { client -> getNotificationList(client) }, + refresh = { client -> getNotificationList(client) }, + gap = { client -> getNotificationList(client) } ) add(Column.TYPE_NOTIFICATION_FROM_ACCT, - procLoading = { client -> parseNotifications(client, column.hashtag_acct) }, - procRefresh = { client -> getNotificationList(client, column.hashtag_acct) }, - procGap = { client -> getNotificationList(client, column.hashtag_acct) } + loading = { client -> getNotificationList(client, column.hashtag_acct) }, + refresh = { client -> getNotificationList(client, column.hashtag_acct) }, + gap = { client -> getNotificationList(client, column.hashtag_acct) } ) add(Column.TYPE_CONVERSATION, - procLoading = { client -> + loading = { client -> if(isMisskey) { // 指定された発言そのもの @@ -664,20 +651,20 @@ val columnTypeProcMap = SparseArray().apply { } ) add(Column.TYPE_HASHTAG, - procLoading = { client -> + loading = { client -> if(isMisskey) { - getStatuses( + getStatusList( client , column.makeHashtagUrl() , misskeyParams = column.makeHashtagParams(parser) ) } else { - getStatuses(client, column.makeHashtagUrl()) + getStatusList(client, column.makeHashtagUrl()) } }, - procRefresh = { client -> + refresh = { client -> if(isMisskey) { getStatusList( client @@ -689,7 +676,7 @@ val columnTypeProcMap = SparseArray().apply { } }, - procGap = { client -> + gap = { client -> if(isMisskey) { getStatusList( client @@ -704,20 +691,20 @@ val columnTypeProcMap = SparseArray().apply { add(Column.TYPE_HASHTAG_FROM_ACCT, - procLoading = { client -> + loading = { client -> if(isMisskey) { // currently not supported - getStatuses( + getStatusList( client , column.makeHashtagAcctUrl(client) , misskeyParams = column.makeHashtagParams(parser) ) } else { - getStatuses(client, column.makeHashtagAcctUrl(client)) + getStatusList(client, column.makeHashtagAcctUrl(client)) } }, - procRefresh = { client -> + refresh = { client -> if(isMisskey) { getStatusList( client @@ -729,7 +716,7 @@ val columnTypeProcMap = SparseArray().apply { } }, - procGap = { client -> + gap = { client -> if(isMisskey) { getStatusList( client @@ -743,24 +730,20 @@ val columnTypeProcMap = SparseArray().apply { ) add(Column.TYPE_SEARCH, - procLoading = { client -> + loading = { client -> if(isMisskey) { var result : TootApiResult? = TootApiResult() val parser = TootParser(context, access_info) - var params : JSONObject list_tmp = ArrayList() val queryAccount = column.search_query.trim().replace("^@".toRegex(), "") if(queryAccount.isNotEmpty()) { - - params = access_info.putMisskeyApiToken(JSONObject()) - .put("query", queryAccount) - .put("localOnly", ! column.search_resolve) - result = client.request( "/api/users/search", - params.toPostRequestBuilder() + access_info.putMisskeyApiToken() + .put("query", queryAccount) + .put("localOnly", ! column.search_resolve).toPostRequestBuilder() ) val jsonArray = result?.jsonArray if(jsonArray != null) { @@ -772,11 +755,11 @@ val columnTypeProcMap = SparseArray().apply { val queryTag = column.search_query.trim().replace("^#".toRegex(), "") if(queryTag.isNotEmpty()) { - params = access_info.putMisskeyApiToken(JSONObject()) - .put("query", queryTag) result = client.request( "/api/hashtags/search", - params.toPostRequestBuilder() + access_info.putMisskeyApiToken() + .put("query", queryTag) + .toPostRequestBuilder() ) val jsonArray = result?.jsonArray if(jsonArray != null) { @@ -785,11 +768,11 @@ val columnTypeProcMap = SparseArray().apply { } } if(column.search_query.isNotEmpty()) { - params = access_info.putMisskeyApiToken(JSONObject()) - .put("query", column.search_query) result = client.request( "/api/notes/search", - params.toPostRequestBuilder() + access_info.putMisskeyApiToken() + .put("query", column.search_query) + .toPostRequestBuilder() ) val jsonArray = result?.jsonArray if(jsonArray != null) { @@ -874,106 +857,129 @@ val columnTypeProcMap = SparseArray().apply { ) add(Column.TYPE_MUTES, - procLoading = { client -> - if(isMisskey) { - column.pagingType = ColumnPagingType.Cursor - parseAccountList( - client - , Column.PATH_MISSKEY_MUTES - , misskeyParams = access_info.putMisskeyApiToken(JSONObject()) - , misskeyArrayFinder = misskeyArrayFinderUsers - ) - } else { - parseAccountList(client, Column.PATH_MUTES) - } - }, - procRefresh = { client -> - if(isMisskey) { - getAccountList( - client - , Column.PATH_MISSKEY_MUTES - , misskeyParams = access_info.putMisskeyApiToken(JSONObject()) - , misskeyArrayFinder = misskeyArrayFinderUsers - ) - } else { - getAccountList(client, Column.PATH_MUTES) - } - }, - procGap = { client -> - if(isMisskey) { - getAccountList( - client - , Column.PATH_MISSKEY_MUTES - , misskeyParams = access_info.putMisskeyApiToken(JSONObject()) + loading = { client -> + + when { + misskeyVersion >= 11 -> { + column.pagingType = ColumnPagingType.Default + getAccountList( + client, + Column.PATH_MISSKEY_MUTES, + misskeyParams = access_info.putMisskeyApiToken(), + misskeyCustomParser = misskeyCustomParserMutes + ) - , misskeyArrayFinder = misskeyArrayFinderUsers + } + isMisskey -> { + // misskey v10 + column.pagingType = ColumnPagingType.Cursor + getAccountList( + client, + Column.PATH_MISSKEY_MUTES, + misskeyParams = access_info.putMisskeyApiToken(), + misskeyArrayFinder = misskeyArrayFinderUsers + ) + } + else -> getAccountList(client, Column.PATH_MUTES) + } + }, + + refresh = { client -> + when { + misskeyVersion >= 11 -> getAccountList( + client, Column.PATH_MISSKEY_MUTES, + misskeyParams = access_info.putMisskeyApiToken(), + misskeyCustomParser = misskeyCustomParserMutes ) - } else { - getAccountList(client, Column.PATH_MUTES) + isMisskey -> getAccountList( + client, Column.PATH_MISSKEY_MUTES, + misskeyParams = access_info.putMisskeyApiToken(), + misskeyArrayFinder = misskeyArrayFinderUsers + ) + else -> getAccountList(client, Column.PATH_MUTES) + } + }, + + gap = { client -> + when { + misskeyVersion >= 11 -> getAccountList( + client, + Column.PATH_MISSKEY_MUTES, + misskeyParams = access_info.putMisskeyApiToken(), + misskeyCustomParser = misskeyCustomParserMutes + ) + isMisskey -> getAccountList( + client, + Column.PATH_MISSKEY_MUTES, + misskeyParams = access_info.putMisskeyApiToken(), + misskeyArrayFinder = misskeyArrayFinderUsers + ) + else -> getAccountList(client, Column.PATH_MUTES) } } ) add(Column.TYPE_BLOCKS, - procLoading = { client -> - if(isMisskey) { - column.pagingType = ColumnPagingType.Default - val params = access_info.putMisskeyApiToken(JSONObject()) - parseAccountList( - client, - "/api/blocking/list", - misskeyParams = params, - misskeyCustomParser = misskeyCustomParserBlocks - ) - } else { - parseAccountList(client, Column.PATH_BLOCKS) + loading = { client -> + when { + isMisskey -> { + column.pagingType = ColumnPagingType.Default + getAccountList( + client, + "/api/blocking/list", + misskeyParams = access_info.putMisskeyApiToken(), + misskeyCustomParser = misskeyCustomParserBlocks + ) + } + else -> getAccountList(client, Column.PATH_BLOCKS) } }, - procRefresh = { client -> - if(isMisskey) { - column.pagingType = ColumnPagingType.Default - val params = access_info.putMisskeyApiToken(JSONObject()) - getAccountList( - client, - "/api/blocking/list", - misskeyParams = params, - misskeyCustomParser = misskeyCustomParserBlocks - ) - } else { - getAccountList(client, Column.PATH_BLOCKS) + refresh = { client -> + when { + isMisskey -> { + column.pagingType = ColumnPagingType.Default + getAccountList( + client, + "/api/blocking/list", + misskeyParams = access_info.putMisskeyApiToken(), + misskeyCustomParser = misskeyCustomParserBlocks + ) + } + else -> getAccountList(client, Column.PATH_BLOCKS) } }, - procGap = { client -> - if(isMisskey) { - column.pagingType = ColumnPagingType.Default - val params = access_info.putMisskeyApiToken(JSONObject()) - getAccountList( - client, - "/api/blocking/list", - misskeyParams = params, - misskeyCustomParser = misskeyCustomParserBlocks - ) - } else { - getAccountList(client, Column.PATH_BLOCKS) + + gap = { client -> + when { + isMisskey -> { + column.pagingType = ColumnPagingType.Default + getAccountList( + client, + "/api/blocking/list", + misskeyParams = access_info.putMisskeyApiToken(), + misskeyCustomParser = misskeyCustomParserBlocks + ) + } + else -> getAccountList(client, Column.PATH_BLOCKS) } } ) add(Column.TYPE_FOLLOW_REQUESTS, - procLoading = { client -> + loading = { client -> if(isMisskey) { column.pagingType = ColumnPagingType.None - parseAccountList( + getAccountList( client , Column.PATH_MISSKEY_FOLLOW_REQUESTS , misskeyParams = access_info.putMisskeyApiToken(JSONObject()) , misskeyCustomParser = misskeyCustomParserFollowRequest ) } else { - parseAccountList(client, Column.PATH_FOLLOW_REQUESTS) + getAccountList(client, Column.PATH_FOLLOW_REQUESTS) } }, - procRefresh = { client -> + refresh = { client -> if(isMisskey) { getAccountList( client @@ -985,7 +991,7 @@ val columnTypeProcMap = SparseArray().apply { getAccountList(client, Column.PATH_FOLLOW_REQUESTS) } }, - procGap = { client -> + gap = { client -> if(isMisskey) { getAccountList( client @@ -1000,19 +1006,19 @@ val columnTypeProcMap = SparseArray().apply { ) add(Column.TYPE_BOOSTED_BY, - procLoading = { client -> - parseAccountList( + loading = { client -> + getAccountList( client, String.format(Locale.JAPAN, Column.PATH_BOOSTED_BY, column.status_id) ) }, - procRefresh = { client -> + refresh = { client -> getAccountList( client, String.format(Locale.JAPAN, Column.PATH_BOOSTED_BY, posted_status_id) ) }, - procGap = { client -> + gap = { client -> getAccountList( client, String.format(Locale.JAPAN, Column.PATH_BOOSTED_BY, column.status_id) @@ -1021,19 +1027,19 @@ val columnTypeProcMap = SparseArray().apply { ) add(Column.TYPE_FAVOURITED_BY, - procLoading = { client -> - parseAccountList( + loading = { client -> + getAccountList( client, String.format(Locale.JAPAN, Column.PATH_FAVOURITED_BY, column.status_id) ) }, - procRefresh = { client -> + refresh = { client -> getAccountList( client, String.format(Locale.JAPAN, Column.PATH_FAVOURITED_BY, posted_status_id) ) }, - procGap = { client -> + gap = { client -> getAccountList( client, String.format(Locale.JAPAN, Column.PATH_FAVOURITED_BY, column.status_id) @@ -1042,13 +1048,13 @@ val columnTypeProcMap = SparseArray().apply { ) add(Column.TYPE_DOMAIN_BLOCKS, - procLoading = { client -> parseDomainList(client, Column.PATH_DOMAIN_BLOCK) }, - procRefresh = { client -> getDomainList(client, Column.PATH_DOMAIN_BLOCK) } + loading = { client -> getDomainList(client, Column.PATH_DOMAIN_BLOCK) }, + refresh = { client -> getDomainList(client, Column.PATH_DOMAIN_BLOCK) } ) add(Column.TYPE_SEARCH_MSP, - procLoading = { client -> + loading = { client -> column.idOld = null val result : TootApiResult? val q = column.search_query.trim { it <= ' ' } @@ -1075,7 +1081,7 @@ val columnTypeProcMap = SparseArray().apply { result }, - procRefresh = { client -> + refresh = { client -> if(! bBottom) { TootApiResult("head of list.") @@ -1108,7 +1114,7 @@ val columnTypeProcMap = SparseArray().apply { add(Column.TYPE_SEARCH_TS, - procLoading = { client -> + loading = { client -> column.idOld = null val result : TootApiResult? val q = column.search_query.trim { it <= ' ' } @@ -1140,7 +1146,7 @@ val columnTypeProcMap = SparseArray().apply { result }, - procRefresh = { client -> + refresh = { client -> if(! bBottom) { TootApiResult("head of list.") } else { @@ -1174,7 +1180,7 @@ val columnTypeProcMap = SparseArray().apply { ) add(Column.TYPE_INSTANCE_INFORMATION, - procLoading = { client -> + loading = { client -> val result = getInstanceInformation(client, column.instance_uri) if(instance_tmp != null) { column.instance_information = instance_tmp @@ -1185,7 +1191,7 @@ val columnTypeProcMap = SparseArray().apply { ) add(Column.TYPE_LIST_LIST, - procLoading = { client -> + loading = { client -> if(isMisskey) { parseListList( client, @@ -1200,29 +1206,35 @@ val columnTypeProcMap = SparseArray().apply { add(Column.TYPE_LIST_TL, - procLoading = { client -> + loading = { client -> column.loadListInfo(client, true) if(isMisskey) { - val params = column.makeMisskeyTimelineParameter(parser) - .put("listId", column.profile_id) - getStatuses(client, column.makeListTlUrl(), misskeyParams = params) - } else { - getStatuses(client, column.makeListTlUrl()) - } - }, - - procRefresh = { client -> - column.loadListInfo(client, false) - if(isMisskey) { - val params = column.makeMisskeyTimelineParameter(parser) - .put("listId", column.profile_id) - getStatusList(client, column.makeListTlUrl(), misskeyParams = params) + getStatusList( + client, + column.makeListTlUrl(), + misskeyParams = column.makeMisskeyTimelineParameter(parser) + .put("listId", column.profile_id) + ) } else { getStatusList(client, column.makeListTlUrl()) } }, - procGap = { client -> + refresh = { client -> + column.loadListInfo(client, false) + if(isMisskey) { + getStatusList( + client, + column.makeListTlUrl(), + misskeyParams = column.makeMisskeyTimelineParameter(parser) + .put("listId", column.profile_id) + ) + } else { + getStatusList(client, column.makeListTlUrl()) + } + }, + + gap = { client -> if(isMisskey) { getStatusList( client, @@ -1238,31 +1250,30 @@ val columnTypeProcMap = SparseArray().apply { add(Column.TYPE_LIST_MEMBER, - procLoading = { client -> + loading = { client -> column.loadListInfo(client, true) if(isMisskey) { column.pagingType = ColumnPagingType.None - val params = access_info.putMisskeyApiToken(JSONObject()) - .put("userIds", JSONArray().apply { - column.list_info?.userIds?.forEach { - this.put(it.toString()) - } - }) - parseAccountList( + getAccountList( client, "/api/users/show", - misskeyParams = params + misskeyParams = access_info.putMisskeyApiToken() + .put("userIds", JSONArray().apply { + column.list_info?.userIds?.forEach { + this.put(it.toString()) + } + }) ) } else { - parseAccountList( + getAccountList( client, String.format(Locale.JAPAN, Column.PATH_LIST_MEMBER, column.profile_id) ) } }, - procRefresh = { client -> + refresh = { client -> column.loadListInfo(client, false) getAccountList( client, @@ -1272,7 +1283,7 @@ val columnTypeProcMap = SparseArray().apply { ) add(Column.TYPE_DIRECT_MESSAGES, - procLoading = { client -> + loading = { client -> column.useConversationSummarys = false if(! column.use_old_api) { @@ -1295,10 +1306,10 @@ val columnTypeProcMap = SparseArray().apply { } // fallback to old api - return@add getStatuses(client, Column.PATH_DIRECT_MESSAGES) + return@add getStatusList(client, Column.PATH_DIRECT_MESSAGES) }, - procRefresh = { client -> + refresh = { client -> if(column.useConversationSummarys) { // try 2.6.0 new API https://github.com/tootsuite/mastodon/pull/8832 getConversationSummaryList(client, Column.PATH_DIRECT_MESSAGES2) @@ -1308,7 +1319,7 @@ val columnTypeProcMap = SparseArray().apply { } }, - procGap = { client -> + gap = { client -> if(column.useConversationSummarys) { // try 2.6.0 new API https://github.com/tootsuite/mastodon/pull/8832 getConversationSummaryList(client, Column.PATH_DIRECT_MESSAGES2) @@ -1320,7 +1331,7 @@ val columnTypeProcMap = SparseArray().apply { ) add(Column.TYPE_TREND_TAG, - procLoading = { client -> + loading = { client -> val result = client.request("/api/v1/trends") val src = parser.trendTagList(result?.jsonArray) @@ -1340,20 +1351,20 @@ val columnTypeProcMap = SparseArray().apply { add(Column.TYPE_FOLLOW_SUGGESTION, - procLoading = { client -> + loading = { client -> if(isMisskey) { column.pagingType = ColumnPagingType.Offset - parseAccountList( + getAccountList( client , Column.PATH_MISSKEY_FOLLOW_SUGGESTION , misskeyParams = access_info.putMisskeyApiToken(JSONObject()) ) } else { - parseAccountList(client, Column.PATH_FOLLOW_SUGGESTION) + getAccountList(client, Column.PATH_FOLLOW_SUGGESTION) } }, - procRefresh = { client -> + refresh = { client -> if(isMisskey) { getAccountList( client @@ -1365,7 +1376,7 @@ val columnTypeProcMap = SparseArray().apply { } }, - procGap = { client -> + gap = { client -> if(isMisskey) { getAccountList( client @@ -1379,16 +1390,16 @@ val columnTypeProcMap = SparseArray().apply { ) add(Column.TYPE_ENDORSEMENT, - procLoading = { client -> parseAccountList(client, Column.PATH_ENDORSEMENT) }, - procRefresh = { client -> getAccountList(client, Column.PATH_ENDORSEMENT) }, - procGap = { client -> getAccountList(client, Column.PATH_ENDORSEMENT) } + loading = { client -> getAccountList(client, Column.PATH_ENDORSEMENT) }, + refresh = { client -> getAccountList(client, Column.PATH_ENDORSEMENT) }, + gap = { client -> getAccountList(client, Column.PATH_ENDORSEMENT) } ) add(Column.TYPE_ACCOUNT_AROUND, - procLoading = { client -> getAccountAroundStatuses(client) }, + loading = { client -> getAccountAroundStatuses(client) }, - procRefresh = { client -> + refresh = { client -> val path = column.makeProfileStatusesUrl(column.profile_id) if(bBottom) { getStatusList(client, path) @@ -1402,19 +1413,19 @@ val columnTypeProcMap = SparseArray().apply { ) add(Column.TYPE_REPORTS, - procLoading = { client -> parseReports(client, Column.PATH_REPORTS) }, - procRefresh = { client -> getReportList(client, Column.PATH_REPORTS) }, - procGap = { client -> getReportList(client, Column.PATH_REPORTS) } + loading = { client -> getReportList(client, Column.PATH_REPORTS) }, + refresh = { client -> getReportList(client, Column.PATH_REPORTS) }, + gap = { client -> getReportList(client, Column.PATH_REPORTS) } ) add(Column.TYPE_KEYWORD_FILTER, - procLoading = { client -> parseFilterList(client, Column.PATH_FILTERS) } + loading = { client -> parseFilterList(client, Column.PATH_FILTERS) } ) add( Column.TYPE_SCHEDULED_STATUS, - procLoading = { client -> getScheduledStatuses(client) }, - procRefresh = { client -> getScheduledStatuses(client) } + loading = { client -> getScheduledStatuses(client) }, + refresh = { client -> getScheduledStatuses(client) } ) } \ No newline at end of file diff --git a/app/src/main/java/jp/juggler/subwaytooter/ColumnUtil.kt b/app/src/main/java/jp/juggler/subwaytooter/ColumnUtil.kt index c021d853..760db942 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ColumnUtil.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ColumnUtil.kt @@ -350,6 +350,25 @@ internal val misskeyCustomParserFollowRequest = dst } +internal val misskeyCustomParserMutes = + { parser : TootParser, jsonArray : JSONArray -> + val dst = ArrayList() + for(i in 0 until jsonArray.length()) { + val src = jsonArray.optJSONObject(i) ?: continue + + val accountRef = TootAccountRef.mayNull( + parser, + parser.account(src.optJSONObject("mutee")) + ) ?: continue + + val requestId = EntityId.mayNull(src.parseString("id")) ?: continue + + accountRef._orderId = requestId + + dst.add(accountRef) + } + dst + } internal val misskeyCustomParserBlocks = { parser : TootParser, jsonArray : JSONArray -> val dst = ArrayList() @@ -369,7 +388,6 @@ internal val misskeyCustomParserBlocks = } dst } - internal val misskeyCustomParserFavorites = { parser : TootParser, jsonArray : JSONArray -> val dst = ArrayList()