fix: refactor request system, sidebar animation, placeholder color transition

This commit is contained in:
Artemy Egorov 2024-08-04 00:06:12 +03:00
parent 20f5234572
commit 15c43e3482
9 changed files with 372 additions and 63 deletions

219
src-tauri/Cargo.lock generated
View file

@ -56,6 +56,55 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "anstream"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]]
name = "anstyle-parse"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.86" version = "1.0.86"
@ -255,6 +304,10 @@ name = "cc"
version = "1.1.6" version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f"
dependencies = [
"jobserver",
"libc",
]
[[package]] [[package]]
name = "cesu8" name = "cesu8"
@ -311,6 +364,46 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "clap"
version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.72",
]
[[package]]
name = "clap_lex"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]] [[package]]
name = "cocoa" name = "cocoa"
version = "0.24.1" version = "0.24.1"
@ -347,6 +440,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colorchoice"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]] [[package]]
name = "combine" name = "combine"
version = "4.6.7" version = "4.6.7"
@ -504,11 +603,16 @@ dependencies = [
[[package]] [[package]]
name = "dalet" name = "dalet"
version = "1.0.0-pre3" version = "1.0.0-pre6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c629ef0fc95fddd843a73e72de3f509665a73f51323f7b6c1b7946eb8937b660" checksum = "8bc4c347533f8341633bd820799dea680f600e50891310b74bc914740681e8c2"
dependencies = [ dependencies = [
"clap",
"enum-procs",
"num_enum 0.7.3",
"serde", "serde",
"serde_repr",
"zstd",
] ]
[[package]] [[package]]
@ -656,6 +760,16 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "enum-procs"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e188616f4527e2cf6128e58622bb2fd16ebcfa37a200b2d16739c3ca227bf649"
dependencies = [
"quote",
"syn 2.0.72",
]
[[package]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.1" version = "1.0.1"
@ -1541,6 +1655,12 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "0.4.8" version = "0.4.8"
@ -1596,6 +1716,15 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "jobserver"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.69" version = "0.3.69"
@ -1807,7 +1936,7 @@ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
"jni-sys", "jni-sys",
"ndk-sys", "ndk-sys",
"num_enum", "num_enum 0.5.11",
"thiserror", "thiserror",
] ]
@ -1869,7 +1998,16 @@ version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9"
dependencies = [ dependencies = [
"num_enum_derive", "num_enum_derive 0.5.11",
]
[[package]]
name = "num_enum"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179"
dependencies = [
"num_enum_derive 0.7.3",
] ]
[[package]] [[package]]
@ -1884,6 +2022,18 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "num_enum_derive"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.72",
]
[[package]] [[package]]
name = "objc" name = "objc"
version = "0.2.7" version = "0.2.7"
@ -2660,6 +2810,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044"
dependencies = [ dependencies = [
"once_cell", "once_cell",
"ring",
"rustls-pki-types", "rustls-pki-types",
"rustls-webpki", "rustls-webpki",
"subtle", "subtle",
@ -3539,6 +3690,20 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "tokio-gemini"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5aea8fd82d63287b051d76b86e0497105564cb8fa269d43bf369a2d1b93bb5d"
dependencies = [
"mime",
"num_enum 0.7.3",
"tokio",
"tokio-rustls",
"url",
"webpki-roots",
]
[[package]] [[package]]
name = "tokio-native-tls" name = "tokio-native-tls"
version = "0.3.1" version = "0.3.1"
@ -3792,6 +3957,12 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.10.0" version = "1.10.0"
@ -3836,11 +4007,14 @@ name = "vigi"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"dalet", "dalet",
"mime",
"reqwest 0.12.5", "reqwest 0.12.5",
"serde", "serde",
"serde_json", "serde_json",
"tauri", "tauri",
"tauri-build", "tauri-build",
"tokio-gemini",
"url",
] ]
[[package]] [[package]]
@ -4030,6 +4204,15 @@ dependencies = [
"system-deps 6.2.2", "system-deps 6.2.2",
] ]
[[package]]
name = "webpki-roots"
version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd"
dependencies = [
"rustls-pki-types",
]
[[package]] [[package]]
name = "webview2-com" name = "webview2-com"
version = "0.19.1" version = "0.19.1"
@ -4565,3 +4748,31 @@ dependencies = [
"crc32fast", "crc32fast",
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]]
name = "zstd"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "7.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059"
dependencies = [
"zstd-sys",
]
[[package]]
name = "zstd-sys"
version = "2.0.13+zstd.1.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa"
dependencies = [
"cc",
"pkg-config",
]

View file

