ui cleanup mobile view also
This commit is contained in:
@@ -284,7 +284,7 @@ pub async fn new_session(
|
||||
hx-target=\"#messages\" \
|
||||
hx-swap=\"beforeend\" \
|
||||
hx-on=\"htmx:afterRequest: this.reset(); scrollMessages()\">\
|
||||
<input id=\"chat-input\" type=\"text\" name=\"content\" placeholder=\"Type your message...\" autocomplete=\"off\" maxlength=\"1000\" oninput=\"sendUserTyping()\" required />\
|
||||
<input id=\"chat-input\" type=\"text\" name=\"content\" placeholder=\"Type your message...\" autocomplete=\"off\" maxlength=\"1000\" oninput=\"handleUserTypingInput()\" required />\
|
||||
<button type=\"submit\">Send</button>\
|
||||
</form>\
|
||||
</div>\
|
||||
|
||||
+25
-10
@@ -9,8 +9,10 @@ use std::sync::Arc;
|
||||
|
||||
use crate::state::{AppState, RESET_EVENT};
|
||||
|
||||
const USER_TYPING_PREFIX: &str = "typing:user:";
|
||||
const SUPPORTER_TYPING_PREFIX: &str = "typing:supporter:";
|
||||
const USER_TYPING_START_PREFIX: &str = "typing:user:start:";
|
||||
const USER_TYPING_STOP_PREFIX: &str = "typing:user:stop:";
|
||||
const SUPPORTER_TYPING_START_PREFIX: &str = "typing:supporter:start:";
|
||||
const SUPPORTER_TYPING_STOP_PREFIX: &str = "typing:supporter:stop:";
|
||||
|
||||
/// WebSocket for user — pushes notifications when supporter replies
|
||||
pub async fn user_ws(
|
||||
@@ -21,6 +23,13 @@ pub async fn user_ws(
|
||||
ws.on_upgrade(move |socket| handle_user_socket(socket, session_id, state))
|
||||
}
|
||||
|
||||
fn is_typing_event_for_session(text: &str, session_id: &str) -> bool {
|
||||
text.strip_prefix(USER_TYPING_START_PREFIX) == Some(session_id)
|
||||
|| text.strip_prefix(USER_TYPING_STOP_PREFIX) == Some(session_id)
|
||||
|| text.strip_prefix(SUPPORTER_TYPING_START_PREFIX) == Some(session_id)
|
||||
|| text.strip_prefix(SUPPORTER_TYPING_STOP_PREFIX) == Some(session_id)
|
||||
}
|
||||
|
||||
async fn handle_user_socket(mut socket: WebSocket, session_id: String, state: Arc<AppState>) {
|
||||
let tx = state.get_or_create_notifier(&session_id);
|
||||
let mut rx = tx.subscribe();
|
||||
@@ -28,9 +37,9 @@ async fn handle_user_socket(mut socket: WebSocket, session_id: String, state: Ar
|
||||
loop {
|
||||
tokio::select! {
|
||||
// Forward broadcast events to the user browser.
|
||||
Ok(sid) = rx.recv() => {
|
||||
if sid == session_id || sid == RESET_EVENT || sid.starts_with(SUPPORTER_TYPING_PREFIX) || sid.starts_with(USER_TYPING_PREFIX) {
|
||||
if socket.send(Message::Text(sid)).await.is_err() {
|
||||
Ok(event) = rx.recv() => {
|
||||
if event == session_id || event == RESET_EVENT || is_typing_event_for_session(&event, &session_id) {
|
||||
if socket.send(Message::Text(event)).await.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -39,8 +48,9 @@ async fn handle_user_socket(mut socket: WebSocket, session_id: String, state: Ar
|
||||
msg = socket.recv() => {
|
||||
match msg {
|
||||
Some(Ok(Message::Text(text))) => {
|
||||
let expected = format!("{USER_TYPING_PREFIX}{session_id}");
|
||||
if text == expected {
|
||||
if is_typing_event_for_session(&text, &session_id)
|
||||
&& (text.starts_with(USER_TYPING_START_PREFIX) || text.starts_with(USER_TYPING_STOP_PREFIX))
|
||||
{
|
||||
let _ = tx.send(text.clone());
|
||||
let _ = state.supporter_notifier.send(text);
|
||||
}
|
||||
@@ -62,20 +72,25 @@ pub async fn supporter_ws(
|
||||
ws.on_upgrade(move |socket| handle_supporter_socket(socket, state))
|
||||
}
|
||||
|
||||
fn supporter_typing_session_id(text: &str) -> Option<&str> {
|
||||
text.strip_prefix(SUPPORTER_TYPING_START_PREFIX)
|
||||
.or_else(|| text.strip_prefix(SUPPORTER_TYPING_STOP_PREFIX))
|
||||
}
|
||||
|
||||
async fn handle_supporter_socket(mut socket: WebSocket, state: Arc<AppState>) {
|
||||
let mut rx = state.supporter_notifier.subscribe();
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
Ok(session_id) = rx.recv() => {
|
||||
if socket.send(Message::Text(session_id)).await.is_err() {
|
||||
Ok(event) = rx.recv() => {
|
||||
if socket.send(Message::Text(event)).await.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
msg = socket.recv() => {
|
||||
match msg {
|
||||
Some(Ok(Message::Text(text))) => {
|
||||
if let Some(session_id) = text.strip_prefix(SUPPORTER_TYPING_PREFIX) {
|
||||
if let Some(session_id) = supporter_typing_session_id(&text) {
|
||||
if !session_id.is_empty() && state.sessions.contains_key(session_id) {
|
||||
let tx = state.get_or_create_notifier(session_id);
|
||||
let _ = tx.send(text);
|
||||
|
||||
Reference in New Issue
Block a user