mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-09 11:38:40 +01:00
fix: deep link (and hide back button if not possible)
This commit is contained in:
parent
e168ab2396
commit
ba7c197957
@ -6,7 +6,7 @@ import org.koin.core.qualifier.named
|
||||
import org.koin.dsl.module
|
||||
|
||||
val coreApiModule = module {
|
||||
single<ServiceProvider> {
|
||||
single<ServiceProvider>(named("default")) {
|
||||
DefaultServiceProvider()
|
||||
}
|
||||
single<ServiceProvider>(named("custom")) {
|
||||
|
@ -57,26 +57,6 @@ internal class DefaultServiceProvider : ServiceProvider {
|
||||
|
||||
private val factory = provideHttpClientEngineFactory()
|
||||
|
||||
private val client = HttpClient(factory) {
|
||||
defaultRequest {
|
||||
url {
|
||||
host = currentInstance
|
||||
}
|
||||
}
|
||||
install(HttpTimeout) {
|
||||
requestTimeoutMillis = 600_000
|
||||
connectTimeoutMillis = 30_000
|
||||
socketTimeoutMillis = 30_000
|
||||
}
|
||||
install(Logging) {
|
||||
logger = defaultLogger
|
||||
level = LogLevel.ALL
|
||||
}
|
||||
install(ContentNegotiation) {
|
||||
json(Json { isLenient = true; ignoreUnknownKeys = true })
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
reinitialize()
|
||||
}
|
||||
@ -87,6 +67,25 @@ internal class DefaultServiceProvider : ServiceProvider {
|
||||
}
|
||||
|
||||
private fun reinitialize() {
|
||||
val client = HttpClient(factory) {
|
||||
defaultRequest {
|
||||
url {
|
||||
host = currentInstance
|
||||
}
|
||||
}
|
||||
install(HttpTimeout) {
|
||||
requestTimeoutMillis = 600_000
|
||||
connectTimeoutMillis = 30_000
|
||||
socketTimeoutMillis = 30_000
|
||||
}
|
||||
install(Logging) {
|
||||
logger = defaultLogger
|
||||
level = LogLevel.ALL
|
||||
}
|
||||
install(ContentNegotiation) {
|
||||
json(Json { isLenient = true; ignoreUnknownKeys = true })
|
||||
}
|
||||
}
|
||||
val ktorfit = Ktorfit.Builder()
|
||||
.baseUrl(baseUrl)
|
||||
.httpClient(client)
|
||||
|
@ -213,14 +213,16 @@ class CommunityDetailScreen(
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick {
|
||||
navigator?.pop()
|
||||
},
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
||||
)
|
||||
if (navigator?.canPop == true) {
|
||||
Image(
|
||||
modifier = Modifier.onClick {
|
||||
navigator.pop()
|
||||
},
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}, floatingActionButton = {
|
||||
|
@ -9,7 +9,7 @@ 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.UserModel
|
||||
|
||||
fun getCommmunityFromUrl(url: String): CommunityModel? {
|
||||
fun getCommunityFromUrl(url: String?): CommunityModel? {
|
||||
val (normalizedUrl, instance) = normalizeUrl(url)
|
||||
val res = extractCommunity(normalizedUrl)
|
||||
return if (res != null && res.host.isEmpty()) {
|
||||
@ -19,7 +19,7 @@ fun getCommmunityFromUrl(url: String): CommunityModel? {
|
||||
}
|
||||
}
|
||||
|
||||
fun getUserFromUrl(url: String): UserModel? {
|
||||
fun getUserFromUrl(url: String?): UserModel? {
|
||||
val (normalizedUrl, instance) = normalizeUrl(url)
|
||||
val res = extractUser(normalizedUrl)
|
||||
return if (res != null && res.host.isEmpty()) {
|
||||
@ -29,10 +29,10 @@ fun getUserFromUrl(url: String): UserModel? {
|
||||
}
|
||||
}
|
||||
|
||||
fun getPostFromUrl(url: String): Pair<PostModel, String>? {
|
||||
fun getPostFromUrl(url: String?): Pair<PostModel, String>? {
|
||||
val (normalizedUrl, instance) = normalizeUrl(url)
|
||||
val post = extractPost(normalizedUrl)
|
||||
return if (post != null && instance != null) {
|
||||
return if (post != null && instance.isNotEmpty()) {
|
||||
post to instance
|
||||
} else {
|
||||
null
|
||||
@ -45,7 +45,7 @@ fun handleUrl(
|
||||
uriHandler: UriHandler,
|
||||
navigator: Navigator? = null,
|
||||
) {
|
||||
val community = getCommmunityFromUrl(url)
|
||||
val community = getCommunityFromUrl(url)
|
||||
val user = getUserFromUrl(url)
|
||||
|
||||
when {
|
||||
@ -79,8 +79,8 @@ fun handleUrl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun normalizeUrl(url: String): Pair<String, String> {
|
||||
val matches = Regex("https?://(?<instance>.*?)(?<pathAndQuery>/.*)").findAll(url)
|
||||
private fun normalizeUrl(url: String?): Pair<String, String> {
|
||||
val matches = Regex("https?://(?<instance>.*?)(?<pathAndQuery>/.*)").findAll(url.orEmpty())
|
||||
var instance = ""
|
||||
val res = buildString {
|
||||
if (matches.count() > 0) {
|
||||
|
@ -7,12 +7,13 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.getAndUpdate
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
internal class DefaultNavigationCoordinator : NavigationCoordinator {
|
||||
|
||||
override val onDoubleTabSelection = MutableSharedFlow<Tab>()
|
||||
override val deeplinkUrl = MutableStateFlow<String?>(null)
|
||||
override val deepLinkUrl = MutableStateFlow<String?>(null)
|
||||
|
||||
private var connection: NestedScrollConnection? = null
|
||||
private var navigator: Navigator? = null
|
||||
@ -43,8 +44,10 @@ internal class DefaultNavigationCoordinator : NavigationCoordinator {
|
||||
}
|
||||
}
|
||||
|
||||
override fun submitDeeplink(url: String?) {
|
||||
deeplinkUrl.value = url
|
||||
override fun consumeDeeplink(): String? = deepLinkUrl.getAndUpdate { null }
|
||||
|
||||
override fun submitDeeplink(url: String) {
|
||||
deepLinkUrl.value = url
|
||||
}
|
||||
|
||||
override fun setCanGoBackCallback(value: (() -> Boolean)?) {
|
||||
|
@ -3,18 +3,20 @@ package com.github.diegoberaldin.raccoonforlemmy.core.commonui.navigation
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
import cafe.adriel.voyager.navigator.tab.Tab
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
interface NavigationCoordinator {
|
||||
|
||||
val deeplinkUrl: StateFlow<String?>
|
||||
val onDoubleTabSelection: SharedFlow<Tab>
|
||||
val onDoubleTabSelection: Flow<Tab>
|
||||
val inboxUnread: StateFlow<Int>
|
||||
val deepLinkUrl: StateFlow<String?>
|
||||
|
||||
fun setCurrentSection(tab: Tab)
|
||||
|
||||
fun submitDeeplink(url: String?)
|
||||
fun consumeDeeplink(): String?
|
||||
|
||||
fun submitDeeplink(url: String)
|
||||
|
||||
fun setRootNavigator(value: Navigator?)
|
||||
|
||||
|
@ -127,7 +127,8 @@ class PostDetailScreen(
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val isOnOtherInstance = otherInstance.isNotEmpty()
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val navigator = remember { navigationCoordinator.getRootNavigator() }
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val topAppBarState = rememberTopAppBarState()
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
|
||||
@ -207,14 +208,16 @@ class PostDetailScreen(
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick {
|
||||
navigator?.pop()
|
||||
},
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
||||
)
|
||||
if (navigator?.canPop == true) {
|
||||
Image(
|
||||
modifier = Modifier.onClick {
|
||||
navigator.pop()
|
||||
},
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
|
@ -107,7 +107,6 @@ class PostDetailViewModel(
|
||||
}
|
||||
|
||||
if (highlightCommentId != null) {
|
||||
val auth = identityRepository.authToken.value
|
||||
val comment = commentRepository.getBy(
|
||||
id = highlightCommentId,
|
||||
auth = auth,
|
||||
|
@ -192,14 +192,16 @@ class UserDetailScreen(
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick {
|
||||
navigator?.pop()
|
||||
},
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
||||
)
|
||||
if (navigator?.canPop == true) {
|
||||
Image(
|
||||
modifier = Modifier.onClick {
|
||||
navigator.pop()
|
||||
},
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
|
@ -12,12 +12,13 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.identity.usecase.DefaultS
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.usecase.LoginUseCase
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.usecase.LogoutUseCase
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.usecase.SwitchAccountUseCase
|
||||
import org.koin.core.qualifier.named
|
||||
import org.koin.dsl.module
|
||||
|
||||
val coreIdentityModule = module {
|
||||
single<ApiConfigurationRepository> {
|
||||
DefaultApiConfigurationRepository(
|
||||
serviceProvider = get(),
|
||||
serviceProvider = get(named("default")),
|
||||
)
|
||||
}
|
||||
single<IdentityRepository> {
|
||||
@ -27,7 +28,7 @@ val coreIdentityModule = module {
|
||||
}
|
||||
single<AuthRepository> {
|
||||
DefaultAuthRepository(
|
||||
services = get(),
|
||||
services = get(named("default")),
|
||||
)
|
||||
}
|
||||
single<LoginUseCase> {
|
||||
@ -52,7 +53,7 @@ val coreIdentityModule = module {
|
||||
identityRepository = get(),
|
||||
accountRepository = get(),
|
||||
settingsRepository = get(),
|
||||
serviceProvider = get(),
|
||||
serviceProvider = get(named("default")),
|
||||
notificationCenter = get(),
|
||||
)
|
||||
}
|
||||
|
@ -1,12 +1,10 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
interface ApiConfigurationRepository {
|
||||
|
||||
val instance: Flow<String>
|
||||
|
||||
fun getInstance(): String
|
||||
val instance: StateFlow<String>
|
||||
|
||||
fun changeInstance(value: String)
|
||||
}
|
||||
|
@ -1,25 +1,32 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.provider.ServiceProvider
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.isActive
|
||||
|
||||
internal class DefaultApiConfigurationRepository(
|
||||
private val serviceProvider: ServiceProvider,
|
||||
) : ApiConfigurationRepository {
|
||||
|
||||
override val instance: Flow<String> = channelFlow {
|
||||
private val scope = CoroutineScope(SupervisorJob())
|
||||
|
||||
override val instance = channelFlow {
|
||||
while (isActive) {
|
||||
val value = getInstance()
|
||||
val value = serviceProvider.currentInstance
|
||||
trySend(value)
|
||||
delay(1000)
|
||||
}
|
||||
}.distinctUntilChanged()
|
||||
|
||||
override fun getInstance() = serviceProvider.currentInstance
|
||||
}.distinctUntilChanged().stateIn(
|
||||
scope = scope,
|
||||
started = SharingStarted.Lazily,
|
||||
initialValue = "",
|
||||
)
|
||||
|
||||
override fun changeInstance(value: String) {
|
||||
serviceProvider.changeInstance(value)
|
||||
|
@ -23,7 +23,7 @@ internal class DefaultLoginUseCase(
|
||||
password: String,
|
||||
totp2faToken: String?,
|
||||
): Result<Unit> {
|
||||
val oldInstance = apiConfigurationRepository.getInstance()
|
||||
val oldInstance = apiConfigurationRepository.instance.value
|
||||
apiConfigurationRepository.changeInstance(instance)
|
||||
|
||||
val response = authRepository.login(
|
||||
|
@ -8,7 +8,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.to
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toModel
|
||||
|
||||
class PrivateMessageRepository(
|
||||
private val serviceProvider: ServiceProvider,
|
||||
private val services: ServiceProvider,
|
||||
) {
|
||||
suspend fun getAll(
|
||||
auth: String? = null,
|
||||
@ -16,7 +16,7 @@ class PrivateMessageRepository(
|
||||
limit: Int = PostRepository.DEFAULT_PAGE_SIZE,
|
||||
unreadOnly: Boolean = true,
|
||||
): List<PrivateMessageModel>? = runCatching {
|
||||
val response = serviceProvider.privateMessages.getPrivateMessages(
|
||||
val response = services.privateMessages.getPrivateMessages(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
limit = limit,
|
||||
@ -37,7 +37,7 @@ class PrivateMessageRepository(
|
||||
auth = auth.orEmpty(),
|
||||
recipientId = recipiendId,
|
||||
)
|
||||
serviceProvider.privateMessages.createPrivateMessage(
|
||||
services.privateMessages.createPrivateMessage(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
@ -53,7 +53,7 @@ class PrivateMessageRepository(
|
||||
auth = auth.orEmpty(),
|
||||
read = read,
|
||||
)
|
||||
serviceProvider.privateMessages.markPrivateMessageAsRead(
|
||||
services.privateMessages.markPrivateMessageAsRead(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
|
@ -9,10 +9,10 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.to
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toModel
|
||||
|
||||
class SiteRepository(
|
||||
private val serviceProvider: ServiceProvider,
|
||||
private val services: ServiceProvider,
|
||||
) {
|
||||
suspend fun getCurrentUser(auth: String): UserModel? = runCatching {
|
||||
val response = serviceProvider.site.get(
|
||||
val response = services.site.get(
|
||||
auth = auth,
|
||||
authHeader = auth.toAuthHeader(),
|
||||
)
|
||||
@ -28,14 +28,14 @@ class SiteRepository(
|
||||
instanceId = id,
|
||||
block = blocked,
|
||||
)
|
||||
serviceProvider.site.block(
|
||||
services.site.block(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getMetadata(url: String): MetadataModel? = runCatching {
|
||||
val response = serviceProvider.site.getSiteMetadata(
|
||||
val response = services.site.getSiteMetadata(
|
||||
url = url,
|
||||
)
|
||||
response.body()?.metadata?.toModel()
|
||||
|
@ -16,8 +16,8 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.to
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.toModel
|
||||
|
||||
class UserRepository(
|
||||
private val serviceProvider: ServiceProvider,
|
||||
private val customServiceProvider: ServiceProvider,
|
||||
private val services: ServiceProvider,
|
||||
private val customServices: ServiceProvider,
|
||||
) {
|
||||
|
||||
suspend fun get(
|
||||
@ -25,7 +25,7 @@ class UserRepository(
|
||||
auth: String? = null,
|
||||
username: String? = null,
|
||||
): UserModel? = runCatching {
|
||||
val response = serviceProvider.user.getDetails(
|
||||
val response = services.user.getDetails(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
personId = id,
|
||||
@ -48,8 +48,8 @@ class UserRepository(
|
||||
username: String? = null,
|
||||
auth: String? = null,
|
||||
): UserModel? = runCatching {
|
||||
customServiceProvider.changeInstance(instance)
|
||||
val response = customServiceProvider.user.getDetails(
|
||||
customServices.changeInstance(instance)
|
||||
val response = customServices.user.getDetails(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
username = username,
|
||||
@ -73,7 +73,7 @@ class UserRepository(
|
||||
limit: Int = PostRepository.DEFAULT_PAGE_SIZE,
|
||||
sort: SortType = SortType.Active,
|
||||
): List<PostModel>? = runCatching {
|
||||
val response = serviceProvider.user.getDetails(
|
||||
val response = services.user.getDetails(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
personId = id,
|
||||
@ -92,7 +92,7 @@ class UserRepository(
|
||||
limit: Int = PostRepository.DEFAULT_PAGE_SIZE,
|
||||
sort: SortType = SortType.Active,
|
||||
): List<PostModel>? = runCatching {
|
||||
val response = serviceProvider.user.getDetails(
|
||||
val response = services.user.getDetails(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
personId = id,
|
||||
@ -112,7 +112,7 @@ class UserRepository(
|
||||
limit: Int = PostRepository.DEFAULT_PAGE_SIZE,
|
||||
sort: SortType = SortType.Active,
|
||||
): List<CommentModel>? = runCatching {
|
||||
val response = serviceProvider.user.getDetails(
|
||||
val response = services.user.getDetails(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
personId = id,
|
||||
@ -131,7 +131,7 @@ class UserRepository(
|
||||
limit: Int = PostRepository.DEFAULT_PAGE_SIZE,
|
||||
sort: SortType = SortType.Active,
|
||||
): List<CommentModel>? = runCatching {
|
||||
val response = serviceProvider.user.getDetails(
|
||||
val response = services.user.getDetails(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
personId = id,
|
||||
@ -151,7 +151,7 @@ class UserRepository(
|
||||
sort: SortType = SortType.New,
|
||||
unreadOnly: Boolean = true,
|
||||
): List<PersonMentionModel>? = runCatching {
|
||||
val response = serviceProvider.user.getMentions(
|
||||
val response = services.user.getMentions(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
limit = limit,
|
||||
@ -170,7 +170,7 @@ class UserRepository(
|
||||
sort: SortType = SortType.New,
|
||||
unreadOnly: Boolean = true,
|
||||
): List<PersonMentionModel>? = runCatching {
|
||||
val response = serviceProvider.user.getReplies(
|
||||
val response = services.user.getReplies(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
auth = auth,
|
||||
limit = limit,
|
||||
@ -186,7 +186,7 @@ class UserRepository(
|
||||
auth: String? = null,
|
||||
) {
|
||||
val data = MarkAllAsReadForm(auth.orEmpty())
|
||||
serviceProvider.user.markAllAsRead(
|
||||
services.user.markAllAsRead(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
@ -198,7 +198,7 @@ class UserRepository(
|
||||
read = read,
|
||||
auth = auth.orEmpty(),
|
||||
)
|
||||
serviceProvider.user.markPersonMentionAsRead(
|
||||
services.user.markPersonMentionAsRead(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
@ -210,7 +210,7 @@ class UserRepository(
|
||||
read = read,
|
||||
auth = auth.orEmpty(),
|
||||
)
|
||||
serviceProvider.user.markCommentReplyAsRead(
|
||||
services.user.markCommentReplyAsRead(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
@ -222,7 +222,7 @@ class UserRepository(
|
||||
block = blocked,
|
||||
auth = auth.orEmpty(),
|
||||
)
|
||||
serviceProvider.user.block(
|
||||
services.user.block(
|
||||
authHeader = auth.toAuthHeader(),
|
||||
form = data,
|
||||
)
|
||||
|
@ -6,25 +6,42 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepo
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PrivateMessageRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.UserRepository
|
||||
import org.koin.core.module.dsl.singleOf
|
||||
import org.koin.core.qualifier.named
|
||||
import org.koin.dsl.module
|
||||
|
||||
val repositoryModule = module {
|
||||
single {
|
||||
PostRepository(
|
||||
services = get(),
|
||||
services = get(named("default")),
|
||||
customServices = get(named("custom")),
|
||||
)
|
||||
}
|
||||
single {
|
||||
CommunityRepository(
|
||||
services = get(),
|
||||
services = get(named("default")),
|
||||
customServices = get(named("custom")),
|
||||
)
|
||||
}
|
||||
singleOf(::UserRepository)
|
||||
singleOf(::SiteRepository)
|
||||
singleOf(::CommentRepository)
|
||||
singleOf(::PrivateMessageRepository)
|
||||
single {
|
||||
UserRepository(
|
||||
services = get(named("default")),
|
||||
customServices = get(named("custom")),
|
||||
)
|
||||
}
|
||||
single {
|
||||
SiteRepository(
|
||||
services = get(named("default")),
|
||||
)
|
||||
}
|
||||
single {
|
||||
CommentRepository(
|
||||
services = get(named("default")),
|
||||
customServices = get(named("custom")),
|
||||
)
|
||||
}
|
||||
single {
|
||||
PrivateMessageRepository(
|
||||
services = get(named("default")),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ class ExploreViewModel(
|
||||
mvi.onStarted()
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
instance = apiConfigRepository.getInstance(),
|
||||
instance = apiConfigRepository.instance.value,
|
||||
)
|
||||
}
|
||||
mvi.scope?.launch(Dispatchers.Main) {
|
||||
|
@ -31,9 +31,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.CurrentScreen
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.BottomSheetNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.TabNavigator
|
||||
@ -47,7 +45,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.AppTheme
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.CornerSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.getCommmunityFromUrl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.getCommunityFromUrl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.getPostFromUrl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.getUserFromUrl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getDrawerCoordinator
|
||||
@ -77,12 +75,20 @@ fun App() {
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val settings by settingsRepository.currentSettings.collectAsState()
|
||||
var hasBeenInitialized by remember { mutableStateOf(false) }
|
||||
LaunchedEffect(settingsRepository) {
|
||||
val apiConfigurationRepository = remember { getApiConfigurationRepository() }
|
||||
|
||||
LaunchedEffect(accountRepository) {
|
||||
val accountId = accountRepository.getActive()?.id
|
||||
val currentSettings = settingsRepository.getSettings(accountId)
|
||||
settingsRepository.changeCurrentSettings(currentSettings)
|
||||
val lastActiveAccount = accountRepository.getActive()
|
||||
val lastInstance = lastActiveAccount?.instance
|
||||
if (lastInstance != null) {
|
||||
apiConfigurationRepository.changeInstance(lastInstance)
|
||||
}
|
||||
hasBeenInitialized = true
|
||||
}
|
||||
|
||||
val defaultTheme = if (isSystemInDarkTheme()) {
|
||||
UiTheme.Dark.toInt()
|
||||
} else {
|
||||
@ -100,15 +106,6 @@ fun App() {
|
||||
StringDesc.localeType = StringDesc.LocaleType.Custom(lang)
|
||||
}.launchIn(scope)
|
||||
|
||||
val apiConfigurationRepository = remember { getApiConfigurationRepository() }
|
||||
LaunchedEffect(Unit) {
|
||||
val lastActiveAccount = accountRepository.getActive()
|
||||
val lastInstance = lastActiveAccount?.instance
|
||||
if (lastInstance != null) {
|
||||
apiConfigurationRepository.changeInstance(lastInstance)
|
||||
}
|
||||
}
|
||||
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
LaunchedEffect(settings) {
|
||||
with(themeRepository) {
|
||||
@ -136,6 +133,73 @@ fun App() {
|
||||
val lang by languageRepository.currentLanguage.collectAsState()
|
||||
LaunchedEffect(lang) {}
|
||||
|
||||
val url = navigationCoordinator.consumeDeeplink()
|
||||
LaunchedEffect(navigationCoordinator, url) {
|
||||
val community = getCommunityFromUrl(url)
|
||||
val user = getUserFromUrl(url)
|
||||
val postAndInstance = getPostFromUrl(url)
|
||||
val newScreen = when {
|
||||
community != null -> {
|
||||
CommunityDetailScreen(
|
||||
community = community,
|
||||
otherInstance = community.host,
|
||||
)
|
||||
}
|
||||
|
||||
user != null -> {
|
||||
UserDetailScreen(
|
||||
user = user,
|
||||
otherInstance = user.host,
|
||||
)
|
||||
}
|
||||
|
||||
postAndInstance != null -> {
|
||||
val (post, otherInstance) = postAndInstance
|
||||
PostDetailScreen(
|
||||
post = post,
|
||||
otherInstance = otherInstance,
|
||||
)
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
if (newScreen != null) {
|
||||
navigationCoordinator.getRootNavigator()?.push(newScreen)
|
||||
}
|
||||
}
|
||||
|
||||
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
LaunchedEffect(drawerCoordinator) {
|
||||
drawerCoordinator.toggleEvents.onEach { evt ->
|
||||
val navigator = navigationCoordinator.getRootNavigator()
|
||||
when (evt) {
|
||||
DrawerEvent.Toggled -> {
|
||||
drawerState.apply {
|
||||
if (isClosed) open() else close()
|
||||
}
|
||||
}
|
||||
|
||||
is DrawerEvent.OpenCommunity -> {
|
||||
navigator?.push(CommunityDetailScreen(evt.community))
|
||||
}
|
||||
|
||||
is DrawerEvent.OpenMultiCommunity -> {
|
||||
navigator?.push(MultiCommunityScreen(evt.community))
|
||||
}
|
||||
|
||||
DrawerEvent.ManageSubscriptions -> {
|
||||
navigator?.push(ManageSubscriptionsScreen())
|
||||
}
|
||||
|
||||
DrawerEvent.OpenBookmarks -> {
|
||||
navigator?.push(SavedItemsScreen())
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
}
|
||||
val drawerGestureEnabled by drawerCoordinator.gesturesEnabled.collectAsState()
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalDensity provides Density(
|
||||
density = LocalDensity.current.density,
|
||||
@ -143,73 +207,12 @@ fun App() {
|
||||
),
|
||||
) {
|
||||
BottomSheetNavigator(
|
||||
sheetShape = RoundedCornerShape(topStart = CornerSize.xl, topEnd = CornerSize.xl),
|
||||
sheetShape = RoundedCornerShape(
|
||||
topStart = CornerSize.xl,
|
||||
topEnd = CornerSize.xl
|
||||
),
|
||||
sheetBackgroundColor = MaterialTheme.colorScheme.background,
|
||||
) {
|
||||
val screens: List<Screen> = remember(navigationCoordinator.deeplinkUrl) {
|
||||
val url = navigationCoordinator.deeplinkUrl.value.orEmpty()
|
||||
val community = getCommmunityFromUrl(url)
|
||||
val user = getUserFromUrl(url)
|
||||
val postAndInstance = getPostFromUrl(url)
|
||||
buildList {
|
||||
if (community != null) {
|
||||
add(
|
||||
CommunityDetailScreen(
|
||||
community = community,
|
||||
otherInstance = community.host,
|
||||
)
|
||||
)
|
||||
} else if (user != null) {
|
||||
add(
|
||||
UserDetailScreen(
|
||||
user = user,
|
||||
otherInstance = user.host,
|
||||
)
|
||||
)
|
||||
} else if (postAndInstance != null) {
|
||||
val (post, otherInstance) = postAndInstance
|
||||
add(
|
||||
PostDetailScreen(
|
||||
post = post,
|
||||
otherInstance = otherInstance,
|
||||
)
|
||||
)
|
||||
} else {
|
||||
add(MainScreen())
|
||||
}
|
||||
}
|
||||
}
|
||||
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
LaunchedEffect(drawerCoordinator) {
|
||||
drawerCoordinator.toggleEvents.onEach { evt ->
|
||||
val navigator = navigationCoordinator.getRootNavigator()
|
||||
when (evt) {
|
||||
DrawerEvent.Toggled -> {
|
||||
drawerState.apply {
|
||||
if (isClosed) open() else close()
|
||||
}
|
||||
}
|
||||
|
||||
is DrawerEvent.OpenCommunity -> {
|
||||
navigator?.push(CommunityDetailScreen(evt.community))
|
||||
}
|
||||
|
||||
is DrawerEvent.OpenMultiCommunity -> {
|
||||
navigator?.push(MultiCommunityScreen(evt.community))
|
||||
}
|
||||
|
||||
DrawerEvent.ManageSubscriptions -> {
|
||||
navigator?.push(ManageSubscriptionsScreen())
|
||||
}
|
||||
|
||||
DrawerEvent.OpenBookmarks -> {
|
||||
navigator?.push(SavedItemsScreen())
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
}
|
||||
val drawerGestureEnabled by drawerCoordinator.gesturesEnabled.collectAsState()
|
||||
ModalNavigationDrawer(
|
||||
drawerState = drawerState,
|
||||
gesturesEnabled = drawerGestureEnabled,
|
||||
@ -217,21 +220,19 @@ fun App() {
|
||||
ModalDrawerSheet {
|
||||
TabNavigator(ModalDrawerContent)
|
||||
}
|
||||
}
|
||||
},
|
||||
) {
|
||||
Navigator(
|
||||
screens = screens,
|
||||
screen = MainScreen,
|
||||
onBackPressed = {
|
||||
val callback = navigationCoordinator.getCanGoBackCallback()
|
||||
callback?.let { it() } ?: true
|
||||
}
|
||||
) {
|
||||
val navigator = LocalNavigator.current
|
||||
) { navigator ->
|
||||
navigationCoordinator.setRootNavigator(navigator)
|
||||
if (hasBeenInitialized) {
|
||||
CurrentScreen()
|
||||
} else {
|
||||
// loading screen
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center,
|
||||
|
@ -43,7 +43,7 @@ import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
internal class MainScreen : Screen {
|
||||
internal object MainScreen : Screen {
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user