Skip to content

Commit

Permalink
Make external links open in external browser
Browse files Browse the repository at this point in the history
  • Loading branch information
MarmadileManteater committed Feb 5, 2024
1 parent 9fd04d2 commit 920906b
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,12 @@ class FreeTubeJavaScriptInterface {
@JavascriptInterface
fun readFile(basedir: String, filename: String): String {
try {
if (basedir.startsWith("content://")) {
val stream = context.contentResolver.openInputStream(Uri.parse(basedir))
val content = String(stream!!.readBytes())
stream!!.close()
return content
}
val path = getDirectory(basedir)
val file = File(path, filename)
return FileInputStream(file).bufferedReader().use { it.readText() }
Expand Down Expand Up @@ -398,18 +404,40 @@ class FreeTubeJavaScriptInterface {
}
try {
val uri = result!!.data!!.data
var stringUri = uri.toString()
// something about the java bridge url decodes all strings, so I am going to double encode this one
val uriBase = "content://com.android.providers.downloads.documents/document/"
var stringUri = uri.toString().replace(uriBase, "")

resolve(promise, "${uriBase}${URLEncoder.encode(stringUri, "utf-8")}")
resolve(promise, "{ \"uri\": \"${URLEncoder.encode(stringUri, "utf-8")}\" }")
} catch (ex: Exception) {
reject(promise, ex.toString())
}
}
context.activityResultLauncher.launch(saveDialogIntent)
return promise
}
@JavascriptInterface
fun requestOpenDialog(fileTypes: String): String {
val promise = jsPromise()
val openDialogIntent = Intent(Intent.ACTION_GET_CONTENT)
.setType("*/*")
.putExtra(Intent.EXTRA_MIME_TYPES, fileTypes.split(",").toTypedArray())

context.listenForActivityResults {
result: ActivityResult? ->
if (result!!.resultCode == Activity.RESULT_CANCELED) {
resolve(promise, "USER_CANCELED")
}
try {
val uri = result!!.data!!.data
var mimeType = context.contentResolver.getType(uri!!)

resolve(promise, "{ \"uri\": \"${URLEncoder.encode(uri.toString(), "utf-8")}\", \"type\": \"${mimeType}\" }")
} catch (ex: Exception) {
reject(promise, ex.toString())
}
}
context.activityResultLauncher.launch(openDialogIntent)
return promise
}

/**
* @return the id of a promise on the window
Expand All @@ -426,7 +454,7 @@ class FreeTubeJavaScriptInterface {
* resolves a js promise given the id
*/
private fun resolve(id: String, message: String) {
context.webView.loadUrl("javascript: window['${id}'].resolve(\"${message}\")")
context.webView.loadUrl("javascript: window['${id}'].resolve(`${message}`)")
}

/**
Expand Down
11 changes: 11 additions & 0 deletions android/app/src/main/java/io/freetubeapp/freetube/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.webkit.WebChromeClient
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.FrameLayout
Expand Down Expand Up @@ -107,6 +108,16 @@ class MainActivity : AppCompatActivity(), OnRequestPermissionsResultCallback {
}
}
webView.webViewClient = object: WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
if (request!!.url!!.scheme == "file") {
// don't send file url requests to a web browser (it will crash the app)
return true
}
// send all requests to a real web browser
val intent = Intent(Intent.ACTION_VIEW, request!!.url)
this@MainActivity.startActivity(intent)
return true
}
override fun onPageFinished(view: WebView?, url: String?) {
webView.loadUrl(
"javascript: window.mediaSessionListeners = window.mediaSessionListeners || {};" +
Expand Down
13 changes: 8 additions & 5 deletions src/renderer/components/data-settings/data-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,13 @@ export default defineComponent({
}
response.filePaths.forEach(filePath => {
// db and opml are the same mime type in android
if (textDecode.trim().startsWith('{') && filePath.endsWith('.opml')) {
filePath = filePath.split().splice(filePath.length - 5, 5, '.db'.split()).join()
if (process.env.IS_ANDROID) {
if (textDecode.trim().startsWith('{') && filePath.endsWith('.opml')) {
filePath = filePath.split().splice(filePath.length - 5, 5, '.db'.split()).join()
}
}
if (filePath.endsWith('.csv')) {
this.importCsvYouTubeSubscriptions(textDecode)
// opml and db are the same mime type 🤷‍♀️
} else if (filePath.endsWith('.db')) {
this.importFreeTubeSubscriptions(textDecode)
} else if (filePath.endsWith('.opml') || filePath.endsWith('.xml')) {
Expand Down Expand Up @@ -696,8 +697,10 @@ export default defineComponent({

response.filePaths.forEach(filePath => {
// db and opml are the same mime type in android
if (textDecode.trim().startsWith('{') && filePath.endsWith('.opml')) {
filePath = filePath.split().splice(filePath.length - 5, 5, '.db'.split()).join()
if (process.env.IS_ANDROID) {
if (textDecode.trim().startsWith('{') && filePath.endsWith('.opml')) {
filePath = filePath.split().splice(filePath.length - 5, 5, '.db'.split()).join()
}
}
if (filePath.endsWith('.db')) {
this.importFreeTubeHistory(textDecode.split('\n'))
Expand Down

0 comments on commit 920906b

Please sign in to comment.