aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/build.gradle2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt53
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt31
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt84
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt19
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt148
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt47
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt84
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt76
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt120
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt76
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt22
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt54
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt29
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt82
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/contracts/DynamicUiContract.kt20
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt35
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt21
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostObservables.kt19
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostThemable.kt25
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/contracts/VideoViewHolder.kt17
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt79
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/dbflow/DbUtils.kt19
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/dbflow/NotificationDb.kt45
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/debugger/OfflineWebsite.kt65
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/enums/MainActivityLayout.kt39
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/enums/OverlayContext.kt25
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/enums/Support.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt106
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt27
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt32
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt24
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbRegex.kt17
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt46
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt29
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt98
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt94
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt37
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt61
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.kt49
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.kt137
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.kt26
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.kt32
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt93
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt27
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt17
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt34
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragments.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/glide/GlideUtils.kt30
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/glide/RoundCornerTransformation.kt36
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/iitems/GenericIItems.kt53
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/iitems/MenuIItem.kt41
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/iitems/NotificationIItem.kt62
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/iitems/TabIItem.kt29
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt48
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt33
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt21
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt19
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt34
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt25
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt52
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt23
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/rx/RxFlyweight.kt25
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt196
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt50
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt55
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/services/NotificationUtils.kt69
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/services/UpdateReceiver.kt19
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt41
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt22
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt40
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt19
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Network.kt24
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt72
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/AnimatedVectorDelegate.kt62
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/BuildUtils.kt21
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt43
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/EnumUtils.kt25
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/JsoupCleaner.kt22
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt20
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt20
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Showcase.kt17
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt143
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/WebContextMenu.kt22
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt69
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/BadgedIcon.kt44
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt91
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt29
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt37
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt54
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/FrostViewPager.kt43
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt31
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/KPrefTextSeekbar.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/Keywords.kt35
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt48
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt35
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt44
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt34
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt38
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt84
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt36
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/NestedWebView.kt46
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/MiscTest.kt32
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt27
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/facebook/FbDomTest.kt19
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRegexTest.kt22
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/facebook/FbUrlTest.kt38
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt22
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbFullImageTest.kt18
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbRequestTest.kt22
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/injectors/InjectorTest.kt16
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt20
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/rx/ResettableFlyweightTest.kt20
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/utils/BuildUtilsTest.kt18
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/utils/JsoupCleanerTest.kt24
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/utils/PrefsTest.kt18
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/utils/StringEscapeUtilsTest.kt18
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/utils/UrlTests.kt44
-rw-r--r--build.gradle1
-rw-r--r--gradle.properties3
-rw-r--r--spotless.gradle11
-rw-r--r--spotless.license.kt16
128 files changed, 3870 insertions, 1354 deletions
diff --git a/app/build.gradle b/app/build.gradle
index 2c7c5bcc..1b8feda7 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -6,6 +6,8 @@ apply plugin: 'kotlin-kapt'
apply plugin: 'com.getkeepsafe.dexcount'
apply plugin: 'com.gladed.androidgitversion'
+apply from: '../spotless.gradle'
+
android {
compileSdkVersion kau.targetSdk
buildToolsVersion kau.buildTools
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
index c566aa05..7f3d6b62 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost
import android.app.Activity
@@ -21,7 +37,11 @@ import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.glide.GlideApp
import com.pitchedapps.frost.services.scheduleNotifications
import com.pitchedapps.frost.services.setupNotificationChannels
-import com.pitchedapps.frost.utils.*
+import com.pitchedapps.frost.utils.BuildUtils
+import com.pitchedapps.frost.utils.FrostPglAdBlock
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.Showcase
import com.raizlabs.android.dbflow.config.DatabaseConfig
import com.raizlabs.android.dbflow.config.FlowConfig
import com.raizlabs.android.dbflow.config.FlowManager
@@ -30,10 +50,9 @@ import io.reactivex.exceptions.UndeliverableException
import io.reactivex.plugins.RxJavaPlugins
import java.net.SocketTimeoutException
import java.net.UnknownHostException
-import java.util.*
+import java.util.Random
import kotlin.reflect.KClass
-
/**
* Created by Allan Wang on 2017-05-28.
*/
@@ -46,10 +65,12 @@ class FrostApp : Application() {
// lateinit var refWatcher: RefWatcher
private fun FlowConfig.Builder.withDatabase(name: String, klass: KClass<*>) =
- addDatabaseConfig(DatabaseConfig.builder(klass.java)
- .databaseName(name)
- .modelNotifier(ContentResolverNotifier("${BuildConfig.APPLICATION_ID}.dbflow.provider"))
- .build())
+ addDatabaseConfig(
+ DatabaseConfig.builder(klass.java)
+ .databaseName(name)
+ .modelNotifier(ContentResolverNotifier("${BuildConfig.APPLICATION_ID}.dbflow.provider"))
+ .build()
+ )
override fun onCreate() {
if (!buildIsLollipopAndUp) { // not supported
@@ -57,11 +78,13 @@ class FrostApp : Application() {
return
}
- FlowManager.init(FlowConfig.Builder(this)
+ FlowManager.init(
+ FlowConfig.Builder(this)
.withDatabase(CookiesDb.NAME, CookiesDb::class)
.withDatabase(FbTabsDb.NAME, FbTabsDb::class)
.withDatabase(NotificationDb.NAME, NotificationDb::class)
- .build())
+ .build()
+ )
Showcase.initialize(this, "${BuildConfig.APPLICATION_ID}.showcase")
Prefs.initialize(this, "${BuildConfig.APPLICATION_ID}.prefs")
// if (LeakCanary.isInAnalyzerProcess(this)) return
@@ -95,9 +118,11 @@ class FrostApp : Application() {
val c = imageView.context
val request = GlideApp.with(c)
val old = request.load(uri).apply(RequestOptions().placeholder(placeholder))
- request.load(uri).apply(RequestOptions()
- .signature(ApplicationVersionSignature.obtain(c)))
- .thumbnail(old).into(imageView)
+ request.load(uri).apply(
+ RequestOptions()
+ .signature(ApplicationVersionSignature.obtain(c))
+ )
+ .thumbnail(old).into(imageView)
}
})
if (BuildConfig.DEBUG)
@@ -127,7 +152,6 @@ class FrostApp : Application() {
L.e(it) { "RxJava error" }
}
}
-
}
private fun initBugsnag() {
@@ -136,7 +160,7 @@ class FrostApp : Application() {
Bugsnag.disableExceptionHandler()
if (!BuildConfig.APPLICATION_ID.startsWith("com.pitchedapps.frost")) return
val version = BuildUtils.match(BuildConfig.VERSION_NAME)
- ?: return L.d { "Bugsnag disabled for ${BuildConfig.VERSION_NAME}" }
+ ?: return L.d { "Bugsnag disabled for ${BuildConfig.VERSION_NAME}" }
Bugsnag.enableExceptionHandler()
Bugsnag.setNotifyReleaseStages(*BuildUtils.getAllStages())
Bugsnag.setAppVersion(version.versionName)
@@ -157,5 +181,4 @@ class FrostApp : Application() {
}
}
}
-
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
index 034dabe2..14cc579f 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost
import android.content.Intent
@@ -21,7 +37,8 @@ import com.pitchedapps.frost.utils.EXTRA_COOKIES
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.launchNewTask
-import java.util.*
+import java.util.ArrayList
+import java.util.IllegalFormatException
/**
* Created by Allan Wang on 2017-05-28.
@@ -46,7 +63,8 @@ class StartActivity : KauBaseActivity() {
if (Prefs.userId != -1L)
startActivity<MainActivity>(intentBuilder = {
putParcelableArrayListExtra(EXTRA_COOKIES, cookies)
- flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or
+ Intent.FLAG_ACTIVITY_SINGLE_TOP
})
else
launchNewTask<SelectorActivity>(cookies)
@@ -57,11 +75,10 @@ class StartActivity : KauBaseActivity() {
} catch (e: Exception) {
showInvalidWebView()
}
-
}
private fun showInvalidWebView() =
- showInvalidView(R.string.error_webview)
+ showInvalidView(R.string.error_webview)
private fun showInvalidSdkView() {
val text = try {
@@ -73,12 +90,12 @@ class StartActivity : KauBaseActivity() {
}
private fun showInvalidView(textRes: Int) =
- showInvalidView(string(textRes))
+ showInvalidView(string(textRes))
private fun showInvalidView(text: String) {
setContentView(R.layout.activity_invalid)
findViewById<ImageView>(R.id.invalid_icon)
- .setIcon(GoogleMaterial.Icon.gmd_adb, -1, Color.WHITE)
+ .setIcon(GoogleMaterial.Icon.gmd_adb, -1, Color.WHITE)
findViewById<TextView>(R.id.invalid_text).text = text
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt
index 4d333099..a110071c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt
@@ -1,17 +1,40 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.activities
-import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.constraintlayout.widget.ConstraintSet
-import androidx.recyclerview.widget.RecyclerView
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.about.AboutActivityBase
import ca.allanwang.kau.about.LibraryIItem
import ca.allanwang.kau.adapters.FastItemThemedAdapter
import ca.allanwang.kau.adapters.ThemableIItem
import ca.allanwang.kau.adapters.ThemableIItemDelegate
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.dimenPixelSize
+import ca.allanwang.kau.utils.resolveDrawable
+import ca.allanwang.kau.utils.startLink
+import ca.allanwang.kau.utils.string
+import ca.allanwang.kau.utils.toDrawable
+import ca.allanwang.kau.utils.toast
+import ca.allanwang.kau.utils.withMinAlpha
import com.mikepenz.aboutlibraries.Libs
import com.mikepenz.aboutlibraries.entity.Library
import com.mikepenz.aboutlibraries.entity.License
@@ -25,7 +48,6 @@ import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
-
/**
* Created by Allan Wang on 2017-06-26.
*/
@@ -42,21 +64,21 @@ class AboutActivity : AboutActivityBase(null, {
override fun getLibraries(libs: Libs): List<Library> {
val include = arrayOf(
- "AboutLibraries",
- "AndroidIconics",
- "androidin_appbillingv3",
- "androidslidinguppanel",
- "Crashlytics",
- "dbflow",
- "fastadapter",
- "glide",
- "Jsoup",
- "kau",
- "kotterknife",
- "materialdialogs",
- "materialdrawer",
- "rxjava",
- "subsamplingscaleimageview"
+ "AboutLibraries",
+ "AndroidIconics",
+ "androidin_appbillingv3",
+ "androidslidinguppanel",
+ "Crashlytics",
+ "dbflow",
+ "fastadapter",
+ "glide",
+ "Jsoup",
+ "kau",
+ "kotterknife",
+ "materialdialogs",
+ "materialdrawer",
+ "rxjava",
+ "subsamplingscaleimageview"
)
val l = libs.prepareLibraries(this, include, null, false, true, true)
@@ -136,11 +158,11 @@ class AboutActivity : AboutActivityBase(null, {
val c = itemView.context
val size = c.dimenPixelSize(R.dimen.kau_avatar_bounds)
images = arrayOf<Pair<IIcon, () -> Unit>>(
- GoogleMaterial.Icon.gmd_arrow_downward to { c.startLink(R.string.github_downloads_url) },
- CommunityMaterial.Icon2.cmd_reddit to { c.startLink(R.string.reddit_url) },
- CommunityMaterial.Icon.cmd_github_circle to { c.startLink(R.string.github_url) },
- CommunityMaterial.Icon2.cmd_slack to { c.startLink(R.string.slack_url) },
- CommunityMaterial.Icon2.cmd_xda to { c.startLink(R.string.xda_url) }
+ GoogleMaterial.Icon.gmd_arrow_downward to { c.startLink(R.string.github_downloads_url) },
+ CommunityMaterial.Icon2.cmd_reddit to { c.startLink(R.string.reddit_url) },
+ CommunityMaterial.Icon.cmd_github_circle to { c.startLink(R.string.github_url) },
+ CommunityMaterial.Icon2.cmd_slack to { c.startLink(R.string.slack_url) },
+ CommunityMaterial.Icon2.cmd_xda to { c.startLink(R.string.xda_url) }
).mapIndexed { i, (icon, onClick) ->
ImageView(c).apply {
layoutParams = ViewGroup.LayoutParams(size, size)
@@ -154,10 +176,16 @@ class AboutActivity : AboutActivityBase(null, {
}
val set = ConstraintSet()
set.clone(container)
- set.createHorizontalChain(ConstraintSet.PARENT_ID, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT,
- images.map { it.id }.toIntArray(), null, ConstraintSet.CHAIN_SPREAD_INSIDE)
+ set.createHorizontalChain(ConstraintSet.PARENT_ID,
+ ConstraintSet.LEFT,
+ ConstraintSet.PARENT_ID,
+ ConstraintSet.RIGHT,
+ images.map { it.id }.toIntArray(),
+ null,
+ ConstraintSet.CHAIN_SPREAD_INSIDE
+ )
set.applyTo(container)
}
}
}
-} \ No newline at end of file
+}
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 3ac8c6ce..08b5ab0c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.activities
import android.content.res.Configuration
@@ -80,7 +96,6 @@ abstract class BaseActivity : KauBaseActivity() {
//// disposeNetworkConnectivity()
// }
-
override fun onStop() {
if (this is VideoViewHolder) videoOnStop()
super.onStop()
@@ -90,4 +105,4 @@ abstract class BaseActivity : KauBaseActivity() {
super.onConfigurationChanged(newConfig)
if (this is VideoViewHolder) videoViewer?.updateLocation()
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
index 8f6bbacb..20b5727f 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.activities
import android.annotation.SuppressLint
@@ -8,25 +24,31 @@ import android.graphics.PointF
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Bundle
-import androidx.annotation.StringRes
-import com.google.android.material.appbar.AppBarLayout
-import androidx.coordinatorlayout.widget.CoordinatorLayout
-import com.google.android.material.floatingactionbutton.FloatingActionButton
-import com.google.android.material.tabs.TabLayout
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentPagerAdapter
-import androidx.appcompat.widget.Toolbar
import android.view.Menu
import android.view.MenuItem
import android.webkit.ValueCallback
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.widget.FrameLayout
+import androidx.annotation.StringRes
+import androidx.appcompat.widget.Toolbar
+import androidx.coordinatorlayout.widget.CoordinatorLayout
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentPagerAdapter
import ca.allanwang.kau.searchview.SearchItem
import ca.allanwang.kau.searchview.SearchView
import ca.allanwang.kau.searchview.SearchViewHolder
import ca.allanwang.kau.searchview.bindSearchView
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.fadeScaleTransition
+import ca.allanwang.kau.utils.restart
+import ca.allanwang.kau.utils.setIcon
+import ca.allanwang.kau.utils.setMenuIcons
+import ca.allanwang.kau.utils.showIf
+import ca.allanwang.kau.utils.string
+import ca.allanwang.kau.utils.tint
+import ca.allanwang.kau.utils.toast
+import ca.allanwang.kau.utils.withMinAlpha
import co.zsmb.materialdrawerkt.builders.Builder
import co.zsmb.materialdrawerkt.builders.accountHeader
import co.zsmb.materialdrawerkt.builders.drawer
@@ -35,6 +57,9 @@ import co.zsmb.materialdrawerkt.draweritems.badgeable.secondaryItem
import co.zsmb.materialdrawerkt.draweritems.divider
import co.zsmb.materialdrawerkt.draweritems.profile.profile
import co.zsmb.materialdrawerkt.draweritems.profile.profileSetting
+import com.google.android.material.appbar.AppBarLayout
+import com.google.android.material.floatingactionbutton.FloatingActionButton
+import com.google.android.material.tabs.TabLayout
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.IIcon
@@ -57,7 +82,26 @@ import com.pitchedapps.frost.facebook.parsers.SearchParser
import com.pitchedapps.frost.facebook.profilePictureUrl
import com.pitchedapps.frost.fragments.BaseFragment
import com.pitchedapps.frost.fragments.WebFragment
-import com.pitchedapps.frost.utils.*
+import com.pitchedapps.frost.utils.ACTIVITY_SETTINGS
+import com.pitchedapps.frost.utils.EXTRA_COOKIES
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.MAIN_TIMEOUT_DURATION
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.REQUEST_NAV
+import com.pitchedapps.frost.utils.REQUEST_REFRESH
+import com.pitchedapps.frost.utils.REQUEST_RESTART
+import com.pitchedapps.frost.utils.REQUEST_RESTART_APPLICATION
+import com.pitchedapps.frost.utils.REQUEST_SEARCH
+import com.pitchedapps.frost.utils.REQUEST_TEXT_ZOOM
+import com.pitchedapps.frost.utils.cookies
+import com.pitchedapps.frost.utils.frostChangelog
+import com.pitchedapps.frost.utils.frostEvent
+import com.pitchedapps.frost.utils.frostNavigationBar
+import com.pitchedapps.frost.utils.launchLogin
+import com.pitchedapps.frost.utils.launchNewTask
+import com.pitchedapps.frost.utils.launchWebOverlay
+import com.pitchedapps.frost.utils.materialDialogThemed
+import com.pitchedapps.frost.utils.setFrostColors
import com.pitchedapps.frost.views.BadgedIcon
import com.pitchedapps.frost.views.FrostVideoViewer
import com.pitchedapps.frost.views.FrostViewPager
@@ -68,8 +112,8 @@ import com.pitchedapps.frost.views.FrostViewPager
* Most of the logic that is unrelated to handling fragments
*/
abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
- FileChooserContract by FileChooserDelegate(),
- VideoViewHolder, SearchViewHolder {
+ FileChooserContract by FileChooserDelegate(),
+ VideoViewHolder, SearchViewHolder {
protected lateinit var adapter: SectionsPagerAdapter
override val frameWrapper: FrameLayout by bindView(R.id.frame_wrapper)
@@ -111,12 +155,14 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
Prefs.versionCode = BuildConfig.VERSION_CODE
if (!BuildConfig.DEBUG) {
frostChangelog()
- frostEvent("Version",
- "Version code" to BuildConfig.VERSION_CODE,
- "Prev version code" to Prefs.prevVersionCode,
- "Version name" to BuildConfig.VERSION_NAME,
- "Build type" to BuildConfig.BUILD_TYPE,
- "Frost id" to Prefs.frostId)
+ frostEvent(
+ "Version",
+ "Version code" to BuildConfig.VERSION_CODE,
+ "Prev version code" to Prefs.prevVersionCode,
+ "Version name" to BuildConfig.VERSION_NAME,
+ "Build type" to BuildConfig.BUILD_TYPE,
+ "Frost id" to Prefs.frostId
+ )
}
}
setupDrawer(savedInstanceState)
@@ -204,7 +250,9 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
identifier = -2L
}
profileSetting(nameRes = R.string.kau_add_account) {
- iconDrawable = IconicsDrawable(this@BaseMainActivity, GoogleMaterial.Icon.gmd_add).actionBar().paddingDp(5).color(Prefs.textColor)
+ iconDrawable =
+ IconicsDrawable(this@BaseMainActivity, GoogleMaterial.Icon.gmd_add).actionBar().paddingDp(5)
+ .color(Prefs.textColor)
textColor = Prefs.textColor.toLong()
identifier = -3L
}
@@ -225,8 +273,12 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
} else {
materialDialogThemed {
title(R.string.kau_logout)
- content(String.format(string(R.string.kau_logout_confirm_as_x), currentCookie.name
- ?: Prefs.userId.toString()))
+ content(
+ String.format(
+ string(R.string.kau_logout_confirm_as_x), currentCookie.name
+ ?: Prefs.userId.toString()
+ )
+ )
positiveText(R.string.kau_yes)
negativeText(R.string.kau_no)
onPositive { _, _ -> FbCookie.logout(this@BaseMainActivity) }
@@ -295,9 +347,11 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
toolbar.tint(Prefs.iconColor)
- setMenuIcons(menu, Prefs.iconColor,
- R.id.action_settings to GoogleMaterial.Icon.gmd_settings,
- R.id.action_search to GoogleMaterial.Icon.gmd_search)
+ setMenuIcons(
+ menu, Prefs.iconColor,
+ R.id.action_settings to GoogleMaterial.Icon.gmd_settings,
+ R.id.action_search to GoogleMaterial.Icon.gmd_search
+ )
searchViewBindIfNull {
bindSearchView(menu, R.id.action_search, Prefs.iconColor) {
textCallback = { query, searchView ->
@@ -309,7 +363,13 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
if (data != null) {
val items = data.mapTo(mutableListOf(), FrostSearch::toSearchItem)
if (items.isNotEmpty())
- items.add(SearchItem("${FbItem._SEARCH.url}?q=$query", string(R.string.show_all_results), iicon = null))
+ items.add(
+ SearchItem(
+ "${FbItem._SEARCH.url}?q=$query",
+ string(R.string.show_all_results),
+ iicon = null
+ )
+ )
searchViewCache[query] = items
searchView.results = items
}
@@ -332,7 +392,8 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
R.id.action_settings -> {
val intent = Intent(this, SettingsActivity::class.java)
intent.putParcelableArrayListExtra(EXTRA_COOKIES, cookies())
- val bundle = ActivityOptions.makeCustomAnimation(this, R.anim.kau_slide_in_right, R.anim.kau_fade_out).toBundle()
+ val bundle =
+ ActivityOptions.makeCustomAnimation(this, R.anim.kau_slide_in_right, R.anim.kau_fade_out).toBundle()
startActivityForResult(intent, ACTIVITY_SETTINGS, bundle)
}
else -> return super.onOptionsItemSelected(item)
@@ -340,7 +401,10 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
return true
}
- override fun openFileChooser(filePathCallback: ValueCallback<Array<Uri>?>, fileChooserParams: WebChromeClient.FileChooserParams) {
+ override fun openFileChooser(
+ filePathCallback: ValueCallback<Array<Uri>?>,
+ fileChooserParams: WebChromeClient.FileChooserParams
+ ) {
openMediaPicker(filePathCallback, fileChooserParams)
}
@@ -377,8 +441,10 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
adapter.forcedFallbacks.clear()
- adapter.forcedFallbacks.addAll(savedInstanceState.getStringArrayList(STATE_FORCE_FALLBACK)
- ?: emptyList())
+ adapter.forcedFallbacks.addAll(
+ savedInstanceState.getStringArrayList(STATE_FORCE_FALLBACK)
+ ?: emptyList()
+ )
}
override fun onResume() {
@@ -444,10 +510,12 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
override fun getItem(position: Int): Fragment {
val item = pages[position]
- return BaseFragment(item.fragmentCreator,
- forcedFallbacks.contains(item.name),
- item,
- position)
+ return BaseFragment(
+ item.fragmentCreator,
+ forcedFallbacks.contains(item.name),
+ item,
+ position
+ )
}
override fun getCount() = pages.size
@@ -455,12 +523,12 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
override fun getPageTitle(position: Int): CharSequence = getString(pages[position].titleId)
override fun getItemPosition(fragment: Any) =
- if (fragment !is BaseFragment)
- POSITION_UNCHANGED
- else if (fragment is WebFragment || fragment.valid)
- POSITION_UNCHANGED
- else
- POSITION_NONE
+ if (fragment !is BaseFragment)
+ POSITION_UNCHANGED
+ else if (fragment is WebFragment || fragment.valid)
+ POSITION_UNCHANGED
+ else
+ POSITION_NONE
}
override val lowerVideoPadding: PointF
@@ -469,4 +537,4 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
PointF(0f, toolbar.height.toFloat())
else
PointF(0f, 0f)
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt
index 3acbf7b3..6257e6f1 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.activities
import android.app.Activity
@@ -9,9 +25,9 @@ import ca.allanwang.kau.internal.KauBaseActivity
import ca.allanwang.kau.utils.setIcon
import ca.allanwang.kau.utils.visible
import com.mikepenz.google_material_typeface_library.GoogleMaterial
+import com.pitchedapps.frost.R
import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.injectors.JsActions
-import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.createFreshDir
@@ -73,23 +89,22 @@ class DebugActivity : KauBaseActivity() {
val body = it[1] as? String
screenshot to body
}.observeOn(AndroidSchedulers.mainThread())
- .subscribe { (screenshot, body), err ->
- if (err != null) {
- L.e { "DebugActivity error ${err.message}" }
- setResult(Activity.RESULT_CANCELED)
- finish()
- return@subscribe
- }
- val intent = Intent()
- intent.putExtra(RESULT_URL, debug_webview.url)
- intent.putExtra(RESULT_SCREENSHOT, screenshot)
- if (body != null)
- intent.putExtra(RESULT_BODY, body)
- setResult(Activity.RESULT_OK, intent)
+ .subscribe { (screenshot, body), err ->
+ if (err != null) {
+ L.e { "DebugActivity error ${err.message}" }
+ setResult(Activity.RESULT_CANCELED)
finish()
+ return@subscribe
}
+ val intent = Intent()
+ intent.putExtra(RESULT_URL, debug_webview.url)
+ intent.putExtra(RESULT_SCREENSHOT, screenshot)
+ if (body != null)
+ intent.putExtra(RESULT_BODY, body)
+ setResult(Activity.RESULT_OK, intent)
+ finish()
+ }
}
-
}
override fun onSupportNavigateUp(): Boolean {
@@ -113,4 +128,4 @@ class DebugActivity : KauBaseActivity() {
else
super.onBackPressed()
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt
index 348b36b9..83f617ba 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.activities
import android.content.Intent
@@ -5,16 +21,25 @@ import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
import android.os.Environment
-import com.google.android.material.floatingactionbutton.FloatingActionButton
import android.view.View
import ca.allanwang.kau.internal.KauBaseActivity
import ca.allanwang.kau.logging.KauLoggerExtension
import ca.allanwang.kau.mediapicker.scanMedia
import ca.allanwang.kau.permissions.PERMISSION_WRITE_EXTERNAL_STORAGE
import ca.allanwang.kau.permissions.kauRequestPermissions
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.colorToForeground
+import ca.allanwang.kau.utils.fadeOut
+import ca.allanwang.kau.utils.fadeScaleTransition
+import ca.allanwang.kau.utils.isHidden
+import ca.allanwang.kau.utils.scaleXY
+import ca.allanwang.kau.utils.setIcon
+import ca.allanwang.kau.utils.tint
+import ca.allanwang.kau.utils.use
+import ca.allanwang.kau.utils.withAlpha
+import ca.allanwang.kau.utils.withMinAlpha
import com.davemorrissey.labs.subscaleview.ImageSource
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
+import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.mikepenz.iconics.typeface.IIcon
import com.pitchedapps.frost.R
@@ -23,7 +48,19 @@ import com.pitchedapps.frost.facebook.get
import com.pitchedapps.frost.facebook.requests.call
import com.pitchedapps.frost.facebook.requests.getFullSizedImageUrl
import com.pitchedapps.frost.facebook.requests.requestBuilder
-import com.pitchedapps.frost.utils.*
+import com.pitchedapps.frost.utils.ARG_COOKIE
+import com.pitchedapps.frost.utils.ARG_IMAGE_URL
+import com.pitchedapps.frost.utils.ARG_TEXT
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.createFreshFile
+import com.pitchedapps.frost.utils.frostSnackbar
+import com.pitchedapps.frost.utils.frostUriFromFile
+import com.pitchedapps.frost.utils.isIndirectImageUrl
+import com.pitchedapps.frost.utils.logFrostEvent
+import com.pitchedapps.frost.utils.materialDialogThemed
+import com.pitchedapps.frost.utils.sendFrostEmail
+import com.pitchedapps.frost.utils.setFrostColors
import com.sothree.slidinguppanel.SlidingUpPanelLayout
import kotlinx.android.synthetic.main.activity_image.*
import okhttp3.Response
@@ -34,7 +71,8 @@ import java.io.File
import java.io.FileFilter
import java.io.IOException
import java.text.SimpleDateFormat
-import java.util.*
+import java.util.Date
+import java.util.Locale
/**
* Created by Allan Wang on 2017-07-15.
@@ -94,8 +132,10 @@ class ImageActivity : KauBaseActivity() {
// a unique image identifier based on the id (if it exists), and its hash
private val imageHash: String by lazy {
- "${Math.abs(FB_IMAGE_ID_MATCHER.find(imageUrl)[1]?.hashCode()
- ?: 0)}_${Math.abs(imageUrl.hashCode())}"
+ "${Math.abs(
+ FB_IMAGE_ID_MATCHER.find(imageUrl)[1]?.hashCode()
+ ?: 0
+ )}_${Math.abs(imageUrl.hashCode())}"
}
override fun onCreate(savedInstanceState: Bundle?) {
@@ -105,11 +145,15 @@ class ImageActivity : KauBaseActivity() {
L.v { "Displaying image $imageUrl" }
val layout = if (!imageText.isNullOrBlank()) R.layout.activity_image else R.layout.activity_image_textless
setContentView(layout)
- image_container.setBackgroundColor(if (Prefs.blackMediaBg) Color.BLACK
- else Prefs.bgColor.withMinAlpha(222))
+ image_container.setBackgroundColor(
+ if (Prefs.blackMediaBg) Color.BLACK
+ else Prefs.bgColor.withMinAlpha(222)
+ )
image_text?.setTextColor(if (Prefs.blackMediaBg) Color.WHITE else Prefs.textColor)
- image_text?.setBackgroundColor((if (Prefs.blackMediaBg) Color.BLACK else Prefs.bgColor)
- .colorToForeground(0.2f).withAlpha(255))
+ image_text?.setBackgroundColor(
+ (if (Prefs.blackMediaBg) Color.BLACK else Prefs.bgColor)
+ .colorToForeground(0.2f).withAlpha(255)
+ )
image_text?.text = imageText
image_progress.tint(if (Prefs.blackMediaBg) Color.WHITE else Prefs.accentColor)
image_panel?.addPanelSlideListener(object : SlidingUpPanelLayout.SimplePanelSlideListener() {
@@ -208,16 +252,15 @@ class ImageActivity : KauBaseActivity() {
}
private fun getImageResponse(): Response = cookie.requestBuilder()
- .url(trueImageUrl)
- .get()
- .call()
- .execute()
-
+ .url(trueImageUrl)
+ .get()
+ .call()
+ .execute()
@Throws(IOException::class)
private fun downloadImageTo(file: File) {
val body = getImageResponse().body()
- ?: throw IOException("Failed to retrieve image body")
+ ?: throw IOException("Failed to retrieve image body")
body.byteStream().use { input ->
file.outputStream().use { output ->
input.copyTo(output)
@@ -272,7 +315,11 @@ class ImageActivity : KauBaseActivity() {
}
}
-internal enum class FabStates(val iicon: IIcon, val iconColor: Int = Prefs.iconColor, val backgroundTint: Int = Int.MAX_VALUE) {
+internal enum class FabStates(
+ val iicon: IIcon,
+ val iconColor: Int = Prefs.iconColor,
+ val backgroundTint: Int = Int.MAX_VALUE
+) {
ERROR(GoogleMaterial.Icon.gmd_error, Color.WHITE, Color.RED) {
override fun onClick(activity: ImageActivity) {
activity.materialDialogThemed {
@@ -334,5 +381,4 @@ internal enum class FabStates(val iicon: IIcon, val iconColor: Int = Prefs.iconC
}
abstract fun onClick(activity: ImageActivity)
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt
index c41229da..a3ab6172 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt
@@ -1,31 +1,60 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.activities
import android.animation.ValueAnimator
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentManager
-import androidx.fragment.app.FragmentPagerAdapter
-import androidx.viewpager.widget.ViewPager
import android.view.View
import android.view.WindowManager
import android.widget.Button
import android.widget.ImageButton
import android.widget.ImageView
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentManager
+import androidx.fragment.app.FragmentPagerAdapter
+import androidx.viewpager.widget.ViewPager
import ca.allanwang.kau.internal.KauBaseActivity
import ca.allanwang.kau.ui.views.RippleCanvas
import ca.allanwang.kau.ui.widgets.InkPageIndicator
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.blendWith
+import ca.allanwang.kau.utils.color
+import ca.allanwang.kau.utils.fadeScaleTransition
+import ca.allanwang.kau.utils.navigationBarColor
+import ca.allanwang.kau.utils.postDelayed
+import ca.allanwang.kau.utils.scaleXY
+import ca.allanwang.kau.utils.setIcon
+import ca.allanwang.kau.utils.statusBarColor
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.pitchedapps.frost.R
-import com.pitchedapps.frost.intro.*
+import com.pitchedapps.frost.intro.BaseIntroFragment
+import com.pitchedapps.frost.intro.IntroAccountFragment
+import com.pitchedapps.frost.intro.IntroFragmentEnd
+import com.pitchedapps.frost.intro.IntroFragmentTheme
+import com.pitchedapps.frost.intro.IntroFragmentWelcome
+import com.pitchedapps.frost.intro.IntroTabContextFragment
+import com.pitchedapps.frost.intro.IntroTabTouchFragment
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.cookies
import com.pitchedapps.frost.utils.launchNewTask
import org.jetbrains.anko.find
-
/**
* Created by Allan Wang on 2017-07-25.
*
@@ -43,12 +72,12 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On
private var barHasNext = true
val fragments = listOf(
- IntroFragmentWelcome(),
- IntroFragmentTheme(),
- IntroAccountFragment(),
- IntroTabTouchFragment(),
- IntroTabContextFragment(),
- IntroFragmentEnd()
+ IntroFragmentWelcome(),
+ IntroFragmentTheme(),
+ IntroAccountFragment(),
+ IntroTabTouchFragment(),
+ IntroTabContextFragment(),
+ IntroFragmentEnd()
)
override fun onCreate(savedInstanceState: Bundle?) {
@@ -97,7 +126,6 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On
page.alpha = 1f
page.translationX = 0f
}
-
}
fun finish(x: Float, y: Float) {
@@ -107,9 +135,11 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On
postDelayed(1000) { finish() }
}
val lastView: View? = fragments.last().view
- arrayOf<View?>(skip, indicator, next,
- lastView?.find(R.id.intro_title),
- lastView?.find(R.id.intro_desc)).forEach {
+ arrayOf<View?>(
+ skip, indicator, next,
+ lastView?.find(R.id.intro_title),
+ lastView?.find(R.id.intro_desc)
+ ).forEach {
it?.animate()?.alpha(0f)?.setDuration(600)?.start()
}
if (Prefs.textColor != Color.WHITE) {
@@ -147,7 +177,6 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On
}
override fun onPageScrollStateChanged(state: Int) {
-
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
@@ -162,16 +191,19 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On
if (barHasNext == hasNext) return
barHasNext = hasNext
next.fadeScaleTransition {
- setIcon(if (barHasNext) GoogleMaterial.Icon.gmd_navigate_next else GoogleMaterial.Icon.gmd_done, color = Prefs.textColor)
+ setIcon(
+ if (barHasNext) GoogleMaterial.Icon.gmd_navigate_next else GoogleMaterial.Icon.gmd_done,
+ color = Prefs.textColor
+ )
}
skip.animate().scaleXY(if (barHasNext) 1f else 0f)
}
- class IntroPageAdapter(fm: FragmentManager, private val fragments: List<BaseIntroFragment>) : FragmentPagerAdapter(fm) {
+ class IntroPageAdapter(fm: FragmentManager, private val fragments: List<BaseIntroFragment>) :
+ FragmentPagerAdapter(fm) {
override fun getItem(position: Int): Fragment = fragments[position]
override fun getCount(): Int = fragments.size
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
index 9c8a60aa..8b5fe38d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
@@ -1,12 +1,28 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.activities
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Handler
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+import android.widget.ImageView
import androidx.appcompat.widget.AppCompatTextView
import androidx.appcompat.widget.Toolbar
-import android.widget.ImageView
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import ca.allanwang.kau.utils.bindView
import ca.allanwang.kau.utils.fadeIn
import ca.allanwang.kau.utils.fadeOut
@@ -24,14 +40,18 @@ import com.pitchedapps.frost.facebook.profilePictureUrl
import com.pitchedapps.frost.glide.FrostGlide
import com.pitchedapps.frost.glide.GlideApp
import com.pitchedapps.frost.glide.transform
-import com.pitchedapps.frost.utils.*
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Showcase
+import com.pitchedapps.frost.utils.frostEvent
+import com.pitchedapps.frost.utils.launchNewTask
+import com.pitchedapps.frost.utils.logFrostEvent
+import com.pitchedapps.frost.utils.setFrostColors
import com.pitchedapps.frost.web.LoginWebView
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.BiFunction
import io.reactivex.subjects.SingleSubject
-
/**
* Created by Allan Wang on 2017-06-01.
*/
@@ -78,51 +98,62 @@ class LoginActivity : BaseActivity() {
private fun loadInfo(cookie: CookieModel) {
refresh = true
Single.zip<Boolean, String, Pair<Boolean, String>>(
- profileSubject,
- usernameSubject,
- BiFunction(::Pair))
- .observeOn(AndroidSchedulers.mainThread()).subscribe { (foundImage, name) ->
- refresh = false
- if (!foundImage) {
- L.e { "Could not get profile photo; Invalid userId?" }
- L._i { cookie }
- }
- textview.text = String.format(getString(R.string.welcome), name)
- textview.fadeIn()
- frostEvent("Login", "success" to true)
- /*
- * The user may have logged into an account that is already in the database
- * We will let the db handle duplicates and load it now after the new account has been saved
- */
- loadFbCookiesAsync {
- val cookies = ArrayList(it)
- Handler().postDelayed({
- if (Showcase.intro)
- launchNewTask<IntroActivity>(cookies, true)
- else
- launchNewTask<MainActivity>(cookies, true)
- }, 1000)
- }
- }.disposeOnDestroy()
+ profileSubject,
+ usernameSubject,
+ BiFunction(::Pair)
+ )
+ .observeOn(AndroidSchedulers.mainThread()).subscribe { (foundImage, name) ->
+ refresh = false
+ if (!foundImage) {
+ L.e { "Could not get profile photo; Invalid userId?" }
+ L._i { cookie }
+ }
+ textview.text = String.format(getString(R.string.welcome), name)
+ textview.fadeIn()
+ frostEvent("Login", "success" to true)
+ /*
+ * The user may have logged into an account that is already in the database
+ * We will let the db handle duplicates and load it now after the new account has been saved
+ */
+ loadFbCookiesAsync {
+ val cookies = ArrayList(it)
+ Handler().postDelayed({
+ if (Showcase.intro)
+ launchNewTask<IntroActivity>(cookies, true)
+ else
+ launchNewTask<MainActivity>(cookies, true)
+ }, 1000)
+ }
+ }.disposeOnDestroy()
loadProfile(cookie.id)
loadUsername(cookie)
}
-
private fun loadProfile(id: Long) {
profileLoader.load(profilePictureUrl(id))
- .transform(FrostGlide.roundCorner).listener(object : RequestListener<Drawable> {
- override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
- profileSubject.onSuccess(true)
- return false
- }
-
- override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
- e.logFrostEvent("Profile loading exception")
- profileSubject.onSuccess(false)
- return false
- }
- }).into(profile)
+ .transform(FrostGlide.roundCorner).listener(object : RequestListener<Drawable> {
+ override fun onResourceReady(
+ resource: Drawable?,
+ model: Any?,
+ target: Target<Drawable>?,
+ dataSource: DataSource?,
+ isFirstResource: Boolean
+ ): Boolean {
+ profileSubject.onSuccess(true)
+ return false
+ }
+
+ override fun onLoadFailed(
+ e: GlideException?,
+ model: Any?,
+ target: Target<Drawable>?,
+ isFirstResource: Boolean
+ ): Boolean {
+ e.logFrostEvent("Profile loading exception")
+ profileSubject.onSuccess(false)
+ return false
+ }
+ }).into(profile)
}
private fun loadUsername(cookie: CookieModel) {
@@ -146,5 +177,4 @@ class LoginActivity : BaseActivity() {
web.pauseTimers()
super.onPause()
}
-
-} \ No newline at end of file
+}
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 2555fe5b..d03c6496 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
@@ -1,8 +1,24 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.activities
import android.os.Bundle
-import com.google.android.material.tabs.TabLayout
import androidx.viewpager.widget.ViewPager
+import com.google.android.material.tabs.TabLayout
import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.views.BadgedIcon
import io.reactivex.android.schedulers.AndroidSchedulers
@@ -36,19 +52,19 @@ class MainActivity : BaseMainActivity() {
super.onPageScrolled(position, positionOffset, positionOffsetPixels)
val delta = positionOffset * (255 - 128).toFloat()
tabsForEachView { tabPosition, view ->
- view.setAllAlpha(when (tabPosition) {
- position -> 255.0f - delta
- position + 1 -> 128.0f + delta
- else -> 128f
- })
+ view.setAllAlpha(
+ when (tabPosition) {
+ position -> 255.0f - delta
+ position + 1 -> 128.0f + delta
+ else -> 128f
+ }
+ )
}
}
})
viewPager.post { fragmentSubject.onNext(0); lastPosition = 0 } //trigger hook so title is set
-
}
-
private fun setupTabs() {
viewPager.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabs))
tabs.addOnTabSelectedListener(object : TabLayout.ViewPagerOnTabSelectedListener(viewPager) {
@@ -63,31 +79,31 @@ class MainActivity : BaseMainActivity() {
}
})
headerBadgeObservable.throttleFirst(15, TimeUnit.SECONDS)
- .subscribeOn(Schedulers.newThread())
- .map { Jsoup.parse(it) }
- .filter { it.select("[data-sigil=count]").size >= 0 } //ensure headers exist
- .map {
- val feed = it.select("[data-sigil*=feed] [data-sigil=count]")
- val requests = it.select("[data-sigil*=requests] [data-sigil=count]")
- val messages = it.select("[data-sigil*=messages] [data-sigil=count]")
- val notifications = it.select("[data-sigil*=notifications] [data-sigil=count]")
- return@map arrayOf(feed, requests, messages, notifications).map { e -> e?.getOrNull(0)?.ownText() }
- }
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe { (feed, requests, messages, notifications) ->
- tabsForEachView { _, view ->
- when (view.iicon) {
- FbItem.FEED.icon -> view.badgeText = feed
- FbItem.FRIENDS.icon -> view.badgeText = requests
- FbItem.MESSAGES.icon -> view.badgeText = messages
- FbItem.NOTIFICATIONS.icon -> view.badgeText = notifications
- }
+ .subscribeOn(Schedulers.newThread())
+ .map { Jsoup.parse(it) }
+ .filter { it.select("[data-sigil=count]").size >= 0 } //ensure headers exist
+ .map {
+ val feed = it.select("[data-sigil*=feed] [data-sigil=count]")
+ val requests = it.select("[data-sigil*=requests] [data-sigil=count]")
+ val messages = it.select("[data-sigil*=messages] [data-sigil=count]")
+ val notifications = it.select("[data-sigil*=notifications] [data-sigil=count]")
+ return@map arrayOf(feed, requests, messages, notifications).map { e -> e?.getOrNull(0)?.ownText() }
+ }
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe { (feed, requests, messages, notifications) ->
+ tabsForEachView { _, view ->
+ when (view.iicon) {
+ FbItem.FEED.icon -> view.badgeText = feed
+ FbItem.FRIENDS.icon -> view.badgeText = requests
+ FbItem.MESSAGES.icon -> view.badgeText = messages
+ FbItem.NOTIFICATIONS.icon -> view.badgeText = notifications
}
- }.disposeOnDestroy()
+ }
+ }.disposeOnDestroy()
adapter.pages.forEach {
tabs.addTab(tabs.newTab()
- .setCustomView(BadgedIcon(this).apply { iicon = it.icon }))
+ .setCustomView(BadgedIcon(this).apply { iicon = it.icon })
+ )
}
}
-
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt
index 514af197..2907bac6 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt
@@ -1,11 +1,27 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.activities
import android.os.Bundle
-import androidx.constraintlayout.widget.ConstraintLayout
+import android.view.View
import androidx.appcompat.widget.AppCompatTextView
+import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
-import android.view.View
import ca.allanwang.kau.utils.bindView
import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
@@ -47,4 +63,4 @@ class SelectorActivity : BaseActivity() {
background(container)
}
}
-} \ No newline at end of file
+}
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 7663b70f..37047448 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.activities
import android.annotation.SuppressLint
@@ -12,14 +28,33 @@ import ca.allanwang.kau.kpref.activity.CoreAttributeContract
import ca.allanwang.kau.kpref.activity.KPrefActivity
import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
import ca.allanwang.kau.ui.views.RippleCanvas
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.finishSlideOut
+import ca.allanwang.kau.utils.setMenuIcons
+import ca.allanwang.kau.utils.startActivityForResult
+import ca.allanwang.kau.utils.startLink
+import ca.allanwang.kau.utils.string
+import ca.allanwang.kau.utils.tint
+import ca.allanwang.kau.utils.withSceneTransitionAnimation
import com.mikepenz.community_material_typeface_library.CommunityMaterial
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.pitchedapps.frost.R
import com.pitchedapps.frost.enums.Support
-import com.pitchedapps.frost.settings.*
-import com.pitchedapps.frost.utils.*
-
+import com.pitchedapps.frost.settings.getAppearancePrefs
+import com.pitchedapps.frost.settings.getBehaviourPrefs
+import com.pitchedapps.frost.settings.getDebugPrefs
+import com.pitchedapps.frost.settings.getExperimentalPrefs
+import com.pitchedapps.frost.settings.getFeedPrefs
+import com.pitchedapps.frost.settings.getNotificationPrefs
+import com.pitchedapps.frost.settings.sendDebug
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.REQUEST_RESTART
+import com.pitchedapps.frost.utils.cookies
+import com.pitchedapps.frost.utils.frostChangelog
+import com.pitchedapps.frost.utils.frostNavigationBar
+import com.pitchedapps.frost.utils.launchNewTask
+import com.pitchedapps.frost.utils.materialDialogThemed
+import com.pitchedapps.frost.utils.setFrostTheme
/**
* Created by Allan Wang on 2017-06-06.
@@ -146,7 +181,6 @@ class SettingsActivity : KPrefActivity() {
iicon = CommunityMaterial.Icon.cmd_android_debug_bridge
visible = { Prefs.debugSettings }
}
-
}
fun shouldRestartMain() {
@@ -179,9 +213,11 @@ class SettingsActivity : KPrefActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_settings, menu)
toolbar.tint(Prefs.iconColor)
- setMenuIcons(menu, Prefs.iconColor,
- R.id.action_email to GoogleMaterial.Icon.gmd_email,
- R.id.action_changelog to GoogleMaterial.Icon.gmd_info)
+ setMenuIcons(
+ menu, Prefs.iconColor,
+ R.id.action_email to GoogleMaterial.Icon.gmd_email,
+ R.id.action_changelog to GoogleMaterial.Icon.gmd_info
+ )
return true
}
@@ -201,4 +237,4 @@ class SettingsActivity : KPrefActivity() {
fun setFrostResult(flag: Int) {
resultFlag = resultFlag or flag
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt
index 6222d98f..7f632940 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.activities
import android.app.Activity
@@ -5,21 +21,18 @@ import android.content.res.ColorStateList
import android.os.Bundle
import android.view.View
import android.view.animation.AnimationUtils
-import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
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 com.pitchedapps.frost.R
import ca.allanwang.kau.utils.withAlpha
-import com.google.android.material.floatingactionbutton.FloatingActionButton
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
@@ -28,7 +41,7 @@ import com.pitchedapps.frost.iitems.TabIItem
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.setFrostColors
import kotlinx.android.synthetic.main.activity_tab_customizer.*
-import java.util.*
+import java.util.Collections
/**
* Created by Allan Wang on 26/11/17.
@@ -96,9 +109,9 @@ class TabCustomizerActivity : BaseActivity() {
override fun itemTouchDropped(oldPosition: Int, newPosition: Int) = Unit
}
-
private class TabDragCallback(
- directions: Int, itemTouchCallback: ItemTouchCallback
+ directions: Int,
+ itemTouchCallback: ItemTouchCallback
) : SimpleDragCallback(directions, itemTouchCallback) {
private var draggingView: TabIItem.ViewHolder? = null
@@ -122,7 +135,5 @@ class TabCustomizerActivity : BaseActivity() {
}
}
}
-
}
-
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt
index 6d930fff..b706d467 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.activities
import android.annotation.SuppressLint
@@ -5,25 +21,52 @@ import android.content.Intent
import android.graphics.PointF
import android.net.Uri
import android.os.Bundle
-import androidx.coordinatorlayout.widget.CoordinatorLayout
-import androidx.appcompat.widget.Toolbar
import android.view.Menu
import android.view.MenuItem
import android.webkit.ValueCallback
import android.webkit.WebChromeClient
import android.widget.FrameLayout
+import androidx.appcompat.widget.Toolbar
+import androidx.coordinatorlayout.widget.CoordinatorLayout
import ca.allanwang.kau.swipe.kauSwipeOnCreate
import ca.allanwang.kau.swipe.kauSwipeOnDestroy
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.copyToClipboard
+import ca.allanwang.kau.utils.darken
+import ca.allanwang.kau.utils.dpToPx
+import ca.allanwang.kau.utils.finishSlideOut
+import ca.allanwang.kau.utils.navigationBarColor
+import ca.allanwang.kau.utils.setMenuIcons
+import ca.allanwang.kau.utils.shareText
+import ca.allanwang.kau.utils.statusBarColor
+import ca.allanwang.kau.utils.tint
+import ca.allanwang.kau.utils.toDrawable
+import ca.allanwang.kau.utils.toast
+import ca.allanwang.kau.utils.withAlpha
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.mikepenz.community_material_typeface_library.CommunityMaterial
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.pitchedapps.frost.R
-import com.pitchedapps.frost.contracts.*
+import com.pitchedapps.frost.contracts.ActivityContract
+import com.pitchedapps.frost.contracts.FileChooserContract
+import com.pitchedapps.frost.contracts.FileChooserDelegate
+import com.pitchedapps.frost.contracts.FrostContentContainer
+import com.pitchedapps.frost.contracts.VideoViewHolder
import com.pitchedapps.frost.enums.OverlayContext
-import com.pitchedapps.frost.facebook.*
+import com.pitchedapps.frost.facebook.FB_URL_BASE
+import com.pitchedapps.frost.facebook.FbCookie
+import com.pitchedapps.frost.facebook.FbItem
+import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
+import com.pitchedapps.frost.facebook.formattedFbUrl
import com.pitchedapps.frost.services.FrostRunnable
-import com.pitchedapps.frost.utils.*
+import com.pitchedapps.frost.utils.ARG_URL
+import com.pitchedapps.frost.utils.ARG_USER_ID
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.Showcase
+import com.pitchedapps.frost.utils.frostSnackbar
+import com.pitchedapps.frost.utils.materialDialogThemed
+import com.pitchedapps.frost.utils.setFrostColors
import com.pitchedapps.frost.views.FrostContentWeb
import com.pitchedapps.frost.views.FrostVideoViewer
import com.pitchedapps.frost.views.FrostWebView
@@ -31,7 +74,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import okhttp3.HttpUrl
-
/**
* Created by Allan Wang on 2017-06-01.
*
@@ -103,8 +145,8 @@ class WebOverlayActivity : WebOverlayActivityBase(false)
@SuppressLint("Registered")
open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseActivity(),
- ActivityContract, FrostContentContainer,
- VideoViewHolder, FileChooserContract by FileChooserDelegate() {
+ ActivityContract, FrostContentContainer,
+ VideoViewHolder, FileChooserContract by FileChooserDelegate() {
override val frameWrapper: FrameLayout by bindView(R.id.frame_wrapper)
val toolbar: Toolbar by bindView(R.id.overlay_toolbar)
@@ -156,9 +198,9 @@ open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseAc
content.bind(this)
content.titleObservable
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe { toolbar.title = it }
- .disposeOnDestroy()
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe { toolbar.title = it }
+ .disposeOnDestroy()
with(web) {
if (forceBasicAgent) //todo check; the webview already adds it dynamically
@@ -235,7 +277,10 @@ open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseAc
kauSwipeOnDestroy()
}
- override fun openFileChooser(filePathCallback: ValueCallback<Array<Uri>?>, fileChooserParams: WebChromeClient.FileChooserParams) {
+ override fun openFileChooser(
+ filePathCallback: ValueCallback<Array<Uri>?>,
+ fileChooserParams: WebChromeClient.FileChooserParams
+ ) {
openMediaPicker(filePathCallback, fileChooserParams)
}
@@ -247,9 +292,11 @@ open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseAc
menuInflater.inflate(R.menu.menu_web, menu)
overlayContext?.onMenuCreate(this, menu)
toolbar.tint(Prefs.iconColor)
- setMenuIcons(menu, Prefs.iconColor,
- R.id.action_share to CommunityMaterial.Icon2.cmd_share,
- R.id.action_copy_link to GoogleMaterial.Icon.gmd_content_copy)
+ setMenuIcons(
+ menu, Prefs.iconColor,
+ R.id.action_share to CommunityMaterial.Icon2.cmd_share,
+ R.id.action_copy_link to GoogleMaterial.Icon.gmd_content_copy
+ )
return true
}
@@ -270,5 +317,4 @@ open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseAc
*/
override var videoViewer: FrostVideoViewer? = null
override val lowerVideoPadding: PointF = PointF(0f, 0f)
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt
index 1182e609..2ce83871 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.contracts
import com.mikepenz.iconics.typeface.IIcon
@@ -25,4 +41,4 @@ interface MainActivityContract : ActivityContract, MainFabContract {
interface MainFabContract {
fun showFab(iicon: IIcon, clickEvent: () -> Unit)
fun hideFab()
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/DynamicUiContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/DynamicUiContract.kt
index 303c64b3..736ef72d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/DynamicUiContract.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/DynamicUiContract.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.contracts
/**
@@ -21,10 +37,8 @@ interface DynamicUiContract {
*/
fun reloadTextSize()
-
/**
* Change text size without propagation
*/
fun reloadTextSizeSelf()
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt
index 15165456..73d5c56d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.contracts
import android.app.Activity
@@ -17,12 +33,19 @@ import com.pitchedapps.frost.utils.L
const val MEDIA_CHOOSER_RESULT = 67
interface FileChooserActivityContract {
- fun openFileChooser(filePathCallback: ValueCallback<Array<Uri>?>, fileChooserParams: WebChromeClient.FileChooserParams)
+ fun openFileChooser(
+ filePathCallback: ValueCallback<Array<Uri>?>,
+ fileChooserParams: WebChromeClient.FileChooserParams
+ )
}
interface FileChooserContract {
var filePathCallback: ValueCallback<Array<Uri>?>?
- fun Activity.openMediaPicker(filePathCallback: ValueCallback<Array<Uri>?>, fileChooserParams: WebChromeClient.FileChooserParams)
+ fun Activity.openMediaPicker(
+ filePathCallback: ValueCallback<Array<Uri>?>,
+ fileChooserParams: WebChromeClient.FileChooserParams
+ )
+
fun Activity.onActivityResultWeb(requestCode: Int, resultCode: Int, intent: Intent?): Boolean
}
@@ -30,7 +53,10 @@ class FileChooserDelegate : FileChooserContract {
override var filePathCallback: ValueCallback<Array<Uri>?>? = null
- override fun Activity.openMediaPicker(filePathCallback: ValueCallback<Array<Uri>?>, fileChooserParams: WebChromeClient.FileChooserParams) {
+ override fun Activity.openMediaPicker(
+ filePathCallback: ValueCallback<Array<Uri>?>,
+ fileChooserParams: WebChromeClient.FileChooserParams
+ ) {
kauRequestPermissions(PERMISSION_WRITE_EXTERNAL_STORAGE) { granted, _ ->
if (!granted) {
filePathCallback.onReceiveValue(null)
@@ -52,5 +78,4 @@ class FileChooserDelegate : FileChooserContract {
filePathCallback = null
return true
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt
index 613295e6..50c2fe77 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.contracts
import android.view.View
@@ -23,7 +39,6 @@ interface FrostContentContainer {
* Update toolbar title
*/
fun setTitle(title: String)
-
}
/**
@@ -84,7 +99,6 @@ interface FrostContentParent : DynamicUiContract {
* For those cases, we will return false to stop it
*/
fun registerTransition(urlChanged: Boolean, animate: Boolean): Boolean
-
}
/**
@@ -147,5 +161,4 @@ interface FrostContentCore : DynamicUiContract {
* Signal destruction to release some content manually
*/
fun destroy()
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostObservables.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostObservables.kt
index 882b67a0..b3b93b66 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostObservables.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostObservables.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.contracts
import io.reactivex.subjects.BehaviorSubject
@@ -27,5 +43,4 @@ interface FrostObservables {
other.progressObservable = progressObservable
other.titleObservable = titleObservable
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostThemable.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostThemable.kt
index 3322f62e..93d827a6 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostThemable.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostThemable.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.contracts
import android.view.View
@@ -18,12 +34,11 @@ interface FrostThemable {
fun reloadTheme()
fun setTextColors(color: Int, vararg textViews: TextView?) =
- themeViews(color, *textViews) { setTextColor(it) }
+ themeViews(color, *textViews) { setTextColor(it) }
fun setBackgrounds(color: Int, vararg views: View?) =
- themeViews(color, *views) { setBackgroundColor(it) }
+ themeViews(color, *views) { setBackgroundColor(it) }
fun <T : View> themeViews(color: Int, vararg views: T?, action: T.(Int) -> Unit) =
- views.filterNotNull().forEach { it.action(color) }
-
-} \ No newline at end of file
+ views.filterNotNull().forEach { it.action(color) }
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/VideoViewHolder.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/VideoViewHolder.kt
index 13b6a7aa..e749b0d3 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/VideoViewHolder.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/VideoViewHolder.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.contracts
import android.app.Activity
@@ -49,5 +65,4 @@ interface FrameWrapper {
setContentView(R.layout.activity_frame_wrapper)
frameWrapper.inflate(layoutRes, true)
}
-
}
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 1fe65d5a..db3bf973 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.dbflow
import android.os.Parcel
@@ -11,7 +27,13 @@ import com.raizlabs.android.dbflow.annotation.ConflictAction
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.*
+import com.raizlabs.android.dbflow.kotlinextensions.async
+import com.raizlabs.android.dbflow.kotlinextensions.delete
+import com.raizlabs.android.dbflow.kotlinextensions.eq
+import com.raizlabs.android.dbflow.kotlinextensions.from
+import com.raizlabs.android.dbflow.kotlinextensions.save
+import com.raizlabs.android.dbflow.kotlinextensions.select
+import com.raizlabs.android.dbflow.kotlinextensions.where
import com.raizlabs.android.dbflow.structure.BaseModel
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
@@ -30,7 +52,8 @@ object CookiesDb {
@PaperParcel
@Table(database = CookiesDb::class, allFields = true, primaryKeyConflict = ConflictAction.REPLACE)
-data class CookieModel(@PrimaryKey var id: Long = -1L, var name: String? = null, var cookie: String? = null) : BaseModel(), Parcelable {
+data class CookieModel(@PrimaryKey var id: Long = -1L, var name: String? = null, var cookie: String? = null) :
+ BaseModel(), Parcelable {
companion object {
@JvmField
val CREATOR = PaperParcelCookieModel.CREATOR
@@ -40,18 +63,22 @@ data class CookieModel(@PrimaryKey var id: Long = -1L, var name: String? = null,
override fun writeToParcel(dest: Parcel, flags: Int) = PaperParcelCookieModel.writeToParcel(this, dest, flags)
}
-fun loadFbCookie(id: Long): CookieModel? = (select from CookieModel::class where (CookieModel_Table.id eq id)).querySingle()
-fun loadFbCookie(name: String): CookieModel? = (select from CookieModel::class where (CookieModel_Table.name eq name)).querySingle()
+fun loadFbCookie(id: Long): CookieModel? =
+ (select from CookieModel::class where (CookieModel_Table.id eq id)).querySingle()
+
+fun loadFbCookie(name: String): CookieModel? =
+ (select from CookieModel::class where (CookieModel_Table.name eq name)).querySingle()
/**
* Loads cookies sorted by name
*/
fun loadFbCookiesAsync(callback: (cookies: List<CookieModel>) -> Unit) {
- (select from CookieModel::class).orderBy(CookieModel_Table.name, true).async().queryListResultCallback { _, tResult -> callback(tResult) }.execute()
+ (select from CookieModel::class).orderBy(CookieModel_Table.name, true).async()
+ .queryListResultCallback { _, tResult -> callback(tResult) }.execute()
}
-fun loadFbCookiesSync(): List<CookieModel> = (select from CookieModel::class).orderBy(CookieModel_Table.name, true).queryList()
-
+fun loadFbCookiesSync(): List<CookieModel> =
+ (select from CookieModel::class).orderBy(CookieModel_Table.name, true).queryList()
inline fun saveFbCookie(cookie: CookieModel, crossinline callback: (() -> Unit) = {}) {
cookie.async save {
@@ -69,24 +96,24 @@ fun removeCookie(id: Long) {
}
inline fun CookieModel.fetchUsername(crossinline callback: (String) -> Unit): Disposable =
- ReactiveNetwork.checkInternetConnectivity().subscribeOn(Schedulers.io()).subscribe { yes, _ ->
- if (!yes) return@subscribe callback("")
- var result = ""
- try {
- result = frostJsoup(cookie, FbItem.PROFILE.url).title()
- L.d { "Fetch username found" }
- } catch (e: Exception) {
- if (e !is UnknownHostException)
- e.logFrostEvent("Fetch username failed")
- } finally {
- if (result.isBlank() && (name?.isNotBlank() == true)) {
- callback(name!!)
- return@subscribe
- }
- if (name != result) {
- name = result
- saveFbCookie(this@fetchUsername)
- }
- callback(result)
+ ReactiveNetwork.checkInternetConnectivity().subscribeOn(Schedulers.io()).subscribe { yes, _ ->
+ if (!yes) return@subscribe callback("")
+ var result = ""
+ try {
+ result = frostJsoup(cookie, FbItem.PROFILE.url).title()
+ L.d { "Fetch username found" }
+ } catch (e: Exception) {
+ if (e !is UnknownHostException)
+ e.logFrostEvent("Fetch username failed")
+ } finally {
+ if (result.isBlank() && (name?.isNotBlank() == true)) {
+ callback(name!!)
+ return@subscribe
}
+ if (name != result) {
+ name = result
+ saveFbCookie(this@fetchUsername)
+ }
+ callback(result)
}
+ }
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/DbUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/DbUtils.kt
index e4aef2a9..740fef62 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/DbUtils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/DbUtils.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.dbflow
import android.content.Context
@@ -14,11 +30,10 @@ object DbUtils {
fun db(name: String) = FlowManager.getDatabase(name)
fun dbName(name: String) = "$name.db"
fun deleteDatabase(c: Context, name: String) = c.deleteDatabase(dbName(name))
-
}
inline fun <reified T : Any> List<T>.replace(dbName: String) {
L.d { "Replacing $dbName.db" }
DbUtils.db(dbName).reset()
FastStoreModelTransaction.saveBuilder(FlowManager.getModelAdapter(T::class.java)).addAll(this).build()
-} \ No newline at end of file
+}
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 827881e3..9d330169 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.dbflow
import com.pitchedapps.frost.facebook.FbItem
@@ -39,4 +55,4 @@ fun loadFbTabs(): List<FbItem> {
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/dbflow/NotificationDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/NotificationDb.kt
index b61fc218..a054d95e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/NotificationDb.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/NotificationDb.kt
@@ -1,8 +1,33 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.dbflow
import com.pitchedapps.frost.utils.L
-import com.raizlabs.android.dbflow.annotation.*
-import com.raizlabs.android.dbflow.kotlinextensions.*
+import com.raizlabs.android.dbflow.annotation.ConflictAction
+import com.raizlabs.android.dbflow.annotation.Database
+import com.raizlabs.android.dbflow.annotation.Migration
+import com.raizlabs.android.dbflow.annotation.PrimaryKey
+import com.raizlabs.android.dbflow.annotation.Table
+import com.raizlabs.android.dbflow.kotlinextensions.async
+import com.raizlabs.android.dbflow.kotlinextensions.eq
+import com.raizlabs.android.dbflow.kotlinextensions.from
+import com.raizlabs.android.dbflow.kotlinextensions.save
+import com.raizlabs.android.dbflow.kotlinextensions.select
+import com.raizlabs.android.dbflow.kotlinextensions.where
import com.raizlabs.android.dbflow.sql.SQLiteType
import com.raizlabs.android.dbflow.sql.migration.AlterTableMigration
import com.raizlabs.android.dbflow.structure.BaseModel
@@ -18,7 +43,8 @@ object NotificationDb {
}
@Migration(version = 2, database = NotificationDb::class)
-class NotificationMigration2(modelClass: Class<NotificationModel>) : AlterTableMigration<NotificationModel>(modelClass) {
+class NotificationMigration2(modelClass: Class<NotificationModel>) :
+ AlterTableMigration<NotificationModel>(modelClass) {
override fun onPreMigrate() {
super.onPreMigrate()
addColumn(SQLiteType.INTEGER, "epochIm")
@@ -27,11 +53,14 @@ class NotificationMigration2(modelClass: Class<NotificationModel>) : AlterTableM
}
@Table(database = NotificationDb::class, allFields = true, primaryKeyConflict = ConflictAction.REPLACE)
-data class NotificationModel(@PrimaryKey var id: Long = -1L,
- var epoch: Long = -1L,
- var epochIm: Long = -1L) : BaseModel()
+data class NotificationModel(
+ @PrimaryKey var id: Long = -1L,
+ var epoch: Long = -1L,
+ var epochIm: Long = -1L
+) : BaseModel()
-fun lastNotificationTime(id: Long): NotificationModel = (select from NotificationModel::class where (NotificationModel_Table.id eq id)).querySingle()
+fun lastNotificationTime(id: Long): NotificationModel =
+ (select from NotificationModel::class where (NotificationModel_Table.id eq id)).querySingle()
?: NotificationModel(id = id)
fun saveNotificationTime(notificationModel: NotificationModel, callback: (() -> Unit)? = null) {
@@ -40,4 +69,4 @@ fun saveNotificationTime(notificationModel: NotificationModel, callback: (() ->
L._d { notificationModel }
callback?.invoke()
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/debugger/OfflineWebsite.kt b/app/src/main/kotlin/com/pitchedapps/frost/debugger/OfflineWebsite.kt
index 6298f1f9..f5009cc5 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/debugger/OfflineWebsite.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/debugger/OfflineWebsite.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.debugger
import ca.allanwang.kau.logging.KauLoggerExtension
@@ -32,21 +48,23 @@ import java.util.zip.ZipOutputStream
*
* Inspired by <a href="https://github.com/JonasCz/save-for-offline">Save for Offline</a>
*/
-class OfflineWebsite(private val url: String,
- private val cookie: String = "",
- baseUrl: String? = null,
- private val html: String? = null,
- /**
- * Directory that holds all the files
- */
- val baseDir: File,
- private val userAgent: String = USER_AGENT_BASIC) {
+class OfflineWebsite(
+ private val url: String,
+ private val cookie: String = "",
+ baseUrl: String? = null,
+ private val html: String? = null,
+ /**
+ * Directory that holds all the files
+ */
+ val baseDir: File,
+ private val userAgent: String = USER_AGENT_BASIC
+) {
/**
* Supplied url without the queries
*/
private val baseUrl = (baseUrl ?: url.substringBefore("?")
- .substringBefore(".com")).trim('/')
+ .substringBefore(".com")).trim('/')
private val mainFile = File(baseDir, "index.html")
private val assetDir = File(baseDir, "assets")
@@ -67,11 +85,11 @@ class OfflineWebsite(private val url: String,
private val cssQueue = mutableSetOf<String>()
private fun request(url: String) = Request.Builder()
- .header("Cookie", cookie)
- .header("User-Agent", userAgent)
- .url(url)
- .get()
- .call()
+ .header("Cookie", cookie)
+ .header("User-Agent", userAgent)
+ .url(url)
+ .get()
+ .call()
private val compositeDisposable = CompositeDisposable()
@@ -94,7 +112,6 @@ class OfflineWebsite(private val url: String,
return callback(false)
}
-
if (!assetDir.createFreshDir()) {
L.e { "Could not create ${assetDir.absolutePath}" }
return callback(false)
@@ -245,8 +262,10 @@ class OfflineWebsite(private val url: String,
}
})
- private inline fun <T> String.downloadUrl(fallback: () -> T,
- action: (file: File, body: ResponseBody) -> T): T {
+ private inline fun <T> String.downloadUrl(
+ fallback: () -> T,
+ action: (file: File, body: ResponseBody) -> T
+ ): T {
val file = File(assetDir, fileName())
if (!file.createNewFile()) {
@@ -289,11 +308,10 @@ class OfflineWebsite(private val url: String,
if (mapped != null) return mapped
val candidate = substringBefore("?").trim('/')
- .substringAfterLast("/").shorten()
+ .substringAfterLast("/").shorten()
val index = atomicInt.getAndIncrement()
-
var newUrl = "a${index}_$candidate"
/**
@@ -308,10 +326,10 @@ class OfflineWebsite(private val url: String,
}
private fun String.shorten() =
- if (length <= 10) this else substring(length - 10)
+ if (length <= 10) this else substring(length - 10)
private fun Set<String>.clean(): List<String> =
- filter(String::isNotBlank).filter { it.startsWith("http") }
+ filter(String::isNotBlank).filter { it.startsWith("http") }
private fun reset() {
cancelled = false
@@ -326,5 +344,4 @@ class OfflineWebsite(private val url: String,
compositeDisposable.dispose()
L.v { "Request cancelled" }
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt b/app/src/main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt
index d8a0f349..7312399e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.enums
import androidx.annotation.StringRes
@@ -16,4 +32,4 @@ enum class FeedSort(@StringRes val textRes: Int, val item: FbItem) {
val values = values() //save one instance
operator fun invoke(index: Int) = values[index]
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/enums/MainActivityLayout.kt b/app/src/main/kotlin/com/pitchedapps/frost/enums/MainActivityLayout.kt
index 79b11752..2d51b032 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/enums/MainActivityLayout.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/enums/MainActivityLayout.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.enums
import com.pitchedapps.frost.R
@@ -7,23 +23,24 @@ import com.pitchedapps.frost.utils.Prefs
* Created by Allan Wang on 2017-08-19.
*/
enum class MainActivityLayout(
- val titleRes: Int,
- val layoutRes: Int,
- val backgroundColor: () -> Int,
- val iconColor: () -> Int) {
+ val titleRes: Int,
+ val layoutRes: Int,
+ val backgroundColor: () -> Int,
+ val iconColor: () -> Int
+) {
TOP_BAR(R.string.top_bar,
- R.layout.activity_main,
- { Prefs.headerColor },
- { Prefs.iconColor }),
+ R.layout.activity_main,
+ { Prefs.headerColor },
+ { Prefs.iconColor }),
BOTTOM_BAR(R.string.bottom_bar,
- R.layout.activity_main_bottom_tabs,
- { Prefs.bgColor },
- { Prefs.textColor });
+ R.layout.activity_main_bottom_tabs,
+ { Prefs.bgColor },
+ { Prefs.textColor });
companion object {
val values = values() //save one instance
operator fun invoke(index: Int) = values[index]
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/enums/OverlayContext.kt b/app/src/main/kotlin/com/pitchedapps/frost/enums/OverlayContext.kt
index f93a2229..d529db12 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/enums/OverlayContext.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/enums/OverlayContext.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.enums
import android.content.Context
@@ -52,12 +68,13 @@ enum class OverlayContext(private val menuItem: FrostMenuItem?) : EnumBundle<Ove
* Frame for an injectable menu item
*/
class FrostMenuItem(
- val id: Int,
- val fbItem: FbItem,
- val showAsAction: Int = MenuItem.SHOW_AS_ACTION_IF_ROOM) {
+ val id: Int,
+ val fbItem: FbItem,
+ val showAsAction: Int = MenuItem.SHOW_AS_ACTION_IF_ROOM
+) {
fun addToMenu(context: Context, menu: Menu, index: Int) {
val item = menu.add(Menu.NONE, id, index, fbItem.titleId)
item.icon = fbItem.icon.toDrawable(context, 18)
item.setShowAsAction(showAsAction)
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/enums/Support.kt b/app/src/main/kotlin/com/pitchedapps/frost/enums/Support.kt
index 34fa4b5f..23ea5a8f 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/enums/Support.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/enums/Support.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.enums
import android.content.Context
@@ -21,4 +37,4 @@ enum class Support(@StringRes val title: Int) {
}
}
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt b/app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt
index 934dda07..345aa88e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.enums
import android.graphics.Color
@@ -14,61 +30,63 @@ import com.pitchedapps.frost.utils.Prefs
const val FACEBOOK_BLUE = 0xff3b5998.toInt()
const val BLUE_LIGHT = 0xff5d86dd.toInt()
-enum class Theme(@StringRes val textRes: Int,
- val injector: InjectorContract,
- private val textColorGetter: () -> Int,
- private val accentColorGetter: () -> Int,
- private val backgroundColorGetter: () -> Int,
- private val headerColorGetter: () -> Int,
- private val iconColorGetter: () -> Int) {
+enum class Theme(
+ @StringRes val textRes: Int,
+ val injector: InjectorContract,
+ private val textColorGetter: () -> Int,
+ private val accentColorGetter: () -> Int,
+ private val backgroundColorGetter: () -> Int,
+ private val headerColorGetter: () -> Int,
+ private val iconColorGetter: () -> Int
+) {
DEFAULT(R.string.kau_default,
- JsActions.EMPTY,
- { 0xde000000.toInt() },
- { FACEBOOK_BLUE },
- { 0xfffafafa.toInt() },
- { FACEBOOK_BLUE },
- { Color.WHITE }),
+ JsActions.EMPTY,
+ { 0xde000000.toInt() },
+ { FACEBOOK_BLUE },
+ { 0xfffafafa.toInt() },
+ { FACEBOOK_BLUE },
+ { Color.WHITE }),
LIGHT(R.string.kau_light,
- CssAssets.MATERIAL_LIGHT,
- { 0xde000000.toInt() },
- { FACEBOOK_BLUE },
- { 0xfffafafa.toInt() },
- { FACEBOOK_BLUE },
- { Color.WHITE }),
+ CssAssets.MATERIAL_LIGHT,
+ { 0xde000000.toInt() },
+ { FACEBOOK_BLUE },
+ { 0xfffafafa.toInt() },
+ { FACEBOOK_BLUE },
+ { Color.WHITE }),
DARK(R.string.kau_dark,
- CssAssets.MATERIAL_DARK,
- { Color.WHITE },
- { BLUE_LIGHT },
- { 0xff303030.toInt() },
- { 0xff2e4b86.toInt() },
- { Color.WHITE }),
+ CssAssets.MATERIAL_DARK,
+ { Color.WHITE },
+ { BLUE_LIGHT },
+ { 0xff303030.toInt() },
+ { 0xff2e4b86.toInt() },
+ { Color.WHITE }),
AMOLED(R.string.kau_amoled,
- CssAssets.MATERIAL_AMOLED,
- { Color.WHITE },
- { BLUE_LIGHT },
- { Color.BLACK },
- { Color.BLACK },
- { Color.WHITE }),
+ CssAssets.MATERIAL_AMOLED,
+ { Color.WHITE },
+ { BLUE_LIGHT },
+ { Color.BLACK },
+ { Color.BLACK },
+ { Color.WHITE }),
GLASS(R.string.kau_glass,
- CssAssets.MATERIAL_GLASS,
- { Color.WHITE },
- { BLUE_LIGHT },
- { 0x80000000.toInt() },
- { 0xb3000000.toInt() },
- { Color.WHITE }),
+ CssAssets.MATERIAL_GLASS,
+ { Color.WHITE },
+ { BLUE_LIGHT },
+ { 0x80000000.toInt() },
+ { 0xb3000000.toInt() },
+ { Color.WHITE }),
CUSTOM(R.string.kau_custom,
- CssAssets.CUSTOM,
- { Prefs.customTextColor },
- { Prefs.customAccentColor },
- { Prefs.customBackgroundColor },
- { Prefs.customHeaderColor },
- { Prefs.customIconColor });
+ CssAssets.CUSTOM,
+ { Prefs.customTextColor },
+ { Prefs.customAccentColor },
+ { Prefs.customBackgroundColor },
+ { Prefs.customHeaderColor },
+ { Prefs.customIconColor });
val textColor: Int
get() = textColorGetter()
@@ -89,4 +107,4 @@ enum class Theme(@StringRes val textRes: Int,
val values = values() //save one instance
operator fun invoke(index: Int) = values[index]
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt
index 2b881d1c..b6207a7b 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook
/**
@@ -12,9 +28,12 @@ fun profilePictureUrl(id: Long) = "https://graph.facebook.com/$id/picture?type=l
const val FB_LOGIN_URL = "${FB_URL_BASE}login"
const val FB_HOME_URL = "${FB_URL_BASE}home.php"
-const val USER_AGENT_FULL = "Mozilla/5.0 (Linux; Android 4.4.2; en-us; SAMSUNG SM-G900T Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.6 Chrome/28.0.1500.94 Mobile Safari/537.36"
-const val USER_AGENT_BASIC_OLD = "Mozilla/5.0 (Linux; Android 6.0) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.1.0.4633 Mobile Safari/537.10+"
-const val USER_AGENT_MESSENGER = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"
+const val USER_AGENT_FULL =
+ "Mozilla/5.0 (Linux; Android 4.4.2; en-us; SAMSUNG SM-G900T Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.6 Chrome/28.0.1500.94 Mobile Safari/537.36"
+const val USER_AGENT_BASIC_OLD =
+ "Mozilla/5.0 (Linux; Android 6.0) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.1.0.4633 Mobile Safari/537.10+"
+const val USER_AGENT_MESSENGER =
+ "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"
const val USER_AGENT_BASIC = USER_AGENT_MESSENGER
/**
@@ -27,4 +46,4 @@ const val WEB_LOAD_DELAY = 50L
* Note that transitions are also called from onFinish, so this value
* will never make a load slower than it is
*/
-const val WEB_COMMIT_LOAD_DELAY = 200L \ No newline at end of file
+const val WEB_COMMIT_LOAD_DELAY = 200L
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt
index ab7e165a..c6583712 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook
import android.app.Activity
@@ -38,13 +54,13 @@ object FbCookie {
val cookies = cookie.split(";").map { Pair(it, SingleSubject.create<Boolean>()) }
cookies.forEach { (cookie, callback) -> setCookie(FB_URL_BASE, cookie) { callback.onSuccess(it) } }
Observable.zip<Boolean, Unit>(cookies.map { (_, callback) -> callback.toObservable() }) {}
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe {
- callback?.invoke()
- L.d { "Cookies set" }
- L._d { cookie }
- flush()
- }
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe {
+ callback?.invoke()
+ L.d { "Cookies set" }
+ L._d { cookie }
+ flush()
+ }
}
}
}
@@ -132,4 +148,4 @@ object FbCookie {
}
} else callback()
}
-} \ 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 2f0e4e22..723ed450 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook
import androidx.annotation.StringRes
@@ -15,10 +31,10 @@ import com.pitchedapps.frost.utils.EnumBundleCompanion
import com.pitchedapps.frost.utils.EnumCompanion
enum class FbItem(
- @StringRes val titleId: Int,
- val icon: IIcon,
- relativeUrl: String,
- val fragmentCreator: () -> BaseFragment = ::WebFragment
+ @StringRes val titleId: Int,
+ val icon: IIcon,
+ relativeUrl: String,
+ val fragmentCreator: () -> BaseFragment = ::WebFragment
) : EnumBundle<FbItem> {
ACTIVITY_LOG(R.string.activity_log, GoogleMaterial.Icon.gmd_list, "me/allactivity"),
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbRegex.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbRegex.kt
index 9b29d009..2c987a48 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbRegex.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbRegex.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook
/**
@@ -29,4 +45,3 @@ val FB_IMAGE_ID_MATCHER: Regex = Regex("fbcdn.*?/[0-9]+_([0-9]+)_")
val FB_REDIRECT_URL_MATCHER: Regex = Regex("url=(.*?fbcdn.*?)\"")
operator fun MatchResult?.get(groupIndex: Int) = this?.groupValues?.get(groupIndex)
-
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt
index 62675df6..2c171762 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook
import com.pitchedapps.frost.utils.L
@@ -91,13 +107,13 @@ class FbUrlFormatter(url: String) {
* That shouldn't break anything
*/
val discardable = arrayOf(
- "http://lm.facebook.com/l.php?u=",
- "https://lm.facebook.com/l.php?u=",
- "http://m.facebook.com/l.php?u=",
- "https://m.facebook.com/l.php?u=",
- "http://touch.facebook.com/l.php?u=",
- "https://touch.facebook.com/l.php?u=",
- VIDEO_REDIRECT
+ "http://lm.facebook.com/l.php?u=",
+ "https://lm.facebook.com/l.php?u=",
+ "http://m.facebook.com/l.php?u=",
+ "https://m.facebook.com/l.php?u=",
+ "http://touch.facebook.com/l.php?u=",
+ "https://touch.facebook.com/l.php?u=",
+ VIDEO_REDIRECT
)
/**
@@ -108,13 +124,13 @@ class FbUrlFormatter(url: String) {
val discardableQueries = arrayOf("ref", "refid", "SharedWith")
val converter = listOf(
- "\\3C " to "%3C", "\\3E " to "%3E", "\\23 " to "%23", "\\25 " to "%25",
- "\\7B " to "%7B", "\\7D " to "%7D", "\\7C " to "%7C", "\\5C " to "%5C",
- "\\5E " to "%5E", "\\7E " to "%7E", "\\5B " to "%5B", "\\5D " to "%5D",
- "\\60 " to "%60", "\\3B " to "%3B", "\\2F " to "%2F", "\\3F " to "%3F",
- "\\3A " to "%3A", "\\40 " to "%40", "\\3D " to "%3D", "\\26 " to "%26",
- "\\24 " to "%24", "\\2B " to "%2B", "\\22 " to "%22", "\\2C " to "%2C",
- "\\20 " to "%20"
+ "\\3C " to "%3C", "\\3E " to "%3E", "\\23 " to "%23", "\\25 " to "%25",
+ "\\7B " to "%7B", "\\7D " to "%7D", "\\7C " to "%7C", "\\5C " to "%5C",
+ "\\5E " to "%5E", "\\7E " to "%7E", "\\5B " to "%5B", "\\5D " to "%5D",
+ "\\60 " to "%60", "\\3B " to "%3B", "\\2F " to "%2F", "\\3F " to "%3F",
+ "\\3A " to "%3A", "\\40 " to "%40", "\\3D " to "%3D", "\\26 " to "%26",
+ "\\24 " to "%24", "\\2B " to "%2B", "\\22 " to "%22", "\\2C " to "%2C",
+ "\\20 " to "%20"
)
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt
index 3d5c5bce..5709bb9f 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.parsers
import com.pitchedapps.frost.dbflow.CookieModel
@@ -54,7 +70,6 @@ interface FrostParser<out T : Any> {
* Call parsing with given data
*/
fun parseFromData(cookie: String?, text: String): ParseResponse<T>?
-
}
const val FALLBACK_TIME_MOD = 1000000
@@ -92,7 +107,7 @@ internal abstract class FrostParserBase<out T : Any>(private val redirectToText:
}
final override fun parseFromUrl(cookie: String?, url: String): ParseResponse<T>? =
- parse(cookie, frostJsoup(cookie, url))
+ parse(cookie, frostJsoup(cookie, url))
override fun parse(cookie: String?, document: Document): ParseResponse<T>? {
cookie ?: return null
@@ -109,17 +124,17 @@ internal abstract class FrostParserBase<out T : Any>(private val redirectToText:
* Returns the formatted url, or an empty string if nothing was found
*/
protected fun Element.getInnerImgStyle(): String? =
- select("i.img[style*=url]").getStyleUrl()
+ select("i.img[style*=url]").getStyleUrl()
protected fun Elements.getStyleUrl(): String? =
- FB_CSS_URL_MATCHER.find(attr("style"))[1]?.formattedFbUrl
+ FB_CSS_URL_MATCHER.find(attr("style"))[1]?.formattedFbUrl
protected open fun textToDoc(text: String): Document? =
- if (!redirectToText) Jsoup.parse(text)
- else throw RuntimeException("${this::class.java.simpleName} requires text redirect but did not implement textToDoc")
+ if (!redirectToText) Jsoup.parse(text)
+ else throw RuntimeException("${this::class.java.simpleName} requires text redirect but did not implement textToDoc")
protected fun parseLink(element: Element?): FrostLink? {
val a = element?.getElementsByTag("a")?.first() ?: return null
return FrostLink(a.text(), a.attr("href"))
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt
index 27b731bc..f05c42e9 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt
@@ -1,7 +1,27 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.parsers
import com.pitchedapps.frost.dbflow.CookieModel
-import com.pitchedapps.frost.facebook.*
+import com.pitchedapps.frost.facebook.FB_EPOCH_MATCHER
+import com.pitchedapps.frost.facebook.FB_MESSAGE_NOTIF_ID_MATCHER
+import com.pitchedapps.frost.facebook.FbItem
+import com.pitchedapps.frost.facebook.formattedFbUrl
+import com.pitchedapps.frost.facebook.get
import com.pitchedapps.frost.services.NotificationContent
import com.pitchedapps.frost.utils.L
import org.apache.commons.text.StringEscapeUtils
@@ -19,12 +39,12 @@ import org.jsoup.nodes.Element
object MessageParser : FrostParser<FrostMessages> by MessageParserImpl() {
fun queryUser(cookie: String?, name: String) = parseFromUrl(cookie, "${FbItem.MESSAGES.url}/?q=$name")
-
}
-data class FrostMessages(val threads: List<FrostThread>,
- val seeMore: FrostLink?,
- val extraLinks: List<FrostLink>
+data class FrostMessages(
+ val threads: List<FrostThread>,
+ val seeMore: FrostLink?,
+ val extraLinks: List<FrostLink>
) : ParseNotification {
override fun toString() = StringBuilder().apply {
append("FrostMessages {\n")
@@ -35,19 +55,19 @@ data class FrostMessages(val threads: List<FrostThread>,
}.toString()
override fun getUnreadNotifications(data: CookieModel) =
- threads.asSequence().filter(FrostThread::unread).map {
- with(it) {
- NotificationContent(
- data = data,
- id = id,
- href = url,
- title = title,
- text = content ?: "",
- timestamp = time,
- profileUrl = img
- )
- }
- }.toList()
+ threads.asSequence().filter(FrostThread::unread).map {
+ with(it) {
+ NotificationContent(
+ data = data,
+ id = id,
+ href = url,
+ title = title,
+ text = content ?: "",
+ timestamp = time,
+ profileUrl = img
+ )
+ }
+ }.toList()
}
/**
@@ -58,14 +78,16 @@ data class FrostMessages(val threads: List<FrostThread>,
* [unread] true if image is unread, false otherwise
* [content] optional string for thread
*/
-data class FrostThread(val id: Long,
- val img: String?,
- val title: String,
- val time: Long,
- val url: String,
- val unread: Boolean,
- val content: String?,
- val contentImgUrl: String?)
+data class FrostThread(
+ val id: Long,
+ val img: String?,
+ val title: String,
+ val time: Long,
+ val url: String,
+ val unread: Boolean,
+ val content: String?,
+ val contentImgUrl: String?
+)
private class MessageParserImpl : FrostParserBase<FrostMessages>(true) {
@@ -92,11 +114,12 @@ private class MessageParserImpl : FrostParserBase<FrostMessages>(true) {
override fun parseImpl(doc: Document): FrostMessages? {
val threadList = doc.getElementById("threadlist_rows") ?: return null
- val threads: List<FrostThread> = threadList.getElementsByAttributeValueMatching("id", ".*${FB_MESSAGE_NOTIF_ID_MATCHER.pattern}.*")
+ val threads: List<FrostThread> =
+ threadList.getElementsByAttributeValueMatching("id", ".*${FB_MESSAGE_NOTIF_ID_MATCHER.pattern}.*")
.mapNotNull(this::parseMessage)
val seeMore = parseLink(doc.getElementById("see_older_threads"))
val extraLinks = threadList.nextElementSibling().select("a")
- .mapNotNull(this::parseLink)
+ .mapNotNull(this::parseLink)
return FrostMessages(threads, seeMore, extraLinks)
}
@@ -106,21 +129,20 @@ private class MessageParserImpl : FrostParserBase<FrostMessages>(true) {
val epoch = FB_EPOCH_MATCHER.find(abbr.attr("data-store"))[1]?.toLongOrNull() ?: -1L
//fetch id
val id = FB_MESSAGE_NOTIF_ID_MATCHER.find(element.id())[1]?.toLongOrNull()
- ?: System.currentTimeMillis() % FALLBACK_TIME_MOD
+ ?: System.currentTimeMillis() % FALLBACK_TIME_MOD
val snippet = element.select("span.snippet").firstOrNull()
val content = snippet?.text()?.trim()
val contentImg = snippet?.select("i[style*=url]")?.getStyleUrl()
val img = element.getInnerImgStyle()
return FrostThread(
- id = id,
- img = img,
- title = a.text(),
- time = epoch,
- url = a.attr("href").formattedFbUrl,
- unread = !element.hasClass("acw"),
- content = content,
- contentImgUrl = contentImg
+ id = id,
+ img = img,
+ title = a.text(),
+ time = epoch,
+ url = a.attr("href").formattedFbUrl,
+ unread = !element.hasClass("acw"),
+ content = content,
+ contentImgUrl = contentImg
)
}
-
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt
index 8aa8e706..b8aa899b 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt
@@ -1,7 +1,27 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.parsers
import com.pitchedapps.frost.dbflow.CookieModel
-import com.pitchedapps.frost.facebook.*
+import com.pitchedapps.frost.facebook.FB_EPOCH_MATCHER
+import com.pitchedapps.frost.facebook.FB_NOTIF_ID_MATCHER
+import com.pitchedapps.frost.facebook.FbItem
+import com.pitchedapps.frost.facebook.formattedFbUrl
+import com.pitchedapps.frost.facebook.get
import com.pitchedapps.frost.services.NotificationContent
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
@@ -13,8 +33,8 @@ import org.jsoup.nodes.Element
object NotifParser : FrostParser<FrostNotifs> by NotifParserImpl()
data class FrostNotifs(
- val notifs: List<FrostNotif>,
- val seeMore: FrostLink?
+ val notifs: List<FrostNotif>,
+ val seeMore: FrostLink?
) : ParseNotification {
override fun toString() = StringBuilder().apply {
append("FrostNotifs {\n")
@@ -24,19 +44,19 @@ data class FrostNotifs(
}.toString()
override fun getUnreadNotifications(data: CookieModel) =
- notifs.asSequence().filter(FrostNotif::unread).map {
- with(it) {
- NotificationContent(
- data = data,
- id = id,
- href = url,
- title = null,
- text = content,
- timestamp = time,
- profileUrl = img
- )
- }
- }.toList()
+ notifs.asSequence().filter(FrostNotif::unread).map {
+ with(it) {
+ NotificationContent(
+ data = data,
+ id = id,
+ href = url,
+ title = null,
+ text = content,
+ timestamp = time,
+ profileUrl = img
+ )
+ }
+ }.toList()
}
/**
@@ -49,14 +69,16 @@ data class FrostNotifs(
* [timeString] text version of time from Facebook
* [thumbnailUrl] optional thumbnail url if existent
*/
-data class FrostNotif(val id: Long,
- val img: String?,
- val time: Long,
- val url: String,
- val unread: Boolean,
- val content: String,
- val timeString: String,
- val thumbnailUrl: String?)
+data class FrostNotif(
+ val id: Long,
+ val img: String?,
+ val time: Long,
+ val url: String,
+ val unread: Boolean,
+ val content: String,
+ val timeString: String,
+ val thumbnailUrl: String?
+)
private class NotifParserImpl : FrostParserBase<FrostNotifs>(false) {
@@ -67,8 +89,8 @@ private class NotifParserImpl : FrostParserBase<FrostNotifs>(false) {
override fun parseImpl(doc: Document): FrostNotifs? {
val notificationList = doc.getElementById("notifications_list") ?: return null
val notifications = notificationList
- .getElementsByAttributeValueMatching("id", ".*${FB_NOTIF_ID_MATCHER.pattern}.*")
- .mapNotNull(this::parseNotif)
+ .getElementsByAttributeValueMatching("id", ".*${FB_NOTIF_ID_MATCHER.pattern}.*")
+ .mapNotNull(this::parseNotif)
val seeMore = parseLink(doc.getElementsByAttributeValue("href", "/notifications.php?more").first())
return FrostNotifs(notifications, seeMore)
}
@@ -79,22 +101,20 @@ private class NotifParserImpl : FrostParserBase<FrostNotifs>(false) {
val epoch = FB_EPOCH_MATCHER.find(abbr.attr("data-store"))[1]?.toLongOrNull() ?: -1L
//fetch id
val id = FB_NOTIF_ID_MATCHER.find(element.id())[1]?.toLongOrNull()
- ?: System.currentTimeMillis() % FALLBACK_TIME_MOD
+ ?: System.currentTimeMillis() % FALLBACK_TIME_MOD
val img = element.getInnerImgStyle()
val timeString = abbr.text()
val content = a.text().replace("\u00a0", " ").removeSuffix(timeString).trim() //remove &nbsp;
val thumbnail = element.selectFirst("img.thumbnail")?.attr("src")
return FrostNotif(
- id = id,
- img = img,
- time = epoch,
- url = a.attr("href").formattedFbUrl,
- unread = !element.hasClass("acw"),
- content = content,
- timeString = timeString,
- thumbnailUrl = if (thumbnail?.isNotEmpty() == true) thumbnail else null
+ id = id,
+ img = img,
+ time = epoch,
+ url = a.attr("href").formattedFbUrl,
+ unread = !element.hasClass("acw"),
+ content = content,
+ timeString = timeString,
+ thumbnailUrl = if (thumbnail?.isNotEmpty() == true) thumbnail else null
)
}
-
-
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt
index d3367514..7869d881 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.parsers
import ca.allanwang.kau.searchview.SearchItem
@@ -46,9 +62,9 @@ data class FrostSearch(val href: String, val title: String, val description: Str
companion object {
fun create(href: String, title: String, description: String?) = FrostSearch(
- with(href.indexOf("?")) { if (this == -1) href else href.substring(0, this) },
- title.format(),
- description?.format()
+ with(href.indexOf("?")) { if (this == -1) href else href.substring(0, this) },
+ title.format(),
+ description?.format()
)
}
}
@@ -61,17 +77,18 @@ private class SearchParserImpl : FrostParserBase<FrostSearches>(false) {
override fun parseImpl(doc: Document): FrostSearches? {
val container: Element = doc.getElementById("BrowseResultsContainer")
- ?: doc.getElementById("root")
- ?: return null
+ ?: doc.getElementById("root")
+ ?: return null
/**
*
* Removed [data-store*=result_id]
*/
return FrostSearches(container.select("a.touchable[href]").filter(Element::hasText).map {
- FrostSearch.create(it.attr("href").formattedFbUrl,
- it.select("._uoi").first()?.text() ?: "",
- it.select("._1tcc").first()?.text())
+ FrostSearch.create(
+ it.attr("href").formattedFbUrl,
+ it.select("._uoi").first()?.text() ?: "",
+ it.select("._1tcc").first()?.text()
+ )
}.filter { it.title.isNotBlank() })
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt
index 500c4102..584107cc 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt
@@ -1,7 +1,29 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.requests
import com.pitchedapps.frost.BuildConfig
-import com.pitchedapps.frost.facebook.*
+import com.pitchedapps.frost.facebook.FB_DTSG_MATCHER
+import com.pitchedapps.frost.facebook.FB_JSON_URL_MATCHER
+import com.pitchedapps.frost.facebook.FB_REV_MATCHER
+import com.pitchedapps.frost.facebook.FB_URL_BASE
+import com.pitchedapps.frost.facebook.FB_USER_MATCHER
+import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
+import com.pitchedapps.frost.facebook.get
import com.pitchedapps.frost.rx.RxFlyweight
import com.pitchedapps.frost.utils.L
import io.reactivex.Single
@@ -21,10 +43,9 @@ private class RxAuth : RxFlyweight<String, Long, RequestAuth>() {
override fun call(input: String) = input.getAuth()
override fun validate(input: String, cond: Long) =
- System.currentTimeMillis() - cond < 3600000 // valid for an hour
+ System.currentTimeMillis() - cond < 3600000 // valid for an hour
override fun cache(input: String) = System.currentTimeMillis()
-
}
private val auth = RxAuth()
@@ -48,10 +69,12 @@ fun String?.fbRequest(fail: () -> Unit = {}, action: RequestAuth.() -> Unit) {
/**
* Underlying container for all fb requests
*/
-data class RequestAuth(val userId: Long = -1,
- val cookie: String = "",
- val fb_dtsg: String = "",
- val rev: String = "") {
+data class RequestAuth(
+ val userId: Long = -1,
+ val cookie: String = "",
+ val fb_dtsg: String = "",
+ val rev: String = ""
+) {
val isComplete
get() = userId > 0 && cookie.isNotEmpty() && fb_dtsg.isNotEmpty() && rev.isNotEmpty()
}
@@ -64,8 +87,8 @@ class FrostRequest<out T : Any?>(val call: Call, private val invoke: (Call) -> T
}
internal inline fun <T : Any?> RequestAuth.frostRequest(
- noinline invoke: (Call) -> T,
- builder: Request.Builder.() -> Request.Builder // to ensure we don't do anything extra at the end
+ noinline invoke: (Call) -> T,
+ builder: Request.Builder.() -> Request.Builder // to ensure we don't do anything extra at the end
): FrostRequest<T> {
val request = cookie.requestBuilder()
request.builder()
@@ -75,8 +98,10 @@ internal inline fun <T : Any?> RequestAuth.frostRequest(
val httpClient: OkHttpClient by lazy {
val builder = OkHttpClient.Builder()
if (BuildConfig.DEBUG)
- builder.addInterceptor(HttpLoggingInterceptor()
- .setLevel(HttpLoggingInterceptor.Level.BASIC))
+ builder.addInterceptor(
+ HttpLoggingInterceptor()
+ .setLevel(HttpLoggingInterceptor.Level.BASIC)
+ )
builder.build()
}
@@ -97,7 +122,7 @@ internal fun List<Pair<String, Any?>>.withEmptyData(vararg key: String): List<Pa
internal fun String?.requestBuilder(): Request.Builder {
val builder = Request.Builder()
- .header("User-Agent", USER_AGENT_BASIC)
+ .header("User-Agent", USER_AGENT_BASIC)
if (this != null)
builder.header("Cookie", this)
// .cacheControl(CacheControl.FORCE_NETWORK)
@@ -112,9 +137,9 @@ fun String.getAuth(): RequestAuth {
val id = FB_USER_MATCHER.find(this)[1]?.toLong() ?: return auth
auth = auth.copy(userId = id)
val call = this.requestBuilder()
- .url(FB_URL_BASE)
- .get()
- .call()
+ .url(FB_URL_BASE)
+ .get()
+ .call()
call.execute().body()?.charStream()?.useLines { lines ->
lines.forEach {
val text = StringEscapeUtils.unescapeEcmaScript(it)
@@ -135,8 +160,10 @@ fun String.getAuth(): RequestAuth {
return auth
}
-inline fun <T, reified R : Any, O> Array<T>.zip(crossinline mapper: (List<R>) -> O,
- crossinline caller: (T) -> R): Single<O> {
+inline fun <T, reified R : Any, O> Array<T>.zip(
+ crossinline mapper: (List<R>) -> O,
+ crossinline caller: (T) -> R
+): Single<O> {
if (isEmpty())
return Single.just(mapper(emptyList()))
val singles = map { Single.fromCallable { caller(it) }.subscribeOn(Schedulers.io()) }
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.kt
index 8eeef08d..e0ccea81 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.requests
import com.bumptech.glide.Priority
@@ -11,7 +27,11 @@ import com.bumptech.glide.load.model.MultiModelLoaderFactory
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.signature.ObjectKey
-import com.pitchedapps.frost.facebook.*
+import com.pitchedapps.frost.facebook.FB_IMAGE_ID_MATCHER
+import com.pitchedapps.frost.facebook.FB_REDIRECT_URL_MATCHER
+import com.pitchedapps.frost.facebook.FB_URL_BASE
+import com.pitchedapps.frost.facebook.formattedFbUrl
+import com.pitchedapps.frost.facebook.get
import io.reactivex.Maybe
import okhttp3.Call
import okhttp3.Request
@@ -33,9 +53,9 @@ val test: () -> InputStream? = { null }
*/
fun String.getFullSizedImageUrl(url: String): Maybe<String?> = Maybe.fromCallable {
val redirect = requestBuilder().url(url).get().call()
- .execute().body()?.string() ?: return@fromCallable null
+ .execute().body()?.string() ?: return@fromCallable null
return@fromCallable FB_REDIRECT_URL_MATCHER.find(redirect)[1]?.formattedFbUrl
- ?: return@fromCallable null
+ ?: return@fromCallable null
}.onErrorComplete()
/**
@@ -51,7 +71,6 @@ data class HdImageMaybe(val url: String, val cookie: String) {
val isValid: Boolean by lazy {
id != -1L && cookie.isNotBlank()
}
-
}
/*
@@ -69,18 +88,20 @@ class HdImageLoadingFactory : ModelLoaderFactory<HdImageMaybe, InputStream> {
}
fun <T> RequestBuilder<T>.loadWithPotentialHd(model: HdImageMaybe) =
- thumbnail(clone().load(model.url))
- .load(model)
- .apply(RequestOptions().override(Target.SIZE_ORIGINAL))
+ thumbnail(clone().load(model.url))
+ .load(model)
+ .apply(RequestOptions().override(Target.SIZE_ORIGINAL))
class HdImageLoading : ModelLoader<HdImageMaybe, InputStream> {
- override fun buildLoadData(model: HdImageMaybe,
- width: Int,
- height: Int,
- options: Options): ModelLoader.LoadData<InputStream>? =
- if (!model.isValid) null
- else ModelLoader.LoadData(ObjectKey(model), HdImageFetcher(model))
+ override fun buildLoadData(
+ model: HdImageMaybe,
+ width: Int,
+ height: Int,
+ options: Options
+ ): ModelLoader.LoadData<InputStream>? =
+ if (!model.isValid) null
+ else ModelLoader.LoadData(ObjectKey(model), HdImageFetcher(model))
override fun handles(model: HdImageMaybe) = model.isValid
}
@@ -105,7 +126,7 @@ class HdImageFetcher(private val model: HdImageMaybe) : DataFetcher<InputStream>
model.cookie.fbRequest(fail = { callback.fail("Invalid auth") }) {
if (cancelled) return@fbRequest callback.fail("Cancelled")
val url = getFullSizedImage(model.id).invoke()
- ?: return@fbRequest callback.fail("Null url")
+ ?: return@fbRequest callback.fail("Null url")
if (cancelled) return@fbRequest callback.fail("Cancelled")
if (!url.contains("png") && !url.contains("jpg")) return@fbRequest callback.fail("Invalid format")
urlCall = Request.Builder().url(url).get().call()
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.kt
index e83e4e43..dcb0ce10 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.requests
import com.fasterxml.jackson.annotation.JsonCreator
@@ -19,28 +35,27 @@ import java.io.IOException
fun RequestAuth.getMenuData(): FrostRequest<MenuData?> {
val body = listOf(
- "fb_dtsg" to fb_dtsg,
- "__user" to userId
+ "fb_dtsg" to fb_dtsg,
+ "__user" to userId
).withEmptyData("m_sess", "__dyn", "__req", "__ajax__")
return frostRequest(::parseMenu) {
url("${FB_URL_BASE}bookmarks/flyout/body/?id=u_0_2")
post(body.toForm())
}
-
}
fun parseMenu(call: Call): MenuData? {
val fullString = call.execute().body()?.string() ?: return null
var jsonString = fullString.substringAfter("bookmarkGroups", "")
- .substringAfter("[", "")
+ .substringAfter("[", "")
if (jsonString.isBlank()) return null
jsonString = "{ \"data\" : [${StringEscapeUtils.unescapeEcmaScript(jsonString)}"
val mapper = ObjectMapper()
- .disable(MapperFeature.AUTO_DETECT_SETTERS)
+ .disable(MapperFeature.AUTO_DETECT_SETTERS)
return try {
val data = mapper.readValue(jsonString, MenuData::class.java)
@@ -48,11 +63,14 @@ fun parseMenu(call: Call): MenuData? {
// parse footer content
val footer = fullString.substringAfter("footerMarkup", "")
- .substringAfter("{", "")
- .substringBefore("}", "")
-
- val doc = Jsoup.parseBodyFragment(StringEscapeUtils.unescapeEcmaScript(
- StringEscapeUtils.unescapeEcmaScript(footer)))
+ .substringAfter("{", "")
+ .substringBefore("}", "")
+
+ val doc = Jsoup.parseBodyFragment(
+ StringEscapeUtils.unescapeEcmaScript(
+ StringEscapeUtils.unescapeEcmaScript(footer)
+ )
+ )
val footerData = mutableListOf<MenuFooterItem>()
val footerSmallData = mutableListOf<MenuFooterItem>()
@@ -76,11 +94,14 @@ fun parseMenu(call: Call): MenuData? {
}
@JsonIgnoreProperties(ignoreUnknown = true)
-data class MenuData(val data: List<MenuHeader> = emptyList(),
- val footer: MenuFooter = MenuFooter()) {
-
- @JsonCreator constructor(
- @JsonProperty("data") data: List<MenuHeader>?
+data class MenuData(
+ val data: List<MenuHeader> = emptyList(),
+ val footer: MenuFooter = MenuFooter()
+) {
+
+ @JsonCreator
+ constructor(
+ @JsonProperty("data") data: List<MenuHeader>?
) : this(data ?: emptyList(), MenuFooter())
fun flatMapValid(): List<MenuItemData> {
@@ -95,7 +116,6 @@ data class MenuData(val data: List<MenuHeader> = emptyList(),
return items
}
-
}
interface MenuItemData {
@@ -103,17 +123,20 @@ interface MenuItemData {
}
@JsonIgnoreProperties(ignoreUnknown = true)
-data class MenuHeader(val id: String? = null,
- val header: String? = null,
- val visible: List<MenuItem> = emptyList(),
- val all: List<MenuItem> = emptyList()) : MenuItemData {
-
- @JsonCreator constructor(
- @JsonProperty("id") id: String?,
- @JsonProperty("header") header: String?,
- @JsonProperty("visible") visible: List<MenuItem>?,
- @JsonProperty("all") all: List<MenuItem>?,
- @JsonProperty("fake") fake: Boolean?
+data class MenuHeader(
+ val id: String? = null,
+ val header: String? = null,
+ val visible: List<MenuItem> = emptyList(),
+ val all: List<MenuItem> = emptyList()
+) : MenuItemData {
+
+ @JsonCreator
+ constructor(
+ @JsonProperty("id") id: String?,
+ @JsonProperty("header") header: String?,
+ @JsonProperty("visible") visible: List<MenuItem>?,
+ @JsonProperty("all") all: List<MenuItem>?,
+ @JsonProperty("fake") fake: Boolean?
) : this(id, header, visible ?: emptyList(), all ?: emptyList())
override val isValid: Boolean
@@ -121,41 +144,49 @@ data class MenuHeader(val id: String? = null,
}
@JsonIgnoreProperties(ignoreUnknown = true)
-data class MenuItem(val id: String? = null,
- val name: String? = null,
- val pic: String? = null,
- val url: String? = null,
- val badge: String? = null,
- val countDetails: String? = null) : MenuItemData {
-
- @JsonCreator constructor(
- @JsonProperty("id") id: String?,
- @JsonProperty("name") name: String?,
- @JsonProperty("pic") pic: String?,
- @JsonProperty("url") url: String?,
- @JsonProperty("count") badge: String?,
- @JsonProperty("count_details") countDetails: String?,
- @JsonProperty("fake") fake: Boolean?
- ) : this(id, name, pic?.formattedFbUrl,
- url?.formattedFbUrl,
- if (badge == "0") null else badge,
- countDetails)
+data class MenuItem(
+ val id: String? = null,
+ val name: String? = null,
+ val pic: String? = null,
+ val url: String? = null,
+ val badge: String? = null,
+ val countDetails: String? = null
+) : MenuItemData {
+
+ @JsonCreator
+ constructor(
+ @JsonProperty("id") id: String?,
+ @JsonProperty("name") name: String?,
+ @JsonProperty("pic") pic: String?,
+ @JsonProperty("url") url: String?,
+ @JsonProperty("count") badge: String?,
+ @JsonProperty("count_details") countDetails: String?,
+ @JsonProperty("fake") fake: Boolean?
+ ) : this(
+ id, name, pic?.formattedFbUrl,
+ url?.formattedFbUrl,
+ if (badge == "0") null else badge,
+ countDetails
+ )
override val isValid: Boolean
get() = !name.isNullOrBlank() && !url.isNullOrBlank()
}
-data class MenuFooter(val data: List<MenuFooterItem> = emptyList(),
- val smallData: List<MenuFooterItem> = emptyList()) {
+data class MenuFooter(
+ val data: List<MenuFooterItem> = emptyList(),
+ val smallData: List<MenuFooterItem> = emptyList()
+) {
val hasContent
get() = data.isNotEmpty() || smallData.isNotEmpty()
-
}
-data class MenuFooterItem(val name: String? = null,
- val url: String? = null,
- val isSmall: Boolean = false) : MenuItemData {
+data class MenuFooterItem(
+ val name: String? = null,
+ val url: String? = null,
+ val isSmall: Boolean = false
+) : MenuItemData {
override val isValid: Boolean
get() = name != null && url != null
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.kt
index 0e37a61e..f350c547 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.requests
import com.pitchedapps.frost.facebook.FB_URL_BASE
@@ -10,10 +26,10 @@ fun RequestAuth.sendMessage(group: String, content: String): FrostRequest<Boolea
// todo test more; only tested against tids=cid...
val body = listOf(
- "tids" to group,
- "body" to content,
- "fb_dtsg" to fb_dtsg,
- "__user" to userId
+ "tids" to group,
+ "body" to content,
+ "fb_dtsg" to fb_dtsg,
+ "__user" to userId
).withEmptyData("m_sess", "__dyn", "__req", "__ajax__")
return frostRequest(::validateMessage) {
@@ -29,4 +45,4 @@ private fun validateMessage(call: Call): Boolean {
val body = call.execute().body() ?: return false
// todo
return true
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.kt
index 0d3926dc..43815b67 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.requests
import com.pitchedapps.frost.facebook.FB_URL_BASE
@@ -8,11 +24,11 @@ import com.pitchedapps.frost.facebook.FB_URL_BASE
fun RequestAuth.markNotificationRead(notifId: Long): FrostRequest<Boolean> {
val body = listOf(
- "click_type" to "notification_click",
- "id" to notifId,
- "target_id" to "null",
- "fb_dtsg" to fb_dtsg,
- "__user" to userId
+ "click_type" to "notification_click",
+ "id" to notifId,
+ "target_id" to "null",
+ "fb_dtsg" to fb_dtsg,
+ "__user" to userId
).withEmptyData("m_sess", "__dyn", "__req", "__ajax__")
return frostRequest(::executeForNoError) {
@@ -22,6 +38,6 @@ fun RequestAuth.markNotificationRead(notifId: Long): FrostRequest<Boolean> {
}
fun RequestAuth.markNotificationsRead(vararg notifId: Long) =
- notifId.toTypedArray().zip<Long, Boolean, Boolean>(
- { it.all { self -> self } },
- { markNotificationRead(it).invoke() }) \ No newline at end of file
+ notifId.toTypedArray().zip<Long, Boolean, Boolean>(
+ { it.all { self -> self } },
+ { markNotificationRead(it).invoke() })
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt
index 34e28c2e..98e28bd3 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt
@@ -1,15 +1,31 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.fragments
import android.content.Context
import android.os.Bundle
-import com.google.android.material.floatingactionbutton.FloatingActionButton
-import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.fragment.app.Fragment
import ca.allanwang.kau.utils.fadeScaleTransition
import ca.allanwang.kau.utils.setIcon
import ca.allanwang.kau.utils.withArguments
+import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.mikepenz.iconics.typeface.IIcon
import com.pitchedapps.frost.contracts.DynamicUiContract
import com.pitchedapps.frost.contracts.FrostContentParent
@@ -17,7 +33,12 @@ import com.pitchedapps.frost.contracts.MainActivityContract
import com.pitchedapps.frost.contracts.MainFabContract
import com.pitchedapps.frost.enums.FeedSort
import com.pitchedapps.frost.facebook.FbItem
-import com.pitchedapps.frost.utils.*
+import com.pitchedapps.frost.utils.ARG_URL
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.REQUEST_REFRESH
+import com.pitchedapps.frost.utils.REQUEST_TEXT_ZOOM
+import com.pitchedapps.frost.utils.frostEvent
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
@@ -33,12 +54,17 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract {
private const val ARG_POSITION = "arg_position"
private const val ARG_VALID = "arg_valid"
- internal operator fun invoke(base: () -> BaseFragment, useFallback: Boolean, data: FbItem, position: Int): BaseFragment {
+ internal operator fun invoke(
+ base: () -> BaseFragment,
+ useFallback: Boolean,
+ data: FbItem,
+ position: Int
+ ): BaseFragment {
val fragment = if (!useFallback) base() else WebFragment()
val d = if (data == FbItem.FEED) FeedSort(Prefs.feedSort).item else data
fragment.withArguments(
- ARG_URL to d.url,
- ARG_POSITION to position
+ ARG_URL to d.url,
+ ARG_POSITION to position
)
d.put(fragment.arguments!!)
return fragment
@@ -55,8 +81,10 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract {
if (value || this is WebFragment) return
arguments!!.putBoolean(ARG_VALID, value)
L.e { "Invalidating position $position" }
- frostEvent("Native Fallback",
- "Item" to baseEnum.name)
+ frostEvent(
+ "Native Fallback",
+ "Item" to baseEnum.name
+ )
(context as MainActivityContract).reloadFragment(this)
}
@@ -75,10 +103,14 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract {
throw IllegalArgumentException("${this::class.java.simpleName} is not attached to a context implementing MainActivityContract")
}
- final override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ final override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
val view = inflater.inflate(layoutRes, container, false)
- val content = view as? FrostContentParent
- ?: throw IllegalArgumentException("layoutRes for fragment must return view implementing FrostContentParent")
+ val content = view as? FrostContentParent
+ ?: throw IllegalArgumentException("layoutRes for fragment must return view implementing FrostContentParent")
this.content = content
content.bind(this)
return view
@@ -113,28 +145,28 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract {
}
override fun attachMainObservable(contract: MainActivityContract): Disposable =
- contract.fragmentSubject.observeOn(AndroidSchedulers.mainThread()).subscribe {
- when (it) {
- REQUEST_REFRESH -> {
- core?.apply {
- clearHistory()
- firstLoad = true
- firstLoadRequest()
- }
- }
- position -> {
- contract.setTitle(baseEnum.titleId)
- updateFab(contract)
- core?.active = true
- }
- -(position + 1) -> {
- core?.active = false
- }
- REQUEST_TEXT_ZOOM -> {
- reloadTextSize()
+ contract.fragmentSubject.observeOn(AndroidSchedulers.mainThread()).subscribe {
+ when (it) {
+ REQUEST_REFRESH -> {
+ core?.apply {
+ clearHistory()
+ firstLoad = true
+ firstLoadRequest()
}
}
+ position -> {
+ contract.setTitle(baseEnum.titleId)
+ updateFab(contract)
+ core?.active = true
+ }
+ -(position + 1) -> {
+ core?.active = false
+ }
+ REQUEST_TEXT_ZOOM -> {
+ reloadTextSize()
+ }
}
+ }
override fun updateFab(contract: MainFabContract) {
contract.hideFab() // default
@@ -197,4 +229,3 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract {
override fun onTabClick(): Unit = content?.core?.onTabClicked() ?: Unit
}
-
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt
index 6555e076..e24e8308 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt
@@ -1,6 +1,26 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.fragments
-import com.pitchedapps.frost.contracts.*
+import com.pitchedapps.frost.contracts.FrostContentContainer
+import com.pitchedapps.frost.contracts.FrostContentCore
+import com.pitchedapps.frost.contracts.FrostContentParent
+import com.pitchedapps.frost.contracts.MainActivityContract
+import com.pitchedapps.frost.contracts.MainFabContract
import com.pitchedapps.frost.views.FrostRecyclerView
import io.reactivex.disposables.Disposable
@@ -74,8 +94,6 @@ interface FragmentContract : FrostContentContainer {
fun onBackPressed(): Boolean
fun onTabClick()
-
-
}
interface RecyclerContentContract {
@@ -88,5 +106,4 @@ interface RecyclerContentContract {
* Callback returns [true] for success, [false] otherwise
*/
fun reload(progress: (Int) -> Unit, callback: (Boolean) -> Unit)
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt
index 4f9133a6..f77f83ea 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.fragments
import ca.allanwang.kau.adapters.fastAdapter
@@ -65,7 +81,6 @@ abstract class GenericRecyclerFragment<T, Item : IItem<*, *>> : RecyclerFragment
* Create the fast adapter to bind to the recyclerview
*/
open fun getAdapter(): FastAdapter<IItem<*, *>> = fastAdapter(this.adapter)
-
}
abstract class FrostParserFragment<T : Any, Item : IItem<*, *>> : RecyclerFragment() {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt
index 4f597731..ff37b66d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.fragments
import com.mikepenz.fastadapter.IItem
@@ -6,8 +22,18 @@ import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.facebook.parsers.FrostNotifs
import com.pitchedapps.frost.facebook.parsers.NotifParser
import com.pitchedapps.frost.facebook.parsers.ParseResponse
-import com.pitchedapps.frost.facebook.requests.*
-import com.pitchedapps.frost.iitems.*
+import com.pitchedapps.frost.facebook.requests.MenuFooterItem
+import com.pitchedapps.frost.facebook.requests.MenuHeader
+import com.pitchedapps.frost.facebook.requests.MenuItem
+import com.pitchedapps.frost.facebook.requests.MenuItemData
+import com.pitchedapps.frost.facebook.requests.fbRequest
+import com.pitchedapps.frost.facebook.requests.getMenuData
+import com.pitchedapps.frost.iitems.ClickableIItemContract
+import com.pitchedapps.frost.iitems.MenuContentIItem
+import com.pitchedapps.frost.iitems.MenuFooterIItem
+import com.pitchedapps.frost.iitems.MenuFooterSmallIItem
+import com.pitchedapps.frost.iitems.MenuHeaderIItem
+import com.pitchedapps.frost.iitems.NotificationIItem
import com.pitchedapps.frost.utils.frostJsoup
import com.pitchedapps.frost.views.FrostRecyclerView
import org.jetbrains.anko.doAsync
@@ -23,7 +49,7 @@ class NotificationFragment : FrostParserFragment<FrostNotifs, NotificationIItem>
override fun getDoc(cookie: String?) = frostJsoup(cookie, "${FbItem.NOTIFICATIONS.url}?more")
override fun toItems(response: ParseResponse<FrostNotifs>): List<NotificationIItem> =
- response.data.notifs.map { NotificationIItem(it, response.cookie) }
+ response.data.notifs.map { NotificationIItem(it, response.cookie) }
override fun bindImpl(recyclerView: FrostRecyclerView) {
NotificationIItem.bindEvents(adapter)
@@ -61,4 +87,4 @@ class MenuFragment : GenericRecyclerFragment<MenuItemData, IItem<*, *>>() {
}
}
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragments.kt
index d9edda78..72367eaa 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragments.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragments.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.fragments
import android.webkit.WebView
@@ -43,4 +59,4 @@ class WebFragment : BaseFragment() {
}
super.updateFab(contract)
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/glide/GlideUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/glide/GlideUtils.kt
index 50d4d7b4..0c471c63 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/glide/GlideUtils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/glide/GlideUtils.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.glide
import android.content.Context
@@ -30,11 +46,11 @@ object FrostGlide {
}
fun <T> RequestBuilder<T>.transform(vararg transformation: BitmapTransformation): RequestBuilder<T> =
- when (transformation.size) {
- 0 -> this
- 1 -> apply(RequestOptions.bitmapTransform(transformation[0]))
- else -> apply(RequestOptions.bitmapTransform(MultiTransformation(*transformation)))
- }
+ when (transformation.size) {
+ 0 -> this
+ 1 -> apply(RequestOptions.bitmapTransform(transformation[0]))
+ else -> apply(RequestOptions.bitmapTransform(MultiTransformation(*transformation)))
+ }
@GlideModule
class FrostGlideModule : AppGlideModule() {
@@ -48,7 +64,7 @@ class FrostGlideModule : AppGlideModule() {
}
private fun getFrostHttpClient(): OkHttpClient =
- OkHttpClient.Builder().addInterceptor(FrostCookieInterceptor()).build()
+ OkHttpClient.Builder().addInterceptor(FrostCookieInterceptor()).build()
class FrostCookieInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
@@ -58,4 +74,4 @@ class FrostCookieInterceptor : Interceptor {
val request = origRequest.newBuilder().addHeader("Cookie", cookie).build()
return chain.proceed(request)
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/glide/RoundCornerTransformation.kt b/app/src/main/kotlin/com/pitchedapps/frost/glide/RoundCornerTransformation.kt
index 5eded159..564224ea 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/glide/RoundCornerTransformation.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/glide/RoundCornerTransformation.kt
@@ -1,12 +1,32 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.glide
-import android.graphics.*
+import android.graphics.Bitmap
+import android.graphics.BitmapShader
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.graphics.RectF
+import android.graphics.Shader
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
import com.pitchedapps.frost.utils.Prefs
import java.security.MessageDigest
-
/**
* Created by Allan Wang on 27/12/17.
*/
@@ -25,17 +45,17 @@ class RoundCornerTransformation : BitmapTransformation() {
bitmap.setHasAlpha(true)
val radius = Math.min(width, height).toFloat() /
- (if (Prefs.showRoundedIcons) 2f else 10f)
+ (if (Prefs.showRoundedIcons) 2f else 10f)
val canvas = Canvas(bitmap)
val paint = Paint()
paint.isAntiAlias = true
paint.shader = BitmapShader(toTransform, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
- canvas.drawRoundRect(RectF(0f, 0f, width.toFloat(), height.toFloat()),
- radius, radius, paint)
+ canvas.drawRoundRect(
+ RectF(0f, 0f, width.toFloat(), height.toFloat()),
+ radius, radius, paint
+ )
return bitmap
}
-
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/iitems/GenericIItems.kt b/app/src/main/kotlin/com/pitchedapps/frost/iitems/GenericIItems.kt
index 1211b742..6eacf48e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/iitems/GenericIItems.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/iitems/GenericIItems.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.iitems
import android.content.Context
@@ -32,25 +48,25 @@ interface ClickableIItemContract {
companion object {
fun bindEvents(adapter: IAdapter<IItem<*, *>>) {
adapter.fastAdapter.withSelectable(false)
- .withOnClickListener { v, _, item, _ ->
- if (item is ClickableIItemContract) {
- item.click(v!!.context)
- true
- } else
- false
- }
+ .withOnClickListener { v, _, item, _ ->
+ if (item is ClickableIItemContract) {
+ item.click(v!!.context)
+ true
+ } else
+ false
+ }
}
}
-
}
/**
* Generic header item
* Not clickable with an accent color
*/
-open class HeaderIItem(val text: String?,
- itemId: Int = R.layout.iitem_header)
- : KauIItem<HeaderIItem, HeaderIItem.ViewHolder>(R.layout.iitem_header, ::ViewHolder, itemId) {
+open class HeaderIItem(
+ val text: String?,
+ itemId: Int = R.layout.iitem_header
+) : KauIItem<HeaderIItem, HeaderIItem.ViewHolder>(R.layout.iitem_header, ::ViewHolder, itemId) {
class ViewHolder(itemView: View) : FastAdapter.ViewHolder<HeaderIItem>(itemView) {
@@ -66,18 +82,18 @@ open class HeaderIItem(val text: String?,
text.text = null
}
}
-
}
/**
* Generic text item
* Clickable with text color
*/
-open class TextIItem(val text: String?,
- override val url: String?,
- itemId: Int = R.layout.iitem_text)
- : KauIItem<TextIItem, TextIItem.ViewHolder>(R.layout.iitem_text, ::ViewHolder, itemId),
- ClickableIItemContract {
+open class TextIItem(
+ val text: String?,
+ override val url: String?,
+ itemId: Int = R.layout.iitem_text
+) : KauIItem<TextIItem, TextIItem.ViewHolder>(R.layout.iitem_text, ::ViewHolder, itemId),
+ ClickableIItemContract {
class ViewHolder(itemView: View) : FastAdapter.ViewHolder<TextIItem>(itemView) {
@@ -93,5 +109,4 @@ open class TextIItem(val text: String?,
text.text = null
}
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/iitems/MenuIItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/iitems/MenuIItem.kt
index 4a7356b0..651a4a2a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/iitems/MenuIItem.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/iitems/MenuIItem.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.iitems
import android.view.View
@@ -21,9 +37,9 @@ import com.pitchedapps.frost.utils.Prefs
/**
* Created by Allan Wang on 30/12/17.
*/
-class MenuContentIItem(val data: MenuItem)
- : KauIItem<MenuContentIItem, MenuContentIItem.ViewHolder>(R.layout.iitem_menu, ::ViewHolder),
- ClickableIItemContract {
+class MenuContentIItem(val data: MenuItem) :
+ KauIItem<MenuContentIItem, MenuContentIItem.ViewHolder>(R.layout.iitem_menu, ::ViewHolder),
+ ClickableIItemContract {
override val url: String?
get() = data.url
@@ -42,9 +58,9 @@ class MenuContentIItem(val data: MenuItem)
val iconUrl = item.data.pic
if (iconUrl != null)
GlideApp.with(itemView)
- .load(iconUrl)
- .transform(FrostGlide.roundCorner)
- .into(icon.visible())
+ .load(iconUrl)
+ .transform(FrostGlide.roundCorner)
+ .into(icon.visible())
else
icon.gone()
content.text = item.data.name
@@ -59,12 +75,11 @@ class MenuContentIItem(val data: MenuItem)
}
}
-class MenuHeaderIItem(val data: MenuHeader) : HeaderIItem(data.header,
- itemId = R.id.item_menu_header)
-
-class MenuFooterIItem(val data: MenuFooterItem)
- : TextIItem(data.name, data.url, R.id.item_menu_footer)
+class MenuHeaderIItem(val data: MenuHeader) : HeaderIItem(
+ data.header,
+ itemId = R.id.item_menu_header
+)
-class MenuFooterSmallIItem(val data: MenuFooterItem)
- : TextIItem(data.name, data.url, R.id.item_menu_footer_small)
+class MenuFooterIItem(val data: MenuFooterItem) : TextIItem(data.name, data.url, R.id.item_menu_footer)
+class MenuFooterSmallIItem(val data: MenuFooterItem) : TextIItem(data.name, data.url, R.id.item_menu_footer_small)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/iitems/NotificationIItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/iitems/NotificationIItem.kt
index 06bc0604..e8332955 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/iitems/NotificationIItem.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/iitems/NotificationIItem.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.iitems
import android.view.View
@@ -26,23 +42,24 @@ import com.pitchedapps.frost.utils.launchWebOverlay
/**
* Created by Allan Wang on 27/12/17.
*/
-class NotificationIItem(val notification: FrostNotif, val cookie: String) : KauIItem<NotificationIItem, NotificationIItem.ViewHolder>(
+class NotificationIItem(val notification: FrostNotif, val cookie: String) :
+ KauIItem<NotificationIItem, NotificationIItem.ViewHolder>(
R.layout.iitem_notification, ::ViewHolder
-) {
+ ) {
companion object {
fun bindEvents(adapter: ItemAdapter<NotificationIItem>) {
adapter.fastAdapter.withSelectable(false)
- .withOnClickListener { v, _, item, position ->
- val notif = item.notification
- if (notif.unread) {
- FrostRunnable.markNotificationRead(v!!.context, notif.id, item.cookie)
- adapter.set(position, NotificationIItem(notif.copy(unread = false), item.cookie))
- }
- // TODO temp fix. If url is dependent, we cannot load it directly
- v!!.context.launchWebOverlay(if (notif.url.isIndependent) notif.url else FbItem.NOTIFICATIONS.url)
- true
+ .withOnClickListener { v, _, item, position ->
+ val notif = item.notification
+ if (notif.unread) {
+ FrostRunnable.markNotificationRead(v!!.context, notif.id, item.cookie)
+ adapter.set(position, NotificationIItem(notif.copy(unread = false), item.cookie))
}
+ // TODO temp fix. If url is dependent, we cannot load it directly
+ v!!.context.launchWebOverlay(if (notif.url.isIndependent) notif.url else FbItem.NOTIFICATIONS.url)
+ true
+ }
}
//todo see if necessary
@@ -52,12 +69,17 @@ class NotificationIItem(val notification: FrostNotif, val cookie: String) : KauI
private class Diff : DiffCallback<NotificationIItem> {
override fun areItemsTheSame(oldItem: NotificationIItem, newItem: NotificationIItem) =
- oldItem.notification.id == newItem.notification.id
+ oldItem.notification.id == newItem.notification.id
override fun areContentsTheSame(oldItem: NotificationIItem, newItem: NotificationIItem) =
- oldItem.notification == newItem.notification
+ oldItem.notification == newItem.notification
- override fun getChangePayload(oldItem: NotificationIItem, oldItemPosition: Int, newItem: NotificationIItem, newItemPosition: Int): Any? {
+ override fun getChangePayload(
+ oldItem: NotificationIItem,
+ oldItemPosition: Int,
+ newItem: NotificationIItem,
+ newItemPosition: Int
+ ): Any? {
return newItem
}
}
@@ -75,15 +97,17 @@ class NotificationIItem(val notification: FrostNotif, val cookie: String) : KauI
override fun bindView(item: NotificationIItem, payloads: MutableList<Any>) {
val notif = item.notification
- frame.background = createSimpleRippleDrawable(Prefs.textColor,
- Prefs.nativeBgColor(notif.unread))
+ frame.background = createSimpleRippleDrawable(
+ Prefs.textColor,
+ Prefs.nativeBgColor(notif.unread)
+ )
content.setTextColor(Prefs.textColor)
date.setTextColor(Prefs.textColor.withAlpha(150))
val glide = glide
glide.load(notif.img)
- .transform(FrostGlide.roundCorner)
- .into(avatar)
+ .transform(FrostGlide.roundCorner)
+ .into(avatar)
if (notif.thumbnailUrl != null)
glide.load(notif.thumbnailUrl).into(thumbnail.visible())
@@ -101,4 +125,4 @@ class NotificationIItem(val notification: FrostNotif, val cookie: String) : KauI
date.text = null
}
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/iitems/TabIItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/iitems/TabIItem.kt
index 506d1cab..51201d09 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/iitems/TabIItem.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/iitems/TabIItem.kt
@@ -1,10 +1,30 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.iitems
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import ca.allanwang.kau.iitems.KauIItem
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.invisible
+import ca.allanwang.kau.utils.setIcon
+import ca.allanwang.kau.utils.visible
+import ca.allanwang.kau.utils.withAlpha
import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.IItem
import com.mikepenz.fastadapter_extensions.drag.IDraggable
@@ -16,8 +36,8 @@ 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) }
+ R.layout.iitem_tab_preview,
+ { ViewHolder(it) }
), IDraggable<TabIItem, IItem<*, *>> {
override fun withIsDraggable(draggable: Boolean): TabIItem = this
@@ -45,6 +65,5 @@ class TabIItem(val item: FbItem) : KauIItem<TabIItem, TabIItem.ViewHolder>(
image.setImageDrawable(null)
text.visible().text = null
}
-
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt
index 033e482f..de19f99c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt
@@ -1,14 +1,35 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.injectors
import android.graphics.Color
import android.webkit.WebView
import ca.allanwang.kau.kotlin.lazyContext
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.adjustAlpha
+import ca.allanwang.kau.utils.colorToBackground
+import ca.allanwang.kau.utils.colorToForeground
+import ca.allanwang.kau.utils.toRgbaString
+import ca.allanwang.kau.utils.use
+import ca.allanwang.kau.utils.withAlpha
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import java.io.BufferedReader
import java.io.FileNotFoundException
-import java.util.*
+import java.util.Locale
/**
* Created by Allan Wang on 2017-05-31.
@@ -32,17 +53,17 @@ enum class CssAssets(val folder: String = "themes") : InjectorContract {
val bb = Prefs.bgColor.colorToForeground(0.35f)
content = content
- .replace("\$T\$", Prefs.textColor.toRgbaString())
- .replace("\$TT\$", Prefs.textColor.colorToBackground(0.05f).toRgbaString())
- .replace("\$A\$", Prefs.accentColor.toRgbaString())
- .replace("\$B\$", Prefs.bgColor.toRgbaString())
- .replace("\$BT\$", bt)
- .replace("\$BBT\$", bb.withAlpha(51).toRgbaString())
- .replace("\$O\$", Prefs.bgColor.withAlpha(255).toRgbaString())
- .replace("\$OO\$", bb.withAlpha(255).toRgbaString())
- .replace("\$D\$", Prefs.textColor.adjustAlpha(0.3f).toRgbaString())
- .replace("\$TI\$", bb.withAlpha(60).toRgbaString())
- .replace("\$C\$", bt)
+ .replace("\$T\$", Prefs.textColor.toRgbaString())
+ .replace("\$TT\$", Prefs.textColor.colorToBackground(0.05f).toRgbaString())
+ .replace("\$A\$", Prefs.accentColor.toRgbaString())
+ .replace("\$B\$", Prefs.bgColor.toRgbaString())
+ .replace("\$BT\$", bt)
+ .replace("\$BBT\$", bb.withAlpha(51).toRgbaString())
+ .replace("\$O\$", Prefs.bgColor.withAlpha(255).toRgbaString())
+ .replace("\$OO\$", bb.withAlpha(255).toRgbaString())
+ .replace("\$D\$", Prefs.textColor.adjustAlpha(0.3f).toRgbaString())
+ .replace("\$TI\$", bb.withAlpha(60).toRgbaString())
+ .replace("\$C\$", bt)
}
JsBuilder().css(content).build()
} catch (e: FileNotFoundException) {
@@ -58,5 +79,4 @@ enum class CssAssets(val folder: String = "themes") : InjectorContract {
fun reset() {
injector.invalidate()
}
-
}
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 5444fad8..7da6295f 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.injectors
import android.webkit.WebView
@@ -9,10 +25,14 @@ import android.webkit.WebView
*/
enum class CssHider(vararg val items: String) : InjectorContract {
CORE("[data-sigil=m_login_upsell]", "[role=progressbar]"),
- HEADER("#header", "#mJewelNav", "[data-sigil=MTopBlueBarHeader]",
- "#header-notices", "[data-sigil*=m-promo-jewel-header]"),
- ADS("article[data-xt*=sponsor]",
- "article[data-store*=sponsor]"),
+ HEADER(
+ "#header", "#mJewelNav", "[data-sigil=MTopBlueBarHeader]",
+ "#header-notices", "[data-sigil*=m-promo-jewel-header]"
+ ),
+ ADS(
+ "article[data-xt*=sponsor]",
+ "article[data-store*=sponsor]"
+ ),
PEOPLE_YOU_MAY_KNOW("article._d2r"),
SUGGESTED_GROUPS("article[data-ft*=\"ei\":]"),
COMPOSER("#MComposer"),
@@ -22,11 +42,10 @@ enum class CssHider(vararg val items: String) : InjectorContract {
val injector: JsInjector by lazy {
JsBuilder().css("${items.joinToString(separator = ",")}{display:none !important}")
- .single(name).build()
+ .single(name).build()
}
override fun inject(webView: WebView, callback: (() -> Unit)?) {
injector.inject(webView, callback)
}
-
-} \ 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
index 1ab00153..e64d4faa 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.injectors
import android.webkit.WebView
@@ -27,10 +43,9 @@ enum class JsActions(body: String) : InjectorContract {
val function = "(function(){$body})();"
override fun inject(webView: WebView, callback: (() -> Unit)?) =
- JsInjector(function).inject(webView, callback)
-
+ JsInjector(function).inject(webView, callback)
}
@Suppress("NOTHING_TO_INLINE")
private inline fun clickBySelector(selector: String): String =
- """document.querySelector("$selector").click()""" \ No newline at end of file
+ """document.querySelector("$selector").click()"""
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 980481a4..0dccc751 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.injectors
import android.webkit.WebView
@@ -5,7 +21,7 @@ import ca.allanwang.kau.kotlin.lazyContext
import com.pitchedapps.frost.utils.L
import java.io.BufferedReader
import java.io.FileNotFoundException
-import java.util.*
+import java.util.Locale
/**
* Created by Allan Wang on 2017-05-31.
@@ -31,5 +47,4 @@ enum class JsAssets : InjectorContract {
override fun inject(webView: WebView, callback: (() -> Unit)?) {
injector(webView.context).inject(webView, callback)
}
-
}
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 acda2d9b..8ae3a2f4 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.injectors
import android.webkit.WebView
@@ -8,7 +24,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.subjects.SingleSubject
import org.apache.commons.text.StringEscapeUtils
-import java.util.*
+import java.util.Locale
class JsBuilder {
private val css = StringBuilder()
@@ -90,10 +106,10 @@ fun WebView.jsInject(vararg injectors: InjectorContract, callback: ((Int) -> Uni
}
val observables = Array(validInjectors.size) { SingleSubject.create<Unit>() }
val disposable = Single.zip<Unit, Int>(observables.asList()) { it.size }
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe { res, _ ->
- callback(res)
- }
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe { res, _ ->
+ callback(res)
+ }
(0 until validInjectors.size).forEach { i ->
validInjectors[i].inject(this) {
observables[i].onSuccess(Unit)
@@ -102,8 +118,10 @@ fun WebView.jsInject(vararg injectors: InjectorContract, callback: ((Int) -> Uni
return disposable
}
-fun FrostWebViewClient.jsInject(vararg injectors: InjectorContract,
- callback: ((Int) -> Unit)? = null) = web.jsInject(*injectors, callback = callback)
+fun FrostWebViewClient.jsInject(
+ vararg injectors: InjectorContract,
+ callback: ((Int) -> Unit)? = null
+) = web.jsInject(*injectors, callback = callback)
/**
* Wrapper class to convert a function into an injector
@@ -112,4 +130,4 @@ class JsInjector(val function: String) : InjectorContract {
override fun inject(webView: WebView, callback: (() -> Unit)?) {
webView.evaluateJavascript(function) { callback?.invoke() }
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt
index 3e40b6ba..afa8df35 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.intro
import android.os.Bundle
@@ -17,7 +33,11 @@ class IntroFragmentTheme : BaseIntroFragment(R.layout.intro_theme) {
val themeList
get() = listOf(intro_theme_light, intro_theme_dark, intro_theme_amoled, intro_theme_glass)
- override fun viewArray(): Array<Array<out View>> = arrayOf(arrayOf(title), arrayOf(intro_theme_light, intro_theme_dark), arrayOf(intro_theme_amoled, intro_theme_glass))
+ override fun viewArray(): Array<Array<out View>> = arrayOf(
+ arrayOf(title),
+ arrayOf(intro_theme_light, intro_theme_dark),
+ arrayOf(intro_theme_amoled, intro_theme_glass)
+ )
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -40,5 +60,4 @@ class IntroFragmentTheme : BaseIntroFragment(R.layout.intro_theme) {
themeList.forEach { it.animate().scaleXY(if (it == this) 1.6f else 0.8f).start() }
}
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt
index c0ccd649..1fd8c76e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.intro
import android.graphics.drawable.Drawable
@@ -5,7 +21,12 @@ import android.graphics.drawable.LayerDrawable
import android.os.Bundle
import android.view.View
import android.widget.ImageView
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.bindViewResettable
+import ca.allanwang.kau.utils.colorToForeground
+import ca.allanwang.kau.utils.setIcon
+import ca.allanwang.kau.utils.tint
+import ca.allanwang.kau.utils.visible
+import ca.allanwang.kau.utils.withAlpha
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.Prefs
@@ -15,9 +36,9 @@ import com.pitchedapps.frost.utils.launchTabCustomizerActivity
* Created by Allan Wang on 2017-07-28.
*/
abstract class BaseImageIntroFragment(
- val titleRes: Int,
- val imageRes: Int,
- val descRes: Int
+ val titleRes: Int,
+ val imageRes: Int,
+ val descRes: Int
) : BaseIntroFragment(R.layout.intro_image) {
val imageDrawable: LayerDrawable by lazyResettableRegistered { image.drawable as LayerDrawable }
@@ -68,7 +89,7 @@ abstract class BaseImageIntroFragment(
}
class IntroAccountFragment : BaseImageIntroFragment(
- R.string.intro_multiple_accounts, R.drawable.intro_phone_nav, R.string.intro_multiple_accounts_desc
+ R.string.intro_multiple_accounts, R.drawable.intro_phone_nav, R.string.intro_multiple_accounts_desc
) {
override fun themeFragmentImpl() {
@@ -85,7 +106,7 @@ class IntroAccountFragment : BaseImageIntroFragment(
}
class IntroTabTouchFragment : BaseImageIntroFragment(
- R.string.intro_easy_navigation, R.drawable.intro_phone_tab, R.string.intro_easy_navigation_desc
+ R.string.intro_easy_navigation, R.drawable.intro_phone_tab, R.string.intro_easy_navigation_desc
) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -98,14 +119,20 @@ class IntroTabTouchFragment : BaseImageIntroFragment(
override fun themeFragmentImpl() {
super.themeFragmentImpl()
- themeImageComponent(Prefs.iconColor, R.id.intro_phone_icon_1, R.id.intro_phone_icon_2, R.id.intro_phone_icon_3, R.id.intro_phone_icon_4)
+ themeImageComponent(
+ Prefs.iconColor,
+ R.id.intro_phone_icon_1,
+ R.id.intro_phone_icon_2,
+ R.id.intro_phone_icon_3,
+ R.id.intro_phone_icon_4
+ )
themeImageComponent(Prefs.headerColor, R.id.intro_phone_tab)
themeImageComponent(Prefs.textColor.withAlpha(80), R.id.intro_phone_icon_ripple)
}
}
class IntroTabContextFragment : BaseImageIntroFragment(
- R.string.intro_context_aware, R.drawable.intro_phone_long_press, R.string.intro_context_aware_desc
+ R.string.intro_context_aware, R.drawable.intro_phone_long_press, R.string.intro_context_aware_desc
) {
override fun themeFragmentImpl() {
@@ -115,11 +142,16 @@ class IntroTabContextFragment : BaseImageIntroFragment(
themeImageComponent(Prefs.bgColor.colorToForeground(0.2f), R.id.intro_phone_like, R.id.intro_phone_share)
themeImageComponent(Prefs.bgColor.colorToForeground(0.3f), R.id.intro_phone_comment)
themeImageComponent(Prefs.bgColor.colorToForeground(0.1f), R.id.intro_phone_card_1, R.id.intro_phone_card_2)
- themeImageComponent(Prefs.textColor, R.id.intro_phone_image_indicator, R.id.intro_phone_comment_indicator, R.id.intro_phone_card_indicator)
+ themeImageComponent(
+ Prefs.textColor,
+ R.id.intro_phone_image_indicator,
+ R.id.intro_phone_comment_indicator,
+ R.id.intro_phone_card_indicator
+ )
}
override fun onPageScrolledImpl(positionOffset: Float) {
super.onPageScrolledImpl(positionOffset)
lastImageFragmentTransition(positionOffset)
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt
index 6e953777..a4f9e193 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt
@@ -1,15 +1,31 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.intro
import android.annotation.SuppressLint
import android.content.res.ColorStateList
import android.os.Bundle
-import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.fragment.app.Fragment
import ca.allanwang.kau.kotlin.LazyResettableRegistry
import ca.allanwang.kau.utils.Kotterknife
import ca.allanwang.kau.utils.bindViewResettable
@@ -99,7 +115,6 @@ abstract class BaseIntroFragment(val layoutRes: Int) : Fragment() {
}
protected open fun onPageSelectedImpl() {
-
}
}
@@ -131,4 +146,4 @@ class IntroFragmentEnd : BaseIntroFragment(R.layout.intro_end) {
(activity as IntroActivity).finish(event.x, event.y)
}
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/rx/RxFlyweight.kt b/app/src/main/kotlin/com/pitchedapps/frost/rx/RxFlyweight.kt
index e8373dd6..25f6d6aa 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/rx/RxFlyweight.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/rx/RxFlyweight.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.rx
import io.reactivex.Single
@@ -72,9 +88,9 @@ abstract class RxFlyweight<in T : Any, C : Any, R : Any> {
* you likely won't have a need for flyweights
*/
protected open fun createNewSource(input: T): Single<R> =
- Single.fromCallable { call(input) }
- .timeout(15, TimeUnit.SECONDS)
- .subscribeOn(Schedulers.io())
+ Single.fromCallable { call(input) }
+ .timeout(15, TimeUnit.SECONDS)
+ .subscribeOn(Schedulers.io())
fun reset() {
synchronized(lock) {
@@ -82,5 +98,4 @@ abstract class RxFlyweight<in T : Any, C : Any, R : Any> {
conditionals.clear()
}
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt
index ededaad4..ee515a55 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.services
import android.app.Notification
@@ -26,8 +42,12 @@ import com.pitchedapps.frost.facebook.parsers.NotifParser
import com.pitchedapps.frost.facebook.parsers.ParseNotification
import com.pitchedapps.frost.glide.FrostGlide
import com.pitchedapps.frost.glide.GlideApp
-import com.pitchedapps.frost.utils.*
-import java.util.*
+import com.pitchedapps.frost.utils.ARG_USER_ID
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.frostEvent
+import com.pitchedapps.frost.utils.isIndependent
+import java.util.Locale
/**
* Created by Allan Wang on 2017-07-08.
@@ -40,33 +60,38 @@ private val _40_DP = 40.dpToPx
* Enum to handle notification creations
*/
enum class NotificationType(
- private val channelId: String,
- private val overlayContext: OverlayContext,
- private val fbItem: FbItem,
- private val parser: FrostParser<ParseNotification>,
- private val getTime: (notif: NotificationModel) -> Long,
- private val putTime: (notif: NotificationModel, time: Long) -> NotificationModel,
- private val ringtone: () -> String) {
+ private val channelId: String,
+ private val overlayContext: OverlayContext,
+ private val fbItem: FbItem,
+ private val parser: FrostParser<ParseNotification>,
+ private val getTime: (notif: NotificationModel) -> Long,
+ private val putTime: (notif: NotificationModel, time: Long) -> NotificationModel,
+ private val ringtone: () -> String
+) {
- GENERAL(NOTIF_CHANNEL_GENERAL,
- OverlayContext.NOTIFICATION,
- FbItem.NOTIFICATIONS,
- NotifParser,
- NotificationModel::epoch,
- { notif, time -> notif.copy(epoch = time) },
- Prefs::notificationRingtone) {
+ GENERAL(
+ NOTIF_CHANNEL_GENERAL,
+ OverlayContext.NOTIFICATION,
+ FbItem.NOTIFICATIONS,
+ NotifParser,
+ NotificationModel::epoch,
+ { notif, time -> notif.copy(epoch = time) },
+ Prefs::notificationRingtone
+ ) {
override fun bindRequest(content: NotificationContent, cookie: String) =
- FrostRunnable.prepareMarkNotificationRead(content.id, cookie)
+ FrostRunnable.prepareMarkNotificationRead(content.id, cookie)
},
- MESSAGE(NOTIF_CHANNEL_MESSAGES,
- OverlayContext.MESSAGE,
- FbItem.MESSAGES,
- MessageParser,
- NotificationModel::epochIm,
- { notif, time -> notif.copy(epochIm = time) },
- Prefs::messageRingtone);
+ MESSAGE(
+ NOTIF_CHANNEL_MESSAGES,
+ OverlayContext.MESSAGE,
+ FbItem.MESSAGES,
+ MessageParser,
+ NotificationModel::epochIm,
+ { notif, time -> notif.copy(epochIm = time) },
+ Prefs::messageRingtone
+ );
private val groupPrefix = "frost_${name.toLowerCase(Locale.CANADA)}"
@@ -133,13 +158,15 @@ enum class NotificationType(
}
fun debugNotification(context: Context, data: CookieModel) {
- val content = NotificationContent(data,
- System.currentTimeMillis(),
- "https://github.com/AllanWang/Frost-for-Facebook",
- "Debug Notif",
- "Test 123",
- System.currentTimeMillis() / 1000,
- "https://www.iconexperience.com/_img/v_collection_png/256x256/shadow/dog.png")
+ val content = NotificationContent(
+ data,
+ System.currentTimeMillis(),
+ "https://github.com/AllanWang/Frost-for-Facebook",
+ "Debug Notif",
+ "Test 123",
+ System.currentTimeMillis() / 1000,
+ "https://www.iconexperience.com/_img/v_collection_png/256x256/shadow/dog.png"
+ )
createNotification(context, content).notify(context)
}
@@ -147,44 +174,43 @@ enum class NotificationType(
* Create and submit a new notification with the given [content]
*/
private fun createNotification(context: Context, content: NotificationContent): FrostNotification =
- with(content) {
- val intent = Intent(context, FrostWebActivity::class.java)
- // TODO temp fix; we will show notification page for dependent urls. We can trigger a click next time
- intent.data = Uri.parse(if (href.isIndependent) href else FbItem.NOTIFICATIONS.url)
- intent.putExtra(ARG_USER_ID, data.id)
- overlayContext.put(intent)
- bindRequest(intent, content, data.cookie)
+ with(content) {
+ val intent = Intent(context, FrostWebActivity::class.java)
+ // TODO temp fix; we will show notification page for dependent urls. We can trigger a click next time
+ intent.data = Uri.parse(if (href.isIndependent) href else FbItem.NOTIFICATIONS.url)
+ intent.putExtra(ARG_USER_ID, data.id)
+ overlayContext.put(intent)
+ bindRequest(intent, content, data.cookie)
- val group = "${groupPrefix}_${data.id}"
- val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
- val notifBuilder = context.frostNotification(channelId)
- .setContentTitle(title ?: context.string(R.string.frost_name))
- .setContentText(text)
- .setContentIntent(pendingIntent)
- .setCategory(Notification.CATEGORY_SOCIAL)
- .setSubText(data.name)
- .setGroup(group)
+ val group = "${groupPrefix}_${data.id}"
+ val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
+ val notifBuilder = context.frostNotification(channelId)
+ .setContentTitle(title ?: context.string(R.string.frost_name))
+ .setContentText(text)
+ .setContentIntent(pendingIntent)
+ .setCategory(Notification.CATEGORY_SOCIAL)
+ .setSubText(data.name)
+ .setGroup(group)
- if (timestamp != -1L) notifBuilder.setWhen(timestamp * 1000)
- L.v { "Notif load $content" }
+ if (timestamp != -1L) notifBuilder.setWhen(timestamp * 1000)
+ L.v { "Notif load $content" }
- if (profileUrl != null) {
- try {
- val profileImg = GlideApp.with(context)
- .asBitmap()
- .load(profileUrl)
- .transform(FrostGlide.circleCrop)
- .submit(_40_DP, _40_DP)
- .get()
- notifBuilder.setLargeIcon(profileImg)
- } catch (e: Exception) {
- L.e { "Failed to get image $profileUrl" }
- }
+ if (profileUrl != null) {
+ try {
+ val profileImg = GlideApp.with(context)
+ .asBitmap()
+ .load(profileUrl)
+ .transform(FrostGlide.circleCrop)
+ .submit(_40_DP, _40_DP)
+ .get()
+ notifBuilder.setLargeIcon(profileImg)
+ } catch (e: Exception) {
+ L.e { "Failed to get image $profileUrl" }
}
-
- FrostNotification(group, notifId, notifBuilder)
}
+ FrostNotification(group, notifId, notifBuilder)
+ }
/**
* Create a summary notification to wrap the previous ones
@@ -198,12 +224,12 @@ enum class NotificationType(
val group = "${groupPrefix}_$userId"
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
val notifBuilder = context.frostNotification(channelId)
- .setContentTitle(context.string(R.string.frost_name))
- .setContentText("$count ${context.string(fbItem.titleId)}")
- .setGroup(group)
- .setGroupSummary(true)
- .setContentIntent(pendingIntent)
- .setCategory(Notification.CATEGORY_SOCIAL)
+ .setContentTitle(context.string(R.string.frost_name))
+ .setContentText("$count ${context.string(fbItem.titleId)}")
+ .setGroup(group)
+ .setGroupSummary(true)
+ .setContentIntent(pendingIntent)
+ .setCategory(Notification.CATEGORY_SOCIAL)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notifBuilder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN)
@@ -211,31 +237,33 @@ enum class NotificationType(
return FrostNotification(group, 1, notifBuilder)
}
-
}
/**
* Notification data holder
*/
-data class NotificationContent(val data: CookieModel,
- val id: Long,
- val href: String,
- val title: String? = null, // defaults to frost title
- val text: String,
- val timestamp: Long,
- val profileUrl: String?) {
+data class NotificationContent(
+ val data: CookieModel,
+ val id: Long,
+ val href: String,
+ val title: String? = null, // defaults to frost title
+ val text: String,
+ val timestamp: Long,
+ val profileUrl: String?
+) {
val notifId = Math.abs(id.toInt())
-
}
/**
* Wrapper for a complete notification builder and identifier
* which can be immediately notified when given a [Context]
*/
-data class FrostNotification(private val tag: String,
- private val id: Int,
- val notif: NotificationCompat.Builder) {
+data class FrostNotification(
+ private val tag: String,
+ private val id: Int,
+ val notif: NotificationCompat.Builder
+) {
fun withAlert(enable: Boolean, ringtone: String): FrostNotification {
notif.setFrostAlert(enable, ringtone)
@@ -243,15 +271,15 @@ data class FrostNotification(private val tag: String,
}
fun notify(context: Context) =
- NotificationManagerCompat.from(context).notify(tag, id, notif.build())
+ NotificationManagerCompat.from(context).notify(tag, id, notif.build())
}
const val NOTIFICATION_PERIODIC_JOB = 7
fun Context.scheduleNotifications(minutes: Long): Boolean =
- scheduleJob<NotificationService>(NOTIFICATION_PERIODIC_JOB, minutes)
+ scheduleJob<NotificationService>(NOTIFICATION_PERIODIC_JOB, minutes)
const val NOTIFICATION_JOB_NOW = 6
fun Context.fetchNotifications(): Boolean =
- fetchJob<NotificationService>(NOTIFICATION_JOB_NOW) \ No newline at end of file
+ fetchJob<NotificationService>(NOTIFICATION_JOB_NOW)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt
index b2ccaea2..22acc9fb 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.services
import android.app.job.JobInfo
@@ -37,10 +53,10 @@ private enum class FrostRequestCommands : EnumBundle<FrostRequestCommands> {
}
override fun propagate(bundle: BaseBundle) =
- FrostRunnable.prepareMarkNotificationRead(
- bundle.getLong(ARG_0),
- bundle.getCookie())
-
+ FrostRunnable.prepareMarkNotificationRead(
+ bundle.getLong(ARG_0),
+ bundle.getCookie()
+ )
};
override val bundleContract: EnumBundleCompanion<FrostRequestCommands>
@@ -58,7 +74,6 @@ private enum class FrostRequestCommands : EnumBundle<FrostRequestCommands> {
abstract fun propagate(bundle: BaseBundle): BaseBundle.() -> Unit
companion object : EnumCompanion<FrostRequestCommands>("frost_arg_commands", values())
-
}
private const val ARG_COMMAND = "frost_request_command"
@@ -99,8 +114,10 @@ object FrostRunnable {
L.d { "Invalid notification id $id for marking as read" }
return false
}
- return schedule(context, FrostRequestCommands.NOTIF_READ,
- prepareMarkNotificationRead(id, cookie))
+ return schedule(
+ context, FrostRequestCommands.NOTIF_READ,
+ prepareMarkNotificationRead(id, cookie)
+ )
}
fun propagate(context: Context, intent: Intent?) {
@@ -112,9 +129,11 @@ object FrostRunnable {
schedule(context, command, builder)
}
- private fun schedule(context: Context,
- command: FrostRequestCommands,
- bundleBuilder: PersistableBundle.() -> Unit): Boolean {
+ private fun schedule(
+ context: Context,
+ command: FrostRequestCommands,
+ bundleBuilder: PersistableBundle.() -> Unit
+ ): Boolean {
val scheduler = context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
val serviceComponent = ComponentName(context, FrostRequestService::class.java)
val bundle = PersistableBundle()
@@ -127,10 +146,10 @@ object FrostRunnable {
}
val builder = JobInfo.Builder(JOB_REQUEST_BASE + command.ordinal, serviceComponent)
- .setMinimumLatency(0L)
- .setExtras(bundle)
- .setOverrideDeadline(2000L)
- .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
+ .setMinimumLatency(0L)
+ .setExtras(bundle)
+ .setOverrideDeadline(2000L)
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
val result = scheduler.schedule(builder.build())
if (result <= 0) {
L.eThrow("FrostRequestService scheduler failed for ${command.name}")
@@ -139,7 +158,6 @@ object FrostRunnable {
L.d { "Scheduled ${command.name}" }
return true
}
-
}
class FrostRequestService : JobService() {
@@ -183,4 +201,4 @@ class FrostRequestService : JobService() {
}
return true
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt
index f15df482..4ede5163 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.services
import android.app.job.JobParameters
@@ -31,10 +47,12 @@ class NotificationService : JobService() {
override fun onStopJob(params: JobParameters?): Boolean {
val time = System.currentTimeMillis() - startTime
L.d { "Notification service has finished abruptly in $time ms" }
- frostEvent("NotificationTime",
- "Type" to "Service force stop",
- "IM Included" to Prefs.notificationsInstantMessages,
- "Duration" to time)
+ frostEvent(
+ "NotificationTime",
+ "Type" to "Service force stop",
+ "IM Included" to Prefs.notificationsInstantMessages,
+ "Duration" to time
+ )
future?.cancel(true)
future = null
return false
@@ -43,10 +61,12 @@ class NotificationService : JobService() {
fun finish(params: JobParameters?) {
val time = System.currentTimeMillis() - startTime
L.i { "Notification service has finished in $time ms" }
- frostEvent("NotificationTime",
- "Type" to "Service",
- "IM Included" to Prefs.notificationsInstantMessages,
- "Duration" to time)
+ frostEvent(
+ "NotificationTime",
+ "Type" to "Service",
+ "IM Included" to Prefs.notificationsInstantMessages,
+ "Duration" to time
+ )
jobFinished(params, false)
future?.cancel(true)
future = null
@@ -61,11 +81,13 @@ class NotificationService : JobService() {
var notifCount = 0
cookies.forEach {
val current = it.id == currentId
- if (Prefs.notificationsGeneral
- && (current || Prefs.notificationAllAccounts))
+ if (Prefs.notificationsGeneral &&
+ (current || Prefs.notificationAllAccounts)
+ )
notifCount += fetch(jobId, NotificationType.GENERAL, it)
- if (Prefs.notificationsInstantMessages
- && (current || Prefs.notificationsImAllAccounts))
+ if (Prefs.notificationsInstantMessages &&
+ (current || Prefs.notificationsImAllAccounts)
+ )
notifCount += fetch(jobId, NotificationType.MESSAGE, it)
}
@@ -99,10 +121,9 @@ class NotificationService : JobService() {
private fun generalNotification(id: Int, textRes: Int, withDefaults: Boolean) {
val notifBuilder = frostNotification(NOTIF_CHANNEL_GENERAL)
- .setFrostAlert(withDefaults, Prefs.notificationRingtone)
- .setContentTitle(string(R.string.frost_name))
- .setContentText(string(textRes))
+ .setFrostAlert(withDefaults, Prefs.notificationRingtone)
+ .setContentTitle(string(R.string.frost_name))
+ .setContentText(string(textRes))
NotificationManagerCompat.from(this).notify(id, notifBuilder.build())
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationUtils.kt
index 707220f6..20a497e3 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationUtils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationUtils.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.services
import android.app.Notification
@@ -31,11 +47,11 @@ fun setupNotificationChannels(c: Context) {
val appName = c.string(R.string.frost_name)
val msg = c.string(R.string.messages)
manager.notificationChannels
- .filter {
- it.id != NOTIF_CHANNEL_GENERAL
- && it.id != NOTIF_CHANNEL_MESSAGES
- }
- .forEach { manager.deleteNotificationChannel(it.id) }
+ .filter {
+ it.id != NOTIF_CHANNEL_GENERAL &&
+ it.id != NOTIF_CHANNEL_MESSAGES
+ }
+ .forEach { manager.deleteNotificationChannel(it.id) }
manager.createNotificationChannel(NOTIF_CHANNEL_GENERAL, appName)
manager.createNotificationChannel(NOTIF_CHANNEL_MESSAGES, "$appName: $msg")
L.d { "Created notification channels: ${manager.notificationChannels.size} channels, ${manager.notificationChannelGroups.size} groups" }
@@ -43,8 +59,10 @@ fun setupNotificationChannels(c: Context) {
@RequiresApi(Build.VERSION_CODES.O)
private fun NotificationManager.createNotificationChannel(id: String, name: String): NotificationChannel {
- val channel = NotificationChannel(id,
- name, NotificationManager.IMPORTANCE_DEFAULT)
+ val channel = NotificationChannel(
+ id,
+ name, NotificationManager.IMPORTANCE_DEFAULT
+ )
channel.enableLights(true)
channel.lightColor = Prefs.accentColor
channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
@@ -53,14 +71,14 @@ private fun NotificationManager.createNotificationChannel(id: String, name: Stri
}
fun Context.frostNotification(id: String) =
- NotificationCompat.Builder(this, id)
- .apply {
- setSmallIcon(R.drawable.frost_f_24)
- setAutoCancel(true)
- setOnlyAlertOnce(true)
- setStyle(NotificationCompat.BigTextStyle())
- color = color(R.color.frost_notification_accent)
- }
+ NotificationCompat.Builder(this, id)
+ .apply {
+ setSmallIcon(R.drawable.frost_f_24)
+ setAutoCancel(true)
+ setOnlyAlertOnce(true)
+ setStyle(NotificationCompat.BigTextStyle())
+ color = color(R.color.frost_notification_accent)
+ }
/**
* Dictates whether a notification should have sound/vibration/lights or not
@@ -70,8 +88,9 @@ fun Context.frostNotification(id: String) =
fun NotificationCompat.Builder.setFrostAlert(enable: Boolean, ringtone: String): NotificationCompat.Builder {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setGroupAlertBehavior(
- if (enable) NotificationCompat.GROUP_ALERT_CHILDREN
- else NotificationCompat.GROUP_ALERT_SUMMARY)
+ if (enable) NotificationCompat.GROUP_ALERT_CHILDREN
+ else NotificationCompat.GROUP_ALERT_SUMMARY
+ )
} else if (!enable) {
setDefaults(0)
} else {
@@ -111,10 +130,10 @@ inline fun <reified T : JobService> Context.scheduleJob(id: Int, minutes: Long):
if (minutes < 0L) return true
val serviceComponent = ComponentName(this, T::class.java)
val builder = JobInfo.Builder(id, serviceComponent)
- .setPeriodic(minutes * 60000)
- .setExtras(id)
- .setPersisted(true)
- .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) //TODO add options
+ .setPeriodic(minutes * 60000)
+ .setExtras(id)
+ .setPersisted(true)
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) //TODO add options
val result = scheduler.schedule(builder.build())
if (result <= 0) {
L.eThrow("${T::class.java.simpleName} scheduler failed")
@@ -130,10 +149,10 @@ inline fun <reified T : JobService> Context.fetchJob(id: Int): Boolean {
val scheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
val serviceComponent = ComponentName(this, T::class.java)
val builder = JobInfo.Builder(id, serviceComponent)
- .setMinimumLatency(0L)
- .setExtras(id)
- .setOverrideDeadline(2000L)
- .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
+ .setMinimumLatency(0L)
+ .setExtras(id)
+ .setOverrideDeadline(2000L)
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
val result = scheduler.schedule(builder.build())
if (result <= 0) {
L.eThrow("${T::class.java.simpleName} instant scheduler failed")
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/UpdateReceiver.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/UpdateReceiver.kt
index 59df9ed7..2d86f3b9 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/services/UpdateReceiver.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/services/UpdateReceiver.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.services
import android.content.BroadcastReceiver
@@ -18,5 +34,4 @@ class UpdateReceiver : BroadcastReceiver() {
L.d { "Frost has updated" }
context.scheduleNotifications(Prefs.notificationFreq) //Update notifications
}
-
-} \ 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 9253d926..538e20f1 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.settings
import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
@@ -10,7 +26,16 @@ import com.pitchedapps.frost.activities.SettingsActivity
import com.pitchedapps.frost.enums.MainActivityLayout
import com.pitchedapps.frost.enums.Theme
import com.pitchedapps.frost.injectors.CssAssets
-import com.pitchedapps.frost.utils.*
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.REQUEST_NAV
+import com.pitchedapps.frost.utils.REQUEST_REFRESH
+import com.pitchedapps.frost.utils.REQUEST_TEXT_ZOOM
+import com.pitchedapps.frost.utils.frostEvent
+import com.pitchedapps.frost.utils.frostNavigationBar
+import com.pitchedapps.frost.utils.frostSnackbar
+import com.pitchedapps.frost.utils.launchTabCustomizerActivity
+import com.pitchedapps.frost.utils.materialDialogThemed
+import com.pitchedapps.frost.utils.setFrostTheme
import com.pitchedapps.frost.views.KPrefTextSeekbar
/**
@@ -74,7 +99,6 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
allowCustomAlpha = false
}
-
colorPicker(R.string.background_color, Prefs::customBackgroundColor, {
Prefs.customBackgroundColor = it
bgCanvas.ripple(it, duration = 500L)
@@ -146,17 +170,20 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
descRes = R.string.tint_nav_desc
}
- list.add(KPrefTextSeekbar(
+ list.add(
+ KPrefTextSeekbar(
KPrefSeekbar.KPrefSeekbarBuilder(
- globalOptions,
- R.string.web_text_scaling, Prefs::webTextScaling) {
+ globalOptions,
+ R.string.web_text_scaling, Prefs::webTextScaling
+ ) {
Prefs.webTextScaling = it
setFrostResult(REQUEST_TEXT_ZOOM)
- }))
+ })
+ )
checkbox(R.string.enforce_black_media_bg, Prefs::blackMediaBg, {
Prefs.blackMediaBg = it
}) {
descRes = R.string.enforce_black_media_bg_desc
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt
index 02a86e58..10fa5c99 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.settings
import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
@@ -15,7 +31,10 @@ fun SettingsActivity.getBehaviourPrefs(): KPrefAdapterBuilder.() -> Unit = {
descRes = R.string.fancy_animations_desc
}
- checkbox(R.string.overlay_swipe, Prefs::overlayEnabled, { Prefs.overlayEnabled = it; setFrostResult(REQUEST_REFRESH) }) {
+ checkbox(
+ R.string.overlay_swipe,
+ Prefs::overlayEnabled,
+ { Prefs.overlayEnabled = it; setFrostResult(REQUEST_REFRESH) }) {
descRes = R.string.overlay_swipe_desc
}
@@ -46,5 +65,4 @@ fun SettingsActivity.getBehaviourPrefs(): KPrefAdapterBuilder.() -> Unit = {
checkbox(R.string.analytics, Prefs::analytics, { Prefs.analytics = it }) {
descRes = R.string.analytics_desc
}
-
}
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 91dac242..4b538e87 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.settings
import android.content.Context
@@ -77,25 +93,26 @@ fun SettingsActivity.getDebugPrefs(): KPrefAdapterBuilder.() -> Unit = {
}
}
}
-
}
}
}
private fun Context.createEmail(parser: FrostParser<*>, content: Any?) =
- sendFrostEmail("${string(R.string.debug_report)}: ${parser::class.java.simpleName}") {
- addItem("Url", parser.url)
- addItem("Contents", "$content")
- }
+ sendFrostEmail("${string(R.string.debug_report)}: ${parser::class.java.simpleName}") {
+ addItem("Url", parser.url)
+ addItem("Contents", "$content")
+ }
private const val ZIP_NAME = "debug"
fun SettingsActivity.sendDebug(url: String, html: String?) {
- val downloader = OfflineWebsite(url, FbCookie.webCookie ?: "",
- baseUrl = FB_URL_BASE,
- html = html,
- baseDir = DebugActivity.baseDir(this))
+ val downloader = OfflineWebsite(
+ url, FbCookie.webCookie ?: "",
+ baseUrl = FB_URL_BASE,
+ html = html,
+ baseDir = DebugActivity.baseDir(this)
+ )
val md = materialDialog {
title(R.string.parsing_data)
@@ -114,7 +131,8 @@ fun SettingsActivity.sendDebug(url: String, html: String?) {
it.dismiss()
if (success) {
val zipUri = it.context.frostUriFromFile(
- File(downloader.baseDir, "$ZIP_NAME.zip"))
+ File(downloader.baseDir, "$ZIP_NAME.zip")
+ )
L.i { "Sending debug zip with uri $zipUri" }
sendFrostEmail(R.string.debug_report_email_title) {
addItem("Url", url)
@@ -128,7 +146,5 @@ fun SettingsActivity.sendDebug(url: String, html: String?) {
}
}
}
-
}
-
}
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 fe95e7f1..e0d314a8 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.settings
import android.util.Log
@@ -24,7 +40,6 @@ fun SettingsActivity.getExperimentalPrefs(): KPrefAdapterBuilder.() -> Unit = {
// Experimental content starts here ------------------
-
// Experimental content ends here --------------------
checkbox(R.string.verbose_logging, Prefs::verboseLogging, {
@@ -41,4 +56,4 @@ fun SettingsActivity.getExperimentalPrefs(): KPrefAdapterBuilder.() -> Unit = {
finish()
}
}
-} \ 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 402322ad..ff0badf0 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.settings
import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
@@ -66,4 +82,4 @@ fun SettingsActivity.getFeedPrefs(): KPrefAdapterBuilder.() -> Unit = {
}) {
descRes = R.string.facebook_ads_desc
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Network.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Network.kt
index b5515a52..a1ec33e6 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Network.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Network.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.settings
import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
@@ -10,8 +26,10 @@ import com.pitchedapps.frost.utils.Prefs
*/
fun SettingsActivity.getNetworkPrefs(): KPrefAdapterBuilder.() -> Unit = {
- checkbox(R.string.network_media_on_metered, { !Prefs.loadMediaOnMeteredNetwork }, { Prefs.loadMediaOnMeteredNetwork = !it }) {
+ checkbox(
+ R.string.network_media_on_metered,
+ { !Prefs.loadMediaOnMeteredNetwork },
+ { Prefs.loadMediaOnMeteredNetwork = !it }) {
descRes = R.string.network_media_on_metered_desc
}
-
-} \ No newline at end of file
+}
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 1f9411e4..0200f109 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.settings
import android.annotation.SuppressLint
@@ -22,7 +38,6 @@ import com.pitchedapps.frost.utils.frostSnackbar
import com.pitchedapps.frost.utils.materialDialogThemed
import com.pitchedapps.frost.views.Keywords
-
/**
* Created by Allan Wang on 2017-06-29.
*/
@@ -66,33 +81,33 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
}
checkbox(R.string.notification_general, Prefs::notificationsGeneral,
- {
- Prefs.notificationsGeneral = it
- reloadByTitle(R.string.notification_general_all_accounts)
- if (!Prefs.notificationsInstantMessages)
- reloadByTitle(R.string.notification_frequency)
- }) {
+ {
+ Prefs.notificationsGeneral = it
+ reloadByTitle(R.string.notification_general_all_accounts)
+ if (!Prefs.notificationsInstantMessages)
+ reloadByTitle(R.string.notification_frequency)
+ }) {
descRes = R.string.notification_general_desc
}
checkbox(R.string.notification_general_all_accounts, Prefs::notificationAllAccounts,
- { Prefs.notificationAllAccounts = it }) {
+ { Prefs.notificationAllAccounts = it }) {
descRes = R.string.notification_general_all_accounts_desc
enabler = Prefs::notificationsGeneral
}
checkbox(R.string.notification_messages, Prefs::notificationsInstantMessages,
- {
- Prefs.notificationsInstantMessages = it
- reloadByTitle(R.string.notification_messages_all_accounts)
- if (!Prefs.notificationsGeneral)
- reloadByTitle(R.string.notification_frequency)
- }) {
+ {
+ Prefs.notificationsInstantMessages = it
+ reloadByTitle(R.string.notification_messages_all_accounts)
+ if (!Prefs.notificationsGeneral)
+ reloadByTitle(R.string.notification_frequency)
+ }) {
descRes = R.string.notification_messages_desc
}
checkbox(R.string.notification_messages_all_accounts, Prefs::notificationsImAllAccounts,
- { Prefs.notificationsImAllAccounts = it }) {
+ { Prefs.notificationsImAllAccounts = it }) {
descRes = R.string.notification_messages_all_accounts_desc
enabler = Prefs::notificationsInstantMessages
}
@@ -102,15 +117,17 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
descRes = R.string.notification_channel_desc
onClick = {
val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
- .putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
+ .putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
startActivity(intent)
}
}
} else {
checkbox(R.string.notification_sound, Prefs::notificationSound, {
Prefs.notificationSound = it
- reloadByTitle(R.string.notification_ringtone,
- R.string.message_ringtone)
+ reloadByTitle(
+ R.string.notification_ringtone,
+ R.string.message_ringtone
+ )
})
fun KPrefText.KPrefTextContract<String>.ringtone(code: Int) {
@@ -118,8 +135,8 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
textGetter = {
if (it.isBlank()) string(R.string.kau_default)
else RingtoneManager.getRingtone(this@getNotificationPrefs, Uri.parse(it))
- ?.getTitle(this@getNotificationPrefs)
- ?: "---" //todo figure out why this happens
+ ?.getTitle(this@getNotificationPrefs)
+ ?: "---" //todo figure out why this happens
}
onClick = {
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER).apply {
@@ -135,20 +152,20 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
}
text(R.string.notification_ringtone, Prefs::notificationRingtone,
- { Prefs.notificationRingtone = it }) {
+ { Prefs.notificationRingtone = it }) {
ringtone(SettingsActivity.REQUEST_NOTIFICATION_RINGTONE)
}
text(R.string.message_ringtone, Prefs::messageRingtone,
- { Prefs.messageRingtone = it }) {
+ { Prefs.messageRingtone = it }) {
ringtone(SettingsActivity.REQUEST_MESSAGE_RINGTONE)
}
checkbox(R.string.notification_vibrate, Prefs::notificationVibrate,
- { Prefs.notificationVibrate = it })
+ { Prefs.notificationVibrate = it })
checkbox(R.string.notification_lights, Prefs::notificationLights,
- { Prefs.notificationLights = it })
+ { Prefs.notificationLights = it })
}
if (BuildConfig.DEBUG) {
@@ -165,10 +182,9 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
descRes = R.string.notification_fetch_now_desc
onClick = {
val text =
- if (fetchNotifications()) R.string.notification_fetch_success
- else R.string.notification_fetch_fail
+ if (fetchNotifications()) R.string.notification_fetch_success
+ else R.string.notification_fetch_fail
frostSnackbar(text)
}
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt
index 1bb0449b..61a90024 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import android.content.Context
@@ -45,4 +61,4 @@ open class AdBlocker(val assetPath: String) {
if (host.contains(host)) return true
return isAdHost(host.substring(index + 1))
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/AnimatedVectorDelegate.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/AnimatedVectorDelegate.kt
index 223eed3f..c9e64eb3 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/AnimatedVectorDelegate.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/AnimatedVectorDelegate.kt
@@ -1,8 +1,24 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import android.graphics.drawable.AnimatedVectorDrawable
-import androidx.annotation.DrawableRes
import android.widget.ImageView
+import androidx.annotation.DrawableRes
import ca.allanwang.kau.utils.drawable
/**
@@ -23,23 +39,23 @@ interface AnimatedVectorContract {
}
class AnimatedVectorDelegate(
- /**
- * The res for the starting resource; must have parent tag animated-vector
- */
- @param:DrawableRes val avdStart: Int,
- /**
- * The res for the ending resource; must have parent tag animated-vector
- */
- @param:DrawableRes val avdEnd: Int,
- /**
- * The delegate will automatically set the start resource when bound
- * If [emitOnBind] is true, it will also trigger the listener
- */
- val emitOnBind: Boolean = true,
- /**
- * The optional listener that will be triggered every time the avd is switched by the delegate
- */
- override var animatedVectorListener: ((avd: AnimatedVectorDrawable, forwards: Boolean) -> Unit)? = null
+ /**
+ * The res for the starting resource; must have parent tag animated-vector
+ */
+ @param:DrawableRes val avdStart: Int,
+ /**
+ * The res for the ending resource; must have parent tag animated-vector
+ */
+ @param:DrawableRes val avdEnd: Int,
+ /**
+ * The delegate will automatically set the start resource when bound
+ * If [emitOnBind] is true, it will also trigger the listener
+ */
+ val emitOnBind: Boolean = true,
+ /**
+ * The optional listener that will be triggered every time the avd is switched by the delegate
+ */
+ override var animatedVectorListener: ((avd: AnimatedVectorDrawable, forwards: Boolean) -> Unit)? = null
) : AnimatedVectorContract {
lateinit var view: ImageView
@@ -55,9 +71,9 @@ class AnimatedVectorDelegate(
override fun bind(view: ImageView) {
this.view = view
view.context.drawable(avdStart) as? AnimatedVectorDrawable
- ?: throw IllegalArgumentException("AnimatedVectorDelegate has a starting drawable that isn't an avd")
+ ?: throw IllegalArgumentException("AnimatedVectorDelegate has a starting drawable that isn't an avd")
view.context.drawable(avdEnd) as? AnimatedVectorDrawable
- ?: throw IllegalArgumentException("AnimatedVectorDelegate has an ending drawable that isn't an avd")
+ ?: throw IllegalArgumentException("AnimatedVectorDelegate has an ending drawable that isn't an avd")
view.setImageResource(avdStart)
if (emitOnBind) animatedVectorListener?.invoke(avd!!, false)
}
@@ -70,15 +86,11 @@ class AnimatedVectorDelegate(
private fun animateImpl(toStart: Boolean) {
if ((atStart == toStart)) return L.d { "AVD already at ${if (toStart) "start" else "end"}" }
- if (avd == null) return L.d { "AVD null resource" }//no longer using animated vector; do not modify
+ if (avd == null) return L.d { "AVD null resource" } //no longer using animated vector; do not modify
avd?.stop()
view.setImageResource(if (toStart) avdEnd else avdStart)
animatedVectorListener?.invoke(avd!!, !toStart)
atStart = toStart
avd?.start()
}
-
}
-
-
-
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/BuildUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/BuildUtils.kt
index c9a2f285..33da56f2 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/BuildUtils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/BuildUtils.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
object BuildUtils {
@@ -18,8 +34,7 @@ object BuildUtils {
}
fun getAllStages(): Array<String> =
- arrayOf(BUILD_PRODUCTION, BUILD_TEST, BUILD_GITHUB, BUILD_RELEASE, BUILD_UNNAMED)
+ arrayOf(BUILD_PRODUCTION, BUILD_TEST, BUILD_GITHUB, BUILD_RELEASE, BUILD_UNNAMED)
fun getStage(build: String): String = build.takeIf { it in getAllStages() } ?: BUILD_UNNAMED
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt
index 0cb57ed5..3c76759c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
/**
@@ -15,4 +31,4 @@ const val REQUEST_TEXT_ZOOM = 1 shl 14
const val REQUEST_NAV = 1 shl 15
const val REQUEST_SEARCH = 1 shl 16
-const val MAIN_TIMEOUT_DURATION = 30 * 60 * 1000 // 30 min \ No newline at end of file
+const val MAIN_TIMEOUT_DURATION = 30 * 60 * 1000 // 30 min
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 16b1d149..f4baa242 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import android.app.DownloadManager
@@ -16,26 +32,29 @@ import com.pitchedapps.frost.R
import com.pitchedapps.frost.dbflow.loadFbCookie
import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
-
/**
* Created by Allan Wang on 2017-08-04.
*
* With reference to <a href="https://stackoverflow.com/questions/33434532/android-webview-download-files-like-browsers-do">Stack Overflow</a>
*/
-fun Context.frostDownload(url: String?,
- userAgent: String = USER_AGENT_BASIC,
- contentDisposition: String? = null,
- mimeType: String? = null,
- contentLength: Long = 0L) {
+fun Context.frostDownload(
+ url: String?,
+ userAgent: String = USER_AGENT_BASIC,
+ contentDisposition: String? = null,
+ mimeType: String? = null,
+ contentLength: Long = 0L
+) {
url ?: return
frostDownload(Uri.parse(url), userAgent, contentDisposition, mimeType, contentLength)
}
-fun Context.frostDownload(uri: Uri?,
- userAgent: String = USER_AGENT_BASIC,
- contentDisposition: String? = null,
- mimeType: String? = null,
- contentLength: Long = 0L) {
+fun Context.frostDownload(
+ uri: Uri?,
+ userAgent: String = USER_AGENT_BASIC,
+ contentDisposition: String? = null,
+ mimeType: String? = null,
+ contentLength: Long = 0L
+) {
uri ?: return
L.d { "Received download request" }
if (uri.scheme != "http" && uri.scheme != "https") {
@@ -75,4 +94,4 @@ fun Context.frostDownload(uri: Uri?,
}
}
-private const val DOWNLOAD_MANAGER_PACKAGE = "com.android.providers.downloads" \ No newline at end of file
+private const val DOWNLOAD_MANAGER_PACKAGE = "com.android.providers.downloads"
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/EnumUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/EnumUtils.kt
index 2a562ba2..b6d9b833 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/EnumUtils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/EnumUtils.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import android.content.Intent
@@ -39,12 +55,12 @@ interface EnumBundleCompanion<E : Enum<E>> {
operator fun get(bundle: BaseBundle?) = get(bundle?.getString(argTag))
operator fun get(intent: Intent?) = get(intent?.getStringExtra(argTag))
-
}
open class EnumCompanion<E : Enum<E>>(
- final override val argTag: String,
- final override val values: Array<E>) : EnumBundleCompanion<E> {
+ final override val argTag: String,
+ final override val values: Array<E>
+) : EnumBundleCompanion<E> {
final override val valueMap: Map<String, E> = values.map { it.name to it }.toMap()
@@ -53,5 +69,4 @@ open class EnumCompanion<E : Enum<E>>(
final override fun get(bundle: BaseBundle?) = super.get(bundle)
final override fun get(intent: Intent?) = super.get(intent)
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/JsoupCleaner.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/JsoupCleaner.kt
index da8672f4..c783a842 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/JsoupCleaner.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/JsoupCleaner.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import org.jsoup.Jsoup
@@ -21,8 +37,10 @@ internal fun String.cleanJsoup(): String = Jsoup.clean(this, PrivacyWhitelist())
class PrivacyWhitelist : Whitelist() {
val blacklistAttrs = arrayOf("style", "aria-label", "rel")
- val blacklistTags = arrayOf("body", "html", "head", "i", "b", "u", "style", "script",
- "br", "p", "span", "ul", "ol", "li")
+ val blacklistTags = arrayOf(
+ "body", "html", "head", "i", "b", "u", "style", "script",
+ "br", "p", "span", "ul", "ol", "li"
+ )
override fun isSafeAttribute(tagName: String, el: Element, attr: Attribute): Boolean {
val key = attr.key
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt
index bee2f49b..8364c34e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import android.util.Log
@@ -5,7 +21,6 @@ import ca.allanwang.kau.logging.KauLogger
import com.bugsnag.android.Bugsnag
import com.pitchedapps.frost.BuildConfig
-
/**
* Created by Allan Wang on 2017-05-28.
*
@@ -45,5 +60,4 @@ object L : KauLogger("Frost", {
Bugsnag.notify(t)
}
}
-
-} \ 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 9f068a58..303142af 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import android.graphics.Color
@@ -71,8 +87,8 @@ object Prefs : KPref() {
get() = Prefs.bgColor.withAlpha(30)
fun nativeBgColor(unread: Boolean) = Prefs.bgColor
- .colorToForeground(if (unread) 0.7f else 0.0f)
- .withAlpha(30)
+ .colorToForeground(if (unread) 0.7f else 0.0f)
+ .withAlpha(30)
val bgColor: Int
get() = t.bgColor
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Showcase.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Showcase.kt
index cafba223..27016018 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Showcase.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Showcase.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import ca.allanwang.kau.kpref.KPref
@@ -21,4 +37,3 @@ object Showcase : KPref() {
override fun deleteKeys() = arrayOf("shown_release")
}
-
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 650f277b..56c1d6d9 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import android.annotation.SuppressLint
@@ -8,33 +24,59 @@ import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
-import androidx.annotation.StringRes
-import com.google.android.material.snackbar.Snackbar
-import androidx.core.content.FileProvider
-import androidx.appcompat.widget.Toolbar
import android.view.View
import android.widget.FrameLayout
import android.widget.TextView
+import androidx.annotation.StringRes
+import androidx.appcompat.widget.Toolbar
+import androidx.core.content.FileProvider
import ca.allanwang.kau.email.EmailBuilder
import ca.allanwang.kau.email.sendEmail
import ca.allanwang.kau.mediapicker.createMediaFile
import ca.allanwang.kau.mediapicker.createPrivateMediaFile
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.adjustAlpha
+import ca.allanwang.kau.utils.colorToForeground
+import ca.allanwang.kau.utils.darken
+import ca.allanwang.kau.utils.isColorDark
+import ca.allanwang.kau.utils.lighten
+import ca.allanwang.kau.utils.navigationBarColor
+import ca.allanwang.kau.utils.snackbar
+import ca.allanwang.kau.utils.startActivity
+import ca.allanwang.kau.utils.startActivityForResult
+import ca.allanwang.kau.utils.statusBarColor
+import ca.allanwang.kau.utils.string
+import ca.allanwang.kau.utils.with
+import ca.allanwang.kau.utils.withAlpha
+import ca.allanwang.kau.utils.withMinAlpha
import ca.allanwang.kau.xml.showChangelog
import com.afollestad.materialdialogs.MaterialDialog
+import com.google.android.material.snackbar.Snackbar
import com.google.android.material.snackbar.SnackbarContentLayout
import com.pitchedapps.frost.BuildConfig
import com.pitchedapps.frost.R
-import com.pitchedapps.frost.activities.*
+import com.pitchedapps.frost.activities.ImageActivity
+import com.pitchedapps.frost.activities.LoginActivity
+import com.pitchedapps.frost.activities.SelectorActivity
+import com.pitchedapps.frost.activities.SettingsActivity
+import com.pitchedapps.frost.activities.TabCustomizerActivity
+import com.pitchedapps.frost.activities.WebOverlayActivity
+import com.pitchedapps.frost.activities.WebOverlayActivityBase
+import com.pitchedapps.frost.activities.WebOverlayBasicActivity
import com.pitchedapps.frost.dbflow.CookieModel
-import com.pitchedapps.frost.facebook.*
+import com.pitchedapps.frost.facebook.FACEBOOK_COM
+import com.pitchedapps.frost.facebook.FBCDN_NET
+import com.pitchedapps.frost.facebook.FbCookie
+import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.facebook.FbUrlFormatter.Companion.VIDEO_REDIRECT
+import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
+import com.pitchedapps.frost.facebook.formattedFbUrl
import org.apache.commons.text.StringEscapeUtils
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import java.io.File
import java.io.IOException
-import java.util.*
+import java.util.ArrayList
+import java.util.Locale
/**
* Created by Allan Wang on 2017-06-03.
@@ -46,7 +88,10 @@ const val ARG_IMAGE_URL = "arg_image_url"
const val ARG_TEXT = "arg_text"
const val ARG_COOKIE = "arg_cookie"
-inline fun <reified T : Activity> Context.launchNewTask(cookieList: ArrayList<CookieModel> = arrayListOf(), clearStack: Boolean = false) {
+inline fun <reified T : Activity> Context.launchNewTask(
+ cookieList: ArrayList<CookieModel> = arrayListOf(),
+ clearStack: Boolean = false
+) {
startActivity<T>(clearStack, intentBuilder = {
putParcelableArrayListExtra(EXTRA_COOKIES, cookieList)
})
@@ -81,8 +126,10 @@ fun Context.launchWebOverlay(url: String) = launchWebOverlayImpl<WebOverlayActiv
fun Context.launchWebOverlayBasic(url: String) = launchWebOverlayImpl<WebOverlayBasicActivity>(url)
-private fun Context.fadeBundle() = ActivityOptions.makeCustomAnimation(this,
- android.R.anim.fade_in, android.R.anim.fade_out).toBundle()
+private fun Context.fadeBundle() = ActivityOptions.makeCustomAnimation(
+ this,
+ android.R.anim.fade_in, android.R.anim.fade_out
+).toBundle()
fun Context.launchImageActivity(imageUrl: String, text: String? = null, cookie: String? = null) {
startActivity<ImageActivity>(intentBuilder = {
@@ -174,7 +221,6 @@ inline fun Activity.setFrostColors(builder: ActivityThemeUtils.() -> Unit) {
themer.theme(this)
}
-
fun frostEvent(name: String, vararg events: Pair<String, Any>) {
// todo bind
L.v { "Event: $name ${events.joinToString(", ")}" }
@@ -189,9 +235,11 @@ fun Throwable?.logFrostEvent(text: String) {
frostEvent("Errors", "text" to text, "message" to (this?.message ?: "NA"))
}
-fun Activity.frostSnackbar(@StringRes text: Int, builder: Snackbar.() -> Unit = {}) = snackbar(text, Snackbar.LENGTH_LONG, frostSnackbar(builder))
+fun Activity.frostSnackbar(@StringRes text: Int, builder: Snackbar.() -> Unit = {}) =
+ snackbar(text, Snackbar.LENGTH_LONG, frostSnackbar(builder))
-fun View.frostSnackbar(@StringRes text: Int, builder: Snackbar.() -> Unit = {}) = snackbar(text, Snackbar.LENGTH_LONG, frostSnackbar(builder))
+fun View.frostSnackbar(@StringRes text: Int, builder: Snackbar.() -> Unit = {}) =
+ snackbar(text, Snackbar.LENGTH_LONG, frostSnackbar(builder))
@SuppressLint("RestrictedApi")
private inline fun frostSnackbar(crossinline builder: Snackbar.() -> Unit): Snackbar.() -> Unit = {
@@ -240,7 +288,7 @@ inline val String?.isFacebookUrl
*/
inline val String.isVideoUrl
get() = startsWith(VIDEO_REDIRECT) ||
- (startsWith("https://video-") && contains(FBCDN_NET))
+ (startsWith("https://video-") && contains(FBCDN_NET))
/**
* [true] if url directly leads to a usable image
@@ -271,22 +319,22 @@ inline val String?.isIndependent: Boolean
}
val dependentSegments = arrayOf(
- "photoset_token", "direct_action_execute", "messages/?pageNum", "sharer.php",
- "events/permalink", "events/feed/watch",
- /*
- * Add new members to groups
- */
- "madminpanel",
- /**
- * Editing images
- */
- "/confirmation/?",
- /*
- * Facebook messages have the following cases for the tid query
- * mid* or id* for newer threads, which can be launched in new windows
- * or a hash for old threads, which must be loaded on old threads
- */
- "messages/read/?tid=id", "messages/read/?tid=mid"
+ "photoset_token", "direct_action_execute", "messages/?pageNum", "sharer.php",
+ "events/permalink", "events/feed/watch",
+ /*
+ * Add new members to groups
+ */
+ "madminpanel",
+ /**
+ * Editing images
+ */
+ "/confirmation/?",
+ /*
+ * Facebook messages have the following cases for the tid query
+ * mid* or id* for newer threads, which can be launched in new windows
+ * or a hash for old threads, which must be loaded on old threads
+ */
+ "messages/read/?tid=id", "messages/read/?tid=mid"
)
inline val String?.isExplicitIntent
@@ -297,16 +345,20 @@ fun Context.frostChangelog() = showChangelog(R.xml.frost_changelog, Prefs.textCo
}
fun Context.frostUriFromFile(file: File): Uri =
- FileProvider.getUriForFile(this,
- BuildConfig.APPLICATION_ID + ".provider",
- file)
-
-inline fun Context.sendFrostEmail(@StringRes subjectId: Int, crossinline builder: EmailBuilder.() -> Unit) = sendFrostEmail(string(subjectId), builder)
-
-inline fun Context.sendFrostEmail(subjectId: String, crossinline builder: EmailBuilder.() -> Unit) = sendEmail(string(R.string.dev_email), subjectId) {
- builder()
- addFrostDetails()
-}
+ FileProvider.getUriForFile(
+ this,
+ BuildConfig.APPLICATION_ID + ".provider",
+ file
+ )
+
+inline fun Context.sendFrostEmail(@StringRes subjectId: Int, crossinline builder: EmailBuilder.() -> Unit) =
+ sendFrostEmail(string(subjectId), builder)
+
+inline fun Context.sendFrostEmail(subjectId: String, crossinline builder: EmailBuilder.() -> Unit) =
+ sendEmail(string(R.string.dev_email), subjectId) {
+ builder()
+ addFrostDetails()
+ }
fun EmailBuilder.addFrostDetails() {
addItem("Prev version", Prefs.prevVersionCode.toString())
@@ -318,7 +370,8 @@ fun EmailBuilder.addFrostDetails() {
fun frostJsoup(url: String) = frostJsoup(FbCookie.webCookie, url)
-fun frostJsoup(cookie: String?, url: String) = Jsoup.connect(url).cookie(FACEBOOK_COM, cookie).userAgent(USER_AGENT_BASIC).get()!!
+fun frostJsoup(cookie: String?, url: String) =
+ Jsoup.connect(url).cookie(FACEBOOK_COM, cookie).userAgent(USER_AGENT_BASIC).get()!!
fun Element.first(vararg select: String): Element? {
select.forEach {
@@ -346,6 +399,6 @@ fun File.createFreshDir(): Boolean {
}
fun String.unescapeHtml(): String =
- StringEscapeUtils.unescapeXml(this)
- .replace("\\u003C", "<")
- .replace("\\\"", "\"")
+ StringEscapeUtils.unescapeXml(this)
+ .replace("\\u003C", "<")
+ .replace("\\\"", "\"")
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/WebContextMenu.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/WebContextMenu.kt
index dc2d7549..62330e4d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/WebContextMenu.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/WebContextMenu.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import android.content.Context
@@ -41,7 +57,9 @@ class WebContext(val unformattedUrl: String, val text: String?) {
enum class WebContextType(val textId: Int, val onClick: (c: Context, wc: WebContext) -> Unit) {
OPEN_LINK(R.string.open_link, { c, wc -> c.launchWebOverlay(wc.unformattedUrl) }),
COPY_LINK(R.string.copy_link, { c, wc -> c.copyToClipboard(wc.url) }),
- COPY_TEXT(R.string.copy_text, { c, wc -> if (wc.text != null) c.copyToClipboard(wc.text) else c.toast(R.string.no_text) }),
+ COPY_TEXT(
+ R.string.copy_text,
+ { c, wc -> if (wc.text != null) c.copyToClipboard(wc.text) else c.toast(R.string.no_text) }),
SHARE_LINK(R.string.share_link, { c, wc -> c.shareText(wc.url) }),
DEBUG_LINK(R.string.debug_link, { c, wc ->
c.materialDialogThemed {
@@ -63,4 +81,4 @@ enum class WebContextType(val textId: Int, val onClick: (c: Context, wc: WebCont
val values = values()
operator fun get(index: Int) = values[index]
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt
index 9f6d0c06..d7a7de0e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt
@@ -1,12 +1,32 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.views
import android.graphics.drawable.Drawable
-import androidx.appcompat.widget.AppCompatTextView
-import androidx.recyclerview.widget.RecyclerView
import android.view.View
import android.widget.ImageView
+import androidx.appcompat.widget.AppCompatTextView
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.iitems.KauIItem
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.fadeIn
+import ca.allanwang.kau.utils.invisible
+import ca.allanwang.kau.utils.toDrawable
+import ca.allanwang.kau.utils.visible
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
@@ -23,7 +43,7 @@ import com.pitchedapps.frost.utils.Prefs
* Created by Allan Wang on 2017-06-05.
*/
class AccountItem(val cookie: CookieModel?) : KauIItem<AccountItem, AccountItem.ViewHolder>
-(R.layout.view_account, { ViewHolder(it) }, R.id.item_account) {
+ (R.layout.view_account, { ViewHolder(it) }, R.id.item_account) {
override fun bindView(viewHolder: ViewHolder, payloads: MutableList<Any>) {
super.bindView(viewHolder, payloads)
@@ -33,20 +53,37 @@ class AccountItem(val cookie: CookieModel?) : KauIItem<AccountItem, AccountItem.
if (cookie != null) {
text.text = cookie.name
GlideApp.with(itemView).load(profilePictureUrl(cookie.id))
- .transform(FrostGlide.roundCorner).listener(object : RequestListener<Drawable> {
- override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
- text.fadeIn()
- return false
- }
+ .transform(FrostGlide.roundCorner).listener(object : RequestListener<Drawable> {
+ override fun onResourceReady(
+ resource: Drawable?,
+ model: Any?,
+ target: Target<Drawable>?,
+ dataSource: DataSource?,
+ isFirstResource: Boolean
+ ): Boolean {
+ text.fadeIn()
+ return false
+ }
- override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
- text.fadeIn()
- return false
- }
- }).into(image)
+ override fun onLoadFailed(
+ e: GlideException?,
+ model: Any?,
+ target: Target<Drawable>?,
+ isFirstResource: Boolean
+ ): Boolean {
+ text.fadeIn()
+ return false
+ }
+ }).into(image)
} else {
text.visible()
- image.setImageDrawable(GoogleMaterial.Icon.gmd_add_circle_outline.toDrawable(itemView.context, 100, Prefs.textColor))
+ image.setImageDrawable(
+ GoogleMaterial.Icon.gmd_add_circle_outline.toDrawable(
+ itemView.context,
+ 100,
+ Prefs.textColor
+ )
+ )
text.text = itemView.context.getString(R.string.kau_add_account)
}
}
@@ -64,4 +101,4 @@ class AccountItem(val cookie: CookieModel?) : KauIItem<AccountItem, AccountItem.
val image: ImageView by bindView(R.id.account_image)
val text: AppCompatTextView by bindView(R.id.account_text)
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/BadgedIcon.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/BadgedIcon.kt
index 8093c852..51a7a8e9 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/BadgedIcon.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/BadgedIcon.kt
@@ -1,27 +1,50 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.views
import android.content.Context
import android.graphics.drawable.GradientDrawable
-import androidx.constraintlayout.widget.ConstraintLayout
import android.util.AttributeSet
-import ca.allanwang.kau.utils.*
+import androidx.constraintlayout.widget.ConstraintLayout
+import ca.allanwang.kau.utils.colorToForeground
+import ca.allanwang.kau.utils.dpToPx
+import ca.allanwang.kau.utils.gone
+import ca.allanwang.kau.utils.toDrawable
+import ca.allanwang.kau.utils.visible
+import ca.allanwang.kau.utils.withAlpha
import com.mikepenz.iconics.typeface.IIcon
import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.Prefs
import kotlinx.android.synthetic.main.view_badged_icon.view.*
-
/**
* Created by Allan Wang on 2017-06-19.
*/
class BadgedIcon @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
init {
inflate(context, R.layout.view_badged_icon, this)
val badgeColor = Prefs.mainActivityLayout.backgroundColor().withAlpha(255).colorToForeground(0.2f)
- val badgeBackground = GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, intArrayOf(badgeColor, badgeColor))
+ val badgeBackground =
+ GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, intArrayOf(badgeColor, badgeColor))
badgeBackground.cornerRadius = 13.dpToPx.toFloat()
badge_text.background = badgeBackground
badge_text.setTextColor(Prefs.mainActivityLayout.iconColor())
@@ -30,7 +53,13 @@ class BadgedIcon @JvmOverloads constructor(
var iicon: IIcon? = null
set(value) {
field = value
- badge_image.setImageDrawable(value?.toDrawable(context, sizeDp = 20, color = Prefs.mainActivityLayout.iconColor()))
+ badge_image.setImageDrawable(
+ value?.toDrawable(
+ context,
+ sizeDp = 20,
+ color = Prefs.mainActivityLayout.iconColor()
+ )
+ )
}
fun setAllAlpha(alpha: Float) {
@@ -46,5 +75,4 @@ class BadgedIcon @JvmOverloads constructor(
if (value != null && value != "0") badge_text.visible()
else badge_text.gone()
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt
index c44a8188..d17a424c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt
@@ -1,13 +1,36 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.views
import android.content.Context
import android.os.Build
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import android.util.AttributeSet
import android.view.View
import android.widget.FrameLayout
import android.widget.ProgressBar
-import ca.allanwang.kau.utils.*
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.circularReveal
+import ca.allanwang.kau.utils.fadeIn
+import ca.allanwang.kau.utils.fadeOut
+import ca.allanwang.kau.utils.invisibleIf
+import ca.allanwang.kau.utils.isVisible
+import ca.allanwang.kau.utils.tint
+import ca.allanwang.kau.utils.withAlpha
import com.pitchedapps.frost.R
import com.pitchedapps.frost.contracts.FrostContentContainer
import com.pitchedapps.frost.contracts.FrostContentCore
@@ -24,25 +47,32 @@ import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.PublishSubject
class FrostContentWeb @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0,
+ defStyleRes: Int = 0
) : FrostContentView<FrostWebView>(context, attrs, defStyleAttr, defStyleRes) {
override val layoutRes: Int = R.layout.view_content_base_web
-
}
class FrostContentRecycler @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0,
+ defStyleRes: Int = 0
) : FrostContentView<FrostRecyclerView>(context, attrs, defStyleAttr, defStyleRes) {
override val layoutRes: Int = R.layout.view_content_base_recycler
-
}
abstract class FrostContentView<out T> @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0,
+ defStyleRes: Int = 0
) : FrameLayout(context, attrs, defStyleAttr, defStyleRes),
- FrostContentParent where T : View, T : FrostContentCore {
+ FrostContentParent where T : View, T : FrostContentCore {
private val refresh: SwipeRefreshLayout by bindView(R.id.content_refresh)
private val progress: ProgressBar by bindView(R.id.content_progress)
@@ -88,15 +118,14 @@ abstract class FrostContentView<out T> @JvmOverloads constructor(
}.addTo(compositeDisposable)
refreshObservable
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe {
- refresh.isRefreshing = it
- refresh.isEnabled = true
- }.addTo(compositeDisposable)
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe {
+ refresh.isRefreshing = it
+ refresh.isEnabled = true
+ }.addTo(compositeDisposable)
refresh.setOnRefreshListener { coreView.reload(true) }
reloadThemeSelf()
-
}
override fun bind(container: FrostContentContainer) {
@@ -151,24 +180,24 @@ abstract class FrostContentView<out T> @JvmOverloads constructor(
var loading = dispose != null
dispose?.dispose()
dispose = refreshObservable
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe {
- if (it) {
- loading = true
- transitionStart = System.currentTimeMillis()
- clearAnimation()
- if (isVisible)
- fadeOut(duration = 200L)
- } else if (loading) {
- loading = false
- if (animate && Prefs.animate) circularReveal(offset = WEB_LOAD_DELAY)
- else fadeIn(duration = 200L, offset = WEB_LOAD_DELAY)
- L.v { "Transition loaded in ${System.currentTimeMillis() - transitionStart} ms" }
- dispose?.dispose()
- dispose = null
- }
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe {
+ if (it) {
+ loading = true
+ transitionStart = System.currentTimeMillis()
+ clearAnimation()
+ if (isVisible)
+ fadeOut(duration = 200L)
+ } else if (loading) {
+ loading = false
+ if (animate && Prefs.animate) circularReveal(offset = WEB_LOAD_DELAY)
+ else fadeIn(duration = 200L, offset = WEB_LOAD_DELAY)
+ L.v { "Transition loaded in ${System.currentTimeMillis() - transitionStart} ms" }
+ dispose?.dispose()
+ dispose = null
}
+ }
}
return true
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt
index 19869426..2b9e8f9c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt
@@ -1,10 +1,26 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.views
import android.content.Context
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
import android.util.AttributeSet
import android.view.View
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.utils.circularReveal
import ca.allanwang.kau.utils.fadeOut
import com.pitchedapps.frost.contracts.FrostContentContainer
@@ -18,9 +34,11 @@ import com.pitchedapps.frost.utils.Prefs
*
*/
class FrostRecyclerView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : RecyclerView(context, attrs, defStyleAttr),
- FrostContentCore {
+ FrostContentCore {
override fun reload(animate: Boolean) = reloadBase(animate)
@@ -102,5 +120,4 @@ class FrostRecyclerView @JvmOverloads constructor(
override fun reloadTextSizeSelf() {
// todo
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt
index 85dc7e18..6ee34a2b 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.views
import android.annotation.SuppressLint
@@ -27,7 +43,9 @@ import com.pitchedapps.frost.utils.Prefs
* Parent must have layout with both height & width as match_parent
*/
class FrostVideoView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : VideoView(context, attrs, defStyleAttr) {
/**
@@ -105,7 +123,10 @@ class FrostVideoView @JvmOverloads constructor(
videoDimensions.set(dimen, dimen)
}
val portrait = height > width
- val scale = Math.min(height / (if (portrait) 4f else 2.3f) / videoDimensions.y, width / (if (portrait) 2.3f else 4f) / videoDimensions.x)
+ val scale = Math.min(
+ height / (if (portrait) 4f else 2.3f) / videoDimensions.y,
+ width / (if (portrait) 2.3f else 4f) / videoDimensions.x
+ )
val desiredHeight = scale * videoDimensions.y
val desiredWidth = scale * videoDimensions.x
val padding = containerContract.lowerVideoPadding
@@ -151,8 +172,8 @@ class FrostVideoView @JvmOverloads constructor(
/**
* Only remap if not expanded and if dimensions have changed
*/
- val shouldRemap = !isExpanded
- && (videoDimensions.x != ratio * intrinsicWidth || videoDimensions.y != ratio * intrinsicHeight)
+ val shouldRemap = !isExpanded &&
+ (videoDimensions.x != ratio * intrinsicWidth || videoDimensions.y != ratio * intrinsicHeight)
videoDimensions.set(ratio * intrinsicWidth, ratio * intrinsicHeight)
if (shouldRemap) updateLocation()
}
@@ -226,7 +247,8 @@ class FrostVideoView @JvmOverloads constructor(
* -------------------------------------------------------------------
*/
- private inner class FrameTouchListener(context: Context) : GestureDetector.SimpleOnGestureListener(), View.OnTouchListener {
+ private inner class FrameTouchListener(context: Context) : GestureDetector.SimpleOnGestureListener(),
+ View.OnTouchListener {
private val gestureDetector: GestureDetector = GestureDetector(context, this)
@@ -252,7 +274,8 @@ class FrostVideoView @JvmOverloads constructor(
/**
* Monitors the view click events to show and hide the video controls if they have been specified.
*/
- private inner class VideoTouchListener(context: Context) : GestureDetector.SimpleOnGestureListener(), View.OnTouchListener {
+ private inner class VideoTouchListener(context: Context) : GestureDetector.SimpleOnGestureListener(),
+ View.OnTouchListener {
private val gestureDetector: GestureDetector = GestureDetector(context, this)
private val downLoc = PointF()
@@ -315,4 +338,4 @@ class FrostVideoView @JvmOverloads constructor(
return true
}
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt
index b2796999..c2535940 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.views
import android.content.Context
@@ -8,11 +24,22 @@ import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ViewTreeObserver
import android.widget.FrameLayout
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.fadeIn
+import ca.allanwang.kau.utils.fadeOut
+import ca.allanwang.kau.utils.gone
+import ca.allanwang.kau.utils.goneIf
+import ca.allanwang.kau.utils.inflate
+import ca.allanwang.kau.utils.isColorDark
+import ca.allanwang.kau.utils.isGone
+import ca.allanwang.kau.utils.isVisible
+import ca.allanwang.kau.utils.setIcon
+import ca.allanwang.kau.utils.setMenuIcons
+import ca.allanwang.kau.utils.visible
+import ca.allanwang.kau.utils.withMinAlpha
import com.devbrackets.android.exomedia.listener.VideoControlsVisibilityListener
import com.mikepenz.google_material_typeface_library.GoogleMaterial
-import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.R
+import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.frostDownload
import kotlinx.android.synthetic.main.view_video.view.*
@@ -21,7 +48,9 @@ import kotlinx.android.synthetic.main.view_video.view.*
* Created by Allan Wang on 2017-10-13.
*/
class FrostVideoViewer @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr), FrostVideoViewerContract {
companion object {
@@ -51,16 +80,18 @@ class FrostVideoViewer @JvmOverloads constructor(
inflate(R.layout.view_video, true)
alpha = 0f
video_background.setBackgroundColor(
- if (!Prefs.blackMediaBg && Prefs.bgColor.isColorDark)
- Prefs.bgColor.withMinAlpha(200)
- else
- Color.BLACK)
+ if (!Prefs.blackMediaBg && Prefs.bgColor.isColorDark)
+ Prefs.bgColor.withMinAlpha(200)
+ else
+ Color.BLACK
+ )
video.setViewerContract(this)
video.pause()
video_toolbar.inflateMenu(R.menu.menu_video)
- context.setMenuIcons(video_toolbar.menu, Prefs.iconColor,
- R.id.action_pip to GoogleMaterial.Icon.gmd_picture_in_picture_alt,
- R.id.action_download to GoogleMaterial.Icon.gmd_file_download
+ context.setMenuIcons(
+ video_toolbar.menu, Prefs.iconColor,
+ R.id.action_pip to GoogleMaterial.Icon.gmd_picture_in_picture_alt,
+ R.id.action_download to GoogleMaterial.Icon.gmd_file_download
)
video_toolbar.setOnMenuItemClickListener {
when (it.itemId) {
@@ -141,7 +172,6 @@ class FrostVideoViewer @JvmOverloads constructor(
if (!video_toolbar.isGone)
video_toolbar.fadeOut(duration = CONTROL_ANIMATION_DURATION) { video_toolbar.gone() }
}
-
}
interface FrostVideoViewerContract : VideoControlsVisibilityListener {
@@ -171,4 +201,4 @@ interface FrostVideoContainerContract {
* Called once the video has stopped & should be removed
*/
fun onVideoFinished()
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostViewPager.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostViewPager.kt
index 18b7ae49..bf2f771d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostViewPager.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostViewPager.kt
@@ -1,10 +1,26 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.views
import android.annotation.SuppressLint
import android.content.Context
-import androidx.viewpager.widget.ViewPager
import android.util.AttributeSet
import android.view.MotionEvent
+import androidx.viewpager.widget.ViewPager
import com.pitchedapps.frost.utils.Prefs
/**
@@ -12,21 +28,22 @@ import com.pitchedapps.frost.utils.Prefs
*
* Basic override to allow us to control swiping
*/
-class FrostViewPager @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : ViewPager(context, attrs) {
+class FrostViewPager @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
+ ViewPager(context, attrs) {
var enableSwipe = true
override fun onInterceptTouchEvent(ev: MotionEvent?) =
- try {
- Prefs.viewpagerSwipe && enableSwipe && super.onInterceptTouchEvent(ev)
- } catch (e: IllegalArgumentException) {
- false
- }
+ try {
+ Prefs.viewpagerSwipe && enableSwipe && super.onInterceptTouchEvent(ev)
+ } catch (e: IllegalArgumentException) {
+ false
+ }
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(ev: MotionEvent?): Boolean =
- try {
- Prefs.viewpagerSwipe && enableSwipe && super.onTouchEvent(ev)
- } catch (e: IllegalArgumentException) {
- false
- }
-} \ No newline at end of file
+ try {
+ Prefs.viewpagerSwipe && enableSwipe && super.onTouchEvent(ev)
+ } catch (e: IllegalArgumentException) {
+ false
+ }
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt
index 8230c338..b15ad5cf 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.views
import android.animation.ValueAnimator
@@ -16,16 +32,22 @@ import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
import com.pitchedapps.frost.fragments.WebFragment
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.frostDownload
-import com.pitchedapps.frost.web.*
+import com.pitchedapps.frost.web.FrostChromeClient
+import com.pitchedapps.frost.web.FrostJSI
+import com.pitchedapps.frost.web.FrostWebViewClient
+import com.pitchedapps.frost.web.NestedWebView
+import com.pitchedapps.frost.web.shouldUseBasicAgent
/**
* Created by Allan Wang on 2017-05-29.
*
*/
class FrostWebView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : NestedWebView(context, attrs, defStyleAttr),
- FrostContentCore {
+ FrostContentCore {
override fun reload(animate: Boolean) {
if (parent.registerTransition(false, animate))
@@ -59,7 +81,6 @@ class FrostWebView @JvmOverloads constructor(
return this
}
-
/**
* Wrapper to the main userAgentString to cache it.
* This decouples it from the UiThread
@@ -168,4 +189,4 @@ class FrostWebView @JvmOverloads constructor(
super.destroy()
}
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/KPrefTextSeekbar.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/KPrefTextSeekbar.kt
index 14f77e72..7f0d792a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/KPrefTextSeekbar.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/KPrefTextSeekbar.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.views
import android.annotation.SuppressLint
@@ -43,4 +59,4 @@ class KPrefTextSeekbar(builder: KPrefSeekbarContract) : KPrefSeekbar(builder) {
holder.desc?.setTextSize(TypedValue.COMPLEX_UNIT_PX, descOriginalSize)
super.unbindView(holder)
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/Keywords.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/Keywords.kt
index c171ce77..e63fcc21 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/Keywords.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/Keywords.kt
@@ -1,15 +1,31 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.views
import android.content.Context
import android.graphics.drawable.Drawable
-import androidx.constraintlayout.widget.ConstraintLayout
+import android.util.AttributeSet
+import android.view.View
+import android.widget.ImageView
import androidx.appcompat.widget.AppCompatEditText
import androidx.appcompat.widget.AppCompatTextView
+import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
-import android.util.AttributeSet
-import android.view.View
-import android.widget.ImageView
import ca.allanwang.kau.utils.bindView
import ca.allanwang.kau.utils.string
import ca.allanwang.kau.utils.tint
@@ -23,12 +39,13 @@ import com.mikepenz.iconics.typeface.IIcon
import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.Prefs
-
/**
* Created by Allan Wang on 2017-06-19.
*/
class Keywords @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
val editText: AppCompatEditText by bindView(R.id.edit_text)
@@ -51,7 +68,8 @@ class Keywords @JvmOverloads constructor(
recycler.layoutManager = LinearLayoutManager(context)
recycler.adapter = adapter
adapter.withEventHook(object : ClickEventHook<KeywordItem>() {
- override fun onBind(viewHolder: RecyclerView.ViewHolder): View? = (viewHolder as? KeywordItem.ViewHolder)?.delete
+ override fun onBind(viewHolder: RecyclerView.ViewHolder): View? =
+ (viewHolder as? KeywordItem.ViewHolder)?.delete
override fun onClick(v: View, position: Int, fastAdapter: FastAdapter<KeywordItem>, item: KeywordItem) {
adapter.remove(position)
@@ -62,7 +80,6 @@ class Keywords @JvmOverloads constructor(
fun save() {
Prefs.notificationKeywords = adapter.adapterItems.mapTo(mutableSetOf()) { it.keyword }
}
-
}
private fun IIcon.keywordDrawable(context: Context): Drawable = toDrawable(context, 20, Prefs.textColor)
@@ -94,4 +111,4 @@ class KeywordItem(val keyword: String) : AbstractItem<KeywordItem, KeywordItem.V
delete.setImageDrawable(GoogleMaterial.Icon.gmd_delete.keywordDrawable(itemView.context))
}
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt
index 4ce6f005..bb196221 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt
@@ -1,13 +1,29 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.web
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
-import androidx.annotation.WorkerThread
import android.util.AttributeSet
import android.view.View
import android.webkit.WebView
+import androidx.annotation.WorkerThread
import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
import com.pitchedapps.frost.injectors.CssAssets
import com.pitchedapps.frost.injectors.CssHider
@@ -25,7 +41,9 @@ import java.io.File
* A barebone webview with a refresh listener
*/
class DebugWebView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : WebView(context, attrs, defStyleAttr) {
var onPageFinished: (String?) -> Unit = {}
@@ -71,25 +89,27 @@ class DebugWebView @JvmOverloads constructor(
private fun injectBackgroundColor() {
setBackgroundColor(
- if (url.isFacebookUrl) Prefs.bgColor.withAlpha(255)
- else Color.WHITE)
+ if (url.isFacebookUrl) Prefs.bgColor.withAlpha(255)
+ else Color.WHITE
+ )
}
-
override fun onPageCommitVisible(view: WebView, url: String?) {
super.onPageCommitVisible(view, url)
injectBackgroundColor()
if (url.isFacebookUrl)
view.jsInject(
- CssAssets.ROUND_ICONS.maybe(Prefs.showRoundedIcons),
+ CssAssets.ROUND_ICONS.maybe(Prefs.showRoundedIcons),
// CssHider.CORE,
- CssHider.COMPOSER.maybe(!Prefs.showComposer),
- CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends),
- CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups),
- Prefs.themeInjector,
- CssHider.NON_RECENT.maybe((url?.contains("?sk=h_chr") ?: false)
- && Prefs.aggressiveRecents))
+ CssHider.COMPOSER.maybe(!Prefs.showComposer),
+ CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends),
+ CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups),
+ Prefs.themeInjector,
+ CssHider.NON_RECENT.maybe(
+ (url?.contains("?sk=h_chr") ?: false) &&
+ Prefs.aggressiveRecents
+ )
+ )
}
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt
index 3c3c063a..12df8000 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt
@@ -1,7 +1,27 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.web
import android.net.Uri
-import android.webkit.*
+import android.webkit.ConsoleMessage
+import android.webkit.GeolocationPermissions
+import android.webkit.ValueCallback
+import android.webkit.WebChromeClient
+import android.webkit.WebView
import ca.allanwang.kau.permissions.PERMISSION_ACCESS_FINE_LOCATION
import ca.allanwang.kau.permissions.kauRequestPermissions
import com.pitchedapps.frost.R
@@ -12,7 +32,6 @@ import com.pitchedapps.frost.views.FrostWebView
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.Subject
-
/**
* Created by Allan Wang on 2017-05-31.
*
@@ -45,9 +64,13 @@ class FrostChromeClient(web: FrostWebView) : WebChromeClient() {
progress.onNext(newProgress)
}
- override fun onShowFileChooser(webView: WebView, filePathCallback: ValueCallback<Array<Uri>?>, fileChooserParams: FileChooserParams): Boolean {
+ override fun onShowFileChooser(
+ webView: WebView,
+ filePathCallback: ValueCallback<Array<Uri>?>,
+ fileChooserParams: FileChooserParams
+ ): Boolean {
activity?.openFileChooser(filePathCallback, fileChooserParams)
- ?: webView.frostSnackbar(R.string.file_chooser_not_found)
+ ?: webView.frostSnackbar(R.string.file_chooser_not_found)
return activity != null
}
@@ -58,6 +81,4 @@ class FrostChromeClient(web: FrostWebView) : WebChromeClient() {
callback(origin, granted, true)
}
}
-
-
-} \ No newline at end of file
+}
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 564b0e04..2afb28c9 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.web
import android.webkit.JavascriptInterface
@@ -5,11 +21,16 @@ import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.contracts.MainActivityContract
import com.pitchedapps.frost.contracts.VideoViewHolder
import com.pitchedapps.frost.facebook.FbCookie
-import com.pitchedapps.frost.utils.*
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.WebContext
+import com.pitchedapps.frost.utils.cookies
+import com.pitchedapps.frost.utils.isIndependent
+import com.pitchedapps.frost.utils.launchImageActivity
+import com.pitchedapps.frost.utils.showWebContextMenu
import com.pitchedapps.frost.views.FrostWebView
import io.reactivex.subjects.Subject
-
/**
* Created by Allan Wang on 2017-06-01.
*/
@@ -31,15 +52,15 @@ class FrostJSI(val web: FrostWebView) {
@JavascriptInterface
fun loadVideo(url: String?, isGif: Boolean): Boolean =
- if (url != null && Prefs.enablePip) {
- web.post {
- (context as? VideoViewHolder)?.showVideo(url, isGif)
- ?: L.e { "Could not load video; contract not implemented" }
- }
- true
- } else {
- false
+ if (url != null && Prefs.enablePip) {
+ web.post {
+ (context as? VideoViewHolder)?.showVideo(url, isGif)
+ ?: L.e { "Could not load video; contract not implemented" }
}
+ true
+ } else {
+ false
+ }
@JavascriptInterface
fun reloadBaseUrl(animate: Boolean) {
@@ -113,5 +134,4 @@ class FrostJSI(val web: FrostWebView) {
html ?: return
header?.onNext(html)
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt
index 4e4df027..bd696b02 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.web
import android.webkit.WebResourceRequest
@@ -8,14 +24,19 @@ import com.pitchedapps.frost.utils.L
import okhttp3.HttpUrl
import java.io.ByteArrayInputStream
-
/**
* Created by Allan Wang on 2017-07-13.
*
* Handler to decide when a request should be done by us
* This is the crux of Frost's optimizations for the web browser
*/
-private val blankResource: WebResourceResponse by lazy { WebResourceResponse("text/plain", "utf-8", ByteArrayInputStream("".toByteArray())) }
+private val blankResource: WebResourceResponse by lazy {
+ WebResourceResponse(
+ "text/plain",
+ "utf-8",
+ ByteArrayInputStream("".toByteArray())
+ )
+}
fun WebView.shouldFrostInterceptRequest(request: WebResourceRequest): WebResourceResponse? {
val requestUrl = request.url?.toString() ?: return null
@@ -46,12 +67,13 @@ val WebResourceRequest.isMedia: Boolean
* Generic filter passthrough
* If Resource is already nonnull, pass it, otherwise check if filter is met and override the response accordingly
*/
-fun WebResourceResponse?.filter(request: WebResourceRequest, filter: (url: String) -> Boolean) = filter(request.query { filter(it) })
+fun WebResourceResponse?.filter(request: WebResourceRequest, filter: (url: String) -> Boolean) =
+ filter(request.query { filter(it) })
fun WebResourceResponse?.filter(filter: Boolean): WebResourceResponse? = this
- ?: if (filter) blankResource else null
+ ?: if (filter) blankResource else null
-fun WebResourceResponse?.filterCss(request: WebResourceRequest): WebResourceResponse? = filter(request) { it.endsWith(".css") }
+fun WebResourceResponse?.filterCss(request: WebResourceRequest): WebResourceResponse? =
+ filter(request) { it.endsWith(".css") }
fun WebResourceResponse?.filterImage(request: WebResourceRequest): WebResourceResponse? = filter(request.isImage)
-
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt
index b83002a3..e2d294f7 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.web
import com.pitchedapps.frost.activities.WebOverlayActivity
@@ -8,7 +24,15 @@ import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
import com.pitchedapps.frost.facebook.formattedFbUrl
-import com.pitchedapps.frost.utils.*
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.isImageUrl
+import com.pitchedapps.frost.utils.isIndependent
+import com.pitchedapps.frost.utils.isIndirectImageUrl
+import com.pitchedapps.frost.utils.isVideoUrl
+import com.pitchedapps.frost.utils.launchImageActivity
+import com.pitchedapps.frost.utils.launchWebOverlay
+import com.pitchedapps.frost.utils.launchWebOverlayBasic
import com.pitchedapps.frost.views.FrostWebView
import org.jetbrains.anko.runOnUiThread
@@ -77,14 +101,14 @@ fun FrostWebView.requestWebOverlay(url: String): Boolean {
* If the url contains any one of the whitelist segments, switch to the chat overlay
*/
val messageWhitelist: Set<String> =
- setOf(FbItem.MESSAGES, FbItem.CHAT, FbItem.FEED_MOST_RECENT, FbItem.FEED_TOP_STORIES)
- .mapTo(mutableSetOf(), FbItem::url)
+ setOf(FbItem.MESSAGES, FbItem.CHAT, FbItem.FEED_MOST_RECENT, FbItem.FEED_TOP_STORIES)
+ .mapTo(mutableSetOf(), FbItem::url)
val String.shouldUseBasicAgent: Boolean
get() {
- if (contains("story.php")) // do not use basic for comment section
+ if (contains("story.php")) // do not use basic for comment section
return false
- if (contains("/events/")) // do not use for events (namely the map)
+ if (contains("/events/")) // do not use for events (namely the map)
return false
- return true // use for everything else
- } \ No newline at end of file
+ return true // use for everything else
+ }
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt
index 8824e635..d75f03bb 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.web
import android.graphics.Bitmap
@@ -10,8 +26,19 @@ import com.pitchedapps.frost.facebook.FB_URL_BASE
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.facebook.formattedFbUrl
-import com.pitchedapps.frost.injectors.*
-import com.pitchedapps.frost.utils.*
+import com.pitchedapps.frost.injectors.CssAssets
+import com.pitchedapps.frost.injectors.CssHider
+import com.pitchedapps.frost.injectors.JsActions
+import com.pitchedapps.frost.injectors.JsAssets
+import com.pitchedapps.frost.injectors.jsInject
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+import com.pitchedapps.frost.utils.isExplicitIntent
+import com.pitchedapps.frost.utils.isFacebookUrl
+import com.pitchedapps.frost.utils.isImageUrl
+import com.pitchedapps.frost.utils.isIndirectImageUrl
+import com.pitchedapps.frost.utils.launchImageActivity
+import com.pitchedapps.frost.utils.resolveActivityForUri
import com.pitchedapps.frost.views.FrostWebView
import io.reactivex.subjects.Subject
import org.jetbrains.anko.withAlpha
@@ -28,8 +55,8 @@ import org.jetbrains.anko.withAlpha
*/
open class BaseWebViewClient : WebViewClient() {
- override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? = view.shouldFrostInterceptRequest(request)
-
+ override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? =
+ view.shouldFrostInterceptRequest(request)
}
/**
@@ -51,11 +78,11 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
private fun injectBackgroundColor() {
web.setBackgroundColor(
- when {
- isMain -> Color.TRANSPARENT
- web.url.isFacebookUrl -> Prefs.bgColor.withAlpha(255)
- else -> Color.WHITE
- }
+ when {
+ isMain -> Color.TRANSPARENT
+ web.url.isFacebookUrl -> Prefs.bgColor.withAlpha(255)
+ else -> Color.WHITE
+ }
)
}
@@ -64,21 +91,24 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
injectBackgroundColor()
if (url.isFacebookUrl)
view.jsInject(
- CssAssets.ROUND_ICONS.maybe(Prefs.showRoundedIcons),
+ CssAssets.ROUND_ICONS.maybe(Prefs.showRoundedIcons),
// CssHider.CORE,
- CssHider.HEADER,
- CssHider.COMPOSER.maybe(!Prefs.showComposer),
- CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends),
- CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups),
- Prefs.themeInjector,
- CssHider.NON_RECENT.maybe((web.url?.contains("?sk=h_chr") ?: false)
- && Prefs.aggressiveRecents),
- JsAssets.DOCUMENT_WATCHER,
- JsAssets.CLICK_A,
- CssHider.ADS.maybe(!Prefs.showFacebookAds),
- JsAssets.CONTEXT_A,
+ CssHider.HEADER,
+ CssHider.COMPOSER.maybe(!Prefs.showComposer),
+ CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends),
+ CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups),
+ Prefs.themeInjector,
+ CssHider.NON_RECENT.maybe(
+ (web.url?.contains("?sk=h_chr") ?: false) &&
+ Prefs.aggressiveRecents
+ ),
+ JsAssets.DOCUMENT_WATCHER,
+ JsAssets.CLICK_A,
+ CssHider.ADS.maybe(!Prefs.showFacebookAds),
+ JsAssets.CONTEXT_A,
// JsAssets.HEADER_HIDER,
- JsAssets.MEDIA)
+ JsAssets.MEDIA
+ )
else
refresh.onNext(false)
}
@@ -104,9 +134,10 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
refresh.onNext(false)
injectBackgroundColor()
web.jsInject(
- JsActions.LOGIN_CHECK,
- JsAssets.TEXTAREA_LISTENER,
- JsAssets.HEADER_BADGES.maybe(isMain))
+ JsActions.LOGIN_CHECK,
+ JsAssets.TEXTAREA_LISTENER,
+ JsAssets.HEADER_BADGES.maybe(isMain)
+ )
}
open fun handleHtml(html: String?) {
@@ -151,7 +182,6 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
if (Prefs.linksInDefaultApp && view.context.resolveActivityForUri(request.url)) return true
return super.shouldOverrideUrlLoading(view, request)
}
-
}
private const val EMIT_THEME = 0b1
@@ -189,4 +219,4 @@ class FrostWebViewClientMenu(web: FrostWebView) : FrostWebViewClient(web) {
v { "Should inject ${url.shouldInjectMenu}" }
if (!url.shouldInjectMenu) injectAndFinish()
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
index 1f22f303..392cb353 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.web
import android.annotation.SuppressLint
@@ -5,7 +21,11 @@ import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.View
-import android.webkit.*
+import android.webkit.ConsoleMessage
+import android.webkit.CookieManager
+import android.webkit.WebChromeClient
+import android.webkit.WebResourceRequest
+import android.webkit.WebView
import ca.allanwang.kau.utils.fadeIn
import ca.allanwang.kau.utils.isVisible
import com.pitchedapps.frost.dbflow.CookieModel
@@ -26,7 +46,9 @@ import org.jetbrains.anko.uiThread
* Created by Allan Wang on 2017-05-29.
*/
class LoginWebView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : WebView(context, attrs, defStyleAttr) {
private lateinit var loginCallback: (CookieModel) -> Unit
@@ -73,9 +95,11 @@ class LoginWebView @JvmOverloads constructor(
L.d { "Login page commit visible" }
view.setBackgroundColor(Color.TRANSPARENT)
if (url.isFacebookUrl)
- view.jsInject(JsAssets.HEADER_HIDER,
- CssHider.CORE,
- Prefs.themeInjector)
+ view.jsInject(
+ JsAssets.HEADER_HIDER,
+ CssHider.CORE,
+ Prefs.themeInjector
+ )
}
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
@@ -97,4 +121,4 @@ class LoginWebView @JvmOverloads constructor(
progressCallback(newProgress)
}
}
-} \ No newline at end of file
+}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/NestedWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/NestedWebView.kt
index 760d81fc..6e7fc0b6 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/NestedWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/NestedWebView.kt
@@ -1,14 +1,29 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.web
import android.annotation.SuppressLint
import android.content.Context
-import androidx.core.view.NestedScrollingChild
-import androidx.core.view.NestedScrollingChildHelper
-import androidx.core.view.ViewCompat
import android.util.AttributeSet
import android.view.MotionEvent
import android.webkit.WebView
-
+import androidx.core.view.NestedScrollingChild
+import androidx.core.view.NestedScrollingChildHelper
+import androidx.core.view.ViewCompat
/**
* Created by Allan Wang on 20/12/17.
@@ -16,7 +31,9 @@ import android.webkit.WebView
* Webview extension that handles nested scrolls
*/
open class NestedWebView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : WebView(context, attrs, defStyleAttr), NestedScrollingChild {
private lateinit var childHelper: NestedScrollingChildHelper
@@ -99,11 +116,20 @@ open class NestedWebView @JvmOverloads constructor(
final override fun hasNestedScrollingParent() = childHelper.hasNestedScrollingParent()
- final override fun dispatchNestedScroll(dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int, offsetInWindow: IntArray?) = childHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow)
+ final override fun dispatchNestedScroll(
+ dxConsumed: Int,
+ dyConsumed: Int,
+ dxUnconsumed: Int,
+ dyUnconsumed: Int,
+ offsetInWindow: IntArray?
+ ) = childHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow)
- final override fun dispatchNestedPreScroll(dx: Int, dy: Int, consumed: IntArray?, offsetInWindow: IntArray?) = childHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow)
+ final override fun dispatchNestedPreScroll(dx: Int, dy: Int, consumed: IntArray?, offsetInWindow: IntArray?) =
+ childHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow)
- final override fun dispatchNestedFling(velocityX: Float, velocityY: Float, consumed: Boolean) = childHelper.dispatchNestedFling(velocityX, velocityY, consumed)
+ final override fun dispatchNestedFling(velocityX: Float, velocityY: Float, consumed: Boolean) =
+ childHelper.dispatchNestedFling(velocityX, velocityY, consumed)
- final override fun dispatchNestedPreFling(velocityX: Float, velocityY: Float) = childHelper.dispatchNestedPreFling(velocityX, velocityY)
-} \ No newline at end of file
+ final override fun dispatchNestedPreFling(velocityX: Float, velocityY: Float) =
+ childHelper.dispatchNestedPreFling(velocityX, velocityY)
+}
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/MiscTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/MiscTest.kt
index d730b933..20610b2a 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/MiscTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/MiscTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost
import com.pitchedapps.frost.facebook.requests.zip
@@ -19,12 +35,14 @@ class MiscTest {
val now = System.currentTimeMillis()
val base = 1
val data: LongArray = (0..15).map { Math.random() + base }
- .toTypedArray().zip(List<Long>::toLongArray) {
- Thread.sleep((it * 1000).toLong())
- System.currentTimeMillis() - now
- }.blockingGet()
+ .toTypedArray().zip(List<Long>::toLongArray) {
+ Thread.sleep((it * 1000).toLong())
+ System.currentTimeMillis() - now
+ }.blockingGet()
println(data.contentToString())
- assertTrue(data.all { it >= base * 1000 && it < base * 1000 * 5 },
- "zip did not seem to work on different threads")
+ assertTrue(
+ data.all { it >= base * 1000 && it < base * 1000 * 5 },
+ "zip did not seem to work on different threads"
+ )
}
-} \ No newline at end of file
+}
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt
index e30ec174..f7dad4d3 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.debugger
import com.pitchedapps.frost.facebook.FB_URL_BASE
@@ -16,11 +32,10 @@ class OfflineWebsiteTest {
val countdown = CountDownLatch(1)
val buildPath = if (File(".").parentFile?.name == "app") "build/offline_test" else "app/build/offline_test"
OfflineWebsite(FB_URL_BASE, COOKIE, baseDir = File(buildPath))
- .loadAndZip("test") {
- println("Outcome $it")
- countdown.countDown()
- }
+ .loadAndZip("test") {
+ println("Outcome $it")
+ countdown.countDown()
+ }
countdown.await()
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbDomTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbDomTest.kt
index ce748907..9472adfe 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbDomTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbDomTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook
import com.pitchedapps.frost.internal.authDependent
@@ -22,5 +38,4 @@ class FbDomTest {
assertNotNull(doc.getElementById("header"))
assertNotNull(doc.getElementById("mJewelNav"))
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRegexTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRegexTest.kt
index 08853466..f872cfc7 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRegexTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRegexTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook
import org.apache.commons.text.StringEscapeUtils
@@ -18,7 +34,8 @@ class FbRegexTest {
@Test
fun fbDtsgRegex() {
val fb_dtsg = "readme"
- val input = "data-sigil=\"mbasic_inline_feed_composer\">\u003Cinput type=\"hidden\" name=\"fb_dtsg\" value=\"$fb_dtsg\" autocomplete=\"off\" \\/>\u003Cinput type=\"hidden\" name=\"privacyx\" value=\"12345\""
+ val input =
+ "data-sigil=\"mbasic_inline_feed_composer\">\u003Cinput type=\"hidden\" name=\"fb_dtsg\" value=\"$fb_dtsg\" autocomplete=\"off\" \\/>\u003Cinput type=\"hidden\" name=\"privacyx\" value=\"12345\""
assertEquals(fb_dtsg, FB_DTSG_MATCHER.find(input)[1])
}
@@ -56,5 +73,4 @@ class FbRegexTest {
val img = "https://scontent-yyz1-1.xx.fbcdn.net/v/t31.0-8/fr/cp0/e15/q65/89056_${id}_98239_o.jpg"
assertEquals(id, FB_IMAGE_ID_MATCHER.find(img)[1]?.toLongOrNull())
}
-
-} \ No newline at end of file
+}
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbUrlTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbUrlTest.kt
index beda26ef..3bd59fd3 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbUrlTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbUrlTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook
import com.pitchedapps.frost.utils.isImageUrl
@@ -7,7 +23,6 @@ import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
-
/**
* Created by Allan Wang on 2017-07-07.
*/
@@ -63,16 +78,17 @@ class FbUrlTest {
@Test
fun video() {
//note that the video numbers have been changed to maintain privacy
- val url = "/video_redirect/?src=https%3A%2F%2Fvideo-yyz1-1.xx.fbcdn.net%2Fv%2Ft42.1790-2%2F2349078999904_n.mp4%3Fefg%3DeyJ87J9%26oh%3Df5777784%26oe%3D56FD4&source=media_collage&id=1735049&refid=8&_ft_=qid.6484464%3Amf_story_key.-43172431214%3Atop_level_post_id.102773&__tn__=FEH-R"
- val expected = "https://video-yyz1-1.xx.fbcdn.net/v/t42.1790-2/2349078999904_n.mp4?efg=eyJ87J9&oh=f5777784&oe=56FD4&source=media_collage&id=1735049&_ft_=qid.6484464:mf_story_key.-43172431214:top_level_post_id.102773&__tn__=FEH-R"
+ val url =
+ "/video_redirect/?src=https%3A%2F%2Fvideo-yyz1-1.xx.fbcdn.net%2Fv%2Ft42.1790-2%2F2349078999904_n.mp4%3Fefg%3DeyJ87J9%26oh%3Df5777784%26oe%3D56FD4&source=media_collage&id=1735049&refid=8&_ft_=qid.6484464%3Amf_story_key.-43172431214%3Atop_level_post_id.102773&__tn__=FEH-R"
+ val expected =
+ "https://video-yyz1-1.xx.fbcdn.net/v/t42.1790-2/2349078999904_n.mp4?efg=eyJ87J9&oh=f5777784&oe=56FD4&source=media_collage&id=1735049&_ft_=qid.6484464:mf_story_key.-43172431214:top_level_post_id.102773&__tn__=FEH-R"
assertFbFormat(expected, url)
}
-
@Test
fun image() {
arrayOf(
- "https://scontent-yyz1-1.xx.fbcdn.net/v/t1.0-9/fr/cp0/e15/q65/229_546131_836546862_n.jpg?efg=e343J9&oh=d4245b1&oe=5453"
+ "https://scontent-yyz1-1.xx.fbcdn.net/v/t1.0-9/fr/cp0/e15/q65/229_546131_836546862_n.jpg?efg=e343J9&oh=d4245b1&oe=5453"
// "/photo/view_full_size/?fbid=1523&ref_component=mbasic_photo_permalink&ref_page=%2Fwap%2Fphoto.php&refid=153&_ft_=...",
// "#!/photo/view_full_size/?fbid=1523&ref_component=mbasic_photo_permalink&ref_page=%2Fwap%2Fphoto.php&refid=153&_ft_=..."
).forEach {
@@ -83,7 +99,7 @@ class FbUrlTest {
@Test
fun indirectImage() {
arrayOf(
- "#!/photo/view_full_size/?fbid=107368839645039"
+ "#!/photo/view_full_size/?fbid=107368839645039"
).forEach {
assertTrue(it.isIndirectImageUrl, "Failed to match indirect image for $it")
}
@@ -92,13 +108,12 @@ class FbUrlTest {
@Test
fun antiImageRegex() {
arrayOf(
- "http...fbcdn.net...mp4",
- "/photo/...png",
- "https://www.google.ca"
+ "http...fbcdn.net...mp4",
+ "/photo/...png",
+ "https://www.google.ca"
).forEach {
assertFalse(it.isImageUrl, "Should not have matched image for $it")
}
-
}
@Test
@@ -112,5 +127,4 @@ class FbUrlTest {
// val urlBase = "photo/view_full_size/?fbid=1234&ref_component=mbasic_photo_permalink&ref_page=%2Fwap%2Fphoto.php&refid=13&_ft_=qid.1234%3Amf_story_key.1234%3Atop_level_post_id"
// assertFbFormat("$FB_URL_BASE$urlBase", "#!/$urlBase")
// }
-
-} \ No newline at end of file
+}
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt
index 3307c72e..075f045e 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.parsers
import com.pitchedapps.frost.internal.COOKIE
@@ -24,11 +40,11 @@ class FbParseTest {
}
private inline fun <reified T : Any> FrostParser<T>.test(action: T.() -> Unit = {}) =
- parse(COOKIE).test(url, action)
+ parse(COOKIE).test(url, action)
private inline fun <reified T : Any> ParseResponse<T>?.test(url: String, action: T.() -> Unit = {}) {
val response = this
- ?: fail("${T::class.simpleName} parser returned null for $url")
+ ?: fail("${T::class.simpleName} parser returned null for $url")
println(response)
response.data.action()
}
@@ -58,4 +74,4 @@ class FbParseTest {
}
notifs.map(FrostNotif::time).assertDescending("notif time values")
}
-} \ No newline at end of file
+}
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbFullImageTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbFullImageTest.kt
index c4e51d41..4eb90d74 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbFullImageTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbFullImageTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.requests
import com.pitchedapps.frost.internal.COOKIE
@@ -26,4 +42,4 @@ class FbFullImageTest {
assertNotNull(result)
println(result)
}
-} \ No newline at end of file
+}
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbRequestTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbRequestTest.kt
index c5fc8e8e..3a7abec4 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbRequestTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbRequestTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.facebook.requests
import com.fasterxml.jackson.databind.ObjectMapper
@@ -8,7 +24,11 @@ import com.pitchedapps.frost.internal.authDependent
import okhttp3.Call
import org.junit.BeforeClass
import org.junit.Test
-import kotlin.test.*
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertNotNull
+import kotlin.test.assertTrue
+import kotlin.test.fail
/**
* Created by Allan Wang on 21/12/17.
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/injectors/InjectorTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/injectors/InjectorTest.kt
index 76b37afe..f38f03bb 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/injectors/InjectorTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/injectors/InjectorTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.injectors
import org.junit.Test
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt b/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt
index 81175b19..061e7c38 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.internal
import com.pitchedapps.frost.facebook.FB_USER_MATCHER
@@ -11,7 +27,7 @@ import org.junit.Assume
import org.junit.Test
import java.io.File
import java.io.FileInputStream
-import java.util.*
+import java.util.Properties
import java.util.concurrent.TimeUnit
import kotlin.reflect.full.starProjectedType
import kotlin.test.assertEquals
@@ -111,4 +127,4 @@ class InternalTest {
} catch (e: Exception) {
// pass
}
-} \ No newline at end of file
+}
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/rx/ResettableFlyweightTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/rx/ResettableFlyweightTest.kt
index a520e9e3..26a5a8de 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/rx/ResettableFlyweightTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/rx/ResettableFlyweightTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.rx
import com.pitchedapps.frost.internal.concurrentTest
@@ -54,6 +70,4 @@ class ResettableFlyweightTest {
}
}
}
-
-
-} \ No newline at end of file
+}
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/utils/BuildUtilsTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/utils/BuildUtilsTest.kt
index 92bd5bec..b3d44d69 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/utils/BuildUtilsTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/utils/BuildUtilsTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import com.pitchedapps.frost.BuildConfig
@@ -19,4 +35,4 @@ class BuildUtilsTest {
fun androidTests() {
assertNotNull(BuildUtils.match(BuildConfig.VERSION_NAME))
}
-} \ No newline at end of file
+}
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/utils/JsoupCleanerTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/utils/JsoupCleanerTest.kt
index 4ec09ea6..72cca836 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/utils/JsoupCleanerTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/utils/JsoupCleanerTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import org.junit.Test
@@ -47,10 +63,10 @@ class JsoupCleanerTest {
@Test
fun kau() {
- val html = """<div class="col s12 m6"> <div id="kau" class="card medium sticky-action"> <div class="card-image waves-effect waves-block waves-light"> <img class="activator" src="images/kau.jpg"> <span class="card-title activator background-gradient">KAU</span> </div><div class="card-content"><p>An extensive collection of Kotlin Android Utils</p></div><div class="card-action"> <a href="https://github.com/AllanWang/KAU" target="_blank" class="inline-block">Github</a> <a href="https://allanwang.github.io/KAU/" target="_blank" class="inline-block">Page</a> </div><div class="card-reveal"> <span class="card-title grey-text text-darken-4">KAU<i class="material-icons right">close</i></span> <ul class="browser-default"> <li>Huge package of one line extension functions</li><li>Custom UI views</li><li>Adapter items and animators</li><li>SearchView</li><li>Custom delegates</li></ul> </div></div></div>"""
- val expected = """<div class="col s12 m6"><div id="kau" class="card medium sticky-action"><div class="card-image waves-effect waves-block waves-light"><img class="activator" src="images/kau.jpg"></div><div class="card-action"><a href="-" target="_blank" class="inline-block"></a><a href="-" target="_blank" class="inline-block"></a></div></div></div>"""
+ val html =
+ """<div class="col s12 m6"> <div id="kau" class="card medium sticky-action"> <div class="card-image waves-effect waves-block waves-light"> <img class="activator" src="images/kau.jpg"> <span class="card-title activator background-gradient">KAU</span> </div><div class="card-content"><p>An extensive collection of Kotlin Android Utils</p></div><div class="card-action"> <a href="https://github.com/AllanWang/KAU" target="_blank" class="inline-block">Github</a> <a href="https://allanwang.github.io/KAU/" target="_blank" class="inline-block">Page</a> </div><div class="card-reveal"> <span class="card-title grey-text text-darken-4">KAU<i class="material-icons right">close</i></span> <ul class="browser-default"> <li>Huge package of one line extension functions</li><li>Custom UI views</li><li>Adapter items and animators</li><li>SearchView</li><li>Custom delegates</li></ul> </div></div></div>"""
+ val expected =
+ """<div class="col s12 m6"><div id="kau" class="card medium sticky-action"><div class="card-image waves-effect waves-block waves-light"><img class="activator" src="images/kau.jpg"></div><div class="card-action"><a href="-" target="_blank" class="inline-block"></a><a href="-" target="_blank" class="inline-block"></a></div></div></div>"""
html.assertCleanHtml(expected)
}
-
}
-
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/utils/PrefsTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/utils/PrefsTest.kt
index 56ec4c02..088a7fbe 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/utils/PrefsTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/utils/PrefsTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import org.junit.Before
@@ -38,4 +54,4 @@ class PrefsTest {
test = 3L
assertEquals(3L, file)
}
-} \ No newline at end of file
+}
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/utils/StringEscapeUtilsTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/utils/StringEscapeUtilsTest.kt
index 86bd4ce5..f5ea56ae 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/utils/StringEscapeUtilsTest.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/utils/StringEscapeUtilsTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import org.junit.Test
@@ -13,4 +29,4 @@ class StringEscapeUtilsTest {
val escaped = "\\u003Chead&gt; color=\\\"#3b5998\\\""
assertEquals("<head> color=\"#3b5998\"", escaped.unescapeHtml())
}
-} \ No newline at end of file
+}
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/utils/UrlTests.kt b/app/src/test/kotlin/com/pitchedapps/frost/utils/UrlTests.kt
index 109387a0..44e8377a 100644
--- a/app/src/test/kotlin/com/pitchedapps/frost/utils/UrlTests.kt
+++ b/app/src/test/kotlin/com/pitchedapps/frost/utils/UrlTests.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package com.pitchedapps.frost.utils
import com.pitchedapps.frost.facebook.FACEBOOK_COM
@@ -17,19 +33,21 @@ class UrlTests {
fun independence() {
mapOf(
- GOOGLE to true,
- FACEBOOK_COM to true,
- "#!/photos/viewer/?photoset_token=pcb.1234" to false,
- "#test-id" to false,
- "#" to false,
- "#!" to false,
- "#!/" to false,
- "#!/events/permalink/going/?event_id=" to false,
- "/this/is/valid" to true,
- "#!/facebook/segment" to true
+ GOOGLE to true,
+ FACEBOOK_COM to true,
+ "#!/photos/viewer/?photoset_token=pcb.1234" to false,
+ "#test-id" to false,
+ "#" to false,
+ "#!" to false,
+ "#!/" to false,
+ "#!/events/permalink/going/?event_id=" to false,
+ "/this/is/valid" to true,
+ "#!/facebook/segment" to true
).forEach { (url, valid) ->
- assertEquals(valid, url.isIndependent,
- "Independence test failed for $url; should be $valid")
+ assertEquals(
+ valid, url.isIndependent,
+ "Independence test failed for $url; should be $valid"
+ )
}
}
@@ -38,4 +56,4 @@ class UrlTests {
assertFalse(GOOGLE.isFacebookUrl, "google")
assertTrue(FACEBOOK_COM.isFacebookUrl, "facebook")
}
-} \ No newline at end of file
+}
diff --git a/build.gradle b/build.gradle
index ef1dc448..64e324d2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -12,6 +12,7 @@ buildscript {
classpath "com.android.tools.build:gradle:${ANDROID_GRADLE}"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${KOTLIN}"
classpath "com.bugsnag:bugsnag-android-gradle-plugin:${BUGSNAG_PLUGIN}"
+ classpath "com.diffplug.spotless:spotless-plugin-gradle:${SPOTLESS}"
classpath "com.getkeepsafe.dexcount:dexcount-gradle-plugin:${DEX_PLUGIN}"
classpath "gradle.plugin.com.gladed.gradle.androidgitversion:gradle-android-git-version:${GIT_PLUGIN}"
}
diff --git a/gradle.properties b/gradle.properties
index f708598c..1af54944 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -20,6 +20,9 @@ KOTLIN=1.3.11
# https://mvnrepository.com/artifact/com.android.tools.build/gradle?repo=google
ANDROID_GRADLE=3.2.1
+# https://github.com/diffplug/spotless/blob/master/plugin-gradle/CHANGES.md
+SPOTLESS=3.17.0
+
# https://github.com/bugsnag/bugsnag-android/releases
BUGSNAG=4.9.3
# https://github.com/bugsnag/bugsnag-android-gradle-plugin/releases
diff --git a/spotless.gradle b/spotless.gradle
new file mode 100644
index 00000000..22dba3a8
--- /dev/null
+++ b/spotless.gradle
@@ -0,0 +1,11 @@
+apply plugin: "com.diffplug.gradle.spotless"
+
+spotless {
+ kotlin {
+ target "**/*.kt"
+ ktlint()
+ licenseHeaderFile '../spotless.license.kt'
+ trimTrailingWhitespace()
+ endWithNewline()
+ }
+} \ No newline at end of file
diff --git a/spotless.license.kt b/spotless.license.kt
new file mode 100644
index 00000000..35d16571
--- /dev/null
+++ b/spotless.license.kt
@@ -0,0 +1,16 @@
+/*
+ * Copyright $YEAR Allan Wang
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */ \ No newline at end of file