diff --git a/app/src/main/java/com/anytypeio/anytype/ui/main/MainActivity.kt b/app/src/main/java/com/anytypeio/anytype/ui/main/MainActivity.kt
index 20367e3cfe..7d0640dda5 100644
--- a/app/src/main/java/com/anytypeio/anytype/ui/main/MainActivity.kt
+++ b/app/src/main/java/com/anytypeio/anytype/ui/main/MainActivity.kt
@@ -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 {
diff --git a/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultFragment.kt
index ae69abbdd0..4c8d246127 100644
--- a/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultFragment.kt
+++ b/app/src/main/java/com/anytypeio/anytype/ui/vault/VaultFragment.kt
@@ -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)
diff --git a/app/src/main/res/navigation/graph.xml b/app/src/main/res/navigation/graph.xml
index 9c298a509f..c5b4ef95a4 100644
--- a/app/src/main/res/navigation/graph.xml
+++ b/app/src/main/res/navigation/graph.xml
@@ -401,15 +401,6 @@
android:name="com.anytypeio.anytype.ui.splash.SplashFragment"
android:label="SplashFragment"
tools:layout="@layout/fragment_splash">
-
BaseBottomSheetComposeFragment.proceed(flow: Flow, 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)
}
\ No newline at end of file
diff --git a/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseBottomSheetFragment.kt b/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseBottomSheetFragment.kt
index c78bcbdc3b..c957e11332 100644
--- a/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseBottomSheetFragment.kt
+++ b/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseBottomSheetFragment.kt
@@ -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(
@@ -33,13 +34,18 @@ abstract class BaseBottomSheetFragment(
val sheet: FrameLayout? get() = dialog?.findViewById(BOTTOM_SHEET_ID)
private val throttleFlow = MutableSharedFlow<() -> Unit>(0)
+ val jobs = mutableListOf()
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()
-
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@@ -64,7 +70,13 @@ abstract class BaseBottomSheetFragment(
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(
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(
}
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(
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 BaseBottomSheetFragment<*>.proceed(flow: Flow, 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)
}
\ No newline at end of file
diff --git a/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseBottomSheetTextInputFragment.kt b/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseBottomSheetTextInputFragment.kt
index a77a80bfa1..ada3ff9411 100644
--- a/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseBottomSheetTextInputFragment.kt
+++ b/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseBottomSheetTextInputFragment.kt
@@ -22,7 +22,7 @@ abstract class BaseBottomSheetTextInputFragment(
}
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()
}
}
diff --git a/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseComposeFragment.kt b/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseComposeFragment.kt
index 0751047af0..c205f87e85 100644
--- a/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseComposeFragment.kt
+++ b/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseComposeFragment.kt
@@ -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 BaseComposeFragment.proceed(flow: Flow, 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)
}
\ No newline at end of file
diff --git a/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseFragment.kt b/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseFragment.kt
index b42227e85b..784ecefca1 100644
--- a/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseFragment.kt
+++ b/core-utils/src/main/java/com/anytypeio/anytype/core_utils/ui/BaseFragment.kt
@@ -90,7 +90,7 @@ abstract class BaseFragment(
}
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(
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(
}
fun BaseFragment<*>.proceed(flow: Flow, 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
\ No newline at end of file
diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt
index 9b2a1c5525..cf025667f8 100644
--- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt
+++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt
@@ -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() {