aboutsummaryrefslogtreecommitdiff
path: root/app/src
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-06-06 23:24:06 -0700
committerAllan Wang <me@allanwang.ca>2017-06-06 23:24:06 -0700
commit605a08c2e2e8634263d7626cf7471310add3acb2 (patch)
tree7652ecc94a4969688ce85ed94ab9233117d78a40 /app/src
parent067ea15188f20fa268255153e35c2df732fdffee (diff)
downloadfrost-605a08c2e2e8634263d7626cf7471310add3acb2.tar.gz
frost-605a08c2e2e8634263d7626cf7471310add3acb2.tar.bz2
frost-605a08c2e2e8634263d7626cf7471310add3acb2.zip
Preparing preferences
Diffstat (limited to 'app/src')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt11
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt10
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt17
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceBuilder.kt65
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceCheckboxView.kt24
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/preferences/PreferenceView.kt73
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/BaseSubSettingsActivity.kt11
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/MaterialDialogColorPreference.kt13
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/ContextUtils.kt16
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt51
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt10
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt4
-rw-r--r--app/src/main/res/layout/preference_frost.xml64
-rw-r--r--app/src/main/res/values/strings_preferences3
-rw-r--r--app/src/main/res/xml/preferences_appearance.xml12
17 files changed, 373 insertions, 31 deletions
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 <T> createView(builder: PrefItem<T>) {
+
+ }
+}
+
+@PreferenceMarker
+class PrefFrame(val context: Context, val theme: ThemeBuilder? = null, builder: PrefFrameBuilder.() -> Unit)
+
+@PreferenceMarker
+class PrefFrameBuilder() {
+ val items: MutableList<PrefItem<*>> = mutableListOf()
+
+ fun <T> item(item: PrefItem<T>) {
+ 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<T>(
+ 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<Boolean>, themeBuilder: ThemeBuilder?) : PreferenceView<Boolean>(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<T>(
+ context: Context, builder: PrefItem<T>, 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<out Activity>, cookieList: ArrayList<CookieModel> = arrayListOf(), clearStack: Boolean = true) {
+fun Context.launchNewTask(clazz: Class<out Activity>, cookieList: ArrayList<CookieModel> = 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<CookieModel>) {
+class FrostJSI(val context: Context) {
+
+ val cookies: ArrayList<CookieModel>
+ 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<CookieModel>) {
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<Boolean>) : 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?) {
diff --git a/app/src/main/res/layout/preference_frost.xml b/app/src/main/res/layout/preference_frost.xml
new file mode 100644
index 00000000..bcbed7f2
--- /dev/null
+++ b/app/src/main/res/layout/preference_frost.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:background="?android:attr/activatedBackgroundIndicator"
+ android:clipToPadding="false"
+ android:baselineAligned="false">
+
+ <LinearLayout
+ android:id="@+id/icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="-4dp"
+ android:minWidth="60dp"
+ android:gravity="start|center_vertical"
+ android:orientation="horizontal"
+ android:paddingEnd="12dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp">
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxWidth="48dp"
+ android:maxHeight="48dp" />
+ </LinearLayout>
+
+ <RelativeLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp">
+
+ <TextView android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:ellipsize="marquee" />
+
+ <TextView android:id="@+id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/title"
+ android:layout_alignStart="@id/title"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="10"
+ android:ellipsize="end" />
+
+ </RelativeLayout>
+
+ <CheckBox
+ android:id="@+id/checkbox"
+ android:visibility="gone"
+ android:paddingStart="16dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/values/strings_preferences b/app/src/main/res/values/strings_preferences
new file mode 100644
index 00000000..5b10d8ae
--- /dev/null
+++ b/app/src/main/res/values/strings_preferences
@@ -0,0 +1,3 @@
+<resources>
+ <string name="frost_pref_title_title">Settings</string>
+</resources> \ No newline at end of file
diff --git a/app/src/main/res/xml/preferences_appearance.xml b/app/src/main/res/xml/preferences_appearance.xml
new file mode 100644
index 00000000..23e179fd
--- /dev/null
+++ b/app/src/main/res/xml/preferences_appearance.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ <!--<com.afollestad.materialdialogs.prefs.MaterialDialogPreference-->
+ <!--android:dialogIcon="@mipmap/ic_launcher"-->
+ <!--android:dialogMessage="@string/preference_dialog_message"-->
+ <!--android:dialogTitle="Title Color"-->
+ <!--android:key="unused_key00"-->
+ <!--android:negativeButtonText="@android:string/cancel"-->
+ <!--android:positiveButtonText="@android:string/ok"-->
+ <!--android:summary="@string/material_dialog_pref_summary"-->
+ <!--android:title="@string/material_dialog_pref_title" />-->
+</PreferenceScreen> \ No newline at end of file