mirror of
https://github.com/tauri-apps/tauri.git
synced 2025-01-03 16:42:42 +03:00
refactor(core): use wry RPC API (#1327)
This commit is contained in:
parent
e7f65ebdd7
commit
b0c1009098
@ -1,4 +1,4 @@
|
||||
import { invoke } from './tauri'
|
||||
import { invokeTauriCommand } from './helpers/tauri'
|
||||
|
||||
export interface ArgMatch {
|
||||
/**
|
||||
@ -27,7 +27,7 @@ export interface CliMatches {
|
||||
* gets the CLI matches
|
||||
*/
|
||||
async function getMatches(): Promise<CliMatches> {
|
||||
return invoke<CliMatches>({
|
||||
return invokeTauriCommand<CliMatches>({
|
||||
__tauriModule: 'Cli',
|
||||
message: {
|
||||
cmd: 'cliMatches'
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { invoke } from './tauri'
|
||||
import { invokeTauriCommand } from './helpers/tauri'
|
||||
|
||||
export interface DialogFilter {
|
||||
name: string
|
||||
@ -34,7 +34,7 @@ async function open(
|
||||
Object.freeze(options)
|
||||
}
|
||||
|
||||
return invoke<string | string[]>({
|
||||
return invokeTauriCommand<string | string[]>({
|
||||
__tauriModule: 'Dialog',
|
||||
mainThread: true,
|
||||
message: {
|
||||
@ -57,7 +57,7 @@ async function save(options: SaveDialogOptions = {}): Promise<string> {
|
||||
Object.freeze(options)
|
||||
}
|
||||
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Dialog',
|
||||
mainThread: true,
|
||||
message: {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { invoke } from './tauri'
|
||||
import { invokeTauriCommand } from './helpers/tauri'
|
||||
|
||||
export enum BaseDirectory {
|
||||
Audio = 1,
|
||||
@ -61,7 +61,7 @@ async function readTextFile(
|
||||
filePath: string,
|
||||
options: FsOptions = {}
|
||||
): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'readTextFile',
|
||||
@ -83,7 +83,7 @@ async function readBinaryFile(
|
||||
filePath: string,
|
||||
options: FsOptions = {}
|
||||
): Promise<number[]> {
|
||||
return invoke<number[]>({
|
||||
return invokeTauriCommand<number[]>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'readBinaryFile',
|
||||
@ -114,7 +114,7 @@ async function writeFile(
|
||||
Object.freeze(file)
|
||||
}
|
||||
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'writeFile',
|
||||
@ -179,7 +179,7 @@ async function writeBinaryFile(
|
||||
Object.freeze(file)
|
||||
}
|
||||
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'writeBinaryFile',
|
||||
@ -203,7 +203,7 @@ async function readDir(
|
||||
dir: string,
|
||||
options: FsDirOptions = {}
|
||||
): Promise<FileEntry[]> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'readDir',
|
||||
@ -228,7 +228,7 @@ async function createDir(
|
||||
dir: string,
|
||||
options: FsDirOptions = {}
|
||||
): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'createDir',
|
||||
@ -252,7 +252,7 @@ async function removeDir(
|
||||
dir: string,
|
||||
options: FsDirOptions = {}
|
||||
): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'removeDir',
|
||||
@ -276,7 +276,7 @@ async function copyFile(
|
||||
destination: string,
|
||||
options: FsOptions = {}
|
||||
): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'copyFile',
|
||||
@ -299,7 +299,7 @@ async function removeFile(
|
||||
file: string,
|
||||
options: FsOptions = {}
|
||||
): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'removeFile',
|
||||
@ -323,7 +323,7 @@ async function renameFile(
|
||||
newPath: string,
|
||||
options: FsOptions = {}
|
||||
): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'renameFile',
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { invoke, transformCallback } from './tauri'
|
||||
import { invokeTauriCommand } from './helpers/tauri'
|
||||
import { transformCallback } from './tauri'
|
||||
|
||||
/**
|
||||
* Register a global shortcut
|
||||
@ -9,7 +10,7 @@ async function register(
|
||||
shortcut: string,
|
||||
handler: (shortcut: string) => void
|
||||
): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'GlobalShortcut',
|
||||
message: {
|
||||
cmd: 'register',
|
||||
@ -28,7 +29,7 @@ async function registerAll(
|
||||
shortcuts: string[],
|
||||
handler: (shortcut: string) => void
|
||||
): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'GlobalShortcut',
|
||||
message: {
|
||||
cmd: 'registerAll',
|
||||
@ -45,7 +46,7 @@ async function registerAll(
|
||||
* @return {Promise<boolean>} promise resolving to the state
|
||||
*/
|
||||
async function isRegistered(shortcut: string): Promise<boolean> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'GlobalShortcut',
|
||||
message: {
|
||||
cmd: 'isRegistered',
|
||||
@ -59,7 +60,7 @@ async function isRegistered(shortcut: string): Promise<boolean> {
|
||||
* @param shortcut shortcut definition, modifiers and key separated by "+" e.g. CmdOrControl+Q
|
||||
*/
|
||||
async function unregister(shortcut: string): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'GlobalShortcut',
|
||||
message: {
|
||||
cmd: 'unregister',
|
||||
@ -72,7 +73,7 @@ async function unregister(shortcut: string): Promise<void> {
|
||||
* Unregisters all shortcuts registered by the application.
|
||||
*/
|
||||
async function unregisterAll(): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'GlobalShortcut',
|
||||
message: {
|
||||
cmd: 'unregisterAll'
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { invoke, transformCallback } from '../tauri'
|
||||
import { invokeTauriCommand } from './tauri'
|
||||
import { transformCallback } from '../tauri'
|
||||
|
||||
export interface Event<T> {
|
||||
type: string
|
||||
@ -12,7 +13,7 @@ async function _listen<T>(
|
||||
handler: EventCallback<T>,
|
||||
once: boolean
|
||||
): Promise<void> {
|
||||
await invoke({
|
||||
await invokeTauriCommand({
|
||||
__tauriModule: 'Event',
|
||||
message: {
|
||||
cmd: 'listen',
|
||||
@ -60,7 +61,7 @@ async function emit(
|
||||
windowLabel?: string,
|
||||
payload?: string
|
||||
): Promise<void> {
|
||||
await invoke({
|
||||
await invokeTauriCommand({
|
||||
__tauriModule: 'Event',
|
||||
message: {
|
||||
cmd: 'emit',
|
||||
|
22
api/src/helpers/tauri.ts
Normal file
22
api/src/helpers/tauri.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { invoke } from '../tauri'
|
||||
|
||||
export type TauriModule = 'Fs' |
|
||||
'Window' |
|
||||
'Shell' |
|
||||
'Event' |
|
||||
'Internal' |
|
||||
'Dialog' |
|
||||
'Cli' |
|
||||
'Notification' |
|
||||
'Http' |
|
||||
'GlobalShortcut'
|
||||
|
||||
export interface TauriCommand {
|
||||
__tauriModule: TauriModule
|
||||
mainThread?: boolean
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
export async function invokeTauriCommand<T>(command: TauriCommand): Promise<T> {
|
||||
return invoke('tauri', command)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { invoke } from './tauri'
|
||||
import { invokeTauriCommand } from './helpers/tauri'
|
||||
|
||||
export interface ClientOptions {
|
||||
maxRedirections: boolean
|
||||
@ -80,7 +80,7 @@ export class Client {
|
||||
* drops the client instance
|
||||
*/
|
||||
async drop(): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Http',
|
||||
message: {
|
||||
cmd: 'dropClient',
|
||||
@ -97,7 +97,7 @@ export class Client {
|
||||
* @return promise resolving to the response
|
||||
*/
|
||||
async request<T>(options: HttpOptions): Promise<Response<T>> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Http',
|
||||
message: {
|
||||
cmd: 'httpRequest',
|
||||
@ -201,7 +201,7 @@ export class Client {
|
||||
}
|
||||
|
||||
async function getClient(options?: ClientOptions): Promise<Client> {
|
||||
return invoke<number>({
|
||||
return invokeTauriCommand<number>({
|
||||
__tauriModule: 'Http',
|
||||
message: {
|
||||
cmd: 'createClient',
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { invoke } from './tauri'
|
||||
import { invokeTauriCommand } from './helpers/tauri'
|
||||
|
||||
export interface Options {
|
||||
title: string
|
||||
@ -13,7 +13,7 @@ async function isPermissionGranted(): Promise<boolean | null> {
|
||||
if (window.Notification.permission !== 'default') {
|
||||
return Promise.resolve(window.Notification.permission === 'granted')
|
||||
}
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Notification',
|
||||
message: {
|
||||
cmd: 'isNotificationPermissionGranted'
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { invoke } from './tauri'
|
||||
import { invokeTauriCommand } from './helpers/tauri'
|
||||
import { BaseDirectory } from './fs'
|
||||
|
||||
/**
|
||||
@ -7,7 +7,7 @@ import { BaseDirectory } from './fs'
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function appDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -23,7 +23,7 @@ async function appDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function audioDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -39,7 +39,7 @@ async function audioDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function cacheDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -55,7 +55,7 @@ async function cacheDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function configDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -71,7 +71,7 @@ async function configDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function dataDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -87,7 +87,7 @@ async function dataDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function desktopDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -103,7 +103,7 @@ async function desktopDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function documentDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -119,7 +119,7 @@ async function documentDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function downloadDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -135,7 +135,7 @@ async function downloadDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function executableDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -151,7 +151,7 @@ async function executableDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function fontDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -167,7 +167,7 @@ async function fontDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function homeDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -183,7 +183,7 @@ async function homeDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function localDataDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -199,7 +199,7 @@ async function localDataDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function pictureDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -215,7 +215,7 @@ async function pictureDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function publicDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -231,7 +231,7 @@ async function publicDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function resourceDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -247,7 +247,7 @@ async function resourceDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function runtimeDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -263,7 +263,7 @@ async function runtimeDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function templateDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -279,7 +279,7 @@ async function templateDir(): Promise<string> {
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function videoDir(): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
@ -298,7 +298,7 @@ async function resolvePath(
|
||||
path: string,
|
||||
directory: BaseDirectory
|
||||
): Promise<string> {
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Fs',
|
||||
message: {
|
||||
cmd: 'resolvePath',
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { invoke } from './tauri'
|
||||
import { invokeTauriCommand } from './helpers/tauri'
|
||||
|
||||
/**
|
||||
* spawns a process
|
||||
@ -15,7 +15,7 @@ async function execute(
|
||||
Object.freeze(args)
|
||||
}
|
||||
|
||||
return invoke<string>({
|
||||
return invokeTauriCommand<string>({
|
||||
__tauriModule: 'Shell',
|
||||
message: {
|
||||
cmd: 'execute',
|
||||
@ -31,7 +31,7 @@ async function execute(
|
||||
* @param url the URL to open
|
||||
*/
|
||||
async function open(url: string): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Shell',
|
||||
message: {
|
||||
cmd: 'open',
|
||||
|
@ -1,7 +1,9 @@
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
interface Window {
|
||||
__TAURI_INVOKE_HANDLER__: (command: { [key: string]: unknown }) => void
|
||||
rpc: {
|
||||
notify: (command: string, args?: { [key: string]: unknown }) => void
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,6 +51,11 @@ function transformCallback(
|
||||
return identifier
|
||||
}
|
||||
|
||||
export interface InvokeArgs {
|
||||
mainThread?: boolean
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
/**
|
||||
* sends a message to the backend
|
||||
*
|
||||
@ -57,8 +64,8 @@ function transformCallback(
|
||||
* @return {Promise<T>} Promise resolving or rejecting to the backend response
|
||||
*/
|
||||
async function invoke<T>(
|
||||
cmd: string | { [key: string]: unknown },
|
||||
args: { [key: string]: unknown } = {}
|
||||
cmd: string,
|
||||
args: InvokeArgs = {}
|
||||
): Promise<T> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const callback = transformCallback((e) => {
|
||||
@ -70,15 +77,7 @@ async function invoke<T>(
|
||||
Reflect.deleteProperty(window, callback)
|
||||
}, true)
|
||||
|
||||
if (typeof cmd === 'string') {
|
||||
args.cmd = cmd
|
||||
} else if (typeof cmd === 'object') {
|
||||
args = cmd
|
||||
} else {
|
||||
return reject(new Error('Invalid argument type.'))
|
||||
}
|
||||
|
||||
window.__TAURI_INVOKE_HANDLER__({
|
||||
window.rpc.notify(cmd, {
|
||||
callback,
|
||||
error,
|
||||
...args
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { invoke } from './tauri'
|
||||
import { invokeTauriCommand } from './helpers/tauri'
|
||||
import { EventCallback, emit, listen, once } from './helpers/event'
|
||||
|
||||
interface WindowDef {
|
||||
@ -90,14 +90,12 @@ class WebviewWindowHandle {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
_emitTauriEvent(event: string): void {}
|
||||
}
|
||||
|
||||
class WebviewWindow extends WebviewWindowHandle {
|
||||
constructor(label: string, options: WindowOptions = {}) {
|
||||
super(label)
|
||||
invoke({
|
||||
invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'createWebview',
|
||||
@ -131,7 +129,7 @@ class WindowManager {
|
||||
* Updates the window resizable flag.
|
||||
*/
|
||||
async setResizable(resizable: boolean): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'setResizable',
|
||||
@ -146,7 +144,7 @@ class WindowManager {
|
||||
* @param title the new title
|
||||
*/
|
||||
async setTitle(title: string): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'setTitle',
|
||||
@ -159,7 +157,7 @@ class WindowManager {
|
||||
* Maximizes the window.
|
||||
*/
|
||||
async maximize(): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'maximize'
|
||||
@ -171,7 +169,7 @@ class WindowManager {
|
||||
* Unmaximizes the window.
|
||||
*/
|
||||
async unmaximize(): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'unmaximize'
|
||||
@ -183,7 +181,7 @@ class WindowManager {
|
||||
* Minimizes the window.
|
||||
*/
|
||||
async minimize(): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'minimize'
|
||||
@ -195,7 +193,7 @@ class WindowManager {
|
||||
* Unminimizes the window.
|
||||
*/
|
||||
async unminimize(): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'unminimize'
|
||||
@ -207,7 +205,7 @@ class WindowManager {
|
||||
* Sets the window visibility to true.
|
||||
*/
|
||||
async show(): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'show'
|
||||
@ -219,7 +217,7 @@ class WindowManager {
|
||||
* Sets the window visibility to false.
|
||||
*/
|
||||
async hide(): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'hide'
|
||||
@ -231,7 +229,7 @@ class WindowManager {
|
||||
* Closes the window.
|
||||
*/
|
||||
async close(): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'close'
|
||||
@ -245,7 +243,7 @@ class WindowManager {
|
||||
* @param {boolean} decorations whether the window should have borders and bars
|
||||
*/
|
||||
async setDecorations(decorations: boolean): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'setDecorations',
|
||||
@ -260,7 +258,7 @@ class WindowManager {
|
||||
* @param {boolean} alwaysOnTop whether the window should always be on top of other windows or not
|
||||
*/
|
||||
async setAlwaysOnTop(alwaysOnTop: boolean): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'setAlwaysOnTop',
|
||||
@ -275,7 +273,7 @@ class WindowManager {
|
||||
* @param {number} width the new window width
|
||||
*/
|
||||
async setWidth(width: number): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'setWidth',
|
||||
@ -290,7 +288,7 @@ class WindowManager {
|
||||
* @param {number} height the new window height
|
||||
*/
|
||||
async setHeight(height: number): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'setHeight',
|
||||
@ -306,7 +304,7 @@ class WindowManager {
|
||||
* @param {number} height the new window height
|
||||
*/
|
||||
async resize(width: number, height: number): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'resize',
|
||||
@ -323,7 +321,7 @@ class WindowManager {
|
||||
* @param {number} minHeight the new window min height
|
||||
*/
|
||||
async setMinSize(minWidth: number, minHeight: number): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'setMinSize',
|
||||
@ -340,7 +338,7 @@ class WindowManager {
|
||||
* @param {number} maxHeight the new window max height
|
||||
*/
|
||||
async setMaxSize(maxWidth: number, maxHeight: number): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'setMaxSize',
|
||||
@ -356,7 +354,7 @@ class WindowManager {
|
||||
* @param {number} x the new window x position
|
||||
*/
|
||||
async setX(x: number): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'setX',
|
||||
@ -371,7 +369,7 @@ class WindowManager {
|
||||
* @param {number} y the new window y position
|
||||
*/
|
||||
async setY(y: number): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'setY',
|
||||
@ -387,7 +385,7 @@ class WindowManager {
|
||||
* @param {number} y the new window y position
|
||||
*/
|
||||
async setPosition(x: number, y: number): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'setPosition',
|
||||
@ -403,7 +401,7 @@ class WindowManager {
|
||||
* @param {boolean} fullscreen whether the window should go to fullscreen or not
|
||||
*/
|
||||
async setFullscreen(fullscreen: boolean): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'setFullscreen',
|
||||
@ -418,7 +416,7 @@ class WindowManager {
|
||||
* @param {string | number[]} icon icon bytes or path to the icon file
|
||||
*/
|
||||
async setIcon(icon: 'string' | number[]): Promise<void> {
|
||||
return invoke({
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Window',
|
||||
message: {
|
||||
cmd: 'setIcon',
|
||||
|
@ -124,8 +124,9 @@ if (!String.prototype.startsWith) {
|
||||
return reject(new Error("Invalid argument type."));
|
||||
}
|
||||
|
||||
if (window.__TAURI_INVOKE_HANDLER__) {
|
||||
window.__TAURI_INVOKE_HANDLER__(
|
||||
if (window.rpc) {
|
||||
window.rpc.notify(
|
||||
cmd,
|
||||
_objectSpread(
|
||||
{
|
||||
callback: callback,
|
||||
@ -136,7 +137,8 @@ if (!String.prototype.startsWith) {
|
||||
);
|
||||
} else {
|
||||
window.addEventListener("DOMContentLoaded", function () {
|
||||
window.__TAURI_INVOKE_HANDLER__(
|
||||
window.rpc.notify(
|
||||
cmd,
|
||||
_objectSpread(
|
||||
{
|
||||
callback: callback,
|
||||
@ -165,7 +167,7 @@ if (!String.prototype.startsWith) {
|
||||
target.href.startsWith("http") &&
|
||||
target.target === "_blank"
|
||||
) {
|
||||
window.__TAURI__.invoke({
|
||||
window.__TAURI__.invoke('tauri', {
|
||||
__tauriModule: "Shell",
|
||||
message: {
|
||||
cmd: "open",
|
||||
@ -198,7 +200,7 @@ if (!String.prototype.startsWith) {
|
||||
);
|
||||
}
|
||||
|
||||
window.__TAURI__.invoke({
|
||||
window.__TAURI__.invoke('tauri', {
|
||||
__tauriModule: "Event",
|
||||
message: {
|
||||
cmd: "listen",
|
||||
@ -219,7 +221,7 @@ if (!String.prototype.startsWith) {
|
||||
if (window.Notification.permission !== "default") {
|
||||
return Promise.resolve(window.Notification.permission === "granted");
|
||||
}
|
||||
return window.__TAURI__.invoke({
|
||||
return window.__TAURI__.invoke('tauri', {
|
||||
__tauriModule: "Notification",
|
||||
message: {
|
||||
cmd: "isNotificationPermissionGranted",
|
||||
@ -235,7 +237,7 @@ if (!String.prototype.startsWith) {
|
||||
|
||||
function requestPermission() {
|
||||
return window.__TAURI__
|
||||
.invoke({
|
||||
.invoke('tauri', {
|
||||
__tauriModule: "Notification",
|
||||
mainThread: true,
|
||||
message: {
|
||||
@ -255,7 +257,7 @@ if (!String.prototype.startsWith) {
|
||||
|
||||
isPermissionGranted().then(function (permission) {
|
||||
if (permission) {
|
||||
return window.__TAURI__.invoke({
|
||||
return window.__TAURI__.invoke('tauri', {
|
||||
__tauriModule: "Notification",
|
||||
message: {
|
||||
cmd: "notification",
|
||||
@ -304,7 +306,7 @@ if (!String.prototype.startsWith) {
|
||||
});
|
||||
|
||||
window.alert = function (message) {
|
||||
window.__TAURI__.invoke({
|
||||
window.__TAURI__.invoke('tauri', {
|
||||
__tauriModule: "Dialog",
|
||||
mainThread: true,
|
||||
message: {
|
||||
@ -315,7 +317,7 @@ if (!String.prototype.startsWith) {
|
||||
};
|
||||
|
||||
window.confirm = function (message) {
|
||||
return window.__TAURI__.invoke({
|
||||
return window.__TAURI__.invoke('tauri', {
|
||||
__tauriModule: "Dialog",
|
||||
mainThread: true,
|
||||
message: {
|
||||
|
@ -136,9 +136,7 @@
|
||||
})
|
||||
|
||||
setTimeout(function () {
|
||||
window.__TAURI_INVOKE_HANDLER__({
|
||||
cmd: 'exit'
|
||||
})
|
||||
window.rpc.notify('exit')
|
||||
}, 15000)
|
||||
</script>
|
||||
</body>
|
||||
|
@ -1,8 +0,0 @@
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(tag = "cmd", rename_all = "camelCase")]
|
||||
pub enum Cmd {
|
||||
// your custom commands
|
||||
// multiple arguments are allowed
|
||||
// note that rename_all = "camelCase": you need to use "myCustomCommand" on JS
|
||||
Exit {},
|
||||
}
|
@ -1,5 +1,3 @@
|
||||
mod cmd;
|
||||
|
||||
use tauri::ApplicationDispatcherExt;
|
||||
|
||||
#[derive(tauri::FromTauriContext)]
|
||||
@ -21,19 +19,9 @@ fn main() {
|
||||
.current_webview()
|
||||
.eval("window.onTauriInit && window.onTauriInit()");
|
||||
})
|
||||
.invoke_handler(|webview_manager, arg| async move {
|
||||
use cmd::Cmd::*;
|
||||
match serde_json::from_str(&arg) {
|
||||
Err(e) => Err(e.into()),
|
||||
Ok(command) => {
|
||||
match command {
|
||||
// definitions for your custom commands from Cmd here
|
||||
Exit {} => {
|
||||
// TODO dispatcher.terminate();
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
.invoke_handler(|webview_manager, command, _arg| async move {
|
||||
if &command == "exit" {
|
||||
webview_manager.close().unwrap();
|
||||
}
|
||||
})
|
||||
.build()
|
||||
|
@ -133,17 +133,10 @@ pub fn generate_handler(item: proc_macro::TokenStream) -> TokenStream {
|
||||
});
|
||||
|
||||
quote! {
|
||||
|webview_manager, arg| async move {
|
||||
let dispatch: ::std::result::Result<::tauri::DispatchInstructions, ::serde_json::Error> =
|
||||
::serde_json::from_str(&arg);
|
||||
match dispatch {
|
||||
Err(e) => Err(e.into()),
|
||||
Ok(dispatch) => {
|
||||
match dispatch.cmd.as_str() {
|
||||
#(stringify!(#fn_names) => #fn_wrappers(webview_manager, dispatch.args).await,)*
|
||||
_ => Err(tauri::Error::UnknownApi(None)),
|
||||
}
|
||||
}
|
||||
|webview_manager, command, arg| async move {
|
||||
match command.as_str() {
|
||||
#(stringify!(#fn_names) => #fn_wrappers(webview_manager, arg).await,)*
|
||||
_ => Err(tauri::Error::UnknownApi(None)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ thiserror = "1.0.24"
|
||||
once_cell = "1.7.0"
|
||||
tauri-api = { version = "0.7.5", path = "../tauri-api" }
|
||||
tauri-macros = { version = "0.1", path = "../tauri-macros" }
|
||||
wry = { git = "https://github.com/tauri-apps/wry", rev = "a607d6aba95e6ee0d9620394b7ee0092527095dc" }
|
||||
wry = { git = "https://github.com/tauri-apps/wry", rev = "729fdc182eaf4af44d822dfc9396deb3f5f5810a" }
|
||||
rand = "0.8"
|
||||
|
||||
[build-dependencies]
|
||||
|
10
tauri/examples/api/src-tauri/Cargo.lock
generated
10
tauri/examples/api/src-tauri/Cargo.lock
generated
@ -1285,6 +1285,12 @@ dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "infer"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34ad0755c42f65a1374dcd0aae07e03dfefc911eceb3f409d2b4a888189447e6"
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.9"
|
||||
@ -3547,7 +3553,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.5.1"
|
||||
source = "git+https://github.com/tauri-apps/wry?rev=a607d6aba95e6ee0d9620394b7ee0092527095dc#a607d6aba95e6ee0d9620394b7ee0092527095dc"
|
||||
source = "git+https://github.com/tauri-apps/wry?rev=729fdc182eaf4af44d822dfc9396deb3f5f5810a#729fdc182eaf4af44d822dfc9396deb3f5f5810a"
|
||||
dependencies = [
|
||||
"cairo-rs",
|
||||
"cocoa",
|
||||
@ -3558,8 +3564,8 @@ dependencies = [
|
||||
"glib",
|
||||
"gtk",
|
||||
"image",
|
||||
"infer",
|
||||
"libc",
|
||||
"mime_guess",
|
||||
"objc",
|
||||
"objc_id",
|
||||
"once_cell",
|
||||
|
@ -103,7 +103,7 @@ if (!String.prototype.startsWith) {
|
||||
return identifier;
|
||||
};
|
||||
|
||||
window.__TAURI__.invoke = function invoke(args) {
|
||||
window.__TAURI__.invoke = function invoke(cmd, args = {}) {
|
||||
var _this = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
@ -116,8 +116,17 @@ if (!String.prototype.startsWith) {
|
||||
delete window[callback];
|
||||
}, true);
|
||||
|
||||
if (window.__TAURI_INVOKE_HANDLER__) {
|
||||
window.__TAURI_INVOKE_HANDLER__(
|
||||
if (typeof cmd === "string") {
|
||||
args.cmd = cmd;
|
||||
} else if (typeof cmd === "object") {
|
||||
args = cmd;
|
||||
} else {
|
||||
return reject(new Error("Invalid argument type."));
|
||||
}
|
||||
|
||||
if (window.rpc) {
|
||||
window.rpc.notify(
|
||||
cmd,
|
||||
_objectSpread(
|
||||
{
|
||||
callback: callback,
|
||||
@ -128,7 +137,8 @@ if (!String.prototype.startsWith) {
|
||||
);
|
||||
} else {
|
||||
window.addEventListener("DOMContentLoaded", function () {
|
||||
window.__TAURI_INVOKE_HANDLER__(
|
||||
window.rpc.notify(
|
||||
cmd,
|
||||
_objectSpread(
|
||||
{
|
||||
callback: callback,
|
||||
@ -157,7 +167,7 @@ if (!String.prototype.startsWith) {
|
||||
target.href.startsWith("http") &&
|
||||
target.target === "_blank"
|
||||
) {
|
||||
window.__TAURI__.invoke({
|
||||
window.__TAURI__.invoke('tauri', {
|
||||
__tauriModule: "Shell",
|
||||
message: {
|
||||
cmd: "open",
|
||||
@ -190,19 +200,19 @@ if (!String.prototype.startsWith) {
|
||||
);
|
||||
}
|
||||
|
||||
window.__TAURI__.invoke({
|
||||
__tauriModule: 'Event',
|
||||
window.__TAURI__.invoke('tauri', {
|
||||
__tauriModule: "Event",
|
||||
message: {
|
||||
cmd: 'listen',
|
||||
event: 'tauri://window-created',
|
||||
cmd: "listen",
|
||||
event: "tauri://window-created",
|
||||
handler: window.__TAURI__.transformCallback(function (event) {
|
||||
if (event.payload) {
|
||||
var windowLabel = event.payload.label
|
||||
window.__TAURI__.__windows.push({ label: windowLabel })
|
||||
var windowLabel = event.payload.label;
|
||||
window.__TAURI__.__windows.push({ label: windowLabel });
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
let permissionSettable = false;
|
||||
let permissionValue = "default";
|
||||
@ -211,7 +221,7 @@ if (!String.prototype.startsWith) {
|
||||
if (window.Notification.permission !== "default") {
|
||||
return Promise.resolve(window.Notification.permission === "granted");
|
||||
}
|
||||
return window.__TAURI__.invoke({
|
||||
return window.__TAURI__.invoke('tauri', {
|
||||
__tauriModule: "Notification",
|
||||
message: {
|
||||
cmd: "isNotificationPermissionGranted",
|
||||
@ -227,7 +237,7 @@ if (!String.prototype.startsWith) {
|
||||
|
||||
function requestPermission() {
|
||||
return window.__TAURI__
|
||||
.invoke({
|
||||
.invoke('tauri', {
|
||||
__tauriModule: "Notification",
|
||||
mainThread: true,
|
||||
message: {
|
||||
@ -247,7 +257,7 @@ if (!String.prototype.startsWith) {
|
||||
|
||||
isPermissionGranted().then(function (permission) {
|
||||
if (permission) {
|
||||
return window.__TAURI__.invoke({
|
||||
return window.__TAURI__.invoke('tauri', {
|
||||
__tauriModule: "Notification",
|
||||
message: {
|
||||
cmd: "notification",
|
||||
@ -296,7 +306,7 @@ if (!String.prototype.startsWith) {
|
||||
});
|
||||
|
||||
window.alert = function (message) {
|
||||
window.__TAURI__.invoke({
|
||||
window.__TAURI__.invoke('tauri', {
|
||||
__tauriModule: "Dialog",
|
||||
mainThread: true,
|
||||
message: {
|
||||
@ -307,7 +317,7 @@ if (!String.prototype.startsWith) {
|
||||
};
|
||||
|
||||
window.confirm = function (message) {
|
||||
return window.__TAURI__.invoke({
|
||||
return window.__TAURI__.invoke('tauri', {
|
||||
__tauriModule: "Dialog",
|
||||
mainThread: true,
|
||||
message: {
|
||||
|
10
tauri/examples/helloworld/src-tauri/Cargo.lock
generated
10
tauri/examples/helloworld/src-tauri/Cargo.lock
generated
@ -1242,6 +1242,12 @@ dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "infer"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34ad0755c42f65a1374dcd0aae07e03dfefc911eceb3f409d2b4a888189447e6"
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.9"
|
||||
@ -3461,7 +3467,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.5.1"
|
||||
source = "git+https://github.com/tauri-apps/wry?rev=a607d6aba95e6ee0d9620394b7ee0092527095dc#a607d6aba95e6ee0d9620394b7ee0092527095dc"
|
||||
source = "git+https://github.com/tauri-apps/wry?rev=729fdc182eaf4af44d822dfc9396deb3f5f5810a#729fdc182eaf4af44d822dfc9396deb3f5f5810a"
|
||||
dependencies = [
|
||||
"cairo-rs",
|
||||
"cocoa",
|
||||
@ -3472,8 +3478,8 @@ dependencies = [
|
||||
"glib",
|
||||
"gtk",
|
||||
"image",
|
||||
"infer",
|
||||
"libc",
|
||||
"mime_guess",
|
||||
"objc",
|
||||
"objc_id",
|
||||
"once_cell",
|
||||
|
50
tauri/examples/multiwindow/dist/__tauri.js
vendored
50
tauri/examples/multiwindow/dist/__tauri.js
vendored
File diff suppressed because one or more lines are too long
10
tauri/examples/multiwindow/src-tauri/Cargo.lock
generated
10
tauri/examples/multiwindow/src-tauri/Cargo.lock
generated
@ -1240,6 +1240,12 @@ dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "infer"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34ad0755c42f65a1374dcd0aae07e03dfefc911eceb3f409d2b4a888189447e6"
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.9"
|
||||
@ -3459,7 +3465,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.5.1"
|
||||
source = "git+https://github.com/tauri-apps/wry?rev=a607d6aba95e6ee0d9620394b7ee0092527095dc#a607d6aba95e6ee0d9620394b7ee0092527095dc"
|
||||
source = "git+https://github.com/tauri-apps/wry?rev=729fdc182eaf4af44d822dfc9396deb3f5f5810a#729fdc182eaf4af44d822dfc9396deb3f5f5810a"
|
||||
dependencies = [
|
||||
"cairo-rs",
|
||||
"cocoa",
|
||||
@ -3470,8 +3476,8 @@ dependencies = [
|
||||
"glib",
|
||||
"gtk",
|
||||
"image",
|
||||
"infer",
|
||||
"libc",
|
||||
"mime_guess",
|
||||
"objc",
|
||||
"objc_id",
|
||||
"once_cell",
|
||||
|
@ -1,5 +1,5 @@
|
||||
use futures::future::BoxFuture;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Serialize;
|
||||
use serde_json::Value as JsonValue;
|
||||
use tauri_api::{config::Config, private::AsTauriContext};
|
||||
|
||||
@ -15,12 +15,12 @@ mod webview_manager;
|
||||
pub use crate::api::config::WindowUrl;
|
||||
use crate::flavors::Wry;
|
||||
pub use webview::{
|
||||
wry::WryApplication, ApplicationDispatcherExt, ApplicationExt, Callback, CustomProtocol, Icon,
|
||||
Message, WebviewBuilderExt,
|
||||
wry::WryApplication, ApplicationDispatcherExt, ApplicationExt, CustomProtocol, Icon, Message,
|
||||
RpcRequest, WebviewBuilderExt, WebviewRpcHandler,
|
||||
};
|
||||
pub use webview_manager::{WebviewDispatcher, WebviewManager};
|
||||
|
||||
type InvokeHandler<A> = dyn Fn(WebviewManager<A>, String) -> BoxFuture<'static, crate::Result<InvokeResponse>>
|
||||
type InvokeHandler<A> = dyn Fn(WebviewManager<A>, String, JsonValue) -> BoxFuture<'static, crate::Result<InvokeResponse>>
|
||||
+ Send
|
||||
+ Sync;
|
||||
type Setup<A> = dyn Fn(WebviewManager<A>) -> BoxFuture<'static, ()> + Send + Sync;
|
||||
@ -63,15 +63,6 @@ impl<T: Serialize> From<T> for InvokeResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[allow(missing_docs)]
|
||||
#[serde(tag = "cmd", rename_all = "camelCase")]
|
||||
pub struct DispatchInstructions {
|
||||
pub cmd: String,
|
||||
#[serde(flatten)]
|
||||
pub args: JsonValue,
|
||||
}
|
||||
|
||||
/// The application runner.
|
||||
pub struct App<A: ApplicationExt> {
|
||||
/// The JS message handler.
|
||||
@ -116,10 +107,11 @@ impl<A: ApplicationExt + 'static> App<A> {
|
||||
pub(crate) async fn run_invoke_handler(
|
||||
&self,
|
||||
dispatcher: &WebviewManager<A>,
|
||||
command: String,
|
||||
arg: &JsonValue,
|
||||
) -> crate::Result<Option<InvokeResponse>> {
|
||||
if let Some(ref invoke_handler) = self.invoke_handler {
|
||||
let fut = invoke_handler(dispatcher.clone(), arg.to_string());
|
||||
let fut = invoke_handler(dispatcher.clone(), command, arg.clone());
|
||||
fut.await.map(Some)
|
||||
} else {
|
||||
Ok(None)
|
||||
@ -142,7 +134,7 @@ trait WebviewInitializer<A: ApplicationExt> {
|
||||
webview: Webview<A>,
|
||||
) -> crate::Result<(
|
||||
<A as ApplicationExt>::WebviewBuilder,
|
||||
Vec<Callback<A::Dispatcher>>,
|
||||
Option<WebviewRpcHandler<A::Dispatcher>>,
|
||||
Option<CustomProtocol>,
|
||||
)>;
|
||||
|
||||
@ -161,7 +153,7 @@ impl<A: ApplicationExt + 'static> WebviewInitializer<A> for Arc<App<A>> {
|
||||
webview: Webview<A>,
|
||||
) -> crate::Result<(
|
||||
<A as ApplicationExt>::WebviewBuilder,
|
||||
Vec<Callback<A::Dispatcher>>,
|
||||
Option<WebviewRpcHandler<A::Dispatcher>>,
|
||||
Option<CustomProtocol>,
|
||||
)> {
|
||||
let webview_manager = WebviewManager::new(
|
||||
@ -229,13 +221,13 @@ impl<A: ApplicationExt + 'static, C: AsTauriContext> AppBuilder<C, A> {
|
||||
/// Defines the JS message handler callback.
|
||||
pub fn invoke_handler<
|
||||
T: futures::Future<Output = crate::Result<InvokeResponse>> + Send + Sync + 'static,
|
||||
F: Fn(WebviewManager<A>, String) -> T + Send + Sync + 'static,
|
||||
F: Fn(WebviewManager<A>, String, JsonValue) -> T + Send + Sync + 'static,
|
||||
>(
|
||||
mut self,
|
||||
invoke_handler: F,
|
||||
) -> Self {
|
||||
self.invoke_handler = Some(Box::new(move |webview_manager, arg| {
|
||||
Box::pin(invoke_handler(webview_manager, arg))
|
||||
self.invoke_handler = Some(Box::new(move |webview_manager, command, args| {
|
||||
Box::pin(invoke_handler(webview_manager, command, args))
|
||||
}));
|
||||
self
|
||||
}
|
||||
@ -319,10 +311,10 @@ fn run<A: ApplicationExt + 'static>(mut application: App<A>) -> crate::Result<()
|
||||
application.dispatchers.clone(),
|
||||
webview_label.to_string(),
|
||||
);
|
||||
let (webview_builder, callbacks, custom_protocol) =
|
||||
let (webview_builder, rpc_handler, custom_protocol) =
|
||||
crate::async_runtime::block_on(application.init_webview(webview))?;
|
||||
|
||||
let dispatcher = webview_app.create_webview(webview_builder, callbacks, custom_protocol)?;
|
||||
let dispatcher = webview_app.create_webview(webview_builder, rpc_handler, custom_protocol)?;
|
||||
crate::async_runtime::block_on(application.on_webview_created(
|
||||
webview_label,
|
||||
dispatcher,
|
||||
|
@ -11,8 +11,8 @@ use crate::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
webview::{Callback, CustomProtocol, WebviewBuilderExtPrivate},
|
||||
App, Context, Webview, WebviewManager,
|
||||
webview::{CustomProtocol, WebviewBuilderExtPrivate, WebviewRpcHandler},
|
||||
App, Context, RpcRequest, Webview, WebviewManager,
|
||||
};
|
||||
|
||||
use serde::Deserialize;
|
||||
@ -84,11 +84,11 @@ pub(super) fn initialization_script(
|
||||
r#"
|
||||
{tauri_initialization_script}
|
||||
{event_initialization_script}
|
||||
if (window.__TAURI_INVOKE_HANDLER__) {{
|
||||
window.__TAURI__.invoke({{ cmd: "__initialized" }})
|
||||
if (window.rpc) {{
|
||||
window.__TAURI__.invoke("__initialized")
|
||||
}} else {{
|
||||
window.addEventListener('DOMContentLoaded', function () {{
|
||||
window.__TAURI__.invoke({{ cmd: "__initialized" }})
|
||||
window.__TAURI__.invoke("__initialized")
|
||||
}})
|
||||
}}
|
||||
{plugin_initialization_script}
|
||||
@ -140,7 +140,7 @@ fn event_initialization_script() -> String {
|
||||
|
||||
pub(super) type BuiltWebview<A> = (
|
||||
<A as ApplicationExt>::WebviewBuilder,
|
||||
Vec<Callback<<A as ApplicationExt>::Dispatcher>>,
|
||||
Option<WebviewRpcHandler<<A as ApplicationExt>::Dispatcher>>,
|
||||
Option<CustomProtocol>,
|
||||
);
|
||||
|
||||
@ -164,7 +164,7 @@ pub(super) fn build_webview<A: ApplicationExt + 'static>(
|
||||
WindowUrl::App => true,
|
||||
WindowUrl::Custom(url) => &url[0..8] == "tauri://",
|
||||
};
|
||||
let (webview_builder, callbacks, custom_protocol) = if is_local {
|
||||
let (webview_builder, rpc_handler, custom_protocol) = if is_local {
|
||||
let mut webview_builder = webview.builder.url(webview_url)
|
||||
.initialization_script(&initialization_script(plugin_initialization_script, &context.tauri_script))
|
||||
.initialization_script(&format!(
|
||||
@ -184,10 +184,17 @@ pub(super) fn build_webview<A: ApplicationExt + 'static>(
|
||||
}
|
||||
|
||||
let webview_manager_ = webview_manager.clone();
|
||||
let tauri_invoke_handler = crate::Callback::<A::Dispatcher> {
|
||||
name: "__TAURI_INVOKE_HANDLER__".to_string(),
|
||||
function: Box::new(move |_, arg| {
|
||||
let arg = arg.into_iter().next().unwrap_or(JsonValue::Null);
|
||||
let rpc_handler: Box<dyn Fn(<A as ApplicationExt>::Dispatcher, RpcRequest) + Send> =
|
||||
Box::new(move |_, request: RpcRequest| {
|
||||
let command = request.command.clone();
|
||||
let arg = request
|
||||
.params
|
||||
.unwrap()
|
||||
.as_array_mut()
|
||||
.unwrap()
|
||||
.first_mut()
|
||||
.unwrap_or(&mut JsonValue::Null)
|
||||
.take();
|
||||
let webview_manager = webview_manager_.clone();
|
||||
match serde_json::from_value::<Message>(arg) {
|
||||
Ok(message) => {
|
||||
@ -199,7 +206,12 @@ pub(super) fn build_webview<A: ApplicationExt + 'static>(
|
||||
crate::async_runtime::block_on(async move {
|
||||
execute_promise(
|
||||
&webview_manager,
|
||||
on_message(application, webview_manager.clone(), message),
|
||||
on_message(
|
||||
application,
|
||||
webview_manager.clone(),
|
||||
command.clone(),
|
||||
message,
|
||||
),
|
||||
callback,
|
||||
error,
|
||||
)
|
||||
@ -209,7 +221,7 @@ pub(super) fn build_webview<A: ApplicationExt + 'static>(
|
||||
crate::async_runtime::spawn(async move {
|
||||
execute_promise(
|
||||
&webview_manager,
|
||||
on_message(application, webview_manager.clone(), message),
|
||||
on_message(application, webview_manager.clone(), command, message),
|
||||
callback,
|
||||
error,
|
||||
)
|
||||
@ -229,8 +241,7 @@ pub(super) fn build_webview<A: ApplicationExt + 'static>(
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
};
|
||||
});
|
||||
let assets = context.assets;
|
||||
let custom_protocol = CustomProtocol {
|
||||
name: "tauri".into(),
|
||||
@ -268,16 +279,12 @@ pub(super) fn build_webview<A: ApplicationExt + 'static>(
|
||||
}
|
||||
}),
|
||||
};
|
||||
(
|
||||
webview_builder,
|
||||
vec![tauri_invoke_handler],
|
||||
Some(custom_protocol),
|
||||
)
|
||||
(webview_builder, Some(rpc_handler), Some(custom_protocol))
|
||||
} else {
|
||||
(webview.builder.url(webview_url), Vec::new(), None)
|
||||
(webview.builder.url(webview_url), None, None)
|
||||
};
|
||||
|
||||
Ok((webview_builder, callbacks, custom_protocol))
|
||||
Ok((webview_builder, rpc_handler, custom_protocol))
|
||||
}
|
||||
|
||||
/// Asynchronously executes the given task
|
||||
@ -313,9 +320,10 @@ async fn execute_promise<
|
||||
async fn on_message<A: ApplicationExt + 'static>(
|
||||
application: Arc<App<A>>,
|
||||
webview_manager: WebviewManager<A>,
|
||||
command: String,
|
||||
message: Message,
|
||||
) -> crate::Result<InvokeResponse> {
|
||||
if message.inner == serde_json::json!({ "cmd":"__initialized" }) {
|
||||
if &command == "__initialized" {
|
||||
application.run_setup(&webview_manager).await;
|
||||
crate::plugin::ready(A::plugin_store(), &webview_manager).await;
|
||||
Ok(().into())
|
||||
@ -330,7 +338,7 @@ async fn on_message<A: ApplicationExt + 'static>(
|
||||
.await
|
||||
} else {
|
||||
let mut response = match application
|
||||
.run_invoke_handler(&webview_manager, &message.inner)
|
||||
.run_invoke_handler(&webview_manager, command.clone(), &message.inner)
|
||||
.await
|
||||
{
|
||||
Ok(value) => {
|
||||
@ -343,7 +351,14 @@ async fn on_message<A: ApplicationExt + 'static>(
|
||||
Err(e) => Err(e),
|
||||
};
|
||||
if let Err(crate::Error::UnknownApi(_)) = response {
|
||||
match crate::plugin::extend_api(A::plugin_store(), &webview_manager, &message.inner).await {
|
||||
match crate::plugin::extend_api(
|
||||
A::plugin_store(),
|
||||
&webview_manager,
|
||||
command,
|
||||
&message.inner,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(value) => {
|
||||
// If value is None, that means that no plugin matched the command
|
||||
// and the UnknownApi error should be sent to the webview
|
||||
|
@ -157,14 +157,17 @@ pub trait WebviewBuilderExt: Sized {
|
||||
fn finish(self) -> crate::Result<Self::Webview>;
|
||||
}
|
||||
|
||||
/// Binds the given callback to a global variable on the window object.
|
||||
pub struct Callback<D> {
|
||||
/// Function name to bind.
|
||||
pub name: String,
|
||||
/// Function callback handler.
|
||||
pub function: Box<dyn FnMut(D, Vec<JsonValue>) + Send>,
|
||||
/// Rpc request.
|
||||
pub struct RpcRequest {
|
||||
/// RPC command.
|
||||
pub command: String,
|
||||
/// Params.
|
||||
pub params: Option<JsonValue>,
|
||||
}
|
||||
|
||||
/// Rpc handler.
|
||||
pub type WebviewRpcHandler<D> = Box<dyn Fn(D, RpcRequest) + Send>;
|
||||
|
||||
/// Uses a custom handler to resolve file requests
|
||||
pub struct CustomProtocol {
|
||||
/// Name of the protocol
|
||||
@ -185,7 +188,7 @@ pub trait ApplicationDispatcherExt: Clone + Send + Sync + Sized {
|
||||
fn create_webview(
|
||||
&self,
|
||||
webview_builder: Self::WebviewBuilder,
|
||||
callbacks: Vec<Callback<Self>>,
|
||||
rpc_handler: Option<WebviewRpcHandler<Self>>,
|
||||
custom_protocol: Option<CustomProtocol>,
|
||||
) -> crate::Result<Self>;
|
||||
|
||||
@ -278,7 +281,7 @@ pub trait ApplicationExt: Sized {
|
||||
fn create_webview(
|
||||
&mut self,
|
||||
webview_builder: Self::WebviewBuilder,
|
||||
callbacks: Vec<Callback<Self::Dispatcher>>,
|
||||
rpc_handler: Option<WebviewRpcHandler<Self::Dispatcher>>,
|
||||
custom_protocol: Option<CustomProtocol>,
|
||||
) -> crate::Result<Self::Dispatcher>;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{
|
||||
ApplicationDispatcherExt, ApplicationExt, Callback, CustomProtocol, Icon, WebviewBuilderExt,
|
||||
WebviewBuilderExtPrivate, WindowConfig,
|
||||
ApplicationDispatcherExt, ApplicationExt, CustomProtocol, Icon, RpcRequest, WebviewBuilderExt,
|
||||
WebviewBuilderExtPrivate, WebviewRpcHandler, WindowConfig,
|
||||
};
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
@ -177,6 +177,15 @@ impl WebviewBuilderExt for wry::Attributes {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<wry::RpcRequest> for RpcRequest {
|
||||
fn from(request: wry::RpcRequest) -> Self {
|
||||
Self {
|
||||
command: request.method,
|
||||
params: request.params,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WryDispatcher(
|
||||
Arc<Mutex<wry::WindowProxy>>,
|
||||
@ -189,25 +198,22 @@ impl ApplicationDispatcherExt for WryDispatcher {
|
||||
fn create_webview(
|
||||
&self,
|
||||
attributes: Self::WebviewBuilder,
|
||||
callbacks: Vec<Callback<Self>>,
|
||||
rpc_handler: Option<WebviewRpcHandler<Self>>,
|
||||
custom_protocol: Option<CustomProtocol>,
|
||||
) -> crate::Result<Self> {
|
||||
let mut wry_callbacks = Vec::new();
|
||||
let app_dispatcher = self.1.clone();
|
||||
for mut callback in callbacks {
|
||||
let app_dispatcher = app_dispatcher.clone();
|
||||
let callback = wry::Callback {
|
||||
name: callback.name.to_string(),
|
||||
function: Box::new(move |dispatcher, _, req| {
|
||||
(callback.function)(
|
||||
Self(Arc::new(Mutex::new(dispatcher)), app_dispatcher.clone()),
|
||||
req,
|
||||
|
||||
let wry_rpc_handler = Box::new(
|
||||
move |dispatcher: wry::WindowProxy, request: wry::RpcRequest| {
|
||||
if let Some(handler) = &rpc_handler {
|
||||
handler(
|
||||
WryDispatcher(Arc::new(Mutex::new(dispatcher)), app_dispatcher.clone()),
|
||||
request.into(),
|
||||
);
|
||||
Ok(())
|
||||
}),
|
||||
};
|
||||
wry_callbacks.push(callback);
|
||||
}
|
||||
}
|
||||
None
|
||||
},
|
||||
);
|
||||
|
||||
let window_dispatcher = self
|
||||
.1
|
||||
@ -215,7 +221,7 @@ impl ApplicationDispatcherExt for WryDispatcher {
|
||||
.unwrap()
|
||||
.add_window_with_configs(
|
||||
attributes,
|
||||
Some(wry_callbacks),
|
||||
Some(wry_rpc_handler),
|
||||
custom_protocol.map(|p| wry::CustomProtocol {
|
||||
name: p.name.clone(),
|
||||
handler: Box::new(move |a| (*p.handler)(a).map_err(|_| wry::Error::InitScriptError)),
|
||||
@ -449,31 +455,29 @@ impl ApplicationExt for WryApplication {
|
||||
fn create_webview(
|
||||
&mut self,
|
||||
webview_builder: Self::WebviewBuilder,
|
||||
callbacks: Vec<Callback<Self::Dispatcher>>,
|
||||
rpc_handler: Option<WebviewRpcHandler<Self::Dispatcher>>,
|
||||
custom_protocol: Option<CustomProtocol>,
|
||||
) -> crate::Result<Self::Dispatcher> {
|
||||
let mut wry_callbacks = Vec::new();
|
||||
let app_dispatcher = Arc::new(Mutex::new(self.inner.application_proxy()));
|
||||
for mut callback in callbacks {
|
||||
let app_dispatcher = app_dispatcher.clone();
|
||||
let callback = wry::Callback {
|
||||
name: callback.name.to_string(),
|
||||
function: Box::new(move |dispatcher, _, req| {
|
||||
(callback.function)(
|
||||
WryDispatcher(Arc::new(Mutex::new(dispatcher)), app_dispatcher.clone()),
|
||||
req,
|
||||
|
||||
let app_dispatcher_ = app_dispatcher.clone();
|
||||
let wry_rpc_handler = Box::new(
|
||||
move |dispatcher: wry::WindowProxy, request: wry::RpcRequest| {
|
||||
if let Some(handler) = &rpc_handler {
|
||||
handler(
|
||||
WryDispatcher(Arc::new(Mutex::new(dispatcher)), app_dispatcher_.clone()),
|
||||
request.into(),
|
||||
);
|
||||
Ok(())
|
||||
}),
|
||||
};
|
||||
wry_callbacks.push(callback);
|
||||
}
|
||||
}
|
||||
None
|
||||
},
|
||||
);
|
||||
|
||||
let dispatcher = self
|
||||
.inner
|
||||
.add_window_with_configs(
|
||||
webview_builder.finish()?,
|
||||
Some(wry_callbacks),
|
||||
Some(wry_rpc_handler),
|
||||
custom_protocol.map(|p| wry::CustomProtocol {
|
||||
name: p.name.clone(),
|
||||
handler: Box::new(move |a| (*p.handler)(a).map_err(|_| wry::Error::InitScriptError)),
|
||||
|
@ -250,12 +250,12 @@ impl<A: ApplicationExt + 'static> WebviewManager<A> {
|
||||
.lock()
|
||||
.await
|
||||
.push(label.to_string());
|
||||
let (webview_builder, callbacks, custom_protocol) =
|
||||
let (webview_builder, rpc_handler, custom_protocol) =
|
||||
self.application.init_webview(webview).await?;
|
||||
|
||||
let window_dispatcher = self.current_webview().await?.dispatcher.create_webview(
|
||||
webview_builder,
|
||||
callbacks,
|
||||
rpc_handler,
|
||||
custom_protocol,
|
||||
)?;
|
||||
let webview_manager = Self::new(
|
||||
|
@ -374,7 +374,7 @@ mod test {
|
||||
// .resizable(true)
|
||||
// .debug(true)
|
||||
// .user_data(())
|
||||
// .invoke_handler(|_wv, _arg| Ok(()))
|
||||
// .invoke_handler(|_wv, _command, _arg| Ok(()))
|
||||
// .content(Content::Html(content))
|
||||
// .build()?,
|
||||
// )
|
||||
|
@ -39,6 +39,7 @@ pub trait Plugin<A: ApplicationExt + 'static>: Send + Sync {
|
||||
async fn extend_api(
|
||||
&mut self,
|
||||
webview_manager: WebviewManager<A>,
|
||||
command: String,
|
||||
payload: &JsonValue,
|
||||
) -> crate::Result<JsonValue> {
|
||||
Err(crate::Error::UnknownApi(None))
|
||||
@ -123,11 +124,15 @@ pub(crate) async fn ready<A: ApplicationExt + 'static>(
|
||||
pub(crate) async fn extend_api<A: ApplicationExt + 'static>(
|
||||
store: &PluginStore<A>,
|
||||
webview_manager: &crate::WebviewManager<A>,
|
||||
command: String,
|
||||
arg: &JsonValue,
|
||||
) -> crate::Result<Option<JsonValue>> {
|
||||
let mut plugins = store.lock().await;
|
||||
for ext in plugins.iter_mut() {
|
||||
match ext.extend_api(webview_manager.clone(), arg).await {
|
||||
match ext
|
||||
.extend_api(webview_manager.clone(), command.clone(), arg)
|
||||
.await
|
||||
{
|
||||
Ok(value) => {
|
||||
return Ok(Some(value));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user