This commit is contained in:
parent
b8f59fef2a
commit
8c22c9d35d
2 changed files with 92 additions and 36 deletions
|
@ -7,7 +7,6 @@ rust-version = "1.72"
|
|||
|
||||
|
||||
[dependencies]
|
||||
arc-swap = "1.7.0"
|
||||
cosmic-jotdown = { git = "https://git.nations.lol/fnmain/cosmic-jotdown" }
|
||||
eframe = { version = "0.26.2", default-features = false, features = [
|
||||
"accesskit", # Make egui comptaible with screen readers. NOTE: adds a lot of dependencies.
|
||||
|
@ -24,8 +23,6 @@ image = { version = "0.24.9", features = ["jpeg", "png"] }
|
|||
keyframe = { version = "1.1.1", default-features = false }
|
||||
log = "0.4"
|
||||
range-map = "0.2.0"
|
||||
wasm-bindgen = "0.2.92"
|
||||
web-sys = { version = "0.3.69", features = ["Window", "History", "PopStateEvent"] }
|
||||
|
||||
# native:
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
|
@ -35,6 +32,9 @@ env_logger = "0.10"
|
|||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
wgpu = { version = "0.19.3", features = ["webgpu", "webgl"] }
|
||||
wasm-bindgen-futures = "0.4"
|
||||
wasm-bindgen = "0.2.92"
|
||||
web-sys = { version = "0.3.69", features = ["Window", "History", "PopStateEvent"] }
|
||||
arc-swap = "1.7.0"
|
||||
|
||||
|
||||
[profile.release]
|
||||
|
|
122
src/app.rs
122
src/app.rs
|
@ -1,12 +1,17 @@
|
|||
use std as alloc;
|
||||
use std::borrow::Cow;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use std::cell::RefCell;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use std::mem::ManuallyDrop;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use std::ops::Deref;
|
||||
use std::ops::DerefMut;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use alloc::cell::RefCell;
|
||||
use alloc::mem::ManuallyDrop;
|
||||
use alloc::ops::Deref;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use arc_swap::ArcSwapAny;
|
||||
use cosmic_jotdown::jotdown::{self, Event, ListKind};
|
||||
use cosmic_jotdown::{Indent, INDENT_AMOUNT};
|
||||
|
@ -47,10 +52,13 @@ pub struct Portfolio {
|
|||
window: ContextWindow,
|
||||
buffer_size: Vec2,
|
||||
max_size: Rect,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
states: Rc<RefCell<Vec<State>>>,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
next_state: Rc<ArcSwapAny<Option<Rc<State>>>>,
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum State {
|
||||
Home,
|
||||
|
@ -61,6 +69,7 @@ pub enum State {
|
|||
pub struct ContextWindow {
|
||||
pub size: Vec2,
|
||||
pub text: Vec<(Rect, Indent, ContextBlock)>,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub name: &'static str,
|
||||
}
|
||||
|
||||
|
@ -226,11 +235,11 @@ impl ContextWindow {
|
|||
pub fn set_content(
|
||||
&mut self,
|
||||
content: &'static Cow<'static, [Event<'static>]>,
|
||||
transform: Option<Mat2>,
|
||||
name: Option<&'static str>,
|
||||
#[cfg(target_arch = "wasm32")] transform: Option<Mat2>,
|
||||
#[cfg(target_arch = "wasm32")] name: Option<&'static str>,
|
||||
font_system: &mut FontSystem,
|
||||
mut max_width: f32,
|
||||
states: &mut Vec<State>,
|
||||
#[cfg(target_arch = "wasm32")] states: &mut Vec<State>,
|
||||
) {
|
||||
self.size = Vec2::new(max_width / 1.5, 0.0);
|
||||
let mut last_indent = None;
|
||||
|
@ -343,6 +352,7 @@ impl ContextWindow {
|
|||
self.size.y += size.y;
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
if let Some(name) = name {
|
||||
self.name = name;
|
||||
let state = states.len();
|
||||
|
@ -410,28 +420,35 @@ impl Portfolio {
|
|||
// Load previous app state (if any).
|
||||
// Note that you must enable the `persistence` feature for this to work.
|
||||
|
||||
let states = Rc::new(RefCell::new(Vec::new()));
|
||||
let pop_state = Rc::clone(&states);
|
||||
let next_state = Rc::new(ArcSwapAny::new(None));
|
||||
let pop_next_state = Rc::clone(&next_state);
|
||||
let popstate_closure =
|
||||
ManuallyDrop::new(wasm_bindgen::closure::Closure::<dyn FnMut(_)>::new(
|
||||
move |s: web_sys::PopStateEvent| {
|
||||
let state = s.state();
|
||||
if state.is_null() {
|
||||
pop_next_state.store(Some(Rc::new(State::Home)));
|
||||
} else {
|
||||
let state = state.as_f64().unwrap() as usize;
|
||||
let pop_state = pop_state.borrow();
|
||||
pop_next_state.store(pop_state.get(state).map(|s| Rc::new(*s)));
|
||||
}
|
||||
},
|
||||
));
|
||||
web_sys::window()
|
||||
.unwrap()
|
||||
.set_onpopstate(Some(wasm_bindgen::JsCast::unchecked_ref(
|
||||
popstate_closure.as_ref(),
|
||||
)));
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
let states;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
let next_state;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
states = Rc::new(RefCell::new(Vec::new()));
|
||||
let pop_state = Rc::clone(&states);
|
||||
next_state = Rc::new(ArcSwapAny::new(None));
|
||||
let pop_next_state = Rc::clone(&next_state);
|
||||
let popstate_closure =
|
||||
ManuallyDrop::new(wasm_bindgen::closure::Closure::<dyn FnMut(_)>::new(
|
||||
move |s: web_sys::PopStateEvent| {
|
||||
let state = s.state();
|
||||
if state.is_null() {
|
||||
pop_next_state.store(Some(Rc::new(State::Home)));
|
||||
} else {
|
||||
let state = state.as_f64().unwrap() as usize;
|
||||
let pop_state = pop_state.borrow();
|
||||
pop_next_state.store(pop_state.get(state).map(|s| Rc::new(*s)));
|
||||
}
|
||||
},
|
||||
));
|
||||
web_sys::window()
|
||||
.unwrap()
|
||||
.set_onpopstate(Some(wasm_bindgen::JsCast::unchecked_ref(
|
||||
popstate_closure.as_ref(),
|
||||
)));
|
||||
}
|
||||
|
||||
egui_extras::install_image_loaders(&cc.egui_ctx);
|
||||
let mut font_system = FontSystem::new();
|
||||
|
@ -486,12 +503,19 @@ impl Portfolio {
|
|||
buffer_size,
|
||||
window: ContextWindow::default(),
|
||||
max_size: Rect::ZERO,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
states,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
next_state,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn click(&mut self, ui: &egui::Ui, transform: Option<Mat2>, push_state: bool) {
|
||||
pub fn click(
|
||||
&mut self,
|
||||
ui: &egui::Ui,
|
||||
transform: Option<Mat2>,
|
||||
#[cfg(target_arch = "wasm32")] push_state: bool,
|
||||
) {
|
||||
self.from_size = self.to_size;
|
||||
self.from_pos = self.to_pos;
|
||||
self.click_time_offset = ui.input(|i| i.time);
|
||||
|
@ -499,6 +523,7 @@ impl Portfolio {
|
|||
self.to_size = 0.6;
|
||||
self.to_pos = [0.0, 0.0];
|
||||
self.zoomed = false;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
if push_state {
|
||||
let mut states = self.states.borrow_mut();
|
||||
let state = states.len();
|
||||
|
@ -596,6 +621,7 @@ impl Portfolio {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
fn update_state(&mut self, ui: &mut egui::Ui) {
|
||||
if let Some(state) = self.next_state.load().deref() {
|
||||
log::info!("update_state");
|
||||
|
@ -632,6 +658,7 @@ impl eframe::App for Portfolio {
|
|||
.frame(Frame::default().fill(Color32::BLACK))
|
||||
.show(ctx, |ui| {
|
||||
self.update_customs(ui);
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
self.update_state(ui);
|
||||
self.custom.custom_painting(ui);
|
||||
if ui.max_rect() != self.max_size {
|
||||
|
@ -921,7 +948,12 @@ impl eframe::App for Portfolio {
|
|||
self.image_zoomed = false;
|
||||
});
|
||||
} else if icon_link.is_none() {
|
||||
self.click(ui, None, true);
|
||||
self.click(
|
||||
ui,
|
||||
None,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -938,13 +970,21 @@ impl eframe::App for Portfolio {
|
|||
}
|
||||
|
||||
if name_resp.clicked() {
|
||||
self.click(ui, None, true);
|
||||
self.click(
|
||||
ui,
|
||||
None,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
true,
|
||||
);
|
||||
self.window.set_content(
|
||||
&ABOUT_ME,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
None,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
Some("About Me"),
|
||||
self.font_system.lock().deref_mut(),
|
||||
ui.max_rect().width(),
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
self.states.borrow_mut().deref_mut(),
|
||||
);
|
||||
}
|
||||
|
@ -991,13 +1031,21 @@ impl eframe::App for Portfolio {
|
|||
if response.clicked() {
|
||||
self.window.set_content(
|
||||
i.content,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
Some(transform),
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
Some(i.name),
|
||||
self.font_system.lock().deref_mut(),
|
||||
ui.max_rect().width(),
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
self.states.borrow_mut().deref_mut(),
|
||||
);
|
||||
self.click(ui, Some(transform), true);
|
||||
self.click(
|
||||
ui,
|
||||
Some(transform),
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
true,
|
||||
);
|
||||
scroll_area.state.offset = Vec2::ZERO;
|
||||
scroll_area.state.store(ui.ctx(), scroll_area.id);
|
||||
}
|
||||
|
@ -1014,15 +1062,23 @@ impl eframe::App for Portfolio {
|
|||
let transform = glam::Mat2::from_angle((-icon.angle_at).to_radians());
|
||||
self.window.set_content(
|
||||
icon.content,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
Some(transform),
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
Some(icon.name),
|
||||
self.font_system.lock().deref_mut(),
|
||||
ui.max_rect().width(),
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
self.states.borrow_mut().deref_mut(),
|
||||
);
|
||||
|
||||
self.zoomed = false;
|
||||
self.click(ui, Some(transform), true);
|
||||
self.click(
|
||||
ui,
|
||||
Some(transform),
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
true,
|
||||
);
|
||||
self.zoomed = true;
|
||||
|
||||
scroll_area.state.offset = Vec2::ZERO;
|
||||
|
|
Loading…
Reference in a new issue