mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-12 10:40:25 +09:00
DROID-210 Editor | Underline markup (#2508)
* DROID-210 underline icon design * DROID-210 underline added to markup toolbar * DROID-210 underline mapping etc * DROID-210 underline span * DROID-210 update underline span with sdk version * DROID-210 url span, add text and line colors * DROID-210 add underline to extra toolbar * DROID-210 underline height as param * DROID-210 tests * DROID-210 underline added to slash menu * DROID-210 rename * DROID-210 rename param * DROID-210 update icon * DROID-210 analytics param Co-authored-by: konstantiniiv <ki@anytype.io>
This commit is contained in:
parent
cceb6bb4a7
commit
a655e711a2
42 changed files with 302 additions and 29 deletions
|
@ -1776,6 +1776,9 @@ class EditorViewModel(
|
|||
is StylingEvent.Markup.Code -> {
|
||||
onUpdateBlockListMarkup(ids, Markup.Type.KEYBOARD)
|
||||
}
|
||||
is StylingEvent.Markup.Underline -> {
|
||||
onUpdateBlockListMarkup(ids, Markup.Type.UNDERLINE)
|
||||
}
|
||||
is StylingEvent.Markup.Link -> {
|
||||
if (ids.size == 1) {
|
||||
onBlockStyleLinkClicked(ids[0])
|
||||
|
|
|
@ -31,6 +31,7 @@ interface Markup {
|
|||
data class Bold(override val from: Int, override val to: Int) : Mark()
|
||||
data class Italic(override val from: Int, override val to: Int) : Mark()
|
||||
data class Strikethrough(override val from: Int, override val to: Int) : Mark()
|
||||
data class Underline(override val from: Int, override val to: Int) : Mark()
|
||||
data class Keyboard(override val from: Int, override val to: Int) : Mark()
|
||||
data class TextColor(
|
||||
override val from: Int,
|
||||
|
@ -142,7 +143,8 @@ interface Markup {
|
|||
LINK,
|
||||
KEYBOARD,
|
||||
MENTION,
|
||||
OBJECT
|
||||
OBJECT,
|
||||
UNDERLINE
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -46,6 +46,7 @@ fun Markup.Type.toCoreModel(): Mark.Type = when (this) {
|
|||
Markup.Type.KEYBOARD -> Mark.Type.KEYBOARD
|
||||
Markup.Type.MENTION -> Mark.Type.MENTION
|
||||
Markup.Type.OBJECT -> Mark.Type.OBJECT
|
||||
Markup.Type.UNDERLINE -> Mark.Type.UNDERLINE
|
||||
}
|
||||
|
||||
fun Block.Content.Text.addMarkToContent(mark: Mark): Block.Content.Text {
|
||||
|
|
|
@ -40,6 +40,7 @@ fun SlashItem.Style.Markup.convertToMarkType() = when (this) {
|
|||
SlashItem.Style.Markup.Strikethrough -> Block.Content.Text.Mark.Type.STRIKETHROUGH
|
||||
SlashItem.Style.Markup.Code -> Block.Content.Text.Mark.Type.KEYBOARD
|
||||
SlashItem.Style.Markup.Italic -> Block.Content.Text.Mark.Type.ITALIC
|
||||
SlashItem.Style.Markup.Underline -> Block.Content.Text.Mark.Type.UNDERLINE
|
||||
}
|
||||
|
||||
object SlashExtensions {
|
||||
|
@ -85,6 +86,7 @@ object SlashExtensions {
|
|||
SlashItem.Style.Markup.Bold,
|
||||
SlashItem.Style.Markup.Italic,
|
||||
SlashItem.Style.Markup.Strikethrough,
|
||||
SlashItem.Style.Markup.Underline,
|
||||
SlashItem.Style.Markup.Code
|
||||
)
|
||||
}
|
||||
|
|
|
@ -251,6 +251,11 @@ sealed class SlashItem {
|
|||
override fun getAbbreviation(): List<String>? = null
|
||||
}
|
||||
|
||||
object Underline : Markup() {
|
||||
override fun getSearchName(): String = SlashConst.SLASH_STYLE_UNDERLINE
|
||||
override fun getAbbreviation(): List<String>? = null
|
||||
}
|
||||
|
||||
object Code : Markup() {
|
||||
override fun getSearchName(): String = SlashConst.SLASH_STYLE_CODE
|
||||
override fun getAbbreviation(): List<String>? = null
|
||||
|
|
|
@ -114,12 +114,14 @@ fun List<Block.Content.Text>.getStyleOtherToolbarState(): StyleToolbarState.Othe
|
|||
isSupportCode = true,
|
||||
isSupportLinked = true,
|
||||
isSupportStrikethrough = true,
|
||||
isSupportUnderline = true,
|
||||
isSupportAlignStart = all { it.alignmentSupport().contains(Alignment.START) },
|
||||
isSupportAlignCenter = all { it.alignmentSupport().contains(Alignment.CENTER) },
|
||||
isSupportAlignEnd = all { it.alignmentSupport().contains(Alignment.END) },
|
||||
isBoldSelected = isBoldSelected,
|
||||
isItalicSelected = all { it.isItalic() },
|
||||
isStrikethroughSelected = all { it.isStrikethrough() },
|
||||
isUnderlineSelected = all { it.isUnderline() },
|
||||
isCodeSelected = all { it.isCode() },
|
||||
isLinkedSelected = all { it.isLinked() },
|
||||
isAlignCenterSelected = all { it.isAlignCenter() },
|
||||
|
@ -158,6 +160,7 @@ fun Block.Content.Text.getSupportedMarkupTypes(): List<Markup.Type> = when (styl
|
|||
Markup.Type.BOLD,
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.UNDERLINE,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
|
@ -167,6 +170,7 @@ fun Block.Content.Text.getSupportedMarkupTypes(): List<Markup.Type> = when (styl
|
|||
listOf(
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.UNDERLINE,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
|
@ -197,3 +201,7 @@ fun Block.Content.Text.isLinked(): Boolean = marks.any { mark ->
|
|||
fun Block.Content.Text.isAlignStart(): Boolean = this.align == Block.Align.AlignLeft
|
||||
fun Block.Content.Text.isAlignCenter(): Boolean = this.align == Block.Align.AlignCenter
|
||||
fun Block.Content.Text.isAlignEnd(): Boolean = this.align == Block.Align.AlignRight
|
||||
|
||||
fun Block.Content.Text.isUnderline(): Boolean = marks.any { mark ->
|
||||
mark.type == Block.Content.Text.Mark.Type.UNDERLINE && mark.range.first == 0 && mark.range.last == text.length
|
||||
}
|
|
@ -14,6 +14,7 @@ sealed class StyleToolbarState {
|
|||
val isSupportBold: Boolean = false,
|
||||
val isSupportItalic: Boolean = false,
|
||||
val isSupportStrikethrough: Boolean = false,
|
||||
val isSupportUnderline: Boolean = false,
|
||||
val isSupportCode: Boolean = false,
|
||||
val isSupportLinked: Boolean = false,
|
||||
val isSupportAlignStart: Boolean = false,
|
||||
|
@ -22,6 +23,7 @@ sealed class StyleToolbarState {
|
|||
val isBoldSelected: Boolean = false,
|
||||
val isItalicSelected: Boolean = false,
|
||||
val isStrikethroughSelected: Boolean = false,
|
||||
val isUnderlineSelected: Boolean = false,
|
||||
val isCodeSelected: Boolean = false,
|
||||
val isLinkedSelected: Boolean = false,
|
||||
val isAlignStartSelected: Boolean = false,
|
||||
|
|
|
@ -17,6 +17,7 @@ sealed class StylingEvent {
|
|||
object StrikeThrough : Markup()
|
||||
object Code : Markup()
|
||||
object Link : Markup()
|
||||
object Underline : Markup()
|
||||
}
|
||||
|
||||
sealed class Coloring : StylingEvent() {
|
||||
|
|
|
@ -6,6 +6,7 @@ interface MarkupStyleDescriptor {
|
|||
val isBold: Boolean
|
||||
val isItalic: Boolean
|
||||
val isStrikethrough: Boolean
|
||||
val isUnderline: Boolean
|
||||
val isCode: Boolean
|
||||
val isLinked: Boolean
|
||||
val markupTextColor: String?
|
||||
|
@ -20,6 +21,7 @@ interface MarkupStyleDescriptor {
|
|||
override val isItalic: Boolean,
|
||||
override val isCode: Boolean,
|
||||
override val isStrikethrough: Boolean,
|
||||
override val isUnderline: Boolean,
|
||||
override val isLinked: Boolean,
|
||||
override val markupTextColor: String?,
|
||||
override val markupHighlightColor: String?,
|
||||
|
|
|
@ -148,7 +148,7 @@ fun Block.Content.Text.Mark.Type.getPropName() = when (this) {
|
|||
Block.Content.Text.Mark.Type.KEYBOARD -> "code"
|
||||
Block.Content.Text.Mark.Type.ITALIC -> "italic"
|
||||
Block.Content.Text.Mark.Type.BOLD -> "bold"
|
||||
Block.Content.Text.Mark.Type.UNDERSCORED -> "underscored"
|
||||
Block.Content.Text.Mark.Type.UNDERLINE -> "underline"
|
||||
Block.Content.Text.Mark.Type.LINK -> "linkURL"
|
||||
Block.Content.Text.Mark.Type.TEXT_COLOR -> "color"
|
||||
Block.Content.Text.Mark.Type.BACKGROUND_COLOR -> "bgcolor"
|
||||
|
@ -167,6 +167,7 @@ fun Markup.Type.getPropName() = when (this) {
|
|||
Markup.Type.KEYBOARD -> "code"
|
||||
Markup.Type.MENTION -> "mention"
|
||||
Markup.Type.OBJECT -> "linkObject"
|
||||
Markup.Type.UNDERLINE -> "underline"
|
||||
}
|
||||
|
||||
fun DVViewerType.getPropName() = when (this) {
|
||||
|
|
|
@ -61,6 +61,7 @@ fun Block.style(selection: IntRange): MarkupStyleDescriptor {
|
|||
var isBold = false
|
||||
var isItalic = false
|
||||
var isStrike = false
|
||||
var isUnderline = false
|
||||
var isCode = false
|
||||
var isLinked = false
|
||||
|
||||
|
@ -94,6 +95,12 @@ fun Block.style(selection: IntRange): MarkupStyleDescriptor {
|
|||
if (overlap.inside()) isStrike = true
|
||||
}
|
||||
}
|
||||
Block.Content.Text.Mark.Type.UNDERLINE -> {
|
||||
if (!isUnderline) {
|
||||
val overlap = selection.overlap(mark.range)
|
||||
if (overlap.inside()) isUnderline = true
|
||||
}
|
||||
}
|
||||
Block.Content.Text.Mark.Type.KEYBOARD -> {
|
||||
if (!isCode) {
|
||||
val overlap = selection.overlap(mark.range)
|
||||
|
@ -135,7 +142,8 @@ fun Block.style(selection: IntRange): MarkupStyleDescriptor {
|
|||
markupHighlightColor = markupHighlightColor,
|
||||
markupUrl = markupUrl,
|
||||
blockTextColor = blockTextColor,
|
||||
blockBackroundColor = blockBackgroundColor
|
||||
blockBackroundColor = blockBackgroundColor,
|
||||
isUnderline = isUnderline
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -181,6 +189,7 @@ private fun Markup.Mark.updateRanges(start: Int, length: Int): Markup.Mark {
|
|||
is Markup.Mark.BackgroundColor -> copy(from = newFrom, to = newTo)
|
||||
is Markup.Mark.Bold -> copy(from = newFrom, to = newTo)
|
||||
is Markup.Mark.Italic -> copy(from = newFrom, to = newTo)
|
||||
is Markup.Mark.Underline -> copy(from = newFrom, to = newTo)
|
||||
is Markup.Mark.Keyboard -> copy(from = newFrom, to = newTo)
|
||||
is Markup.Mark.Link -> copy(from = newFrom, to = newTo)
|
||||
is Markup.Mark.Mention.Base -> copy(from = newFrom, to = newTo)
|
||||
|
|
|
@ -220,6 +220,12 @@ fun Block.Content.Text.marks(
|
|||
to = mark.range.last
|
||||
)
|
||||
}
|
||||
Block.Content.Text.Mark.Type.UNDERLINE -> {
|
||||
Markup.Mark.Underline(
|
||||
from = mark.range.first,
|
||||
to = mark.range.last
|
||||
)
|
||||
}
|
||||
Block.Content.Text.Mark.Type.TEXT_COLOR -> {
|
||||
val color = mark.param
|
||||
if (color.isNullOrBlank()) null
|
||||
|
@ -478,6 +484,10 @@ fun Markup.Mark.mark(): Block.Content.Text.Mark = when (this) {
|
|||
range = from..to,
|
||||
type = Block.Content.Text.Mark.Type.ITALIC
|
||||
)
|
||||
is Markup.Mark.Underline -> Block.Content.Text.Mark(
|
||||
range = from..to,
|
||||
type = Block.Content.Text.Mark.Type.UNDERLINE
|
||||
)
|
||||
is Markup.Mark.Strikethrough -> Block.Content.Text.Mark(
|
||||
range = from..to,
|
||||
type = Block.Content.Text.Mark.Type.STRIKETHROUGH
|
||||
|
@ -777,7 +787,10 @@ fun List<ObjectType.Layout>.toView(): List<ObjectLayoutView> = map { layout ->
|
|||
isSelected = false
|
||||
)
|
||||
ObjectType.Layout.SPACE -> ObjectLayoutView.Space(id = layout.code, isSelected = false)
|
||||
ObjectType.Layout.BOOKMARK -> ObjectLayoutView.Bookmark(id = layout.code, isSelected = false)
|
||||
ObjectType.Layout.BOOKMARK -> ObjectLayoutView.Bookmark(
|
||||
id = layout.code,
|
||||
isSelected = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -426,6 +426,7 @@ class ControlPanelStateReducerTest {
|
|||
isCode = false,
|
||||
isLinked = false,
|
||||
isStrikethrough = false,
|
||||
isUnderline = false,
|
||||
markupTextColor = "yellow",
|
||||
markupUrl = null,
|
||||
markupHighlightColor = "red",
|
||||
|
@ -481,6 +482,7 @@ class ControlPanelStateReducerTest {
|
|||
isCode = false,
|
||||
isLinked = false,
|
||||
isStrikethrough = false,
|
||||
isUnderline = false,
|
||||
markupTextColor = null,
|
||||
markupUrl = null,
|
||||
markupHighlightColor = null,
|
||||
|
@ -731,6 +733,7 @@ class ControlPanelStateReducerTest {
|
|||
isCode = false,
|
||||
isLinked = false,
|
||||
isStrikethrough = false,
|
||||
isUnderline = false,
|
||||
markupTextColor = null,
|
||||
markupUrl = null,
|
||||
markupHighlightColor = null,
|
||||
|
@ -742,6 +745,7 @@ class ControlPanelStateReducerTest {
|
|||
Markup.Type.BOLD,
|
||||
Markup.Type.ITALIC,
|
||||
Markup.Type.STRIKETHROUGH,
|
||||
Markup.Type.UNDERLINE,
|
||||
Markup.Type.KEYBOARD,
|
||||
Markup.Type.LINK
|
||||
)
|
||||
|
|
|
@ -107,6 +107,7 @@ class EditorSlashWidgetClicksTest: EditorPresentationTestSetup() {
|
|||
SlashItem.Style.Markup.Bold,
|
||||
SlashItem.Style.Markup.Italic,
|
||||
SlashItem.Style.Markup.Strikethrough,
|
||||
SlashItem.Style.Markup.Underline,
|
||||
SlashItem.Style.Markup.Code
|
||||
),
|
||||
mediaItems = emptyList(),
|
||||
|
|
|
@ -257,6 +257,7 @@ class EditorSlashWidgetFilterTest : EditorPresentationTestSetup() {
|
|||
SlashItem.Style.Type.Bulleted,
|
||||
SlashItem.Style.Type.Numbered,
|
||||
SlashItem.Style.Markup.Bold,
|
||||
SlashItem.Style.Markup.Underline,
|
||||
SlashItem.Style.Markup.Code
|
||||
)
|
||||
assertEquals(expected = expectedStyleItems, actual = command.styleItems)
|
||||
|
|
|
@ -443,6 +443,7 @@ class StyleToolbarExtKtTest {
|
|||
isSupportBold = true,
|
||||
isSupportItalic = true,
|
||||
isSupportStrikethrough = true,
|
||||
isSupportUnderline = true,
|
||||
isSupportCode = true,
|
||||
isSupportLinked = true,
|
||||
isSupportAlignEnd = false,
|
||||
|
@ -507,6 +508,7 @@ class StyleToolbarExtKtTest {
|
|||
isSupportBold = false,
|
||||
isSupportItalic = true,
|
||||
isSupportStrikethrough = true,
|
||||
isSupportUnderline = true,
|
||||
isSupportCode = true,
|
||||
isSupportLinked = true,
|
||||
isSupportAlignEnd = true,
|
||||
|
@ -588,6 +590,7 @@ class StyleToolbarExtKtTest {
|
|||
isSupportBold = true,
|
||||
isSupportItalic = true,
|
||||
isSupportStrikethrough = true,
|
||||
isSupportUnderline = true,
|
||||
isSupportCode = true,
|
||||
isSupportLinked = true,
|
||||
isSupportAlignEnd = true,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue