Compare commits

...

24 Commits

Author SHA1 Message Date
Gregory Schier
a83e094f00 Fix copy-as-curl variables 2024-06-05 06:53:38 -07:00
Gregory Schier
e683a2cb2a Bump version 2024-06-04 23:53:45 -07:00
Gregory Schier
1f231c2722 Only release on tag again 2024-06-04 23:53:31 -07:00
Gregory Schier
0fc2575ef6 Fix default workspace settings on initial Workspace 2024-06-04 17:06:40 -07:00
Gregory Schier
44c718e6bc Better analytics error log 2024-06-04 16:27:22 -07:00
Gregory Schier
495df847ab Merge branch 'beta' into master 2024-06-04 15:01:55 -07:00
Gregory Schier
5dbb9852f3 Bump version 2024-06-04 15:00:34 -07:00
Gregory Schier
82d3304c38 Hopefully fix AppImage build not finding migrations. I think it was because the productName had a capital Yaak in it. 2024-06-04 14:59:40 -07:00
Gregory Schier
5e2218fd64 Remove Windows plugin 2024-06-04 02:56:52 -07:00
Gregory Schier
5b12fad173 2024.5.0-beta.2 (#38) 2024-06-03 14:03:25 -07:00
Gregory Schier
8d6f23eacb Bump version 2024-06-03 14:00:49 -07:00
Gregory Schier
75a09859bc Move Postman to first plugin 2024-06-03 14:00:40 -07:00
Gregory Schier
dc47c4ceba Preserve JSON/XPath filter (Closes #22) 2024-06-03 13:49:51 -07:00
Gregory Schier
8ae0290aed Don't send request on completion (Fixes #27) 2024-06-03 07:49:13 -07:00
Gregory Schier
f01d1e704b Don't always change request method. Closes #29 2024-06-03 07:26:40 -07:00
Gregory Schier
3f72996e64 Tweak settings labels 2024-06-02 23:54:00 -07:00
Gregory Schier
fe862517fb Fix dropdown icon color 2024-06-02 23:50:26 -07:00
Gregory Schier
b39335dc4f Don't call is_fullscreen so much 2024-06-02 23:38:56 -07:00
Gregory Schier
8f3bdb5039 Fix autocomplete for environment editor names 2024-06-02 17:52:51 -07:00
Gregory Schier
b47ec01f9c <Select> uses custom component on Windows 2024-06-02 16:57:23 -07:00
Gregory Schier
36728d1d1f Tweak Moonlight theme 2024-06-02 15:48:27 -07:00
Gregory Schier
c3f0351445 Fix font size 2024-06-02 11:53:41 -07:00
Gregory Schier
9a5364187c Better invalid URL errors 2024-06-02 11:53:35 -07:00
Gregory Schier
a9db14994f Import content-type from Postman multi-part form 2024-06-02 11:53:25 -07:00
40 changed files with 367 additions and 433 deletions

View File

@@ -1,9 +1,8 @@
name: Generate Artifacts
on:
push:
branches:
- release
- beta
tags: [ v* ]
jobs:
build-artifacts:
permissions:

View File

@@ -1 +0,0 @@
plugins

88
package-lock.json generated
View File

@@ -54,7 +54,7 @@
"devDependencies": {
"@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
"@tanstack/react-query-devtools": "^5.35.5",
"@tauri-apps/cli": "^2.0.0-beta.15",
"@tauri-apps/cli": ">=2.0.0-beta.0",
"@types/node": "^18.7.10",
"@types/papaparse": "^5.3.7",
"@types/parse-color": "^1.0.1",
@@ -2309,9 +2309,9 @@
}
},
"node_modules/@tauri-apps/cli": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.0-beta.15.tgz",
"integrity": "sha512-3pCvc54QfsRY+i9B7w3Q5jPAGtf8p+g7N/BamWPeiW6YqDqbHi9rNVI3SzrHkRRNOJnzMW8E5a8G0HziOluZGg==",
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.0-beta.20.tgz",
"integrity": "sha512-707q9uIc2oNrYHd2dtMvxTrpZXVpart5EIktnRymNOpphkLlB6WUBjHD+ga45WqTU6cNGKbYvkKqTNfshNul9Q==",
"dev": true,
"bin": {
"tauri": "tauri.js"
@@ -2324,22 +2324,22 @@
"url": "https://opencollective.com/tauri"
},
"optionalDependencies": {
"@tauri-apps/cli-darwin-arm64": "2.0.0-beta.15",
"@tauri-apps/cli-darwin-x64": "2.0.0-beta.15",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.0.0-beta.15",
"@tauri-apps/cli-linux-arm64-gnu": "2.0.0-beta.15",
"@tauri-apps/cli-linux-arm64-musl": "2.0.0-beta.15",
"@tauri-apps/cli-linux-x64-gnu": "2.0.0-beta.15",
"@tauri-apps/cli-linux-x64-musl": "2.0.0-beta.15",
"@tauri-apps/cli-win32-arm64-msvc": "2.0.0-beta.15",
"@tauri-apps/cli-win32-ia32-msvc": "2.0.0-beta.15",
"@tauri-apps/cli-win32-x64-msvc": "2.0.0-beta.15"
"@tauri-apps/cli-darwin-arm64": "2.0.0-beta.20",
"@tauri-apps/cli-darwin-x64": "2.0.0-beta.20",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.0.0-beta.20",
"@tauri-apps/cli-linux-arm64-gnu": "2.0.0-beta.20",
"@tauri-apps/cli-linux-arm64-musl": "2.0.0-beta.20",
"@tauri-apps/cli-linux-x64-gnu": "2.0.0-beta.20",
"@tauri-apps/cli-linux-x64-musl": "2.0.0-beta.20",
"@tauri-apps/cli-win32-arm64-msvc": "2.0.0-beta.20",
"@tauri-apps/cli-win32-ia32-msvc": "2.0.0-beta.20",
"@tauri-apps/cli-win32-x64-msvc": "2.0.0-beta.20"
}
},
"node_modules/@tauri-apps/cli-darwin-arm64": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.0-beta.15.tgz",
"integrity": "sha512-M4owBLoRdJb2/IK48KOQDU3j5xrjqGxa539rDXMjvaKydBk8x+aLdk3xZNsk/owHTI1GnrQZsPCMQaOgetYHaw==",
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.0-beta.20.tgz",
"integrity": "sha512-oCJOCib7GuYkwkBXx+ekamR8NZZU+2i3MLP+DHpDxK5gS2uhCE+CBkamJkNt6y1x6xdVnwyqZOm5RvN4SRtyIA==",
"cpu": [
"arm64"
],
@@ -2353,9 +2353,9 @@
}
},
"node_modules/@tauri-apps/cli-darwin-x64": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.0-beta.15.tgz",
"integrity": "sha512-ECpatfJdT4xKyFoE7tNEtTUIRxjQ2XSXa0TQkP3g7Kn7H/jRse+7pYe69jASA7shixajatAwmD4bXNT8jYRyNA==",
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.0-beta.20.tgz",
"integrity": "sha512-lC5QSnRExedYN4Ds6ZlSvC2PxP8qfIYBJQ5ktf+PJI5gQALdNeVtd6YnTG1ODCEklfLq9WKkGwp7JdALTU5wDA==",
"cpu": [
"x64"
],
@@ -2369,9 +2369,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.0-beta.15.tgz",
"integrity": "sha512-GQz2nnPwIamzDbmmfGWvmmoLthOkOBs0RO5u72KYAa78ZRFTx7S6AovnxJv48Fq+zeGGdDKoD9+ZG2Ue+sCL4w==",
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.0-beta.20.tgz",
"integrity": "sha512-nZCeBMHHye5DLOJV5k2w658hnCS+LYaOZ8y/G9l3ei+g0L/HBjlSy6r4simsAT5TG8+l3oCZzLBngfTMdDS/YA==",
"cpu": [
"arm"
],
@@ -2385,9 +2385,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.0-beta.15.tgz",
"integrity": "sha512-YBIfq0GbmIsWmRy6dVuDv3oMJN7a3R8HGVPMsa1W526AdCxoZDiPOQpSQN4VihJlbebUHxS/HyYF6maCY8uGzA==",
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.0-beta.20.tgz",
"integrity": "sha512-B79ISVLPVBgwnCchVqwTKU+vxnFYqxKomcR4rmsvxfs0NVtT5QuNzE1k4NUQnw3966yjwhYR3mnHsSJQSB4Eyw==",
"cpu": [
"arm64"
],
@@ -2401,9 +2401,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.0-beta.15.tgz",
"integrity": "sha512-2ZBXoShz7UfqVGmc85mhwjI6ckdtrk15V69adxt/x+VS68yK6Ddbj+yqlffpeFNL90fZrsVhFoRIDqgkxtwksQ==",
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.0-beta.20.tgz",
"integrity": "sha512-ojIkv/1uZHhcrgfIN8xgn4BBeo/Xg+bnV0wer6lD78zyxkUMWeEZ+u3mae1ejCJNhhaZOxNaUQ67MvDOiGyr5Q==",
"cpu": [
"arm64"
],
@@ -2417,9 +2417,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.0-beta.15.tgz",
"integrity": "sha512-cwJqIIdc4Kq9sBl/vYc+Y95iMe+mlTYUj7ZnSn4YAbLKFz432bGg6uBn2qHXFN5jzwXtEOVZiB1zDZ2kveVoAQ==",
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.0-beta.20.tgz",
"integrity": "sha512-xBy1FNbHKlc7T6pOmFQQPECxJaI5A9QWX7Kb9N64cNVusoOGlvc3xHYkXMS4PTr7xXOT0yiE1Ww2OwDRJ3lYsg==",
"cpu": [
"x64"
],
@@ -2433,9 +2433,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-musl": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.0-beta.15.tgz",
"integrity": "sha512-nNuxZ8/qs0vQbdLO2hovskZGxwGn2z4x1QFJuL4xwd6Tryy9vVcznvyZS+t/72dCLoIkY9pKZQq5nYtAHYfTEg==",
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.0-beta.20.tgz",
"integrity": "sha512-+O6zq5jmtUxA1FUAAwF2ywPysy4NRo2Y6G+ESZDkY9XosRwdt5OUjqAsYktZA3AxDMZVei8r9buwTqUwi9ny/g==",
"cpu": [
"x64"
],
@@ -2449,9 +2449,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.0-beta.15.tgz",
"integrity": "sha512-DXiXMTE00INjBkTgq1CYduMWgUwQ0NvLw+uXfu8BUupA+aOlv9ODhsGu7bZSaxKx4/glwxNAGZum4kQ0E0AxUg==",
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.0-beta.20.tgz",
"integrity": "sha512-RswgMbWyOQcv53CHvIuiuhAh4kKDqaGyZfWD4VlxqX/XhkoF5gsNgr0MxzrY7pmoL+89oVI+fiGVJz4nOQE5vA==",
"cpu": [
"arm64"
],
@@ -2465,9 +2465,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.0-beta.15.tgz",
"integrity": "sha512-ajEQdW2jx2raPp7eDYryJkbBrgI8PIY1dz5ro8FweRrRmbotaUlclsro1kfNMQrfDah8+qfwnRvW3MahOBE5Wg==",
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.0-beta.20.tgz",
"integrity": "sha512-5lgWmDVXhX3SBGbiv5SduM1yajiRnUEJClWhSdRrEEJeXdsxpCsBEhxYnUnDCEzPKxLLn5fdBv3VrVctJ03csQ==",
"cpu": [
"ia32"
],
@@ -2481,9 +2481,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.0-beta.15.tgz",
"integrity": "sha512-yzsSgoiY0PmFiR5LvVOFr1b7h9l3aLPPQFlDG6+kRMrxCo7x7Pbyh4D5cqiMUuZO0QacwSP38EH6w0F88Y+4OA==",
"version": "2.0.0-beta.20",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.0-beta.20.tgz",
"integrity": "sha512-SuSiiVQTQPSzWlsxQp/NMzWbzDS9TdVDOw7CCfgiG5wnT2GsxzrcIAVN6i7ILsVFLxrjr0bIgPldSJcdcH84Yw==",
"cpu": [
"x64"
],

