web: add tablet rendering, listen to window resize events.

This commit is contained in:
Bill Thiede 2023-12-02 10:56:14 -08:00
parent 4c2526c70b
commit 714b057fdb
5 changed files with 61 additions and 19 deletions

View File

@ -133,7 +133,7 @@ blockquote[type="cite"],
}
*/
.desktop-main-content {
.desktop .main-content {
display: grid;
grid-template-columns: 12rem 1fr;
}
@ -153,6 +153,11 @@ blockquote[type="cite"],
.navbar {
border: none;
}
.desktop nav.pagination,
.tablet nav.pagination {
margin-left: .5em;
margin-bottom: 0 !important;
}
</style>
</head>

View File

@ -19,6 +19,7 @@ pub fn init(url: Url, orders: &mut impl Orders<Msg>) -> Model {
} else {
orders.notify(subs::UrlRequested::new(url));
};
orders.stream(streams::window_event(Ev::Resize, |_| Msg::OnResize));
orders.subscribe(on_url_changed);
Model {
@ -127,6 +128,7 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
Msg::Reload => {
orders.perform_cmd(async move { on_url_changed(subs::UrlChanged(Url::current())) });
}
Msg::OnResize => (),
Msg::SearchRequest {
query,
@ -357,6 +359,8 @@ pub enum Msg {
Noop,
// Tell the client to refresh its state
Reload,
// Window has changed size
OnResize,
// Tell the server to update state
RefreshStart,
RefreshDone(Option<FetchError>),

View File

@ -86,7 +86,7 @@ pub(super) fn view(model: &Model) -> Node<Msg> {
let tags_open = use_state(|| false);
let force_tags_open = unread.is_empty();
div![
C!["desktop-main-content"],
C!["main-content"],
aside![
C!["tags-menu", "menu"],
IF!(!unread.is_empty() => p![C!["menu-label"], "Unread"]),

View File

@ -19,6 +19,7 @@ use crate::{
mod desktop;
mod legacy;
mod mobile;
mod tablet;
fn set_title(title: &str) {
seed::document().set_title(&format!("lb: {}", title));
@ -395,26 +396,28 @@ fn view_footer(render_time_ms: u128) -> Node<Msg> {
// `view` describes what to display.
pub fn view(model: &Model) -> Node<Msg> {
info!("refreshing {:?}", model.refreshing_state);
let is_mobile = seed::window()
.match_media("(max-width: 768px)")
.expect("failed media query")
.map(|mql| mql.matches())
.unwrap_or(false);
let start = Instant::now();
info!("refreshing {:?}", model.refreshing_state);
let win = seed::window();
let w = win
.inner_width()
.expect("window width")
.as_f64()
.expect("window width f64");
let h = win
.inner_height()
.expect("window height")
.as_f64()
.expect("window height f64");
info!("win: {w}x{h}");
info!("view called");
div![
if is_mobile {
C!["mobile"]
} else {
C!["desktop"]
match w {
w if w < 800. => div![C!["mobile"], mobile::view(model)],
w if w < 1024. => div![C!["tablet"], tablet::view(model)],
_ => div![C!["desktop"], desktop::view(model)],
},
if is_mobile {
mobile::view(model)
} else {
desktop::view(model)
},
view_footer(start.elapsed().as_millis())
view_footer(start.elapsed().as_millis()),
]
}

30
web/src/view/tablet.rs Normal file
View File

@ -0,0 +1,30 @@
use seed::{prelude::*, *};
use crate::{
state::{Context, Model, Msg},
view::{view_header, view_search_results, view_thread},
};
pub(super) fn view(model: &Model) -> Node<Msg> {
// Do two queries, one without `unread` so it loads fast, then a second with unread.
let content = match &model.context {
Context::None => div![h1!["Loading"]],
Context::Thread(_) => unimplemented!("tablet legacy thread view"),
Context::ThreadResult(thread) => view_thread(thread),
Context::Search(_) => unimplemented!("tablet legacy search results view"),
Context::SearchResult {
query,
results,
count,
pager,
} => view_search_results(&query, results.as_slice(), *count, pager),
};
div![
C!["main-content"],
div![
view_header(&model.query, &model.refreshing_state),
content,
view_header(&model.query, &model.refreshing_state),
]
]
}