owenclave / app/src/main/java/io/nekohasekai/sagernet/database/GroupManager.kt

github - dev - back to tree - upstream
/****************************************************************************** * * * Copyright (C) 2021 by nekohasekai * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * ******************************************************************************/ package io.nekohasekai.sagernet.database import io.nekohasekai.sagernet.GroupType import io.nekohasekai.sagernet.bg.SubscriptionUpdater import io.nekohasekai.sagernet.ktx.applyDefaultValues object GroupManager { interface Listener { suspend fun groupAdd(group: ProxyGroup) suspend fun groupUpdated(group: ProxyGroup) suspend fun groupRemoved(groupId: Long) suspend fun groupUpdated(groupId: Long) } interface Interface { suspend fun confirm(message: String): Boolean suspend fun onUpdateSuccess( group: ProxyGroup, changed: Int, added: List, updated: Map, deleted: List, duplicate: List ) suspend fun onUpdateFailure(group: ProxyGroup, message: String) } private val listeners = ArrayList() var userInterface: Interface? = null suspend fun iterator(what: suspend Listener.() -> Unit) { synchronized(listeners) { listeners.toList() }.forEach { listener -> what(listener) } } fun addListener(listener: Listener) { synchronized(listeners) { listeners.add(listener) } } fun removeListener(listener: Listener) { synchronized(listeners) { listeners.remove(listener) } } suspend fun clearGroup(groupId: Long) { if (SagerDatabase.proxyDao.isIdInGroup(DataStore.selectedProxy, groupId) > 0) { DataStore.selectedProxy = 0L } SagerDatabase.proxyDao.deleteAll(groupId) iterator { groupUpdated(groupId) } } fun rearrange(groupId: Long) { val entities = SagerDatabase.proxyDao.getByGroup(groupId) for (index in entities.indices) { entities[index].userOrder = (index + 1).toLong() } SagerDatabase.proxyDao.updateProxy(entities) } suspend fun postUpdate(group: ProxyGroup) { iterator { groupUpdated(group) } } suspend fun postUpdate(groupId: Long) { postUpdate(SagerDatabase.groupDao.getById(groupId) ?: return) } suspend fun postReload(groupId: Long) { iterator { groupUpdated(groupId) } } suspend fun createGroup(group: ProxyGroup): ProxyGroup { group.userOrder = SagerDatabase.groupDao.nextOrder() ?: 1 group.id = SagerDatabase.groupDao.createGroup(group.applyDefaultValues()) iterator { groupAdd(group) } if (group.type == GroupType.SUBSCRIPTION && group.subscription?.autoUpdate == true) { SubscriptionUpdater.reconfigureUpdater() } return group } suspend fun updateGroup(group: ProxyGroup, reconfigureUpdater: Boolean = true) { SagerDatabase.groupDao.updateGroup(group) iterator { groupUpdated(group) } if (reconfigureUpdater && group.type == GroupType.SUBSCRIPTION && group.subscription?.autoUpdate == true) { SubscriptionUpdater.reconfigureUpdater() } } suspend fun deleteGroup(groupId: Long) { val group = SagerDatabase.groupDao.getById(groupId) SagerDatabase.groupDao.deleteById(groupId) SagerDatabase.proxyDao.deleteByGroup(groupId) iterator { groupRemoved(groupId) } if (group?.type == GroupType.SUBSCRIPTION && group.subscription?.autoUpdate == true) { SubscriptionUpdater.reconfigureUpdater() } } suspend fun deleteGroup(group: List) { SagerDatabase.groupDao.deleteGroup(group) SagerDatabase.proxyDao.deleteByGroup(group.map { it.id }.toLongArray()) for (proxyGroup in group) iterator { groupRemoved(proxyGroup.id) } if (group.any { it.type == GroupType.SUBSCRIPTION && it.subscription?.autoUpdate == true }) { SubscriptionUpdater.reconfigureUpdater() } } }