aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-12-11 17:52:24 -0500
committerGitHub <noreply@github.com>2017-12-11 17:52:24 -0500
commitdb262e95779e0a17275bdb94be2b0ac12819178e (patch)
tree42b89edf8796e85e362ca86dead1170cb38f6434
parent1d4380cee77fc049a54d280a27dcefa3fa6ff1fd (diff)
downloadfrost-db262e95779e0a17275bdb94be2b0ac12819178e.tar.gz
frost-db262e95779e0a17275bdb94be2b0ac12819178e.tar.bz2
frost-db262e95779e0a17275bdb94be2b0ac12819178e.zip
Feature/tab customization (#522)
* Add initial tab customizing view * Add rest of content for now * Delete project file backups * Stash * Support full tab customization * Test activity animations * Update kau and fix sound uri * Try catch download, resolves #523
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml2
-rw-r--r--app/build.gradle4
-rw-r--r--app/src/main/AndroidManifest.xml3
-rw-r--r--app/src/main/assets/.gitignore2
-rw-r--r--app/src/main/assets/package-lock.json986
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt3
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt34
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt131
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt6
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt19
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt7
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/iitems/TabIItem.kt52
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt5
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt10
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt23
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt17
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt3
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt4
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt12
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt19
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt12
-rw-r--r--app/src/main/res/anim/rotate_delta.xml9
-rw-r--r--app/src/main/res/layout/activity_tab_customizer.xml51
-rw-r--r--app/src/main/res/layout/iitem_tab_preview.xml23
-rw-r--r--app/src/main/res/layout/view_badged_icon.xml4
-rw-r--r--app/src/main/res/values-de-rDE/strings_pref_appearance.xml2
-rw-r--r--app/src/main/res/values-es-rES/strings_pref_appearance.xml2
-rw-r--r--app/src/main/res/values-fr-rFR/strings_pref_appearance.xml2
-rw-r--r--app/src/main/res/values-gl-rES/strings_pref_appearance.xml2
-rw-r--r--app/src/main/res/values-it-rIT/strings_pref_appearance.xml2
-rw-r--r--app/src/main/res/values-ko-rKR/strings_pref_appearance.xml2
-rw-r--r--app/src/main/res/values-pl-rPL/strings_pref_appearance.xml2
-rw-r--r--app/src/main/res/values-pt-rBR/strings_pref_appearance.xml2
-rw-r--r--app/src/main/res/values-vi-rVN/strings_pref_appearance.xml2
-rw-r--r--app/src/main/res/values-zh-rCN/strings_pref_appearance.xml2
-rw-r--r--app/src/main/res/values/dimens.xml1
-rw-r--r--app/src/main/res/values/strings.xml3
-rw-r--r--app/src/main/res/values/strings_download.xml2
-rw-r--r--app/src/main/res/values/strings_errors.xml1
-rw-r--r--app/src/main/res/values/strings_pref_appearance.xml5
-rw-r--r--app/src/main/res/values/strings_pref_notifications.xml2
-rw-r--r--gradle.properties15
46 files changed, 428 insertions, 1069 deletions
diff --git a/.gitignore b/.gitignore
index b755a372..5a2af93b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@
.externalNativeBuild
*.min.css
.sass-cache/
+/projectFilesBackupd
diff --git a/.travis.yml b/.travis.yml
index 696cce55..d2376120 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@ android:
components:
- tools
- platform-tools
- - build-tools-27.0.1
+ - build-tools-27.0.2
- android-27
- extra-android-support
- extra-android-m2repository
diff --git a/app/build.gradle b/app/build.gradle
index 591ed9ba..7fa3fe71 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,5 +1,5 @@
plugins {
- id 'com.gladed.androidgitversion' version '0.3.4'
+ id 'com.gladed.androidgitversion' version '0.4.3'
}
apply plugin: 'com.android.application'
@@ -164,6 +164,8 @@ dependencies {
implementation "com.devbrackets.android:exomedia:${EXOMEDIA}"
+ implementation"com.mikepenz:fastadapter-extensions:${FAST_ADAPTER_EXTENSIONS}@aar"
+
//noinspection GradleDependency
releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:${LEAK_CANARY}"
//noinspection GradleDependency
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 136a467f..f1877bc3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -131,6 +131,9 @@
android:name=".activities.SelectorActivity"
android:theme="@style/FrostTheme" />
<activity
+ android:name=".activities.TabCustomizerActivity"
+ android:theme="@style/FrostTheme" />
+ <activity
android:name=".activities.SettingsActivity"
android:theme="@style/FrostTheme.Settings" />
<activity
diff --git a/app/src/main/assets/.gitignore b/app/src/main/assets/.gitignore
index 1fe1b00e..f195f4ab 100644
--- a/app/src/main/assets/.gitignore
+++ b/app/src/main/assets/.gitignore
@@ -1,2 +1,4 @@
.idea/
node_modules/
+.sass-cache/
+package-lock.json \ No newline at end of file
diff --git a/app/src/main/assets/package-lock.json b/app/src/main/assets/package-lock.json
deleted file mode 100644
index 9bea5fd3..00000000
--- a/app/src/main/assets/package-lock.json
+++ /dev/null
@@ -1,986 +0,0 @@
-{
- "requires": true,
- "lockfileVersion": 1,
- "dependencies": {
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
- "dev": true
- },
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
- "dev": true
- },
- "babel-code-frame": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
- "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
- "dev": true,
- "requires": {
- "chalk": "1.1.3",
- "esutils": "2.0.2",
- "js-tokens": "3.0.2"
- }
- },
- "babel-core": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
- "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
- "dev": true,
- "requires": {
- "babel-code-frame": "6.26.0",
- "babel-generator": "6.26.0",
- "babel-helpers": "6.24.1",
- "babel-messages": "6.23.0",
- "babel-register": "6.26.0",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0",
- "babylon": "6.18.0",
- "convert-source-map": "1.5.1",
- "debug": "2.6.9",
- "json5": "0.5.1",
- "lodash": "4.17.4",
- "minimatch": "3.0.4",
- "path-is-absolute": "1.0.1",
- "private": "0.1.8",
- "slash": "1.0.0",
- "source-map": "0.5.7"
- }
- },
- "babel-generator": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz",
- "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=",
- "dev": true,
- "requires": {
- "babel-messages": "6.23.0",
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0",
- "detect-indent": "4.0.0",
- "jsesc": "1.3.0",
- "lodash": "4.17.4",
- "source-map": "0.5.7",
- "trim-right": "1.0.1"
- }
- },
- "babel-helper-builder-binary-assignment-operator-visitor": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
- "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
- "dev": true,
- "requires": {
- "babel-helper-explode-assignable-expression": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-helper-call-delegate": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
- "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
- "dev": true,
- "requires": {
- "babel-helper-hoist-variables": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-helper-define-map": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
- "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
- "dev": true,
- "requires": {
- "babel-helper-function-name": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0",
- "lodash": "4.17.4"
- }
- },
- "babel-helper-explode-assignable-expression": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
- "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-helper-function-name": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
- "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
- "dev": true,
- "requires": {
- "babel-helper-get-function-arity": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-helper-get-function-arity": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
- "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-helper-hoist-variables": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
- "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-helper-optimise-call-expression": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
- "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-helper-regex": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
- "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0",
- "lodash": "4.17.4"
- }
- },
- "babel-helper-remap-async-to-generator": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
- "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
- "dev": true,
- "requires": {
- "babel-helper-function-name": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-helper-replace-supers": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
- "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
- "dev": true,
- "requires": {
- "babel-helper-optimise-call-expression": "6.24.1",
- "babel-messages": "6.23.0",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-helpers": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
- "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0"
- }
- },
- "babel-messages": {
- "version": "6.23.0",
- "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
- "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0"
- }
- },
- "babel-plugin-check-es2015-constants": {
- "version": "6.22.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
- "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0"
- }
- },
- "babel-plugin-syntax-async-functions": {
- "version": "6.13.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
- "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
- "dev": true
- },
- "babel-plugin-syntax-exponentiation-operator": {
- "version": "6.13.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
- "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
- "dev": true
- },
- "babel-plugin-syntax-trailing-function-commas": {
- "version": "6.22.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
- "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
- "dev": true
- },
- "babel-plugin-transform-async-to-generator": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
- "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
- "dev": true,
- "requires": {
- "babel-helper-remap-async-to-generator": "6.24.1",
- "babel-plugin-syntax-async-functions": "6.13.0",
- "babel-runtime": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-arrow-functions": {
- "version": "6.22.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
- "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-block-scoped-functions": {
- "version": "6.22.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
- "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-block-scoping": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
- "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0",
- "lodash": "4.17.4"
- }
- },
- "babel-plugin-transform-es2015-classes": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
- "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
- "dev": true,
- "requires": {
- "babel-helper-define-map": "6.26.0",
- "babel-helper-function-name": "6.24.1",
- "babel-helper-optimise-call-expression": "6.24.1",
- "babel-helper-replace-supers": "6.24.1",
- "babel-messages": "6.23.0",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-computed-properties": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
- "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-destructuring": {
- "version": "6.23.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
- "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-duplicate-keys": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
- "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-for-of": {
- "version": "6.23.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
- "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-function-name": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
- "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
- "dev": true,
- "requires": {
- "babel-helper-function-name": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-literals": {
- "version": "6.22.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
- "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-modules-amd": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
- "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
- "dev": true,
- "requires": {
- "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-modules-commonjs": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz",
- "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=",
- "dev": true,
- "requires": {
- "babel-plugin-transform-strict-mode": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-modules-systemjs": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
- "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
- "dev": true,
- "requires": {
- "babel-helper-hoist-variables": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-modules-umd": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
- "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
- "dev": true,
- "requires": {
- "babel-plugin-transform-es2015-modules-amd": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-object-super": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
- "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
- "dev": true,
- "requires": {
- "babel-helper-replace-supers": "6.24.1",
- "babel-runtime": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-parameters": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
- "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
- "dev": true,
- "requires": {
- "babel-helper-call-delegate": "6.24.1",
- "babel-helper-get-function-arity": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-shorthand-properties": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
- "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-spread": {
- "version": "6.22.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
- "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-sticky-regex": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
- "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
- "dev": true,
- "requires": {
- "babel-helper-regex": "6.26.0",
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-template-literals": {
- "version": "6.22.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
- "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-typeof-symbol": {
- "version": "6.23.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
- "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0"
- }
- },
- "babel-plugin-transform-es2015-unicode-regex": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
- "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
- "dev": true,
- "requires": {
- "babel-helper-regex": "6.26.0",
- "babel-runtime": "6.26.0",
- "regexpu-core": "2.0.0"
- }
- },
- "babel-plugin-transform-exponentiation-operator": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
- "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
- "dev": true,
- "requires": {
- "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1",
- "babel-plugin-syntax-exponentiation-operator": "6.13.0",
- "babel-runtime": "6.26.0"
- }
- },
- "babel-plugin-transform-regenerator": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
- "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
- "dev": true,
- "requires": {
- "regenerator-transform": "0.10.1"
- }
- },
- "babel-plugin-transform-strict-mode": {
- "version": "6.24.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
- "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
- }
- },
- "babel-preset-env": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz",
- "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==",
- "dev": true,
- "requires": {
- "babel-plugin-check-es2015-constants": "6.22.0",
- "babel-plugin-syntax-trailing-function-commas": "6.22.0",
- "babel-plugin-transform-async-to-generator": "6.24.1",
- "babel-plugin-transform-es2015-arrow-functions": "6.22.0",
- "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0",
- "babel-plugin-transform-es2015-block-scoping": "6.26.0",
- "babel-plugin-transform-es2015-classes": "6.24.1",
- "babel-plugin-transform-es2015-computed-properties": "6.24.1",
- "babel-plugin-transform-es2015-destructuring": "6.23.0",
- "babel-plugin-transform-es2015-duplicate-keys": "6.24.1",
- "babel-plugin-transform-es2015-for-of": "6.23.0",
- "babel-plugin-transform-es2015-function-name": "6.24.1",
- "babel-plugin-transform-es2015-literals": "6.22.0",
- "babel-plugin-transform-es2015-modules-amd": "6.24.1",
- "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
- "babel-plugin-transform-es2015-modules-systemjs": "6.24.1",
- "babel-plugin-transform-es2015-modules-umd": "6.24.1",
- "babel-plugin-transform-es2015-object-super": "6.24.1",
- "babel-plugin-transform-es2015-parameters": "6.24.1",
- "babel-plugin-transform-es2015-shorthand-properties": "6.24.1",
- "babel-plugin-transform-es2015-spread": "6.22.0",
- "babel-plugin-transform-es2015-sticky-regex": "6.24.1",
- "babel-plugin-transform-es2015-template-literals": "6.22.0",
- "babel-plugin-transform-es2015-typeof-symbol": "6.23.0",
- "babel-plugin-transform-es2015-unicode-regex": "6.24.1",
- "babel-plugin-transform-exponentiation-operator": "6.24.1",
- "babel-plugin-transform-regenerator": "6.26.0",
- "browserslist": "2.10.0",
- "invariant": "2.2.2",
- "semver": "5.4.1"
- }
- },
- "babel-register": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
- "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
- "dev": true,
- "requires": {
- "babel-core": "6.26.0",
- "babel-runtime": "6.26.0",
- "core-js": "2.5.2",
- "home-or-tmp": "2.0.0",
- "lodash": "4.17.4",
- "mkdirp": "0.5.1",
- "source-map-support": "0.4.18"
- }
- },
- "babel-runtime": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
- "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
- "dev": true,
- "requires": {
- "core-js": "2.5.2",
- "regenerator-runtime": "0.11.1"
- }
- },
- "babel-template": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
- "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0",
- "babylon": "6.18.0",
- "lodash": "4.17.4"
- }
- },
- "babel-traverse": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
- "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
- "dev": true,
- "requires": {
- "babel-code-frame": "6.26.0",
- "babel-messages": "6.23.0",
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0",
- "babylon": "6.18.0",
- "debug": "2.6.9",
- "globals": "9.18.0",
- "invariant": "2.2.2",
- "lodash": "4.17.4"
- }
- },
- "babel-types": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
- "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "esutils": "2.0.2",
- "lodash": "4.17.4",
- "to-fast-properties": "1.0.3"
- }
- },
- "babylon": {
- "version": "6.18.0",
- "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
- "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
- "dev": true
- },
- "balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
- "dev": true
- },
- "brace-expansion": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
- "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
- "dev": true,
- "requires": {
- "balanced-match": "1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "browserslist": {
- "version": "2.10.0",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.10.0.tgz",
- "integrity": "sha512-WyvzSLsuAVPOjbljXnyeWl14Ae+ukAT8MUuagKVzIDvwBxl4UAwD1xqtyQs2eWYPGUKMeC3Ol62goqYuKqTTcw==",
- "dev": true,
- "requires": {
- "caniuse-lite": "1.0.30000782",
- "electron-to-chromium": "1.3.28"
- }
- },
- "caniuse-lite": {
- "version": "1.0.30000782",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000782.tgz",
- "integrity": "sha1-W4K4w4XyU0h0XEccpRMgr7G38lQ=",
- "dev": true
- },
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "dev": true,
- "requires": {
- "ansi-styles": "2.2.1",
- "escape-string-regexp": "1.0.5",
- "has-ansi": "2.0.0",
- "strip-ansi": "3.0.1",
- "supports-color": "2.0.0"
- }
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
- "dev": true
- },
- "convert-source-map": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
- "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
- "dev": true
- },
- "core-js": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.2.tgz",
- "integrity": "sha1-vEZIZW59ydyA19PHu8Fy2W50TmM=",
- "dev": true
- },
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "detect-indent": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
- "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
- "dev": true,
- "requires": {
- "repeating": "2.0.1"
- }
- },
- "electron-to-chromium": {
- "version": "1.3.28",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.28.tgz",
- "integrity": "sha1-jdTmRYCGZE6fnwoc8y4qH53/2e4=",
- "dev": true
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
- "dev": true
- },
- "esutils": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
- "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
- "dev": true
- },
- "globals": {
- "version": "9.18.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
- "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
- "dev": true
- },
- "has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
- "dev": true,
- "requires": {
- "ansi-regex": "2.1.1"
- }
- },
- "home-or-tmp": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
- "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
- "dev": true,
- "requires": {
- "os-homedir": "1.0.2",
- "os-tmpdir": "1.0.2"
- }
- },
- "invariant": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
- "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
- "dev": true,
- "requires": {
- "loose-envify": "1.3.1"
- }
- },
- "is-finite": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
- "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
- "dev": true,
- "requires": {
- "number-is-nan": "1.0.1"
- }
- },
- "js-tokens": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
- "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
- "dev": true
- },
- "jsesc": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
- "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
- "dev": true
- },
- "json5": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
- "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
- "dev": true
- },
- "lodash": {
- "version": "4.17.4",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
- "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
- "dev": true
- },
- "loose-envify": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
- "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
- "dev": true,
- "requires": {
- "js-tokens": "3.0.2"
- }
- },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "dev": true,
- "requires": {
- "brace-expansion": "1.1.8"
- }
- },
- "minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
- "dev": true
- },
- "mkdirp": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
- "dev": true,
- "requires": {
- "minimist": "0.0.8"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "dev": true
- },
- "number-is-nan": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
- "dev": true
- },
- "os-homedir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
- "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
- "dev": true
- },
- "os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
- "dev": true
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
- "dev": true
- },
- "private": {
- "version": "0.1.8",
- "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
- "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
- "dev": true
- },
- "regenerate": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz",
- "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==",
- "dev": true
- },
- "regenerator-runtime": {
- "version": "0.11.1",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
- "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
- "dev": true
- },
- "regenerator-transform": {
- "version": "0.10.1",
- "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
- "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
- "dev": true,
- "requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0",
- "private": "0.1.8"
- }
- },
- "regexpu-core": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
- "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
- "dev": true,
- "requires": {
- "regenerate": "1.3.3",
- "regjsgen": "0.2.0",
- "regjsparser": "0.1.5"
- }
- },
- "regjsgen": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
- "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
- "dev": true
- },
- "regjsparser": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
- "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
- "dev": true,
- "requires": {
- "jsesc": "0.5.0"
- },
- "dependencies": {
- "jsesc": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
- "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
- "dev": true
- }
- }
- },
- "repeating": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
- "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
- "dev": true,
- "requires": {
- "is-finite": "1.0.2"
- }
- },
- "semver": {
- "version": "5.4.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
- "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
- "dev": true
- },
- "slash": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
- "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
- "dev": true
- },
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
- "dev": true
- },
- "source-map-support": {
- "version": "0.4.18",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
- "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
- "dev": true,
- "requires": {
- "source-map": "0.5.7"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "dev": true,
- "requires": {
- "ansi-regex": "2.1.1"
- }
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
- "dev": true
- },
- "to-fast-properties": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
- "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
- "dev": true
- },
- "trim-right": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
- "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
- "dev": true
- }
- }
-}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
index 8c70f5f2..9888c377 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
@@ -1,10 +1,12 @@
package com.pitchedapps.frost
+import android.content.Context
import android.os.Bundle
import ca.allanwang.kau.internal.KauBaseActivity
import com.pitchedapps.frost.activities.LoginActivity
import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.activities.SelectorActivity
+import com.pitchedapps.frost.activities.TabCustomizerActivity
import com.pitchedapps.frost.dbflow.loadFbCookiesAsync
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.utils.L
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt
index 97afd480..6ab65399 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt
@@ -2,6 +2,7 @@ package com.pitchedapps.frost.activities
import android.content.res.Configuration
import android.os.Bundle
+import android.transition.Fade
import ca.allanwang.kau.internal.KauBaseActivity
import ca.allanwang.kau.searchview.SearchViewHolder
import com.pitchedapps.frost.contracts.VideoViewHolder
@@ -28,6 +29,7 @@ abstract class BaseActivity : KauBaseActivity() {
super.onCreate(savedInstanceState)
if (this !is WebOverlayActivityBase) setFrostTheme()
}
+
//
// private var networkDisposable: Disposable? = null
// private var networkConsumer: ((Connectivity) -> Unit)? = null
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
index 57cda44a..1ba7f4c3 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
@@ -49,6 +49,7 @@ import com.pitchedapps.frost.contracts.ActivityWebContract
import com.pitchedapps.frost.contracts.FileChooserContract
import com.pitchedapps.frost.contracts.FileChooserDelegate
import com.pitchedapps.frost.contracts.VideoViewHolder
+import com.pitchedapps.frost.dbflow.TAB_COUNT
import com.pitchedapps.frost.dbflow.loadFbCookie
import com.pitchedapps.frost.dbflow.loadFbTabs
import com.pitchedapps.frost.enums.MainActivityLayout
@@ -134,7 +135,7 @@ class MainActivity : BaseActivity(),
setSupportActionBar(toolbar)
adapter = SectionsPagerAdapter(supportFragmentManager, loadFbTabs())
viewPager.adapter = adapter
- viewPager.offscreenPageLimit = 5
+ viewPager.offscreenPageLimit = TAB_COUNT
viewPager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt
index 293be694..f17ccf20 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt
@@ -37,10 +37,16 @@ class SettingsActivity : KPrefActivity(), FrostBilling by IabSettings() {
private const val REQUEST_RINGTONE = 0b10111 shl 5
const val REQUEST_NOTIFICATION_RINGTONE = REQUEST_RINGTONE or 1
const val REQUEST_MESSAGE_RINGTONE = REQUEST_RINGTONE or 2
+ const val ACTIVITY_REQUEST_TABS = 29
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (fetchRingtone(requestCode, resultCode, data)) return
+ if (requestCode == ACTIVITY_REQUEST_TABS) {
+ if (resultCode == Activity.RESULT_OK)
+ shouldRestartMain()
+ return
+ }
if (!onActivityResultBilling(requestCode, resultCode, data))
super.onActivityResult(requestCode, resultCode, data)
reloadList()
@@ -52,14 +58,22 @@ class SettingsActivity : KPrefActivity(), FrostBilling by IabSettings() {
*/
private fun fetchRingtone(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
if (requestCode and REQUEST_RINGTONE != REQUEST_RINGTONE || resultCode != Activity.RESULT_OK) return false
- val uri: String = data?.getParcelableExtra<Uri>(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)?.toString() ?: ""
+ val uri = data?.getParcelableExtra<Uri>(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)
+ val uriString: String = uri?.toString() ?: ""
+ if (uri != null) {
+ try {
+ grantUriPermission("com.android.systemui", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ } catch (e: Exception) {
+ L.e(e, "grantUriPermission")
+ }
+ }
when (requestCode) {
REQUEST_NOTIFICATION_RINGTONE -> {
- Prefs.notificationRingtone = uri
+ Prefs.notificationRingtone = uriString
reloadByTitle(R.string.notification_ringtone)
}
REQUEST_MESSAGE_RINGTONE -> {
- Prefs.messageRingtone = uri
+ Prefs.messageRingtone = uriString
reloadByTitle(R.string.message_ringtone)
}
}
@@ -106,24 +120,28 @@ class SettingsActivity : KPrefActivity(), FrostBilling by IabSettings() {
descRes = R.string.get_pro_desc
iicon = GoogleMaterial.Icon.gmd_star
visible = { !IS_FROST_PRO }
- onClick = { _, _, _ -> restorePurchases(); true }
+ onClick = { restorePurchases() }
}
plainText(R.string.about_frost) {
descRes = R.string.about_frost_desc
iicon = GoogleMaterial.Icon.gmd_info
- onClick = { _, _, _ -> startActivityForResult(AboutActivity::class.java, 9, true); true }
+ onClick = {
+ startActivityForResult(AboutActivity::class.java, 9, bundleBuilder = {
+ withSceneTransitionAnimation(this@SettingsActivity)
+ })
+ }
}
plainText(R.string.help_translate) {
descRes = R.string.help_translate_desc
iicon = GoogleMaterial.Icon.gmd_translate
- onClick = { _, _, _ -> startLink(R.string.translation_url); true }
+ onClick = { startLink(R.string.translation_url) }
}
plainText(R.string.replay_intro) {
iicon = GoogleMaterial.Icon.gmd_replay
- onClick = { _, _, _ -> launchIntroActivity(cookies()); true }
+ onClick = { launchIntroActivity(cookies()) }
}
subItems(R.string.debug_frost, getDebugPrefs()) {
@@ -138,7 +156,7 @@ class SettingsActivity : KPrefActivity(), FrostBilling by IabSettings() {
}
fun KPrefItemBase.BaseContract<*>.dependsOnPro() {
- onDisabledClick = { _, _, _ -> purchasePro(); true }
+ onDisabledClick = { purchasePro() }
enabler = { IS_FROST_PRO }
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt
new file mode 100644
index 00000000..bac352af
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt
@@ -0,0 +1,131 @@
+package com.pitchedapps.frost.activities
+
+import android.app.Activity
+import android.content.res.ColorStateList
+import android.os.Bundle
+import android.support.design.widget.FloatingActionButton
+import android.support.v7.widget.GridLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.support.v7.widget.helper.ItemTouchHelper
+import android.view.View
+import android.view.animation.AnimationUtils
+import android.widget.TextView
+import ca.allanwang.kau.kotlin.lazyContext
+import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.scaleXY
+import ca.allanwang.kau.utils.setIcon
+import ca.allanwang.kau.utils.withAlpha
+import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
+import com.mikepenz.fastadapter_extensions.drag.ItemTouchCallback
+import com.mikepenz.fastadapter_extensions.drag.SimpleDragCallback
+import com.mikepenz.google_material_typeface_library.GoogleMaterial
+import com.pitchedapps.frost.R
+import com.pitchedapps.frost.dbflow.TAB_COUNT
+import com.pitchedapps.frost.dbflow.loadFbTabs
+import com.pitchedapps.frost.dbflow.save
+import com.pitchedapps.frost.facebook.FbItem
+import com.pitchedapps.frost.iitems.TabIItem
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.setFrostColors
+import java.util.*
+
+/**
+ * Created by Allan Wang on 26/11/17.
+ */
+class TabCustomizerActivity : BaseActivity() {
+
+ val toolbar: View by bindView(R.id.pseudo_toolbar)
+ val recycler: RecyclerView by bindView(R.id.tab_recycler)
+ val instructions: TextView by bindView(R.id.instructions)
+ val divider: View by bindView(R.id.divider)
+ val adapter = FastItemAdapter<TabIItem>()
+ val fabCancel: FloatingActionButton by bindView(R.id.fab_cancel)
+ val fabSave: FloatingActionButton by bindView(R.id.fab_save)
+
+ private val wobble = lazyContext { AnimationUtils.loadAnimation(it, R.anim.rotate_delta) }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_tab_customizer)
+
+ toolbar.setBackgroundColor(Prefs.headerColor)
+
+ recycler.layoutManager = GridLayoutManager(this, TAB_COUNT, GridLayoutManager.VERTICAL, false)
+ recycler.adapter = adapter
+ recycler.setHasFixedSize(true)
+
+ divider.setBackgroundColor(Prefs.textColor.withAlpha(30))
+ instructions.setTextColor(Prefs.textColor)
+
+ val tabs = loadFbTabs().toMutableList()
+ val remaining = FbItem.values().toMutableList()
+ remaining.removeAll(tabs)
+ tabs.addAll(remaining)
+
+ adapter.add(tabs.map(::TabIItem))
+ bindSwapper(adapter, recycler)
+
+ adapter.withOnClickListener { view, _, _, _ -> view.wobble(); true }
+
+ setResult(Activity.RESULT_CANCELED)
+
+ fabSave.setIcon(GoogleMaterial.Icon.gmd_check, Prefs.iconColor)
+ fabSave.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor)
+ fabSave.setOnClickListener {
+ adapter.adapterItems.subList(0, TAB_COUNT).map(TabIItem::item).save()
+ setResult(Activity.RESULT_OK)
+ finish()
+ }
+ fabCancel.setIcon(GoogleMaterial.Icon.gmd_close, Prefs.iconColor)
+ fabCancel.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor)
+ fabCancel.setOnClickListener { finish() }
+ setFrostColors(themeWindow = true)
+ }
+
+ private fun View.wobble() = startAnimation(wobble(context))
+
+ private fun bindSwapper(adapter: FastItemAdapter<*>, recycler: RecyclerView) {
+ val dragCallback = TabDragCallback(SimpleDragCallback.ALL, swapper(adapter))
+ ItemTouchHelper(dragCallback).attachToRecyclerView(recycler)
+ }
+
+ private fun swapper(adapter: FastItemAdapter<*>) = object : ItemTouchCallback {
+ override fun itemTouchOnMove(oldPosition: Int, newPosition: Int): Boolean {
+ Collections.swap(adapter.adapterItems, oldPosition, newPosition)
+ adapter.notifyAdapterDataSetChanged()
+ return true
+ }
+
+ override fun itemTouchDropped(oldPosition: Int, newPosition: Int) = Unit
+ }
+
+
+ private class TabDragCallback(
+ directions: Int, itemTouchCallback: ItemTouchCallback
+ ) : SimpleDragCallback(directions, itemTouchCallback) {
+
+ private var draggingView: TabIItem.ViewHolder? = null
+
+ override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
+ super.onSelectedChanged(viewHolder, actionState)
+ when (actionState) {
+ ItemTouchHelper.ACTION_STATE_DRAG -> {
+ (viewHolder as? TabIItem.ViewHolder)?.apply {
+ draggingView = this
+ itemView.animate().scaleXY(1.3f)
+ text.animate().alpha(0f)
+ }
+ }
+ ItemTouchHelper.ACTION_STATE_IDLE -> {
+ draggingView?.apply {
+ itemView.animate().scaleXY(1f)
+ text.animate().alpha(1f)
+ }
+ draggingView = null
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
index ff46856c..762dd4c1 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
@@ -52,10 +52,10 @@ fun loadFbCookiesAsync(callback: (cookies: List<CookieModel>) -> Unit) {
fun loadFbCookiesSync(): List<CookieModel> = (select from CookieModel::class).orderBy(CookieModel_Table.name, true).queryList()
-fun saveFbCookie(cookie: CookieModel, callback: (() -> Unit)? = null) {
+inline fun saveFbCookie(cookie: CookieModel, crossinline callback: (() -> Unit) = {}) {
cookie.async save {
L.d("Fb cookie saved", cookie.toString())
- callback?.invoke()
+ callback()
}
}
@@ -65,7 +65,7 @@ fun removeCookie(id: Long) {
}
}
-fun CookieModel.fetchUsername(callback: (String) -> Unit) {
+inline fun CookieModel.fetchUsername(crossinline callback: (String) -> Unit) {
ReactiveNetwork.checkInternetConnectivity().subscribeOn(Schedulers.io()).subscribe { yes, _ ->
if (!yes) return@subscribe callback("")
var result = ""
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt
index 7fc56af0..18f0e2e8 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt
@@ -6,13 +6,16 @@ import com.pitchedapps.frost.utils.L
import com.raizlabs.android.dbflow.annotation.Database
import com.raizlabs.android.dbflow.annotation.PrimaryKey
import com.raizlabs.android.dbflow.annotation.Table
+import com.raizlabs.android.dbflow.kotlinextensions.database
+import com.raizlabs.android.dbflow.kotlinextensions.fastSave
import com.raizlabs.android.dbflow.kotlinextensions.from
-import com.raizlabs.android.dbflow.sql.language.SQLite
+import com.raizlabs.android.dbflow.kotlinextensions.select
import com.raizlabs.android.dbflow.structure.BaseModel
/**
* Created by Allan Wang on 2017-05-30.
*/
+const val TAB_COUNT = 4
@Database(version = FbTabsDb.VERSION)
object FbTabsDb {
@@ -23,13 +26,17 @@ object FbTabsDb {
@Table(database = FbTabsDb::class, allFields = true)
data class FbTabModel(@PrimaryKey var position: Int = -1, var tab: FbItem = FbItem.FEED) : BaseModel()
+/**
+ * Load tabs synchronously
+ * Note that tab length should never be a big number anyways
+ */
fun loadFbTabs(): List<FbItem> {
- val tabs: List<FbTabModel>? = SQLite.select().from(FbTabModel::class).orderBy(FbTabModel_Table.position, true).queryList()
- if (tabs?.isNotEmpty() ?: false) return tabs!!.map { it.tab }
- L.d("No tabs; loading default")
+ val tabs: List<FbTabModel>? = (select from (FbTabModel::class)).orderBy(FbTabModel_Table.position, true).queryList()
+ if (tabs?.size == TAB_COUNT) return tabs.map(FbTabModel::tab)
+ L.d("No tabs (${tabs?.size}); loading default")
return defaultTabs()
}
-fun List<FbItem>.saveAsync() {
- mapIndexed { index, fbTab -> FbTabModel(index, fbTab) }.replace(FbTabsDb.NAME)
+fun List<FbItem>.save() {
+ database<FbTabsDb>().beginTransactionAsync(mapIndexed(::FbTabModel).fastSave().build()).execute()
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt
index 2f478d44..27479691 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt
@@ -10,7 +10,12 @@ import com.pitchedapps.frost.web.FrostWebViewClient
import com.pitchedapps.frost.web.FrostWebViewClientMenu
import com.pitchedapps.frost.web.FrostWebViewCore
-enum class FbItem(@StringRes val titleId: Int, val icon: IIcon, relativeUrl: String, val webClient: ((webCore: FrostWebViewCore) -> FrostWebViewClient)? = null) {
+enum class FbItem(
+ @StringRes val titleId: Int,
+ val icon: IIcon,
+ relativeUrl: String,
+ val webClient: ((webCore: FrostWebViewCore) -> FrostWebViewClient)? = null
+) {
ACTIVITY_LOG(R.string.activity_log, GoogleMaterial.Icon.gmd_list, "me/allactivity"),
BIRTHDAYS(R.string.birthdays, GoogleMaterial.Icon.gmd_cake, "events/birthdays"),
CHAT(R.string.chat, GoogleMaterial.Icon.gmd_chat, "buddylist"),
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/iitems/TabIItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/iitems/TabIItem.kt
new file mode 100644
index 00000000..73d80538
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/iitems/TabIItem.kt
@@ -0,0 +1,52 @@
+package com.pitchedapps.frost.iitems
+
+import android.graphics.Color
+import android.view.View
+import android.widget.ImageView
+import android.widget.TextView
+import ca.allanwang.kau.iitems.KauIItem
+import ca.allanwang.kau.utils.*
+import com.mikepenz.fastadapter.FastAdapter
+import com.mikepenz.fastadapter.IItem
+import com.mikepenz.fastadapter_extensions.drag.IDraggable
+import com.pitchedapps.frost.R
+import com.pitchedapps.frost.facebook.FbItem
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+
+/**
+ * Created by Allan Wang on 26/11/17.
+ */
+class TabIItem(val item: FbItem) : KauIItem<TabIItem, TabIItem.ViewHolder>(
+ R.layout.iitem_tab_preview,
+ { ViewHolder(it) }
+), IDraggable<TabIItem, IItem<*, *>> {
+
+ override fun withIsDraggable(draggable: Boolean): TabIItem = this
+
+ override fun isDraggable() = true
+
+ class ViewHolder(itemView: View) : FastAdapter.ViewHolder<TabIItem>(itemView) {
+
+ val image: ImageView by bindView(R.id.image)
+ val text: TextView by bindView(R.id.text)
+
+ override fun bindView(item: TabIItem, payloads: MutableList<Any>) {
+ val isInToolbar = adapterPosition < 4
+ val color = if (isInToolbar) Prefs.iconColor else Prefs.textColor
+ image.setIcon(item.item.icon, 20, color)
+ if (isInToolbar)
+ text.invisible()
+ else {
+ text.visible().setText(item.item.titleId)
+ text.setTextColor(color.withAlpha(200))
+ }
+ }
+
+ override fun unbindView(item: TabIItem) {
+ image.setImageDrawable(null)
+ text.visible().text = null
+ }
+
+ }
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt
index 5b26ebac..de268360 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt
@@ -21,7 +21,10 @@ enum class CssHider(vararg val items: String) : InjectorContract {
NON_RECENT("article:not([data-store*=actor_name])")
;
- val injector: JsInjector by lazy { JsBuilder().css("${items.joinToString(separator = ",")}{display:none!important}").build() }
+ val injector: JsInjector by lazy {
+ JsBuilder().css("${items.joinToString(separator = ",")}{display:none !important}")
+ .single(name).build()
+ }
override fun inject(webView: WebView, callback: ((String) -> Unit)?) {
injector.inject(webView, callback)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt
index 0e46225c..beb60293 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt
@@ -19,7 +19,7 @@ enum class JsAssets : InjectorContract {
var injector = lazyContext {
try {
val content = it.assets.open("js/$file").bufferedReader().use { it.readText() }
- JsBuilder().js(singleInjector(content)).build()
+ JsBuilder().js(content).single(name).build()
} catch (e: FileNotFoundException) {
L.e(e, "JsAssets file not found")
JsInjector(JsActions.EMPTY.function)
@@ -30,12 +30,4 @@ enum class JsAssets : InjectorContract {
injector(webView.context).inject(webView, callback)
}
- private fun singleInjector(content: String) = StringBuilder().apply {
- val name = "_frost_$name"
- append("if (!window.hasOwnProperty(\"$name\")) {")
- append("console.log(\"Registering $name\");")
- append("window.$name = true;")
- append(content)
- append("}")
- }.toString()
}
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 a29ff55e..4fed2db9 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
@@ -7,11 +7,14 @@ import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.subjects.SingleSubject
import org.apache.commons.text.StringEscapeUtils
+import java.util.*
class JsBuilder {
private val css = StringBuilder()
private val js = StringBuilder()
+ private var tag: String? = null
+
fun css(css: String): JsBuilder {
this.css.append(StringEscapeUtils.escapeEcmaScript(css))
return this
@@ -22,6 +25,11 @@ class JsBuilder {
return this
}
+ fun single(tag: String): JsBuilder {
+ this.tag = tag
+ return this
+ }
+
fun build() = JsInjector(toString())
override fun toString(): String {
@@ -32,8 +40,19 @@ class JsBuilder {
}
if (js.isNotBlank())
builder.append(js)
- return builder.append("}()").toString()
+ var content = builder.append("}()").toString()
+ if (tag != null) content = singleInjector(tag!!, content)
+ return content
}
+
+ private fun singleInjector(tag: String, content: String) = StringBuilder().apply {
+ val name = "_frost_${tag.toLowerCase(Locale.CANADA)}"
+ append("if (!window.hasOwnProperty(\"$name\")) {")
+ append("console.log(\"Registering $name\");")
+ append("window.$name = true;")
+ append(content)
+ append("}")
+ }.toString()
}
/**
@@ -72,4 +91,4 @@ class JsInjector(val function: String) : InjectorContract {
override fun inject(webView: WebView, callback: ((String) -> Unit)?) {
webView.evaluateJavascript(function, { value -> callback?.invoke(value) })
}
-}
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt
index 382b2dad..2c229830 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt
@@ -23,7 +23,7 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
header(R.string.theme_customization)
text(R.string.theme, { Prefs.theme }, { Prefs.theme = it }) {
- onClick = { _, _, item ->
+ onClick = {
materialDialogThemed {
title(R.string.theme)
items(Theme.values()
@@ -46,7 +46,6 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
true
}
}
- true
}
textGetter = {
string(Theme(it).textRes)
@@ -55,12 +54,12 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
fun KPrefColorPicker.KPrefColorContract.dependsOnCustom() {
enabler = { Prefs.isCustomTheme }
- onDisabledClick = { _, _, _ -> frostSnackbar(R.string.requires_custom_theme); true }
+ onDisabledClick = { frostSnackbar(R.string.requires_custom_theme) }
allowCustom = true
}
fun invalidateCustomTheme() {
- CssAssets.CUSTOM.injector = null
+ CssAssets.CUSTOM.injector.invalidate()
}
colorPicker(R.string.text_color, { Prefs.customTextColor }, {
@@ -119,9 +118,9 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
text(R.string.main_activity_layout, { Prefs.mainActivityLayoutType }, { Prefs.mainActivityLayoutType = it }) {
textGetter = { string(Prefs.mainActivityLayout.titleRes) }
- onClick = { _, _, item ->
+ onClick = {
materialDialogThemed {
- title(R.string.set_main_activity_layout)
+ title(R.string.main_activity_layout_desc)
items(MainActivityLayout.values.map { string(it.titleRes) })
itemsCallbackSingleChoice(item.pref) { _, _, which, _ ->
if (item.pref != which) {
@@ -132,10 +131,14 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
true
}
}
- true
}
}
+ plainText(R.string.main_tabs) {
+ descRes = R.string.main_tabs_desc
+ onClick = { launchTabCustomizerActivity() }
+ }
+
checkbox(R.string.rounded_icons, { Prefs.showRoundedIcons }, {
Prefs.showRoundedIcons = it
setFrostResult(MainActivity.REQUEST_REFRESH)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt
index fc008765..60397158 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt
@@ -36,7 +36,7 @@ fun SettingsActivity.getDebugPrefs(): KPrefAdapterBuilder.() -> Unit = {
Debugger.values().forEach {
plainText(it.data.titleId) {
iicon = it.data.icon
- onClick = { itemView, _, _ -> it.debug(itemView.context); true }
+ onClick = { it.debug(itemView.context) }
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
index aad2fe9a..ed011af9 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
@@ -39,10 +39,9 @@ fun SettingsActivity.getExperimentalPrefs(): KPrefAdapterBuilder.() -> Unit = {
plainText(R.string.restart_frost) {
descRes = R.string.restart_frost_desc
- onClick = { _, _, _ ->
+ onClick = {
setFrostResult(MainActivity.REQUEST_RESTART_APPLICATION)
finish()
- true
}
}
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt
index e3a0872a..2a0f913c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt
@@ -7,7 +7,6 @@ import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.activities.SettingsActivity
import com.pitchedapps.frost.enums.FeedSort
import com.pitchedapps.frost.utils.Prefs
-import com.pitchedapps.frost.utils.launchWebOverlay
import com.pitchedapps.frost.utils.materialDialogThemed
/**
@@ -17,7 +16,7 @@ fun SettingsActivity.getFeedPrefs(): KPrefAdapterBuilder.() -> Unit = {
text(R.string.newsfeed_sort, { Prefs.feedSort }, { Prefs.feedSort = it }) {
descRes = R.string.newsfeed_sort_desc
- onClick = { _, _, item ->
+ onClick = {
materialDialogThemed {
title(R.string.newsfeed_sort)
items(FeedSort.values().map { string(it.textRes) })
@@ -29,7 +28,6 @@ fun SettingsActivity.getFeedPrefs(): KPrefAdapterBuilder.() -> Unit = {
true
})
}
- true
}
textGetter = { string(FeedSort(it).textRes) }
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt
index f46517ac..4bd41802 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt
@@ -25,7 +25,7 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
text(R.string.notification_frequency, { Prefs.notificationFreq }, { Prefs.notificationFreq = it }) {
val options = longArrayOf(-1, 15, 30, 60, 120, 180, 300, 1440, 2880)
val texts = options.map { if (it <= 0) string(R.string.no_notifications) else minuteToText(it) }
- onClick = { _, _, item ->
+ onClick = {
materialDialogThemed {
title(R.string.notification_frequency)
items(texts)
@@ -35,14 +35,13 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
true
})
}
- true
}
textGetter = { minuteToText(it) }
}
plainText(R.string.notification_keywords) {
descRes = R.string.notification_keywords_desc
- onClick = { _, _, _ ->
+ onClick = {
val keywordView = Keywords(this@getNotificationPrefs)
materialDialogThemed {
title(R.string.notification_keywords)
@@ -50,7 +49,6 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
dismissListener { keywordView.save() }
positiveText(R.string.kau_done)
}
- true
}
}
@@ -76,7 +74,7 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
else RingtoneManager.getRingtone(this@getNotificationPrefs, Uri.parse(it))
?.getTitle(this@getNotificationPrefs) ?: "---" //todo figure out why this happens
}
- onClick = { _, _, item ->
+ onClick = {
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER).apply {
putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, string(R.string.select_ringtone))
putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false)
@@ -86,7 +84,6 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, Uri.parse(item.pref))
}
startActivityForResult(intent, code)
- true
}
}
@@ -104,10 +101,9 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
plainText(R.string.notification_fetch_now) {
descRes = R.string.notification_fetch_now_desc
- onClick = { _, _, _ ->
+ onClick = {
val text = if (fetchNotifications()) R.string.notification_fetch_success else R.string.notification_fetch_fail
frostSnackbar(text)
- true
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt
index e6db8eee..2c638dfd 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt
@@ -9,14 +9,12 @@ import android.webkit.URLUtil
import ca.allanwang.kau.permissions.PERMISSION_WRITE_EXTERNAL_STORAGE
import ca.allanwang.kau.permissions.kauRequestPermissions
import ca.allanwang.kau.utils.isAppEnabled
+import ca.allanwang.kau.utils.showAppInfo
import ca.allanwang.kau.utils.string
+import ca.allanwang.kau.utils.toast
import com.pitchedapps.frost.R
import com.pitchedapps.frost.dbflow.loadFbCookie
import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
-import android.support.v4.content.ContextCompat.startActivity
-import android.content.Intent
-import android.content.ActivityNotFoundException
-import ca.allanwang.kau.utils.showAppInfo
/**
@@ -40,8 +38,10 @@ fun Context.frostDownload(uri: Uri?,
contentLength: Long = 0L) {
uri ?: return
L.d("Received download request", "Download $uri")
- if (uri.scheme != "http" && uri.scheme != "https")
- return L.e("Invalid download attempt", uri.toString())
+ if (uri.scheme != "http" && uri.scheme != "https") {
+ toast(R.string.error_invalid_download)
+ return L.e(string(R.string.error_invalid_download), uri.toString())
+ }
if (!isAppEnabled(DOWNLOAD_MANAGER_PACKAGE)) {
materialDialogThemed {
title(R.string.no_download_manager)
@@ -66,7 +66,12 @@ fun Context.frostDownload(uri: Uri?,
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "Frost/$title")
val dm = getSystemService(DOWNLOAD_SERVICE) as DownloadManager
- dm.enqueue(request)
+ try {
+ dm.enqueue(request)
+ } catch (e: Exception) {
+ toast(R.string.error_generic)
+ L.e(e, "Download")
+ }
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
index d8fa2ce9..ccc4033c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
@@ -10,6 +10,7 @@ import android.net.Uri
import android.support.annotation.StringRes
import android.support.design.internal.SnackbarContentLayout
import android.support.design.widget.Snackbar
+import android.support.v4.app.ActivityOptionsCompat
import android.support.v7.widget.Toolbar
import android.view.View
import android.widget.FrameLayout
@@ -80,13 +81,24 @@ fun Context.launchWebOverlay(url: String, clazz: Class<out WebOverlayActivityBas
})
}
+private fun Context.fadeBundle() = ActivityOptionsCompat.makeCustomAnimation(this,
+ android.R.anim.fade_in, android.R.anim.fade_out).toBundle()
+
fun Context.launchImageActivity(imageUrl: String, text: String?) {
startActivity(ImageActivity::class.java, intentBuilder = {
+ putExtras(fadeBundle())
putExtra(ARG_IMAGE_URL, imageUrl)
putExtra(ARG_TEXT, text)
})
}
+fun Activity.launchTabCustomizerActivity() {
+ startActivityForResult(TabCustomizerActivity::class.java,
+ SettingsActivity.ACTIVITY_REQUEST_TABS, bundleBuilder = {
+ with(fadeBundle())
+ })
+}
+
fun Activity.launchIntroActivity(cookieList: ArrayList<CookieModel>)
= launchNewTask(IntroActivity::class.java, cookieList, true)
diff --git a/app/src/main/res/anim/rotate_delta.xml b/app/src/main/res/anim/rotate_delta.xml
new file mode 100644
index 00000000..99837e95
--- /dev/null
+++ b/app/src/main/res/anim/rotate_delta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<rotate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:duration="100"
+ android:fromDegrees="-5"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:repeatCount="3"
+ android:repeatMode="reverse"
+ android:toDegrees="5" /> \ No newline at end of file
diff --git a/app/src/main/res/layout/activity_tab_customizer.xml b/app/src/main/res/layout/activity_tab_customizer.xml
new file mode 100644
index 00000000..b72bb953
--- /dev/null
+++ b/app/src/main/res/layout/activity_tab_customizer.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <View
+ android:id="@+id/pseudo_toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:elevation="0dp" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <android.support.v7.widget.RecyclerView
+ android:id="@+id/tab_recycler"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <View
+ android:id="@+id/divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dp" />
+
+ <TextView
+ android:id="@+id/instructions"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="@dimen/kau_padding_normal"
+ android:text="@string/tab_customizer_instructions"
+ android:textAlignment="center" />
+
+ </LinearLayout>
+
+ <android.support.design.widget.FloatingActionButton
+ android:id="@+id/fab_cancel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="start|bottom"
+ android:layout_margin="@dimen/kau_fab_margin" />
+
+ <android.support.design.widget.FloatingActionButton
+ android:id="@+id/fab_save"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end|bottom"
+ android:layout_margin="@dimen/kau_fab_margin" />
+
+</FrameLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/iitem_tab_preview.xml b/app/src/main/res/layout/iitem_tab_preview.xml
new file mode 100644
index 00000000..15e2ee7d
--- /dev/null
+++ b/app/src/main/res/layout/iitem_tab_preview.xml
@@ -0,0 +1,23 @@
+<?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:orientation="vertical"
+ android:padding="@dimen/kau_padding_normal">
+
+ <ImageView
+ android:id="@+id/image"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:contentDescription=""
+ android:scaleType="center" />
+
+ <TextView
+ android:id="@+id/text"
+ style="@style/TextAppearance.AppCompat.Caption"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/kau_padding_small"
+ android:textAlignment="center" />
+
+</LinearLayout>
diff --git a/app/src/main/res/layout/view_badged_icon.xml b/app/src/main/res/layout/view_badged_icon.xml
index c64e7809..4c6ca190 100644
--- a/app/src/main/res/layout/view_badged_icon.xml
+++ b/app/src/main/res/layout/view_badged_icon.xml
@@ -26,8 +26,8 @@
<ImageView
android:id="@+id/badge_image"
- android:layout_width="20dp"
- android:layout_height="20dp"
+ android:layout_width="@dimen/badge_icon_size"
+ android:layout_height="@dimen/badge_icon_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toLeftOf="parent"
diff --git a/app/src/main/res/values-de-rDE/strings_pref_appearance.xml b/app/src/main/res/values-de-rDE/strings_pref_appearance.xml
index 33204db3..ecb4d6dc 100644
--- a/app/src/main/res/values-de-rDE/strings_pref_appearance.xml
+++ b/app/src/main/res/values-de-rDE/strings_pref_appearance.xml
@@ -10,7 +10,7 @@
<string name="icon_color">Symbol Farbe</string>
<string name="global_customization">Globale Anpassung</string>
<string name="main_activity_layout">Haupt-Aktivitäten Layout</string>
- <string name="set_main_activity_layout">Setzte das Haupt-Aktivitäten Layout</string>
+ <string name="main_activity_layout_desc">Setzte das Haupt-Aktivitäten Layout</string>
<string name="rounded_icons">Runde Symbole</string>
<string name="rounded_icons_desc">Profilfotos und Gruppengespräch Symbole werden abgerundet</string>
<string name="tint_nav">Färbe Navigationsbar</string>
diff --git a/app/src/main/res/values-es-rES/strings_pref_appearance.xml b/app/src/main/res/values-es-rES/strings_pref_appearance.xml
index 8357f202..3603772c 100644
--- a/app/src/main/res/values-es-rES/strings_pref_appearance.xml
+++ b/app/src/main/res/values-es-rES/strings_pref_appearance.xml
@@ -10,7 +10,7 @@
<string name="icon_color">Color del icono</string>
<string name="global_customization">Personalización Global</string>
<string name="main_activity_layout">Diseño de la Pantalla Principal</string>
- <string name="set_main_activity_layout">Establecer Diseño de la Pantalla Principal</string>
+ <string name="main_activity_layout_desc">Establecer Diseño de la Pantalla Principal</string>
<string name="rounded_icons">Iconos redondeados</string>
<string name="rounded_icons_desc">Los iconos de conversación de grupo y fotos de perfil se redondearán</string>
<string name="tint_nav">Colorear Barra de Navegación</string>
diff --git a/app/src/main/res/values-fr-rFR/strings_pref_appearance.xml b/app/src/main/res/values-fr-rFR/strings_pref_appearance.xml
index e23a8457..5e128669 100644
--- a/app/src/main/res/values-fr-rFR/strings_pref_appearance.xml
+++ b/app/src/main/res/values-fr-rFR/strings_pref_appearance.xml
@@ -10,7 +10,7 @@
<string name="icon_color">Couleur d\'icône</string>
<string name="global_customization">Personnalisation globale</string>
<string name="main_activity_layout">Disposition de l\'activité principale</string>
- <string name="set_main_activity_layout">Régler la disposition de l\'activité principale</string>
+ <string name="main_activity_layout_desc">Régler la disposition de l\'activité principale</string>
<string name="rounded_icons">Icônes rondes</string>
<string name="rounded_icons_desc">Les photos de profil et les icônes de conversation de groupe seront arrondis</string>
<string name="tint_nav">Teinter la barre de navigation</string>
diff --git a/app/src/main/res/values-gl-rES/strings_pref_appearance.xml b/app/src/main/res/values-gl-rES/strings_pref_appearance.xml
index 0086a57f..752ff415 100644
--- a/app/src/main/res/values-gl-rES/strings_pref_appearance.xml
+++ b/app/src/main/res/values-gl-rES/strings_pref_appearance.xml
@@ -10,7 +10,7 @@
<string name="icon_color">Cor das iconas</string>
<string name="global_customization">Personalización xeral</string>
<string name="main_activity_layout">Deseño da pantalla principal</string>
- <string name="set_main_activity_layout">Define o deseño da pantalla principal</string>
+ <string name="main_activity_layout_desc">Define o deseño da pantalla principal</string>
<string name="rounded_icons">Iconas arredondadas</string>
<string name="rounded_icons_desc">As fotos dos perfís e as iconas de conversas en grupo serán redondas</string>
<string name="tint_nav">Cor da barra de navegación</string>
diff --git a/app/src/main/res/values-it-rIT/strings_pref_appearance.xml b/app/src/main/res/values-it-rIT/strings_pref_appearance.xml
index e86fd73a..1204257a 100644
--- a/app/src/main/res/values-it-rIT/strings_pref_appearance.xml
+++ b/app/src/main/res/values-it-rIT/strings_pref_appearance.xml
@@ -10,7 +10,7 @@
<string name="icon_color">Colore dell\'Icona</string>
<string name="global_customization">Personalizzazione Globale</string>
<string name="main_activity_layout">Layout Pagina Principale</string>
- <string name="set_main_activity_layout">Imposta Layout</string>
+ <string name="main_activity_layout_desc">Imposta Layout</string>
<string name="rounded_icons">Icone Arrotondate</string>
<string name="rounded_icons_desc">Le immagini profilo e le conversazioni di gruppo saranno arrotondate</string>
<string name="tint_nav">Barra di Navigazione in tinta</string>
diff --git a/app/src/main/res/values-ko-rKR/strings_pref_appearance.xml b/app/src/main/res/values-ko-rKR/strings_pref_appearance.xml
index dbb3ada7..b1b51c78 100644
--- a/app/src/main/res/values-ko-rKR/strings_pref_appearance.xml
+++ b/app/src/main/res/values-ko-rKR/strings_pref_appearance.xml
@@ -10,7 +10,7 @@
<string name="icon_color">아이콘 색상</string>
<string name="global_customization">전역 사용자 지정</string>
<string name="main_activity_layout">주 액티비티 구성</string>
- <string name="set_main_activity_layout">주 액티비티 구성으로 설정</string>
+ <string name="main_activity_layout_desc">주 액티비티 구성으로 설정</string>
<string name="rounded_icons">원형 아이콘</string>
<string name="rounded_icons_desc">프로필 사진과 그룹 대화 아이콘이 둥글어 집니다.</string>
<string name="tint_nav">내비게이션 바 색상</string>
diff --git a/app/src/main/res/values-pl-rPL/strings_pref_appearance.xml b/app/src/main/res/values-pl-rPL/strings_pref_appearance.xml
index 23d04210..6e950ddd 100644
--- a/app/src/main/res/values-pl-rPL/strings_pref_appearance.xml
+++ b/app/src/main/res/values-pl-rPL/strings_pref_appearance.xml
@@ -10,7 +10,7 @@
<string name="icon_color">Kolor ikon</string>
<string name="global_customization">Ogólne dostosowanie</string>
<string name="main_activity_layout">Układ aktywności</string>
- <string name="set_main_activity_layout">Ustaw układ aktywności</string>
+ <string name="main_activity_layout_desc">Ustaw układ aktywności</string>
<string name="rounded_icons">Okrągłe ikony</string>
<string name="rounded_icons_desc">Zdjęcia profilowe i ikony konwersacji grupowych zostaną zaokrąglone</string>
<string name="tint_nav">Koloruj pasek nawigacji</string>
diff --git a/app/src/main/res/values-pt-rBR/strings_pref_appearance.xml b/app/src/main/res/values-pt-rBR/strings_pref_appearance.xml
index a18c18d1..8a987481 100644
--- a/app/src/main/res/values-pt-rBR/strings_pref_appearance.xml
+++ b/app/src/main/res/values-pt-rBR/strings_pref_appearance.xml
@@ -10,7 +10,7 @@
<string name="icon_color">Cor dos ícones</string>
<string name="global_customization">Personalização geral</string>
<string name="main_activity_layout">Layout da atividade principal</string>
- <string name="set_main_activity_layout">Definir o layout das abas principais</string>
+ <string name="main_activity_layout_desc">Definir o layout das abas principais</string>
<string name="rounded_icons">Ícones Arredondados</string>
<string name="rounded_icons_desc">Fotos de perfil e ícones de conversas em grupo serão arredondados</string>
<string name="tint_nav">Cor da Barra de Navegação</string>
diff --git a/app/src/main/res/values-vi-rVN/strings_pref_appearance.xml b/app/src/main/res/values-vi-rVN/strings_pref_appearance.xml
index d479a0dc..3cbc484e 100644
--- a/app/src/main/res/values-vi-rVN/strings_pref_appearance.xml
+++ b/app/src/main/res/values-vi-rVN/strings_pref_appearance.xml
@@ -10,7 +10,7 @@
<string name="icon_color">Màu biểu tượng</string>
<string name="global_customization">Tuỳ chỉnh chung</string>
<string name="main_activity_layout">Giao diện màn hình chính</string>
- <string name="set_main_activity_layout">Đặt giao diện màn hình chính</string>
+ <string name="main_activity_layout_desc">Đặt giao diện màn hình chính</string>
<string name="rounded_icons">Làm tròn biểu tượng</string>
<string name="rounded_icons_desc">Ảnh đại diện và biểu tượng hội thoại nhóm sẽ được làm tròn</string>
<string name="tint_nav">Đổi màu thanh điều hướng</string>
diff --git a/app/src/main/res/values-zh-rCN/strings_pref_appearance.xml b/app/src/main/res/values-zh-rCN/strings_pref_appearance.xml
index 9c52e86e..cdb3015a 100644
--- a/app/src/main/res/values-zh-rCN/strings_pref_appearance.xml
+++ b/app/src/main/res/values-zh-rCN/strings_pref_appearance.xml
@@ -10,7 +10,7 @@
<string name="icon_color">图标颜色</string>
<string name="global_customization">全局定制</string>
<string name="main_activity_layout">主要活动布局</string>
- <string name="set_main_activity_layout">设置主要活动布局</string>
+ <string name="main_activity_layout_desc">设置主要活动布局</string>
<string name="rounded_icons">圆形图标</string>
<string name="rounded_icons_desc">圆形图标说明</string>
<string name="tint_nav">淡色导航栏</string>
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 888340e9..3d03888e 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -7,4 +7,5 @@
<dimen name="tab_bar_height">50dp</dimen>
<dimen name="intro_bar_height">64dp</dimen>
+ <dimen name="badge_icon_size">20dp</dimen>
</resources>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e1d3c530..540ee0da 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -54,5 +54,8 @@
<string name="bottom_bar">Bottom Bar</string>
<string name="pip" translatable="false">PIP</string>
+ <string name="preview">Preview</string>
+ <string name="options">Options</string>
+ <string name="tab_customizer_instructions">Long press and drag to rearrange the top icons.</string>
</resources>
diff --git a/app/src/main/res/values/strings_download.xml b/app/src/main/res/values/strings_download.xml
index c0cb8cd4..5a1e3fa7 100644
--- a/app/src/main/res/values/strings_download.xml
+++ b/app/src/main/res/values/strings_download.xml
@@ -11,4 +11,6 @@
<string name="downloaded_video">Video Downloaded</string>
<string name="downloading_file">Downloading File</string>
<string name="downloaded_file">File Downloaded</string>
+
+ <string name="error_invalid_download">Invalid download attempt</string>
</resources> \ No newline at end of file
diff --git a/app/src/main/res/values/strings_errors.xml b/app/src/main/res/values/strings_errors.xml
index 88428652..173ed58e 100644
--- a/app/src/main/res/values/strings_errors.xml
+++ b/app/src/main/res/values/strings_errors.xml
@@ -6,4 +6,5 @@
<string name="invalid_share_url_desc">You have shared a block of text that is not a url. The text has been copied to your clipboard, so you may share it manually yourself.</string>
<string name="no_download_manager">No Download Manager</string>
<string name="no_download_manager_desc">The download manager is not enabled. Would you like to enable it to allow downloads?</string>
+ <string name="error_generic">An error occurred.</string>
</resources> \ No newline at end of file
diff --git a/app/src/main/res/values/strings_pref_appearance.xml b/app/src/main/res/values/strings_pref_appearance.xml
index f2e0f9e0..a179b096 100644
--- a/app/src/main/res/values/strings_pref_appearance.xml
+++ b/app/src/main/res/values/strings_pref_appearance.xml
@@ -13,7 +13,10 @@
<string name="global_customization">Global Customization</string>
<string name="main_activity_layout">Main Activity Layout</string>
- <string name="set_main_activity_layout">Set Main Activity Layout</string>
+ <string name="main_activity_layout_desc">Set Main Activity Layout</string>
+
+ <string name="main_tabs">Main Activity Tabs</string>
+ <string name="main_tabs_desc">Customize which tabs you\'ll see in your main activity</string>
<string name="rounded_icons">Rounded Icons</string>
<string name="rounded_icons_desc">Profile photos and group conversation icons will be rounded</string>
diff --git a/app/src/main/res/values/strings_pref_notifications.xml b/app/src/main/res/values/strings_pref_notifications.xml
index 61c8c598..49665f8e 100644
--- a/app/src/main/res/values/strings_pref_notifications.xml
+++ b/app/src/main/res/values/strings_pref_notifications.xml
@@ -22,7 +22,7 @@
<string name="notification_ringtone">Notification Ringtone</string>
<string name="message_ringtone">Message Ringtone</string>
- <string name="select_ringtone">Selet Ringtone</string>
+ <string name="select_ringtone">Select Ringtone</string>
<string name="notification_vibrate">Notification vibration</string>
<string name="notification_lights">Notification lights</string>
diff --git a/gradle.properties b/gradle.properties
index cfed8d27..723f2cd3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -15,22 +15,23 @@ APP_ID=Frost
APP_GROUP=com.pitchedapps
MIN_SDK=21
TARGET_SDK=27
-BUILD_TOOLS=27.0.1
+BUILD_TOOLS=27.0.2
-KAU=3.5.1
+KAU=6f24f23
KOTLIN=1.2.0
COMMONS_TEXT=1.1
CRASHLYTICS=2.8.0
DBFLOW=4.1.2
EXOMEDIA=4.0.3
+FAST_ADAPTER_EXTENSIONS=3.0.3
IAB=1.0.44
IICON_COMMUNITY=2.0.46.1
-IICON_MATERIAL=2.2.0.3
-JSOUP=1.11.1
+IICON_MATERIAL=2.2.0.4
+JSOUP=1.11.2
LEAK_CANARY=1.5.4
MATERIAL_DRAWER_KT=1.2.2
-OKHTTP=3.9.0
+OKHTTP=3.9.1
PAPER_PARCEL=2.0.4
ROBOELECTRIC=3.4
RX_ANDROID=2.0.1
@@ -43,6 +44,4 @@ SLIDING_PANEL=3.4.0
JUNIT=4.12
TEST_RULE=0.5
-TEST_RUNNER=1.0.0
-
-#android.enableAapt2=false \ No newline at end of file
+TEST_RUNNER=1.0.0 \ No newline at end of file