refactor: read local file with fs plugin for Tauri App, closes #553 and closes #489 (#785)

This commit is contained in:
Huang Xin 2025-04-01 20:26:26 +08:00 committed by GitHub
parent 39fb7f759e
commit 7ccf3d0632
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
46 changed files with 1164 additions and 790 deletions

View file

@ -1,18 +1,26 @@
package com.readest.native_bridge
import android.app.Activity
import android.net.Uri
import app.tauri.annotation.Command
import app.tauri.annotation.InvokeArg
import app.tauri.annotation.TauriPlugin
import app.tauri.plugin.JSObject
import app.tauri.plugin.Plugin
import app.tauri.plugin.Invoke
import java.io.*
@InvokeArg
class SafariAuthRequestArgs {
var authUrl: String? = null
}
@InvokeArg
class CopyURIRequestArgs {
var uri: String? = null
var dst: String? = null
}
@TauriPlugin
class NativeBridgePlugin(private val activity: Activity): Plugin(activity) {
private val implementation = NativeBridge()
@ -25,4 +33,31 @@ class NativeBridgePlugin(private val activity: Activity): Plugin(activity) {
ret.put("redirectUrl", implementation.auth_with_safari(args.authUrl ?: ""))
invoke.resolve(ret)
}
@Command
fun copy_uri_to_path(invoke: Invoke) {
val args = invoke.parseArgs(CopyURIRequestArgs::class.java)
val ret = JSObject()
try {
val uri = Uri.parse(args.uri ?: "")
val dst = File(args.dst ?: "")
val inputStream = activity.contentResolver.openInputStream(uri)
if (inputStream != null) {
dst.outputStream().use { output ->
inputStream.use { input ->
input.copyTo(output)
}
}
ret.put("success", true)
} else {
ret.put("success", false)
ret.put("error", "Failed to open input stream from URI")
}
} catch (e: Exception) {
ret.put("success", false)
ret.put("error", e.message)
}
invoke.resolve(ret)
}
}

View file

@ -1,8 +1,8 @@
const COMMANDS: &[&str] = &["auth_with_safari"];
const COMMANDS: &[&str] = &["auth_with_safari", "copy_uri_to_path"];
fn main() {
tauri_plugin::Builder::new(COMMANDS)
.android_path("android")
.ios_path("ios")
.build();
tauri_plugin::Builder::new(COMMANDS)
.android_path("android")
.ios_path("ios")
.build();
}

View file

@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-copy-uri-to-path"
description = "Enables the copy_uri_to_path command without any pre-configured scope."
commands.allow = ["copy_uri_to_path"]
[[permission]]
identifier = "deny-copy-uri-to-path"
description = "Denies the copy_uri_to_path command without any pre-configured scope."
commands.deny = ["copy_uri_to_path"]

View file

@ -3,6 +3,7 @@
Default permissions for the plugin
- `allow-auth-with-safari`
- `allow-copy-uri-to-path`
## Permission Table
@ -36,6 +37,32 @@ Enables the auth_with_safari command without any pre-configured scope.
Denies the auth_with_safari command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`native-bridge:allow-copy-uri-to-path`
</td>
<td>
Enables the copy_uri_to_path command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`native-bridge:deny-copy-uri-to-path`
</td>
<td>
Denies the copy_uri_to_path command without any pre-configured scope.
</td>
</tr>
</table>

View file

@ -1,3 +1,3 @@
[default]
description = "Default permissions for the plugin"
permissions = ["allow-auth-with-safari"]
permissions = ["allow-auth-with-safari", "allow-copy-uri-to-path"]

View file

@ -304,6 +304,16 @@
"type": "string",
"const": "deny-auth-with-safari"
},
{
"description": "Enables the copy_uri_to_path command without any pre-configured scope.",
"type": "string",
"const": "allow-copy-uri-to-path"
},
{
"description": "Denies the copy_uri_to_path command without any pre-configured scope.",
"type": "string",
"const": "deny-copy-uri-to-path"
},
{
"description": "Default permissions for the plugin",
"type": "string",

View file

@ -11,3 +11,11 @@ pub(crate) async fn auth_with_safari<R: Runtime>(
) -> Result<SafariAuthResponse> {
app.native_bridge().auth_with_safari(payload)
}
#[command]
pub(crate) async fn copy_uri_to_path<R: Runtime>(
app: AppHandle<R>,
payload: CopyURIRequest,
) -> Result<CopyURIResponse> {
app.native_bridge().copy_uri_to_path(payload)
}

View file

@ -20,4 +20,8 @@ impl<R: Runtime> NativeBridge<R> {
) -> crate::Result<SafariAuthResponse> {
Err(crate::Error::UnsupportedPlatformError)
}
pub fn copy_uri_to_path(&self, _payload: CopyURIRequest) -> crate::Result<CopyURIResponse> {
Err(crate::Error::UnsupportedPlatformError)
}
}

View file

@ -36,7 +36,10 @@ impl<R: Runtime, T: Manager<R>> crate::NativeBridgeExt<R> for T {
/// Initializes the plugin.
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("native-bridge")
.invoke_handler(tauri::generate_handler![commands::auth_with_safari])
.invoke_handler(tauri::generate_handler![
commands::auth_with_safari,
commands::copy_uri_to_path,
])
.setup(|app, api| {
#[cfg(mobile)]
let native_bridge = mobile::init(app, api)?;

View file

@ -34,3 +34,11 @@ impl<R: Runtime> NativeBridge<R> {
.map_err(Into::into)
}
}
impl<R: Runtime> NativeBridge<R> {
pub fn copy_uri_to_path(&self, payload: CopyURIRequest) -> crate::Result<CopyURIResponse> {
self.0
.run_mobile_plugin("copy_uri_to_path", payload)
.map_err(Into::into)
}
}

View file

@ -11,3 +11,17 @@ pub struct SafariAuthRequest {
pub struct SafariAuthResponse {
pub redirect_url: String,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CopyURIRequest {
pub uri: String,
pub dst: String,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CopyURIResponse {
pub success: bool,
pub error: Option<String>,
}