Skip to content

Commit 3fdf9b6

Browse files
authored
Merge pull request #1061 from DimensionDev/feature/rss_source
add rss source display
2 parents e255f99 + d3b8a31 commit 3fdf9b6

7 files changed

Lines changed: 197 additions & 163 deletions

File tree

server/src/commonMain/kotlin/dev/dimension/flare/server/service/ai/OpenAIAIService.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,7 @@ internal class OpenAIAIService(
6969
),
7070
)
7171
)
72-
response.choices.firstOrNull()?.message?.content?.let {
73-
return it
74-
} ?: run {
72+
return response.choices.firstOrNull()?.message?.content ?:
7573
throw IllegalStateException("No response from OpenAI")
76-
}
7774
}
7875
}

shared/src/commonMain/kotlin/dev/dimension/flare/data/database/cache/model/StatusContent.kt

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -89,24 +89,32 @@ internal sealed interface StatusContent {
8989
) : StatusContent
9090

9191
@Serializable
92-
sealed interface RSS : StatusContent {
92+
data class Rss(
93+
val data: RssContent,
94+
) : StatusContent {
9395
@Serializable
94-
@SerialName("rss-atom")
95-
data class Atom internal constructor(
96-
internal val data: Feed.Atom.Entry,
97-
) : RSS
98-
99-
@Serializable
100-
@SerialName("rss-rss20")
101-
data class Rss20 internal constructor(
102-
internal val data: Feed.Rss20.Item,
103-
) : RSS
104-
105-
@Serializable
106-
@SerialName("rss-rdf")
107-
data class RDF internal constructor(
108-
internal val data: Feed.RDF.Item,
109-
) : RSS
96+
sealed interface RssContent {
97+
@Serializable
98+
@SerialName("atom")
99+
data class Atom internal constructor(
100+
internal val data: Feed.Atom.Entry,
101+
internal val source: String,
102+
) : RssContent
103+
104+
@Serializable
105+
@SerialName("rss20")
106+
data class Rss20 internal constructor(
107+
internal val data: Feed.Rss20.Item,
108+
internal val source: String,
109+
) : RssContent
110+
111+
@Serializable
112+
@SerialName("rdf")
113+
data class RDF internal constructor(
114+
internal val data: Feed.RDF.Item,
115+
internal val source: String,
116+
) : RssContent
117+
}
110118
}
111119
}
112120

shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/rss/RssTimelineRemoteMediator.kt

Lines changed: 80 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import dev.dimension.flare.data.network.rss.model.Feed
1717
import dev.dimension.flare.model.AccountType
1818
import dev.dimension.flare.model.MicroBlogKey
1919
import dev.dimension.flare.ui.model.mapper.fromRss
20+
import dev.dimension.flare.ui.model.mapper.title
2021
import dev.dimension.flare.ui.render.parseHtml
2122