View File

@@ -74,7 +74,7 @@
"devDependencies": {
"@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
"@tanstack/react-query-devtools": "^5.35.5",
"@tauri-apps/cli": "^2.0.0-beta.15",
"@tauri-apps/cli": ">=2.0.0-beta.0",
"@types/node": "^18.7.10",
"@types/papaparse": "^5.3.7",
"@types/parse-color": "^1.0.1",

View File

@@ -180,6 +180,7 @@ function importBody(rawBody: any): Pick<HttpRequest, 'body' | 'bodyType' | 'head
f.src != null
? {
enabled: !f.disabled,
contentType: f.contentType ?? null,
name: f.key ?? '',
file: f.src ?? '',
}
@@ -244,6 +245,7 @@ function convertTemplateSyntax<T>(obj: T): T {
}
const idCount: Partial<Record<Model['model'], number>> = {};
function generateId(model: Model['model']): string {
idCount[model] = (idCount[model] ?? -1) + 1;
return `GENERATE_ID::${model.toUpperCase()}_${idCount[model]}`;

123
src-tauri/Cargo.lock generated
View File

@@ -162,12 +162,12 @@ dependencies = [
[[package]]
name = "async-broadcast"
version = "0.7.0"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "258b52a1aa741b9f09783b2d86cf0aeeb617bbf847f6933340a39644227acbdb"
checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e"
dependencies = [
"event-listener 5.3.1",
"event-listener-strategy 0.5.2",
"event-listener-strategy",
"futures-core",
"pin-project-lite",
]
@@ -179,7 +179,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a"
dependencies = [
"concurrent-queue",
"event-listener-strategy 0.5.2",
"event-listener-strategy",
"futures-core",
"pin-project-lite",
]
@@ -200,9 +200,9 @@ dependencies = [
[[package]]
name = "async-io"
version = "2.3.2"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884"
checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964"
dependencies = [
"async-lock",
"cfg-if",
@@ -219,20 +219,20 @@ dependencies = [
[[package]]
name = "async-lock"
version = "3.3.0"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b"
checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
dependencies = [
"event-listener 4.0.3",
"event-listener-strategy 0.4.0",
"event-listener 5.3.1",
"event-listener-strategy",
"pin-project-lite",
]
[[package]]
name = "async-process"
version = "2.2.2"
version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a53fc6301894e04a92cb2584fedde80cb25ba8e02d9dc39d4a87d036e22f397d"
checksum = "f7eda79bbd84e29c2b308d1dc099d7de8dcc7035e48f4bf5dc4a531a44ff5e2a"
dependencies = [
"async-channel",
"async-io",
@@ -261,9 +261,9 @@ dependencies = [
[[package]]
name = "async-signal"
version = "0.2.6"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afe66191c335039c7bb78f99dc7520b0cbb166b3a1cb33a03f53d8a1c6f2afda"
checksum = "329972aa325176e89114919f2a80fdae4f4c040f66a370b1a1159c6c0f94e7aa"
dependencies = [
"async-io",
"async-lock",
@@ -373,7 +373,7 @@ dependencies = [
"futures-util",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.28",
"hyper 0.14.29",
"itoa 1.0.11",
"matchit",
"memchr",
@@ -1606,17 +1606,6 @@ version = "2.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "event-listener"
version = "4.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e"
dependencies = [
"concurrent-queue",
"parking",
"pin-project-lite",
]
[[package]]
name = "event-listener"
version = "5.3.1"
@@ -1628,16 +1617,6 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "event-listener-strategy"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3"
dependencies = [
"event-listener 4.0.3",
"pin-project-lite",
]
[[package]]
name = "event-listener-strategy"
version = "0.5.2"
@@ -2188,7 +2167,7 @@ name = "grpc"
version = "0.1.0"
dependencies = [
"anyhow",
"hyper 0.14.28",
"hyper 0.14.29",
"hyper-rustls 0.24.2",
"log",
"prost",
@@ -2467,9 +2446,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "0.14.28"
version = "0.14.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80"
checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33"
dependencies = [
"bytes",
"futures-channel",
@@ -2516,7 +2495,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
dependencies = [
"futures-util",
"http 0.2.12",
"hyper 0.14.28",
"hyper 0.14.29",
"log",
"rustls 0.21.12",
"rustls-native-certs",
@@ -2547,7 +2526,7 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
dependencies = [
"hyper 0.14.28",
"hyper 0.14.29",
"pin-project-lite",
"tokio",
"tokio-io-timeout",
@@ -2560,7 +2539,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
"hyper 0.14.28",
"hyper 0.14.29",
"native-tls",
"tokio",
"tokio-native-tls",
@@ -3683,9 +3662,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "open"
version = "5.1.3"
version = "5.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eb49fbd5616580e9974662cb96a3463da4476e649a7e4b258df0de065db0657"
checksum = "b5ca541f22b1c46d4bb9801014f234758ab4297e7870b904b6a8415b980a7388"
dependencies = [
"is-wsl",
"libc",
@@ -3726,9 +3705,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-src"
version = "300.3.0+3.3.0"
version = "300.3.1+3.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eba8804a1c5765b18c4b3f907e6897ebabeedebc9830e1a0046c4a4cf44663e1"
checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91"
dependencies = [
"cc",
]
@@ -4066,9 +4045,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "piper"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "464db0c665917b13ebb5d453ccdec4add5658ee1adc7affc7677615356a8afaf"
checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391"
dependencies = [
"atomic-waker",
"fastrand",
@@ -4131,9 +4110,9 @@ dependencies = [
[[package]]
name = "polling"
version = "3.7.0"
version = "3.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "645493cf344456ef24219d02a768cf1fb92ddf8c92161679ae3d91b91a637be3"
checksum = "5e6a007746f34ed64099e88783b0ae369eaa3da6392868ba262e2af9b8fbaea1"
dependencies = [
"cfg-if",
"concurrent-queue",
@@ -4226,9 +4205,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]]
name = "proc-macro2"
version = "1.0.84"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6"
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
dependencies = [
"unicode-ident",
]
@@ -4588,7 +4567,7 @@ dependencies = [
"h2",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.28",
"hyper 0.14.29",
"hyper-tls",
"ipnet",
"js-sys",
@@ -5973,7 +5952,8 @@ dependencies = [
[[package]]
name = "tauri-plugin-clipboard-manager"
version = "2.1.0-beta.4"
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v2#0f739dbc483a1f091977cbe575c3862fd39f8cf1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76fceedc022b7590245c5bd0ba0ef5909e44480d84b72fb498b76ba8bc0da7db"
dependencies = [
"arboard",
"image 0.24.9",
@@ -5988,7 +5968,8 @@ dependencies = [
[[package]]
name = "tauri-plugin-deep-link"
version = "2.0.0-beta.7"
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v2#0f739dbc483a1f091977cbe575c3862fd39f8cf1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bfc538a38845f08c7a63acd9e03737b5e89c815273ed8e2a447780a4e2583f4"
dependencies = [
"dunce",
"log",
@@ -6007,7 +5988,8 @@ dependencies = [
[[package]]
name = "tauri-plugin-dialog"
version = "2.0.0-beta.9"
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v2#0f739dbc483a1f091977cbe575c3862fd39f8cf1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed4b22c59f7b04ae2a0bed8241aa715b41973c3f042c84aa67a1f4dc0174a8d"
dependencies = [
"dunce",
"log",
@@ -6024,7 +6006,8 @@ dependencies = [
[[package]]
name = "tauri-plugin-fs"
version = "2.0.0-beta.9"
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v2#0f739dbc483a1f091977cbe575c3862fd39f8cf1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3aa91955751f329e0aa431b87c199b7378b6f91ec0765d2ad9d4c64e017c3cda"
dependencies = [
"anyhow",
"glob",
@@ -6042,7 +6025,8 @@ dependencies = [
[[package]]
name = "tauri-plugin-log"
version = "2.0.0-beta.6"
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v2#0f739dbc483a1f091977cbe575c3862fd39f8cf1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28be50bb36ac6b5181a360cee0606a4364d9e0bdcdd8974c40710d7af12e60ec"
dependencies = [
"android_logger",
"byte-unit",
@@ -6062,7 +6046,8 @@ dependencies = [
[[package]]
name = "tauri-plugin-os"
version = "2.0.0-beta.6"
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v2#0f739dbc483a1f091977cbe575c3862fd39f8cf1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ae3c8aeb113ce614cc36a43b1061fdf64381f7635d02c390052ce7579ec628"
dependencies = [
"gethostname",
"log",
@@ -6079,7 +6064,8 @@ dependencies = [
[[package]]
name = "tauri-plugin-shell"
version = "2.0.0-beta.7"
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v2#0f739dbc483a1f091977cbe575c3862fd39f8cf1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8675bf7ab71f571a99192d0685ae870eb7af1264bdbbb66a1d655609f6c7ebd"
dependencies = [
"encoding_rs",
"log",
@@ -6099,7 +6085,8 @@ dependencies = [
[[package]]
name = "tauri-plugin-updater"
version = "2.0.0-beta.7"
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v2#0f739dbc483a1f091977cbe575c3862fd39f8cf1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b0bec1fe304e1ff350b5e7be5048047f9bdec19dcc224ba266e9f2a692b8e"
dependencies = [
"base64 0.22.1",
"dirs-next",
@@ -6127,7 +6114,8 @@ dependencies = [
[[package]]
name = "tauri-plugin-window-state"
version = "2.0.0-beta.9"
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v2#0f739dbc483a1f091977cbe575c3862fd39f8cf1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74b5596f41b90668ea37562d512e1dead687d9ae5eadb49f9faa8b875a2740a3"
dependencies = [
"bitflags 2.5.0",
"log",
@@ -6537,7 +6525,7 @@ dependencies = [
"h2",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.28",
"hyper 0.14.29",
"hyper-timeout",
"percent-encoding",
"pin-project",
@@ -6791,9 +6779,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]]
name = "unicode-width"
version = "0.1.12"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]]
name = "unicode_categories"
@@ -7557,9 +7545,9 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
[[package]]
name = "wry"
version = "0.40.0"
version = "0.40.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cd42682bad8d1efd0e0d0593770c602c13b8922bb1ca705cb845967de81bbc4"
checksum = "1fa597526af53f310a8e6218630c5024fdde8271f229e70d7d2fc70b52b8fb1e"
dependencies = [
"base64 0.22.1",
"block",
@@ -7702,7 +7690,6 @@ dependencies = [
"tokio",
"tokio-stream",
"uuid",
"windows 0.56.0",
]
[[package]]

View File

@@ -8,7 +8,7 @@ edition = "2021"
# Produce a library for mobile support
[lib]
name = "tauri_app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
crate-type = ["staticlib", "cdylib", "lib"]
[profile.release]
strip = true # Automatically strip symbols from the binary.
@@ -20,13 +20,6 @@ tauri-build = { version = "2.0.0-beta", features = [] }
objc = "0.2.7"
cocoa = "0.25.0"
[target.'cfg(target_os = "windows")'.dependencies]
windows = { version = "0.56.0", features = [
"Win32_Graphics_Dwm",
"Win32_Foundation",
"Win32_UI_Controls",
] }
[target.'cfg(target_os = "linux")'.dependencies]
openssl-sys = { version = "0.9", features = ["vendored"] } # For Ubuntu installation to work
@@ -41,16 +34,16 @@ reqwest = { version = "0.11.23", features = ["multipart", "cookies", "gzip", "br
serde = { version = "1.0.198", features = ["derive"] }
serde_json = { version = "1.0.116", features = ["raw_value"] }
sqlx = { version = "0.7.4", features = ["sqlite", "runtime-tokio-rustls", "json", "chrono", "time"] }
tauri = { version = "2.0.0-beta.22", features = ["config-toml", "devtools", "protocol-asset"] }
tauri-plugin-clipboard-manager = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
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 = "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" }
tauri-plugin-deep-link = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri = { version = "2.0.0-beta", features = ["config-toml", "devtools", "protocol-asset"] }
tauri-plugin-clipboard-manager = "2.1.0-beta"
tauri-plugin-dialog = "2.0.0-beta"
tauri-plugin-log = { version = "2.0.0-beta", features = ["colored"] }
tauri-plugin-shell = "2.0.0-beta"
tauri-plugin-os = "2.0.0-beta"
tauri-plugin-updater = "2.0.0-beta"
tauri-plugin-window-state = "2.0.0-beta"
tauri-plugin-fs = "2.0.0-beta"
tauri-plugin-deep-link = "2.0.0-beta"
tokio = { version = "1.36.0", features = ["sync"] }
uuid = "1.7.0"
log = "0.4.21"

View File

@@ -18,5 +18,5 @@ anyhow = "1.0.79"
hyper = { version = "0.14" }
hyper-rustls = { version = "0.24.0", features = ["http2"] }
uuid = { version = "1.7.0", features = ["v4"] }
tauri = { version = "2.0.0-beta.16" }
tauri-plugin-shell = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri = { version = "2.0.0-beta" }
tauri-plugin-shell = "2.0.0-beta"

View File

@@ -131,6 +131,7 @@ function j(e) {
form: b(t.formdata).map(
(n) => n.src != null ? {
enabled: !n.disabled,
contentType: n.contentType ?? null,
name: n.key ?? "",
file: n.src ?? ""
} : {

View File

@@ -1,6 +1,6 @@
use std::fmt::Display;
use log::{debug, warn};
use log::{debug, info, warn};
use serde::{Deserialize, Serialize};
use serde_json::json;
use sqlx::types::JsonValue;
@@ -194,10 +194,7 @@ pub async fn track_event(
}
if let Err(e) = req.send().await {
warn!(
"Error sending analytics event: {} {} {} {:?}",
e, event, attributes_json, params,
);
info!("Error sending analytics event: {}", e);
}
}

View File

@@ -89,14 +89,24 @@ pub async fn send_http_request(
let uri = match http::Uri::from_str(url_string.as_str()) {
Ok(u) => u,
Err(e) => {
return response_err(response, e.to_string(), window).await;
return response_err(
response,
format!("Failed to parse URL \"{}\": {}", url_string, e.to_string()),
window,
)
.await;
}
};
// Yes, we're parsing both URI and URL because they could return different errors
let url = match Url::from_str(uri.to_string().as_str()) {
Ok(u) => u,
Err(e) => {
return response_err(response, e.to_string(), window).await;
return response_err(
response,
format!("Failed to parse URL \"{}\": {}", url_string, e.to_string()),
window,
)
.await;
}
};

View File

@@ -69,8 +69,6 @@ mod plugin;
mod render;
#[cfg(target_os = "macos")]
mod tauri_plugin_mac_window;
#[cfg(target_os = "windows")]
mod tauri_plugin_windows_window;
mod updates;
mod window_menu;
@@ -752,16 +750,16 @@ async fn cmd_import_data(
) -> Result<WorkspaceExportResources, String> {
let mut result: Option<ImportResult> = None;
let plugins = vec![
"importer-yaak",
"importer-insomnia",
"importer-postman",
"importer-insomnia",
"importer-yaak",
"importer-curl",
];
let file = fs::read_to_string(file_path)
let file = read_to_string(file_path)
.unwrap_or_else(|_| panic!("Unable to read file {}", file_path));
let file_contents = file.as_str();
for plugin_name in plugins {
let v = plugin::run_plugin_import(&w.app_handle(), plugin_name, file_contents)
let v = run_plugin_import(&w.app_handle(), plugin_name, file_contents)
.await
.map_err(|e| e.to_string())?;
if let Some(r) = v {
@@ -1493,6 +1491,8 @@ async fn cmd_list_workspaces(w: WebviewWindow) -> Result<Vec<Workspace>, String>
&w,
Workspace {
name: "Yaak".to_string(),
setting_follow_redirects: true,
setting_validate_certificates: true,
..Default::default()
},
)
@@ -1553,11 +1553,6 @@ pub fn run() {
.plugin(tauri_plugin_os::init())
.plugin(tauri_plugin_fs::init());
#[cfg(target_os = "windows")]
{
builder = builder.plugin(tauri_plugin_windows_window::init());
}
#[cfg(target_os = "macos")]
{
builder = builder.plugin(tauri_plugin_mac_window::init());

View File

@@ -1,97 +0,0 @@
use hex_color::HexColor;
use tauri::{Manager, Runtime, Window, WindowEvent};
use std::mem::transmute;
use std::{ffi::c_void, mem::size_of, ptr};
use tauri::plugin::{Builder, TauriPlugin};
use windows::Win32::UI::Controls::{
WTA_NONCLIENT, WTNCA_NODRAWICON, WTNCA_NOMIRRORHELP, WTNCA_NOSYSMENU,
};
use windows::Win32::Foundation::COLORREF;
use windows::Win32::Foundation::{BOOL, HWND};
use windows::Win32::Graphics::Dwm::DwmSetWindowAttribute;
use windows::Win32::Graphics::Dwm::DWMWA_CAPTION_COLOR;
use windows::Win32::Graphics::Dwm::DWMWA_USE_IMMERSIVE_DARK_MODE;
use windows::Win32::UI::Controls::SetWindowThemeAttribute;
use windows::Win32::UI::Controls::WTNCA_NODRAWCAPTION;
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("windows_window")
.on_window_ready(|window| {
#[cfg(target_os = "windows")]
setup_win_window(window);
return;
})
.build()
}
fn hex_color_to_colorref(color: HexColor) -> COLORREF {
// TODO: Remove this unsafe, This operation doesn't need to be unsafe!
unsafe { COLORREF(transmute::<[u8; 4], u32>([color.r, color.g, color.b, 0])) }
}
struct WinThemeAttribute {
#[allow(dead_code)]
flag: u32,
#[allow(dead_code)]
mask: u32,
}
#[cfg(target_os = "windows")]
fn update_bg_color(hwnd: &HWND, bg_color: HexColor) {
let use_dark_mode = BOOL::from(true);
let final_color = hex_color_to_colorref(bg_color);
unsafe {
DwmSetWindowAttribute(
HWND(hwnd.0),
DWMWA_USE_IMMERSIVE_DARK_MODE,
ptr::addr_of!(use_dark_mode) as *const c_void,
size_of::<BOOL>().try_into().unwrap(),
)
.unwrap();
DwmSetWindowAttribute(
HWND(hwnd.0),
DWMWA_CAPTION_COLOR,
ptr::addr_of!(final_color) as *const c_void,
size_of::<COLORREF>().try_into().unwrap(),
)
.unwrap();
let flags = WTNCA_NODRAWCAPTION | WTNCA_NODRAWICON;
let mask = WTNCA_NODRAWCAPTION | WTNCA_NODRAWICON | WTNCA_NOSYSMENU | WTNCA_NOMIRRORHELP;
let options = WinThemeAttribute { flag: flags, mask };
SetWindowThemeAttribute(
HWND(hwnd.0),
WTA_NONCLIENT,
ptr::addr_of!(options) as *const c_void,
size_of::<WinThemeAttribute>().try_into().unwrap(),
)
.unwrap();
}
}
#[cfg(target_os = "windows")]
pub fn setup_win_window<R: Runtime>(window: Window<R>) {
let win_handle = window.hwnd().unwrap();
let win_clone = win_handle.clone();
let event_id = window.listen("yaak_bg_changed", move |ev| {
let payload = serde_json::from_str::<&str>(ev.payload()).unwrap().trim();
let color = HexColor::parse_rgb(payload).unwrap();
update_bg_color(&HWND(win_clone.0), color);
});
let h = window.app_handle().clone();
window.on_window_event(move |e| match e {
WindowEvent::Destroyed => {
h.unlisten(event_id);
}
_ => {}
})
}

View File

@@ -1,13 +1,13 @@
{
"productName": "yaak",
"version": "2024.5.2",
"identifier": "app.yaak.desktop",
"build": {
"beforeBuildCommand": "npm run build",
"beforeDevCommand": "npm run dev",
"devUrl": "http://localhost:1420",
"frontendDist": "../dist"
},
"productName": "Yaak",
"version": "2024.5.0-beta.1",
"identifier": "app.yaak.desktop",
"app": {
"withGlobalTauri": false,
"security": {

View File

@@ -281,7 +281,7 @@ function SidebarButton({
},
},
{
key: 'delete',
key: 'delete-environment',
variant: 'danger',
label: 'Delete',
leftSlot: <Icon icon="trash" size="sm" />,

View File

@@ -30,6 +30,8 @@ export function FormUrlencodedEditor({ body, forceUpdateKey, onChange }: Props)
<PairEditor
valueAutocompleteVariables
nameAutocompleteVariables
namePlaceholder="entry_name"
valuePlaceholder="Value"
pairs={pairs}
onChange={handleChange}
forceUpdateKey={forceUpdateKey}

View File

@@ -4,6 +4,7 @@ import { useEffect } from 'react';
import { useClipboardText } from '../hooks/useClipboardText';
import { useCommandPalette } from '../hooks/useCommandPalette';
import { cookieJarsQueryKey } from '../hooks/useCookieJars';
import { environmentsQueryKey } from '../hooks/useEnvironments';
import { foldersQueryKey } from '../hooks/useFolders';
import { useGlobalCommands } from '../hooks/useGlobalCommands';
import { grpcConnectionsQueryKey } from '../hooks/useGrpcConnections';
@@ -62,6 +63,8 @@ export function GlobalHooks() {
? httpResponsesQueryKey(model)
: model.model === 'folder'
? foldersQueryKey(model)
: model.model === 'environment'
? environmentsQueryKey(model)
: model.model === 'grpc_connection'
? grpcConnectionsQueryKey(model)
: model.model === 'grpc_event'
@@ -96,10 +99,8 @@ export function GlobalHooks() {
queryClient.setQueryData<Model[]>(queryKey, (values = []) => {
const index = values.findIndex((v) => modelsEq(v, model)) ?? -1;
if (index >= 0) {
// console.log('UPDATED', payload);
return [...values.slice(0, index), model, ...values.slice(index + 1)];
} else {
// console.log('CREATED', payload);
return pushToFront ? [model, ...(values ?? [])] : [...(values ?? []), model];
}
});
@@ -117,6 +118,8 @@ export function GlobalHooks() {
queryClient.setQueryData(httpResponsesQueryKey(model), removeById(model));
} else if (model.model === 'folder') {
queryClient.setQueryData(foldersQueryKey(model), removeById(model));
} else if (model.model === 'environment') {
queryClient.setQueryData(environmentsQueryKey(model), removeById(model));
} else if (model.model === 'grpc_request') {
queryClient.setQueryData(grpcRequestsQueryKey(model), removeById(model));
} else if (model.model === 'grpc_connection') {

View File

@@ -1,6 +1,7 @@
import type { ReactNode } from 'react';
import { createPortal } from 'react-dom';
import { usePortal } from '../hooks/usePortal';
interface Props {
children: ReactNode;
name: string;

View File

@@ -109,11 +109,14 @@ export const RequestPane = memo(function RequestPane({
if (bodyType === BODY_TYPE_NONE) {
newContentType = null;
} else if (
bodyType === BODY_TYPE_FORM_URLENCODED ||
bodyType === BODY_TYPE_FORM_MULTIPART ||
bodyType === BODY_TYPE_JSON ||
bodyType === BODY_TYPE_OTHER ||
bodyType === BODY_TYPE_XML
activeRequest.method.toLowerCase() !== 'put' &&
activeRequest.method.toLowerCase() !== 'patch' &&
activeRequest.method.toLowerCase() !== 'post' &&
(bodyType === BODY_TYPE_FORM_URLENCODED ||
bodyType === BODY_TYPE_FORM_MULTIPART ||
bodyType === BODY_TYPE_JSON ||
bodyType === BODY_TYPE_OTHER ||
bodyType === BODY_TYPE_XML)
) {
patch.method = 'POST';
newContentType = bodyType === BODY_TYPE_OTHER ? 'text/plain' : bodyType;
@@ -181,6 +184,7 @@ export const RequestPane = memo(function RequestPane({
activeRequest.authenticationType,
activeRequest.bodyType,
activeRequest.headers,
activeRequest.method,
activeRequest.urlParameters,
handleContentTypeChange,
updateRequest,

View File

@@ -14,7 +14,7 @@ import { Editor } from '../core/Editor';
import type { IconProps } from '../core/Icon';
import { Icon } from '../core/Icon';
import { IconButton } from '../core/IconButton';
import type { SelectOption } from '../core/Select';
import type { SelectProps } from '../core/Select';
import { Select } from '../core/Select';
import { Separator } from '../core/Separator';
import { HStack, VStack } from '../core/Stacks';
@@ -64,14 +64,14 @@ export function SettingsAppearance() {
return null;
}
const lightThemes: SelectOption<string>[] = themes
const lightThemes: SelectProps<string>['options'] = themes
.filter((theme) => !isThemeDark(theme))
.map((theme) => ({
label: theme.name,
value: theme.id,
}));
const darkThemes: SelectOption<string>[] = themes
const darkThemes: SelectProps<string>['options'] = themes
.filter((theme) => isThemeDark(theme))
.map((theme) => ({
label: theme.name,
@@ -109,7 +109,7 @@ export function SettingsAppearance() {
<Select
name="appearance"
label="Appearance"
labelPosition="left"
labelPosition="top"
size="sm"
value={settings.appearance}
onChange={(appearance) => {
@@ -123,7 +123,6 @@ export function SettingsAppearance() {
]}
/>
<HStack space={2}>
<div>Theme</div>
{(settings.appearance === 'system' || settings.appearance === 'light') && (
<Select
hideLabel
@@ -131,8 +130,9 @@ export function SettingsAppearance() {
name="lightTheme"
label="Light Theme"
size="sm"
className="flex-1"
value={activeTheme.light.id}
options={[{ label: 'Light Mode Themes', options: lightThemes }]}
options={lightThemes}
onChange={(themeLight) => {
trackEvent('theme', 'update', { theme: themeLight, appearance: 'light' });
updateSettings.mutateAsync({ ...settings, themeLight });
@@ -143,11 +143,12 @@ export function SettingsAppearance() {
<Select
hideLabel
name="darkTheme"
className="flex-1"
label="Dark Theme"
leftSlot={<Icon icon="moon" />}
size="sm"
value={activeTheme.dark.id}
options={[{ label: 'Dark Mode Themes', options: darkThemes }]}
options={darkThemes}
onChange={(themeDark) => {
trackEvent('theme', 'update', { theme: themeDark, appearance: 'dark' });
updateSettings.mutateAsync({ ...settings, themeDark });

View File

@@ -8,8 +8,8 @@ import { useUpdateWorkspace } from '../../hooks/useUpdateWorkspace';
import { Checkbox } from '../core/Checkbox';
import { Heading } from '../core/Heading';
import { IconButton } from '../core/IconButton';
import { Input } from '../core/Input';
import { KeyValueRow, KeyValueRows } from '../core/KeyValueRow';
import { PlainInput } from '../core/PlainInput';
import { Select } from '../core/Select';
import { Separator } from '../core/Separator';
import { VStack } from '../core/Stacks';
@@ -59,7 +59,7 @@ export function SettingsGeneral() {
</div>
</Heading>
<VStack className="mt-1 w-full" space={3}>
<Input
<PlainInput
size="sm"
name="requestTimeout"
label="Request Timeout (ms)"
@@ -68,6 +68,7 @@ export function SettingsGeneral() {
defaultValue={`${workspace.settingRequestTimeout}`}
validate={(value) => parseInt(value) >= 0}
onChange={(v) => updateWorkspace.mutate({ settingRequestTimeout: parseInt(v) || 0 })}
type="number"
/>
<Checkbox

View File

@@ -12,6 +12,8 @@ export function UrlParametersEditor({ urlParameters, forceUpdateKey, onChange }:
<PairEditor
valueAutocompleteVariables
nameAutocompleteVariables
namePlaceholder="param_name"
valuePlaceholder="Value"
pairs={urlParameters}
onChange={onChange}
forceUpdateKey={forceUpdateKey}

View File

@@ -120,7 +120,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button
{isLoading ? (
<Icon icon="refresh" size={size} className="animate-spin mr-1" />
) : leftSlot ? (
<div className="mr-1">{leftSlot}</div>
<div className="mr-2">{leftSlot}</div>
) : null}
<div
className={classNames(

View File

@@ -59,6 +59,7 @@ export interface DropdownProps {
items: DropdownItem[];
onOpen?: () => void;
onClose?: () => void;
fullWidth?: boolean;
hotKeyAction?: HotkeyAction;
}
@@ -73,7 +74,7 @@ export interface DropdownRef {
}
export const Dropdown = forwardRef<DropdownRef, DropdownProps>(function Dropdown(
{ children, items, onOpen, onClose, hotKeyAction }: DropdownProps,
{ children, items, onOpen, onClose, hotKeyAction, fullWidth }: DropdownProps,
ref,
) {
const [isOpen, _setIsOpen] = useState<boolean>(false);
@@ -153,6 +154,7 @@ export const Dropdown = forwardRef<DropdownRef, DropdownProps>(function Dropdown
<Menu
ref={menuRef}
showTriangle
fullWidth={fullWidth}
defaultSelectedIndex={defaultSelectedIndex}
items={items}
triggerShape={triggerRect ?? null}
@@ -203,6 +205,7 @@ interface MenuProps {
triggerShape: Pick<DOMRect, 'top' | 'bottom' | 'left' | 'right'> | null;
onClose: () => void;
showTriangle?: boolean;
fullWidth?: boolean;
isOpen: boolean;
}
@@ -211,6 +214,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
className,
isOpen,
items,
fullWidth,
onClose,
triggerShape,
defaultSelectedIndex,
@@ -359,21 +363,23 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
const heightAbove = triggerShape.top;
const heightBelow = docRect.height - triggerShape.bottom;
const hSpaceRemaining = docRect.width - triggerShape.left;
const top = triggerShape?.bottom + 5;
const top = triggerShape.bottom + 5;
const onRight = hSpaceRemaining < 200;
const upsideDown = heightAbove > heightBelow && heightBelow < 200;
const triggerWidth = triggerShape.right - triggerShape.left;
const containerStyles = {
top: !upsideDown ? top : undefined,
bottom: upsideDown ? docRect.height - top : undefined,
right: onRight ? docRect.width - triggerShape?.right : undefined,
left: !onRight ? triggerShape?.left : undefined,
right: onRight ? docRect.width - triggerShape.right : undefined,
left: !onRight ? triggerShape.left : undefined,
minWidth: fullWidth ? triggerWidth : undefined,
};
const size = { top: '-0.2rem', width: '0.4rem', height: '0.4rem' };
const triangleStyles = onRight
? { right: width / 2, marginRight: '-0.2rem', ...size }
: { left: width / 2, marginLeft: '-0.2rem', ...size };
return { containerStyles, triangleStyles };
}, [triggerShape]);
}, [fullWidth, triggerShape]);
const filteredItems = useMemo(
() => items.filter((i) => getNodeText(i.label).toLowerCase().includes(filter.toLowerCase())),
@@ -521,9 +527,7 @@ function MenuItem({ className, focused, onFocus, item, onSelect, ...props }: Men
onClick={handleClick}
justify="start"
leftSlot={
item.leftSlot && (
<div className="pr-2 flex justify-start text-fg-subtle">{item.leftSlot}</div>
)
item.leftSlot && <div className="pr-2 flex justify-start opacity-70">{item.leftSlot}</div>
}
rightSlot={rightSlot && <div className="ml-auto pl-3">{rightSlot}</div>}
innerClassName="!text-left"

View File

@@ -266,7 +266,7 @@
}
&.cm-completionInfo-right {
@apply ml-1 -mt-0.5;
@apply ml-1 -mt-0.5 font-sans;
}
&.cm-completionInfo-right-narrow {
@@ -278,7 +278,7 @@
}
&.cm-tooltip-autocomplete {
@apply font-mono text-editor;
@apply font-mono;
& > ul {
@apply p-1 max-h-[40vh];

View File

@@ -195,7 +195,7 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
placeholderCompartment.current.of(
placeholderExt(placeholderElFromText(placeholder ?? '')),
),
wrapLinesCompartment.current.of([]),
wrapLinesCompartment.current.of(wrapLines ? [EditorView.lineWrapping] : []),
...getExtensions({
container,
readOnly,
@@ -331,7 +331,25 @@ function getExtensions({
undefined;
return [
// NOTE: These *must* be anonymous functions so the references update properly
...baseExtensions, // Must be first
tooltips({ parent }),
keymap.of(singleLine ? defaultKeymap.filter((k) => k.key !== 'Enter') : defaultKeymap),
...(singleLine ? [singleLineExt()] : []),
...(!singleLine ? [multiLineExtensions] : []),
...(readOnly
? [EditorState.readOnly.of(true), EditorView.contentAttributes.of({ tabindex: '-1' })]
: []),
// ------------------------ //
// Things that must be last //
// ------------------------ //
EditorView.updateListener.of((update) => {
if (onChange && update.docChanged) {
onChange.current?.(update.state.doc.toString());
}
}),
EditorView.domEventHandlers({
focus: () => {
onFocus.current?.();
@@ -346,22 +364,6 @@ function getExtensions({
onPaste.current?.(e.clipboardData?.getData('text/plain') ?? '');
},
}),
tooltips({ parent }),
keymap.of(singleLine ? defaultKeymap.filter((k) => k.key !== 'Enter') : defaultKeymap),
...(singleLine ? [singleLineExt()] : []),
...(!singleLine ? [multiLineExtensions] : []),
...(readOnly
? [EditorState.readOnly.of(true), EditorView.contentAttributes.of({ tabindex: '-1' })]
: []),
// Handle onChange
EditorView.updateListener.of((update) => {
if (onChange && update.docChanged) {
onChange.current?.(update.state.doc.toString());
}
}),
...baseExtensions,
];
}

View File

@@ -39,7 +39,7 @@ import { text } from './text/extension';
import { twig } from './twig/extension';
import { url } from './url/extension';
export const myHighlightStyle = HighlightStyle.define([
export const syntaxHighlightStyle = HighlightStyle.define([
{
tag: [t.documentMeta, t.blockComment, t.lineComment, t.docComment, t.comment],
color: 'var(--fg-subtler)',
@@ -61,7 +61,7 @@ export const myHighlightStyle = HighlightStyle.define([
{ tag: [t.atom, t.meta, t.operator, t.bool, t.null, t.keyword], color: 'var(--fg-danger)' },
]);
const myTheme = EditorView.theme({}, { dark: true });
const syntaxTheme = EditorView.theme({}, { dark: true });
const syntaxExtensions: Record<string, LanguageSupport> = {
'application/graphql': graphqlLanguageSupport(),
@@ -108,8 +108,8 @@ export const baseExtensions = [
return (a.boost ?? 0) - (b.boost ?? 0);
},
}),
syntaxHighlighting(myHighlightStyle),
myTheme,
syntaxHighlighting(syntaxHighlightStyle),
syntaxTheme,
EditorState.allowMultipleSelections.of(true),
];

View File

@@ -20,7 +20,11 @@ export interface GenericCompletionConfig {
/**
* Complete options, always matching until the start of the line
*/
export function genericCompletion({ options, minMatch = 1 }: GenericCompletionConfig) {
export function genericCompletion(config?: GenericCompletionConfig) {
if (config == null) return [];
const { minMatch = 1, options } = config;
return function completions(context: CompletionContext) {
const toMatch = context.matchBefore(/.*/);

View File

@@ -1,13 +1,13 @@
import type { LanguageSupport } from '@codemirror/language';
import { LRLanguage } from '@codemirror/language';
import { parseMixed } from '@lezer/common';
import type { Environment, Workspace } from '../../../../lib/models';
import type { GenericCompletionConfig } from '../genericCompletion';
import { genericCompletion } from '../genericCompletion';
import { placeholders } from './placeholder';
import { textLanguageName } from '../text/extension';
import { twigCompletion } from './completion';
import { placeholders } from './placeholder';
import { parser as twigParser } from './twig';
import type { Environment, Workspace } from '../../../../lib/models';
export function twig(
base: LanguageSupport,
@@ -15,25 +15,19 @@ export function twig(
workspace: Workspace | null,
autocomplete?: GenericCompletionConfig,
) {
const variables =
[...(workspace?.variables ?? []), ...(environment?.variables ?? [])].filter((v) => v.enabled) ??
[];
const completions = twigCompletion({ options: variables });
const language = mixLanguage(base);
const completion = language.data.of({ autocomplete: completions });
const completionBase = base.language.data.of({ autocomplete: completions });
const additionalCompletion = autocomplete
? [base.language.data.of({ autocomplete: genericCompletion(autocomplete) })]
: [];
const allVariables = [...(workspace?.variables ?? []), ...(environment?.variables ?? [])];
const variables = allVariables.filter((v) => v.enabled) ?? [];
const completions = twigCompletion({ options: variables });
return [
language,
completion,
completionBase,
base.support,
placeholders(variables),
...additionalCompletion,
language.data.of({ autocomplete: completions }),
base.language.data.of({ autocomplete: completions }),
language.data.of({ autocomplete: genericCompletion(autocomplete) }),
base.language.data.of({ autocomplete: genericCompletion(autocomplete) }),
];
}

View File

@@ -9,7 +9,7 @@ export function FormattedError({ children }: Props) {
return (
<pre
className={classNames(
'w-full select-auto cursor-text bg-gray-100 p-3 rounded',
'w-full select-auto cursor-text bg-background-highlight-secondary p-3 rounded',
'whitespace-pre-wrap border border-fg-danger border-dashed overflow-x-auto',
)}
>

View File

@@ -133,7 +133,11 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
>
<label
htmlFor={id}
className={classNames(labelClassName, 'text-fg whitespace-nowrap', hideLabel && 'sr-only')}
className={classNames(
labelClassName,
'text-fg-subtle whitespace-nowrap',
hideLabel && 'sr-only',
)}
>
{label}
</label>

View File

@@ -389,7 +389,7 @@ function PairEditorRow({
<Button
size="xs"
color="secondary"
className="font-mono text-sm"
className="font-mono text-2xs rtl"
onClick={async (e) => {
e.preventDefault();
const selected = await open({
@@ -403,7 +403,9 @@ function PairEditorRow({
handleChangeValueFile(selected.path);
}}
>
{getFileName(pairContainer.pair.value) || 'Select File'}
{/* Special character to insert ltr text in rtl element without making things wonky */}
&#x200E;
{pairContainer.pair.value || 'Select File'}
</Button>
) : (
<Input
@@ -494,9 +496,3 @@ const newPairContainer = (initialPair?: Pair): PairContainer => {
const pair = initialPair ?? { name: '', value: '', enabled: true, isFile: false };
return { id, pair };
};
const getFileName = (path: string | null | undefined): string => {
if (typeof path !== 'string') return '';
const parts = path.split(/[\\/]/);
return parts[parts.length - 1] ?? '';
};

View File

@@ -85,7 +85,11 @@ export const PlainInput = forwardRef<HTMLInputElement, PlainInputProps>(function
>
<label
htmlFor={id}
className={classNames(labelClassName, 'text-fg whitespace-nowrap', hideLabel && 'sr-only')}
className={classNames(
labelClassName,
'text-fg-subtle whitespace-nowrap',
hideLabel && 'sr-only',
)}
>
{label}
</label>

View File

@@ -50,5 +50,9 @@ export function RadioDropdown<T = string | null>({
[items, extraItems, value, onChange],
);
return <Dropdown items={dropdownItems}>{children}</Dropdown>;
return (
<Dropdown fullWidth items={dropdownItems}>
{children}
</Dropdown>
);
}

View File

@@ -1,9 +1,14 @@
import classNames from 'classnames';
import type { CSSProperties, ReactNode } from 'react';
import { useState } from 'react';
import { useOsInfo } from '../../hooks/useOsInfo';
import type { ButtonProps } from './Button';
import { Button } from './Button';
import type { RadioDropdownItem } from './RadioDropdown';
import { RadioDropdown } from './RadioDropdown';
import { HStack } from './Stacks';
interface Props<T extends string> {
export interface SelectProps<T extends string> {
name: string;
label: string;
labelPosition?: 'top' | 'left';
@@ -11,22 +16,12 @@ interface Props<T extends string> {
hideLabel?: boolean;
value: T;
leftSlot?: ReactNode;
options: SelectOption<T>[] | SelectOptionGroup<T>[];
options: RadioDropdownItem<T>[];
onChange: (value: T) => void;
size?: 'xs' | 'sm' | 'md' | 'lg';
size?: ButtonProps['size'];
className?: string;
}
export interface SelectOption<T extends string> {
label: string;
value: T;
}
export interface SelectOptionGroup<T extends string> {
label: string;
options: SelectOption<T>[];
}
export function Select<T extends string>({
labelPosition = 'top',
name,
@@ -39,7 +34,8 @@ export function Select<T extends string>({
onChange,
className,
size = 'md',
}: Props<T>) {
}: SelectProps<T>) {
const osInfo = useOsInfo();
const [focused, setFocused] = useState<boolean>(false);
const id = `input-${name}`;
return (
@@ -49,55 +45,68 @@ export function Select<T extends string>({
'x-theme-input',
'w-full',
'pointer-events-auto', // Just in case we're placing in disabled parent
labelPosition === 'left' && 'flex items-center gap-2',
labelPosition === 'left' && 'grid grid-cols-[auto_1fr] items-center gap-2',
labelPosition === 'top' && 'flex-row gap-0.5',
)}
>
<label
htmlFor={id}
className={classNames(labelClassName, 'text-fg whitespace-nowrap', hideLabel && 'sr-only')}
className={classNames(
labelClassName,
'text-fg-subtle whitespace-nowrap',
hideLabel && 'sr-only',
)}
>
{label}
</label>
<HStack
space={2}
className={classNames(
'w-full rounded-md text-fg text-sm font-mono',
'pl-2',
'border',
focused ? 'border-border-focus' : 'border-background-highlight',
size === 'xs' && 'h-xs',
size === 'sm' && 'h-sm',
size === 'md' && 'h-md',
size === 'lg' && 'h-lg',
)}
>
{leftSlot && <div>{leftSlot}</div>}
<select
value={value}
style={selectBackgroundStyles}
onChange={(e) => onChange(e.target.value as T)}
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
className={classNames('pr-7 w-full outline-none bg-transparent')}
>
{options.map((o) =>
'options' in o ? (
<optgroup key={o.label} label={o.label}>
{o.options.map(({ label, value }) => (
<option key={label} value={value}>
{label}
</option>
))}
</optgroup>
) : (
<option key={o.label} value={o.value}>
{o.label}
</option>
),
{osInfo?.osType === 'macos' ? (
<HStack
space={2}
className={classNames(
'w-full rounded-md text-fg text-sm font-mono',
'pl-2',
'border',
focused ? 'border-border-focus' : 'border-background-highlight',
size === 'xs' && 'h-xs',
size === 'sm' && 'h-sm',
size === 'md' && 'h-md',
)}
</select>
</HStack>
>
{leftSlot && <div>{leftSlot}</div>}
<select
value={value}
style={selectBackgroundStyles}
onChange={(e) => onChange(e.target.value as T)}
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
className={classNames('pr-7 w-full outline-none bg-transparent')}
>
{options.map((o) => {
if (o.type === 'separator') return null;
return (
<option key={o.label} value={o.value}>
{o.label}
</option>
);
})}
</select>
</HStack>
) : (
// Use custom "select" component until Tauri can be configured to have select menus not always appear in
// light mode
<RadioDropdown value={value} onChange={onChange} items={options}>
<Button
className="w-full text-sm font-mono"
justify="start"
variant="border"
size={size}
leftSlot={leftSlot}
forDropdown
>
{options.find((o) => o.type !== 'separator' && o.value === value)?.label ?? '--'}
</Button>
</RadioDropdown>
)}
</div>
);
}

View File

@@ -1,11 +1,11 @@
import classNames from 'classnames';
import type { ReactNode } from 'react';
import { useCallback, useMemo } from 'react';
import { createGlobalState } from 'react-use';
import { useContentTypeFromHeaders } from '../../hooks/useContentTypeFromHeaders';
import { useDebouncedState } from '../../hooks/useDebouncedState';
import { useDebouncedValue } from '../../hooks/useDebouncedValue';
import { useFilterResponse } from '../../hooks/useFilterResponse';
import { useResponseBodyText } from '../../hooks/useResponseBodyText';
import { useToggle } from '../../hooks/useToggle';
import { tryFormatJson, tryFormatXml } from '../../lib/formatters';
import type { HttpResponse } from '../../lib/models';
import { Editor } from '../core/Editor';
@@ -21,25 +21,42 @@ interface Props {
className?: string;
}
const useFilterText = createGlobalState<Record<string, string | null>>({});
export function TextViewer({ response, pretty, className }: Props) {
const [isSearching, toggleIsSearching] = useToggle();
const [filterText, setDebouncedFilterText, setFilterText] = useDebouncedState<string>('', 400);
const [filterTextMap, setFilterTextMap] = useFilterText();
const filterText = filterTextMap[response.id] ?? null;
const debouncedFilterText = useDebouncedValue(filterText, 300);
const setFilterText = useCallback(
(v: string | null) => {
setFilterTextMap((m) => ({ ...m, [response.id]: v }));
},
[setFilterTextMap, response],
);
const contentType = useContentTypeFromHeaders(response.headers);
const rawBody = useResponseBodyText(response) ?? '';
const isSearching = filterText != null;
const formattedBody =
pretty && contentType?.includes('json')
? tryFormatJson(rawBody)
: pretty && contentType?.includes('xml')
? tryFormatXml(rawBody)
: rawBody;
const filteredResponse = useFilterResponse({ filter: filterText, responseId: response.id });
const body = filteredResponse ?? formattedBody;
const clearSearch = useCallback(() => {
toggleIsSearching();
setFilterText('');
}, [setFilterText, toggleIsSearching]);
const filteredResponse = useFilterResponse({
filter: debouncedFilterText ?? '',
responseId: response.id,
});
const body = isSearching && filterText?.length > 0 ? filteredResponse : formattedBody;
const toggleSearch = useCallback(() => {
if (isSearching) {
setFilterText(null);
} else {
setFilterText('');
}
}, [isSearching, setFilterText]);
const isJson = contentType?.includes('json');
const isXml = contentType?.includes('xml') || contentType?.includes('html');
@@ -54,16 +71,17 @@ export function TextViewer({ response, pretty, className }: Props) {
result.push(
<div key="input" className="w-full !opacity-100">
<Input
key={response.id}
hideLabel
autoFocus
containerClassName="bg-gray-100 dark:bg-gray-50"
containerClassName="bg-background"
size="sm"
placeholder={isJson ? 'JSONPath expression' : 'XPath expression'}
label="Filter expression"
name="filter"
defaultValue={filterText}
onKeyDown={(e) => e.key === 'Escape' && clearSearch()}
onChange={setDebouncedFilterText}
onKeyDown={(e) => e.key === 'Escape' && toggleSearch()}
onChange={setFilterText}
/>
</div>,
);
@@ -75,13 +93,16 @@ export function TextViewer({ response, pretty, className }: Props) {
size="sm"
icon={isSearching ? 'x' : 'filter'}
title={isSearching ? 'Close filter' : 'Filter response'}
onClick={clearSearch}
className={classNames(isSearching && '!opacity-100')}
onClick={toggleSearch}
className={classNames(
'bg-background border !border-background-highlight',
isSearching && '!opacity-100',
)}
/>,
);
return result;
}, [canFilter, clearSearch, filterText, isJson, isSearching, setDebouncedFilterText]);
}, [canFilter, filterText, isJson, isSearching, setFilterText, toggleSearch]);
return (
<Editor

View File

@@ -1,10 +1,12 @@
import { invoke } from '@tauri-apps/api/core';
import { useActiveEnvironmentId } from './useActiveEnvironmentId';
import { useClipboardText } from './useClipboardText';
export function useCopyAsCurl(requestId: string) {
const [, copy] = useClipboardText();
const environmentId = useActiveEnvironmentId();
return async () => {
const cmd: string = await invoke('cmd_request_to_curl', { requestId });
const cmd: string = await invoke('cmd_request_to_curl', { requestId, environmentId });
copy(cmd);
return cmd;
};

View File

@@ -18,6 +18,6 @@ export function useFilterResponse({
return (await invoke('cmd_filter_response', { responseId, filter })) as string | null;
},
}).data ?? null
}).data ?? ''
);
}

View File

@@ -1,26 +1,22 @@
import { useQuery } from '@tanstack/react-query';
import { getCurrent } from '@tauri-apps/api/webviewWindow';
import { useEffect, useState } from 'react';
import { useWindowSize } from 'react-use';
import { useDebouncedValue } from './useDebouncedValue';
export function useIsFullscreen() {
const [isFullscreen, setIsFullscreen] = useState<boolean>(false);
const windowSize = useWindowSize();
const debouncedWindowWidth = useDebouncedValue(windowSize.width);
useEffect(() => {
(async function () {
// Fullscreen state isn't updated right after resize event on Mac (needs to wait for animation) so
// we'll poll for 10 seconds to see if it changes. Hopefully Tauri eventually adds a way to listen
// for this.
for (let i = 0; i < 100; i++) {
await new Promise((resolve) => setTimeout(resolve, 100));
const newIsFullscreen = await getCurrent().isFullscreen();
if (newIsFullscreen !== isFullscreen) {
setIsFullscreen(newIsFullscreen);
break;
}
}
})();
}, [windowSize, isFullscreen]);
// NOTE: Fullscreen state isn't updated right after resize event on Mac (needs to wait for animation) so
// we'll wait for a bit using the debounced window size. Hopefully Tauri eventually adds a way to listen
// for fullscreen change events.
return isFullscreen;
return (
useQuery({
queryKey: ['is_fullscreen', debouncedWindowWidth],
queryFn: async () => {
return getCurrent().isFullscreen();
},
}).data ?? false
);
}

View File

@@ -40,12 +40,10 @@ export const colors = {
const moonlightDefault: YaakTheme = {
id: 'moonlight',
name: 'Moonlight',
background: new Color(colors.gray4, 'dark'),
backgroundHighlight: new Color(colors.gray5, 'dark'),
backgroundHighlightSecondary: new Color(colors.gray5, 'dark'),
foreground: new Color(colors.gray11, 'dark'),
foregroundSubtle: new Color(colors.gray7, 'dark'),
foregroundSubtler: new Color(colors.gray6, 'dark'),
background: new Color('#222436', 'dark'),
foreground: new Color('#d5def8', 'dark'),
foregroundSubtle: new Color('#828bb8', 'dark'),
foregroundSubtler: new Color('hsl(232,26%,43%)', 'dark'),
colors: {
primary: new Color(colors.purple, 'dark'),
secondary: new Color(colors.desaturatedGray, 'dark'),
@@ -58,13 +56,9 @@ const moonlightDefault: YaakTheme = {
components: {
appHeader: {
background: new Color(colors.gray3, 'dark'),
backgroundHighlight: new Color(colors.gray5, 'dark'),
backgroundHighlightSecondary: new Color(colors.gray4, 'dark'),
},
sidebar: {
background: new Color(colors.gray3, 'dark'),
backgroundHighlight: new Color(colors.gray5, 'dark'),
backgroundHighlightSecondary: new Color(colors.gray4, 'dark'),
},
},
};