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

Feature | Styling toolbar | Colors menu | Design + Visibility control (#1459)

This commit is contained in:
Evgenii Kozlov 2021-05-12 16:05:36 +03:00 committed by GitHub
parent 94231266f2
commit 2a004fe2ce
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 204 additions and 142 deletions

View file

@ -148,6 +148,9 @@ open class PageFragment :
stylingToolbar.id -> {
vm.onCloseBlockStyleToolbarClicked()
}
styleToolbarColors.id -> {
vm.onCloseBlockStyleColorToolbarClicked()
}
}
}
}
@ -594,6 +597,10 @@ open class PageFragment :
vm.onBlockStyleToolbarOtherClicked()
}
lifecycleScope.subscribe(stylingToolbar.colors) {
vm.onBlockStyleToolbarColorClicked()
}
mentionSuggesterToolbar.setupClicks(
mentionClick = vm::onMentionSuggestClick,
newPageClick = vm::onAddMentionNewPageClicked
@ -621,6 +628,7 @@ open class PageFragment :
BottomSheetBehavior.from(stylingToolbar).state = BottomSheetBehavior.STATE_HIDDEN
BottomSheetBehavior.from(styleToolbarOther).state = BottomSheetBehavior.STATE_HIDDEN
BottomSheetBehavior.from(styleToolbarColors).state = BottomSheetBehavior.STATE_HIDDEN
}
private fun onApplyScrollAndMoveClicked() {
@ -1144,6 +1152,22 @@ open class PageFragment :
}
}
state.styleColorToolbar.apply {
if (isVisible) {
lifecycleScope.launch {
BottomSheetBehavior.from(styleToolbarColors).apply {
setState(BottomSheetBehavior.STATE_EXPANDED)
addBottomSheetCallback(onHideBottomSheetCallback)
}
}
} else {
BottomSheetBehavior.from(styleToolbarColors).apply {
removeBottomSheetCallback(onHideBottomSheetCallback)
setState(BottomSheetBehavior.STATE_HIDDEN)
}
}
}
state.mentionToolbar.apply {
if (isVisible) {
if (!mentionSuggesterToolbar.isVisible) {

View file

@ -152,15 +152,15 @@
tools:visibility="visible" />
<View
android:visibility="invisible"
android:id="@+id/blocker"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/setMarkupUrlToolbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/setMarkupUrlToolbar"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="0dp"
android:layout_height="0dp"/>
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
@ -204,27 +204,32 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:behavior_hideable="true"
app:cardUseCompatPadding="true"
app:behavior_skipCollapsed="true"
app:cardCornerRadius="16dp"
app:cardElevation="6dp"
app:layout_behavior="@string/bottom_sheet_behavior"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent" />
app:cardUseCompatPadding="true"
app:layout_behavior="@string/bottom_sheet_behavior" />
<com.anytypeio.anytype.core_ui.widgets.toolbar.StyleToolbarOther
android:id="@+id/styleToolbarOther"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:behavior_hideable="true"
app:cardUseCompatPadding="true"
app:behavior_skipCollapsed="true"
app:cardCornerRadius="16dp"
app:cardElevation="6dp"
app:layout_behavior="@string/bottom_sheet_behavior"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent" />
app:cardUseCompatPadding="true"
app:layout_behavior="@string/bottom_sheet_behavior" />
<com.anytypeio.anytype.core_ui.widgets.toolbar.style.StyleColorToolbarWidget
android:id="@+id/styleToolbarColors"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:behavior_hideable="true"
app:behavior_skipCollapsed="true"
app:cardCornerRadius="16dp"
app:cardElevation="6dp"
app:cardUseCompatPadding="true"
app:layout_behavior="@string/bottom_sheet_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -18,6 +18,8 @@ class StyleAdapter(
private val enabledAlignment: ArrayList<Alignment>,
private val onStylingEvent: (StylingEvent) -> Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@Deprecated("Maybe legacy, maybe not.")
fun updateConfig(config: StyleConfig, props: ControlPanelState.Toolbar.Styling.Props?) {
visibleTypes.clear()
visibleTypes.addAll(config.visibleTypes)
@ -31,21 +33,14 @@ class StyleAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return when (viewType) {
StylingType.STYLE.ordinal -> StyleTextViewHolder(
view = inflater.inflate(
R.layout.block_style_toolbar_style,
parent,
false
)
)
StylingType.TEXT_COLOR.ordinal -> StyleTextColorViewHolder(
HOLDER_TEXT_COLOR -> StyleTextColorViewHolder(
view = inflater.inflate(
R.layout.block_style_toolbar_color,
parent,
false
)
)
StylingType.BACKGROUND.ordinal -> StyleBackgroundViewHolder(
HOLDER_BACKGROUND_COLOR -> StyleBackgroundViewHolder(
view = inflater.inflate(
R.layout.block_style_toolbar_background,
parent,
@ -58,9 +53,6 @@ class StyleAdapter(
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is StyleTextViewHolder -> {
holder.bind(onStylingEvent, enabledMarkup, enabledAlignment, props)
}
is StyleTextColorViewHolder -> {
holder.bind(onStylingEvent, props?.color)
}
@ -70,6 +62,11 @@ class StyleAdapter(
}
}
override fun getItemCount(): Int = visibleTypes.size
override fun getItemViewType(position: Int): Int = visibleTypes[position].getViewType()
override fun getItemCount(): Int = 2
override fun getItemViewType(position: Int): Int = position
companion object {
const val HOLDER_TEXT_COLOR = 0
const val HOLDER_BACKGROUND_COLOR = 1
}
}

View file

@ -0,0 +1,63 @@
package com.anytypeio.anytype.core_ui.widgets.toolbar.style
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.TextView
import androidx.cardview.widget.CardView
import com.anytypeio.anytype.core_ui.R
import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.presentation.page.editor.control.ControlPanelState
import com.anytypeio.anytype.presentation.page.editor.styling.StyleConfig
import com.anytypeio.anytype.presentation.page.editor.styling.StylingEvent
import com.google.android.material.tabs.TabLayoutMediator
import kotlinx.android.synthetic.main.widget_block_style_toolbar_new.view.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.consumeAsFlow
import timber.log.Timber
class StyleColorToolbarWidget @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : CardView(context, attrs) {
private val channel = Channel<StylingEvent>()
private val blockStyleAdapter = StyleAdapter(
props = null,
visibleTypes = arrayListOf(),
enabledAlignment = arrayListOf(),
enabledMarkup = arrayListOf()
) { event ->
Timber.d("Styling Event : $event")
channel.offer(event)
}
val events = channel.consumeAsFlow()
init {
LayoutInflater.from(context).inflate(R.layout.widget_block_style_toolbar_colors, this)
setup()
}
private fun setup() {
val inflater = LayoutInflater.from(context)
pager.adapter = blockStyleAdapter
TabLayoutMediator(tabLayout, pager) { tab, position ->
tab.customView = inflater.inflate(R.layout.tab_item_style_toolbar, null).apply {
rootView.findViewById<TextView>(R.id.tabText).text = when (position) {
0 -> context.getString(R.string.color)
1 -> context.getString(R.string.background)
else -> throw IllegalStateException("Unexpected position: $position")
}
}
}.attach()
}
fun update(config: StyleConfig, props: ControlPanelState.Toolbar.Styling.Props?) {
blockStyleAdapter.updateConfig(config, props)
blockStyleAdapter.notifyDataSetChanged()
}
fun closeButtonClicks() = close.clicks()
}

View file

@ -1,98 +0,0 @@
package com.anytypeio.anytype.core_ui.widgets.toolbar.style
import android.animation.ObjectAnimator
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import com.anytypeio.anytype.core_ui.R
import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_ui.widgets.toolbar.BlockStyleToolbarWidget
import com.anytypeio.anytype.core_utils.ext.dimen
import com.anytypeio.anytype.presentation.page.editor.control.ControlPanelState
import com.anytypeio.anytype.presentation.page.editor.styling.StyleConfig
import com.anytypeio.anytype.presentation.page.editor.styling.StylingEvent
import com.anytypeio.anytype.presentation.page.editor.styling.StylingMode
import com.anytypeio.anytype.presentation.page.editor.styling.StylingType
import com.google.android.material.tabs.TabLayoutMediator
import kotlinx.android.synthetic.main.widget_block_style_toolbar_new.view.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.consumeAsFlow
import timber.log.Timber
import kotlin.properties.Delegates
class StyleToolbarWidget @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
private val channel = Channel<StylingEvent>()
private val blockStyleAdapter = StyleAdapter(
props = null,
visibleTypes = arrayListOf(),
enabledAlignment = arrayListOf(),
enabledMarkup = arrayListOf()
) { event ->
Timber.d("Styling Event : $event")
channel.offer(event)
}
val events = channel.consumeAsFlow()
var mode: StylingMode by Delegates.observable(StylingMode.BLOCK) { _, _, _ -> }
init {
LayoutInflater.from(context).inflate(R.layout.widget_block_style_toolbar_new, this)
setup()
}
private fun setup() {
pager.adapter = blockStyleAdapter
TabLayoutMediator(tabLayout, pager) { tab, position ->
val viewType = blockStyleAdapter.getItemViewType(position)
val customView = LayoutInflater.from(context).inflate(R.layout.tab_item_style_toolbar, null)
(customView.rootView as TextView).text = getTabTitle(viewType)
tab.customView = customView
}.attach()
}
fun update(config: StyleConfig, props: ControlPanelState.Toolbar.Styling.Props?) {
blockStyleAdapter.updateConfig(config, props)
blockStyleAdapter.notifyDataSetChanged()
}
fun showWithAnimation() {
ObjectAnimator.ofFloat(this, BlockStyleToolbarWidget.ANIMATED_PROPERTY, 0f).apply {
duration = BlockStyleToolbarWidget.ANIMATION_DURATION
interpolator = DecelerateInterpolator()
start()
}
}
fun hideWithAnimation() {
ObjectAnimator.ofFloat(
this,
BlockStyleToolbarWidget.ANIMATED_PROPERTY,
context.dimen(com.anytypeio.anytype.core_ui.R.dimen.dp_203)
).apply {
duration = BlockStyleToolbarWidget.ANIMATION_DURATION
interpolator = AccelerateInterpolator()
start()
}
}
private fun getTabTitle(viewType: Int) =
when (viewType) {
StylingType.STYLE.ordinal -> context.getString(R.string.text)
StylingType.TEXT_COLOR.ordinal -> context.getString(R.string.color)
StylingType.BACKGROUND.ordinal -> context.getString(R.string.background)
else -> throw IllegalStateException("Unexpected view type: $viewType")
}
fun closeButtonClicks() = close.clicks()
}

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="15dp" />
<corners android:radius="14dp" />
<solid android:color="#FFFFFF" />
</shape>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="15dp" />
<solid android:color="#FFB522" />
<corners android:radius="14dp" />
<solid android:color="#F3F2EC" />
</shape>

View file

@ -75,7 +75,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="8dp"
app:constraint_referenced_ids="backgroundColorDefault,backgroundColorGrey,backgroundColorYellow,backgroundColorOrange,backgroundColorRed,backgroundColorPink,backgroundColorPurple,backgroundColorBlue,backgroundColorIce,backgroundColorTeal,backgroundColorGreen"
app:flow_horizontalGap="0dp"

View file

@ -76,7 +76,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="8dp"
app:constraint_referenced_ids="textColorDefault,textColorGrey,textColorYellow,textColorOrange,textColorRed,textColorPink,textColorPurple,textColorBlue,textColorIce,textColorTeal,textColorGreen"
app:flow_horizontalGap="0dp"

View file

@ -1,18 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tabText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/tab_style_toolbar_selector"
android:fontFamily="@font/inter_medium"
android:gravity="center"
android:layout_marginTop="6dp"
android:paddingStart="@dimen/dp_16"
android:paddingTop="3dp"
android:paddingEnd="@dimen/dp_16"
android:paddingBottom="3dp"
android:singleLine="true"
android:textColor="@color/selector_style_toolbar_tab_text_color"
android:maxLines="1"
android:textColor="@color/black"
android:textSize="15sp"
tools:text="Text" />
</FrameLayout>

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="@+id/dragger"
android:layout_width="48dp"
android:layout_height="4dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="6dp"
android:background="@drawable/dragger" />
<com.google.android.material.tabs.TabLayout
android:layout_marginTop="4dp"
android:id="@+id/tabLayout"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_gravity="center_horizontal"
app:tabIndicatorColor="@android:color/transparent"
app:tabMode="auto"
app:tabPaddingTop="0dp"
app:tabPaddingBottom="0dp"
app:tabPaddingEnd="0dp"
app:tabPaddingStart="0dp"
app:tabRippleColor="@null"/>
<androidx.viewpager2.widget.ViewPager2
android:layout_marginTop="2dp"
android:layout_marginBottom="20dp"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

View file

@ -55,6 +55,7 @@
android:id="@+id/pager"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View file

@ -103,7 +103,7 @@
<dimen name="indent">28dp</dimen>
<dimen name="default_block_type_width">24dp</dimen>
<dimen name="block_style_toolbar_circle_size">56dp</dimen>
<dimen name="block_style_toolbar_circle_size">52dp</dimen>
<dimen name="default_document_content_padding_start">12dp</dimen>
<dimen name="default_document_content_padding_end">12dp</dimen>
<dimen name="default_document_item_margin_top">1dp</dimen>

View file

@ -150,7 +150,9 @@ sealed class ControlPanelMachine {
sealed class StylingToolbar : Event() {
object OnExtraClicked : StylingToolbar()
object OnColorClicked : StylingToolbar()
object OnExtraClosed : StylingToolbar()
object OnColorClosed : StylingToolbar()
data class OnClose(val focused: Boolean) : StylingToolbar()
}
@ -682,6 +684,14 @@ sealed class ControlPanelMachine {
styleExtraToolbar = Toolbar.Styling.Other(true)
)
}
is Event.StylingToolbar.OnColorClicked -> {
state.copy(
stylingToolbar = state.stylingToolbar.copy(
isVisible = false
),
styleColorToolbar = Toolbar.Styling.Color(true)
)
}
is Event.StylingToolbar.OnExtraClosed -> {
state.copy(
stylingToolbar = state.stylingToolbar.copy(
@ -690,6 +700,14 @@ sealed class ControlPanelMachine {
styleExtraToolbar = Toolbar.Styling.Other(false)
)
}
is Event.StylingToolbar.OnColorClosed -> {
state.copy(
stylingToolbar = state.stylingToolbar.copy(
isVisible = true
),
styleColorToolbar = Toolbar.Styling.Color(false)
)
}
}
private fun handleMentionEvent(

View file

@ -1971,6 +1971,12 @@ class PageViewModel(
)
}
fun onCloseBlockStyleColorToolbarClicked() {
controlPanelInteractor.onEvent(
ControlPanelMachine.Event.StylingToolbar.OnColorClosed
)
}
fun onBlockToolbarBlockActionsClicked() {
val target = orchestrator.stores.focus.current().id
val view = views.first { it.id == target }
@ -2267,6 +2273,10 @@ class PageViewModel(
controlPanelInteractor.onEvent(ControlPanelMachine.Event.StylingToolbar.OnExtraClicked)
}
fun onBlockStyleToolbarColorClicked() {
controlPanelInteractor.onEvent(ControlPanelMachine.Event.StylingToolbar.OnColorClicked)
}
private fun proceedUpdateBlockStyle(
targets: List<String>,
uiBlock: UiBlock,

View file

@ -19,6 +19,7 @@ data class ControlPanelState(
val mainToolbar: Toolbar.Main,
val stylingToolbar: Toolbar.Styling,
val styleExtraToolbar: Toolbar.Styling.Other = Toolbar.Styling.Other(),
val styleColorToolbar: Toolbar.Styling.Color = Toolbar.Styling.Color(),
val markupMainToolbar: Toolbar.MarkupMainToolbar = Toolbar.MarkupMainToolbar.reset(),
val markupUrlToolbar: Toolbar.MarkupUrlToolbar = Toolbar.MarkupUrlToolbar(),
val markupColorToolbar: Toolbar.MarkupColorToolbar = Toolbar.MarkupColorToolbar(),
@ -117,6 +118,7 @@ data class ControlPanelState(
}
data class Other(override val isVisible: Boolean = false) : Toolbar()
data class Color(override val isVisible: Boolean = false) : Toolbar()
/**
* Target's properties corresponding to current selection or styling mode.

View file

@ -21,7 +21,7 @@ class LongClickActivity: AppCompatActivity() {
setContentView(R.layout.activity_long_clicked)
findViewById<ImageView>(R.id.close).setOnClickListener {
styleToolbar.hideWithAnimation()
//styleToolbar.hideWithAnimation()
}
textInputWidget.enableEditMode()

View file

@ -16,7 +16,7 @@ class StyleActivity: AppCompatActivity() {
setContentView(R.layout.activity_style)
findViewById<ImageView>(R.id.close).setOnClickListener {
styleToolbar.hideWithAnimation()
//styleToolbar.hideWithAnimation()
}
button.setOnClickListener {
@ -50,7 +50,7 @@ class StyleActivity: AppCompatActivity() {
alignment = null
)
)
styleToolbar.showWithAnimation()
//styleToolbar.showWithAnimation()
}
}

View file

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -15,7 +14,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.anytypeio.anytype.core_ui.widgets.toolbar.style.StyleToolbarWidget
<com.anytypeio.anytype.core_ui.widgets.toolbar.style.StyleColorToolbarWidget
android:id="@+id/styleToolbar"
android:layout_width="0dp"
android:layout_height="@dimen/dp_203"

View file

@ -14,7 +14,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.anytypeio.anytype.core_ui.widgets.toolbar.style.StyleToolbarWidget
<com.anytypeio.anytype.core_ui.widgets.toolbar.style.StyleColorToolbarWidget
android:id="@+id/styleToolbar"
android:layout_width="0dp"
android:layout_height="@dimen/dp_203"