@@ -13,7 +13,9 @@ import features.proxy.server.usecase.withUpdatedSubscriptionServers
1313import features.subscription.runtime.AndroidSubscriptionFetcher
1414import features.subscription.usecase.toSubscriptionFetchOptions
1515import features.subscription.usecase.updateSubscriptions
16+ import features.subscription.usecase.subscriptionUpdateMessage
1617import io.ktor.http.Url
18+ import ui.text.formatTemplate
1719import utils.decodeUrlComponentPreservingPlus
1820
1921internal data class SubscriptionInstallConfig (
@@ -22,14 +24,19 @@ internal data class SubscriptionInstallConfig(
2224 val userAgent : String ,
2325)
2426
27+ internal data class SubscriptionInstallResult (
28+ val updateResult : ProxyServerListSubscriptionUpdateResult ,
29+ val existingGroupName : String? ,
30+ )
31+
2532internal class SubscriptionInstallConfigUseCase (
2633 private val stateStore : AndroidAppStateStore ,
2734 private val subscriptionFetcher : AndroidSubscriptionFetcher ,
2835) {
29- suspend fun install (config : SubscriptionInstallConfig ): ProxyServerListSubscriptionUpdateResult {
30- val group = stateStore.prepareSubscriptionInstallGroup(config)
36+ suspend fun install (config : SubscriptionInstallConfig ): SubscriptionInstallResult {
37+ val preparedGroup = stateStore.prepareSubscriptionInstallGroup(config)
3138 val result = updateSubscriptions(
32- groups = listOf (group),
39+ groups = listOf (preparedGroup. group),
3340 subscriptionFetcher = subscriptionFetcher,
3441 fetchOptions = { stateStore.state.value.toSubscriptionFetchOptions(it) },
3542 )
@@ -41,10 +48,31 @@ internal class SubscriptionInstallConfigUseCase(
4148 )
4249 }
4350 }
44- return result
51+ return SubscriptionInstallResult (
52+ updateResult = result,
53+ existingGroupName = preparedGroup.existingGroupName,
54+ )
4555 }
4656}
4757
58+ internal fun subscriptionInstallMessage (
59+ result : SubscriptionInstallResult ,
60+ existingUrlTemplate : String ,
61+ successTemplate : String ,
62+ failedTemplate : String ,
63+ ): String {
64+ val updateMessage = subscriptionUpdateMessage(
65+ result = result.updateResult,
66+ successTemplate = successTemplate,
67+ failedTemplate = failedTemplate,
68+ )
69+ val existingGroupName = result.existingGroupName ? : return updateMessage
70+ return listOf (
71+ existingUrlTemplate.formatTemplate(" name" to existingGroupName),
72+ updateMessage,
73+ ).joinToString(separator = " \n " )
74+ }
75+
4876internal fun Intent.toSubscriptionInstallConfigOrNull (): SubscriptionInstallConfig ? {
4977 if (action != Intent .ACTION_VIEW ) return null
5078 return data?.toString()?.toSubscriptionInstallConfigOrNull()
@@ -103,15 +131,26 @@ private fun Url.toRawHttpsSubscriptionInstallConfigOrNull(rawValue: String): Sub
103131
104132private fun AndroidAppStateStore.prepareSubscriptionInstallGroup (
105133 config : SubscriptionInstallConfig ,
106- ): SubscriptionGroupState {
107- var savedGroup : SubscriptionGroupState ? = null
134+ ): PreparedSubscriptionInstallGroup {
135+ var preparedGroup : PreparedSubscriptionInstallGroup ? = null
108136 update { state ->
137+ val existingGroup = state.existingSubscriptionGroupByUrl(config.url)
138+ if (existingGroup != null ) {
139+ preparedGroup = PreparedSubscriptionInstallGroup (
140+ group = existingGroup,
141+ existingGroupName = existingGroup.name,
142+ )
143+ return @update state
144+ }
109145 val reusableGroup = state.reusableDefaultSubscriptionGroup()
110146 val group = reusableGroup?.copy(
111147 url = config.url,
112148 userAgent = config.userAgent,
113149 ) ? : state.newSubscriptionGroup(config)
114- savedGroup = group
150+ preparedGroup = PreparedSubscriptionInstallGroup (
151+ group = group,
152+ existingGroupName = null ,
153+ )
115154 if (reusableGroup == null ) {
116155 state.copy(
117156 subscriptionGroups = state.subscriptionGroups + group,
@@ -125,7 +164,16 @@ private fun AndroidAppStateStore.prepareSubscriptionInstallGroup(
125164 )
126165 }
127166 }
128- return checkNotNull(savedGroup)
167+ return checkNotNull(preparedGroup)
168+ }
169+
170+ private data class PreparedSubscriptionInstallGroup (
171+ val group : SubscriptionGroupState ,
172+ val existingGroupName : String? ,
173+ )
174+
175+ private fun AppState.existingSubscriptionGroupByUrl (url : String ): SubscriptionGroupState ? {
176+ return subscriptionGroups.firstOrNull { group -> group.url == url }
129177}
130178
131179private fun AppState.reusableDefaultSubscriptionGroup (): SubscriptionGroupState ? {
0 commit comments