Skip to content

Commit ebd7fb9

Browse files
committed
Improve Akkoma support for bubble timeline and feature detection
1 parent a86ab4c commit ebd7fb9

4 files changed

Lines changed: 67 additions & 6 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package site.remlit.snowdrop.api.timeline
2+
3+
import com.russhwolf.settings.ExperimentalSettingsApi
4+
import io.ktor.client.request.get
5+
import io.ktor.client.request.header
6+
import io.ktor.client.request.parameter
7+
import site.remlit.snowdrop.model.ApiResponse
8+
import site.remlit.snowdrop.model.Status
9+
import site.remlit.snowdrop.util.config.endOfRequest
10+
import site.remlit.snowdrop.util.getCurrentAccountHost
11+
import site.remlit.snowdrop.util.getCurrentAccountId
12+
import site.remlit.snowdrop.util.config.httpClient
13+
import site.remlit.snowdrop.util.getFeature
14+
import site.remlit.snowdrop.util.safeApiRequest
15+
import site.remlit.snowdrop.util.settings
16+
17+
@OptIn(ExperimentalSettingsApi::class)
18+
suspend fun getBubbleTimeline(
19+
limit: Int = 30,
20+
21+
maxId: String? = null,
22+
sinceId: String? = null,
23+
offset: Int? = null,
24+
minId: String? = null,
25+
26+
local: Boolean? = null,
27+
remote: Boolean? = null,
28+
onlyMedia: Boolean? = null
29+
): ApiResponse<List<Status>> = safeApiRequest {
30+
if (getFeature("bubble_timeline_chuckya")) {
31+
return getPublicTimeline(maxId = maxId, minId = minId, sinceId = sinceId, bubble = true)
32+
}
33+
34+
val accountId = getCurrentAccountId()
35+
val host = getCurrentAccountHost()
36+
val token = settings.getString("account_${accountId}_token", "")
37+
38+
val req = httpClient.get("https://$host/api/v1/timelines/bubble") {
39+
header("Authorization", "Bearer $token")
40+
41+
parameter("limit", limit)
42+
43+
if (maxId != null) parameter("max_id", maxId)
44+
if (sinceId != null) parameter("since_id", sinceId)
45+
if (offset != null) parameter("offset", offset)
46+
if (minId != null) parameter("min_id", minId)
47+
48+
if (local != null) parameter("local", local)
49+
if (remote != null) parameter("remote", remote)
50+
if (onlyMedia != null) parameter("only_media", onlyMedia)
51+
}
52+
53+
endOfRequest(req)
54+
}

shared/src/commonMain/kotlin/site/remlit/snowdrop/model/InstanceV1.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ data class InstanceV1(
2626
val urls: Urls? = null,
2727
val configuration: Configuration? = null,
2828

29-
val rules: List<Rule>,
29+
val rules: List<Rule> = emptyList(),
3030
val thumbnail: String? = null
3131
) {
3232
@Serializable

shared/src/commonMain/kotlin/site/remlit/snowdrop/util/Features.kt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,23 @@ suspend fun determineFeatures() {
6969
) putFeature("reactions", true)
7070
else putFeature("reactions", false)
7171

72+
// sharkey has a bubble tl but its unlikely it has good mastoapi support
7273
if (
73-
software == Software.Akkoma ||
7474
software == Software.Chuckya ||
7575
software == Software.IceshrimpJS ||
7676
software == Software.IceshrimpNET
7777
) putFeature("bubble_timeline", true)
7878
else putFeature("bubble_timeline", false)
7979

80+
// and akkoma has a different route!
81+
if (
82+
software == Software.Akkoma
83+
) putFeature("bubble_timeline_akkoma", true)
84+
else putFeature("bubble_timeline_akkoma", false)
85+
8086
if (
8187
software == Software.IceshrimpNET
82-
)
83-
putFeature("biting", true)
88+
) putFeature("biting", true)
8489
else putFeature("biting", false)
8590

8691
determiningFeatures = false

shared/src/commonMain/kotlin/site/remlit/snowdrop/view/TimelineView.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import org.jetbrains.compose.resources.painterResource
3434
import org.jetbrains.compose.resources.stringResource
3535
import site.remlit.snowdrop.SettingsRoute
3636
import site.remlit.snowdrop.api.getBookmarks
37+
import site.remlit.snowdrop.api.timeline.getBubbleTimeline
3738
import site.remlit.snowdrop.api.timeline.getHomeTimeline
3839
import site.remlit.snowdrop.api.timeline.getPublicTimeline
3940
import site.remlit.snowdrop.component.RefreshableTimeline
@@ -97,7 +98,8 @@ fun TimelineView() = ViewSurface {
9798
return when (timelineType) {
9899
0 -> getHomeTimeline(maxId = maxId, minId = minId, sinceId = sinceId)
99100
1 -> getPublicTimeline(maxId = maxId, minId = minId, sinceId = sinceId, local = true)
100-
2 -> getPublicTimeline(maxId = maxId, minId = minId, sinceId = sinceId, bubble = true)
101+
2 -> if (getFeature("bubble_timeline_akkoma")) getBubbleTimeline(maxId = maxId, minId = minId, sinceId = sinceId)
102+
else getPublicTimeline(maxId = maxId, minId = minId, sinceId = sinceId, bubble = true)
101103
3 -> getPublicTimeline(maxId = maxId, minId = minId, sinceId = sinceId, remote = true)
102104

103105
else -> getBookmarks(maxId = maxId, minId = minId, sinceId = sinceId) // else 4
@@ -132,7 +134,7 @@ fun TimelineView() = ViewSurface {
132134
text = { Text(stringResource(Res.string.local)) },
133135
onClick = { blockingSettings.putInt("timeline", 1); timelinePickerOpen = false }
134136
)
135-
if (getFeature("bubble_timeline"))
137+
if (getFeature("bubble_timeline") || getFeature("bubble_timeline_akkoma"))
136138
DropdownMenuItem(
137139
leadingIcon = { RenderTimelineTypeIcon(2) },
138140
text = { Text(stringResource(Res.string.bubble)) },

0 commit comments

Comments
 (0)