Sample app, adding and reading samples
This commit is contained in:
parent
66f77f35fe
commit
860d70d6d1
@ -1,4 +1,35 @@
|
||||
[
|
||||
{
|
||||
"javaClassName": "io.noties.markwon.app.samples.nested.ThirdSample",
|
||||
"id": "202006177155827",
|
||||
"title": "Third sample",
|
||||
"description": "\u003e yo! \n\n```\nfinal int i \u003d 0;\n```",
|
||||
"artifacts": [
|
||||
"EDITOR",
|
||||
"SIMPLE_EXT"
|
||||
],
|
||||
"tags": [
|
||||
"a",
|
||||
"c",
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"javaClassName": "io.noties.markwon.app.samples.nested.SecondSample",
|
||||
"id": "202006177155656",
|
||||
"title": "Second sample",
|
||||
"description": "# Hey hey hey",
|
||||
"artifacts": [
|
||||
"CORE",
|
||||
"RECYCLER"
|
||||
],
|
||||
"tags": [
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"javaClassName": "io.noties.markwon.app.samples.FirstSample",
|
||||
"id": "202006164150023",
|
||||
|
1
app-sample/src/main/assets/samples
Symbolic link
1
app-sample/src/main/assets/samples
Symbolic link
@ -0,0 +1 @@
|
||||
../../main/java/io/noties/markwon/app/samples/
|
@ -12,4 +12,11 @@ data class Sample(
|
||||
val description: String,
|
||||
val artifacts: List<MarkwonArtifact>,
|
||||
val tags: List<String>
|
||||
) : Parcelable
|
||||
) : Parcelable {
|
||||
|
||||
enum class Language {
|
||||
JAVA, KOTLIN
|
||||
}
|
||||
|
||||
data class Code(val language: Language, val sourceCode: String)
|
||||
}
|
@ -81,6 +81,21 @@ class SampleItem(
|
||||
val artifacts: FlowLayout = requireView(R.id.artifacts)
|
||||
val tags: FlowLayout = requireView(R.id.tags)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as SampleItem
|
||||
|
||||
if (sample != other.sample) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return sample.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
private fun FlowLayout.ensure(viewsCount: Int, layoutResId: Int): List<View> {
|
||||
|
@ -0,0 +1,3 @@
|
||||
[{*.java, *.kt}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
@ -1,15 +1,30 @@
|
||||
package io.noties.markwon.app.samples
|
||||
|
||||
import io.noties.markwon.app.ui.MarkwonSample
|
||||
import io.noties.markwon.Markwon
|
||||
import io.noties.markwon.app.ui.MarkwonTextViewSample
|
||||
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
||||
import io.noties.markwon.sample.annotations.MarkwonSampleInfo
|
||||
|
||||
@MarkwonSampleInfo(
|
||||
id = "202006164150023",
|
||||
title = "First Sample",
|
||||
description = "This **is** _the first_ sample",
|
||||
artifacts = [MarkwonArtifact.CORE],
|
||||
tags = ["test"]
|
||||
id = "202006164150023",
|
||||
title = "First Sample",
|
||||
description = "This **is** _the first_ sample",
|
||||
artifacts = [MarkwonArtifact.CORE],
|
||||
tags = ["test"]
|
||||
)
|
||||
class FirstSample : MarkwonSample() {
|
||||
class FirstSample : MarkwonTextViewSample() {
|
||||
|
||||
override fun render() {
|
||||
|
||||
val md = """
|
||||
# Hello there!
|
||||
> How are you?
|
||||
|
||||
**bold** and _italic_ and **bold _italic bold_ just bold**
|
||||
""".trimIndent()
|
||||
|
||||
val markwon: Markwon = Markwon.create(context)
|
||||
|
||||
markwon.setMarkdown(textView, md)
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package io.noties.markwon.app.samples.nested
|
||||
|
||||
import io.noties.markwon.Markwon
|
||||
import io.noties.markwon.app.ui.MarkwonTextViewSample
|
||||
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
||||
import io.noties.markwon.sample.annotations.MarkwonSampleInfo
|
||||
|
||||
@MarkwonSampleInfo(
|
||||
id = "202006177155656",
|
||||
title = "Second sample",
|
||||
description = "# Hey hey hey",
|
||||
artifacts = [MarkwonArtifact.CORE, MarkwonArtifact.RECYCLER],
|
||||
tags = ["b", "c", "a", "test"]
|
||||
)
|
||||
class SecondSample : MarkwonTextViewSample() {
|
||||
override fun render() {
|
||||
val md = """
|
||||
# Hello second
|
||||
|
||||
```java
|
||||
final int i = 0;
|
||||
```
|
||||
""".trimIndent()
|
||||
|
||||
val markwon = Markwon.create(context)
|
||||
markwon.setMarkdown(textView, md)
|
||||
}
|
||||
|
||||
val _mock: String
|
||||
get() = """
|
||||
a
|
||||
b
|
||||
d
|
||||
s
|
||||
as
|
||||
sd
|
||||
ds
|
||||
sd
|
||||
s
|
||||
sd
|
||||
sd
|
||||
ds
|
||||
sd
|
||||
sd
|
||||
sd
|
||||
sd
|
||||
sd
|
||||
sd
|
||||
ds
|
||||
sd
|
||||
sd
|
||||
|
||||
s
|
||||
sd
|
||||
sd
|
||||
sd
|
||||
sd
|
||||
sd
|
||||
|
||||
ds
|
||||
sd
|
||||
sd
|
||||
sd
|
||||
""".trimIndent()
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package io.noties.markwon.app.samples.nested;
|
||||
|
||||
import io.noties.markwon.Markwon;
|
||||
import io.noties.markwon.app.ui.MarkwonTextViewSample;
|
||||
import io.noties.markwon.sample.annotations.MarkwonArtifact;
|
||||
import io.noties.markwon.sample.annotations.MarkwonSampleInfo;
|
||||
|
||||
@MarkwonSampleInfo(
|
||||
id = "202006177155827",
|
||||
title = "Third sample",
|
||||
description = "> yo! \n\n```\nfinal int i = 0;\n```",
|
||||
artifacts = {MarkwonArtifact.SIMPLE_EXT, MarkwonArtifact.EDITOR},
|
||||
tags = {"a", "c", "test"}
|
||||
)
|
||||
public class ThirdSample extends MarkwonTextViewSample {
|
||||
@Override
|
||||
public void render() {
|
||||
final String md = "# Hello!";
|
||||
final Markwon markwon = Markwon.create(context);
|
||||
markwon.setMarkdown(textView, md);
|
||||
}
|
||||
}
|
@ -1,5 +1,16 @@
|
||||
package io.noties.markwon.app.ui
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
||||
abstract class MarkwonSample {
|
||||
|
||||
fun createView(inflater: LayoutInflater, container: ViewGroup?): View {
|
||||
return inflater.inflate(layoutResId, container, false)
|
||||
}
|
||||
|
||||
abstract fun onViewCreated(view: View)
|
||||
|
||||
protected abstract val layoutResId: Int
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package io.noties.markwon.app.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
|
||||
import io.noties.markwon.app.R
|
||||
|
||||
abstract class MarkwonTextViewSample : MarkwonSample() {
|
||||
|
||||
protected lateinit var context: Context
|
||||
protected lateinit var textView: TextView
|
||||
|
||||
override val layoutResId: Int = R.layout.sample_text_view
|
||||
|
||||
final override fun onViewCreated(view: View) {
|
||||
context = view.context
|
||||
textView = view.findViewById(R.id.text_view)
|
||||
render()
|
||||
}
|
||||
|
||||
abstract fun render()
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package io.noties.markwon.app.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import io.noties.markwon.app.R
|
||||
import io.noties.markwon.app.Sample
|
||||
import io.noties.markwon.app.utils.readCode
|
||||
|
||||
class SampleCodeFragment : Fragment() {
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_sample_code, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val textView: TextView = view.findViewById(R.id.text_view)
|
||||
val code = sample.readCode(requireContext())
|
||||
|
||||
textView.text = code.sourceCode
|
||||
}
|
||||
|
||||
private val sample: Sample by lazy(LazyThreadSafetyMode.NONE) {
|
||||
arguments!!.getParcelable<Sample>(ARG_SAMPLE)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ARG_SAMPLE = "arg.Sample"
|
||||
|
||||
fun init(sample: Sample): SampleCodeFragment {
|
||||
return SampleCodeFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putParcelable(ARG_SAMPLE, sample)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,127 @@
|
||||
package io.noties.markwon.app.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import io.noties.markwon.app.R
|
||||
import io.noties.markwon.app.Sample
|
||||
import io.noties.markwon.app.utils.active
|
||||
|
||||
class SampleFragment : Fragment() {
|
||||
|
||||
private lateinit var container: ViewGroup
|
||||
|
||||
private var isCodeSelected = false
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_sample, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
container = view.findViewById(R.id.container)
|
||||
isCodeSelected = savedInstanceState?.getBoolean(KEY_CODE_SELECTED) ?: false
|
||||
|
||||
initAppBar(view)
|
||||
initTabBar(view)
|
||||
}
|
||||
|
||||
private fun initAppBar(view: View) {
|
||||
val appBar: View = view.findViewById(R.id.app_bar)
|
||||
val icon: View = appBar.findViewById(R.id.app_bar_icon)
|
||||
val title: TextView = appBar.findViewById(R.id.app_bar_title)
|
||||
|
||||
icon.setOnClickListener {
|
||||
activity?.onBackPressed()
|
||||
}
|
||||
|
||||
title.text = sample.title
|
||||
}
|
||||
|
||||
private fun initTabBar(view: View) {
|
||||
val tabBar: View = view.findViewById(R.id.tab_bar)
|
||||
val preview: View = tabBar.findViewById(R.id.tab_bar_preview)
|
||||
val code: View = tabBar.findViewById(R.id.tab_bar_code)
|
||||
|
||||
preview.setOnClickListener {
|
||||
if (!it.active) {
|
||||
it.active = true
|
||||
code.active = false
|
||||
showPreview()
|
||||
}
|
||||
}
|
||||
|
||||
code.setOnClickListener {
|
||||
if (!it.active) {
|
||||
it.active = true
|
||||
preview.active = false
|
||||
showCode()
|
||||
}
|
||||
}
|
||||
|
||||
// maybe check state (in case of restoration)
|
||||
|
||||
// initial values
|
||||
preview.active = !isCodeSelected
|
||||
code.active = isCodeSelected
|
||||
|
||||
if (isCodeSelected) {
|
||||
showCode()
|
||||
} else {
|
||||
showPreview()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showPreview() {
|
||||
isCodeSelected = false
|
||||
showFragment(TAG_PREVIEW, TAG_CODE) { SamplePreviewFragment.init(sample) }
|
||||
}
|
||||
|
||||
private fun showCode() {
|
||||
isCodeSelected = true
|
||||
showFragment(TAG_CODE, TAG_PREVIEW) { SampleCodeFragment.init(sample) }
|
||||
}
|
||||
|
||||
private fun showFragment(showTag: String, hideTag: String, provider: () -> Fragment) {
|
||||
val manager = childFragmentManager
|
||||
manager.beginTransaction().apply {
|
||||
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
|
||||
|
||||
val existing = manager.findFragmentByTag(showTag)
|
||||
if (existing != null) {
|
||||
show(existing)
|
||||
} else {
|
||||
add(container.id, provider(), showTag)
|
||||
}
|
||||
|
||||
manager.findFragmentByTag(hideTag)?.also {
|
||||
hide(it)
|
||||
}
|
||||
|
||||
commitAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
|
||||
outState.putBoolean(KEY_CODE_SELECTED, isCodeSelected)
|
||||
}
|
||||
|
||||
private val sample: Sample by lazy(LazyThreadSafetyMode.NONE) {
|
||||
(arguments!!.getParcelable<Sample>(ARG_SAMPLE))
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ARG_SAMPLE = "arg.Sample"
|
||||
private const val TAG_PREVIEW = "tag.Preview"
|
||||
private const val TAG_CODE = "tag.Code"
|
||||
private const val KEY_CODE_SELECTED = "key.Selected"
|
||||
|
||||
fun init(sample: Sample): SampleFragment {
|
||||
val fragment = SampleFragment()
|
||||
|
@ -0,0 +1,38 @@
|
||||
package io.noties.markwon.app.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import io.noties.markwon.app.Sample
|
||||
|
||||
class SamplePreviewFragment : Fragment() {
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return markwonSample.createView(inflater, container)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
markwonSample.onViewCreated(view)
|
||||
}
|
||||
|
||||
private val markwonSample: MarkwonSample by lazy(LazyThreadSafetyMode.NONE) {
|
||||
val sample: Sample = arguments!!.getParcelable<Sample>(ARG_SAMPLE)!!
|
||||
Class.forName(sample.javaClassName).newInstance() as MarkwonSample
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ARG_SAMPLE = "arg.Sample"
|
||||
|
||||
fun init(sample: Sample): SamplePreviewFragment {
|
||||
return SamplePreviewFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putParcelable(ARG_SAMPLE, sample)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,58 @@
|
||||
package io.noties.markwon.app.utils
|
||||
|
||||
import android.content.Context
|
||||
import io.noties.markwon.app.Sample
|
||||
import io.noties.markwon.sample.annotations.MarkwonArtifact
|
||||
import java.io.InputStream
|
||||
import java.util.Scanner
|
||||
|
||||
val MarkwonArtifact.displayName: String
|
||||
get() = "@${artifactName()}"
|
||||
|
||||
val String.tagDisplayName: String
|
||||
get() = "#$this"
|
||||
get() = "#$this"
|
||||
|
||||
private const val SAMPLE_PREFIX = "io.noties.markwon.app."
|
||||
|
||||
fun Sample.readCode(context: Context): Sample.Code {
|
||||
val assets = context.assets
|
||||
|
||||
// keep sample and nested directories
|
||||
val path = javaClassName
|
||||
.removePrefix(SAMPLE_PREFIX)
|
||||
.replace('.', '/')
|
||||
|
||||
// now, we have 2 possibilities -> Kotlin or Java
|
||||
fun read(stream: InputStream): String {
|
||||
return Scanner(stream).useDelimiter("\\A").next()
|
||||
}
|
||||
|
||||
fun obtain(path: String): InputStream? {
|
||||
return try {
|
||||
assets.open(path)
|
||||
} catch (t: Throwable) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
var language: Sample.Language = Sample.Language.KOTLIN
|
||||
var stream = obtain("$path.kt")
|
||||
if (stream == null) {
|
||||
language = Sample.Language.JAVA
|
||||
stream = obtain("$path.java")
|
||||
}
|
||||
|
||||
if (stream == null) {
|
||||
throw IllegalStateException("Cannot obtain sample file at path: $path")
|
||||
}
|
||||
|
||||
val code = read(stream)
|
||||
|
||||
try {
|
||||
stream.close()
|
||||
} catch (t: Throwable) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return Sample.Code(language, code)
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package io.noties.markwon.app.utils
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
||||
val ViewGroup.children: List<View>
|
||||
get() = (0 until childCount).map { getChildAt(it) }
|
@ -3,6 +3,7 @@ package io.noties.markwon.app.utils
|
||||
import android.view.View
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewTreeObserver
|
||||
|
||||
var View.hidden: Boolean
|
||||
@ -23,4 +24,12 @@ fun View.onPreDraw(action: () -> Unit) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var View.active: Boolean
|
||||
get() = isActivated
|
||||
set(newValue) {
|
||||
isActivated = newValue
|
||||
|
||||
(this as? ViewGroup)?.children?.forEach { it.active = newValue }
|
||||
}
|
5
app-sample/src/main/res/color/tab_bar_item.xml
Normal file
5
app-sample/src/main/res/color/tab_bar_item.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/accent" android:state_activated="true" />
|
||||
<item android:color="@color/gray" />
|
||||
</selector>
|
@ -1,5 +1,10 @@
|
||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" />
|
||||
</vector>
|
||||
|
@ -2,8 +2,8 @@
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" />
|
||||
|
10
app-sample/src/main/res/drawable/ic_code_white_24dp.xml
Normal file
10
app-sample/src/main/res/drawable/ic_code_white_24dp.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M9.4,16.6L4.8,12l4.6,-4.6L8,6l-6,6 6,6 1.4,-1.4zM14.6,16.6l4.6,-4.6 -4.6,-4.6L16,6l6,6 -6,6 -1.4,-1.4z" />
|
||||
</vector>
|
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,4.5C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z" />
|
||||
</vector>
|
@ -2,8 +2,8 @@
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />
|
||||
|
80
app-sample/src/main/res/layout/fragment_sample.xml
Normal file
80
app-sample/src/main/res/layout/fragment_sample.xml
Normal file
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
style="@style/AppBarContainer"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
style="@style/AppBarIcon"
|
||||
android:src="@drawable/ic_arrow_back_white_24dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/app_bar_height">
|
||||
|
||||
<TextView
|
||||
style="@style/AppBarTitle"
|
||||
tools:text="Sample title with a lot of content, can it fit here?" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0px"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/divider_height"
|
||||
android:background="@color/divider" />
|
||||
|
||||
<LinearLayout
|
||||
style="@style/TabBarContainer"
|
||||
tools:ignore="DisableBaselineAlignment">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@id/tab_bar_preview"
|
||||
style="@style/TabBarItem"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
style="@style/TabBarItemIcon"
|
||||
android:src="@drawable/ic_remove_red_eye_white_24dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
style="@style/TabBarItemText"
|
||||
android:text="@string/tab_bar_preview" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@id/tab_bar_code"
|
||||
style="@style/TabBarItem"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
style="@style/TabBarItemIcon"
|
||||
android:src="@drawable/ic_code_white_24dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
style="@style/TabBarItemText"
|
||||
android:text="@string/tab_bar_code" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
28
app-sample/src/main/res/layout/fragment_sample_code.xml
Normal file
28
app-sample/src/main/res/layout/fragment_sample_code.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<HorizontalScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:fillViewport="true"
|
||||
android:padding="@dimen/content_padding_double"
|
||||
android:scrollbarStyle="outsideInset">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="monospace"
|
||||
android:lineSpacingExtra="2dip"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textSize="14sp"
|
||||
tools:text="package io.noties.markwon" />
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
@ -7,18 +7,13 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/app_bar"
|
||||
style="@style/AppBarContainer"
|
||||
android:elevation="4dip"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/app_bar_icon"
|
||||
style="@style/AppBarIcon"
|
||||
android:contentDescription="@null"
|
||||
android:padding="8dip"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
android:src="@mipmap/ic_launcher"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
@ -26,18 +21,8 @@
|
||||
android:layout_marginEnd="@dimen/app_bar_height">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_bar_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:paddingLeft="@dimen/content_padding_double"
|
||||
android:paddingTop="@dimen/content_padding_half"
|
||||
android:paddingRight="@dimen/content_padding_double"
|
||||
android:paddingBottom="@dimen/content_padding_half"
|
||||
android:text="@string/app_name"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textColor="@color/white"
|
||||
android:textStyle="bold" />
|
||||
style="@style/AppBarTitle"
|
||||
android:text="@string/app_name" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
13
app-sample/src/main/res/layout/fragment_sample_preview.xml
Normal file
13
app-sample/src/main/res/layout/fragment_sample_preview.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#efe">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="PREVUEW" />
|
||||
|
||||
</FrameLayout>
|
@ -13,7 +13,7 @@
|
||||
android:id="@+id/text_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/content_padding"
|
||||
android:padding="@dimen/content_padding_double"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
tools:text="Hello there" />
|
||||
|
@ -12,4 +12,7 @@
|
||||
<color name="search_bar_background">#eee</color>
|
||||
<color name="search_bar_background_full">#BFFFFFFF</color>
|
||||
|
||||
<color name="divider">#eee</color>
|
||||
<color name="tab_bar_background">#fafafa</color>
|
||||
|
||||
</resources>
|
@ -8,4 +8,7 @@
|
||||
|
||||
<dimen name="search_bar_icon_side">36dip</dimen>
|
||||
<dimen name="adapt_sample_hash_width">36dip</dimen>
|
||||
|
||||
<dimen name="divider_height">1dip</dimen>
|
||||
<dimen name="tab_bar_height">56dip</dimen>
|
||||
</resources>
|
@ -1,4 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<item name="text" type="id" />
|
||||
|
||||
<item name="app_bar" type="id" />
|
||||
<item name="app_bar_icon" type="id" />
|
||||
<item name="app_bar_title" type="id" />
|
||||
|
||||
<item name="tab_bar" type="id" />
|
||||
<item name="tab_bar_preview" type="id" />
|
||||
<item name="tab_bar_code" type="id" />
|
||||
</resources>
|
@ -1,4 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Markwon</string>
|
||||
|
||||
<string name="tab_bar_preview">Preview</string>
|
||||
<string name="tab_bar_code">Code</string>
|
||||
</resources>
|
@ -6,22 +6,46 @@
|
||||
<item name="android:colorPrimary">@color/gray_light</item>
|
||||
<item name="android:colorPrimaryDark">@color/gray</item>
|
||||
<item name="android:windowBackground">@color/window_background</item>
|
||||
<item name="android:windowSplashscreenContent" tools:ignore="NewApi">@drawable/bg_splash</item>
|
||||
<item name="android:windowSplashscreenContent" tools:ignore="NewApi">@drawable/bg_splash
|
||||
</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme" parent="AppThemeBase" />
|
||||
|
||||
<style name="AppBarContainer">
|
||||
<item name="android:id">@id/app_bar</item>
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">@dimen/app_bar_height</item>
|
||||
<item name="android:background">@color/gray_light</item>
|
||||
<item name="android:elevation">4dip</item>
|
||||
</style>
|
||||
|
||||
<style name="AppBarIcon">
|
||||
<item name="android:id">@id/app_bar_icon</item>
|
||||
<item name="android:layout_width">@dimen/app_bar_height</item>
|
||||
<item name="android:layout_height">@dimen/app_bar_height</item>
|
||||
<item name="android:scaleType">centerInside</item>
|
||||
<item name="android:background">?android:attr/selectableItemBackgroundBorderless</item>
|
||||
<item name="android:contentDescription">@null</item>
|
||||
<item name="android:padding">8dip</item>
|
||||
</style>
|
||||
|
||||
<style name="AppBarTitle">
|
||||
<item name="android:id">@id/app_bar_title</item>
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_gravity">center</item>
|
||||
<item name="android:paddingLeft">@dimen/content_padding_double</item>
|
||||
<item name="android:paddingRight">@dimen/content_padding_double</item>
|
||||
<item name="android:paddingTop">@dimen/content_padding_half</item>
|
||||
<item name="android:paddingBottom">@dimen/content_padding_half</item>
|
||||
<item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
|
||||
<item name="android:textColor">@color/white</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:lines">1</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:maxLines">1</item>
|
||||
<item name="android:ellipsize">end</item>
|
||||
</style>
|
||||
|
||||
<style name="ArtifactTagText">
|
||||
@ -39,4 +63,35 @@
|
||||
<item name="android:textColor">@color/white</item>
|
||||
</style>
|
||||
|
||||
<style name="TabBarContainer">
|
||||
<item name="android:id">@id/tab_bar</item>
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">@dimen/tab_bar_height</item>
|
||||
<item name="android:background">@color/tab_bar_background</item>
|
||||
<item name="android:baselineAligned">false</item>
|
||||
<item name="android:orientation">horizontal</item>
|
||||
</style>
|
||||
|
||||
<style name="TabBarItem">
|
||||
<item name="android:layout_width">0px</item>
|
||||
<item name="android:layout_height">match_parent</item>
|
||||
<item name="android:layout_weight">1</item>
|
||||
<item name="android:background">?android:attr/selectableItemBackgroundBorderless</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:orientation">vertical</item>
|
||||
</style>
|
||||
|
||||
<style name="TabBarItemIcon">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:tint">@color/tab_bar_item</item>
|
||||
</style>
|
||||
|
||||
<style name="TabBarItemText">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
|
||||
<item name="android:textColor">@color/tab_bar_item</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
Binary file not shown.
@ -20,11 +20,14 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
@ -33,6 +36,7 @@ import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
import io.noties.markwon.sample.annotations.MarkwonArtifact;
|
||||
import io.noties.markwon.sample.annotations.MarkwonSampleInfo;
|
||||
|
||||
public class MarkwonSampleProcessor extends AbstractProcessor {
|
||||
@ -159,6 +163,8 @@ public class MarkwonSampleProcessor extends AbstractProcessor {
|
||||
// new items come first (DESC order)
|
||||
Collections.sort(samples, (lhs, rhs) -> rhs.id.compareTo(lhs.id));
|
||||
|
||||
// sort each sample artifacts (alphabet) and tags (alphabet)
|
||||
|
||||
final String json = new GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
@ -176,13 +182,17 @@ public class MarkwonSampleProcessor extends AbstractProcessor {
|
||||
|
||||
final String id = info.id();
|
||||
|
||||
// NB! sorted artifacts (by name) and tags
|
||||
final Set<MarkwonArtifact> artifacts = Stream.of(info.artifacts())
|
||||
.collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MarkwonArtifact::name))));
|
||||
|
||||
final MarkwonSample sample = new MarkwonSample(
|
||||
element.getQualifiedName().toString(),
|
||||
id,
|
||||
info.title(),
|
||||
info.description(),
|
||||
new HashSet<>(Arrays.asList(info.artifacts())),
|
||||
new HashSet<>(Arrays.asList(info.tags()))
|
||||
artifacts,
|
||||
new TreeSet<>(Arrays.asList(info.tags()))
|
||||
);
|
||||
|
||||
try {
|
||||
|
Loading…
x
Reference in New Issue
Block a user