mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 13:57:10 +09:00
367 Block action bar, part 1 (#378)
* #367: add action icons * #367: add action bar view * #367: class Mark as Parcelable, Mark.param as String? * #367: blockView, add parcelable * #367: update Parcelize * #367: block action toolbar + layout * #367: fix name * #367: update versions * #367: show action bar fragment + listener * #367: block adapter on long click * #367: add custom long click listener * #367: add custom long click listener to paragraph block * #367: dismiss action bar * #367: update page fragment on back pressed * #367: update clicks + hide keybard * #367: add animation * #367: add divider * #367: update kotlin * #367: fix else * #367: sample app * #367: fix linking conflict * #367: pr fixes * #367: update method
This commit is contained in:
parent
43970f3172
commit
5cb4bf9c4c
42 changed files with 987 additions and 47 deletions
|
@ -29,6 +29,7 @@ import com.agileburo.anytype.core_ui.reactive.clicks
|
|||
import com.agileburo.anytype.core_ui.state.ControlPanelState
|
||||
import com.agileburo.anytype.core_ui.tools.FirstItemInvisibilityDetector
|
||||
import com.agileburo.anytype.core_ui.tools.OutsideClickDetector
|
||||
import com.agileburo.anytype.core_ui.widgets.ActionItemType
|
||||
import com.agileburo.anytype.core_ui.widgets.toolbar.ActionToolbarWidget.ActionConfig.ACTION_DELETE
|
||||
import com.agileburo.anytype.core_ui.widgets.toolbar.ActionToolbarWidget.ActionConfig.ACTION_DUPLICATE
|
||||
import com.agileburo.anytype.core_ui.widgets.toolbar.ActionToolbarWidget.ActionConfig.ACTION_REDO
|
||||
|
@ -62,10 +63,7 @@ import com.agileburo.anytype.ext.extractMarks
|
|||
import com.agileburo.anytype.presentation.page.PageViewModel
|
||||
import com.agileburo.anytype.presentation.page.PageViewModelFactory
|
||||
import com.agileburo.anytype.ui.base.NavigationFragment
|
||||
import com.agileburo.anytype.ui.page.modals.AddBlockFragment
|
||||
import com.agileburo.anytype.ui.page.modals.CreateBookmarkFragment
|
||||
import com.agileburo.anytype.ui.page.modals.PageIconPickerFragment
|
||||
import com.agileburo.anytype.ui.page.modals.SetLinkFragment
|
||||
import com.agileburo.anytype.ui.page.modals.*
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.hbisoft.pickit.PickiT
|
||||
import com.hbisoft.pickit.PickiTCallbacks
|
||||
|
@ -145,7 +143,8 @@ open class PageFragment :
|
|||
onToggleClicked = vm::onToggleClicked,
|
||||
onMediaBlockMenuClick = vm::onMediaBlockMenuClicked,
|
||||
onBookmarkMenuClicked = vm::onBookmarkMenuClicked,
|
||||
onMarkupActionClicked = vm::onMarkupActionClicked
|
||||
onMarkupActionClicked = vm::onMarkupActionClicked,
|
||||
onLongClickListener = vm::onBlockLongPressedClicked
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -260,11 +259,12 @@ open class PageFragment :
|
|||
setupOnBackPressedDispatcher()
|
||||
}
|
||||
|
||||
private fun setupOnBackPressedDispatcher() {
|
||||
private fun setupOnBackPressedDispatcher() =
|
||||
requireActivity()
|
||||
.onBackPressedDispatcher
|
||||
.addCallback(this) { vm.onSystemBackPressed() }
|
||||
}
|
||||
.addCallback(this) {
|
||||
vm.onSystemBackPressed(childFragmentManager.backStackEntryCount > 0)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -558,6 +558,10 @@ open class PageFragment :
|
|||
vm.commands.observe(viewLifecycleOwner, Observer { execute(it) })
|
||||
}
|
||||
|
||||
override fun onBlockActionClicked(id: String, action: ActionItemType) {
|
||||
vm.onActionBarItemClicked(id, action)
|
||||
}
|
||||
|
||||
private fun handleFocus(focus: Id) {
|
||||
Timber.d("Handling focus: $focus")
|
||||
if (focus.isEmpty()) {
|
||||
|
@ -593,6 +597,17 @@ open class PageFragment :
|
|||
is PageViewModel.Command.RequestDownloadPermission -> {
|
||||
startDownloadWithPermissionCheck(command.id)
|
||||
}
|
||||
is PageViewModel.Command.PopBackStack -> {
|
||||
childFragmentManager.popBackStack()
|
||||
}
|
||||
is PageViewModel.Command.OpenActionBar -> {
|
||||
hideKeyboard()
|
||||
childFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.action_bar_enter, R.anim.action_bar_exit)
|
||||
.add(R.id.root, BlockActionToolbar.newInstance(command.block), null)
|
||||
.addToBackStack(null)
|
||||
.commit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -728,9 +743,15 @@ open class PageFragment :
|
|||
const val ID_EMPTY_VALUE = ""
|
||||
const val NOT_IMPLEMENTED_MESSAGE = "Not implemented."
|
||||
}
|
||||
|
||||
override fun onDismissBlockActionToolbar() {
|
||||
vm.onSystemBackPressed(childFragmentManager.backStackEntryCount > 0)
|
||||
}
|
||||
}
|
||||
|
||||
interface OnFragmentInteractionListener {
|
||||
fun onAddMarkupLinkClicked(blockId: String, link: String, range: IntRange)
|
||||
fun onRemoveMarkupLinkClicked(blockId: String, range: IntRange)
|
||||
fun onBlockActionClicked(id: String, action: ActionItemType)
|
||||
fun onDismissBlockActionToolbar()
|
||||
}
|
|
@ -0,0 +1,232 @@
|
|||
package com.agileburo.anytype.ui.page.modals
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.text.method.ScrollingMovementMethod
|
||||
import android.view.View
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.agileburo.anytype.R
|
||||
import com.agileburo.anytype.core_ui.extensions.color
|
||||
import com.agileburo.anytype.core_ui.extensions.addVerticalDivider
|
||||
import com.agileburo.anytype.core_ui.features.page.BlockView
|
||||
import com.agileburo.anytype.core_ui.widgets.BlockActionBarItem
|
||||
import com.agileburo.anytype.core_ui.widgets.ActionItemType
|
||||
import com.agileburo.anytype.ui.page.OnFragmentInteractionListener
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.action_toolbar.*
|
||||
|
||||
class BlockActionToolbar : Fragment(R.layout.action_toolbar) {
|
||||
|
||||
companion object {
|
||||
|
||||
val ARG_BLOCK = "arg.block"
|
||||
fun newInstance(block: BlockView): BlockActionToolbar =
|
||||
BlockActionToolbar().apply {
|
||||
arguments = bundleOf(ARG_BLOCK to block)
|
||||
}
|
||||
}
|
||||
|
||||
private var block: BlockView? = null
|
||||
|
||||
private var actionClick: (ActionItemType) -> Unit = {}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
block = arguments?.getParcelable<BlockView.Paragraph>(ARG_BLOCK)
|
||||
actionClick = { actionType: ActionItemType ->
|
||||
(parentFragment as? OnFragmentInteractionListener)?.onBlockActionClicked(
|
||||
block?.id.orEmpty(),
|
||||
actionType
|
||||
)
|
||||
}
|
||||
|
||||
container.setOnClickListener {
|
||||
(parentFragment as? OnFragmentInteractionListener)?.onDismissBlockActionToolbar()
|
||||
}
|
||||
|
||||
text.movementMethod = ScrollingMovementMethod()
|
||||
text.text = (block as? BlockView.Paragraph)?.text
|
||||
|
||||
when (block) {
|
||||
is BlockView.Paragraph -> addButtons(ACTIONS.TEXT)
|
||||
is BlockView.Title -> addButtons(ACTIONS.TEXT)
|
||||
is BlockView.HeaderOne -> addButtons(ACTIONS.TEXT)
|
||||
is BlockView.HeaderTwo -> addButtons(ACTIONS.TEXT)
|
||||
is BlockView.HeaderThree -> addButtons(ACTIONS.TEXT)
|
||||
is BlockView.Highlight -> addButtons(ACTIONS.TEXT)
|
||||
is BlockView.Code -> addButtons(ACTIONS.CODE)
|
||||
is BlockView.Checkbox -> addButtons(ACTIONS.TEXT)
|
||||
is BlockView.Task -> addButtons(ACTIONS.TEXT)
|
||||
is BlockView.Bulleted -> addButtons(ACTIONS.TEXT)
|
||||
is BlockView.Numbered -> addButtons(ACTIONS.TEXT)
|
||||
is BlockView.Toggle -> addButtons(ACTIONS.TEXT)
|
||||
is BlockView.Contact -> TODO()
|
||||
is BlockView.File.View -> addButtons(ACTIONS.FILE)
|
||||
is BlockView.File.Upload -> addButtons(ACTIONS.FILE)
|
||||
is BlockView.File.Placeholder -> addButtons(ACTIONS.FILE)
|
||||
is BlockView.File.Error -> addButtons(ACTIONS.FILE)
|
||||
is BlockView.Video.View -> addButtons(ACTIONS.VIDEO_PICTURE)
|
||||
is BlockView.Video.Upload -> addButtons(ACTIONS.VIDEO_PICTURE)
|
||||
is BlockView.Video.Placeholder -> addButtons(ACTIONS.VIDEO_PICTURE)
|
||||
is BlockView.Video.Error -> addButtons(ACTIONS.VIDEO_PICTURE)
|
||||
is BlockView.Page -> addButtons(ACTIONS.PAGE)
|
||||
is BlockView.Divider -> addButtons(ACTIONS.DIVIDER)
|
||||
is BlockView.Bookmark.Placeholder -> addButtons(ACTIONS.BOOKMARK)
|
||||
is BlockView.Bookmark.View -> addButtons(ACTIONS.BOOKMARK)
|
||||
is BlockView.Bookmark.Error -> addButtons(ACTIONS.BOOKMARK)
|
||||
is BlockView.Picture.View -> addButtons(ACTIONS.VIDEO_PICTURE)
|
||||
is BlockView.Picture.Placeholder -> addButtons(ACTIONS.VIDEO_PICTURE)
|
||||
is BlockView.Picture.Error -> addButtons(ACTIONS.VIDEO_PICTURE)
|
||||
is BlockView.Picture.Upload -> addButtons(ACTIONS.VIDEO_PICTURE)
|
||||
BlockView.Footer -> TODO()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addButtons(actions: List<ActionItemType>) =
|
||||
with(action_container) {
|
||||
actions.forEach { type ->
|
||||
when (type) {
|
||||
ActionItemType.Divider -> {
|
||||
addVerticalDivider(
|
||||
height = 1,
|
||||
alpha = 1.0f,
|
||||
color = context.color(R.color.light_grayish)
|
||||
)
|
||||
}
|
||||
ActionItemType.DividerExtended -> {
|
||||
addVerticalDivider(
|
||||
height = 8,
|
||||
alpha = 1.0f,
|
||||
color = context.color(R.color.light_grayish)
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
addView(
|
||||
createActionBarItem(
|
||||
type = type,
|
||||
context = requireContext(),
|
||||
actionClick = actionClick
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createActionBarItem(
|
||||
type: ActionItemType,
|
||||
context: Context,
|
||||
actionClick: (ActionItemType) -> Unit
|
||||
) = BlockActionBarItem(context = context).apply {
|
||||
setTypeAndClick(
|
||||
itemType = type,
|
||||
clickListener = { actionClick(it) }
|
||||
)
|
||||
}
|
||||
|
||||
object ACTIONS {
|
||||
|
||||
val PAGE = listOf(
|
||||
ActionItemType.TurnInto,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Delete,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Duplicate,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Rename,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.MoveTo,
|
||||
ActionItemType.DividerExtended,
|
||||
ActionItemType.Color,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Background
|
||||
)
|
||||
|
||||
val TEXT = listOf(
|
||||
ActionItemType.TurnInto,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Delete,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Duplicate,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.MoveTo,
|
||||
ActionItemType.DividerExtended,
|
||||
ActionItemType.Style,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Color,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Background
|
||||
)
|
||||
|
||||
val VIDEO_PICTURE = listOf(
|
||||
ActionItemType.Delete,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Duplicate,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Download,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Replace,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.MoveTo,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.AddCaption,
|
||||
ActionItemType.DividerExtended,
|
||||
ActionItemType.Background
|
||||
)
|
||||
|
||||
val FILE = listOf(
|
||||
ActionItemType.Delete,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Duplicate,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Download,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Replace,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Rename,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.MoveTo,
|
||||
ActionItemType.DividerExtended,
|
||||
ActionItemType.Color,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Background
|
||||
)
|
||||
|
||||
val BOOKMARK = listOf(
|
||||
ActionItemType.Delete,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Duplicate,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.MoveTo
|
||||
)
|
||||
|
||||
val CODE = listOf(
|
||||
ActionItemType.TurnInto,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Delete,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Duplicate,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.MoveTo
|
||||
)
|
||||
|
||||
val DIVIDER = listOf(
|
||||
ActionItemType.Delete,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.Duplicate,
|
||||
ActionItemType.Divider,
|
||||
ActionItemType.MoveTo
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
sealed class ActionType {
|
||||
|
||||
@Parcelize
|
||||
data class Text(val id: String, val text: String) : ActionType(), Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class MediaImage(val id: String, val url: String) : ActionType(), Parcelable
|
||||
}
|
12
app/src/main/res/anim/action_bar_enter.xml
Normal file
12
app/src/main/res/anim/action_bar_enter.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="false" >
|
||||
<scale android:fromXScale="0.9" android:toXScale="1.0"
|
||||
android:fromYScale="0.9" android:toYScale="1.0"
|
||||
android:pivotX="50%" android:pivotY="50%"
|
||||
android:interpolator="@android:anim/accelerate_interpolator"
|
||||
android:duration="220" />
|
||||
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
|
||||
android:interpolator="@android:interpolator/decelerate_cubic"
|
||||
android:duration="150" />
|
||||
</set>
|
12
app/src/main/res/anim/action_bar_exit.xml
Normal file
12
app/src/main/res/anim/action_bar_exit.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="false" >
|
||||
<scale android:fromXScale="1.0" android:toXScale="0.9"
|
||||
android:fromYScale="1.0" android:toYScale="0.9"
|
||||
android:pivotX="50%" android:pivotY="50%"
|
||||
android:interpolator="@android:interpolator/decelerate_quint"
|
||||
android:duration="220" />
|
||||
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
|
||||
android:interpolator="@android:interpolator/decelerate_cubic"
|
||||
android:duration="150"/>
|
||||
</set>
|
40
app/src/main/res/layout/action_toolbar.xml
Normal file
40
app/src/main/res/layout/action_toolbar.xml
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?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:focusable="true"
|
||||
android:clickable="true"
|
||||
android:background="#52000000"
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/action_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="48dp"
|
||||
android:layout_marginEnd="48dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:layout_height="200dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:padding="@dimen/dp_16"
|
||||
style="@style/BlockTextContentStyle"
|
||||
android:background="@drawable/rounded_text_action_bg"
|
||||
app:layout_constraintBottom_toTopOf="@+id/action_container"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:layout_height="200dp" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -75,4 +75,9 @@
|
|||
<item name="android:windowSoftInputMode">adjustResize</item>
|
||||
</style>
|
||||
|
||||
<!-- resolve linking conflicts between constrain:2.0.0-beta4 and Android Studio 3.6.3 -->
|
||||
<attr name="flow_horizontalGap" format="dimension" />
|
||||
<attr name="flow_horizontalSeparator" format="dimension"/>
|
||||
|
||||
|
||||
</resources>
|
|
@ -1,7 +1,7 @@
|
|||
apply from: './dependencies.gradle'
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.70'
|
||||
ext.kotlin_version = '1.3.72'
|
||||
ext.gradle_tools = '3.1.3'
|
||||
ext.build_tools = '29.0.0'
|
||||
ext.nav_version = '2.2.0-rc01'
|
||||
|
@ -28,7 +28,7 @@ buildscript {
|
|||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.3'
|
||||
classpath 'com.android.tools.build:gradle:3.6.3'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
|
||||
classpath 'com.google.gms:google-services:4.3.3'
|
||||
|
|
|
@ -49,7 +49,6 @@ dependencies {
|
|||
implementation applicationDependencies.kotlin
|
||||
implementation applicationDependencies.coroutines
|
||||
implementation applicationDependencies.androidxCore
|
||||
implementation applicationDependencies.ktxCore
|
||||
|
||||
implementation applicationDependencies.design
|
||||
implementation applicationDependencies.recyclerView
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.agileburo.anytype.core_ui.common
|
|||
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.os.Parcelable
|
||||
import android.text.Annotation
|
||||
import android.text.Editable
|
||||
import android.text.Spannable
|
||||
|
@ -11,6 +12,7 @@ import com.agileburo.anytype.core_utils.ext.KEY_ROUNDED
|
|||
import com.agileburo.anytype.core_utils.ext.VALUE_ROUNDED
|
||||
import com.agileburo.anytype.core_utils.ext.removeRoundedSpans
|
||||
import com.agileburo.anytype.core_utils.ext.removeSpans
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
/**
|
||||
* Classes implementing this interface should support markup rendering.
|
||||
|
@ -32,14 +34,15 @@ interface Markup {
|
|||
* @property to caracter index where this markup ends (inclusive)
|
||||
* @property type markup's type
|
||||
*/
|
||||
@Parcelize
|
||||
data class Mark(
|
||||
val from: Int,
|
||||
val to: Int,
|
||||
val type: Type,
|
||||
val param: Any? = null
|
||||
) {
|
||||
val param: String? = null
|
||||
) : Parcelable {
|
||||
|
||||
fun color(): Int = Color.parseColor(param as String)
|
||||
fun color(): Int = Color.parseColor(param)
|
||||
|
||||
}
|
||||
|
||||
|
@ -96,7 +99,7 @@ fun Markup.toSpannable() = SpannableStringBuilder(body).apply {
|
|||
Markup.DEFAULT_SPANNABLE_FLAG
|
||||
)
|
||||
Markup.Type.LINK -> setSpan(
|
||||
URLSpan(mark.param as String),
|
||||
URLSpan(mark.param),
|
||||
mark.from,
|
||||
mark.to,
|
||||
Markup.DEFAULT_SPANNABLE_FLAG
|
||||
|
@ -155,7 +158,7 @@ fun Editable.setMarkup(markup: Markup) {
|
|||
)
|
||||
Markup.Type.LINK -> {
|
||||
setSpan(
|
||||
URLSpan(mark.param as String),
|
||||
URLSpan(mark.param),
|
||||
mark.from,
|
||||
mark.to,
|
||||
Markup.DEFAULT_SPANNABLE_FLAG
|
||||
|
|
|
@ -3,8 +3,10 @@ package com.agileburo.anytype.core_ui.extensions
|
|||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Toast
|
||||
import com.agileburo.anytype.core_ui.R
|
||||
import com.agileburo.anytype.core_utils.ext.px
|
||||
|
||||
fun View.invisible() {
|
||||
this.visibility = View.INVISIBLE
|
||||
|
@ -35,4 +37,19 @@ fun Context.toast(
|
|||
|
||||
fun View.tint(color: Int) {
|
||||
backgroundTintList = ColorStateList.valueOf(color)
|
||||
}
|
||||
}
|
||||
|
||||
fun LinearLayout.addVerticalDivider(
|
||||
alpha: Float,
|
||||
height: Int,
|
||||
color: Int
|
||||
) = addView(
|
||||
View(context).apply {
|
||||
setBackgroundColor(color)
|
||||
setAlpha(alpha)
|
||||
layoutParams = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
height
|
||||
)
|
||||
}
|
||||
)
|
|
@ -75,7 +75,8 @@ class BlockAdapter(
|
|||
private val onToggleClicked: (String) -> Unit,
|
||||
private val onMediaBlockMenuClick: (String) -> Unit,
|
||||
private val onBookmarkMenuClicked: (String) -> Unit,
|
||||
private val onMarkupActionClicked: (Markup.Type) -> Unit
|
||||
private val onMarkupActionClicked: (Markup.Type) -> Unit,
|
||||
private val onLongClickListener: (BlockView) -> Unit
|
||||
) : RecyclerView.Adapter<BlockViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BlockViewHolder {
|
||||
|
@ -449,7 +450,8 @@ class BlockAdapter(
|
|||
item = blocks[position] as BlockView.Paragraph,
|
||||
onTextChanged = onParagraphTextChanged,
|
||||
onSelectionChanged = onSelectionChanged,
|
||||
onFocusChanged = onFocusChanged
|
||||
onFocusChanged = onFocusChanged,
|
||||
onLongClickListener = onLongClickListener
|
||||
)
|
||||
}
|
||||
is BlockViewHolder.Title -> {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.agileburo.anytype.core_ui.features.page
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.agileburo.anytype.core_ui.common.Checkable
|
||||
import com.agileburo.anytype.core_ui.common.Focusable
|
||||
import com.agileburo.anytype.core_ui.common.Markup
|
||||
|
@ -35,11 +36,13 @@ import com.agileburo.anytype.core_ui.features.page.BlockViewHolder.Companion.HOL
|
|||
import com.agileburo.anytype.core_ui.features.page.BlockViewHolder.Companion.HOLDER_VIDEO_ERROR
|
||||
import com.agileburo.anytype.core_ui.features.page.BlockViewHolder.Companion.HOLDER_VIDEO_PLACEHOLDER
|
||||
import com.agileburo.anytype.core_ui.features.page.BlockViewHolder.Companion.HOLDER_VIDEO_UPLOAD
|
||||
import kotlinx.android.parcel.IgnoredOnParcel
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
/**
|
||||
* UI-models for different types of blocks.
|
||||
*/
|
||||
sealed class BlockView : ViewType {
|
||||
sealed class BlockView : ViewType, Parcelable {
|
||||
|
||||
|
||||
/**
|
||||
|
@ -85,6 +88,7 @@ sealed class BlockView : ViewType {
|
|||
* @property focused whether this block is currently focused or not
|
||||
* @property color text color
|
||||
*/
|
||||
@Parcelize
|
||||
data class Paragraph(
|
||||
override val id: String,
|
||||
override val text: String,
|
||||
|
@ -104,6 +108,7 @@ sealed class BlockView : ViewType {
|
|||
* @property text text content (i.e. title text)
|
||||
* @property emoji emoji as a page's logo (if present)
|
||||
*/
|
||||
@Parcelize
|
||||
data class Title(
|
||||
override val id: String,
|
||||
override val focused: Boolean,
|
||||
|
@ -119,6 +124,7 @@ sealed class BlockView : ViewType {
|
|||
* @property text header's content (i.e. a header's text)
|
||||
* @property color text color
|
||||
*/
|
||||
@Parcelize
|
||||
data class HeaderOne(
|
||||
override val id: String,
|
||||
override val text: String,
|
||||
|
@ -135,6 +141,7 @@ sealed class BlockView : ViewType {
|
|||
* @property text header's content (i.e. a header's text)
|
||||
* @property color text color
|
||||
*/
|
||||
@Parcelize
|
||||
data class HeaderTwo(
|
||||
override val id: String,
|
||||
override val color: String? = null,
|
||||
|
@ -151,6 +158,7 @@ sealed class BlockView : ViewType {
|
|||
* @property text header's content (i.e. a header's text)
|
||||
* @property color text color
|
||||
*/
|
||||
@Parcelize
|
||||
data class HeaderThree(
|
||||
override val id: String,
|
||||
override val color: String? = null,
|
||||
|
@ -166,6 +174,7 @@ sealed class BlockView : ViewType {
|
|||
* @property id block's id
|
||||
* @property text block's content
|
||||
*/
|
||||
@Parcelize
|
||||
data class Highlight(
|
||||
override val id: String,
|
||||
val text: String,
|
||||
|
@ -179,6 +188,7 @@ sealed class BlockView : ViewType {
|
|||
* @property id block's id
|
||||
* @property snippet blocks's content (i.e. code snippet)
|
||||
*/
|
||||
@Parcelize
|
||||
data class Code(
|
||||
override val id: String,
|
||||
val snippet: String
|
||||
|
@ -192,6 +202,7 @@ sealed class BlockView : ViewType {
|
|||
* @property text checkbox's content text
|
||||
* @property isChecked immutable checkbox state (whether this checkbox is checked or not)
|
||||
*/
|
||||
@Parcelize
|
||||
data class Checkbox(
|
||||
override val id: String,
|
||||
override val marks: List<Markup.Mark> = emptyList(),
|
||||
|
@ -212,6 +223,7 @@ sealed class BlockView : ViewType {
|
|||
* @property text task's content text
|
||||
* @property checked immutable taks state (whether this task is completed or not)
|
||||
*/
|
||||
@Parcelize
|
||||
data class Task(
|
||||
override val id: String,
|
||||
val text: String,
|
||||
|
@ -227,6 +239,7 @@ sealed class BlockView : ViewType {
|
|||
* @property indent indentation value
|
||||
* @property color text color
|
||||
*/
|
||||
@Parcelize
|
||||
data class Bulleted(
|
||||
override val id: String,
|
||||
override val marks: List<Markup.Mark> = emptyList(),
|
||||
|
@ -247,6 +260,7 @@ sealed class BlockView : ViewType {
|
|||
* @property number number value
|
||||
* @property indent indentation value
|
||||
*/
|
||||
@Parcelize
|
||||
data class Numbered(
|
||||
override val id: String,
|
||||
override val text: String,
|
||||
|
@ -268,6 +282,7 @@ sealed class BlockView : ViewType {
|
|||
* @property indent indentation value
|
||||
* @property toggled toggle state (whether this toggle is expanded or not)
|
||||
*/
|
||||
@Parcelize
|
||||
data class Toggle(
|
||||
override val id: String,
|
||||
override val text: String,
|
||||
|
@ -289,6 +304,7 @@ sealed class BlockView : ViewType {
|
|||
* @property name a person's name
|
||||
* @property avatar a person's avatar image
|
||||
*/
|
||||
@Parcelize
|
||||
data class Contact(
|
||||
override val id: String,
|
||||
val name: String,
|
||||
|
@ -303,12 +319,13 @@ sealed class BlockView : ViewType {
|
|||
*/
|
||||
sealed class File(
|
||||
override val id: String
|
||||
) : BlockView(), Indentable {
|
||||
) : BlockView(), Indentable, Parcelable {
|
||||
|
||||
/**
|
||||
* UI-model for block containing file, with state DONE.
|
||||
* @property id block's id
|
||||
*/
|
||||
@Parcelize
|
||||
data class View(
|
||||
override val id: String,
|
||||
override val indent: Int,
|
||||
|
@ -325,6 +342,7 @@ sealed class BlockView : ViewType {
|
|||
* UI-model for block containing file, with state UPLOADING.
|
||||
* @property id block's id
|
||||
*/
|
||||
@Parcelize
|
||||
data class Upload(
|
||||
override val id: String,
|
||||
override val indent: Int
|
||||
|
@ -336,6 +354,7 @@ sealed class BlockView : ViewType {
|
|||
* UI-model for block containing file, with state EMPTY.
|
||||
* @property id block's id
|
||||
*/
|
||||
@Parcelize
|
||||
data class Placeholder(
|
||||
override val id: String,
|
||||
override val indent: Int
|
||||
|
@ -347,6 +366,7 @@ sealed class BlockView : ViewType {
|
|||
* UI-model for block containing file, with state ERROR.
|
||||
* @property id block's id
|
||||
*/
|
||||
@Parcelize
|
||||
data class Error(
|
||||
override val id: String,
|
||||
override val indent: Int
|
||||
|
@ -361,11 +381,12 @@ sealed class BlockView : ViewType {
|
|||
*/
|
||||
sealed class Video(
|
||||
override val id: String
|
||||
) : BlockView(), Indentable {
|
||||
) : BlockView(), Indentable, Parcelable {
|
||||
|
||||
/**
|
||||
* UI-model for block containing video, with state DONE.
|
||||
*/
|
||||
@Parcelize
|
||||
data class View(
|
||||
override val id: String,
|
||||
override val indent: Int,
|
||||
|
@ -382,6 +403,7 @@ sealed class BlockView : ViewType {
|
|||
* UI-model for block containing video, with state UPLOADING.
|
||||
* @property id block's id
|
||||
*/
|
||||
@Parcelize
|
||||
data class Upload(
|
||||
override val id: String,
|
||||
override val indent: Int
|
||||
|
@ -393,6 +415,7 @@ sealed class BlockView : ViewType {
|
|||
* UI-model for block containing video, with state EMPTY.
|
||||
* @property id block's id
|
||||
*/
|
||||
@Parcelize
|
||||
data class Placeholder(
|
||||
override val id: String,
|
||||
override val indent: Int
|
||||
|
@ -404,6 +427,7 @@ sealed class BlockView : ViewType {
|
|||
* UI-model for block containing video, with state ERROR.
|
||||
* @property id block's id
|
||||
*/
|
||||
@Parcelize
|
||||
data class Error(
|
||||
override val id: String,
|
||||
override val indent: Int
|
||||
|
@ -420,6 +444,7 @@ sealed class BlockView : ViewType {
|
|||
* @property isEmpty this property determines whether this page is empty or not
|
||||
* @property isArchived this property determines whether this page is archived or not
|
||||
*/
|
||||
@Parcelize
|
||||
data class Page(
|
||||
override val id: String,
|
||||
override val indent: Int,
|
||||
|
@ -435,6 +460,7 @@ sealed class BlockView : ViewType {
|
|||
* UI-model for a divider block.
|
||||
* @property id block's id
|
||||
*/
|
||||
@Parcelize
|
||||
data class Divider(
|
||||
override val id: String
|
||||
) : BlockView() {
|
||||
|
@ -447,11 +473,12 @@ sealed class BlockView : ViewType {
|
|||
*/
|
||||
sealed class Bookmark(
|
||||
override val id: String
|
||||
) : BlockView(), Indentable {
|
||||
) : BlockView(), Indentable, Parcelable {
|
||||
|
||||
/**
|
||||
* UI-model for a bookmark placeholder (used when bookmark url is not set)
|
||||
*/
|
||||
@Parcelize
|
||||
data class Placeholder(
|
||||
override val id: String,
|
||||
override val indent: Int
|
||||
|
@ -467,6 +494,7 @@ sealed class BlockView : ViewType {
|
|||
* @property faviconUrl website's favicon url
|
||||
* @property imageUrl content's main image url
|
||||
*/
|
||||
@Parcelize
|
||||
data class View(
|
||||
override val id: String,
|
||||
override val indent: Int,
|
||||
|
@ -483,6 +511,7 @@ sealed class BlockView : ViewType {
|
|||
* UI-model for a bookmark view in error state
|
||||
* @property url url originally entered by user to create a bookmark
|
||||
*/
|
||||
@Parcelize
|
||||
data class Error(
|
||||
override val id: String,
|
||||
override val indent: Int,
|
||||
|
@ -498,11 +527,12 @@ sealed class BlockView : ViewType {
|
|||
*/
|
||||
sealed class Picture(
|
||||
override val id: String
|
||||
) : BlockView(), Indentable {
|
||||
) : BlockView(), Indentable, Parcelable {
|
||||
|
||||
/**
|
||||
* UI-model for block containing image, with state DONE.
|
||||
*/
|
||||
@Parcelize
|
||||
data class View(
|
||||
override val id: String,
|
||||
override val indent: Int,
|
||||
|
@ -518,6 +548,7 @@ sealed class BlockView : ViewType {
|
|||
/**
|
||||
* UI-model for block containing image, with state EMPTY.
|
||||
*/
|
||||
@Parcelize
|
||||
data class Placeholder(
|
||||
override val id: String,
|
||||
override val indent: Int
|
||||
|
@ -528,6 +559,7 @@ sealed class BlockView : ViewType {
|
|||
/**
|
||||
* UI-model for block containing image, with state ERROR.
|
||||
*/
|
||||
@Parcelize
|
||||
data class Error(
|
||||
override val id: String,
|
||||
override val indent: Int
|
||||
|
@ -538,6 +570,7 @@ sealed class BlockView : ViewType {
|
|||
/**
|
||||
* UI-model for block containing image, with state UPLOADING.
|
||||
*/
|
||||
@Parcelize
|
||||
data class Upload(
|
||||
override val id: String,
|
||||
override val indent: Int
|
||||
|
@ -549,7 +582,9 @@ sealed class BlockView : ViewType {
|
|||
/**
|
||||
* Footer block. Just holds space at the end of the page.
|
||||
*/
|
||||
@Parcelize
|
||||
object Footer : BlockView() {
|
||||
@IgnoredOnParcel
|
||||
override val id: String = FOOTER_ID
|
||||
override fun getViewType() = HOLDER_FOOTER
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import com.agileburo.anytype.core_ui.features.page.BlockViewDiffUtil.Payload
|
|||
import com.agileburo.anytype.core_ui.menu.TextStyleMenu
|
||||
import com.agileburo.anytype.core_ui.tools.DefaultSpannableFactory
|
||||
import com.agileburo.anytype.core_ui.tools.DefaultTextWatcher
|
||||
import com.agileburo.anytype.core_ui.widgets.text.EditorLongClickListener
|
||||
import com.agileburo.anytype.core_ui.widgets.text.TextInputWidget
|
||||
import com.agileburo.anytype.core_utils.const.MimeTypes
|
||||
import com.agileburo.anytype.core_utils.ext.dimen
|
||||
|
@ -107,10 +108,13 @@ sealed class BlockViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
|||
item: BlockView.Paragraph,
|
||||
onTextChanged: (String, Editable) -> Unit,
|
||||
onSelectionChanged: (String, IntRange) -> Unit,
|
||||
onFocusChanged: (String, Boolean) -> Unit
|
||||
onFocusChanged: (String, Boolean) -> Unit,
|
||||
onLongClickListener: (BlockView) -> Unit
|
||||
) {
|
||||
indentize(item)
|
||||
|
||||
content.setOnLongClickListener(EditorLongClickListener(item, onLongClickListener))
|
||||
|
||||
content.clearTextWatchers()
|
||||
|
||||
if (item.marks.isLinksPresent()) {
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
package com.agileburo.anytype.core_ui.widgets
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.agileburo.anytype.core_ui.R
|
||||
import com.agileburo.anytype.core_ui.extensions.drawable
|
||||
import kotlinx.android.synthetic.main.action_item.view.*
|
||||
|
||||
sealed class ActionItemType {
|
||||
object TurnInto : ActionItemType()
|
||||
object Delete : ActionItemType()
|
||||
object Duplicate : ActionItemType()
|
||||
object Rename : ActionItemType()
|
||||
object MoveTo : ActionItemType()
|
||||
object Color : ActionItemType()
|
||||
object Background : ActionItemType()
|
||||
object Style : ActionItemType()
|
||||
object Download : ActionItemType()
|
||||
object Replace : ActionItemType()
|
||||
object AddCaption : ActionItemType()
|
||||
object Divider : ActionItemType()
|
||||
object DividerExtended : ActionItemType()
|
||||
}
|
||||
|
||||
class BlockActionBarItem @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
||||
) : ConstraintLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
private var itemType: ActionItemType = ActionItemType.Divider
|
||||
private var click: (ActionItemType) -> Unit = {}
|
||||
|
||||
init {
|
||||
LayoutInflater.from(context).inflate(R.layout.action_item, this)
|
||||
}
|
||||
|
||||
private fun updateView() {
|
||||
when (itemType) {
|
||||
ActionItemType.TurnInto -> updateContent(
|
||||
R.string.action_bar_turn_into,
|
||||
R.drawable.ic_action_turn_into
|
||||
)
|
||||
ActionItemType.Delete -> updateContent(
|
||||
R.string.action_bar_delete,
|
||||
R.drawable.ic_action_delete
|
||||
)
|
||||
ActionItemType.Duplicate -> updateContent(
|
||||
R.string.action_bar_duplicate,
|
||||
R.drawable.ic_action_duplicate
|
||||
)
|
||||
ActionItemType.Rename -> updateContent(
|
||||
R.string.action_bar_rename,
|
||||
R.drawable.ic_action_rename
|
||||
)
|
||||
ActionItemType.MoveTo -> updateContent(
|
||||
R.string.action_bar_move_to,
|
||||
R.drawable.ic_action_move_to
|
||||
)
|
||||
ActionItemType.Color -> updateContent(
|
||||
R.string.action_bar_color,
|
||||
R.drawable.ic_action_color
|
||||
)
|
||||
ActionItemType.Background -> updateContent(
|
||||
R.string.action_bar_background,
|
||||
R.drawable.ic_action_background
|
||||
)
|
||||
ActionItemType.Style -> updateContent(
|
||||
R.string.action_bar_style,
|
||||
R.drawable.ic_action_style
|
||||
)
|
||||
ActionItemType.Download -> updateContent(
|
||||
R.string.action_bar_download,
|
||||
R.drawable.ic_action_download
|
||||
)
|
||||
ActionItemType.Replace -> updateContent(
|
||||
R.string.action_bar_replace,
|
||||
R.drawable.ic_action_replace
|
||||
)
|
||||
ActionItemType.AddCaption -> updateContent(
|
||||
R.string.action_bar_add_caption,
|
||||
R.drawable.ic_action_add_caption
|
||||
)
|
||||
else -> throw RuntimeException("Unknown action item type:$itemType")
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateContent(text: Int, img: Int) {
|
||||
tvAction.text = resources.getText(text)
|
||||
ivAction.setImageDrawable(context.drawable(img))
|
||||
}
|
||||
|
||||
fun setTypeAndClick(itemType: ActionItemType, clickListener: (ActionItemType) -> Unit) {
|
||||
this.click = clickListener
|
||||
this.itemType = itemType
|
||||
setOnClickListener { click.invoke(itemType) }
|
||||
updateView()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.agileburo.anytype.core_ui.widgets.text
|
||||
|
||||
import android.view.View
|
||||
|
||||
class EditorLongClickListener<T>(t: T, private val click: (T) -> Unit) :
|
||||
View.OnLongClickListener {
|
||||
|
||||
var value: T = t
|
||||
|
||||
override fun onLongClick(view: View?): Boolean =
|
||||
if (view != null && !view.hasFocus()) {
|
||||
click(value)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
20
core-ui/src/main/res/drawable/ic_action_add_caption.xml
Normal file
20
core-ui/src/main/res/drawable/ic_action_add_caption.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M5,3L19,3A2,2 0,0 1,21 5L21,15A2,2 0,0 1,19 17L5,17A2,2 0,0 1,3 15L3,5A2,2 0,0 1,5 3z"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M9,22V20H17V22H9Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M3,22V20H7V22H3Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M19,22V20H21V22H19Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
</vector>
|
9
core-ui/src/main/res/drawable/ic_action_background.xml
Normal file
9
core-ui/src/main/res/drawable/ic_action_background.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="22dp"
|
||||
android:height="23dp"
|
||||
android:viewportWidth="22"
|
||||
android:viewportHeight="23">
|
||||
<path
|
||||
android:pathData="M11,11.2695m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0"
|
||||
android:fillColor="#FEF3C5"/>
|
||||
</vector>
|
9
core-ui/src/main/res/drawable/ic_action_color.xml
Normal file
9
core-ui/src/main/res/drawable/ic_action_color.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="22dp"
|
||||
android:height="22dp"
|
||||
android:viewportWidth="22"
|
||||
android:viewportHeight="22">
|
||||
<path
|
||||
android:pathData="M11,11m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0"
|
||||
android:fillColor="#2C2B27"/>
|
||||
</vector>
|
22
core-ui/src/main/res/drawable/ic_action_delete.xml
Normal file
22
core-ui/src/main/res/drawable/ic_action_delete.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M9,8H11V18H9V8Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M4,6C3.4477,6 3,5.5523 3,5C3,4.4477 3.4477,4 4,4L20,4C20.5523,4 21,4.4477 21,5C21,5.5523 20.5523,6 20,6L4,6Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M13,8H15V18H13V8Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M5,6H7V19C7,19.5523 7.4477,20 8,20H16C16.5523,20 17,19.5523 17,19V6H19C19,8.4687 19,15.0927 19,19.0004C19,20.6572 17.6569,22 16,22H8C6.3432,22 5,20.6569 5,19V6Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M13,3H11C10.4477,3 10,3.4477 10,4H14C14,3.4477 13.5523,3 13,3ZM11,1C9.3432,1 8,2.3431 8,4V6H16V4C16,2.3431 14.6569,1 13,1H11Z"
|
||||
android:fillColor="#ACA996"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
16
core-ui/src/main/res/drawable/ic_action_download.xml
Normal file
16
core-ui/src/main/res/drawable/ic_action_download.xml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M11,15.125C11,15.6082 11.4477,16 12,16C12.5523,16 13,15.6082 13,15.125V2H11V15.125Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M12,18.4L19.7071,10.7046C20.0976,10.3146 20.0976,9.6824 19.7071,9.2925C19.3166,8.9025 18.6834,8.9025 18.2929,9.2925L12,15.5759L5.7071,9.2925C5.3166,8.9025 4.6834,8.9025 4.2929,9.2925C3.9024,9.6824 3.9024,10.3146 4.2929,10.7046L12,18.4Z"
|
||||
android:fillColor="#ACA996"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M4,20h16v2h-16z"
|
||||
android:fillColor="#ACA996"/>
|
||||
</vector>
|
15
core-ui/src/main/res/drawable/ic_action_duplicate.xml
Normal file
15
core-ui/src/main/res/drawable/ic_action_duplicate.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M5,7L15,7A2,2 0,0 1,17 9L17,19A2,2 0,0 1,15 21L5,21A2,2 0,0 1,3 19L3,9A2,2 0,0 1,5 7z"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M9,4H19C19.5523,4 20,4.4477 20,5V15C20,15.5523 19.5523,16 19,16H18V18H19C20.6569,18 22,16.6569 22,15V5C22,3.3431 20.6569,2 19,2H9C7.3432,2 6,3.3431 6,5V6H8V5C8,4.4477 8.4477,4 9,4Z"
|
||||
android:fillColor="#ACA996"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
18
core-ui/src/main/res/drawable/ic_action_move_to.xml
Normal file
18
core-ui/src/main/res/drawable/ic_action_move_to.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M11.2929,7.2929C11.6834,6.9024 12.3166,6.9024 12.7071,7.2929L17.4142,12L12.7071,16.7071C12.3166,17.0976 11.6834,17.0976 11.2929,16.7071C10.9024,16.3166 10.9024,15.6834 11.2929,15.2929L14.5858,12L11.2929,8.7071C10.9024,8.3166 10.9024,7.6834 11.2929,7.2929Z"
|
||||
android:fillColor="#ACA996"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M7,11h8v2h-8z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M5.125,3L19,3A2,2 0,0 1,21 5L21,19A2,2 0,0 1,19 21L5.125,21A2,2 0,0 1,3.125 19L3.125,5A2,2 0,0 1,5.125 3z"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#ACA996"/>
|
||||
</vector>
|
12
core-ui/src/main/res/drawable/ic_action_rename.xml
Normal file
12
core-ui/src/main/res/drawable/ic_action_rename.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M20,0.9766h2v22h-2z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M10.3255,4.9978L5.6443,19.0021H8.0926L9.1894,15.5353H14.5365L15.653,19.0021H18.3559L13.7335,4.9978H10.3255ZM9.7966,13.6354L11.8728,7.1327L13.9294,13.6354H9.7966Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
</vector>
|
22
core-ui/src/main/res/drawable/ic_action_replace.xml
Normal file
22
core-ui/src/main/res/drawable/ic_action_replace.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M19,3.9686C19,3.4163 19.4477,2.9686 20,2.9686C20.5523,2.9686 21,3.4163 21,3.9686V9.9686H19V3.9686Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M15,9.9999C14.4477,9.9999 14,9.5522 14,8.9999C14,8.4476 14.4477,7.9999 15,7.9999H21V9.9999H15Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M5,19.9999C5,20.5522 4.5523,20.9999 4,20.9999C3.4477,20.9999 3,20.5522 3,19.9999V13.9999H5V19.9999Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M9,13.9686C9.5523,13.9686 10,14.4163 10,14.9686C10,15.5209 9.5523,15.9686 9,15.9686H3V13.9686H9Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M18.679,13.9686C17.8184,16.8601 15.1399,18.9686 11.9689,18.9686C8.7979,18.9686 6.1193,16.8601 5.2588,13.9686H3.1919C4.1013,17.9766 7.6857,20.9686 11.9689,20.9686C16.2521,20.9686 19.8364,17.9766 20.7459,13.9686H18.679ZM5.2588,9.9686C6.1193,7.0771 8.7979,4.9686 11.9689,4.9686C15.1399,4.9686 17.8184,7.0771 18.679,9.9686H20.7459C19.8364,5.9606 16.2521,2.9686 11.9689,2.9686C7.6857,2.9686 4.1013,5.9606 3.1919,9.9686H5.2588Z"
|
||||
android:fillColor="#ACA996"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
12
core-ui/src/main/res/drawable/ic_action_style.xml
Normal file
12
core-ui/src/main/res/drawable/ic_action_style.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M4.8433,5L0.1621,19.0043H2.6104L3.7073,15.5375H9.0544L10.1708,19.0043H12.8737L8.2513,5H4.8433ZM4.3144,13.6376L6.3906,7.1349L8.4472,13.6376H4.3144Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M17.4811,19.2002C19.048,19.2002 19.9294,18.6322 20.6149,17.7508V19.0043H22.9457V12.2862C22.9457,9.4657 21.1438,8.5452 18.8522,8.5452C16.5605,8.5452 14.6802,9.5441 14.4648,11.9336H16.7564C16.8935,10.9151 17.4615,10.3275 18.715,10.3275C20.1253,10.3275 20.5758,10.9935 20.5758,12.3841V12.913H19.3026C16.3843,12.913 14.0535,13.7748 14.0535,16.1643C14.0535,18.2992 15.6008,19.2002 17.4811,19.2002ZM18.0491,17.4962C16.8739,17.4962 16.4038,16.9282 16.4038,16.0664C16.4038,14.8128 17.5594,14.4015 19.3614,14.4015H20.5758V15.42C20.5758,16.7519 19.5181,17.4962 18.0491,17.4962Z"
|
||||
android:fillColor="#ACA996"/>
|
||||
</vector>
|
20
core-ui/src/main/res/drawable/ic_action_turn_into.xml
Normal file
20
core-ui/src/main/res/drawable/ic_action_turn_into.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M8.2071,12.2929C7.8166,11.9024 7.1834,11.9024 6.7929,12.2929L2.0858,17L6.7929,21.7071C7.1834,22.0976 7.8166,22.0976 8.2071,21.7071C8.5976,21.3166 8.5976,20.6834 8.2071,20.2929L4.9142,17L8.2071,13.7071C8.5976,13.3166 8.5976,12.6834 8.2071,12.2929Z"
|
||||
android:fillColor="#ACA996"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M4,16h16v2h-16z"
|
||||
android:fillColor="#ACA996"/>
|
||||
<path
|
||||
android:pathData="M15.7926,2.2929C16.1832,1.9024 16.8163,1.9024 17.2069,2.2929L21.914,7L17.2069,11.7071C16.8163,12.0976 16.1832,12.0976 15.7926,11.7071C15.4021,11.3166 15.4021,10.6834 15.7926,10.2929L19.0855,7L15.7926,3.7071C15.4021,3.3166 15.4021,2.6834 15.7926,2.2929Z"
|
||||
android:fillColor="#ACA996"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M19.9998,6l-16,0l-0,2l16,0z"
|
||||
android:fillColor="#ACA996"/>
|
||||
</vector>
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@android:color/white" />
|
||||
<solid android:color="@android:color/holo_red_dark" />
|
||||
<corners
|
||||
android:topLeftRadius="10dp"
|
||||
android:topRightRadius="10dp" />
|
||||
|
|
9
core-ui/src/main/res/drawable/rounded_text_action_bg.xml
Normal file
9
core-ui/src/main/res/drawable/rounded_text_action_bg.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="10dp" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@color/white" />
|
||||
<solid android:color="@color/white" />
|
||||
</shape>
|
37
core-ui/src/main/res/layout/action_item.xml
Normal file
37
core-ui/src/main/res/layout/action_item.xml
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?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:id="@+id/container"
|
||||
android:background="#FFFFFF"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAction"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="11dp"
|
||||
android:layout_marginBottom="9dp"
|
||||
android:fontFamily="@font/graphik_font"
|
||||
android:lineSpacingExtra="7sp"
|
||||
android:textColor="#2C2B27"
|
||||
android:textSize="17sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/ivAction"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Turn Into" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivAction"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tvAction"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/tvAction"
|
||||
tools:src="@drawable/ic_action_download" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -54,6 +54,8 @@
|
|||
|
||||
<color name="markup_keyboard_bg">#F3F2EC</color>
|
||||
|
||||
<color name="light_grayish">#f3f2ec</color>
|
||||
|
||||
<array name="toolbar_color_text_colors">
|
||||
<item>#2C2B27</item>
|
||||
<item>#ACA996</item>
|
||||
|
|
|
@ -178,5 +178,16 @@
|
|||
<string-array name="certs">
|
||||
<item>MIIEqDCCA5CgAwIBAgIJA071MA0GCSqGSIb3DQEBBAUAMIGUMQsww...</item>
|
||||
</string-array>
|
||||
<string name="action_bar_turn_into">Turn into</string>
|
||||
<string name="action_bar_delete">Delete</string>
|
||||
<string name="action_bar_duplicate">Duplicate</string>
|
||||
<string name="action_bar_move_to">Move to</string>
|
||||
<string name="action_bar_style">Style</string>
|
||||
<string name="action_bar_color">Color</string>
|
||||
<string name="action_bar_background">Background</string>
|
||||
<string name="action_bar_download">Download</string>
|
||||
<string name="action_bar_replace">Replace</string>
|
||||
<string name="action_bar_add_caption">Add caption</string>
|
||||
<string name="action_bar_rename">Rename</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -26,7 +26,7 @@ data class BlockEntity(
|
|||
data class Mark(
|
||||
val range: IntRange,
|
||||
val type: Type,
|
||||
val param: Any?
|
||||
val param: String?
|
||||
) {
|
||||
enum class Type {
|
||||
STRIKETHROUGH,
|
||||
|
|
|
@ -10,15 +10,14 @@ ext {
|
|||
kotlin_coroutines_version = '1.3.4'
|
||||
|
||||
// AndroidX
|
||||
androidx_core_version = '1.1.0'
|
||||
androidx_core_version = '1.2.0'
|
||||
androidx_test_core_version = '1.2.0'
|
||||
appcompat_version = '1.1.0'
|
||||
constraintLayout_version = '2.0.0-beta1'
|
||||
constraintLayout_version = '2.0.0-beta4'
|
||||
recyclerview_version = '1.1.0'
|
||||
cardview_version = '1.0.0'
|
||||
material_version = '1.1.0-beta02'
|
||||
fragment_version = "1.2.3"
|
||||
ktx_core_version = "1.2.0"
|
||||
emoji_compat_version = '1.1.0-beta01'
|
||||
view_pager_2_version = '1.0.0'
|
||||
|
||||
|
@ -98,7 +97,6 @@ ext {
|
|||
design: "com.google.android.material:material:$material_version",
|
||||
androidAnnotations: "androidx.annotation:annotation:$appcompat_version",
|
||||
betterLinkMovement: "me.saket:better-link-movement-method:$better_link_method_version",
|
||||
ktxCore: "androidx.core:core-ktx:$ktx_core_version",
|
||||
emojiCompat: "androidx.emoji:emoji-appcompat:$emoji_compat_version",
|
||||
|
||||
glide: "com.github.bumptech.glide:glide:$glide_version",
|
||||
|
|
|
@ -103,7 +103,7 @@ data class Block(
|
|||
data class Mark(
|
||||
val range: IntRange,
|
||||
val type: Type,
|
||||
val param: Any? = null
|
||||
val param: String? = null
|
||||
) {
|
||||
enum class Type {
|
||||
STRIKETHROUGH,
|
||||
|
|
5
gradle/wrapper/gradle-wrapper.properties
vendored
5
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,7 +1,6 @@
|
|||
#Tue Oct 22 17:14:40 MSK 2019
|
||||
#Wed Oct 23 20:41:38 MSK 2019
|
||||
#Mon Apr 13 21:05:02 MSK 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
|
||||
|
|
|
@ -55,7 +55,7 @@ fun BlockEntity.Content.Text.Mark.toMiddleware(): Block.Content.Text.Mark {
|
|||
.newBuilder()
|
||||
.setType(Block.Content.Text.Mark.Type.TextColor)
|
||||
.setRange(rangeModel)
|
||||
.setParam(param as String)
|
||||
.setParam(param)
|
||||
.build()
|
||||
}
|
||||
BlockEntity.Content.Text.Mark.Type.LINK -> {
|
||||
|
@ -63,7 +63,7 @@ fun BlockEntity.Content.Text.Mark.toMiddleware(): Block.Content.Text.Mark {
|
|||
.newBuilder()
|
||||
.setType(Block.Content.Text.Mark.Type.Link)
|
||||
.setRange(rangeModel)
|
||||
.setParam(param as String)
|
||||
.setParam(param)
|
||||
.build()
|
||||
}
|
||||
BlockEntity.Content.Text.Mark.Type.BACKGROUND_COLOR -> {
|
||||
|
@ -71,7 +71,7 @@ fun BlockEntity.Content.Text.Mark.toMiddleware(): Block.Content.Text.Mark {
|
|||
.newBuilder()
|
||||
.setType(Block.Content.Text.Mark.Type.BackgroundColor)
|
||||
.setRange(rangeModel)
|
||||
.setParam(param as String)
|
||||
.setParam(param)
|
||||
.build()
|
||||
}
|
||||
BlockEntity.Content.Text.Mark.Type.KEYBOARD -> {
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.agileburo.anytype.core_ui.features.page.BlockView
|
|||
import com.agileburo.anytype.core_ui.features.page.pattern.Matcher
|
||||
import com.agileburo.anytype.core_ui.features.page.pattern.Pattern
|
||||
import com.agileburo.anytype.core_ui.state.ControlPanelState
|
||||
import com.agileburo.anytype.core_ui.widgets.ActionItemType
|
||||
import com.agileburo.anytype.core_utils.common.EventWrapper
|
||||
import com.agileburo.anytype.core_utils.ext.*
|
||||
import com.agileburo.anytype.core_utils.tools.Counter
|
||||
|
@ -521,8 +522,12 @@ class PageViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun onSystemBackPressed() {
|
||||
proceedWithExiting()
|
||||
fun onSystemBackPressed(editorHasChildrenScreens: Boolean) {
|
||||
if (editorHasChildrenScreens) {
|
||||
dispatch(Command.PopBackStack)
|
||||
} else {
|
||||
proceedWithExiting()
|
||||
}
|
||||
}
|
||||
|
||||
fun onBackButtonPressed() {
|
||||
|
@ -755,6 +760,10 @@ class PageViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun onBlockLongPressedClicked(block: BlockView) {
|
||||
dispatch(Command.OpenActionBar(block = block))
|
||||
}
|
||||
|
||||
fun onMarkupActionClicked(markup: Markup.Type) {
|
||||
viewModelScope.launch {
|
||||
markupActionChannel.send(MarkupAction(type = markup))
|
||||
|
@ -840,6 +849,49 @@ class PageViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun onActionBarItemClicked(id: String, action: ActionItemType) {
|
||||
when (action) {
|
||||
ActionItemType.TurnInto -> {
|
||||
stateData.value = ViewState.Error("Turn Into not implemented")
|
||||
}
|
||||
ActionItemType.Delete -> {
|
||||
proceedWithUnlinking(target = id)
|
||||
dispatch(Command.PopBackStack)
|
||||
}
|
||||
ActionItemType.Duplicate -> {
|
||||
duplicateBlock(target = id)
|
||||
dispatch(Command.PopBackStack)
|
||||
}
|
||||
ActionItemType.Rename -> {
|
||||
stateData.value = ViewState.Error("Rename not implemented")
|
||||
}
|
||||
ActionItemType.MoveTo -> {
|
||||
stateData.value = ViewState.Error("Move To not implemented")
|
||||
}
|
||||
ActionItemType.Color -> {
|
||||
stateData.value = ViewState.Error("Color not implemented")
|
||||
}
|
||||
ActionItemType.Background -> {
|
||||
stateData.value = ViewState.Error("Background not implemented")
|
||||
}
|
||||
ActionItemType.Style -> {
|
||||
stateData.value = ViewState.Error("Style not implemented")
|
||||
}
|
||||
ActionItemType.Download -> {
|
||||
stateData.value = ViewState.Error("Download not implemented")
|
||||
}
|
||||
ActionItemType.Replace -> {
|
||||
stateData.value = ViewState.Error("Replace not implemented")
|
||||
}
|
||||
ActionItemType.AddCaption -> {
|
||||
stateData.value = ViewState.Error("Add caption not implemented")
|
||||
}
|
||||
ActionItemType.Divider -> {
|
||||
stateData.value = ViewState.Error("not implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithUnlinking(target: String) {
|
||||
|
||||
// TODO support nested blocks
|
||||
|
@ -876,11 +928,15 @@ class PageViewModel(
|
|||
}
|
||||
|
||||
fun onActionDuplicateClicked() {
|
||||
duplicateBlock(target = focusChannel.value)
|
||||
}
|
||||
|
||||
private fun duplicateBlock(target : String) {
|
||||
duplicateBlock.invoke(
|
||||
scope = viewModelScope,
|
||||
params = DuplicateBlock.Params(
|
||||
context = context,
|
||||
original = focusChannel.value
|
||||
original = target
|
||||
),
|
||||
onResult = { result ->
|
||||
result.either(
|
||||
|
@ -1324,6 +1380,12 @@ class PageViewModel(
|
|||
data class RequestDownloadPermission(
|
||||
val id: String
|
||||
) : Command()
|
||||
|
||||
object PopBackStack : Command()
|
||||
|
||||
data class OpenActionBar(
|
||||
val block: BlockView
|
||||
) : Command()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -1334,7 +1396,7 @@ class PageViewModel(
|
|||
|
||||
data class MarkupAction(
|
||||
val type: Markup.Type,
|
||||
val param: Any? = null
|
||||
val param: String? = null
|
||||
)
|
||||
|
||||
override fun onCleared() {
|
||||
|
|
|
@ -55,8 +55,8 @@ dependencies {
|
|||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation applicationDependencies.fragment
|
||||
implementation 'androidx.appcompat:appcompat:1.0.2'
|
||||
implementation 'androidx.core:core-ktx:1.0.2'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.core:core-ktx:1.2.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation applicationDependencies.design
|
||||
|
||||
|
@ -64,6 +64,6 @@ dependencies {
|
|||
kapt applicationDependencies.permissionDispCompiler
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
}
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
package com.agileburo.anytype.sample
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.agileburo.anytype.core_ui.widgets.BlockActionBarItem
|
||||
import com.agileburo.anytype.core_ui.widgets.ActionItemType
|
||||
import com.agileburo.anytype.core_ui.widgets.dialog.AboveDialog
|
||||
import kotlinx.android.synthetic.main.above_fragment.*
|
||||
import kotlinx.android.synthetic.main.activity_keyboard.*
|
||||
import timber.log.Timber
|
||||
|
||||
class KeyboardActivity : AppCompatActivity(), UpdateValues {
|
||||
|
||||
|
@ -15,7 +21,38 @@ class KeyboardActivity : AppCompatActivity(), UpdateValues {
|
|||
tvThree.text = "333"
|
||||
|
||||
btnTest.setOnClickListener {
|
||||
AboveDialogFragment().show(supportFragmentManager, null)
|
||||
AboveDialogFragment().apply {
|
||||
//setStyle(DialogFragment.STYLE_NORMAL, R.style.AppBottomSheetDialogTheme)
|
||||
}
|
||||
.show(supportFragmentManager, null)
|
||||
}
|
||||
|
||||
edtTest.setOnFocusChangeListener { v, hasFocus ->
|
||||
Timber.d("EditText1 hasFocus:$hasFocus")
|
||||
}
|
||||
|
||||
edtTest.setOnClickListener {
|
||||
Timber.d("EditText1 : OnClick, hasFocus:${it.hasFocus()}")
|
||||
}
|
||||
|
||||
edtTest.setOnLongClickListener {
|
||||
Timber.d("EditText1 : OnLongClick, hasFocus: ${it.hasFocus()} , hasOtherBlocksInFocus : ${it.hasWindowFocus()}")
|
||||
val focus = it.hasFocus()
|
||||
if (!focus) {
|
||||
TestDialog().show(supportFragmentManager, "TAG")
|
||||
}
|
||||
return@setOnLongClickListener !it.hasFocus()
|
||||
}
|
||||
|
||||
with(edtTest2) {
|
||||
setOnLongClickListener {
|
||||
Timber.d("EditText2 : OnLongClick, hasFocus: ${it.hasFocus()}, hasOtherBlocksInFocus : ${it.hasWindowFocus()}")
|
||||
val focus = it.hasFocus()
|
||||
if (!focus) {
|
||||
TestDialog().show(supportFragmentManager, "TAG")
|
||||
}
|
||||
return@setOnLongClickListener !it.hasFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,4 +76,41 @@ interface UpdateValues {
|
|||
fun update1()
|
||||
fun update2()
|
||||
fun update3()
|
||||
}
|
||||
|
||||
class TestDialog : AboveDialog() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
|
||||
|
||||
with(action_container) {
|
||||
addView(BlockActionBarItem(context = requireContext()).apply {
|
||||
setTypeAndClick(
|
||||
ActionItemType.Replace,
|
||||
{})
|
||||
})
|
||||
addView(BlockActionBarItem(context = requireContext()).apply {
|
||||
setTypeAndClick(
|
||||
ActionItemType.TurnInto,
|
||||
{})
|
||||
})
|
||||
addView(BlockActionBarItem(context = requireContext()).apply {
|
||||
setTypeAndClick(
|
||||
ActionItemType.Delete,
|
||||
{})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun layout(): Int {
|
||||
return R.layout.above_fragment
|
||||
}
|
||||
|
||||
override fun title(): String? {
|
||||
return null
|
||||
}
|
||||
}
|
39
sample/src/main/res/layout/above_fragment.xml
Normal file
39
sample/src/main/res/layout/above_fragment.xml
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?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">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:background="@color/chapter_yellow"
|
||||
android:padding="16dp"
|
||||
android:text="To generate a method trace of your app's execution, you can instrument your app using the Debug class. Instrumenting your app this way gives you more control over exactly when the device starts and stops recording tracing information. The device also saves your trace logs using the names you specify, so you can easily identify each log later. You can then view each trace log using the Android Studio CPU Profiler."
|
||||
android:textColor="@color/black"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/action_container"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/action_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="48dp"
|
||||
android:layout_marginEnd="48dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:layout_height="300dp">
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -56,8 +56,15 @@
|
|||
android:id="@+id/edtTest"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Test1983"
|
||||
android:hint="Start typing" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edtTest2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Second "/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnTest"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -6,6 +6,35 @@
|
|||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<!-- <item name="android:dialogTheme">@style/AppBottomSheetDialogTheme</item>-->
|
||||
<item name="alertDialogTheme">@style/DialogTheme</item>
|
||||
<!-- <item name="android:alertDialogTheme">?alertDialogTheme</item>-->
|
||||
<!-- <item name="dialogTheme">?alertDialogTheme</item>-->
|
||||
</style>
|
||||
|
||||
<!-- define your dialog theme -->
|
||||
<style name="DialogTheme" parent="Theme.AppCompat.Light.Dialog.MinWidth">
|
||||
<item name="android:colorBackground">@android:color/transparent</item>
|
||||
<item name="android:textColorHint">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
<style name="AppBottomSheetDialogTheme" parent="Theme.AppCompat.Light.Dialog">
|
||||
<item name="android:colorBackground">@color/black</item>
|
||||
<!-- <item name="colorPrimary">@color/black</item>-->
|
||||
<!-- <item name="bottomSheetStyle">@style/AppModalStyle</item>-->
|
||||
<!-- <item name="android:windowIsTranslucent">true</item>-->
|
||||
<!-- <item name="android:windowBackground">@android:color/transparent</item>-->
|
||||
<!-- <item name="android:windowCloseOnTouchOutside">false</item>-->
|
||||
</style>
|
||||
|
||||
<style name="AppModalStyle" parent="Widget.Design.BottomSheet.Modal">
|
||||
<item name="android:background">@drawable/rounded_dialog</item>
|
||||
<item name="android:windowBackground">@color/black</item>
|
||||
<item name="android:windowBackgroundFallback">@color/black</item>
|
||||
<item name="android:windowFullscreen">true</item>
|
||||
</style>
|
||||
|
||||
<attr name="flow_horizontalGap" format="dimension" />
|
||||
<attr name="flow_horizontalSeparator" format="dimension"/>
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue