1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

App | Feature | Other settings screen + default type (#1873)

* rename

* rename

* rename legacy icon

* update object type choose screen di

* update object change type screen + editor

* update prefs for object types

* fixes

* other settings screen update

* design fix

* update icon

* fix tests

* fix di

* pr fix

* pr fix

* pr fix

* pr fix

* ci off
This commit is contained in:
Konstantin Ivanov 2021-10-27 14:16:27 +03:00 committed by GitHub
parent a2dd817782
commit 66d4cbdd97
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
58 changed files with 407 additions and 462 deletions

View file

@ -75,6 +75,7 @@ object EventsDictionary {
const val ACCOUNT_STOP = "AccountStop"
const val PAGE_CREATE = "BlockCreatePage"
const val DEFAULT_TYPE_CHANGED = "DefaultTypeChanged"
const val OBJECT_CREATE = "BlockCreateObject"
const val PAGE_MENTION_CREATE = "PageCreate"

View file

@ -172,9 +172,9 @@ class ComponentManager(private val main: MainComponent) {
.build()
}
val userSettingsComponent = Component {
main.userSettingsComponentBuilder()
.module(UserSettingsModule)
val otherSettingsComponent = Component {
main.otherSettingsComponentBuilder()
.module(OtherSettingsModule)
.build()
}
@ -546,9 +546,8 @@ class ComponentManager(private val main: MainComponent) {
.build()
}
val objectTypeChangeComponent = DependentComponentMap { ctx ->
editorComponent
.get(ctx)
val objectTypeChangeComponent = Component {
main
.objectTypeChangeComponent()
.module(ObjectTypeChangeModule)
.build()

View file

@ -91,8 +91,6 @@ interface EditorSubComponent {
fun documentAddNewBlockComponentBuilder(): DocumentAddNewBlockSubComponent.Builder
fun objectLayoutComponent() : ObjectLayoutSubComponent.Builder
fun objectTypeChangeComponent(): ObjectTypeChangeSubComponent.Builder
}
@ -717,13 +715,6 @@ object EditorUseCaseModule {
repo: BlockRepository
): SetObjectType = SetObjectType(repo)
@JvmStatic
@Provides
@PerScreen
fun provideGetCompatibleObjectTypesUseCase(
repository: BlockRepository
): GetCompatibleObjectTypes = GetCompatibleObjectTypes(repository)
@JvmStatic
@Provides
@PerScreen
@ -736,4 +727,11 @@ object EditorUseCaseModule {
@PerScreen
fun provideGetDefaultPageType(repo: UserSettingsRepository): GetDefaultEditorType =
GetDefaultEditorType(repo)
@JvmStatic
@Provides
@PerScreen
fun provideGetCompatibleObjectTypesUseCase(
repository: BlockRepository
): GetCompatibleObjectTypes = GetCompatibleObjectTypes(repository)
}

View file

@ -1,6 +1,7 @@
package com.anytypeio.anytype.di.feature
import com.anytypeio.anytype.core_utils.di.scope.PerModal
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.dataview.interactor.GetCompatibleObjectTypes
import com.anytypeio.anytype.presentation.objects.ObjectTypeChangeViewModelFactory
import com.anytypeio.anytype.ui.objects.ObjectTypeChangeFragment
@ -9,7 +10,7 @@ import dagger.Provides
import dagger.Subcomponent
@Subcomponent(modules = [ObjectTypeChangeModule::class])
@PerModal
@PerScreen
interface ObjectTypeChangeSubComponent {
@Subcomponent.Builder
@ -26,7 +27,7 @@ object ObjectTypeChangeModule {
@JvmStatic
@Provides
@PerModal
@PerScreen
fun provideObjectTypeViewModelFactory(
getCompatibleObjectTypes: GetCompatibleObjectTypes
): ObjectTypeChangeViewModelFactory {
@ -34,4 +35,11 @@ object ObjectTypeChangeModule {
getCompatibleObjectTypes = getCompatibleObjectTypes
)
}
@JvmStatic
@Provides
@PerScreen
fun provideGetCompatibleObjectTypesUseCase(
repository: BlockRepository
): GetCompatibleObjectTypes = GetCompatibleObjectTypes(repository)
}

View file

@ -5,27 +5,27 @@ import com.anytypeio.anytype.core_utils.di.scope.PerScreen
import com.anytypeio.anytype.domain.config.UserSettingsRepository
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.launch.SetDefaultEditorType
import com.anytypeio.anytype.presentation.settings.UserSettingsViewModel
import com.anytypeio.anytype.ui.settings.UserSettingsFragment
import com.anytypeio.anytype.presentation.settings.OtherSettingsViewModel
import com.anytypeio.anytype.ui.settings.OtherSettingsFragment
import dagger.Module
import dagger.Provides
import dagger.Subcomponent
@PerScreen
@Subcomponent(modules = [UserSettingsModule::class])
interface UserSettingsSubComponent {
@Subcomponent(modules = [OtherSettingsModule::class])
interface OtherSettingsSubComponent {
@Subcomponent.Builder
interface Builder {
fun module(module: UserSettingsModule): Builder
fun build(): UserSettingsSubComponent
fun module(module: OtherSettingsModule): Builder
fun build(): OtherSettingsSubComponent
}
fun inject(fragment: UserSettingsFragment)
fun inject(fragment: OtherSettingsFragment)
}
@Module
object UserSettingsModule {
object OtherSettingsModule {
@JvmStatic
@PerScreen
@ -42,10 +42,10 @@ object UserSettingsModule {
@JvmStatic
@Provides
@PerScreen
fun provideUserSettingsFabric(
fun provideOtherSettingsFactory(
getDefaultEditorType: GetDefaultEditorType,
setDefaultEditorType: SetDefaultEditorType,
analytics: Analytics
): UserSettingsViewModel.Factory =
UserSettingsViewModel.Factory(getDefaultEditorType, setDefaultEditorType, analytics)
): OtherSettingsViewModel.Factory =
OtherSettingsViewModel.Factory(getDefaultEditorType, setDefaultEditorType, analytics)
}

View file

@ -40,5 +40,6 @@ interface MainComponent {
fun createSetComponentBuilder(): CreateSetSubComponent.Builder
fun createObjectTypeComponentBuilder(): CreateObjectTypeSubComponent.Builder
fun objectSetComponentBuilder(): ObjectSetSubComponent.Builder
fun userSettingsComponentBuilder(): UserSettingsSubComponent.Builder
fun otherSettingsComponentBuilder(): OtherSettingsSubComponent.Builder
fun objectTypeChangeComponent(): ObjectTypeChangeSubComponent.Builder
}

View file

@ -33,6 +33,7 @@ import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.lifecycle.*
import androidx.navigation.fragment.findNavController
@ -409,6 +410,10 @@ open class EditorFragment : NavigationFragment(R.layout.fragment_editor),
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setFragmentResultListener(ObjectTypeChangeFragment.OBJECT_TYPE_REQUEST_KEY) { _, bundle ->
val id = bundle.getString(ObjectTypeChangeFragment.OBJECT_TYPE_URL_KEY)
onObjectTypePicked(id = id)
}
pickiT = PickiT(requireContext(), this, requireActivity())
setupOnBackPressedDispatcher()
getEditorSettings()
@ -738,7 +743,7 @@ open class EditorFragment : NavigationFragment(R.layout.fragment_editor),
vm.onSetRelationKeyClicked(blockId = blockId, key = key)
}
override fun onObjectTypePicked(id: Id) {
private fun onObjectTypePicked(id: Id?) {
vm.onObjectTypeChanged(id)
}
@ -966,11 +971,13 @@ open class EditorFragment : NavigationFragment(R.layout.fragment_editor),
}
is Command.OpenChangeObjectTypeScreen -> {
hideKeyboard()
val fr = ObjectTypeChangeFragment.new(
ctx = command.ctx,
smartBlockType = command.smartBlockType
)
fr.show(childFragmentManager, null)
findNavController()
.navigate(
R.id.objectTypeChangeFragment,
bundleOf(
ObjectTypeChangeFragment.ARG_SMART_BLOCK_TYPE to command.smartBlockType
)
)
}
is Command.OpenMoveToScreen -> {
lifecycleScope.launch {
@ -2312,5 +2319,4 @@ interface OnFragmentInteractionListener {
fun onAddBookmarkUrlClicked(target: String, url: String)
fun onExitToDesktopClicked()
fun onSetRelationKeyClicked(blockId: Id, key: Id)
fun onObjectTypePicked(id: Id)
}

View file

@ -5,26 +5,28 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.setFragmentResult
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.SmartBlockType
import com.anytypeio.anytype.core_ui.features.objects.ObjectTypeVerticalAdapter
import com.anytypeio.anytype.core_ui.reactive.textChanges
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ext.arg
import com.anytypeio.anytype.core_utils.ext.hideKeyboard
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.objects.ObjectTypeChangeViewModel
import com.anytypeio.anytype.presentation.objects.ObjectTypeChangeViewModelFactory
import com.anytypeio.anytype.presentation.objects.ObjectTypeView
import com.anytypeio.anytype.ui.editor.OnFragmentInteractionListener
import kotlinx.android.synthetic.main.fragment_object_type_change.*
import javax.inject.Inject
class ObjectTypeChangeFragment : BaseBottomSheetFragment() {
private val ctx: String get() = argString(ARG_CTX)
private val smartBlockType: SmartBlockType get() = arg(ARG_SMART_BLOCK_TYPE)
private val vm by viewModels<ObjectTypeChangeViewModel> { factory }
@ -34,13 +36,7 @@ class ObjectTypeChangeFragment : BaseBottomSheetFragment() {
private val objectTypeAdapter by lazy {
ObjectTypeVerticalAdapter(
onItemClick = { id ->
withParent<OnFragmentInteractionListener> {
onObjectTypePicked(id)
}
view?.rootView?.hideKeyboard()
dismiss()
},
onItemClick = ::onItemClicked,
data = arrayListOf()
)
}
@ -63,6 +59,13 @@ class ObjectTypeChangeFragment : BaseBottomSheetFragment() {
objectTypeAdapter.update(views)
}
private fun onItemClicked(id: String, name: String) {
val bundle = bundleOf(OBJECT_TYPE_URL_KEY to id, OBJECT_TYPE_NAME_KEY to name)
setFragmentResult(OBJECT_TYPE_REQUEST_KEY, bundle)
view?.rootView?.hideKeyboard()
dismiss()
}
override fun onStart() {
with(lifecycleScope) {
jobs += subscribe(vm.results) { observeViews(it) }
@ -75,22 +78,17 @@ class ObjectTypeChangeFragment : BaseBottomSheetFragment() {
}
override fun injectDependencies() {
componentManager().objectTypeChangeComponent.get(ctx).inject(this)
componentManager().objectTypeChangeComponent.get().inject(this)
}
override fun releaseDependencies() {
componentManager().objectTypeChangeComponent.release(ctx)
componentManager().objectTypeChangeComponent.release()
}
companion object {
fun new(ctx: String, smartBlockType: SmartBlockType) = ObjectTypeChangeFragment().apply {
arguments = bundleOf(
ARG_CTX to ctx,
ARG_SMART_BLOCK_TYPE to smartBlockType
)
}
const val ARG_CTX = "arg.object-type.ctx"
const val ARG_SMART_BLOCK_TYPE = "arg.object-type.smart-block-type"
const val OBJECT_TYPE_URL_KEY = "object-type-url.key"
const val OBJECT_TYPE_NAME_KEY = "object-type-name.key"
const val OBJECT_TYPE_REQUEST_KEY = "object-type.request"
}
}

View file

@ -0,0 +1,83 @@
package com.anytypeio.anytype.ui.settings
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.settings.OtherSettingsViewModel
import com.anytypeio.anytype.ui.objects.ObjectTypeChangeFragment
import kotlinx.android.synthetic.main.fragment_user_settings.*
import javax.inject.Inject
class OtherSettingsFragment : BaseBottomSheetFragment() {
@Inject
lateinit var factory: OtherSettingsViewModel.Factory
private val vm by viewModels<OtherSettingsViewModel> { factory }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setFragmentResultListener(ObjectTypeChangeFragment.OBJECT_TYPE_REQUEST_KEY) { _, bundle ->
val id = bundle.getString(ObjectTypeChangeFragment.OBJECT_TYPE_URL_KEY)
val name = bundle.getString(ObjectTypeChangeFragment.OBJECT_TYPE_NAME_KEY)
vm.proceedWithUpdateType(type = id, name = name)
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_user_settings, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
tvDefaultObjectTypeTitle.setOnClickListener { vm.onObjectTypeClicked() }
objectType.setOnClickListener { vm.onObjectTypeClicked() }
ivArrowForward.setOnClickListener { vm.onObjectTypeClicked() }
}
override fun onStart() {
super.onStart()
with(lifecycleScope) {
jobs += subscribe(vm.commands) { observe(it) }
}
}
private fun observe(command: OtherSettingsViewModel.Command) {
when (command) {
OtherSettingsViewModel.Command.Exit -> dismiss()
is OtherSettingsViewModel.Command.NavigateToObjectTypesScreen -> {
findNavController().navigate(
R.id.objectTypeChangeFragment,
bundleOf(
ObjectTypeChangeFragment.ARG_SMART_BLOCK_TYPE to command.smartBlockType
)
)
}
is OtherSettingsViewModel.Command.SetObjectType -> {
objectType.text = command.name
}
is OtherSettingsViewModel.Command.Toast -> toast(command.msg)
}
}
override fun injectDependencies() {
componentManager().otherSettingsComponent.get().inject(this)
}
override fun releaseDependencies() {
componentManager().otherSettingsComponent.release()
}
}

View file

@ -1,72 +0,0 @@
package com.anytypeio.anytype.ui.settings
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ext.invisible
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.settings.UserSettingsViewModel
import kotlinx.android.synthetic.main.fragment_user_settings.*
import javax.inject.Inject
class UserSettingsFragment : BaseBottomSheetFragment() {
@Inject
lateinit var factory: UserSettingsViewModel.Factory
private val vm by viewModels<UserSettingsViewModel> { factory }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_user_settings, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
ivIconNote.setEmoji(getString(R.string.name_type_note_icon))
ivIconPage.setEmoji(getString(R.string.name_type_page_icon))
noteListener.setOnClickListener { vm.onNoteClicked() }
pageListener.setOnClickListener { vm.onPageClicked() }
}
override fun onStart() {
super.onStart()
with(lifecycleScope) {
jobs += subscribe(vm.commands) { observe(it) }
}
}
private fun observe(command: UserSettingsViewModel.Command) {
when (command) {
UserSettingsViewModel.Command.Exit -> dismiss()
UserSettingsViewModel.Command.NoteSelected -> setNoteSelected()
UserSettingsViewModel.Command.PageSelected -> setPageSelected()
}
}
private fun setNoteSelected() {
ivCheckedNote.visible()
ivCheckedPage.invisible()
}
private fun setPageSelected() {
ivCheckedNote.invisible()
ivCheckedPage.visible()
}
override fun injectDependencies() {
componentManager().userSettingsComponent.get().inject(this)
}
override fun releaseDependencies() {
componentManager().userSettingsComponent.release()
}
}

View file

@ -1,22 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ACA996"
android:pathData="M4,6L20,6A1,1 0,0 1,21 7L21,7A1,1 0,0 1,20 8L4,8A1,1 0,0 1,3 7L3,7A1,1 0,0 1,4 6z" />
<path
android:fillColor="#ffffff"
android:pathData="M17.25,7C17.25,8.1046 16.3546,9 15.25,9C14.1454,9 13.25,8.1046 13.25,7C13.25,5.8954 14.1454,5 15.25,5C16.3546,5 17.25,5.8954 17.25,7Z"
android:strokeWidth="2"
android:strokeColor="#ACA996" />
<path
android:fillColor="#ACA996"
android:pathData="M4,16L20,16A1,1 0,0 1,21 17L21,17A1,1 0,0 1,20 18L4,18A1,1 0,0 1,3 17L3,17A1,1 0,0 1,4 16z" />
<path
android:fillColor="#ffffff"
android:pathData="M9.25,17m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"
android:strokeWidth="2"
android:strokeColor="#ACA996" />
</vector>

View file

@ -124,7 +124,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="20dp"
android:drawableEnd="@drawable/ic_arrow_forward"
android:drawableEnd="@drawable/ic_arrow_forward_legacy"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:text="@string/or_scan_qr_code"

View file

@ -240,7 +240,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/thirdDivider"
app:srcCompat="@drawable/ic_settings" />
app:srcCompat="@drawable/ic_other_settings" />
<TextView
android:id="@+id/userSettingsText"
@ -250,7 +250,7 @@
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:drawableEnd="@drawable/ic_profile_forward"
android:text="@string/user_settings"
android:text="@string/other_settings"
app:layout_constraintBottom_toBottomOf="@+id/userSettingsIcon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/userSettingsIcon"

View file

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.anytypeio.anytype.ui.settings.UserSettingsFragment">
tools:context="com.anytypeio.anytype.ui.settings.OtherSettingsFragment">
<ImageView
android:id="@+id/sheet_top"
@ -24,185 +24,66 @@
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:gravity="center"
android:text="@string/user_settings_title"
android:text="@string/other_settings"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sheet_top" />
<TextView
android:id="@+id/tvDefaultObjectType"
android:id="@+id/tvDefaultObjectTypeTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="22dp"
android:layout_marginTop="26dp"
android:fontFamily="@font/inter_regular"
android:text="@string/default_object_type_title"
android:textColor="#929082"
android:textSize="@dimen/sp_13"
android:textColor="@color/black"
android:textSize="17sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvUserSettingsHeader" />
<View
android:id="@+id/divider1"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginStart="20dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="20dp"
android:background="@drawable/divider_dv_grid"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvDefaultObjectType" />
<com.anytypeio.anytype.core_ui.widgets.ObjectIconWidget
android:id="@+id/ivIconNote"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
app:emojiSize="24dp"
app:hasEmojiRounded8Background="true"
app:hasInitialRounded8Background="true"
app:imageSize="40dp"
app:initialTextSize="22sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/divider1" />
<TextView
android:id="@+id/tvTitleNote"
style="@style/SlashWidgetStyleItemTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="14dp"
android:text="@string/name_type_note"
app:layout_constraintStart_toEndOf="@+id/ivIconNote"
app:layout_constraintTop_toBottomOf="@+id/divider1" />
<TextView
android:id="@+id/tvSubtitleNote"
style="@style/ObjectTypeNameStyle"
android:id="@+id/objectType"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="8dp"
android:ellipsize="end"
android:maxLines="1"
android:layout_marginStart="20dp"
android:layout_marginEnd="10dp"
android:fontFamily="@font/inter_regular"
android:text="TextView"
android:singleLine="true"
android:text="@string/name_type_note_subtitle"
app:layout_constraintBottom_toBottomOf="@+id/ivIconNote"
app:layout_constraintEnd_toStartOf="@+id/ivCheckedNote"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/ivIconNote"
app:layout_constraintTop_toBottomOf="@+id/tvTitleNote" />
android:maxLines="1"
android:ellipsize="end"
android:textColor="#929082"
android:textSize="17sp"
android:gravity="center_vertical|end"
tools:text="Note"
app:layout_constraintBottom_toBottomOf="@+id/tvDefaultObjectTypeTitle"
app:layout_constraintEnd_toStartOf="@+id/ivArrowForward"
app:layout_constraintStart_toEndOf="@+id/tvDefaultObjectTypeTitle"
app:layout_constraintTop_toTopOf="@+id/tvDefaultObjectTypeTitle" />
<ImageView
android:id="@+id/ivCheckedNote"
android:id="@+id/ivArrowForward"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:src="@drawable/ic_option_checked_black"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/ivIconNote"
android:layout_marginEnd="20dp"
android:src="@drawable/ic_arrow_forward"
app:layout_constraintBottom_toBottomOf="@+id/objectType"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/ivIconNote"
tools:visibility="visible" />
app:layout_constraintTop_toTopOf="@+id/objectType" />
<View
android:id="@+id/divider2"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:background="@drawable/divider_dv_grid"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ivIconNote" />
<com.anytypeio.anytype.core_ui.widgets.ObjectIconWidget
android:id="@+id/ivIconPage"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
app:emojiSize="24dp"
app:hasEmojiRounded8Background="true"
app:hasInitialRounded8Background="true"
app:imageSize="40dp"
app:initialTextSize="22sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/divider2" />
<TextView
android:id="@+id/tvTitlePage"
style="@style/SlashWidgetStyleItemTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="14dp"
android:text="@string/name_type_page"
app:layout_constraintStart_toEndOf="@+id/ivIconPage"
app:layout_constraintTop_toBottomOf="@+id/divider2" />
<TextView
android:id="@+id/tvSubtitlePage"
style="@style/ObjectTypeNameStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="8dp"
android:ellipsize="end"
android:maxLines="1"
android:singleLine="true"
android:text="@string/name_type_page_subtitle"
app:layout_constraintBottom_toBottomOf="@+id/ivIconPage"
app:layout_constraintEnd_toStartOf="@+id/ivCheckedPage"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/ivIconPage"
app:layout_constraintTop_toBottomOf="@+id/tvTitlePage" />
<ImageView
android:id="@+id/ivCheckedPage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:src="@drawable/ic_option_checked_black"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/ivIconPage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/ivIconPage"
tools:visibility="visible" />
<View
android:id="@+id/divider3"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:layout_marginBottom="44dp"
android:background="@drawable/divider_dv_grid"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ivIconPage" />
app:layout_constraintTop_toBottomOf="@+id/tvDefaultObjectTypeTitle" />
<View
android:id="@+id/noteListener"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/divider2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/divider1" />
<View
android:id="@+id/pageListener"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/divider3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/divider2" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -128,7 +128,7 @@
app:layout_constraintBottom_toBottomOf="@+id/propType"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/propType"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<View
android:id="@+id/divider3"

View file

@ -457,8 +457,14 @@
tools:layout="@layout/fragment_create_set" />
<dialog
android:id="@+id/userSettingsFragment"
android:name="com.anytypeio.anytype.ui.settings.UserSettingsFragment"
android:name="com.anytypeio.anytype.ui.settings.OtherSettingsFragment"
android:label="fragment_user_settings"
tools:layout="@layout/fragment_user_settings" />
tools:layout="@layout/fragment_user_settings" >
</dialog>
<dialog
android:id="@+id/objectTypeChangeFragment"
android:name="com.anytypeio.anytype.ui.objects.ObjectTypeChangeFragment"
android:label="ObjectTypeChangeFragment"
tools:layout="@layout/fragment_object_type_change"/>
</navigation>

View file

@ -82,6 +82,7 @@ Do the computation of an expensive paragraph of text on a background thread:
<string name="keychain_phrase">Keychain phrase</string>
<string name="pin_code">Pin code</string>
<string name="user_settings">User settings</string>
<string name="other_settings">Other settings</string>
<string name="your_page">Your public page</string>
<string name="updates">Updates</string>
<string name="log_out">Log out</string>

View file

@ -2,6 +2,7 @@ package com.anytypeio.anytype.core_ui.features.objects
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_ui.R
import com.anytypeio.anytype.core_ui.features.objects.holders.ObjectTypeHolder
import com.anytypeio.anytype.core_ui.features.objects.holders.ObjectTypeHorizontalHolder
@ -10,7 +11,7 @@ import com.anytypeio.anytype.presentation.objects.ObjectTypeView
abstract class ObjectTypeBaseAdapter(
private var data: ArrayList<ObjectTypeView>,
private val onItemClick: (String) -> Unit,
private val onItemClick: (Id, String) -> Unit,
private val onSearchClick: (() -> Unit)? = null
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@ -25,8 +26,10 @@ abstract class ObjectTypeBaseAdapter(
R.layout.item_object_type_item -> {
ObjectTypeHolder(parent).apply {
itemView.setOnClickListener {
if (bindingAdapterPosition != RecyclerView.NO_POSITION)
onItemClick(data[bindingAdapterPosition].id)
if (bindingAdapterPosition != RecyclerView.NO_POSITION) {
val item = data[bindingAdapterPosition] as ObjectTypeView.Item
onItemClick(item.id, item.name)
}
}
}
}
@ -34,7 +37,8 @@ abstract class ObjectTypeBaseAdapter(
ObjectTypeHorizontalHolder(parent).apply {
itemView.setOnClickListener {
if (bindingAdapterPosition != RecyclerView.NO_POSITION) {
onItemClick(data[bindingAdapterPosition].id)
val item = data[bindingAdapterPosition] as ObjectTypeView.Item
onItemClick(item.id, item.name)
}
}
}
@ -71,7 +75,7 @@ abstract class ObjectTypeBaseAdapter(
class ObjectTypeVerticalAdapter(
data: ArrayList<ObjectTypeView>,
onItemClick: (String) -> Unit
onItemClick: (Id, String) -> Unit
) : ObjectTypeBaseAdapter(data, onItemClick) {
override fun getItemViewType(position: Int): Int = R.layout.item_object_type_item
@ -80,14 +84,14 @@ class ObjectTypeVerticalAdapter(
class ObjectTypeHorizontalListAdapter(
private var data: ArrayList<ObjectTypeView>,
onItemClick: (String) -> Unit,
onItemClick: (Id, String) -> Unit,
onSearchClick: () -> Unit
) : ObjectTypeBaseAdapter(data, onItemClick, onSearchClick) {
override fun getItemViewType(position: Int): Int {
return when (data[position]) {
is ObjectTypeView.Item -> R.layout.item_object_type_horizontal_item
is ObjectTypeView.Search -> R.layout.item_object_type_search
ObjectTypeView.Search -> R.layout.item_object_type_search
else -> throw IllegalStateException("Unexpected ObjectTypeView!")
}
}

View file

@ -26,7 +26,7 @@ class ObjectTypesWidget @JvmOverloads constructor(
private val typesAdapter by lazy {
ObjectTypeHorizontalListAdapter(
data = arrayListOf(),
onItemClick = { id -> onItemClick?.invoke(id) },
onItemClick = this::onItemClicked,
onSearchClick = { onSearchClick?.invoke() }
)
}
@ -88,4 +88,8 @@ class ObjectTypesWidget @JvmOverloads constructor(
iconArrowUp.gone()
iconArrowDown.visible()
}
private fun onItemClicked(id: Id, name: String) {
onItemClick?.invoke(id)
}
}

View file

@ -1,10 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="13dp"
android:height="24dp"
android:viewportWidth="8"
android:viewportHeight="13">
<path
android:pathData="M0.2929,1.288C0.6834,0.8975 1.3166,0.8975 1.7071,1.288L7.4142,6.9951L1.7071,12.7022C1.3166,13.0927 0.6834,13.0927 0.2929,12.7022C-0.0976,12.3117 -0.0976,11.6785 0.2929,11.288L4.5858,6.9951L0.2929,2.7022C-0.0976,2.3117 -0.0976,1.6785 0.2929,1.288Z"
android:fillColor="#DFDDD0"
android:fillType="evenOdd"/>
android:viewportHeight="24">
<group>
<clip-path
android:pathData="M0,24l0,-24l8,-0l0,24z"/>
<path
android:pathData="M0.9597,18.0303C0.6668,17.7374 0.6668,17.2626 0.9597,16.9697L5.9293,12L0.9597,7.0303C0.6668,6.7374 0.6668,6.2626 0.9597,5.9697C1.2526,5.6768 1.7274,5.6768 2.0203,5.9697L8.0506,12L2.0203,18.0303C1.7274,18.3232 1.2526,18.3232 0.9597,18.0303Z"
android:fillColor="#CBC9BD"
android:fillType="evenOdd"/>
</group>
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="13dp"
android:viewportWidth="8"
android:viewportHeight="13">
<path
android:pathData="M0.2929,1.288C0.6834,0.8975 1.3166,0.8975 1.7071,1.288L7.4142,6.9951L1.7071,12.7022C1.3166,13.0927 0.6834,13.0927 0.2929,12.7022C-0.0976,12.3117 -0.0976,11.6785 0.2929,11.288L4.5858,6.9951L0.2929,2.7022C-0.0976,2.3117 -0.0976,1.6785 0.2929,1.288Z"
android:fillColor="#DFDDD0"
android:fillType="evenOdd"/>
</vector>

View file

@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="28dp"
android:height="28dp"
android:viewportWidth="28"
android:viewportHeight="28">
<path
android:pathData="M6,0L22,0A6,6 0,0 1,28 6L28,22A6,6 0,0 1,22 28L6,28A6,6 0,0 1,0 22L0,6A6,6 0,0 1,6 0z"
android:fillColor="#0FC8BA"/>
<path
android:pathData="M10,22C12.2091,22 14,20.2091 14,18C14,15.7909 12.2091,14 10,14C7.7909,14 6,15.7909 6,18C6,20.2091 7.7909,22 10,22Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M18,14C20.2091,14 22,12.2091 22,10C22,7.7909 20.2091,6 18,6C15.7909,6 14,7.7909 14,10C14,12.2091 15.7909,14 18,14Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -46,7 +46,7 @@
app:layout_constraintBottom_toBottomOf="@+id/textCheckbox"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/textCheckbox"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<ImageView
android:id="@+id/checkboxHide"

View file

@ -46,7 +46,7 @@
app:layout_constraintBottom_toBottomOf="@+id/propDate"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/propDate"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<ImageView
android:id="@+id/dateHide"

View file

@ -46,7 +46,7 @@
app:layout_constraintBottom_toBottomOf="@+id/propEmail"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/propEmail"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<ImageView
android:id="@+id/emailHide"

View file

@ -46,7 +46,7 @@
app:layout_constraintBottom_toBottomOf="@+id/textFile"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/textFile"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<ImageView
android:id="@+id/fileHide"

View file

@ -46,7 +46,7 @@
app:layout_constraintBottom_toBottomOf="@+id/textMultiple"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/textMultiple"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<ImageView
android:id="@+id/multipleHide"

View file

@ -46,7 +46,7 @@
app:layout_constraintBottom_toBottomOf="@+id/propNumber"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/propNumber"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<ImageView
android:id="@+id/numberHide"

View file

@ -46,7 +46,7 @@
app:layout_constraintBottom_toBottomOf="@+id/propPerson"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/propPerson"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<ImageView
android:id="@+id/personHide"

View file

@ -46,7 +46,7 @@
app:layout_constraintBottom_toBottomOf="@+id/textPhone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/textPhone"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<ImageView
android:id="@+id/phoneHide"

View file

@ -46,7 +46,7 @@
app:layout_constraintBottom_toBottomOf="@+id/propSelect"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/propSelect"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<ImageView
android:id="@+id/selectHide"

View file

@ -47,7 +47,7 @@
app:layout_constraintBottom_toBottomOf="@+id/propText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/propText"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<ImageView
android:id="@+id/textHide"

View file

@ -47,7 +47,7 @@
app:layout_constraintBottom_toBottomOf="@+id/propTitle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/propTitle"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<ImageView
android:id="@+id/titleHide"

View file

@ -46,7 +46,7 @@
app:layout_constraintBottom_toBottomOf="@+id/textURL"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/textURL"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<ImageView
android:id="@+id/urlHide"

View file

@ -38,7 +38,7 @@
app:layout_constraintBottom_toBottomOf="@+id/filter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/filter"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<TextView
android:id="@+id/filterCount"

View file

@ -37,7 +37,7 @@
app:layout_constraintBottom_toBottomOf="@+id/gallery"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/gallery"
app:srcCompat="@drawable/ic_arrow_forward"
app:srcCompat="@drawable/ic_arrow_forward_legacy"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -38,7 +38,7 @@
app:layout_constraintBottom_toBottomOf="@+id/group"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/group"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<TextView
android:id="@+id/groupCount"

View file

@ -37,7 +37,7 @@
app:layout_constraintBottom_toBottomOf="@+id/kanban"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/kanban"
app:srcCompat="@drawable/ic_arrow_forward"
app:srcCompat="@drawable/ic_arrow_forward_legacy"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -38,7 +38,7 @@
app:layout_constraintBottom_toBottomOf="@+id/list"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/list"
app:srcCompat="@drawable/ic_arrow_forward"
app:srcCompat="@drawable/ic_arrow_forward_legacy"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -37,6 +37,6 @@
app:layout_constraintBottom_toBottomOf="@+id/relationsText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/relationsText"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -38,7 +38,7 @@
app:layout_constraintBottom_toBottomOf="@+id/sort"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/sort"
app:srcCompat="@drawable/ic_arrow_forward" />
app:srcCompat="@drawable/ic_arrow_forward_legacy" />
<TextView
android:id="@+id/sortsCount"

View file

@ -37,7 +37,7 @@
app:layout_constraintBottom_toBottomOf="@+id/table"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/table"
app:srcCompat="@drawable/ic_arrow_forward"
app:srcCompat="@drawable/ic_arrow_forward_legacy"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,6 +1,6 @@
package com.anytypeio.anytype.data.auth.repo
interface UserSettingsCache {
suspend fun setDefaultPageType(type: String)
suspend fun getDefaultPageType(): String?
suspend fun setDefaultObjectType(type: String, name: String)
suspend fun getDefaultObjectType(): Pair<String?, String?>
}

View file

@ -4,9 +4,9 @@ import com.anytypeio.anytype.domain.config.UserSettingsRepository
class UserSettingsDataRepository(private val cache: UserSettingsCache) : UserSettingsRepository {
override suspend fun setDefaultPageType(type: String) {
cache.setDefaultPageType(type)
override suspend fun setDefaultObjectType(type: String, name: String) {
cache.setDefaultObjectType(type, name)
}
override suspend fun getDefaultPageType(): String? = cache.getDefaultPageType()
override suspend fun getDefaultObjectType(): Pair<String?, String?> = cache.getDefaultObjectType()
}

View file

@ -1,6 +1,6 @@
package com.anytypeio.anytype.domain.config
interface UserSettingsRepository {
suspend fun setDefaultPageType(type: String)
suspend fun getDefaultPageType(): String?
suspend fun setDefaultObjectType(type: String, name: String)
suspend fun getDefaultObjectType(): Pair<String?, String?>
}

View file

@ -8,8 +8,9 @@ class GetDefaultEditorType(
) : BaseUseCase<GetDefaultEditorType.Response, Unit>() {
override suspend fun run(params: Unit) = safe {
Response(userSettingsRepository.getDefaultPageType())
val pair = userSettingsRepository.getDefaultObjectType()
Response(pair.first, pair.second)
}
class Response(val type: String?)
class Response(val type: String?, val name: String?)
}

View file

@ -7,7 +7,7 @@ class SetDefaultEditorType(private val repo: UserSettingsRepository) :
BaseUseCase<Unit, SetDefaultEditorType.Params>() {
override suspend fun run(params: Params) = safe {
repo.setDefaultPageType(params.type)
repo.setDefaultObjectType(params.type, params.name)
}
/**
@ -15,6 +15,7 @@ class SetDefaultEditorType(private val repo: UserSettingsRepository) :
@see ObjectTypeConst for possible values.
**/
class Params(
val type: String
val type: String,
val name: String
)
}

View file

@ -5,15 +5,21 @@ import com.anytypeio.anytype.data.auth.repo.UserSettingsCache
class DefaultUserSettingsCache(private val prefs: SharedPreferences) : UserSettingsCache {
override suspend fun setDefaultPageType(type: String) {
prefs.edit().putString(DEFAULT_PAGE_KEY, type).apply()
override suspend fun setDefaultObjectType(type: String, name: String) {
prefs.edit()
.putString(DEFAULT_OBJECT_TYPE_ID_KEY, type)
.putString(DEFAULT_OBJECT_TYPE_NAME_KEY, name)
.apply()
}
override suspend fun getDefaultPageType(): String? {
return prefs.getString(DEFAULT_PAGE_KEY, null)
override suspend fun getDefaultObjectType(): Pair<String?, String?> {
val type = prefs.getString(DEFAULT_OBJECT_TYPE_ID_KEY, null)
val name = prefs.getString(DEFAULT_OBJECT_TYPE_NAME_KEY, null)
return Pair(type, name)
}
companion object {
const val DEFAULT_PAGE_KEY = "prefs.user_settings.default_page"
const val DEFAULT_OBJECT_TYPE_ID_KEY = "prefs.user_settings.default_object_type.id"
const val DEFAULT_OBJECT_TYPE_NAME_KEY = "prefs.user_settings.default_object_type.name"
}
}

View file

@ -3709,8 +3709,12 @@ class EditorViewModel(
}
}
fun onObjectTypeChanged(id: Id) {
fun onObjectTypeChanged(id: Id?) {
Timber.d("onObjectTypeChanged, typeId:[$id]")
if (id == null) {
_toasts.offer(CANNOT_CHANGE_NULL_OBJECT_TYPE)
return
}
viewModelScope.launch {
orchestrator.proxies.intents.send(
Intent.Document.SetObjectType(
@ -3733,6 +3737,7 @@ class EditorViewModel(
const val FORMAT_WEBP = "webp"
const val CANNOT_MOVE_BLOCK_ON_SAME_POSITION = "Selected block is already on the position"
const val CANNOT_BE_DROPPED_INSIDE_ITSELF_ERROR = "A block cannot be moved inside itself."
const val CANNOT_CHANGE_NULL_OBJECT_TYPE = "Cannot change object type, when new one is unknown"
const val CANNOT_BE_PARENT_ERROR = "This block does not support nesting."
const val CANNOT_MOVE_PARENT_INTO_CHILD = "Cannot move parent into child."
@ -5238,11 +5243,11 @@ class EditorViewModel(
}
}
private suspend fun proceedWithSortingObjectTypesForObjectTypeWidget(views: List<ObjectTypeView>) {
private suspend fun proceedWithSortingObjectTypesForObjectTypeWidget(views: List<ObjectTypeView.Item>) {
getDefaultEditorType.invoke(Unit).proceed(
failure = { Timber.e(it, "Error while getting default object type") },
success = { response ->
val sorted = listOf(ObjectTypeView.Search()) + views.toMutableList()
val sorted = listOf(ObjectTypeView.Search) + views.toMutableList()
.sortByType(response.type)
controlPanelInteractor.onEvent(
ControlPanelMachine.Event.ObjectTypesWidgetEvent.Show(sorted)

View file

@ -6,22 +6,18 @@ import com.anytypeio.anytype.core_models.ObjectType.Companion.PAGE_URL
sealed class ObjectTypeView {
abstract val id: String
data class Item(
override val id: String,
val id: String,
val name: String,
val description: String?,
val emoji: String?,
val layout: ObjectType.Layout
) : ObjectTypeView()
data class Search(
override val id: String = ""
) : ObjectTypeView()
object Search: ObjectTypeView()
}
fun MutableList<ObjectTypeView>.sortByType(
fun MutableList<ObjectTypeView.Item>.sortByType(
defaultType: String?
): List<ObjectTypeView> {
if (defaultType == NOTE_URL) {

View file

@ -0,0 +1,94 @@
package com.anytypeio.anytype.presentation.settings
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.anytypeio.anytype.analytics.base.Analytics
import com.anytypeio.anytype.analytics.base.EventsDictionary
import com.anytypeio.anytype.analytics.base.EventsDictionary.PROP_TYPE
import com.anytypeio.anytype.analytics.event.EventAnalytics
import com.anytypeio.anytype.analytics.props.Props
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.SmartBlockType
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.launch.SetDefaultEditorType
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import timber.log.Timber
class OtherSettingsViewModel(
private val getDefaultEditorType: GetDefaultEditorType,
private val setDefaultEditorType: SetDefaultEditorType,
private val analytics: Analytics
) : ViewModel() {
val commands = MutableSharedFlow<Command>(replay = 0)
init {
viewModelScope.launch {
getDefaultEditorType.invoke(Unit).proceed(
failure = { Timber.e(it, "Error while getting user settings") },
success = { commands.emit(Command.SetObjectType(name = it.name)) }
)
}
}
fun onObjectTypeClicked() {
viewModelScope.launch {
commands.emit(Command.NavigateToObjectTypesScreen(DEFAULT_SETTINGS_SMART_BLOCK_TYPE))
}
}
fun proceedWithUpdateType(type: Id?, name: String?) {
if (type == null || name == null) {
viewModelScope.launch {
commands.emit(Command.Toast("Cannot change default object type"))
}
return
}
viewModelScope.launch {
setDefaultEditorType.invoke(SetDefaultEditorType.Params(type, name)).process(
failure = {
Timber.e(it, "Error while setting default object type")
commands.emit(Command.Toast(msg = "Error while setting default object type"))
},
success = {
commands.emit(Command.SetObjectType(name = name))
analytics.registerEvent(
EventAnalytics.Anytype(
name = EventsDictionary.DEFAULT_TYPE_CHANGED,
props = Props(mapOf(PROP_TYPE to type)),
duration = null
)
)
}
)
}
}
sealed class Command {
data class SetObjectType(val name: String?) : Command()
data class Toast(val msg: String) : Command()
data class NavigateToObjectTypesScreen(val smartBlockType: SmartBlockType) : Command()
object Exit : Command()
}
companion object {
private val DEFAULT_SETTINGS_SMART_BLOCK_TYPE = SmartBlockType.PAGE
}
class Factory(
private val getDefaultEditorType: GetDefaultEditorType,
private val setDefaultEditorType: SetDefaultEditorType,
private val analytics: Analytics
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(
modelClass: Class<T>
): T = OtherSettingsViewModel(
getDefaultEditorType = getDefaultEditorType,
setDefaultEditorType = setDefaultEditorType,
analytics = analytics
) as T
}
}

View file

@ -1,78 +0,0 @@
package com.anytypeio.anytype.presentation.settings
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.anytypeio.anytype.analytics.base.Analytics
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.launch.SetDefaultEditorType
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import timber.log.Timber
class UserSettingsViewModel(
private val getDefaultEditorType: GetDefaultEditorType,
private val setDefaultEditorType: SetDefaultEditorType,
private val analytics: Analytics
) : ViewModel() {
val commands = MutableSharedFlow<Command>(replay = 0)
init {
viewModelScope.launch {
getDefaultEditorType.invoke(Unit).proceed(
failure = { Timber.e(it, "Error while getting user settings") },
success = { response ->
if (response.type == ObjectType.NOTE_URL) {
commands.emit(Command.NoteSelected)
} else {
commands.emit(Command.PageSelected)
}
}
)
}
}
fun onNoteClicked() {
proceedWithUpdateType(ObjectType.NOTE_URL)
}
fun onPageClicked() {
proceedWithUpdateType(ObjectType.PAGE_URL)
}
private fun proceedWithUpdateType(type: String) {
viewModelScope.launch {
setDefaultEditorType.invoke(SetDefaultEditorType.Params(type)).process(
failure = {
Timber.e(it, "Error while setting default object type")
commands.emit(Command.Exit)
},
success = { commands.emit(Command.Exit) }
)
}
}
sealed class Command {
object NoteSelected : Command()
object PageSelected : Command()
object Exit : Command()
}
class Factory(
private val getDefaultEditorType: GetDefaultEditorType,
private val setDefaultEditorType: SetDefaultEditorType,
private val analytics: Analytics
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(
modelClass: Class<T>
): T = UserSettingsViewModel(
getDefaultEditorType = getDefaultEditorType,
setDefaultEditorType = setDefaultEditorType,
analytics = analytics
) as T
}
}

View file

@ -77,7 +77,7 @@ class SplashViewModel(
DEFAULT_TYPE_UPDATE
}
viewModelScope.launch {
val params = SetDefaultEditorType.Params(defaultType)
val params = SetDefaultEditorType.Params(defaultType.first, defaultType.second)
Timber.d("Start to update Default Page Type:${params.type}")
setDefaultEditorType.invoke(params).process(
failure = {
@ -221,7 +221,8 @@ class SplashViewModel(
companion object {
const val ERROR_MESSAGE = "An error occurred while starting account..."
const val DEFAULT_TYPE_FIRST_INSTALL = NOTE_URL
const val DEFAULT_TYPE_UPDATE = PAGE_URL
//ToDo better to take the name from middleware (see GetLastOpenedObject use case)
val DEFAULT_TYPE_FIRST_INSTALL = Pair(NOTE_URL, "Note")
val DEFAULT_TYPE_UPDATE = Pair(PAGE_URL, "Page")
}
}

View file

@ -310,7 +310,7 @@ class HomeDashboardViewModelTest {
fun `should start creating page when requested from UI`() {
stubObserveEvents()
stubGetDefaultObjectType(null)
stubGetDefaultObjectType()
vm = buildViewModel()
@ -328,7 +328,7 @@ class HomeDashboardViewModelTest {
stubGetEditorSettings()
stubCloseDashboard()
stubCreatePage(id)
stubGetDefaultObjectType(null)
stubGetDefaultObjectType()
vm = buildViewModel()
@ -392,9 +392,9 @@ class HomeDashboardViewModelTest {
}
}
private fun stubGetDefaultObjectType(type: String?) {
private fun stubGetDefaultObjectType(type: String? = null, name: String? = null) {
getDefaultEditorType.stub {
onBlocking { invoke(Unit) } doReturn Either.Right(GetDefaultEditorType.Response(type))
onBlocking { invoke(Unit) } doReturn Either.Right(GetDefaultEditorType.Response(type, name))
}
}
}

View file

@ -3901,9 +3901,9 @@ open class EditorViewModelTest {
}
}
private fun stubGetDefaultObjectType(type: String?) {
private fun stubGetDefaultObjectType(type: String? = null, name: String? = null) {
getDefaultEditorType.stub {
onBlocking { invoke(Unit) } doReturn Either.Right(GetDefaultEditorType.Response(type))
onBlocking { invoke(Unit) } doReturn Either.Right(GetDefaultEditorType.Response(type, null))
}
}

View file

@ -116,7 +116,7 @@ class EditorNoteLayoutTest : EditorPresentationTestSetup() {
stubInterceptEvents()
stubInterceptThreadStatus()
stubGetObjectTypes(objectTypes = listOf())
stubGetDefaultObjectType(null)
stubGetDefaultObjectType()
stubOpenDocument(
document = doc,
details = customDetails,

View file

@ -520,9 +520,9 @@ open class EditorPresentationTestSetup {
}
}
fun stubGetDefaultObjectType(type: String?) {
fun stubGetDefaultObjectType(type: String? = null, name: String? = null) {
getDefaultEditorType.stub {
onBlocking { invoke(Unit) } doReturn Either.Right(GetDefaultEditorType.Response(type))
onBlocking { invoke(Unit) } doReturn Either.Right(GetDefaultEditorType.Response(type, name))
}
}
}

View file

@ -310,15 +310,9 @@ class SplashViewModelTest {
}
}
private fun stubGetDefaultObjectType(type: String?) {
private fun stubGetDefaultObjectType(type: String? = null, name: String? = null) {
getDefaultEditorType.stub {
onBlocking { invoke(Unit) } doReturn Either.Right(GetDefaultEditorType.Response(type))
}
}
private fun stubSetDefaultObjectType(type: String) {
setDefaultEditorType.stub {
onBlocking { invoke(SetDefaultEditorType.Params(type)) } doReturn Either.Right(Unit)
onBlocking { invoke(Unit) } doReturn Either.Right(GetDefaultEditorType.Response(type, name))
}
}
}