mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 13:57:10 +09:00
Merge branch 'feature_render_blocks_with_header_content_types' into 'develop'
Feature render blocks with header content types See merge request ra3orbladez/anytype.io.mobile!7
This commit is contained in:
commit
0394e6205e
17 changed files with 339 additions and 40 deletions
|
@ -5,23 +5,31 @@
|
|||
"parentId": "",
|
||||
"type": 3,
|
||||
"contentType": 3,
|
||||
"content": "{\"text\":\"Заголовок\",\"marks\":[]}",
|
||||
"content": "{\"text\":\"Заголовок (h1)\",\"marks\":[]}",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": "02ca4410-2cff-5978-81e5-09dc76dd003c",
|
||||
"parentId": "",
|
||||
"type": 3,
|
||||
"contentType": 1,
|
||||
"content": "{\"text\":\"первый элемент\",\"marks\":[]}",
|
||||
"contentType": 4,
|
||||
"content": "{\"text\":\"первый элемент (h3)\",\"marks\":[]}",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": "116271cc-c6e3-5c58-8598-9342567b9a66",
|
||||
"parentId": "",
|
||||
"type": 3,
|
||||
"contentType": 1,
|
||||
"content": "{\"text\":\"второй элемент\",\"marks\":[]}",
|
||||
"contentType": 8,
|
||||
"content": "{\"text\":\"Все счастливые семьи похожи друг на друга, каждая несчастливая семья несчастлива по-своему\",\"marks\":[]}",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": "116271cc-c6e3-5c58-8598-9342567b9a66",
|
||||
"parentId": "",
|
||||
"type": 3,
|
||||
"contentType": 10,
|
||||
"content": "{\"text\":\"Написать письмо\",\"marks\":[]}",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
|
@ -35,8 +43,8 @@
|
|||
"id": "22a8f9f5-b042-5532-bb5d-cbda07f579e0",
|
||||
"parentId": "93f8810e-590f-5962-a662-2c1fe17e5cbe",
|
||||
"type": 3,
|
||||
"contentType": 1,
|
||||
"content": "{\"text\":\"чайлд третьего\",\"marks\":[]}",
|
||||
"contentType": 2,
|
||||
"content": "{\"text\":\"data class User(val name : String)\",\"marks\":[]}",
|
||||
"children": [
|
||||
{
|
||||
"id": "1983",
|
||||
|
@ -62,8 +70,8 @@
|
|||
"id": "21fe093a-5f74-583b-9c17-ee798e1bfc7e",
|
||||
"parentId": "",
|
||||
"type": 3,
|
||||
"contentType": 1,
|
||||
"content": "{\"text\":\"четвертый элемент\",\"marks\":[]}",
|
||||
"contentType": 2,
|
||||
"content": "{\"text\":\"data class User(val name : String)\",\"marks\":[]}",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@ import com.agileburo.anytype.feature_editor.data.BlockConverter
|
|||
import com.agileburo.anytype.feature_editor.data.BlockConverterImpl
|
||||
import com.agileburo.anytype.feature_editor.data.EditorRepo
|
||||
import com.agileburo.anytype.feature_editor.data.EditorRepoImpl
|
||||
import com.agileburo.anytype.feature_editor.data.datasource.IPFSDataSource
|
||||
import com.agileburo.anytype.feature_editor.data.datasource.BlockDataSource
|
||||
import com.agileburo.anytype.feature_editor.data.datasource.IPFSDataSourceImpl
|
||||
import com.agileburo.anytype.feature_editor.domain.EditorInteractor
|
||||
import com.agileburo.anytype.feature_editor.domain.EditorInteractorImpl
|
||||
|
@ -39,7 +39,7 @@ class EditorModule {
|
|||
|
||||
@Provides
|
||||
@PerFeature
|
||||
fun provideRepo(blockConverter: BlockConverter, dataSource: IPFSDataSource): EditorRepo =
|
||||
fun provideRepo(blockConverter: BlockConverter, dataSource: BlockDataSource): EditorRepo =
|
||||
EditorRepoImpl(dataSource = dataSource, blockConverter = blockConverter)
|
||||
|
||||
@Provides
|
||||
|
@ -48,7 +48,7 @@ class EditorModule {
|
|||
|
||||
@Provides
|
||||
@PerFeature
|
||||
fun provideDataSource(context: Context, gson: Gson): IPFSDataSource =
|
||||
fun provideDataSource(context: Context, gson: Gson): BlockDataSource =
|
||||
IPFSDataSourceImpl(context = context, gson = gson)
|
||||
|
||||
@Provides
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package com.agileburo.anytype.feature_editor.data
|
||||
|
||||
import com.agileburo.anytype.feature_editor.domain.Block
|
||||
import com.agileburo.anytype.feature_editor.domain.toContentType
|
||||
import com.agileburo.anytype.feature_editor.domain.toNumericalCode
|
||||
|
||||
/**
|
||||
* Created by Konstantin Ivanov
|
||||
|
@ -17,13 +19,15 @@ class BlockConverterImpl : BlockConverter {
|
|||
override fun modelToDomain(model: BlockModel) = Block(
|
||||
id = model.id,
|
||||
content = model.content,
|
||||
parentId = model.parentId
|
||||
parentId = model.parentId,
|
||||
contentType = model.contentType.toContentType()
|
||||
)
|
||||
|
||||
override fun domainToModel(block: Block) = BlockModel(
|
||||
id = block.id,
|
||||
content = block.content,
|
||||
parentId = block.parentId,
|
||||
children = mutableListOf()
|
||||
children = mutableListOf(),
|
||||
contentType = block.contentType.toNumericalCode()
|
||||
)
|
||||
}
|
|
@ -9,5 +9,6 @@ data class BlockModel(
|
|||
val id: String,
|
||||
val parentId: String = "",
|
||||
val content: String = "",
|
||||
val contentType : Int,
|
||||
val children: List<BlockModel>
|
||||
)
|
|
@ -1,6 +1,6 @@
|
|||
package com.agileburo.anytype.feature_editor.data
|
||||
|
||||
import com.agileburo.anytype.feature_editor.data.datasource.IPFSDataSource
|
||||
import com.agileburo.anytype.feature_editor.data.datasource.BlockDataSource
|
||||
import com.agileburo.anytype.feature_editor.domain.Block
|
||||
import io.reactivex.Single
|
||||
import javax.inject.Inject
|
||||
|
@ -12,19 +12,19 @@ interface EditorRepo {
|
|||
}
|
||||
|
||||
class EditorRepoImpl @Inject constructor(
|
||||
private val dataSource: IPFSDataSource,
|
||||
private val dataSource: BlockDataSource,
|
||||
private val blockConverter: BlockConverter
|
||||
) : EditorRepo {
|
||||
|
||||
override fun getBlocks(): Single<List<Block>> {
|
||||
return dataSource.getBlocks()
|
||||
.flatMap { t: List<BlockModel> -> Single.just(unwrap(t)) }
|
||||
return dataSource.getBlocks().map(this::unwrap)
|
||||
}
|
||||
|
||||
override fun saveState(list: List<Block>) {
|
||||
wrap(list)
|
||||
}
|
||||
|
||||
// TODO перевести в отдельный маппер, пусть репозиторий отвечает толька за CRUD-операции
|
||||
private fun unwrap(blocks: List<BlockModel>): List<Block> {
|
||||
val result = mutableListOf<Block>()
|
||||
if (blocks.isEmpty()) return result
|
||||
|
|
|
@ -11,14 +11,14 @@ import javax.inject.Inject
|
|||
* email : ki@agileburo.com
|
||||
* on 20.03.2019.
|
||||
*/
|
||||
interface IPFSDataSource {
|
||||
interface BlockDataSource {
|
||||
fun getBlocks(): Single<List<BlockModel>>
|
||||
}
|
||||
|
||||
class IPFSDataSourceImpl @Inject constructor(
|
||||
private val context: Context,
|
||||
private val gson: Gson
|
||||
) : IPFSDataSource {
|
||||
) : BlockDataSource {
|
||||
|
||||
override fun getBlocks(): Single<List<BlockModel>> {
|
||||
return Single.create<List<BlockModel>> { emitter ->
|
||||
|
@ -26,8 +26,11 @@ class IPFSDataSourceImpl @Inject constructor(
|
|||
val json = context.assets.open("test.json").bufferedReader().use {
|
||||
it.readText()
|
||||
}
|
||||
|
||||
val ipfsResponse = gson.fromJson<IpfsResponse>(json, IpfsResponse::class.java)
|
||||
|
||||
emitter.onSuccess(ipfsResponse.blocks)
|
||||
|
||||
} catch (e: Exception) {
|
||||
emitter.onError(e)
|
||||
}
|
|
@ -26,18 +26,19 @@ sealed class ContentType {
|
|||
object H3 : ContentType()
|
||||
object OL : ContentType()
|
||||
object UL : ContentType()
|
||||
object HL : ContentType()
|
||||
object Quote : ContentType()
|
||||
object Toggle : ContentType()
|
||||
object Check : ContentType()
|
||||
object H4 : ContentType()
|
||||
}
|
||||
|
||||
data class Block(
|
||||
val id: String = "",
|
||||
val parentId: String = "",
|
||||
//val type: BlockType = BlockType.Editable,
|
||||
//val contentType: ContentType = ContentType.H1,
|
||||
val content: String = ""
|
||||
val id: String,
|
||||
val parentId: String,
|
||||
val contentType: ContentType,
|
||||
// TODO parse marks and other stuff
|
||||
val content: String
|
||||
// TODO add blockType
|
||||
)
|
||||
|
||||
fun Int.toContentType(): ContentType =
|
||||
|
@ -49,13 +50,25 @@ fun Int.toContentType(): ContentType =
|
|||
5 -> ContentType.H3
|
||||
6 -> ContentType.OL
|
||||
7 -> ContentType.UL
|
||||
8 -> ContentType.HL
|
||||
8 -> ContentType.Quote
|
||||
9 -> ContentType.Toggle
|
||||
10 -> ContentType.Check
|
||||
11 -> ContentType.H4
|
||||
else -> ContentType.H1
|
||||
}
|
||||
|
||||
fun ContentType.toNumericalCode() : Int {
|
||||
return when(this) {
|
||||
ContentType.P -> 1
|
||||
ContentType.Code -> 2
|
||||
ContentType.H1 -> 3
|
||||
ContentType.H2 -> 4
|
||||
ContentType.Quote -> 8
|
||||
ContentType.Check -> 10
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
|
||||
fun Int.toBlockType(): BlockType =
|
||||
when (this) {
|
||||
1 -> BlockType.HrGrid
|
||||
|
|
|
@ -25,12 +25,10 @@ class EditorViewModel(private val interactor: EditorInteractor) : ViewModel() {
|
|||
interactor.getBlocks()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe({ blocks: List<Block> ->
|
||||
progress.accept(EditorState.Result(blocks))
|
||||
},
|
||||
{ t: Throwable ->
|
||||
Timber.d("Get blocks error : $t")
|
||||
})
|
||||
.subscribe(
|
||||
{ blocks -> progress.accept(EditorState.Result(blocks)) },
|
||||
{ error -> Timber.d("Get blocks error : $error") }
|
||||
)
|
||||
.disposedBy(disposable)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,28 +7,85 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.agileburo.anytype.core_utils.swap
|
||||
import com.agileburo.anytype.feature_editor.R
|
||||
import com.agileburo.anytype.feature_editor.domain.Block
|
||||
import com.agileburo.anytype.feature_editor.domain.ContentType
|
||||
import kotlinx.android.synthetic.main.item_block_checkbox.view.*
|
||||
import kotlinx.android.synthetic.main.item_block_code_snippet.view.*
|
||||
import kotlinx.android.synthetic.main.item_block_editable.view.*
|
||||
import kotlinx.android.synthetic.main.item_block_header_one.view.*
|
||||
import kotlinx.android.synthetic.main.item_block_header_three.view.*
|
||||
import kotlinx.android.synthetic.main.item_block_header_two.view.*
|
||||
import kotlinx.android.synthetic.main.item_block_quote.view.*
|
||||
import timber.log.Timber
|
||||
|
||||
class EditorAdapter(private val blocks: MutableList<Block>): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
fun setBlocks(blocks: List<Block>) {
|
||||
Timber.d("Set blocks ${blocks.size}")
|
||||
this.blocks.addAll(blocks)
|
||||
fun setBlocks(items: List<Block>) {
|
||||
Timber.d("Set blocks ${items.size}")
|
||||
blocks.addAll(items)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
val view = inflater.inflate(R.layout.item_block_editable, parent, false)
|
||||
return ViewHolder.TextHolder(view)
|
||||
|
||||
return when(viewType) {
|
||||
HOLDER_PARAGRAPH -> {
|
||||
val view = inflater.inflate(R.layout.item_block_editable, parent, false)
|
||||
ViewHolder.ParagraphHolder(view)
|
||||
}
|
||||
HOLDER_HEADER_ONE -> {
|
||||
val view = inflater.inflate(R.layout.item_block_header_one, parent, false)
|
||||
ViewHolder.HeaderOneHolder(view)
|
||||
}
|
||||
HOLDER_HEADER_TWO -> {
|
||||
val view = inflater.inflate(R.layout.item_block_header_two, parent, false)
|
||||
ViewHolder.HeaderTwoHolder(view)
|
||||
}
|
||||
HOLDER_HEADER_THREE -> {
|
||||
val view = inflater.inflate(R.layout.item_block_header_three, parent, false)
|
||||
ViewHolder.HeaderThreeHolder(view)
|
||||
}
|
||||
HOLDER_QUOTE -> {
|
||||
val view = inflater.inflate(R.layout.item_block_quote, parent, false)
|
||||
ViewHolder.QuoteHolder(view)
|
||||
}
|
||||
HOLDER_CHECKBOX -> {
|
||||
val view = inflater.inflate(R.layout.item_block_checkbox, parent, false)
|
||||
ViewHolder.CheckBoxHolder(view)
|
||||
}
|
||||
HOLDER_CODE_SNIPPET -> {
|
||||
val view = inflater.inflate(R.layout.item_block_code_snippet, parent, false)
|
||||
ViewHolder.CodeSnippetHolder(view)
|
||||
}
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return when(blocks[position].contentType) {
|
||||
is ContentType.P -> HOLDER_PARAGRAPH
|
||||
is ContentType.H1 -> HOLDER_HEADER_ONE
|
||||
is ContentType.H2 -> HOLDER_HEADER_TWO
|
||||
is ContentType.H3 -> HOLDER_HEADER_THREE
|
||||
is ContentType.Quote -> HOLDER_QUOTE
|
||||
is ContentType.Check -> HOLDER_CHECKBOX
|
||||
is ContentType.Code -> HOLDER_CODE_SNIPPET
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount() = blocks.size
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
when (holder) {
|
||||
is ViewHolder.TextHolder -> holder.bind(blocks[position])
|
||||
is ViewHolder.ParagraphHolder -> holder.bind(blocks[position])
|
||||
is ViewHolder.HeaderOneHolder -> holder.bind(blocks[position])
|
||||
is ViewHolder.HeaderTwoHolder -> holder.bind(blocks[position])
|
||||
is ViewHolder.HeaderThreeHolder -> holder.bind(blocks[position])
|
||||
is ViewHolder.QuoteHolder -> holder.bind(blocks[position])
|
||||
is ViewHolder.CheckBoxHolder -> holder.bind(blocks[position])
|
||||
is ViewHolder.CodeSnippetHolder -> holder.bind(blocks[position])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,7 +101,7 @@ class EditorAdapter(private val blocks: MutableList<Block>): RecyclerView.Adapte
|
|||
|
||||
sealed class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
class TextHolder(itemView: View) : ViewHolder(itemView) {
|
||||
class ParagraphHolder(itemView: View) : ViewHolder(itemView) {
|
||||
|
||||
fun bind(block : Block) {
|
||||
itemView.tvId.text = "id :${block.id}"
|
||||
|
@ -52,5 +109,58 @@ class EditorAdapter(private val blocks: MutableList<Block>): RecyclerView.Adapte
|
|||
}
|
||||
}
|
||||
|
||||
class HeaderOneHolder(itemView: View) : ViewHolder(itemView) {
|
||||
|
||||
fun bind(block : Block) {
|
||||
itemView.headerContentText.text = block.content
|
||||
}
|
||||
}
|
||||
|
||||
class HeaderTwoHolder(itemView: View) : ViewHolder(itemView) {
|
||||
|
||||
fun bind(block : Block) {
|
||||
itemView.headerTwoContentText.text = block.content
|
||||
}
|
||||
}
|
||||
|
||||
class HeaderThreeHolder(itemView: View) : ViewHolder(itemView) {
|
||||
|
||||
fun bind(block : Block) {
|
||||
itemView.headerThreeContentText.text = block.content
|
||||
}
|
||||
}
|
||||
|
||||
class QuoteHolder(itemView: View) : ViewHolder(itemView) {
|
||||
|
||||
fun bind(block : Block) {
|
||||
itemView.quoteContent.text = block.content
|
||||
}
|
||||
}
|
||||
|
||||
class CheckBoxHolder(itemView: View) : ViewHolder(itemView) {
|
||||
|
||||
fun bind(block : Block) {
|
||||
itemView.checkBoxContent.text = block.content
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CodeSnippetHolder(itemView: View) : ViewHolder(itemView) {
|
||||
|
||||
fun bind(block: Block) {
|
||||
itemView.codeSnippetContent.text = block.content
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val HOLDER_PARAGRAPH = 0
|
||||
const val HOLDER_HEADER_ONE = 1
|
||||
const val HOLDER_HEADER_TWO = 2
|
||||
const val HOLDER_HEADER_THREE = 3
|
||||
const val HOLDER_QUOTE = 4
|
||||
const val HOLDER_CHECKBOX = 5
|
||||
const val HOLDER_CODE_SNIPPET = 6
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="@color/dark_gray"/>
|
||||
<corners android:radius="4dp"/>
|
||||
|
||||
</shape>
|
21
feature_editor/src/main/res/layout/item_block_checkbox.xml
Normal file
21
feature_editor/src/main/res/layout/item_block_checkbox.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<CheckBox
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/checkBoxContent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginBottom="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,26 @@
|
|||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:textSize="12sp"
|
||||
android:typeface="monospace"
|
||||
android:textColor="#FFFF"
|
||||
android:padding="8dp"
|
||||
android:background="@drawable/rounded_rectangle_gray"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/codeSnippetContent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginStart="16dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginBottom="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
23
feature_editor/src/main/res/layout/item_block_header_one.xml
Normal file
23
feature_editor/src/main/res/layout/item_block_header_one.xml
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:textStyle="bold"
|
||||
android:textSize="24sp"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/headerContentText"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,23 @@
|
|||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:textStyle="bold"
|
||||
android:textSize="16sp"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/headerThreeContentText"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
23
feature_editor/src/main/res/layout/item_block_header_two.xml
Normal file
23
feature_editor/src/main/res/layout/item_block_header_two.xml
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:textStyle="bold"
|
||||
android:textSize="18sp"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/headerTwoContentText"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
32
feature_editor/src/main/res/layout/item_block_quote.xml
Normal file
32
feature_editor/src/main/res/layout/item_block_quote.xml
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<TextView
|
||||
android:textStyle="bold"
|
||||
android:textSize="14sp"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/quoteContent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginStart="32dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
<View android:layout_width="1dp"
|
||||
android:background="#808080"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent"
|
||||
/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
6
feature_editor/src/main/res/values/colors.xml
Normal file
6
feature_editor/src/main/res/values/colors.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#7a1ced</color>
|
||||
<color name="dark_gray">#222936</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
</resources>
|
Loading…
Add table
Add a link
Reference in a new issue