diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 12ade03d7..90bc8c701 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -56,8 +56,8 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tagName: app-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version - releaseName: "App v__VERSION__" + tagName: v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version + releaseName: "Spyglass v__VERSION__" releaseBody: "See the assets to download this version and install." releaseDraft: true prerelease: false diff --git a/Cargo.lock b/Cargo.lock index 5275c0eb4..d43609969 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -847,9 +847,9 @@ dependencies = [ [[package]] name = "dashmap" -version = "5.3.1" +version = "5.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084c61a88f94d7557441d01e89fc3800b0b80658462b05aa7b55dfae069da09b" +checksum = "94b5a84352d6654d195b2365e38b5a7eacfdca4ad1b375196a1f76c6d7dd01ce" dependencies = [ "cfg-if", "hashbrown 0.12.0", @@ -1851,9 +1851,6 @@ name = "hashbrown" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c21d40587b92fa6a6c6e3c1bdbf87d75511db5672f9c93175574b3a00df1758" -dependencies = [ - "ahash", -] [[package]] name = "hashlink" @@ -2458,9 +2455,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" @@ -2977,7 +2974,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" dependencies = [ "lock_api", - "parking_lot_core 0.9.2", + "parking_lot_core 0.9.3", ] [[package]] @@ -2996,9 +2993,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ "cfg-if", "libc", @@ -3900,9 +3897,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "f972498cf015f7c0746cac89ebe1d6ef10c293b94175a243a2d9442c163d9944" dependencies = [ "itoa 1.0.1", "ryu", @@ -3911,9 +3908,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" +checksum = "a2ad84e47328a31223de7fed7a4f5087f2d6ddfe586cf3ca25b7a165bc0a5aed" dependencies = [ "proc-macro2", "quote", @@ -4865,18 +4862,18 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", @@ -5660,15 +5657,15 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.34.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows_aarch64_msvc 0.34.0", - "windows_i686_gnu 0.34.0", - "windows_i686_msvc 0.34.0", - "windows_x86_64_gnu 0.34.0", - "windows_x86_64_msvc 0.34.0", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", ] [[package]] @@ -5679,15 +5676,15 @@ checksum = "29277a4435d642f775f63c7d1faeb927adba532886ce0287bd985bffb16b6bca" [[package]] name = "windows_aarch64_msvc" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" +checksum = "db3bc5134e8ce0da5d64dcec3529793f1d33aee5a51fc2b4662e0f881dd463e6" [[package]] name = "windows_aarch64_msvc" -version = "0.35.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3bc5134e8ce0da5d64dcec3529793f1d33aee5a51fc2b4662e0f881dd463e6" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] name = "windows_gen" @@ -5713,15 +5710,15 @@ checksum = "1145e1989da93956c68d1864f32fb97c8f561a8f89a5125f6a2b7ea75524e4b8" [[package]] name = "windows_i686_gnu" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" +checksum = "0343a6f35bf43a07b009b8591b78b10ea03de86b06f48e28c96206cd0f453b50" [[package]] name = "windows_i686_gnu" -version = "0.35.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0343a6f35bf43a07b009b8591b78b10ea03de86b06f48e28c96206cd0f453b50" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" [[package]] name = "windows_i686_msvc" @@ -5737,15 +5734,15 @@ checksum = "d4a09e3a0d4753b73019db171c1339cd4362c8c44baf1bcea336235e955954a6" [[package]] name = "windows_i686_msvc" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" +checksum = "1acdcbf4ca63d8e7a501be86fee744347186275ec2754d129ddeab7a1e3a02e4" [[package]] name = "windows_i686_msvc" -version = "0.35.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1acdcbf4ca63d8e7a501be86fee744347186275ec2754d129ddeab7a1e3a02e4" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" [[package]] name = "windows_macros" @@ -5785,15 +5782,15 @@ checksum = "8ca64fcb0220d58db4c119e050e7af03c69e6f4f415ef69ec1773d9aab422d5a" [[package]] name = "windows_x86_64_gnu" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" +checksum = "893c0924c5a990ec73cd2264d1c0cba1773a929e1a3f5dbccffd769f8c4edebb" [[package]] name = "windows_x86_64_gnu" -version = "0.35.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "893c0924c5a990ec73cd2264d1c0cba1773a929e1a3f5dbccffd769f8c4edebb" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" [[package]] name = "windows_x86_64_msvc" @@ -5809,15 +5806,15 @@ checksum = "08cabc9f0066848fef4bc6a1c1668e6efce38b661d2aeec75d18d8617eebb5f1" [[package]] name = "windows_x86_64_msvc" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" +checksum = "a29bd61f32889c822c99a8fdf2e93378bd2fae4d7efd2693fab09fcaaf7eff4b" [[package]] name = "windows_x86_64_msvc" -version = "0.35.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a29bd61f32889c822c99a8fdf2e93378bd2fae4d7efd2693fab09fcaaf7eff4b" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" [[package]] name = "winreg" diff --git a/crates/client/public/glue.js b/crates/client/public/glue.js index 8ffdaf324..f543eb8d8 100644 --- a/crates/client/public/glue.js +++ b/crates/client/public/glue.js @@ -13,6 +13,10 @@ export async function onClearSearch(callback) { await listen('clear_search', callback); } +export async function onFocus(callback) { + await listen('focus_window', callback); +} + export async function searchDocs(lenses, query) { return await invoke("search_docs", { lenses, query }); } @@ -25,6 +29,6 @@ export async function openResult(url) { return await invoke("open_result", { url }); } -export function resizeWindow(height) { - return invoke("resize_window", { height }); +export async function resizeWindow(height) { + return await invoke("resize_window", { height }); } \ No newline at end of file diff --git a/crates/client/src/events.rs b/crates/client/src/events.rs index 1387a36db..656d5ea09 100644 --- a/crates/client/src/events.rs +++ b/crates/client/src/events.rs @@ -1,3 +1,4 @@ +use js_sys::Date; use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; use wasm_bindgen_futures::spawn_local; @@ -6,6 +7,7 @@ use yew::prelude::*; use super::{clear_results, escape, open}; use crate::components::ResultListData; +use crate::constants; pub fn handle_global_key_down( event: &Event, @@ -66,3 +68,27 @@ pub fn handle_global_key_down( } } } + +pub fn handle_query_change( + query: &str, + query_debounce: UseStateHandle, + node_ref: UseStateHandle, + lens: UseStateHandle>, + search_results: UseStateHandle>, + selected_idx: UseStateHandle, +) { + // Was the last char typed > 1 sec ago? + let is_debounced = *query_debounce >= constants::DEBOUNCE_TIME_MS; + + if is_debounced && query.len() >= constants::MIN_CHARS { + let el = node_ref.cast::().unwrap(); + if query.starts_with(constants::LENS_SEARCH_PREFIX) { + // show lens search + super::show_lens_results(search_results, el, selected_idx, query.to_string()); + } else { + super::show_doc_results(search_results, &lens, el, selected_idx, query.to_string()); + } + } + + query_debounce.set(Date::now()); +} diff --git a/crates/client/src/main.rs b/crates/client/src/main.rs index 317bf64b0..e37544842 100644 --- a/crates/client/src/main.rs +++ b/crates/client/src/main.rs @@ -2,7 +2,7 @@ use gloo::events::EventListener; use js_sys::Date; use wasm_bindgen::{prelude::*, JsCast}; use wasm_bindgen_futures::spawn_local; -use web_sys::{window, Element, HtmlElement, HtmlInputElement, VisibilityState}; +use web_sys::{window, Element, HtmlElement, HtmlInputElement}; use yew::prelude::*; mod components; @@ -22,6 +22,9 @@ extern "C" { #[wasm_bindgen(js_name = "onClearSearch")] pub async fn on_clear_search(callback: &Closure); + #[wasm_bindgen(js_name = "onFocus")] + pub async fn on_focus(callback: &Closure); + #[wasm_bindgen(js_name = "openResult", catch)] pub async fn open(url: String) -> Result<(), JsValue>; @@ -29,7 +32,7 @@ extern "C" { pub async fn escape() -> Result<(), JsValue>; #[wasm_bindgen(js_name = "resizeWindow", catch)] - pub fn resize_window(height: f64) -> Result<(), JsValue>; + pub async fn resize_window(height: f64) -> Result<(), JsValue>; } fn main() { @@ -72,23 +75,6 @@ pub fn app() -> Html { }); || drop(listener) }); - - use_effect(move || { - // Attach a keydown event listener to the document. - let document = gloo::utils::document(); - let listener = EventListener::new(&document.clone(), "visibilitychange", move |_| { - if document.visibility_state() == VisibilityState::Visible { - match document.get_element_by_id("searchbox") { - Some(el) => { - let el: HtmlElement = el.unchecked_into(); - let _ = el.focus(); - }, - _ => {} - } - } - }); - || drop(listener) - }); } // Handle changes to the query string @@ -99,33 +85,29 @@ pub fn app() -> Html { let node_ref = node_ref.clone(); use_effect_with_deps( move |query| { - // Was the last char typed > 1 sec ago? - let is_debounced = *query_debounce >= constants::DEBOUNCE_TIME_MS; - - if is_debounced && query.len() >= constants::MIN_CHARS { - if query.starts_with(constants::LENS_SEARCH_PREFIX) { - // show lens search - let el = node_ref.cast::().unwrap(); - show_lens_results(search_results, el, selected_idx, query.clone()); - } else { - let el = node_ref.cast::().unwrap(); - show_doc_results(search_results, &lens, el, selected_idx, query.clone()); - } - } - - query_debounce.set(Date::now()); + events::handle_query_change( + query, + query_debounce, + node_ref, + lens, + search_results, + selected_idx, + ); || () }, (*query).clone(), ); } + // Handle callbacks to Tauri + // TODO: Is this the best way to handle calls from Tauri? { - // TODO: Is this the best way to handle calls from Tauri? let lens = lens.clone(); let query = query.clone(); let results = search_results.clone(); let selected_idx = selected_idx.clone(); + // Reset query string, results list, etc when we receive a "clear_search" + // event from tauri spawn_local(async move { let cb = Closure::wrap(Box::new(move || { query.set("".to_string()); @@ -137,6 +119,20 @@ pub fn app() -> Html { on_clear_search(&cb).await; cb.forget(); }); + + // Focus on the search box when we receive an "focus_window" event from + // tauri + spawn_local(async move { + let cb = Closure::wrap(Box::new(move || { + let document = gloo::utils::document(); + if let Some(el) = document.get_element_by_id("searchbox") { + let el: HtmlElement = el.unchecked_into(); + let _ = el.focus(); + } + }) as Box); + on_focus(&cb).await; + cb.forget(); + }); } let results = search_results @@ -148,31 +144,21 @@ pub fn app() -> Html { let onkeyup = { let query = query.clone(); Callback::from(move |e: KeyboardEvent| { - let key = e.key(); - match key.as_str() { - "ArrowUp" => e.prevent_default(), - "ArrowDown" => e.prevent_default(), - _ => { - let input: HtmlInputElement = e.target_unchecked_into(); - query.set(input.value()); - } - } + let input: HtmlInputElement = e.target_unchecked_into(); + query.set(input.value()); }) }; let onkeydown = { - let search_results = search_results.clone(); Callback::from(move |e: KeyboardEvent| { - // No need to prevent default behavior if there are no search results. - if search_results.is_empty() { - return; - } - let key = e.key(); match key.as_str() { + // Prevent cursor from moving around "ArrowUp" => e.prevent_default(), "ArrowDown" => e.prevent_default(), - _ => return, + // Prevent search box from losing focus + "Tab" => e.prevent_default(), + _ => (), } }) }; @@ -202,7 +188,9 @@ pub fn app() -> Html { fn clear_results(handle: UseStateHandle>, node: Element) { handle.set(Vec::new()); - resize_window(node.client_height() as f64).unwrap(); + spawn_local(async move { + resize_window(node.client_height() as f64).await.unwrap(); + }); } fn show_lens_results( @@ -227,9 +215,9 @@ fn show_lens_results( } handle.set(results); - - let height = node.client_height(); - resize_window(height as f64).unwrap(); + spawn_local(async move { + resize_window(node.client_height() as f64).await.unwrap(); + }); } Err(e) => { let window = window().unwrap(); @@ -265,9 +253,9 @@ fn show_doc_results( } handle.set(results); - - let height = node.client_height(); - resize_window(height as f64).unwrap(); + spawn_local(async move { + resize_window(node.client_height() as f64).await.unwrap(); + }); } Err(e) => { let window = window().unwrap(); diff --git a/crates/tauri/src/cmd.rs b/crates/tauri/src/cmd.rs index eeef62664..302f5c1b9 100644 --- a/crates/tauri/src/cmd.rs +++ b/crates/tauri/src/cmd.rs @@ -16,8 +16,8 @@ pub async fn open_result(_: tauri::Window, url: &str) -> Result<(), String> { } #[tauri::command] -pub fn resize_window(window: tauri::Window, height: f64) { - window::resize_window(&window, height); +pub async fn resize_window(window: tauri::Window, height: f64) { + window::resize_window(&window, height).await; } #[tauri::command] diff --git a/crates/tauri/src/window.rs b/crates/tauri/src/window.rs index 69bd628c6..64a9d1ba8 100644 --- a/crates/tauri/src/window.rs +++ b/crates/tauri/src/window.rs @@ -1,4 +1,4 @@ -use tauri::{LogicalSize, Size, Window}; +use tauri::{async_runtime::spawn, LogicalSize, Size, Window}; use crate::{cmd, constants}; @@ -23,7 +23,7 @@ pub fn hide_window(window: &Window) { window.emit("clear_search", true).unwrap(); } -pub fn resize_window(window: &Window, height: f64) { +pub async fn resize_window(window: &Window, height: f64) { window .set_size(Size::Logical(LogicalSize { width: constants::INPUT_WIDTH, @@ -33,8 +33,9 @@ pub fn resize_window(window: &Window, height: f64) { } pub fn show_window(window: &Window) { + window.emit("focus_window", true).unwrap(); window.show().unwrap(); window.set_focus().unwrap(); - cmd::resize_window(window.clone(), constants::INPUT_HEIGHT); + spawn(cmd::resize_window(window.clone(), constants::INPUT_HEIGHT)); center_window(window); } diff --git a/crates/tauri/tauri.conf.json b/crates/tauri/tauri.conf.json index 307a179e2..9c18cffcd 100644 --- a/crates/tauri/tauri.conf.json +++ b/crates/tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "package": { "productName": "Spyglass", - "version": "2022.4.29" + "version": "2022.4.30" }, "build": { "distDir": "../client/dist",