aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-08-02 16:21:49 -0700
committerGitHub <noreply@github.com>2017-08-02 16:21:49 -0700
commit53382b44bb7ab7ccb559e96fd1f93c47020878ee (patch)
tree79c1862992f458ac52c1910b3a2e0c01cb7d5a5a
parent7d894be6de118357ec908d2d171b6152ce67307d (diff)
downloadkau-53382b44bb7ab7ccb559e96fd1f93c47020878ee.tar.gz
kau-53382b44bb7ab7ccb559e96fd1f93c47020878ee.tar.bz2
kau-53382b44bb7ab7ccb559e96fd1f93c47020878ee.zip
Improve video prefetching (#17)
* Create base activity and add thumbnails to media picker * Add checker to see if requested permission is inside the manifest * Add faq parser with tests * Add kpref testers and expose sp * Test jitpack sample exclusion * Test caching * Improve glide caching
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt3
-rw-r--r--android-lib.gradle7
-rw-r--r--core-ui/src/main/kotlin/ca/allanwang/kau/ui/activities/ElasticRecyclerActivity.kt3
-rw-r--r--core/README.md15
-rw-r--r--core/src/androidTest/kotlin/ca/allanwang/kau/kpref/KPrefTest.kt85
-rw-r--r--core/src/androidTest/kotlin/ca/allanwang/kau/utils/KotterknifeTest.kt4
-rw-r--r--core/src/androidTest/kotlin/ca/allanwang/kau/xml/ChangelogTest.kt4
-rw-r--r--core/src/androidTest/kotlin/ca/allanwang/kau/xml/FaqTest.kt38
-rw-r--r--core/src/androidTest/res/xml/test_changelog.xml12
-rw-r--r--core/src/androidTest/res/xml/test_faq.xml9
-rw-r--r--core/src/androidTest/res/xml/text_changelog.xml11
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/internal/KauBaseActivity.kt21
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt2
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt3
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt22
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/ui/views/MeasureSpecDelegate.kt12
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/xml/FAQ.kt28
-rw-r--r--docs/Changelog.md6
-rw-r--r--gradle.properties2
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefActivity.kt3
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt1
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt1
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt7
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt46
-rw-r--r--mediapicker/src/main/res/layout/kau_blurred_imageview.xml1
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt13
-rw-r--r--sample/src/main/res/xml/kau_changelog.xml9
-rw-r--r--settings.gradle6
28 files changed, 322 insertions, 52 deletions
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt b/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt
index 19fb4c4..61a3bb2 100644
--- a/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt
@@ -16,6 +16,7 @@ import ca.allanwang.kau.adapters.ThemableIItemColorsDelegate
import ca.allanwang.kau.animators.FadeScaleAnimatorAdd
import ca.allanwang.kau.animators.KauAnimator
import ca.allanwang.kau.iitems.HeaderIItem
+import ca.allanwang.kau.internal.KauBaseActivity
import ca.allanwang.kau.ui.widgets.ElasticDragDismissFrameLayout
import ca.allanwang.kau.ui.widgets.InkPageIndicator
import ca.allanwang.kau.utils.*
@@ -37,7 +38,7 @@ import java.security.InvalidParameterException
* Note that for the auto detection to work, the R fields must be excluded from Proguard
* Manual lib listings and other extra modifications can be done so by overriding the open functions
*/
-abstract class AboutActivityBase(val rClass: Class<*>?, val configBuilder: Configs.() -> Unit = {}) : AppCompatActivity(), ViewPager.OnPageChangeListener {
+abstract class AboutActivityBase(val rClass: Class<*>?, val configBuilder: Configs.() -> Unit = {}) : KauBaseActivity(), ViewPager.OnPageChangeListener {
val draggableFrame: ElasticDragDismissFrameLayout by bindView(R.id.about_draggable_frame)
val pager: ViewPager by bindView(R.id.about_pager)
diff --git a/android-lib.gradle b/android-lib.gradle
index f45aa02..46de84c 100644
--- a/android-lib.gradle
+++ b/android-lib.gradle
@@ -72,10 +72,7 @@ android {
dependencies {
androidTestCompile 'com.android.support.test:runner:0.5'
- androidTestCompile 'com.android.support.test:rules:0.5'
- androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
- exclude group: 'com.android.support', module: 'support-annotations'
- })
- testCompile 'junit:junit:4.12'
+ androidTestCompile "org.jetbrains.kotlin:kotlin-test-junit:${KOTLIN}"
testCompile "org.jetbrains.kotlin:kotlin-test-junit:${KOTLIN}"
+ testCompile 'junit:junit:4.12'
} \ No newline at end of file
diff --git a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/activities/ElasticRecyclerActivity.kt b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/activities/ElasticRecyclerActivity.kt
index 20a81e4..4c5563b 100644
--- a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/activities/ElasticRecyclerActivity.kt
+++ b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/activities/ElasticRecyclerActivity.kt
@@ -10,6 +10,7 @@ import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.Toolbar
import android.transition.TransitionInflater
+import ca.allanwang.kau.internal.KauBaseActivity
import ca.allanwang.kau.ui.R
import ca.allanwang.kau.ui.widgets.ElasticDragDismissFrameLayout
import ca.allanwang.kau.utils.bindView
@@ -26,7 +27,7 @@ import ca.allanwang.kau.utils.bindView
* The exit animation is set to slide out, but the entrance must be defined yourself
*/
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
-abstract class ElasticRecyclerActivity : AppCompatActivity() {
+abstract class ElasticRecyclerActivity : KauBaseActivity() {
val appBar: AppBarLayout by bindView(R.id.kau_appbar)
val toolbar: Toolbar by bindView(R.id.kau_toolbar)
diff --git a/core/README.md b/core/README.md
index c26836e..b952797 100644
--- a/core/README.md
+++ b/core/README.md
@@ -6,6 +6,7 @@
* [KPrefs](#kprefs)
* [Changelog XML](#changelog)
+* [FAQ XML](#faq-xml)
* [Kotterknife](#kotterknife)
* [Ripple Canvas](#ripple-canvas)
* [MeasureSpecDelegate](#measure-spec-delegate)
@@ -106,6 +107,20 @@ Here is a template xml changelog file:
</resources>
```
+<a name="faq-xml"></a>
+## FAQ XML
+
+There is another parser for a FAQ list with the following format:
+
+```xml
+<question>This is a question</question>
+<answer>This is an answer</answer>
+```
+
+Calling `kauParseFaq` will give you a `List<Pair<Spanned, Spanned>` that you can work with.
+By default, the questions are numbered, and the content is formatted with HTML.
+You may still need to add your own methods to allow interaction with certain elements such as links.
+
<a name="kotterknife"></a>
## Kotterknife
diff --git a/core/src/androidTest/kotlin/ca/allanwang/kau/kpref/KPrefTest.kt b/core/src/androidTest/kotlin/ca/allanwang/kau/kpref/KPrefTest.kt
new file mode 100644
index 0000000..e806a3f
--- /dev/null
+++ b/core/src/androidTest/kotlin/ca/allanwang/kau/kpref/KPrefTest.kt
@@ -0,0 +1,85 @@
+package ca.allanwang.kau.kpref
+
+import android.annotation.SuppressLint
+import android.support.test.InstrumentationRegistry
+import android.support.test.filters.MediumTest
+import android.support.test.runner.AndroidJUnit4
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+/**
+ * Created by Allan Wang on 2017-08-01.
+ */
+@RunWith(AndroidJUnit4::class)
+@MediumTest
+class ChangelogTest {
+
+ lateinit var pref: TestPref
+
+ class TestPref : KPref() {
+ init {
+ initialize(InstrumentationRegistry.getTargetContext(), "kpref_test_${System.currentTimeMillis()}")
+ }
+
+ var one: Int by kpref("one", 1)
+
+ var `true`: Boolean by kpref("true", true)
+
+ var hello: String by kpref("hello", "hello")
+
+ var set: StringSet by kpref("set", setOf("po", "ta", "to"))
+
+ val oneShot: Boolean by kprefSingle("asdf")
+ }
+
+ @Before
+ fun init() {
+ pref = TestPref()
+ }
+
+ @Test
+ fun getDefaults() {
+ assertEquals(1, pref.one)
+ assertEquals(true, pref.`true`)
+ assertEquals("hello", pref.hello)
+ assertEquals(3, pref.set.size)
+ assertTrue(pref.set.contains("po"))
+ assertTrue(pref.set.contains("ta"))
+ assertTrue(pref.set.contains("to"))
+ }
+
+ @Test
+ fun setter() {
+ assertEquals(1, pref.one)
+ pref.one = 2
+ assertEquals(2, pref.one)
+ pref.hello = "goodbye"
+ assertEquals("goodbye", pref.hello)
+ assertEquals(pref.hello, pref.sp.getString("hello", "hello"))
+ }
+
+ @SuppressLint("CommitPrefEdits")
+ @Test
+ fun reset() {
+ pref.one = 2
+ assertEquals(2, pref.one)
+ pref.reset() //only invalidates our lazy delegate; doesn't change the actual pref
+ assertEquals(2, pref.one)
+ pref.sp.edit().putInt("one", -1).commit()
+ assertEquals(2, pref.one) //our lazy delegate still retains the old value
+ pref.reset()
+ assertEquals(-1, pref.one) //back in sync with sp
+ }
+
+
+ @Test
+ fun single() {
+ assertTrue(pref.oneShot)
+ assertFalse(pref.oneShot)
+ }
+
+} \ No newline at end of file
diff --git a/core/src/androidTest/kotlin/ca/allanwang/kau/utils/KotterknifeTest.kt b/core/src/androidTest/kotlin/ca/allanwang/kau/utils/KotterknifeTest.kt
index 3282911..1dac92f 100644
--- a/core/src/androidTest/kotlin/ca/allanwang/kau/utils/KotterknifeTest.kt
+++ b/core/src/androidTest/kotlin/ca/allanwang/kau/utils/KotterknifeTest.kt
@@ -7,10 +7,12 @@ import android.support.test.runner.AndroidJUnit4
import android.view.View
import android.widget.FrameLayout
import android.widget.TextView
-import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+import kotlin.test.assertNull
/**
* Created by Allan Wang on 2017-07-30.
diff --git a/core/src/androidTest/kotlin/ca/allanwang/kau/xml/ChangelogTest.kt b/core/src/androidTest/kotlin/ca/allanwang/kau/xml/ChangelogTest.kt
index dcff70e..a3c9ff1 100644
--- a/core/src/androidTest/kotlin/ca/allanwang/kau/xml/ChangelogTest.kt
+++ b/core/src/androidTest/kotlin/ca/allanwang/kau/xml/ChangelogTest.kt
@@ -14,9 +14,9 @@ import org.junit.runner.RunWith
@MediumTest
class ChangelogTest {
- @Test
+// @Test //todo internal function sharing is only available on gradle 3.0.0+
fun simpleTest() {
- val data = parse(InstrumentationRegistry.getTargetContext(), R.xml.text_changelog)
+// val data = parse(InstrumentationRegistry.getTargetContext(), R.xml.test_changelog)
}
} \ No newline at end of file
diff --git a/core/src/androidTest/kotlin/ca/allanwang/kau/xml/FaqTest.kt b/core/src/androidTest/kotlin/ca/allanwang/kau/xml/FaqTest.kt
new file mode 100644
index 0000000..94d1330
--- /dev/null
+++ b/core/src/androidTest/kotlin/ca/allanwang/kau/xml/FaqTest.kt
@@ -0,0 +1,38 @@
+package ca.allanwang.kau.xml
+
+import android.support.test.InstrumentationRegistry
+import android.support.test.filters.MediumTest
+import android.support.test.runner.AndroidJUnit4
+import ca.allanwang.kau.test.R
+import org.junit.Test
+import org.junit.runner.RunWith
+import kotlin.test.assertEquals
+
+/**
+ * Created by Allan Wang on 2017-08-01.
+ */
+@RunWith(AndroidJUnit4::class)
+@MediumTest
+class FaqTest {
+
+ @Test
+ fun simpleTest() {
+ val data = InstrumentationRegistry.getTargetContext().kauParseFaq(R.xml.test_faq)
+ assertEquals(2, data.size, "FAQ size is incorrect")
+ assertEquals("1. This is a question", data.first().first.toString(), "First question does not match")
+ assertEquals("This is an answer", data.first().second.toString(), "First answer does not match")
+ assertEquals("2. This is another question", data.last().first.toString(), "Second question does not match")
+ assertEquals("This is another answer", data.last().second.toString(), "Second answer does not match")
+ }
+
+ @Test
+ fun withoutNumbering() {
+ val data = InstrumentationRegistry.getTargetContext().kauParseFaq(R.xml.test_faq, false)
+ assertEquals(2, data.size, "FAQ size is incorrect")
+ assertEquals("This is a question", data.first().first.toString(), "First question does not match")
+ assertEquals("This is an answer", data.first().second.toString(), "First answer does not match")
+ assertEquals("This is another question", data.last().first.toString(), "Second question does not match")
+ assertEquals("This is another answer", data.last().second.toString(), "Second answer does not match")
+ }
+
+} \ No newline at end of file
diff --git a/core/src/androidTest/res/xml/test_changelog.xml b/core/src/androidTest/res/xml/test_changelog.xml
new file mode 100644
index 0000000..2e90561
--- /dev/null
+++ b/core/src/androidTest/res/xml/test_changelog.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <version title="v1.1"/>
+ <item text="This is version 1.1" />
+ <item text="This is the last line to be displayed" />
+ <item text="" />
+
+ <version title="v1.0"/>
+ <item text="potato 1.0" />
+
+</resources> \ No newline at end of file
diff --git a/core/src/androidTest/res/xml/test_faq.xml b/core/src/androidTest/res/xml/test_faq.xml
new file mode 100644
index 0000000..4905df3
--- /dev/null
+++ b/core/src/androidTest/res/xml/test_faq.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <question>This is a question</question>
+ <answer>This is an answer</answer>
+ <question>This is another question</question>
+ <answer>This is another answer</answer>
+
+</resources> \ No newline at end of file
diff --git a/core/src/androidTest/res/xml/text_changelog.xml b/core/src/androidTest/res/xml/text_changelog.xml
deleted file mode 100644
index 6294144..0000000
--- a/core/src/androidTest/res/xml/text_changelog.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
- <version title="title1"/>
- <item text="test case" />
- <item text="" />
-
- <version title="title2"/>
- <item text="potato" />
-
-</resources> \ No newline at end of file
diff --git a/core/src/main/kotlin/ca/allanwang/kau/internal/KauBaseActivity.kt b/core/src/main/kotlin/ca/allanwang/kau/internal/KauBaseActivity.kt
new file mode 100644
index 0000000..87d94ce
--- /dev/null
+++ b/core/src/main/kotlin/ca/allanwang/kau/internal/KauBaseActivity.kt
@@ -0,0 +1,21 @@
+package ca.allanwang.kau.internal
+
+import android.support.v7.app.AppCompatActivity
+import ca.allanwang.kau.permissions.kauOnRequestPermissionsResult
+
+/**
+ * Created by Allan Wang on 2017-08-01.
+ *
+ * Base activity for any activity that would have extended [AppCompatActivity]
+ *
+ * Ensures that some singleton methods are called.
+ * This is simply a convenience class;
+ * you can always copy and paste this to your own class.
+ */
+abstract class KauBaseActivity : AppCompatActivity() {
+
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ kauOnRequestPermissionsResult(permissions, grantResults)
+ }
+} \ No newline at end of file
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt b/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt
index 701cb07..2ac5d2f 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt
@@ -50,7 +50,7 @@ open class LazyResettable<T : Any>(private val initializer: () -> T, lock: Any?
}
}
-interface ILazyResettable<T> : Lazy<T> {
+interface ILazyResettable<out T> : Lazy<T> {
fun invalidate()
}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt
index c1ce282..be16c7c 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt
@@ -39,7 +39,8 @@ open class KPref {
}
}
- internal val sp: SharedPreferences by lazy {
+ //todo hide this
+ val sp: SharedPreferences by lazy {
if (!initialized) throw KPrefException("KPref object has not yet been initialized; please initialize it with a context and preference name")
c.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE)
}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt b/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt
index d6e17db..0c42574 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt
@@ -2,13 +2,17 @@ package ca.allanwang.kau.permissions
import android.app.Activity
import android.content.Context
+import android.content.pm.PackageManager
import android.support.v4.app.ActivityCompat
+import ca.allanwang.kau.kotlin.lazyContext
import ca.allanwang.kau.logging.KL
import ca.allanwang.kau.utils.KauException
import ca.allanwang.kau.utils.buildIsMarshmallowAndUp
import ca.allanwang.kau.utils.hasPermission
+import ca.allanwang.kau.utils.toast
import java.lang.ref.WeakReference
+
/**
* Created by Allan Wang on 2017-07-03.
*/
@@ -17,6 +21,17 @@ internal object PermissionManager {
var requestInProgress = false
val pendingResults: MutableList<WeakReference<PermissionResult>> by lazy { mutableListOf<WeakReference<PermissionResult>>() }
+ /**
+ * Retrieve permissions requested in our manifest
+ */
+ val manifestPermission = lazyContext<Array<String>> {
+ try {
+ it.packageManager.getPackageInfo(it.packageName, PackageManager.GET_PERMISSIONS)?.requestedPermissions ?: emptyArray()
+ } catch (e: Exception) {
+ emptyArray()
+ }
+ }
+
operator fun invoke(context: Context, permissions: Array<out String>, callback: (granted: Boolean, deniedPerm: String?) -> Unit) {
KL.d("Permission manager for: ${permissions.contentToString()}")
if (!buildIsMarshmallowAndUp) return callback(true, null)
@@ -30,6 +45,13 @@ internal object PermissionManager {
}
@Synchronized internal fun requestPermissions(context: Context, permissions: Array<out String>) {
+ permissions.forEach {
+ if (!manifestPermission(context).contains(it)) {
+ KL.e("Requested permission $it is not stated in the manifest")
+ context.toast("$it is not in the manifest")
+ //we'll let the request pass through so it can be denied and so the callback can be triggered
+ }
+ }
val activity = (context as? Activity) ?: throw KauException("Context is not an instance of an activity; cannot request permissions")
KL.d("Requesting permissions ${permissions.contentToString()}")
ActivityCompat.requestPermissions(activity, permissions, 1)
diff --git a/core/src/main/kotlin/ca/allanwang/kau/ui/views/MeasureSpecDelegate.kt b/core/src/main/kotlin/ca/allanwang/kau/ui/views/MeasureSpecDelegate.kt
index edc1536..716fd71 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/ui/views/MeasureSpecDelegate.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/ui/views/MeasureSpecDelegate.kt
@@ -11,6 +11,8 @@ import ca.allanwang.kau.utils.parentViewGroup
* Created by Allan Wang on 2017-07-14.
*
* Handles relative sizes for any view
+ * You may delegate all methods to [MeasureSpecDelegate]
+ * and call the two methods: [initAttrs] and [onMeasure]
*/
interface MeasureSpecContract {
@@ -53,6 +55,16 @@ interface MeasureSpecContract {
* Calculates the final measure specs
* Call this from [View.onMeasure] and send the Pair result as the specs
* The pair is of the format (width, height)
+ *
+ * Example:
+ * <pre>
+ * {@code
+ * override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+ * val result = onMeasure(this, widthMeasureSpec, heightMeasureSpec)
+ * super.onMeasure(result.first, result.second)
+ * }
+ * }
+ * </pre>
*/
fun onMeasure(view: View, widthMeasureSpec: Int, heightMeasureSpec: Int): Pair<Int, Int>
}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/xml/FAQ.kt b/core/src/main/kotlin/ca/allanwang/kau/xml/FAQ.kt
index dedfbbf..b39540c 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/xml/FAQ.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/xml/FAQ.kt
@@ -22,16 +22,28 @@ fun Context.kauParseFaq(@XmlRes xmlRes: Int, withNumbering: Boolean = true): Lis
parser: XmlResourceParser ->
var eventType = parser.eventType
var question: Spanned? = null
+ var flag = -1 //-1, 0, 1 -> invalid, question, answer
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
- if (parser.name == "question") {
- var q = parser.text.replace("\n", "<br/>")
- if (withNumbering) q = "${items.size + 1}. $q"
- question = Html.fromHtml(q)
- } else if (parser.name == "answer") {
- items.add(Pair(question ?: throw IllegalArgumentException("KAU FAQ answer found without a question"),
- Html.fromHtml(parser.text.replace("\n", "<br/>"))))
- question = null
+ flag = when (parser.name) {
+ "question" -> 0
+ "answer" -> 1
+ else -> -1
+ }
+ } else if (eventType == XmlPullParser.TEXT) {
+ when (flag) {
+ 0 -> {
+ var q = parser.text.replace("\n", "<br/>")
+ if (withNumbering) q = "${items.size + 1}. $q"
+ question = Html.fromHtml(q)
+ flag = -1
+ }
+ 1 -> {
+ items.add(Pair(question ?: throw IllegalArgumentException("KAU FAQ answer found without a question"),
+ Html.fromHtml(parser.text.replace("\n", "<br/>"))))
+ question = null
+ flag = -1
+ }
}
}
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 9a1ec82..64d4644 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -1,5 +1,11 @@
# Changelog
+## v3.2.2
+* :core: Add simple KauBaseActivity so that activities extending AppCompatActivity can have some default kau helpers implemented
+* :core: The permission manager will now notify you if you try to request a permission that isn\'t added to your manifest
+* :core: Create faq parser
+* Begin writing android tests
+
## v3.2.1
* :core: Remove requestLayout call from setMargin and setPadding
* :core: Fix kau direction bits
diff --git a/gradle.properties b/gradle.properties
index 084621b..5fa8125 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -30,7 +30,7 @@ BLURRY=2.1.1
CONSTRAINT_LAYOUT=1.1.0-beta1
FAST_ADAPTER=2.6.2
FAST_ADAPTER_COMMONS=2.6.0
-GLIDE=4.0.0-RC1
+GLIDE=4.0.0
ICONICS=2.9.0
IICON_GOOGLE=3.0.1.1
MATERIAL_DIALOG=0.9.4.5
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefActivity.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefActivity.kt
index 91c0cf2..4324fd3 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefActivity.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefActivity.kt
@@ -12,6 +12,7 @@ import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.FrameLayout
import android.widget.ViewAnimator
+import ca.allanwang.kau.internal.KauBaseActivity
import ca.allanwang.kau.kpref.activity.items.KPrefItemCore
import ca.allanwang.kau.ui.views.RippleCanvas
import ca.allanwang.kau.ui.widgets.TextSlider
@@ -21,7 +22,7 @@ import ca.allanwang.kau.utils.statusBarColor
import ca.allanwang.kau.utils.string
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
-abstract class KPrefActivity : AppCompatActivity(), KPrefActivityContract {
+abstract class KPrefActivity : KauBaseActivity(), KPrefActivityContract {
val adapter: FastItemAdapter<KPrefItemCore>
@Suppress("UNCHECKED_CAST")
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt
index 3947809..b6f3721 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt
@@ -40,6 +40,7 @@ class MediaItem(val data: MediaModel)
super.bindView(holder, payloads)
Glide.with(holder.itemView)
.load(data.data)
+ .applyMediaOptions(holder.itemView.context)
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(e: GlideException?, model: Any, target: Target<Drawable>, isFirstResource: Boolean): Boolean {
failedToLoad = true
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt
index 4fbe955..c28ed29 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt
@@ -47,6 +47,7 @@ class MediaItemBasic(val data: MediaModel)
super.bindView(holder, payloads)
Glide.with(holder.itemView)
.load(data.data)
+ .applyMediaOptions(holder.itemView.context)
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(e: GlideException?, model: Any, target: Target<Drawable>, isFirstResource: Boolean): Boolean {
holder.image.setImageDrawable(MediaPickerCore.getErrorDrawable(holder.itemView.context))
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt
index bdd25ba..cb218fc 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt
@@ -1,8 +1,12 @@
package ca.allanwang.kau.mediapicker
import android.app.Activity
+import android.content.Context
import android.content.Intent
import ca.allanwang.kau.utils.startActivityForResult
+import com.bumptech.glide.RequestBuilder
+import com.bumptech.glide.load.engine.DiskCacheStrategy
+import com.bumptech.glide.request.RequestOptions
/**
* Created by Allan Wang on 2017-07-21.
@@ -31,3 +35,6 @@ internal const val MEDIA_PICKER_RESULT = "media_picker_result"
internal const val ANIMATION_DURATION = 200L
internal const val ANIMATION_SCALE = 0.95f
+internal fun <T> RequestBuilder<T>.applyMediaOptions(context: Context)
+ = apply(RequestOptions().diskCacheStrategy(DiskCacheStrategy.RESOURCE).centerCrop().override(MediaPickerCore.viewSize(context)))
+
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt
index 255cec4..ee3481d 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt
@@ -12,34 +12,42 @@ import android.provider.MediaStore
import android.support.v4.app.LoaderManager
import android.support.v4.content.CursorLoader
import android.support.v4.content.Loader
-import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.RecyclerView
import ca.allanwang.kau.animators.FadeScaleAnimatorAdd
import ca.allanwang.kau.animators.KauAnimator
+import ca.allanwang.kau.internal.KauBaseActivity
+import ca.allanwang.kau.kotlin.lazyContext
import ca.allanwang.kau.permissions.kauRequestPermissions
import ca.allanwang.kau.utils.dimenPixelSize
import ca.allanwang.kau.utils.toast
+import com.bumptech.glide.Glide
import com.mikepenz.fastadapter.IItem
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.mikepenz.iconics.IconicsDrawable
+import org.jetbrains.anko.doAsync
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.Future
/**
* Created by Allan Wang on 2017-07-23.
*
* Container for the main logic behind the both pickers
*/
-abstract class MediaPickerCore<T : IItem<*, *>>(val mediaType: MediaType) : AppCompatActivity(), LoaderManager.LoaderCallbacks<Cursor> {
+abstract class MediaPickerCore<T : IItem<*, *>>(
+ val mediaType: MediaType, val preload: Boolean = mediaType == MediaType.VIDEO
+) : KauBaseActivity(), LoaderManager.LoaderCallbacks<Cursor> {
companion object {
+ val viewSize = lazyContext { computeViewSize(it) }
/**
* Given the dimensions of our device and a minimum image size,
* Computer the optimal column count for our grid layout
*
* @return column count
*/
- fun computeColumnCount(context: Context): Int {
+ private fun computeColumnCount(context: Context): Int {
val minImageSizePx = context.dimenPixelSize(R.dimen.kau_image_minimum_size)
val screenWidthPx = context.resources.displayMetrics.widthPixels
return screenWidthPx / minImageSizePx
@@ -48,7 +56,7 @@ abstract class MediaPickerCore<T : IItem<*, *>>(val mediaType: MediaType) : AppC
/**
* Compute our resulting image size
*/
- fun computeViewSize(context: Context): Int {
+ private fun computeViewSize(context: Context): Int {
val screenWidthPx = context.resources.displayMetrics.widthPixels
return screenWidthPx / computeColumnCount(context)
}
@@ -84,6 +92,9 @@ abstract class MediaPickerCore<T : IItem<*, *>>(val mediaType: MediaType) : AppC
const val CACHE_SIZE = 80
}
+ private var hasPreloaded = false
+ private var prefetcher: Future<*>? = null
+
val adapter: FastItemAdapter<T> = FastItemAdapter()
/**
@@ -140,13 +151,30 @@ abstract class MediaPickerCore<T : IItem<*, *>>(val mediaType: MediaType) : AppC
onStatusChange(false)
return
}
- val items = mutableListOf<T>()
+ val models = mutableListOf<MediaModel>()
do {
val model = MediaModel(data)
if (!shouldLoad(model)) continue
- items.add(converter(model))
+ models.add(model)
} while (data.moveToNext())
- addItems(items)
+ addItems(models.map { converter(it) })
+ if (!hasPreloaded && preload) {
+ hasPreloaded = true
+ prefetcher = doAsync {
+ models.subList(0, Math.min(models.size, 50)).map { it.data }.forEach {
+ val target = Glide.with(this@MediaPickerCore).load(it)
+ .applyMediaOptions(this@MediaPickerCore)
+ .submit()
+ try {
+ target.get()
+ } catch (ignored: InterruptedException) {
+ } catch (ignored: ExecutionException) {
+ } finally {
+ Glide.with(this@MediaPickerCore).clear(target)
+ }
+ }
+ }
+ }
}
abstract fun converter(model: MediaModel): T
@@ -179,4 +207,8 @@ abstract class MediaPickerCore<T : IItem<*, *>>(val mediaType: MediaType) : AppC
open fun onStatusChange(loaded: Boolean) {}
+ override fun onDestroy() {
+ prefetcher?.cancel(true)
+ super.onDestroy()
+ }
} \ No newline at end of file
diff --git a/mediapicker/src/main/res/layout/kau_blurred_imageview.xml b/mediapicker/src/main/res/layout/kau_blurred_imageview.xml
index e28cb9a..70ad00e 100644
--- a/mediapicker/src/main/res/layout/kau_blurred_imageview.xml
+++ b/mediapicker/src/main/res/layout/kau_blurred_imageview.xml
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<merge 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="match_parent">
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt
index abf44d8..cd86d38 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt
@@ -1,11 +1,11 @@
package ca.allanwang.kau.sample
import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
+import ca.allanwang.kau.internal.KauBaseActivity
import ca.allanwang.kau.logging.KL
import ca.allanwang.kau.permissions.PERMISSION_ACCESS_COARSE_LOCATION
import ca.allanwang.kau.permissions.PERMISSION_ACCESS_FINE_LOCATION
-import ca.allanwang.kau.permissions.kauOnRequestPermissionsResult
+import ca.allanwang.kau.permissions.PERMISSION_CAMERA
import ca.allanwang.kau.permissions.kauRequestPermissions
import ca.allanwang.kau.swipe.SWIPE_EDGE_LEFT
import ca.allanwang.kau.swipe.kauSwipeOnCreate
@@ -23,7 +23,7 @@ import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
* Activity for animations
* Now also showcases permissions
*/
-class AnimActivity : AppCompatActivity() {
+class AnimActivity : KauBaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -32,7 +32,8 @@ class AnimActivity : AppCompatActivity() {
adapter.add(listOf(
PERMISSION_ACCESS_COARSE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION
+ PERMISSION_ACCESS_FINE_LOCATION,
+ PERMISSION_CAMERA
).map { PermissionCheckbox(it) })
adapter.withOnClickListener { _, _, item, _ ->
KL.d("Perm Click")
@@ -62,8 +63,4 @@ class AnimActivity : AppCompatActivity() {
startActivitySlideOut(MainActivity::class.java)
}
- override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults)
- kauOnRequestPermissionsResult(permissions, grantResults)
- }
} \ No newline at end of file
diff --git a/sample/src/main/res/xml/kau_changelog.xml b/sample/src/main/res/xml/kau_changelog.xml
index 59d51c2..615f467 100644
--- a/sample/src/main/res/xml/kau_changelog.xml
+++ b/sample/src/main/res/xml/kau_changelog.xml
@@ -6,7 +6,14 @@
<item text="" />
-->
- <version title="v3.2.1"/>
+ <version title="v3.2.2"/>
+ <item text=":core: Add simple KauBaseActivity so that activities extending AppCompatActivity can have some default kau helpers implemented" />
+ <item text=":core: The permission manager will now notify you if you try to request a permission that isn\'t added to your manifest" />
+ <item text=":core: Create faq parser" />
+ <item text="Begin writing android tests" />
+ <item text="" />
+
+ <version title="v3.2.1"/>
<item text=":core: Remove requestLayout call from setMargin and setPadding" />
<item text=":core: Fix kau direction bits" />
<item text=":core: Greatly simplify ripple canvas and truly support transparent ripples" />
diff --git a/settings.gradle b/settings.gradle
index 1a883b6..031dff4 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,10 +1,12 @@
include ':core',
- ':sample',
+ ':core-ui',
':about',
':adapter',
':colorpicker',
- ':core-ui',
':mediapicker',
':kpref-activity',
':searchview'
+
+if (!System.env.JITPACK)
+ include ':sample' \ No newline at end of file