diff --git a/shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/rss/RssTimelineRemoteMediator.kt b/shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/rss/RssTimelineRemoteMediator.kt index cc9042fcc..f00399ab6 100644 --- a/shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/rss/RssTimelineRemoteMediator.kt +++ b/shared/src/commonMain/kotlin/dev/dimension/flare/data/datasource/rss/RssTimelineRemoteMediator.kt @@ -104,8 +104,8 @@ internal class RssTimelineRemoteMediator( content = StatusContent.Rss(it), text = it.data.description - .let { html -> parseHtml(html) } - .wholeText(), + ?.let { html -> parseHtml(html) } + ?.wholeText(), createdAt = it.data.date?.let { parseRssDateToInstant(it) } ?: Clock.System.now(), diff --git a/shared/src/commonMain/kotlin/dev/dimension/flare/data/network/rss/RssService.kt b/shared/src/commonMain/kotlin/dev/dimension/flare/data/network/rss/RssService.kt index f559438d7..e10eb3e00 100644 --- a/shared/src/commonMain/kotlin/dev/dimension/flare/data/network/rss/RssService.kt +++ b/shared/src/commonMain/kotlin/dev/dimension/flare/data/network/rss/RssService.kt @@ -5,13 +5,9 @@ import dev.dimension.flare.data.network.ktorClient import dev.dimension.flare.data.network.rss.model.Feed import dev.dimension.flare.data.repository.tryRun import dev.dimension.flare.ui.model.mapper.link -import io.ktor.client.call.body -import io.ktor.client.plugins.contentnegotiation.ContentNegotiation import io.ktor.client.request.get import io.ktor.client.statement.bodyAsText -import io.ktor.http.ContentType import io.ktor.http.Url -import io.ktor.serialization.kotlinx.xml.xml import kotlinx.serialization.decodeFromString import nl.adaptivity.xmlutil.serialization.XML @@ -25,16 +21,15 @@ internal object RssService { defaultToGenericParser = true } } + private val client = ktorClient { } - suspend fun fetch(url: String): Feed = - ktorClient(config = { - install(ContentNegotiation) { - xml(xml, contentType = ContentType.Any) - } - }).get(url).body() + suspend fun fetch(url: String): Feed { + val response = client.get(url).bodyAsText() + return xml.decodeFromString(response) + } suspend fun detectLinkSources(url: String): List = - ktorClient() + client .get(url) .bodyAsText() .let(Ksoup::parse) @@ -53,9 +48,7 @@ internal object RssService { suspend fun fetchIcon(url: String): String? { val webContent = tryRun { - ktorClient( - config = {}, - ).get(url).bodyAsText() + client.get(url).bodyAsText() }.getOrNull() ?: return null val feed = tryRun { @@ -76,9 +69,7 @@ internal object RssService { val html = if (feed?.link != null && feed.link != url) { tryRun { - ktorClient( - config = {}, - ).get(feedLink).bodyAsText() + client.get(feedLink).bodyAsText() }.getOrNull() ?: return null } else { webContent @@ -106,9 +97,7 @@ internal object RssService { val hasFavIcon = tryRun { val response = - ktorClient( - config = {}, - ).get(favIcon) + client.get(favIcon) if (response.status.value !in 200..299) { throw Exception("Failed to fetch favicon: ${response.status}") } diff --git a/shared/src/commonMain/kotlin/dev/dimension/flare/data/network/rss/model/Feed.kt b/shared/src/commonMain/kotlin/dev/dimension/flare/data/network/rss/model/Feed.kt index 2081dc700..7de95fd7c 100644 --- a/shared/src/commonMain/kotlin/dev/dimension/flare/data/network/rss/model/Feed.kt +++ b/shared/src/commonMain/kotlin/dev/dimension/flare/data/network/rss/model/Feed.kt @@ -257,7 +257,7 @@ internal sealed interface Feed { @XmlElement(true) val link: String, @XmlElement(true) - val description: String, + val description: String? = null, @XmlElement(true) val language: String? = null, @XmlElement(true) @@ -404,7 +404,7 @@ internal sealed interface Feed { @XmlElement(true) val link: String, @XmlElement(true) - val description: String, + val description: String? = null, @XmlElement(true) @XmlSerialName(value = "date", namespace = "http://purl.org/dc/elements/1.1/", prefix = "dc") val date: String? = null, @@ -417,7 +417,7 @@ internal sealed interface Feed { @XmlElement(true) val link: String, @XmlElement(true) - val description: String, + val description: String? = null, @XmlElement(true) @XmlSerialName(value = "date", namespace = "http://purl.org/dc/elements/1.1/", prefix = "dc") val date: String? = null, diff --git a/shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/mapper/Rss.kt b/shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/mapper/Rss.kt index 695d0ee5c..b7dadac4a 100644 --- a/shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/mapper/Rss.kt +++ b/shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/mapper/Rss.kt @@ -101,16 +101,16 @@ internal fun StatusContent.Rss.RssContent.Rss20.render(): UiTimeline = internal fun StatusContent.Rss.RssContent.RDF.render(): UiTimeline = with(data) { val descHtml = - description.let { + description?.let { Ksoup.parse(it) } - val img = descHtml.select("img").firstOrNull() + val img = descHtml?.select("img")?.firstOrNull() return UiTimeline( topMessage = null, content = UiTimeline.ItemContent.Feed( title = title, - description = descHtml.text(), + description = descHtml?.text(), url = link.replace("http://", "https://"), image = img?.attr("src"), source = source,