working send + view messages
This commit is contained in:
parent
c629ae5ce3
commit
82c86bba16
@ -1,6 +1,8 @@
|
|||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
|
use dhcparse::dhcpv4::MAX_MESSAGE_SIZE;
|
||||||
use embassy_sync::{blocking_mutex::raw::ThreadModeRawMutex, mutex::Mutex};
|
use embassy_sync::{blocking_mutex::raw::ThreadModeRawMutex, mutex::Mutex};
|
||||||
use heapless::{String, Vec};
|
use heapless::{String, Vec};
|
||||||
|
use log::info;
|
||||||
use percent_encoding::percent_decode_str;
|
use percent_encoding::percent_decode_str;
|
||||||
use pico_website::unwrap;
|
use pico_website::unwrap;
|
||||||
use ringbuffer::{ConstGenericRingBuffer, RingBuffer};
|
use ringbuffer::{ConstGenericRingBuffer, RingBuffer};
|
||||||
@ -44,7 +46,7 @@ impl App for ChatApp {
|
|||||||
let (path, args) = path.split_once('?').unwrap_or((path, ""));
|
let (path, args) = path.split_once('?').unwrap_or((path, ""));
|
||||||
let mut load = None;
|
let mut load = None;
|
||||||
let mut username = None;
|
let mut username = None;
|
||||||
// let mut msg_content = None;
|
let mut msg_content = None;
|
||||||
for arg in args.split('&').chain(content.split('&')) {
|
for arg in args.split('&').chain(content.split('&')) {
|
||||||
match arg.split_once('=') {
|
match arg.split_once('=') {
|
||||||
Some(("load", n)) => {
|
Some(("load", n)) => {
|
||||||
@ -57,49 +59,76 @@ impl App for ChatApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(("username", u)) => {
|
Some(("username", u)) => {
|
||||||
if u.len() < USERNAME_MIN_SIZE || u.len() > USERNAME_SIZE {
|
let mut name = String::<USERNAME_SIZE>::new();
|
||||||
|
for c in percent_decode_str(u) {
|
||||||
|
if let Err(_) = name.push(c as char) {
|
||||||
return (HttpResCode::BadRequest, "", &[]);
|
return (HttpResCode::BadRequest, "", &[]);
|
||||||
}
|
}
|
||||||
username = Some(u);
|
}
|
||||||
|
if u.len() < USERNAME_MIN_SIZE {
|
||||||
|
return (HttpResCode::BadRequest, "", &[]);
|
||||||
|
}
|
||||||
|
username = Some(name);
|
||||||
}
|
}
|
||||||
Some(("msg", m)) => {
|
Some(("msg", m)) => {
|
||||||
let mut msg = String::<MSG_SIZE>::new();
|
let mut msg = String::<MSG_SIZE>::new();
|
||||||
for c in percent_decode_str(m) {
|
for c in percent_decode_str(m) {
|
||||||
msg.push(c as char);
|
if let Err(_) = msg.push(c as char) {
|
||||||
}
|
|
||||||
if m.len() > MSG_SIZE {
|
|
||||||
return (HttpResCode::BadRequest, "", &[]);
|
return (HttpResCode::BadRequest, "", &[]);
|
||||||
}
|
}
|
||||||
// msg_content = Some();
|
}
|
||||||
|
msg_content = Some(msg);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
info!(
|
||||||
|
"load:{:?} | username:{:?} | msg:{:?}",
|
||||||
|
load, username, msg_content
|
||||||
|
);
|
||||||
if path == "/chat/connect" && username.is_some() {
|
if path == "/chat/connect" && username.is_some() {
|
||||||
self.res_buf.clear();
|
self.res_buf.clear();
|
||||||
unwrap(write!(
|
unwrap(write!(
|
||||||
&mut self.res_buf,
|
&mut self.res_buf,
|
||||||
"<div \
|
"<input id=\"username\" style=\"display: none;\" name=\"username\" value=\"{}\">
|
||||||
|
<div id=\"messages\" >\
|
||||||
|
<div \
|
||||||
class=\"message\" \
|
class=\"message\" \
|
||||||
hx-get=\"/chat/message/abs/0?load={}&username={}\" \
|
hx-get=\"/chat/message/0?load={}\" \
|
||||||
hx-target=\"this\" \
|
hx-target=\"this\" \
|
||||||
hx-swap=\"outerHTML\" \
|
hx-swap=\"outerHTML\" \
|
||||||
hx-trigger=\"load\" \
|
hx-trigger=\"load\" \
|
||||||
></div>",
|
></div>\
|
||||||
|
</div>\
|
||||||
|
<input \
|
||||||
|
id=\"msg\" \
|
||||||
|
name=\"msg\" \
|
||||||
|
maxlength=\"{}\" \
|
||||||
|
hx-post=\"/chat/send\" \
|
||||||
|
hx-include=\"#username\" \
|
||||||
|
hx-target=\"#messages\" \
|
||||||
|
hx-swap=\"beforeend\"\
|
||||||
|
>",
|
||||||
|
username.unwrap(),
|
||||||
MEMORY_SIZE,
|
MEMORY_SIZE,
|
||||||
username.unwrap()
|
MAX_MESSAGE_SIZE
|
||||||
))
|
))
|
||||||
.await;
|
.await;
|
||||||
return (HttpResCode::Ok, "html", &self.res_buf);
|
return (HttpResCode::Ok, "html", &self.res_buf);
|
||||||
} else if path == "/chat/send" && username.is_some() {
|
} else if path == "/chat/send" && username.is_some() && msg_content.is_some() {
|
||||||
return (HttpResCode::Ok, "html", &self.res_buf);
|
let mut msgs = MESSAGES.lock().await;
|
||||||
} else if path.starts_with("/chat/message/abs/") && path.len() > 18 {
|
msgs.push(Message {
|
||||||
let msg_id: u16 = match path[18..].parse() {
|
author: username.unwrap(),
|
||||||
|
content: msg_content.unwrap(),
|
||||||
|
});
|
||||||
|
return (HttpResCode::NoContent, "", &[]);
|
||||||
|
} else if path.starts_with("/chat/message/") && path.len() > 14 {
|
||||||
|
let msg_id: u16 = match path[14..].parse() {
|
||||||
Ok(n) => n,
|
Ok(n) => n,
|
||||||
Err(_) => return (HttpResCode::BadRequest, "", &[]),
|
Err(_) => return (HttpResCode::BadRequest, "", &[]),
|
||||||
};
|
};
|
||||||
let msgs = MESSAGES.lock().await;
|
let msgs = MESSAGES.lock().await;
|
||||||
if msg_id >= msgs.next {
|
if msg_id > msgs.next {
|
||||||
return (HttpResCode::BadRequest, "", &[]);
|
return (HttpResCode::BadRequest, "", &[]);
|
||||||
}
|
}
|
||||||
if msg_id < msgs.next.saturating_sub(MEMORY_SIZE as u16 + 1) {
|
if msg_id < msgs.next.saturating_sub(MEMORY_SIZE as u16 + 1) {
|
||||||
@ -107,18 +136,37 @@ impl App for ChatApp {
|
|||||||
}
|
}
|
||||||
self.res_buf.clear();
|
self.res_buf.clear();
|
||||||
unwrap(write!(&mut self.res_buf, "<div class=\"message\"")).await;
|
unwrap(write!(&mut self.res_buf, "<div class=\"message\"")).await;
|
||||||
if let Some(n) = load {
|
if msg_id == msgs.next {
|
||||||
|
unwrap(write!(&mut self.res_buf, " style=\"display: none;\"")).await;
|
||||||
|
}
|
||||||
|
info!("msg_id:{} | next:{}", msg_id, msgs.next);
|
||||||
|
if msg_id == msgs.next {
|
||||||
|
info!("test1");
|
||||||
unwrap(write!(
|
unwrap(write!(
|
||||||
&mut self.res_buf,
|
&mut self.res_buf,
|
||||||
" hx-get=\"/chat/message/abs/{}?load={}\" \
|
" hx-get=\"/chat/message/{}?load={}\" \
|
||||||
|
hx-target=\"this\" \
|
||||||
|
hx-swap=\"outerHTML\" \
|
||||||
|
hx-trigger=\"every 100ms\"",
|
||||||
|
msg_id,
|
||||||
|
load.unwrap_or(0)
|
||||||
|
))
|
||||||
|
.await;
|
||||||
|
} else {
|
||||||
|
if let Some(n) = load {
|
||||||
|
info!("test2");
|
||||||
|
unwrap(write!(
|
||||||
|
&mut self.res_buf,
|
||||||
|
" hx-get=\"/chat/message/{}?load={}\" \
|
||||||
hx-target=\"this\" \
|
hx-target=\"this\" \
|
||||||
hx-swap=\"afterend\" \
|
hx-swap=\"afterend\" \
|
||||||
hx-trigger=\"load\"",
|
hx-trigger=\"load\"",
|
||||||
msg_id + 1,
|
msg_id + 1,
|
||||||
n - 1
|
n - 1,
|
||||||
))
|
))
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
info!("test3");
|
||||||
let msg = match msgs.get_abs(msg_id) {
|
let msg = match msgs.get_abs(msg_id) {
|
||||||
Some(msg) => msg,
|
Some(msg) => msg,
|
||||||
None => return (HttpResCode::NoContent, "", &[]),
|
None => return (HttpResCode::NoContent, "", &[]),
|
||||||
@ -129,6 +177,8 @@ impl App for ChatApp {
|
|||||||
msg.author, msg.content
|
msg.author, msg.content
|
||||||
))
|
))
|
||||||
.await;
|
.await;
|
||||||
|
};
|
||||||
|
|
||||||
return (HttpResCode::Ok, "html", &self.res_buf);
|
return (HttpResCode::Ok, "html", &self.res_buf);
|
||||||
} else {
|
} else {
|
||||||
(HttpResCode::NotFound, "", &[])
|
(HttpResCode::NotFound, "", &[])
|
||||||
@ -151,11 +201,15 @@ impl Messages {
|
|||||||
const fn new() -> Self {
|
const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: ConstGenericRingBuffer::new(),
|
inner: ConstGenericRingBuffer::new(),
|
||||||
next: 2,
|
next: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_abs(&self, id: u16) -> Option<&Message> {
|
fn get_abs(&self, id: u16) -> Option<&Message> {
|
||||||
self.inner
|
self.inner.get_signed((id as isize) - (self.next as isize))
|
||||||
.get_signed((id as isize) + 1 - (self.next as isize))
|
}
|
||||||
|
fn push(&mut self, msg: Message) {
|
||||||
|
info!("{}: {}", msg.author, msg.content);
|
||||||
|
self.inner.push(msg);
|
||||||
|
self.next += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user