Skip to content

Commit 3e310a4

Browse files
committed
add bookmark support for bluesky
1 parent 0be3b0b commit 3e310a4

File tree

5 files changed

+122
-0
lines changed

5 files changed

+122
-0
lines changed

compose-ui/src/commonMain/kotlin/dev/dimension/flare/data/model/TabSettings.kt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,9 @@ public sealed interface TimelineTabItem : TabItem {
490490
icon = IconType.Mixed(IconType.Material.MaterialIcon.Feeds, accountKey),
491491
),
492492
),
493+
Bluesky.BookmarkTimelineTabItem(
494+
accountType = AccountType.Specific(accountKey),
495+
),
493496
DirectMessageTabItem(
494497
account = AccountType.Specific(accountKey),
495498
metaData =
@@ -887,6 +890,30 @@ public object Bluesky {
887890

888891
override fun update(metaData: TabMetaData): TabItem = copy(metaData = metaData)
889892
}
893+
894+
@Serializable
895+
public data class BookmarkTimelineTabItem(
896+
override val account: AccountType,
897+
override val metaData: TabMetaData,
898+
) : TimelineTabItem {
899+
override val key: String = "bookmark_$account"
900+
901+
override fun createPresenter(): TimelinePresenter =
902+
dev.dimension.flare.ui.presenter.home.bluesky
903+
.BlueskyBookmarkTimelinePresenter(account)
904+
905+
override fun update(metaData: TabMetaData): TabItem = copy(metaData = metaData)
906+
907+
public constructor(accountType: AccountType) :
908+
this(
909+
account = accountType,
910+
metaData =
911+
TabMetaData(
912+
title = TitleType.Localized(TitleType.Localized.LocalizedKey.Bookmark),
913+
icon = IconType.Material(IconType.Material.MaterialIcon.Bookmark),
914+
),
915+
)
916+
}
890917
}
891918

892919
@Serializable

shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/bluesky/BlueskyDataSource.kt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import app.bsky.actor.PreferencesUnion
1313
import app.bsky.actor.PutPreferencesRequest
1414
import app.bsky.actor.SavedFeed
1515
import app.bsky.actor.SavedFeedType
16+
import app.bsky.bookmark.CreateBookmarkRequest
17+
import app.bsky.bookmark.DeleteBookmarkRequest
1618
import app.bsky.embed.Images
1719
import app.bsky.embed.ImagesImage
1820
import app.bsky.embed.Record
@@ -59,6 +61,7 @@ import com.atproto.repo.PutRecordRequest
5961
import com.atproto.repo.StrongRef
6062
import dev.dimension.flare.common.BasePagingSource
6163
import dev.dimension.flare.common.BaseRemoteMediator
64+
import dev.dimension.flare.common.BaseTimelineLoader
6265
import dev.dimension.flare.common.CacheData
6366
import dev.dimension.flare.common.Cacheable
6467
import dev.dimension.flare.common.FileItem
@@ -2349,6 +2352,47 @@ internal class BlueskyDataSource(
23492352
null
23502353
},
23512354
).toPersistentList()
2355+
2356+
fun bookmarkTimeline(): BaseTimelineLoader =
2357+
BookmarkTimelineRemoteMediator(
2358+
service = service,
2359+
accountKey = accountKey,
2360+
database = database,
2361+
)
2362+
2363+
override fun bookmark(
2364+
uri: String,
2365+
cid: String,
2366+
) {
2367+
coroutineScope.launch {
2368+
tryRun {
2369+
service
2370+
.createBookmark(
2371+
CreateBookmarkRequest(
2372+
uri = AtUri(uri),
2373+
cid = Cid(cid),
2374+
),
2375+
).requireResponse()
2376+
}.onFailure {
2377+
it.printStackTrace()
2378+
}
2379+
}
2380+
}
2381+
2382+
override fun unbookmark(uri: String) {
2383+
coroutineScope.launch {
2384+
tryRun {
2385+
service
2386+
.deleteBookmark(
2387+
DeleteBookmarkRequest(
2388+
uri = AtUri(uri),
2389+
),
2390+
).requireResponse()
2391+
}.onFailure {
2392+
it.printStackTrace()
2393+
}
2394+
}
2395+
}
23522396
}
23532397

23542398
internal inline fun <reified T : Any> T.bskyJson(): JsonContent = bskyJson.encodeAsJsonContent(this)

shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/microblog/StatusEvent.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,13 @@ internal sealed interface StatusEvent {
116116
likedUri: String?,
117117
)
118118

119+
fun bookmark(
120+
uri: String,
121+
cid: String,
122+
)
123+
124+
fun unbookmark(uri: String)
125+
119126
fun likeWithResult(
120127
statusKey: MicroBlogKey,
121128
cid: String,

shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/mapper/Bluesky.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,22 @@ internal fun PostView.renderStatus(
504504
displayItem = StatusAction.Item.More,
505505
actions =
506506
listOfNotNull(
507+
StatusAction.Item.Bookmark(
508+
count = 0,
509+
bookmarked = viewer?.bookmarked == true,
510+
onClicked = {
511+
if (viewer?.bookmarked == true) {
512+
event.unbookmark(
513+
uri = uri.atUri,
514+
)
515+
} else {
516+
event.bookmark(
517+
uri = uri.atUri,
518+
cid = cid.cid,
519+
)
520+
}
521+
},
522+
),
507523
if (isFromMe) {
508524
StatusAction.Item.Delete(
509525
onClicked = {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package dev.dimension.flare.ui.presenter.home.bluesky
2+
3+
import dev.dimension.flare.common.BaseTimelineLoader
4+
import dev.dimension.flare.data.datasource.bluesky.BlueskyDataSource
5+
import dev.dimension.flare.data.repository.AccountRepository
6+
import dev.dimension.flare.data.repository.accountServiceFlow
7+
import dev.dimension.flare.model.AccountType
8+
import dev.dimension.flare.ui.presenter.home.TimelinePresenter
9+
import kotlinx.coroutines.flow.Flow
10+
import kotlinx.coroutines.flow.map
11+
import org.koin.core.component.KoinComponent
12+
import org.koin.core.component.inject
13+
14+
public class BlueskyBookmarkTimelinePresenter(
15+
private val accountType: AccountType,
16+
) : TimelinePresenter(),
17+
KoinComponent {
18+
private val accountRepository: AccountRepository by inject()
19+
override val loader: Flow<BaseTimelineLoader> by lazy {
20+
accountServiceFlow(
21+
accountType = accountType,
22+
repository = accountRepository,
23+
).map { value ->
24+
require(value is BlueskyDataSource)
25+
value.bookmarkTimeline()
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)