feat(images): share target working and receiving images!

This commit is contained in:
2025-04-21 11:44:34 +01:00
parent 8cad29a661
commit a859abfc17
7 changed files with 89 additions and 16 deletions

View File

@ -20,6 +20,7 @@
"@tabler/icons-solidjs": "^3.30.0",
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-dialog": "~2",
"@tauri-apps/plugin-fs": "~2",
"@tauri-apps/plugin-http": "~2",
"@tauri-apps/plugin-opener": "^2",
"clsx": "^2.1.1",
@ -30,6 +31,7 @@
"solid-motionone": "^1.0.3",
"solidjs-markdown": "^0.2.0",
"tailwind-scrollbar-hide": "^2.0.0",
"tauri-plugin-sharetarget-api": "^0.1.6",
"valibot": "^1.0.0-rc.2"
},
"devDependencies": {

View File

@ -14,9 +14,11 @@ dependencies = [
"serde_json",
"tauri",
"tauri-build",
"tauri-plugin-fs",
"tauri-plugin-global-shortcut",
"tauri-plugin-http",
"tauri-plugin-log",
"tauri-plugin-sharetarget",
"tauri-plugin-store",
"tokio",
]
@ -4060,6 +4062,20 @@ dependencies = [
"time",
]
[[package]]
name = "tauri-plugin-sharetarget"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15a6e4638b6a5492a46847fc9e994df8cfd2dbc1bacc11f15c207d6a2163c341"
dependencies = [
"serde",
"serde_json",
"tauri",
"tauri-build",
"tauri-plugin",
"thiserror 1.0.69",
]
[[package]]
name = "tauri-plugin-store"
version = "2.2.0"

View File

@ -28,6 +28,8 @@ tauri-plugin-store = "2.0.0-beta.12"
tauri-plugin-http = "2.0.0-beta.12"
chrono = "0.4"
tauri-plugin-log = "2"
tauri-plugin-sharetarget = "0.1.6"
tauri-plugin-fs = "2"
[target."cfg(target_os = \"macos\")".dependencies]
cocoa = "0.26"

View File

@ -10,19 +10,26 @@
"core:window:allow-show",
"core:window:allow-set-focus",
{
"identifier": "http:default",
"allow": [
{
"url": "https://haystack.johncosta.tech"
},
{
"url": "http://localhost:3040"
},
{
"url": "http://192.168.1.199:3040"
}
]
"path": "$APPDATA/databases/*"
}
]
},
{
"identifier": "http:default",
"allow": [
{
"url": "https://haystack.johncosta.tech"
},
"log:default"
]
}
{
"url": "http://localhost:3040"
},
{
"url": "http://192.168.1.199:3040"
}
]
},
"log:default",
"fs:default",
"fs:default"
]
}

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- AndroidTV support -->
<uses-feature android:name="android.software.leanback" android:required="false" />
@ -18,7 +19,10 @@
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
<data android:mimeType="image/*" />
<!-- AndroidTV support -->
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>

View File

@ -13,9 +13,11 @@ pub fn run() {
let watcher_state = new_shared_watcher_state();
tauri::Builder::default()
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_log::Builder::new().build())
.plugin(tauri_plugin_store::Builder::new().build())
.plugin(tauri_plugin_http::init())
.plugin(tauri_plugin_sharetarget::init())
// .plugin(tauri_plugin_dialog::init())
// .plugin(tauri_plugin_opener::init())
.manage(watcher_state)

View File

@ -1,13 +1,22 @@
import { Route, Router } from "@solidjs/router";
import { listen } from "@tauri-apps/api/event";
import { createEffect, onCleanup } from "solid-js";
import { createEffect, createSignal, For, onCleanup, Show } from "solid-js";
import { Login } from "./Login";
import { ProtectedRoute } from "./ProtectedRoute";
import { Search } from "./Search";
import { Settings } from "./Settings";
import { ImageViewer } from "./components/ImageViewer";
import type { PluginListener } from "@tauri-apps/api/core";
import {
listenForShareEvents,
type ShareEvent,
} from "tauri-plugin-sharetarget-api";
import { readFile } from "@tauri-apps/plugin-fs";
export const App = () => {
const [logs, setLogs] = createSignal<string[]>([]);
const [file, setFile] = createSignal<File>();
createEffect(() => {
// TODO: Don't use window.location.href
const unlisten = listen("focus-search", () => {
@ -19,9 +28,40 @@ export const App = () => {
});
});
createEffect(() => {
let listener: PluginListener;
const setupListener = async () => {
listener = await listenForShareEvents(
async (intent: ShareEvent) => {
const contents = await readFile(intent.stream).catch(
(error: Error) => {
console.warn("fetching shared content failed:");
throw error;
},
);
setFile(
new File([contents], intent.name ?? "no-name", {
type: intent.content_type,
}),
);
setLogs((l) => [...l, intent.uri]);
},
);
};
setupListener();
return () => {
listener?.unregister();
};
});
return (
<>
<ImageViewer />
<p>Hello</p>
<Show when={file()}>
{(f) => <img alt="my-image" src={URL.createObjectURL(f())} />}
</Show>
<For each={logs()}>{(log) => <p>{log}</p>}</For>
<Router>
<Route path="/login" component={Login} />