From fbbc92e4c98a30e107fb2a63887f8b6d20bffabb Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Wed, 14 Jun 2017 17:01:13 -0700 Subject: Update themes and started theme settings --- .../kotlin/com/pitchedapps/frost/MainActivity.kt | 9 ++- .../com/pitchedapps/frost/SettingsActivity.kt | 82 +++++++++++++++------- .../com/pitchedapps/frost/injectors/CssAssets.kt | 8 +-- .../com/pitchedapps/frost/injectors/CssHider.kt | 19 +++++ .../com/pitchedapps/frost/injectors/JsInjector.kt | 28 +++++++- .../com/pitchedapps/frost/utils/ContextUtils.kt | 4 +- .../kotlin/com/pitchedapps/frost/utils/Prefs.kt | 2 + .../kotlin/com/pitchedapps/frost/utils/Theme.kt | 19 +++++ .../pitchedapps/frost/web/FrostWebViewClient.kt | 7 +- .../frost/web/FrostWebViewClientMenu.kt | 4 -- 10 files changed, 137 insertions(+), 45 deletions(-) create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/utils/Theme.kt (limited to 'app/src/main/kotlin/com') diff --git a/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt index 12b308d0..fce3e670 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt @@ -30,10 +30,7 @@ import com.pitchedapps.frost.facebook.FbCookie.switchUser import com.pitchedapps.frost.facebook.FbTab import com.pitchedapps.frost.facebook.PROFILE_PICTURE_URL import com.pitchedapps.frost.fragments.WebFragment -import com.pitchedapps.frost.utils.Prefs -import com.pitchedapps.frost.utils.cookies -import com.pitchedapps.frost.utils.launchNewTask -import com.pitchedapps.frost.utils.launchWebOverlay +import com.pitchedapps.frost.utils.* import io.reactivex.disposables.Disposable import io.reactivex.subjects.PublishSubject @@ -176,7 +173,9 @@ class MainActivity : BaseActivity() { override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.action_settings -> { - startActivity(Intent(this, SettingsActivity::class.java)) + startActivitySlideIn(SettingsActivity::class.java, clearStack = true, intentBuilder = { + putParcelableArrayListExtra(EXTRA_COOKIES, cookies()) + }) } R.id.action_changelog -> showChangelog(R.xml.changelog) R.id.action_call -> launchNewTask(LoginActivity::class.java) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt index b5770739..60499c4a 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt @@ -3,11 +3,13 @@ package com.pitchedapps.frost import android.os.Bundle import ca.allanwang.kau.kpref.KPrefActivity import ca.allanwang.kau.kpref.KPrefAdapterBuilder -import ca.allanwang.kau.utils.darken -import ca.allanwang.kau.utils.navigationBarColor +import ca.allanwang.kau.utils.* import ca.allanwang.kau.views.RippleCanvas import com.mikepenz.google_material_typeface_library.GoogleMaterial +import com.pitchedapps.frost.utils.EXTRA_COOKIES import com.pitchedapps.frost.utils.Prefs +import com.pitchedapps.frost.utils.Theme +import com.pitchedapps.frost.utils.cookies /** * Created by Allan Wang on 2017-06-06. @@ -17,28 +19,54 @@ class SettingsActivity : KPrefActivity() { textColor = { Prefs.textColor } accentColor = { Prefs.textColor } header(R.string.settings) - colorPicker(title = R.string.text_color, - getter = { Prefs.textColor }, setter = { Prefs.textColor = it; reload() }, - configs = { - allowCustom = true - }) - colorPicker(iicon = GoogleMaterial.Icon.gmd_colorize, - title = R.string.background_color, - getter = { Prefs.bgColor }, setter = { Prefs.bgColor = it; bgCanvas.ripple(it, duration = 500L) }, - configs = { - allowCustomAlpha = false - allowCustom = true - }) - colorPicker(title = R.string.header_color, - getter = { Prefs.headerColor }, setter = { - Prefs.headerColor = it - val darkerColor = it.darken() - this@SettingsActivity.navigationBarColor = darkerColor - toolbarCanvas.ripple(darkerColor, RippleCanvas.MIDDLE, RippleCanvas.END, duration = 500L) - }, - configs = { - allowCustom = false - }) + text(title = R.string.theme, itemBuilder = { + onClick = { + itemView, innerContent, item -> + this@SettingsActivity.materialDialog { + title(R.string.theme) + items(Theme.values().map { this@SettingsActivity.string(it.textRes) }) + itemsCallbackSingleChoice(item.pref, { + _, _, which, _ -> + if (item.pref != which) { + item.pref = which + reload() + } + true + }) + } + true + } + getter = { Prefs.theme } + setter = { Prefs.theme = it } + }, textGetter = { this@SettingsActivity.string(Theme(it).textRes) }) + colorPicker(title = R.string.text_color, itemBuilder = { + getter = { Prefs.textColor } + setter = { Prefs.textColor = it; reload() } + }, colorBuilder = { + allowCustom = true + }) + + colorPicker(title = R.string.background_color, coreBuilder = { + iicon = GoogleMaterial.Icon.gmd_colorize + }, itemBuilder = { + getter = { Prefs.bgColor } + setter = { Prefs.bgColor = it; bgCanvas.ripple(it, duration = 500L) } + }, colorBuilder = { + allowCustomAlpha = false + allowCustom = true + }) + + colorPicker(title = R.string.header_color, itemBuilder = { + getter = { Prefs.headerColor } + setter = { + Prefs.headerColor = it + val darkerColor = it.darken() + this@SettingsActivity.navigationBarColor = darkerColor + toolbarCanvas.ripple(darkerColor, RippleCanvas.MIDDLE, RippleCanvas.END, duration = 500L) + } + }, colorBuilder = { + allowCustom = false + }) } override fun onCreate(savedInstanceState: Bundle?) { @@ -48,4 +76,10 @@ class SettingsActivity : KPrefActivity() { toolbarCanvas.set(darkAccent) this.navigationBarColor = darkAccent } + + override fun onBackPressed() { + startActivitySlideOut(MainActivity::class.java, clearStack = true, intentBuilder = { + putParcelableArrayListExtra(EXTRA_COOKIES, cookies()) + }) + } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt index ad257276..7ef358f3 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt @@ -9,16 +9,16 @@ import com.pitchedapps.frost.utils.L * The enum name must match the css file name * //TODO add folder mapping using Prefs */ -enum class CssAssets { - HEADER, LOGIN +enum class CssAssets(val folder: String = "themes") : InjectorContract { + LOGIN("core"), MATERIAL_LIGHT, MATERIAL_DARK, MATERIAL_AMOLED, MATERIAL_GLASS ; var file = "${name.toLowerCase()}.compact.css" var injector: JsInjector? = null - fun inject(webView: WebView, callback: ((String) -> Unit)?) { + override fun inject(webView: WebView, callback: ((String) -> Unit)?) { if (injector == null) { - val content = webView.context.assets.open("css/core/$file").bufferedReader().use { it.readText() } + val content = webView.context.assets.open("css/$folder/$file").bufferedReader().use { it.readText() } injector = JsBuilder().css(content).build() } injector!!.inject(webView, callback) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt new file mode 100644 index 00000000..5ecc6d66 --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt @@ -0,0 +1,19 @@ +package com.pitchedapps.frost.injectors + +import android.webkit.WebView + +/** + * Created by Allan Wang on 2017-05-31. + */ +enum class CssHider(vararg val items: String) : InjectorContract { + HEADER("#header[data-sigil=\"MTopBlueBarHeader\"]", "#header-notices", "[data-sigil*=\"m-promo-jewel-header\"]"), + ADS("[data-xt*=\"is_sponsored.1\"]") + ; + + val injector: JsInjector by lazy { JsBuilder().css("${items.joinToString(separator = ",")}{display:none!important}").build() } + + override fun inject(webView: WebView, callback: ((String) -> Unit)?) { + injector.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 14e0606b..0000ecf1 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt @@ -1,6 +1,11 @@ package com.pitchedapps.frost.injectors import android.webkit.WebView +import com.pitchedapps.frost.facebook.FbCookie +import com.pitchedapps.frost.utils.L +import io.reactivex.Observable +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.subjects.SingleSubject class JsBuilder { private val css = StringBuilder() @@ -30,8 +35,27 @@ class JsBuilder { } } -class JsInjector(val function: String) { - fun inject(webView: WebView, callback: ((String) -> Unit)? = null) { +interface InjectorContract { + fun inject(webView: WebView) = inject(webView, null) + fun inject(webView: WebView, callback: ((String) -> Unit)?) +} + +/** + * Helper method to inject multiple functions simultaneously with a single callback + */ +fun WebView.jsInject(vararg injectors: InjectorContract, callback: ((Array) -> Unit)) { + val observables = Array(injectors.size, { SingleSubject.create() }) + Observable.zip>(observables.map { it.toObservable() }, { it.map { it.toString() }.toTypedArray() }).subscribeOn(AndroidSchedulers.mainThread()).subscribe({ + callback.invoke(it) + }) + (0 until injectors.size).asSequence().forEach { + i -> + injectors[i].inject(this, { observables[i].onSuccess(it) }) + } +} + +class JsInjector(val function: String) : InjectorContract { + override fun inject(webView: WebView, callback: ((String) -> Unit)?) { webView.evaluateJavascript(function, { value -> callback?.invoke(value) }) } } 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 1569532c..2053a6bf 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/ContextUtils.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/ContextUtils.kt @@ -18,8 +18,8 @@ import com.pitchedapps.frost.facebook.FbTab /** * Created by Allan Wang on 2017-06-03. */ -private const val EXTRA_COOKIES = "extra_cookies" -private const val ARG_URL = "arg_url" +internal const val EXTRA_COOKIES = "extra_cookies" +internal const val ARG_URL = "arg_url" fun Context.launchNewTask(clazz: Class, cookieList: ArrayList = arrayListOf(), clearStack: Boolean = clazz != LoginActivity::class.java) { startActivity(clazz, clearStack, { 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 6284a2f8..115f981a 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt @@ -15,6 +15,8 @@ object Prefs : KPref() { var userId: Long by kpref("user_id", -1L) + var theme: Int by kpref("theme", 0) + var textColor: Int by kpref("color_text", Color.BLACK) var bgColor: Int by kpref("color_bg", Color.WHITE) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Theme.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Theme.kt new file mode 100644 index 00000000..4a0ffd8f --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Theme.kt @@ -0,0 +1,19 @@ +package com.pitchedapps.frost.utils + +import com.pitchedapps.frost.R + +/** + * Created by Allan Wang on 2017-06-14. + */ +enum class Theme(val textRes: Int) { + DEFAULT(R.string._default), + LIGHT(R.string.light), + DARK(R.string.dark), + AMOLED(R.string.amoled), + GLASS(R.string.glass), + CUSTOM(R.string.custom); + + companion object { + operator fun invoke(index: Int) = values()[index] + } +} \ 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 2f24d055..4845f553 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt @@ -10,9 +10,7 @@ import com.pitchedapps.frost.MainActivity import com.pitchedapps.frost.SelectorActivity import com.pitchedapps.frost.facebook.FACEBOOK_COM import com.pitchedapps.frost.facebook.FbCookie -import com.pitchedapps.frost.injectors.CssAssets -import com.pitchedapps.frost.injectors.JsActions -import com.pitchedapps.frost.injectors.JsAssets +import com.pitchedapps.frost.injectors.* import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.utils.Prefs import com.pitchedapps.frost.utils.cookies @@ -63,7 +61,8 @@ open class FrostWebViewClient(val refreshObservable: Subject) : WebView internal fun onPageFinishedReveal(view: FrostWebViewCore, animate: Boolean) { L.d("Page finished reveal") - CssAssets.HEADER.inject(view, { + view.jsInject(CssHider.HEADER, CssAssets.MATERIAL_DARK, callback = { + L.d("Finished ${it.contentToString()}") refreshObservable.onNext(false) if (animate) view.circularReveal(offset = 150L) else view.fadeIn(duration = 100L) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt index faf42fdd..3b032f62 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt @@ -13,7 +13,6 @@ class FrostWebViewClientMenu(refreshObservable: Subject) : FrostWebView var content: String? = null var view: FrostWebViewCore? = null - var loadingFromBase: Boolean = false override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) { super.onPageStarted(view, url, favicon) @@ -22,7 +21,6 @@ class FrostWebViewClientMenu(refreshObservable: Subject) : FrostWebView "https://m.facebook.com/settings", "https://m.facebook.com/settings#", "https://m.facebook.com/settings#!/settings?soft=bookmarks" -> { - loadingFromBase = true L.d("Load from stored $url") view.stopLoading() view.loadDataWithBaseURL("https://touch.facebook.com/notifications", content, "text/html", "utf-8", "https://google.ca/test") @@ -33,8 +31,6 @@ class FrostWebViewClientMenu(refreshObservable: Subject) : FrostWebView override fun onPageFinished(view: WebView, url: String) { super.onPageFinished(view, url) - L.d("DON $url") - loadingFromBase = false with(view as FrostWebViewCore) { if (url == view.baseUrl) { this@FrostWebViewClientMenu.view = view -- cgit v1.2.3