diff --git a/.github/workflows/artifacts.yml b/.github/workflows/artifacts.yml new file mode 100644 index 00000000..faba92bd --- /dev/null +++ b/.github/workflows/artifacts.yml @@ -0,0 +1,54 @@ +# Copyright 2019-2021 Tauri Programme within The Commons Conservancy +# SPDX-License-Identifier: Apache-2.0 +# SPDX-License-Identifier: MIT + +name: updater test artifacts +on: + tags: [ v* ] + +jobs: + build-artifacts: + runs-on: ${{ matrix.platform }} + + strategy: + fail-fast: false + matrix: + platform: [ ubuntu-latest, macos-latest, windows-latest ] + + steps: + - uses: actions/checkout@v3 + - name: install stable + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + - name: install webkit2gtk (ubuntu only) + if: matrix.platform == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -y webkit2gtk-4.0 + - name: build sample artifacts (updater) + working-directory: ./src-tauri + run: | + npm install + node ../../tooling/cli.js/bin/tauri build + env: + TAURI_PRIVATE_KEY: ${{secret.TAURI_PRIVATE_KEY}} + TAURI_KEY_PASSWORD: ${{secret.TAURI_KEY_PASSWORD}} + + - uses: actions/upload-artifact@v2 + if: matrix.platform == 'ubuntu-latest' + with: + name: linux-updater-artifacts + path: ./target/release/bundle/appimage/updater-example_*.AppImage.* + + - uses: actions/upload-artifact@v2 + if: matrix.platform == 'windows-latest' + with: + name: windows-updater-artifacts + path: ./target/release/bundle/msi/* + + - uses: actions/upload-artifact@v2 + if: matrix.platform == 'macos-latest' + with: + name: macos-updater-artifacts + path: ./target/release/bundle/macos/updater-example_*.app.tar.* diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 226fb289..2c083caf 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -121,6 +121,22 @@ dependencies = [ "num-traits", ] +[[package]] +name = "attohttpc" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fcf00bc6d5abb29b5f97e3c61a90b6d3caa12f3faf897d4a3e3607c050a35a7" +dependencies = [ + "flate2", + "http", + "log", + "native-tls", + "serde", + "serde_json", + "serde_urlencoded", + "url", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -1158,7 +1174,7 @@ dependencies = [ "libc", "log", "rustversion", - "windows", + "windows 0.39.0", ] [[package]] @@ -2006,6 +2022,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "minisign-verify" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "933dca44d65cdd53b355d0b73d380a2ff5da71f87f036053188bf1eab6a19881" + [[package]] name = "miniz_oxide" version = "0.6.2" @@ -2208,6 +2230,17 @@ dependencies = [ "objc_exception", ] +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + [[package]] name = "objc_exception" version = "0.1.2" @@ -2840,6 +2873,30 @@ dependencies = [ "winreg", ] +[[package]] +name = "rfd" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0149778bd99b6959285b0933288206090c50e2327f47a9c463bfdbf45c8823ea" +dependencies = [ + "block", + "dispatch", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "lazy_static", + "log", + "objc", + "objc-foundation", + "objc_id", + "raw-window-handle", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows 0.37.0", +] + [[package]] name = "ring" version = "0.16.20" @@ -3909,7 +3966,7 @@ dependencies = [ "serde", "unicode-segmentation", "uuid 1.3.0", - "windows", + "windows 0.39.0", "windows-implement", "x11-dl", ] @@ -3932,6 +3989,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac135e45c2923bd91edbb95a0d656f8d025389697e34d6d79166952bfa79c61c" dependencies = [ "anyhow", + "attohttpc", + "base64 0.13.1", "cocoa", "dirs-next", "embed_plist", @@ -3944,6 +4003,7 @@ dependencies = [ "heck 0.4.1", "http", "ignore", + "minisign-verify", "objc", "once_cell", "open", @@ -3951,6 +4011,7 @@ dependencies = [ "rand 0.8.5", "raw-window-handle", "regex", + "rfd", "semver 1.0.16", "serde", "serde_json", @@ -3964,12 +4025,14 @@ dependencies = [ "tauri-utils", "tempfile", "thiserror", + "time 0.3.17", "tokio", "url", "uuid 1.3.0", "webkit2gtk", "webview2-com", - "windows", + "windows 0.39.0", + "zip", ] [[package]] @@ -4067,7 +4130,7 @@ dependencies = [ "thiserror", "uuid 1.3.0", "webview2-com", - "windows", + "windows 0.39.0", ] [[package]] @@ -4086,7 +4149,7 @@ dependencies = [ "uuid 1.3.0", "webkit2gtk", "webview2-com", - "windows", + "windows 0.39.0", "wry", ] @@ -4116,7 +4179,7 @@ dependencies = [ "toml", "url", "walkdir", - "windows", + "windows 0.39.0", ] [[package]] @@ -4766,7 +4829,7 @@ checksum = "b4a769c9f1a64a8734bde70caafac2b96cada12cd4aefa49196b3a386b8b4178" dependencies = [ "webview2-com-macros", "webview2-com-sys", - "windows", + "windows 0.39.0", "windows-implement", ] @@ -4791,7 +4854,7 @@ dependencies = [ "serde", "serde_json", "thiserror", - "windows", + "windows 0.39.0", "windows-bindgen", "windows-metadata", ] @@ -4838,6 +4901,19 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57b543186b344cc61c85b5aab0d2e3adf4e0f99bc076eff9aa5927bcc0b8a647" +dependencies = [ + "windows_aarch64_msvc 0.37.0", + "windows_i686_gnu 0.37.0", + "windows_i686_msvc 0.37.0", + "windows_x86_64_gnu 0.37.0", + "windows_x86_64_msvc 0.37.0", +] + [[package]] name = "windows" version = "0.39.0" @@ -4929,6 +5005,12 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +[[package]] +name = "windows_aarch64_msvc" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a" + [[package]] name = "windows_aarch64_msvc" version = "0.39.0" @@ -4941,6 +5023,12 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +[[package]] +name = "windows_i686_gnu" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1" + [[package]] name = "windows_i686_gnu" version = "0.39.0" @@ -4953,6 +5041,12 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +[[package]] +name = "windows_i686_msvc" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c" + [[package]] name = "windows_i686_msvc" version = "0.39.0" @@ -4965,6 +5059,12 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +[[package]] +name = "windows_x86_64_gnu" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d" + [[package]] name = "windows_x86_64_gnu" version = "0.39.0" @@ -4983,6 +5083,12 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +[[package]] +name = "windows_x86_64_msvc" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d" + [[package]] name = "windows_x86_64_msvc" version = "0.39.0" @@ -5047,7 +5153,7 @@ dependencies = [ "webkit2gtk", "webkit2gtk-sys", "webview2-com", - "windows", + "windows 0.39.0", "windows-implement", ] @@ -5080,3 +5186,14 @@ checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" dependencies = [ "libc", ] + +[[package]] +name = "zip" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0445d0fbc924bb93539b4316c11afb121ea39296f99a3c4c9edad09e3658cdef" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", +] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index b26a472c..3953ab82 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -15,7 +15,7 @@ tauri-build = { version = "1.2", features = [] } [dependencies] serde_json = { version = "1.0", features = ["raw_value"] } serde = { version = "1.0", features = ["derive"] } -tauri = { version = "1.2", features = ["config-toml", "devtools", "shell-open", "system-tray", "window-start-dragging"] } +tauri = { version = "1.2", features = ["config-toml", "devtools", "shell-open", "system-tray", "updater", "window-start-dragging"] } http = { version = "0.2.8" } reqwest = { version = "0.11.14", features = ["json"] } tokio = { version = "1.25.0", features = ["sync"] } diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns index 7b53f7f5..aac3daab 100644 Binary files a/src-tauri/icons/icon.icns and b/src-tauri/icons/icon.icns differ diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 4942d258..1472bb30 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -10,7 +10,7 @@ extern crate objc; use std::collections::HashMap; use std::fs::create_dir_all; -use http::header::{HeaderName, USER_AGENT}; +use http::header::{ACCEPT, HeaderName, USER_AGENT}; use http::{HeaderMap, HeaderValue, Method}; use reqwest::redirect::Policy; use sqlx::migrate::Migrator; @@ -18,7 +18,7 @@ use sqlx::sqlite::SqlitePoolOptions; use sqlx::types::Json; use sqlx::{Pool, Sqlite}; use tauri::regex::Regex; -use tauri::{AppHandle, Menu, MenuItem, State, Submenu, Wry}; +use tauri::{AppHandle, Menu, State, Submenu, Wry}; use tauri::{CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, WindowEvent}; use tokio::sync::Mutex; @@ -104,6 +104,7 @@ async fn send_request( let mut headers = HeaderMap::new(); headers.insert(USER_AGENT, HeaderValue::from_static("yaak")); + headers.insert(ACCEPT, HeaderValue::from_static("*/*")); for h in req.headers.0 { if h.name.is_empty() && h.value.is_empty() { @@ -337,12 +338,14 @@ fn main() { let tray_menu = SystemTrayMenu::new().add_item(quit); let system_tray = SystemTray::new().with_menu(tray_menu); - let submenu = Submenu::new("View", Menu::new() + let default_menu = Menu::os_default("Yaak".to_string().as_str()); + let submenu = Submenu::new("Test Menu", Menu::new() .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+-")), ); - let menu = Menu::new().add_native_item(MenuItem::Quit).add_submenu(submenu); + + let menu = default_menu.add_submenu(submenu); tauri::Builder::default() .menu(menu) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json new file mode 100644 index 00000000..20413c28 --- /dev/null +++ b/src-tauri/tauri.conf.json @@ -0,0 +1,86 @@ +{ + "build": { + "beforeBuildCommand": "npm run build", + "beforeDevCommand": "npm run dev", + "devPath": "http://localhost:1420", + "distDir": "../dist", + "withGlobalTauri": false + }, + "package": { + "productName": "Yaak", + "version": "0.0.1" + }, + "tauri": { + "windows": [ + { + "fullscreen": false, + "height": 800, + "hiddenTitle": true, + "resizable": true, + "title": "Yaak", + "titleBarStyle": "Overlay", + "width": 1400 + } + ], + "allowlist": { + "all": false, + "fs": { + "scope": [ + "$RESOURCE/*" + ] + }, + "shell": { + "all": false, + "open": true + }, + "window": { + "startDragging": true + } + }, + "bundle": { + "active": true, + "category": "DeveloperTool", + "copyright": "", + "externalBin": [], + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ], + "identifier": "co.schier.yaak", + "longDescription": "", + "resources": [ + "plugins/*", + "migrations/*" + ], + "shortDescription": "", + "targets": "all", + "deb": { + "depends": [] + }, + "macOS": { + "exceptionDomain": "", + "frameworks": [] + }, + "windows": { + "digestAlgorithm": "sha256", + "timestampUrl": "" + } + }, + "security": {}, + "systemTray": { + "iconAsTemplate": true, + "iconPath": "icons/icon.png" + }, + "updater": { + "active": true, + "dialog": true, + "endpoints": [ + "https://update.yaak.app/check/{{target}}/{{current_version}}" + ], + "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEMxRDJFREQ1MjExQjdGN0IKUldSN2Z4c2gxZTNTd1FHNCtmYnFXMHVVQzhuNkJOM1cwOFBodmdLall3ckhKenpKUytHSTR1MlkK" + } + } +} diff --git a/src-tauri/tauri.toml b/src-tauri/tauri.toml deleted file mode 100644 index 616e6268..00000000 --- a/src-tauri/tauri.toml +++ /dev/null @@ -1,73 +0,0 @@ -[build] -beforeDevCommand = "npm run dev" -beforeBuildCommand = "npm run build" -devPath = "http://localhost:1420" -distDir = "../dist" -withGlobalTauri = false - -[package] -productName = "Yaak" -version = "0.0.1" - -[tauri.allowlist] -all = false - -[tauri.allowlist.shell] -all = false -open = true - -[tauri.allowlist.window] -startDragging = true - -[tauri.allowlist.fs] -scope = [ "$RESOURCE/*" ] - -[tauri.bundle] -active = true -category = "DeveloperTool" -copyright = "" -externalBin = [ ] -icon = [ - "icons/32x32.png", - "icons/128x128.png", - "icons/128x128@2x.png", - "icons/icon.icns", - "icons/icon.ico" -] -identifier = "co.schier.yaak" -longDescription = "" -resources = [ "plugins/*", "migrations/*" ] -shortDescription = "" -targets = "all" - -[tauri.bundle.deb] -depends = [ ] - -[tauri.bundle.macOS] -exceptionDomain = "" -frameworks = [ ] - -[tauri.bundle.windows] -digestAlgorithm = "sha256" -timestampUrl = "" - -[tauri.security] - -[tauri.updater] -active = false -endpoints = [ ] -pubkey = "" -dialog = true - -[[tauri.windows]] -fullscreen = false -height = 800 -resizable = true -title = "Yaak" -width = 1_400 -titleBarStyle = "Overlay" -hiddenTitle = true - -[tauri.systemTray] -iconPath = "icons/icon.png" -iconAsTemplate = true diff --git a/src-web/components/Colors.tsx b/src-web/components/Colors.tsx index 7ee58f30..34f1b162 100644 --- a/src-web/components/Colors.tsx +++ b/src-web/components/Colors.tsx @@ -1,5 +1,4 @@ import classnames from 'classnames'; -import React from 'react'; import { HStack, VStack } from './Stacks'; export function Colors() { diff --git a/src-web/components/HeaderEditor.tsx b/src-web/components/HeaderEditor.tsx index c989f77d..b6d80a3b 100644 --- a/src-web/components/HeaderEditor.tsx +++ b/src-web/components/HeaderEditor.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { useRequestUpdate } from '../hooks/useRequest'; import type { HttpHeader, HttpRequest } from '../lib/models'; import { IconButton } from './IconButton'; diff --git a/src-web/components/ResponsePane.tsx b/src-web/components/ResponsePane.tsx index 40379bf7..f82dcc97 100644 --- a/src-web/components/ResponsePane.tsx +++ b/src-web/components/ResponsePane.tsx @@ -1,6 +1,7 @@ import classnames from 'classnames'; import { useEffect, useMemo, useState } from 'react'; import { useDeleteAllResponses, useDeleteResponse, useResponses } from '../hooks/useResponses'; +import { tryFormatJson } from '../lib/formatters'; import { Dropdown } from './Dropdown'; import { Editor } from './Editor'; import { Icon } from './Icon'; @@ -16,7 +17,7 @@ interface Props { export function ResponsePane({ requestId, className }: Props) { const [activeResponseId, setActiveResponseId] = useState(null); - const [viewMode, setViewMode] = useState<'pretty' | 'raw'>('raw'); + const [viewMode, setViewMode] = useState<'pretty' | 'raw'>('pretty'); const responses = useResponses(requestId); const response = activeResponseId ? responses.data.find((r) => r.id === activeResponseId) @@ -69,14 +70,12 @@ export function ResponsePane({ requestId, className }: Props) { )} - {contentType.includes('html') && ( - setViewMode((m) => (m === 'pretty' ? 'raw' : 'pretty'))} - /> - )} + setViewMode((m) => (m === 'pretty' ? 'raw' : 'pretty'))} + />
{response.error}
- ) : viewMode === 'pretty' ? ( + ) : viewMode === 'pretty' && contentType.includes('html') ? ( + ) : viewMode === 'pretty' && contentType.includes('json') ? ( + ) : response?.body ? (