From 605a08c2e2e8634263d7626cf7471310add3acb2 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Tue, 6 Jun 2017 23:24:06 -0700 Subject: Preparing preferences --- .../com/pitchedapps/frost/SettingsActivity.kt | 11 ++++ .../kotlin/com/pitchedapps/frost/StartActivity.kt | 10 ++- .../com/pitchedapps/frost/injectors/JsActions.kt | 18 ++++++ .../com/pitchedapps/frost/injectors/JsInjector.kt | 17 +---- .../frost/preferences/PreferenceBuilder.kt | 65 +++++++++++++++++++ .../frost/preferences/PreferenceCheckboxView.kt | 24 +++++++ .../frost/preferences/PreferenceView.kt | 73 ++++++++++++++++++++++ .../frost/settings/BaseSubSettingsActivity.kt | 11 ++++ .../settings/MaterialDialogColorPreference.kt | 13 ++++ .../com/pitchedapps/frost/utils/ContextUtils.kt | 16 +++-- .../kotlin/com/pitchedapps/frost/utils/Prefs.kt | 51 +++++++++++++++ .../kotlin/com/pitchedapps/frost/web/FrostJSI.kt | 10 ++- .../pitchedapps/frost/web/FrostWebViewClient.kt | 2 +- .../com/pitchedapps/frost/web/FrostWebViewCore.kt | 4 +- 14 files changed, 294 insertions(+), 31 deletions(-) create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceBuilder.kt create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceCheckboxView.kt create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceView.kt create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/settings/BaseSubSettingsActivity.kt create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/settings/MaterialDialogColorPreference.kt (limited to 'app/src/main/kotlin') diff --git a/app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt new file mode 100644 index 00000000..56effb37 --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt @@ -0,0 +1,11 @@ +package com.pitchedapps.frost + +import android.preference.PreferenceActivity +import android.support.v7.app.AppCompatActivity + +/** + * Created by Allan Wang on 2017-06-06. + */ +class SettingsActivity:AppCompatActivity() { + +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt index 16860cc5..3dcfc004 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt @@ -18,12 +18,10 @@ class StartActivity : AppCompatActivity() { loadFbCookiesAsync { cookies -> L.d("Cookies loaded ${System.currentTimeMillis()} $cookies") - if (cookies.isNotEmpty()) { - if (Prefs.userId != Prefs.userIdDefault) - launchNewTask(MainActivity::class.java, ArrayList(cookies)) - else - launchNewTask(SelectorActivity::class.java, ArrayList(cookies)) - } else launchNewTask(LoginActivity::class.java) + if (cookies.isNotEmpty()) + launchNewTask(if (Prefs.userId != Prefs.userIdDefault) MainActivity::class.java else SelectorActivity::class.java, ArrayList(cookies)) + else + launchNewTask(LoginActivity::class.java) } } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt new file mode 100644 index 00000000..7d59f797 --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt @@ -0,0 +1,18 @@ +package com.pitchedapps.frost.injectors + +import android.webkit.WebView + +/** + * Created by Allan Wang on 2017-05-31. + */ +enum class JsActions(body: String) { + /** + * Redirects to login activity if create account is found + * see [com.pitchedapps.frost.web.FrostJSI.loadLogin] + */ + LOGIN_CHECK("document.getElementById('signup-button')&&Frost.loadLogin();"); + + val function = "!function(){$body}();" + + fun inject(webView: WebView, callback: ((String) -> Unit)? = null) = JsInjector(function).inject(webView, callback) +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt index 556a5555..bda9ae16 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt @@ -2,26 +2,11 @@ package com.pitchedapps.frost.injectors import android.webkit.WebView -/** - * Created by Allan Wang on 2017-05-31. - */ -enum class JsActions(body: String) { - /** - * Redirects to login activity if create account is found - * see [com.pitchedapps.frost.web.FrostJSI.loadLogin] - */ - LOGIN_CHECK("document.getElementById('signup-button')&&Android.loadLogin();"); - - val function = "!function(){$body}();" - - fun inject(webView: WebView, callback: ((String) -> Unit)? = null) = JsInjector(function).inject(webView, callback) -} - class JsBuilder { private val css: StringBuilder by lazy { StringBuilder() } fun css(css: String): JsBuilder { - this.css.append(css.trim()) + this.css.append(css) return this } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceBuilder.kt b/app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceBuilder.kt new file mode 100644 index 00000000..f49eac8f --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceBuilder.kt @@ -0,0 +1,65 @@ +package com.pitchedapps.frost.preferences + +import android.content.Context +import android.support.annotation.ColorInt +import android.support.annotation.ColorRes +import android.support.annotation.StringRes +import com.mikepenz.iconics.typeface.IIcon +import com.pitchedapps.frost.utils.toColor +import com.pitchedapps.frost.utils.toString + +/** + * Created by Allan Wang on 2017-06-06. + */ +//fun Context.preference(setup: PreferenceBuild) + +@DslMarker +annotation class PreferenceMarker + +@PreferenceMarker +enum class PreferenceType() { + HEADER, TEXT, CHECKBOX; + + fun createView(builder: PrefItem) { + + } +} + +@PreferenceMarker +class PrefFrame(val context: Context, val theme: ThemeBuilder? = null, builder: PrefFrameBuilder.() -> Unit) + +@PreferenceMarker +class PrefFrameBuilder() { + val items: MutableList> = mutableListOf() + + fun item(item: PrefItem) { + items.add(item) + } +} + +@PreferenceMarker +class ThemeBuilder(context: Context, @ColorInt text: Int? = null, @ColorRes textRes: Int? = null, + @ColorInt accent: Int? = null, @ColorRes accentRes: Int? = null, + @ColorInt background: Int? = null, @ColorRes backgroundRes: Int? = null) { + val textColor = text ?: textRes?.toColor(context) + val accentColor = accent ?: accentRes?.toColor(context) + val backgroundColor = background ?: backgroundRes?.toColor(context) +} + +@PreferenceMarker +class PrefItem( + context: Context, + val key: String, + title: String? = null, + @StringRes titleRes: Int? = null, + description: String? = null, + @StringRes descriptionRes: Int? = null, + val onClick: (key: String, current: T, callback: (T) -> Unit) -> Unit, + val iicon: IIcon? = null, + val getter: (key: String) -> T, + val setter: (key: String, value: T) -> Unit +) { + val title: String = titleRes?.toString(context) ?: title ?: "" + val description: String = descriptionRes?.toString(context) ?: description ?: "" + val originalValue: T by lazy { getter.invoke(key) } +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceCheckboxView.kt b/app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceCheckboxView.kt new file mode 100644 index 00000000..311ce051 --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceCheckboxView.kt @@ -0,0 +1,24 @@ +package com.pitchedapps.frost.preferences + +import android.content.Context +import android.content.res.ColorStateList +import android.support.annotation.ColorInt +import android.view.View + +/** + * Created by Allan Wang on 2017-06-06. + */ +class PreferenceCheckboxView(context: Context, builder: PrefItem, themeBuilder: ThemeBuilder?) : PreferenceView(context, builder, themeBuilder) { + + init { + checkbox.visibility = View.VISIBLE + } + + override fun viewWithClick() = checkbox + + override fun setAccentColor(@ColorInt color: Int) { + val state = ColorStateList.valueOf(color) + checkbox.buttonTintList = state + icon.imageTintList = state + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceView.kt b/app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceView.kt new file mode 100644 index 00000000..60c3bb9d --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceView.kt @@ -0,0 +1,73 @@ +package com.pitchedapps.frost.preferences + +import android.annotation.SuppressLint +import android.content.Context +import android.support.annotation.ColorInt +import android.view.View +import android.widget.CheckBox +import android.widget.ImageView +import android.widget.LinearLayout +import android.widget.TextView +import butterknife.ButterKnife +import com.pitchedapps.frost.R +import com.pitchedapps.frost.utils.bindView +import com.pitchedapps.frost.utils.toDrawable + +@SuppressLint("ViewConstructor") +/** + * Created by Allan Wang on 2017-06-06. + */ +open class PreferenceView( + context: Context, builder: PrefItem, themeBuilder: ThemeBuilder? +) : LinearLayout(context) { + + val iconFrame: LinearLayout by bindView(R.id.icon_frame) + val icon: ImageView by bindView(R.id.icon) + val title: TextView by bindView(R.id.title) + val desc: TextView by bindView(R.id.summary) + val checkbox: CheckBox by bindView(R.id.checkbox) + val key = builder.key + private val getter = builder.getter + private val setter = builder.setter + var pref: T + get() = getter.invoke(key) + set(value) { + setter.invoke(key, value) + } + val original = pref + val hasChanged: Boolean + get() = original == pref + + init { + ButterKnife.bind(this) + title.text = builder.title + desc.text = builder.description + if (builder.iicon == null) iconFrame.visibility = View.GONE + else icon.setImageDrawable(builder.iicon.toDrawable(context, sizeDp = 48)) + if (themeBuilder != null) { + with(themeBuilder) { + if (textColor != null) setTextColor(textColor) + if (accentColor != null) setAccentColor(accentColor) + } + } + setClick(builder.onClick) + } + + fun setClick(listener: (key: String, current: T, callback: (T) -> Unit) -> Unit) { + viewWithClick().setOnClickListener { + listener.invoke(key, pref, { pref = it }) + } + } + + open fun viewWithClick(): View = this + + open fun setTextColor(@ColorInt color: Int) { + title.setTextColor(color) + desc.setTextColor(color) + desc.alpha = 0.7f + } + + //Accent color is not needed for basic prefs + open fun setAccentColor(@ColorInt color: Int) {} + +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/BaseSubSettingsActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/BaseSubSettingsActivity.kt new file mode 100644 index 00000000..a6af3ba6 --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/BaseSubSettingsActivity.kt @@ -0,0 +1,11 @@ +package com.pitchedapps.frost.settings + +import android.preference.PreferenceActivity +import android.support.v7.app.AppCompatActivity + +/** + * Created by Allan Wang on 2017-06-06. + */ +class BaseSubSettingsActivity:PreferenceActivity() { + +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/MaterialDialogColorPreference.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/MaterialDialogColorPreference.kt new file mode 100644 index 00000000..56a371f8 --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/MaterialDialogColorPreference.kt @@ -0,0 +1,13 @@ +package com.pitchedapps.frost.settings + +import android.content.Context +import android.util.AttributeSet +import com.afollestad.materialdialogs.prefs.MaterialDialogPreference + +/** + * Created by Allan Wang on 2017-06-06. + */ +class MaterialDialogColorPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0) + : MaterialDialogPreference(context, attrs, defStyleAttr, defStyleRes) { + +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/ContextUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/ContextUtils.kt index 59600a4d..f13ec20d 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/ContextUtils.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/ContextUtils.kt @@ -17,9 +17,9 @@ import com.pitchedapps.frost.facebook.FbTab private const val EXTRA_COOKIES = "extra_cookies" private const val ARG_URL = "arg_url" -fun Context.launchNewTask(clazz: Class, cookieList: ArrayList = arrayListOf(), clearStack: Boolean = true) { +fun Context.launchNewTask(clazz: Class, cookieList: ArrayList = arrayListOf()) { val intent = (Intent(this, clazz)) - if (clearStack && (clazz != LoginActivity::class.java)) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) + if (clazz != LoginActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) intent.putParcelableArrayListExtra(EXTRA_COOKIES, cookieList) startActivity(intent) if (this is Activity) finish() @@ -41,9 +41,15 @@ fun WebOverlayActivity.url(): String { return intent.extras?.getString(ARG_URL) ?: FbTab.FEED.url } -fun Activity.restart() { - finish() +fun Activity.restart(extras: ((Intent) -> Unit)? = null) { + val i = Intent(this, this::class.java) + i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION) + extras?.invoke(i) + startActivity(i) overridePendingTransition(0, 0) //No transitions - startActivity(intent); + finish() overridePendingTransition(0, 0) } + +fun Int.toString(c: Context) = c.getString(this) +fun Int.toColor(c: Context) = ContextCompat.getColor(c, this) \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt index d99e8417..ec296309 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt @@ -2,6 +2,7 @@ package com.pitchedapps.frost.utils import android.content.Context import android.content.SharedPreferences +import android.graphics.Color /** * Created by Allan Wang on 2017-05-28. @@ -12,10 +13,16 @@ import android.content.SharedPreferences private val PREFERENCE_NAME = "${com.pitchedapps.frost.BuildConfig.APPLICATION_ID}.prefs" private val LAST_ACTIVE = "last_active" private val USER_ID = "user_id" +private val COLOR_TEXT = "color_text" +private val COLOR_BG = "color_bg" +private val COLOR_HEADER = "color_header" +private val COLOR_ICONS = "color_icons" +private val THEME_TYPE = "theme_type" object Prefs { private const val prefDefaultLong = -2L + private const val prefDefaultInt = -2 lateinit private var c: Context operator fun invoke(c: Context) { @@ -46,6 +53,46 @@ object Prefs { if (value != prefDefaultLong) set(USER_ID, value) } + var textColor: Int = prefDefaultInt + get() { + if (field == prefDefaultInt) field = sp.getInt(COLOR_TEXT, Color.BLACK) + return field + } + set(value) { + field = value + if (value != prefDefaultInt) set(COLOR_TEXT, value) + } + + var bgColor: Int = prefDefaultInt + get() { + if (field == prefDefaultInt) field = sp.getInt(COLOR_BG, Color.WHITE) + return field + } + set(value) { + field = value + if (value != prefDefaultInt) set(COLOR_BG, value) + } + + var headerColor: Int = prefDefaultInt + get() { + if (field == prefDefaultInt) field = sp.getInt(COLOR_HEADER, 0xff3b5998.toInt()) + return field + } + set(value) { + field = value + if (value != prefDefaultInt) set(COLOR_HEADER, value) + } + + var iconColor: Int = prefDefaultInt + get() { + if (field == prefDefaultInt) field = sp.getInt(COLOR_ICONS, Color.WHITE) + return field + } + set(value) { + field = value + if (value != prefDefaultInt) set(COLOR_ICONS, value) + } + private fun set(key: String, value: Boolean) = sp.edit().putBoolean(key, value).apply() private fun set(key: String, value: Int) = sp.edit().putInt(key, value).apply() private fun set(key: String, value: Long) = sp.edit().putLong(key, value).apply() @@ -56,5 +103,9 @@ object Prefs { sp.edit().clear().apply() lastActive = prefDefaultLong userId = prefDefaultLong + textColor = prefDefaultInt + bgColor = prefDefaultInt + headerColor = prefDefaultInt + iconColor = prefDefaultInt } } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt index 045c180f..66f638af 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt @@ -3,15 +3,21 @@ package com.pitchedapps.frost.web import android.content.Context import android.webkit.JavascriptInterface import com.pitchedapps.frost.LoginActivity +import com.pitchedapps.frost.MainActivity import com.pitchedapps.frost.SelectorActivity import com.pitchedapps.frost.dbflow.CookieModel +import com.pitchedapps.frost.utils.cookies import com.pitchedapps.frost.utils.launchNewTask import com.pitchedapps.frost.utils.launchWebOverlay /** * Created by Allan Wang on 2017-06-01. */ -class FrostJSI(val context: Context, val cookies: ArrayList) { +class FrostJSI(val context: Context) { + + val cookies: ArrayList + get() = (context as? MainActivity)?.cookies() ?: arrayListOf() + @JavascriptInterface fun loadUrl(url: String) = context.launchWebOverlay(url) @@ -20,7 +26,7 @@ class FrostJSI(val context: Context, val cookies: ArrayList) { if (cookies.isNotEmpty()) context.launchNewTask(SelectorActivity::class.java, cookies) else - context.launchNewTask(LoginActivity::class.java, clearStack = false) + context.launchNewTask(LoginActivity::class.java) } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt index 37d10015..922d527b 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt @@ -48,7 +48,7 @@ class FrostWebViewClient(val refreshObservable: Subject) : WebViewClien if (c is MainActivity && c.cookies().isNotEmpty()) c.launchNewTask(SelectorActivity::class.java, c.cookies()) else - c.launchNewTask(LoginActivity::class.java, clearStack = false) + c.launchNewTask(LoginActivity::class.java) } override fun onPageFinished(view: WebView, url: String) { diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt index 6477deda..146f5a33 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt @@ -11,9 +11,10 @@ import android.util.AttributeSet import android.view.MotionEvent import android.view.View import android.view.animation.DecelerateInterpolator -import android.webkit.CookieManager import android.webkit.WebView +import com.pitchedapps.frost.MainActivity import com.pitchedapps.frost.utils.L +import com.pitchedapps.frost.utils.cookies import io.reactivex.Scheduler import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable @@ -56,6 +57,7 @@ class FrostWebViewCore @JvmOverloads constructor( setLayerType(View.LAYER_TYPE_HARDWARE, null) setWebViewClient(FrostWebViewClient(refreshObservable)) setWebChromeClient(FrostChromeClient(progressObservable, titleObservable)) + addJavascriptInterface(FrostJSI(context), "Frost") } override fun loadUrl(url: String?) { -- cgit v1.2.3