@ -12,7 +12,8 @@ license = "AGPL-3.0"
tauri-build = { version = "1", features = [] } tauri-build = { version = "1", features = [] }
[dependencies] [dependencies]
tauri = { version = "1", features = [ "updater", tauri = { version = "1", features = [
"updater",
"window-hide", "window-hide",
"window-start-dragging", "window-start-dragging",
"window-close", "window-close",
@ -25,8 +26,12 @@ tauri = { version = "1", features = [ "updater",
] } ] }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
dalet = "1.0.0-pre3" dalet = "1.0.0-pre6"
reqwest = "0.12.5" reqwest = "0.12.5"
tokio-gemini = "0.1.0"
url = "2.5.2"
mime = "0.3.17"
[features] [features]
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!! # This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!

View file

@ -3,6 +3,7 @@
use std::fs::{self}; use std::fs::{self};
mod process_input;
mod types; mod types;
mod utils; mod utils;

View file

@ -0,0 +1,25 @@
use crate::types::{VigiError, VigiOutput};
use mime::Mime;
use url::Url;
mod process_data;
mod process_url;
use process_data::process_data;
use process_url::process_url;
type Data = Vec<u8>;
type ReqResult = (Mime, Data);
pub async fn process_input(input: &String) -> Result<VigiOutput, VigiError> {
let parsed = Url::parse(input);
let (mime, data) = match parsed {
Ok(url) => process_url(url).await?,
Err(_) => Err(VigiError::Network)?,
};
let result = process_data(mime, data).await?;
Ok(result)
}

View file

@ -0,0 +1,25 @@
use dalet::{daletl::ToDaletlPage, typed::Tag::*};
use mime::Mime;
use crate::types::{VigiError, VigiOutput};
pub async fn process_data(mime: Mime, data: Vec<u8>) -> Result<VigiOutput, VigiError> {
let result = match (mime.type_().as_str(), mime.subtype().as_str()) {
("text", "plain") => {
process_text(String::from_utf8(data).map_err(|_| VigiError::TextIsNotUtf8)?).await
}
// ("text", "gemini") => {
// process_text(String::from_utf8(data).map_err(|_| VigiError::TextIsNotUtf8)?).await
// }
_ => Err(VigiError::UnsupportedMimeType)?,
};
Ok(result)
}
async fn process_text(data: String) -> VigiOutput {
let mut truncated = data.clone();
truncated.truncate(50);
VigiOutput::new(truncated, vec![El(data.into())].to_dl_page())
}

View file

@ -0,0 +1,52 @@
use mime::Mime;
use reqwest::header::CONTENT_TYPE;
use url::Url;
use crate::types::VigiError;
use super::ReqResult;
pub async fn process_url(url: Url) -> Result<ReqResult, VigiError> {
let result = match url.scheme() {
"http" | "https" => process_http(url.to_string()).await?,
// "gemini" => process_gemini(url.to_string()).await?,
_ => Err(VigiError::UnsupportedProtocol)?,
};
Ok(result)
}
async fn process_http(url: String) -> Result<ReqResult, VigiError> {
let res = reqwest::get(&url).await.map_err(|_| VigiError::Network)?;
let mime_type = {
match res.headers().get(CONTENT_TYPE) {
Some(header) => match header.to_str() {
Ok(mime) => mime.to_owned(),
Err(_) => "text/plain".to_owned(),
},
None => "text/plain".to_owned(),
}
}
.parse::<Mime>()
.map_err(|_| VigiError::InvalidMimeType)?;
Ok((
mime_type,
res.bytes().await.map_err(|_| VigiError::Network)?.into(),
))
}
// async fn process_gemini(url: String) -> Result<ReqResult, VigiError> {
// let res = tokio_gemini::Client::default()
// .request(&url)
// .await
// .map_err(|e| {
// println!("{:#?}", e);
// VigiError::Network
// })?;
// let mime_type = res.mime().map_err(|_| VigiError::InvalidMimeType)?;
// Ok((mime_type, res.message().as_bytes().into()))
// }

View file

@ -1,9 +1,12 @@
use dalet::{Argument, Body, Tag}; use dalet::daletl::{Tag, ToDaletlPage};
use dalet::typed::Tag::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fs, path::PathBuf}; use std::{collections::HashMap, fs, path::PathBuf};
use crate::utils::write_tabs; use crate::utils::write_tabs;
use crate::process_input::process_input;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub enum VigiError { pub enum VigiError {
Network, Network,
@ -13,9 +16,15 @@ pub enum VigiError {
Filesystem, Filesystem,
Config, Config,
GetTab, GetTab,
UnsupportedProtocol,
UnsupportedMimeType,
InvalidMimeType,
TextIsNotUtf8,
} }
#[derive(Serialize, Debug, Clone)] #[derive(Debug, Clone)]
pub struct VigiState { pub struct VigiState {
pub tabs_id_counter_path: PathBuf, pub tabs_id_counter_path: PathBuf,
pub current_tab_index_path: PathBuf, pub current_tab_index_path: PathBuf,
@ -36,7 +45,7 @@ pub struct VigiState {
pub cached_inputs: HashMap<String, VigiOutput>, pub cached_inputs: HashMap<String, VigiOutput>,
} }
#[derive(Serialize, Debug, Clone)] #[derive(Debug, Clone)]
pub struct VigiOutput { pub struct VigiOutput {
pub title: String, pub title: String,
pub data: Vec<Tag>, pub data: Vec<Tag>,
@ -113,9 +122,6 @@ impl VigiState {
} }
async fn process_input(&mut self, ignore_cache: bool) -> Result<(), VigiError> { async fn process_input(&mut self, ignore_cache: bool) -> Result<(), VigiError> {
// TODO: Implement mime type, language, protocol or search detection
// TODO: Implement text links parsing
println!("process_input \"{}\"", self.top_bar_input); println!("process_input \"{}\"", self.top_bar_input);
let cached = !ignore_cache && self.cached_inputs.contains_key(&self.top_bar_input); let cached = !ignore_cache && self.cached_inputs.contains_key(&self.top_bar_input);
@ -123,34 +129,13 @@ impl VigiState {
let output = { let output = {
if cached { if cached {
self.cached_inputs.get(&self.top_bar_input).unwrap().clone() self.cached_inputs.get(&self.top_bar_input).unwrap().clone()
} else if self.top_bar_input.starts_with("https://")
|| self.top_bar_input.starts_with("http://")
{
let res = reqwest::get(&self.top_bar_input)
.await
.map_err(|_| VigiError::Network)?
.text()
.await
.map_err(|_| VigiError::Network)?;
let mut truncated = res.clone();
truncated.truncate(50);
VigiOutput::new(
truncated,
vec![Tag::new(0, Body::Text(res), Argument::Null)],
)
} else if self.top_bar_input.is_empty() { } else if self.top_bar_input.is_empty() {
VigiOutput::new( VigiOutput::new(
"Homepage".to_owned(), "Homepage".to_owned(),
vec![Tag::new( vec![El("Type something in the address bar".into())].to_dl_page(),
0,
Body::Text("Type something in the address bar".to_owned()),
Argument::Null,
)],
) )
} else { } else {
Err(VigiError::Parse)? process_input(&self.top_bar_input).await?
} }
}; };

View file

@ -68,6 +68,11 @@ body {
@apply flex justify-between mt-2 mx-2; @apply flex justify-between mt-2 mx-2;
} }
.tabs-category-text {
@apply overflow-hidden;
white-space: nowrap;
}
.block { .block {
@apply p-2 rounded-xl color-vigi-60; @apply p-2 rounded-xl color-vigi-60;
} }
@ -76,18 +81,18 @@ body {
@apply shrink-0 grow-0 flex flex-col w-1/5; @apply shrink-0 grow-0 flex flex-col w-1/5;
@apply ease-out duration-300; @apply ease-out duration-300;
@apply max-sm:hidden; @apply max-md:hidden;
} }
.sidebar.collapsed { .sidebar.collapsed {
@apply basis-0; @apply basis-0 w-0;
@apply p-0 m-0; @apply p-0 m-0;
@apply overflow-hidden; @apply overflow-hidden;
} }
.top-bar { .top-bar {
@apply flex max-sm:flex-row-reverse gap-3; @apply flex max-md:flex-row-reverse gap-3;
} }
.top-bar-buttons { .top-bar-buttons {
@ -97,11 +102,11 @@ body {
.hide-sidebar-button, .hide-sidebar-button,
.back-button, .back-button,
.forward-button { .forward-button {
@apply max-sm:hidden; @apply max-md:hidden;
} }
.open-tabs-page-button { .open-tabs-page-button {
@apply sm:hidden; @apply md:hidden;
} }
.search-input { .search-input {
@ -116,6 +121,7 @@ body {
input::placeholder { input::placeholder {
@apply color-vigi-60; @apply color-vigi-60;
@apply focus:color-vigi-50 hover:color-vigi-55; @apply focus:color-vigi-50 hover:color-vigi-55;
@apply ease-out duration-100;
} }
.tabs { .tabs {

View file

@ -7,6 +7,7 @@
import { addTab } from "$lib/utils"; import { addTab } from "$lib/utils";
import Button from "./Button.svelte"; import Button from "./Button.svelte";
import Add from "$lib/icons/Add.svelte"; import Add from "$lib/icons/Add.svelte";
import { fade } from "svelte/transition";
export let collapsed = true; export let collapsed = true;
@ -24,11 +25,10 @@
</script> </script>
<Block className={`sidebar${collapsed ? "" : " collapsed"}`} draggable> <Block className={`sidebar${collapsed ? "" : " collapsed"}`} draggable>
{#if collapsed}
<WindowControls /> <WindowControls />
<div class="tabs-category"> <div class="tabs-category">
Open tabs <div class="tabs-category-text">Open tabs</div>
<Button onClick={addTab}> <Button onClick={addTab}>
<Add /> <Add />
</Button> </Button>
@ -39,5 +39,4 @@
<Tab {tab} active={currentTabIndex === i} index={i} /> <Tab {tab} active={currentTabIndex === i} index={i} />
{/each} {/each}
</div> </div>
{/if}
</Block> </Block>