diff --git a/app/src/main/kotlin/li/songe/gkd/data/RawSubscription.kt b/app/src/main/kotlin/li/songe/gkd/data/RawSubscription.kt index f21bfbe..a5de106 100644 --- a/app/src/main/kotlin/li/songe/gkd/data/RawSubscription.kt +++ b/app/src/main/kotlin/li/songe/gkd/data/RawSubscription.kt @@ -814,9 +814,8 @@ data class RawSubscription( return subscription } - fun parseRawApp(source: String, json5: Boolean = true): RawApp { - val text = if (json5) json5ToJson(source) else source - val a = jsonToAppRaw(json.parseToJsonElement(text).jsonObject, 0) + fun parseApp(jsonObject: JsonObject): RawApp { + val a = jsonToAppRaw(jsonObject, 0) a.groups.findDuplicatedItem { v -> v.key }?.let { v -> error("duplicated app group: key=${v.key}") } @@ -828,15 +827,24 @@ data class RawSubscription( return a } - fun parseRawGroup(source: String, json5: Boolean = true): RawAppGroup { + fun parseRawApp(source: String, json5: Boolean = true): RawApp { val text = if (json5) json5ToJson(source) else source - val g = jsonToGroupRaw(json.parseToJsonElement(text).jsonObject, 0) + return parseApp(json.parseToJsonElement(text).jsonObject) + } + + fun parseGroup(jsonObject: JsonObject): RawAppGroup { + val g = jsonToGroupRaw(jsonObject, 0) g.rules.findDuplicatedItem { v -> v.key }?.let { v -> error("duplicated app rule: key=${v.key}") } return g } + fun parseRawGroup(source: String, json5: Boolean = true): RawAppGroup { + val text = if (json5) json5ToJson(source) else source + return parseGroup(json.parseToJsonElement(text).jsonObject) + } + fun parseRawGlobalGroup(source: String, json5: Boolean = true): RawGlobalGroup { val text = if (json5) json5ToJson(source) else source val g = jsonToGlobalGroups(json.parseToJsonElement(text).jsonObject, 0) diff --git a/app/src/main/kotlin/li/songe/gkd/ui/AppItemPage.kt b/app/src/main/kotlin/li/songe/gkd/ui/AppItemPage.kt index ac699a9..56abec9 100644 --- a/app/src/main/kotlin/li/songe/gkd/ui/AppItemPage.kt +++ b/app/src/main/kotlin/li/songe/gkd/ui/AppItemPage.kt @@ -60,6 +60,8 @@ import com.blankj.utilcode.util.LogUtils import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootNavGraph import kotlinx.coroutines.Dispatchers +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.jsonObject import li.songe.gkd.data.ExcludeData import li.songe.gkd.data.RawSubscription import li.songe.gkd.data.SubsConfig @@ -74,6 +76,7 @@ import li.songe.gkd.util.appInfoCacheFlow import li.songe.gkd.util.encodeToJson5String import li.songe.gkd.util.getGroupRawEnable import li.songe.gkd.util.json +import li.songe.gkd.util.json5ToJson import li.songe.gkd.util.launchAsFn import li.songe.gkd.util.launchTry import li.songe.gkd.util.navigate @@ -407,29 +410,40 @@ fun AppItemPage( } }, confirmButton = { - TextButton(onClick = { + TextButton(onClick = vm.viewModelScope.launchAsFn(Dispatchers.Default) { if (oldSource == source) { - toast("规则无变动") + toast("规则组无变动") setEditGroupRaw(null) - return@TextButton + return@launchAsFn } - val newGroupRaw = try { - RawSubscription.parseRawGroup(source) + val element = try { + json.parseToJsonElement(json5ToJson(source)).jsonObject } catch (e: Exception) { LogUtils.d(e) - toast("非法规则:${e.message}") - return@TextButton + error("非法JSON:${e.message}") + } + val newGroupRaw = try { + if (element["groups"] is JsonArray) { + RawSubscription.parseApp(element).groups.let { + it.find { g -> g.key == editGroupRaw.key } ?: it.firstOrNull() + } + } else { + null + } ?: RawSubscription.parseGroup(element) + } catch (e: Exception) { + LogUtils.d(e) + error("非法规则:${e.message}") } if (newGroupRaw.key != editGroupRaw.key) { toast("不能更改规则组的key") - return@TextButton + return@launchAsFn } if (newGroupRaw.errorDesc != null) { toast(newGroupRaw.errorDesc!!) - return@TextButton + return@launchAsFn } setEditGroupRaw(null) - subsRaw ?: return@TextButton + subsRaw ?: return@launchAsFn val newSubsRaw = subsRaw.copy(apps = subsRaw.apps.toMutableList().apply { set( indexOfFirst { a -> a.id == appRaw.id }, @@ -440,11 +454,9 @@ fun AppItemPage( }) ) }) - vm.viewModelScope.launchTry(Dispatchers.IO) { - updateSubscription(newSubsRaw) - DbSet.subsItemDao.update(subsItem.copy(mtime = System.currentTimeMillis())) - toast("更新成功") - } + updateSubscription(newSubsRaw) + DbSet.subsItemDao.update(subsItem.copy(mtime = System.currentTimeMillis())) + toast("更新成功") }, enabled = source.isNotEmpty()) { Text(text = "更新") }