aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/kotlin/com')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt1
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt55
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/services/DownloadService.kt4
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Animator.kt70
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt19
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt4
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt7
8 files changed, 66 insertions, 96 deletions
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 0a713649..2fe6b8d8 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt
@@ -76,6 +76,7 @@ class ImageActivity : KauBaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ intent?.extras ?: return finish()
L.i("Displaying image", imageUrl)
val layout = if (!text.isNullOrBlank()) R.layout.activity_image else R.layout.activity_image_textless
setContentView(layout)
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 0e74bb59..22ca3138 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt
@@ -26,30 +26,39 @@ class FbUrlFormatter(url: String) {
* 4. Url is split into sections
*/
init {
- if (url.isBlank()) cleaned = ""
- else {
- var cleanedUrl = url
- discardable.forEach { cleanedUrl = cleanedUrl.replace(it, "", true) }
- converter.forEach { (k, v) -> cleanedUrl = cleanedUrl.replace(k, v, true) }
- if (cleanedUrl != url && !cleanedUrl.contains("?")) cleanedUrl = cleanedUrl.replaceFirst("&", "?")
+ cleaned = clean(url)
+ }
+
+ fun clean(url: String): String {
+ if (url.isBlank()) return ""
+ var cleanedUrl = url
+ discardable.forEach { cleanedUrl = cleanedUrl.replace(it, "", true) }
+ val changed = cleanedUrl != url
+ converter.forEach { (k, v) -> cleanedUrl = cleanedUrl.replace(k, v, true) }
+ try {
cleanedUrl = URLDecoder.decode(cleanedUrl, StandardCharsets.UTF_8.name())
- val qm = cleanedUrl.indexOf("?")
- if (qm > -1) {
- cleanedUrl.substring(qm + 1).split("&").forEach {
- val p = it.split("=")
- queries.put(p[0], p.elementAtOrNull(1) ?: "")
- }
- cleanedUrl = cleanedUrl.substring(0, qm)
+ } catch (e: Exception) {
+ L.e(e, "Failed url formatting")
+ return url
+ }
+ if (changed && !cleanedUrl.contains("?")) //ensure we aren't missing '?'
+ cleanedUrl = cleanedUrl.replaceFirst("&", "?")
+ val qm = cleanedUrl.indexOf("?")
+ if (qm > -1) {
+ cleanedUrl.substring(qm + 1).split("&").forEach {
+ val p = it.split("=")
+ queries.put(p[0], p.elementAtOrNull(1) ?: "")
}
- discardableQueries.forEach { queries.remove(it) }
- //final cleanup
- misc.forEach { (k, v) -> cleanedUrl = cleanedUrl.replace(k, v, true) }
- if (cleanedUrl.startsWith("#!")) cleanedUrl = cleanedUrl.substring(2)
- if (cleanedUrl.startsWith("/")) cleanedUrl = FB_URL_BASE + cleanedUrl.substring(1)
- cleanedUrl = cleanedUrl.replaceFirst(".facebook.com//", ".facebook.com/") //sometimes we are given a bad url
- L.v(null, "Formatted url from $url to $cleanedUrl")
- cleaned = cleanedUrl
+ cleanedUrl = cleanedUrl.substring(0, qm)
}
+ discardableQueries.forEach { queries.remove(it) }
+ //final cleanup
+ misc.forEach { (k, v) -> cleanedUrl = cleanedUrl.replace(k, v, true) }
+ if (cleanedUrl.startsWith("#!")) cleanedUrl = cleanedUrl.substring(2)
+ if (cleanedUrl.startsWith("/")) cleanedUrl = FB_URL_BASE + cleanedUrl.substring(1)
+ cleanedUrl = cleanedUrl.replaceFirst(".facebook.com//", ".facebook.com/") //sometimes we are given a bad url
+ L.v(null, "Formatted url from $url to $cleanedUrl")
+ return cleanedUrl
}
override fun toString(): String {
@@ -76,6 +85,10 @@ class FbUrlFormatter(url: String) {
* Items here are explicitly removed from the url
* Taken from FaceSlim
* https://github.com/indywidualny/FaceSlim/blob/master/app/src/main/java/org/indywidualni/fblite/util/Miscellany.java
+ *
+ * Note: Typically, in this case, the redirect url should have all the necessary queries
+ * I am unsure how Facebook reacts in all cases, so the ones after the redirect are appended on afterwards
+ * That shouldn't break anything
*/
val discardable = arrayOf(
"http://lm.facebook.com/l.php?u=",
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/DownloadService.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/DownloadService.kt
index fda5ebf5..520d750f 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/services/DownloadService.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/services/DownloadService.kt
@@ -1,5 +1,6 @@
package com.pitchedapps.frost.services
+import android.annotation.SuppressLint
import android.app.IntentService
import android.app.Notification
import android.app.PendingIntent
@@ -26,11 +27,14 @@ import java.io.File
/**
* Created by Allan Wang on 2017-08-08.
*
+ * Not in use
+ *
* Background file downloader
* All we are given is a link and a mime type
*
* With reference to the <a href="https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/Progress.java">OkHttp3 sample</a>
*/
+@SuppressLint("Registered")
class DownloadService : IntentService("FrostVideoDownloader") {
companion object {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Animator.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Animator.kt
deleted file mode 100644
index da852e6e..00000000
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Animator.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.pitchedapps.frost.utils
-
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
-import android.animation.ValueAnimator
-import android.view.animation.Interpolator
-
-/**
- * Created by Allan Wang on 2017-11-10.
- */
-class ProgressAnimator private constructor(private vararg val values: Float) {
-
- companion object {
- inline fun ofFloat(crossinline builder: ProgressAnimator.() -> Unit) = ofFloat(0f, 1f) { builder() }
-
- fun ofFloat(vararg values: Float, builder: ProgressAnimator.() -> Unit) = ProgressAnimator(*values).apply {
- builder()
- build()
- }
- }
-
- private val animators: MutableList<(Float) -> Unit> = mutableListOf()
- private val startActions: MutableList<() -> Unit> = mutableListOf()
- private val endActions: MutableList<() -> Unit> = mutableListOf()
-
- var duration: Long = -1L
- var interpolator: Interpolator? = null
-
- /**
- * Add more changes to the [ValueAnimator] before running
- */
- var extraConfigs: ValueAnimator.() -> Unit = {}
-
- fun withAnimator(from: Float, to: Float, animator: (Float) -> Unit) = animators.add {
- val range = to - from
- animator(range * it + from)
- }
-
- fun withAnimator(animator: (Float) -> Unit) = animators.add(animator)
-
- fun withAnimatorInv(animator: (Float) -> Unit) = animators.add { animator(1f - it) }
-
- fun withStartAction(action: () -> Unit) = startActions.add(action)
-
- fun withEndAction(action: () -> Unit) = endActions.add(action)
-
- fun build() {
- ValueAnimator.ofFloat(*values).apply {
- if (this@ProgressAnimator.duration > 0L)
- duration = this@ProgressAnimator.duration
- if (this@ProgressAnimator.interpolator != null)
- interpolator = this@ProgressAnimator.interpolator
- addUpdateListener {
- val progress = it.animatedValue as Float
- animators.forEach { it(progress) }
- }
- addListener(object : AnimatorListenerAdapter() {
- override fun onAnimationStart(animation: Animator?) {
- startActions.forEach { it() }
- }
-
- override fun onAnimationEnd(animation: Animator?) {
- endActions.forEach { it() }
- }
- })
- extraConfigs()
- start()
- }
- }
-} \ No newline at end of file
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 3e1e1dde..e6db8eee 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt
@@ -8,10 +8,15 @@ import android.os.Environment
import android.webkit.URLUtil
import ca.allanwang.kau.permissions.PERMISSION_WRITE_EXTERNAL_STORAGE
import ca.allanwang.kau.permissions.kauRequestPermissions
+import ca.allanwang.kau.utils.isAppEnabled
import ca.allanwang.kau.utils.string
import com.pitchedapps.frost.R
import com.pitchedapps.frost.dbflow.loadFbCookie
import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
+import android.support.v4.content.ContextCompat.startActivity
+import android.content.Intent
+import android.content.ActivityNotFoundException
+import ca.allanwang.kau.utils.showAppInfo
/**
@@ -37,6 +42,16 @@ fun Context.frostDownload(uri: Uri?,
L.d("Received download request", "Download $uri")
if (uri.scheme != "http" && uri.scheme != "https")
return L.e("Invalid download attempt", uri.toString())
+ if (!isAppEnabled(DOWNLOAD_MANAGER_PACKAGE)) {
+ materialDialogThemed {
+ title(R.string.no_download_manager)
+ content(R.string.no_download_manager_desc)
+ positiveText(R.string.kau_yes)
+ onPositive { _, _ -> showAppInfo(DOWNLOAD_MANAGER_PACKAGE) }
+ negativeText(R.string.kau_no)
+ }
+ return
+ }
kauRequestPermissions(PERMISSION_WRITE_EXTERNAL_STORAGE) { granted, _ ->
if (!granted) return@kauRequestPermissions
val request = DownloadManager.Request(uri)
@@ -53,4 +68,6 @@ fun Context.frostDownload(uri: Uri?,
val dm = getSystemService(DOWNLOAD_SERVICE) as DownloadManager
dm.enqueue(request)
}
-} \ No newline at end of file
+}
+
+private const val DOWNLOAD_MANAGER_PACKAGE = "com.android.providers.downloads" \ No newline at end of file
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 22c77f5f..c644499e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
@@ -202,7 +202,7 @@ inline val String?.isFacebookUrl
get() = this != null && this.contains(FACEBOOK_COM)
inline val String?.isVideoUrl
- get() = this != null && this.startsWith(VIDEO_REDIRECT)
+ get() = this != null && (this.startsWith(VIDEO_REDIRECT) || this.startsWith("https://video-"))
fun Context.frostChangelog() = showChangelog(R.xml.frost_changelog, Prefs.textColor) {
theme()
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 639dc9ba..9d5e199a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt
@@ -8,12 +8,12 @@ import android.util.AttributeSet
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
+import ca.allanwang.kau.ui.ProgressAnimator
import ca.allanwang.kau.utils.AnimHolder
import ca.allanwang.kau.utils.dpToPx
import ca.allanwang.kau.utils.scaleXY
import com.devbrackets.android.exomedia.ui.widget.VideoView
import com.pitchedapps.frost.utils.L
-import com.pitchedapps.frost.utils.ProgressAnimator
/**
* Created by Allan Wang on 2017-10-13.
@@ -83,7 +83,7 @@ class FrostVideoView @JvmOverloads constructor(
ProgressAnimator.ofFloat {
duration = ANIMATION_DURATION
interpolator = AnimHolder.fastOutSlowInInterpolator(context)
- withAnimatorInv { viewerContract.onExpand(it) }
+ withAnimator { viewerContract.onExpand(1f - it) }
withAnimator(origScale, scale) { scaleXY = it }
withAnimator(origX, tX) { translationX = it }
withAnimator(origY, tY) { translationY = it }
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 ca88a23e..e8f9fee9 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt
@@ -3,11 +3,13 @@ package com.pitchedapps.frost.web
import com.pitchedapps.frost.activities.WebOverlayActivity
import com.pitchedapps.frost.activities.WebOverlayActivityBase
import com.pitchedapps.frost.activities.WebOverlayBasicActivity
+
import com.pitchedapps.frost.contracts.VideoViewHolder
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 org.jetbrains.anko.runOnUiThread
/**
* Created by Allan Wang on 2017-08-15.
@@ -18,6 +20,9 @@ import com.pitchedapps.frost.utils.*
* This helper method will collect all known cases and launch the overlay accordingly
* Returns {@code true} (default) if action is consumed, {@code false} otherwise
*
+ * Note that this is not always called on the main thread!
+ * UI related methods should always be posted or they may not be properly executed.
+ *
* If the request already comes from an instance of [WebOverlayActivity], we will then judge
* whether the user agent string should be changed. All propagated results will return false,
* as we have no need of sending a new intent to the same activity
@@ -26,7 +31,7 @@ fun FrostWebViewCore.requestWebOverlay(url: String): Boolean {
if (url == "#") return false
if (url.isVideoUrl && context is VideoViewHolder) {
L.i("Found video", url)
- (context as VideoViewHolder).showVideo(url)
+ context.runOnUiThread { (context as VideoViewHolder).showVideo(url) }
return true
}
if (!Prefs.overlayEnabled) return false