mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-09 07:48:44 +01:00
refactor: improve community opening on other instances (#486)
This commit is contained in:
parent
4fee7addfd
commit
1b1facbdfe
@ -45,6 +45,7 @@ kotlin {
|
||||
implementation(projects.core.navigation)
|
||||
implementation(projects.core.commonui.detailopenerApi)
|
||||
|
||||
implementation(projects.domain.identity)
|
||||
implementation(projects.domain.lemmy.data)
|
||||
implementation(projects.domain.lemmy.repository)
|
||||
|
||||
|
@ -2,10 +2,14 @@ package com.github.diegoberaldin.raccoonforlemmy.core.commonui.detailopener.impl
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.detailopener.api.DetailOpener
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.navigation.NavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SearchResult
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SearchResultType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommunityRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.LemmyItemCache
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.communitydetail.CommunityDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.createcomment.CreateCommentScreen
|
||||
@ -14,23 +18,35 @@ import com.github.diegoberaldin.raccoonforlemmy.unit.postdetail.PostDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.userdetail.UserDetailScreen
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class DefaultDetailOpener(
|
||||
private val navigationCoordinator: NavigationCoordinator,
|
||||
private val itemCache: LemmyItemCache,
|
||||
private val identityRepository: IdentityRepository,
|
||||
private val communityRepository: CommunityRepository,
|
||||
) : DetailOpener {
|
||||
|
||||
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
||||
|
||||
override fun openCommunityDetail(community: CommunityModel, otherInstance: String) {
|
||||
scope.launch {
|
||||
itemCache.putCommunity(community)
|
||||
val (actualCommunity, actualInstance) = withContext(Dispatchers.IO) {
|
||||
val found = searchCommunity(community.name)
|
||||
if (found != null) {
|
||||
found to ""
|
||||
} else {
|
||||
community to otherInstance
|
||||
}
|
||||
}
|
||||
itemCache.putCommunity(actualCommunity)
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(
|
||||
communityId = community.id,
|
||||
otherInstance = otherInstance,
|
||||
communityId = actualCommunity.id,
|
||||
otherInstance = actualInstance,
|
||||
),
|
||||
)
|
||||
}
|
||||
@ -113,4 +129,31 @@ class DefaultDetailOpener(
|
||||
navigationCoordinator.pushScreen(screen)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun searchCommunity(name: String): CommunityModel? {
|
||||
val auth = identityRepository.authToken.value
|
||||
|
||||
tailrec suspend fun searchRec(page: Int = 0): CommunityModel? {
|
||||
val results = communityRepository.getAll(
|
||||
auth = auth,
|
||||
query = name,
|
||||
resultType = SearchResultType.Communities,
|
||||
page = page,
|
||||
limit = 50,
|
||||
)?.filterIsInstance<SearchResult.Community>().orEmpty()
|
||||
|
||||
val found = results.firstOrNull {
|
||||
it.model.name == name
|
||||
}?.model
|
||||
// iterates for no more than 20 pages before giving up
|
||||
if (found != null || page >= 20) {
|
||||
return found
|
||||
}
|
||||
|
||||
return searchRec(page + 1)
|
||||
}
|
||||
|
||||
// start recursive search
|
||||
return searchRec()
|
||||
}
|
||||
}
|
@ -18,6 +18,8 @@ internal val internalSharedModule = module {
|
||||
DefaultDetailOpener(
|
||||
navigationCoordinator = get(),
|
||||
itemCache = get(),
|
||||
identityRepository = get(),
|
||||
communityRepository = get(),
|
||||
)
|
||||
}
|
||||
}
|
@ -20,7 +20,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
@ -44,6 +43,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotific
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.about.AboutConstants.CHANGELOG_URL
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.about.AboutConstants.REPORT_EMAIL_ADDRESS
|
||||
@ -52,8 +52,6 @@ import com.github.diegoberaldin.raccoonforlemmy.unit.about.AboutConstants.WEBSIT
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.web.WebViewScreen
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
class AboutDialog : Screen {
|
||||
|
||||
@ -72,19 +70,6 @@ class AboutDialog : Screen {
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
val detailOpener = remember { getDetailOpener() }
|
||||
|
||||
LaunchedEffect(viewModel) {
|
||||
viewModel.effects.onEach { effect ->
|
||||
when (effect) {
|
||||
is AboutDialogMviModel.Effect.OpenCommunity -> {
|
||||
detailOpener.openCommunityDetail(
|
||||
community = effect.community,
|
||||
otherInstance = effect.instance,
|
||||
)
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
}
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
notificationCenter.send(NotificationCenterEvent.CloseDialog)
|
||||
@ -187,7 +172,10 @@ class AboutDialog : Screen {
|
||||
text = stringResource(MR.strings.settings_about_view_lemmy),
|
||||
textDecoration = TextDecoration.Underline,
|
||||
onClick = {
|
||||
viewModel.reduce(AboutDialogMviModel.Intent.OpenOwnCommunity)
|
||||
detailOpener.openCommunityDetail(
|
||||
community = CommunityModel(name = AboutConstants.LEMMY_COMMUNITY_NAME),
|
||||
otherInstance = AboutConstants.LEMMY_COMMUNITY_INSTANCE
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -199,7 +187,6 @@ class AboutDialog : Screen {
|
||||
onClick = {
|
||||
runCatching {
|
||||
uriHandler.openUri(AboutConstants.MATRIX_URL)
|
||||
viewModel.reduce(AboutDialogMviModel.Intent.OpenOwnCommunity)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -2,25 +2,16 @@ package com.github.diegoberaldin.raccoonforlemmy.unit.about
|
||||
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
|
||||
interface AboutDialogMviModel :
|
||||
MviModel<AboutDialogMviModel.Intent, AboutDialogMviModel.UiState, AboutDialogMviModel.Effect>,
|
||||
ScreenModel {
|
||||
|
||||
sealed interface Intent {
|
||||
data object OpenOwnCommunity : Intent
|
||||
}
|
||||
sealed interface Intent
|
||||
|
||||
data class UiState(
|
||||
val version: String = "",
|
||||
)
|
||||
|
||||
sealed interface Effect {
|
||||
data class OpenCommunity(
|
||||
val community: CommunityModel,
|
||||
val instance: String = "",
|
||||
) : Effect
|
||||
}
|
||||
|
||||
sealed interface Effect
|
||||
}
|
@ -3,23 +3,10 @@ package com.github.diegoberaldin.raccoonforlemmy.unit.about
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.debug.AppInfo
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SearchResult
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SearchResultType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommunityRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.about.AboutConstants.LEMMY_COMMUNITY_INSTANCE
|
||||
import com.github.diegoberaldin.raccoonforlemmy.unit.about.AboutConstants.LEMMY_COMMUNITY_NAME
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
|
||||
|
||||
class AboutDialogViewModel(
|
||||
private val mvi: DefaultMviModel<AboutDialogMviModel.Intent, AboutDialogMviModel.UiState, AboutDialogMviModel.Effect>,
|
||||
private val identityRepository: IdentityRepository,
|
||||
private val communityRepository: CommunityRepository,
|
||||
) : AboutDialogMviModel,
|
||||
MviModel<AboutDialogMviModel.Intent, AboutDialogMviModel.UiState, AboutDialogMviModel.Effect> by mvi {
|
||||
|
||||
@ -31,53 +18,4 @@ class AboutDialogViewModel(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun reduce(intent: AboutDialogMviModel.Intent) {
|
||||
when (intent) {
|
||||
AboutDialogMviModel.Intent.OpenOwnCommunity -> {
|
||||
mvi.scope?.launch(Dispatchers.IO) {
|
||||
val (community, instance) = searchCommunity().let { community ->
|
||||
if (community != null) {
|
||||
community to ""
|
||||
} else {
|
||||
communityRepository.get(
|
||||
name = LEMMY_COMMUNITY_NAME,
|
||||
instance = LEMMY_COMMUNITY_INSTANCE
|
||||
) to LEMMY_COMMUNITY_INSTANCE
|
||||
}
|
||||
}
|
||||
|
||||
if (community != null) {
|
||||
mvi.emitEffect(
|
||||
AboutDialogMviModel.Effect.OpenCommunity(
|
||||
community = community,
|
||||
instance = instance
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun searchCommunity(): CommunityModel? {
|
||||
val auth = identityRepository.authToken.value
|
||||
suspend fun searchRec(page: Int = 0): CommunityModel? {
|
||||
return communityRepository.getAll(
|
||||
auth = auth,
|
||||
query = LEMMY_COMMUNITY_NAME,
|
||||
resultType = SearchResultType.Communities,
|
||||
page = page,
|
||||
limit = 50,
|
||||
)
|
||||
?.filterIsInstance<SearchResult.Community>()
|
||||
?.firstOrNull {
|
||||
it.model.name == LEMMY_COMMUNITY_NAME
|
||||
}?.model ?: searchRec(page + 1)
|
||||
}
|
||||
return withTimeoutOrNull(5000) {
|
||||
// start recursive search
|
||||
searchRec()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,6 @@ val aboutModule = module {
|
||||
factory<AboutDialogMviModel> {
|
||||
AboutDialogViewModel(
|
||||
mvi = DefaultMviModel(AboutDialogMviModel.UiState()),
|
||||
identityRepository = get(),
|
||||
communityRepository = get(),
|
||||
)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user