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

Tech | Remove deprecated Kotlin Android Extensions (#2108)

This commit is contained in:
Evgenii Kozlov 2022-02-15 12:30:48 +03:00 committed by GitHub
parent fa0df5a27f
commit bf0fb77e9e
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
119 changed files with 2262 additions and 2077 deletions

View file

@ -1,11 +1,9 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: "androidx.navigation.safeargs.kotlin"
apply plugin: 'com.google.firebase.crashlytics'
apply from: "$rootDir/versioning.gradle"
def apikeyPropertiesFile = rootProject.file("apikeys.properties")
@ -111,18 +109,17 @@ android {
jvmTarget = JavaVersion.VERSION_11
}
androidExtensions {
experimental = true
}
lint {
abortOnError false
disable 'InvalidPackage', 'OldTargetApi', 'IconDensities', 'IconMissingDensityFolder'
ignoreWarnings true
quiet true
}
buildFeatures {
viewBinding true
}
splits {
// Configures multiple APKs based on ABI.
abi {

View file

@ -310,14 +310,6 @@ class ComponentManager(private val main: MainComponent) {
.build()
}
val documentAddNewBlockComponent = DependentComponentMap { ctx ->
editorComponent
.get(ctx)
.documentAddNewBlockComponentBuilder()
.documentAddNewBlockModule(DocumentAddNewBlockModule)
.build()
}
val viewerFilterComponent = DependentComponentMap { ctx ->
objectSetComponent
.get(ctx)

View file

@ -1,34 +0,0 @@
package com.anytypeio.anytype.di.feature
import com.anytypeio.anytype.core_utils.di.scope.PerModal
import com.anytypeio.anytype.domain.block.interactor.sets.GetObjectTypes
import com.anytypeio.anytype.presentation.editor.picker.DocumentAddBlockViewModelFactory
import com.anytypeio.anytype.ui.editor.modals.AddBlockFragment
import dagger.Module
import dagger.Provides
import dagger.Subcomponent
@Subcomponent(modules = [DocumentAddNewBlockModule::class])
@PerModal
interface DocumentAddNewBlockSubComponent{
@Subcomponent.Builder
interface Builder {
fun documentAddNewBlockModule(module: DocumentAddNewBlockModule): Builder
fun build(): DocumentAddNewBlockSubComponent
}
fun inject(fragment: AddBlockFragment)
}
@Module
object DocumentAddNewBlockModule {
@JvmStatic
@Provides
@PerModal
fun provideFactory(
getObjectTypes: GetObjectTypes,
): DocumentAddBlockViewModelFactory =
DocumentAddBlockViewModelFactory(getObjectTypes)
}

View file

@ -91,8 +91,6 @@ interface EditorSubComponent {
fun objectCoverComponent() : SelectCoverObjectSubComponent.Builder
fun objectMenuComponent() : ObjectMenuComponent.Builder
fun documentAddNewBlockComponentBuilder(): DocumentAddNewBlockSubComponent.Builder
fun objectLayoutComponent() : ObjectLayoutSubComponent.Builder
fun objectAppearanceSettingComponent() : ObjectAppearanceSettingSubComponent.Builder
fun objectAppearanceIconComponent() : ObjectAppearanceIconSubComponent.Builder

View file

@ -9,10 +9,10 @@ import android.view.View
import android.view.ViewGroup
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentAlertBinding
import com.anytypeio.anytype.ui.editor.OnFragmentInteractionListener
import kotlinx.android.synthetic.main.fragment_alert.*
class AlertUpdateAppFragment : BaseBottomSheetFragment() {
class AlertUpdateAppFragment : BaseBottomSheetFragment<FragmentAlertBinding>() {
companion object {
const val TG_PACKAGE = "org.telegram.messenger"
@ -29,11 +29,11 @@ class AlertUpdateAppFragment : BaseBottomSheetFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
later.setOnClickListener {
binding.later.setOnClickListener {
(parentFragment as? OnFragmentInteractionListener)?.onExitToDesktopClicked()
dismiss()
}
update.setOnClickListener {
binding.update.setOnClickListener {
val intent = telegramIntent(requireContext())
startActivity(intent)
}
@ -54,4 +54,11 @@ class AlertUpdateAppFragment : BaseBottomSheetFragment() {
override fun injectDependencies() {}
override fun releaseDependencies() {}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentAlertBinding = FragmentAlertBinding.inflate(
inflater, container, false
)
}

View file

@ -1,7 +1,9 @@
package com.anytypeio.anytype.ui.archive
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
@ -11,16 +13,16 @@ import com.anytypeio.anytype.core_ui.tools.FirstItemInvisibilityDetector
import com.anytypeio.anytype.core_utils.ext.hideSoftInput
import com.anytypeio.anytype.core_utils.ext.invisible
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.databinding.FragmentArchiveBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.editor.archive.ArchiveViewModel
import com.anytypeio.anytype.presentation.editor.archive.ArchiveViewModelFactory
import com.anytypeio.anytype.presentation.editor.archive.ArchiveViewState
import com.anytypeio.anytype.ui.base.NavigationFragment
import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.android.synthetic.main.fragment_archive.*
import javax.inject.Inject
open class ArchiveFragment : NavigationFragment(R.layout.fragment_archive) {
open class ArchiveFragment : NavigationFragment<FragmentArchiveBinding>(R.layout.fragment_archive) {
@Inject
lateinit var factory: ArchiveViewModelFactory
@ -37,9 +39,9 @@ open class ArchiveFragment : NavigationFragment(R.layout.fragment_archive) {
private val titleVisibilityDetector by lazy {
FirstItemInvisibilityDetector { isVisible ->
if (isVisible) {
topToolbar.title.invisible()
binding.topToolbar.title.invisible()
} else {
topToolbar.title.visible()
binding.topToolbar.title.visible()
}
}
}
@ -47,10 +49,10 @@ open class ArchiveFragment : NavigationFragment(R.layout.fragment_archive) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
vm.state.observe(viewLifecycleOwner, { render(it) })
vm.state.observe(viewLifecycleOwner) { render(it) }
vm.navigation.observe(viewLifecycleOwner, navObserver)
BottomSheetBehavior.from(sheet).apply {
BottomSheetBehavior.from(binding.sheet).apply {
state = BottomSheetBehavior.STATE_EXPANDED
isHideable = true
addBottomSheetCallback(
@ -66,16 +68,16 @@ open class ArchiveFragment : NavigationFragment(R.layout.fragment_archive) {
)
}
topToolbar.menu.invisible()
binding.topToolbar.menu.invisible()
with(bottomMenu) {
with(binding.bottomMenu) {
update(COUNTER_INIT)
findViewById<TextView>(R.id.btnPutBack).setOnClickListener {
vm.onPutBackClicked()
}
}
recycler.apply {
binding.recycler.apply {
layoutManager = LinearLayoutManager(requireContext())
setHasFixedSize(true)
adapter = archiveAdapter
@ -88,7 +90,7 @@ open class ArchiveFragment : NavigationFragment(R.layout.fragment_archive) {
ArchiveViewState.Loading -> {}
is ArchiveViewState.Success -> {
archiveAdapter.update(state.blocks)
bottomMenu.update(state.selections)
binding.bottomMenu.update(state.selections)
}
}
}
@ -116,6 +118,14 @@ open class ArchiveFragment : NavigationFragment(R.layout.fragment_archive) {
.getString(ID_KEY)
?: throw IllegalStateException("Document id missing")
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentArchiveBinding = FragmentArchiveBinding.inflate(
inflater, container, false
)
companion object {
const val ID_KEY = "args.id"
const val COUNTER_INIT = 0

View file

@ -2,21 +2,23 @@ package com.anytypeio.anytype.ui.auth
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.extensions.toast
import com.anytypeio.anytype.core_utils.common.EventWrapper
import com.anytypeio.anytype.databinding.FragmentInvitationBinding
import com.anytypeio.anytype.presentation.navigation.AppNavigation
import com.anytypeio.anytype.ui.base.NavigationFragment
import kotlinx.android.synthetic.main.fragment_invitation.*
class InvitationFragment : NavigationFragment(R.layout.fragment_invitation) {
class InvitationFragment : NavigationFragment<FragmentInvitationBinding>(R.layout.fragment_invitation) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnConfirm.setOnClickListener {
if (edtCode.text.isNullOrEmpty()) {
binding.btnConfirm.setOnClickListener {
if (binding.edtCode.text.isNullOrEmpty()) {
requireActivity().toast(
msg = getString(R.string.code_empty),
gravity = Gravity.TOP,
@ -26,17 +28,24 @@ class InvitationFragment : NavigationFragment(R.layout.fragment_invitation) {
navObserver.onChanged(
EventWrapper(
AppNavigation.Command.OpenCreateAccount(
invitationCode = edtCode.text.toString()
invitationCode = binding.edtCode.text.toString()
)
)
)
}
}
btnBack.setOnClickListener {
binding.btnBack.setOnClickListener {
navObserver.onChanged(EventWrapper(AppNavigation.Command.Exit))
}
}
override fun injectDependencies() {}
override fun releaseDependencies() {}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentInvitationBinding = FragmentInvitationBinding.inflate(
inflater, container, false
)
}

View file

@ -2,23 +2,25 @@ package com.anytypeio.anytype.ui.auth
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.viewModels
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ext.hideKeyboard
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ui.DoneActionListener
import com.anytypeio.anytype.databinding.FragmentKeychainLoginBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.auth.keychain.KeychainLoginViewModel
import com.anytypeio.anytype.presentation.auth.keychain.KeychainLoginViewModelFactory
import com.anytypeio.anytype.presentation.common.ViewState
import com.anytypeio.anytype.ui.base.NavigationFragment
import com.google.zxing.integration.android.IntentIntegrator
import kotlinx.android.synthetic.main.fragment_keychain_login.*
import javax.inject.Inject
class KeychainLoginFragment : NavigationFragment(R.layout.fragment_keychain_login) {
class KeychainLoginFragment : NavigationFragment<FragmentKeychainLoginBinding>(R.layout.fragment_keychain_login) {
@Inject
lateinit var factory: KeychainLoginViewModelFactory
@ -31,10 +33,10 @@ class KeychainLoginFragment : NavigationFragment(R.layout.fragment_keychain_logi
}
private fun setupEditTextListener() {
keychainInputField.setOnEditorActionListener(
binding.keychainInputField.setOnEditorActionListener(
DoneActionListener(
onActionDone = {
vm.onActionDone(keychainInputField.text.toString())
vm.onActionDone(binding.keychainInputField.text.toString())
}
)
)
@ -46,17 +48,17 @@ class KeychainLoginFragment : NavigationFragment(R.layout.fragment_keychain_logi
vm.state.observe(viewLifecycleOwner) { state ->
when (state) {
ViewState.Loading -> {
progress.visibility = View.VISIBLE
loginButton.isEnabled = false
binding.progress.visibility = View.VISIBLE
binding.loginButton.isEnabled = false
}
is ViewState.Error -> {
loginButton.isEnabled = true
progress.visibility = View.INVISIBLE
binding.loginButton.isEnabled = true
binding.progress.visibility = View.INVISIBLE
requireActivity().toast(state.error)
}
is ViewState.Success -> {
loginButton.isEnabled = true
progress.visibility = View.INVISIBLE
binding.loginButton.isEnabled = true
binding.progress.visibility = View.INVISIBLE
}
}
}
@ -72,13 +74,13 @@ class KeychainLoginFragment : NavigationFragment(R.layout.fragment_keychain_logi
}
private fun setupButtons() {
loginButton.setOnClickListener {
binding.loginButton.setOnClickListener {
vm.onLoginClicked(
chain = keychainInputField.text.toString()
chain = binding.keychainInputField.text.toString()
)
}
backButton.setOnClickListener { vm.onBackButtonPressed() }
tvqrcode.setOnClickListener { showAlert() }
binding.backButton.setOnClickListener { vm.onBackButtonPressed() }
binding.tvqrcode.setOnClickListener { showAlert() }
}
private fun showAlert() {
@ -112,4 +114,11 @@ class KeychainLoginFragment : NavigationFragment(R.layout.fragment_keychain_logi
override fun releaseDependencies() {
componentManager().keychainLoginComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentKeychainLoginBinding = FragmentKeychainLoginBinding.inflate(
inflater, container, false
)
}

View file

@ -1,17 +1,19 @@
package com.anytypeio.anytype.ui.auth
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import com.anytypeio.anytype.R
import com.anytypeio.anytype.databinding.FragmentStartLoginBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.auth.start.StartLoginViewModel
import com.anytypeio.anytype.presentation.auth.start.StartLoginViewModelFactory
import com.anytypeio.anytype.ui.base.NavigationFragment
import kotlinx.android.synthetic.main.fragment_start_login.*
import javax.inject.Inject
class StartLoginFragment : NavigationFragment(R.layout.fragment_start_login) {
class StartLoginFragment : NavigationFragment<FragmentStartLoginBinding>(R.layout.fragment_start_login) {
@Inject
lateinit var factory: StartLoginViewModelFactory
@ -30,8 +32,8 @@ class StartLoginFragment : NavigationFragment(R.layout.fragment_start_login) {
}
private fun setupButtonClicks() {
signUpButton.setOnClickListener { vm.onSignUpClicked() }
loginButton.setOnClickListener { vm.onLoginClicked() }
binding.signUpButton.setOnClickListener { vm.onSignUpClicked() }
binding.loginButton.setOnClickListener { vm.onLoginClicked() }
}
override fun injectDependencies() {
@ -41,4 +43,11 @@ class StartLoginFragment : NavigationFragment(R.layout.fragment_start_login) {
override fun releaseDependencies() {
componentManager().startLoginComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentStartLoginBinding = FragmentStartLoginBinding.inflate(
inflater, container, false
)
}

View file

@ -7,7 +7,9 @@ import android.content.pm.PackageManager
import android.os.Bundle
import android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.fragment.app.viewModels
@ -18,17 +20,17 @@ import com.anytypeio.anytype.core_utils.ext.hideKeyboard
import com.anytypeio.anytype.core_utils.ext.invisible
import com.anytypeio.anytype.core_utils.ext.parsePath
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.databinding.FragmentCreateAccountBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.auth.account.CreateAccountViewModel
import com.anytypeio.anytype.presentation.auth.account.CreateAccountViewModelFactory
import com.anytypeio.anytype.ui.base.NavigationFragment
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_create_account.*
import timber.log.Timber
import javax.inject.Inject
class CreateAccountFragment : NavigationFragment(R.layout.fragment_create_account) {
class CreateAccountFragment : NavigationFragment<FragmentCreateAccountBinding>(R.layout.fragment_create_account) {
@Inject
lateinit var factory: CreateAccountViewModelFactory
@ -37,14 +39,14 @@ class CreateAccountFragment : NavigationFragment(R.layout.fragment_create_accoun
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
createProfileButton.setOnClickListener {
binding.createProfileButton.setOnClickListener {
vm.onCreateProfileClicked(
input = nameInputField.text.toString(),
input = binding.nameInputField.text.toString(),
invitationCode = getCode()
)
}
profileIconPlaceholder.setOnClickListener { proceedWithImagePick() }
backButton.setOnClickListener { vm.onBackButtonClicked() }
binding.profileIconPlaceholder.setOnClickListener { proceedWithImagePick() }
binding.backButton.setOnClickListener { vm.onBackButtonClicked() }
setupNavigation()
vm.error.observe(viewLifecycleOwner, Observer(this::showError))
}
@ -78,7 +80,7 @@ class CreateAccountFragment : NavigationFragment(R.layout.fragment_create_accoun
if (resultCode == RESULT_OK && requestCode == SELECT_IMAGE_CODE) {
data?.data?.let { uri ->
profileIcon.apply {
binding.profileIcon.apply {
visible()
Glide
.with(this)
@ -87,7 +89,7 @@ class CreateAccountFragment : NavigationFragment(R.layout.fragment_create_accoun
.into(this)
}
profileIconPlaceholder.invisible()
binding.profileIconPlaceholder.invisible()
vm.onAvatarSet(uri.parsePath(requireContext()))
}
@ -147,6 +149,13 @@ class CreateAccountFragment : NavigationFragment(R.layout.fragment_create_accoun
componentManager().createAccountComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentCreateAccountBinding = FragmentCreateAccountBinding.inflate(
inflater, container, false
)
companion object {
const val ARGS_CODE = "args.code"
const val EMPTY_CODE = ""

View file

@ -4,11 +4,11 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.R
import com.anytypeio.anytype.databinding.ItemChooseProfileAddBinding
import com.anytypeio.anytype.databinding.ItemChooseProfileProfileBinding
import com.anytypeio.anytype.presentation.auth.model.SelectAccountView
import com.anytypeio.anytype.presentation.auth.model.SelectAccountView.Companion.ADD_NEW_PROFILE
import com.anytypeio.anytype.presentation.auth.model.SelectAccountView.Companion.PROFILE
import kotlinx.android.synthetic.main.item_choose_profile_profile.view.*
class SelectAccountAdapter(
private val views: MutableList<SelectAccountView>,
@ -23,12 +23,12 @@ class SelectAccountAdapter(
return when (viewType) {
PROFILE -> {
ViewHolder.ProfileHolder(
view = inflater.inflate(R.layout.item_choose_profile_profile, parent, false)
ItemChooseProfileProfileBinding.inflate(inflater, parent, false)
)
}
ADD_NEW_PROFILE -> {
ViewHolder.AddNewProfileViewHolder(
view = inflater.inflate(R.layout.item_choose_profile_add, parent, false)
ItemChooseProfileAddBinding.inflate(inflater, parent, false)
)
}
else -> throw IllegalStateException("Unknown view type: $viewType")
@ -65,10 +65,10 @@ class SelectAccountAdapter(
sealed class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
class ProfileHolder(view: View) : ViewHolder(view) {
class ProfileHolder(val binding: ItemChooseProfileProfileBinding) : ViewHolder(binding.root) {
private val name = itemView.name
private val avatar = itemView.avatar
private val name = binding.name
private val avatar = binding.avatar
fun bind(
model: SelectAccountView.AccountView,
@ -85,7 +85,7 @@ class SelectAccountAdapter(
}
}
class AddNewProfileViewHolder(view: View) : ViewHolder(view) {
class AddNewProfileViewHolder(val binding: ItemChooseProfileAddBinding) : ViewHolder(binding.root) {
fun bind(
onAddNewProfileClicked: () -> Unit

View file

@ -1,21 +1,23 @@
package com.anytypeio.anytype.ui.auth.account
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.layout.SpacingItemDecoration
import com.anytypeio.anytype.core_utils.ext.dimen
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.databinding.FragmentSelectAccountBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.auth.account.SelectAccountViewModel
import com.anytypeio.anytype.presentation.auth.account.SelectAccountViewModelFactory
import com.anytypeio.anytype.ui.base.NavigationFragment
import kotlinx.android.synthetic.main.fragment_select_account.*
import javax.inject.Inject
class SelectAccountFragment : NavigationFragment(R.layout.fragment_select_account) {
class SelectAccountFragment : NavigationFragment<FragmentSelectAccountBinding>(R.layout.fragment_select_account) {
@Inject
lateinit var factory: SelectAccountViewModelFactory
@ -32,7 +34,7 @@ class SelectAccountFragment : NavigationFragment(R.layout.fragment_select_accoun
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
profileRecycler.apply {
binding.profileRecycler.apply {
layoutManager = LinearLayoutManager(requireContext())
addItemDecoration(
SpacingItemDecoration(
@ -58,4 +60,11 @@ class SelectAccountFragment : NavigationFragment(R.layout.fragment_select_accoun
override fun releaseDependencies() {
componentManager().selectAccountComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentSelectAccountBinding = FragmentSelectAccountBinding.inflate(
inflater, container, false
)
}

View file

@ -1,7 +1,9 @@
package com.anytypeio.anytype.ui.auth.account
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import androidx.activity.OnBackPressedCallback
import androidx.activity.addCallback
@ -11,15 +13,15 @@ import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ext.gone
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.databinding.FragmentSetupNewAccountBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.auth.account.SetupNewAccountViewModel
import com.anytypeio.anytype.presentation.auth.account.SetupNewAccountViewModelFactory
import com.anytypeio.anytype.presentation.auth.account.SetupNewAccountViewState
import com.anytypeio.anytype.ui.base.NavigationFragment
import kotlinx.android.synthetic.main.fragment_setup_new_account.*
import javax.inject.Inject
class SetupNewAccountFragment : NavigationFragment(R.layout.fragment_setup_new_account),
class SetupNewAccountFragment : NavigationFragment<FragmentSetupNewAccountBinding>(R.layout.fragment_setup_new_account),
Observer<SetupNewAccountViewState> {
@Inject
@ -43,25 +45,25 @@ class SetupNewAccountFragment : NavigationFragment(R.layout.fragment_setup_new_a
override fun onChanged(state: SetupNewAccountViewState) {
when (state) {
is SetupNewAccountViewState.Loading -> {
tvError.gone()
binding.tvError.gone()
disableBackNavigation()
icon.startAnimation(animation)
binding.icon.startAnimation(animation)
}
is SetupNewAccountViewState.Success -> {
tvError.gone()
binding.tvError.gone()
enableBackNavigation()
animation.cancel()
}
is SetupNewAccountViewState.Error -> {
enableBackNavigation()
animation.cancel()
tvError.text = state.message
tvError.visible()
binding.tvError.text = state.message
binding.tvError.visible()
}
is SetupNewAccountViewState.InvalidCodeError -> {
enableBackNavigation()
animation.cancel()
tvError.gone()
binding.tvError.gone()
requireActivity().toast(state.message)
}
}
@ -82,4 +84,11 @@ class SetupNewAccountFragment : NavigationFragment(R.layout.fragment_setup_new_a
override fun releaseDependencies() {
componentManager().setupNewAccountComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentSetupNewAccountBinding = FragmentSetupNewAccountBinding.inflate(
inflater, container, false
)
}

View file

@ -1,7 +1,9 @@
package com.anytypeio.anytype.ui.auth.account
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AlphaAnimation
import android.view.animation.AnimationUtils
import androidx.fragment.app.viewModels
@ -13,17 +15,16 @@ import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ext.gone
import com.anytypeio.anytype.core_utils.ext.invisible
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.databinding.FragmentSetupSelectedAccountBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.auth.account.SetupSelectedAccountViewModel
import com.anytypeio.anytype.presentation.auth.account.SetupSelectedAccountViewModelFactory
import com.anytypeio.anytype.ui.auth.Keys
import com.anytypeio.anytype.ui.base.NavigationFragment
import kotlinx.android.synthetic.main.fragment_setup_selected_account.*
import kotlinx.coroutines.launch
import javax.inject.Inject
open class SetupSelectedAccountFragment :
NavigationFragment(R.layout.fragment_setup_selected_account) {
open class SetupSelectedAccountFragment : NavigationFragment<FragmentSetupSelectedAccountBinding>(R.layout.fragment_setup_selected_account) {
@Inject
lateinit var factory: SetupSelectedAccountViewModelFactory
@ -41,11 +42,11 @@ open class SetupSelectedAccountFragment :
}
private val errorObserver = Observer<String> {
tvError.visible()
tvError.text = it
binding.tvError.visible()
binding.tvError.text = it
rotationAnimation.cancel()
blinkingAnimation.cancel()
tvMigrationInProgress.gone()
binding.tvMigrationInProgress.gone()
}
private val vm : SetupSelectedAccountViewModel by viewModels { factory }
@ -57,7 +58,7 @@ open class SetupSelectedAccountFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
icon.startAnimation(rotationAnimation)
binding.icon.startAnimation(rotationAnimation)
subscribe()
}
@ -68,11 +69,11 @@ open class SetupSelectedAccountFragment :
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
vm.isMigrationInProgress.collect { isInProgress ->
if (isInProgress) {
tvMigrationInProgress.visible()
tvMigrationInProgress.startAnimation(blinkingAnimation)
binding.tvMigrationInProgress.visible()
binding.tvMigrationInProgress.startAnimation(blinkingAnimation)
}
else {
tvMigrationInProgress.invisible()
binding.tvMigrationInProgress.invisible()
}
}
}
@ -87,6 +88,13 @@ open class SetupSelectedAccountFragment :
componentManager().setupSelectedAccountComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentSetupSelectedAccountBinding = FragmentSetupSelectedAccountBinding.inflate(
inflater, container, false
)
companion object {
const val BLINKING_ANIMATION_DURATION = 1000L
}

View file

@ -1,15 +1,17 @@
package com.anytypeio.anytype.ui.auth.pin
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.R
import com.anytypeio.anytype.databinding.FragmentChoosePinCodeBinding
import com.anytypeio.anytype.presentation.auth.pin.ChoosePinCodeViewModel
import com.anytypeio.anytype.presentation.auth.pin.ChoosePinCodeViewModelFactory
import kotlinx.android.synthetic.main.fragment_choose_pin_code.*
class ChoosePinCodeFragment : PinCodeFragment(R.layout.fragment_choose_pin_code) {
class ChoosePinCodeFragment : PinCodeFragment<FragmentChoosePinCodeBinding>(R.layout.fragment_choose_pin_code) {
//@Inject
lateinit var factory: ChoosePinCodeViewModelFactory
@ -30,13 +32,13 @@ class ChoosePinCodeFragment : PinCodeFragment(R.layout.fragment_choose_pin_code)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupRecyclers()
doItLaterButton.setOnClickListener {
binding.doItLaterButton.setOnClickListener {
//vm.onDoItLaterClicked()
}
}
override fun provideDotRecycler(): RecyclerView = dotRecycler
override fun provideNumPadRecycler(): RecyclerView = numPadRecycler
override fun provideDotRecycler(): RecyclerView = binding.dotRecycler
override fun provideNumPadRecycler(): RecyclerView = binding.numPadRecycler
override fun provideNumPadAdapter(): NumPadAdapter = numPadAdapter
override fun onActivityCreated(savedInstanceState: Bundle?) {
@ -49,11 +51,13 @@ class ChoosePinCodeFragment : PinCodeFragment(R.layout.fragment_choose_pin_code)
//vm.observeNavigation().subscribe { navigation(it) }.disposedBy(subscriptions)
}
override fun injectDependencies() {
override fun injectDependencies() {}
override fun releaseDependencies() {}
}
override fun releaseDependencies() {
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentChoosePinCodeBinding = FragmentChoosePinCodeBinding.inflate(
inflater, container, false
)
}

View file

@ -2,19 +2,18 @@ package com.anytypeio.anytype.feature_login.ui.login.presentation.ui.pin
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.R
import com.anytypeio.anytype.databinding.FragmentConfirmPinCodeBinding
import com.anytypeio.anytype.presentation.auth.pin.ConfirmPinCodeViewModel
import com.anytypeio.anytype.presentation.auth.pin.ConfirmPinCodeViewModelFactory
import com.anytypeio.anytype.ui.auth.pin.NumPadAdapter
import com.anytypeio.anytype.ui.auth.pin.PinCodeFragment
import kotlinx.android.synthetic.main.fragment_confirm_pin_code.*
import javax.inject.Inject
class ConfirmPinCodeFragment : PinCodeFragment(R.layout.fragment_confirm_pin_code) {
class ConfirmPinCodeFragment : PinCodeFragment<FragmentConfirmPinCodeBinding>(R.layout.fragment_confirm_pin_code) {
@Inject
lateinit var factory: ConfirmPinCodeViewModelFactory
@ -32,16 +31,10 @@ class ConfirmPinCodeFragment : PinCodeFragment(R.layout.fragment_confirm_pin_cod
)
}
override fun provideDotRecycler(): RecyclerView = dotRecycler
override fun provideNumPadRecycler(): RecyclerView = numPadRecycler
override fun provideDotRecycler(): RecyclerView = binding.dotRecycler
override fun provideNumPadRecycler(): RecyclerView = binding.numPadRecycler
override fun provideNumPadAdapter(): NumPadAdapter = numPadAdapter
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_confirm_pin_code, container, false)
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setupPinCode()
@ -64,4 +57,11 @@ class ConfirmPinCodeFragment : PinCodeFragment(R.layout.fragment_confirm_pin_cod
override fun releaseDependencies() {
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentConfirmPinCodeBinding = FragmentConfirmPinCodeBinding.inflate(
inflater, container, false
)
}

View file

@ -1,11 +1,9 @@
package com.anytypeio.anytype.ui.auth.pin
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.R
import kotlinx.android.synthetic.main.item_dot.view.*
import com.anytypeio.anytype.databinding.ItemDotBinding
class DotAdapter(
val dots: MutableList<DotView> = initialData().toMutableList()
@ -13,8 +11,7 @@ class DotAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val view = inflater.inflate(R.layout.item_dot, parent, false)
return ViewHolder(view)
return ViewHolder(ItemDotBinding.inflate(inflater, parent, false))
}
override fun getItemCount(): Int = dots.size
@ -23,9 +20,9 @@ class DotAdapter(
holder.bind(model = dots[position])
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
class ViewHolder(val bindind: ItemDotBinding) : RecyclerView.ViewHolder(bindind.root) {
private val dot = itemView.dot
private val dot = bindind.dot
fun bind(model: DotView) {
dot.isSelected = model.active

View file

@ -10,12 +10,12 @@ import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.layout.SpacingItemDecoration
import com.anytypeio.anytype.core_utils.ext.dimen
import com.anytypeio.anytype.core_utils.ui.BaseFragment
import com.anytypeio.anytype.databinding.FragmentEnterPinCodeBinding
import com.anytypeio.anytype.presentation.auth.pin.EnterPinCodeViewModel
import com.anytypeio.anytype.presentation.auth.pin.EnterPinCodeViewModelFactory
import kotlinx.android.synthetic.main.fragment_enter_pin_code.*
import javax.inject.Inject
class EnterPinCodeFragment : BaseFragment(R.layout.fragment_enter_pin_code) {
class EnterPinCodeFragment : BaseFragment<FragmentEnterPinCodeBinding>(R.layout.fragment_enter_pin_code) {
@Inject
lateinit var factory: EnterPinCodeViewModelFactory
@ -57,7 +57,7 @@ class EnterPinCodeFragment : BaseFragment(R.layout.fragment_enter_pin_code) {
super.onViewCreated(view, savedInstanceState)
setupNumPad()
dotRecycler.apply {
binding.dotRecycler.apply {
layoutManager = GridLayoutManager(
requireContext(), 1, GridLayoutManager.HORIZONTAL, false
)
@ -74,11 +74,13 @@ class EnterPinCodeFragment : BaseFragment(R.layout.fragment_enter_pin_code) {
//
}
override fun injectDependencies() {
override fun injectDependencies() {}
override fun releaseDependencies() {}
}
override fun releaseDependencies() {
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentEnterPinCodeBinding = FragmentEnterPinCodeBinding.inflate(
inflater, container, false
)
}

View file

@ -4,13 +4,13 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.R
import com.anytypeio.anytype.databinding.ItemNumPadEmptyBinding
import com.anytypeio.anytype.databinding.ItemNumPadNumberBinding
import com.anytypeio.anytype.databinding.ItemNumPadRemoveBinding
import com.anytypeio.anytype.presentation.auth.pin.NumPadView
import com.anytypeio.anytype.presentation.auth.pin.NumPadView.Companion.EMPTY
import com.anytypeio.anytype.presentation.auth.pin.NumPadView.Companion.NUMBER
import com.anytypeio.anytype.presentation.auth.pin.NumPadView.Companion.REMOVE
import kotlinx.android.synthetic.main.item_num_pad_number.view.*
import kotlinx.android.synthetic.main.item_num_pad_remove.view.*
class NumPadAdapter(
private val views: List<NumPadView> = initialData(),
@ -23,16 +23,13 @@ class NumPadAdapter(
return when (viewType) {
NUMBER -> ViewHolder.NumberViewHolder(
view = inflater
.inflate(R.layout.item_num_pad_number, parent, false)
ItemNumPadNumberBinding.inflate(inflater, parent, false)
)
REMOVE -> ViewHolder.RemoveViewHolder(
view = inflater
.inflate(R.layout.item_num_pad_remove, parent, false)
ItemNumPadRemoveBinding.inflate(inflater, parent, false)
)
EMPTY -> ViewHolder.EmptyViewHolder(
view = inflater
.inflate(R.layout.item_num_pad_empty, parent, false)
ItemNumPadEmptyBinding.inflate(inflater, parent, false)
)
else -> throw IllegalStateException("Unexpected view type: $viewType")
}
@ -55,14 +52,17 @@ class NumPadAdapter(
onRemoveClicked = onRemoveClicked
)
}
is ViewHolder.EmptyViewHolder -> {
// Do nothing.
}
}
}
sealed class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
class NumberViewHolder(view: View) : ViewHolder(view) {
class NumberViewHolder(val binding: ItemNumPadNumberBinding) : ViewHolder(binding.root) {
private val number = itemView.number
private val number = binding.number
fun bind(
view: NumPadView.NumberView,
@ -74,13 +74,13 @@ class NumPadAdapter(
}
class RemoveViewHolder(view: View) : ViewHolder(view) {
class RemoveViewHolder(val binding: ItemNumPadRemoveBinding) : ViewHolder(binding.root) {
fun bind(onRemoveClicked: () -> Unit) {
itemView.remove.setOnClickListener { onRemoveClicked() }
binding.remove.setOnClickListener { onRemoveClicked() }
}
}
class EmptyViewHolder(view: View) : ViewHolder(view)
class EmptyViewHolder(val binding: ItemNumPadEmptyBinding) : ViewHolder(binding.root)
}
companion object {

View file

@ -3,15 +3,16 @@ package com.anytypeio.anytype.ui.auth.pin
import androidx.annotation.LayoutRes
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.layout.SpacingItemDecoration
import com.anytypeio.anytype.core_utils.ext.dimen
import com.anytypeio.anytype.core_utils.ui.BaseFragment
import com.anytypeio.anytype.presentation.auth.pin.PinCodeState
abstract class PinCodeFragment(
abstract class PinCodeFragment<T : ViewBinding>(
@LayoutRes private val layout: Int
) : BaseFragment(layout) {
) : BaseFragment<T>(layout) {
private val dotAdapter by lazy { DotAdapter() }

View file

@ -2,15 +2,16 @@ package com.anytypeio.anytype.ui.base
import androidx.annotation.LayoutRes
import androidx.lifecycle.Observer
import androidx.viewbinding.ViewBinding
import com.anytypeio.anytype.core_utils.common.EventWrapper
import com.anytypeio.anytype.core_utils.ui.BaseFragment
import com.anytypeio.anytype.presentation.navigation.AppNavigation
import com.anytypeio.anytype.presentation.navigation.AppNavigation.Command
import timber.log.Timber
abstract class NavigationFragment(
abstract class NavigationFragment<BINDING : ViewBinding>(
@LayoutRes private val layout: Int
) : BaseFragment(layout) {
) : BaseFragment<BINDING>(layout) {
val navObserver = Observer<EventWrapper<Command>> { event ->
event.getContentIfNotHandled()?.let { navigate(it) }

View file

@ -2,10 +2,11 @@ package com.anytypeio.anytype.ui.base
import androidx.annotation.LayoutRes
import androidx.lifecycle.Observer
import androidx.viewbinding.ViewBinding
abstract class ViewStateFragment<VS>(
abstract class ViewStateFragment<VS, BINDING : ViewBinding>(
@LayoutRes private val layout: Int
) : NavigationFragment(layout), Observer<VS> {
) : NavigationFragment<BINDING>(layout), Observer<VS> {
override fun onChanged(state: VS) {
render(state)
}

View file

@ -5,32 +5,25 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import kotlinx.android.synthetic.main.fragment_clear_cache.*
import com.anytypeio.anytype.databinding.FragmentClearCacheBinding
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
class ClearCacheAlertFragment : BaseBottomSheetFragment() {
class ClearCacheAlertFragment : BaseBottomSheetFragment<FragmentClearCacheBinding>() {
var onClearAccepted: () -> Unit = {}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_clear_cache, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnCancel
binding.btnCancel
.clicks()
.onEach { dismiss() }
.launchIn(lifecycleScope)
btnClear
binding.btnClear
.clicks()
.onEach {
onClearAccepted()
@ -42,6 +35,12 @@ class ClearCacheAlertFragment : BaseBottomSheetFragment() {
override fun injectDependencies() {}
override fun releaseDependencies() {}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentClearCacheBinding = FragmentClearCacheBinding.inflate(
inflater, container, false
)
companion object {
fun new(): ClearCacheAlertFragment = ClearCacheAlertFragment()
}

View file

@ -15,13 +15,12 @@ import com.anytypeio.anytype.core_utils.ext.invisible
import com.anytypeio.anytype.core_utils.ext.shift
import com.anytypeio.anytype.core_utils.ext.typeOf
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.databinding.ItemDashboardCardDefaultBinding
import com.anytypeio.anytype.databinding.ItemDesktopArchiveBinding
import com.anytypeio.anytype.databinding.ItemDesktopSetWithoutIconBinding
import com.anytypeio.anytype.presentation.dashboard.DashboardView
import com.anytypeio.anytype.presentation.objects.ObjectIcon
import com.facebook.shimmer.ShimmerFrameLayout
import kotlinx.android.synthetic.main.item_dashboard_card_default.view.*
import kotlinx.android.synthetic.main.item_dashboard_card_default.view.shimmer
import kotlinx.android.synthetic.main.item_desktop_archive.view.*
import kotlinx.android.synthetic.main.item_desktop_set_without_icon.view.*
import timber.log.Timber
class DashboardAdapter(
@ -48,7 +47,7 @@ class DashboardAdapter(
return when (viewType) {
VIEW_TYPE_DOCUMENT -> {
ViewHolder.DocumentHolder(
inflater.inflate(R.layout.item_dashboard_card_default, parent, false)
ItemDashboardCardDefaultBinding.inflate(inflater, parent, false)
).apply {
itemView.setOnClickListener {
val pos = bindingAdapterPosition
@ -89,7 +88,7 @@ class DashboardAdapter(
}
VIEW_TYPE_ARCHIVE -> {
ViewHolder.ArchiveHolder(
inflater.inflate(R.layout.item_desktop_archive, parent, false)
ItemDesktopArchiveBinding.inflate(inflater, parent, false)
).apply {
itemView.setOnClickListener {
val pos = bindingAdapterPosition
@ -104,7 +103,7 @@ class DashboardAdapter(
}
VIEW_TYPE_SET -> {
ViewHolder.ObjectSetHolder(
inflater.inflate(R.layout.item_dashboard_card_default, parent, false)
ItemDashboardCardDefaultBinding.inflate(inflater, parent, false)
).apply {
itemView.setOnClickListener {
val pos = bindingAdapterPosition
@ -115,12 +114,12 @@ class DashboardAdapter(
}
}
}
itemView.typeTitle.setText(R.string.set)
binding.typeTitle.setText(R.string.set)
}
}
VIEW_TYPE_SET_WITHOUT_ICON -> {
ViewHolder.ObjectSetWithoutIconHolder(
inflater.inflate(R.layout.item_desktop_set_without_icon, parent, false)
ItemDesktopSetWithoutIconBinding.inflate(inflater, parent, false)
).apply {
itemView.setOnClickListener {
val pos = bindingAdapterPosition
@ -131,7 +130,7 @@ class DashboardAdapter(
}
}
}
itemView.tvSetTypeName.setText(R.string.set)
binding.tvSetTypeName.setText(R.string.set)
}
}
VIEW_TYPE_DOCUMENT_NOTE -> {
@ -355,13 +354,13 @@ class DashboardAdapter(
abstract fun bindSelection(isSelected: Boolean)
class ArchiveHolder(itemView: View) : ViewHolder(itemView) {
class ArchiveHolder(val binding: ItemDesktopArchiveBinding) : ViewHolder(binding.root) {
private val selection = itemView.findViewById<ImageView>(R.id.ivSelection)
fun bindTitle(title: String) {
if (title.isNotEmpty()) {
itemView.archiveTitle.text = title
binding.archiveTitle.text = title
}
}
@ -370,11 +369,11 @@ class DashboardAdapter(
}
}
class DocumentHolder(itemView: View) : ViewHolder(itemView) {
class DocumentHolder(val binding: ItemDashboardCardDefaultBinding) : ViewHolder(binding.root) {
private val tvTitle = itemView.title
private val tvSubtitle = itemView.typeTitle
private val shimmer = itemView.shimmer
private val tvTitle = binding.title
private val tvSubtitle = binding.typeTitle
private val shimmer = binding.shimmer
private val selection = itemView.findViewById<ImageView>(R.id.ivSelection)
fun bindTitle(title: String?) {
@ -389,7 +388,7 @@ class DashboardAdapter(
}
fun bindIcon(icon: ObjectIcon) {
itemView.iconWidget.bind(icon)
binding.iconWidget.bind(icon)
}
fun bindLoading(isLoading: Boolean) {
@ -538,10 +537,10 @@ class DashboardAdapter(
}
}
class ObjectSetHolder(itemView: View) : ViewHolder(itemView) {
class ObjectSetHolder(val binding: ItemDashboardCardDefaultBinding) : ViewHolder(binding.root) {
private val tvTitle = itemView.title
private val shimmer = itemView.shimmer
private val tvTitle = binding.title
private val shimmer = binding.shimmer
private val selection = itemView.findViewById<ImageView>(R.id.ivSelection)
fun bindLoading(isLoading: Boolean) {
@ -564,7 +563,7 @@ class DashboardAdapter(
}
fun bindIcon(icon: ObjectIcon) {
itemView.iconWidget.bind(icon)
binding.iconWidget.bind(icon)
}
override fun bindSelection(isSelected: Boolean) {
@ -572,7 +571,7 @@ class DashboardAdapter(
}
}
class ObjectSetWithoutIconHolder(itemView: View) : ViewHolder(itemView) {
class ObjectSetWithoutIconHolder(val binding: ItemDesktopSetWithoutIconBinding) : ViewHolder(binding.root) {
private val tvTitle = itemView.findViewById<TextView>(R.id.tvSetTitle)
private val shimmer = itemView.findViewById<ShimmerFrameLayout>(R.id.shimmer)

View file

@ -1,7 +1,9 @@
package com.anytypeio.anytype.ui.dashboard
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintSet
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
@ -16,6 +18,7 @@ import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.ViewState
import com.anytypeio.anytype.databinding.FragmentDashboardBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.presentation.dashboard.DashboardView
@ -27,14 +30,13 @@ import com.anytypeio.anytype.ui.base.ViewStateFragment
import com.anytypeio.anytype.ui.editor.EditorFragment
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import kotlinx.android.synthetic.main.fragment_dashboard.*
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
class DashboardFragment : ViewStateFragment<State>(R.layout.fragment_dashboard) {
class DashboardFragment : ViewStateFragment<State, FragmentDashboardBinding>(R.layout.fragment_dashboard) {
private val isMnemonicReminderDialogNeeded: Boolean?
get() = argOrNull(
@ -167,7 +169,7 @@ class DashboardFragment : ViewStateFragment<State>(R.layout.fragment_dashboard)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setup()
dashboardRoot.progress = motionProgress
binding.dashboardRoot.progress = motionProgress
with(vm) {
state.observe(viewLifecycleOwner, this@DashboardFragment)
navigation.observe(viewLifecycleOwner, navObserver)
@ -192,7 +194,7 @@ class DashboardFragment : ViewStateFragment<State>(R.layout.fragment_dashboard)
vm.archived.collect { dashboardArchiveAdapter.update(it) }
}
launch {
vm.count.collect { tvSelectedCount.text = "$it object selected" }
vm.count.collect { binding.tvSelectedCount.text = "$it object selected" }
}
launch {
vm.alerts.collect { alert ->
@ -209,10 +211,10 @@ class DashboardFragment : ViewStateFragment<State>(R.layout.fragment_dashboard)
vm.mode.collect { mode ->
when (mode) {
HomeDashboardViewModel.Mode.DEFAULT -> {
selectionTopToolbar.invisible()
tabsLayout.visible()
binding.selectionTopToolbar.invisible()
binding.tabsLayout.visible()
val set = ConstraintSet().apply {
clone(dashboardRoot)
clone(binding.dashboardRoot)
clear(R.id.selectionBottomToolbar, ConstraintSet.BOTTOM)
connect(
R.id.selectionBottomToolbar,
@ -226,16 +228,16 @@ class DashboardFragment : ViewStateFragment<State>(R.layout.fragment_dashboard)
duration = 100
}
TransitionManager.beginDelayedTransition(
dashboardRoot,
binding.dashboardRoot,
transitionSet
)
set.applyTo(dashboardRoot)
set.applyTo(binding.dashboardRoot)
}
HomeDashboardViewModel.Mode.SELECTION -> {
tabsLayout.invisible()
selectionTopToolbar.visible()
binding.tabsLayout.invisible()
binding.selectionTopToolbar.visible()
val set = ConstraintSet().apply {
clone(dashboardRoot)
clone(binding.dashboardRoot)
clear(R.id.selectionBottomToolbar, ConstraintSet.TOP)
connect(
R.id.selectionBottomToolbar,
@ -249,10 +251,10 @@ class DashboardFragment : ViewStateFragment<State>(R.layout.fragment_dashboard)
duration = 100
}
TransitionManager.beginDelayedTransition(
dashboardRoot,
binding.dashboardRoot,
transitionSet
)
set.applyTo(dashboardRoot)
set.applyTo(binding.dashboardRoot)
}
}
}
@ -290,9 +292,9 @@ class DashboardFragment : ViewStateFragment<State>(R.layout.fragment_dashboard)
launch {
vm.isDeletionInProgress.collect { isDeletionInProgress ->
if (isDeletionInProgress) {
objectRemovalProgressBar.visible()
binding.objectRemovalProgressBar.visible()
} else {
objectRemovalProgressBar.gone()
binding.objectRemovalProgressBar.gone()
}
}
}
@ -312,17 +314,17 @@ class DashboardFragment : ViewStateFragment<State>(R.layout.fragment_dashboard)
when (profile) {
is ViewState.Success -> {
val obj = profile.data
avatarContainer.bind(
binding.avatarContainer.bind(
name = obj.name.orEmpty(),
color = context?.getColor(R.color.dashboard_default_avatar_circle_color)
)
obj.iconImage?.let { avatar ->
avatarContainer.icon(builder.image(avatar))
binding.avatarContainer.icon(builder.image(avatar))
}
if (obj.name.isNullOrEmpty()) {
tvGreeting.text = getText(R.string.greet_user)
binding.tvGreeting.text = getText(R.string.greet_user)
} else {
tvGreeting.text = getString(R.string.greet, obj.name)
binding.tvGreeting.text = getString(R.string.greet, obj.name)
}
}
else -> {
@ -333,8 +335,8 @@ class DashboardFragment : ViewStateFragment<State>(R.layout.fragment_dashboard)
override fun onPause() {
super.onPause()
motionProgress = dashboardRoot.progress
tabsLayout.removeOnTabSelectedListener(onTabSelectedListener)
motionProgress = binding.dashboardRoot.progress
binding.tabsLayout.removeOnTabSelectedListener(onTabSelectedListener)
}
override fun onStop() {
@ -346,7 +348,7 @@ class DashboardFragment : ViewStateFragment<State>(R.layout.fragment_dashboard)
override fun onResume() {
super.onResume()
vm.onResume()
tabsLayout.apply {
binding.tabsLayout.apply {
addOnTabSelectedListener(onTabSelectedListener)
}
if (isMnemonicReminderDialogNeeded == true) {
@ -382,63 +384,70 @@ class DashboardFragment : ViewStateFragment<State>(R.layout.fragment_dashboard)
private fun setup() {
tabsLayout.apply {
binding.tabsLayout.apply {
tabMode = TabLayout.MODE_SCROLLABLE
}
dashboardPager.apply {
binding.dashboardPager.apply {
adapter = dashboardPagerAdapter
TabLayoutMediator(tabsLayout, dashboardPager) { tab, position ->
TabLayoutMediator(binding.tabsLayout, binding.dashboardPager) { tab, position ->
tab.text = dashboardPagerAdapter.getTitle(position)
}.attach()
}
btnAddDoc
binding.btnAddDoc
.clicks()
.onEach { vm.onAddNewDocumentClicked() }
.launchIn(lifecycleScope)
btnSearch
binding.btnSearch
.clicks()
.onEach { vm.onPageSearchClicked() }
.launchIn(lifecycleScope)
btnMarketplace
binding.btnMarketplace
.clicks()
.onEach { toast(getString(R.string.coming_soon)) }
.launchIn(lifecycleScope)
ivSettings
binding.ivSettings
.clicks()
.onEach { vm.onSettingsClicked() }
.launchIn(lifecycleScope)
avatarContainer
binding.avatarContainer
.clicks()
.onEach { vm.onAvatarClicked() }
.launchIn(lifecycleScope)
tvCancel
binding.tvCancel
.clicks()
.onEach { vm.onCancelSelectionClicked() }
.launchIn(lifecycleScope)
tvSelectAll
binding.tvSelectAll
.clicks()
.onEach { vm.onSelectAllClicked() }
.launchIn(lifecycleScope)
tvPutBack
binding.tvPutBack
.clicks()
.onEach { vm.onPutBackClicked() }
.launchIn(lifecycleScope)
tvDelete
binding.tvDelete
.clicks()
.onEach { vm.onDeleteObjectsClicked() }
.launchIn(lifecycleScope)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentDashboardBinding = FragmentDashboardBinding.inflate(
inflater, container, false
)
override fun injectDependencies() {
componentManager().dashboardComponent.get().inject(this)
}

View file

@ -10,18 +10,20 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ui.ViewState
import com.anytypeio.anytype.databinding.DialogDashboardKeychainPhraseBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.keychain.KeychainPhraseViewModel
import com.anytypeio.anytype.presentation.keychain.KeychainPhraseViewModelFactory
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.dialog_keychain_phrase.*
import javax.inject.Inject
class DashboardMnemonicReminderDialog : BottomSheetDialogFragment(), Observer<ViewState<String>> {
private var _binding: DialogDashboardKeychainPhraseBinding? = null
private val binding: DialogDashboardKeychainPhraseBinding get() = _binding!!
private val vm : KeychainPhraseViewModel by viewModels { factory }
@Inject
@ -41,30 +43,38 @@ class DashboardMnemonicReminderDialog : BottomSheetDialogFragment(), Observer<Vi
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.dialog_dashboard_keychain_phrase, container, false)
): View? {
_binding = DialogDashboardKeychainPhraseBinding.inflate(inflater, container, false)
return _binding?.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setBlur()
keychain.setOnClickListener {
if (keychain.layerType == View.LAYER_TYPE_SOFTWARE) {
binding.keychain.setOnClickListener {
if (binding.keychain.layerType == View.LAYER_TYPE_SOFTWARE) {
removeBlur()
}
}
btnCopy.setOnClickListener {
binding.btnCopy.setOnClickListener {
copyMnemonicToClipboard()
}
root.setOnClickListener {
binding.root.setOnClickListener {
setBlur()
}
vm.state.observe(viewLifecycleOwner, this)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
private fun copyMnemonicToClipboard() {
try {
val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText(MNEMONIC_LABEL, keychain.text.toString())
val clip = ClipData.newPlainText(MNEMONIC_LABEL, binding.keychain.text.toString())
clipboard.setPrimaryClip(clip)
toast("Mnemonic copied to clipboard.")
} catch (e: Exception) {
@ -75,7 +85,7 @@ class DashboardMnemonicReminderDialog : BottomSheetDialogFragment(), Observer<Vi
override fun onChanged(state: ViewState<String>) {
when (state) {
is ViewState.Success -> {
keychain.text = state.data
binding.keychain.text = state.data
}
is ViewState.Error -> {
// TODO
@ -83,17 +93,20 @@ class DashboardMnemonicReminderDialog : BottomSheetDialogFragment(), Observer<Vi
is ViewState.Loading -> {
// TODO
}
is ViewState.Init -> {
}
}
}
private fun setBlur() = with(keychain) {
private fun setBlur() = with(binding.keychain) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null)
val radius = textSize / 3
val filter = BlurMaskFilter(radius, BlurMaskFilter.Blur.NORMAL)
paint.maskFilter = filter
}
private fun removeBlur() = with(keychain) {
private fun removeBlur() = with(binding.keychain) {
setLayerType(View.LAYER_TYPE_NONE, null)
paint.maskFilter = null
isFocusable = true

View file

@ -10,11 +10,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ext.dimen
import com.anytypeio.anytype.core_utils.ui.DashboardSpacingItemDecoration
import kotlinx.android.synthetic.main.item_dashboard_page.view.*
import kotlinx.android.synthetic.main.item_dashboard_page_archived.view.*
import kotlinx.android.synthetic.main.item_dashboard_recent.view.*
import kotlinx.android.synthetic.main.item_dashboard_sets.view.*
import kotlinx.android.synthetic.main.item_dashboard_shared.view.*
import com.anytypeio.anytype.databinding.*
class DashboardPager(
private var items: List<TabItem>,
@ -24,9 +20,9 @@ class DashboardPager(
private val archiveAdapter: DashboardAdapter,
private val sharedAdapter: DashboardAdapter,
private val dndBehavior: DashboardDragAndDropBehavior
): RecyclerView.Adapter<DashboardPager.ViewHolder>() {
) : RecyclerView.Adapter<DashboardPager.ViewHolder>() {
fun getTitle(position: Int) : String = items[position].title
fun getTitle(position: Int): String = items[position].title
fun setItems(items: List<TabItem>) {
this.items = items
@ -36,11 +32,18 @@ class DashboardPager(
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ViewHolder = when(viewType) {
): ViewHolder = when (viewType) {
R.layout.item_dashboard_page -> {
ViewHolder.Default(parent).apply {
itemView.rvDashboard.apply {
val spacing = itemView.context.dimen(R.dimen.default_dashboard_item_spacing).toInt()
ViewHolder.Default(
ItemDashboardPageBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
).apply {
binding.rvDashboard.apply {
val spacing =
itemView.context.dimen(R.dimen.default_dashboard_item_spacing).toInt()
layoutManager = GridLayoutManager(context, COLUMN_COUNT)
overScrollMode = OVER_SCROLL_NEVER
addItemDecoration(DashboardSpacingItemDecoration(spacing))
@ -51,9 +54,16 @@ class DashboardPager(
}
}
R.layout.item_dashboard_recent -> {
ViewHolder.Recent(parent).apply {
itemView.rvDashboardRecent.apply {
val spacing = itemView.context.dimen(R.dimen.default_dashboard_item_spacing).toInt()
ViewHolder.Recent(
ItemDashboardRecentBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
).apply {
binding.rvDashboardRecent.apply {
val spacing =
itemView.context.dimen(R.dimen.default_dashboard_item_spacing).toInt()
layoutManager = GridLayoutManager(context, COLUMN_COUNT)
overScrollMode = OVER_SCROLL_NEVER
addItemDecoration(DashboardSpacingItemDecoration(spacing))
@ -63,9 +73,16 @@ class DashboardPager(
}
}
R.layout.item_dashboard_sets -> {
ViewHolder.Sets(parent).apply {
itemView.rvDashboardSets.apply {
val spacing = itemView.context.dimen(R.dimen.default_dashboard_item_spacing).toInt()
ViewHolder.Sets(
ItemDashboardSetsBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
).apply {
binding.rvDashboardSets.apply {
val spacing =
itemView.context.dimen(R.dimen.default_dashboard_item_spacing).toInt()
layoutManager = GridLayoutManager(context, COLUMN_COUNT)
overScrollMode = OVER_SCROLL_NEVER
addItemDecoration(DashboardSpacingItemDecoration(spacing))
@ -75,9 +92,16 @@ class DashboardPager(
}
}
R.layout.item_dashboard_page_archived -> {
ViewHolder.Archived(parent).apply {
itemView.rvDashboardArchived.apply {
val spacing = itemView.context.dimen(R.dimen.default_dashboard_item_spacing).toInt()
ViewHolder.Archived(
ItemDashboardPageArchivedBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
).apply {
binding.rvDashboardArchived.apply {
val spacing =
itemView.context.dimen(R.dimen.default_dashboard_item_spacing).toInt()
layoutManager = GridLayoutManager(context, COLUMN_COUNT)
overScrollMode = OVER_SCROLL_NEVER
addItemDecoration(DashboardSpacingItemDecoration(spacing))
@ -87,9 +111,16 @@ class DashboardPager(
}
}
R.layout.item_dashboard_shared -> {
ViewHolder.Shared(parent).apply {
itemView.rvDashboardShared.apply {
val spacing = itemView.context.dimen(R.dimen.default_dashboard_item_spacing).toInt()
ViewHolder.Shared(
ItemDashboardSharedBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
).apply {
binding.rvDashboardShared.apply {
val spacing =
itemView.context.dimen(R.dimen.default_dashboard_item_spacing).toInt()
layoutManager = GridLayoutManager(context, COLUMN_COUNT)
overScrollMode = OVER_SCROLL_NEVER
addItemDecoration(DashboardSpacingItemDecoration(spacing))
@ -98,16 +129,16 @@ class DashboardPager(
}
}
}
else -> throw IllegalStateException("Unexpected view type: $viewType")
else -> throw IllegalStateException("Unexpected view type: $viewType")
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {}
override fun getItemCount(): Int = items.size
override fun getItemViewType(position: Int) = when(items[position].type) {
override fun getItemViewType(position: Int) = when (items[position].type) {
TYPE_FAVOURITES -> R.layout.item_dashboard_page
TYPE_RECENT -> R.layout.item_dashboard_recent
TYPE_SETS-> R.layout.item_dashboard_sets
TYPE_SETS -> R.layout.item_dashboard_sets
TYPE_BIN -> R.layout.item_dashboard_page_archived
TYPE_SHARED -> R.layout.item_dashboard_shared
else -> throw IllegalStateException("Unexpected item: ${items[position]}")
@ -122,41 +153,11 @@ class DashboardPager(
const val TYPE_SHARED = 5
}
sealed class ViewHolder(view : View) : RecyclerView.ViewHolder(view) {
class Default(parent: ViewGroup) : ViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_dashboard_page,
parent,
false
)
)
class Recent(parent: ViewGroup) : ViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_dashboard_recent,
parent,
false
)
)
class Sets(parent: ViewGroup) : ViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_dashboard_sets,
parent,
false
)
)
class Archived(parent: ViewGroup) : ViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_dashboard_page_archived,
parent,
false
)
)
class Shared(parent: ViewGroup) : ViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_dashboard_shared,
parent,
false
)
)
sealed class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
class Default(val binding: ItemDashboardPageBinding) : ViewHolder(binding.root)
class Recent(val binding: ItemDashboardRecentBinding) : ViewHolder(binding.root)
class Sets(val binding: ItemDashboardSetsBinding) : ViewHolder(binding.root)
class Archived(val binding: ItemDashboardPageArchivedBinding) : ViewHolder(binding.root)
class Shared(val binding: ItemDashboardSharedBinding) : ViewHolder(binding.root)
}
}

View file

@ -10,39 +10,33 @@ import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_utils.ext.arg
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import kotlinx.android.synthetic.main.fragment_delete_alert.*
import com.anytypeio.anytype.databinding.FragmentDeleteAlertBinding
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
class DeleteAlertFragment : BaseBottomSheetFragment() {
class DeleteAlertFragment : BaseBottomSheetFragment<FragmentDeleteAlertBinding>() {
private val count get() = arg<Int>(COUNT_KEY)
var onDeletionAccepted: () -> Unit = {}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_delete_alert, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (count > 1) {
tvTitle.text = getString(R.string.are_you_sure_delete_n_objects, count)
tvSubtitle.setText(R.string.delete_irrevocably)
binding.tvTitle.text = getString(R.string.are_you_sure_delete_n_objects, count)
binding.tvSubtitle.setText(R.string.delete_irrevocably)
} else {
tvTitle.setText(R.string.are_you_sure_delete_one_object)
tvSubtitle.setText(R.string.delete_irrevocably_one_object)
binding.tvTitle.setText(R.string.are_you_sure_delete_one_object)
binding.tvSubtitle.setText(R.string.delete_irrevocably_one_object)
}
btnCancel
binding.btnCancel
.clicks()
.onEach { dismiss() }
.launchIn(lifecycleScope)
btnDelete
binding.btnDelete
.clicks()
.onEach {
onDeletionAccepted()
@ -54,6 +48,13 @@ class DeleteAlertFragment : BaseBottomSheetFragment() {
override fun injectDependencies() {}
override fun releaseDependencies() {}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentDeleteAlertBinding = FragmentDeleteAlertBinding.inflate(
inflater, container, false
)
companion object {
const val COUNT_KEY = "arg.delete-alert-dialog.count"
fun new(count: Int) : DeleteAlertFragment = DeleteAlertFragment().apply {

View file

@ -7,20 +7,14 @@ import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import kotlinx.android.synthetic.main.alert_mnemonic_reminder.*
import com.anytypeio.anytype.databinding.AlertMnemonicReminderBinding
class MnemonicReminderDialog : BaseBottomSheetFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) : View? = inflater.inflate(R.layout.alert_mnemonic_reminder, container, false)
class MnemonicReminderDialog : BaseBottomSheetFragment<AlertMnemonicReminderBinding>() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnClose.setOnClickListener { dismiss() }
btnSettings.setOnClickListener {
binding.btnClose.setOnClickListener { dismiss() }
binding.btnSettings.setOnClickListener {
dismiss()
findNavController().navigate(R.id.keychainDialog)
}
@ -28,4 +22,11 @@ class MnemonicReminderDialog : BaseBottomSheetFragment() {
override fun injectDependencies() {}
override fun releaseDependencies() {}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): AlertMnemonicReminderBinding = AlertMnemonicReminderBinding.inflate(
inflater, container, false
)
}

View file

@ -14,12 +14,12 @@ import com.anytypeio.anytype.core_ui.features.wallpaper.WallpaperSelectAdapter
import com.anytypeio.anytype.core_utils.ext.dimen
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentWallpaperSelectBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.wallpaper.WallpaperSelectViewModel
import kotlinx.android.synthetic.main.fragment_wallpaper_select.*
import javax.inject.Inject
class WallpaperSelectFragment : BaseBottomSheetFragment() {
class WallpaperSelectFragment : BaseBottomSheetFragment<FragmentWallpaperSelectBinding>() {
@Inject
lateinit var factory: WallpaperSelectViewModel.Factory
@ -30,16 +30,10 @@ class WallpaperSelectFragment : BaseBottomSheetFragment() {
WallpaperSelectAdapter { vm.onWallpaperSelected(it) }
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_wallpaper_select, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val spacing = requireContext().dimen(R.dimen.cover_gallery_item_spacing).toInt()
wallpaperRecycler.apply {
binding.wallpaperRecycler.apply {
adapter = wallpaperSelectAdapter
layoutManager = GridLayoutManager(context, 3).apply {
spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
@ -86,4 +80,11 @@ class WallpaperSelectFragment : BaseBottomSheetFragment() {
override fun releaseDependencies() {
componentManager().wallpaperSelectComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentWallpaperSelectBinding = FragmentWallpaperSelectBinding.inflate(
inflater, container, false
)
}

View file

@ -1,5 +1,7 @@
package com.anytypeio.anytype.ui.editor
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
@ -10,11 +12,12 @@ import com.anytypeio.anytype.core_utils.ext.arg
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ui.BaseFragment
import com.anytypeio.anytype.databinding.FragmentCreateObjectBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.objects.CreateObjectViewModel
import javax.inject.Inject
class CreateObjectFragment : BaseFragment(R.layout.fragment_create_object) {
class CreateObjectFragment : BaseFragment<FragmentCreateObjectBinding>(R.layout.fragment_create_object) {
@Inject
lateinit var factory: CreateObjectViewModel.Factory
@ -52,6 +55,13 @@ class CreateObjectFragment : BaseFragment(R.layout.fragment_create_object) {
componentManager().createObjectComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentCreateObjectBinding = FragmentCreateObjectBinding.inflate(
inflater, container, false
)
companion object {
const val TYPE_KEY = "arg.ui.editor.create.type"
}

View file

@ -26,17 +26,17 @@ import com.anytypeio.anytype.core_ui.features.editor.modal.DocCoverGalleryAdapte
import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentDocCoverGalleryBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.editor.cover.SelectCoverObjectSetViewModel
import com.anytypeio.anytype.presentation.editor.cover.SelectCoverObjectViewModel
import com.anytypeio.anytype.presentation.editor.cover.SelectCoverViewModel
import kotlinx.android.synthetic.main.fragment_doc_cover_gallery.*
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import javax.inject.Inject
abstract class SelectCoverGalleryFragment : BaseBottomSheetFragment() {
abstract class SelectCoverGalleryFragment : BaseBottomSheetFragment<FragmentDocCoverGalleryBinding>() {
abstract val ctx: String
abstract val vm: SelectCoverViewModel
@ -64,28 +64,20 @@ abstract class SelectCoverGalleryFragment : BaseBottomSheetFragment() {
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_doc_cover_gallery, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnRemove.clicks()
binding.btnRemove.clicks()
.onEach { vm.onRemoveCover(ctx) }
.launchIn(lifecycleScope)
btnUpload.clicks()
binding.btnUpload.clicks()
.onEach { proceedWithImagePick() }
.launchIn(lifecycleScope)
val spacing = requireContext().dimen(R.dimen.cover_gallery_item_spacing).toInt() / 2
docCoverGalleryRecycler.apply {
binding.docCoverGalleryRecycler.apply {
adapter = docCoverGalleryAdapter
layoutManager = GridLayoutManager(context, 2).apply {
spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
@ -146,6 +138,13 @@ abstract class SelectCoverGalleryFragment : BaseBottomSheetFragment() {
Manifest.permission.WRITE_EXTERNAL_STORAGE
).let { result -> result == PackageManager.PERMISSION_GRANTED }
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentDocCoverGalleryBinding = FragmentDocCoverGalleryBinding.inflate(
inflater, container, false
)
companion object {
private const val SELECT_IMAGE_CODE = 1
private const val REQUEST_PERMISSION_CODE = 2

View file

@ -1,14 +1,16 @@
package com.anytypeio.anytype.ui.editor.gallery
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ui.BaseFragment
import com.anytypeio.anytype.databinding.FragmentFullScreenPictureBinding
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_full_screen_picture.*
class FullScreenPictureFragment : BaseFragment(R.layout.fragment_full_screen_picture) {
class FullScreenPictureFragment : BaseFragment<FragmentFullScreenPictureBinding>(R.layout.fragment_full_screen_picture) {
private val url: String
get() = requireArguments().getString(ARG_URL_KEY) ?: throw IllegalStateException()
@ -28,10 +30,17 @@ class FullScreenPictureFragment : BaseFragment(R.layout.fragment_full_screen_pic
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Glide.with(picture).load(url).into(picture)
picture.setOnClickListener { parentFragmentManager.popBackStack() }
Glide.with(binding.picture).load(url).into(binding.picture)
binding.picture.setOnClickListener { parentFragmentManager.popBackStack() }
}
override fun injectDependencies() {}
override fun releaseDependencies() {}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentFullScreenPictureBinding = FragmentFullScreenPictureBinding.inflate(
inflater, container, false
)
}

View file

@ -8,24 +8,22 @@ import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_ui.common.FooterAdapter
import com.anytypeio.anytype.core_ui.features.objects.ObjectLayoutAdapter
import com.anytypeio.anytype.core_utils.ext.argString
import com.anytypeio.anytype.core_utils.ext.drawable
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentObjectLayoutBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.editor.layout.ObjectLayoutViewModel
import com.anytypeio.anytype.presentation.objects.ObjectLayoutView
import kotlinx.android.synthetic.main.fragment_object_layout.*
import javax.inject.Inject
class ObjectLayoutFragment : BaseBottomSheetFragment() {
class ObjectLayoutFragment : BaseBottomSheetFragment<FragmentObjectLayoutBinding>() {
private val ctx: String get() = argString(CONTEXT_ID_KEY)
@ -41,15 +39,9 @@ class ObjectLayoutFragment : BaseBottomSheetFragment() {
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_object_layout, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(rvLayouts) {
with(binding.rvLayouts) {
layoutManager = LinearLayoutManager(context)
adapter = adapterLayouts
addItemDecoration(
@ -85,12 +77,20 @@ class ObjectLayoutFragment : BaseBottomSheetFragment() {
componentManager().objectLayoutComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentObjectLayoutBinding = FragmentObjectLayoutBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: Id) : ObjectLayoutFragment = ObjectLayoutFragment().apply {
fun new(ctx: Id): ObjectLayoutFragment = ObjectLayoutFragment().apply {
arguments = bundleOf(
CONTEXT_ID_KEY to ctx
)
}
const val CONTEXT_ID_KEY = "arg.object-layout.ctx"
}
}

View file

@ -1,130 +0,0 @@
package com.anytypeio.anytype.ui.editor.modals
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.core.os.bundleOf
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.ObjectType
import com.anytypeio.anytype.core_ui.features.editor.modal.AddBlockOrTurnIntoAdapter
import com.anytypeio.anytype.core_utils.ext.argString
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ext.withParent
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.editor.editor.model.UiBlock
import com.anytypeio.anytype.presentation.editor.picker.AddBlockView
import com.anytypeio.anytype.presentation.editor.picker.DocumentAddBlockViewModel
import com.anytypeio.anytype.presentation.editor.picker.DocumentAddBlockViewModelFactory
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.android.synthetic.main.fragment_add_block.*
import javax.inject.Inject
@Deprecated("To be deleted")
class AddBlockFragment : BaseBottomSheetFragment() {
companion object {
fun newInstance(ctx: Id): AddBlockFragment = AddBlockFragment().apply {
arguments = bundleOf(CONTEXT_ID to ctx)
}
const val CONTEXT_ID = "arg.add-new-block.ctx"
}
@Inject
lateinit var factory: DocumentAddBlockViewModelFactory
private val vm by viewModels<DocumentAddBlockViewModel> { factory }
private val ctx get() = argString(CONTEXT_ID)
private val addBlockOrTurnIntoAdapter = AddBlockOrTurnIntoAdapter(
views = mutableListOf(),
onUiBlockClicked = { type -> dispatchAndExit(type) },
onObjectClicked = { vm.onObjectTypeClicked(it) }
)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_add_block, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupAdapter()
close.setOnClickListener { dismiss() }
skipCollapsedState()
}
override fun onStart() {
with(lifecycleScope) {
jobs += subscribe(vm.views) { observeViews(it) }
jobs += subscribe(vm.commands) { observeCommands(it) }
}
super.onStart()
vm.onStart()
}
private fun observeViews(views: List<AddBlockView>) {
addBlockOrTurnIntoAdapter.update(views)
}
private fun observeCommands(commands: DocumentAddBlockViewModel.Commands) {
when (commands) {
is DocumentAddBlockViewModel.Commands.NotifyOnObjectTypeClicked -> {
withParent<AddBlockActionReceiver> {
onAddObjectClicked(
commands.url,
commands.layout
)
}
dismiss()
}
}
}
private fun skipCollapsedState() {
dialog?.setOnShowListener { dg ->
val bottomSheet = (dg as? BottomSheetDialog)?.findViewById<FrameLayout>(
com.google.android.material.R.id.design_bottom_sheet
)
bottomSheet?.let {
val behavior = BottomSheetBehavior.from(it)
behavior.skipCollapsed = true
}
}
}
private fun setupAdapter() {
recycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = addBlockOrTurnIntoAdapter
setHasFixedSize(true)
}
}
private fun dispatchAndExit(block: UiBlock) {
(parentFragment as? AddBlockActionReceiver)?.onAddBlockClicked(block)
dismiss()
}
override fun injectDependencies() {
componentManager().documentAddNewBlockComponent.get(ctx).inject(this)
}
override fun releaseDependencies() {
componentManager().documentAddNewBlockComponent.release(ctx)
}
interface AddBlockActionReceiver {
fun onAddBlockClicked(block: UiBlock)
fun onAddObjectClicked(url: String, layout: ObjectType.Layout)
}
}

View file

@ -9,23 +9,23 @@ import androidx.core.os.bundleOf
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.extensions.color
import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_utils.ext.hideKeyboard
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.DialogCreateBookmarkBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.editor.bookmark.CreateBookmarkViewModel
import com.anytypeio.anytype.presentation.editor.bookmark.CreateBookmarkViewModel.ViewState
import com.anytypeio.anytype.ui.editor.OnFragmentInteractionListener
import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.android.synthetic.main.dialog_create_bookmark.*
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import javax.inject.Inject
class CreateBookmarkFragment : BaseBottomSheetFragment(), Observer<ViewState> {
class CreateBookmarkFragment : BaseBottomSheetFragment<DialogCreateBookmarkBinding>(),
Observer<ViewState> {
private val target: String
get() = requireArguments()
@ -49,12 +49,6 @@ class CreateBookmarkFragment : BaseBottomSheetFragment(), Observer<ViewState> {
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.dialog_create_bookmark, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
dialog?.setOnShowListener { dg ->
@ -63,15 +57,17 @@ class CreateBookmarkFragment : BaseBottomSheetFragment(), Observer<ViewState> {
)
bottomSheet?.setBackgroundColor(requireContext().color(android.R.color.transparent))
}
cancelBookmarkButton.setOnClickListener {
binding.cancelBookmarkButton.setOnClickListener {
it.hideKeyboard()
this.dismiss()
}
createBookmarkButton
binding.createBookmarkButton
.clicks()
.onEach {
vm.onCreateBookmarkClicked(
url = urlInput.text.toString()
url = binding.urlInput.text.toString()
)
}
.launchIn(lifecycleScope)
@ -104,4 +100,11 @@ class CreateBookmarkFragment : BaseBottomSheetFragment(), Observer<ViewState> {
override fun releaseDependencies() {
componentManager().createBookmarkSubComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): DialogCreateBookmarkBinding = DialogCreateBookmarkBinding.inflate(
inflater, container, false
)
}

View file

@ -15,9 +15,9 @@ import androidx.core.widget.doAfterTextChanged
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentPageIconPickerBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.library_page_icon_picker_widget.ui.DocumentEmojiIconPickerAdapter
import com.anytypeio.anytype.presentation.editor.picker.EmojiPickerView.Companion.HOLDER_EMOJI_CATEGORY_HEADER
@ -26,11 +26,10 @@ import com.anytypeio.anytype.presentation.editor.picker.ObjectIconPickerBaseView
import com.anytypeio.anytype.presentation.editor.picker.ObjectIconPickerBaseViewModel.ViewState
import com.anytypeio.anytype.presentation.editor.picker.ObjectIconPickerViewModel
import com.anytypeio.anytype.presentation.editor.picker.ObjectIconPickerViewModelFactory
import kotlinx.android.synthetic.main.fragment_page_icon_picker.*
import timber.log.Timber
import javax.inject.Inject
abstract class ObjectIconPickerBaseFragment : BaseBottomSheetFragment() {
abstract class ObjectIconPickerBaseFragment : BaseBottomSheetFragment<FragmentPageIconPickerBinding>() {
protected val target: String
get() = requireArguments()
@ -57,28 +56,24 @@ abstract class ObjectIconPickerBaseFragment : BaseBottomSheetFragment() {
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_page_icon_picker, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupRecycler()
clearSearchText.setOnClickListener {
filterInputField.setText(EMPTY_FILTER_TEXT)
clearSearchText.invisible()
with(binding) {
clearSearchText.setOnClickListener {
filterInputField.setText(EMPTY_FILTER_TEXT)
clearSearchText.invisible()
}
filterInputField.doAfterTextChanged { vm.onQueryChanged(it.toString()) }
btnRemoveIcon.setOnClickListener { vm.onRemoveClicked(context) }
tvTabRandom.setOnClickListener { vm.onRandomEmoji(ctx = context, target = target) }
tvTabUpload.setOnClickListener { proceedWithImagePick() }
}
filterInputField.doAfterTextChanged { vm.onQueryChanged(it.toString()) }
btnRemoveIcon.setOnClickListener { vm.onRemoveClicked(context) }
tvTabRandom.setOnClickListener { vm.onRandomEmoji(ctx = context, target = target) }
tvTabUpload.setOnClickListener { proceedWithImagePick() }
expand()
}
private fun setupRecycler() {
pickerRecycler.apply {
binding.pickerRecycler.apply {
setItemViewCacheSize(EMOJI_RECYCLER_ITEM_VIEW_CACHE_SIZE)
setHasFixedSize(true)
layoutManager = GridLayoutManager(context, PAGE_ICON_PICKER_DEFAULT_SPAN_COUNT).apply {
@ -103,24 +98,26 @@ abstract class ObjectIconPickerBaseFragment : BaseBottomSheetFragment() {
}
private fun render(state: ViewState) {
when (state) {
is ViewState.Success -> {
if (filterInputField.text.isNotEmpty())
clearSearchText.visible()
else
with(binding) {
when (state) {
is ViewState.Success -> {
if (filterInputField.text.isNotEmpty())
clearSearchText.visible()
else
clearSearchText.invisible()
emojiPickerAdapter.update(state.views)
progressBar.invisible()
}
is ViewState.Loading -> {
clearSearchText.invisible()
emojiPickerAdapter.update(state.views)
progressBar.invisible()
progressBar.visible()
}
is ViewState.Init -> {
clearSearchText.visible()
progressBar.invisible()
}
is ViewState.Exit -> dismiss()
}
is ViewState.Loading -> {
clearSearchText.invisible()
progressBar.visible()
}
is ViewState.Init -> {
clearSearchText.visible()
progressBar.invisible()
}
is ViewState.Exit -> dismiss()
}
}
@ -180,6 +177,13 @@ abstract class ObjectIconPickerBaseFragment : BaseBottomSheetFragment() {
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentPageIconPickerBinding = FragmentPageIconPickerBinding.inflate(
inflater, container, false
)
companion object {
private const val EMPTY_FILTER_TEXT = ""
private const val PAGE_ICON_PICKER_DEFAULT_SPAN_COUNT = 6

View file

@ -7,17 +7,17 @@ import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.core.os.bundleOf
import androidx.recyclerview.widget.LinearLayoutManager
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_ui.extensions.color
import com.anytypeio.anytype.core_ui.features.editor.modal.SelectProgrammingLanguageAdapter
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentSelectProgrammingLanguageBinding
import com.anytypeio.anytype.library_syntax_highlighter.obtainLanguages
import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.android.synthetic.main.fragment_select_programming_language.*
import timber.log.Timber
class SelectProgrammingLanguageFragment : BaseBottomSheetFragment() {
class SelectProgrammingLanguageFragment :
BaseBottomSheetFragment<FragmentSelectProgrammingLanguageBinding>() {
private val selectLangAdapter by lazy {
SelectProgrammingLanguageAdapter(
@ -35,12 +35,6 @@ class SelectProgrammingLanguageFragment : BaseBottomSheetFragment() {
.getString(ARG_TARGET)
?: throw IllegalStateException(MISSING_TARGET_ERROR)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_select_programming_language, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Timber.d("onViewCreated")
@ -50,7 +44,7 @@ class SelectProgrammingLanguageFragment : BaseBottomSheetFragment() {
)
bottomSheet?.setBackgroundColor(requireContext().color(android.R.color.transparent))
}
recycler.apply {
binding.recycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = selectLangAdapter
}
@ -59,6 +53,13 @@ class SelectProgrammingLanguageFragment : BaseBottomSheetFragment() {
override fun injectDependencies() {}
override fun releaseDependencies() {}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentSelectProgrammingLanguageBinding = FragmentSelectProgrammingLanguageBinding.inflate(
inflater, container, false
)
companion object {
fun new(target: Id) = SelectProgrammingLanguageFragment().apply {
arguments = bundleOf(ARG_TARGET to target)

View file

@ -17,6 +17,7 @@ import com.anytypeio.anytype.core_utils.ext.invisible
import com.anytypeio.anytype.core_utils.ext.multilineIme
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentLinkBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.editor.LinkAddViewModel
import com.anytypeio.anytype.presentation.editor.LinkAddViewModelFactory
@ -24,10 +25,9 @@ import com.anytypeio.anytype.presentation.editor.LinkViewState
import com.anytypeio.anytype.ui.editor.OnFragmentInteractionListener
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.android.synthetic.main.fragment_link.*
import javax.inject.Inject
class SetLinkFragment : BaseBottomSheetFragment() {
class SetLinkFragment : BaseBottomSheetFragment<FragmentLinkBinding>() {
companion object {
const val ARG_URL = "arg.link.url"
@ -58,12 +58,6 @@ class SetLinkFragment : BaseBottomSheetFragment() {
lateinit var factory: LinkAddViewModelFactory
private val vm by viewModels<LinkAddViewModel> { factory }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_link, container, false)
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
setModalToFullScreenState(dialog)
@ -97,24 +91,24 @@ class SetLinkFragment : BaseBottomSheetFragment() {
private fun render(state: LinkViewState) {
when (state) {
is LinkViewState.Init -> {
text.text = state.text
link.setText(state.url)
binding.text.text = state.text
binding.link.setText(state.url)
if (state.url.isNullOrBlank()) {
enableEditMode()
buttonLink.visible()
buttonUnlink.invisible()
binding.buttonLink.visible()
binding.buttonUnlink.invisible()
} else {
enableReadMode()
buttonLink.invisible()
buttonUnlink.visible()
binding.buttonLink.invisible()
binding.buttonUnlink.visible()
}
buttonCancel.setOnClickListener {
binding.buttonCancel.setOnClickListener {
vm.onCancelClicked()
}
buttonLink.setOnClickListener {
vm.onLinkButtonClicked(link.text.toString())
binding.buttonLink.setOnClickListener {
vm.onLinkButtonClicked(binding.link.text.toString())
}
buttonUnlink.setOnClickListener {
binding.buttonUnlink.setOnClickListener {
vm.onUnlinkButtonClicked()
}
}
@ -140,7 +134,7 @@ class SetLinkFragment : BaseBottomSheetFragment() {
}
private fun enableEditMode() {
with(link) {
with(binding.link) {
setTextColor(requireContext().color(R.color.black))
multilineIme(action = EditorInfo.IME_ACTION_DONE)
setTextIsSelectable(true)
@ -148,7 +142,7 @@ class SetLinkFragment : BaseBottomSheetFragment() {
}
private fun enableReadMode() {
with(link) {
with(binding.link) {
setTextColor(requireContext().color(R.color.hint_color))
inputType = InputType.TYPE_NULL
setRawInputType(InputType.TYPE_NULL)
@ -165,4 +159,11 @@ class SetLinkFragment : BaseBottomSheetFragment() {
override fun releaseDependencies() {
componentManager().linkAddComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentLinkBinding = FragmentLinkBinding.inflate(
inflater, container, false
)
}

View file

@ -12,12 +12,13 @@ import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_ui.features.editor.TurnIntoActionReceiver
import com.anytypeio.anytype.core_ui.features.editor.modal.AddBlockOrTurnIntoAdapter
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentTurnIntoBinding
import com.anytypeio.anytype.presentation.editor.editor.model.UiBlock
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.android.synthetic.main.fragment_add_block.*
class TurnIntoFragment : BaseBottomSheetFragment() {
@Deprecated("To be deleted")
class TurnIntoFragment : BaseBottomSheetFragment<FragmentTurnIntoBinding>() {
private val excludedCategories: List<UiBlock.Category>
get() {
@ -61,7 +62,7 @@ class TurnIntoFragment : BaseBottomSheetFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupAdapter()
close.setOnClickListener { dismiss() }
binding.close.setOnClickListener { dismiss() }
skipCollapsedState()
}
@ -78,7 +79,7 @@ class TurnIntoFragment : BaseBottomSheetFragment() {
}
private fun setupAdapter() {
recycler.apply {
binding.recycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = addBlockOrTurnIntoAdapter
setHasFixedSize(true)
@ -102,6 +103,13 @@ class TurnIntoFragment : BaseBottomSheetFragment() {
override fun injectDependencies() {}
override fun releaseDependencies() {}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentTurnIntoBinding = FragmentTurnIntoBinding.inflate(
inflater, container, false
)
companion object {
fun single(

View file

@ -19,6 +19,7 @@ import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ext.withParent
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentObjectMenuBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.objects.ObjectAction
import com.anytypeio.anytype.presentation.objects.ObjectMenuViewModel
@ -28,19 +29,18 @@ import com.anytypeio.anytype.ui.editor.cover.SelectCoverObjectSetFragment
import com.anytypeio.anytype.ui.editor.layout.ObjectLayoutFragment
import com.anytypeio.anytype.ui.editor.modals.ObjectIconPickerBaseFragment
import com.anytypeio.anytype.ui.relations.RelationListFragment
import kotlinx.android.synthetic.main.fragment_object_menu.*
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import javax.inject.Inject
abstract class ObjectMenuBaseFragment : BaseBottomSheetFragment() {
abstract class ObjectMenuBaseFragment : BaseBottomSheetFragment<FragmentObjectMenuBinding>() {
protected val ctx get() = arg<String>(CTX_KEY)
private val isProfile get() = arg<Boolean>(IS_PROFILE_KEY)
private val isArchived get() = arg<Boolean>(IS_ARCHIVED_KEY)
private val isFavorite get() = arg<Boolean>(IS_FAVORITE_KEY)
abstract val vm : ObjectMenuViewModelBase
abstract val vm: ObjectMenuViewModelBase
private val actionAdapter by lazy {
ObjectActionAdapter { action ->
@ -66,41 +66,35 @@ abstract class ObjectMenuBaseFragment : BaseBottomSheetFragment() {
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_object_menu, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
optionHistory
binding.optionHistory
.clicks()
.onEach { vm.onHistoryClicked() }
.launchIn(lifecycleScope)
optionLayout
binding.optionLayout
.clicks()
.onEach { vm.onLayoutClicked(ctx) }
.launchIn(lifecycleScope)
optionIcon
binding.optionIcon
.clicks()
.onEach { vm.onIconClicked(ctx) }
.launchIn(lifecycleScope)
optionRelations
binding.optionRelations
.clicks()
.onEach { vm.onRelationsClicked() }
.launchIn(lifecycleScope)
optionCover
binding.optionCover
.clicks()
.onEach { vm.onCoverClicked(ctx) }
.launchIn(lifecycleScope)
rvActions.apply {
binding.rvActions.apply {
layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
adapter = actionAdapter
addItemDecoration(
@ -184,6 +178,13 @@ abstract class ObjectMenuBaseFragment : BaseBottomSheetFragment() {
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentObjectMenuBinding = FragmentObjectMenuBinding.inflate(
inflater, container, false
)
companion object {
const val CTX_KEY = "arg.doc-menu-bottom-sheet.ctx"
const val IS_ARCHIVED_KEY = "arg.doc-menu-bottom-sheet.is-archived"

View file

@ -21,19 +21,18 @@ import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_ui.features.navigation.DefaultObjectViewAdapter
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentObjectSearchBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.linking.LinkToObjectViewModel
import com.anytypeio.anytype.presentation.linking.LinkToObjectViewModelFactory
import com.anytypeio.anytype.presentation.search.ObjectSearchView
import com.anytypeio.anytype.ui.search.ObjectSearchFragment
import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.android.synthetic.main.fragment_link_to_object.progressBar
import kotlinx.android.synthetic.main.fragment_object_search.*
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
class LinkToObjectFragment : BaseBottomSheetFragment() {
class LinkToObjectFragment : BaseBottomSheetFragment<FragmentObjectSearchBinding>() {
private val vm by viewModels<LinkToObjectViewModel> { factory }
@ -52,17 +51,11 @@ class LinkToObjectFragment : BaseBottomSheetFragment() {
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_object_search, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupFullHeight()
setTransparent()
BottomSheetBehavior.from(sheet).apply {
BottomSheetBehavior.from(binding.sheet).apply {
state = BottomSheetBehavior.STATE_EXPANDED
isHideable = true
skipCollapsed = true
@ -77,9 +70,9 @@ class LinkToObjectFragment : BaseBottomSheetFragment() {
}
)
}
vm.state.observe(viewLifecycleOwner, { observe(it) })
clearSearchText = searchView.findViewById(R.id.clearSearchText)
filterInputField = searchView.findViewById(R.id.filterInputField)
vm.state.observe(viewLifecycleOwner) { observe(it) }
clearSearchText = binding.searchView.root.findViewById(R.id.clearSearchText)
filterInputField = binding.searchView.root.findViewById(R.id.filterInputField)
filterInputField.setHint(R.string.search)
filterInputField.imeOptions = EditorInfo.IME_ACTION_DONE
filterInputField.setOnEditorActionListener { _, actionId, _ ->
@ -108,38 +101,49 @@ class LinkToObjectFragment : BaseBottomSheetFragment() {
private fun observe(state: ObjectSearchView) {
when (state) {
ObjectSearchView.Loading -> {
recyclerView.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
progressBar.visible()
with(binding) {
recyclerView.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
progressBar.visible()
}
}
is ObjectSearchView.Success -> {
progressBar.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
recyclerView.visible()
moveToAdapter.submitList(state.objects)
with(binding) {
progressBar.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
recyclerView.visible()
moveToAdapter.submitList(state.objects)
}
}
ObjectSearchView.EmptyPages -> {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = getString(R.string.search_empty_pages)
tvScreenStateSubMessage.invisible()
with(binding) {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = getString(R.string.search_empty_pages)
tvScreenStateSubMessage.invisible()
}
}
is ObjectSearchView.NoResults -> {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = getString(R.string.search_no_results, state.searchText)
tvScreenStateSubMessage.visible()
with(binding) {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text =
getString(R.string.search_no_results, state.searchText)
tvScreenStateSubMessage.visible()
}
}
is ObjectSearchView.Error -> {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = state.error
tvScreenStateSubMessage.invisible()
with(binding) {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = state.error
tvScreenStateSubMessage.invisible()
}
}
else -> Timber.d("Skipping state: $state")
}
@ -170,13 +174,13 @@ class LinkToObjectFragment : BaseBottomSheetFragment() {
}
private fun initialize() {
with(tvScreenTitle) {
with(binding.tvScreenTitle) {
text = getString(R.string.link_to)
visible()
}
recyclerView.invisible()
tvScreenStateMessage.invisible()
progressBar.invisible()
binding.recyclerView.invisible()
binding.tvScreenStateMessage.invisible()
binding.progressBar.invisible()
clearSearchText.setOnClickListener {
filterInputField.setText(ObjectSearchFragment.EMPTY_FILTER_TEXT)
clearSearchText.invisible()
@ -191,7 +195,7 @@ class LinkToObjectFragment : BaseBottomSheetFragment() {
clearSearchText.visible()
}
}
with(recyclerView) {
with(binding.recyclerView) {
layoutManager = LinearLayoutManager(requireContext())
adapter = moveToAdapter
addItemDecoration(
@ -203,14 +207,14 @@ class LinkToObjectFragment : BaseBottomSheetFragment() {
}
private fun setupFullHeight() {
val lp = (root.layoutParams as FrameLayout.LayoutParams)
val lp = (binding.root.layoutParams as FrameLayout.LayoutParams)
lp.height =
Resources.getSystem().displayMetrics.heightPixels - requireActivity().statusBarHeight
root.layoutParams = lp
binding.root.layoutParams = lp
}
private fun setTransparent() {
with(root) {
with(binding.root) {
background = null
(parent as? View)?.setBackgroundColor(Color.TRANSPARENT)
}
@ -224,6 +228,13 @@ class LinkToObjectFragment : BaseBottomSheetFragment() {
componentManager().linkToObjectComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentObjectSearchBinding = FragmentObjectSearchBinding.inflate(
inflater, container, false
)
companion object {
const val ARG_TARGET = "arg.link_to.target"
const val ARG_POSITION = "arg.link_to.position"

View file

@ -18,43 +18,37 @@ import com.anytypeio.anytype.core_ui.reactive.textChanges
import com.anytypeio.anytype.core_ui.widgets.toolbar.adapter.ObjectLinksAdapter
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentLinkToObjectOrWebBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.linking.LinkToObjectOrWebViewModel
import com.anytypeio.anytype.presentation.linking.LinkToObjectOrWebViewModelFactory
import com.anytypeio.anytype.ui.editor.OnFragmentInteractionListener
import com.anytypeio.anytype.ui.search.ObjectSearchFragment
import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.android.synthetic.main.fragment_link_to_object_or_web.*
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
class LinkToObjectOrWebPagesFragment() : BaseBottomSheetFragment() {
class LinkToObjectOrWebPagesFragment() : BaseBottomSheetFragment<FragmentLinkToObjectOrWebBinding>() {
private val vm by viewModels<LinkToObjectOrWebViewModel> { factory }
@Inject
lateinit var factory: LinkToObjectOrWebViewModelFactory
private val clearSearchText: View get() = searchView.findViewById(R.id.clearSearchText)
private val filterInputField: EditText get() = searchView.findViewById(R.id.filterInputField)
private val clearSearchText: View get() = binding.searchView.root.findViewById(R.id.clearSearchText)
private val filterInputField: EditText get() = binding.searchView.root.findViewById(R.id.filterInputField)
private val uri get() = arg<String>(LINK_TO_OBJ_OR_WEB_FILTER_ARG)
private val objectLinksAdapter by lazy {
ObjectLinksAdapter(onClicked = { vm.onClicked(it) })
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_link_to_object_or_web, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupFullHeight()
setTransparent()
BottomSheetBehavior.from(sheet).apply {
BottomSheetBehavior.from(binding.sheet).apply {
state = BottomSheetBehavior.STATE_EXPANDED
isHideable = true
skipCollapsed = true
@ -78,14 +72,14 @@ class LinkToObjectOrWebPagesFragment() : BaseBottomSheetFragment() {
true
}
}
recyclerView.invisible()
tvScreenStateMessage.invisible()
progressBar.invisible()
binding.recyclerView.invisible()
binding.tvScreenStateMessage.invisible()
binding.progressBar.invisible()
clearSearchText.setOnClickListener {
filterInputField.setText(ObjectSearchFragment.EMPTY_FILTER_TEXT)
clearSearchText.invisible()
}
with(recyclerView) {
with(binding.recyclerView) {
layoutManager = LinearLayoutManager(requireContext())
adapter = objectLinksAdapter
}
@ -137,10 +131,10 @@ class LinkToObjectOrWebPagesFragment() : BaseBottomSheetFragment() {
private fun state(state: LinkToObjectOrWebViewModel.ViewState) {
when (state) {
LinkToObjectOrWebViewModel.ViewState.Init -> {
recyclerView.invisible()
binding.recyclerView.invisible()
}
is LinkToObjectOrWebViewModel.ViewState.Success -> {
recyclerView.visible()
binding.recyclerView.visible()
objectLinksAdapter.submitList(state.items)
}
is LinkToObjectOrWebViewModel.ViewState.SetFilter -> {
@ -150,14 +144,14 @@ class LinkToObjectOrWebPagesFragment() : BaseBottomSheetFragment() {
}
private fun setupFullHeight() {
val lp = (root.layoutParams as FrameLayout.LayoutParams)
val lp = (binding.root.layoutParams as FrameLayout.LayoutParams)
val metrics = Resources.getSystem().displayMetrics
lp.height = metrics.heightPixels - requireActivity().statusBarHeight
root.layoutParams = lp
binding.root.layoutParams = lp
}
private fun setTransparent() {
with(root) {
with(binding.root) {
background = null
(parent as? View)?.setBackgroundColor(Color.TRANSPARENT)
}
@ -171,6 +165,13 @@ class LinkToObjectOrWebPagesFragment() : BaseBottomSheetFragment() {
componentManager().linkToObjectOrWebComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentLinkToObjectOrWebBinding = FragmentLinkToObjectOrWebBinding.inflate(
inflater, container, false
)
companion object {
const val LINK_TO_OBJ_OR_WEB_FILTER_ARG = "link-to-object-or-web.filter.arg"

View file

@ -13,6 +13,7 @@ import com.anytypeio.anytype.R
import com.anytypeio.anytype.app.DefaultAppActionManager
import com.anytypeio.anytype.core_models.Wallpaper
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.databinding.ActivityMainBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.navigation.Navigator
import com.anytypeio.anytype.presentation.editor.cover.CoverGradient
@ -21,11 +22,13 @@ import com.anytypeio.anytype.presentation.main.MainViewModelFactory
import com.anytypeio.anytype.presentation.navigation.AppNavigation
import com.anytypeio.anytype.presentation.wallpaper.WallpaperColor
import com.anytypeio.anytype.ui.editor.CreateObjectFragment
import kotlinx.android.synthetic.main.activity_main.*
import javax.inject.Inject
class MainActivity : AppCompatActivity(R.layout.activity_main), AppNavigation.Provider {
private lateinit var binding: ActivityMainBinding
private val vm by viewModels<MainViewModel> { factory }
private val navigator by lazy { Navigator() }
@ -38,6 +41,7 @@ class MainActivity : AppCompatActivity(R.layout.activity_main), AppNavigation.Pr
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
inject()
if (savedInstanceState != null) vm.onRestore()
with(lifecycleScope) {
@ -66,27 +70,27 @@ class MainActivity : AppCompatActivity(R.layout.activity_main), AppNavigation.Pr
when (wallpaper) {
is Wallpaper.Gradient -> {
when (wallpaper.code) {
CoverGradient.YELLOW -> fragment.setBackgroundResource(R.drawable.cover_gradient_yellow)
CoverGradient.RED -> fragment.setBackgroundResource(R.drawable.cover_gradient_red)
CoverGradient.BLUE -> fragment.setBackgroundResource(R.drawable.cover_gradient_blue)
CoverGradient.TEAL -> fragment.setBackgroundResource(R.drawable.cover_gradient_teal)
CoverGradient.PINK_ORANGE -> fragment.setBackgroundResource(R.drawable.wallpaper_gradient_1)
CoverGradient.BLUE_PINK -> fragment.setBackgroundResource(R.drawable.wallpaper_gradient_2)
CoverGradient.GREEN_ORANGE -> fragment.setBackgroundResource(R.drawable.wallpaper_gradient_3)
CoverGradient.SKY -> fragment.setBackgroundResource(R.drawable.wallpaper_gradient_4)
CoverGradient.YELLOW -> binding.fragment.setBackgroundResource(R.drawable.cover_gradient_yellow)
CoverGradient.RED -> binding.fragment.setBackgroundResource(R.drawable.cover_gradient_red)
CoverGradient.BLUE -> binding.fragment.setBackgroundResource(R.drawable.cover_gradient_blue)
CoverGradient.TEAL -> binding.fragment.setBackgroundResource(R.drawable.cover_gradient_teal)
CoverGradient.PINK_ORANGE -> binding.fragment.setBackgroundResource(R.drawable.wallpaper_gradient_1)
CoverGradient.BLUE_PINK -> binding.fragment.setBackgroundResource(R.drawable.wallpaper_gradient_2)
CoverGradient.GREEN_ORANGE -> binding.fragment.setBackgroundResource(R.drawable.wallpaper_gradient_3)
CoverGradient.SKY -> binding.fragment.setBackgroundResource(R.drawable.wallpaper_gradient_4)
}
}
is Wallpaper.Default -> {
fragment.setBackgroundResource(R.color.default_dashboard_background_color)
binding.fragment.setBackgroundResource(R.color.default_dashboard_background_color)
}
is Wallpaper.Color -> {
val color = WallpaperColor.values().find { it.code == wallpaper.code }
if (color != null) {
fragment.setBackgroundColor(Color.parseColor(color.hex))
binding.fragment.setBackgroundColor(Color.parseColor(color.hex))
}
}
is Wallpaper.Image -> {
fragment.setBackgroundResource(R.color.default_dashboard_background_color)
binding.fragment.setBackgroundResource(R.color.default_dashboard_background_color)
}
}
}

View file

@ -15,15 +15,13 @@ import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.HorizontalScrollView
import android.widget.PopupWindow
import android.widget.*
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.common.Span
import com.anytypeio.anytype.core_ui.menu.ContextMenuType
import com.anytypeio.anytype.core_utils.ext.invisible
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.ext.isSpanInRange
import kotlinx.android.synthetic.main.popup_context_menu.view.*
class ContextPopupWindow @JvmOverloads constructor(
type: ContextMenuType,
@ -106,37 +104,37 @@ class ContextPopupWindow @JvmOverloads constructor(
}
private fun init(view: View, ids: List<Int>, editable: Editable, textRange: IntRange) {
view.btnCopy.apply {
view.findViewById<View>(R.id.btnCopy).apply {
if (this.id in ids) {
visible()
view.divCopy.visible()
view.findViewById<View>(R.id.divCopy).visible()
}
setOnClickListener {
onContextMenuButtonClicked(ContextMenuButtonClick.Copy)
}
}
view.btnCut.apply {
view.findViewById<View>(R.id.btnCut).apply {
if (this.id in ids) {
visible()
view.divCut.visible()
view.findViewById<View>(R.id.divCut).visible()
}
setOnClickListener {
onContextMenuButtonClicked(ContextMenuButtonClick.Cut)
}
}
view.btnPaste.apply {
view.findViewById<View>(R.id.btnPaste).apply {
if (this.id in ids) {
visible()
view.divPaste.visible()
view.findViewById<View>(R.id.divPaste).visible()
}
setOnClickListener {
onContextMenuButtonClicked(ContextMenuButtonClick.Paste)
}
}
view.btnBold.apply {
view.findViewById<ImageView>(R.id.btnBold).apply {
if (this.id in ids) {
visible()
view.divBold.visible()
view.findViewById<View>(R.id.divBold).visible()
}
setOnClickListener {
onContextMenuButtonClicked(ContextMenuButtonClick.Bold)
@ -149,10 +147,10 @@ class ContextPopupWindow @JvmOverloads constructor(
imageTintList = tintColor
}
}
view.btnItalic.apply {
view.findViewById<ImageView>(R.id.btnItalic).apply {
if (this.id in ids) {
visible()
view.divItalic.visible()
view.findViewById<View>(R.id.divItalic).visible()
}
setOnClickListener {
onContextMenuButtonClicked(ContextMenuButtonClick.Italic)
@ -165,10 +163,10 @@ class ContextPopupWindow @JvmOverloads constructor(
imageTintList = tintColor
}
}
view.btnStroke.apply {
view.findViewById<ImageView>(R.id.btnStroke).apply {
if (this.id in ids) {
visible()
view.divStroke.visible()
view.findViewById<View>(R.id.divStroke).visible()
}
setOnClickListener {
onContextMenuButtonClicked(ContextMenuButtonClick.Stroke)
@ -181,10 +179,10 @@ class ContextPopupWindow @JvmOverloads constructor(
imageTintList = tintColor
}
}
view.btnCode.apply {
view.findViewById<ImageView>(R.id.btnCode).apply {
if (this.id in ids) {
visible()
view.divCode.visible()
view.findViewById<View>(R.id.divCode).visible()
}
setOnClickListener {
onContextMenuButtonClicked(ContextMenuButtonClick.Code)
@ -197,10 +195,10 @@ class ContextPopupWindow @JvmOverloads constructor(
imageTintList = tintColor
}
}
view.btnLink.apply {
view.findViewById<ImageView>(R.id.btnLink).apply {
if (this.id in ids) {
visible()
view.divLink.visible()
view.findViewById<View>(R.id.divLink).visible()
}
setOnClickListener {
onContextMenuButtonClicked(ContextMenuButtonClick.Link)
@ -213,10 +211,10 @@ class ContextPopupWindow @JvmOverloads constructor(
imageTintList = tintColor
}
}
view.btnColor.apply {
view.findViewById<TextView>(R.id.btnColor).apply {
if (this.id in ids) {
visible()
view.divColor.visible()
view.findViewById<View>(R.id.divColor).visible()
}
setOnClickListener {
onContextMenuButtonClicked(ContextMenuButtonClick.Color)
@ -229,7 +227,7 @@ class ContextPopupWindow @JvmOverloads constructor(
setTextColor(tintColor)
}
}
view.btnBackground.apply {
view.findViewById<TextView>(R.id.btnBackground).apply {
if (this.id in ids) {
visible()
}
@ -245,17 +243,19 @@ class ContextPopupWindow @JvmOverloads constructor(
}
}
val arrowRight = view.arrowRightContainer
val arrowRight = view.findViewById<FrameLayout>(R.id.arrowRightContainer)
arrowRight.setOnClickListener {
view.scrollContainer.fullScroll(HorizontalScrollView.FOCUS_RIGHT)
view.findViewById<HorizontalScrollView>(R.id.scrollContainer)
.fullScroll(HorizontalScrollView.FOCUS_RIGHT)
}
view.scrollContainer.setOnScrollChangeListener { _, scrollX, _, oldScrollX, _ ->
if (scrollX != oldScrollX) {
if (scrollX == 0) arrowRight.visible() else arrowRight.invisible()
} else {
arrowRight.visible()
view.findViewById<HorizontalScrollView>(R.id.scrollContainer)
.setOnScrollChangeListener { _, scrollX, _, oldScrollX, _ ->
if (scrollX != oldScrollX) {
if (scrollX == 0) arrowRight.visible() else arrowRight.invisible()
} else {
arrowRight.visible()
}
}
}
}
private fun createEnterAnimation(view: View): AnimatorSet? {
@ -289,7 +289,7 @@ class ContextPopupWindow @JvmOverloads constructor(
val availableHeightBelowContent = viewPortOnScreen.bottom - selectedContentBounds.bottom
val margin = popupMargin * 2
val toolbarHeightWithVerticalMargin = popupHeight + margin
val y = if (availableHeightAboveContent >= toolbarHeightWithVerticalMargin) {
// There is enough space at the top of the content.
selectedContentBounds.top - toolbarHeightWithVerticalMargin
@ -314,49 +314,49 @@ class ContextPopupWindow @JvmOverloads constructor(
* Updates buttons state, when markup changed in text
*/
fun updateMarkupButtons(textRange: IntRange, spanned: Spanned) {
contentView.btnBold.apply {
contentView.findViewById<ImageView>(R.id.btnBold).apply {
imageTintList = if (spanned.isSpanInRange(
textRange = textRange,
type = Span.Bold::class.java
)
) tintColor else null
}
contentView.btnItalic.apply {
contentView.findViewById<ImageView>(R.id.btnItalic).apply {
imageTintList = if (spanned.isSpanInRange(
textRange = textRange,
type = Span.Italic::class.java
)
) tintColor else null
}
contentView.btnStroke.apply {
contentView.findViewById<ImageView>(R.id.btnStroke).apply {
imageTintList = if (spanned.isSpanInRange(
textRange = textRange,
type = Span.Strikethrough::class.java
)
) tintColor else null
}
contentView.btnCode.apply {
contentView.findViewById<ImageView>(R.id.btnCode).apply {
imageTintList = if (spanned.isSpanInRange(
textRange = textRange,
type = Span.Keyboard::class.java
)
) tintColor else null
}
contentView.btnLink.apply {
contentView.findViewById<ImageView>(R.id.btnLink).apply {
imageTintList = if (spanned.isSpanInRange(
textRange = textRange,
type = Span.Url::class.java
)
) tintColor else null
}
contentView.btnColor.apply {
contentView.findViewById<TextView>(R.id.btnColor).apply {
if (spanned.isSpanInRange(
textRange = textRange,
type = Span.TextColor::class.java
)
) setTextColor(tintColor) else setTextColor(textDefaultColor)
}
contentView.btnBackground.apply {
contentView.findViewById<TextView>(R.id.btnBackground).apply {
if (spanned.isSpanInRange(
textRange = textRange,
type = Span.Highlight::class.java

View file

@ -21,17 +21,17 @@ import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_ui.features.navigation.DefaultObjectViewAdapter
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentObjectSearchBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.moving.MoveToView
import com.anytypeio.anytype.presentation.moving.MoveToViewModel
import com.anytypeio.anytype.presentation.moving.MoveToViewModelFactory
import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.android.synthetic.main.fragment_object_search.*
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
class MoveToFragment : BaseBottomSheetFragment() {
class MoveToFragment : BaseBottomSheetFragment<FragmentObjectSearchBinding>() {
private val vm by viewModels<MoveToViewModel> { factory }
@ -52,17 +52,11 @@ class MoveToFragment : BaseBottomSheetFragment() {
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_object_search, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupFullHeight()
setTransparent()
BottomSheetBehavior.from(sheet).apply {
BottomSheetBehavior.from(binding.sheet).apply {
state = BottomSheetBehavior.STATE_EXPANDED
isHideable = true
skipCollapsed = true
@ -77,8 +71,8 @@ class MoveToFragment : BaseBottomSheetFragment() {
}
)
}
clearSearchText = searchView.findViewById(R.id.clearSearchText)
filterInputField = searchView.findViewById(R.id.filterInputField)
clearSearchText = binding.searchView.root.findViewById(R.id.clearSearchText)
filterInputField = binding.searchView.root.findViewById(R.id.filterInputField)
filterInputField.setHint(R.string.search)
filterInputField.imeOptions = EditorInfo.IME_ACTION_DONE
filterInputField.setOnEditorActionListener { _, actionId, _ ->
@ -108,44 +102,57 @@ class MoveToFragment : BaseBottomSheetFragment() {
private fun observe(state: MoveToView) {
when (state) {
MoveToView.Loading -> {
recyclerView.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
progressBar.visible()
with(binding) {
recyclerView.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
progressBar.visible()
}
}
is MoveToView.Success -> {
progressBar.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
recyclerView.visible()
moveToAdapter.submitList(state.objects)
with(binding) {
progressBar.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
recyclerView.visible()
moveToAdapter.submitList(state.objects)
}
}
MoveToView.EmptyPages -> {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = getString(R.string.search_empty_pages)
tvScreenStateSubMessage.invisible()
with(binding) {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = getString(R.string.search_empty_pages)
tvScreenStateSubMessage.invisible()
}
}
is MoveToView.NoResults -> {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = getString(R.string.search_no_results, state.searchText)
tvScreenStateSubMessage.visible()
with(binding) {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text =
getString(R.string.search_no_results, state.searchText)
tvScreenStateSubMessage.visible()
}
}
is MoveToView.Error -> {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = state.error
tvScreenStateSubMessage.invisible()
with(binding) {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = state.error
tvScreenStateSubMessage.invisible()
}
}
MoveToView.Init -> {
recyclerView.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
progressBar.invisible()
with(binding) {
recyclerView.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
progressBar.invisible()
}
}
else -> Timber.d("Skipping state: $state")
}
@ -181,13 +188,13 @@ class MoveToFragment : BaseBottomSheetFragment() {
}
private fun initialize() {
with(tvScreenTitle) {
with(binding.tvScreenTitle) {
text = getString(R.string.move_to)
visible()
}
recyclerView.invisible()
tvScreenStateMessage.invisible()
progressBar.invisible()
binding.recyclerView.invisible()
binding.tvScreenStateMessage.invisible()
binding.progressBar.invisible()
clearSearchText.setOnClickListener {
filterInputField.setText(EMPTY_FILTER_TEXT)
clearSearchText.invisible()
@ -202,7 +209,7 @@ class MoveToFragment : BaseBottomSheetFragment() {
clearSearchText.visible()
}
}
with(recyclerView) {
with(binding.recyclerView) {
layoutManager = LinearLayoutManager(requireContext())
adapter = moveToAdapter
addItemDecoration(
@ -214,14 +221,14 @@ class MoveToFragment : BaseBottomSheetFragment() {
}
private fun setupFullHeight() {
val lp = (root.layoutParams as FrameLayout.LayoutParams)
val lp = (binding.root.layoutParams as FrameLayout.LayoutParams)
lp.height =
Resources.getSystem().displayMetrics.heightPixels - requireActivity().statusBarHeight
root.layoutParams = lp
binding.root.layoutParams = lp
}
private fun setTransparent() {
with(root) {
with(binding.root) {
background = null
(parent as? View)?.setBackgroundColor(Color.TRANSPARENT)
}
@ -235,6 +242,13 @@ class MoveToFragment : BaseBottomSheetFragment() {
componentManager().moveToComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentObjectSearchBinding = FragmentObjectSearchBinding.inflate(
inflater, container, false
)
companion object {
const val ARG_BLOCKS = "arg.move_to.blocks"
const val ARG_CTX = "arg.move_to.ctx"

View file

@ -1,7 +1,9 @@
package com.anytypeio.anytype.ui.navigation
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import androidx.core.view.minusAssign
import androidx.core.view.plusAssign
@ -13,6 +15,7 @@ import com.anytypeio.anytype.core_ui.layout.AppBarLayoutStateChangeListener
import com.anytypeio.anytype.core_ui.layout.State
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.ViewState
import com.anytypeio.anytype.databinding.FragmentPageNavigationBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.emojifier.Emojifier
import com.anytypeio.anytype.presentation.navigation.PageNavigationView
@ -22,14 +25,11 @@ import com.anytypeio.anytype.ui.base.ViewStateFragment
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.google.android.material.tabs.TabLayoutMediator
import kotlinx.android.synthetic.main.fragment_page_navigation.*
import kotlinx.android.synthetic.main.view_page_navigation_open_bottom.*
import kotlinx.android.synthetic.main.view_page_preview.*
import timber.log.Timber
import javax.inject.Inject
class PageNavigationFragment
: ViewStateFragment<ViewState<PageNavigationView>>(R.layout.fragment_page_navigation) {
: ViewStateFragment<ViewState<PageNavigationView>, FragmentPageNavigationBinding>(R.layout.fragment_page_navigation) {
@Inject
lateinit var factory: PageNavigationViewModelFactory
@ -45,16 +45,16 @@ class PageNavigationFragment
override fun render(state: ViewState<PageNavigationView>) {
when (state) {
ViewState.Init -> {
appBarLayout.addOnOffsetChangedListener(object : AppBarLayoutStateChangeListener() {
binding.appBarLayout.addOnOffsetChangedListener(object : AppBarLayoutStateChangeListener() {
override fun onStateChanged(state: State) {
if (state == State.COLLAPSED) {
pagePreviewSmall.visible()
binding.pagePreviewSmall.root.visible()
} else {
pagePreviewSmall.gone()
binding.pagePreviewSmall.root.gone()
}
}
})
viewPager.adapter = PageNavigationAdapter(vm::onPageLinkClick) { links ->
binding.viewPager.adapter = PageNavigationAdapter(vm::onPageLinkClick) { links ->
val filterView = FilterView(requireContext()).apply {
cancelClicked = { closeFilterView() }
pageClicked = {
@ -63,90 +63,90 @@ class PageNavigationFragment
}
bind(links)
}
filterContainer.plusAssign(filterView)
binding.filterContainer.plusAssign(filterView)
filterView.inputField.requestFocus()
context?.imm()?.showSoftInput(filterView.inputField, InputMethodManager.SHOW_FORCED)
}
viewPager.setCurrentItem(1, false)
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
binding.viewPager.setCurrentItem(1, false)
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
when (position) {
POSITION_FROM -> tab.text = getString(R.string.page_nav_link_from)
POSITION_TO -> tab.text = getString(R.string.page_nav_links_to)
}
}.attach()
btnOpenPage.setOnClickListener { vm.onOpenPageClicked() }
btnOpenPageSmall.setOnClickListener { vm.onOpenPageClicked() }
binding.pagePreviewContainer.btnOpenPage.setOnClickListener { vm.onOpenPageClicked() }
binding.pagePreviewSmall.btnOpenPageSmall.setOnClickListener { vm.onOpenPageClicked() }
vm.onGetPageLinks(requireArguments().getString(TARGET_ID_KEY, ""))
}
ViewState.Loading -> {
progressBar.visible()
binding.progressBar.visible()
}
is ViewState.Success -> {
progressBar.invisible()
binding.progressBar.invisible()
state.data.title.let { title ->
pageTitleSmall.text =
if (title.isEmpty()) getString(R.string.untitled) else title
tvPageTitle.text =
if (title.isEmpty()) getString(R.string.untitled) else title
binding.pagePreviewSmall.pageTitleSmall.text =
title.ifEmpty { getString(R.string.untitled) }
binding.pagePreviewContainer.tvPageTitle.text =
title.ifEmpty { getString(R.string.untitled) }
}
if (state.data.subtitle.isNotEmpty()) {
tvPageSubtitle.visible()
tvPageSubtitle.text = state.data.subtitle
binding.pagePreviewContainer.tvPageSubtitle.visible()
binding.pagePreviewContainer.tvPageSubtitle.text = state.data.subtitle
} else {
tvPageSubtitle.text = null
tvPageSubtitle.gone()
binding.pagePreviewContainer.tvPageSubtitle.text = null
binding.pagePreviewContainer.tvPageSubtitle.gone()
}
imageIcon.setImageDrawable(null)
avatarSmall.setImageDrawable(null)
emojiIcon.setImageDrawable(null)
binding.pagePreviewContainer.imageIcon.setImageDrawable(null)
binding.pagePreviewSmall.avatarSmall.setImageDrawable(null)
binding.pagePreviewContainer.emojiIcon.setImageDrawable(null)
state.data.image?.let { url ->
Glide
.with(imageIcon)
.with(binding.pagePreviewContainer.imageIcon)
.load(url)
.centerInside()
.circleCrop()
.into(imageIcon)
.into(binding.pagePreviewContainer.imageIcon)
Glide
.with(avatarSmall)
.with(binding.pagePreviewSmall.avatarSmall)
.load(url)
.centerInside()
.circleCrop()
.into(avatarSmall)
.into(binding.pagePreviewSmall.avatarSmall)
}
state.data.emoji?.let { emoji ->
try {
Glide
.with(emojiIcon)
.with(binding.pagePreviewContainer.emojiIcon)
.load(Emojifier.uri(emoji))
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(emojiIcon)
.into(binding.pagePreviewContainer.emojiIcon)
Glide
.with(avatarSmall)
.with(binding.pagePreviewSmall.avatarSmall)
.load(Emojifier.uri(emoji))
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(avatarSmall)
.into(binding.pagePreviewSmall.avatarSmall)
} catch (e: Exception) {
Timber.e(e, "Error while setting emoji icon for: $emoji")
}
}
(viewPager.adapter as? PageNavigationAdapter)?.setPageLinks(
(binding.viewPager.adapter as? PageNavigationAdapter)?.setPageLinks(
inbound = state.data.inbound,
outbound = state.data.outbound
)
}
is ViewState.Error -> {
progressBar.invisible()
coordinatorLayout.showSnackbar(state.error)
binding.progressBar.invisible()
binding.coordinatorLayout.showSnackbar(state.error)
}
}
}
private fun closeFilterView() {
filterContainer.getChildAt(0)?.let { filterContainer.minusAssign(it) }
binding.filterContainer.getChildAt(0)?.let { binding.filterContainer.minusAssign(it) }
requireActivity().hideSoftInput()
}
@ -158,6 +158,13 @@ class PageNavigationFragment
componentManager().navigationComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentPageNavigationBinding = FragmentPageNavigationBinding.inflate(
inflater, container, false
)
companion object {
const val TARGET_ID_KEY = "ID_KEY"
const val POSITION_FROM = 0

View file

@ -12,7 +12,10 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_ui.features.objects.ObjectAppearanceSettingAdapter
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ext.argString
import com.anytypeio.anytype.core_utils.ext.drawable
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.databinding.FragmentObjAppearanceBaseBinding
import com.anytypeio.anytype.di.common.componentManager
@ -22,7 +25,7 @@ import com.anytypeio.anytype.presentation.objects.appearance.ObjectAppearancePre
import javax.inject.Inject
//region ICON
class ObjectAppearanceIconFragment : BaseBottomSheetFragment() {
class ObjectAppearanceIconFragment : BaseBottomSheetFragment<FragmentObjAppearanceBaseBinding>() {
@Inject
lateinit var factory: ObjectAppearanceIconViewModel.Factory
@ -37,13 +40,8 @@ class ObjectAppearanceIconFragment : BaseBottomSheetFragment() {
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val binding = FragmentObjAppearanceBaseBinding.inflate(inflater, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.tvScreenTitle.text = getString(R.string.icon)
binding.recyclerView.apply {
layoutManager = LinearLayoutManager(requireContext())
@ -55,7 +53,6 @@ class ObjectAppearanceIconFragment : BaseBottomSheetFragment() {
)
}
return binding.root
}
override fun onStart() {
@ -90,6 +87,13 @@ class ObjectAppearanceIconFragment : BaseBottomSheetFragment() {
componentManager().objectAppearanceIconComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentObjAppearanceBaseBinding = FragmentObjAppearanceBaseBinding.inflate(
inflater, container, false
)
private val ctx: String get() = argString(CONTEXT_ID_KEY)
private val block: String get() = argString(BLOCK_ID_KEY)
@ -105,7 +109,8 @@ class ObjectAppearanceIconFragment : BaseBottomSheetFragment() {
//endregion
//region PREVIEW LAYOUT
class ObjectAppearancePreviewLayoutFragment : BaseBottomSheetFragment() {
class ObjectAppearancePreviewLayoutFragment :
BaseBottomSheetFragment<FragmentObjAppearanceBaseBinding>() {
@Inject
lateinit var factory: ObjectAppearancePreviewLayoutViewModel.Factory
@ -120,14 +125,8 @@ class ObjectAppearancePreviewLayoutFragment : BaseBottomSheetFragment() {
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val binding = FragmentObjAppearanceBaseBinding.inflate(inflater, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.tvScreenTitle.text = getString(R.string.preview_layout)
binding.recyclerView.apply {
layoutManager = LinearLayoutManager(requireContext())
@ -138,8 +137,6 @@ class ObjectAppearancePreviewLayoutFragment : BaseBottomSheetFragment() {
}
)
}
return binding.root
}
override fun onStart() {
@ -172,6 +169,13 @@ class ObjectAppearancePreviewLayoutFragment : BaseBottomSheetFragment() {
componentManager().objectAppearancePreviewLayoutComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentObjAppearanceBaseBinding = FragmentObjAppearanceBaseBinding.inflate(
inflater, container, false
)
private val ctx: String get() = argString(CONTEXT_ID_KEY)
private val block: String get() = argString(BLOCK_ID_KEY)
@ -187,7 +191,7 @@ class ObjectAppearancePreviewLayoutFragment : BaseBottomSheetFragment() {
//endregion
//region COVER
class ObjectAppearanceCoverFragment : BaseBottomSheetFragment() {
class ObjectAppearanceCoverFragment : BaseBottomSheetFragment<FragmentObjAppearanceBaseBinding>() {
@Inject
lateinit var factory: ObjectAppearanceCoverViewModel.Factory
@ -202,13 +206,8 @@ class ObjectAppearanceCoverFragment : BaseBottomSheetFragment() {
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val binding = FragmentObjAppearanceBaseBinding.inflate(inflater, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.tvScreenTitle.text = getString(R.string.cover)
binding.recyclerView.apply {
layoutManager = LinearLayoutManager(requireContext())
@ -219,11 +218,8 @@ class ObjectAppearanceCoverFragment : BaseBottomSheetFragment() {
}
)
}
return binding.root
}
override fun onStart() {
jobs += lifecycleScope.subscribe(vm.state) { state ->
when (state) {
@ -256,6 +252,13 @@ class ObjectAppearanceCoverFragment : BaseBottomSheetFragment() {
componentManager().objectAppearanceCoverComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentObjAppearanceBaseBinding = FragmentObjAppearanceBaseBinding.inflate(
inflater, container, false
)
private val ctx: String get() = argString(CONTEXT_ID_KEY)
private val block: String get() = argString(BLOCK_ID_KEY)

View file

@ -17,12 +17,12 @@ import com.anytypeio.anytype.core_utils.ext.drawable
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.databinding.FragmentObjectAppearanceSettingBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.objects.ObjectAppearanceSettingViewModel
import kotlinx.android.synthetic.main.fragment_object_appearance_setting.*
import javax.inject.Inject
class ObjectAppearanceSettingFragment : BaseBottomSheetFragment() {
class ObjectAppearanceSettingFragment : BaseBottomSheetFragment<FragmentObjectAppearanceSettingBinding>() {
@Inject
lateinit var factory: ObjectAppearanceSettingViewModel.Factory
@ -39,15 +39,9 @@ class ObjectAppearanceSettingFragment : BaseBottomSheetFragment() {
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_object_appearance_setting, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(recyclerView) {
with(binding.recyclerView) {
layoutManager = LinearLayoutManager(requireContext())
adapter = adapterAppearance
addItemDecoration(
@ -101,6 +95,13 @@ class ObjectAppearanceSettingFragment : BaseBottomSheetFragment() {
componentManager().objectAppearanceSettingComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentObjectAppearanceSettingBinding = FragmentObjectAppearanceSettingBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: Id, block: Id) = ObjectAppearanceSettingFragment().apply {
arguments = bundleOf(

View file

@ -9,8 +9,6 @@ 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
@ -18,14 +16,14 @@ 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.databinding.FragmentObjectTypeChangeBinding
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 kotlinx.android.synthetic.main.fragment_object_type_change.*
import javax.inject.Inject
class ObjectTypeChangeFragment : BaseBottomSheetFragment() {
class ObjectTypeChangeFragment : BaseBottomSheetFragment<FragmentObjectTypeChangeBinding>() {
private val smartBlockType: SmartBlockType get() = arg(ARG_SMART_BLOCK_TYPE)
@ -41,15 +39,9 @@ class ObjectTypeChangeFragment : BaseBottomSheetFragment() {
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_object_type_change, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recycler.apply {
binding.recycler.apply {
adapter = objectTypeAdapter
layoutManager = LinearLayoutManager(context)
}
@ -69,7 +61,7 @@ class ObjectTypeChangeFragment : BaseBottomSheetFragment() {
override fun onStart() {
with(lifecycleScope) {
jobs += subscribe(vm.results) { observeViews(it) }
jobs += subscribe(searchObjectTypeInput.textChanges()) {
jobs += subscribe(binding.searchObjectTypeInput.textChanges()) {
vm.onQueryChanged(it.toString())
}
}
@ -85,6 +77,13 @@ class ObjectTypeChangeFragment : BaseBottomSheetFragment() {
componentManager().objectTypeChangeComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentObjectTypeChangeBinding = FragmentObjectTypeChangeBinding.inflate(
inflater, container, false
)
companion object {
const val ARG_SMART_BLOCK_TYPE = "arg.object-type.smart-block-type"
const val OBJECT_TYPE_URL_KEY = "object-type-url.key"

View file

@ -10,51 +10,34 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.core_utils.ui.ViewState
import com.anytypeio.anytype.databinding.DialogKeychainPhraseBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.keychain.KeychainPhraseViewModel
import com.anytypeio.anytype.presentation.keychain.KeychainPhraseViewModelFactory
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.dialog_keychain_phrase.*
import javax.inject.Inject
class KeychainPhraseDialog : BottomSheetDialogFragment(), Observer<ViewState<String>> {
class KeychainPhraseDialog : BaseBottomSheetFragment<DialogKeychainPhraseBinding>(), Observer<ViewState<String>> {
private val vm : KeychainPhraseViewModel by viewModels { factory }
@Inject
lateinit var factory: KeychainPhraseViewModelFactory
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
injectDependencies()
}
override fun onDestroy() {
super.onDestroy()
releaseDependencies()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.dialog_keychain_phrase, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setBlur()
keychain.setOnClickListener {
if (keychain.layerType == View.LAYER_TYPE_SOFTWARE) {
binding.keychain.setOnClickListener {
if (binding.keychain.layerType == View.LAYER_TYPE_SOFTWARE) {
removeBlur()
}
}
btnCopy.setOnClickListener {
binding.btnCopy.setOnClickListener {
copyMnemonicToClipboard()
}
root.setOnClickListener {
binding.root.setOnClickListener {
setBlur()
}
}
@ -62,7 +45,7 @@ class KeychainPhraseDialog : BottomSheetDialogFragment(), Observer<ViewState<Str
private fun copyMnemonicToClipboard() {
try {
val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText(MNEMONIC_LABEL, keychain.text.toString())
val clip = ClipData.newPlainText(MNEMONIC_LABEL, binding.keychain.text.toString())
clipboard.setPrimaryClip(clip)
toast("Mnemonic copied to clipboard.")
} catch (e: Exception) {
@ -78,7 +61,7 @@ class KeychainPhraseDialog : BottomSheetDialogFragment(), Observer<ViewState<Str
override fun onChanged(state: ViewState<String>) {
when (state) {
is ViewState.Success -> {
keychain.text = state.data
binding.keychain.text = state.data
}
is ViewState.Error -> {
// TODO
@ -86,31 +69,41 @@ class KeychainPhraseDialog : BottomSheetDialogFragment(), Observer<ViewState<Str
is ViewState.Loading -> {
// TODO
}
ViewState.Init -> {
// Do nothing
}
}
}
private fun setBlur() = with(keychain) {
private fun setBlur() = with(binding.keychain) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null)
val radius = textSize / 3
val filter = BlurMaskFilter(radius, BlurMaskFilter.Blur.NORMAL)
paint.maskFilter = filter
}
private fun removeBlur() = with(keychain) {
private fun removeBlur() = with(binding.keychain) {
setLayerType(View.LAYER_TYPE_NONE, null)
paint.maskFilter = null
isFocusable = true
setTextIsSelectable(true)
}
private fun injectDependencies() {
override fun injectDependencies() {
componentManager().keychainPhraseComponent.get().inject(this)
}
private fun releaseDependencies() {
override fun releaseDependencies() {
componentManager().keychainPhraseComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): DialogKeychainPhraseBinding = DialogKeychainPhraseBinding.inflate(
inflater, container, false
)
companion object {
const val MNEMONIC_LABEL = "Your Anytype mnemonic phrase"
}

View file

@ -1,7 +1,9 @@
package com.anytypeio.anytype.ui.profile
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
@ -15,16 +17,16 @@ import com.anytypeio.anytype.core_utils.ext.invisible
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.core_utils.ui.ViewState
import com.anytypeio.anytype.databinding.FragmentProfileBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.profile.ProfileView
import com.anytypeio.anytype.presentation.profile.ProfileViewModel
import com.anytypeio.anytype.presentation.profile.ProfileViewModelFactory
import com.anytypeio.anytype.ui.base.ViewStateFragment
import kotlinx.android.synthetic.main.fragment_profile.*
import kotlinx.coroutines.launch
import javax.inject.Inject
class ProfileFragment : ViewStateFragment<ViewState<ProfileView>>(R.layout.fragment_profile) {
class ProfileFragment : ViewStateFragment<ViewState<ProfileView>, FragmentProfileBinding>(R.layout.fragment_profile) {
@Inject
lateinit var factory: ProfileViewModelFactory
@ -35,14 +37,14 @@ class ProfileFragment : ViewStateFragment<ViewState<ProfileView>>(R.layout.fragm
vm.state.observe(viewLifecycleOwner, this)
vm.version.observe(viewLifecycleOwner) { version(it) }
vm.navigation.observe(viewLifecycleOwner, navObserver)
backButtonContainer.setOnClickListener { vm.onBackButtonClicked() }
binding.backButtonContainer.setOnClickListener { vm.onBackButtonClicked() }
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
vm.isLoggingOut.collect { isLoggingOut ->
if (isLoggingOut)
logoutProgressBar.visible()
binding.logoutProgressBar.visible()
else
logoutProgressBar.invisible()
binding.logoutProgressBar.invisible()
}
}
}
@ -52,34 +54,36 @@ class ProfileFragment : ViewStateFragment<ViewState<ProfileView>>(R.layout.fragm
override fun render(state: ViewState<ProfileView>) {
when (state) {
is ViewState.Init -> {
wallpaperText.setOnClickListener {
findNavController().navigate(R.id.wallpaperSetFragment)
}
logoutButton.setOnClickListener { vm.onLogoutClicked() }
pinCodeText.setOnClickListener {
vm.onPinCodeClicked()
toast("Coming soon...")
}
keychainPhrase.setOnClickListener { vm.onKeyChainPhraseClicked() }
backButton.setOnClickListener { vm.onBackButtonClicked() }
profileCardContainer.setOnClickListener { vm.onProfileCardClicked() }
userSettingsText.setOnClickListener { vm.onUserSettingsClicked() }
with(binding) {
wallpaperText.setOnClickListener {
findNavController().navigate(R.id.wallpaperSetFragment)
}
logoutButton.setOnClickListener { vm.onLogoutClicked() }
pinCodeText.setOnClickListener {
vm.onPinCodeClicked()
toast("Coming soon...")
}
keychainPhrase.setOnClickListener { vm.onKeyChainPhraseClicked() }
backButton.setOnClickListener { vm.onBackButtonClicked() }
profileCardContainer.setOnClickListener { vm.onProfileCardClicked() }
userSettingsText.setOnClickListener { vm.onUserSettingsClicked() }
if (BuildConfig.DEBUG) {
with(debugSettingsButton) {
visible()
setOnClickListener { vm.onDebugSettingsClicked() }
if (BuildConfig.DEBUG) {
with(debugSettingsButton) {
visible()
setOnClickListener { vm.onDebugSettingsClicked() }
}
}
}
}
is ViewState.Success -> {
name.text = state.data.name
binding.name.text = state.data.name
val pos = state.data.name.firstDigitByHash()
avatar.bind(
binding.avatar.bind(
name = state.data.name,
color = requireContext().avatarColor(pos)
)
state.data.avatar?.let { avatar.icon(it) }
state.data.avatar?.let { binding.avatar.icon(it) }
}
is ViewState.Error -> {}
ViewState.Loading -> {}
@ -88,9 +92,9 @@ class ProfileFragment : ViewStateFragment<ViewState<ProfileView>>(R.layout.fragm
private fun version(version: String) {
if (version.isEmpty()) {
tvVersion.text = "Android v${BuildConfig.VERSION_NAME}-alpha"
binding.tvVersion.text = "Android v${BuildConfig.VERSION_NAME}-alpha"
} else {
tvVersion.text = "Android v${BuildConfig.VERSION_NAME}-alpha ($version)"
binding.tvVersion.text = "Android v${BuildConfig.VERSION_NAME}-alpha ($version)"
}
}
@ -101,4 +105,11 @@ class ProfileFragment : ViewStateFragment<ViewState<ProfileView>>(R.layout.fragm
override fun releaseDependencies() {
componentManager().profileComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentProfileBinding = FragmentProfileBinding.inflate(
inflater, container, false
)
}

View file

@ -4,9 +4,9 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ui.ViewType
import kotlinx.android.synthetic.main.item_select_profile_profile.view.*
import com.anytypeio.anytype.databinding.ItemSelectProfileAddProfileBinding
import com.anytypeio.anytype.databinding.ItemSelectProfileProfileBinding
class SelectProfileAdapter(
private val models: MutableList<Model>,
@ -18,20 +18,18 @@ class SelectProfileAdapter(
return LayoutInflater.from(parent.context).let { inflater ->
when (viewType) {
PROFILE_HOLDER -> {
inflater.inflate(
R.layout.item_select_profile_profile,
parent, false
).let { view ->
ViewHolder.ProfileViewHolder(view)
}
ViewHolder.ProfileViewHolder(
ItemSelectProfileProfileBinding.inflate(
inflater, parent, false
)
)
}
ADD_PROFILE_HOLDER -> {
inflater.inflate(
R.layout.item_select_profile_add_profile,
parent, false
).let { view ->
ViewHolder.AddProfileViewHolder(view)
}
ViewHolder.AddProfileViewHolder(
ItemSelectProfileAddProfileBinding.inflate(
inflater, parent, false
)
)
}
else -> throw IllegalStateException("Unexpected type: $viewType")
}
@ -63,23 +61,25 @@ class SelectProfileAdapter(
sealed class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
class ProfileViewHolder(view: View) : ViewHolder(view) {
class ProfileViewHolder(val binding: ItemSelectProfileProfileBinding) :
ViewHolder(binding.root) {
fun bind(
model: Model,
onClick: (Model.Profile) -> Unit
) {
check(model is Model.Profile)
itemView.apply {
isSelected = model.active
binding.apply {
root.isSelected = model.active
name.text = model.name
status.text = model.status
setOnClickListener { onClick(model) }
root.setOnClickListener { onClick(model) }
}
}
}
class AddProfileViewHolder(view: View) : ViewHolder(view) {
class AddProfileViewHolder(val binding: ItemSelectProfileAddProfileBinding) :
ViewHolder(binding.root) {
fun bind(onClick: () -> Unit) {
itemView.setOnClickListener { onClick() }
}

View file

@ -5,12 +5,10 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.anytypeio.anytype.R
import com.anytypeio.anytype.ui.profile.SelectProfileAdapter
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.dialog_select_profile.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.DialogSelectProfileBinding
class SelectProfileDialog : BottomSheetDialogFragment() {
class SelectProfileDialog : BaseBottomSheetFragment<DialogSelectProfileBinding>() {
private val selectProfileAdapter by lazy {
SelectProfileAdapter(
@ -33,21 +31,21 @@ class SelectProfileDialog : BottomSheetDialogFragment() {
)
}
companion object {
fun newInstance(): SelectProfileDialog = SelectProfileDialog()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.dialog_select_profile, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
selectProfileRecycler.apply {
binding.selectProfileRecycler.apply {
layoutManager = LinearLayoutManager(requireContext())
adapter = selectProfileAdapter
}
}
override fun injectDependencies() {}
override fun releaseDependencies() {}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): DialogSelectProfileBinding = DialogSelectProfileBinding.inflate(
inflater, container, false
)
}

View file

@ -8,30 +8,24 @@ import android.view.ViewGroup
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ext.withParent
import com.anytypeio.anytype.core_utils.ui.BaseDialogFragment
import kotlinx.android.synthetic.main.fragment_relation_file_value_action.*
import com.anytypeio.anytype.databinding.FragmentRelationFileValueActionBinding
class FileActionsFragment : BaseDialogFragment() {
class FileActionsFragment : BaseDialogFragment<FragmentRelationFileValueActionBinding>() {
override fun injectDependencies() {}
override fun releaseDependencies() {}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_relation_file_value_action, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnAdd.setOnClickListener {
binding.btnAdd.setOnClickListener {
withParent<FileActionReceiver> { onFileValueActionAdd() }
dismiss()
}
btnUploadFromGallery.setOnClickListener {
binding.btnUploadFromGallery.setOnClickListener {
withParent<FileActionReceiver> { onFileValueActionUploadFromGallery() }
dismiss()
}
btnUploadFromStorage.setOnClickListener {
binding.btnUploadFromStorage.setOnClickListener {
withParent<FileActionReceiver> { onFileValueActionUploadFromStorage() }
dismiss()
}
@ -51,6 +45,13 @@ class FileActionsFragment : BaseDialogFragment() {
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentRelationFileValueActionBinding = FragmentRelationFileValueActionBinding.inflate(
inflater, container, false
)
interface FileActionReceiver {
fun onFileValueActionAdd()
fun onFileValueActionUploadFromGallery()

View file

@ -22,17 +22,17 @@ import com.anytypeio.anytype.core_ui.reactive.focusChanges
import com.anytypeio.anytype.core_ui.reactive.textChanges
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentRelationAddBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.relations.RelationAddBaseViewModel
import com.anytypeio.anytype.presentation.relations.RelationAddToDataViewViewModel
import com.anytypeio.anytype.presentation.relations.RelationAddToObjectViewModel
import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.android.synthetic.main.fragment_relation_add.*
import java.io.Serializable
import javax.inject.Inject
abstract class RelationAddBaseFragment : BaseBottomSheetFragment() {
abstract class RelationAddBaseFragment : BaseBottomSheetFragment<FragmentRelationAddBinding>() {
abstract val vm: RelationAddBaseViewModel
@ -59,17 +59,17 @@ abstract class RelationAddBaseFragment : BaseBottomSheetFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
searchRelationInput = searchBar.findViewById(R.id.filterInputField)
searchRelationInput = binding.searchBar.root.findViewById(R.id.filterInputField)
searchRelationInput.apply {
hint = getString(R.string.find_a_relation)
}
clearSearchText = searchBar.findViewById(R.id.clearSearchText)
clearSearchText = binding.searchBar.root.findViewById(R.id.clearSearchText)
clearSearchText.setOnClickListener {
searchRelationInput.setText("")
clearSearchText.invisible()
}
setupFullHeight()
relationAddRecycler.apply {
binding.relationAddRecycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = concatAdapter
addItemDecoration(
@ -94,9 +94,10 @@ abstract class RelationAddBaseFragment : BaseBottomSheetFragment() {
}
private fun setupFullHeight() {
val lp = (root.layoutParams as FrameLayout.LayoutParams)
lp.height = Resources.getSystem().displayMetrics.heightPixels - requireActivity().statusBarHeight
root.layoutParams = lp
val lp = (binding.root.layoutParams as FrameLayout.LayoutParams)
lp.height =
Resources.getSystem().displayMetrics.heightPixels - requireActivity().statusBarHeight
binding.root.layoutParams = lp
}
private fun expand(root: View) {
@ -111,6 +112,13 @@ abstract class RelationAddBaseFragment : BaseBottomSheetFragment() {
abstract fun onRelationSelected(ctx: Id, relation: Id)
abstract fun onCreateFromScratchClicked()
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentRelationAddBinding = FragmentRelationAddBinding.inflate(
inflater, container, false
)
companion object {
const val CTX_KEY = "arg.relation-add.ctx"
}

View file

@ -21,6 +21,7 @@ import com.anytypeio.anytype.core_utils.ext.drawable
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.databinding.FragmentRelationCreateFromScratchBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.relations.RelationCreateFromScratchBaseViewModel
import com.anytypeio.anytype.presentation.relations.RelationCreateFromScratchForDataViewViewModel
@ -28,11 +29,11 @@ import com.anytypeio.anytype.presentation.relations.RelationCreateFromScratchFor
import com.anytypeio.anytype.presentation.relations.RelationCreateFromScratchForObjectViewModel
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.android.synthetic.main.fragment_relation_create_from_scratch.*
import java.io.Serializable
import javax.inject.Inject
abstract class RelationCreateFromScratchBaseFragment : BaseBottomSheetFragment() {
abstract class RelationCreateFromScratchBaseFragment :
BaseBottomSheetFragment<FragmentRelationCreateFromScratchBinding>() {
abstract val vm: RelationCreateFromScratchBaseViewModel
@ -53,8 +54,8 @@ abstract class RelationCreateFromScratchBaseFragment : BaseBottomSheetFragment()
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? =
inflater.inflate(R.layout.fragment_relation_create_from_scratch, container, false).apply {
): View? {
return super.onCreateView(inflater, container, savedInstanceState).apply {
dialog?.setOnShowListener { dg ->
val bottomSheet = (dg as? BottomSheetDialog)?.findViewById<FrameLayout>(
com.google.android.material.R.id.design_bottom_sheet
@ -66,11 +67,12 @@ abstract class RelationCreateFromScratchBaseFragment : BaseBottomSheetFragment()
}
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
nameInputAdapter.query = query
rvCreateRelationFromScratch.apply {
binding.rvCreateRelationFromScratch.apply {
layoutManager = LinearLayoutManager(context)
adapter = concatAdapter
addItemDecoration(
@ -79,12 +81,12 @@ abstract class RelationCreateFromScratchBaseFragment : BaseBottomSheetFragment()
}
)
}
btnAction.setOnClickListener { onCreateRelationClicked() }
binding.btnAction.setOnClickListener { onCreateRelationClicked() }
with(lifecycleScope) {
subscribe(vm.views) { relationAdapter.submitList(it) }
subscribe(vm.isActionButtonEnabled) { btnAction.isEnabled = it }
subscribe(vm.isActionButtonEnabled) { binding.btnAction.isEnabled = it }
subscribe(vm.isDismissed) { isDismissed ->
if (isDismissed) {
// Refact parent dismissing
@ -100,6 +102,13 @@ abstract class RelationCreateFromScratchBaseFragment : BaseBottomSheetFragment()
abstract fun onCreateRelationClicked()
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentRelationCreateFromScratchBinding = FragmentRelationCreateFromScratchBinding.inflate(
inflater, container, false
)
companion object {
const val CTX_KEY = "arg.relation-create-from-scratch.ctx"
const val QUERY_KEY = "arg.relation-create-from-scratch.query"

View file

@ -7,19 +7,18 @@ import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentRelationDateValueBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.DateValueCommand
import com.anytypeio.anytype.presentation.sets.DateValueView
import com.anytypeio.anytype.presentation.sets.RelationDateValueViewModel
import com.anytypeio.anytype.ui.sets.modals.DatePickerFragment
import kotlinx.android.synthetic.main.fragment_relation_date_value.*
import javax.inject.Inject
open class RelationDateValueFragment : BaseBottomSheetFragment(),
open class RelationDateValueFragment : BaseBottomSheetFragment<FragmentRelationDateValueBinding>(),
DatePickerFragment.DatePickerReceiver {
@Inject
@ -31,26 +30,22 @@ open class RelationDateValueFragment : BaseBottomSheetFragment(),
private val relationId get() = argString(RELATION_ID)
private val flow get() = arg<Int>(FLOW_KEY)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_relation_date_value, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setTransparentBackground()
btnBottomAction.setOnClickListener { vm.onActionClicked() }
tvNoDate.setOnClickListener { vm.onNoDateClicked() }
ivExactDayCheck.setOnClickListener { vm.onExactDayClicked() }
tvExactDay.setOnClickListener { vm.onExactDayClicked() }
tvDate.setOnClickListener { vm.onExactDayClicked() }
tvToday.setOnClickListener { vm.onTodayClicked() }
ivTodayCheck.setOnClickListener { vm.onTodayClicked() }
tvTomorrow.setOnClickListener { vm.onTomorrowClicked() }
ivTomorrowCheck.setOnClickListener { vm.onTomorrowClicked() }
tvYesterday.setOnClickListener { vm.onYesterdayClicked() }
ivYesterdayCheck.setOnClickListener { vm.onYesterdayClicked() }
with(binding) {
btnBottomAction.setOnClickListener { vm.onActionClicked() }
tvNoDate.setOnClickListener { vm.onNoDateClicked() }
ivExactDayCheck.setOnClickListener { vm.onExactDayClicked() }
tvExactDay.setOnClickListener { vm.onExactDayClicked() }
tvDate.setOnClickListener { vm.onExactDayClicked() }
tvToday.setOnClickListener { vm.onTodayClicked() }
ivTodayCheck.setOnClickListener { vm.onTodayClicked() }
tvTomorrow.setOnClickListener { vm.onTomorrowClicked() }
ivTomorrowCheck.setOnClickListener { vm.onTomorrowClicked() }
tvYesterday.setOnClickListener { vm.onYesterdayClicked() }
ivYesterdayCheck.setOnClickListener { vm.onYesterdayClicked() }
}
}
override fun onStart() {
@ -66,28 +61,30 @@ open class RelationDateValueFragment : BaseBottomSheetFragment(),
}
private fun observeState(state: DateValueView) {
tvRelationHeader.text = state.title
ivNoDateCheck.invisible()
ivTodayCheck.invisible()
ivYesterdayCheck.invisible()
ivTomorrowCheck.invisible()
ivExactDayCheck.invisible()
tvDate.text = null
if (state.isToday) {
ivTodayCheck.visible()
}
if (state.isYesterday) {
ivYesterdayCheck.visible()
}
if (state.isTomorrow) {
ivTomorrowCheck.visible()
}
if (state.exactDayFormat != null) {
tvDate.text = state.exactDayFormat
ivExactDayCheck.visible()
}
if (state.timeInSeconds == null) {
ivNoDateCheck.visible()
with(binding) {
tvRelationHeader.text = state.title
ivNoDateCheck.invisible()
ivTodayCheck.invisible()
ivYesterdayCheck.invisible()
ivTomorrowCheck.invisible()
ivExactDayCheck.invisible()
tvDate.text = null
if (state.isToday) {
ivTodayCheck.visible()
}
if (state.isYesterday) {
ivYesterdayCheck.visible()
}
if (state.isTomorrow) {
ivTomorrowCheck.visible()
}
if (state.exactDayFormat != null) {
tvDate.text = state.exactDayFormat
ivExactDayCheck.visible()
}
if (state.timeInSeconds == null) {
ivNoDateCheck.visible()
}
}
}
@ -139,6 +136,13 @@ open class RelationDateValueFragment : BaseBottomSheetFragment(),
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentRelationDateValueBinding = FragmentRelationDateValueBinding.inflate(
inflater, container, false
)
companion object {
fun new(

View file

@ -15,14 +15,15 @@ import com.anytypeio.anytype.core_ui.features.relations.RelationFileValueAdapter
import com.anytypeio.anytype.core_ui.reactive.textChanges
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentRelationValueFileAddBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.relations.FileValueAddCommand
import com.anytypeio.anytype.presentation.relations.FileValueAddView
import com.anytypeio.anytype.presentation.relations.RelationFileValueAddViewModel
import kotlinx.android.synthetic.main.fragment_relation_value_file_add.*
import javax.inject.Inject
class RelationFileValueAddFragment : BaseBottomSheetFragment() {
class RelationFileValueAddFragment :
BaseBottomSheetFragment<FragmentRelationValueFileAddBinding>() {
@Inject
lateinit var factory: RelationFileValueAddViewModel.Factory
@ -42,12 +43,6 @@ class RelationFileValueAddFragment : BaseBottomSheetFragment() {
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_relation_value_file_add, container, false)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setTransparentBackground()
@ -55,14 +50,14 @@ class RelationFileValueAddFragment : BaseBottomSheetFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
rvFiles.layoutManager = LinearLayoutManager(requireContext())
rvFiles.adapter = adapter
btnBottomAction.setOnClickListener { vm.onActionButtonClicked() }
searchRelationInput = searchBar.findViewById(R.id.filterInputField)
binding.rvFiles.layoutManager = LinearLayoutManager(requireContext())
binding.rvFiles.adapter = adapter
binding.btnBottomAction.setOnClickListener { vm.onActionButtonClicked() }
searchRelationInput = binding.searchBar.root.findViewById(R.id.filterInputField)
searchRelationInput.apply {
hint = getString(R.string.choose_options)
}
clearSearchText = searchBar.findViewById(R.id.clearSearchText)
clearSearchText = binding.searchBar.root.findViewById(R.id.clearSearchText)
clearSearchText.setOnClickListener {
searchRelationInput.setText("")
clearSearchText.invisible()
@ -88,7 +83,7 @@ class RelationFileValueAddFragment : BaseBottomSheetFragment() {
private fun observeState(state: FileValueAddView) {
adapter.update(state.files)
tvFilesCount.text = state.count
binding.tvFilesCount.text = state.count
}
private fun observeCommands(command: FileValueAddCommand) {
@ -131,6 +126,13 @@ class RelationFileValueAddFragment : BaseBottomSheetFragment() {
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentRelationValueFileAddBinding = FragmentRelationValueFileAddBinding.inflate(
inflater, container, false
)
companion object {
fun new(

View file

@ -17,17 +17,17 @@ import com.anytypeio.anytype.core_ui.features.relations.DocumentRelationAdapter
import com.anytypeio.anytype.core_ui.reactive.textChanges
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentRelationListBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.relations.ObjectRelationListViewModelFactory
import com.anytypeio.anytype.presentation.relations.RelationListViewModel
import com.anytypeio.anytype.presentation.relations.RelationListViewModel.Command
import com.anytypeio.anytype.ui.editor.OnFragmentInteractionListener
import kotlinx.android.synthetic.main.fragment_relation_list.*
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.onStart
import javax.inject.Inject
open class RelationListFragment : BaseBottomSheetFragment(),
open class RelationListFragment : BaseBottomSheetFragment<FragmentRelationListBinding>(),
RelationTextValueFragment.TextValueEditReceiver,
RelationDateValueFragment.DateValueEditReceiver {
@ -68,24 +68,18 @@ open class RelationListFragment : BaseBottomSheetFragment(),
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_relation_list, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
searchRelationInput = searchBar.findViewById(R.id.filterInputField)
searchRelationInput = binding.searchBar.root.findViewById(R.id.filterInputField)
searchRelationInput.apply {
hint = getString(R.string.choose_options)
}
clearSearchText = searchBar.findViewById(R.id.clearSearchText)
clearSearchText = binding.searchBar.root.findViewById(R.id.clearSearchText)
clearSearchText.setOnClickListener {
searchRelationInput.setText("")
clearSearchText.invisible()
}
recycler.apply {
binding.recycler.apply {
adapter = docRelationAdapter
layoutManager = LinearLayoutManager(context)
addItemDecoration(
@ -94,10 +88,10 @@ open class RelationListFragment : BaseBottomSheetFragment(),
}
)
}
btnPlus.setOnClickListener {
binding.btnPlus.setOnClickListener {
RelationAddToObjectFragment.new(ctx).show(childFragmentManager, null)
}
btnEditOrDone.setOnClickListener {
binding.btnEditOrDone.setOnClickListener {
vm.onEditOrDoneClicked()
}
}
@ -106,7 +100,7 @@ open class RelationListFragment : BaseBottomSheetFragment(),
super.onActivityCreated(savedInstanceState)
with(lifecycleScope) {
if (mode == MODE_ADD) {
searchBar.visible()
binding.searchBar.root.visible()
val queries = searchRelationInput.textChanges()
.onStart { emit(searchRelationInput.text.toString()) }
val views = vm.views.combine(queries) { views, query ->
@ -127,18 +121,18 @@ open class RelationListFragment : BaseBottomSheetFragment(),
}
subscribe(views) { docRelationAdapter.update(it) }
} else {
searchBar.gone()
binding.searchBar.root.gone()
subscribe(vm.views) { docRelationAdapter.update(it) }
}
subscribe(vm.commands) { command -> execute(command) }
subscribe(vm.toasts) { toast(it) }
subscribe(vm.isEditMode) { isEditMode ->
if (isEditMode) {
btnEditOrDone.setText(R.string.done)
btnPlus.invisible()
binding.btnEditOrDone.setText(R.string.done)
binding.btnPlus.invisible()
} else {
btnPlus.visible()
btnEditOrDone.setText(R.string.edit)
binding.btnPlus.visible()
binding.btnEditOrDone.setText(R.string.edit)
}
}
}
@ -236,6 +230,13 @@ open class RelationListFragment : BaseBottomSheetFragment(),
componentManager().documentRelationComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentRelationListBinding = FragmentRelationListBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: String, target: String?, mode: Int) = RelationListFragment().apply {
arguments = bundleOf(

View file

@ -14,17 +14,17 @@ import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_ui.reactive.textChanges
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseDialogFragment
import com.anytypeio.anytype.databinding.FragmentRelationObjectValueAddBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.relations.ObjectValueAddCommand
import com.anytypeio.anytype.presentation.relations.ObjectValueAddView
import com.anytypeio.anytype.presentation.relations.RelationObjectValueAddViewModel
import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.android.synthetic.main.fragment_relation_object_value_add.*
import javax.inject.Inject
class RelationObjectValueAddFragment : BaseDialogFragment() {
class RelationObjectValueAddFragment : BaseDialogFragment<FragmentRelationObjectValueAddBinding>() {
private val behavior get() = BottomSheetBehavior.from(sheet)
private val behavior get() = BottomSheetBehavior.from(binding.sheet)
@Inject
lateinit var factory: RelationObjectValueAddViewModel.Factory
@ -49,8 +49,10 @@ class RelationObjectValueAddFragment : BaseDialogFragment() {
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_relation_object_value_add, container, false).apply {
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
): View? {
return super.onCreateView(inflater, container, savedInstanceState).apply {
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -58,15 +60,15 @@ class RelationObjectValueAddFragment : BaseDialogFragment() {
with(lifecycleScope) {
subscribe(view.clicks()) { dismiss() }
}
rvObjects.layoutManager = LinearLayoutManager(requireContext())
rvObjects.adapter = adapter
btnBottomAction.setOnClickListener { vm.onActionButtonClicked() }
binding.rvObjects.layoutManager = LinearLayoutManager(requireContext())
binding.rvObjects.adapter = adapter
binding.btnBottomAction.setOnClickListener { vm.onActionButtonClicked() }
setupBottomSheet()
searchRelationInput = searchBar.findViewById(R.id.filterInputField)
searchRelationInput = binding.searchBar.root.findViewById(R.id.filterInputField)
searchRelationInput.apply {
hint = getString(R.string.choose_options)
}
clearSearchText = searchBar.findViewById(R.id.clearSearchText)
clearSearchText = binding.searchBar.root.findViewById(R.id.clearSearchText)
clearSearchText.setOnClickListener {
searchRelationInput.setText("")
clearSearchText.invisible()
@ -83,11 +85,11 @@ class RelationObjectValueAddFragment : BaseDialogFragment() {
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {
if (btnAddContainer == null) return
if (binding.btnAddContainer == null) return
if (slideOffset < 0)
btnAddContainer.gone()
binding.btnAddContainer.gone()
else
btnAddContainer.visible()
binding.btnAddContainer.visible()
}
}
)
@ -114,7 +116,7 @@ class RelationObjectValueAddFragment : BaseDialogFragment() {
private fun observeState(state: ObjectValueAddView) {
adapter.update(state.objects)
tvObjectsCount.text = state.count
binding.tvObjectsCount.text = state.count
}
private fun observeCommands(command: ObjectValueAddCommand) {
@ -162,6 +164,13 @@ class RelationObjectValueAddFragment : BaseDialogFragment() {
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentRelationObjectValueAddBinding = FragmentRelationObjectValueAddBinding.inflate(
inflater, container, false
)
companion object {
fun new(

View file

@ -14,15 +14,15 @@ import com.anytypeio.anytype.core_ui.reactive.focusChanges
import com.anytypeio.anytype.core_ui.reactive.textChanges
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseDialogFragment
import com.anytypeio.anytype.databinding.RelationOptionValueAddFragmentBinding
import com.anytypeio.anytype.presentation.relations.AddObjectRelationValueViewModel
import com.anytypeio.anytype.presentation.sets.RelationValueBaseViewModel
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.relation_option_value_add_fragment.*
abstract class RelationOptionValueBaseAddFragment : BaseDialogFragment() {
abstract class RelationOptionValueBaseAddFragment : BaseDialogFragment<RelationOptionValueAddFragmentBinding>() {
private val behavior get() = BottomSheetBehavior.from(sheet)
private val behavior get() = BottomSheetBehavior.from(binding.sheet)
val ctx get() = argString(CTX_KEY)
val relation get() = argString(RELATION_KEY)
@ -58,13 +58,16 @@ abstract class RelationOptionValueBaseAddFragment : BaseDialogFragment() {
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.relation_option_value_add_fragment, container, false).apply {
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
): View? {
return super.onCreateView(inflater, container, savedInstanceState).apply {
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recycler.apply {
binding.recycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = editCellTagAdapter
addItemDecoration(
@ -73,15 +76,15 @@ abstract class RelationOptionValueBaseAddFragment : BaseDialogFragment() {
}
)
}
searchRelationInput = searchBar.findViewById(R.id.filterInputField)
clearSearchText = searchBar.findViewById(R.id.clearSearchText)
searchRelationInput = binding.searchBar.root.findViewById(R.id.filterInputField)
clearSearchText = binding.searchBar.root.findViewById(R.id.clearSearchText)
clearSearchText.setOnClickListener {
searchRelationInput.setText("")
clearSearchText.invisible()
}
with(lifecycleScope) {
subscribe(view.clicks()) { dismiss() }
subscribe(btnAdd.clicks()) { onAddButtonClicked() }
subscribe(binding.btnAdd.clicks()) { onAddButtonClicked() }
subscribe(searchRelationInput.textChanges()) {
if (it.isEmpty()) clearSearchText.invisible() else clearSearchText.visible()
vm.onFilterInputChanged(it.toString())
@ -102,9 +105,9 @@ abstract class RelationOptionValueBaseAddFragment : BaseDialogFragment() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
if (vm.isMultiple.value) {
if (slideOffset < 0)
btnAddContainer.gone()
binding.btnAddContainer.gone()
else
btnAddContainer.visible()
binding.btnAddContainer.visible()
}
}
}
@ -116,9 +119,9 @@ abstract class RelationOptionValueBaseAddFragment : BaseDialogFragment() {
super.onActivityCreated(savedInstanceState)
with(lifecycleScope) {
subscribe(vm.ui) { editCellTagAdapter.update(it) }
subscribe(vm.counter) { tvSelectionCounter.text = it.toString() }
subscribe(vm.counter) { binding.tvSelectionCounter.text = it.toString() }
subscribe(vm.isAddButtonVisible) { isVisible ->
if (!isVisible) btnAddContainer.gone() else btnAddContainer.visible()
if (!isVisible) binding.btnAddContainer.gone() else binding.btnAddContainer.visible()
}
subscribe(vm.isDismissed) { isDismissed ->
if (isDismissed) {
@ -132,12 +135,12 @@ abstract class RelationOptionValueBaseAddFragment : BaseDialogFragment() {
}
subscribe(vm.isMultiple) { isMultiple ->
if (isMultiple) {
recycler.updatePadding(
binding.recycler.updatePadding(
bottom = dimen(R.dimen.multiple_option_value_bottom_list_margin)
)
searchRelationInput.setHint(R.string.choose_options)
} else {
recycler.updatePadding(
binding.recycler.updatePadding(
bottom = dimen(R.dimen.single_option_value_bottom_list_margin)
)
searchRelationInput.setHint(R.string.choose_option)
@ -181,6 +184,13 @@ abstract class RelationOptionValueBaseAddFragment : BaseDialogFragment() {
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): RelationOptionValueAddFragmentBinding = RelationOptionValueAddFragmentBinding.inflate(
inflater, container, false
)
companion object {
const val CTX_KEY = "arg.add-object-relation-value.ctx"
const val RELATION_KEY = "arg.add-object-relation-value.relation"

View file

@ -11,21 +11,20 @@ import androidx.core.os.bundleOf
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_ui.features.relations.RelationTextValueAdapter
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentRelationTextValueBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.EditGridCellAction
import com.anytypeio.anytype.presentation.sets.RelationTextValueView
import com.anytypeio.anytype.presentation.sets.RelationTextValueViewModel
import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.android.synthetic.main.fragment_relation_text_value.*
import javax.inject.Inject
import com.google.android.material.R.id.design_bottom_sheet as BOTTOM_SHEET_ID
open class RelationTextValueFragment : BaseBottomSheetFragment() {
open class RelationTextValueFragment : BaseBottomSheetFragment<FragmentRelationTextValueBinding>() {
@Inject
lateinit var factory: RelationTextValueViewModel.Factory
@ -59,15 +58,9 @@ open class RelationTextValueFragment : BaseBottomSheetFragment() {
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_relation_text_value, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recycler.apply {
binding.recycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = relationValueAdapter
}
@ -76,7 +69,7 @@ open class RelationTextValueFragment : BaseBottomSheetFragment() {
override fun onStart() {
jobs += lifecycleScope.subscribe(vm.views) { relationValueAdapter.update(it) }
jobs += lifecycleScope.subscribe(vm.title) { tvRelationHeader.text = it }
jobs += lifecycleScope.subscribe(vm.title) { binding.tvRelationHeader.text = it }
super.onStart()
vm.onStart(relationId = relationId, recordId = objectId)
}
@ -129,7 +122,7 @@ open class RelationTextValueFragment : BaseBottomSheetFragment() {
}
private fun dispatchTextResultAndExit(txt: String) {
recycler.hideKeyboard()
binding.recycler.hideKeyboard()
withParent<TextValueEditReceiver> {
onTextValueChanged(
ctx = ctx,
@ -142,7 +135,7 @@ open class RelationTextValueFragment : BaseBottomSheetFragment() {
}
private fun dispatchNumberResultAndExit(number: Double?) {
recycler.hideKeyboard()
binding.recycler.hideKeyboard()
withParent<TextValueEditReceiver> {
onNumberValueChanged(
ctx = ctx,
@ -165,6 +158,7 @@ open class RelationTextValueFragment : BaseBottomSheetFragment() {
bottomSheet.hideKeyboard()
}
}
override fun onStateChanged(bottomSheet: View, newState: Int) {}
})
}
@ -187,6 +181,13 @@ open class RelationTextValueFragment : BaseBottomSheetFragment() {
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentRelationTextValueBinding = FragmentRelationTextValueBinding.inflate(
inflater, container, false
)
companion object {
fun new(

View file

@ -33,6 +33,7 @@ import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.core_utils.ui.DragAndDropViewHolder
import com.anytypeio.anytype.core_utils.ui.OnStartDragListener
import com.anytypeio.anytype.databinding.FragmentRelationValueBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.navigation.AppNavigation
import com.anytypeio.anytype.presentation.sets.RelationValueBaseViewModel
@ -44,14 +45,10 @@ import com.anytypeio.anytype.ui.sets.ObjectSetFragment
import com.google.android.material.snackbar.Snackbar
import com.hbisoft.pickit.PickiT
import com.hbisoft.pickit.PickiTCallbacks
import kotlinx.android.synthetic.main.fragment_relation_value.*
import kotlinx.android.synthetic.main.fragment_relation_value.recycler
import kotlinx.android.synthetic.main.fragment_relation_value.root
import timber.log.Timber
import java.util.ArrayList
import javax.inject.Inject
abstract class RelationValueBaseFragment : BaseBottomSheetFragment(),
abstract class RelationValueBaseFragment : BaseBottomSheetFragment<FragmentRelationValueBinding>(),
OnStartDragListener,
RelationObjectValueAddFragment.ObjectValueAddReceiver,
FileActionsFragment.FileActionReceiver,
@ -116,15 +113,9 @@ abstract class RelationValueBaseFragment : BaseBottomSheetFragment(),
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_relation_value, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recycler.apply {
binding.recycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = relationValueAdapter
}
@ -135,8 +126,8 @@ abstract class RelationValueBaseFragment : BaseBottomSheetFragment(),
setDrawable(drawable(R.drawable.divider_relations_edit))
}
with(lifecycleScope) {
subscribe(btnEditOrDone.clicks()) { vm.onEditOrDoneClicked() }
subscribe(btnAddValue.clicks()) { vm.onAddValueClicked() }
subscribe(binding.btnEditOrDone.clicks()) { vm.onEditOrDoneClicked() }
subscribe(binding.btnAddValue.clicks()) { vm.onAddValueClicked() }
}
}
@ -146,7 +137,7 @@ abstract class RelationValueBaseFragment : BaseBottomSheetFragment(),
jobs += lifecycleScope.subscribe(vm.isDimissed) { observeDismiss(it) }
jobs += lifecycleScope.subscribe(vm.isEditing) { observeEditing(it) }
jobs += lifecycleScope.subscribe(vm.views) { relationValueAdapter.update(it) }
jobs += lifecycleScope.subscribe(vm.name) { tvTagOrStatusRelationHeader.text = it }
jobs += lifecycleScope.subscribe(vm.name) { binding.tvTagOrStatusRelationHeader.text = it }
jobs += lifecycleScope.subscribe(vm.navigation) { command -> navigate(command) }
jobs += lifecycleScope.subscribe(vm.isLoading) { isLoading -> observeLoading(isLoading) }
jobs += lifecycleScope.subscribe(vm.copyFileStatus) { command -> onCopyFileCommand(command) }
@ -156,11 +147,11 @@ abstract class RelationValueBaseFragment : BaseBottomSheetFragment(),
private fun observeLoading(isLoading: Boolean) {
if (isLoading) {
refresh.visible()
btnAddValue.invisible()
binding.refresh.visible()
binding.btnAddValue.invisible()
} else {
refresh.gone()
btnAddValue.visible()
binding.refresh.gone()
binding.btnAddValue.visible()
}
}
@ -193,20 +184,20 @@ abstract class RelationValueBaseFragment : BaseBottomSheetFragment(),
private fun observeEditing(isEditing: Boolean) {
if (isEditing) {
recycler.apply {
binding.recycler.apply {
removeItemDecoration(dividerItem)
addItemDecoration(dividerItemEdit)
}
btnAddValue.invisible()
btnEditOrDone.setText(R.string.done)
dndItemTouchHelper.attachToRecyclerView(recycler)
binding.btnAddValue.invisible()
binding.btnEditOrDone.setText(R.string.done)
dndItemTouchHelper.attachToRecyclerView(binding.recycler)
} else {
recycler.apply {
binding.recycler.apply {
removeItemDecoration(dividerItemEdit)
addItemDecoration(dividerItem)
}
btnAddValue.visible()
btnEditOrDone.setText(R.string.edit)
binding.btnAddValue.visible()
binding.btnEditOrDone.setText(R.string.edit)
dndItemTouchHelper.attachToRecyclerView(null)
}
}
@ -309,7 +300,7 @@ abstract class RelationValueBaseFragment : BaseBottomSheetFragment(),
//region READ PERMISSION
private fun takeReadStoragePermission() {
if (requireActivity().shouldShowRequestPermissionRationaleCompat(READ_EXTERNAL_STORAGE)) {
root.showSnackbar(
binding.root.showSnackbar(
R.string.permission_read_rationale,
Snackbar.LENGTH_INDEFINITE,
R.string.button_ok
@ -327,7 +318,7 @@ abstract class RelationValueBaseFragment : BaseBottomSheetFragment(),
if (readResult == true) {
startFilePicker(MIME_FILE_ALL)
} else {
root.showSnackbar(R.string.permission_read_denied, Snackbar.LENGTH_SHORT)
binding.root.showSnackbar(R.string.permission_read_denied, Snackbar.LENGTH_SHORT)
}
}
//endregion
@ -376,7 +367,7 @@ abstract class RelationValueBaseFragment : BaseBottomSheetFragment(),
onFilePathReady(command.result)
}
CopyFileStatus.Started -> {
mSnackbar = root.showSnackbar(
mSnackbar = binding.root.showSnackbar(
R.string.loading_file,
Snackbar.LENGTH_INDEFINITE,
R.string.cancel
@ -407,6 +398,13 @@ abstract class RelationValueBaseFragment : BaseBottomSheetFragment(),
abstract fun onRemoveObjectClicked(objectId: Id)
abstract fun onRemoveFileClicked(fileId: Id)
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentRelationValueBinding = FragmentRelationValueBinding.inflate(
inflater, container, false
)
companion object {
const val CTX_KEY = "arg.edit-cell-tag.ctx"
const val RELATION_KEY = "arg.edit-cell-tag.relation"

View file

@ -1,7 +1,9 @@
package com.anytypeio.anytype.ui.search
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
@ -12,18 +14,21 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.extensions.drawable
import com.anytypeio.anytype.core_ui.features.navigation.DefaultObjectViewAdapter
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ext.hideSoftInput
import com.anytypeio.anytype.core_utils.ext.imm
import com.anytypeio.anytype.core_utils.ext.invisible
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.databinding.FragmentObjectSearchBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.search.ObjectSearchView
import com.anytypeio.anytype.presentation.search.ObjectSearchViewModel
import com.anytypeio.anytype.presentation.search.ObjectSearchViewModelFactory
import com.anytypeio.anytype.ui.base.ViewStateFragment
import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.android.synthetic.main.fragment_object_search.*
import timber.log.Timber
import javax.inject.Inject
class ObjectSearchFragment : ViewStateFragment<ObjectSearchView>(R.layout.fragment_object_search) {
class ObjectSearchFragment : ViewStateFragment<ObjectSearchView, FragmentObjectSearchBinding>(R.layout.fragment_object_search) {
@Inject
lateinit var factory: ObjectSearchViewModelFactory
@ -41,7 +46,7 @@ class ObjectSearchFragment : ViewStateFragment<ObjectSearchView>(R.layout.fragme
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
BottomSheetBehavior.from(sheet).apply {
BottomSheetBehavior.from(binding.sheet).apply {
skipCollapsed = true
state = BottomSheetBehavior.STATE_EXPANDED
isHideable = true
@ -59,8 +64,8 @@ class ObjectSearchFragment : ViewStateFragment<ObjectSearchView>(R.layout.fragme
}
vm.state.observe(viewLifecycleOwner, this)
vm.navigation.observe(viewLifecycleOwner, navObserver)
clearSearchText = searchView.findViewById(R.id.clearSearchText)
filterInputField = searchView.findViewById(R.id.filterInputField)
clearSearchText = binding.searchView.root.findViewById(R.id.clearSearchText)
filterInputField = binding.searchView.root.findViewById(R.id.filterInputField)
filterInputField.setHint(R.string.search)
filterInputField.imeOptions = EditorInfo.IME_ACTION_DONE
filterInputField.setOnEditorActionListener { _, actionId, _ ->
@ -89,49 +94,61 @@ class ObjectSearchFragment : ViewStateFragment<ObjectSearchView>(R.layout.fragme
override fun render(state: ObjectSearchView) {
when (state) {
ObjectSearchView.Loading -> {
recyclerView.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
progressBar.visible()
with(binding) {
recyclerView.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
progressBar.visible()
}
}
is ObjectSearchView.Success -> {
progressBar.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
recyclerView.visible()
with(binding) {
progressBar.invisible()
tvScreenStateMessage.invisible()
tvScreenStateSubMessage.invisible()
recyclerView.visible()
}
searchAdapter.submitList(state.objects)
}
ObjectSearchView.EmptyPages -> {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = getString(R.string.search_empty_pages)
tvScreenStateSubMessage.invisible()
with(binding) {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = getString(R.string.search_empty_pages)
tvScreenStateSubMessage.invisible()
}
}
is ObjectSearchView.NoResults -> {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = getString(R.string.search_no_results, state.searchText)
tvScreenStateSubMessage.visible()
with(binding) {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = getString(R.string.search_no_results, state.searchText)
tvScreenStateSubMessage.visible()
}
}
is ObjectSearchView.Error -> {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = state.error
tvScreenStateSubMessage.invisible()
with(binding) {
progressBar.invisible()
recyclerView.invisible()
tvScreenStateMessage.visible()
tvScreenStateMessage.text = state.error
tvScreenStateSubMessage.invisible()
}
}
else -> Timber.d("Skipping state: $state")
}
}
private fun initialize() {
recyclerView.invisible()
tvScreenStateMessage.invisible()
progressBar.invisible()
searchView.findViewById<View>(R.id.clearSearchText).setOnClickListener {
with(binding) {
recyclerView.invisible()
tvScreenStateMessage.invisible()
progressBar.invisible()
searchView.root.findViewById<View>(R.id.clearSearchText).setOnClickListener {
}
}
clearSearchText.setOnClickListener {
filterInputField.setText(EMPTY_FILTER_TEXT)
@ -147,7 +164,7 @@ class ObjectSearchFragment : ViewStateFragment<ObjectSearchView>(R.layout.fragme
clearSearchText.visible()
}
}
with(recyclerView) {
with(binding.recyclerView) {
layoutManager = LinearLayoutManager(requireContext())
adapter = searchAdapter
addItemDecoration(
@ -167,6 +184,13 @@ class ObjectSearchFragment : ViewStateFragment<ObjectSearchView>(R.layout.fragme
componentManager().objectSearchComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentObjectSearchBinding = FragmentObjectSearchBinding.inflate(
inflater, container, false
)
companion object {
const val EMPTY_FILTER_TEXT = ""
}

View file

@ -1,7 +1,9 @@
package com.anytypeio.anytype.ui.sets
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 androidx.lifecycle.observe
@ -11,18 +13,18 @@ import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.features.sets.CreateSetHeaderAdapter
import com.anytypeio.anytype.core_ui.features.sets.CreateSetObjectTypeAdapter
import com.anytypeio.anytype.core_utils.ext.argString
import com.anytypeio.anytype.databinding.FragmentCreateSetBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.CreateObjectSetViewModel
import com.anytypeio.anytype.presentation.sets.CreateObjectTypeView
import com.anytypeio.anytype.presentation.sets.CreateSetViewState
import com.anytypeio.anytype.ui.base.NavigationFragment
import kotlinx.android.synthetic.main.fragment_create_set.*
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import javax.inject.Inject
class CreateObjectSetFragment : NavigationFragment(R.layout.fragment_create_set),
class CreateObjectSetFragment : NavigationFragment<FragmentCreateSetBinding>(R.layout.fragment_create_set),
CreateObjectTypeCallback {
private val ctx: String get() = argString(CONTEXT_ID_KEY)
@ -47,7 +49,7 @@ class CreateObjectSetFragment : NavigationFragment(R.layout.fragment_create_set)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
vm.state.observe(viewLifecycleOwner) { observe(it) }
recycler.apply {
binding.recycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = createSetAdapter
}
@ -84,6 +86,13 @@ class CreateObjectSetFragment : NavigationFragment(R.layout.fragment_create_set)
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentCreateSetBinding = FragmentCreateSetBinding.inflate(
inflater, container, false
)
companion object {
const val CONTEXT_ID_KEY = "arg.create_object_set.context"
}

View file

@ -7,18 +7,17 @@ import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.lifecycle.observe
import androidx.recyclerview.widget.LinearLayoutManager
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.features.sets.CreateObjectTypeAdapter
import com.anytypeio.anytype.core_utils.ext.hideKeyboard
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentCreateObjectTypeBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.CreateObjectTypeView
import com.anytypeio.anytype.presentation.sets.CreateObjectTypeViewModel
import com.anytypeio.anytype.presentation.sets.CreateObjectTypeViewState
import kotlinx.android.synthetic.main.fragment_create_object_type.*
import javax.inject.Inject
class CreateObjectTypeFragment : BaseBottomSheetFragment() {
class CreateObjectTypeFragment : BaseBottomSheetFragment<FragmentCreateObjectTypeBinding>() {
@Inject
lateinit var factory: CreateObjectTypeViewModel.Factory
@ -33,19 +32,12 @@ class CreateObjectTypeFragment : BaseBottomSheetFragment() {
return list
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_create_object_type, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnCreate.setOnClickListener { vm.onCreateClicked(edtTypeName.text.toString()) }
binding.btnCreate.setOnClickListener { vm.onCreateClicked(binding.edtTypeName.text.toString()) }
vm.state.observe(viewLifecycleOwner) { observeData(it) }
rvTypes.layoutManager = LinearLayoutManager(requireContext())
rvTypes.adapter = typesAdapter
binding.rvTypes.layoutManager = LinearLayoutManager(requireContext())
binding.rvTypes.adapter = typesAdapter
vm.init(types)
}
@ -61,7 +53,7 @@ class CreateObjectTypeFragment : BaseBottomSheetFragment() {
state.type,
state.name
)
edtTypeName.hideKeyboard()
binding.edtTypeName.hideKeyboard()
dismiss()
}
}
@ -75,6 +67,13 @@ class CreateObjectTypeFragment : BaseBottomSheetFragment() {
componentManager().createObjectTypeComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentCreateObjectTypeBinding = FragmentCreateObjectTypeBinding.inflate(
inflater, container, false
)
companion object {
private const val ARG_TYPES = "arg.create.object.types"

View file

@ -6,6 +6,7 @@ import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.view.GestureDetector
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AccelerateDecelerateInterpolator
@ -40,6 +41,7 @@ import com.anytypeio.anytype.core_ui.widgets.StatusBadgeWidget
import com.anytypeio.anytype.core_ui.widgets.text.TextInputWidget
import com.anytypeio.anytype.core_utils.OnSwipeListener
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.databinding.FragmentObjectSetBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.editor.cover.CoverColor
import com.anytypeio.anytype.presentation.editor.cover.CoverGradient
@ -62,55 +64,54 @@ import com.anytypeio.anytype.ui.relations.RelationValueBaseFragment
import com.anytypeio.anytype.ui.sets.modals.*
import com.anytypeio.anytype.ui.sets.modals.sort.ViewerSortFragment
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_object_set.*
import kotlinx.coroutines.flow.filterNotNull
import javax.inject.Inject
open class ObjectSetFragment :
NavigationFragment(R.layout.fragment_object_set),
NavigationFragment<FragmentObjectSetBinding>(R.layout.fragment_object_set),
TextValueEditReceiver,
DateValueEditReceiver {
// Controls
private val title: TextInputWidget
get() = objectHeader.findViewById(R.id.tvSetTitle)
get() = binding.objectHeader.root.findViewById(R.id.tvSetTitle)
private val topToolbarTitle: TextView
get() = topToolbar.findViewById(R.id.tvTopToolbarTitle)
get() = binding.topToolbar.root.findViewById(R.id.tvTopToolbarTitle)
private val topToolbarThreeDotsButton : ViewGroup
get() = topToolbar.findViewById(R.id.threeDotsButton)
get() = binding.topToolbar.root.findViewById(R.id.threeDotsButton)
private val topToolbarStatusContainer: ViewGroup
get() = topToolbar.findViewById(R.id.statusContainer)
get() = binding.topToolbar.root.findViewById(R.id.statusContainer)
private val topToolbarThreeDotsIcon : ImageView
get() = topToolbar.findViewById(R.id.ivThreeDots)
get() = binding.topToolbar.root.findViewById(R.id.ivThreeDots)
private val topToolbarStatusText: TextView
get() = topToolbar.findViewById(R.id.tvStatus)
get() = binding.topToolbar.root.findViewById(R.id.tvStatus)
private val addNewButton: ImageView
get() = dataViewHeader.findViewById(R.id.addNewButton)
get() = binding.dataViewHeader.root.findViewById(R.id.addNewButton)
private val customizeViewButton: ImageView
get() = dataViewHeader.findViewById(R.id.customizeViewButton)
get() = binding.dataViewHeader.root.findViewById(R.id.customizeViewButton)
private val tvCurrentViewerName: TextView
get() = dataViewHeader.findViewById(R.id.tvCurrentViewerName)
get() = binding.dataViewHeader.root.findViewById(R.id.tvCurrentViewerName)
private val menuButton: FrameLayout
get() = topToolbar.findViewById(R.id.threeDotsButton)
get() = binding.topToolbar.root.findViewById(R.id.threeDotsButton)
private val featuredRelations: FeaturedRelationGroupWidget
get() = objectHeader.findViewById(R.id.featuredRelationsWidget)
get() = binding.objectHeader.root.findViewById(R.id.featuredRelationsWidget)
private val rvHeaders: RecyclerView get() = root.findViewById(R.id.rvHeader)
private val rvRows: RecyclerView get() = root.findViewById(R.id.rvRows)
private val rvHeaders: RecyclerView get() = binding.root.findViewById(R.id.rvHeader)
private val rvRows: RecyclerView get() = binding.root.findViewById(R.id.rvRows)
private val bottomPanelTranslationDelta: Float
get() = (bottomPanel.height + bottomPanel.marginBottom).toFloat()
get() = (binding.bottomPanel.root.height + binding.bottomPanel.root.marginBottom).toFloat()
private val actionHandler: (Int) -> Boolean = { action ->
action == IME_ACTION_GO || action == IME_ACTION_DONE
@ -153,7 +154,7 @@ open class ObjectSetFragment :
setupGridAdapters(view)
title.clearFocus()
topToolbarTitle.alpha = 0f
root.setTransitionListener(transitionListener)
binding.root.setTransitionListener(transitionListener)
with(lifecycleScope) {
subscribe(addNewButton.clicks()) { vm.onCreateNewRecord() }
@ -167,28 +168,28 @@ open class ObjectSetFragment :
subscribe(menuButton.clicks()) { vm.onMenuClicked() }
subscribe(customizeViewButton.clicks()) { vm.onViewerCustomizeButtonClicked() }
subscribe(tvCurrentViewerName.clicks()) { vm.onExpandViewerMenuClicked() }
subscribe(unsupportedViewError.clicks()) { vm.onUnsupportedViewErrorClicked() }
subscribe(bottomPanel.findViewById<FrameLayout>(R.id.btnFilter).clicks()) {
subscribe(binding.unsupportedViewError.clicks()) { vm.onUnsupportedViewErrorClicked() }
subscribe(binding.bottomPanel.root.findViewById<FrameLayout>(R.id.btnFilter).clicks()) {
vm.onViewerFiltersClicked()
}
subscribe(bottomPanel.findViewById<FrameLayout>(R.id.btnRelations).clicks()) {
subscribe(binding.bottomPanel.root.findViewById<FrameLayout>(R.id.btnRelations).clicks()) {
vm.onViewerRelationsClicked()
}
subscribe(bottomPanel.findViewById<FrameLayout>(R.id.btnSort).clicks()) {
subscribe(binding.bottomPanel.root.findViewById<FrameLayout>(R.id.btnSort).clicks()) {
vm.onViewerSortsClicked()
}
subscribe(bottomPanel.findViewById<FrameLayout>(R.id.btnGroup).clicks()) {
subscribe(binding.bottomPanel.root.findViewById<FrameLayout>(R.id.btnGroup).clicks()) {
toast(getString(R.string.coming_soon))
}
subscribe(bottomPanel.touches()) { swipeDetector.onTouchEvent(it) }
subscribe(binding.bottomPanel.root.touches()) { swipeDetector.onTouchEvent(it) }
subscribe(bottomToolbar.homeClicks()) { vm.onHomeButtonClicked() }
subscribe(bottomToolbar.backClicks()) { vm.onBackButtonClicked() }
subscribe(bottomToolbar.searchClicks()) { vm.onSearchButtonClicked() }
subscribe(binding.bottomToolbar.homeClicks()) { vm.onHomeButtonClicked() }
subscribe(binding.bottomToolbar.backClicks()) { vm.onBackButtonClicked() }
subscribe(binding.bottomToolbar.searchClicks()) { vm.onSearchButtonClicked() }
}
with(paginatorToolbar) {
with(binding.paginatorToolbar) {
onNumberClickCallback = { (num, isSelected) ->
vm.onPaginatorToolbarNumberClicked(num, isSelected)
}
@ -196,19 +197,19 @@ open class ObjectSetFragment :
onPrevious = { vm.onPaginatorNextElsePrevious(false) }
}
galleryView.onGalleryItemClicked = { id ->
binding.galleryView.onGalleryItemClicked = { id ->
vm.onObjectHeaderClicked(id)
}
galleryView.onTaskCheckboxClicked = { id ->
binding.galleryView.onTaskCheckboxClicked = { id ->
vm.onTaskCheckboxClicked(id)
}
listView.onListItemClicked = { id ->
binding.listView.onListItemClicked = { id ->
vm.onObjectHeaderClicked(id)
}
listView.onTaskCheckboxClicked = { id ->
binding.listView.onTaskCheckboxClicked = { id ->
vm.onTaskCheckboxClicked(id)
}
}
@ -242,7 +243,7 @@ open class ObjectSetFragment :
)
}
gridContainer.setOnScrollChangeListener { _, scrollX, _, _, _ ->
binding.gridContainer.root.setOnScrollChangeListener { _, scrollX, _, _, _ ->
val translationX = scrollX.toFloat()
viewerGridAdapter.recordNamePositionX = translationX
rvRows.children.forEach { child ->
@ -252,7 +253,7 @@ open class ObjectSetFragment :
}
private fun showBottomPanel() {
val animation = bottomPanel.animate().translationY(-bottomPanelTranslationDelta).apply {
val animation = binding.bottomPanel.root.animate().translationY(-bottomPanelTranslationDelta).apply {
duration = BOTTOM_PANEL_ANIM_DURATION
interpolator = AccelerateDecelerateInterpolator()
}
@ -260,7 +261,7 @@ open class ObjectSetFragment :
}
private fun hideBottomPanel() {
val animation = bottomPanel.animate().translationY(0f).apply {
val animation = binding.bottomPanel.root.animate().translationY(0f).apply {
duration = BOTTOM_PANEL_ANIM_DURATION
interpolator = AccelerateDecelerateInterpolator()
}
@ -291,8 +292,8 @@ open class ObjectSetFragment :
}
private fun setStatus(status: SyncStatus) {
topToolbar.findViewById<StatusBadgeWidget>(R.id.statusBadge).bind(status)
val tvStatus = topToolbar.findViewById<TextView>(R.id.tvStatus)
binding.topToolbar.root.findViewById<StatusBadgeWidget>(R.id.statusBadge).bind(status)
val tvStatus = binding.topToolbar.root.findViewById<TextView>(R.id.tvStatus)
when (status) {
SyncStatus.UNKNOWN -> tvStatus.setText(R.string.sync_status_unknown)
SyncStatus.FAILED -> tvStatus.setText(R.string.sync_status_failed)
@ -303,72 +304,80 @@ open class ObjectSetFragment :
}
private fun observeGrid(viewer: Viewer) {
dataViewHeader.findViewById<TextView>(R.id.tvCurrentViewerName).text = viewer.title
binding.dataViewHeader.root.findViewById<TextView>(R.id.tvCurrentViewerName).text = viewer.title
when (viewer) {
is Viewer.GridView -> {
unsupportedViewError.gone()
unsupportedViewError.text = null
galleryView.clear()
galleryView.gone()
listView.gone()
listView.setViews(emptyList())
with(binding) {
unsupportedViewError.gone()
unsupportedViewError.text = null
galleryView.clear()
galleryView.gone()
listView.gone()
listView.setViews(emptyList())
}
viewerGridHeaderAdapter.submitList(viewer.columns)
viewerGridAdapter.submitList(viewer.rows)
}
is Viewer.GalleryView -> {
unsupportedViewError.gone()
unsupportedViewError.text = null
viewerGridHeaderAdapter.submitList(emptyList())
viewerGridAdapter.submitList(emptyList())
listView.gone()
listView.setViews(emptyList())
galleryView.visible()
galleryView.setViews(
views = viewer.items,
largeCards = viewer.largeCards
)
with(binding) {
unsupportedViewError.gone()
unsupportedViewError.text = null
listView.gone()
listView.setViews(emptyList())
galleryView.visible()
galleryView.setViews(
views = viewer.items,
largeCards = viewer.largeCards
)
}
}
is Viewer.ListView -> {
unsupportedViewError.gone()
unsupportedViewError.text = null
galleryView.gone()
galleryView.clear()
viewerGridHeaderAdapter.submitList(emptyList())
viewerGridAdapter.submitList(emptyList())
listView.visible()
listView.setViews(viewer.items)
with(binding) {
unsupportedViewError.gone()
unsupportedViewError.text = null
galleryView.gone()
galleryView.clear()
listView.visible()
listView.setViews(viewer.items)
}
}
is Viewer.Unsupported -> {
viewerGridHeaderAdapter.submitList(emptyList())
viewerGridAdapter.submitList(emptyList())
galleryView.gone()
galleryView.clear()
listView.gone()
listView.setViews(emptyList())
unsupportedViewError.visible()
unsupportedViewError.text = viewer.error
with(binding) {
galleryView.gone()
galleryView.clear()
listView.gone()
listView.setViews(emptyList())
unsupportedViewError.visible()
unsupportedViewError.text = viewer.error
}
}
}
}
private fun bindHeader(title: BlockView.Title.Basic) {
this.title.setText(title.text)
topToolbar.findViewById<TextView>(R.id.tvTopToolbarTitle).text = title.text
binding.topToolbar.root.findViewById<TextView>(R.id.tvTopToolbarTitle).text = title.text
objectHeader.findViewById<ViewGroup>(R.id.docEmojiIconContainer).apply {
binding.objectHeader.root.findViewById<ViewGroup>(R.id.docEmojiIconContainer).apply {
if (title.emoji != null) visible() else gone()
setOnClickListener { vm.onIconClicked() }
}
objectHeader.findViewById<ViewGroup>(R.id.docImageIconContainer).apply {
binding.objectHeader.root.findViewById<ViewGroup>(R.id.docImageIconContainer).apply {
if (title.image != null) visible() else gone()
setOnClickListener { vm.onIconClicked() }
}
objectHeader.findViewById<ImageView>(R.id.emojiIcon).setEmojiOrNull(title.emoji)
binding.objectHeader.root.findViewById<ImageView>(R.id.emojiIcon).setEmojiOrNull(title.emoji)
if (title.image != null) {
objectHeader.findViewById<ImageView>(R.id.imageIcon).apply {
binding.objectHeader.root.findViewById<ImageView>(R.id.imageIcon).apply {
Glide
.with(this)
.load(title.image)
@ -376,7 +385,7 @@ open class ObjectSetFragment :
.into(this)
}
} else {
objectHeader.findViewById<ImageView>(R.id.imageIcon).setImageDrawable(null)
binding.objectHeader.root.findViewById<ImageView>(R.id.imageIcon).setImageDrawable(null)
}
setCover(
@ -391,8 +400,8 @@ open class ObjectSetFragment :
coverImage: String?,
coverGradient: String?
) {
val ivCover = objectHeader.findViewById<ImageView>(R.id.cover)
val container = objectHeader.findViewById<FrameLayout>(R.id.coverAndIconContainer)
val ivCover = binding.objectHeader.root.findViewById<ImageView>(R.id.cover)
val container = binding.objectHeader.root.findViewById<FrameLayout>(R.id.coverAndIconContainer)
ivCover.setOnClickListener { vm.onCoverClicked() }
when {
coverColor != null -> {
@ -455,7 +464,7 @@ open class ObjectSetFragment :
topToolbarStatusContainer.apply {
setBackgroundResource(R.drawable.rect_object_menu_button_default)
}
if (root.currentState == R.id.start) {
if (binding.root.currentState == R.id.start) {
topToolbarStatusText.setTextColor(Color.WHITE)
topToolbarThreeDotsIcon.apply {
imageTintList = ColorStateList.valueOf(Color.WHITE)
@ -640,7 +649,7 @@ open class ObjectSetFragment :
title.enableReadMode()
topToolbarStatusText.animate().alpha(0f).setDuration(DEFAULT_ANIM_DURATION).start()
topToolbarTitle.animate().alpha(1f).setDuration(DEFAULT_ANIM_DURATION).start()
topToolbar.findViewById<ImageView>(R.id.ivThreeDots).apply {
binding.topToolbar.root.findViewById<ImageView>(R.id.ivThreeDots).apply {
imageTintList = null
}
topToolbarThreeDotsButton.apply {
@ -661,20 +670,20 @@ open class ObjectSetFragment :
jobs += lifecycleScope.subscribe(vm.commands) { observeCommands(it) }
jobs += lifecycleScope.subscribe(vm.header.filterNotNull()) { bindHeader(it) }
jobs += lifecycleScope.subscribe(vm.viewerGrid) { observeGrid(it) }
jobs += lifecycleScope.subscribe(vm.error) { tvError.text = it }
jobs += lifecycleScope.subscribe(vm.error) { binding.tvError.text = it }
jobs += lifecycleScope.subscribe(vm.pagination) { (index, count) ->
paginatorToolbar.set(count = count, index = index)
binding.paginatorToolbar.set(count = count, index = index)
if (count > 1) {
paginatorToolbar.visible()
binding.paginatorToolbar.visible()
} else {
paginatorToolbar.gone()
binding.paginatorToolbar.gone()
}
}
jobs += lifecycleScope.subscribe(vm.isLoading) { isLoading ->
if (isLoading) {
dvProgressBar.show()
binding.dvProgressBar.show()
} else {
dvProgressBar.hide()
binding.dvProgressBar.hide()
}
}
vm.onStart(ctx)
@ -759,6 +768,13 @@ open class ObjectSetFragment :
componentManager().objectSetComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentObjectSetBinding = FragmentObjectSetBinding.inflate(
inflater, container, false
)
companion object {
const val CONTEXT_ID_KEY = "arg.object_set.context"
val EMPTY_TAG = null

View file

@ -9,19 +9,18 @@ import android.view.inputmethod.EditorInfo
import androidx.core.os.bundleOf
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_ui.reactive.editorActionEvents
import com.anytypeio.anytype.core_utils.ext.argString
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.databinding.FragmentSetObjectSetRecordNameBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.ObjectSetRecordViewModel
import kotlinx.android.synthetic.main.fragment_set_object_set_record_name.*
import javax.inject.Inject
class SetObjectSetRecordNameFragment : BaseBottomSheetFragment() {
class SetObjectSetRecordNameFragment : BaseBottomSheetFragment<FragmentSetObjectSetRecordNameBinding>() {
private val ctx: String get() = argString(CONTEXT_KEY)
@ -33,21 +32,15 @@ class SetObjectSetRecordNameFragment : BaseBottomSheetFragment() {
action == EditorInfo.IME_ACTION_DONE
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_set_object_set_record_name, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
textInputField.apply {
binding.textInputField.apply {
setRawInputType(TYPE_CLASS_TEXT or TYPE_TEXT_FLAG_CAP_SENTENCES or TYPE_TEXT_FLAG_AUTO_CORRECT)
}
lifecycleScope.subscribe(textInputField.editorActionEvents(handler)) {
textInputField.clearFocus()
textInputField.hideKeyboard()
vm.onComplete(ctx, textInputField.text.toString())
lifecycleScope.subscribe(binding.textInputField.editorActionEvents(handler)) {
binding.textInputField.clearFocus()
binding.textInputField.hideKeyboard()
vm.onComplete(ctx, binding.textInputField.text.toString())
}
}
@ -64,6 +57,13 @@ class SetObjectSetRecordNameFragment : BaseBottomSheetFragment() {
componentManager().objectSetRecordComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentSetObjectSetRecordNameBinding = FragmentSetObjectSetRecordNameBinding.inflate(
inflater, container, false
)
companion object {
const val CONTEXT_KEY = "arg.object-set-record.context"

View file

@ -16,6 +16,7 @@ import com.anytypeio.anytype.core_ui.layout.DividerVerticalItemDecoration
import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentFilterBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.filter.ViewerFilterCommand
import com.anytypeio.anytype.presentation.sets.filter.ViewerFilterViewModel
@ -23,10 +24,9 @@ import com.anytypeio.anytype.ui.sets.modals.ViewerBottomSheetRootFragment
import com.anytypeio.anytype.ui.sets.modals.filter.CreateFilterFlowRootFragment
import com.anytypeio.anytype.ui.sets.modals.filter.ModifyFilterFromInputFieldValueFragment
import com.anytypeio.anytype.ui.sets.modals.filter.ModifyFilterFromSelectedValueFragment
import kotlinx.android.synthetic.main.fragment_filter.*
import javax.inject.Inject
open class ViewerFilterFragment : BaseBottomSheetFragment() {
open class ViewerFilterFragment : BaseBottomSheetFragment<FragmentFilterBinding>() {
private val ctx get() = argString(CONTEXT_ID_KEY)
@ -40,21 +40,15 @@ open class ViewerFilterFragment : BaseBottomSheetFragment() {
lateinit var factory: ViewerFilterViewModel.Factory
private val vm: ViewerFilterViewModel by viewModels { factory }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_filter, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recycler.layoutManager = LinearLayoutManager(requireContext())
recycler.adapter = filterAdapter
binding.recycler.layoutManager = LinearLayoutManager(requireContext())
binding.recycler.adapter = filterAdapter
with(lifecycleScope) {
subscribe(vm.commands) { observeCommands(it) }
subscribe(addButton.clicks()) { vm.onAddNewFilterClicked() }
subscribe(doneBtn.clicks()) { vm.onDoneButtonClicked() }
subscribe(editBtn.clicks()) { vm.onEditButtonClicked() }
subscribe(binding.addButton.clicks()) { vm.onAddNewFilterClicked() }
subscribe(binding.doneBtn.clicks()) { vm.onDoneButtonClicked() }
subscribe(binding.editBtn.clicks()) { vm.onEditButtonClicked() }
}
}
@ -69,45 +63,51 @@ open class ViewerFilterFragment : BaseBottomSheetFragment() {
private fun render(state: ViewerFilterViewModel.ScreenState) {
when (state) {
ViewerFilterViewModel.ScreenState.LIST -> {
editBtn.visible()
addButton.visible()
doneBtn.invisible()
txtEmptyState.gone()
removeDivider()
recycler.addItemDecoration(
DividerVerticalItemDecoration(
divider = requireContext().drawable(R.drawable.divider_filter_list),
isShowInLastItem = false
),
0
)
with(binding) {
editBtn.visible()
addButton.visible()
doneBtn.invisible()
txtEmptyState.gone()
recycler.addItemDecoration(
DividerVerticalItemDecoration(
divider = requireContext().drawable(R.drawable.divider_filter_list),
isShowInLastItem = false
),
0
)
}
}
ViewerFilterViewModel.ScreenState.EDIT -> {
doneBtn.visible()
editBtn.invisible()
addButton.invisible()
txtEmptyState.gone()
removeDivider()
recycler.addItemDecoration(
DividerVerticalItemDecoration(
divider = requireContext().drawable(R.drawable.divider_filter_edit),
isShowInLastItem = false
),
0
)
with(binding) {
doneBtn.visible()
editBtn.invisible()
addButton.invisible()
txtEmptyState.gone()
recycler.addItemDecoration(
DividerVerticalItemDecoration(
divider = requireContext().drawable(R.drawable.divider_filter_edit),
isShowInLastItem = false
),
0
)
}
}
ViewerFilterViewModel.ScreenState.EMPTY -> {
doneBtn.invisible()
editBtn.invisible()
addButton.visible()
txtEmptyState.visible()
removeDivider()
with(binding) {
doneBtn.invisible()
editBtn.invisible()
addButton.visible()
txtEmptyState.visible()
}
}
}
}
private fun removeDivider() {
if (recycler.itemDecorationCount > 0) recycler.removeItemDecorationAt(0)
if (binding.recycler.itemDecorationCount > 0) binding.recycler.removeItemDecorationAt(0)
}
private fun observeCommands(command: ViewerFilterCommand) {
@ -153,6 +153,13 @@ open class ViewerFilterFragment : BaseBottomSheetFragment() {
componentManager().viewerFilterComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentFilterBinding = FragmentFilterBinding.inflate(
inflater, container, false
)
companion object {
const val CONTEXT_ID_KEY = "arg.viewer.filters.context"

View file

@ -15,6 +15,7 @@ import com.anytypeio.anytype.core_utils.ext.argString
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ext.withParent
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentSortingBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.ViewerSortByCommand
import com.anytypeio.anytype.presentation.sets.ViewerSortByViewModel
@ -23,10 +24,9 @@ import com.anytypeio.anytype.presentation.sets.model.Viewer
import com.anytypeio.anytype.ui.sets.modals.PickSortingKeyFragment
import com.anytypeio.anytype.ui.sets.modals.PickSortingTypeFragment
import com.anytypeio.anytype.ui.sets.modals.ViewerBottomSheetRootFragment
import kotlinx.android.synthetic.main.fragment_sorting.*
import javax.inject.Inject
class ViewerSortByFragment : BaseBottomSheetFragment() {
class ViewerSortByFragment : BaseBottomSheetFragment<FragmentSortingBinding>() {
private val sortingAdapter by lazy {
SortByAdapter(click = vm::itemClicked)
@ -47,12 +47,12 @@ class ViewerSortByFragment : BaseBottomSheetFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(recyclerView) {
with(binding.recyclerView) {
adapter = sortingAdapter
}
lifecycleScope.subscribe(vm.viewState) { observeState(it) }
lifecycleScope.subscribe(vm.commands.stream()) { observeCommands(it) }
lifecycleScope.subscribe(ivBack.clicks()) { vm.onBackClicked() }
lifecycleScope.subscribe(binding.ivBack.clicks()) { vm.onBackClicked() }
vm.onViewCreated(viewer)
}
@ -119,6 +119,13 @@ class ViewerSortByFragment : BaseBottomSheetFragment() {
componentManager().viewerSortByComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentSortingBinding = FragmentSortingBinding.inflate(
inflater, container, false
)
companion object {
const val CONTEXT_ID_KEY = "arg.viewer.sorts.context"
const val VIEWER_ID_KEY = "arg.viewer.sorts.viewer_id"

View file

@ -6,7 +6,6 @@ import android.view.*
import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.R
import kotlinx.android.synthetic.main.fragment_list.*
abstract class BaseDialogListFragment : DialogFragment() {
@ -28,7 +27,7 @@ abstract class BaseDialogListFragment : DialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setAdapter(recycler)
setAdapter(view.findViewById(R.id.recycler))
}
override fun onStart() {

View file

@ -7,16 +7,15 @@ import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentCreateDataViewViewerBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.CreateDataViewViewerViewModel
import kotlinx.android.synthetic.main.fragment_create_data_view_viewer.*
import javax.inject.Inject
class CreateDataViewViewerFragment : BaseBottomSheetFragment() {
class CreateDataViewViewerFragment : BaseBottomSheetFragment<FragmentCreateDataViewViewerBinding>() {
val ctx get() = arg<String>(CTX_KEY)
val target get() = arg<String>(TARGET_KEY)
@ -25,25 +24,19 @@ class CreateDataViewViewerFragment : BaseBottomSheetFragment() {
lateinit var factory: CreateDataViewViewerViewModel.Factory
private val vm: CreateDataViewViewerViewModel by viewModels { factory }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_create_data_view_viewer, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(lifecycleScope) {
subscribe(btnCreateViewer.clicks()) {
subscribe(binding.btnCreateViewer.clicks()) {
vm.onAddViewer(
name = viewerNameInput.text.toString(),
name = binding.viewerNameInput.text.toString(),
ctx = ctx,
target = target
)
}
subscribe(gridContainer.clicks()) { vm.onGridClicked() }
subscribe(galleryContainer.clicks()) { vm.onGalleryClicked() }
subscribe(listContainer.clicks()) { vm.onListClicked() }
subscribe(binding.gridContainer.clicks()) { vm.onGridClicked() }
subscribe(binding.galleryContainer.clicks()) { vm.onGalleryClicked() }
subscribe(binding.listContainer.clicks()) { vm.onListClicked() }
}
}
@ -57,9 +50,9 @@ class CreateDataViewViewerFragment : BaseBottomSheetFragment() {
private fun render(state: CreateDataViewViewerViewModel.ViewState) {
when (state) {
CreateDataViewViewerViewModel.ViewState.Init -> {
isListChosen.invisible()
isTableChosen.visible()
isGalleryChosen.invisible()
binding.isListChosen.invisible()
binding.isTableChosen.visible()
binding.isGalleryChosen.invisible()
}
CreateDataViewViewerViewModel.ViewState.Completed -> {
dismiss()
@ -68,20 +61,20 @@ class CreateDataViewViewerFragment : BaseBottomSheetFragment() {
toast(state.msg)
}
CreateDataViewViewerViewModel.ViewState.Gallery -> {
isListChosen.invisible()
isTableChosen.invisible()
isGalleryChosen.visible()
binding.isListChosen.invisible()
binding.isTableChosen.invisible()
binding.isGalleryChosen.visible()
}
CreateDataViewViewerViewModel.ViewState.Grid -> {
isListChosen.invisible()
isTableChosen.visible()
isGalleryChosen.invisible()
binding.isListChosen.invisible()
binding.isTableChosen.visible()
binding.isGalleryChosen.invisible()
}
CreateDataViewViewerViewModel.ViewState.List -> {
isListChosen.visible()
isTableChosen.invisible()
isGalleryChosen.invisible()
binding.isListChosen.visible()
binding.isTableChosen.invisible()
binding.isGalleryChosen.invisible()
}
}
}
@ -94,6 +87,13 @@ class CreateDataViewViewerFragment : BaseBottomSheetFragment() {
componentManager().createDataViewViewerComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentCreateDataViewViewerBinding = FragmentCreateDataViewViewerBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: String, target: String) = CreateDataViewViewerFragment().apply {
arguments = bundleOf(

View file

@ -14,13 +14,13 @@ import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_utils.ext.arg
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ui.BaseDialogFragment
import com.anytypeio.anytype.databinding.FragmentDataViewViewerActionsBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.DataViewViewerActionViewModel
import kotlinx.android.synthetic.main.fragment_data_view_viewer_actions.*
import javax.inject.Inject
@Deprecated("Legacy")
class DataViewViewerActionFragment : BaseDialogFragment() {
class DataViewViewerActionFragment : BaseDialogFragment<FragmentDataViewViewerActionsBinding>() {
private val ctx: String get() = arg(CTX_KEY)
private val viewer: String get() = arg(VIEWER_KEY)
@ -31,23 +31,17 @@ class DataViewViewerActionFragment : BaseDialogFragment() {
private val vm: DataViewViewerActionViewModel by viewModels { factory }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_data_view_viewer_actions, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
tvTitle.text = title
binding.tvTitle.text = title
with(lifecycleScope) {
subscribe(duplicateViewContainer.clicks()) {
subscribe(binding.duplicateViewContainer.clicks()) {
vm.onDuplicateClicked(ctx = ctx, viewer = viewer)
}
subscribe(deleteViewContainer.clicks()) {
subscribe(binding.deleteViewContainer.clicks()) {
vm.onDeleteClicked(ctx = ctx, viewer = viewer)
}
subscribe(editViewContainer.clicks()) {
subscribe(binding.editViewContainer.clicks()) {
val fr = EditDataViewViewerFragment.new(
ctx = ctx,
viewer = viewer
@ -77,6 +71,13 @@ class DataViewViewerActionFragment : BaseDialogFragment() {
componentManager().dataviewViewerActionComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentDataViewViewerActionsBinding = FragmentDataViewViewerActionsBinding.inflate(
inflater, container, false
)
private fun setupAppearance() {
dialog?.window?.apply {
setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)

View file

@ -5,39 +5,31 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ext.argLong
import com.anytypeio.anytype.core_utils.ext.timeInSeconds
import com.anytypeio.anytype.core_utils.ext.withParent
import kotlinx.android.synthetic.main.fragment_date_picker.*
import timber.log.Timber
import com.anytypeio.anytype.core_utils.ui.BaseDialogFragment
import com.anytypeio.anytype.databinding.FragmentDatePickerBinding
import java.util.*
class DatePickerFragment : DialogFragment() {
class DatePickerFragment : BaseDialogFragment<FragmentDatePickerBinding>() {
private val mTimeInSeconds get() = argLong(TIMESTAMP_KEY)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_date_picker, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setTransparentBackground()
initializePicker()
saveButton.setOnClickListener {
binding.saveButton.setOnClickListener {
dispatchResultAndDismiss()
}
}
private fun dispatchResultAndDismiss() {
val calendar = Calendar.getInstance().apply {
set(Calendar.YEAR, picker.year)
set(Calendar.MONTH, picker.month)
set(Calendar.DAY_OF_MONTH, picker.dayOfMonth)
set(Calendar.YEAR, binding.picker.year)
set(Calendar.MONTH, binding.picker.month)
set(Calendar.DAY_OF_MONTH, binding.picker.dayOfMonth)
}
withParent<DatePickerReceiver> { onPickDate(calendar.timeInSeconds()) }
dismiss()
@ -51,7 +43,7 @@ class DatePickerFragment : DialogFragment() {
Date(System.currentTimeMillis())
}
}
picker.init(
binding.picker.init(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
@ -63,6 +55,16 @@ class DatePickerFragment : DialogFragment() {
dialog?.window?.setBackgroundDrawableResource(android.R.color.transparent)
}
override fun injectDependencies() {}
override fun releaseDependencies() {}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentDatePickerBinding = FragmentDatePickerBinding.inflate(
inflater, container, false
)
companion object {
fun new(timeInSeconds: Long?) = DatePickerFragment().apply {

View file

@ -14,12 +14,12 @@ import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_ui.reactive.textChanges
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentEditDataViewViewerBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.EditDataViewViewerViewModel
import kotlinx.android.synthetic.main.fragment_edit_data_view_viewer.*
import javax.inject.Inject
class EditDataViewViewerFragment : BaseBottomSheetFragment() {
class EditDataViewViewerFragment : BaseBottomSheetFragment<FragmentEditDataViewViewerBinding>() {
private val ctx: Id get() = arg(CTX_KEY)
private val viewer: Id get() = arg(VIEWER_KEY)
@ -28,25 +28,19 @@ class EditDataViewViewerFragment : BaseBottomSheetFragment() {
lateinit var factory: EditDataViewViewerViewModel.Factory
private val vm: EditDataViewViewerViewModel by viewModels { factory }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_edit_data_view_viewer, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(lifecycleScope) {
subscribe(viewerNameInput.textChanges()) { name ->
subscribe(binding.viewerNameInput.textChanges()) { name ->
vm.onViewerNameChanged(name = name.toString())
}
subscribe(btnDone.clicks()) {
subscribe(binding.btnDone.clicks()) {
vm.onDoneClicked(ctx, viewer)
}
subscribe(threeDotsButton.clicks()) { vm.onMenuClicked() }
subscribe(gridContainer.clicks()) { vm.onGridClicked() }
subscribe(galleryContainer.clicks()) { vm.onGalleryClicked() }
subscribe(listContainer.clicks()) { vm.onListClicked() }
subscribe(binding.threeDotsButton.clicks()) { vm.onMenuClicked() }
subscribe(binding.gridContainer.clicks()) { vm.onGridClicked() }
subscribe(binding.galleryContainer.clicks()) { vm.onGalleryClicked() }
subscribe(binding.listContainer.clicks()) { vm.onListClicked() }
}
}
@ -55,7 +49,7 @@ class EditDataViewViewerFragment : BaseBottomSheetFragment() {
jobs += subscribe(vm.viewState) { render(it) }
jobs += subscribe(vm.isDismissed) { isDismissed ->
if (isDismissed) {
viewerNameInput.apply {
binding.viewerNameInput.apply {
clearFocus()
hideKeyboard()
}
@ -63,13 +57,13 @@ class EditDataViewViewerFragment : BaseBottomSheetFragment() {
}
}
jobs += subscribe(vm.isLoading) { isLoading ->
if (isLoading) progressBar.visible() else progressBar.gone()
if (isLoading) binding.progressBar.visible() else binding.progressBar.gone()
}
jobs += subscribe(vm.toasts) { toast(it) }
jobs += subscribe(vm.popupCommands) { cmd ->
DataViewEditViewPopupMenu(
requireContext(),
threeDotsButton,
binding.threeDotsButton,
cmd.isDeletionAllowed
).apply {
setOnMenuItemClickListener { item ->
@ -89,13 +83,15 @@ class EditDataViewViewerFragment : BaseBottomSheetFragment() {
private fun render(state: EditDataViewViewerViewModel.ViewState) {
when (state) {
EditDataViewViewerViewModel.ViewState.Init -> {
viewerNameInput.text = null
isListChosen.invisible()
isTableChosen.invisible()
isGalleryChosen.invisible()
with(binding) {
viewerNameInput.text = null
isListChosen.invisible()
isTableChosen.invisible()
isGalleryChosen.invisible()
}
}
is EditDataViewViewerViewModel.ViewState.Name -> {
viewerNameInput.setText(state.name)
binding.viewerNameInput.setText(state.name)
}
EditDataViewViewerViewModel.ViewState.Completed -> {
dismiss()
@ -104,20 +100,26 @@ class EditDataViewViewerFragment : BaseBottomSheetFragment() {
toast(state.msg)
}
EditDataViewViewerViewModel.ViewState.Gallery -> {
isListChosen.invisible()
isTableChosen.invisible()
isGalleryChosen.visible()
with(binding) {
isListChosen.invisible()
isTableChosen.invisible()
isGalleryChosen.visible()
}
}
EditDataViewViewerViewModel.ViewState.Grid -> {
isListChosen.invisible()
isTableChosen.visible()
isGalleryChosen.invisible()
with(binding) {
isListChosen.invisible()
isTableChosen.visible()
isGalleryChosen.invisible()
}
}
EditDataViewViewerViewModel.ViewState.List -> {
isListChosen.visible()
isTableChosen.invisible()
isGalleryChosen.invisible()
with(binding) {
isListChosen.visible()
isTableChosen.invisible()
isGalleryChosen.invisible()
}
}
EditDataViewViewerViewModel.ViewState.Kanban -> {}
}
@ -131,6 +133,13 @@ class EditDataViewViewerFragment : BaseBottomSheetFragment() {
componentManager().editDataViewViewerComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentEditDataViewViewerBinding = FragmentEditDataViewViewerBinding.inflate(
inflater, container, false
)
companion object {
const val CTX_KEY = "arg.edit-data-view-viewer.ctx"
const val VIEWER_KEY = "arg.edit-data-view-viewer.viewer"

View file

@ -19,13 +19,14 @@ import com.anytypeio.anytype.core_ui.tools.DefaultDragAndDropBehavior
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.core_utils.ui.OnStartDragListener
import com.anytypeio.anytype.databinding.FragmentManageViewerBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.ManageViewerViewModel
import kotlinx.android.synthetic.main.fragment_manage_viewer.*
import kotlinx.coroutines.launch
import javax.inject.Inject
class ManageViewerFragment : BaseBottomSheetFragment(), OnStartDragListener {
class ManageViewerFragment : BaseBottomSheetFragment<FragmentManageViewerBinding>(),
OnStartDragListener {
private val manageViewerAdapter by lazy {
ManageViewerDoneAdapter(
@ -56,20 +57,14 @@ class ManageViewerFragment : BaseBottomSheetFragment(), OnStartDragListener {
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_manage_viewer, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
dataViewViewerRecycler.apply {
binding.dataViewViewerRecycler.apply {
layoutManager = LinearLayoutManager(context)
}
with(lifecycleScope) {
subscribe(btnEditViewers.clicks()) { vm.onButtonEditClicked() }
subscribe(btnAddNewViewer.clicks()) { vm.onButtonAddClicked() }
subscribe(binding.btnEditViewers.clicks()) { vm.onButtonEditClicked() }
subscribe(binding.btnAddNewViewer.clicks()) { vm.onButtonAddClicked() }
}
}
@ -89,21 +84,25 @@ class ManageViewerFragment : BaseBottomSheetFragment(), OnStartDragListener {
}
jobs += subscribe(vm.isEditEnabled) { isEditEnabled ->
if (isEditEnabled) {
btnEditViewers.setText(R.string.done)
btnAddNewViewer.invisible()
dataViewViewerRecycler.apply {
adapter = manageViewerEditAdapter
//ToDo temporary blocked, because of missing middleware command
//dndItemTouchHelper.attachToRecyclerView(this)
with(binding) {
btnEditViewers.setText(R.string.done)
btnAddNewViewer.invisible()
dataViewViewerRecycler.apply {
adapter = manageViewerEditAdapter
//ToDo temporary blocked, because of missing middleware command
//dndItemTouchHelper.attachToRecyclerView(this)
}
}
} else {
btnEditViewers.setText(R.string.edit)
btnAddNewViewer.visible()
dataViewViewerRecycler.apply {
adapter = manageViewerAdapter
//ToDo temporary blocked, because of missing middleware command
//dndItemTouchHelper.attachToRecyclerView(null)
with(binding) {
btnEditViewers.setText(R.string.edit)
btnAddNewViewer.visible()
dataViewViewerRecycler.apply {
adapter = manageViewerAdapter
//ToDo temporary blocked, because of missing middleware command
//dndItemTouchHelper.attachToRecyclerView(null)
}
}
}
}
@ -138,6 +137,13 @@ class ManageViewerFragment : BaseBottomSheetFragment(), OnStartDragListener {
componentManager().manageViewerComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentManageViewerBinding = FragmentManageViewerBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: Id, dataview: Id): ManageViewerFragment = ManageViewerFragment().apply {
arguments = bundleOf(CTX_KEY to ctx, DATA_VIEW_KEY to dataview)

View file

@ -1,7 +1,7 @@
package com.anytypeio.anytype.ui.sets.modals
import android.os.Bundle
import android.view.*
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
@ -15,16 +15,17 @@ import com.anytypeio.anytype.core_utils.ext.argInt
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ext.withParent
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentSelectFilterConditionBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.filter.PickFilterConditionViewModel
import com.anytypeio.anytype.presentation.sets.model.Viewer
import com.anytypeio.anytype.ui.sets.modals.filter.UpdateConditionActionReceiver
import kotlinx.android.synthetic.main.fragment_select_filter_condition.*
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
class PickFilterConditionFragment : BaseBottomSheetFragment() {
class PickFilterConditionFragment :
BaseBottomSheetFragment<FragmentSelectFilterConditionBinding>() {
private val ctx: String get() = arg(CTX_KEY)
private val mode: Int get() = argInt(ARG_MODE)
@ -37,25 +38,17 @@ class PickFilterConditionFragment : BaseBottomSheetFragment() {
val isDismissed = MutableSharedFlow<Boolean>(replay = 0)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_select_filter_condition, container, false)
}
override fun onStart() {
super.onStart()
with(lifecycleScope) {
jobs += subscribe(isDismissed) { isDismissed -> if (isDismissed) dismiss() }
jobs += subscribe(vm.views) { screenState ->
recycler.adapter = PickFilterConditionAdapter(
binding.recycler.adapter = PickFilterConditionAdapter(
picked = screenState.picked,
conditions = screenState.conditions,
click = this@PickFilterConditionFragment::click
)
recycler.addItemDecoration(
binding.recycler.addItemDecoration(
DividerVerticalItemDecoration(
divider = requireContext().drawable(R.drawable.divider_relations),
isShowInLastItem = false
@ -89,6 +82,12 @@ class PickFilterConditionFragment : BaseBottomSheetFragment() {
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentSelectFilterConditionBinding = FragmentSelectFilterConditionBinding.inflate(
inflater, container, false
)
companion object {

View file

@ -9,16 +9,16 @@ import androidx.core.os.bundleOf
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentViewerCustomizeBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.presentation.sets.ViewerCustomizeViewModel
import com.anytypeio.anytype.presentation.sets.ViewerCustomizeViewState
import kotlinx.android.synthetic.main.fragment_viewer_customize.*
import javax.inject.Inject
class ViewerCustomizeFragment : BaseBottomSheetFragment() {
class ViewerCustomizeFragment : BaseBottomSheetFragment<FragmentViewerCustomizeBinding>() {
private val ctx get() = argString(CONTEXT_ID_KEY)
private val viewer get() = argString(VIEWER_ID_KEY)
@ -30,12 +30,6 @@ class ViewerCustomizeFragment : BaseBottomSheetFragment() {
lateinit var filtersCount: TextView
lateinit var sortsCount: TextView
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_viewer_customize, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
filtersCount = view.findViewById(R.id.filterCount)
@ -43,13 +37,13 @@ class ViewerCustomizeFragment : BaseBottomSheetFragment() {
lifecycleScope.subscribe(vm.viewState) {
observeViewState(it)
}
itemFilter.setOnClickListener {
binding.itemFilter.root.setOnClickListener {
withParent<ViewerBottomSheetRootFragment> { transitToFilter() }
}
itemSort.setOnClickListener {
binding.itemSort.root.setOnClickListener {
withParent<ViewerBottomSheetRootFragment> { transitToSorting() }
}
itemRelations.setOnClickListener {
binding.itemRelations.root.setOnClickListener {
withParent<ViewerBottomSheetRootFragment> { transitToRelations() }
}
vm.onViewCreated(viewerId = viewer)
@ -60,7 +54,7 @@ class ViewerCustomizeFragment : BaseBottomSheetFragment() {
ViewerCustomizeViewState.Init -> {
}
is ViewerCustomizeViewState.InitGrid -> {
itemTable.show()
binding.itemTable.root.show()
if (viewState.isShowFilterSize) {
filtersCount.text = viewState.filterSize
} else {
@ -83,6 +77,13 @@ class ViewerCustomizeFragment : BaseBottomSheetFragment() {
componentManager().viewerCustomizeComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentViewerCustomizeBinding = FragmentViewerCustomizeBinding.inflate(
inflater, container, false
)
companion object {
const val CONTEXT_ID_KEY = "arg.viewer.customize.context"
const val VIEWER_ID_KEY = "arg.viewer.customize.viewer_id"

View file

@ -15,33 +15,27 @@ import com.anytypeio.anytype.core_utils.ext.arg
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ui.BaseDialogFragment
import com.anytypeio.anytype.databinding.FragmentViewerRelationOptionBinding
import com.anytypeio.anytype.presentation.sets.model.ColumnView
import kotlinx.android.synthetic.main.fragment_viewer_relation_option.*
import java.util.*
class ViewerRelationOptionFragment : BaseDialogFragment() {
class ViewerRelationOptionFragment : BaseDialogFragment<FragmentViewerRelationOptionBinding>() {
private val ctx: String get() = arg(CTX_KEY)
private val relation: String get() = arg(RELATION_KEY)
private val format: ColumnView.Format? get() = requireArguments().getParcelable(FORMAT_KEY)
private val title: String get() = arg(TITLE_KEY)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_viewer_relation_option, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
tvTitle.text = title
binding.tvTitle.text = title
format?.let {
tvFormat.text = it.name.toLowerCase(Locale.ROOT).capitalize(Locale.ROOT)
iconFormat.setBackgroundResource(it.relationIcon())
binding.tvFormat.text = it.name.toLowerCase(Locale.ROOT).capitalize(Locale.ROOT)
binding.iconFormat.setBackgroundResource(it.relationIcon())
}
with(lifecycleScope) {
subscribe(openToEditViewContainer.clicks()) { toast("Not implemented yet") }
subscribe(removeViewContainer.clicks()) { toast("Not implemented yet") }
subscribe(binding.openToEditViewContainer.clicks()) { toast("Not implemented yet") }
subscribe(binding.removeViewContainer.clicks()) { toast("Not implemented yet") }
}
}
@ -65,6 +59,13 @@ class ViewerRelationOptionFragment : BaseDialogFragment() {
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentViewerRelationOptionBinding = FragmentViewerRelationOptionBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: Id, title: String, relation: Id, format: ColumnView.Format) =
ViewerRelationOptionFragment().apply {

View file

@ -22,16 +22,17 @@ import com.anytypeio.anytype.core_ui.tools.DefaultDragAndDropBehavior
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.core_utils.ui.OnStartDragListener
import com.anytypeio.anytype.databinding.FragmentViewerRelationsListBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.relations.ViewerRelationsViewModel
import com.anytypeio.anytype.presentation.sets.model.SimpleRelationView
import com.anytypeio.anytype.ui.relations.RelationAddToDataViewFragment
import com.anytypeio.anytype.ui.sets.modals.viewer.ViewerCardSizeSelectFragment
import com.anytypeio.anytype.ui.sets.modals.viewer.ViewerImagePreviewSelectFragment
import kotlinx.android.synthetic.main.fragment_viewer_relations_list.*
import javax.inject.Inject
class ViewerRelationsFragment : BaseBottomSheetFragment(), OnStartDragListener {
class ViewerRelationsFragment : BaseBottomSheetFragment<FragmentViewerRelationsListBinding>(),
OnStartDragListener {
@Inject
lateinit var factory: ViewerRelationsViewModel.Factory
@ -112,12 +113,6 @@ class ViewerRelationsFragment : BaseBottomSheetFragment(), OnStartDragListener {
private lateinit var itemDivider: DividerVerticalItemDecoration
private lateinit var itemDividerEdit: DividerVerticalItemDecoration
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_viewer_relations_list, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
itemDivider = DividerVerticalItemDecoration(
@ -128,13 +123,13 @@ class ViewerRelationsFragment : BaseBottomSheetFragment(), OnStartDragListener {
divider = requireContext().drawable(R.drawable.divider_relation_layer_edit),
isShowInLastItem = false
)
recycler.apply {
binding.recycler.apply {
layoutManager = LinearLayoutManager(requireContext())
}
with(lifecycleScope) {
subscribe(editBtn.clicks()) { vm.onEditButtonClicked() }
subscribe(doneBtn.clicks()) { vm.onDoneButtonClicked() }
subscribe(iconAdd.clicks()) {
subscribe(binding.editBtn.clicks()) { vm.onEditButtonClicked() }
subscribe(binding.doneBtn.clicks()) { vm.onDoneButtonClicked() }
subscribe(binding.iconAdd.clicks()) {
RelationAddToDataViewFragment.new(
ctx = ctx,
dv = dv,
@ -159,29 +154,33 @@ class ViewerRelationsFragment : BaseBottomSheetFragment(), OnStartDragListener {
private fun render(state: ViewerRelationsViewModel.ScreenState) {
when (state) {
ViewerRelationsViewModel.ScreenState.LIST -> {
recycler.apply {
dndItemTouchHelper.attachToRecyclerView(null)
}
iconAdd.visible()
editBtn.visible()
doneBtn.invisible()
recycler.apply {
adapter = listAdapter
removeItemDecoration(itemDividerEdit)
addItemDecoration(itemDivider)
with(binding) {
recycler.apply {
dndItemTouchHelper.attachToRecyclerView(null)
}
iconAdd.visible()
editBtn.visible()
doneBtn.invisible()
recycler.apply {
adapter = listAdapter
removeItemDecoration(itemDividerEdit)
addItemDecoration(itemDivider)
}
}
}
ViewerRelationsViewModel.ScreenState.EDIT -> {
recycler.apply {
dndItemTouchHelper.attachToRecyclerView(this)
}
iconAdd.invisible()
doneBtn.visible()
editBtn.invisible()
recycler.apply {
adapter = editAdapter
removeItemDecoration(itemDivider)
addItemDecoration(itemDividerEdit)
with(binding) {
recycler.apply {
dndItemTouchHelper.attachToRecyclerView(this)
}
iconAdd.invisible()
doneBtn.visible()
editBtn.invisible()
recycler.apply {
adapter = editAdapter
removeItemDecoration(itemDivider)
addItemDecoration(itemDividerEdit)
}
}
}
}
@ -209,6 +208,13 @@ class ViewerRelationsFragment : BaseBottomSheetFragment(), OnStartDragListener {
componentManager().viewerRelationsComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentViewerRelationsListBinding = FragmentViewerRelationsListBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: Id, dv: Id, viewer: Id) = ViewerRelationsFragment().apply {
arguments = bundleOf(CTX_KEY to ctx, DV_KEY to dv, VIEWER_KEY to viewer)

View file

@ -2,7 +2,6 @@ package com.anytypeio.anytype.ui.sets.modals.filter
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.lifecycle.lifecycleScope
@ -11,21 +10,19 @@ import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_utils.ext.arg
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentViewerBottomSheetRootBinding
import com.anytypeio.anytype.presentation.sets.filter.CreateFilterFlowViewModel
import com.anytypeio.anytype.presentation.sets.filter.CreateFilterFlowViewModel.Step
import com.anytypeio.anytype.presentation.sets.model.SimpleRelationView
import com.anytypeio.anytype.ui.sets.modals.ViewerBottomSheetRootFragment
class CreateFilterFlowRootFragment : BaseBottomSheetFragment(), CreateFilterFlow {
class CreateFilterFlowRootFragment :
BaseBottomSheetFragment<FragmentViewerBottomSheetRootBinding>(), CreateFilterFlow {
private val ctx: String get() = arg(CTX_KEY)
val vm by lazy { CreateFilterFlowViewModel() }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.fragment_viewer_bottom_sheet_root, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
lifecycleScope.subscribe(vm.step) { step ->
@ -79,6 +76,13 @@ class CreateFilterFlowRootFragment : BaseBottomSheetFragment(), CreateFilterFlow
override fun injectDependencies() {}
override fun releaseDependencies() {}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentViewerBottomSheetRootBinding = FragmentViewerBottomSheetRootBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: Id): CreateFilterFlowRootFragment = CreateFilterFlowRootFragment().apply {
arguments = bundleOf(CTX_KEY to ctx)

View file

@ -1,7 +1,9 @@
package com.anytypeio.anytype.ui.sets.modals.filter
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.viewModels
import androidx.lifecycle.lifecycleScope
@ -12,19 +14,17 @@ import com.anytypeio.anytype.core_ui.extensions.setInputTypeBaseOnFormat
import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseFragment
import com.anytypeio.anytype.databinding.FragmentCreateOrUpdateFilterInputFieldValueBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.filter.FilterViewModel
import com.anytypeio.anytype.presentation.sets.model.Viewer
import com.anytypeio.anytype.ui.sets.modals.PickFilterConditionFragment
import kotlinx.android.synthetic.main.fragment_create_or_update_filter.btnBottomAction
import kotlinx.android.synthetic.main.fragment_create_or_update_filter.ivRelationIcon
import kotlinx.android.synthetic.main.fragment_create_or_update_filter.tvRelationName
import kotlinx.android.synthetic.main.fragment_create_or_update_filter_input_field_value.*
import kotlinx.coroutines.flow.filterNotNull
import javax.inject.Inject
class CreateFilterFromInputFieldValueFragment :
BaseFragment(R.layout.fragment_create_or_update_filter_input_field_value), UpdateConditionActionReceiver {
BaseFragment<FragmentCreateOrUpdateFilterInputFieldValueBinding>(R.layout.fragment_create_or_update_filter_input_field_value),
UpdateConditionActionReceiver {
private val ctx: String get() = arg(CTX_KEY)
private val relation: String get() = arg(RELATION_KEY)
@ -35,16 +35,16 @@ class CreateFilterFromInputFieldValueFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnBottomAction.setText(R.string.create)
binding.btnBottomAction.setText(R.string.create)
with(lifecycleScope) {
subscribe(btnBottomAction.clicks()) {
subscribe(binding.btnBottomAction.clicks()) {
vm.onCreateInputValueFilterClicked(
ctx = ctx,
relation = relation,
input = enterTextValueInputField.text.toString()
input = binding.enterTextValueInputField.text.toString()
)
}
subscribe(tvFilterCondition.clicks()) {
subscribe(binding.tvFilterCondition.clicks()) {
vm.onConditionClicked()
}
}
@ -61,10 +61,10 @@ class CreateFilterFromInputFieldValueFragment :
).show(childFragmentManager, null)
}
FilterViewModel.Commands.HideInput -> {
enterTextValueInputField.gone()
binding.enterTextValueInputField.gone()
}
FilterViewModel.Commands.ShowInput -> {
enterTextValueInputField.visible()
binding.enterTextValueInputField.visible()
}
else -> {
}
@ -84,15 +84,15 @@ class CreateFilterFromInputFieldValueFragment :
private fun setupJobs() {
jobs += lifecycleScope.subscribe(vm.relationState.filterNotNull()) {
enterTextValueInputField.setInputTypeBaseOnFormat(it.format)
tvRelationName.text = it.title
ivRelationIcon.setImageResource(it.format.relationIcon(true))
binding.enterTextValueInputField.setInputTypeBaseOnFormat(it.format)
binding.tvRelationName.text = it.title
binding.ivRelationIcon.setImageResource(it.format.relationIcon(true))
}
jobs += lifecycleScope.subscribe(vm.isCompleted) {
if (it) withParent<CreateFilterFlow> { onFilterCreated() }
}
jobs += lifecycleScope.subscribe(vm.conditionState) {
tvFilterCondition.text = it?.condition?.title
binding.tvFilterCondition.text = it?.condition?.title
}
jobs += lifecycleScope.subscribe(vm.commands) {
observeCommands(it)
@ -111,6 +111,13 @@ class CreateFilterFromInputFieldValueFragment :
componentManager().createFilterComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentCreateOrUpdateFilterInputFieldValueBinding = FragmentCreateOrUpdateFilterInputFieldValueBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: Id, relation: Id) = CreateFilterFromInputFieldValueFragment().apply {
arguments = bundleOf(CTX_KEY to ctx, RELATION_KEY to relation)

View file

@ -1,7 +1,9 @@
package com.anytypeio.anytype.ui.sets.modals.filter
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.core.os.bundleOf
import androidx.fragment.app.viewModels
@ -16,6 +18,7 @@ import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_ui.reactive.textChanges
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseFragment
import com.anytypeio.anytype.databinding.FragmentCreateOrUpdateFilterBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.filter.FilterViewModel
import com.anytypeio.anytype.presentation.sets.model.Viewer
@ -23,14 +26,13 @@ import com.anytypeio.anytype.ui.sets.modals.DatePickerFragment
import com.anytypeio.anytype.ui.sets.modals.DatePickerFragment.DatePickerReceiver
import com.anytypeio.anytype.ui.sets.modals.PickFilterConditionFragment
import com.anytypeio.anytype.ui.sets.modals.filter.CreateFilterFromInputFieldValueFragment.Companion.FILTER_INDEX_EMPTY
import kotlinx.android.synthetic.main.fragment_create_or_update_filter.*
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.onStart
import javax.inject.Inject
open class CreateFilterFromSelectedValueFragment :
BaseFragment(R.layout.fragment_create_or_update_filter),
BaseFragment<FragmentCreateOrUpdateFilterBinding>(R.layout.fragment_create_or_update_filter),
UpdateConditionActionReceiver,
DatePickerReceiver {
@ -53,17 +55,17 @@ open class CreateFilterFromSelectedValueFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnBottomAction.setText(R.string.create)
searchRelationInput = searchBar.findViewById(R.id.filterInputField)
binding.btnBottomAction.setText(R.string.create)
searchRelationInput = binding.searchBar.root.findViewById(R.id.filterInputField)
searchRelationInput.apply {
hint = getString(R.string.choose_options)
}
clearSearchText = searchBar.findViewById(R.id.clearSearchText)
clearSearchText = binding.searchBar.root.findViewById(R.id.clearSearchText)
clearSearchText.setOnClickListener {
searchRelationInput.setText("")
clearSearchText.invisible()
}
rvViewerFilterRecycler.apply {
binding.rvViewerFilterRecycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = createFilterAdapter
addItemDecoration(
@ -73,22 +75,22 @@ open class CreateFilterFromSelectedValueFragment :
)
}
with(lifecycleScope) {
subscribe(tvFilterCondition.clicks()) {
subscribe(binding.tvFilterCondition.clicks()) {
vm.onConditionClicked()
}
subscribe(btnBottomAction.clicks()) {
subscribe(binding.btnBottomAction.clicks()) {
vm.onCreateFilterFromSelectedValueClicked(ctx = ctx, relation = relation)
}
subscribe(vm.relationState.filterNotNull()) {
tvRelationName.text = it.title
ivRelationIcon.setImageResource(it.format.relationIcon(true))
binding.tvRelationName.text = it.title
binding.ivRelationIcon.setImageResource(it.format.relationIcon(true))
}
subscribe(vm.optionCountState) { tvOptionCount.text = it.toString() }
subscribe(vm.optionCountState) { binding.tvOptionCount.text = it.toString() }
subscribe(vm.isCompleted) { isCompleted ->
if (isCompleted) withParent<CreateFilterFlow> { onFilterCreated() }
}
subscribe(vm.conditionState) {
tvFilterCondition.text = it?.condition?.title
binding.tvFilterCondition.text = it?.condition?.title
}
subscribe(searchRelationInput.textChanges()) {
if (it.isEmpty()) {
@ -136,10 +138,10 @@ open class CreateFilterFromSelectedValueFragment :
index = commands.index
).show(childFragmentManager, null)
}
FilterViewModel.Commands.ShowCount -> tvOptionCount.visible()
FilterViewModel.Commands.HideCount -> tvOptionCount.gone()
FilterViewModel.Commands.ShowSearchbar -> searchBar.visible()
FilterViewModel.Commands.HideSearchbar -> searchBar.gone()
FilterViewModel.Commands.ShowCount -> binding.tvOptionCount.visible()
FilterViewModel.Commands.HideCount -> binding.tvOptionCount.gone()
FilterViewModel.Commands.ShowSearchbar -> binding.searchBar.root.visible()
FilterViewModel.Commands.HideSearchbar -> binding.searchBar.root.gone()
FilterViewModel.Commands.DateDivider -> setDivider(R.drawable.divider_relation_date)
FilterViewModel.Commands.ObjectDivider -> setDivider(R.drawable.divider_relation_object)
FilterViewModel.Commands.TagDivider -> setDivider(R.drawable.divider_relation_tag)
@ -149,7 +151,7 @@ open class CreateFilterFromSelectedValueFragment :
}
private fun setDivider(divider: Int) {
rvViewerFilterRecycler.apply {
binding.rvViewerFilterRecycler.apply {
addItemDecoration(
DividerItemDecoration(context, DividerItemDecoration.VERTICAL).apply {
setDrawable(drawable(divider))
@ -174,6 +176,13 @@ open class CreateFilterFromSelectedValueFragment :
componentManager().createFilterComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentCreateOrUpdateFilterBinding = FragmentCreateOrUpdateFilterBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: Id, relation: Id): CreateFilterFromSelectedValueFragment = CreateFilterFromSelectedValueFragment().apply {
arguments = bundleOf(CTX_KEY to ctx, RELATION_KEY to relation)

View file

@ -17,16 +17,18 @@ import com.anytypeio.anytype.core_utils.ext.gone
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.databinding.FragmentCreateOrUpdateFilterInputFieldValueBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.extension.getTextValue
import com.anytypeio.anytype.presentation.sets.filter.FilterViewModel
import com.anytypeio.anytype.presentation.sets.model.Viewer
import com.anytypeio.anytype.ui.sets.modals.PickFilterConditionFragment
import kotlinx.android.synthetic.main.fragment_create_or_update_filter_input_field_value.*
import kotlinx.coroutines.flow.filterNotNull
import javax.inject.Inject
open class ModifyFilterFromInputFieldValueFragment : BaseBottomSheetFragment(), UpdateConditionActionReceiver {
open class ModifyFilterFromInputFieldValueFragment :
BaseBottomSheetFragment<FragmentCreateOrUpdateFilterInputFieldValueBinding>(),
UpdateConditionActionReceiver {
private val ctx: String get() = arg(CTX_KEY)
private val relation: String get() = arg(RELATION_KEY)
@ -37,21 +39,17 @@ open class ModifyFilterFromInputFieldValueFragment : BaseBottomSheetFragment(),
private val vm: FilterViewModel by viewModels { factory }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_create_or_update_filter_input_field_value, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnBottomAction.setText(R.string.apply)
binding.btnBottomAction.setText(R.string.apply)
with(lifecycleScope) {
subscribe(btnBottomAction.clicks()) {
subscribe(binding.btnBottomAction.clicks()) {
vm.onModifyApplyClicked(
ctx = ctx,
input = enterTextValueInputField.text.toString()
input = binding.enterTextValueInputField.text.toString()
)
}
subscribe(tvFilterCondition.clicks()) {
subscribe(binding.tvFilterCondition.clicks()) {
vm.onConditionClicked()
}
}
@ -59,18 +57,18 @@ open class ModifyFilterFromInputFieldValueFragment : BaseBottomSheetFragment(),
private fun setupJobs() {
jobs += lifecycleScope.subscribe(vm.relationState.filterNotNull()) {
tvRelationName.text = it.title
ivRelationIcon.setImageResource(it.format.relationIcon(true))
enterTextValueInputField.setInputTypeBaseOnFormat(it.format)
binding.tvRelationName.text = it.title
binding.ivRelationIcon.setImageResource(it.format.relationIcon(true))
binding.enterTextValueInputField.setInputTypeBaseOnFormat(it.format)
}
jobs += lifecycleScope.subscribe(vm.filterValueState) { value ->
enterTextValueInputField.setText(value.getTextValue())
binding.enterTextValueInputField.setText(value.getTextValue())
}
jobs += lifecycleScope.subscribe(vm.isCompleted) { isCompleted ->
if (isCompleted) dismiss()
}
jobs += lifecycleScope.subscribe(vm.conditionState) {
tvFilterCondition.text = it?.condition?.title
binding.tvFilterCondition.text = it?.condition?.title
}
jobs += lifecycleScope.subscribe(vm.commands) { observeCommands(it) }
}
@ -86,10 +84,10 @@ open class ModifyFilterFromInputFieldValueFragment : BaseBottomSheetFragment(),
).show(childFragmentManager, null)
}
FilterViewModel.Commands.HideInput -> {
enterTextValueInputField.gone()
binding.enterTextValueInputField.gone()
}
FilterViewModel.Commands.ShowInput -> {
enterTextValueInputField.visible()
binding.enterTextValueInputField.visible()
}
else -> {}
}
@ -118,10 +116,18 @@ open class ModifyFilterFromInputFieldValueFragment : BaseBottomSheetFragment(),
componentManager().modifyFilterComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentCreateOrUpdateFilterInputFieldValueBinding = FragmentCreateOrUpdateFilterInputFieldValueBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: Id, relation: Id, index: Int) = ModifyFilterFromInputFieldValueFragment().apply {
arguments = bundleOf(CTX_KEY to ctx, RELATION_KEY to relation, IDX_KEY to index)
}
fun new(ctx: Id, relation: Id, index: Int) =
ModifyFilterFromInputFieldValueFragment().apply {
arguments = bundleOf(CTX_KEY to ctx, RELATION_KEY to relation, IDX_KEY to index)
}
const val CTX_KEY = "arg.modify-filter-relation.ctx"
const val RELATION_KEY = "arg.modify-filter-relation.relation"

View file

@ -18,6 +18,7 @@ import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_ui.reactive.textChanges
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentCreateOrUpdateFilterBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.filter.FilterViewModel
import com.anytypeio.anytype.presentation.sets.model.ColumnView
@ -25,13 +26,13 @@ import com.anytypeio.anytype.presentation.sets.model.Viewer
import com.anytypeio.anytype.ui.sets.modals.DatePickerFragment
import com.anytypeio.anytype.ui.sets.modals.DatePickerFragment.DatePickerReceiver
import com.anytypeio.anytype.ui.sets.modals.PickFilterConditionFragment
import kotlinx.android.synthetic.main.fragment_create_or_update_filter.*
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.onStart
import javax.inject.Inject
open class ModifyFilterFromSelectedValueFragment : BaseBottomSheetFragment(),
open class ModifyFilterFromSelectedValueFragment :
BaseBottomSheetFragment<FragmentCreateOrUpdateFilterBinding>(),
UpdateConditionActionReceiver, DatePickerReceiver {
private val ctx: String get() = arg(CTX_KEY)
@ -52,23 +53,27 @@ open class ModifyFilterFromSelectedValueFragment : BaseBottomSheetFragment(),
)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_create_or_update_filter, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnBottomAction.setText(R.string.apply)
searchRelationInput = searchBar.findViewById(R.id.filterInputField)
binding.btnBottomAction.setText(R.string.apply)
searchRelationInput = binding.searchBar.root.findViewById(R.id.filterInputField)
searchRelationInput.apply {
hint = getString(R.string.choose_options)
}
clearSearchText = searchBar.findViewById(R.id.clearSearchText)
clearSearchText = binding.searchBar.root.findViewById(R.id.clearSearchText)
clearSearchText.setOnClickListener {
searchRelationInput.setText("")
clearSearchText.invisible()
}
rvViewerFilterRecycler.apply {
binding.rvViewerFilterRecycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = createFilterAdapter
addItemDecoration(
@ -78,24 +83,24 @@ open class ModifyFilterFromSelectedValueFragment : BaseBottomSheetFragment(),
)
}
with(lifecycleScope) {
subscribe(tvFilterCondition.clicks()) {
subscribe(binding.tvFilterCondition.clicks()) {
vm.onConditionClicked()
}
subscribe(btnBottomAction.clicks()) {
subscribe(binding.btnBottomAction.clicks()) {
vm.onModifyApplyClicked(ctx = ctx)
}
subscribe(vm.relationState.filterNotNull()) {
if (it.format == ColumnView.Format.DATE) {
searchBar.gone()
tvOptionCount.gone()
binding.searchBar.root.gone()
binding.tvOptionCount.gone()
}
tvRelationName.text = it.title
ivRelationIcon.setImageResource(it.format.relationIcon(true))
binding.tvRelationName.text = it.title
binding.ivRelationIcon.setImageResource(it.format.relationIcon(true))
}
subscribe(vm.optionCountState) { tvOptionCount.text = it.toString() }
subscribe(vm.optionCountState) { binding.tvOptionCount.text = it.toString() }
subscribe(vm.isCompleted) { isCompleted -> if (isCompleted) dismiss() }
subscribe(vm.conditionState) {
tvFilterCondition.text = it?.condition?.title
binding.tvFilterCondition.text = it?.condition?.title
}
subscribe(searchRelationInput.textChanges()) {
if (it.isEmpty()) {
@ -132,10 +137,10 @@ open class ModifyFilterFromSelectedValueFragment : BaseBottomSheetFragment(),
)
.show(childFragmentManager, null)
}
FilterViewModel.Commands.ShowCount -> tvOptionCount.visible()
FilterViewModel.Commands.HideCount -> tvOptionCount.gone()
FilterViewModel.Commands.ShowSearchbar -> searchBar.visible()
FilterViewModel.Commands.HideSearchbar -> searchBar.gone()
FilterViewModel.Commands.ShowCount -> binding.tvOptionCount.visible()
FilterViewModel.Commands.HideCount -> binding.tvOptionCount.gone()
FilterViewModel.Commands.ShowSearchbar -> binding.searchBar.root.visible()
FilterViewModel.Commands.HideSearchbar -> binding.searchBar.root.gone()
FilterViewModel.Commands.DateDivider -> setDivider(R.drawable.divider_relation_date)
FilterViewModel.Commands.ObjectDivider -> setDivider(R.drawable.divider_relation_object)
FilterViewModel.Commands.TagDivider -> setDivider(R.drawable.divider_relation_tag)
@ -145,7 +150,7 @@ open class ModifyFilterFromSelectedValueFragment : BaseBottomSheetFragment(),
}
private fun setDivider(divider: Int) {
rvViewerFilterRecycler.apply {
binding.rvViewerFilterRecycler.apply {
addItemDecoration(
DividerItemDecoration(context, DividerItemDecoration.VERTICAL).apply {
setDrawable(drawable(divider))
@ -181,10 +186,18 @@ open class ModifyFilterFromSelectedValueFragment : BaseBottomSheetFragment(),
componentManager().modifyFilterComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentCreateOrUpdateFilterBinding = FragmentCreateOrUpdateFilterBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: Id, relation: Id, index: Int): ModifyFilterFromSelectedValueFragment = ModifyFilterFromSelectedValueFragment().apply {
arguments = bundleOf(CTX_KEY to ctx, RELATION_KEY to relation, IDX_KEY to index)
}
fun new(ctx: Id, relation: Id, index: Int): ModifyFilterFromSelectedValueFragment =
ModifyFilterFromSelectedValueFragment().apply {
arguments = bundleOf(CTX_KEY to ctx, RELATION_KEY to relation, IDX_KEY to index)
}
const val CTX_KEY = "arg.modify-filter-relation.ctx"
const val RELATION_KEY = "arg.modify-filter-relation.relation"

View file

@ -17,11 +17,12 @@ 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.databinding.FragmentSelectSortOrFilterRelationBinding
import com.anytypeio.anytype.presentation.sets.SearchRelationViewModel
import com.anytypeio.anytype.presentation.sets.model.SimpleRelationView
import kotlinx.android.synthetic.main.fragment_select_sort_or_filter_relation.*
abstract class SearchRelationFragment : BaseBottomSheetFragment() {
abstract class SearchRelationFragment :
BaseBottomSheetFragment<FragmentSelectSortOrFilterRelationBinding>() {
abstract val ctx: String
abstract val vm: SearchRelationViewModel
@ -35,25 +36,19 @@ abstract class SearchRelationFragment : BaseBottomSheetFragment() {
abstract fun onRelationClicked(ctx: Id, relation: SimpleRelationView)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_select_sort_or_filter_relation, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
searchRelationInput = searchBar.findViewById(R.id.filterInputField)
searchRelationInput = binding.searchBar.root.findViewById(R.id.filterInputField)
searchRelationInput.apply {
hint = getString(R.string.choose_relation_to_filter)
}
clearSearchText = searchBar.findViewById(R.id.clearSearchText)
clearSearchText = binding.searchBar.root.findViewById(R.id.clearSearchText)
clearSearchText.setOnClickListener {
searchRelationInput.setText("")
clearSearchText.invisible()
}
searchRelationRecycler.apply {
binding.searchRelationRecycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = searchRelationAdapter
addItemDecoration(
@ -81,4 +76,12 @@ abstract class SearchRelationFragment : BaseBottomSheetFragment() {
subscribe(vm.isDismissed) { isDismissed -> if (isDismissed) dismiss() }
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentSelectSortOrFilterRelationBinding =
FragmentSelectSortOrFilterRelationBinding.inflate(
inflater, container, false
)
}

View file

@ -7,7 +7,6 @@ import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.DVSortType
import com.anytypeio.anytype.core_models.Id
@ -18,13 +17,13 @@ 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.databinding.FragmentModifyViewerSortBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.sort.ModifyViewerSortViewModel
import kotlinx.android.synthetic.main.fragment_modify_viewer_sort.*
import kotlinx.coroutines.flow.filterNotNull
import javax.inject.Inject
class ModifyViewerSortFragment : BaseBottomSheetFragment() {
class ModifyViewerSortFragment : BaseBottomSheetFragment<FragmentModifyViewerSortBinding>() {
private val ctx: String get() = arg(CTX_KEY)
private val relation: String get() = arg(RELATION_KEY)
@ -34,17 +33,11 @@ class ModifyViewerSortFragment : BaseBottomSheetFragment() {
private val vm: ModifyViewerSortViewModel by viewModels { factory }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_modify_viewer_sort, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(lifecycleScope) {
subscribe(tvSortAsc.clicks()) { vm.onSortAscSelected(ctx, relation) }
subscribe(tvSortDesc.clicks()) { vm.onSortDescSelected(ctx, relation) }
subscribe(binding.tvSortAsc.clicks()) { vm.onSortAscSelected(ctx, relation) }
subscribe(binding.tvSortDesc.clicks()) { vm.onSortDescSelected(ctx, relation) }
}
}
@ -53,17 +46,19 @@ class ModifyViewerSortFragment : BaseBottomSheetFragment() {
with(lifecycleScope) {
subscribe(vm.isDismissed) { isDismissed -> if (isDismissed) dismiss() }
subscribe(vm.viewState.filterNotNull()) { state ->
tvSortAsc.setText(DVSortType.ASC.text(state.format))
tvSortDesc.setText(DVSortType.DESC.text(state.format))
txtName.text = state.name
when (state.type) {
Block.Content.DataView.Sort.Type.ASC -> {
ivAscSelected.visible()
ivDescSelected.invisible()
}
Block.Content.DataView.Sort.Type.DESC -> {
ivAscSelected.invisible()
ivDescSelected.visible()
with(binding) {
tvSortAsc.setText(DVSortType.ASC.text(state.format))
tvSortDesc.setText(DVSortType.DESC.text(state.format))
txtName.text = state.name
when (state.type) {
Block.Content.DataView.Sort.Type.ASC -> {
ivAscSelected.visible()
ivDescSelected.invisible()
}
Block.Content.DataView.Sort.Type.DESC -> {
ivAscSelected.invisible()
ivDescSelected.visible()
}
}
}
}
@ -88,10 +83,18 @@ class ModifyViewerSortFragment : BaseBottomSheetFragment() {
componentManager().modifyViewerSortComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentModifyViewerSortBinding = FragmentModifyViewerSortBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: Id, relation: Id): ModifyViewerSortFragment = ModifyViewerSortFragment().apply {
arguments = bundleOf(CTX_KEY to ctx, RELATION_KEY to relation)
}
fun new(ctx: Id, relation: Id): ModifyViewerSortFragment =
ModifyViewerSortFragment().apply {
arguments = bundleOf(CTX_KEY to ctx, RELATION_KEY to relation)
}
private const val CTX_KEY = "arg.modify-viewer-sort.ctx"
private const val RELATION_KEY = "arg.modify-viewer-sort.relation"

View file

@ -16,12 +16,13 @@ import com.anytypeio.anytype.core_ui.features.sets.SearchRelationAdapter
import com.anytypeio.anytype.core_ui.reactive.textChanges
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentSelectSortOrFilterRelationBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.SelectSortRelationViewModel
import kotlinx.android.synthetic.main.fragment_select_sort_or_filter_relation.*
import javax.inject.Inject
class SelectSortRelationFragment : BaseBottomSheetFragment() {
class SelectSortRelationFragment :
BaseBottomSheetFragment<FragmentSelectSortOrFilterRelationBinding>() {
private val ctx: String get() = arg(CTX_KEY)
@ -39,25 +40,19 @@ class SelectSortRelationFragment : BaseBottomSheetFragment() {
private val vm: SelectSortRelationViewModel by viewModels { factory }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_select_sort_or_filter_relation, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
searchRelationInput = searchBar.findViewById(R.id.filterInputField)
searchRelationInput = binding.searchBar.root.findViewById(R.id.filterInputField)
searchRelationInput.apply {
hint = getString(R.string.choose_relation_to_sort)
}
clearSearchText = searchBar.findViewById(R.id.clearSearchText)
clearSearchText = binding.searchBar.root.findViewById(R.id.clearSearchText)
clearSearchText.setOnClickListener {
searchRelationInput.setText("")
clearSearchText.invisible()
}
searchRelationRecycler.apply {
binding.searchRelationRecycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = searchRelationAdapter
addItemDecoration(
@ -94,6 +89,14 @@ class SelectSortRelationFragment : BaseBottomSheetFragment() {
componentManager().selectSortRelationComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentSelectSortOrFilterRelationBinding =
FragmentSelectSortOrFilterRelationBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: Id): SelectSortRelationFragment = SelectSortRelationFragment().apply {

View file

@ -15,13 +15,13 @@ import com.anytypeio.anytype.core_ui.features.sets.ViewerSortAdapter
import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_utils.ext.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentViewerSortBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.sort.ViewerSortViewModel
import com.anytypeio.anytype.presentation.sets.sort.ViewerSortViewModel.ScreenState
import kotlinx.android.synthetic.main.fragment_viewer_sort.*
import javax.inject.Inject
open class ViewerSortFragment : BaseBottomSheetFragment() {
open class ViewerSortFragment : BaseBottomSheetFragment<FragmentViewerSortBinding>() {
private val ctx: String get() = arg(CTX_KEY)
@ -39,7 +39,7 @@ open class ViewerSortFragment : BaseBottomSheetFragment() {
)
}
private lateinit var dividerItem : DividerItemDecoration
private lateinit var dividerItem: DividerItemDecoration
private lateinit var dividerItemEdit: DividerItemDecoration
private fun navigateToSelectSort() {
@ -52,12 +52,6 @@ open class ViewerSortFragment : BaseBottomSheetFragment() {
fr.show(parentFragmentManager, null)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_viewer_sort, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
dividerItem = DividerItemDecoration(context, DividerItemDecoration.VERTICAL).apply {
@ -66,16 +60,16 @@ open class ViewerSortFragment : BaseBottomSheetFragment() {
dividerItemEdit = DividerItemDecoration(context, DividerItemDecoration.VERTICAL).apply {
setDrawable(drawable(R.drawable.decoration_viewer_sort_edit))
}
viewerSortRecycler.apply {
binding.viewerSortRecycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = viewerSortAdapter
}
with(lifecycleScope) {
subscribe(btnAdd.clicks()) { navigateToSelectSort() }
subscribe(btnEditSortOrDone.clicks()) {
if (btnEditSortOrDone.text == getString(R.string.edit))
subscribe(binding.btnAdd.clicks()) { navigateToSelectSort() }
subscribe(binding.btnEditSortOrDone.clicks()) {
if (binding.btnEditSortOrDone.text == getString(R.string.edit))
vm.onEditClicked()
else if (btnEditSortOrDone.text == getString(R.string.done))
else if (binding.btnEditSortOrDone.text == getString(R.string.done))
vm.onDoneClicked()
}
}
@ -93,27 +87,33 @@ open class ViewerSortFragment : BaseBottomSheetFragment() {
private fun render(state: ScreenState) {
when (state) {
ScreenState.READ -> {
btnEditSortOrDone.setText(R.string.edit)
btnAdd.visible()
viewerSortRecycler.apply {
removeItemDecoration(dividerItemEdit)
addItemDecoration(dividerItem)
with(binding) {
btnEditSortOrDone.setText(R.string.edit)
btnAdd.visible()
viewerSortRecycler.apply {
removeItemDecoration(dividerItemEdit)
addItemDecoration(dividerItem)
}
txtEmptyState.gone()
}
txtEmptyState.gone()
}
ScreenState.EDIT -> {
btnEditSortOrDone.setText(R.string.done)
btnAdd.invisible()
viewerSortRecycler.apply {
removeItemDecoration(dividerItem)
addItemDecoration(dividerItemEdit)
with(binding) {
btnEditSortOrDone.setText(R.string.done)
btnAdd.invisible()
viewerSortRecycler.apply {
removeItemDecoration(dividerItem)
addItemDecoration(dividerItemEdit)
}
txtEmptyState.gone()
}
txtEmptyState.gone()
}
ScreenState.EMPTY -> {
txtEmptyState.visible()
btnEditSortOrDone.text = ""
btnAdd.visible()
with(binding) {
txtEmptyState.visible()
btnEditSortOrDone.text = ""
btnAdd.visible()
}
}
}
}
@ -126,6 +126,13 @@ open class ViewerSortFragment : BaseBottomSheetFragment() {
componentManager().viewerSortComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentViewerSortBinding = FragmentViewerSortBinding.inflate(
inflater, container, false
)
companion object {
fun new(ctx: Id): ViewerSortFragment = ViewerSortFragment().apply {
arguments = bundleOf(CTX_KEY to ctx)

View file

@ -6,15 +6,14 @@ 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.*
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentViewerCardSizeSelectBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.viewer.ViewerCardSizeSelectViewModel
import kotlinx.android.synthetic.main.fragment_viewer_card_size_select.*
import javax.inject.Inject
class ViewerCardSizeSelectFragment : BaseBottomSheetFragment() {
class ViewerCardSizeSelectFragment : BaseBottomSheetFragment<FragmentViewerCardSizeSelectBinding>() {
@Inject
lateinit var factory: ViewerCardSizeSelectViewModel.Factory
@ -22,35 +21,35 @@ class ViewerCardSizeSelectFragment : BaseBottomSheetFragment() {
private val ctx get() = arg<String>(CTX_KEY)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_viewer_card_size_select, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnCardSmall.setOnClickListener {
binding.btnCardSmall.setOnClickListener {
vm.onSmallCardClicked(ctx)
}
btnCardLarge.setOnClickListener {
binding.btnCardLarge.setOnClickListener {
vm.onLargeCardClicked(ctx)
}
with(lifecycleScope) {
subscribe(vm.state) { state ->
when(state) {
when (state) {
ViewerCardSizeSelectViewModel.STATE_DISMISSED -> dismiss()
ViewerCardSizeSelectViewModel.STATE_LARGE_CARD_SELECTED -> {
smallCardCheckbox.invisible()
largeCardCheckbox.visible()
with(binding) {
smallCardCheckbox.invisible()
largeCardCheckbox.visible()
}
}
ViewerCardSizeSelectViewModel.STATE_SMALL_CARD_SELECTED -> {
smallCardCheckbox.visible()
largeCardCheckbox.invisible()
with(binding) {
smallCardCheckbox.visible()
largeCardCheckbox.invisible()
}
}
ViewerCardSizeSelectViewModel.STATE_IDLE -> {
smallCardCheckbox.invisible()
largeCardCheckbox.invisible()
with(binding) {
smallCardCheckbox.invisible()
largeCardCheckbox.invisible()
}
}
else -> toast("Unexpected state: $state")
}
@ -66,6 +65,13 @@ class ViewerCardSizeSelectFragment : BaseBottomSheetFragment() {
componentManager().viewerCardSizeSelectComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentViewerCardSizeSelectBinding = FragmentViewerCardSizeSelectBinding.inflate(
inflater, container, false
)
companion object {
const val CTX_KEY = "arg.viewer-card-size-select.ctx"
}

View file

@ -7,17 +7,16 @@ import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.features.sets.viewer.ViewerCoverAdapter
import com.anytypeio.anytype.core_utils.ext.arg
import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentViewerImagePreviewSelectBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.sets.viewer.ViewerImagePreviewSelectViewModel
import kotlinx.android.synthetic.main.fragment_viewer_image_preview_select.*
import javax.inject.Inject
class ViewerImagePreviewSelectFragment : BaseBottomSheetFragment() {
class ViewerImagePreviewSelectFragment : BaseBottomSheetFragment<FragmentViewerImagePreviewSelectBinding>() {
@Inject
lateinit var factory: ViewerImagePreviewSelectViewModel.Factory
@ -31,15 +30,9 @@ class ViewerImagePreviewSelectFragment : BaseBottomSheetFragment() {
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_viewer_image_preview_select, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewrCoverRecycler.apply {
binding.viewrCoverRecycler.apply {
adapter = viewerCoverAdapter
layoutManager = LinearLayoutManager(context)
}
@ -60,6 +53,13 @@ class ViewerImagePreviewSelectFragment : BaseBottomSheetFragment() {
componentManager().viewerImagePreviewSelectComponent.release(ctx)
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentViewerImagePreviewSelectBinding = FragmentViewerImagePreviewSelectBinding.inflate(
inflater, container, false
)
companion object {
const val CTX_KEY = "arg.viewer-cover-select.ctx"
}

View file

@ -7,18 +7,20 @@ import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.core_utils.ui.BaseFragment
import com.anytypeio.anytype.databinding.FragmentDebugSettingsBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.domain.config.GetDebugSettings
import com.anytypeio.anytype.domain.config.UseCustomContextMenu
import com.anytypeio.anytype.domain.dataview.interactor.DebugLocalStore
import com.anytypeio.anytype.domain.dataview.interactor.DebugSync
import kotlinx.android.synthetic.main.fragment_debug_settings.*
import kotlinx.coroutines.launch
import timber.log.Timber
import java.io.File
@ -26,7 +28,7 @@ import java.text.SimpleDateFormat
import java.util.*
import javax.inject.Inject
class DebugSettingsFragment : BaseFragment(R.layout.fragment_debug_settings) {
class DebugSettingsFragment : BaseFragment<FragmentDebugSettingsBinding>(R.layout.fragment_debug_settings) {
@Inject
lateinit var useCustomContextMenu: UseCustomContextMenu
@ -50,7 +52,7 @@ class DebugSettingsFragment : BaseFragment(R.layout.fragment_debug_settings) {
)
}
btnSync.setOnClickListener {
binding.btnSync.setOnClickListener {
viewLifecycleOwner.lifecycleScope.launch {
debugSync.invoke(Unit).proceed(
failure = {},
@ -59,7 +61,7 @@ class DebugSettingsFragment : BaseFragment(R.layout.fragment_debug_settings) {
}
}
btnLocalStore.setOnClickListener {
binding.btnLocalStore.setOnClickListener {
val directory = File(requireContext().getExternalFilesDir(null), "debugLocalStore")
directory.mkdir()
viewLifecycleOwner.lifecycleScope.launch {
@ -70,16 +72,16 @@ class DebugSettingsFragment : BaseFragment(R.layout.fragment_debug_settings) {
}
}
tvSync.setOnClickListener {
binding.tvSync.setOnClickListener {
val cm = activity?.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
cm.text = tvSync.text
cm.text = binding.tvSync.text
requireContext().toast("Sync status is copied to the clipboard")
}
}
private fun showStatus(msg: String) {
scrollContainer.visible()
tvSync.text = msg
binding.scrollContainer.visible()
binding.tvSync.text = msg
}
private fun saveToFile(status: String) {
@ -130,4 +132,11 @@ class DebugSettingsFragment : BaseFragment(R.layout.fragment_debug_settings) {
override fun releaseDependencies() {
componentManager().debugSettingsComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentDebugSettingsBinding = FragmentDebugSettingsBinding.inflate(
inflater, container, false
)
}

View file

@ -15,14 +15,14 @@ import com.anytypeio.anytype.core_utils.ext.subscribe
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
import com.anytypeio.anytype.databinding.FragmentUserSettingsBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.settings.OtherSettingsViewModel
import com.anytypeio.anytype.ui.dashboard.ClearCacheAlertFragment
import com.anytypeio.anytype.ui.objects.ObjectTypeChangeFragment
import kotlinx.android.synthetic.main.fragment_user_settings.*
import javax.inject.Inject
class OtherSettingsFragment : BaseBottomSheetFragment() {
class OtherSettingsFragment : BaseBottomSheetFragment<FragmentUserSettingsBinding>() {
@Inject
lateinit var factory: OtherSettingsViewModel.Factory
@ -38,18 +38,12 @@ class OtherSettingsFragment : BaseBottomSheetFragment() {
}
}
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() }
btnDefaultObjectType.setOnClickListener { vm.onObjectTypeClicked() }
btnClearFileCache.setOnClickListener { vm.onClearCacheClicked() }
ivArrowForward.setOnClickListener { vm.onObjectTypeClicked() }
binding.tvDefaultObjectTypeTitle.setOnClickListener { vm.onObjectTypeClicked() }
binding.btnDefaultObjectType.setOnClickListener { vm.onObjectTypeClicked() }
binding.btnClearFileCache.setOnClickListener { vm.onClearCacheClicked() }
binding.ivArrowForward.setOnClickListener { vm.onObjectTypeClicked() }
}
override fun onStart() {
@ -58,9 +52,9 @@ class OtherSettingsFragment : BaseBottomSheetFragment() {
jobs += subscribe(vm.commands) { observe(it) }
jobs += subscribe(vm.isClearFileCacheInProgress) { isInProgress ->
if (isInProgress)
clearFileCacheProgressBar.visible()
binding.clearFileCacheProgressBar.visible()
else
clearFileCacheProgressBar.gone()
binding.clearFileCacheProgressBar.gone()
}
}
}
@ -77,7 +71,7 @@ class OtherSettingsFragment : BaseBottomSheetFragment() {
)
}
is OtherSettingsViewModel.Command.SetObjectType -> {
objectType.text = command.name
binding.objectType.text = command.name
}
is OtherSettingsViewModel.Command.Toast -> toast(command.msg)
OtherSettingsViewModel.Command.ShowClearCacheAlert -> {
@ -88,6 +82,13 @@ class OtherSettingsFragment : BaseBottomSheetFragment() {
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentUserSettingsBinding = FragmentUserSettingsBinding.inflate(
inflater, container, false
)
override fun injectDependencies() {
componentManager().otherSettingsComponent.get().inject(this)
}

View file

@ -3,7 +3,9 @@ package com.anytypeio.anytype.ui.splash
import android.content.Intent
import android.content.pm.PackageManager
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.viewModels
import androidx.lifecycle.Lifecycle
@ -16,12 +18,12 @@ import com.anytypeio.anytype.app.DefaultAppActionManager.Companion.ACTION_CREATE
import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.core_utils.ui.BaseFragment
import com.anytypeio.anytype.databinding.FragmentSplashBinding
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.presentation.splash.SplashViewModel
import com.anytypeio.anytype.presentation.splash.SplashViewModelFactory
import com.anytypeio.anytype.ui.editor.EditorFragment
import com.anytypeio.anytype.ui.sets.ObjectSetFragment
import kotlinx.android.synthetic.main.fragment_splash.*
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@ -31,7 +33,7 @@ import javax.inject.Inject
* email : ki@agileburo.com
* on 2019-10-21.
*/
class SplashFragment : BaseFragment(R.layout.fragment_splash) {
class SplashFragment : BaseFragment<FragmentSplashBinding>(R.layout.fragment_splash) {
@Inject
lateinit var factory: SplashViewModelFactory
@ -61,7 +63,7 @@ class SplashFragment : BaseFragment(R.layout.fragment_splash) {
}
is SplashViewModel.Command.Error -> {
toast(command.msg)
error.visible()
binding.error.visible()
}
SplashViewModel.Command.NavigateToDashboard -> {
try {
@ -113,7 +115,7 @@ class SplashFragment : BaseFragment(R.layout.fragment_splash) {
}
private fun showVersion() {
version.text = "${BuildConfig.VERSION_NAME}-alpha"
binding.version.text = "${BuildConfig.VERSION_NAME}-alpha"
}
private fun isFirstInstall(): Boolean {
@ -142,4 +144,9 @@ class SplashFragment : BaseFragment(R.layout.fragment_splash) {
override fun releaseDependencies() {
componentManager().splashLoginComponent.release()
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentSplashBinding = FragmentSplashBinding.inflate(inflater, container, false)
}

View file

@ -1,6 +1,5 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
def config = rootProject.extensions.getByName("ext")

View file

@ -19,6 +19,10 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
buildFeatures {
viewBinding true
}
}
dependencies {

View file

@ -5,22 +5,29 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.viewbinding.ViewBinding
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.coroutines.Job
import com.google.android.material.R.id.design_bottom_sheet as BOTTOM_SHEET_ID
abstract class BaseBottomSheetFragment(
abstract class BaseBottomSheetFragment<T : ViewBinding>(
private val fragmentScope: Boolean = true
) : BottomSheetDialogFragment() {
private var _binding: T? = null
protected val binding: T get() = _binding!!
protected val jobs = mutableListOf<Job>()
abstract override fun onCreateView(
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View?
): View? {
_binding = inflateBinding(inflater, container)
return _binding?.root
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -50,4 +57,11 @@ abstract class BaseBottomSheetFragment(
abstract fun injectDependencies()
abstract fun releaseDependencies()
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
protected abstract fun inflateBinding(inflater: LayoutInflater, container: ViewGroup?): T
}

View file

@ -1,11 +1,18 @@
package com.anytypeio.anytype.core_utils.ui
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import androidx.viewbinding.ViewBinding
import com.anytypeio.anytype.core_utils.ext.cancel
import kotlinx.coroutines.Job
abstract class BaseDialogFragment(private val fragmentScope: Boolean = true) : DialogFragment() {
abstract class BaseDialogFragment<T : ViewBinding>(private val fragmentScope: Boolean = true) : DialogFragment() {
private var _binding: T? = null
protected val binding: T get() = _binding!!
protected val jobs = mutableListOf<Job>()
@ -22,8 +29,24 @@ abstract class BaseDialogFragment(private val fragmentScope: Boolean = true) : D
if (fragmentScope) releaseDependencies()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = inflateBinding(inflater, container)
return _binding?.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onStop() {
super.onStop()
jobs.cancel()
}
protected abstract fun inflateBinding(inflater: LayoutInflater, container: ViewGroup?): T
}

Some files were not shown because too many files have changed in this diff Show more