This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| private val ddMMMMyyyyRegex = "([0-9]{1,2})\\s+([A-Za-z]{3,4})\\s+([0-9]{4})".toRegex() | |
| private val monthMapping = mapOf( | |
| "Jan" to Month.JANUARY, | |
| ... | |
| "Sep" to Month.SEPTEMBER, | |
| "Sept" to Month.SEPTEMBER, | |
| ... | |
| "Dec" to Month.DECEMBER | |
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class PostListViewModelStateObject : ObservableObject { | |
| @Published public private(set) var state: PostListState | |
| init(viewModel: PostListViewModel) { | |
| self.state = viewModel.container.stateFlow.value as! PostListState | |
| (viewModel.container.stateFlow.asPublisher() as AnyPublisher<PostListState, Never>) | |
| .receive(on: RunLoop.main) | |
| .assign(to: &$state) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Foundation | |
| import Combine | |
| import shared | |
| public extension Kotlinx_coroutines_coreFlow { | |
| func asPublisher<T: AnyObject>() -> AnyPublisher<T, Never> { | |
| (FlowPublisher(flow: self) as FlowPublisher<T>).eraseToAnyPublisher() | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| fun Flow<*>.subscribe(onEach: (item: Any) -> Unit, onComplete: () -> Unit, onThrow: (error: Throwable) -> Unit): Job = | |
| this.onEach { onEach(it as Any) } | |
| .catch { onThrow(it) } | |
| .onCompletion { onComplete() } | |
| .launchIn(CoroutineScope(Job() + Dispatchers.Main)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class PostListViewModel( | |
| private val postRepository: PostRepository, | |
| ) : ViewModel(), ContainerHost<PostListState, NavigationEvent> { | |
| override val container = viewModelScope.container<PostListState, NavigationEvent>( | |
| initialState = PostListState() | |
| ) { | |
| loadOverviews() | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @Composable | |
| fun Screen() { | |
| val lazyListState = rememberLazyListState() | |
| Column { | |
| AppBar(stringResource(id = R.string.app_name), elevation = lazyListState.elevation) | |
| LazyColumn(state = lazyListState) { | |
| ... | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| val lazyListState = rememberLazyListState() | |
| LazyColumn(state = lazyListState) { | |
| ... | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| val LazyListState.elevation: Dp | |
| get() = if (firstVisibleItemIndex == 0) { | |
| // For the first element, use the minimum of scroll offset and default elevation | |
| // i.e. a value between 0 and 4.dp | |
| minOf(firstVisibleItemScrollOffset.toFloat().dp, AppBarDefaults.TopAppBarElevation) | |
| } else { | |
| // If not the first element, always set elevation and show the shadow | |
| AppBarDefaults.TopAppBarElevation | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class ShadowScrollBehavior(context: Context, attrs: AttributeSet) : AppBarLayout.ScrollingViewBehavior(context, attrs) { | |
| @SuppressLint("PrivateResource") | |
| private val maxElevation = context.resources.getDimensionPixelSize(R.dimen.design_appbar_elevation).toFloat() | |
| override fun onDependentViewChanged(parent: CoordinatorLayout, child: View, dependency: View): | |
| Boolean { | |
| if (dependency is AppBarLayout) { | |
| when (child) { | |
| is NestedScrollView -> { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| lifecycleScope.launch { | |
| // See https://medium.com/androiddevelopers/a-safer-way-to-collect-flows-from-android-uis-23080b1f8bda | |
| lifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { | |
| launch { viewModel.container.stateFlow.collect(::reduce) | |
| launch { viewModel.container.sideEffectFlow.collect(::sideEffect) | |
| } | |
| } |
NewerOlder