mirror of
https://github.com/TxtDot/vigi.git
synced 2024-11-23 11:56:21 +03:00
fix: rewrite state system
This commit is contained in:
parent
7bb18fd062
commit
febafc94df
12 changed files with 243 additions and 158 deletions
4
src-tauri/Cargo.lock
generated
4
src-tauri/Cargo.lock
generated
|
@ -501,9 +501,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dalet"
|
name = "dalet"
|
||||||
version = "1.0.0-pre2"
|
version = "1.0.0-pre3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7a4c96bc370794e34c34ed93abe3f04140b9909bc80b942b98a9abd7b8c248d"
|
checksum = "c629ef0fc95fddd843a73e72de3f509665a73f51323f7b6c1b7946eb8937b660"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
|
@ -25,7 +25,7 @@ tauri = { version = "1", features = [
|
||||||
] }
|
] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
dalet = "1.0.0-pre2"
|
dalet = "1.0.0-pre3"
|
||||||
reqwest = "0.12.5"
|
reqwest = "0.12.5"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
@ -1,118 +1,79 @@
|
||||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||||
|
|
||||||
use std::{
|
use std::fs::{self};
|
||||||
fs::{self},
|
|
||||||
sync::Mutex,
|
|
||||||
};
|
|
||||||
|
|
||||||
use dalet::{Argument, Body, Tag};
|
|
||||||
|
|
||||||
mod types;
|
mod types;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use tauri::Manager;
|
use tauri::async_runtime::Mutex;
|
||||||
use types::{TabType, VigiError, VigiState};
|
use types::{VigiError, VigiJsState, VigiState};
|
||||||
use utils::{read_or_create_jsonl, read_or_create_number};
|
use utils::{read_or_create_jsonl, read_or_create_number};
|
||||||
|
|
||||||
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn process_input(
|
async fn update_input(
|
||||||
input: String,
|
input: String,
|
||||||
state: tauri::State<'_, Mutex<VigiState>>,
|
state: tauri::State<'_, Mutex<VigiState>>,
|
||||||
) -> Result<Vec<Tag>, VigiError> {
|
|
||||||
// TODO: Implement mime type, language, protocol or search detection
|
|
||||||
// TODO: Implement text links parsing
|
|
||||||
|
|
||||||
println!("Processing: {}", input);
|
|
||||||
|
|
||||||
match reqwest::get(input.clone()).await {
|
|
||||||
Ok(res) => match res.text().await {
|
|
||||||
Ok(res) => {
|
|
||||||
update_tab(state, TabType::Text, res.clone(), input.clone())?;
|
|
||||||
Ok(vec![Tag::new(0, Body::Text(res), Argument::Null)])
|
|
||||||
}
|
|
||||||
Err(_) => Err(VigiError::Parse),
|
|
||||||
},
|
|
||||||
Err(_) => Err(VigiError::Network),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn get_state(state: tauri::State<Mutex<VigiState>>) -> VigiState {
|
|
||||||
(*state.lock().unwrap()).clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn select_tab(state: tauri::State<Mutex<VigiState>>, index: usize) -> Result<(), VigiError> {
|
|
||||||
match state.lock() {
|
|
||||||
Ok(mut state) => {
|
|
||||||
state.update_current_tab_index(index)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Err(_) => Err(VigiError::StateLock),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn add_tab(state: tauri::State<Mutex<VigiState>>) -> Result<(), VigiError> {
|
|
||||||
match state.lock() {
|
|
||||||
Ok(mut state) => {
|
|
||||||
state.add_tab()?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Err(_) => Err(VigiError::StateLock),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn remove_tab(state: tauri::State<Mutex<VigiState>>, index: usize) -> Result<(), VigiError> {
|
|
||||||
match state.lock() {
|
|
||||||
Ok(mut state) => {
|
|
||||||
state.remove_tab(index)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Err(_) => Err(VigiError::StateLock),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_tab(
|
|
||||||
state: tauri::State<Mutex<VigiState>>,
|
|
||||||
tab_type: TabType,
|
|
||||||
tab_title: String,
|
|
||||||
tab_url: String,
|
|
||||||
) -> Result<(), VigiError> {
|
) -> Result<(), VigiError> {
|
||||||
match state.lock() {
|
state.lock().await.update_input(input).await
|
||||||
Ok(mut state) => {
|
}
|
||||||
state.update_tab(tab_type, tab_title, tab_url)?;
|
|
||||||
Ok(())
|
#[tauri::command]
|
||||||
}
|
async fn get_js_state(state: tauri::State<'_, Mutex<VigiState>>) -> Result<VigiJsState, VigiError> {
|
||||||
Err(_) => Err(VigiError::StateLock),
|
Ok(state.lock().await.get_js_state())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn select_tab(
|
||||||
|
index: usize,
|
||||||
|
state: tauri::State<'_, Mutex<VigiState>>,
|
||||||
|
) -> Result<(), VigiError> {
|
||||||
|
state.lock().await.select_tab(index).await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn load_tab(state: tauri::State<'_, Mutex<VigiState>>) -> Result<(), VigiError> {
|
||||||
|
state.lock().await.load_tab().await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn add_tab(state: tauri::State<'_, Mutex<VigiState>>) -> Result<(), VigiError> {
|
||||||
|
state.lock().await.add_tab()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn remove_tab(
|
||||||
|
state: tauri::State<'_, Mutex<VigiState>>,
|
||||||
|
index: usize,
|
||||||
|
) -> Result<(), VigiError> {
|
||||||
|
state.lock().await.remove_tab(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.manage(Mutex::new(VigiState::null()))
|
.manage(Mutex::new(VigiState::null()))
|
||||||
.setup(setup_handler)
|
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
process_input,
|
update_input,
|
||||||
get_state,
|
get_js_state,
|
||||||
select_tab,
|
select_tab,
|
||||||
|
load_tab,
|
||||||
add_tab,
|
add_tab,
|
||||||
remove_tab
|
remove_tab,
|
||||||
|
setup
|
||||||
])
|
])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_handler(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error + 'static>> {
|
#[tauri::command]
|
||||||
|
async fn setup(
|
||||||
|
state: tauri::State<'_, Mutex<VigiState>>,
|
||||||
|
app_handle: tauri::AppHandle,
|
||||||
|
) -> Result<(), VigiError> {
|
||||||
println!("---Setup---");
|
println!("---Setup---");
|
||||||
|
|
||||||
let app_handle = app.handle();
|
let mut state = state.lock().await;
|
||||||
|
|
||||||
let state = app.state::<Mutex<VigiState>>();
|
|
||||||
let mut state = state.lock().unwrap();
|
|
||||||
|
|
||||||
let config_dir = app_handle
|
let config_dir = app_handle
|
||||||
.path_resolver()
|
.path_resolver()
|
||||||
|
@ -138,7 +99,7 @@ fn setup_handler(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error +
|
||||||
// check if config/favorites.jsonl exists
|
// check if config/favorites.jsonl exists
|
||||||
if !config_dir.exists() {
|
if !config_dir.exists() {
|
||||||
println!(" Creating config dir");
|
println!(" Creating config dir");
|
||||||
fs::create_dir_all(&config_dir)?;
|
fs::create_dir_all(&config_dir).map_err(|_| VigiError::Config)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.favorites_tabs_path = config_dir.join("favorites.jsonl");
|
state.favorites_tabs_path = config_dir.join("favorites.jsonl");
|
||||||
|
@ -147,7 +108,7 @@ fn setup_handler(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error +
|
||||||
println!("Checking local data dir");
|
println!("Checking local data dir");
|
||||||
if !local_data_dir.exists() {
|
if !local_data_dir.exists() {
|
||||||
println!(" Creating local data dir");
|
println!(" Creating local data dir");
|
||||||
fs::create_dir_all(&local_data_dir)?;
|
fs::create_dir_all(&local_data_dir).map_err(|_| VigiError::Config)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.local_tabs_path = local_data_dir.join("tabs.jsonl");
|
state.local_tabs_path = local_data_dir.join("tabs.jsonl");
|
||||||
|
@ -159,6 +120,8 @@ fn setup_handler(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error +
|
||||||
state.current_tab_index_path = local_data_dir.join("current_tab_index");
|
state.current_tab_index_path = local_data_dir.join("current_tab_index");
|
||||||
state.current_tab_index = read_or_create_number(&state.current_tab_index_path);
|
state.current_tab_index = read_or_create_number(&state.current_tab_index_path);
|
||||||
|
|
||||||
|
state.update_top_bar_input();
|
||||||
|
|
||||||
println!("---Setup done---");
|
println!("---Setup done---");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use dalet::{Argument, Body, Tag};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{fs, path::PathBuf};
|
use std::{fs, path::PathBuf};
|
||||||
|
|
||||||
|
@ -9,9 +10,11 @@ pub enum VigiError {
|
||||||
Parse,
|
Parse,
|
||||||
StateLock,
|
StateLock,
|
||||||
StateUpdate,
|
StateUpdate,
|
||||||
|
Filesystem,
|
||||||
|
Config,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, 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,
|
||||||
|
@ -20,10 +23,25 @@ pub struct VigiState {
|
||||||
|
|
||||||
pub cache_dir: PathBuf,
|
pub cache_dir: PathBuf,
|
||||||
|
|
||||||
|
// Persistent
|
||||||
pub tabs_id_counter: usize,
|
pub tabs_id_counter: usize,
|
||||||
pub current_tab_index: usize,
|
pub current_tab_index: usize,
|
||||||
pub tabs: Vec<Tab>,
|
pub tabs: Vec<Tab>,
|
||||||
pub favorites_tabs: Vec<Tab>,
|
pub favorites_tabs: Vec<Tab>,
|
||||||
|
|
||||||
|
// Temporary
|
||||||
|
pub top_bar_input: String,
|
||||||
|
pub current_data: Vec<Tag>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug, Clone)]
|
||||||
|
pub struct VigiJsState {
|
||||||
|
pub current_tab_index: usize,
|
||||||
|
pub tabs: Vec<Tab>,
|
||||||
|
pub favorites_tabs: Vec<Tab>,
|
||||||
|
|
||||||
|
pub top_bar_input: String,
|
||||||
|
pub current_data: Vec<Tag>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VigiState {
|
impl VigiState {
|
||||||
|
@ -39,16 +57,24 @@ impl VigiState {
|
||||||
current_tab_index: 0,
|
current_tab_index: 0,
|
||||||
tabs: Vec::new(),
|
tabs: Vec::new(),
|
||||||
favorites_tabs: Vec::new(),
|
favorites_tabs: Vec::new(),
|
||||||
|
|
||||||
|
top_bar_input: "".to_string(),
|
||||||
|
current_data: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_current_tab_index(&mut self, new_index: usize) -> Result<(), VigiError> {
|
pub async fn select_tab(&mut self, new_index: usize) -> Result<(), VigiError> {
|
||||||
self.current_tab_index = new_index;
|
self.current_tab_index = new_index;
|
||||||
|
|
||||||
self.write_current_tab_index()?;
|
self.write_current_tab_index()?;
|
||||||
|
|
||||||
|
self.update_top_bar_input();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_top_bar_input(&mut self) {
|
||||||
|
self.top_bar_input = self.tabs[self.current_tab_index].url.clone();
|
||||||
|
}
|
||||||
|
|
||||||
fn write_current_tab_index(&mut self) -> Result<(), VigiError> {
|
fn write_current_tab_index(&mut self) -> Result<(), VigiError> {
|
||||||
fs::write(
|
fs::write(
|
||||||
&self.current_tab_index_path,
|
&self.current_tab_index_path,
|
||||||
|
@ -62,7 +88,61 @@ impl VigiState {
|
||||||
.map_err(|_| VigiError::StateUpdate)
|
.map_err(|_| VigiError::StateUpdate)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_tab(
|
async fn process_input(&mut self) -> Result<(), VigiError> {
|
||||||
|
// TODO: Implement mime type, language, protocol or search detection
|
||||||
|
// TODO: Implement text links parsing
|
||||||
|
|
||||||
|
println!("process_input {{\n \"{}\"", self.top_bar_input);
|
||||||
|
|
||||||
|
let result = match self.top_bar_input.as_str() {
|
||||||
|
"" => {
|
||||||
|
self.update_tab(TabType::HomePage, "Home".to_owned(), "".to_owned())?;
|
||||||
|
|
||||||
|
self.current_data = vec![Tag::new(
|
||||||
|
0,
|
||||||
|
Body::Text("Type something in the address bar".to_owned()),
|
||||||
|
Argument::Null,
|
||||||
|
)];
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
input => match reqwest::get(input).await {
|
||||||
|
Ok(res) => match res.text().await {
|
||||||
|
Ok(res) => {
|
||||||
|
let mut truncated = res.clone();
|
||||||
|
truncated.truncate(50);
|
||||||
|
|
||||||
|
self.update_tab(TabType::Text, truncated, input.to_owned())?;
|
||||||
|
|
||||||
|
self.current_data = vec![Tag::new(0, Body::Text(res), Argument::Null)];
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(_) => Err(VigiError::Parse),
|
||||||
|
},
|
||||||
|
Err(_) => Err(VigiError::Network),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if result.is_ok() {
|
||||||
|
println!(" Ok\n}}");
|
||||||
|
} else {
|
||||||
|
println!(" Err\n}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn update_input(&mut self, input: String) -> Result<(), VigiError> {
|
||||||
|
self.top_bar_input = input;
|
||||||
|
self.process_input().await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn load_tab(&mut self) -> Result<(), VigiError> {
|
||||||
|
self.process_input().await
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_tab(
|
||||||
&mut self,
|
&mut self,
|
||||||
tab_type: TabType,
|
tab_type: TabType,
|
||||||
tab_title: String,
|
tab_title: String,
|
||||||
|
@ -84,7 +164,7 @@ impl VigiState {
|
||||||
self.tabs_id_counter += 1;
|
self.tabs_id_counter += 1;
|
||||||
self.tabs.push(Tab::new(
|
self.tabs.push(Tab::new(
|
||||||
TabType::HomePage,
|
TabType::HomePage,
|
||||||
"New tab".to_string(),
|
"Home".to_string(),
|
||||||
"".to_string(),
|
"".to_string(),
|
||||||
self.tabs_id_counter,
|
self.tabs_id_counter,
|
||||||
));
|
));
|
||||||
|
@ -95,6 +175,8 @@ impl VigiState {
|
||||||
self.current_tab_index = self.tabs.len() - 1;
|
self.current_tab_index = self.tabs.len() - 1;
|
||||||
self.write_current_tab_index()?;
|
self.write_current_tab_index()?;
|
||||||
|
|
||||||
|
self.update_top_bar_input();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,14 +194,25 @@ impl VigiState {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_js_state(&self) -> VigiJsState {
|
||||||
|
VigiJsState {
|
||||||
|
current_tab_index: self.current_tab_index,
|
||||||
|
tabs: self.tabs.clone(),
|
||||||
|
favorites_tabs: self.favorites_tabs.clone(),
|
||||||
|
|
||||||
|
top_bar_input: self.top_bar_input.clone(),
|
||||||
|
current_data: self.current_data.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct Tab {
|
pub struct Tab {
|
||||||
ty: TabType,
|
pub ty: TabType,
|
||||||
title: String,
|
pub title: String,
|
||||||
url: String,
|
pub url: String,
|
||||||
id: usize,
|
pub id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tab {
|
impl Tab {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@apply bg-vigi-90 text-vigi-10;
|
@apply bg-vigi-90 text-vigi-10 cursor-default;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.browser-window {
|
.browser-window {
|
||||||
@apply grow shadow-inner overflow-auto select-text;
|
@apply grow shadow-inner overflow-auto select-text cursor-auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.window-controls {
|
.window-controls {
|
||||||
|
@ -48,7 +48,7 @@ body {
|
||||||
@apply active:bg-vigi-100;
|
@apply active:bg-vigi-100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.open-tabs {
|
.tabs-category {
|
||||||
@apply flex justify-between mt-2 mx-2;
|
@apply flex justify-between mt-2 mx-2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,24 @@
|
||||||
import type { Root } from "@txtdot/dalet";
|
import type { Root } from "@txtdot/dalet";
|
||||||
import Block from "./Block.svelte";
|
import Block from "./Block.svelte";
|
||||||
import Renderer from "./DaletlRenderer/Renderer.svelte";
|
import Renderer from "./DaletlRenderer/Renderer.svelte";
|
||||||
|
import { isLoading, state } from "$lib/stores";
|
||||||
|
import type { VigiState } from "$lib/types";
|
||||||
|
|
||||||
export let data: Root;
|
let loading = false;
|
||||||
export let isLoading = false;
|
|
||||||
|
let data: Root;
|
||||||
|
|
||||||
|
state.subscribe((st) => {
|
||||||
|
data = (st as VigiState).current_data;
|
||||||
|
});
|
||||||
|
|
||||||
|
isLoading.subscribe((val) => {
|
||||||
|
loading = val;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Block className="browser-window">
|
<Block className="browser-window">
|
||||||
{#if isLoading}
|
{#if loading}
|
||||||
<div>Loading...</div>
|
<div>Loading...</div>
|
||||||
{:else}
|
{:else}
|
||||||
<Renderer {data} />
|
<Renderer {data} />
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
{#if collapsed}
|
{#if collapsed}
|
||||||
<WindowControls />
|
<WindowControls />
|
||||||
|
|
||||||
<div class="open-tabs">
|
<div class="tabs-category">
|
||||||
Open tabs
|
Open tabs
|
||||||
<Button onClick={addTab}>
|
<Button onClick={addTab}>
|
||||||
<Add />
|
<Add />
|
||||||
|
|
|
@ -4,21 +4,21 @@
|
||||||
import Reload from "$lib/icons/Reload.svelte";
|
import Reload from "$lib/icons/Reload.svelte";
|
||||||
import SidebarLeft from "$lib/icons/SidebarLeft.svelte";
|
import SidebarLeft from "$lib/icons/SidebarLeft.svelte";
|
||||||
import SidebarRight from "$lib/icons/SidebarRight.svelte";
|
import SidebarRight from "$lib/icons/SidebarRight.svelte";
|
||||||
import { topBarInput } from "$lib/stores";
|
import { state } from "$lib/stores";
|
||||||
|
import { updateInput } from "$lib/utils";
|
||||||
import Block from "./Block.svelte";
|
import Block from "./Block.svelte";
|
||||||
import Button from "./Button.svelte";
|
import Button from "./Button.svelte";
|
||||||
|
|
||||||
export let onBack = () => {};
|
export let onBack = () => {};
|
||||||
export let onForward = () => {};
|
export let onForward = () => {};
|
||||||
export let onInput = () => {};
|
|
||||||
|
|
||||||
export let sidebarOpen = true;
|
export let sidebarOpen = true;
|
||||||
|
|
||||||
let currentInput = "";
|
let currentInput = "";
|
||||||
let input = "";
|
let input = "";
|
||||||
|
|
||||||
topBarInput.subscribe((val) => {
|
state.subscribe((val) => {
|
||||||
input = val;
|
input = val.top_bar_input;
|
||||||
currentInput = decodeURIComponent(input);
|
currentInput = decodeURIComponent(input);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={onBack}><ArrowLeft /></Button>
|
<Button onClick={onBack}><ArrowLeft /></Button>
|
||||||
<Button onClick={onForward}><ArrowRight /></Button>
|
<Button onClick={onForward}><ArrowRight /></Button>
|
||||||
<Button onClick={onInput}><Reload /></Button>
|
<Button onClick={() => updateInput(input)}><Reload /></Button>
|
||||||
</Block>
|
</Block>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
|
@ -47,8 +47,7 @@
|
||||||
bind:this={iEl}
|
bind:this={iEl}
|
||||||
on:keypress={(e) => {
|
on:keypress={(e) => {
|
||||||
if (e.key === "Enter") {
|
if (e.key === "Enter") {
|
||||||
topBarInput.set(currentInput);
|
updateInput(currentInput);
|
||||||
onInput();
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
on:focus={() => {
|
on:focus={() => {
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
import { writable, type Writable } from "svelte/store";
|
import { writable, type Writable } from "svelte/store";
|
||||||
import type { VigiState } from "./types";
|
import type { VigiState } from "./types";
|
||||||
|
|
||||||
export const topBarInput: Writable<string> = writable("");
|
export const state: Writable<VigiState> = writable({
|
||||||
|
current_tab_index: 0,
|
||||||
|
tabs: [{ id: 0, ty: "HomePage", title: "Home", url: "" }],
|
||||||
|
favorites_tabs: [],
|
||||||
|
top_bar_input: "",
|
||||||
|
current_data: [],
|
||||||
|
});
|
||||||
|
|
||||||
export const state: Writable<VigiState> = writable();
|
export const isLoading: Writable<boolean> = writable(false);
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
|
import type { Tag } from "@txtdot/dalet";
|
||||||
|
|
||||||
export interface VigiState {
|
export interface VigiState {
|
||||||
current_tab_index: number;
|
current_tab_index: number;
|
||||||
tabs: StateTab[];
|
tabs: StateTab[];
|
||||||
favorites_tabs: StateTab[];
|
favorites_tabs: StateTab[];
|
||||||
|
|
||||||
|
top_bar_input: string;
|
||||||
|
current_data: Tag[];
|
||||||
}
|
}
|
||||||
|
|
||||||
type TabType = "HomePage" | "Text";
|
type TabType = "HomePage" | "Text";
|
||||||
|
|
|
@ -1,32 +1,52 @@
|
||||||
import { invoke } from "@tauri-apps/api";
|
import { invoke } from "@tauri-apps/api";
|
||||||
import { state, topBarInput } from "./stores";
|
import { isLoading, state } from "./stores";
|
||||||
import type { StateTab, VigiState } from "./types";
|
import type { VigiState } from "./types";
|
||||||
|
|
||||||
export function updateVigiState() {
|
export async function updateVigiState() {
|
||||||
invoke("get_state")
|
try {
|
||||||
.then((r) => {
|
let st = await invoke("get_js_state");
|
||||||
let st = r as VigiState;
|
state.set(st as VigiState);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state.set(st);
|
export async function updateInput(input: string) {
|
||||||
|
isLoading.set(true);
|
||||||
|
|
||||||
topBarInput.set(st.tabs[st.current_tab_index].url);
|
try {
|
||||||
})
|
await invoke("update_input", { input });
|
||||||
.catch((err) => console.log(err));
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
} finally {
|
||||||
|
await updateVigiState();
|
||||||
|
isLoading.set(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addTab() {
|
export async function addTab() {
|
||||||
await invoke("add_tab");
|
await invoke("add_tab");
|
||||||
|
await updateVigiState();
|
||||||
updateVigiState();
|
await loadTab();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function selectTab(index: number) {
|
export async function selectTab(index: number) {
|
||||||
await invoke("select_tab", { index });
|
await invoke("select_tab", { index });
|
||||||
|
await updateVigiState();
|
||||||
updateVigiState();
|
await loadTab();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function removeTab(index: number) {
|
export async function removeTab(index: number) {
|
||||||
await invoke("remove_tab", { index });
|
await invoke("remove_tab", { index });
|
||||||
updateVigiState();
|
await updateVigiState();
|
||||||
|
await loadTab();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadTab() {
|
||||||
|
isLoading.set(true);
|
||||||
|
|
||||||
|
await invoke("load_tab");
|
||||||
|
await updateVigiState();
|
||||||
|
|
||||||
|
isLoading.set(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,43 +4,31 @@
|
||||||
import TopBar from "$lib/components/TopBar.svelte";
|
import TopBar from "$lib/components/TopBar.svelte";
|
||||||
import Sidebar from "$lib/components/Sidebar.svelte";
|
import Sidebar from "$lib/components/Sidebar.svelte";
|
||||||
import BrowserWindow from "$lib/components/BrowserWindow.svelte";
|
import BrowserWindow from "$lib/components/BrowserWindow.svelte";
|
||||||
import type { Root } from "@txtdot/dalet";
|
|
||||||
|
|
||||||
import { invoke } from "@tauri-apps/api/tauri";
|
import { invoke } from "@tauri-apps/api/tauri";
|
||||||
import { topBarInput } from "$lib/stores";
|
import { loadTab, updateVigiState } from "$lib/utils";
|
||||||
import { updateVigiState } from "$lib/utils";
|
import { isLoading } from "$lib/stores";
|
||||||
|
|
||||||
let sidebarOpen = true;
|
let sidebarOpen = true;
|
||||||
|
|
||||||
let isLoading = false;
|
(async () => {
|
||||||
|
isLoading.set(true);
|
||||||
let data: Root = [];
|
await invoke("setup");
|
||||||
|
await updateVigiState();
|
||||||
updateVigiState();
|
await loadTab();
|
||||||
|
isLoading.set(false);
|
||||||
|
})();
|
||||||
|
|
||||||
document.addEventListener("keypress", (e: KeyboardEvent) => {
|
document.addEventListener("keypress", (e: KeyboardEvent) => {
|
||||||
const formElements = ["INPUT", "TEXTAREA", "SELECT", "OPTION"];
|
if (
|
||||||
if (formElements.includes((e.target as Element).tagName)) {
|
["INPUT", "TEXTAREA", "SELECT", "OPTION"].includes(
|
||||||
|
(e.target as Element).tagName
|
||||||
|
)
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.key === "q") sidebarOpen = !sidebarOpen;
|
if (e.key === "q") sidebarOpen = !sidebarOpen;
|
||||||
});
|
});
|
||||||
|
|
||||||
topBarInput.subscribe((input) => {
|
|
||||||
isLoading = true;
|
|
||||||
invoke("process_input", { input })
|
|
||||||
.then((res) => {
|
|
||||||
data = res as Root;
|
|
||||||
isLoading = false;
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
data = [{ id: 0, body: "Error: " + err, argument: null }];
|
|
||||||
isLoading = false;
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
updateVigiState();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -51,6 +39,6 @@
|
||||||
|
|
||||||
<div class="main-window">
|
<div class="main-window">
|
||||||
<TopBar bind:sidebarOpen />
|
<TopBar bind:sidebarOpen />
|
||||||
<BrowserWindow {data} bind:isLoading />
|
<BrowserWindow />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue