Skip to content

Commit

Permalink
feat: ページネーションしながら取得できるようにした
Browse files Browse the repository at this point in the history
  • Loading branch information
pantasystem committed Jul 3, 2023
1 parent d794eec commit e73465d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
package net.pantasystem.milktea.auth

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.*
import androidx.compose.material.Button
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedButton
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Scaffold
import androidx.compose.material.Switch
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Clear
import androidx.compose.material.icons.filled.Search
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
Expand All @@ -22,10 +44,12 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.flow.distinctUntilChanged
import net.pantasystem.milktea.auth.viewmodel.app.AuthUiState
import net.pantasystem.milktea.auth.viewmodel.app.AuthUserInputState
import net.pantasystem.milktea.common.ResultState
import net.pantasystem.milktea.common.StateContent
import net.pantasystem.milktea.common.ui.isScrolledToTheEnd
import net.pantasystem.milktea.data.infrastructure.auth.Authorization

@Composable
Expand All @@ -43,6 +67,7 @@ fun AuthFormScreen(
onToggleTermsOfServiceAgreement: (Boolean) -> Unit,
onToggleAcceptMastodonAlphaTest: (Boolean) -> Unit,
onSignUpButtonClicked: () -> Unit,
onBottomReached: () -> Unit,
) {

Column(
Expand Down Expand Up @@ -112,6 +137,7 @@ fun AuthFormScreen(
uiState = uiState,
instanceDomain = instanceDomain,
onInputInstanceDomain = onInputInstanceDomain,
onBottomReached = onBottomReached
)

Column(
Expand Down Expand Up @@ -235,14 +261,26 @@ private fun FilteredInstances(
uiState: AuthUiState,
instanceDomain: String,
onInputInstanceDomain: (String) -> Unit,
onBottomReached: () -> Unit,
) {
val listState = rememberLazyListState()
LaunchedEffect(Unit) {
snapshotFlow {
listState.isScrolledToTheEnd()
}.distinctUntilChanged().collect {
if (it) {
onBottomReached()
}
}
}
val instances = remember(uiState.misskeyInstanceInfosResponse, uiState.formState) {
uiState.misskeyInstanceInfosResponse.filter {
it.meta.uri.contains(instanceDomain) || it.name.contains(instanceDomain)
} ?: emptyList()
}
}
LazyColumn(
modifier
modifier,
state = listState,
) {
items(instances) { instance ->
Box(
Expand Down Expand Up @@ -296,7 +334,8 @@ fun Preview_AuthFormScreen() {
onTogglePrivacyPolicyAgreement = {},
onToggleTermsOfServiceAgreement = {},
onToggleAcceptMastodonAlphaTest = {},
onSignUpButtonClicked = {}
onSignUpButtonClicked = {},
onBottomReached = {}
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ fun AuthScreen(
onShowTermsOfService = onShowTermsOfService,
onShowPrivacyPolicy = onShowPrivacyPolicy,
onToggleAcceptMastodonAlphaTest = authViewModel::onToggleAcceptMastodonAlphaTest,
onSignUpButtonClicked = onSignUpButtonClicked
onSignUpButtonClicked = onSignUpButtonClicked,
onBottomReached = authViewModel::onBottomReached
)
}
is Authorization.Waiting4UserAuthorization -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import net.pantasystem.milktea.api.misskey.InstanceInfoAPIBuilder
import net.pantasystem.milktea.api.misskey.infos.InstanceInfosResponse
import net.pantasystem.milktea.common.Logger
import net.pantasystem.milktea.common.PageableState
import net.pantasystem.milktea.common.paginator.EntityConverter
import net.pantasystem.milktea.common.paginator.PaginationState
Expand All @@ -21,11 +22,15 @@ import javax.inject.Inject

class InstanceSuggestionsPagingModel @Inject constructor(
private val instancesInfoAPIBuilder: InstanceInfoAPIBuilder,
private val loggerFactory: Logger.Factory,
) : StateLocker,
PaginationState<InstanceInfosResponse.InstanceInfo>,
PreviousLoader<InstanceInfosResponse.InstanceInfo>,
EntityConverter<InstanceInfosResponse.InstanceInfo, InstanceInfosResponse.InstanceInfo> {

private val logger by lazy {
loggerFactory.create("InstanceSuggestionsPagingModel")
}
private var _offset = 0
private var _name: String = ""
private val _state =
Expand Down Expand Up @@ -62,7 +67,7 @@ class InstanceSuggestionsPagingModel @Inject constructor(
_job?.cancel()
mutex.withLock {
_name = name

_offset = 0
}
setState(PageableState.Loading.Init())
}
Expand All @@ -79,7 +84,9 @@ class InstanceSuggestionsPagingModel @Inject constructor(
fun onLoadNext(scope: CoroutineScope) {
_job?.cancel()
_job = scope.launch {
previousPagingController.loadPrevious()
previousPagingController.loadPrevious().onFailure {
logger.error("Failed to load previous", it)
}
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,26 +88,7 @@ class AppAuthViewModel @Inject constructor(
StateContent.NotExist()
)
)
//
// private val instances = instanceInfoRepository.observeAll()
// .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), emptyList())

// @OptIn(FlowPreview::class, ExperimentalCoroutinesApi::class)
// private val misskeyInstances = instanceDomain.flatMapLatest { name ->
// suspend {
// requireNotNull(
// instancesInfoAPIBuilder.build().getInstances(
// name = name
// ).throwIfHasError()
// .body()
// ).distinctBy {
// it.url
// }
// }.asFlow()
// }.catch {
// logger.error("インスタンス情報の取得に失敗", it)
// }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), null)
//

private val misskeyInstances = instanceSuggestionsPagingModel.state.map {
(it.content as? StateContent.Exist)?.rawContent ?: emptyList()
}.stateIn(
Expand Down Expand Up @@ -346,11 +327,6 @@ class AppAuthViewModel @Inject constructor(
}
}.launchIn(viewModelScope)

// viewModelScope.launch {
// instanceInfoRepository.sync().onFailure {
// logger.error("sync instance info error", it)
// }
// }
}

fun auth() {
Expand Down Expand Up @@ -392,6 +368,9 @@ class AppAuthViewModel @Inject constructor(
isAcceptMastodonAlphaTest.value = value
}

fun onBottomReached() {
instanceSuggestionsPagingModel.onLoadNext(viewModelScope)
}

}

Expand Down

0 comments on commit e73465d

Please sign in to comment.