mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-3601 App | Tech | Release 10 stabilisation (#2354)
This commit is contained in:
parent
df87f33b9d
commit
d38ead4273
9 changed files with 191 additions and 76 deletions
|
@ -215,7 +215,13 @@ class MainActivity : AppCompatActivity(R.layout.activity_main), AppNavigation.Pr
|
|||
)
|
||||
)
|
||||
} else {
|
||||
controller.navigate(R.id.actionOpenSpaceFromVault)
|
||||
controller.navigate(
|
||||
R.id.actionOpenSpaceFromVault,
|
||||
HomeScreenFragment.args(
|
||||
space = command.space,
|
||||
deeplink = null
|
||||
)
|
||||
)
|
||||
}
|
||||
proceedWithOpenObjectNavigation(command.navigation)
|
||||
}.onFailure {
|
||||
|
|
|
@ -150,7 +150,13 @@ class VaultFragment : BaseComposeFragment() {
|
|||
private fun proceed(destination: Navigation) {
|
||||
when (destination) {
|
||||
is Navigation.OpenObject -> runCatching {
|
||||
findNavController().navigate(R.id.actionOpenSpaceFromVault)
|
||||
findNavController().navigate(
|
||||
R.id.actionOpenSpaceFromVault,
|
||||
HomeScreenFragment.args(
|
||||
space = destination.space,
|
||||
deeplink = null
|
||||
)
|
||||
)
|
||||
navigation().openDocument(
|
||||
target = destination.ctx,
|
||||
space = destination.space
|
||||
|
@ -159,7 +165,13 @@ class VaultFragment : BaseComposeFragment() {
|
|||
Timber.e(it, "Error while opening object from vault")
|
||||
}
|
||||
is Navigation.OpenSet -> runCatching {
|
||||
findNavController().navigate(R.id.actionOpenSpaceFromVault)
|
||||
findNavController().navigate(
|
||||
R.id.actionOpenSpaceFromVault,
|
||||
HomeScreenFragment.args(
|
||||
space = destination.space,
|
||||
deeplink = null
|
||||
)
|
||||
)
|
||||
navigation().openObjectSet(
|
||||
target = destination.ctx,
|
||||
space = destination.space,
|
||||
|
@ -169,7 +181,13 @@ class VaultFragment : BaseComposeFragment() {
|
|||
Timber.e(it, "Error while opening set or collection from vault")
|
||||
}
|
||||
is Navigation.OpenChat -> {
|
||||
findNavController().navigate(R.id.actionOpenSpaceFromVault)
|
||||
findNavController().navigate(
|
||||
R.id.actionOpenSpaceFromVault,
|
||||
HomeScreenFragment.args(
|
||||
space = destination.space,
|
||||
deeplink = null
|
||||
)
|
||||
)
|
||||
navigation().openChat(
|
||||
target = destination.ctx,
|
||||
space = destination.space
|
||||
|
@ -177,7 +195,13 @@ class VaultFragment : BaseComposeFragment() {
|
|||
}
|
||||
is Navigation.OpenDateObject -> {
|
||||
runCatching {
|
||||
findNavController().navigate(R.id.actionOpenSpaceFromVault)
|
||||
findNavController().navigate(
|
||||
R.id.actionOpenSpaceFromVault,
|
||||
HomeScreenFragment.args(
|
||||
space = destination.space,
|
||||
deeplink = null
|
||||
)
|
||||
)
|
||||
navigation().openDateObject(
|
||||
objectId = destination.ctx,
|
||||
space = destination.space
|
||||
|
@ -189,7 +213,13 @@ class VaultFragment : BaseComposeFragment() {
|
|||
|
||||
is Navigation.OpenParticipant -> {
|
||||
runCatching {
|
||||
findNavController().navigate(R.id.actionOpenSpaceFromVault)
|
||||
findNavController().navigate(
|
||||
R.id.actionOpenSpaceFromVault,
|
||||
HomeScreenFragment.args(
|
||||
space = destination.space,
|
||||
deeplink = null
|
||||
)
|
||||
)
|
||||
navigation().openParticipantObject(
|
||||
objectId = destination.ctx,
|
||||
space = destination.space
|
||||
|
@ -205,7 +235,7 @@ class VaultFragment : BaseComposeFragment() {
|
|||
}
|
||||
|
||||
override fun onApplyWindowRootInsets(view: View) {
|
||||
if (USE_EDGE_TO_EDGE && SDK_INT >= EDGE_TO_EDGE_MIN_SDK) {
|
||||
if (SDK_INT >= EDGE_TO_EDGE_MIN_SDK) {
|
||||
// Do nothing.
|
||||
} else {
|
||||
super.onApplyWindowRootInsets(view)
|
||||
|
|
|
@ -401,15 +401,6 @@
|
|||
android:name="com.anytypeio.anytype.ui.splash.SplashFragment"
|
||||
android:label="SplashFragment"
|
||||
tools:layout="@layout/fragment_splash">
|
||||
<action
|
||||
android:id="@+id/action_splashScreen_to_homeScreen"
|
||||
app:destination="@id/homeScreen"
|
||||
app:enterAnim="@anim/nav_default_enter_anim"
|
||||
app:exitAnim="@anim/nav_default_exit_anim"
|
||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||
app:popExitAnim="@anim/nav_default_pop_exit_anim"
|
||||
app:popUpTo="@+id/splashScreen"
|
||||
app:popUpToInclusive="true" />
|
||||
<action
|
||||
android:id="@+id/actionOpenVaultFromSplash"
|
||||
app:destination="@id/vaultScreen"
|
||||
|
|
|
@ -36,14 +36,18 @@ abstract class BaseBottomSheetComposeFragment : BottomSheetDialogFragment() {
|
|||
args: Bundle? = null
|
||||
) {
|
||||
jobs += this.lifecycleScope.launch {
|
||||
throttleFlow.emit {
|
||||
if (currentNavigationId == getNavigationId()) {
|
||||
try {
|
||||
findNavController().navigate(id, args)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "safeNavigateMethod is not safe!")
|
||||
try {
|
||||
throttleFlow.emit {
|
||||
if (currentNavigationId == getNavigationId()) {
|
||||
try {
|
||||
findNavController().navigate(id, args)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "safeNavigateMethod is not safe!")
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Error during emit in safeNavigate")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,11 +74,16 @@ abstract class BaseBottomSheetComposeFragment : BottomSheetDialogFragment() {
|
|||
|
||||
protected fun DialogFragment.showChildFragment(tag: String? = null) {
|
||||
jobs += this@BaseBottomSheetComposeFragment.lifecycleScope.launch {
|
||||
throttleFlow.emit {
|
||||
show(
|
||||
this@BaseBottomSheetComposeFragment.childFragmentManager,
|
||||
tag
|
||||
)
|
||||
try {
|
||||
throttleFlow.emit {
|
||||
try {
|
||||
show(this@BaseBottomSheetComposeFragment.childFragmentManager, tag)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Error while showing child dialog")
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Error during emit in showChildFragment")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,5 +127,14 @@ abstract class BaseBottomSheetComposeFragment : BottomSheetDialogFragment() {
|
|||
fun Fragment.getNavigationId() = findNavController().currentDestination?.id
|
||||
|
||||
fun <T> BaseBottomSheetComposeFragment.proceed(flow: Flow<T>, body: suspend (T) -> Unit) {
|
||||
jobs += flow.cancellable().onEach { body(it) }.launchIn(lifecycleScope)
|
||||
jobs += flow
|
||||
.cancellable()
|
||||
.onEach {
|
||||
try {
|
||||
body(it)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Unhandled exception in proceed flow")
|
||||
}
|
||||
}
|
||||
.launchIn(lifecycleScope)
|
||||
}
|
|
@ -21,6 +21,7 @@ import kotlinx.coroutines.flow.cancellable
|
|||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import com.google.android.material.R.id.design_bottom_sheet as BOTTOM_SHEET_ID
|
||||
|
||||
abstract class BaseBottomSheetFragment<T : ViewBinding>(
|
||||
|
@ -33,13 +34,18 @@ abstract class BaseBottomSheetFragment<T : ViewBinding>(
|
|||
val sheet: FrameLayout? get() = dialog?.findViewById(BOTTOM_SHEET_ID)
|
||||
|
||||
private val throttleFlow = MutableSharedFlow<() -> Unit>(0)
|
||||
val jobs = mutableListOf<Job>()
|
||||
|
||||
protected fun throttle(task: () -> Unit) {
|
||||
jobs += this.lifecycleScope.launch { throttleFlow.emit { task() } }
|
||||
jobs += this.lifecycleScope.launch {
|
||||
try {
|
||||
throttleFlow.emit { task() }
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Error during emit in throttle()")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val jobs = mutableListOf<Job>()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
|
@ -64,7 +70,13 @@ abstract class BaseBottomSheetFragment<T : ViewBinding>(
|
|||
if (resources.configuration.orientation == ORIENTATION_LANDSCAPE) {
|
||||
expand()
|
||||
}
|
||||
proceed(throttleFlow.throttleFirst(LONG_THROTTLE_DURATION)) { it() }
|
||||
proceed(throttleFlow.throttleFirst(LONG_THROTTLE_DURATION)) {
|
||||
try {
|
||||
it()
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Unhandled exception in throttled flow execution")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
|
@ -77,7 +89,17 @@ abstract class BaseBottomSheetFragment<T : ViewBinding>(
|
|||
|
||||
protected fun DialogFragment.showChildFragment(tag: String? = null) {
|
||||
jobs += this@BaseBottomSheetFragment.lifecycleScope.launch {
|
||||
throttleFlow.emit { show(this@BaseBottomSheetFragment.childFragmentManager, tag) }
|
||||
try {
|
||||
throttleFlow.emit {
|
||||
try {
|
||||
show(this@BaseBottomSheetFragment.childFragmentManager, tag)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Error while showing child dialog")
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Error during emit in showChildFragment")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,18 +109,14 @@ abstract class BaseBottomSheetFragment<T : ViewBinding>(
|
|||
}
|
||||
|
||||
fun skipCollapsed() {
|
||||
sheet?.let { sheet ->
|
||||
BottomSheetBehavior.from(sheet).apply {
|
||||
skipCollapsed = true
|
||||
}
|
||||
sheet?.let {
|
||||
BottomSheetBehavior.from(it).skipCollapsed = true
|
||||
}
|
||||
}
|
||||
|
||||
fun expand() {
|
||||
sheet?.let { sheet ->
|
||||
BottomSheetBehavior.from(sheet).apply {
|
||||
state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
sheet?.let {
|
||||
BottomSheetBehavior.from(it).state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,17 +124,25 @@ abstract class BaseBottomSheetFragment<T : ViewBinding>(
|
|||
sheet?.layoutParams?.height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
}
|
||||
|
||||
abstract fun injectDependencies()
|
||||
abstract fun releaseDependencies()
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
abstract fun injectDependencies()
|
||||
abstract fun releaseDependencies()
|
||||
protected abstract fun inflateBinding(inflater: LayoutInflater, container: ViewGroup?): T
|
||||
}
|
||||
|
||||
fun <T> BaseBottomSheetFragment<*>.proceed(flow: Flow<T>, body: suspend (T) -> Unit) {
|
||||
jobs += flow.cancellable().onEach { body(it) }.launchIn(lifecycleScope)
|
||||
jobs += flow
|
||||
.cancellable()
|
||||
.onEach {
|
||||
try {
|
||||
body(it)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Unhandled exception in proceed flow")
|
||||
}
|
||||
}
|
||||
.launchIn(lifecycleScope)
|
||||
}
|
|
@ -22,7 +22,7 @@ abstract class BaseBottomSheetTextInputFragment<T : ViewBinding>(
|
|||
}
|
||||
|
||||
private fun setupWindowInsetAnimation() {
|
||||
if (BuildConfig.USE_NEW_WINDOW_INSET_API && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
textInput.syncFocusWithImeVisibility()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import kotlinx.coroutines.flow.Flow
|
|||
import kotlinx.coroutines.flow.cancellable
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
|
||||
abstract class BaseComposeFragment : Fragment() {
|
||||
|
||||
|
@ -42,26 +43,37 @@ abstract class BaseComposeFragment : Fragment() {
|
|||
}
|
||||
|
||||
open fun onApplyWindowRootInsets(view: View) {
|
||||
if (BuildConfig.USE_NEW_WINDOW_INSET_API && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val deferringInsetsListener = RootViewDeferringInsetsCallback(
|
||||
persistentInsetTypes = WindowInsetsCompat.Type.systemBars(),
|
||||
deferredInsetTypes = WindowInsetsCompat.Type.ime()
|
||||
)
|
||||
|
||||
ViewCompat.setWindowInsetsAnimationCallback(view, deferringInsetsListener)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(view, deferringInsetsListener)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun DialogFragment.showChildFragment(tag: String? = null) {
|
||||
show(this@BaseComposeFragment.childFragmentManager, tag)
|
||||
try {
|
||||
show(this@BaseComposeFragment.childFragmentManager, tag)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Error while showing child fragment")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract fun injectDependencies()
|
||||
abstract fun releaseDependencies()
|
||||
}
|
||||
|
||||
fun <T> BaseComposeFragment.proceed(flow: Flow<T>, body: suspend (T) -> Unit) {
|
||||
jobs += flow.cancellable().onEach { body(it) }.launchIn(lifecycleScope)
|
||||
jobs += flow
|
||||
.cancellable()
|
||||
.onEach {
|
||||
try {
|
||||
body(it)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Unhandled exception in proceed flow")
|
||||
}
|
||||
}
|
||||
.launchIn(lifecycleScope)
|
||||
}
|
|
@ -90,7 +90,7 @@ abstract class BaseFragment<T : ViewBinding>(
|
|||
}
|
||||
|
||||
open fun onApplyWindowRootInsets() {
|
||||
if (BuildConfig.USE_NEW_WINDOW_INSET_API && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val deferringInsetsListener = RootViewDeferringInsetsCallback(
|
||||
persistentInsetTypes = WindowInsetsCompat.Type.systemBars(),
|
||||
deferredInsetTypes = WindowInsetsCompat.Type.ime()
|
||||
|
@ -102,17 +102,21 @@ abstract class BaseFragment<T : ViewBinding>(
|
|||
|
||||
protected fun DialogFragment.showChildFragment(tag: String? = null) {
|
||||
jobs += this@BaseFragment.lifecycleScope.launch {
|
||||
throttleFlow.emit {
|
||||
runCatching {
|
||||
show(this@BaseFragment.childFragmentManager, tag)
|
||||
}.fold(
|
||||
onSuccess = {
|
||||
// Do nothing.
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "Error while navigation")
|
||||
}
|
||||
)
|
||||
try {
|
||||
throttleFlow.emit {
|
||||
runCatching {
|
||||
show(this@BaseFragment.childFragmentManager, tag)
|
||||
}.fold(
|
||||
onSuccess = {
|
||||
// Do nothing.
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "Error while navigation")
|
||||
}
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Error while navigation")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +130,16 @@ abstract class BaseFragment<T : ViewBinding>(
|
|||
}
|
||||
|
||||
fun <T> BaseFragment<*>.proceed(flow: Flow<T>, body: suspend (T) -> Unit) {
|
||||
jobs += flow.cancellable().onEach { body(it) }.launchIn(lifecycleScope)
|
||||
jobs += flow
|
||||
.cancellable()
|
||||
.onEach {
|
||||
try {
|
||||
body(it)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Unhandled exception in proceed flow")
|
||||
}
|
||||
}
|
||||
.launchIn(lifecycleScope)
|
||||
}
|
||||
|
||||
const val THROTTLE_DURATION = 300L
|
|
@ -3334,11 +3334,16 @@ class EditorViewModel(
|
|||
private fun onAddNewObjectClicked(
|
||||
objectTypeView: ObjectTypeView
|
||||
) {
|
||||
controlPanelInteractor.onEvent(ControlPanelMachine.Event.OnAddBlockToolbarOptionSelected)
|
||||
|
||||
val position: Position
|
||||
|
||||
val focused = blocks.first { it.id == orchestrator.stores.focus.current().targetOrNull() }
|
||||
val focused = blocks.find { it.id == orchestrator.stores.focus.current().targetOrNull() }
|
||||
|
||||
if (focused == null) {
|
||||
Timber.e("Error while trying to add new object: focused block is null, target is unknown.")
|
||||
return
|
||||
}
|
||||
|
||||
controlPanelInteractor.onEvent(ControlPanelMachine.Event.OnAddBlockToolbarOptionSelected)
|
||||
|
||||
var target = focused.id
|
||||
|
||||
|
@ -3741,7 +3746,9 @@ class EditorViewModel(
|
|||
|
||||
if (target == context) {
|
||||
position = Position.TOP
|
||||
moveTarget = targetBlock.children.first()
|
||||
moveTarget = targetBlock.children.firstOrNull().orEmpty().also {
|
||||
Timber.e("Could not find move target in target block's children")
|
||||
}
|
||||
}
|
||||
|
||||
blocks.filter { selected.contains(it.id) }.forEach { block ->
|
||||
|
@ -5076,7 +5083,11 @@ class EditorViewModel(
|
|||
)
|
||||
}
|
||||
is SlashItem.Main.Color -> {
|
||||
val block = blocks.first { it.id == targetId }
|
||||
val block = blocks.find { it.id == targetId }
|
||||
if (block == null) {
|
||||
Timber.d("Could not find target block for slash item action: color")
|
||||
return
|
||||
}
|
||||
val blockColor = block.content.asText().color
|
||||
val color = if (blockColor != null) {
|
||||
ThemeColor.valueOf(blockColor.toUpperCase())
|
||||
|
@ -5092,7 +5103,11 @@ class EditorViewModel(
|
|||
)
|
||||
}
|
||||
is SlashItem.Main.Background -> {
|
||||
val block = blocks.first { it.id == targetId }
|
||||
val block = blocks.find { it.id == targetId }
|
||||
if (block == null) {
|
||||
Timber.d("Could not find target block for slash item action: background")
|
||||
return
|
||||
}
|
||||
val blockBackground = block.backgroundColor
|
||||
val background = if (blockBackground == null) {
|
||||
ThemeColor.DEFAULT
|
||||
|
@ -5977,12 +5992,16 @@ class EditorViewModel(
|
|||
private fun onMultiSelectAddBelow() {
|
||||
mode = EditorMode.Edit
|
||||
controlPanelInteractor.onEvent(ControlPanelMachine.Event.MultiSelect.OnExit)
|
||||
val target = currentSelection().first()
|
||||
clearSelections()
|
||||
proceedWithCreatingNewTextBlock(
|
||||
target = target,
|
||||
style = Content.Text.Style.P
|
||||
)
|
||||
val target = currentSelection().firstOrNull()
|
||||
if (target != null) {
|
||||
clearSelections()
|
||||
proceedWithCreatingNewTextBlock(
|
||||
target = target,
|
||||
style = Content.Text.Style.P
|
||||
)
|
||||
} else {
|
||||
Timber.e("Could not define target in onMultiSelectAddBelow()")
|
||||
}
|
||||
}
|
||||
|
||||
fun onMultiSelectModeDeleteClicked() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue