Upgrade to Tauri 2.0 (#23)

This commit is contained in:
Gregory Schier
2024-05-04 14:14:19 -07:00
committed by GitHub
parent 7f02060b9c
commit 896e3d5831
128 changed files with 20477 additions and 4114 deletions

2839
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,8 +4,9 @@
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"start": "npm run build:plugins && npm run tauri-dev", "start": "npm run build:plugins && npm run tauri-dev:desktop",
"tauri-dev": "tauri dev --no-watch --config ./src-tauri/tauri-dev.conf.json", "tauri-dev:desktop": "tauri dev --no-watch --config ./src-tauri/tauri-dev.conf.json",
"tauri-dev:ios": "tauri ios dev --no-watch --config ./src-tauri/tauri-dev.conf.json",
"tauri-build": "tauri build", "tauri-build": "tauri build",
"tauri": "tauri", "tauri": "tauri",
"build": "npm run build:frontend", "build": "npm run build:frontend",
@@ -40,7 +41,11 @@
"@tanstack/react-query": "^4.28.0", "@tanstack/react-query": "^4.28.0",
"@tanstack/react-query-devtools": "^4.28.0", "@tanstack/react-query-devtools": "^4.28.0",
"@tanstack/react-query-persist-client": "^4.28.0", "@tanstack/react-query-persist-client": "^4.28.0",
"@tauri-apps/api": "^1.5.3", "@tauri-apps/api": ">=2.0.0-beta.0",
"@tauri-apps/plugin-dialog": ">=2.0.0-beta.0",
"@tauri-apps/plugin-fs": ">=2.0.0-beta.0",
"@tauri-apps/plugin-os": ">=2.0.0-beta.0",
"@tauri-apps/plugin-shell": ">=2.0.0-beta.0",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"classnames": "^2.3.2", "classnames": "^2.3.2",
"cm6-graphql": "^0.0.9", "cm6-graphql": "^0.0.9",
@@ -62,17 +67,18 @@
"react-router-dom": "^6.8.1", "react-router-dom": "^6.8.1",
"react-use": "^17.4.0", "react-use": "^17.4.0",
"slugify": "^1.6.6", "slugify": "^1.6.6",
"tauri-plugin-log-api": "github:tauri-apps/tauri-plugin-log#v1", "tauri-plugin-log-api": "github:tauri-apps/tauri-plugin-log#v2",
"uuid": "^9.0.0", "uuid": "^9.0.0",
"xml-formatter": "^3.6.2" "xml-formatter": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/nesting": "^0.0.0-insiders.565cd3e", "@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
"@tauri-apps/cli": "^1.5.10", "@tauri-apps/cli": ">=2.0.0-beta.0",
"@types/node": "^18.7.10", "@types/node": "^18.7.10",
"@types/papaparse": "^5.3.7", "@types/papaparse": "^5.3.7",
"@types/parse-color": "^1.0.1", "@types/parse-color": "^1.0.1",
"@types/parse-json": "^4.0.0", "@types/parse-json": "^4.0.0",
"internal-ip": "^8.0.0",
"@types/react": "^18.0.31", "@types/react": "^18.0.31",
"@types/react-dom": "^18.0.11", "@types/react-dom": "^18.0.11",
"@types/uuid": "^9.0.1", "@types/uuid": "^9.0.1",
@@ -95,7 +101,7 @@
"react-devtools": "^4.27.2", "react-devtools": "^4.27.2",
"tailwindcss": "^3.2.7", "tailwindcss": "^3.2.7",
"typescript": "^5.3.3", "typescript": "^5.3.3",
"vite": "^5.1.1", "vite": "^5.0.0",
"vite-plugin-svgr": "^4.2.0", "vite-plugin-svgr": "^4.2.0",
"vite-plugin-top-level-await": "^1.4.1", "vite-plugin-top-level-await": "^1.4.1",
"vitest": "^1.3.0" "vitest": "^1.3.0"

View File

@@ -0,0 +1,4 @@
[build]
target = "aarch64-apple-darwin"
[target]

2685
src-tauri/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
workspace = { members = ["grpc"] } workspace = { members = ["grpc"] }
[package] [package]
name = "yaak-app" name = "yaak-app"
version = "0.0.0" version = "0.0.0"
@@ -8,11 +9,16 @@ license = "MIT"
repository = "https://github.com/gschier/yaak-app" repository = "https://github.com/gschier/yaak-app"
edition = "2021" edition = "2021"
# Produce a library for mobile support
[lib]
name = "tauri_app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[profile.release] [profile.release]
strip = true # Automatically strip symbols from the binary. strip = true # Automatically strip symbols from the binary.
[build-dependencies] [build-dependencies]
tauri-build = { version = "1.5", features = [] } tauri-build = { version = "2.0.0-beta", features = [] }
[target.'cfg(target_os = "macos")'.dependencies] [target.'cfg(target_os = "macos")'.dependencies]
objc = "0.2.7" objc = "0.2.7"
@@ -34,28 +40,17 @@ cookie = { version = "0.18.0" }
serde = { version = "1.0.195", features = ["derive"] } serde = { version = "1.0.195", features = ["derive"] }
serde_json = { version = "1.0.111", features = ["raw_value"] } serde_json = { version = "1.0.111", features = ["raw_value"] }
sqlx = { version = "0.7.4", features = ["sqlite", "runtime-tokio-rustls", "json", "chrono", "time"] } sqlx = { version = "0.7.4", features = ["sqlite", "runtime-tokio-rustls", "json", "chrono", "time"] }
tauri = { version = "1.5.4", features = [ tauri = { version = "2.0.0-beta.17", features = [
"config-toml", "config-toml",
"path-all",
"devtools", "devtools",
"dialog-open",
"dialog-save",
"fs-read-file",
"os-all",
"protocol-asset",
"shell-open",
"shell-sidecar",
"updater",
"window-close",
"window-maximize",
"window-minimize",
"window-set-decorations",
"window-set-title",
"window-start-dragging",
"window-unmaximize",
] } ] }
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" } tauri-plugin-dialog = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-plugin-log = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1", features = ["colored"] } tauri-plugin-log = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2", features = ["colored"] }
tauri-plugin-shell = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-plugin-os = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-plugin-updater = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-plugin-fs = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tokio = { version = "1.36.0", features = ["sync"] } tokio = { version = "1.36.0", features = ["sync"] }
uuid = "1.3.0" uuid = "1.3.0"
log = "0.4.20" log = "0.4.20"
@@ -64,11 +59,4 @@ window-shadows = "0.2.2"
reqwest_cookie_store = "0.6.0" reqwest_cookie_store = "0.6.0"
grpc = { path = "./grpc" } grpc = { path = "./grpc" }
tokio-stream = "0.1.15" tokio-stream = "0.1.15"
regex = "1.10.2"
[features]
# by default Tauri runs in production mode
# when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL
default = ["custom-protocol"]
# this feature is used used for production builds where `devPath` points to the filesystem
# DO NOT remove this
custom-protocol = ["tauri/custom-protocol"]

View File

@@ -0,0 +1,49 @@
{
"$schema": "../gen/schemas/capabilities.json",
"identifier": "main",
"description": "Main permissions",
"local": true,
"windows": [
"*"
],
"permissions": [
"os:allow-os-type",
"menu:allow-create-default",
"dialog:allow-open",
"dialog:allow-save",
"event:allow-listen",
"event:allow-unlisten",
"fs:allow-read-file",
"fs:allow-read-text-file",
{
"identifier": "fs:scope",
"allow": [
{
"path": "$APPDATA"
},
{
"path": "$APPDATA/**"
}
]
},
"shell:allow-open",
{
"identifier": "shell:allow-execute",
"allow": [
{
"name": "protoc",
"sidecar": true,
"args": true
}
]
},
"window:allow-close",
"window:allow-is-fullscreen",
"window:allow-maximize",
"window:allow-minimize",
"window:allow-set-decorations",
"window:allow-set-title",
"window:allow-start-dragging",
"window:allow-unmaximize"
]
}

3
src-tauri/gen/apple/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
xcuserdata/
build/
Externals/

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,116 @@
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "AppIcon-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "AppIcon-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "AppIcon-29x29@2x-1.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "AppIcon-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "AppIcon-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "AppIcon-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "AppIcon-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "AppIcon-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "AppIcon-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "AppIcon-20x20@2x-1.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "AppIcon-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "AppIcon-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "AppIcon-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "AppIcon-40x40@2x-1.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "AppIcon-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "AppIcon-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "AppIcon-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "AppIcon-512@2x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>development</string>
</dict>
</plist>

View File

@@ -0,0 +1,21 @@
# Uncomment the next line to define a global platform for your project
target 'yaak-app_iOS' do
platform :ios, '13.0'
# Pods for yaak-app_iOS
end
target 'yaak-app_macOS' do
platform :osx, '11.0'
# Pods for yaak-app_macOS
end
# Delete the deployment target for iOS and macOS, causing it to be inherited from the Podfile
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
config.build_settings.delete 'MACOSX_DEPLOYMENT_TARGET'
end
end
end

View File

@@ -0,0 +1,8 @@
#pragma once
namespace ffi {
extern "C" {
void start_app();
}
}

View File

@@ -0,0 +1,6 @@
#include "bindings/bindings.h"
int main(int argc, char * argv[]) {
ffi::start_app();
return 0;
}

View File

@@ -0,0 +1,90 @@
name: yaak-app
options:
bundleIdPrefix: app.yaak
deploymentTarget:
iOS: 13.0
fileGroups: [../../src]
configs:
debug: debug
release: release
settingGroups:
app:
base:
PRODUCT_NAME: Yaak
PRODUCT_BUNDLE_IDENTIFIER: app.yaak.yaak-app
DEVELOPMENT_TEAM: 7PU3P6ELJ8
targetTemplates:
app:
type: application
sources:
- path: Sources
scheme:
environmentVariables:
RUST_BACKTRACE: full
RUST_LOG: info
settings:
groups: [app]
targets:
yaak-app_iOS:
type: application
platform: iOS
sources:
- path: Sources
- path: Assets.xcassets
- path: Externals
- path: yaak-app_iOS
- path: assets
buildPhase: resources
type: folder
info:
path: yaak-app_iOS/Info.plist
properties:
LSRequiresIPhoneOS: true
UILaunchStoryboardName: LaunchScreen
UIRequiredDeviceCapabilities: [arm64, metal]
UISupportedInterfaceOrientations:
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
UISupportedInterfaceOrientations~ipad:
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
CFBundleShortVersionString: 2024.3.10
CFBundleVersion: 2024.3.10
entitlements:
path: yaak-app_iOS/yaak-app_iOS.entitlements
scheme:
environmentVariables:
RUST_BACKTRACE: full
RUST_LOG: info
settings:
base:
ENABLE_BITCODE: false
ARCHS: [arm64, arm64-sim]
VALID_ARCHS: arm64 arm64-sim
LIBRARY_SEARCH_PATHS[arch=x86_64]: $(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
LIBRARY_SEARCH_PATHS[arch=arm64]: $(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
LIBRARY_SEARCH_PATHS[arch=arm64-sim]: $(inherited) $(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: true
EXCLUDED_ARCHS[sdk=iphonesimulator*]: arm64
EXCLUDED_ARCHS[sdk=iphoneos*]: arm64-sim x86_64
groups: [app]
dependencies:
- framework: libapp_lib.a
embed: false
- sdk: CoreGraphics.framework
- sdk: Metal.framework
- sdk: MetalKit.framework
- sdk: QuartzCore.framework
- sdk: Security.framework
- sdk: UIKit.framework
- sdk: WebKit.framework
preBuildScripts:
- script: node tauri ios xcode-script -v --platform ${PLATFORM_DISPLAY_NAME:?} --sdk-root ${SDKROOT:?} --framework-search-paths "${FRAMEWORK_SEARCH_PATHS:?}" --header-search-paths "${HEADER_SEARCH_PATHS:?}" --gcc-preprocessor-definitions "${GCC_PREPROCESSOR_DEFINITIONS:-}" --configuration ${CONFIGURATION:?} ${FORCE_COLOR} ${ARCHS:?}
name: Build Rust Code
basedOnDependencyAnalysis: false
outputFiles:
- $(SRCROOT)/target/aarch64-apple-ios/${CONFIGURATION}/deps/libapp_lib.a
- $(SRCROOT)/target/x86_64-apple-ios/${CONFIGURATION}/deps/libapp_lib.a

View File

@@ -0,0 +1,481 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
0AC23E163631EF3775908406 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDEF0D2E01608E7F464F71B6 /* WebKit.framework */; };
1B1BFDF8BC345D0D980E4427 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EF0B8CF73BE8166011E2CEAB /* QuartzCore.framework */; };
36588BE1A75B386BB2FEDAC5 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93A95F6B2F31FA92AA099E0 /* MetalKit.framework */; };
38E2C1B0E9FCC9A5FDE8876D /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF2908761467DF191C2A8939 /* Metal.framework */; };
8D518C1A67069BD7D339D055 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F34A96C5084EFDF1802A634 /* CoreGraphics.framework */; };
8DF67739DC49E577EB0FAE3F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 396F45DCFBE2C71866817528 /* Assets.xcassets */; };
A1D932F0E7399066AD07DC6D /* libapp_lib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 75D938BE0FA8770BA965AE1E /* libapp_lib.a */; };
AF0EEC868306E1D1C85994D0 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B5BF2E39256494269E65F8E /* Security.framework */; };
BE9FFDF51EB7DEBF707BB39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5415A3F2D217A47DD3BA40B3 /* UIKit.framework */; };
F0627C04787F4E187EF416F4 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 2A615609009B3AE2728043E4 /* assets */; };
FEE5934F5FFB0FBE10883AF2 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = C754460F1DAF2D414038A7EA /* main.mm */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
106BE62BE01A35403424018C /* main.rs */ = {isa = PBXFileReference; path = main.rs; sourceTree = "<group>"; };
14F240DAC31C5C52D7B4BB96 /* window_ext.rs */ = {isa = PBXFileReference; path = window_ext.rs; sourceTree = "<group>"; };
1B5226A88D8B805E878524C8 /* updates.rs */ = {isa = PBXFileReference; path = updates.rs; sourceTree = "<group>"; };
1F34A96C5084EFDF1802A634 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
1F5A647F82A24722F3C830BB /* plugin.rs */ = {isa = PBXFileReference; path = plugin.rs; sourceTree = "<group>"; };
2A615609009B3AE2728043E4 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = SOURCE_ROOT; };
396F45DCFBE2C71866817528 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
53872C1120171EDC4A6DFEDD /* analytics.rs */ = {isa = PBXFileReference; path = analytics.rs; sourceTree = "<group>"; };
5415A3F2D217A47DD3BA40B3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
5C1B6610F62B56E1947BEBBD /* http.rs */ = {isa = PBXFileReference; path = http.rs; sourceTree = "<group>"; };
6286C385ABAD2E04237679D7 /* yaak-app_iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "yaak-app_iOS.entitlements"; sourceTree = "<group>"; };
75D938BE0FA8770BA965AE1E /* libapp_lib.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libapp_lib.a; sourceTree = "<group>"; };
7B5BF2E39256494269E65F8E /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
A2CC02313D71CECB68031D53 /* grpc.rs */ = {isa = PBXFileReference; path = grpc.rs; sourceTree = "<group>"; };
A6DA9B210723CA84891876F8 /* bindings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bindings.h; sourceTree = "<group>"; };
A93A95F6B2F31FA92AA099E0 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; };
C754460F1DAF2D414038A7EA /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
D69BFB768591FDEEF65198EE /* yaak-app_iOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = "yaak-app_iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
DDDE197D9C6BC5680EEEEA00 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
DF2908761467DF191C2A8939 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
DF45D08D97DE587CABF9537E /* window_menu.rs */ = {isa = PBXFileReference; path = window_menu.rs; sourceTree = "<group>"; };
E1E84E267D81D6437901B1C6 /* render.rs */ = {isa = PBXFileReference; path = render.rs; sourceTree = "<group>"; };
E964D3637BAED49E34B91739 /* models.rs */ = {isa = PBXFileReference; path = models.rs; sourceTree = "<group>"; };
EDEF0D2E01608E7F464F71B6 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
EF0B8CF73BE8166011E2CEAB /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
FB34CB48BB9F25D49F80D513 /* lib.rs */ = {isa = PBXFileReference; path = lib.rs; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
D8E8888B0F3E4411B98AE8EE /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
A1D932F0E7399066AD07DC6D /* libapp_lib.a in Frameworks */,
8D518C1A67069BD7D339D055 /* CoreGraphics.framework in Frameworks */,
38E2C1B0E9FCC9A5FDE8876D /* Metal.framework in Frameworks */,
36588BE1A75B386BB2FEDAC5 /* MetalKit.framework in Frameworks */,
1B1BFDF8BC345D0D980E4427 /* QuartzCore.framework in Frameworks */,
AF0EEC868306E1D1C85994D0 /* Security.framework in Frameworks */,
BE9FFDF51EB7DEBF707BB39A /* UIKit.framework in Frameworks */,
0AC23E163631EF3775908406 /* WebKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0844ACEFE550685042AC6029 /* Products */ = {
isa = PBXGroup;
children = (
D69BFB768591FDEEF65198EE /* yaak-app_iOS.app */,
);
name = Products;
sourceTree = "<group>";
};
6D0B6FF641B88DAF74C78B00 /* Externals */ = {
isa = PBXGroup;
children = (
);
path = Externals;
sourceTree = "<group>";
};
8A07575CB8654BB9107F9A32 /* bindings */ = {
isa = PBXGroup;
children = (
A6DA9B210723CA84891876F8 /* bindings.h */,
);
path = bindings;
sourceTree = "<group>";
};
8F0B46911FBEF2B246BE3385 /* yaak-app */ = {
isa = PBXGroup;
children = (
C754460F1DAF2D414038A7EA /* main.mm */,
8A07575CB8654BB9107F9A32 /* bindings */,
);
path = "yaak-app";
sourceTree = "<group>";
};
90E982C0E9B45CBAAE66E16D /* Frameworks */ = {
isa = PBXGroup;
children = (
1F34A96C5084EFDF1802A634 /* CoreGraphics.framework */,
75D938BE0FA8770BA965AE1E /* libapp_lib.a */,
DF2908761467DF191C2A8939 /* Metal.framework */,
A93A95F6B2F31FA92AA099E0 /* MetalKit.framework */,
EF0B8CF73BE8166011E2CEAB /* QuartzCore.framework */,
7B5BF2E39256494269E65F8E /* Security.framework */,
5415A3F2D217A47DD3BA40B3 /* UIKit.framework */,
EDEF0D2E01608E7F464F71B6 /* WebKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
C88F9D29DC52F052255C35A3 = {
isa = PBXGroup;
children = (
2A615609009B3AE2728043E4 /* assets */,
396F45DCFBE2C71866817528 /* Assets.xcassets */,
6D0B6FF641B88DAF74C78B00 /* Externals */,
EBC83899FBFA4A3D0A92837F /* Sources */,
F3A6B45E25E23922AB1BDB34 /* src */,
D49CF68C9105CE84E2084C14 /* yaak-app_iOS */,
90E982C0E9B45CBAAE66E16D /* Frameworks */,
0844ACEFE550685042AC6029 /* Products */,
);
sourceTree = "<group>";
};
D49CF68C9105CE84E2084C14 /* yaak-app_iOS */ = {
isa = PBXGroup;
children = (
DDDE197D9C6BC5680EEEEA00 /* Info.plist */,
6286C385ABAD2E04237679D7 /* yaak-app_iOS.entitlements */,
);
path = "yaak-app_iOS";
sourceTree = "<group>";
};
EBC83899FBFA4A3D0A92837F /* Sources */ = {
isa = PBXGroup;
children = (
8F0B46911FBEF2B246BE3385 /* yaak-app */,
);
path = Sources;
sourceTree = "<group>";
};
F3A6B45E25E23922AB1BDB34 /* src */ = {
isa = PBXGroup;
children = (
53872C1120171EDC4A6DFEDD /* analytics.rs */,
A2CC02313D71CECB68031D53 /* grpc.rs */,
5C1B6610F62B56E1947BEBBD /* http.rs */,
FB34CB48BB9F25D49F80D513 /* lib.rs */,
106BE62BE01A35403424018C /* main.rs */,
E964D3637BAED49E34B91739 /* models.rs */,
1F5A647F82A24722F3C830BB /* plugin.rs */,
E1E84E267D81D6437901B1C6 /* render.rs */,
1B5226A88D8B805E878524C8 /* updates.rs */,
14F240DAC31C5C52D7B4BB96 /* window_ext.rs */,
DF45D08D97DE587CABF9537E /* window_menu.rs */,
);
name = src;
path = ../../src;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
7C3E2AC18A0A227C2DF356E2 /* yaak-app_iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = C05E07AE7C7B25CACFADCDD4 /* Build configuration list for PBXNativeTarget "yaak-app_iOS" */;
buildPhases = (
5454ED506FC51D41C81A0318 /* Build Rust Code */,
C3495A2849227C6276D3876E /* Sources */,
E148188313FB67F061AB4E59 /* Resources */,
D8E8888B0F3E4411B98AE8EE /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = "yaak-app_iOS";
productName = "yaak-app_iOS";
productReference = D69BFB768591FDEEF65198EE /* yaak-app_iOS.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
A8F6206BC76F061F1FEFD439 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1430;
TargetAttributes = {
7C3E2AC18A0A227C2DF356E2 = {
DevelopmentTeam = 7PU3P6ELJ8;
};
};
};
buildConfigurationList = 24EF8D1B948FFF6B275FB0F4 /* Build configuration list for PBXProject "yaak-app" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
Base,
en,
);
mainGroup = C88F9D29DC52F052255C35A3;
projectDirPath = "";
projectRoot = "";
targets = (
7C3E2AC18A0A227C2DF356E2 /* yaak-app_iOS */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
E148188313FB67F061AB4E59 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8DF67739DC49E577EB0FAE3F /* Assets.xcassets in Resources */,
F0627C04787F4E187EF416F4 /* assets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
5454ED506FC51D41C81A0318 /* Build Rust Code */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "Build Rust Code";
outputFileListPaths = (
);
outputPaths = (
"$(SRCROOT)/target/aarch64-apple-ios/${CONFIGURATION}/deps/libapp_lib.a",
"$(SRCROOT)/target/x86_64-apple-ios/${CONFIGURATION}/deps/libapp_lib.a",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "node tauri ios xcode-script -v --platform ${PLATFORM_DISPLAY_NAME:?} --sdk-root ${SDKROOT:?} --framework-search-paths \"${FRAMEWORK_SEARCH_PATHS:?}\" --header-search-paths \"${HEADER_SEARCH_PATHS:?}\" --gcc-preprocessor-definitions \"${GCC_PREPROCESSOR_DEFINITIONS:-}\" --configuration ${CONFIGURATION:?} ${FORCE_COLOR} ${ARCHS:?}";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
C3495A2849227C6276D3876E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FEE5934F5FFB0FBE10883AF2 /* main.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
35D1DB294FFD067C835186C7 /* debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"DEBUG=1",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
};
name = debug;
};
368BB1E364597E7675463634 /* release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ARCHS = (
arm64,
"arm64-sim",
);
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "yaak-app_iOS/yaak-app_iOS.entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer";
DEVELOPMENT_TEAM = 7PU3P6ELJ8;
ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphoneos*]" = "arm64-sim x86_64";
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\".\"",
);
INFOPLIST_FILE = "yaak-app_iOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
"LIBRARY_SEARCH_PATHS[arch=arm64-sim]" = "$(inherited) $(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
"LIBRARY_SEARCH_PATHS[arch=arm64]" = "$(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
"LIBRARY_SEARCH_PATHS[arch=x86_64]" = "$(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
PRODUCT_BUNDLE_IDENTIFIER = "app.yaak.yaak-app";
PRODUCT_NAME = Yaak;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = "arm64 arm64-sim";
};
name = release;
};
45382E89556BF93E8D1F1C2D /* debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ARCHS = (
arm64,
"arm64-sim",
);
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "yaak-app_iOS/yaak-app_iOS.entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer";
DEVELOPMENT_TEAM = 7PU3P6ELJ8;
ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphoneos*]" = "arm64-sim x86_64";
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\".\"",
);
INFOPLIST_FILE = "yaak-app_iOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
"LIBRARY_SEARCH_PATHS[arch=arm64-sim]" = "$(inherited) $(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
"LIBRARY_SEARCH_PATHS[arch=arm64]" = "$(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
"LIBRARY_SEARCH_PATHS[arch=x86_64]" = "$(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)";
PRODUCT_BUNDLE_IDENTIFIER = "app.yaak.yaak-app";
PRODUCT_NAME = Yaak;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = "arm64 arm64-sim";
};
name = debug;
};
ABD0A3DD3D5C66C839496F44 /* release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
};
name = release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
24EF8D1B948FFF6B275FB0F4 /* Build configuration list for PBXProject "yaak-app" */ = {
isa = XCConfigurationList;
buildConfigurations = (
35D1DB294FFD067C835186C7 /* debug */,
ABD0A3DD3D5C66C839496F44 /* release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = debug;
};
C05E07AE7C7B25CACFADCDD4 /* Build configuration list for PBXNativeTarget "yaak-app_iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
45382E89556BF93E8D1F1C2D /* debug */,
368BB1E364597E7675463634 /* release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = debug;
};
/* End XCConfigurationList section */
};
rootObject = A8F6206BC76F061F1FEFD439 /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Original</string>
<key>DisableBuildSystemDeprecationDiagnostic</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7C3E2AC18A0A227C2DF356E2"
BuildableName = "Yaak.app"
BlueprintName = "yaak-app_iOS"
ReferencedContainer = "container:yaak-app.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "NO">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7C3E2AC18A0A227C2DF356E2"
BuildableName = "Yaak.app"
BlueprintName = "yaak-app_iOS"
ReferencedContainer = "container:yaak-app.xcodeproj">
</BuildableReference>
</MacroExpansion>
<EnvironmentVariables>
<EnvironmentVariable
key = "RUST_BACKTRACE"
value = "full"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "RUST_LOG"
value = "info"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7C3E2AC18A0A227C2DF356E2"
BuildableName = "Yaak.app"
BlueprintName = "yaak-app_iOS"
ReferencedContainer = "container:yaak-app.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "RUST_BACKTRACE"
value = "full"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "RUST_LOG"
value = "info"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "release"
shouldUseLaunchSchemeArgsEnv = "NO"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7C3E2AC18A0A227C2DF356E2"
BuildableName = "Yaak.app"
BlueprintName = "yaak-app_iOS"
ReferencedContainer = "container:yaak-app.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "RUST_BACKTRACE"
value = "full"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "RUST_LOG"
value = "info"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2024.3.10</string>
<key>CFBundleVersion</key>
<string>2024.3.10</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
<string>metal</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"main":{"identifier":"main","description":"Main permissions","local":true,"windows":["*"],"permissions":["os:allow-os-type","menu:allow-create-default","dialog:allow-open","dialog:allow-save","event:allow-listen","event:allow-unlisten","fs:allow-read-file","fs:allow-read-text-file",{"identifier":"fs:scope","allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]},"shell:allow-open",{"identifier":"shell:allow-execute","allow":[{"args":true,"name":"protoc","sidecar":true}]},"window:allow-close","window:allow-is-fullscreen","window:allow-maximize","window:allow-minimize","window:allow-set-decorations","window:allow-set-title","window:allow-start-dragging","window:allow-unmaximize"]}}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -20,4 +20,5 @@ hyper = { version = "0.14" }
hyper-rustls = { version = "0.24.0", features = ["http2"] } hyper-rustls = { version = "0.24.0", features = ["http2"] }
protoc-bin-vendored = "3.0.0" protoc-bin-vendored = "3.0.0"
uuid = { version = "1.7.0", features = ["v4"] } uuid = { version = "1.7.0", features = ["v4"] }
tauri = { version = "1.5.4", features = ["process-command-api"]} tauri = { version = "2.0.0-beta.16" }
tauri-plugin-shell = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }

View File

@@ -1,7 +1,7 @@
use std::env::temp_dir; use std::env::temp_dir;
use std::ops::Deref; use std::ops::Deref;
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::{from_utf8, FromStr};
use anyhow::anyhow; use anyhow::anyhow;
use hyper::client::HttpConnector; use hyper::client::HttpConnector;
@@ -11,8 +11,10 @@ use log::{debug, info, warn};
use prost::Message; use prost::Message;
use prost_reflect::{DescriptorPool, MethodDescriptor}; use prost_reflect::{DescriptorPool, MethodDescriptor};
use prost_types::{FileDescriptorProto, FileDescriptorSet}; use prost_types::{FileDescriptorProto, FileDescriptorSet};
use tauri::api::process::{Command, CommandEvent}; use tauri::path::BaseDirectory;
use tauri::AppHandle; use tauri::{AppHandle, Manager};
use tauri_plugin_shell::process::CommandEvent;
use tauri_plugin_shell::ShellExt;
use tokio::fs; use tokio::fs;
use tokio_stream::StreamExt; use tokio_stream::StreamExt;
use tonic::body::BoxBody; use tonic::body::BoxBody;
@@ -32,8 +34,8 @@ pub async fn fill_pool_from_files(
let random_file_name = format!("{}.desc", uuid::Uuid::new_v4()); let random_file_name = format!("{}.desc", uuid::Uuid::new_v4());
let desc_path = temp_dir().join(random_file_name); let desc_path = temp_dir().join(random_file_name);
let global_import_dir = app_handle let global_import_dir = app_handle
.path_resolver() .path()
.resolve_resource("protoc-vendored/include") .resolve("protoc-vendored/include", BaseDirectory::Resource)
.expect("failed to resolve protoc include directory"); .expect("failed to resolve protoc include directory");
let mut args = vec![ let mut args = vec![
@@ -63,7 +65,9 @@ pub async fn fill_pool_from_files(
} }
} }
let (mut rx, _child) = Command::new_sidecar("protoc") let (mut rx, _child) = app_handle
.shell()
.sidecar("protoc")
.expect("protoc not found") .expect("protoc not found")
.args(args) .args(args)
.spawn() .spawn()
@@ -72,10 +76,16 @@ pub async fn fill_pool_from_files(
while let Some(event) = rx.recv().await { while let Some(event) = rx.recv().await {
match event { match event {
CommandEvent::Stdout(line) => { CommandEvent::Stdout(line) => {
info!("protoc stdout: {}", line); info!(
"protoc stdout: {}",
from_utf8(line.as_slice()).unwrap_or_default().to_string()
);
} }
CommandEvent::Stderr(line) => { CommandEvent::Stderr(line) => {
info!("protoc stderr: {}", line); info!(
"protoc stderr: {}",
from_utf8(line.as_slice()).unwrap_or_default().to_string()
);
} }
CommandEvent::Error(e) => { CommandEvent::Error(e) => {
return Err(e.to_string()); return Err(e.to_string());

View File

@@ -208,7 +208,7 @@ fn get_os() -> &'static str {
} }
fn get_window_size(app_handle: &AppHandle) -> String { fn get_window_size(app_handle: &AppHandle) -> String {
let window = match app_handle.windows().into_values().next() { let window = match app_handle.webview_windows().into_values().next() {
Some(w) => w, Some(w) => w,
None => return "unknown".to_string(), None => return "unknown".to_string(),
}; };

View File

@@ -7,20 +7,20 @@ use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use base64::Engine; use base64::Engine;
use http::header::{ACCEPT, USER_AGENT};
use http::{HeaderMap, HeaderName, HeaderValue, Method}; use http::{HeaderMap, HeaderName, HeaderValue, Method};
use http::header::{ACCEPT, USER_AGENT};
use log::{error, info, warn}; use log::{error, info, warn};
use reqwest::redirect::Policy;
use reqwest::{multipart, Url}; use reqwest::{multipart, Url};
use reqwest::redirect::Policy;
use sqlx::types::{Json, JsonValue}; use sqlx::types::{Json, JsonValue};
use tauri::{Manager, Window}; use tauri::{Manager, WebviewWindow};
use tokio::sync::oneshot; use tokio::sync::oneshot;
use tokio::sync::watch::Receiver; use tokio::sync::watch::Receiver;
use crate::{models, render, response_err}; use crate::{models, render, response_err};
pub async fn send_http_request( pub async fn send_http_request(
window: &Window, window: &WebviewWindow,
request: models::HttpRequest, request: models::HttpRequest,
response: &models::HttpResponse, response: &models::HttpResponse,
environment: Option<models::Environment>, environment: Option<models::Environment>,
@@ -112,7 +112,6 @@ pub async fn send_http_request(
// everything manually to know that). // everything manually to know that).
// if let Some(cookie_store) = maybe_cookie_store.clone() { // if let Some(cookie_store) = maybe_cookie_store.clone() {
// let values1 = cookie_store.get_request_values(&url); // let values1 = cookie_store.get_request_values(&url);
// println!("COOKIE VLUAES: {:?}", values1.collect::<Vec<_>>());
// let raw_value = cookie_store.get_request_values(&url) // let raw_value = cookie_store.get_request_values(&url)
// .map(|(name, value)| format!("{}={}", name, value)) // .map(|(name, value)| format!("{}={}", name, value))
// .collect::<Vec<_>>() // .collect::<Vec<_>>()
@@ -401,7 +400,7 @@ pub async fn send_http_request(
{ {
// Write body to FS // Write body to FS
let dir = window.app_handle().path_resolver().app_data_dir().unwrap(); let dir = window.app_handle().path().app_data_dir().unwrap();
let base_dir = dir.join("responses"); let base_dir = dir.join("responses");
create_dir_all(base_dir.clone()).expect("Failed to create responses dir"); create_dir_all(base_dir.clone()).expect("Failed to create responses dir");
let body_path = match response.id.is_empty() { let body_path = match response.id.is_empty() {

1721
src-tauri/src/lib.rs Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,10 +4,10 @@ use std::fs;
use log::error; use log::error;
use rand::distributions::{Alphanumeric, DistString}; use rand::distributions::{Alphanumeric, DistString};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::types::chrono::NaiveDateTime;
use sqlx::types::{Json, JsonValue};
use sqlx::{Pool, Sqlite}; use sqlx::{Pool, Sqlite};
use tauri::{AppHandle, Manager, Wry}; use sqlx::types::{Json, JsonValue};
use sqlx::types::chrono::NaiveDateTime;
use tauri::{AppHandle, Manager, WebviewWindow, Wry};
use tokio::sync::Mutex; use tokio::sync::Mutex;
fn default_true() -> bool { fn default_true() -> bool {
@@ -426,9 +426,9 @@ pub async fn get_workspace(mgr: &impl Manager<Wry>, id: &str) -> Result<Workspac
.await .await
} }
pub async fn delete_workspace(mgr: &impl Manager<Wry>, id: &str) -> Result<Workspace, sqlx::Error> { pub async fn delete_workspace(window: &WebviewWindow, id: &str) -> Result<Workspace, sqlx::Error> {
let db = get_db(mgr).await; let db = get_db(window).await;
let workspace = get_workspace(mgr, id).await?; let workspace = get_workspace(window, id).await?;
let _ = sqlx::query!( let _ = sqlx::query!(
r#" r#"
DELETE FROM workspaces DELETE FROM workspaces
@@ -439,11 +439,11 @@ pub async fn delete_workspace(mgr: &impl Manager<Wry>, id: &str) -> Result<Works
.execute(&db) .execute(&db)
.await; .await;
for r in list_responses_by_workspace_id(mgr, id).await? { for r in list_responses_by_workspace_id(window, id).await? {
delete_http_response(mgr, &r.id).await?; delete_http_response(window, &r.id).await?;
} }
emit_deleted_model(mgr, workspace) emit_deleted_model(window, workspace)
} }
pub async fn get_cookie_jar(mgr: &impl Manager<Wry>, id: &str) -> Result<CookieJar, sqlx::Error> { pub async fn get_cookie_jar(mgr: &impl Manager<Wry>, id: &str) -> Result<CookieJar, sqlx::Error> {
@@ -482,11 +482,11 @@ pub async fn list_cookie_jars(
} }
pub async fn delete_cookie_jar( pub async fn delete_cookie_jar(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
id: &str, id: &str,
) -> Result<CookieJar, sqlx::Error> { ) -> Result<CookieJar, sqlx::Error> {
let cookie_jar = get_cookie_jar(mgr, id).await?; let cookie_jar = get_cookie_jar(window, id).await?;
let db = get_db(mgr).await; let db = get_db(window).await;
let _ = sqlx::query!( let _ = sqlx::query!(
r#" r#"
@@ -498,23 +498,23 @@ pub async fn delete_cookie_jar(
.execute(&db) .execute(&db)
.await; .await;
emit_deleted_model(mgr, cookie_jar) emit_deleted_model(window, cookie_jar)
} }
pub async fn duplicate_grpc_request( pub async fn duplicate_grpc_request(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
id: &str, id: &str,
) -> Result<GrpcRequest, sqlx::Error> { ) -> Result<GrpcRequest, sqlx::Error> {
let mut request = get_grpc_request(mgr, id).await?.clone(); let mut request = get_grpc_request(window, id).await?.clone();
request.id = "".to_string(); request.id = "".to_string();
upsert_grpc_request(mgr, &request).await upsert_grpc_request(window, &request).await
} }
pub async fn upsert_grpc_request( pub async fn upsert_grpc_request(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
request: &GrpcRequest, request: &GrpcRequest,
) -> Result<GrpcRequest, sqlx::Error> { ) -> Result<GrpcRequest, sqlx::Error> {
let db = get_db(mgr).await; let db = get_db(window).await;
let id = match request.id.as_str() { let id = match request.id.as_str() {
"" => generate_id(Some("gr")), "" => generate_id(Some("gr")),
_ => request.id.to_string(), _ => request.id.to_string(),
@@ -556,8 +556,8 @@ pub async fn upsert_grpc_request(
.execute(&db) .execute(&db)
.await?; .await?;
match get_grpc_request(mgr, &id).await { match get_grpc_request(window, &id).await {
Ok(m) => Ok(emit_upserted_model(mgr, m)), Ok(m) => Ok(emit_upserted_model(window, m)),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@@ -607,10 +607,10 @@ pub async fn list_grpc_requests(
} }
pub async fn upsert_grpc_connection( pub async fn upsert_grpc_connection(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
connection: &GrpcConnection, connection: &GrpcConnection,
) -> Result<GrpcConnection, sqlx::Error> { ) -> Result<GrpcConnection, sqlx::Error> {
let db = get_db(mgr).await; let db = get_db(window).await;
let id = match connection.id.as_str() { let id = match connection.id.as_str() {
"" => generate_id(Some("gc")), "" => generate_id(Some("gc")),
_ => connection.id.to_string(), _ => connection.id.to_string(),
@@ -646,8 +646,8 @@ pub async fn upsert_grpc_connection(
.execute(&db) .execute(&db)
.await?; .await?;
match get_grpc_connection(mgr, &id).await { match get_grpc_connection(window, &id).await {
Ok(m) => Ok(emit_upserted_model(mgr, m)), Ok(m) => Ok(emit_upserted_model(window, m)),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@@ -696,10 +696,10 @@ pub async fn list_grpc_connections(
} }
pub async fn upsert_grpc_event( pub async fn upsert_grpc_event(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
event: &GrpcEvent, event: &GrpcEvent,
) -> Result<GrpcEvent, sqlx::Error> { ) -> Result<GrpcEvent, sqlx::Error> {
let db = get_db(mgr).await; let db = get_db(window).await;
let id = match event.id.as_str() { let id = match event.id.as_str() {
"" => generate_id(Some("ge")), "" => generate_id(Some("ge")),
_ => event.id.to_string(), _ => event.id.to_string(),
@@ -732,8 +732,8 @@ pub async fn upsert_grpc_event(
.execute(&db) .execute(&db)
.await?; .await?;
match get_grpc_event(mgr, &id).await { match get_grpc_event(window, &id).await {
Ok(m) => Ok(emit_upserted_model(mgr, m)), Ok(m) => Ok(emit_upserted_model(window, m)),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@@ -778,7 +778,7 @@ pub async fn list_grpc_events(
} }
pub async fn upsert_cookie_jar( pub async fn upsert_cookie_jar(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
cookie_jar: &CookieJar, cookie_jar: &CookieJar,
) -> Result<CookieJar, sqlx::Error> { ) -> Result<CookieJar, sqlx::Error> {
let id = match cookie_jar.id.as_str() { let id = match cookie_jar.id.as_str() {
@@ -787,7 +787,7 @@ pub async fn upsert_cookie_jar(
}; };
let trimmed_name = cookie_jar.name.trim(); let trimmed_name = cookie_jar.name.trim();
let db = get_db(mgr).await; let db = get_db(window).await;
sqlx::query!( sqlx::query!(
r#" r#"
INSERT INTO cookie_jars ( INSERT INTO cookie_jars (
@@ -807,8 +807,8 @@ pub async fn upsert_cookie_jar(
.execute(&db) .execute(&db)
.await?; .await?;
match get_cookie_jar(mgr, &id).await { match get_cookie_jar(window, &id).await {
Ok(m) => Ok(emit_upserted_model(mgr, m)), Ok(m) => Ok(emit_upserted_model(window, m)),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@@ -833,11 +833,11 @@ pub async fn list_environments(
} }
pub async fn delete_environment( pub async fn delete_environment(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
id: &str, id: &str,
) -> Result<Environment, sqlx::Error> { ) -> Result<Environment, sqlx::Error> {
let db = get_db(mgr).await; let db = get_db(window).await;
let env = get_environment(mgr, id).await?; let env = get_environment(window, id).await?;
let _ = sqlx::query!( let _ = sqlx::query!(
r#" r#"
DELETE FROM environments DELETE FROM environments
@@ -848,7 +848,7 @@ pub async fn delete_environment(
.execute(&db) .execute(&db)
.await; .await;
emit_deleted_model(mgr, env) emit_deleted_model(window, env)
} }
async fn get_settings(mgr: &impl Manager<Wry>) -> Result<Settings, sqlx::Error> { async fn get_settings(mgr: &impl Manager<Wry>) -> Result<Settings, sqlx::Error> {
@@ -886,10 +886,10 @@ pub async fn get_or_create_settings(mgr: &impl Manager<Wry>) -> Settings {
} }
pub async fn update_settings( pub async fn update_settings(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
settings: Settings, settings: Settings,
) -> Result<Settings, sqlx::Error> { ) -> Result<Settings, sqlx::Error> {
let db = get_db(mgr).await; let db = get_db(window).await;
sqlx::query!( sqlx::query!(
r#" r#"
UPDATE settings SET ( UPDATE settings SET (
@@ -903,14 +903,14 @@ pub async fn update_settings(
.execute(&db) .execute(&db)
.await?; .await?;
match get_settings(mgr).await { match get_settings(window).await {
Ok(m) => Ok(emit_upserted_model(mgr, m)), Ok(m) => Ok(emit_upserted_model(window, m)),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
pub async fn upsert_environment( pub async fn upsert_environment(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
environment: Environment, environment: Environment,
) -> Result<Environment, sqlx::Error> { ) -> Result<Environment, sqlx::Error> {
let id = match environment.id.as_str() { let id = match environment.id.as_str() {
@@ -918,7 +918,7 @@ pub async fn upsert_environment(
_ => environment.id.to_string(), _ => environment.id.to_string(),
}; };
let trimmed_name = environment.name.trim(); let trimmed_name = environment.name.trim();
let db = get_db(mgr).await; let db = get_db(window).await;
sqlx::query!( sqlx::query!(
r#" r#"
INSERT INTO environments ( INSERT INTO environments (
@@ -938,8 +938,8 @@ pub async fn upsert_environment(
.execute(&db) .execute(&db)
.await?; .await?;
match get_environment(mgr, &id).await { match get_environment(window, &id).await {
Ok(m) => Ok(emit_upserted_model(mgr, m)), Ok(m) => Ok(emit_upserted_model(window, m)),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@@ -999,9 +999,9 @@ pub async fn list_folders(
.await .await
} }
pub async fn delete_folder(mgr: &impl Manager<Wry>, id: &str) -> Result<Folder, sqlx::Error> { pub async fn delete_folder(window: &WebviewWindow, id: &str) -> Result<Folder, sqlx::Error> {
let folder = get_folder(mgr, id).await?; let folder = get_folder(window, id).await?;
let db = get_db(mgr).await; let db = get_db(window).await;
let _ = sqlx::query!( let _ = sqlx::query!(
r#" r#"
DELETE FROM folders DELETE FROM folders
@@ -1012,17 +1012,17 @@ pub async fn delete_folder(mgr: &impl Manager<Wry>, id: &str) -> Result<Folder,
.execute(&db) .execute(&db)
.await; .await;
emit_deleted_model(mgr, folder) emit_deleted_model(window, folder)
} }
pub async fn upsert_folder(mgr: &impl Manager<Wry>, r: Folder) -> Result<Folder, sqlx::Error> { pub async fn upsert_folder(window: &WebviewWindow, r: Folder) -> Result<Folder, sqlx::Error> {
let id = match r.id.as_str() { let id = match r.id.as_str() {
"" => generate_id(Some("fl")), "" => generate_id(Some("fl")),
_ => r.id.to_string(), _ => r.id.to_string(),
}; };
let trimmed_name = r.name.trim(); let trimmed_name = r.name.trim();
let db = get_db(mgr).await; let db = get_db(window).await;
sqlx::query!( sqlx::query!(
r#" r#"
INSERT INTO folders ( INSERT INTO folders (
@@ -1044,23 +1044,23 @@ pub async fn upsert_folder(mgr: &impl Manager<Wry>, r: Folder) -> Result<Folder,
.execute(&db) .execute(&db)
.await?; .await?;
match get_folder(mgr, &id).await { match get_folder(window, &id).await {
Ok(m) => Ok(emit_upserted_model(mgr, m)), Ok(m) => Ok(emit_upserted_model(window, m)),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
pub async fn duplicate_http_request( pub async fn duplicate_http_request(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
id: &str, id: &str,
) -> Result<HttpRequest, sqlx::Error> { ) -> Result<HttpRequest, sqlx::Error> {
let mut request = get_http_request(mgr, id).await?.clone(); let mut request = get_http_request(window, id).await?.clone();
request.id = "".to_string(); request.id = "".to_string();
upsert_http_request(mgr, request).await upsert_http_request(window, request).await
} }
pub async fn upsert_http_request( pub async fn upsert_http_request(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
r: HttpRequest, r: HttpRequest,
) -> Result<HttpRequest, sqlx::Error> { ) -> Result<HttpRequest, sqlx::Error> {
let id = match r.id.as_str() { let id = match r.id.as_str() {
@@ -1069,7 +1069,7 @@ pub async fn upsert_http_request(
}; };
let trimmed_name = r.name.trim(); let trimmed_name = r.name.trim();
let db = get_db(mgr).await; let db = get_db(window).await;
sqlx::query!( sqlx::query!(
r#" r#"
@@ -1109,8 +1109,8 @@ pub async fn upsert_http_request(
.execute(&db) .execute(&db)
.await?; .await?;
match get_http_request(mgr, &id).await { match get_http_request(window, &id).await {
Ok(m) => Ok(emit_upserted_model(mgr, m)), Ok(m) => Ok(emit_upserted_model(window, m)),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@@ -1165,15 +1165,15 @@ pub async fn get_http_request(
} }
pub async fn delete_http_request( pub async fn delete_http_request(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
id: &str, id: &str,
) -> Result<HttpRequest, sqlx::Error> { ) -> Result<HttpRequest, sqlx::Error> {
let req = get_http_request(mgr, id).await?; let req = get_http_request(window, id).await?;
// DB deletes will cascade but this will delete the files // DB deletes will cascade but this will delete the files
delete_all_http_responses(mgr, id).await?; delete_all_http_responses(window, id).await?;
let db = get_db(mgr).await; let db = get_db(window).await;
let _ = sqlx::query!( let _ = sqlx::query!(
r#" r#"
DELETE FROM http_requests DELETE FROM http_requests
@@ -1184,12 +1184,12 @@ pub async fn delete_http_request(
.execute(&db) .execute(&db)
.await; .await;
emit_deleted_model(mgr, req) emit_deleted_model(window, req)
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub async fn create_http_response( pub async fn create_http_response(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
request_id: &str, request_id: &str,
elapsed: i64, elapsed: i64,
elapsed_headers: i64, elapsed_headers: i64,
@@ -1202,10 +1202,10 @@ pub async fn create_http_response(
version: Option<&str>, version: Option<&str>,
remote_addr: Option<&str>, remote_addr: Option<&str>,
) -> Result<HttpResponse, sqlx::Error> { ) -> Result<HttpResponse, sqlx::Error> {
let req = get_http_request(mgr, request_id).await?; let req = get_http_request(window, request_id).await?;
let id = generate_id(Some("rp")); let id = generate_id(Some("rp"));
let headers_json = Json(headers); let headers_json = Json(headers);
let db = get_db(mgr).await; let db = get_db(window).await;
sqlx::query!( sqlx::query!(
r#" r#"
INSERT INTO http_responses ( INSERT INTO http_responses (
@@ -1231,14 +1231,14 @@ pub async fn create_http_response(
.execute(&db) .execute(&db)
.await?; .await?;
match get_http_response(mgr, &id).await { match get_http_response(window, &id).await {
Ok(m) => Ok(emit_upserted_model(mgr, m)), Ok(m) => Ok(emit_upserted_model(window, m)),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
pub async fn cancel_pending_grpc_connections(mgr: &impl Manager<Wry>) -> Result<(), sqlx::Error> { pub async fn cancel_pending_grpc_connections(app: &AppHandle) -> Result<(), sqlx::Error> {
let db = get_db(mgr).await; let db = get_db(app).await;
sqlx::query!( sqlx::query!(
r#" r#"
UPDATE grpc_connections UPDATE grpc_connections
@@ -1251,8 +1251,8 @@ pub async fn cancel_pending_grpc_connections(mgr: &impl Manager<Wry>) -> Result<
Ok(()) Ok(())
} }
pub async fn cancel_pending_responses(mgr: &impl Manager<Wry>) -> Result<(), sqlx::Error> { pub async fn cancel_pending_responses(app: &AppHandle) -> Result<(), sqlx::Error> {
let db = get_db(mgr).await; let db = get_db(app).await;
sqlx::query!( sqlx::query!(
r#" r#"
UPDATE http_responses UPDATE http_responses
@@ -1266,18 +1266,18 @@ pub async fn cancel_pending_responses(mgr: &impl Manager<Wry>) -> Result<(), sql
} }
pub async fn update_response_if_id( pub async fn update_response_if_id(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
response: &HttpResponse, response: &HttpResponse,
) -> Result<HttpResponse, sqlx::Error> { ) -> Result<HttpResponse, sqlx::Error> {
if response.id.is_empty() { if response.id.is_empty() {
Ok(response.clone()) Ok(response.clone())
} else { } else {
update_response(mgr, response).await update_response(window, response).await
} }
} }
pub async fn upsert_workspace( pub async fn upsert_workspace(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
workspace: Workspace, workspace: Workspace,
) -> Result<Workspace, sqlx::Error> { ) -> Result<Workspace, sqlx::Error> {
let id = match workspace.id.as_str() { let id = match workspace.id.as_str() {
@@ -1286,7 +1286,7 @@ pub async fn upsert_workspace(
}; };
let trimmed_name = workspace.name.trim(); let trimmed_name = workspace.name.trim();
let db = get_db(mgr).await; let db = get_db(window).await;
sqlx::query!( sqlx::query!(
r#" r#"
INSERT INTO workspaces ( INSERT INTO workspaces (
@@ -1314,17 +1314,17 @@ pub async fn upsert_workspace(
.execute(&db) .execute(&db)
.await?; .await?;
match get_workspace(mgr, &id).await { match get_workspace(window, &id).await {
Ok(m) => Ok(emit_upserted_model(mgr, m)), Ok(m) => Ok(emit_upserted_model(window, m)),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
pub async fn update_response( pub async fn update_response(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
response: &HttpResponse, response: &HttpResponse,
) -> Result<HttpResponse, sqlx::Error> { ) -> Result<HttpResponse, sqlx::Error> {
let db = get_db(mgr).await; let db = get_db(window).await;
sqlx::query!( sqlx::query!(
r#" r#"
UPDATE http_responses SET ( UPDATE http_responses SET (
@@ -1348,8 +1348,8 @@ pub async fn update_response(
.execute(&db) .execute(&db)
.await?; .await?;
match get_http_response(mgr, &response.id).await { match get_http_response(window, &response.id).await {
Ok(m) => Ok(emit_upserted_model(mgr, m)), Ok(m) => Ok(emit_upserted_model(window, m)),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@@ -1427,12 +1427,12 @@ pub async fn list_responses_by_workspace_id(
} }
pub async fn delete_grpc_request( pub async fn delete_grpc_request(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
id: &str, id: &str,
) -> Result<GrpcRequest, sqlx::Error> { ) -> Result<GrpcRequest, sqlx::Error> {
let req = get_grpc_request(mgr, id).await?; let req = get_grpc_request(window, id).await?;
let db = get_db(mgr).await; let db = get_db(window).await;
let _ = sqlx::query!( let _ = sqlx::query!(
r#" r#"
DELETE FROM grpc_requests DELETE FROM grpc_requests
@@ -1443,16 +1443,16 @@ pub async fn delete_grpc_request(
.execute(&db) .execute(&db)
.await; .await;
emit_deleted_model(mgr, req) emit_deleted_model(window, req)
} }
pub async fn delete_grpc_connection( pub async fn delete_grpc_connection(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
id: &str, id: &str,
) -> Result<GrpcConnection, sqlx::Error> { ) -> Result<GrpcConnection, sqlx::Error> {
let resp = get_grpc_connection(mgr, id).await?; let resp = get_grpc_connection(window, id).await?;
let db = get_db(mgr).await; let db = get_db(window).await;
let _ = sqlx::query!( let _ = sqlx::query!(
r#" r#"
DELETE FROM grpc_connections DELETE FROM grpc_connections
@@ -1463,14 +1463,14 @@ pub async fn delete_grpc_connection(
.execute(&db) .execute(&db)
.await; .await;
emit_deleted_model(mgr, resp) emit_deleted_model(window, resp)
} }
pub async fn delete_http_response( pub async fn delete_http_response(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
id: &str, id: &str,
) -> Result<HttpResponse, sqlx::Error> { ) -> Result<HttpResponse, sqlx::Error> {
let resp = get_http_response(mgr, id).await?; let resp = get_http_response(window, id).await?;
// Delete the body file if it exists // Delete the body file if it exists
if let Some(p) = resp.body_path.clone() { if let Some(p) = resp.body_path.clone() {
@@ -1479,7 +1479,7 @@ pub async fn delete_http_response(
}; };
} }
let db = get_db(mgr).await; let db = get_db(window).await;
let _ = sqlx::query!( let _ = sqlx::query!(
r#" r#"
DELETE FROM http_responses DELETE FROM http_responses
@@ -1490,25 +1490,25 @@ pub async fn delete_http_response(
.execute(&db) .execute(&db)
.await; .await;
emit_deleted_model(mgr, resp) emit_deleted_model(window, resp)
} }
pub async fn delete_all_grpc_connections( pub async fn delete_all_grpc_connections(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
request_id: &str, request_id: &str,
) -> Result<(), sqlx::Error> { ) -> Result<(), sqlx::Error> {
for r in list_grpc_connections(mgr, request_id).await? { for r in list_grpc_connections(window, request_id).await? {
delete_grpc_connection(mgr, &r.id).await?; delete_grpc_connection(window, &r.id).await?;
} }
Ok(()) Ok(())
} }
pub async fn delete_all_http_responses( pub async fn delete_all_http_responses(
mgr: &impl Manager<Wry>, window: &WebviewWindow,
request_id: &str, request_id: &str,
) -> Result<(), sqlx::Error> { ) -> Result<(), sqlx::Error> {
for r in list_responses(mgr, request_id, None).await? { for r in list_responses(window, request_id, None).await? {
delete_http_response(mgr, &r.id).await?; delete_http_response(window, &r.id).await?;
} }
Ok(()) Ok(())
} }
@@ -1541,9 +1541,10 @@ pub struct WorkspaceExportResources {
} }
pub async fn get_workspace_export_resources( pub async fn get_workspace_export_resources(
app_handle: &AppHandle, window: &WebviewWindow,
workspace_ids: Vec<&str>, workspace_ids: Vec<&str>,
) -> WorkspaceExport { ) -> WorkspaceExport {
let app_handle = window.app_handle();
let mut data = WorkspaceExport { let mut data = WorkspaceExport {
yaak_version: app_handle.package_info().version.clone().to_string(), yaak_version: app_handle.package_info().version.clone().to_string(),
yaak_schema: 2, yaak_schema: 2,
@@ -1559,42 +1560,58 @@ pub async fn get_workspace_export_resources(
for workspace_id in workspace_ids { for workspace_id in workspace_ids {
data.resources.workspaces.push( data.resources.workspaces.push(
get_workspace(app_handle, workspace_id) get_workspace(window, workspace_id)
.await .await
.expect("Failed to get workspace"), .expect("Failed to get workspace"),
); );
data.resources.environments.append( data.resources.environments.append(
&mut list_environments(app_handle, workspace_id) &mut list_environments(window, workspace_id)
.await .await
.expect("Failed to get environments"), .expect("Failed to get environments"),
); );
data.resources.folders.append( data.resources.folders.append(
&mut list_folders(app_handle, workspace_id) &mut list_folders(window, workspace_id)
.await .await
.expect("Failed to get folders"), .expect("Failed to get folders"),
); );
data.resources.http_requests.append( data.resources.http_requests.append(
&mut list_http_requests(app_handle, workspace_id) &mut list_http_requests(window, workspace_id)
.await .await
.expect("Failed to get http requests"), .expect("Failed to get http requests"),
); );
data.resources.grpc_requests.append( data.resources.grpc_requests.append(
&mut list_grpc_requests(app_handle, workspace_id) &mut list_grpc_requests(window, workspace_id)
.await .await
.expect("Failed to get grpc requests"), .expect("Failed to get grpc requests"),
); );
} }
return data; return data;
} }
fn emit_upserted_model<S: Serialize + Clone>(mgr: &impl Manager<Wry>, model: S) -> S { #[derive(Clone, Serialize)]
mgr.emit_all("upserted_model", model.clone()).unwrap(); #[serde(default, rename_all = "camelCase")]
struct ModelPayload<M: Serialize + Clone> {
pub model: M,
pub window_label: String,
}
fn emit_upserted_model<M: Serialize + Clone>(window: &WebviewWindow, model: M) -> M {
let payload = ModelPayload{
model: model.clone(),
window_label: window.label().to_string(),
};
window.emit("upserted_model", payload).unwrap();
model model
} }
fn emit_deleted_model<S: Serialize + Clone, E>(mgr: &impl Manager<Wry>, model: S) -> Result<S, E> { fn emit_deleted_model<M: Serialize + Clone, E>(window: &WebviewWindow, model: M) -> Result<M, E> {
mgr.emit_all("deleted_model", model.clone()).unwrap(); let payload = ModelPayload{
model: model.clone(),
window_label: window.label().to_string(),
};
window.emit("deleted_model", payload).unwrap();
Ok(model) Ok(model)
} }

View File

@@ -10,7 +10,8 @@ use boa_runtime::Console;
use log::{debug, error}; use log::{debug, error};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::json; use serde_json::json;
use tauri::AppHandle; use tauri::{AppHandle, Manager};
use tauri::path::BaseDirectory;
use crate::models::{WorkspaceExportResources}; use crate::models::{WorkspaceExportResources};
@@ -51,7 +52,7 @@ pub async fn run_plugin_import(
app_handle: &AppHandle, app_handle: &AppHandle,
plugin_name: &str, plugin_name: &str,
file_path: &str, file_path: &str,
) -> Option<ImportResult> { ) -> Result<Option<ImportResult>, String> {
let file = fs::read_to_string(file_path) let file = fs::read_to_string(file_path)
.unwrap_or_else(|_| panic!("Unable to read file {}", file_path)); .unwrap_or_else(|_| panic!("Unable to read file {}", file_path));
let file_contents = file.as_str(); let file_contents = file.as_str();
@@ -63,12 +64,12 @@ pub async fn run_plugin_import(
); );
if result_json.is_null() { if result_json.is_null() {
return None; return Ok(None);
} }
let resources: ImportResult = let resources: ImportResult =
serde_json::from_value(result_json).expect("failed to parse result json"); serde_json::from_value(result_json).map_err(|e| e.to_string())?;
Some(resources) Ok(Some(resources))
} }
fn run_plugin( fn run_plugin(
@@ -78,8 +79,8 @@ fn run_plugin(
js_args: &[JsValue], js_args: &[JsValue],
) -> serde_json::Value { ) -> serde_json::Value {
let plugin_dir = app_handle let plugin_dir = app_handle
.path_resolver() .path()
.resolve_resource("plugins") .resolve("plugins", BaseDirectory::Resource)
.expect("failed to resolve plugin directory resource") .expect("failed to resolve plugin directory resource")
.join(plugin_name); .join(plugin_name);
let plugin_index_file = plugin_dir.join("index.mjs"); let plugin_index_file = plugin_dir.join("index.mjs");

View File

@@ -1,6 +1,7 @@
use crate::models::{Environment, Workspace}; use crate::models::{Environment, Workspace};
use std::collections::HashMap; use std::collections::HashMap;
use tauri::regex::Regex; use regex::Regex;
pub fn render(template: &str, workspace: &Workspace, environment: Option<&Environment>) -> String { pub fn render(template: &str, workspace: &Workspace, environment: Option<&Environment>) -> String {
let mut map = HashMap::new(); let mut map = HashMap::new();
@@ -24,7 +25,7 @@ pub fn render(template: &str, workspace: &Workspace, environment: Option<&Enviro
Regex::new(r"\$\{\[\s*([^]\s]+)\s*]}") Regex::new(r"\$\{\[\s*([^]\s]+)\s*]}")
.expect("Failed to create regex") .expect("Failed to create regex")
.replace_all(template, |caps: &tauri::regex::Captures| { .replace_all(template, |caps: &regex::Captures| {
let key = caps.get(1).unwrap().as_str(); let key = caps.get(1).unwrap().as_str();
map.get(key).unwrap_or(&"") map.get(key).unwrap_or(&"")
}) })

View File

@@ -1,8 +1,9 @@
use std::time::SystemTime; use std::time::SystemTime;
use log::info; use log::info;
use tauri::api::dialog; use tauri::{AppHandle};
use tauri::{updater, AppHandle, Window}; use tauri_plugin_dialog::DialogExt;
use tauri_plugin_updater::UpdaterExt;
use crate::is_dev; use crate::is_dev;
@@ -29,7 +30,7 @@ impl YaakUpdater {
&mut self, &mut self,
app_handle: &AppHandle, app_handle: &AppHandle,
mode: UpdateMode, mode: UpdateMode,
) -> Result<bool, updater::Error> { ) -> Result<bool, tauri_plugin_updater::Error> {
self.last_update_check = SystemTime::now(); self.last_update_check = SystemTime::now();
let update_mode = get_update_mode_str(mode); let update_mode = get_update_mode_str(mode);
@@ -44,49 +45,48 @@ impl YaakUpdater {
} }
match app_handle match app_handle
.updater() .updater_builder()
.header("X-Update-Mode", update_mode)? .header("X-Update-Mode", update_mode)?
.build()?
.check() .check()
.await .await
{ {
Ok(update) => { Ok(Some(update)) => {
let h = app_handle.clone(); let h = app_handle.clone();
dialog::ask( app_handle
None::<&Window>, .dialog()
"Update Available", .message(format!(
format!(
"{} is available. Would you like to download and install it now?", "{} is available. Would you like to download and install it now?",
update.latest_version() update.version
), ))
|confirmed| { .title("Update Available")
.show(|confirmed| {
if !confirmed { if !confirmed {
return; return;
} }
tauri::async_runtime::spawn(async move { tauri::async_runtime::spawn(async move {
match update.download_and_install().await { match update.download_and_install(|_, _| {}, || {}).await {
Ok(_) => { Ok(_) => {
if dialog::blocking::ask( if h
None::<&Window>, .dialog()
"Update Installed", .message("Would you like to restart the app?")
"Would you like to restart the app?", .title("Update Installed")
) { .blocking_show()
{
h.restart(); h.restart();
} }
} }
Err(e) => { Err(e) => {
dialog::message( h
None::<&Window>, .dialog()
"Update Failed", .message(format!("The update failed to install: {}", e));
format!("The update failed to install: {}", e),
);
} }
} }
}); });
}, });
);
Ok(true) Ok(true)
} }
Err(updater::Error::UpToDate) => Ok(false), Ok(None) => Ok(false),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@@ -94,7 +94,7 @@ impl YaakUpdater {
&mut self, &mut self,
app_handle: &AppHandle, app_handle: &AppHandle,
mode: UpdateMode, mode: UpdateMode,
) -> Result<bool, updater::Error> { ) -> Result<bool, tauri_plugin_updater::Error> {
let ignore_check = let ignore_check =
self.last_update_check.elapsed().unwrap().as_secs() < MAX_UPDATE_CHECK_SECONDS; self.last_update_check.elapsed().unwrap().as_secs() < MAX_UPDATE_CHECK_SECONDS;
if ignore_check { if ignore_check {

View File

@@ -1,4 +1,4 @@
use tauri::{Runtime, Window}; use tauri::{WebviewWindow};
const TRAFFIC_LIGHT_OFFSET_X: f64 = 13.0; const TRAFFIC_LIGHT_OFFSET_X: f64 = 13.0;
const TRAFFIC_LIGHT_OFFSET_Y: f64 = 18.0; const TRAFFIC_LIGHT_OFFSET_Y: f64 = 18.0;
@@ -7,7 +7,7 @@ pub trait TrafficLightWindowExt {
fn position_traffic_lights(&self); fn position_traffic_lights(&self);
} }
impl<R: Runtime> TrafficLightWindowExt for Window<R> { impl TrafficLightWindowExt for WebviewWindow {
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
fn position_traffic_lights(&self) { fn position_traffic_lights(&self) {
// No-op on other platforms // No-op on other platforms

View File

@@ -1,140 +1,142 @@
use tauri::{AboutMetadata, CustomMenuItem, Menu, MenuItem, Submenu}; use tauri::menu::{
use crate::is_dev; AboutMetadata, Menu, MenuItemBuilder, PredefinedMenuItem, Submenu, HELP_SUBMENU_ID,
WINDOW_SUBMENU_ID,
};
pub use tauri::AppHandle;
use tauri::Wry;
pub fn os_default(#[allow(unused)] app_name: &str) -> Menu { pub fn app_menu(app_handle: &AppHandle) -> tauri::Result<Menu<Wry>> {
let mut menu = Menu::new(); let pkg_info = app_handle.package_info();
#[cfg(target_os = "macos")] let config = app_handle.config();
{ let about_metadata = AboutMetadata {
menu = menu.add_submenu(Submenu::new( name: Some(pkg_info.name.clone()),
app_name, version: Some(pkg_info.version.to_string()),
Menu::new() copyright: config.bundle.copyright.clone(),
.add_native_item(MenuItem::About( authors: config.bundle.publisher.clone().map(|p| vec![p]),
app_name.to_string(), ..Default::default()
AboutMetadata::default(), };
))
.add_native_item(MenuItem::Separator)
.add_item(
CustomMenuItem::new("toggle_settings".to_string(), "Settings")
.accelerator("CmdOrCtrl+,"),
)
.add_native_item(MenuItem::Separator)
.add_native_item(MenuItem::Services)
.add_native_item(MenuItem::Separator)
.add_native_item(MenuItem::Hide)
.add_native_item(MenuItem::HideOthers)
.add_native_item(MenuItem::ShowAll)
.add_native_item(MenuItem::Separator)
.add_native_item(MenuItem::Quit),
));
}
let mut file_menu = Menu::new(); let window_menu = Submenu::with_id_and_items(
file_menu = file_menu.add_native_item(MenuItem::CloseWindow); app_handle,
#[cfg(not(target_os = "macos"))] WINDOW_SUBMENU_ID,
{ "Window",
file_menu = file_menu.add_native_item(MenuItem::Quit); true,
} &[
menu = menu.add_submenu(Submenu::new("File", file_menu)); &PredefinedMenuItem::minimize(app_handle, None)?,
&PredefinedMenuItem::maximize(app_handle, None)?,
#[cfg(target_os = "macos")]
&PredefinedMenuItem::separator(app_handle)?,
&PredefinedMenuItem::close_window(app_handle, None)?,
],
)?;
#[cfg(not(target_os = "linux"))] let help_menu = Submenu::with_id_and_items(
let mut edit_menu = Menu::new(); app_handle,
#[cfg(target_os = "macos")] HELP_SUBMENU_ID,
{ "Help",
edit_menu = edit_menu.add_native_item(MenuItem::Undo); true,
edit_menu = edit_menu.add_native_item(MenuItem::Redo); &[
edit_menu = edit_menu.add_native_item(MenuItem::Separator); #[cfg(not(target_os = "macos"))]
} &PredefinedMenuItem::about(app_handle, None, Some(about_metadata))?,
#[cfg(not(target_os = "linux"))] #[cfg(target_os = "macos")]
{ &MenuItemBuilder::with_id("open_feedback".to_string(), "Give Feedback")
edit_menu = edit_menu.add_native_item(MenuItem::Cut); .build(app_handle)?,
edit_menu = edit_menu.add_native_item(MenuItem::Copy); ],
edit_menu = edit_menu.add_native_item(MenuItem::Paste); )?;
}
#[cfg(target_os = "macos")]
{
edit_menu = edit_menu.add_native_item(MenuItem::SelectAll);
}
#[cfg(not(target_os = "linux"))]
{
menu = menu.add_submenu(Submenu::new("Edit", edit_menu));
}
let mut view_menu = Menu::new();
#[cfg(target_os = "macos")]
{
view_menu = view_menu
.add_native_item(MenuItem::EnterFullScreen)
.add_native_item(MenuItem::Separator);
}
view_menu = view_menu
.add_item(
CustomMenuItem::new("zoom_reset".to_string(), "Zoom to Actual Size")
.accelerator("CmdOrCtrl+0"),
)
.add_item(
CustomMenuItem::new("zoom_in".to_string(), "Zoom In").accelerator("CmdOrCtrl+Plus"),
)
.add_item(
CustomMenuItem::new("zoom_out".to_string(), "Zoom Out").accelerator("CmdOrCtrl+-"),
);
// .add_native_item(MenuItem::Separator)
// .add_item(
// CustomMenuItem::new("toggle_sidebar".to_string(), "Toggle Sidebar")
// .accelerator("CmdOrCtrl+b"),
// )
// .add_item(
// CustomMenuItem::new("focus_sidebar".to_string(), "Focus Sidebar")
// .accelerator("CmdOrCtrl+1"),
// )
// .add_item(
// CustomMenuItem::new("toggle_settings".to_string(), "Toggle Settings")
// .accelerator("CmdOrCtrl+,"),
// )
// .add_item(
// CustomMenuItem::new("focus_url".to_string(), "Focus URL").accelerator("CmdOrCtrl+l"),
// );
menu = menu.add_submenu(Submenu::new("View", view_menu));
let mut window_menu = Menu::new(); let menu = Menu::with_items(
window_menu = window_menu.add_native_item(MenuItem::Minimize); app_handle,
#[cfg(target_os = "macos")] &[
{ #[cfg(target_os = "macos")]
window_menu = window_menu.add_native_item(MenuItem::Zoom); &Submenu::with_items(
window_menu = window_menu.add_native_item(MenuItem::Separator); app_handle,
} pkg_info.name.clone(),
window_menu = window_menu.add_native_item(MenuItem::CloseWindow); true,
menu = menu.add_submenu(Submenu::new("Window", window_menu)); &[
&PredefinedMenuItem::about(app_handle, None, Some(about_metadata))?,
&PredefinedMenuItem::separator(app_handle)?,
&MenuItemBuilder::with_id("settings".to_string(), "Settings")
.accelerator("CmdOrCtrl+,")
.build(app_handle)?,
&PredefinedMenuItem::separator(app_handle)?,
&PredefinedMenuItem::services(app_handle, None)?,
&PredefinedMenuItem::separator(app_handle)?,
&PredefinedMenuItem::hide(app_handle, None)?,
&PredefinedMenuItem::hide_others(app_handle, None)?,
&PredefinedMenuItem::separator(app_handle)?,
&PredefinedMenuItem::quit(app_handle, None)?,
],
)?,
#[cfg(not(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
)))]
&Submenu::with_items(
app_handle,
"File",
true,
&[
&PredefinedMenuItem::close_window(app_handle, None)?,
#[cfg(not(target_os = "macos"))]
&PredefinedMenuItem::quit(app_handle, None)?,
],
)?,
&Submenu::with_items(
app_handle,
"Edit",
true,
&[
&PredefinedMenuItem::undo(app_handle, None)?,
&PredefinedMenuItem::redo(app_handle, None)?,
&PredefinedMenuItem::separator(app_handle)?,
&PredefinedMenuItem::cut(app_handle, None)?,
&PredefinedMenuItem::copy(app_handle, None)?,
&PredefinedMenuItem::paste(app_handle, None)?,
&PredefinedMenuItem::select_all(app_handle, None)?,
],
)?,
&Submenu::with_items(
app_handle,
"View",
true,
&[
#[cfg(target_os = "macos")]
&PredefinedMenuItem::fullscreen(app_handle, None)?,
#[cfg(target_os = "macos")]
&PredefinedMenuItem::separator(app_handle)?,
&MenuItemBuilder::with_id("zoom_reset".to_string(), "Zoom to Actual Size")
.accelerator("CmdOrCtrl+0")
.build(app_handle)?,
&MenuItemBuilder::with_id("zoom_in".to_string(), "Zoom In")
.accelerator("CmdOrCtrl+=")
.build(app_handle)?,
&MenuItemBuilder::with_id("zoom_out".to_string(), "Zoom Out")
.accelerator("CmdOrCtrl+-")
.build(app_handle)?,
],
)?,
&window_menu,
&help_menu,
#[cfg(dev)]
&Submenu::with_items(
app_handle,
"Develop",
true,
&[
&MenuItemBuilder::with_id("refresh".to_string(), "Refresh")
.accelerator("CmdOrCtrl+Shift+r")
.build(app_handle)?,
&MenuItemBuilder::with_id("toggle_devtools".to_string(), "Open Devtools")
.accelerator("CmdOrCtrl+Option+i")
.build(app_handle)?,
],
)?,
],
)?;
// menu = menu.add_submenu(Submenu::new( Ok(menu)
// "Workspace",
// Menu::new()
// .add_item(
// CustomMenuItem::new("send_request".to_string(), "Send Request")
// .accelerator("CmdOrCtrl+r"),
// )
// .add_item(
// CustomMenuItem::new("new_request".to_string(), "New Request")
// .accelerator("CmdOrCtrl+n"),
// )
// .add_item(
// CustomMenuItem::new("duplicate_request".to_string(), "Duplicate Request")
// .accelerator("CmdOrCtrl+d"),
// ),
// ));
if is_dev() {
menu = menu.add_submenu(Submenu::new(
"Developer",
Menu::new()
.add_item(
CustomMenuItem::new("refresh".to_string(), "Refresh")
.accelerator("CmdOrCtrl + Shift + r"),
)
.add_item(
CustomMenuItem::new("toggle_devtools".to_string(), "Open Devtools")
.accelerator("CmdOrCtrl + Option + i"),
),
));
}
menu
} }

View File

@@ -1,17 +1,13 @@
{ {
"package": { "productName": "Daak",
"productName": "Daak" "identifier": "app.yaak.desktop.dev",
}, "bundle": {
"tauri": { "icon": [
"bundle": { "icons/dev/32x32.png",
"icon": [ "icons/dev/128x128.png",
"icons/dev/32x32.png", "icons/dev/128x128@2x.png",
"icons/dev/128x128.png", "icons/dev/icon.icns",
"icons/dev/128x128@2x.png", "icons/dev/icon.ico"
"icons/dev/icon.icns", ]
"icons/dev/icon.ico"
],
"identifier": "app.yaak.desktop.dev"
}
} }
} }

View File

@@ -2,40 +2,49 @@
"build": { "build": {
"beforeBuildCommand": "npm run build", "beforeBuildCommand": "npm run build",
"beforeDevCommand": "npm run dev", "beforeDevCommand": "npm run dev",
"devPath": "http://localhost:1420", "devUrl": "http://localhost:1420",
"distDir": "../dist", "frontendDist": "../dist"
"withGlobalTauri": false
}, },
"package": { "productName": "Yaak",
"productName": "Yaak", "version": "2024.3.10",
"version": "2024.3.10" "identifier": "app.yaak.desktop",
"app": {
"withGlobalTauri": false,
"security": {
"assetProtocol": {
"scope": [
"$APPDATA/responses/*"
]
}
}
}, },
"tauri": { "plugins": {
"windows": [], "updater": {
"endpoints": [
"https://update.yaak.app/check/{{target}}/{{arch}}/{{current_version}}"
],
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEMxRDJFREQ1MjExQjdGN0IKUldSN2Z4c2gxZTNTd1FHNCtmYnFXMHVVQzhuNkJOM1cwOFBodmdLall3ckhKenpKUytHSTR1MlkK"
},
"allowlist": { "allowlist": {
"all": false, "all": false,
"os": { "os": {
"all": true "allow-os-type": true
},
"protocol": {
"assetScope": [
"$APPDATA/responses/*"
],
"asset": true
}, },
"fs": { "fs": {
"readFile": true, "readFile": true,
"scope": [ "scope": [
"$RESOURCE/*", "$RESOURCE/*",
"$APPDATA/responses/*" "$APPDATA/responses/*"
] ]
}, },
"shell": { "shell": {
"all": false, "all": false,
"open": true, "open": true,
"sidecar": true, "sidecar": true,
"scope": [ "scope": [
{ "name": "protoc", "sidecar": true, {
"name": "protoc",
"sidecar": true,
"args": true "args": true
} }
] ]
@@ -57,58 +66,37 @@
"path": { "path": {
"all": true "all": true
} }
}
},
"bundle": {
"active": true,
"category": "DeveloperTool",
"externalBin": [
"protoc-vendored/protoc"
],
"icon": [
"icons/release/32x32.png",
"icons/release/128x128.png",
"icons/release/128x128@2x.png",
"icons/release/icon.icns",
"icons/release/icon.ico"
],
"longDescription": "The best cross-platform visual API client",
"resources": [
"migrations/*",
"plugins/*",
"protoc-vendored/include/*"
],
"shortDescription": "The best API client",
"targets": "all",
"macOS": {
"exceptionDomain": "",
"entitlements": "macos/entitlements.plist",
"frameworks": []
}, },
"bundle": { "windows": {
"active": true, "digestAlgorithm": "sha256",
"category": "DeveloperTool", "timestampUrl": ""
"copyright": "",
"externalBin": [
"protoc-vendored/protoc"
],
"icon": [
"icons/release/32x32.png",
"icons/release/128x128.png",
"icons/release/128x128@2x.png",
"icons/release/icon.icns",
"icons/release/icon.ico"
],
"identifier": "app.yaak.desktop",
"longDescription": "The best cross-platform visual API client",
"resources": [
"migrations/*",
"plugins/*",
"protoc-vendored/include/*"
],
"shortDescription": "The best API client",
"targets": [
"deb",
"appimage",
"nsis",
"app",
"dmg",
"updater"
],
"deb": {
"depends": []
},
"macOS": {
"exceptionDomain": "",
"entitlements": "macos/entitlements.plist",
"frameworks": []
},
"windows": {
"digestAlgorithm": "sha256",
"timestampUrl": ""
}
},
"security": {},
"updater": {
"active": true,
"dialog": false,
"endpoints": [
"https://update.yaak.app/check/{{target}}/{{arch}}/{{current_version}}"
],
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEMxRDJFREQ1MjExQjdGN0IKUldSN2Z4c2gxZTNTd1FHNCtmYnFXMHVVQzhuNkJOM1cwOFBodmdLall3ckhKenpKUytHSTR1MlkK"
} }
} }
} }

View File

@@ -1,4 +1,4 @@
import { open } from '@tauri-apps/api/dialog'; import { open } from '@tauri-apps/plugin-dialog';
import mime from 'mime'; import mime from 'mime';
import { useKeyValue } from '../hooks/useKeyValue'; import { useKeyValue } from '../hooks/useKeyValue';
import type { HttpRequest } from '../lib/models'; import type { HttpRequest } from '../lib/models';

View File

@@ -1,5 +1,5 @@
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { save } from '@tauri-apps/api/dialog'; import { save } from '@tauri-apps/plugin-dialog';
import { useState } from 'react'; import { useState } from 'react';
import slugify from 'slugify'; import slugify from 'slugify';
import type { Workspace } from '../lib/models'; import type { Workspace } from '../lib/models';

View File

@@ -1,9 +1,10 @@
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import { appWindow } from '@tauri-apps/api/window'; import { getCurrent } from '@tauri-apps/api/webviewWindow';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { useCommandPalette } from '../hooks/useCommandPalette'; import { useCommandPalette } from '../hooks/useCommandPalette';
import { cookieJarsQueryKey } from '../hooks/useCookieJars'; import { cookieJarsQueryKey } from '../hooks/useCookieJars';
import { foldersQueryKey } from '../hooks/useFolders';
import { useGlobalCommands } from '../hooks/useGlobalCommands'; import { useGlobalCommands } from '../hooks/useGlobalCommands';
import { grpcConnectionsQueryKey } from '../hooks/useGrpcConnections'; import { grpcConnectionsQueryKey } from '../hooks/useGrpcConnections';
import { grpcEventsQueryKey } from '../hooks/useGrpcEvents'; import { grpcEventsQueryKey } from '../hooks/useGrpcEvents';
@@ -47,93 +48,110 @@ export function GlobalHooks() {
setPathname(location.pathname).catch(console.error); setPathname(location.pathname).catch(console.error);
}, [location.pathname]); }, [location.pathname]);
useListenToTauriEvent<Model>('upserted_model', ({ payload, windowLabel }) => { interface ModelPayload {
model: Model;
windowLabel: string;
}
useListenToTauriEvent<ModelPayload>('upserted_model', ({ payload }) => {
const { model, windowLabel } = payload;
const queryKey = const queryKey =
payload.model === 'http_request' model.model === 'http_request'
? httpRequestsQueryKey(payload) ? httpRequestsQueryKey(model)
: payload.model === 'http_response' : model.model === 'http_response'
? httpResponsesQueryKey(payload) ? httpResponsesQueryKey(model)
: payload.model === 'grpc_connection' : model.model === 'folder'
? grpcConnectionsQueryKey(payload) ? foldersQueryKey(model)
: payload.model === 'grpc_event' : model.model === 'grpc_connection'
? grpcEventsQueryKey(payload) ? grpcConnectionsQueryKey(model)
: payload.model === 'grpc_request' : model.model === 'grpc_event'
? grpcRequestsQueryKey(payload) ? grpcEventsQueryKey(model)
: payload.model === 'workspace' : model.model === 'grpc_request'
? workspacesQueryKey(payload) ? grpcRequestsQueryKey(model)
: payload.model === 'key_value' : model.model === 'workspace'
? keyValueQueryKey(payload) ? workspacesQueryKey(model)
: payload.model === 'cookie_jar' : model.model === 'key_value'
? cookieJarsQueryKey(payload) ? keyValueQueryKey(model)
: payload.model === 'settings' : model.model === 'cookie_jar'
? cookieJarsQueryKey(model)
: model.model === 'settings'
? settingsQueryKey() ? settingsQueryKey()
: null; : null;
if (queryKey === null) { if (queryKey === null) {
console.log('Unrecognized updated model:', payload); console.log('Unrecognized updated model:', model);
return; return;
} }
if (payload.model === 'http_request' && windowLabel !== appWindow.label) { if (model.model === 'http_request' && windowLabel !== getCurrent().label) {
wasUpdatedExternally(payload.id); wasUpdatedExternally(model.id);
} }
const pushToFront = (['http_response', 'grpc_connection'] as Model['model'][]).includes( const pushToFront = (['http_response', 'grpc_connection'] as Model['model'][]).includes(
payload.model, model.model,
); );
if (shouldIgnoreModel(payload)) return; if (shouldIgnoreModel(model)) return;
queryClient.setQueryData<Model[]>(queryKey, (values = []) => { queryClient.setQueryData<Model[]>(queryKey, (values = []) => {
const index = values.findIndex((v) => modelsEq(v, payload)) ?? -1; const index = values.findIndex((v) => modelsEq(v, model)) ?? -1;
if (index >= 0) { if (index >= 0) {
// console.log('UPDATED', payload); // console.log('UPDATED', payload);
return [...values.slice(0, index), payload, ...values.slice(index + 1)]; return [...values.slice(0, index), model, ...values.slice(index + 1)];
} else { } else {
// console.log('CREATED', payload); // console.log('CREATED', payload);
return pushToFront ? [payload, ...(values ?? [])] : [...(values ?? []), payload]; return pushToFront ? [model, ...(values ?? [])] : [...(values ?? []), model];
} }
}); });
}); });
useListenToTauriEvent<Model>('deleted_model', ({ payload }) => { useListenToTauriEvent<ModelPayload>('deleted_model', ({ payload }) => {
if (shouldIgnoreModel(payload)) return; const { model } = payload;
if (shouldIgnoreModel(model)) return;
if (payload.model === 'workspace') { if (model.model === 'workspace') {
queryClient.setQueryData(workspacesQueryKey(), removeById(payload)); queryClient.setQueryData(workspacesQueryKey(), removeById(model));
} else if (payload.model === 'http_request') { } else if (model.model === 'http_request') {
queryClient.setQueryData(httpRequestsQueryKey(payload), removeById(payload)); queryClient.setQueryData(httpRequestsQueryKey(model), removeById(model));
} else if (payload.model === 'http_response') { } else if (model.model === 'http_response') {
queryClient.setQueryData(httpResponsesQueryKey(payload), removeById(payload)); queryClient.setQueryData(httpResponsesQueryKey(model), removeById(model));
} else if (payload.model === 'grpc_request') { } else if (model.model === 'folder') {
queryClient.setQueryData(grpcRequestsQueryKey(payload), removeById(payload)); queryClient.setQueryData(foldersQueryKey(model), removeById(model));
} else if (payload.model === 'grpc_connection') { } else if (model.model === 'grpc_request') {
queryClient.setQueryData(grpcConnectionsQueryKey(payload), removeById(payload)); queryClient.setQueryData(grpcRequestsQueryKey(model), removeById(model));
} else if (payload.model === 'grpc_event') { } else if (model.model === 'grpc_connection') {
queryClient.setQueryData(grpcEventsQueryKey(payload), removeById(payload)); queryClient.setQueryData(grpcConnectionsQueryKey(model), removeById(model));
} else if (payload.model === 'key_value') { } else if (model.model === 'grpc_event') {
queryClient.setQueryData(keyValueQueryKey(payload), undefined); queryClient.setQueryData(grpcEventsQueryKey(model), removeById(model));
} else if (payload.model === 'cookie_jar') { } else if (model.model === 'key_value') {
queryClient.setQueryData(cookieJarsQueryKey(payload), undefined); queryClient.setQueryData(keyValueQueryKey(model), undefined);
} else if (payload.model === 'settings') { } else if (model.model === 'cookie_jar') {
queryClient.setQueryData(cookieJarsQueryKey(model), undefined);
} else if (model.model === 'settings') {
queryClient.setQueryData(settingsQueryKey(), undefined); queryClient.setQueryData(settingsQueryKey(), undefined);
} }
}); });
useListenToTauriEvent<number>('zoom', ({ payload: zoomDelta, windowLabel }) => {
if (windowLabel !== appWindow.label) return;
const fontSize = parseFloat(window.getComputedStyle(document.documentElement).fontSize);
let newFontSize; useListenToTauriEvent<number>(
if (zoomDelta === 0) { 'zoom',
newFontSize = DEFAULT_FONT_SIZE; ({ payload: zoomDelta }) => {
} else if (zoomDelta > 0) { const fontSize = parseFloat(window.getComputedStyle(document.documentElement).fontSize);
newFontSize = Math.min(fontSize * 1.1, DEFAULT_FONT_SIZE * 5);
} else if (zoomDelta < 0) {
newFontSize = Math.max(fontSize * 0.9, DEFAULT_FONT_SIZE * 0.4);
}
document.documentElement.style.fontSize = `${newFontSize}px`; let newFontSize;
}); if (zoomDelta === 0) {
newFontSize = DEFAULT_FONT_SIZE;
} else if (zoomDelta > 0) {
newFontSize = Math.min(fontSize * 1.1, DEFAULT_FONT_SIZE * 5);
} else if (zoomDelta < 0) {
newFontSize = Math.max(fontSize * 0.9, DEFAULT_FONT_SIZE * 0.4);
}
document.documentElement.style.fontSize = `${newFontSize}px`;
},
{
target: { kind: 'WebviewWindow', label: getCurrent().label },
},
);
return null; return null;
} }

View File

@@ -1,4 +1,4 @@
import { open } from '@tauri-apps/api/dialog'; import { open } from '@tauri-apps/plugin-dialog';
import { useGrpc } from '../hooks/useGrpc'; import { useGrpc } from '../hooks/useGrpc';
import { useGrpcProtoFiles } from '../hooks/useGrpcProtoFiles'; import { useGrpcProtoFiles } from '../hooks/useGrpcProtoFiles';
import { useGrpcRequest } from '../hooks/useGrpcRequest'; import { useGrpcRequest } from '../hooks/useGrpcRequest';
@@ -47,8 +47,10 @@ export function GrpcProtoSelection({ requestId }: Props) {
multiple: true, multiple: true,
filters: [{ name: 'Proto Files', extensions: ['proto'] }], filters: [{ name: 'Proto Files', extensions: ['proto'] }],
}); });
if (files == null || typeof files === 'string') return; if (files == null) {
const newFiles = files.filter((f) => !protoFiles.includes(f)); return;
}
const newFiles = files.map((f) => f.path).filter((p) => !protoFiles.includes(p));
await protoFilesKv.set([...protoFiles, ...newFiles]); await protoFilesKv.set([...protoFiles, ...newFiles]);
await grpc.reflect.refetch(); await grpc.reflect.refetch();
}} }}

View File

@@ -19,6 +19,7 @@ const radioItems: RadioDropdownItem<string>[] = [
'PATCH', 'PATCH',
'DELETE', 'DELETE',
'OPTIONS', 'OPTIONS',
'QUERY',
'HEAD', 'HEAD',
].map((m) => ({ ].map((m) => ({
value: m, value: m,
@@ -33,7 +34,6 @@ export const RequestMethodDropdown = memo(function RequestMethodDropdown({
const prompt = usePrompt(); const prompt = usePrompt();
const extraItems = useMemo<DropdownItem[]>( const extraItems = useMemo<DropdownItem[]>(
() => [ () => [
{ type: 'separator' },
{ {
key: 'custom', key: 'custom',
label: 'CUSTOM', label: 'CUSTOM',

View File

@@ -1,4 +1,4 @@
import { shell } from '@tauri-apps/api'; import { open } from '@tauri-apps/plugin-shell';
import type { HttpResponse } from '../lib/models'; import type { HttpResponse } from '../lib/models';
import { IconButton } from './core/IconButton'; import { IconButton } from './core/IconButton';
import { KeyValueRow, KeyValueRows } from './core/KeyValueRow'; import { KeyValueRow, KeyValueRows } from './core/KeyValueRow';
@@ -28,7 +28,7 @@ export function ResponseHeaders({ response }: Props) {
iconSize="sm" iconSize="sm"
className="inline-block w-auto ml-1 !h-auto opacity-50 hover:opacity-100" className="inline-block w-auto ml-1 !h-auto opacity-50 hover:opacity-100"
icon="externalLink" icon="externalLink"
onClick={() => shell.open(response.url)} onClick={() => open(response.url)}
title="Open in browser" title="Open in browser"
/> />
</div> </div>

View File

@@ -1,4 +1,4 @@
import { shell } from '@tauri-apps/api'; import { open } from '@tauri-apps/plugin-shell';
import { useRef, useState } from 'react'; import { useRef, useState } from 'react';
import { useAppInfo } from '../hooks/useAppInfo'; import { useAppInfo } from '../hooks/useAppInfo';
import { useCheckForUpdates } from '../hooks/useCheckForUpdates'; import { useCheckForUpdates } from '../hooks/useCheckForUpdates';
@@ -26,6 +26,17 @@ export function SettingsDropdown() {
setShowChangelog(true); setShowChangelog(true);
}); });
const showSettings = () => {
dialog.show({
id: 'settings',
size: 'md',
title: 'Settings',
render: () => <SettingsDialog />,
});
};
useListenToTauriEvent('settings', showSettings);
return ( return (
<Dropdown <Dropdown
ref={dropdownRef} ref={dropdownRef}
@@ -36,14 +47,7 @@ export function SettingsDropdown() {
label: 'Settings', label: 'Settings',
hotKeyAction: 'settings.show', hotKeyAction: 'settings.show',
leftSlot: <Icon icon="settings" />, leftSlot: <Icon icon="settings" />,
onSelect: () => { onSelect: showSettings,
dialog.show({
id: 'settings',
size: 'md',
title: 'Settings',
render: () => <SettingsDialog />,
});
},
}, },
{ {
key: 'hotkeys', key: 'hotkeys',
@@ -83,7 +87,7 @@ export function SettingsDropdown() {
label: 'Feedback', label: 'Feedback',
leftSlot: <Icon icon="chat" />, leftSlot: <Icon icon="chat" />,
rightSlot: <Icon icon="externalLink" />, rightSlot: <Icon icon="externalLink" />,
onSelect: () => shell.open('https://yaak.canny.io'), onSelect: () => open('https://yaak.canny.io'),
}, },
{ {
key: 'changelog', key: 'changelog',
@@ -91,7 +95,7 @@ export function SettingsDropdown() {
variant: showChangelog ? 'notify' : 'default', variant: showChangelog ? 'notify' : 'default',
leftSlot: <Icon icon="cake" />, leftSlot: <Icon icon="cake" />,
rightSlot: <Icon icon="externalLink" />, rightSlot: <Icon icon="externalLink" />,
onSelect: () => shell.open(`https://yaak.app/changelog/${appInfo.data?.version}`), onSelect: () => open(`https://yaak.app/changelog/${appInfo.data?.version}`),
}, },
]} ]}
> >

View File

@@ -211,7 +211,7 @@ interface HeaderSizeProps extends HTMLAttributes<HTMLDivElement> {
function HeaderSize({ className, style, ...props }: HeaderSizeProps) { function HeaderSize({ className, style, ...props }: HeaderSizeProps) {
const platform = useOsInfo(); const platform = useOsInfo();
const fullscreen = useIsFullscreen(); const fullscreen = useIsFullscreen();
const stoplightsVisible = platform?.osType === 'Darwin' && !fullscreen; const stoplightsVisible = platform?.osType === 'macos' && !fullscreen;
return ( return (
<div <div
style={style} style={style}

View File

@@ -1,4 +1,4 @@
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import classNames from 'classnames'; import classNames from 'classnames';
import { memo, useMemo } from 'react'; import { memo, useMemo } from 'react';
import { useActiveWorkspace } from '../hooks/useActiveWorkspace'; import { useActiveWorkspace } from '../hooks/useActiveWorkspace';

View File

@@ -1,6 +1,9 @@
import { getCurrent } from '@tauri-apps/api/webviewWindow';
import classNames from 'classnames'; import classNames from 'classnames';
import React, { memo, useState } from 'react'; import React, { memo, useState } from 'react';
import { useOsInfo } from '../hooks/useOsInfo';
import { CookieDropdown } from './CookieDropdown'; import { CookieDropdown } from './CookieDropdown';
import { Button } from './core/Button';
import { Icon } from './core/Icon'; import { Icon } from './core/Icon';
import { HStack } from './core/Stacks'; import { HStack } from './core/Stacks';
import { EnvironmentActionsDropdown } from './EnvironmentActionsDropdown'; import { EnvironmentActionsDropdown } from './EnvironmentActionsDropdown';
@@ -8,9 +11,6 @@ import { RecentRequestsDropdown } from './RecentRequestsDropdown';
import { SettingsDropdown } from './SettingsDropdown'; import { SettingsDropdown } from './SettingsDropdown';
import { SidebarActions } from './SidebarActions'; import { SidebarActions } from './SidebarActions';
import { WorkspaceActionsDropdown } from './WorkspaceActionsDropdown'; import { WorkspaceActionsDropdown } from './WorkspaceActionsDropdown';
import { useOsInfo } from '../hooks/useOsInfo';
import { Button } from './core/Button';
import { appWindow } from '@tauri-apps/api/window';
interface Props { interface Props {
className?: string; className?: string;
@@ -40,11 +40,11 @@ export const WorkspaceHeader = memo(function WorkspaceHeader({ className }: Prop
</div> </div>
<div className="flex-1 flex items-center h-full justify-end pointer-events-none"> <div className="flex-1 flex items-center h-full justify-end pointer-events-none">
<SettingsDropdown /> <SettingsDropdown />
{(osInfo?.osType === 'Linux' || osInfo?.osType === 'Windows_NT') && ( {(osInfo?.osType === 'linux' || osInfo?.osType === 'windows') && (
<HStack className="ml-4" alignItems="center"> <HStack className="ml-4" alignItems="center">
<Button <Button
className="px-4 !text-gray-600 rounded-none" className="px-4 !text-gray-600 rounded-none"
onClick={() => appWindow.minimize()} onClick={() => getCurrent().minimize()}
> >
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="currentColor" d="M14 8v1H3V8z" /> <path fill="currentColor" d="M14 8v1H3V8z" />
@@ -53,8 +53,9 @@ export const WorkspaceHeader = memo(function WorkspaceHeader({ className }: Prop
<Button <Button
className="px-4 !text-gray-600 rounded-none" className="px-4 !text-gray-600 rounded-none"
onClick={async () => { onClick={async () => {
await appWindow.toggleMaximize(); const w = getCurrent();
setMaximized(await appWindow.isMaximized()); await w.toggleMaximize();
setMaximized(await w.isMaximized());
}} }}
> >
{maximized ? ( {maximized ? (
@@ -73,7 +74,7 @@ export const WorkspaceHeader = memo(function WorkspaceHeader({ className }: Prop
<Button <Button
color="custom" color="custom"
className="px-4 text-gray-600 rounded-none hocus:bg-red-200 hocus:text-gray-800" className="px-4 text-gray-600 rounded-none hocus:bg-red-200 hocus:text-gray-800"
onClick={() => appWindow.close()} onClick={() => getCurrent().close()}
> >
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path <path

View File

@@ -1,4 +1,4 @@
import { open } from '@tauri-apps/api/dialog'; import { open } from '@tauri-apps/plugin-dialog';
import classNames from 'classnames'; import classNames from 'classnames';
import type { EditorView } from 'codemirror'; import type { EditorView } from 'codemirror';
import { Fragment, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Fragment, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';

View File

@@ -1,4 +1,4 @@
import { convertFileSrc } from '@tauri-apps/api/tauri'; import { convertFileSrc } from '@tauri-apps/api/core';
import classNames from 'classnames'; import classNames from 'classnames';
import { useState } from 'react'; import { useState } from 'react';
import type { HttpResponse } from '../../lib/models'; import type { HttpResponse } from '../../lib/models';

View File

@@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
export function useAppInfo() { export function useAppInfo() {
return useQuery(['appInfo'], async () => { return useQuery(['appInfo'], async () => {

View File

@@ -1,5 +1,5 @@
import { useMutation } from '@tanstack/react-query'; import { useMutation } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { minPromiseMillis } from '../lib/minPromiseMillis'; import { minPromiseMillis } from '../lib/minPromiseMillis';
import { useAlert } from './useAlert'; import { useAlert } from './useAlert';

View File

@@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import type { CookieJar } from '../lib/models'; import type { CookieJar } from '../lib/models';
import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { useActiveWorkspaceId } from './useActiveWorkspaceId';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import type { CookieJar } from '../lib/models'; import type { CookieJar } from '../lib/models';
import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { useActiveWorkspaceId } from './useActiveWorkspaceId';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import type { Environment } from '../lib/models'; import type { Environment } from '../lib/models';
import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { useActiveWorkspaceId } from './useActiveWorkspaceId';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import type { Folder } from '../lib/models'; import type { Folder } from '../lib/models';
import { useActiveRequest } from './useActiveRequest'; import { useActiveRequest } from './useActiveRequest';

View File

@@ -1,5 +1,5 @@
import { useMutation } from '@tanstack/react-query'; import { useMutation } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import type { GrpcRequest } from '../lib/models'; import type { GrpcRequest } from '../lib/models';
import { useActiveEnvironmentId } from './useActiveEnvironmentId'; import { useActiveEnvironmentId } from './useActiveEnvironmentId';

View File

@@ -1,5 +1,5 @@
import { useMutation } from '@tanstack/react-query'; import { useMutation } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import type { HttpRequest } from '../lib/models'; import type { HttpRequest } from '../lib/models';
import { useActiveEnvironmentId } from './useActiveEnvironmentId'; import { useActiveEnvironmentId } from './useActiveEnvironmentId';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { InlineCode } from '../components/core/InlineCode'; import { InlineCode } from '../components/core/InlineCode';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import { fallbackRequestName } from '../lib/fallbackRequestName'; import { fallbackRequestName } from '../lib/fallbackRequestName';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { InlineCode } from '../components/core/InlineCode'; import { InlineCode } from '../components/core/InlineCode';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import { fallbackRequestName } from '../lib/fallbackRequestName'; import { fallbackRequestName } from '../lib/fallbackRequestName';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { InlineCode } from '../components/core/InlineCode'; import { InlineCode } from '../components/core/InlineCode';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import type { CookieJar } from '../lib/models'; import type { CookieJar } from '../lib/models';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { InlineCode } from '../components/core/InlineCode'; import { InlineCode } from '../components/core/InlineCode';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import type { Environment, Workspace } from '../lib/models'; import type { Environment, Workspace } from '../lib/models';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { InlineCode } from '../components/core/InlineCode'; import { InlineCode } from '../components/core/InlineCode';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import type { Folder } from '../lib/models'; import type { Folder } from '../lib/models';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import type { GrpcConnection } from '../lib/models'; import type { GrpcConnection } from '../lib/models';
import { grpcConnectionsQueryKey } from './useGrpcConnections'; import { grpcConnectionsQueryKey } from './useGrpcConnections';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import { grpcConnectionsQueryKey } from './useGrpcConnections'; import { grpcConnectionsQueryKey } from './useGrpcConnections';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import type { HttpResponse } from '../lib/models'; import type { HttpResponse } from '../lib/models';
import { httpResponsesQueryKey } from './useHttpResponses'; import { httpResponsesQueryKey } from './useHttpResponses';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import { httpResponsesQueryKey } from './useHttpResponses'; import { httpResponsesQueryKey } from './useHttpResponses';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { InlineCode } from '../components/core/InlineCode'; import { InlineCode } from '../components/core/InlineCode';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import type { Workspace } from '../lib/models'; import type { Workspace } from '../lib/models';

View File

@@ -1,5 +1,5 @@
import { useMutation } from '@tanstack/react-query'; import { useMutation } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import { setKeyValue } from '../lib/keyValueStore'; import { setKeyValue } from '../lib/keyValueStore';
import type { GrpcRequest } from '../lib/models'; import type { GrpcRequest } from '../lib/models';

View File

@@ -1,5 +1,5 @@
import { useMutation } from '@tanstack/react-query'; import { useMutation } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import type { HttpRequest } from '../lib/models'; import type { HttpRequest } from '../lib/models';
import { useActiveEnvironmentId } from './useActiveEnvironmentId'; import { useActiveEnvironmentId } from './useActiveEnvironmentId';

View File

@@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import type { Environment } from '../lib/models'; import type { Environment } from '../lib/models';
import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { useActiveWorkspaceId } from './useActiveWorkspaceId';

View File

@@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
export function useFilterResponse({ export function useFilterResponse({
responseId, responseId,

View File

@@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import type { Folder } from '../lib/models'; import type { Folder } from '../lib/models';
import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { useActiveWorkspaceId } from './useActiveWorkspaceId';

View File

@@ -1,4 +1,4 @@
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { useAppRoutes } from './useAppRoutes'; import { useAppRoutes } from './useAppRoutes';
import { useRegisterCommand } from './useCommands'; import { useRegisterCommand } from './useCommands';
import { usePrompt } from './usePrompt'; import { usePrompt } from './usePrompt';

View File

@@ -1,5 +1,5 @@
import { useMutation, useQuery } from '@tanstack/react-query'; import { useMutation, useQuery } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import { emit } from '@tauri-apps/api/event'; import { emit } from '@tauri-apps/api/event';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import { minPromiseMillis } from '../lib/minPromiseMillis'; import { minPromiseMillis } from '../lib/minPromiseMillis';

View File

@@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import type { GrpcConnection } from '../lib/models'; import type { GrpcConnection } from '../lib/models';
export function grpcConnectionsQueryKey({ requestId }: { requestId: string }) { export function grpcConnectionsQueryKey({ requestId }: { requestId: string }) {

View File

@@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import type { GrpcEvent } from '../lib/models'; import type { GrpcEvent } from '../lib/models';
export function grpcEventsQueryKey({ connectionId }: { connectionId: string }) { export function grpcEventsQueryKey({ connectionId }: { connectionId: string }) {

View File

@@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import type { GrpcRequest } from '../lib/models'; import type { GrpcRequest } from '../lib/models';
import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { useActiveWorkspaceId } from './useActiveWorkspaceId';

View File

@@ -1,4 +1,4 @@
import type { OsType } from '@tauri-apps/api/os'; import type { OsType } from '@tauri-apps/plugin-os';
import { useEffect, useRef } from 'react'; import { useEffect, useRef } from 'react';
import { capitalize } from '../lib/capitalize'; import { capitalize } from '../lib/capitalize';
import { debounce } from '../lib/debounce'; import { debounce } from '../lib/debounce';
@@ -160,7 +160,7 @@ export function useFormattedHotkey(action: HotkeyAction | null): string[] | null
const labelParts: string[] = []; const labelParts: string[] = [];
for (const p of parts) { for (const p of parts) {
if (os === 'Darwin') { if (os === 'macos') {
if (p === 'CmdCtrl') { if (p === 'CmdCtrl') {
labelParts.push('⌘'); labelParts.push('⌘');
} else if (p === 'Shift') { } else if (p === 'Shift') {
@@ -183,7 +183,7 @@ export function useFormattedHotkey(action: HotkeyAction | null): string[] | null
} }
} }
if (os === 'Darwin') { if (os === 'macos') {
return labelParts; return labelParts;
} else { } else {
return [labelParts.join('+')]; return [labelParts.join('+')];
@@ -191,7 +191,7 @@ export function useFormattedHotkey(action: HotkeyAction | null): string[] | null
} }
const normalizeKey = (key: string, os: OsType | null) => { const normalizeKey = (key: string, os: OsType | null) => {
if (key === 'Meta' && os === 'Darwin') return 'CmdCtrl'; if (key === 'Meta' && os === 'macos') return 'CmdCtrl';
else if (key === 'Control' && os !== 'Darwin') return 'CmdCtrl'; else if (key === 'Control' && os !== 'macos') return 'CmdCtrl';
else return key; else return key;
}; };

View File

@@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api/core';
import type { HttpRequest } from '../lib/models'; import type { HttpRequest } from '../lib/models';
import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { useActiveWorkspaceId } from './useActiveWorkspaceId';

Some files were not shown because too many files have changed in this diff Show More