SubwayTooter-Android-App/app/src/main/java/jp/juggler/subwaytooter/column/ColumnType.kt

2175 lines
72 KiB
Kotlin
Raw Normal View History

2021-06-28 09:09:00 +02:00
package jp.juggler.subwaytooter.column
2019-06-05 23:06:37 +02:00
import android.content.Context
2019-06-05 23:06:37 +02:00
import android.view.Gravity
2021-06-28 09:09:00 +02:00
import jp.juggler.subwaytooter.R
2021-05-17 16:13:04 +02:00
import jp.juggler.subwaytooter.api.ApiPath
import jp.juggler.subwaytooter.api.TootApiClient
import jp.juggler.subwaytooter.api.TootApiResult
2024-01-04 06:41:40 +01:00
import jp.juggler.subwaytooter.api.entity.Acct
import jp.juggler.subwaytooter.api.entity.Host
import jp.juggler.subwaytooter.api.entity.TimelineItem
import jp.juggler.subwaytooter.api.entity.TootAccountRef.Companion.tootAccountRef
2024-01-04 06:41:40 +01:00
import jp.juggler.subwaytooter.api.entity.TootInstance
import jp.juggler.subwaytooter.api.entity.TootMessageHolder
import jp.juggler.subwaytooter.api.entity.TootNotification
import jp.juggler.subwaytooter.api.entity.TootStatus
import jp.juggler.subwaytooter.api.finder.mastodonFollowSuggestion2ListParser
import jp.juggler.subwaytooter.api.finder.misskey11FollowersParser
import jp.juggler.subwaytooter.api.finder.misskey11FollowingParser
import jp.juggler.subwaytooter.api.finder.misskeyArrayFinderUsers
import jp.juggler.subwaytooter.api.finder.misskeyCustomParserBlocks
import jp.juggler.subwaytooter.api.finder.misskeyCustomParserFavorites
import jp.juggler.subwaytooter.api.finder.misskeyCustomParserFollowRequest
import jp.juggler.subwaytooter.api.finder.misskeyCustomParserMutes
import jp.juggler.subwaytooter.search.MspHelper.loadingMSP
import jp.juggler.subwaytooter.search.MspHelper.refreshMSP
import jp.juggler.subwaytooter.search.NotestockHelper.loadingNotestock
import jp.juggler.subwaytooter.search.NotestockHelper.refreshNotestock
import jp.juggler.subwaytooter.search.TootsearchHelper.loadingTootsearch
import jp.juggler.subwaytooter.search.TootsearchHelper.refreshTootsearch
import jp.juggler.subwaytooter.streaming.StreamSpec
import jp.juggler.subwaytooter.table.daoAcctColor
2024-01-04 06:41:40 +01:00
import jp.juggler.util.data.JsonArray
import jp.juggler.util.data.JsonObject
import jp.juggler.util.data.appendIf
import jp.juggler.util.data.ellipsizeDot3
import jp.juggler.util.data.jsonArrayOf
import jp.juggler.util.data.jsonObjectOf
import jp.juggler.util.data.notEmpty
import jp.juggler.util.data.toJsonArray
import jp.juggler.util.log.LogCategory
2024-01-04 06:41:40 +01:00
import java.util.Locale
2019-08-23 03:52:31 +02:00
import kotlin.math.max
import kotlin.math.min
2019-06-05 23:06:37 +02:00
/*
2022-06-04 20:35:07 +02:00
カラム種別ごとの処理
- Loading : 初回ロード
- Refresh : (始端/終端の)差分更新
- Gap : ギャップ部分の読み込み
loading,refresh,gap はそれぞれ this の種類が異なるので注意
同じ関数を呼び出してるように見えても実際には異なるクラスの異なる関数を呼び出している場合がある
2019-06-05 23:06:37 +02:00
*/
private val unsupportedRefresh: suspend ColumnTask_Refresh.(client: TootApiClient) -> TootApiResult? =
2020-12-07 13:53:55 +01:00
{ TootApiResult("edge reading not supported.") }
2019-06-05 23:06:37 +02:00
private val unsupportedGap: suspend ColumnTask_Gap.(client: TootApiClient) -> TootApiResult? =
2020-12-07 13:53:55 +01:00
{ TootApiResult("gap reading not supported.") }
2019-06-05 23:06:37 +02:00
2020-12-07 13:53:55 +01:00
private val unusedIconId: (Acct) -> Int =
{ R.drawable.ic_question }
2020-12-07 13:53:55 +01:00
private val unusedName: (context: Context) -> String =
{ "?" }
2019-08-23 01:49:20 +02:00
2020-12-07 13:53:55 +01:00
private val unusedName2: Column.(long: Boolean) -> String? =
{ null }
2019-08-23 01:49:20 +02:00
2020-12-07 13:53:55 +01:00
private val gapDirectionNone: Column.(head: Boolean) -> Boolean = { false }
2020-12-07 13:53:55 +01:00
private val gapDirectionBoth: Column.(head: Boolean) -> Boolean = { true }
2020-12-07 13:53:55 +01:00
private val gapDirectionHead: Column.(head: Boolean) -> Boolean = { it }
// Pagination in some Mastodon APIs has no relation between the content ID and the pagination ID,
// so the app cannot filter the data using the content ID.
// (max_id..since_id) API request is worked,
// but (max_id..min_id) API is not worked on v3.2.0
// related: https://github.com/tootsuite/mastodon/pull/14776
2020-12-07 13:53:55 +01:00
private val gapDirectionMastodonWorkaround: Column.(head: Boolean) -> Boolean =
{ head ->
when {
isMisskey -> true
isMastodon -> head
else -> false
}
}
private val streamingTypeYes: Column.() -> Boolean = { true }
private val streamingTypeNo: Column.() -> Boolean = { false }
2019-08-23 01:49:20 +02:00
enum class ColumnType(
2021-05-17 15:20:08 +02:00
val id: Int = 0,
val iconId: (Acct) -> Int = unusedIconId,
val name1: (context: Context) -> String = unusedName,
val name2: Column.(long: Boolean) -> String? = unusedName2,
val loading: suspend ColumnTask_Loading.(client: TootApiClient) -> TootApiResult?,
val refresh: suspend ColumnTask_Refresh.(client: TootApiClient) -> TootApiResult? = unsupportedRefresh,
val gap: suspend ColumnTask_Gap.(client: TootApiClient) -> TootApiResult? = unsupportedGap,
val bAllowPseudo: Boolean = true,
val bAllowMisskey: Boolean = true,
val bAllowMastodon: Boolean = true,
val headerType: HeaderType? = null,
val gapDirection: Column.(head: Boolean) -> Boolean = gapDirectionNone,
val canAutoRefresh: Boolean = false,
val canStreamingMastodon: Column.() -> Boolean,
val canStreamingMisskey: Column.() -> Boolean,
2021-05-17 15:20:08 +02:00
val streamKeyMastodon: Column.() -> JsonObject? = { null },
val streamFilterMastodon: Column.(JsonArray, TimelineItem) -> Boolean = { _, _ -> true },
2021-05-17 15:20:08 +02:00
val streamNameMisskey: String? = null,
val streamParamMisskey: Column.() -> JsonObject? = { null },
val streamPathMisskey9: Column.() -> String? = { null },
2019-08-23 01:49:20 +02:00
) {
2020-12-07 13:53:55 +01:00
ProfileStatusMastodon(
2021-05-17 15:20:08 +02:00
loading = { client ->
val (instance, instanceResult) = TootInstance.get(client)
if (instance == null) {
instanceResult
} else {
val path = column.makeProfileStatusesUrl(column.profileId)
2021-05-17 15:20:08 +02:00
if (instance.versionGE(TootInstance.VERSION_1_6)
// 将来的に正しく判定できる見込みがないので、Pleroma条件でのフィルタは行わない
// && instance.instanceType != TootInstance.InstanceType.Pleroma
) {
getStatusesPinned(client, "$path&pinned=true")
}
getStatusList(client, path)
}
},
refresh = { client ->
getStatusList(
client,
column.makeProfileStatusesUrl(column.profileId)
2021-05-17 15:20:08 +02:00
)
},
gap = { client ->
getStatusList(
client,
column.makeProfileStatusesUrl(column.profileId),
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = true,
)
},
gapDirection = gapDirectionBoth,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
ProfileStatusMisskey(
2021-05-17 15:20:08 +02:00
loading = { client ->
// 固定トゥートの取得
val pinnedNotes = column.whoAccount?.get()?.pinnedNotes
2021-05-17 15:20:08 +02:00
if (pinnedNotes != null) {
this.listPinned = addWithFilterStatus(null, pinnedNotes)
2021-05-17 15:20:08 +02:00
}
// 通常トゥートの取得
getStatusList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_STATUSES,
2021-05-17 15:20:08 +02:00
misskeyParams = column.makeMisskeyParamsProfileStatuses(parser)
)
},
refresh = { client ->
getStatusList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_STATUSES,
2021-05-17 15:20:08 +02:00
misskeyParams = column.makeMisskeyParamsProfileStatuses(parser)
)
},
gap = { client ->
getStatusList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_STATUSES,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = true,
misskeyParams = column.makeMisskeyParamsProfileStatuses(parser)
)
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
2020-12-07 13:53:55 +01:00
FollowingMastodon(
2021-05-17 15:20:08 +02:00
loading = { client ->
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_ACCOUNT_FOLLOWING, column.profileId),
2021-05-17 15:20:08 +02:00
emptyMessage = context.getString(R.string.none_or_hidden_following)
)
},
refresh = { client ->
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_ACCOUNT_FOLLOWING, column.profileId)
2021-05-17 15:20:08 +02:00
)
},
gap = { client ->
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_ACCOUNT_FOLLOWING, column.profileId),
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false,
)
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
FollowingMastodonPseudo(
2021-05-17 15:20:08 +02:00
loading = {
column.idRecent = null
column.idOld = null
listTmp = addOne(
listTmp,
2021-05-17 15:20:08 +02:00
TootMessageHolder(context.getString(R.string.pseudo_account_cant_get_follow_list))
)
TootApiResult()
},
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
FollowingMisskey10(
2021-05-17 15:20:08 +02:00
loading = { client ->
column.pagingType = ColumnPagingType.Cursor
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_FOLLOWING,
2021-05-17 15:20:08 +02:00
emptyMessage = context.getString(R.string.none_or_hidden_following),
misskeyParams = column.makeMisskeyParamsUserId(parser),
arrayFinder = misskeyArrayFinderUsers
)
},
refresh = { client ->
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_FOLLOWING,
2021-05-17 15:20:08 +02:00
misskeyParams = column.makeMisskeyParamsUserId(parser),
arrayFinder = misskeyArrayFinderUsers
)
},
gap = { client ->
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_FOLLOWING,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false,
misskeyParams = column.makeMisskeyParamsUserId(parser),
arrayFinder = misskeyArrayFinderUsers
)
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
FollowingMisskey11(
2021-05-17 15:20:08 +02:00
loading = { client ->
column.pagingType = ColumnPagingType.Default
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_FOLLOWING,
2021-05-17 15:20:08 +02:00
emptyMessage = context.getString(R.string.none_or_hidden_following),
misskeyParams = column.makeMisskeyParamsUserId(parser),
listParser = misskey11FollowingParser
)
},
refresh = { client ->
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_FOLLOWING,
2021-05-17 15:20:08 +02:00
misskeyParams = column.makeMisskeyParamsUserId(parser),
listParser = misskey11FollowingParser
)
},
gap = { client ->
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_FOLLOWING,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false,
misskeyParams = column.makeMisskeyParamsUserId(parser),
listParser = misskey11FollowingParser
)
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
FollowersMisskey11(
2021-05-17 15:20:08 +02:00
loading = { client ->
column.pagingType = ColumnPagingType.Default
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_FOLLOWERS,
2021-05-17 15:20:08 +02:00
emptyMessage = context.getString(R.string.none_or_hidden_followers),
misskeyParams = column.makeMisskeyParamsUserId(parser),
listParser = misskey11FollowersParser
)
},
refresh = { client ->
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_FOLLOWERS,
2021-05-17 15:20:08 +02:00
misskeyParams = column.makeMisskeyParamsUserId(parser),
listParser = misskey11FollowersParser
)
},
gap = { client ->
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_FOLLOWING,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false,
misskeyParams = column.makeMisskeyParamsUserId(parser),
listParser = misskey11FollowersParser
)
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
FollowersMisskey10(
2021-05-17 15:20:08 +02:00
loading = { client ->
column.pagingType = ColumnPagingType.Cursor
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_FOLLOWERS,
2021-05-17 15:20:08 +02:00
emptyMessage = context.getString(R.string.none_or_hidden_followers),
misskeyParams = column.makeMisskeyParamsUserId(parser),
arrayFinder = misskeyArrayFinderUsers
)
},
refresh = { client ->
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_FOLLOWERS,
2021-05-17 15:20:08 +02:00
misskeyParams = column.makeMisskeyParamsUserId(parser),
arrayFinder = misskeyArrayFinderUsers
)
},
gap = { client ->
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_PROFILE_FOLLOWERS,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false,
misskeyParams = column.makeMisskeyParamsUserId(parser)
)
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
FollowersMastodonPseudo(
2021-05-17 15:20:08 +02:00
loading = {
column.idRecent = null
column.idOld = null
listTmp = addOne(
listTmp,
2021-05-17 15:20:08 +02:00
TootMessageHolder(context.getString(R.string.pseudo_account_cant_get_follow_list))
)
TootApiResult()
},
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
FollowersMastodon(
2021-05-17 15:20:08 +02:00
loading = { client ->
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_ACCOUNT_FOLLOWERS, column.profileId),
2021-05-17 15:20:08 +02:00
emptyMessage = context.getString(R.string.none_or_hidden_followers)
)
},
refresh = { client ->
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_ACCOUNT_FOLLOWERS, column.profileId)
2021-05-17 15:20:08 +02:00
)
},
gap = { client ->
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_ACCOUNT_FOLLOWERS, column.profileId),
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false
)
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
TabStatus(
2021-05-17 15:20:08 +02:00
loading = { dispatchProfileTabStatus().loading(this, it) },
refresh = { dispatchProfileTabStatus().refresh(this, it) },
gap = { dispatchProfileTabStatus().gap(this, it) },
gapDirection = { dispatchProfileTabStatus().gapDirection(this, it) },
canStreamingMastodon = { dispatchProfileTabStatus().canStreamingMastodon(this) },
canStreamingMisskey = { dispatchProfileTabStatus().canStreamingMisskey(this) },
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
TabFollowing(
2021-05-17 15:20:08 +02:00
loading = { dispatchProfileTabFollowing().loading(this, it) },
refresh = { dispatchProfileTabFollowing().refresh(this, it) },
gap = { dispatchProfileTabFollowing().gap(this, it) },
gapDirection = { dispatchProfileTabFollowing().gapDirection(this, it) },
canStreamingMastodon = { dispatchProfileTabFollowing().canStreamingMastodon(this) },
canStreamingMisskey = { dispatchProfileTabFollowing().canStreamingMisskey(this) },
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
TabFollowers(
2021-05-17 15:20:08 +02:00
loading = { dispatchProfileTabFollowers().loading(this, it) },
refresh = { dispatchProfileTabFollowers().refresh(this, it) },
gap = { dispatchProfileTabFollowers().gap(this, it) },
gapDirection = { dispatchProfileTabFollowers().gapDirection(this, it) },
canStreamingMastodon = { dispatchProfileTabFollowers().canStreamingMastodon(this) },
canStreamingMisskey = { dispatchProfileTabFollowers().canStreamingMisskey(this) },
),
2020-12-07 13:53:55 +01:00
HOME(
2021-05-17 15:20:08 +02:00
id = 1,
iconId = { R.drawable.ic_home },
name1 = { it.getString(R.string.home) },
loading = { client ->
val ra = getAnnouncements(client, force = true)
when {
ra == null || ra.error != null -> ra
else -> getStatusList(client, column.makeHomeTlUrl())
}
2021-05-17 15:20:08 +02:00
},
refresh = { client ->
val ra = getAnnouncements(client)
when {
ra == null || ra.error != null -> ra
else -> getStatusList(client, column.makeHomeTlUrl())
}
2021-05-17 15:20:08 +02:00
},
gap = { client ->
val ra = getAnnouncements(client)
when {
ra == null || ra.error != null -> ra
else -> getStatusList(
2021-05-17 15:20:08 +02:00
client,
column.makeHomeTlUrl(),
mastodonFilterByIdRange = true
)
}
2021-05-17 15:20:08 +02:00
},
gapDirection = gapDirectionBoth,
bAllowPseudo = false,
canAutoRefresh = true,
canStreamingMastodon = streamingTypeYes,
canStreamingMisskey = streamingTypeYes,
2021-05-17 15:20:08 +02:00
streamKeyMastodon = {
jsonObjectOf(StreamSpec.STREAM to "user")
},
streamFilterMastodon = { stream, item ->
when {
item !is TootStatus -> false
unmatchMastodonStream(stream, "user") -> false
else -> true
}
},
streamNameMisskey = "homeTimeline",
streamParamMisskey = { null },
streamPathMisskey9 = { "/" },
),
2020-12-07 13:53:55 +01:00
LOCAL(
2021-05-17 15:20:08 +02:00
id = 2,
iconId = { R.drawable.ic_run },
name1 = { it.getString(R.string.local_timeline) },
bAllowPseudo = true,
loading = { client -> getStatusList(client, column.makePublicLocalUrl()) },
refresh = { client -> getStatusList(client, column.makePublicLocalUrl()) },
gap = { client ->
getStatusList(
client,
column.makePublicLocalUrl(),
mastodonFilterByIdRange = true
)
},
gapDirection = gapDirectionBoth,
canAutoRefresh = true,
canStreamingMastodon = streamingTypeYes,
canStreamingMisskey = streamingTypeYes,
2021-05-17 15:20:08 +02:00
streamKeyMastodon = { jsonObjectOf(StreamSpec.STREAM to streamKeyLtl()) },
streamFilterMastodon = { stream, item ->
when {
item !is TootStatus -> false
unmatchMastodonStream(stream, streamKeyLtl()) -> false
else -> true
}
},
streamNameMisskey = "localTimeline",
streamParamMisskey = { null },
streamPathMisskey9 = { "/local-timeline" },
),
2020-12-07 13:53:55 +01:00
FEDERATE(
2021-05-17 15:20:08 +02:00
3,
iconId = { R.drawable.ic_bike },
name1 = { it.getString(R.string.federate_timeline) },
bAllowPseudo = true,
loading = { client -> getStatusList(client, column.makePublicFederateUrl()) },
refresh = { client -> getStatusList(client, column.makePublicFederateUrl()) },
gap = { client ->
getStatusList(
client,
column.makePublicFederateUrl(),
mastodonFilterByIdRange = true
)
},
gapDirection = gapDirectionBoth,
canAutoRefresh = true,
canStreamingMastodon = streamingTypeYes,
canStreamingMisskey = streamingTypeYes,
2021-05-17 15:20:08 +02:00
streamKeyMastodon = {
jsonObjectOf(StreamSpec.STREAM to streamKeyFtl())
},
streamFilterMastodon = { stream, item ->
when {
item !is TootStatus -> false
unmatchMastodonStream(stream, streamKeyFtl()) -> false
remoteOnly && item.account.acct == accessInfo.acct -> false
withAttachment && item.media_attachments.isNullOrEmpty() -> false
2021-05-17 15:20:08 +02:00
else -> true
}
},
streamNameMisskey = "globalTimeline",
streamParamMisskey = { null },
streamPathMisskey9 = { "/global-timeline" },
),
2020-12-07 13:53:55 +01:00
MISSKEY_HYBRID(
2021-05-17 15:20:08 +02:00
27,
iconId = { R.drawable.ic_share },
name1 = { it.getString(R.string.misskey_hybrid_timeline) },
bAllowPseudo = false,
bAllowMastodon = false,
loading = { client -> getStatusList(client, column.makeMisskeyHybridTlUrl()) },
refresh = { client -> getStatusList(client, column.makeMisskeyHybridTlUrl()) },
gap = { client ->
getStatusList(
client,
column.makeMisskeyHybridTlUrl(),
mastodonFilterByIdRange = true
)
},
gapDirection = gapDirectionBoth,
canAutoRefresh = true,
canStreamingMastodon = streamingTypeYes,
canStreamingMisskey = streamingTypeYes,
2021-05-17 15:20:08 +02:00
streamNameMisskey = "hybridTimeline",
streamParamMisskey = { null },
streamPathMisskey9 = { "/hybrid-timeline" },
),
2020-12-07 13:53:55 +01:00
DOMAIN_TIMELINE(
2021-05-17 15:20:08 +02:00
id = 38,
iconId = { R.drawable.ic_domain },
name1 = { it.getString(R.string.domain_timeline) },
name2 = {
context.getString(
R.string.domain_timeline_of,
instanceUri.notEmpty() ?: "?"
2021-05-17 15:20:08 +02:00
)
},
bAllowPseudo = true, // サイドメニューから開けないのでこの値は参照されない
loading = { client -> getStatusList(client, column.makeDomainTimelineUrl()) },
refresh = { client -> getStatusList(client, column.makeDomainTimelineUrl()) },
gap = { client ->
getStatusList(
client,
column.makeDomainTimelineUrl(),
mastodonFilterByIdRange = true
)
},
gapDirection = gapDirectionBoth,
canAutoRefresh = true,
canStreamingMastodon = streamingTypeYes,
canStreamingMisskey = streamingTypeYes,
2021-05-17 15:20:08 +02:00
streamKeyMastodon = {
jsonObjectOf(StreamSpec.STREAM to streamKeyDomainTl(), "domain" to instanceUri)
2021-05-17 15:20:08 +02:00
},
streamFilterMastodon = { stream, item ->
when {
item !is TootStatus -> false
unmatchMastodonStream(stream, streamKeyDomainTl(), instanceUri) -> false
withAttachment && item.media_attachments.isNullOrEmpty() -> false
2021-05-17 15:20:08 +02:00
else -> true
}
}
),
2020-12-07 13:53:55 +01:00
LOCAL_AROUND(
29,
2021-05-17 15:20:08 +02:00
iconId = { R.drawable.ic_run },
name1 = { it.getString(R.string.ltl_around) },
name2 = {
context.getString(
R.string.ltl_around_of,
statusId?.toString() ?: "null"
2021-05-17 15:20:08 +02:00
)
},
loading = { client -> getPublicTlAroundTime(client, column.makePublicLocalUrl()) },
refresh = { client -> getStatusList(client, column.makePublicLocalUrl(), useMinId = true) },
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
FEDERATED_AROUND(
30,
2021-05-17 15:20:08 +02:00
iconId = { R.drawable.ic_bike },
name1 = { it.getString(R.string.ftl_around) },
name2 = {
context.getString(
R.string.ftl_around_of,
statusId?.toString() ?: "null"
2021-05-17 15:20:08 +02:00
)
},
loading = { client -> getPublicTlAroundTime(client, column.makePublicFederateUrl()) },
refresh = { client ->
getStatusList(
client,
column.makePublicFederateUrl(),
useMinId = true
)
},
2021-05-17 15:20:08 +02:00
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
PROFILE(
2021-05-17 15:20:08 +02:00
4,
iconId = { R.drawable.ic_account_box },
name1 = { it.getString(R.string.profile) },
name2 = {
val who = whoAccount?.get()
2021-05-17 15:20:08 +02:00
context.getString(
R.string.profile_of,
when (who) {
null -> profileId.toString()
else -> daoAcctColor.getNickname(accessInfo, who)
}
2021-05-17 15:20:08 +02:00
)
},
bAllowPseudo = false,
headerType = HeaderType.Profile,
loading = { client ->
val whoResult = column.loadProfileAccount(client, parser, true)
when {
client.isApiCancelled() || column.whoAccount == null -> whoResult
else -> column.profileTab.ct.loading(this, client)
}
2021-05-17 15:20:08 +02:00
},
refresh = { client ->
column.loadProfileAccount(client, parser, false)
column.profileTab.ct.refresh(this, client)
2021-05-17 15:20:08 +02:00
},
gap = { column.profileTab.ct.gap(this, it) },
gapDirection = { profileTab.ct.gapDirection(this, it) },
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
FAVOURITES(
2021-05-17 15:20:08 +02:00
5,
iconId = { R.drawable.ic_star_outline },
2021-05-17 15:20:08 +02:00
name1 = { it.getString(R.string.favourites) },
bAllowPseudo = false,
loading = { client ->
if (isMisskey) {
getStatusList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_FAVORITES,
2021-05-17 15:20:08 +02:00
misskeyParams = column.makeMisskeyTimelineParameter(parser),
listParser = misskeyCustomParserFavorites
)
} else {
2021-05-17 16:13:04 +02:00
getStatusList(client, ApiPath.PATH_FAVOURITES)
2021-05-17 15:20:08 +02:00
}
},
refresh = { client ->
if (isMisskey) {
getStatusList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_FAVORITES,
2021-05-17 15:20:08 +02:00
misskeyParams = column.makeMisskeyTimelineParameter(parser),
listParser = misskeyCustomParserFavorites
)
} else {
2021-05-17 16:13:04 +02:00
getStatusList(client, ApiPath.PATH_FAVOURITES)
2021-05-17 15:20:08 +02:00
}
},
gap = { client ->
if (isMisskey) {
getStatusList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_FAVORITES,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false,
misskeyParams = column.makeMisskeyTimelineParameter(parser),
listParser = misskeyCustomParserFavorites
)
} else {
getStatusList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_FAVOURITES,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false
)
}
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
2021-05-19 10:43:04 +02:00
REACTIONS(
42,
iconId = { R.drawable.ic_face },
name1 = { it.getString(R.string.reactioned_posts) },
2021-05-19 10:43:04 +02:00
bAllowPseudo = false,
bAllowMisskey = false,
loading = { client ->
if (isMisskey) {
getStatusList(
client,
ApiPath.PATH_M544_REACTIONS,
misskeyParams = column.makeMisskeyTimelineParameter(parser),
listParser = misskeyCustomParserFavorites
)
2021-05-19 10:43:04 +02:00
} else {
getStatusList(client, column.makeReactionsUrl())
2021-05-19 10:43:04 +02:00
}
},
refresh = { client ->
if (isMisskey) {
getStatusList(
client,
ApiPath.PATH_M544_REACTIONS,
misskeyParams = column.makeMisskeyTimelineParameter(parser),
listParser = misskeyCustomParserFavorites
)
} else {
getStatusList(client, column.makeReactionsUrl())
}
2021-05-19 10:43:04 +02:00
},
gap = { client ->
if (isMisskey) {
getStatusList(
client,
ApiPath.PATH_M544_REACTIONS,
mastodonFilterByIdRange = false,
misskeyParams = column.makeMisskeyTimelineParameter(parser),
listParser = misskeyCustomParserFavorites
)
} else {
getStatusList(
client,
column.makeReactionsUrl(),
mastodonFilterByIdRange = false
)
}
2021-05-19 10:43:04 +02:00
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-19 10:43:04 +02:00
),
2020-12-07 13:53:55 +01:00
BOOKMARKS(
2021-05-17 15:20:08 +02:00
37,
iconId = { R.drawable.ic_bookmark },
name1 = { it.getString(R.string.bookmarks) },
bAllowPseudo = false,
loading = { client ->
if (isMisskey) {
TootApiResult("Misskey has no bookmarks feature.")
} else {
2021-05-17 16:13:04 +02:00
getStatusList(client, ApiPath.PATH_BOOKMARKS)
2021-05-17 15:20:08 +02:00
}
},
refresh = { client ->
if (isMisskey) {
TootApiResult("Misskey has no bookmarks feature.")
} else {
2021-05-17 16:13:04 +02:00
getStatusList(client, ApiPath.PATH_BOOKMARKS)
2021-05-17 15:20:08 +02:00
}
},
gap = { client ->
if (isMisskey) {
TootApiResult("Misskey has no bookmarks feature.")
} else {
2021-05-17 16:13:04 +02:00
getStatusList(client, ApiPath.PATH_BOOKMARKS, mastodonFilterByIdRange = false)
2021-05-17 15:20:08 +02:00
}
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
NOTIFICATIONS(
2021-05-17 15:20:08 +02:00
7,
iconId = { R.drawable.ic_announcement },
name1 = { it.getString(R.string.notifications) },
name2 = {
context.getString(R.string.notifications) + getNotificationTypeString()
},
loading = { client -> getNotificationList(client) },
refresh = { client -> getNotificationList(client) },
gap = { client -> getNotificationList(client, mastodonFilterByIdRange = true) },
gapDirection = gapDirectionBoth,
bAllowPseudo = false,
canAutoRefresh = true,
canStreamingMastodon = streamingTypeYes,
canStreamingMisskey = streamingTypeYes,
2021-05-17 15:20:08 +02:00
streamKeyMastodon = {
jsonObjectOf(StreamSpec.STREAM to "user")
},
streamFilterMastodon = { stream, item ->
when {
item !is TootNotification -> false
unmatchMastodonStream(stream, "user") -> false
else -> true
}
},
streamNameMisskey = "main",
streamParamMisskey = { null },
streamPathMisskey9 = { "/" },
),
2020-12-07 13:53:55 +01:00
NOTIFICATION_FROM_ACCT(
2021-05-17 15:20:08 +02:00
35,
iconId = { R.drawable.ic_announcement },
name1 = { it.getString(R.string.notifications_from_acct) },
name2 = {
context.getString(
R.string.notifications_from,
hashtagAcct
2021-05-17 15:20:08 +02:00
) + getNotificationTypeString()
},
loading = { client -> getNotificationList(client, column.hashtagAcct) },
refresh = { client -> getNotificationList(client, column.hashtagAcct) },
2021-05-17 15:20:08 +02:00
gap = { client ->
getNotificationList(client, column.hashtagAcct, mastodonFilterByIdRange = true)
2021-05-17 15:20:08 +02:00
},
gapDirection = gapDirectionBoth,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
CONVERSATION(
8,
2021-05-17 15:20:08 +02:00
iconId = { R.drawable.ic_forum },
name1 = { it.getString(R.string.conversation) },
name2 = {
context.getString(
R.string.conversation_around,
statusId?.toString() ?: "null"
2021-05-17 15:20:08 +02:00
)
},
loading = { client -> getConversation(client) },
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
CONVERSATION_WITH_REFERENCE(
47,
iconId = { R.drawable.ic_link },
name1 = { it.getString(R.string.conversation_with_reference) },
name2 = { context.getString(R.string.conversation_with_reference) },
loading = { client -> getConversation(client, withReference = true) },
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
2020-12-07 13:53:55 +01:00
HASHTAG(
2021-05-17 15:20:08 +02:00
9,
iconId = { R.drawable.ic_hashtag },
name1 = { it.getString(R.string.hashtag) },
name2 = {
StringBuilder(
context.getString(
R.string.hashtag_of,
hashtag.ellipsizeDot3(Column.HASHTAG_ELLIPSIZE)
)
)
.appendHashtagExtra(this)
.toString()
},
loading = { client ->
if (isMisskey) {
getStatusList(
client,
column.makeHashtagUrl(),
misskeyParams = column.makeHashtagParams(parser)
)
} else {
getStatusList(client, column.makeHashtagUrl())
}
},
refresh = { client ->
if (isMisskey) {
getStatusList(
client,
column.makeHashtagUrl(),
misskeyParams = column.makeHashtagParams(parser)
)
} else {
getStatusList(client, column.makeHashtagUrl())
}
},
gap = { client ->
if (isMisskey) {
getStatusList(
client,
column.makeHashtagUrl(),
mastodonFilterByIdRange = true,
misskeyParams = column.makeHashtagParams(parser)
)
} else {
getStatusList(client, column.makeHashtagUrl(), mastodonFilterByIdRange = true)
}
},
gapDirection = gapDirectionBoth,
canAutoRefresh = true,
canStreamingMastodon = streamingTypeYes,
canStreamingMisskey = streamingTypeYes,
2021-05-17 15:20:08 +02:00
streamKeyMastodon = {
jsonObjectOf(
StreamSpec.STREAM to streamKeyHashtagTl(),
"tag" to hashtag
)
},
streamFilterMastodon = { stream, item ->
when {
item !is TootStatus -> false
//
unmatchMastodonStream(stream, streamKeyHashtagTl(), hashtag) -> false
instanceLocal && item.account.acct != accessInfo.acct -> false
2021-05-17 15:20:08 +02:00
else -> this.checkHashtagExtra(item)
}
},
// {"type":"connect","body":{"channel":"hashtag","id":"84970575","params":{"q":[["misskey"]]}}}
streamNameMisskey = "hashtag",
streamParamMisskey = { jsonObjectOf("q" to jsonArrayOf(jsonArrayOf(hashtag))) },
// Misskey10 というかめいすきーでタグTLのストリーミングができるのか不明
// streamPathMisskey10 = { "/???? ?q=${hashtag.encodePercent()}" },
),
2020-12-07 13:53:55 +01:00
HASHTAG_FROM_ACCT(
2021-05-17 15:20:08 +02:00
34,
iconId = { R.drawable.ic_hashtag },
name1 = { it.getString(R.string.hashtag_from_acct) },
name2 = {
StringBuilder(
context.getString(
R.string.hashtag_of_from,
hashtag.ellipsizeDot3(Column.HASHTAG_ELLIPSIZE),
hashtagAcct
2021-05-17 15:20:08 +02:00
)
)
.appendHashtagExtra(this)
.toString()
},
loading = { client ->
getStatusList(
client,
column.makeHashtagAcctUrl(client), // null if misskey
misskeyParams = column.makeHashtagParams(parser)
)
},
refresh = { client ->
getStatusList(
client,
column.makeHashtagAcctUrl(client), // null if misskey
misskeyParams = column.makeHashtagParams(parser)
)
},
gap = { client ->
getStatusList(
client,
column.makeHashtagAcctUrl(client), // null if misskey
mastodonFilterByIdRange = true,
misskeyParams = column.makeHashtagParams(parser)
)
},
gapDirection = gapDirectionBoth,
bAllowMisskey = false,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
SEARCH(
2021-05-17 15:20:08 +02:00
10,
iconId = { R.drawable.ic_search },
name1 = { it.getString(R.string.search) },
name2 = { long ->
when {
long -> context.getString(R.string.search_of, searchQuery)
2021-05-17 15:20:08 +02:00
else -> context.getString(R.string.search)
}
},
bAllowPseudo = false,
headerType = HeaderType.Search,
loading = { client -> getSearch(client) },
gap = { client -> getSearchGap(client) },
gapDirection = gapDirectionHead,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
// ミスキーのミュートとブロックののページングは misskey v10 の途中で変わった
// https://github.com/syuilo/misskey/commit/f7069dcd18d72b52408a6bd80ad8f14492163e19
// ST的には新しい方にだけ対応する
MUTES(
2021-05-17 15:20:08 +02:00
11,
iconId = { R.drawable.ic_volume_off },
name1 = { it.getString(R.string.muted_users) },
bAllowPseudo = false,
loading = { client ->
when {
isMisskey -> {
column.pagingType = ColumnPagingType.Default
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_MUTES,
misskeyParams = accessInfo.putMisskeyApiToken(),
2021-05-17 15:20:08 +02:00
listParser = misskeyCustomParserMutes
)
}
2021-05-17 16:13:04 +02:00
else -> getAccountList(client, ApiPath.PATH_MUTES)
2021-05-17 15:20:08 +02:00
}
},
refresh = { client ->
when {
isMisskey -> getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_MUTES,
misskeyParams = accessInfo.putMisskeyApiToken(),
2021-05-17 15:20:08 +02:00
arrayFinder = misskeyArrayFinderUsers,
listParser = misskeyCustomParserMutes
)
2024-01-04 06:41:40 +01:00
2021-05-17 16:13:04 +02:00
else -> getAccountList(client, ApiPath.PATH_MUTES)
2021-05-17 15:20:08 +02:00
}
},
gap = { client ->
when {
isMisskey -> getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_MUTES,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false,
misskeyParams = accessInfo.putMisskeyApiToken(),
2021-05-17 15:20:08 +02:00
arrayFinder = misskeyArrayFinderUsers,
listParser = misskeyCustomParserMutes
)
2024-01-04 06:41:40 +01:00
2021-05-17 15:20:08 +02:00
else -> getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MUTES,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false
)
}
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
BLOCKS(
2021-05-17 15:20:08 +02:00
12,
iconId = { R.drawable.ic_block },
name1 = { it.getString(R.string.blocked_users) },
bAllowPseudo = false,
loading = { client ->
when {
isMisskey -> {
column.pagingType = ColumnPagingType.Default
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_BLOCKS,
misskeyParams = accessInfo.putMisskeyApiToken(),
2021-05-17 15:20:08 +02:00
listParser = misskeyCustomParserBlocks
)
}
2021-05-17 16:13:04 +02:00
else -> getAccountList(client, ApiPath.PATH_BLOCKS)
2021-05-17 15:20:08 +02:00
}
},
refresh = { client ->
when {
isMisskey -> {
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_BLOCKS,
misskeyParams = accessInfo.putMisskeyApiToken(),
2021-05-17 15:20:08 +02:00
listParser = misskeyCustomParserBlocks
)
}
2021-05-17 16:13:04 +02:00
else -> getAccountList(client, ApiPath.PATH_BLOCKS)
2021-05-17 15:20:08 +02:00
}
},
gap = { client ->
when {
isMisskey -> {
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_BLOCKS,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false,
misskeyParams = accessInfo.putMisskeyApiToken(),
2021-05-17 15:20:08 +02:00
listParser = misskeyCustomParserBlocks
)
}
2021-05-17 16:13:04 +02:00
else -> getAccountList(client, ApiPath.PATH_BLOCKS, mastodonFilterByIdRange = false)
2021-05-17 15:20:08 +02:00
}
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
FOLLOW_REQUESTS(
2021-05-17 15:20:08 +02:00
13,
iconId = { R.drawable.ic_follow_wait },
name1 = { it.getString(R.string.follow_requests) },
bAllowPseudo = false,
loading = { client ->
if (isMisskey) {
column.pagingType = ColumnPagingType.None
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_FOLLOW_REQUESTS,
misskeyParams = accessInfo.putMisskeyApiToken(),
2021-05-17 15:20:08 +02:00
listParser = misskeyCustomParserFollowRequest
)
} else {
2021-05-17 16:13:04 +02:00
getAccountList(client, ApiPath.PATH_FOLLOW_REQUESTS)
2021-05-17 15:20:08 +02:00
}
},
refresh = { client ->
if (isMisskey) {
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_FOLLOW_REQUESTS,
misskeyParams = accessInfo.putMisskeyApiToken(),
2021-05-17 15:20:08 +02:00
listParser = misskeyCustomParserFollowRequest
)
} else {
2021-05-17 16:13:04 +02:00
getAccountList(client, ApiPath.PATH_FOLLOW_REQUESTS)
2021-05-17 15:20:08 +02:00
}
},
gap = { client ->
if (isMisskey) {
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_FOLLOW_REQUESTS,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false,
misskeyParams = accessInfo.putMisskeyApiToken(),
2021-05-17 15:20:08 +02:00
listParser = misskeyCustomParserFollowRequest
)
} else {
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_FOLLOW_REQUESTS,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false
)
}
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
BOOSTED_BY(
2021-05-17 15:20:08 +02:00
14,
iconId = { R.drawable.ic_repeat },
name1 = { it.getString(R.string.boosted_by) },
loading = { client ->
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_BOOSTED_BY, column.statusId)
2021-05-17 15:20:08 +02:00
)
},
refresh = { client ->
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_BOOSTED_BY, postedStatusId)
2021-05-17 15:20:08 +02:00
)
},
gap = { client ->
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_BOOSTED_BY, column.statusId),
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false,
)
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
FAVOURITED_BY(
2021-05-17 15:20:08 +02:00
15,
iconId = { R.drawable.ic_star_outline },
2021-05-17 15:20:08 +02:00
name1 = { it.getString(R.string.favourited_by) },
loading = { client ->
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_FAVOURITED_BY, column.statusId)
2021-05-17 15:20:08 +02:00
)
},
refresh = { client ->
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_FAVOURITED_BY, postedStatusId)
2021-05-17 15:20:08 +02:00
)
},
gap = { client ->
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_FAVOURITED_BY, column.statusId),
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false,
)
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
DOMAIN_BLOCKS(
16,
2021-05-17 15:20:08 +02:00
iconId = { R.drawable.ic_cloud_off },
name1 = { it.getString(R.string.blocked_domains) },
bAllowPseudo = false,
bAllowMisskey = false,
2020-12-07 13:53:55 +01:00
2021-05-17 16:13:04 +02:00
loading = { client -> getDomainBlockList(client, ApiPath.PATH_DOMAIN_BLOCK) },
refresh = { client -> getDomainList(client, ApiPath.PATH_DOMAIN_BLOCK) },
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
SEARCH_MSP(
2021-05-17 15:20:08 +02:00
17,
iconId = { R.drawable.ic_search },
name1 = { it.getString(R.string.toot_search_msp) },
name2 = { long ->
when {
long -> context.getString(R.string.toot_search_msp_of, searchQuery)
2021-05-17 15:20:08 +02:00
else -> context.getString(R.string.toot_search_msp)
}
},
headerType = HeaderType.Search,
loading = { loadingMSP(it) },
refresh = { refreshMSP(it) },
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
SEARCH_TS(
2021-05-17 15:20:08 +02:00
22,
iconId = { R.drawable.ic_search },
name1 = { it.getString(R.string.toot_search_ts) },
name2 = { long ->
when {
long -> context.getString(R.string.toot_search_ts_of, searchQuery)
2021-05-17 15:20:08 +02:00
else -> context.getString(R.string.toot_search_ts)
}
},
headerType = HeaderType.Search,
loading = { loadingTootsearch(it) },
refresh = { refreshTootsearch(it) },
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:23:14 +01:00
SEARCH_NOTESTOCK(
2021-05-17 15:20:08 +02:00
41,
iconId = { R.drawable.ic_search },
name1 = { it.getString(R.string.toot_search_notestock) },
name2 = { long ->
when {
long -> context.getString(R.string.toot_search_notestock_of, searchQuery)
2021-05-17 15:20:08 +02:00
else -> context.getString(R.string.toot_search_notestock)
}
},
headerType = HeaderType.Search,
loading = { loadingNotestock(it) },
refresh = { refreshNotestock(it) },
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:23:14 +01:00
INSTANCE_INFORMATION(
18,
iconId = { R.drawable.ic_info_outline },
2021-05-17 15:20:08 +02:00
name1 = { it.getString(R.string.instance_information) },
name2 = { long ->
when {
long -> context.getString(R.string.instance_information_of, instanceUri)
2021-05-17 15:20:08 +02:00
else -> context.getString(R.string.instance_information)
}
},
headerType = HeaderType.Instance,
loading = { client ->
val (ti, ri) = TootInstance.getEx(
client,
Host.parse(column.instanceUri),
2021-05-17 15:20:08 +02:00
allowPixelfed = true,
forceUpdate = true
)
if (ti != null) {
column.instanceInformation = ti
2021-05-17 15:20:08 +02:00
column.handshake = ri?.response?.handshake
}
ri
},
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2020-12-07 13:53:55 +01:00
),
LIST_LIST(
19,
2021-05-17 15:20:08 +02:00
iconId = { R.drawable.ic_list_list },
name1 = { it.getString(R.string.lists) },
bAllowPseudo = false,
loading = { client ->
if (isMisskey) {
getListList(
client,
"/api/users/lists/list",
misskeyParams = column.makeMisskeyBaseParameter(parser)
)
} else {
2021-05-17 16:13:04 +02:00
getListList(client, ApiPath.PATH_LIST_LIST)
2021-05-17 15:20:08 +02:00
}
},
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
2020-12-07 13:53:55 +01:00
LIST_TL(
2021-05-17 15:20:08 +02:00
20,
iconId = { R.drawable.ic_list_tl },
name1 = { it.getString(R.string.list_timeline) },
name2 = {
context.getString(
R.string.list_tl_of,
listInfo?.title ?: profileId.toString()
2021-05-17 15:20:08 +02:00
)
},
loading = { client ->
column.loadListInfo(client, true)
if (isMisskey) {
getStatusList(
client,
column.makeListTlUrl(),
misskeyParams = column.makeMisskeyTimelineParameter(parser).apply {
put("listId", column.profileId)
2021-05-17 15:20:08 +02:00
}
)
} else {
getStatusList(client, column.makeListTlUrl())
}
},
refresh = { client ->
column.loadListInfo(client, false)
if (isMisskey) {
getStatusList(
client,
column.makeListTlUrl(),
misskeyParams = column.makeMisskeyTimelineParameter(parser).apply {
put("listId", column.profileId)
2021-05-17 15:20:08 +02:00
}
)
} else {
getStatusList(client, column.makeListTlUrl())
}
},
gap = { client ->
if (isMisskey) {
getStatusList(
client,
column.makeListTlUrl(),
mastodonFilterByIdRange = true,
misskeyParams = column.makeMisskeyTimelineParameter(parser).apply {
put("listId", column.profileId)
2021-05-17 15:20:08 +02:00
}
)
} else {
getStatusList(client, column.makeListTlUrl(), mastodonFilterByIdRange = true)
}
},
gapDirection = gapDirectionBoth,
canAutoRefresh = true,
canStreamingMastodon = streamingTypeYes,
canStreamingMisskey = streamingTypeYes,
2021-05-17 15:20:08 +02:00
streamKeyMastodon = {
jsonObjectOf(StreamSpec.STREAM to "list", "list" to profileId.toString())
2021-05-17 15:20:08 +02:00
},
streamFilterMastodon = { stream, item ->
when {
item !is TootStatus -> false
unmatchMastodonStream(stream, "list", profileId?.toString()) -> false
2021-05-17 15:20:08 +02:00
else -> true
}
},
2021-05-17 15:20:08 +02:00
streamNameMisskey = "userList",
streamParamMisskey = { jsonObjectOf("listId" to profileId.toString()) },
streamPathMisskey9 = { "/user-list?listId=$profileId" },
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
LIST_MEMBER(
21,
2021-05-17 15:20:08 +02:00
iconId = { R.drawable.ic_list_member },
name1 = { it.getString(R.string.list_member) },
name2 = {
context.getString(
R.string.list_member_of,
listInfo?.title ?: profileId.toString()
2021-05-17 15:20:08 +02:00
)
},
loading = { client ->
column.loadListInfo(client, true)
if (isMisskey) {
column.pagingType = ColumnPagingType.None
getAccountList(
client,
"/api/users/show",
misskeyParams = accessInfo.putMisskeyApiToken().apply {
val list = column.listInfo?.userIds?.map { it.toString() }?.toJsonArray()
2021-05-17 15:20:08 +02:00
if (list != null) put("userIds", list)
}
)
} else {
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_LIST_MEMBER, column.profileId)
2021-05-17 15:20:08 +02:00
)
}
},
refresh = { client ->
column.loadListInfo(client, false)
getAccountList(
client,
String.format(Locale.JAPAN, ApiPath.PATH_LIST_MEMBER, column.profileId)
2021-05-17 15:20:08 +02:00
)
},
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
DIRECT_MESSAGES(
2021-05-17 15:20:08 +02:00
23,
iconId = { R.drawable.ic_mail },
name1 = { it.getString(R.string.direct_messages) },
loading = { client ->
column.useConversationSummaries = false
if (column.useOldApi) {
2021-05-17 16:13:04 +02:00
getStatusList(client, ApiPath.PATH_DIRECT_MESSAGES)
2021-05-17 15:20:08 +02:00
} else {
// try 2.6.0 new API https://github.com/tootsuite/mastodon/pull/8832
2021-05-17 16:13:04 +02:00
val result = getConversationSummary(client, ApiPath.PATH_DIRECT_MESSAGES2)
2021-05-17 15:20:08 +02:00
when {
// cancelled
result == null -> null
// not error
result.error.isNullOrBlank() -> {
column.useConversationSummaries = true
result
}
// fallback to old api
2021-05-17 16:13:04 +02:00
else -> getStatusList(client, ApiPath.PATH_DIRECT_MESSAGES)
2021-05-17 15:20:08 +02:00
}
}
},
refresh = { client ->
if (column.useConversationSummaries) {
// try 2.6.0 new API https://github.com/tootsuite/mastodon/pull/8832
2021-05-17 16:13:04 +02:00
getConversationSummaryList(client, ApiPath.PATH_DIRECT_MESSAGES2)
2021-05-17 15:20:08 +02:00
} else {
// fallback to old api
2021-05-17 16:13:04 +02:00
getStatusList(client, ApiPath.PATH_DIRECT_MESSAGES)
2021-05-17 15:20:08 +02:00
}
},
gap = { client ->
if (column.useConversationSummaries) {
// try 2.6.0 new API https://github.com/tootsuite/mastodon/pull/8832
getConversationSummaryList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_DIRECT_MESSAGES2,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false
)
} else {
// fallback to old api
2021-05-17 16:13:04 +02:00
getStatusList(client, ApiPath.PATH_DIRECT_MESSAGES, mastodonFilterByIdRange = false)
2021-05-17 15:20:08 +02:00
}
},
gapDirection = gapDirectionMastodonWorkaround,
bAllowPseudo = false,
bAllowMisskey = false,
canAutoRefresh = true,
canStreamingMastodon = streamingTypeYes,
canStreamingMisskey = streamingTypeYes,
2021-05-17 15:20:08 +02:00
streamKeyMastodon = {
jsonObjectOf(StreamSpec.STREAM to "direct")
},
streamFilterMastodon = { stream, _ ->
when {
unmatchMastodonStream(stream, "direct") -> false
else -> true
}
}
),
2020-12-07 13:53:55 +01:00
TREND_TAG(
24,
iconId = { R.drawable.ic_trend },
2021-05-17 15:20:08 +02:00
name1 = { it.getString(R.string.trend_tag) },
bAllowPseudo = true,
bAllowMastodon = true,
bAllowMisskey = false,
loading = { client ->
val result = client.request("/api/v1/trends")
val src = parser.tagList(result?.jsonArray)
this.listTmp = addAll(this.listTmp, src)
this.listTmp = addOne(
this.listTmp, TootMessageHolder(
2021-05-17 15:20:08 +02:00
context.getString(R.string.trend_tag_desc),
gravity = Gravity.END
)
)
result
},
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
TREND_LINK(
44,
iconId = { R.drawable.ic_trend },
name1 = { it.getString(R.string.trend_link) },
bAllowPseudo = false,
bAllowMastodon = true,
bAllowMisskey = false,
loading = { client ->
val result = client.request("/api/v1/trends/links")
val src = parser.tagList(result?.jsonArray)
this.listTmp = addAll(this.listTmp, src)
this.listTmp = addOne(
this.listTmp, TootMessageHolder(
context.getString(R.string.trend_tag_desc),
gravity = Gravity.END
)
)
result
},
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
TREND_POST(
45,
iconId = { R.drawable.ic_trend },
name1 = { it.getString(R.string.trend_post) },
bAllowPseudo = false,
bAllowMastodon = true,
bAllowMisskey = false,
loading = { client ->
val result = client.request("/api/v1/trends/statuses")
val src = parser.statusList(result?.jsonArray)
this.listTmp = addAll(this.listTmp, src)
// this.listTmp = addOne(
// this.listTmp, TootMessageHolder(
// context.getString(R.string.trend_tag_desc),
// gravity = Gravity.END
// )
// )
result
},
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
2020-12-07 13:53:55 +01:00
FOLLOW_SUGGESTION(
2021-05-17 15:20:08 +02:00
25,
iconId = { R.drawable.ic_person_add },
2021-05-17 15:20:08 +02:00
name1 = { it.getString(R.string.follow_suggestion) },
bAllowPseudo = false,
loading = { client ->
if (isMisskey) {
column.pagingType = ColumnPagingType.Offset
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_FOLLOW_SUGGESTION,
misskeyParams = accessInfo.putMisskeyApiToken()
2021-05-17 15:20:08 +02:00
)
} else {
val (ti, ri) = TootInstance.get(client)
when {
ti == null -> ri
ti.versionGE(TootInstance.VERSION_3_4_0_rc1) ->
getAccountList(
client,
ApiPath.PATH_FOLLOW_SUGGESTION2,
listParser = mastodonFollowSuggestion2ListParser,
)
2024-01-04 06:41:40 +01:00
2021-05-17 15:20:08 +02:00
else ->
2021-05-17 16:13:04 +02:00
getAccountList(client, ApiPath.PATH_FOLLOW_SUGGESTION)
2021-05-17 15:20:08 +02:00
}
}
},
refresh = { client ->
if (isMisskey) {
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_FOLLOW_SUGGESTION,
misskeyParams = accessInfo.putMisskeyApiToken()
2021-05-17 15:20:08 +02:00
)
} else {
val (ti, ri) = TootInstance.get(client)
when {
ti == null -> ri
ti.versionGE(TootInstance.VERSION_3_4_0_rc1) ->
getAccountList(
client,
ApiPath.PATH_FOLLOW_SUGGESTION2,
listParser = mastodonFollowSuggestion2ListParser,
)
2024-01-04 06:41:40 +01:00
2021-05-17 15:20:08 +02:00
else ->
2021-05-17 16:13:04 +02:00
getAccountList(client, ApiPath.PATH_FOLLOW_SUGGESTION)
2021-05-17 15:20:08 +02:00
}
}
},
gap = { client ->
if (isMisskey) {
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_MISSKEY_FOLLOW_SUGGESTION,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false,
misskeyParams = accessInfo.putMisskeyApiToken()
2021-05-17 15:20:08 +02:00
)
} else {
val (ti, ri) = TootInstance.get(client)
when {
ti == null -> ri
ti.versionGE(TootInstance.VERSION_3_4_0_rc1) ->
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_FOLLOW_SUGGESTION2,
listParser = mastodonFollowSuggestion2ListParser,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false
)
2024-01-04 06:41:40 +01:00
2021-05-17 15:20:08 +02:00
else ->
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_FOLLOW_SUGGESTION,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false
)
}
}
},
gapDirection = gapDirectionMastodonWorkaround,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2021-05-17 15:20:08 +02:00
),
2020-12-07 13:53:55 +01:00
ENDORSEMENT(
2021-05-17 15:20:08 +02:00
28,
iconId = { R.drawable.ic_person_add },
2021-05-17 15:20:08 +02:00
name1 = { it.getString(R.string.endorse_set) },
bAllowPseudo = false,
bAllowMisskey = false,
2021-05-17 16:13:04 +02:00
loading = { client -> getAccountList(client, ApiPath.PATH_ENDORSEMENT) },
refresh = { client -> getAccountList(client, ApiPath.PATH_ENDORSEMENT) },
2021-05-17 15:20:08 +02:00
gap = { client ->
getAccountList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_ENDORSEMENT,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false
)
},
gapDirection = gapDirectionMastodonWorkaround,
2020-12-07 13:53:55 +01:00
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
PROFILE_DIRECTORY(
36,
iconId = { R.drawable.ic_person_add },
2021-05-17 15:20:08 +02:00
name1 = { it.getString(R.string.profile_directory) },
name2 = { context.getString(R.string.profile_directory_of, instanceUri) },
2021-05-17 15:20:08 +02:00
bAllowPseudo = true,
headerType = HeaderType.ProfileDirectory,
loading = { client ->
column.pagingType = ColumnPagingType.Offset
getAccountList(client, profileDirectoryPath)
},
refresh = { client ->
getAccountList(client, profileDirectoryPath)
},
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2020-12-07 13:53:55 +01:00
),
ACCOUNT_AROUND(
31,
2021-05-17 15:20:08 +02:00
iconId = { R.drawable.ic_account_box },
name1 = { it.getString(R.string.account_tl_around) },
name2 = {
val id = statusId?.toString() ?: "null"
2021-05-17 15:20:08 +02:00
context.getString(R.string.account_tl_around_of, id)
},
2020-12-07 13:53:55 +01:00
2021-05-17 15:20:08 +02:00
loading = { client -> getAccountTlAroundTime(client) },
2020-12-07 13:53:55 +01:00
2021-05-17 15:20:08 +02:00
refresh = { client ->
getStatusList(client, column.makeProfileStatusesUrl(column.profileId), useMinId = true)
},
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
2020-12-07 13:53:55 +01:00
@Suppress("unused")
REPORTS(
2021-05-17 15:20:08 +02:00
6,
iconId = { R.drawable.ic_info_outline },
2021-05-17 15:20:08 +02:00
name1 = { it.getString(R.string.reports) },
2021-05-17 16:13:04 +02:00
loading = { client -> getReportList(client, ApiPath.PATH_REPORTS) },
refresh = { client -> getReportList(client, ApiPath.PATH_REPORTS) },
2021-05-17 15:20:08 +02:00
gap = { client ->
getReportList(
client,
2021-05-17 16:13:04 +02:00
ApiPath.PATH_REPORTS,
2021-05-17 15:20:08 +02:00
mastodonFilterByIdRange = false
)
},
gapDirection = gapDirectionMastodonWorkaround,
2020-12-07 13:53:55 +01:00
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
KEYWORD_FILTER(
26,
2021-05-17 15:20:08 +02:00
iconId = { R.drawable.ic_volume_off },
name1 = { it.getString(R.string.keyword_filters) },
bAllowPseudo = false,
bAllowMisskey = false,
headerType = HeaderType.Filter,
2020-12-07 13:53:55 +01:00
loading = { client ->
getFilterList(client)
},
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
2020-12-07 13:53:55 +01:00
),
SCHEDULED_STATUS(
33,
2021-05-17 15:20:08 +02:00
iconId = { R.drawable.ic_timer },
name1 = { it.getString(R.string.scheduled_status) },
bAllowPseudo = false,
bAllowMisskey = false,
loading = { client ->
val result = client.request("/api/v1/accounts/verify_credentials")
if (result == null || result.error != null) {
result
} else {
val a = parser.account(result.jsonObject) ?: accessInfo.loginAccount
2021-05-17 15:20:08 +02:00
if (a == null) {
TootApiResult("can't parse account information")
} else {
column.whoAccount = tootAccountRef(parser, a)
2021-05-17 15:20:08 +02:00
getScheduledStatuses(client)
}
}
},
refresh = { client -> getScheduledStatuses(client) },
2020-12-07 13:53:55 +01:00
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
MISSKEY_ANTENNA_LIST(
39,
2021-05-17 15:20:08 +02:00
iconId = { R.drawable.ic_satellite },
name1 = { it.getString(R.string.antenna_list) },
bAllowPseudo = false,
bAllowMastodon = false,
loading = { client ->
if (isMisskey) {
getAntennaList(
client,
"/api/antennas/list",
misskeyParams = column.makeMisskeyBaseParameter(parser)
)
} else {
TootApiResult("antenna is not supported on Mastodon")
}
},
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
2020-12-07 13:53:55 +01:00
MISSKEY_ANTENNA_TL(
2021-05-17 15:20:08 +02:00
40,
iconId = { R.drawable.ic_satellite },
name1 = { it.getString(R.string.antenna_timeline) },
name2 = {
context.getString(
R.string.antenna_timeline_of,
antennaInfo?.name ?: profileId.toString()
2021-05-17 15:20:08 +02:00
)
},
loading = { client ->
column.loadAntennaInfo(client, true)
if (isMisskey) {
getStatusList(
client,
column.makeAntennaTlUrl(),
misskeyParams = column.makeMisskeyTimelineParameter(parser).apply {
put("antennaId", column.profileId)
2021-05-17 15:20:08 +02:00
}
)
} else {
getStatusList(client, column.makeAntennaTlUrl())
}
},
refresh = { client ->
column.loadAntennaInfo(client, false)
if (isMisskey) {
getStatusList(
client,
column.makeAntennaTlUrl(),
misskeyParams = column.makeMisskeyTimelineParameter(parser).apply {
put("antennaId", column.profileId)
2021-05-17 15:20:08 +02:00
}
)
} else {
getStatusList(client, column.makeAntennaTlUrl())
}
},
gap = { client ->
if (isMisskey) {
getStatusList(
client,
column.makeAntennaTlUrl(),
mastodonFilterByIdRange = true,
misskeyParams = column.makeMisskeyTimelineParameter(parser).apply {
put("antennaId", column.profileId)
2021-05-17 15:20:08 +02:00
}
)
} else {
getStatusList(client, column.makeAntennaTlUrl(), mastodonFilterByIdRange = true)
}
},
gapDirection = gapDirectionBoth,
canAutoRefresh = true,
canStreamingMastodon = streamingTypeYes,
canStreamingMisskey = streamingTypeYes,
2021-05-17 15:20:08 +02:00
streamNameMisskey = "antenna",
streamParamMisskey = { jsonObjectOf("antennaId" to profileId.toString()) },
2021-05-17 15:20:08 +02:00
// Misskey10 にアンテナはない
),
2020-12-07 13:53:55 +01:00
STATUS_HISTORY(
43,
iconId = { R.drawable.ic_history },
name1 = { it.getString(R.string.edit_history) },
bAllowPseudo = true,
bAllowMisskey = false,
loading = { client ->
getEditHistory(client)
},
refresh = { client ->
getEditHistory(client)
},
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
FOLLOWED_HASHTAGS(
46,
iconId = { R.drawable.ic_hashtag },
name1 = { it.getString(R.string.followed_tags) },
bAllowPseudo = false,
bAllowMisskey = false,
loading = { client ->
getFollowedHashtags(client)
},
refresh = { client ->
getFollowedHashtags(client)
},
canAutoRefresh = false,
canStreamingMastodon = streamingTypeNo,
canStreamingMisskey = streamingTypeNo,
),
2020-12-07 13:53:55 +01:00
;
init {
val old = Column.typeMap[id]
if (id > 0 && old != null) error("ColumnType: duplicate id $id. name=$name, ${old.name}")
Column.typeMap.put(id, this)
}
companion object {
val log = LogCategory("ColumnType")
2020-12-07 13:53:55 +01:00
fun dump() {
var min = Int.MAX_VALUE
var max = Int.MIN_VALUE
2024-01-04 06:41:40 +01:00
for (it in entries) {
2020-12-07 13:53:55 +01:00
val id = it.id
min = min(min, id)
max = max(max, id)
}
log.i("dump: ColumnType range=$min..$max")
2020-12-07 13:53:55 +01:00
}
fun parse(id: Int) = Column.typeMap[id] ?: HOME
}
2019-08-23 01:49:20 +02:00
}
// public:local, public:local:media の2種類
fun Column.streamKeyLtl() =
2021-05-17 15:20:08 +02:00
"public:local"
.appendIf(":media", withAttachment)
// public, public:remote, public:remote:media, public:media の4種類
2021-05-17 15:20:08 +02:00
fun Column.streamKeyFtl() =
"public"
.appendIf(":remote", remoteOnly)
.appendIf(":media", withAttachment)
// public:domain, public:domain:media の2種類
fun Column.streamKeyDomainTl() =
2021-05-17 15:20:08 +02:00
"public:domain"
.appendIf(":media", withAttachment)
// hashtag, hashtag:local
// fedibirdだとhashtag:localは無効でイベントが発生しないが、
// REST APIはフラグを無視するのでユーザからはストリーミングが動作していないように見える
2021-05-17 15:20:08 +02:00
fun Column.streamKeyHashtagTl() =
"hashtag"
.appendIf(":local", instanceLocal)
private fun unmatchMastodonStream(
stream: JsonArray,
name: String,
expectArg: String? = null,
): Boolean {
2021-05-17 15:20:08 +02:00
val key = stream.string(0)
// when( key?.elementAtOrNull(0)){
// 'h' -> ColumnType.log.v("unmatchMastodonStream key=$key expect=$name")
// }
2021-05-17 15:20:08 +02:00
return when {
// ストリーム名が合わない
key != name -> true
// 引数が合わない
else -> unmatchMastodonStreamArg(stream.elementAtOrNull(1), expectArg)
}
}
2021-05-17 15:20:08 +02:00
private fun unmatchMastodonStreamArg(actual: Any?, expect: String?) = when {
expect == null -> actual != null
actual == null -> true // unmatch
else -> !expect.equals(actual.toString(), ignoreCase = true)
}