ganfra
9 months ago
6 changed files with 213 additions and 0 deletions
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
/* |
||||
* Copyright (c) 2023 New Vector Ltd |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package io.element.android.libraries.architecture.overlay |
||||
|
||||
import com.bumble.appyx.core.navigation.backpresshandlerstrategies.BaseBackPressHandlerStrategy |
||||
import com.bumble.appyx.navmodel.backstack.BackStack |
||||
import com.bumble.appyx.navmodel.backstack.BackStackElements |
||||
import io.element.android.libraries.architecture.overlay.operation.Hide |
||||
import kotlinx.coroutines.flow.Flow |
||||
import kotlinx.coroutines.flow.map |
||||
|
||||
class HideOverlayBackPressHandler<NavTarget : Any> |
||||
: BaseBackPressHandlerStrategy<NavTarget, BackStack.State>() { |
||||
|
||||
override val canHandleBackPressFlow: Flow<Boolean> by lazy { |
||||
navModel.elements.map(::areThereElements) |
||||
} |
||||
|
||||
private fun areThereElements(elements: BackStackElements<NavTarget>) = |
||||
elements.isNotEmpty() |
||||
|
||||
override fun onBackPressed() { |
||||
navModel.accept(Hide()) |
||||
} |
||||
} |
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
/* |
||||
* Copyright (c) 2023 New Vector Ltd |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package io.element.android.libraries.architecture.overlay |
||||
|
||||
import com.bumble.appyx.core.navigation.BaseNavModel |
||||
import com.bumble.appyx.core.navigation.NavElements |
||||
import com.bumble.appyx.core.navigation.backpresshandlerstrategies.BackPressHandlerStrategy |
||||
import com.bumble.appyx.core.navigation.onscreen.OnScreenStateResolver |
||||
import com.bumble.appyx.core.navigation.operationstrategies.ExecuteImmediately |
||||
import com.bumble.appyx.core.navigation.operationstrategies.OperationStrategy |
||||
import com.bumble.appyx.core.state.SavedStateMap |
||||
import com.bumble.appyx.navmodel.backstack.BackStack |
||||
import com.bumble.appyx.navmodel.backstack.BackStackOnScreenResolver |
||||
import com.bumble.appyx.navmodel.backstack.backpresshandler.PopBackPressHandler |
||||
import com.bumble.appyx.navmodel.backstack.operation.NewRoot |
||||
import com.bumble.appyx.navmodel.backstack.operation.Push |
||||
|
||||
class Overlay<NavTarget : Any>( |
||||
savedStateMap: SavedStateMap?, |
||||
key: String = requireNotNull(Overlay::class.qualifiedName), |
||||
backPressHandler: BackPressHandlerStrategy<NavTarget, BackStack.State> = HideOverlayBackPressHandler(), |
||||
operationStrategy: OperationStrategy<NavTarget, BackStack.State> = ExecuteImmediately(), |
||||
screenResolver: OnScreenStateResolver<BackStack.State> = BackStackOnScreenResolver, |
||||
) : BaseNavModel<NavTarget, BackStack.State>( |
||||
backPressHandler = backPressHandler, |
||||
screenResolver = screenResolver, |
||||
operationStrategy = operationStrategy, |
||||
finalState = BackStack.State.DESTROYED, |
||||
savedStateMap = savedStateMap, |
||||
key = key, |
||||
) { |
||||
|
||||
override val initialElements: NavElements<NavTarget, BackStack.State> |
||||
get() = emptyList() |
||||
} |
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
/* |
||||
* Copyright (c) 2023 New Vector Ltd |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package io.element.android.libraries.architecture.overlay.operation |
||||
|
||||
import com.bumble.appyx.navmodel.backstack.BackStack |
||||
import com.bumble.appyx.navmodel.backstack.BackStackElements |
||||
import com.bumble.appyx.navmodel.backstack.activeIndex |
||||
import io.element.android.libraries.architecture.overlay.Overlay |
||||
import kotlinx.parcelize.Parcelize |
||||
|
||||
@Parcelize |
||||
class Hide<T : Any> : OverlayOperation<T> { |
||||
|
||||
override fun isApplicable(elements: BackStackElements<T>): Boolean = |
||||
elements.any { it.targetState == BackStack.State.ACTIVE } |
||||
|
||||
override fun invoke( |
||||
elements: BackStackElements<T> |
||||
): BackStackElements<T> { |
||||
val hideIndex = elements.activeIndex |
||||
require(hideIndex != -1) { "Nothing to hide, state=$elements" } |
||||
return elements.mapIndexed { index, element -> |
||||
when (index) { |
||||
hideIndex -> element.transitionTo( |
||||
newTargetState = BackStack.State.DESTROYED, |
||||
operation = this |
||||
) |
||||
else -> element |
||||
} |
||||
} |
||||
} |
||||
|
||||
override fun equals(other: Any?): Boolean = this.javaClass == other?.javaClass |
||||
|
||||
override fun hashCode(): Int = this.javaClass.hashCode() |
||||
} |
||||
|
||||
fun <T : Any> Overlay<T>.hide() { |
||||
accept(Hide()) |
||||
} |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
/* |
||||
* Copyright (c) 2023 New Vector Ltd |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package io.element.android.libraries.architecture.overlay.operation |
||||
|
||||
import com.bumble.appyx.core.navigation.Operation |
||||
import com.bumble.appyx.navmodel.backstack.BackStack |
||||
|
||||
interface OverlayOperation<T> : Operation<T, BackStack.State> |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
/* |
||||
* Copyright (c) 2023 New Vector Ltd |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package io.element.android.libraries.architecture.overlay.operation |
||||
|
||||
import com.bumble.appyx.core.navigation.NavKey |
||||
import com.bumble.appyx.navmodel.backstack.BackStack |
||||
import com.bumble.appyx.navmodel.backstack.BackStackElement |
||||
import com.bumble.appyx.navmodel.backstack.BackStackElements |
||||
import com.bumble.appyx.navmodel.backstack.activeElement |
||||
import io.element.android.libraries.architecture.overlay.Overlay |
||||
import kotlinx.parcelize.Parcelize |
||||
import kotlinx.parcelize.RawValue |
||||
|
||||
@Parcelize |
||||
data class Show<T : Any>( |
||||
private val element: @RawValue T |
||||
) : OverlayOperation<T> { |
||||
|
||||
override fun isApplicable(elements: BackStackElements<T>): Boolean = |
||||
element != elements.activeElement |
||||
|
||||
override fun invoke(elements: BackStackElements<T>): BackStackElements<T> = listOf( |
||||
BackStackElement( |
||||
key = NavKey(element), |
||||
fromState = BackStack.State.CREATED, |
||||
targetState = BackStack.State.ACTIVE, |
||||
operation = this |
||||
) |
||||
) |
||||
} |
||||
|
||||
fun <T : Any> Overlay<T>.show(element: T) { |
||||
accept(Show(element)) |
||||
} |
Loading…
Reference in new issue