aboutsummaryrefslogtreecommitdiff
path: root/core
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 /core
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
Diffstat (limited to 'core')
-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
14 files changed, 242 insertions, 24 deletions
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
+ }
}
}