From 26421aa428c669f4123fca7094fff0e1d90b5387 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Wed, 30 Aug 2017 12:13:38 -0400 Subject: fix/mediapicker (#50) * Bring all glide request managers to one instance * Switch to test implementation * Check if parent is null for searchview * Ensure open close runs on ui thread * Make glide contract internal * Update changelog * Update version Update changelog for previous prs --- android-lib.gradle | 8 ++++---- docs/Changelog.md | 3 +++ gradle.properties | 2 +- .../ca/allanwang/kau/mediapicker/GlideHelper.kt | 18 ++++++++++++++++++ .../ca/allanwang/kau/mediapicker/MediaItem.kt | 6 +++--- .../ca/allanwang/kau/mediapicker/MediaItemBasic.kt | 6 +++--- .../ca/allanwang/kau/mediapicker/MediaPickerCore.kt | 11 +++++++++-- sample/src/main/res/xml/kau_changelog.xml | 6 ++++-- .../ca/allanwang/kau/searchview/SearchView.kt | 21 +++++++++++---------- 9 files changed, 56 insertions(+), 25 deletions(-) create mode 100644 mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/GlideHelper.kt diff --git a/android-lib.gradle b/android-lib.gradle index a8417c0..d968dd4 100644 --- a/android-lib.gradle +++ b/android-lib.gradle @@ -70,10 +70,10 @@ android { } dependencies { - androidTestCompile("com.android.support.test:runner:${TEST_RUNNER}") { + androidTestImplementation("com.android.support.test:runner:${TEST_RUNNER}") { exclude group: 'com.android.support', module: 'support-annotations' } - androidTestCompile "org.jetbrains.kotlin:kotlin-test-junit:${KOTLIN}" - testCompile "org.jetbrains.kotlin:kotlin-test-junit:${KOTLIN}" - testCompile "junit:junit:${JUNIT}" + androidTestImplementation "org.jetbrains.kotlin:kotlin-test-junit:${KOTLIN}" + testImplementation "org.jetbrains.kotlin:kotlin-test-junit:${KOTLIN}" + testImplementation "junit:junit:${JUNIT}" } \ No newline at end of file diff --git a/docs/Changelog.md b/docs/Changelog.md index 63927a7..aa37c4d 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -3,6 +3,9 @@ ## v3.4.0 * Update to gradle 4.x; api and implementation rather than compile * Update dependencies +* :searchview: Ensure reveals are called on the UI thread +* :searchview: Check that searchview has a parent before checking card state +* :mediapicker: Reuse request manager from activity ## v3.3.2 * :kpref-activity: Add visibility toggle to Core contract. Items can override this to show/hide given preferences based on boolean callbacks. diff --git a/gradle.properties b/gradle.properties index ad3a84a..9a1177d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,7 +23,7 @@ TARGET_SDK=26 BUILD_TOOLS=26.0.1 ANDROID_SUPPORT_LIBS=26.0.1 -VERSION_NAME=3.3.3 +VERSION_NAME=3.4.0 KOTLIN=1.1.4-2 ABOUT_LIBRARIES=5.9.7 diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/GlideHelper.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/GlideHelper.kt new file mode 100644 index 0000000..8bb341c --- /dev/null +++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/GlideHelper.kt @@ -0,0 +1,18 @@ +package ca.allanwang.kau.mediapicker + +import android.view.View +import com.bumptech.glide.Glide +import com.bumptech.glide.RequestManager + +/** + * Created by Allan Wang on 29/08/2017. + * + * Basic helper to fetch the [RequestManager] from the activity if it exists, before creating another one + */ +internal interface GlideContract { + fun glide(v: View): RequestManager +} + +internal class GlideDelegate : GlideContract { + override fun glide(v: View) = ((v.context as? MediaPickerCore<*>)?.glide ?: Glide.with(v))!! +} \ No newline at end of file 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 b6f3721..0431465 100644 --- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt +++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt @@ -16,7 +16,7 @@ import com.mikepenz.fastadapter.FastAdapter * Created by Allan Wang on 2017-07-04. */ class MediaItem(val data: MediaModel) - : KauIItem(R.layout.kau_iitem_image, { ViewHolder(it) }) { + : KauIItem(R.layout.kau_iitem_image, { ViewHolder(it) }), GlideContract by GlideDelegate() { private var failedToLoad = false @@ -38,7 +38,7 @@ class MediaItem(val data: MediaModel) override fun bindView(holder: ViewHolder, payloads: List?) { super.bindView(holder, payloads) - Glide.with(holder.itemView) + glide(holder.itemView) .load(data.data) .applyMediaOptions(holder.itemView.context) .listener(object : RequestListener { @@ -59,7 +59,7 @@ class MediaItem(val data: MediaModel) override fun unbindView(holder: ViewHolder) { super.unbindView(holder) - Glide.with(holder.itemView).clear(holder.container.imageBase) + glide(holder.itemView).clear(holder.container.imageBase) holder.container.removeBlurInstantly() failedToLoad = false } 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 e546afb..2d6cefa 100644 --- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt +++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt @@ -22,7 +22,7 @@ import com.mikepenz.fastadapter.FastAdapter * Created by Allan Wang on 2017-07-04. */ class MediaItemBasic(val data: MediaModel) - : KauIItem(R.layout.kau_iitem_image_basic, { ViewHolder(it) }) { + : KauIItem(R.layout.kau_iitem_image_basic, { ViewHolder(it) }), GlideContract by GlideDelegate() { companion object { @SuppressLint("NewApi") @@ -40,7 +40,7 @@ class MediaItemBasic(val data: MediaModel) override fun bindView(holder: ViewHolder, payloads: List?) { super.bindView(holder, payloads) - Glide.with(holder.itemView) + glide(holder.itemView) .load(data.data) .applyMediaOptions(holder.itemView.context) .listener(object : RequestListener { @@ -58,7 +58,7 @@ class MediaItemBasic(val data: MediaModel) override fun unbindView(holder: ViewHolder) { super.unbindView(holder) - Glide.with(holder.itemView).clear(holder.image) + glide(holder.itemView).clear(holder.image) } class ViewHolder(v: View) : RecyclerView.ViewHolder(v) { 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 eada173..d518b78 100644 --- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt +++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt @@ -27,6 +27,7 @@ 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.bumptech.glide.RequestManager import com.mikepenz.fastadapter.IItem import com.mikepenz.fastadapter.adapters.HeaderAdapter import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter @@ -103,6 +104,7 @@ abstract class MediaPickerCore>( const val CACHE_SIZE = 80 } + lateinit var glide: RequestManager private var hasPreloaded = false private var prefetcher: Future<*>? = null @@ -113,6 +115,11 @@ abstract class MediaPickerCore>( */ val extraSpace: Int by lazy { resources.displayMetrics.heightPixels } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + glide = Glide.with(this) + } + fun initializeRecycler(recycler: RecyclerView) { val adapterWrapper = HeaderAdapter() adapterWrapper.wrap(adapter) @@ -176,7 +183,7 @@ abstract class MediaPickerCore>( hasPreloaded = true prefetcher = doAsync { models.subList(0, Math.min(models.size, 50)).map { it.data }.forEach { - val target = Glide.with(this@MediaPickerCore).load(it) + val target = glide.load(it) .applyMediaOptions(this@MediaPickerCore) .submit() try { @@ -184,7 +191,7 @@ abstract class MediaPickerCore>( } catch (ignored: InterruptedException) { } catch (ignored: ExecutionException) { } finally { - Glide.with(this@MediaPickerCore).clear(target) + glide.clear(target) } } } diff --git a/sample/src/main/res/xml/kau_changelog.xml b/sample/src/main/res/xml/kau_changelog.xml index 87611f8..6f76f66 100644 --- a/sample/src/main/res/xml/kau_changelog.xml +++ b/sample/src/main/res/xml/kau_changelog.xml @@ -9,8 +9,10 @@ - - + + + + diff --git a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt index 491fbe9..dabf4bc 100644 --- a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt +++ b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt @@ -5,7 +5,6 @@ import android.content.Context import android.content.res.ColorStateList import android.graphics.Color import android.support.annotation.ColorInt -import android.support.annotation.ColorRes import android.support.annotation.IdRes import android.support.transition.ChangeBounds import android.support.transition.TransitionManager @@ -215,7 +214,7 @@ class SearchView @JvmOverloads constructor( val adapter = FastItemAdapter() var menuItem: MenuItem? = null val isOpen: Boolean - get() = isAttachedToWindow && card.isVisible + get() = parent != null && card.isVisible /* * Ripple start points and search view offset @@ -306,7 +305,7 @@ class SearchView @JvmOverloads constructor( val menuItem = menu.findItem(id) ?: throw IllegalArgumentException("Menu item with given id doesn't exist") if (menuItem.icon == null) menuItem.icon = GoogleMaterial.Icon.gmd_search.toDrawable(context, 18, menuIconColor) card.gone() - menuItem.setOnMenuItemClickListener { configureCoords(it); revealOpen(); true } + menuItem.setOnMenuItemClickListener { revealOpen(); true } shadow.setOnClickListener { revealClose() } this.menuItem = menuItem return this @@ -322,7 +321,8 @@ class SearchView @JvmOverloads constructor( menuItem = null } - private fun configureCoords(item: MenuItem) { + private fun configureCoords(item: MenuItem?) { + item ?: return if (parent !is ViewGroup) return val view = parentViewGroup.findViewById(item.itemId) ?: return val locations = IntArray(2) @@ -334,7 +334,7 @@ class SearchView @JvmOverloads constructor( override fun onPreDraw(): Boolean { view.viewTreeObserver.removeOnPreDrawListener(this) card.setMarginTop(menuY - card.height / 2) - return false + return true } }) } @@ -372,14 +372,15 @@ class SearchView @JvmOverloads constructor( } fun revealOpen() { - if (isOpen) return - post { + if (parent == null || isOpen) return + context.runOnUiThread { /** * The y component is relative to the cardView, but it hasn't been drawn yet so its own height is 0 * We therefore use half the menuItem height, which is a close approximation to our intended value * The cardView matches the parent's width, so menuX is correct */ - configs.openListener?.invoke(this) + configureCoords(menuItem) + configs.openListener?.invoke(this@SearchView) shadow.fadeIn() editText.showKeyboard() card.circularReveal(menuX, menuHalfHeight, duration = configs.revealDuration) { @@ -390,8 +391,8 @@ class SearchView @JvmOverloads constructor( } fun revealClose() { - if (!isOpen) return - post { + if (parent == null || !isOpen) return + context.runOnUiThread { shadow.fadeOut(duration = configs.transitionDuration) cardTransition { addEndListener { -- cgit v1.2.3 From 66e7d9505e0baffaf17877c1800939a2e0b936d6 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sat, 23 Sep 2017 15:14:12 -0400 Subject: v3.4.1 (#63) * Check browser intent before launching (#54) * Update changelog * fix/misc (#55) * Add kapt plugin * Fix kau vector * Debug lintRelease * Revert debug * Update dependencies * Check context finishing state before showing dialog (#61) * Keep copy of shared pref rather than application context (#60) * Keep copy of shared pref rather than application context * Add back preference name * Add resolver checks (#62) Squashed commit of the following: commit 7fe57d4ab1dbfe8bfb4d4a15bd0fbf636da491fa Author: Allan Wang Date: Sat Sep 23 15:25:18 2017 -0400 Add missing quote commit ffc3ac99248c2250a7f14ef709f37d787cbe0d83 Author: Allan Wang Date: Sat Sep 23 15:20:54 2017 -0400 Update changelog Update gradle Update version name --- build.gradle | 2 +- .../kotlin/ca/allanwang/kau/email/EmailBuilder.kt | 6 ++- .../main/kotlin/ca/allanwang/kau/kpref/KPref.kt | 17 +++----- .../kotlin/ca/allanwang/kau/utils/ContextUtils.kt | 48 ++++++++++++++++------ .../src/main/res-public/values/strings_commons.xml | 2 +- core/src/main/res/values/strings.xml | 4 -- docs/Changelog.md | 5 +++ gradle.properties | 8 ++-- mediapicker/build.gradle | 1 + sample/src/main/res/drawable/kau.xml | 4 +- sample/src/main/res/xml/kau_changelog.xml | 7 ++++ 11 files changed, 66 insertions(+), 38 deletions(-) delete mode 100644 core/src/main/res/values/strings.xml diff --git a/build.gradle b/build.gradle index 19f3436..20d17ca 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { maven { url 'https://maven.fabric.io/public' } } dependencies { - classpath 'com.android.tools.build:gradle:3.0.0-beta3' + classpath 'com.android.tools.build:gradle:3.0.0-beta6' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${KOTLIN}" classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' classpath 'com.github.triplet.gradle:play-publisher:1.2.0' diff --git a/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt b/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt index 88a0945..8c6acff 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt @@ -13,6 +13,7 @@ import ca.allanwang.kau.logging.KL import ca.allanwang.kau.utils.installerPackageName import ca.allanwang.kau.utils.isAppInstalled import ca.allanwang.kau.utils.string +import ca.allanwang.kau.utils.toast /** @@ -76,7 +77,10 @@ class EmailBuilder(val email: String, val subject: String) { emailBuilder.append("\n").append(footer) intent.putExtra(Intent.EXTRA_TEXT, emailBuilder.toString()) - context.startActivity(Intent.createChooser(intent, context.resources.getString(R.string.kau_send_via))) + if (intent.resolveActivity(context.packageManager) != null) + context.startActivity(Intent.createChooser(intent, context.resources.getString(R.string.kau_send_via))) + else + context.toast("Cannot resolve email activity", log = true) } } 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 be16c7c..fbb8c7d 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt @@ -3,6 +3,7 @@ package ca.allanwang.kau.kpref import android.content.Context import android.content.SharedPreferences import ca.allanwang.kau.kotlin.ILazyResettable +import ca.allanwang.kau.logging.KL /** * Created by Allan Wang on 2017-06-07. @@ -22,15 +23,13 @@ import ca.allanwang.kau.kotlin.ILazyResettable */ open class KPref { - lateinit private var c: Context - lateinit internal var PREFERENCE_NAME: String - private var initialized = false + lateinit var PREFERENCE_NAME: String + lateinit var sp: SharedPreferences fun initialize(c: Context, preferenceName: String) { - if (initialized) throw KPrefException("KPref object $preferenceName has already been initialized; please only do so once") - initialized = true - this.c = c.applicationContext PREFERENCE_NAME = preferenceName + sp = c.applicationContext.getSharedPreferences(preferenceName, Context.MODE_PRIVATE) + KL.d("Shared Preference $preferenceName has been initialized") val toDelete = deleteKeys() if (toDelete.isNotEmpty()) { val edit = sp.edit() @@ -39,12 +38,6 @@ open class KPref { } } - //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) - } - internal val prefMap: MutableMap> = mutableMapOf() fun reset() { diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt index d561c8a..a72c7dd 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt @@ -77,7 +77,11 @@ fun Context.startActivitySlideOut(clazz: Class, clearStack: Boolea fun Context.startPlayStoreLink(@StringRes packageIdRes: Int) = startPlayStoreLink(string(packageIdRes)) fun Context.startPlayStoreLink(packageId: String) { - startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=$packageId"))) + val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=$packageId")) + if (intent.resolveActivity(packageManager) != null) + startActivity(intent) + else + toast("Cannot resolve play store", log = true) } /** @@ -87,22 +91,24 @@ fun Context.startPlayStoreLink(packageId: String) { fun Context.startLink(vararg url: String?) { val link = url.firstOrNull { !it.isNullOrBlank() } ?: return val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(link)) - startActivity(browserIntent) + if (browserIntent.resolveActivity(packageManager) != null) + startActivity(browserIntent) + else + toast("Cannot resolve browser", log = true) } -fun Context.startLink(@StringRes url: Int) { - val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(string(url))) - startActivity(browserIntent) -} +fun Context.startLink(@StringRes url: Int) = startLink(string(url)) //Toast helpers -inline fun View.toast(@StringRes id: Int, duration: Int = Toast.LENGTH_LONG) = context.toast(id, duration) +inline fun View.toast(@StringRes id: Int, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) = context.toast(id, duration, log) + +inline fun Context.toast(@StringRes id: Int, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) = toast(this.string(id), duration, log) -inline fun Context.toast(@StringRes id: Int, duration: Int = Toast.LENGTH_LONG) = toast(this.string(id), duration) +inline fun View.toast(text: String, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) = context.toast(text, duration, log) -inline fun View.toast(text: String, duration: Int = Toast.LENGTH_LONG) = context.toast(text, duration) -inline fun Context.toast(text: String, duration: Int = Toast.LENGTH_LONG) { +inline fun Context.toast(text: String, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) { Toast.makeText(this, text, duration).show() + if (log) KL.i("Toast: $text") } //Resource retrievers @@ -163,6 +169,10 @@ fun Context.resolveString(@AttrRes attr: Int, fallback: String = ""): String { inline fun Context.materialDialog(action: MaterialDialog.Builder.() -> Unit): MaterialDialog { val builder = MaterialDialog.Builder(this) builder.action() + if (isFinishing) { + KL.d("Material Dialog triggered from finishing context; did not show") + return builder.build() + } return builder.show() } @@ -192,9 +202,21 @@ fun Context.copyToClipboard(text: String?, label: String = "Copied Text", showTo } fun Context.shareText(text: String?) { - if (text == null) return toast(R.string.kau_text_is_null) + if (text == null) return toast("Share text is null") val intent = Intent(Intent.ACTION_SEND) intent.type = "text/plain" intent.putExtra(Intent.EXTRA_TEXT, text) - startActivity(Intent.createChooser(intent, string(R.string.kau_share))) -} \ No newline at end of file + val chooserIntent = Intent.createChooser(intent, string(R.string.kau_share)) + if (chooserIntent.resolveActivity(packageManager) != null) + startActivity(chooserIntent) + else + toast("Cannot resolve activity to share text", log = true) +} + +/** + * Check if given context is finishing. + * This is a wrapper to check if it's both an activity and finishing + * As of now, it is only checked when tied to an activity + */ +inline val Context.isFinishing: Boolean + get() = (this as? Activity)?.isFinishing ?: false \ No newline at end of file diff --git a/core/src/main/res-public/values/strings_commons.xml b/core/src/main/res-public/values/strings_commons.xml index d236021..6bea9a6 100644 --- a/core/src/main/res-public/values/strings_commons.xml +++ b/core/src/main/res-public/values/strings_commons.xml @@ -38,7 +38,7 @@ Most resources are verbatim and x represents a formatted item No No Results Found None - @android:string/ok + OK Play Store Rate Report A Bug diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml deleted file mode 100644 index d8b2993..0000000 --- a/core/src/main/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - Text is null - \ No newline at end of file diff --git a/docs/Changelog.md b/docs/Changelog.md index aa37c4d..70a61ee 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -1,11 +1,16 @@ # Changelog +## v3.4.1 +* Validate context before showing dialogs +* Add intent resolver checks prior to all executions. + ## v3.4.0 * Update to gradle 4.x; api and implementation rather than compile * Update dependencies * :searchview: Ensure reveals are called on the UI thread * :searchview: Check that searchview has a parent before checking card state * :mediapicker: Reuse request manager from activity +* :kpref-activity: Add bounds to text item ## v3.3.2 * :kpref-activity: Add visibility toggle to Core contract. Items can override this to show/hide given preferences based on boolean callbacks. diff --git a/gradle.properties b/gradle.properties index 9a1177d..32ea648 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,18 +21,18 @@ CORE_MIN_SDK=19 MIN_SDK=21 TARGET_SDK=26 BUILD_TOOLS=26.0.1 -ANDROID_SUPPORT_LIBS=26.0.1 +ANDROID_SUPPORT_LIBS=26.1.0 -VERSION_NAME=3.4.0 +VERSION_NAME=3.4.2 -KOTLIN=1.1.4-2 +KOTLIN=1.1.4-3 ABOUT_LIBRARIES=5.9.7 ANKO=0.10.1 BLURRY=2.1.1 CONSTRAINT_LAYOUT=1.1.0-beta1 FAST_ADAPTER=2.6.3 FAST_ADAPTER_COMMONS=2.6.3 -GLIDE=4.0.0 +GLIDE=4.1.1 ICONICS=2.9.3 IICON_GOOGLE=3.0.1.1 MATERIAL_DIALOG=0.9.4.7 diff --git a/mediapicker/build.gradle b/mediapicker/build.gradle index eff6a77..0f90f7b 100644 --- a/mediapicker/build.gradle +++ b/mediapicker/build.gradle @@ -1,6 +1,7 @@ ext.kauSubModuleMinSdk = project.CORE_MIN_SDK apply from: '../android-lib.gradle' +apply plugin: 'kotlin-kapt' dependencies { implementation project(':core-ui') diff --git a/sample/src/main/res/drawable/kau.xml b/sample/src/main/res/drawable/kau.xml index b0a7be8..47612e0 100644 --- a/sample/src/main/res/drawable/kau.xml +++ b/sample/src/main/res/drawable/kau.xml @@ -8,11 +8,11 @@ + android:pathData="M42.8336 42.7538l19-42.75 31.67656 57H57.0836zM0 0.08894h27L0 28.6213z" /> + android:pathData="M28.5 0.0038 H57l-57 57v-26.882z" /> --> + + + + + + + -- cgit v1.2.3 From cd41bb2917425599fca5d786ea62a2c3253dda70 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sun, 24 Sep 2017 14:26:09 -0400 Subject: Fix bundle NPE for activity creation Update changelog --- .../kotlin/ca/allanwang/kau/utils/ActivityUtils.kt | 6 +++--- .../kotlin/ca/allanwang/kau/utils/ContextUtils.kt | 20 +++++++++++--------- core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt | 20 ++++++++++++++++---- sample/src/main/res/xml/kau_changelog.xml | 2 +- 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt index 5631e70..33bdc62 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt @@ -32,9 +32,9 @@ fun Activity.startActivityForResult( bundle: Bundle? = null, intentBuilder: Intent.() -> Unit = {}) { val intent = Intent(this, clazz) - val fullBundle = if (transition && buildIsLollipopAndUp) - ActivityOptions.makeSceneTransitionAnimation(this).toBundle() - else Bundle() + val fullBundle = Bundle() + if (transition && buildIsLollipopAndUp) + fullBundle.with(ActivityOptions.makeSceneTransitionAnimation(this).toBundle()) if (bundle != null) fullBundle.putAll(bundle) intent.intentBuilder() startActivityForResult(intent, requestCode, if (fullBundle.isEmpty) null else fullBundle) diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt index a72c7dd..0664dc6 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt @@ -43,9 +43,9 @@ fun Context.startActivity( intentBuilder: Intent.() -> Unit = {}) { val intent = Intent(this, clazz) if (clearStack) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) - val fullBundle = if (transition && this is Activity && buildIsLollipopAndUp) - ActivityOptions.makeSceneTransitionAnimation(this).toBundle() - else Bundle() + val fullBundle = Bundle() + if (transition && this is Activity && buildIsLollipopAndUp) + fullBundle.with(ActivityOptions.makeSceneTransitionAnimation(this).toBundle()) if (transition && this !is Activity) KL.d("Cannot make scene transition when context is not an instance of an Activity") if (bundle != null) fullBundle.putAll(bundle) intent.intentBuilder() @@ -57,9 +57,10 @@ fun Context.startActivity( * Bring in activity from the right */ fun Context.startActivitySlideIn(clazz: Class, clearStack: Boolean = false, intentBuilder: Intent.() -> Unit = {}, bundleBuilder: Bundle.() -> Unit = {}) { - val bundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.kau_slide_in_right, R.anim.kau_fade_out).toBundle() - bundle.bundleBuilder() - startActivity(clazz, clearStack, intentBuilder = intentBuilder, bundle = bundle) + val fullBundle = Bundle() + fullBundle.with(ActivityOptionsCompat.makeCustomAnimation(this, R.anim.kau_slide_in_right, R.anim.kau_fade_out).toBundle()) + fullBundle.bundleBuilder() + startActivity(clazz, clearStack, intentBuilder = intentBuilder, bundle = if (fullBundle.isEmpty) null else fullBundle) } /** @@ -69,9 +70,10 @@ fun Context.startActivitySlideIn(clazz: Class, clearStack: Boolean * Consequently, the stack will be cleared by default */ fun Context.startActivitySlideOut(clazz: Class, clearStack: Boolean = true, intentBuilder: Intent.() -> Unit = {}, bundleBuilder: Bundle.() -> Unit = {}) { - val bundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.kau_fade_in, R.anim.kau_slide_out_right_top).toBundle() - bundle.bundleBuilder() - startActivity(clazz, clearStack, intentBuilder = intentBuilder, bundle = bundle) + val fullBundle = Bundle() + fullBundle.with(ActivityOptionsCompat.makeCustomAnimation(this, R.anim.kau_fade_in, R.anim.kau_slide_out_right_top).toBundle()) + fullBundle.bundleBuilder() + startActivity(clazz, clearStack, intentBuilder = intentBuilder, bundle = if (fullBundle.isEmpty) null else fullBundle) } fun Context.startPlayStoreLink(@StringRes packageIdRes: Int) = startPlayStoreLink(string(packageIdRes)) diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt index 50a3c29..954bedc 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt @@ -6,6 +6,7 @@ import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable +import android.os.Bundle import android.os.Handler import android.os.Looper import android.support.annotation.IntRange @@ -53,14 +54,16 @@ annotation class KauUtils * Converts minute value to string * Whole hours and days will be converted as such, otherwise it will default to x minutes */ -@KauUtils fun Context.minuteToText(minutes: Long): String = with(minutes) { +@KauUtils +fun Context.minuteToText(minutes: Long): String = with(minutes) { if (this < 0L) string(R.string.kau_none) else if (this % 1440L == 0L) plural(R.plurals.kau_x_days, this / 1440L) else if (this % 60L == 0L) plural(R.plurals.kau_x_hours, this / 60L) else plural(R.plurals.kau_x_minutes, this) } -@KauUtils fun Number.round(@IntRange(from = 1L) decimalCount: Int): String { +@KauUtils +fun Number.round(@IntRange(from = 1L) decimalCount: Int): String { val expression = StringBuilder().append("#.") (1..decimalCount).forEach { expression.append("#") } val formatter = DecimalFormat(expression.toString()) @@ -72,7 +75,8 @@ annotation class KauUtils * Extracts the bitmap of a drawable, and applies a scale if given * For solid colors, a 1 x 1 pixel will be generated */ -@KauUtils fun Drawable.toBitmap(scaling: Float = 1f, config: Bitmap.Config = Bitmap.Config.ARGB_8888): Bitmap { +@KauUtils +fun Drawable.toBitmap(scaling: Float = 1f, config: Bitmap.Config = Bitmap.Config.ARGB_8888): Bitmap { if (this is BitmapDrawable && bitmap != null) { if (scaling == 1f) return bitmap val width = (bitmap.width * scaling).toInt() @@ -122,4 +126,12 @@ class KauException(message: String) : RuntimeException(message) fun String.withMaxLength(n: Int): String = if (length <= n) this - else substring(0, n-1) + KAU_ELLIPSIS \ No newline at end of file + else substring(0, n - 1) + KAU_ELLIPSIS + +/** + * Similar to [Bundle.putAll], but checks for a null insert and returns the parent bundle + */ +fun Bundle.with(bundle: Bundle?): Bundle { + if (bundle != null) putAll(bundle) + return this +} \ 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 8476660..53dfe99 100644 --- a/sample/src/main/res/xml/kau_changelog.xml +++ b/sample/src/main/res/xml/kau_changelog.xml @@ -9,7 +9,7 @@ - + -- cgit v1.2.3 From 1a509b896aa670da4ab3e2f039140ad7608387e9 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sun, 24 Sep 2017 16:41:13 -0400 Subject: Feature/kpref time picker (#64) * Init kpref time builder and open up other builders * Enable self refresh * Add readme * Update changelog * Update readme --- core/README.md | 4 +- core/src/main/res/values/ids.xml | 1 + docs/Changelog.md | 1 + kpref-activity/README.md | 2 + .../ca/allanwang/kau/kpref/activity/KPrefBinder.kt | 8 +++ .../kau/kpref/activity/items/KPrefColorPicker.kt | 2 +- .../kau/kpref/activity/items/KPrefPlainText.kt | 2 +- .../kau/kpref/activity/items/KPrefSubItems.kt | 2 +- .../kau/kpref/activity/items/KPrefText.kt | 2 +- .../kau/kpref/activity/items/KPrefTimePicker.kt | 64 ++++++++++++++++++++++ .../kotlin/ca/allanwang/kau/sample/KPrefSample.kt | 3 + .../kotlin/ca/allanwang/kau/sample/MainActivity.kt | 31 ++++++----- sample/src/main/res/values/strings.xml | 3 + sample/src/main/res/xml/kau_changelog.xml | 8 ++- 14 files changed, 110 insertions(+), 23 deletions(-) create mode 100644 kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefTimePicker.kt diff --git a/core/README.md b/core/README.md index 4cb68d0..39899dd 100644 --- a/core/README.md +++ b/core/README.md @@ -178,7 +178,7 @@ KAU's swipe is a Kotlin rewrite, along with support for all directions and weakl # Debounce Debouncing is a means of throttling a function so that it is called no more than once in a given instance of time. -An example where you'd like this behaviour is the searchview; you want to deliver search results quickly, +An example where you'd like this behaviour is the searchview: you want to deliver search results quickly, but you don't want to update your response with each new character. Instead, you can wait until a user finishes their query, then search for the results. @@ -210,7 +210,7 @@ Include your email and subject, along with other optional configurations such as ## Extension Functions > "[Extensions](https://kotlinlang.org/docs/reference/extensions.html) provide the ability to extend a class with new functionality without having to inherit from the class" -Note that since KAU depends on [ANKO](https://github.com/Kotlin/anko), all of the extensions in its core package is also in KAU. +
Note that since KAU depends on [ANKO](https://github.com/Kotlin/anko), all of the extensions in its core package is also in KAU. KAU's vast collection of extensions is one of its strongest features. There are too many to explain here, but you may check out the [utils package](https://github.com/AllanWang/KAU/tree/master/core/src/main/kotlin/ca/allanwang/kau/utils) diff --git a/core/src/main/res/values/ids.xml b/core/src/main/res/values/ids.xml index c4912e2..28ff9d9 100644 --- a/core/src/main/res/values/ids.xml +++ b/core/src/main/res/values/ids.xml @@ -14,6 +14,7 @@ + diff --git a/docs/Changelog.md b/docs/Changelog.md index 70a61ee..6c5bb11 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -3,6 +3,7 @@ ## v3.4.1 * Validate context before showing dialogs * Add intent resolver checks prior to all executions. +* Fix bundle NPE when starting activity ## v3.4.0 * Update to gradle 4.x; api and implementation rather than compile diff --git a/kpref-activity/README.md b/kpref-activity/README.md index a9aac89..69d4892 100644 --- a/kpref-activity/README.md +++ b/kpref-activity/README.md @@ -30,6 +30,7 @@ Contract | Mandatory | Optional | Description `KPrefSeekbarContract` | `NA` | `min` `max` `increments` `toText` `textViewConfigs` | Addtional configurations for a seekbar, as well as text to be displayed on the side. `KPrefSubItemsContract` | `itemBuilder` | `NA` | Contains a new list for the adapter to load when clicked `KPrefTextContract` | `NA` | `textGetter` | Additional configurations for the text item +`KPrefTimeContract` | `NA` | `use24HourFormat` | Additional configurations for time picker The kpref items are as followed: @@ -41,6 +42,7 @@ Item | Implements | Description `header` | `CoreContract` | Header; just a title that isn't clickable `text` | `CoreContract` `BaseContract` `KPrefTextContract` | Text item; displays the kpref as a String on the right; does not have click implementation by default `plainText` | `CoreContract` `BaseContract` | Plain text item; like `text` but does not deal with any preferences directly, so it doesn't need a getter or setter +`timePicker` | `CoreContract` `BaseContract` `KPrefTextContract`, `KPrefTimeContract` | Extension ot `text` that will open and save a time picker This can be used to display text or deal with preference that are completely handed within the click event (eg a dialog). `subItems` | `CoreContract` `KPrefSubItemsContract` | Sub items; contains a new page for the activity to load when clicked diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefBinder.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefBinder.kt index 35821fd..637af03 100644 --- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefBinder.kt +++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefBinder.kt @@ -101,6 +101,14 @@ class KPrefAdapterBuilder(val globalOptions: GlobalOptions) { = list.add(KPrefSeekbar(KPrefSeekbar.KPrefSeekbarBuilder(globalOptions, title, getter, setter) .apply { builder() })) + @KPrefMarker + fun timePicker(@StringRes title: Int, + getter: (() -> Int), + setter: ((value: Int) -> Unit), + builder: KPrefTimePicker.KPrefTimeContract.() -> Unit = {}) + = list.add(KPrefTimePicker(KPrefTimePicker.KPrefTimeBuilder(globalOptions, title, getter, setter) + .apply { builder() })) + @KPrefMarker val list: MutableList = mutableListOf() } \ No newline at end of file diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefColorPicker.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefColorPicker.kt index 315d67b..1950589 100644 --- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefColorPicker.kt +++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefColorPicker.kt @@ -14,7 +14,7 @@ import ca.allanwang.kau.kpref.activity.R * ColorPicker preference * When a color is successfully selected in the dialog, it will be saved as an int */ -open class KPrefColorPicker(val builder: KPrefColorContract) : KPrefItemBase(builder) { +open class KPrefColorPicker(open val builder: KPrefColorContract) : KPrefItemBase(builder) { override fun onPostBindView(viewHolder: ViewHolder, textColor: Int?, accentColor: Int?) { super.onPostBindView(viewHolder, textColor, accentColor) diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefPlainText.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefPlainText.kt index b83df69..d2e49d8 100644 --- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefPlainText.kt +++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefPlainText.kt @@ -12,7 +12,7 @@ import ca.allanwang.kau.kpref.activity.R * and when the preference is completely handled by the click * */ -open class KPrefPlainText(val builder: KPrefPlainTextBuilder) : KPrefItemBase(builder) { +open class KPrefPlainText(open val builder: KPrefPlainTextBuilder) : KPrefItemBase(builder) { override fun defaultOnClick(itemView: View, innerContent: View?): Boolean { //nothing diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSubItems.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSubItems.kt index 1bf0ffc..7c2979c 100644 --- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSubItems.kt +++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSubItems.kt @@ -12,7 +12,7 @@ import ca.allanwang.kau.kpref.activity.R * When clicked, will navigate to a new set of preferences and add the old list to a stack * */ -open class KPrefSubItems(val builder: KPrefSubItemsContract) : KPrefItemCore(builder) { +open class KPrefSubItems(open val builder: KPrefSubItemsContract) : KPrefItemCore(builder) { override fun onClick(itemView: View, innerContent: View?): Boolean { builder.globalOptions.showNextPrefs(builder.titleRes, builder.itemBuilder) diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefText.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefText.kt index 45c9a5d..29dd007 100644 --- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefText.kt +++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefText.kt @@ -14,7 +14,7 @@ import ca.allanwang.kau.utils.toast * This is still a generic preference * */ -open class KPrefText(val builder: KPrefTextContract) : KPrefItemBase(builder) { +open class KPrefText(open val builder: KPrefTextContract) : KPrefItemBase(builder) { /** * Automatically reload on set diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefTimePicker.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefTimePicker.kt new file mode 100644 index 0000000..d4f854b --- /dev/null +++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefTimePicker.kt @@ -0,0 +1,64 @@ +package ca.allanwang.kau.kpref.activity.items + +import android.app.TimePickerDialog +import android.view.View +import android.widget.TimePicker +import ca.allanwang.kau.kpref.activity.GlobalOptions +import ca.allanwang.kau.kpref.activity.R +import java.util.* + +/** + * Created by Allan Wang on 2017-06-14. + * + * Text preference + * Holds a textview to display data on the right + * This is still a generic preference + * + */ +open class KPrefTimePicker(override val builder: KPrefTimeContract) : KPrefText(builder) { + + interface KPrefTimeContract : KPrefText.KPrefTextContract { + var use24HourFormat: Boolean + } + + /** + * Default implementation of [KPrefTimeContract] + */ + class KPrefTimeBuilder( + globalOptions: GlobalOptions, + titleRes: Int, + getter: () -> Int, + setter: (value: Int) -> Unit + ) : KPrefTimeContract, BaseContract by BaseBuilder(globalOptions, titleRes, getter, setter), TimePickerDialog.OnTimeSetListener { + + override var use24HourFormat: Boolean = false + + override fun onTimeSet(view: TimePicker, hourOfDay: Int, minute: Int) { + setter((hourOfDay to minute).mergeTime) + reloadSelf() + } + + override var textGetter: (Int) -> String? = { + val (hour, min) = it.splitTime + if (use24HourFormat) + String.format(Locale.CANADA, "%d:%02d", hour, min) + else + String.format(Locale.CANADA, "%d:%02d %s", hour % 12, min, if (hour >= 12) "PM" else "AM") + } + + override var onClick: ((itemView: View, innerContent: View?, item: KPrefItemBase) -> Boolean)? = { itemView, _, item -> + val (hour, min) = item.pref.splitTime + TimePickerDialog(itemView.context, this, hour, min, use24HourFormat).show() + true + } + + private val Int.splitTime: Pair + get() = Pair(this / 100, this % 100) + + private val Pair.mergeTime: Int + get() = first * 100 + second + } + + override fun getType(): Int = R.id.kau_item_pref_time_picker + +} \ No newline at end of file diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/KPrefSample.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/KPrefSample.kt index 9adabed..0c243e4 100644 --- a/sample/src/main/kotlin/ca/allanwang/kau/sample/KPrefSample.kt +++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/KPrefSample.kt @@ -17,4 +17,7 @@ object KPrefSample : KPref() { var check3: Boolean by kpref("check3", false) var text: String by kpref("text", "empty") var seekbar: Int by kpref("seekbar", 20) + var time12: Int by kpref("time_12", 315) + var time24: Int by kpref("time_24", 2220) + } \ No newline at end of file diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt index 1528970..ca75ebb 100644 --- a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt +++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt @@ -107,8 +107,7 @@ class MainActivity : KPrefActivity() { checkbox(R.string.checkbox_3, { KPrefSample.check3 }, { KPrefSample.check3 = it }) { descRes = R.string.desc_dependent enabler = { KPrefSample.check2 } - onDisabledClick = { - itemView, _, _ -> + onDisabledClick = { itemView, _, _ -> itemView.context.toast("I am still disabled") true } @@ -140,8 +139,7 @@ class MainActivity : KPrefActivity() { text(R.string.text, { KPrefSample.text }, { KPrefSample.text = it }) { descRes = R.string.text_desc - onClick = { - itemView, _, item -> + onClick = { itemView, _, item -> itemView.context.materialDialog { title("Type Text") input("Type here", item.pref, { _, input -> item.pref = input.toString() }) @@ -193,17 +191,25 @@ class MainActivity : KPrefActivity() { textGetter = { string(R.string.kau_lorem_ipsum) } } + timePicker(R.string.time, { KPrefSample.time12 }, { KPrefSample.time12 = it }) { + descRes = R.string.time_desc_12 + use24HourFormat = false + } + + timePicker(R.string.time, { KPrefSample.time24 }, { KPrefSample.time24 = it }) { + descRes = R.string.time_desc_24 + use24HourFormat = true + } + } fun subPrefs(): KPrefAdapterBuilder.() -> Unit = { text(R.string.text, { KPrefSample.text }, { KPrefSample.text = it }) { descRes = R.string.text_desc - onClick = { - itemView, _, item -> + onClick = { itemView, _, item -> itemView.context.materialDialog { title("Type Text") - input("Type here", item.pref, { - _, input -> + input("Type here", item.pref, { _, input -> item.pref = input.toString() reloadSelf() }) @@ -237,21 +243,18 @@ class MainActivity : KPrefActivity() { menuInflater.inflate(R.menu.menu_main, menu) if (searchView == null) searchView = bindSearchView(menu, R.id.action_search) { - textCallback = { - query, searchView -> + textCallback = { query, searchView -> val items = wordBank.filter { it.contains(query) }.sorted().map { SearchItem(it) } searchView.results = items } - searchCallback = { - query, _ -> + searchCallback = { query, _ -> toast("Enter pressed for $query") true } textDebounceInterval = 0 noResultsFound = R.string.kau_no_results_found shouldClearOnClose = false - onItemClick = { - _, _, content, searchView -> + onItemClick = { _, _, content, searchView -> toast(content) searchView.revealClose() } diff --git a/sample/src/main/res/values/strings.xml b/sample/src/main/res/values/strings.xml index a887ad3..1e3361e 100644 --- a/sample/src/main/res/values/strings.xml +++ b/sample/src/main/res/values/strings.xml @@ -15,6 +15,9 @@ Text Pref Saves the text Seekbar + Time Pref + AM PM version + 24h version Sub Item Pref Press this to view the next subset of preferences your.email@here.com diff --git a/sample/src/main/res/xml/kau_changelog.xml b/sample/src/main/res/xml/kau_changelog.xml index 53dfe99..a33edbd 100644 --- a/sample/src/main/res/xml/kau_changelog.xml +++ b/sample/src/main/res/xml/kau_changelog.xml @@ -7,9 +7,11 @@ --> - - - + + + + + -- cgit v1.2.3 From 17c21ba0504faecaab9e2780ffe4a60a06a88bb1 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sat, 7 Oct 2017 00:15:17 -0400 Subject: Update dependencies --- build.gradle | 2 +- docs/Changelog.md | 9 +++++---- gradle.properties | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index 20d17ca..d40ce68 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { maven { url 'https://maven.fabric.io/public' } } dependencies { - classpath 'com.android.tools.build:gradle:3.0.0-beta6' + classpath 'com.android.tools.build:gradle:3.0.0-beta7' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${KOTLIN}" classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' classpath 'com.github.triplet.gradle:play-publisher:1.2.0' diff --git a/docs/Changelog.md b/docs/Changelog.md index 6c5bb11..e85a6aa 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -1,9 +1,10 @@ # Changelog -## v3.4.1 -* Validate context before showing dialogs -* Add intent resolver checks prior to all executions. -* Fix bundle NPE when starting activity +## v3.4.3 +* :core: Validate context before showing dialogs +* :core: Add intent resolver checks prior to all executions. +* :core: Fix bundle NPE when starting activity +* :kpref-activity: Create timePicker ## v3.4.0 * Update to gradle 4.x; api and implementation rather than compile diff --git a/gradle.properties b/gradle.properties index 9c26759..4e690c7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,7 +20,7 @@ APP_GROUP=ca.allanwang CORE_MIN_SDK=19 MIN_SDK=21 TARGET_SDK=26 -BUILD_TOOLS=26.0.1 +BUILD_TOOLS=26.0.2 ANDROID_SUPPORT_LIBS=26.1.0 VERSION_NAME=3.4.3 @@ -29,10 +29,10 @@ KOTLIN=1.1.4-3 ABOUT_LIBRARIES=5.9.7 ANKO=0.10.1 BLURRY=2.1.1 -CONSTRAINT_LAYOUT=1.1.0-beta1 +CONSTRAINT_LAYOUT=1.1.0-beta2 FAST_ADAPTER=2.6.3 FAST_ADAPTER_COMMONS=2.6.3 -GLIDE=4.1.1 +GLIDE=4.2.0 ICONICS=2.9.3 IICON_GOOGLE=3.0.1.1 MATERIAL_DIALOG=0.9.4.7 -- cgit v1.2.3 From 5343e63855d70bd5c801e7d8baf774a3386b5f34 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sat, 7 Oct 2017 00:15:56 -0400 Subject: Update travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index da9bd5c..b991811 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ android: # - android-21 - platform-tools - tools - - build-tools-26.0.1 + - build-tools-26.0.2 - android-26 - extra-android-support - extra-android-m2repository -- cgit v1.2.3 From ff597a7ef456fcb37160fa7a46b45296098ca413 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Tue, 10 Oct 2017 16:44:54 -0400 Subject: fix/validate-document-uri (#80) * Check if id is document before retrieving * Add logging * Add null check for getString index 1 --- .../main/kotlin/ca/allanwang/kau/mediapicker/MediaModel.kt | 2 +- .../kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaModel.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaModel.kt index ae85558..26736d4 100644 --- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaModel.kt +++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaModel.kt @@ -21,7 +21,7 @@ data class MediaModel( @Throws(SQLException::class) constructor(@NonNull cursor: Cursor) : this( cursor.getString(0), - cursor.getString(1), + cursor.getString(1) ?: "", cursor.getLong(2), cursor.getLong(3), cursor.getString(4) 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 d518b78..ec5d2f0 100644 --- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt +++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt @@ -153,8 +153,7 @@ abstract class MediaPickerCore>( * The adapter will be cleared on each successful call */ open fun loadItems() { - kauRequestPermissions(Manifest.permission.READ_EXTERNAL_STORAGE) { - granted, _ -> + kauRequestPermissions(Manifest.permission.READ_EXTERNAL_STORAGE) { granted, _ -> if (granted) { supportLoaderManager.initLoader(LOADER_ID, null, this) onStatusChange(true) @@ -191,7 +190,7 @@ abstract class MediaPickerCore>( } catch (ignored: InterruptedException) { } catch (ignored: ExecutionException) { } finally { - glide.clear(target) + glide.clear(target) } } } @@ -238,9 +237,13 @@ abstract class MediaPickerCore>( * See */ private fun ContentResolver.query(baseUri: Uri, uris: List, block: (cursor: Cursor) -> R) { - val ids = uris.map { + val ids = uris.filter { + val valid = DocumentsContract.isDocumentUri(this@MediaPickerCore, it) + if (!valid) KL.d("Non document uri: ${it.encodedPath}") + valid + }.mapNotNull { DocumentsContract.getDocumentId(it).split(":").getOrNull(1) - }.filterNotNull().joinToString(prefix = "(", separator = ",", postfix = ")") + }.joinToString(prefix = "(", separator = ",", postfix = ")") //? query replacements are done for one arg at a time //since we potentially have a list of ids, we'll just format the WHERE clause ourself query(baseUri, MediaModel.projection, "${BaseColumns._ID} IN $ids", null, sortQuery)?.use(block) -- cgit v1.2.3 From b87c75d607956393ad3b07751eb59ccf41726863 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Wed, 11 Oct 2017 14:17:27 -0400 Subject: fix/misc (#81) * Remove jvmstatic, fixes #68 * Create HO logging * Remove double null boolean notation * Replace multi if else with when * Ignore case in setSpan, closes #82 --- .../main/kotlin/ca/allanwang/kau/about/FaqIItem.kt | 6 ++--- .../kotlin/ca/allanwang/kau/about/LibraryIItem.kt | 6 ++--- .../kotlin/ca/allanwang/kau/iitems/CardIItem.kt | 2 +- .../ca/allanwang/kau/colorpicker/CircleView.kt | 4 ---- .../kotlin/ca/allanwang/kau/ui/views/CutoutView.kt | 12 ++++++---- .../kotlin/ca/allanwang/kau/logging/KauLogger.kt | 28 +++++++++++++++++++++- .../allanwang/kau/permissions/PermissionManager.kt | 6 ++--- .../ca/allanwang/kau/swipe/SwipeBackLayout.kt | 18 ++++++++------ .../main/kotlin/ca/allanwang/kau/xml/Changelog.kt | 2 +- .../kotlin/ca/allanwang/kau/sample/MainActivity.kt | 2 +- .../ca/allanwang/kau/searchview/SearchItem.kt | 8 +++---- 11 files changed, 61 insertions(+), 33 deletions(-) diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/FaqIItem.kt b/about/src/main/kotlin/ca/allanwang/kau/about/FaqIItem.kt index 629aa52..5595aed 100644 --- a/about/src/main/kotlin/ca/allanwang/kau/about/FaqIItem.kt +++ b/about/src/main/kotlin/ca/allanwang/kau/about/FaqIItem.kt @@ -1,5 +1,6 @@ package ca.allanwang.kau.about +import android.annotation.SuppressLint import android.support.v7.widget.RecyclerView import android.text.method.LinkMovementMethod import android.view.View @@ -22,9 +23,7 @@ class FaqIItem(val content: FaqItem) : KauIItem>) { + fun bindEvents(fastAdapter: FastAdapter>) { fastAdapter.withSelectable(false) .withEventHook(object : ClickEventHook>() { @@ -43,6 +42,7 @@ class FaqIItem(val content: FaqItem) : KauIItem?) { super.bindView(holder, payloads) with(holder) { diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt b/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt index e50460e..88e6f9b 100644 --- a/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt +++ b/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt @@ -25,7 +25,7 @@ class LibraryIItem(val lib: Library) : KauIItem>) { + fun bindEvents(fastAdapter: FastAdapter>) { fastAdapter.withSelectable(false) .withOnClickListener { v, _, item, _ -> if (item !is LibraryIItem) false @@ -53,11 +53,11 @@ class LibraryIItem(val lib: Library) : KauIItem>) { + fun bindClickEvents(fastAdapter: FastAdapter>) { fastAdapter.withEventHook(object : ClickEventHook>() { override fun onBindMany(viewHolder: RecyclerView.ViewHolder): List? { return if (viewHolder is ViewHolder) listOf(viewHolder.card, viewHolder.button) else null diff --git a/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/CircleView.kt b/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/CircleView.kt index d697c8b..ed98090 100644 --- a/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/CircleView.kt +++ b/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/CircleView.kt @@ -194,7 +194,6 @@ class CircleView @JvmOverloads constructor(context: Context, attrs: AttributeSet companion object { @ColorInt - @JvmStatic private fun translucentColor(color: Int): Int { val factor = 0.7f val alpha = Math.round(Color.alpha(color) * factor) @@ -205,7 +204,6 @@ class CircleView @JvmOverloads constructor(context: Context, attrs: AttributeSet } @ColorInt - @JvmStatic fun shiftColor(@ColorInt color: Int, @FloatRange(from = 0.0, to = 2.0) by: Float): Int { if (by == 1f) return color @@ -215,11 +213,9 @@ class CircleView @JvmOverloads constructor(context: Context, attrs: AttributeSet } @ColorInt - @JvmStatic fun shiftColorDown(@ColorInt color: Int): Int = shiftColor(color, 0.9f) @ColorInt - @JvmStatic fun shiftColorUp(@ColorInt color: Int): Int = shiftColor(color, 1.1f) } } \ No newline at end of file diff --git a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/CutoutView.kt b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/CutoutView.kt index 9e8ac11..fc03563 100644 --- a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/CutoutView.kt +++ b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/CutoutView.kt @@ -147,14 +147,16 @@ class CutoutView @JvmOverloads constructor( paint.textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, mid, metrics) val maxLineWidth = paint.measureText(text) - return if (high - low < precision) low - else if (maxLineWidth > targetWidth) getSingleLineTextSize(text, paint, targetWidth, low, mid, precision, metrics) - else if (maxLineWidth < targetWidth) getSingleLineTextSize(text, paint, targetWidth, mid, high, precision, metrics) - else mid + return when { + high - low < precision -> low + maxLineWidth > targetWidth -> getSingleLineTextSize(text, paint, targetWidth, low, mid, precision, metrics) + maxLineWidth < targetWidth -> getSingleLineTextSize(text, paint, targetWidth, mid, high, precision, metrics) + else -> mid + } } private fun createBitmap() { - if (!(cutout?.isRecycled ?: true)) + if (cutout?.isRecycled == false) cutout?.recycle() if (width == 0 || height == 0) return cutout = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) diff --git a/core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt b/core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt index 14655f0..61f0708 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt @@ -11,13 +11,33 @@ import android.util.Log * * Base logger class with a predefined tag * This may be extended by an object to effectively replace [Log] + * Almost everything is opened to make everything customizable */ open class KauLogger(val tag: String) { + /** + * Global toggle to enable the whole logger + */ open var enabled = true + + /** + * Global toggle to show private text + */ open var showPrivateText = false + + /** + * If both msg and priv msg are accepted, output the combined output + */ open var messageJoiner: (msg: String, privMsg: String) -> String = { msg, privMsg -> "$msg: $privMsg" } + /** + * Open hook to change the output of the logger (for instance, output to stdout rather than Android log files + * Does not use reference notation to avoid constructor leaks + */ + open var logFun: (priority: Int, message: String?, privateMessage: String?, t: Throwable?) -> Unit = { p, m, pm, t -> + logImpl(p, m, pm, t) + } + /** * Filter pass-through to decide what we wish to log * By default, we will ignore verbose and debug logs @@ -35,14 +55,20 @@ open class KauLogger(val tag: String) { showPrivateText = enable } - open fun log(priority: Int, message: String?, privateMessage: String?, t: Throwable? = null) { + private fun log(priority: Int, message: String?, privateMessage: String?, t: Throwable? = null) { if (!shouldLog(priority, message, privateMessage, t)) return logImpl(priority, message, privateMessage, t) } + /** + * Condition to pass to allow the input to be logged + */ protected open fun shouldLog(priority: Int, message: String?, privateMessage: String?, t: Throwable?): Boolean = enabled && filter(priority) + /** + * Base implementation of the Android logger + */ protected open fun logImpl(priority: Int, message: String?, privateMessage: String?, t: Throwable?) { val text = if (showPrivateText) { if (message == null) privateMessage 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 5fe0ddf..18f3e41 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt @@ -18,8 +18,8 @@ import java.lang.ref.WeakReference */ internal object PermissionManager { - var requestInProgress = false - val pendingResults: MutableList> by lazy { mutableListOf>() } + private var requestInProgress = false + private val pendingResults: MutableList> by lazy { mutableListOf>() } /** * Retrieve permissions requested in our manifest @@ -63,7 +63,7 @@ internal object PermissionManager { val iter = pendingResults.iterator() while (iter.hasNext()) { val action = iter.next().get() - if ((0 until count).any { action?.onResult(permissions[it], grantResults[it]) ?: true }) + if ((0 until count).any { action?.onResult(permissions[it], grantResults[it]) != false }) iter.remove() } if (pendingResults.isEmpty()) diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt index c0875d1..065f4bb 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt @@ -349,7 +349,7 @@ internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs listeners.forEach { it.get()?.onScroll(scrollPercent, contentOffset, edgeFlag) } if (scrollPercent >= 1) { - if (!(activity?.isFinishing ?: true)) { + if (activity?.isFinishing == false) { if (scrollPercent >= scrollThreshold && isScrollOverValid) { isScrollOverValid = false listeners.forEach { it.get()?.onScrollToClose(edgeFlag) } @@ -390,15 +390,19 @@ internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs } override fun clampViewPositionHorizontal(child: View, left: Int, dx: Int): Int { - return if (edgeFlag == SWIPE_EDGE_RIGHT) Math.min(0, Math.max(left, -child.width)) - else if (edgeFlag == SWIPE_EDGE_LEFT) Math.min(child.width, Math.max(left, 0)) - else 0 + return when (edgeFlag) { + SWIPE_EDGE_RIGHT -> Math.min(0, Math.max(left, -child.width)) + SWIPE_EDGE_LEFT -> Math.min(child.width, Math.max(left, 0)) + else -> 0 + } } override fun clampViewPositionVertical(child: View, top: Int, dy: Int): Int { - return if (edgeFlag == SWIPE_EDGE_BOTTOM) Math.min(0, Math.max(top, -child.height)) - else if (edgeFlag == SWIPE_EDGE_TOP) Math.min(child.height, Math.max(top, 0)) - else 0 + return when (edgeFlag) { + SWIPE_EDGE_BOTTOM -> Math.min(0, Math.max(top, -child.height)) + SWIPE_EDGE_TOP -> Math.min(child.height, Math.max(top, 0)) + else -> 0 + } } } diff --git a/core/src/main/kotlin/ca/allanwang/kau/xml/Changelog.kt b/core/src/main/kotlin/ca/allanwang/kau/xml/Changelog.kt index 4bf1836..58f1ccc 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/xml/Changelog.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/xml/Changelog.kt @@ -87,7 +87,7 @@ internal enum class ChangelogType(val tag: String, val attr: String, @LayoutRes ITEM("item", "text", R.layout.kau_changelog_content); companion object { - @JvmStatic val values = values() + val values = values() } /** diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt index ca75ebb..482c911 100644 --- a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt +++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt @@ -277,7 +277,7 @@ class MainActivity : KPrefActivity() { } override fun onBackPressed() { - if (!(searchView?.onBackPressed() ?: false)) super.onBackPressed() + if (searchView?.onBackPressed() != true) super.onBackPressed() } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { diff --git a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt index 75d9b27..29341af 100644 --- a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt +++ b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt @@ -34,8 +34,8 @@ class SearchItem(val key: String, ) { companion object { - @JvmStatic var foregroundColor: Int = 0xdd000000.toInt() - @JvmStatic var backgroundColor: Int = 0xfffafafa.toInt() + var foregroundColor: Int = 0xdd000000.toInt() + var backgroundColor: Int = 0xfffafafa.toInt() } var styledContent: SpannableStringBuilder? = null @@ -44,7 +44,7 @@ class SearchItem(val key: String, * Highlight the subText if it is present in the content */ fun withHighlights(subText: String) { - val index = content.indexOf(subText) + val index = content.indexOf(subText, ignoreCase = true) if (index == -1) return styledContent = SpannableStringBuilder(content) styledContent!!.setSpan(StyleSpan(Typeface.BOLD), index, index + subText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) @@ -60,7 +60,7 @@ class SearchItem(val key: String, holder.container.setRippleBackground(foregroundColor, backgroundColor) holder.title.text = styledContent ?: content - if (description?.isNotBlank() ?: false) holder.desc.visible().text = description + if (description?.isNotBlank() == true) holder.desc.visible().text = description } override fun unbindView(holder: ViewHolder) { -- cgit v1.2.3 From 3f1d6746fd7bcc8d01ef367455628d291d07f434 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Thu, 12 Oct 2017 11:30:40 -0400 Subject: Translations (#84) * Rename string files * Add translations to readme * Check job scheduler null check against travis lint * Remove bad spacing * Update badges * Use vector zenhub badge --- .gitignore | 1 + README.md | 10 +++++-- about/src/main/res/values/strings.xml | 5 ---- about/src/main/res/values/strings_about.xml | 23 +++------------- about/src/main/res/values/strings_about_kau.xml | 20 ++++++++++++++ colorpicker/src/main/res/values/strings.xml | 6 ----- .../src/main/res/values/strings_colorpicker.xml | 6 +++++ gradle.properties | 2 +- mediapicker/src/main/res/values/strings.xml | 14 ---------- .../src/main/res/values/strings_mediapicker.xml | 14 ++++++++++ sample/src/main/res/values/strings.xml | 31 ---------------------- sample/src/main/res/values/strings_sample.xml | 31 ++++++++++++++++++++++ 12 files changed, 85 insertions(+), 78 deletions(-) delete mode 100644 about/src/main/res/values/strings.xml create mode 100644 about/src/main/res/values/strings_about_kau.xml delete mode 100644 colorpicker/src/main/res/values/strings.xml create mode 100644 colorpicker/src/main/res/values/strings_colorpicker.xml delete mode 100644 mediapicker/src/main/res/values/strings.xml create mode 100644 mediapicker/src/main/res/values/strings_mediapicker.xml delete mode 100644 sample/src/main/res/values/strings.xml create mode 100644 sample/src/main/res/values/strings_sample.xml diff --git a/.gitignore b/.gitignore index 4ca0b81..6f35f6b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.iml /.idea .gradle +/crowdin.properties /local.properties .DS_Store /build diff --git a/README.md b/README.md index cf3215c..bc09b0f 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,9 @@ KAU is available on JitPack [![](https://jitpack.io/v/ca.allanwang/kau.svg)](https://jitpack.io/#ca.allanwang/kau) [![Build Status](https://travis-ci.org/AllanWang/KAU.svg?branch=master)](https://travis-ci.org/AllanWang/KAU) +[![Crowdin](https://d322cqt584bo4o.cloudfront.net/kotlin-android-utils/localized.svg)](https://crowdin.com/project/kotlin-android-utils) [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) -[![Stories in Ready](https://badge.waffle.io/AllanWang/KAU.png?label=ready&title=Ready)](https://waffle.io/AllanWang/KAU?utm_source=badge) +[![ZenHub](https://img.shields.io/badge/Shipping%20faster%20with-ZenHub-45529A.svg)](https://app.zenhub.com/workspace/o/allanwang/kau/boards) [![GitHub license](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://raw.githubusercontent.com/AllanWang/KAU/master/LICENSE) To apply, add the following to your root build.gradle: @@ -140,4 +141,9 @@ To resolve that, add `multiDexEnabled true` under your `app.gradle > android > d Likewise, it is highly recommended to use proguard to clean up your project upon release. All KAU components support proguard out of the box. -Some may have extra requirements for certain features, which will be detailed in their respective README. \ No newline at end of file +Some may have extra requirements for certain features, which will be detailed in their respective README. + +## Translations + +KAU depends on translations crowdsourced by the general public. +If you would like to contribute, please visit [here](https://crwd.in/kotlin-android-utils) diff --git a/about/src/main/res/values/strings.xml b/about/src/main/res/values/strings.xml deleted file mode 100644 index 164c0c8..0000000 --- a/about/src/main/res/values/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - This app would not be possible without the following great libraries. - FAQ - \ No newline at end of file diff --git a/about/src/main/res/values/strings_about.xml b/about/src/main/res/values/strings_about.xml index 592f9f4..164c0c8 100644 --- a/about/src/main/res/values/strings_about.xml +++ b/about/src/main/res/values/strings_about.xml @@ -1,20 +1,5 @@ - - - Allan Wang - https://www.allanwang.ca/dev/ - @string/kau_version_code - KAU - -
- KAU aims to make many common functions executable in one line. It adds numerous extensions to match Kotlin\'s DSL, - and supports completely customizable view groups that are usable in any app project. - ]]> -
- https://allanwang.github.io/KAU/ - true - https://github.com/AllanWang/KAU - ca.allanwang.kau - apache_2_0 + + + This app would not be possible without the following great libraries. + FAQ \ No newline at end of file diff --git a/about/src/main/res/values/strings_about_kau.xml b/about/src/main/res/values/strings_about_kau.xml new file mode 100644 index 0000000..592f9f4 --- /dev/null +++ b/about/src/main/res/values/strings_about_kau.xml @@ -0,0 +1,20 @@ + + + Allan Wang + https://www.allanwang.ca/dev/ + @string/kau_version_code + KAU + +
+ KAU aims to make many common functions executable in one line. It adds numerous extensions to match Kotlin\'s DSL, + and supports completely customizable view groups that are usable in any app project. + ]]> +
+ https://allanwang.github.io/KAU/ + true + https://github.com/AllanWang/KAU + ca.allanwang.kau + apache_2_0 +
\ No newline at end of file diff --git a/colorpicker/src/main/res/values/strings.xml b/colorpicker/src/main/res/values/strings.xml deleted file mode 100644 index 5a6f89b..0000000 --- a/colorpicker/src/main/res/values/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Color Palette - Custom - Presets - diff --git a/colorpicker/src/main/res/values/strings_colorpicker.xml b/colorpicker/src/main/res/values/strings_colorpicker.xml new file mode 100644 index 0000000..5a6f89b --- /dev/null +++ b/colorpicker/src/main/res/values/strings_colorpicker.xml @@ -0,0 +1,6 @@ + + + Color Palette + Custom + Presets + diff --git a/gradle.properties b/gradle.properties index 4e690c7..9a45266 100644 --- a/gradle.properties +++ b/gradle.properties @@ -25,7 +25,7 @@ ANDROID_SUPPORT_LIBS=26.1.0 VERSION_NAME=3.4.3 -KOTLIN=1.1.4-3 +KOTLIN=1.1.51 ABOUT_LIBRARIES=5.9.7 ANKO=0.10.1 BLURRY=2.1.1 diff --git a/mediapicker/src/main/res/values/strings.xml b/mediapicker/src/main/res/values/strings.xml deleted file mode 100644 index 717e12b..0000000 --- a/mediapicker/src/main/res/values/strings.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - No items found - No items have been selected - Blurrable ImageView - No items loaded - - No camera found - Please install a camera app and try again. - - Failed to create a temporary file. - - Select Media - \ No newline at end of file diff --git a/mediapicker/src/main/res/values/strings_mediapicker.xml b/mediapicker/src/main/res/values/strings_mediapicker.xml new file mode 100644 index 0000000..717e12b --- /dev/null +++ b/mediapicker/src/main/res/values/strings_mediapicker.xml @@ -0,0 +1,14 @@ + + + No items found + No items have been selected + Blurrable ImageView + No items loaded + + No camera found + Please install a camera app and try again. + + Failed to create a temporary file. + + Select Media + \ No newline at end of file diff --git a/sample/src/main/res/values/strings.xml b/sample/src/main/res/values/strings.xml deleted file mode 100644 index 1e3361e..0000000 --- a/sample/src/main/res/values/strings.xml +++ /dev/null @@ -1,31 +0,0 @@ - - KAU - This is a header - This is a description - Checkbox 1 - Checkbox 2 - Checkbox 3 - I am dependent on checkbox 2 - Text Color - Accent Color - Background Color - This selector allows custom colors - This selector does not allow custom colors - This selector allows for custom colors with alpha values - Text Pref - Saves the text - Seekbar - Time Pref - AM PM version - 24h version - Sub Item Pref - Press this to view the next subset of preferences - your.email@here.com - Your subject - Swipe Showcase - Image Showcase - Video Overlay Showcase - Adapter Showcase - KAU (Kotlin Android Utils) is a collection of common extension functions and complex UIs that can be used in almost all apps. It is meant to implement the shared components, so you can focus on what makes your app unique. - Long Prefs - diff --git a/sample/src/main/res/values/strings_sample.xml b/sample/src/main/res/values/strings_sample.xml new file mode 100644 index 0000000..1e3361e --- /dev/null +++ b/sample/src/main/res/values/strings_sample.xml @@ -0,0 +1,31 @@ + + KAU + This is a header + This is a description + Checkbox 1 + Checkbox 2 + Checkbox 3 + I am dependent on checkbox 2 + Text Color + Accent Color + Background Color + This selector allows custom colors + This selector does not allow custom colors + This selector allows for custom colors with alpha values + Text Pref + Saves the text + Seekbar + Time Pref + AM PM version + 24h version + Sub Item Pref + Press this to view the next subset of preferences + your.email@here.com + Your subject + Swipe Showcase + Image Showcase + Video Overlay Showcase + Adapter Showcase + KAU (Kotlin Android Utils) is a collection of common extension functions and complex UIs that can be used in almost all apps. It is meant to implement the shared components, so you can focus on what makes your app unique. + Long Prefs + -- cgit v1.2.3 From a0b35316f7bb6014ebbd3e18be870e860b30ea71 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Fri, 13 Oct 2017 23:40:39 -0400 Subject: Prepare new version (#85) --- gradle.properties | 2 +- sample/src/main/res/xml/kau_changelog.xml | 101 +++++++++++++++--------------- 2 files changed, 53 insertions(+), 50 deletions(-) diff --git a/gradle.properties b/gradle.properties index 9a45266..e64203d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,7 +23,7 @@ TARGET_SDK=26 BUILD_TOOLS=26.0.2 ANDROID_SUPPORT_LIBS=26.1.0 -VERSION_NAME=3.4.3 +VERSION_NAME=3.4.4 KOTLIN=1.1.51 ABOUT_LIBRARIES=5.9.7 diff --git a/sample/src/main/res/xml/kau_changelog.xml b/sample/src/main/res/xml/kau_changelog.xml index 7f421f8..a4978b3 100644 --- a/sample/src/main/res/xml/kau_changelog.xml +++ b/sample/src/main/res/xml/kau_changelog.xml @@ -2,20 +2,23 @@ - - - - - - - - - - - + + + + + + + + + + + + + + @@ -23,16 +26,16 @@ - + - - - + + + - - + + @@ -40,29 +43,29 @@ - - + + - - - + + + - - + + - - - + + + - - + + @@ -75,32 +78,32 @@ - - - + + + - - - + + + - - - + + + - - - - + + + + @@ -115,7 +118,7 @@ - + @@ -124,7 +127,7 @@ - + @@ -132,7 +135,7 @@ - + @@ -141,20 +144,20 @@ - + - + - + -- cgit v1.2.3