Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ dependencies {
implementation(libs.okhttp)
implementation(libs.okhttp.coroutines)
implementation(libs.retrofit)
implementation(libs.retrofit.gson)
implementation(libs.retrofit.kotlinx.serialization)
implementation(libs.profileinstaller)
implementation(libs.work.runtime.ktx)
implementation(libs.datastore.preferences)
Expand Down
17 changes: 10 additions & 7 deletions app/src/main/java/me/ash/reader/domain/data/DiffMapHolder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package me.ash.reader.domain.data
import android.content.Context
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.snapshotFlow
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.json.Json
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -55,7 +57,8 @@ class DiffMapHolder @Inject constructor(

val shouldSyncWithRemote get() = currentAccount?.type != AccountType.Local

private val gson = Gson()
private val json = Json { ignoreUnknownKeys = true }
private val diffMapSerializer = MapSerializer(String.serializer(), Diff.serializer())

private val cacheDir = context.cacheDir.resolve("diff")
private var userCacheDir = cacheDir
Expand Down Expand Up @@ -210,7 +213,7 @@ class DiffMapHolder @Inject constructor(
private fun writeDiffsToCache() {
applicationScope.launch(ioDispatcher) {
try {
val tmpJson = gson.toJson(diffMap)
val tmpJson = json.encodeToString(diffMapSerializer, diffMap)
userCacheDir.mkdirs()
cacheFile.createNewFile()
if (cacheFile.exists() && cacheFile.canWrite()) {
Expand Down Expand Up @@ -258,9 +261,8 @@ class DiffMapHolder @Inject constructor(
applicationScope.launch(ioDispatcher) {
if (cacheFile.exists() && cacheFile.canRead()) {
val tmpJson = cacheFile.readText()
val mapType = object : TypeToken<Map<String, Diff>>() {}.type
val diffMapFromCache = gson.fromJson<Map<String, Diff>>(
tmpJson, mapType
val diffMapFromCache = json.decodeFromString(
diffMapSerializer, tmpJson
)
diffMapFromCache?.let {
diffMap.clear()
Expand All @@ -282,6 +284,7 @@ class DiffMapHolder @Inject constructor(
}
}

@Serializable
data class Diff(
val isUnread: Boolean, val articleId: String, val feedId: String
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
package me.ash.reader.domain.model.account.security

class FeverSecurityKey private constructor() : SecurityKey() {
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString

var serverUrl: String? = null
var username: String? = null
var password: String? = null
var clientCertificateAlias: String? = null
@Serializable
class FeverSecurityKey(
var serverUrl: String? = null,
var username: String? = null,
var password: String? = null,
var clientCertificateAlias: String? = null,
) : SecurityKey() {

constructor(serverUrl: String?, username: String?, password: String?, clientCertificateAlias: String?) : this() {
this.serverUrl = serverUrl
this.username = username
this.password = password
this.clientCertificateAlias = clientCertificateAlias
}

constructor(value: String? = DESUtils.empty) : this() {
decode(value, FeverSecurityKey::class.java).let {
constructor(value: String?) : this() {
decode<FeverSecurityKey>(value).let {
serverUrl = it.serverUrl
username = it.username
password = it.password
clientCertificateAlias = it.clientCertificateAlias
}
}

override fun toString(): String =
DESUtils.encrypt(json.encodeToString(this))
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
package me.ash.reader.domain.model.account.security

class FreshRSSSecurityKey private constructor() : SecurityKey() {
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString

var serverUrl: String? = null
var username: String? = null
var password: String? = null
var clientCertificateAlias: String? = null
@Serializable
class FreshRSSSecurityKey(
var serverUrl: String? = null,
var username: String? = null,
var password: String? = null,
var clientCertificateAlias: String? = null,
) : SecurityKey() {

constructor(serverUrl: String?, username: String?, password: String?, clientCertificateAlias: String?) : this() {
this.serverUrl = serverUrl
this.username = username
this.password = password
this.clientCertificateAlias = clientCertificateAlias
}

constructor(value: String? = DESUtils.empty) : this() {
decode(value, FreshRSSSecurityKey::class.java).let {
constructor(value: String?) : this() {
decode<FreshRSSSecurityKey>(value).let {
serverUrl = it.serverUrl
username = it.username
password = it.password
clientCertificateAlias = it.clientCertificateAlias
}
}

override fun toString(): String =
DESUtils.encrypt(json.encodeToString(this))
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
package me.ash.reader.domain.model.account.security

class GoogleReaderSecurityKey private constructor() : SecurityKey() {
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString

var serverUrl: String? = null
var username: String? = null
var password: String? = null
var clientCertificateAlias: String? = null
@Serializable
class GoogleReaderSecurityKey(
var serverUrl: String? = null,
var username: String? = null,
var password: String? = null,
var clientCertificateAlias: String? = null,
) : SecurityKey() {

constructor(serverUrl: String?, username: String?, password: String?, clientCertificateAlias: String?) : this() {
this.serverUrl = serverUrl
this.username = username
this.password = password
this.clientCertificateAlias = clientCertificateAlias
}

constructor(value: String? = DESUtils.empty) : this() {
decode(value, GoogleReaderSecurityKey::class.java).let {
constructor(value: String?) : this() {
decode<GoogleReaderSecurityKey>(value).let {
serverUrl = it.serverUrl
username = it.username
password = it.password
clientCertificateAlias = it.clientCertificateAlias
}
}

override fun toString(): String =
DESUtils.encrypt(json.encodeToString(this))
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package me.ash.reader.domain.model.account.security

class LocalSecurityKey private constructor() : SecurityKey() {
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString

constructor(value: String? = DESUtils.empty) : this() {
decode(value, LocalSecurityKey::class.java).let {
@Serializable
class LocalSecurityKey() : SecurityKey() {

}
constructor(value: String?) : this() {
decode<LocalSecurityKey>(value)
}

override fun toString(): String =
DESUtils.encrypt(json.encodeToString(this))
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package me.ash.reader.domain.model.account.security

import com.google.gson.Gson
import kotlinx.serialization.json.Json

abstract class SecurityKey {

fun <T> decode(value: String?, classOfT: Class<T>): T =
Gson().fromJson(DESUtils.decrypt(value?.ifEmpty { DESUtils.empty } ?: DESUtils.empty), classOfT)
@PublishedApi
internal val json: Json = Json { ignoreUnknownKeys = true }

override fun toString(): String {
return DESUtils.encrypt(Gson().toJson(this))
}
inline fun <reified T> decode(value: String?): T =
json.decodeFromString<T>(DESUtils.decrypt(value?.ifEmpty { DESUtils.empty } ?: DESUtils.empty))

override fun equals(other: Any?): Boolean {
return this.toString() == other.toString()
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/java/me/ash/reader/domain/service/AppService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ class AppService @Inject constructor(
val skipVersion = context.skipVersionNumber.toVersion()
val currentVersion = context.getCurrentVersion()
val latest = response.body()!!
val latestVersion = latest.tag_name.toVersion()
val latestVersion = latest.tagName.toVersion()
// val latestVersion = "1.0.0".toVersion()
val latestLog = latest.body ?: ""
val latestPublishDate = latest.published_at ?: latest.created_at ?: ""
val latestPublishDate = latest.publishedAt ?: latest.createdAt ?: ""
val latestSize = latest.assets?.first()?.size ?: 0
val latestDownloadUrl = latest.assets?.first()?.browser_download_url ?: ""
val latestDownloadUrl = latest.assets?.first()?.browserDownloadUrl ?: ""

Log.i("RLog", "current version $currentVersion")
if (latestVersion.whetherNeedUpdate(currentVersion, skipVersion)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.ResponseBody
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.kotlinx.serialization.asConverterFactory
import retrofit2.http.GET
import retrofit2.http.Streaming
import retrofit2.http.Url
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.io.File

interface NetworkDataSource {
Expand All @@ -31,7 +35,7 @@ interface NetworkDataSource {
return instance ?: synchronized(this) {
instance ?: Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(Json { ignoreUnknownKeys = true }.asConverterFactory("application/json; charset=UTF8".toMediaType()))
.build().create(NetworkDataSource::class.java).also {
instance = it
}
Expand Down Expand Up @@ -91,26 +95,28 @@ fun ResponseBody.downloadToFileWithProgress(saveFile: File): Flow<Download> =
}
}.flowOn(Dispatchers.IO).distinctUntilChanged()

@Serializable
data class LatestRelease(
val html_url: String? = null,
val tag_name: String? = null,
@SerialName("html_url") val htmlUrl: String? = null,
@SerialName("tag_name") val tagName: String? = null,
val name: String? = null,
val draft: Boolean? = null,
val prerelease: Boolean? = null,
val created_at: String? = null,
val published_at: String? = null,
@SerialName("created_at") val createdAt: String? = null,
@SerialName("published_at") val publishedAt: String? = null,
val assets: List<AssetsItem>? = null,
val body: String? = null,
)

@Serializable
data class AssetsItem(
val name: String? = null,
val content_type: String? = null,
@SerialName("content_type") val contentType: String? = null,
val size: Int? = null,
val download_count: Int? = null,
val created_at: String? = null,
val updated_at: String? = null,
val browser_download_url: String? = null,
@SerialName("download_count") val downloadCount: Int? = null,
@SerialName("created_at") val createdAt: String? = null,
@SerialName("updated_at") val updatedAt: String? = null,
@SerialName("browser_download_url") val browserDownloadUrl: String? = null,
)

sealed class Download {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package me.ash.reader.infrastructure.rss.provider

import android.content.Context
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import kotlinx.serialization.json.Json
import me.ash.reader.infrastructure.di.UserAgentInterceptor
import me.ash.reader.infrastructure.di.cachingHttpClient
import okhttp3.OkHttpClient
Expand All @@ -17,8 +16,8 @@ abstract class ProviderAPI(context: Context, clientCertificateAlias: String?) {
.addNetworkInterceptor(UserAgentInterceptor)
.build()

protected val gson: Gson = GsonBuilder().create()
protected val json: Json = Json { ignoreUnknownKeys = true }

protected inline fun <reified T> toDTO(jsonStr: String): T =
gson.fromJson(jsonStr, T::class.java)!!
json.decodeFromString(jsonStr)
}
Loading
Loading