From 605a08c2e2e8634263d7626cf7471310add3acb2 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Tue, 6 Jun 2017 23:24:06 -0700 Subject: Preparing preferences --- .idea/misc.xml | 16 ----- app/build.gradle | 1 + app/proguard-rules.pro | 7 ++- .../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 +- app/src/main/res/layout/preference_frost.xml | 64 +++++++++++++++++++ app/src/main/res/values/strings_preferences | 3 + app/src/main/res/xml/preferences_appearance.xml | 12 ++++ 20 files changed, 380 insertions(+), 48 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 create mode 100644 app/src/main/res/layout/preference_frost.xml create mode 100644 app/src/main/res/values/strings_preferences create mode 100644 app/src/main/res/xml/preferences_appearance.xml diff --git a/.idea/misc.xml b/.idea/misc.xml index 8449ce70..059bca8c 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -95,22 +95,6 @@ - - - - - - - - - - - Android - - - - - diff --git a/app/build.gradle b/app/build.gradle index c71f327d..fbd0a32f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -92,6 +92,7 @@ dependencies { //Dialog compile "com.afollestad.material-dialogs:core:${MATERIAL_DIALOG}" + compile "com.afollestad.material-dialogs:commons:${MATERIAL_DIALOG}" compile "com.github.Raizlabs.DBFlow:dbflow:${DBFLOW}" compile "com.github.Raizlabs.DBFlow:dbflow-core:${DBFLOW}" diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index bd688950..bcca6dd4 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -17,4 +17,9 @@ -keepattributes SourceFile,LineNumberTable -keep public class * extends java.lang.Exception -keep class com.crashlytics.** { *; } --dontwarn com.crashlytics.** \ No newline at end of file +-dontwarn com.crashlytics.** +#JavaScript Interface +-keepclassmembers class * { + @android.webkit.JavascriptInterface ; +} +-keepattributes JavascriptInterface \ No newline at end of file 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?) { 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 @@ + + + + + + + + + + + + + + + + + + \ 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 @@ + + Settings + \ 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 @@ + + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3