v2.2.0 - Pirate Stache - Markdown and Clensing
Message format has been changed so that all text boxes will be the same width, rather than they change depending on name length. TL;DR: changed location of name tag You can now format your messages with cmark flavored markdown. There still may be rendering bugs, but I will fix them as they come. Messages are now properly sanitized with the ammonia package. Messages now have proper timestamps with help from chrono. Right now previous versions are not compatible with the new timestamp format. A patch will be introduced in the next couple of updates to remedy that issue. Did some housekeeping in `static/index.css`
This commit is contained in:
parent
b92d1e6236
commit
093b6cd868
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "board_server"
|
||||
version = "2.1.0"
|
||||
version = "2.2.0"
|
||||
edition = "2018"
|
||||
license = "Zlib"
|
||||
repository = "https://git.solow.xyz/cgit.cgi/Boarders/"
|
||||
@ -22,6 +22,9 @@ futures = "0.3.15"
|
||||
handlebars = "4.0.1"
|
||||
maplit = "1.0.2"
|
||||
simple_logger = "1.11.0"
|
||||
chrono = "0.4.19"
|
||||
ammonia = "3.1.2"
|
||||
pulldown-cmark = "0.8.0"
|
||||
|
||||
[lib]
|
||||
name = "boarders"
|
||||
|
||||
@ -18,10 +18,11 @@ use crate::{
|
||||
};
|
||||
|
||||
use handlebars::to_json;
|
||||
|
||||
use maplit::btreemap;
|
||||
|
||||
use super::TimeDerive;
|
||||
use chrono::{DateTime, Utc};
|
||||
use ammonia::clean;
|
||||
use pulldown_cmark::{Parser, Options, html::push_html};
|
||||
|
||||
#[get("/boards/")]
|
||||
pub async fn list_boards(
|
||||
@ -76,7 +77,30 @@ pub async fn get_board(
|
||||
};
|
||||
if let Some(a) = Board::search(boards.iter(), board_id) {
|
||||
let data = btreemap!(
|
||||
"messages" => to_json(&a.messages),
|
||||
"messages" => {
|
||||
let mut msg_json = to_json(&a.messages);
|
||||
let mut op = Options::empty();
|
||||
op.insert(Options::ENABLE_TABLES);
|
||||
|
||||
let msg_json = msg_json.as_array_mut().unwrap().iter_mut().zip(a.messages.borrow().iter()).map(|x| {
|
||||
let parse = Parser::new_ext(&x.1.text, op);
|
||||
let o = x.0.as_object_mut().unwrap();
|
||||
o.insert(
|
||||
"time_meta".to_string(),
|
||||
to_json(DateTime::<Utc>::from(x.1.timestamp).to_rfc2822().trim_matches(|c| c=='0' || c=='+' || c==' '))
|
||||
);
|
||||
o.insert(
|
||||
"render_text".to_string(),
|
||||
{
|
||||
let mut dirty_html = String::new();
|
||||
push_html(&mut dirty_html, parse);
|
||||
to_json(dirty_html)
|
||||
}
|
||||
);
|
||||
x.0
|
||||
}).collect::<Vec<&mut serde_json::Value>>();
|
||||
to_json(msg_json)
|
||||
},
|
||||
"user" => match uid {
|
||||
Ok(a) => to_json(data.user_manager.lock().unwrap().get_user_by_id(a.id)),
|
||||
Err(_) => to_json(None::<Option<u8>>)
|
||||
@ -112,7 +136,6 @@ pub async fn board_post(
|
||||
let um = data.user_manager.lock().unwrap();
|
||||
match board {
|
||||
Some(ref mut a) => {
|
||||
//let a: &mut Board = board.unwrap();
|
||||
let msg = mf.create_message({
|
||||
let user = um.get_user_by_id(form.user_id).ok_or_else(|| {
|
||||
HttpResponse::NotFound().body("Not Found: User does not exist")
|
||||
@ -122,8 +145,7 @@ pub async fn board_post(
|
||||
} else {
|
||||
return Err(HttpResponse::Unauthorized().body("Unauthorized: Bad login attempt, invalid auth token"));
|
||||
}
|
||||
}, form.content.clone().trim());
|
||||
println!("new message");
|
||||
}, clean(&form.content));
|
||||
a.add_message(msg);
|
||||
Ok(HttpResponse::SeeOther().header("location", format!("/board/{}/", a.id)).finish())
|
||||
},
|
||||
|
||||
@ -33,7 +33,7 @@ impl Board {
|
||||
/* backwards compatability */
|
||||
if let Ok(ref mut b) = b {
|
||||
if b.last_active.is_none() {
|
||||
b.last_active = b.messages.borrow().last().map(|x| x.timestamp);
|
||||
b.last_active = b.messages.borrow().last().map(|x| x.as_secs());
|
||||
}
|
||||
}
|
||||
b
|
||||
@ -50,7 +50,7 @@ impl Board {
|
||||
}
|
||||
|
||||
pub fn add_message(&mut self, msg: Message) -> &Board {
|
||||
self.last_active = Some(msg.timestamp);
|
||||
self.last_active = Some(msg.as_secs());
|
||||
self.messages.borrow_mut().push(msg);
|
||||
self
|
||||
}
|
||||
|
||||
@ -14,10 +14,16 @@ use super::{
|
||||
pub struct Message {
|
||||
pub text: String,
|
||||
pub id: u32,
|
||||
pub timestamp: u64,
|
||||
pub timestamp: SystemTime,
|
||||
pub author: RefCell<User>
|
||||
}
|
||||
|
||||
impl Message {
|
||||
pub fn as_secs(&self) -> u64 {
|
||||
self.timestamp.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct MessageFactory {
|
||||
pub next_id: u32,
|
||||
@ -36,11 +42,10 @@ impl MessageFactory {
|
||||
|
||||
pub fn create_message<S>(&mut self, user: User, content: S) -> Message where S: AsRef<str> {
|
||||
self.next_id += 1;
|
||||
let time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
|
||||
Message {
|
||||
text: String::from(content.as_ref()),
|
||||
id: self.next_id-1,
|
||||
timestamp: time,
|
||||
timestamp: SystemTime::now(),
|
||||
author: RefCell::new(user)
|
||||
}
|
||||
}
|
||||
|
||||
15
src/main.rs
15
src/main.rs
@ -42,7 +42,7 @@ use tokio::{
|
||||
select
|
||||
};
|
||||
|
||||
use handlebars::Handlebars;
|
||||
use handlebars::{Handlebars, handlebars_helper};
|
||||
use console::style;
|
||||
use maplit::btreemap;
|
||||
|
||||
@ -274,13 +274,16 @@ async fn main() -> std::io::Result<()> {
|
||||
* variable at compile time
|
||||
*/
|
||||
/* register handlebars partials here */
|
||||
h.register_partial("login_status", include_str!("res/snippets/login_status.hbs")).unwrap();
|
||||
h.register_partial("board_bar", include_str!("res/snippets/board_bar.hbs")).unwrap();
|
||||
handlebars_helper!(msg_helper: |s: str| format!("helped: {}", s.to_string()));
|
||||
h.register_helper("msg", Box::new(msg_helper));
|
||||
h.register_partial("head", include_str!("res/snippets/head.hbs")).unwrap();
|
||||
h.register_partial("login_status", include_str!("res/snippets/login_status.hbs")).unwrap();
|
||||
h.register_partial("board_bar", include_str!("res/snippets/board_bar.hbs")).unwrap();
|
||||
/* register handlebars templates here */
|
||||
h.register_template_string("board_index", include_str!("res/board_index.hbs")).unwrap();
|
||||
h.register_template_string("welcome", include_str!("res/welcome.hbs")).unwrap();
|
||||
h.register_template_string("auth", include_str!("res/auth.hbs")).unwrap();
|
||||
h.register_template_string("board", include_str!("res/board.hbs")).unwrap();
|
||||
h.register_template_string("welcome", include_str!("res/welcome.hbs")).unwrap();
|
||||
h.register_template_string("auth", include_str!("res/auth.hbs")).unwrap();
|
||||
h.register_template_string("board", include_str!("res/board.hbs")).unwrap();
|
||||
h
|
||||
}
|
||||
}).app_data(web_data.clone())
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="https://orbitalfox.us/Music/index.css">
|
||||
<link rel="stylesheet" type="text/css" href="/static/index.css">
|
||||
</head>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{{> head}}
|
||||
<body>
|
||||
<div id="title" class="bar">
|
||||
{{#if user.nick}}
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="https://orbitalfox.us/Music/index.css">
|
||||
<link rel="stylesheet" type="text/css" href="/static/index.css">
|
||||
</head>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{{> head}}
|
||||
<body style="overflow-x: hidden;">
|
||||
{{> board_bar board=board user=user}}
|
||||
<div id="index">
|
||||
@ -18,16 +16,16 @@
|
||||
<b>{{msg.author.username}}</b>
|
||||
{{/if}}
|
||||
<div class="message-content">
|
||||
<pre>{{msg.text}}</pre>
|
||||
<pre>{{{msg.render_text}}}</pre>
|
||||
</div>
|
||||
<div class="message-time">
|
||||
{{msg.timestamp}}
|
||||
{{msg.time_meta}}
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<form action="/boards/post" method="post" style="display: flex; align-items: center; flex-direction: column;">
|
||||
<label for="content">Content:</label><br/>
|
||||
<label for="content">Write a message:</label><br/>
|
||||
<input type="hidden" id="board_id" name="board_id" value="{{board.id}}">
|
||||
<input type="hidden" id="user_id" name="user_id" value="{{user.user_id}}">
|
||||
<textarea name="content" id="content" rows=12 cols=50 placeholder="Enter message here..."></textarea>
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="https://orbitalfox.us/Music/index.css">
|
||||
<link rel="stylesheet" type="text/css" href="/static/index.css">
|
||||
</head>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{{> head}}
|
||||
<body style="overflow-x: hidden;">
|
||||
<div id="title" class="bar">
|
||||
<div>
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="https://orbitalfox.us/Music/index.css">
|
||||
<link rel="stylesheet" type="text/css" href="/static/index.css">
|
||||
</head>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{{> head}}
|
||||
<body>
|
||||
<div id="title" class="bar">
|
||||
<h1>Hello, {{name}}</h1>
|
||||
|
||||
9
src/res/snippets/head.hbs
Normal file
9
src/res/snippets/head.hbs
Normal file
@ -0,0 +1,9 @@
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<link rel="stylesheet" type="text/css" href="https://orbitalfox.us/Music/index.css">
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"/>
|
||||
{{#if nolocal}}
|
||||
{{else}}
|
||||
<link rel="stylesheet" type="text/css" href="/static/index.css">
|
||||
{{/if}}
|
||||
</head>
|
||||
@ -1,7 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="https://orbitalfox.us/Music/index.css">
|
||||
</head>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{{> head nolocal=1}}
|
||||
<body>
|
||||
<h1>
|
||||
<div style="display: flex; align-items: center; flex-direction: column;">
|
||||
|
||||
@ -60,56 +60,17 @@ body {
|
||||
font-size: 2.5em !important;
|
||||
}
|
||||
|
||||
#nav {
|
||||
width: 3em;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
margin-left: 3rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
width: 2.5rem;
|
||||
background-color: #07a6ea;
|
||||
color: white;
|
||||
padding: 0.25rem;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
|
||||
.orange-arrow {
|
||||
width: 2.5rem;
|
||||
color: orange;
|
||||
padding: 0.25rem;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
|
||||
.down {
|
||||
transform: rotate(180deg);
|
||||
-webkit-transform:rotate(180deg);
|
||||
-moz-transform: rotate(180deg);
|
||||
-ms-transform: rotate(180deg);
|
||||
-o-transform: rotate(180deg);
|
||||
}
|
||||
|
||||
#navbar > img.arrow.down {
|
||||
unset: top;
|
||||
bottom: 0;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
#navbar > img.arrow {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.message {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
border-bottom: 1px solid #555;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-direction: inherit;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.message > b {
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.message > * {
|
||||
@ -197,7 +158,12 @@ tr.board:hover {
|
||||
|
||||
.message-content {
|
||||
flex-grow: 1;
|
||||
max-width: 90%;
|
||||
/*max-width: 90%; */
|
||||
}
|
||||
|
||||
.message-content > pre {
|
||||
margin-top: 0.1rem;
|
||||
margin-bottom: 0.1rem;
|
||||
}
|
||||
|
||||
pre {
|
||||
@ -207,3 +173,38 @@ pre {
|
||||
white-space: -o-pre-wrap; /* Opera 7 */
|
||||
word-wrap: break-word; /* Internet Explorer 5.5+ */
|
||||
}
|
||||
|
||||
pre > h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
pre > h2 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
pre > h3 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
pre > h4 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
pre > h5 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
pre > *:last-child {
|
||||
margin-bottom: unset;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #222;
|
||||
padding: 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.message-time {
|
||||
font-size: 0.75rem;
|
||||
color: #555
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user