2223
@OptIn(ExperimentalPagingApi::class)
@@ -34,69 +35,88 @@ internal class RssTimelineRemoteMediator(
3435
val content =
3536
when (response) {
3637
is Feed.Atom ->
37-
response.entries.map { StatusContent.RSS.Atom(it) }.map {
38-
DbStatusWithUser(
39-
user = null,
40-
data =
41-
DbStatus(
42-
statusKey =
43-
MicroBlogKey.fromRss(
44-
it.data.links
45-
.first()
46-
.href,
47-
),
48-
accountType = AccountType.Guest,
49-
userKey = null,
50-
content = it,
51-
text =
52-
it.data.content
53-
?.value
54-
?.let { html -> parseHtml(html) }
55-
?.wholeText(),
56-
),
57-
)
58-
}
38+
response.entries
39+
.map {
40+
StatusContent.Rss.RssContent.Atom(
41+
it,
42+
source = response.title.value,
43+
)
44+
}.map {
45+
DbStatusWithUser(
46+
user = null,
47+
data =
48+
DbStatus(
49+
statusKey =
50+
MicroBlogKey.fromRss(
51+
it.data.links
52+
.first()
53+
.href,
54+
),
55+
accountType = AccountType.Guest,
56+
userKey = null,
57+
content = StatusContent.Rss(it),
58+
text =
59+
it.data.content
60+
?.value
61+
?.let { html -> parseHtml(html) }
62+
?.wholeText(),
63+
),
64+
)
65+
}
5966

6067
is Feed.RDF ->
61-
response.items.map { StatusContent.RSS.RDF(it) }.map {
62-
DbStatusWithUser(
63-
user = null,
64-
data =
65-
DbStatus(
66-
statusKey =
67-
MicroBlogKey.fromRss(
68-
it.data.link,
69-
),
70-
accountType = AccountType.Guest,
71-
userKey = null,
72-
content = it,
73-
text =
74-
it.data.description
75-
.let { html -> parseHtml(html) }
76-
.wholeText(),
77-
),
78-
)
79-
}
68+
response.items
69+
.map {
70+
StatusContent.Rss.RssContent.RDF(
71+
it,
72+
source = response.title,
73+
)
74+
}.map {
75+
DbStatusWithUser(
76+
user = null,
77+
data =
78+
DbStatus(
79+
statusKey =
80+
MicroBlogKey.fromRss(
81+
it.data.link,
82+
),
83+
accountType = AccountType.Guest,
84+
userKey = null,
85+
content = StatusContent.Rss(it),
86+
text =
87+
it.data.description
88+
.let { html -> parseHtml(html) }
89+
.wholeText(),
90+
),
91+
)
92+
}
93+
8094
is Feed.Rss20 ->
81-
response.channel.items.map { StatusContent.RSS.Rss20(it) }.map {
82-
DbStatusWithUser(
83-
user = null,
84-
data =
85-
DbStatus(
86-
statusKey =
87-
MicroBlogKey.fromRss(
88-
it.data.link,
89-
),
90-
accountType = AccountType.Guest,
91-
userKey = null,
92-
content = it,
93-
text =
94-
it.data.description
95-
?.let { html -> parseHtml(html) }
96-
?.wholeText(),
97-
),
98-
)
99-
}
95+
response.channel.items
96+
.map {
97+
StatusContent.Rss.RssContent.Rss20(
98+
it,
99+
source = response.title,
100+
)
101+
}.map {
102+
DbStatusWithUser(
103+
user = null,
104+
data =
105+
DbStatus(
106+
statusKey =
107+
MicroBlogKey.fromRss(
108+
it.data.link,
109+
),
110+
accountType = AccountType.Guest,
111+
userKey = null,
112+
content = StatusContent.Rss(it),
113+
text =
114+
it.data.description
115+
?.let { html -> parseHtml(html) }
116+
?.wholeText(),
117+
),
118+
)
119+
}
100120
}.mapIndexed { index, status ->
101121
createDbPagingTimelineWithStatus(
102122
accountType = AccountType.Guest,

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import dev.dimension.flare.ui.humanizer.humanize
99
import dev.dimension.flare.ui.model.mapper.MisskeyAchievement
1010
import dev.dimension.flare.ui.render.UiDateTime
1111
import dev.dimension.flare.ui.render.UiRichText
12+
import io.ktor.http.Url
1213
import kotlinx.collections.immutable.ImmutableList
1314
import kotlinx.collections.immutable.persistentListOf
1415

@@ -68,9 +69,14 @@ public data class UiTimeline internal constructor(
6869
val onClicked: ClickContext.() -> Unit = {
6970
launcher.launch(AppDeepLink.RSS.invoke(url))
7071
},
72+
val source: String,
7173
) : ItemContent {
7274
override val itemKey: String
7375
get() = "Feed_$url"
76+
val sourceIcon: String by lazy {
77+
val url = Url(url)
78+
"https://${url.host}/favicon.ico"
79+
}
7480
}
7581

7682
public data class Status internal constructor(

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,7 @@ internal fun StatusContent.render(
107107
accountKey = event.accountKey,
108108
)
109109

110-
is StatusContent.RSS.Atom -> data.render()
111-
is StatusContent.RSS.RDF -> data.render()
112-
is StatusContent.RSS.Rss20 -> data.render()
110+
is StatusContent.Rss -> data.render()
113111
}
114112

115113
internal fun DbUser.render(accountKey: MicroBlogKey) =

0 commit comments

Comments
 (0)