mirror of
https://github.com/k0shk0sh/FastHub.git
synced 2025-12-08 19:05:54 +00:00
preparing for markdown editor
This commit is contained in:
parent
fa0f19cb21
commit
efe7a89714
@ -2,6 +2,7 @@ package com.fastaccess.github.di.modules
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.text.util.Linkify
|
||||
import com.fastaccess.data.storage.FastHubSharedPreference
|
||||
import com.fastaccess.github.R
|
||||
import com.fastaccess.github.base.engine.ThemeEngine
|
||||
@ -47,7 +48,7 @@ class FragmentModule {
|
||||
.usePlugin(GlideImagesPlugin.create(context))
|
||||
.usePlugin(TablePlugin.create(context))
|
||||
.usePlugin(StrikethroughPlugin.create())
|
||||
.usePlugin(LinkifyPlugin.create())
|
||||
.usePlugin(LinkifyPlugin.create(Linkify.EMAIL_ADDRESSES or Linkify.WEB_URLS))
|
||||
.usePlugin(
|
||||
SyntaxHighlightPlugin.create(
|
||||
Prism4j(GrammarLocatorDef()), if (ThemeEngine.isLightTheme(preference.theme)) {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
android {
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package com.fastaccess.markdown
|
||||
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.core.view.doOnPreDraw
|
||||
@ -15,17 +17,14 @@ import org.commonmark.renderer.html.HtmlRenderer
|
||||
@PrismBundle(includeAll = true)
|
||||
object MarkdownProvider {
|
||||
|
||||
private const val TOGGLE_START = "<span class=\"email-hidden-toggle\">"
|
||||
private const val TOGGLE_END = "</span>"
|
||||
private const val REPLY_START = "<div class=\"email-quoted-reply\">"
|
||||
private const val REPLY_END = "</div>"
|
||||
private const val SIGNATURE_START = "<div class=\"email-signature-reply\">"
|
||||
private const val SIGNATURE_END = "</div>"
|
||||
private const val HIDDEN_REPLY_START = "<div class=\"email-hidden-reply\" style=\" display:none\">"
|
||||
private const val HIDDEN_REPLY_END = "</div>"
|
||||
private const val BREAK = "<br>"
|
||||
private const val PARAGRAPH_START = "<p>"
|
||||
private const val PARAGRAPH_END = "</p>"
|
||||
private val IMAGE_EXTENSIONS = arrayOf(".png", ".jpg", ".jpeg", ".gif", ".svg")
|
||||
|
||||
private val MARKDOWN_EXTENSIONS = arrayOf(".md", ".mkdn", ".mdwn", ".mdown", ".markdown", ".mkd", ".mkdown", ".ron", ".rst", "adoc")
|
||||
|
||||
private val ARCHIVE_EXTENSIONS = arrayOf(
|
||||
".zip", ".7z", ".rar", ".tar.gz", ".tgz", ".tar.Z", ".tar.bz2", ".tbz2", ".tar.lzma", ".tlz", ".apk", ".jar", ".dmg", ".pdf", ".ico", ".docx",
|
||||
".doc", ".xlsx", ".hwp", ".pptx", ".show", ".mp3", ".ogg", ".ipynb"
|
||||
)
|
||||
|
||||
fun loadIntoTextView(
|
||||
markwon: Markwon,
|
||||
@ -64,4 +63,244 @@ object MarkdownProvider {
|
||||
) {
|
||||
markwon.setMarkdown(textView, html)
|
||||
}
|
||||
|
||||
fun addList(
|
||||
editText: EditText,
|
||||
list: String
|
||||
) {
|
||||
val tag = "$list "
|
||||
val source = editText.text.toString()
|
||||
var selectionStart = editText.selectionStart
|
||||
val selectionEnd = editText.selectionEnd
|
||||
var substring = source.substring(0, selectionStart)
|
||||
val line = substring.lastIndexOf(char = 10.toChar())
|
||||
if (line != -1) {
|
||||
selectionStart = line + 1
|
||||
} else {
|
||||
selectionStart = 0
|
||||
}
|
||||
substring = source.substring(selectionStart, selectionEnd)
|
||||
val split = substring.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
val stringBuffer = StringBuilder()
|
||||
if (split.isNotEmpty())
|
||||
for (s in split) {
|
||||
if (s.isEmpty() && stringBuffer.isNotEmpty()) {
|
||||
stringBuffer.append("\n")
|
||||
continue
|
||||
}
|
||||
if (!s.trim { it <= ' ' }.startsWith(tag)) {
|
||||
if (stringBuffer.isNotEmpty()) stringBuffer.append("\n")
|
||||
stringBuffer.append(tag).append(s)
|
||||
} else {
|
||||
if (stringBuffer.isNotEmpty()) stringBuffer.append("\n")
|
||||
stringBuffer.append(s)
|
||||
}
|
||||
}
|
||||
|
||||
if (stringBuffer.isEmpty()) {
|
||||
stringBuffer.append(tag)
|
||||
}
|
||||
editText.text.replace(selectionStart, selectionEnd, stringBuffer.toString())
|
||||
editText.setSelection(stringBuffer.length + selectionStart)
|
||||
}
|
||||
|
||||
fun addHeader(
|
||||
editText: EditText,
|
||||
level: Int
|
||||
) {
|
||||
val source = editText.text.toString()
|
||||
val selectionStart = editText.selectionStart
|
||||
val selectionEnd = editText.selectionEnd
|
||||
val result = StringBuilder()
|
||||
val substring = source.substring(selectionStart, selectionEnd)
|
||||
if (!hasNewLine(source, selectionStart)) result.append("\n")
|
||||
for (i in 0..level) result.append("#")
|
||||
result.append(" ").append(substring)
|
||||
editText.text.replace(selectionStart, selectionEnd, result.toString())
|
||||
editText.setSelection(selectionStart + result.length)
|
||||
|
||||
}
|
||||
|
||||
fun addItalic(editText: EditText) {
|
||||
val source = editText.text.toString()
|
||||
val selectionStart = editText.selectionStart
|
||||
val selectionEnd = editText.selectionEnd
|
||||
val substring = source.substring(selectionStart, selectionEnd)
|
||||
val result = "_" + substring + "_ "
|
||||
editText.text.replace(selectionStart, selectionEnd, result)
|
||||
editText.setSelection(result.length + selectionStart - 2)
|
||||
|
||||
}
|
||||
|
||||
fun addBold(editText: EditText) {
|
||||
val source = editText.text.toString()
|
||||
val selectionStart = editText.selectionStart
|
||||
val selectionEnd = editText.selectionEnd
|
||||
val substring = source.substring(selectionStart, selectionEnd)
|
||||
val result = "**$substring** "
|
||||
editText.text.replace(selectionStart, selectionEnd, result)
|
||||
editText.setSelection(result.length + selectionStart - 3)
|
||||
|
||||
}
|
||||
|
||||
fun addCode(editText: EditText) {
|
||||
try {
|
||||
val source = editText.text.toString()
|
||||
val selectionStart = editText.selectionStart
|
||||
val selectionEnd = editText.selectionEnd
|
||||
val substring = source.substring(selectionStart, selectionEnd)
|
||||
val result: String
|
||||
result = if (hasNewLine(source, selectionStart))
|
||||
"```\n$substring\n```\n"
|
||||
else
|
||||
"\n```\n$substring\n```\n"
|
||||
|
||||
editText.text.replace(selectionStart, selectionEnd, result)
|
||||
editText.setSelection(result.length + selectionStart - 5)
|
||||
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun addInlinleCode(editText: EditText) {
|
||||
val source = editText.text.toString()
|
||||
val selectionStart = editText.selectionStart
|
||||
val selectionEnd = editText.selectionEnd
|
||||
val substring = source.substring(selectionStart, selectionEnd)
|
||||
val result = "`$substring` "
|
||||
editText.text.replace(selectionStart, selectionEnd, result)
|
||||
editText.setSelection(result.length + selectionStart - 2)
|
||||
|
||||
}
|
||||
|
||||
fun addStrikeThrough(editText: EditText) {
|
||||
val source = editText.text.toString()
|
||||
val selectionStart = editText.selectionStart
|
||||
val selectionEnd = editText.selectionEnd
|
||||
val substring = source.substring(selectionStart, selectionEnd)
|
||||
val result = "~~$substring~~ "
|
||||
editText.text.replace(selectionStart, selectionEnd, result)
|
||||
editText.setSelection(result.length + selectionStart - 3)
|
||||
|
||||
}
|
||||
|
||||
fun addQuote(editText: EditText) {
|
||||
val source = editText.text.toString()
|
||||
val selectionStart = editText.selectionStart
|
||||
val selectionEnd = editText.selectionEnd
|
||||
val substring = source.substring(selectionStart, selectionEnd)
|
||||
val result: String
|
||||
result = if (hasNewLine(source, selectionStart)) {
|
||||
"> $substring"
|
||||
} else {
|
||||
"\n> $substring"
|
||||
|
||||
}
|
||||
editText.text.replace(selectionStart, selectionEnd, result)
|
||||
editText.setSelection(result.length + selectionStart)
|
||||
|
||||
}
|
||||
|
||||
fun addDivider(editText: EditText) {
|
||||
val source = editText.text.toString()
|
||||
val selectionStart = editText.selectionStart
|
||||
val result: String
|
||||
result = if (hasNewLine(source, selectionStart)) {
|
||||
"-------\n"
|
||||
} else {
|
||||
"\n-------\n"
|
||||
}
|
||||
editText.text.replace(selectionStart, selectionStart, result)
|
||||
editText.setSelection(result.length + selectionStart)
|
||||
|
||||
}
|
||||
|
||||
fun addPhoto(
|
||||
editText: EditText,
|
||||
title: String,
|
||||
link: String
|
||||
) {
|
||||
val result = ""
|
||||
insertAtCursor(editText, result)
|
||||
}
|
||||
|
||||
fun addLink(
|
||||
editText: EditText,
|
||||
title: String,
|
||||
link: String
|
||||
) {
|
||||
val result = "[$title]($link)"
|
||||
insertAtCursor(editText, result)
|
||||
}
|
||||
|
||||
private fun hasNewLine(
|
||||
source: String,
|
||||
selectionStart: Int
|
||||
): Boolean {
|
||||
var _source = source
|
||||
try {
|
||||
if (_source.isEmpty()) return true
|
||||
_source = _source.substring(0, selectionStart)
|
||||
return _source[_source.length - 1].toInt() == 10
|
||||
} catch (e: StringIndexOutOfBoundsException) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
fun isImage(name: String?): Boolean {
|
||||
var name = name
|
||||
if (name.isNullOrEmpty()) return false
|
||||
name = name.toLowerCase()
|
||||
for (value in IMAGE_EXTENSIONS) {
|
||||
val extension = MimeTypeMap.getFileExtensionFromUrl(name)
|
||||
if (extension != null && value.replace(".", "") == extension || name.endsWith(value)) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun isMarkdown(name: String?): Boolean {
|
||||
var _name = name
|
||||
if (_name.isNullOrEmpty()) return false
|
||||
_name = _name.toLowerCase()
|
||||
for (value in MARKDOWN_EXTENSIONS) {
|
||||
val extension = MimeTypeMap.getFileExtensionFromUrl(_name)
|
||||
if (extension != null && value.replace(".", "") == extension ||
|
||||
_name.equals("README", ignoreCase = true) || _name.endsWith(value)
|
||||
)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun isArchive(name: String?): Boolean {
|
||||
var _name = name
|
||||
if (_name.isNullOrEmpty()) return false
|
||||
_name = _name.toLowerCase()
|
||||
for (value in ARCHIVE_EXTENSIONS) {
|
||||
val extension = MimeTypeMap.getFileExtensionFromUrl(_name)
|
||||
if (extension != null && value.replace(".", "") == extension || _name.endsWith(value)) return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun insertAtCursor(
|
||||
editText: EditText,
|
||||
text: String
|
||||
) {
|
||||
val oriContent = editText.text.toString()
|
||||
val start = editText.selectionStart
|
||||
val end = editText.selectionEnd
|
||||
if (start >= 0 && end > 0 && start != end) {
|
||||
editText.text = editText.text.replace(start, end, text)
|
||||
} else {
|
||||
val index = if (editText.selectionStart >= 0) editText.selectionStart else 0
|
||||
val builder = StringBuilder(oriContent)
|
||||
builder.insert(index, text)
|
||||
editText.setText(builder.toString())
|
||||
editText.setSelection(index + text.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
package com.fastaccess.markdown.widget
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.LinearLayout
|
||||
import com.fastaccess.markdown.MarkdownProvider
|
||||
import com.fastaccess.markdown.R
|
||||
import kotlinx.android.synthetic.main.markdown_buttons_layout.view.*
|
||||
|
||||
/**
|
||||
* Created by Kosh on 2019-07-22.
|
||||
*/
|
||||
class MarkdownLayout : LinearLayout, View.OnClickListener {
|
||||
|
||||
private lateinit var editText: EditText
|
||||
|
||||
constructor(context: Context?) : super(context)
|
||||
constructor(
|
||||
context: Context?,
|
||||
attrs: AttributeSet?
|
||||
) : super(context, attrs)
|
||||
|
||||
constructor(
|
||||
context: Context?,
|
||||
attrs: AttributeSet?,
|
||||
defStyleAttr: Int
|
||||
) : super(context, attrs, defStyleAttr)
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
orientation = HORIZONTAL
|
||||
View.inflate(context, R.layout.markdown_buttons_layout, this)
|
||||
if (isInEditMode) return
|
||||
}
|
||||
|
||||
fun init(editText: EditText) {
|
||||
this.editText = editText
|
||||
headerOne.setOnClickListener(this)
|
||||
headerTwo.setOnClickListener(this)
|
||||
headerThree.setOnClickListener(this)
|
||||
bold.setOnClickListener(this)
|
||||
italic.setOnClickListener(this)
|
||||
strikethrough.setOnClickListener(this)
|
||||
bullet.setOnClickListener(this)
|
||||
header.setOnClickListener(this)
|
||||
code.setOnClickListener(this)
|
||||
numbered.setOnClickListener(this)
|
||||
quote.setOnClickListener(this)
|
||||
link.setOnClickListener(this)
|
||||
image.setOnClickListener(this)
|
||||
unCheckbox.setOnClickListener(this)
|
||||
checkbox.setOnClickListener(this)
|
||||
inlineCode.setOnClickListener(this)
|
||||
addEmoji.setOnClickListener(this)
|
||||
signature.setOnClickListener(this)
|
||||
|
||||
}
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
if (editText.selectionEnd == -1 || editText.selectionStart == -1) {
|
||||
return
|
||||
}
|
||||
v?.let {
|
||||
when (it.id) {
|
||||
R.id.headerOne -> MarkdownProvider.addHeader(editText, 1)
|
||||
R.id.headerTwo -> MarkdownProvider.addHeader(editText, 2)
|
||||
R.id.headerThree -> MarkdownProvider.addHeader(editText, 3)
|
||||
R.id.bold -> MarkdownProvider.addBold(editText)
|
||||
R.id.italic -> MarkdownProvider.addItalic(editText)
|
||||
R.id.strikethrough -> MarkdownProvider.addStrikeThrough(editText)
|
||||
R.id.bullet -> MarkdownProvider.addList(editText, "-")
|
||||
R.id.header -> MarkdownProvider.addDivider(editText)
|
||||
R.id.code -> MarkdownProvider.addCode(editText)
|
||||
R.id.numbered -> MarkdownProvider.addList(editText, "1")
|
||||
R.id.quote -> MarkdownProvider.addQuote(editText)
|
||||
R.id.link -> MarkdownProvider.addLink(editText, "", "")
|
||||
R.id.image -> MarkdownProvider.addPhoto(editText, "", "")
|
||||
R.id.unCheckbox -> MarkdownProvider.addList(editText, "- [x]")
|
||||
R.id.checkbox -> MarkdownProvider.addList(editText, "- [ ]")
|
||||
R.id.inlineCode -> MarkdownProvider.addInlinleCode(editText)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
214
markdown/src/main/res/layout/markdown_buttons_layout.xml
Normal file
214
markdown/src/main/res/layout/markdown_buttons_layout.xml
Normal file
@ -0,0 +1,214 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/editorIconsHolder"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:fadeScrollbars="true"
|
||||
android:scrollbarFadeDuration="500"
|
||||
android:scrollbarSize="1dp"
|
||||
android:scrollbarStyle="outsideOverlay">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/headerOne"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/header_one"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
android:src="@drawable/ic_header_one" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/headerTwo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/header_two"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
|
||||
android:src="@drawable/ic_header_two" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/headerThree"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/header_three"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
|
||||
android:src="@drawable/ic_header_three" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/bold"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/bold"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
|
||||
android:src="@drawable/ic_format_bold" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/italic"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/italic"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
|
||||
android:src="@drawable/ic_format_italic" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/strikethrough"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/strike_through"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
|
||||
android:src="@drawable/ic_format_strikethrough" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/bullet"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/bullet"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
|
||||
android:src="@drawable/ic_format_list_bulleted" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/numbered"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/numbered_list"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
|
||||
android:src="@drawable/ic_list_numbers" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/todo_checked"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
|
||||
android:src="@drawable/ic_checkbox" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/unCheckbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/todo_unchecked"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
|
||||
android:src="@drawable/ic_checkbox_empty" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/header"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/divider"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
|
||||
android:src="@drawable/ic_minus" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/inlineCode"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/code"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
|
||||
android:src="@drawable/ic_inline_code" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/code"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/code"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
android:src="@drawable/ic_code" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/quote"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/quote"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
|
||||
android:src="@drawable/ic_format_quote" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/link"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/link"
|
||||
android:padding="@dimen/spacing_micro"
|
||||
|
||||
android:src="@drawable/ic_insert_link" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/image"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
android:src="@drawable/ic_image" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/signature"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/app_name"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
android:src="@drawable/ic_fasthub_mascot" />
|
||||
</LinearLayout>
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
||||
<View
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?dividerColor" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/addEmoji"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/reactions"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
android:src="@drawable/ic_add_emoji" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/preview"
|
||||
android:padding="@dimen/spacing_normal"
|
||||
android:src="@drawable/ic_eye" />
|
||||
</merge>
|
||||
Loading…
x
Reference in New Issue
Block a user