store previous function data in local storage

This should maybe be done through website's hash instead? but idk
This commit is contained in:
Simon Gardling 2022-05-11 22:39:46 -04:00
parent 30475eb4f4
commit 3d7f313c18
4 changed files with 158 additions and 10 deletions

12
Cargo.lock generated
View File

@ -668,7 +668,7 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]]
name = "eframe"
version = "0.18.0"
source = "git+https://github.com/Titaniumtown/egui.git#2bfdd60400da7f1f7139e58858bc4910d166f1a0"
source = "git+https://github.com/Titaniumtown/egui.git#49b732b071a0e5e2eb7dbb6896cd7bf1c3ca687d"
dependencies = [
"bytemuck",
"egui",
@ -688,7 +688,7 @@ dependencies = [
[[package]]
name = "egui"
version = "0.18.1"
source = "git+https://github.com/Titaniumtown/egui.git#2bfdd60400da7f1f7139e58858bc4910d166f1a0"
source = "git+https://github.com/Titaniumtown/egui.git#49b732b071a0e5e2eb7dbb6896cd7bf1c3ca687d"
dependencies = [
"ahash",
"epaint",
@ -699,7 +699,7 @@ dependencies = [
[[package]]
name = "egui-winit"
version = "0.18.0"
source = "git+https://github.com/Titaniumtown/egui.git#2bfdd60400da7f1f7139e58858bc4910d166f1a0"
source = "git+https://github.com/Titaniumtown/egui.git#49b732b071a0e5e2eb7dbb6896cd7bf1c3ca687d"
dependencies = [
"arboard",
"egui",
@ -712,7 +712,7 @@ dependencies = [
[[package]]
name = "egui_glow"
version = "0.18.1"
source = "git+https://github.com/Titaniumtown/egui.git#2bfdd60400da7f1f7139e58858bc4910d166f1a0"
source = "git+https://github.com/Titaniumtown/egui.git#49b732b071a0e5e2eb7dbb6896cd7bf1c3ca687d"
dependencies = [
"bytemuck",
"egui",
@ -732,7 +732,7 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "emath"
version = "0.18.0"
source = "git+https://github.com/Titaniumtown/egui.git#2bfdd60400da7f1f7139e58858bc4910d166f1a0"
source = "git+https://github.com/Titaniumtown/egui.git#49b732b071a0e5e2eb7dbb6896cd7bf1c3ca687d"
dependencies = [
"bytemuck",
"serde",
@ -741,7 +741,7 @@ dependencies = [
[[package]]
name = "epaint"
version = "0.18.1"
source = "git+https://github.com/Titaniumtown/egui.git#2bfdd60400da7f1f7139e58858bc4910d166f1a0"
source = "git+https://github.com/Titaniumtown/egui.git#49b732b071a0e5e2eb7dbb6896cd7bf1c3ca687d"
dependencies = [
"ab_glyph",
"ahash",

View File

@ -8,8 +8,9 @@ use egui::{
Checkbox, Context,
};
use epaint::Color32;
use parsing::AutoComplete;
use parsing::{generate_hint, AutoComplete};
use parsing::{process_func_str, BackingFunction};
use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer};
use std::{
fmt::{self, Debug},
intrinsics::assume,
@ -66,6 +67,56 @@ pub struct FunctionEntry {
pub settings_opened: bool,
}
impl Serialize for FunctionEntry {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut s = serializer.serialize_struct("FunctionEntry", 4)?;
s.serialize_field("raw_func_str", &self.raw_func_str)?;
s.serialize_field("integral", &self.integral)?;
s.serialize_field("derivative", &self.derivative)?;
s.serialize_field("curr_nth", &self.curr_nth)?;
s.end()
}
}
impl<'de> Deserialize<'de> for FunctionEntry {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct Helper {
raw_func_str: String,
integral: bool,
derivative: bool,
curr_nth: usize,
}
let helper = Helper::deserialize(deserializer)?;
let mut new_func_entry = FunctionEntry::EMPTY;
let gen_func = BackingFunction::new(&helper.raw_func_str);
match gen_func {
Ok(func) => new_func_entry.function = func,
Err(x) => new_func_entry.test_result = Some(x),
}
new_func_entry.autocomplete = AutoComplete {
i: 0,
hint: generate_hint(&helper.raw_func_str),
string: helper.raw_func_str,
};
new_func_entry.integral = helper.integral;
new_func_entry.derivative = helper.derivative;
new_func_entry.curr_nth = helper.curr_nth;
Ok(new_func_entry)
}
}
impl const Default for FunctionEntry {
/// Creates default FunctionEntry instance (which is empty)
fn default() -> FunctionEntry { FunctionEntry::EMPTY }

View File

@ -5,6 +5,11 @@ use egui::{Button, Id, Key, Modifiers, TextEdit, WidgetText};
use emath::vec2;
use parsing::Hint;
use parsing::Movement;
use serde::ser::SerializeStruct;
use serde::Deserialize;
use serde::Deserializer;
use serde::Serialize;
use serde::Serializer;
use std::ops::BitXorAssign;
use uuid::Uuid;
@ -23,6 +28,46 @@ impl Default for FunctionManager {
}
}
impl Serialize for FunctionManager {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut s = serializer.serialize_struct("FunctionManager", 1)?;
s.serialize_field(
"data",
&self
.functions
.iter()
.cloned()
.map(|(id, func)| (id.value(), func))
.collect::<Vec<(u64, FunctionEntry)>>(),
)?;
s.end()
}
}
impl<'de> Deserialize<'de> for FunctionManager {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct Helper(Vec<(u64, FunctionEntry)>);
let helper = Helper::deserialize(deserializer)?;
Ok(FunctionManager {
functions: helper
.0
.iter()
.cloned()
.map(|(id, func)| (egui::Id::new_from_u64(id), func))
.collect::<Vec<(Id, FunctionEntry)>>(),
})
}
}
/// Function that creates button that's used with the `button_area`
const fn button_area_button(text: impl Into<WidgetText>) -> Button {
Button::new(text).frame(false)

View File

@ -10,7 +10,7 @@ use egui::{
};
use emath::{Align, Align2};
use epaint::Rounding;
use instant::Duration;
use instant::{Duration, Instant};
use std::{io::Read, ops::BitXorAssign};
#[cfg(threading)]
@ -98,6 +98,9 @@ pub struct MathApp {
/// Stores settings (pretty self-explanatory)
settings: AppSettings,
#[cfg(target_arch = "wasm32")]
since_last_save: Instant,
}
impl MathApp {
@ -111,7 +114,7 @@ impl MathApp {
tracing::info!("Threading: Disabled");
tracing::info!("Initializing...");
let start = instant::Instant::now();
let start = Instant::now();
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
@ -164,12 +167,33 @@ impl MathApp {
panic!("unable to get local storage")
}
}
fn get_functions() -> Option<FunctionManager> {
if let Ok(Some(data)) = web_sys::window().expect("Could not get web_sys window").local_storage().unwrap().unwrap().get_item("YTBN-FUNCTIONS") {
let (commit, func_data) = crate::misc::storage_read(data);
if commit == build::SHORT_COMMIT {
tracing::info!("Reading old functions");
let function_manager: FunctionManager = bincode::deserialize(&func_data).unwrap();
return Some(function_manager);
} else {
// is invalid
None
}
} else {
None
}
}
} else {
const fn get_storage_decompressed() -> Option<Vec<u8>> {
None
}
const fn set_storage_decompressed(_: &Vec<u8>) {}
const fn get_functions() -> Option<FunctionManager> { None }
}
}
@ -214,12 +238,14 @@ impl MathApp {
loading_element.remove();
Self {
functions: Default::default(),
functions: get_functions().unwrap_or(FunctionManager::default()),
last_info: (vec![None], None),
dark_mode: true, // dark mode is default and is previously set
text: data.text,
opened: Opened::default(),
settings: Default::default(),
#[cfg(target_arch = "wasm32")]
since_last_save: Instant::now(),
}
}
@ -562,5 +588,31 @@ impl App for MathApp {
// Calculate and store the last time it took to draw the frame
self.last_info.1 = start.map(|a| a.elapsed());
#[cfg(target_arch = "wasm32")]
{
if self.since_last_save.elapsed().as_millis() > 10000 {
self.since_last_save = Instant::now();
if let Ok(Some(local_storage)) = web_sys::window()
.expect("Could not get web_sys window")
.local_storage()
{
tracing::info!("Setting current functions");
let saved_data = &crate::misc::storage_create(
&build::SHORT_COMMIT
.chars()
.map(|c| c as u8)
.collect::<Vec<u8>>(),
bincode::serialize(&self.functions).unwrap().as_slice(),
);
tracing::info!("Data has length of {}", saved_data.len());
local_storage
.set_item("YTBN-FUNCTIONS", saved_data)
.expect("failed to set local function storage");
} else {
panic!("unable to get local storage")
}
}
}
}
}