amélioration continue...

pull/25/head
Nicolas Sanchez 3 years ago
parent 8f615bc219
commit 7c59f67699

@ -1,5 +1,7 @@
create table pages ( create table pages (
page_name text primary key, domain text,
page_name text,
page_text text, page_text text,
active boolean default true not null active boolean default true not null,
primary key (domain, page_name)
); );

Binary file not shown.

@ -6,11 +6,12 @@ pub type Connection = r2d2::PooledConnection<r2d2_sqlite::SqliteConnectionManage
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Page { pub struct Page {
pub domain: String,
pub page_name: String, pub page_name: String,
pub page_text: String, pub page_text: String,
} }
pub async fn get_page_by_name(pool: &Pool, pagename: String) -> Result<Vec<Page>, Error> { pub async fn get_page_by_name(pool: &Pool, domain: String, pagename: String) -> Result<Vec<Page>, Error> {
let pool = pool.clone(); let pool = pool.clone();
let conn = web::block(move || pool.get()) let conn = web::block(move || pool.get())
@ -19,12 +20,13 @@ pub async fn get_page_by_name(pool: &Pool, pagename: String) -> Result<Vec<Page>
web::block(move || { web::block(move || {
let mut stmt = conn let mut stmt = conn
.prepare("SELECT page_name, page_text from pages WHERE active=true and page_name=?")?; .prepare("SELECT domain, page_name, page_text from pages WHERE active=true and domain=? and page_name=?")?;
stmt.query_map([pagename], |row| { stmt.query_map([domain, pagename], |row| {
Ok(Page { Ok(Page {
page_name: row.get(0)?, domain: row.get(0)?,
page_text: row.get(1)?, page_name: row.get(1)?,
page_text: row.get(2)?,
}) })
}) })
.and_then(Iterator::collect) .and_then(Iterator::collect)
@ -33,7 +35,7 @@ pub async fn get_page_by_name(pool: &Pool, pagename: String) -> Result<Vec<Page>
.map_err(error::ErrorInternalServerError) .map_err(error::ErrorInternalServerError)
} }
pub async fn update_page(pool: &Pool, page_name: String, page_text: String) -> Result<usize, Error> { pub async fn update_page(pool: &Pool, domain: String, page_name: String, page_text: String) -> Result<usize, Error> {
let pool = pool.clone(); let pool = pool.clone();
let conn = web::block(move || pool.get()) let conn = web::block(move || pool.get())
@ -42,10 +44,9 @@ pub async fn update_page(pool: &Pool, page_name: String, page_text: String) -> R
web::block(move || { web::block(move || {
let mut stmt = conn let mut stmt = conn
.prepare("insert or replace into pages (page_name, page_text, active) values (?, ?, true)")?; .prepare("insert or replace into pages (domain, page_name, page_text, active) values (?, ?, ?, true)")?;
stmt.execute([page_name, page_text, ]) stmt.execute([domain, page_name, page_text, ])
}) })
.await? .await?
.map_err(error::ErrorInternalServerError) .map_err(error::ErrorInternalServerError)
} }

@ -30,10 +30,10 @@ async fn main() -> std::io::Result<()> {
App::new() App::new()
.app_data(web::Data::new(appdata.to_owned())) .app_data(web::Data::new(appdata.to_owned()))
.service(index::index) .service(index::index)
.service(page::page)
.service(page::save_page)
.service(actix_files::Files::new("/static", "./static")) .service(actix_files::Files::new("/static", "./static"))
.service(actix_files::Files::new("/static/modules", "./static/modules")) .service(actix_files::Files::new("/static/modules", "./static/modules"))
.service(page::page)
.service(page::save_page)
}) })
.bind((ip, port))? .bind((ip, port))?
.run() .run()

@ -3,8 +3,6 @@ use actix_web::{get, put, Responder};
use actix_web::{web, HttpResponse}; use actix_web::{web, HttpResponse};
use serde::Deserialize; use serde::Deserialize;
use std::fs;
use askama_actix::Template; use askama_actix::Template;
use askama_actix::TemplateToResponse; use askama_actix::TemplateToResponse;
@ -25,37 +23,25 @@ struct QueryParams {
pub data: Option<String>, pub data: Option<String>,
} }
async fn get_data(data: & web::Data<AppData>, pagename: String) -> String { async fn get_data(data: & web::Data<AppData>, domain: String, page_name: String) -> String {
let fut_page_datas = db::get_page_by_name(&data.pool, pagename.to_owned()); let fut_page_datas = db::get_page_by_name(&data.pool, domain.to_owned(), page_name.to_owned());
let page_datas = fut_page_datas.await.unwrap(); let page_datas = fut_page_datas.await.unwrap();
let md;
match page_datas.first() { match page_datas.first() {
None => { None => String::from("# ") + page_name.replace("_", " ").as_str(),
let filename = String::from("pages/") + pagename.as_str() + ".md"; Some(dat) => (*dat.page_text).to_string(),
md = match fs::read_to_string(filename) {
Ok(txt) => {
db::update_page(&data.pool, pagename.to_owned(), txt.to_owned())
.await
.unwrap();
txt
}
Err(_) => String::from("# ") + pagename.replace("_", " ").as_str(),
};
}
Some(dat) => md = (*dat.page_text).to_string(),
} }
md
} }
#[get("/page/{page}")] #[get("/{domain}/{page}")]
async fn page( async fn page(
path: web::Path<(String,)>, path: web::Path<(String, String,)>,
data: web::Data<AppData>, data: web::Data<AppData>,
params: web::Query<QueryParams>, params: web::Query<QueryParams>,
) -> impl Responder { ) -> impl Responder {
let pagename = &path.0; let domain = &path.0;
let page_name = &path.1;
let md = get_data(&data, pagename.to_owned()).await; let md = get_data(&data, domain.to_owned(), page_name.to_owned()).await;
match &params.data { match &params.data {
Some(_) => { Some(_) => {
@ -66,7 +52,7 @@ async fn page(
None => {} None => {}
} }
let name = data.name.to_owned() + " - " + pagename.as_str(); let name = data.name.to_owned() + " - " + page_name.as_str();
let root = data.root.to_owned(); let root = data.root.to_owned();
//let init = String::from("init();"); //let init = String::from("init();");
let init = format!("init();"); let init = format!("init();");
@ -79,17 +65,18 @@ async fn page(
.to_response() .to_response()
} }
#[put("/page/{page}")] #[put("/{domain}/{page}")]
async fn save_page( async fn save_page(
body: String, body: String,
path: web::Path<(String,)>, path: web::Path<(String, String)>,
data: web::Data<AppData>, data: web::Data<AppData>,
) -> impl Responder { ) -> impl Responder {
let pagename = &path.0; let domain = &path.0;
let pagename = &path.1;
if pagename == "index" { if pagename == "index" {
return HttpResponse::Ok(); return HttpResponse::Ok();
} }
db::update_page(&data.pool, pagename.to_owned(), body) db::update_page(&data.pool, domain.to_owned(), pagename.to_owned(), body)
.await .await
.unwrap(); .unwrap();
HttpResponse::Ok() HttpResponse::Ok()

@ -149,7 +149,7 @@ div.ta {
textarea#ta { textarea#ta {
position: relative; position: relative;
top: 3rem; top: 0;
display: none; display: none;
width: 100%; width: 100%;
height: 15rem; height: 15rem;
@ -325,13 +325,13 @@ div#cheezenotes div.cheezenotes_line span.token {
overflow: hidden; overflow: hidden;
font-size: 0; font-size: 0;
vertical-align: baseline; vertical-align: baseline;
transition-property: font-size, color; /*transition-property: font-size, color;
transition-duration: .2s; transition-duration: .2s;*/
} }
div#cheezenotes:focus div.cheezenotes_line span.token { div#cheezenotes:focus div.cheezenotes_line span.token {
color: #1353b3; color: #1353b3;
font-size: 95%; font-size: 90%;
} }
div#cheezenotes div.body { div#cheezenotes div.body {

@ -1,3 +1,18 @@
function insertAtLineStart(txtBefore) {
let ret = saveSelection();
let line = ret[0];
let txt = line.innerText;
if (txt == '\n') {
txt = "";
}
line.innerHTML = txtBefore + txt;
let span = document.createElement('span');
span.innerHTML = txtBefore;
ret[1] = ret[1] + span.innerText.length;;
ret[3] = ret[3] + span.innerText.length;;
loadSelection(ret);
}
function insertTextAtCaret(txtBefore, txtAfter = '') { function insertTextAtCaret(txtBefore, txtAfter = '') {
let ret = saveSelection(); let ret = saveSelection();
let line = ret[0]; let line = ret[0];
@ -190,4 +205,4 @@ function setEndPositionInText(obj, position) {
return 0; return 0;
} }
export { saveSelection, loadSelection, insertTextAtCaret }; export { saveSelection, loadSelection, insertTextAtCaret, insertAtLineStart };

@ -1,13 +1,13 @@
import { saveSelection, loadSelection, insertTextAtCaret } from './caret.js'; import { saveSelection, loadSelection, insertTextAtCaret, insertAtLineStart } from './caret.js';
import { formatLine, load, save, formatTable, redrawTables, appendData, dpwidth } from './md.js'; import { formatLine, load, save, formatTable, redrawTables, appendData, dpwidth } from './md.js';
const showtokens = [ const showtokens = [
{ fontSize: 0 }, { fontSize: 0 },
{ fontSize: '95%' } { fontSize: '90%' }
]; ];
const hidetokens = [ const hidetokens = [
{ fontSize: '95%' }, { fontSize: '90%' },
{ fontSize: 0 } { fontSize: 0 }
]; ];
@ -21,14 +21,14 @@ function timeoutSave() {
function showTokens() { function showTokens() {
let tokens = document.getElementsByClassName('token'); let tokens = document.getElementsByClassName('token');
for (let i = 0; i < tokens.length; i++) { for (let i = 0; i < tokens.length; i++) {
tokens[i].animate(showtokens, { duration: 200, iterations: 1 }); tokens[i].animate(showtokens, { duration: 50, iterations: 1 });
} }
} }
function hideTokens() { function hideTokens() {
let tokens = document.getElementsByClassName('token'); let tokens = document.getElementsByClassName('token');
for (let i = 0; i < tokens.length; i++) { for (let i = 0; i < tokens.length; i++) {
tokens[i].animate(hidetokens, { duration: 200, iterations: 1 }); tokens[i].animate(hidetokens, { duration: 50, iterations: 1 });
} }
} }
@ -82,7 +82,12 @@ function onh1button(e) {
e.preventDefault(); e.preventDefault();
let cheezenotes = document.getElementById('cheezenotes'); let cheezenotes = document.getElementById('cheezenotes');
cheezenotes.focus(); cheezenotes.focus();
insertTextAtCaret('#', ''); let sel = saveSelection();
if (sel[0].classList.contains('h')) {
return false;
} else {
insertAtLineStart('#&nbsp;');
}
onedit(e); onedit(e);
return false; return false;
} }
@ -91,7 +96,12 @@ function onh2button(e) {
e.preventDefault(); e.preventDefault();
let cheezenotes = document.getElementById('cheezenotes'); let cheezenotes = document.getElementById('cheezenotes');
cheezenotes.focus(); cheezenotes.focus();
insertTextAtCaret('##', ''); let sel = saveSelection();
if (sel[0].classList.contains('h')) {
return false;
} else {
insertAtLineStart('##&nbsp;');
}
onedit(e); onedit(e);
return false; return false;
} }
@ -100,7 +110,12 @@ function onh3button(e) {
e.preventDefault(); e.preventDefault();
let cheezenotes = document.getElementById('cheezenotes'); let cheezenotes = document.getElementById('cheezenotes');
cheezenotes.focus(); cheezenotes.focus();
insertTextAtCaret('###', ''); let sel = saveSelection();
if (sel[0].classList.contains('h')) {
return false;
} else {
insertAtLineStart('###&nbsp;');
}
onedit(e); onedit(e);
return false; return false;
} }
@ -310,21 +325,13 @@ function onblur(e) {
let cheezenotes = document.getElementById('cheezenotes'); let cheezenotes = document.getElementById('cheezenotes');
redrawTables(cheezenotes); redrawTables(cheezenotes);
onsave(); onsave();
// hideTokens(); hideTokens();
disableFormatButtons(); disableFormatButtons();
} }
function onfocus(e) { function onfocus(e) {
let editModeButton = document.getElementById('editModeButton');
if (editModeButton.classList.contains('buttonoff')) {
e.preventDefault();
let cheezenotes = document.getElementById('cheezenotes');
cheezenotes.contentEditable = false;
cheezenotes.blur();
return false;
}
redrawTables(cheezenotes, dpwidth()); redrawTables(cheezenotes, dpwidth());
// showTokens(); showTokens();
enableFormatButtons(); enableFormatButtons();
} }

@ -94,7 +94,6 @@ function onlink(e) {
if (link.host !== document.location.host) { if (link.host !== document.location.host) {
open(link.href); open(link.href);
} else { } else {
//open(link.href, '_self');
fetch(link.href + "?data=").then((response) => { fetch(link.href + "?data=").then((response) => {
let ta = document.getElementById('ta'); let ta = document.getElementById('ta');
response.text().then((data) => { response.text().then((data) => {
@ -103,8 +102,15 @@ function onlink(e) {
let top = content.scrollTop; let top = content.scrollTop;
window.history.replaceState({ top: top, left: left }, ""); window.history.replaceState({ top: top, left: left }, "");
window.history.pushState({}, "", link.href); window.history.pushState({}, "", link.href);
document.title = 'CheezeNotes - ' + link.getAttribute('data-href');
ta.value = data; ta.value = data;
load(document.getElementById('ta'), document.getElementById('cheezenotes')); load(document.getElementById('ta'), document.getElementById('cheezenotes'));
let editModeButton = document.getElementById('editModeButton');
if (editModeButton.classList.contains('buttonoff')) {
let cheezenotes = document.getElementById('cheezenotes');
cheezenotes.contentEditable = false;
}
content.scrollTop = 0; content.scrollTop = 0;
content.scrollLeft = 0; content.scrollLeft = 0;
}); });
@ -149,21 +155,27 @@ function formatLine(line) {
} else if (line.match(/^\s*######(\s|$)/i)) { } else if (line.match(/^\s*######(\s|$)/i)) {
token = /^(\s*######(\s|$))/i; token = /^(\s*######(\s|$))/i;
elem.classList.add('h6'); elem.classList.add('h6');
elem.classList.add('h');
} else if (line.match(/^\s*#####(\s|$)/i)) { } else if (line.match(/^\s*#####(\s|$)/i)) {
token = /^(\s*#####(\s|$))/i; token = /^(\s*#####(\s|$))/i;
elem.classList.add('h5'); elem.classList.add('h5');
elem.classList.add('h');
} else if (line.match(/^\s*####(\s|$)/i)) { } else if (line.match(/^\s*####(\s|$)/i)) {
token = /^(\s*####(\s|$))/i; token = /^(\s*####(\s|$))/i;
elem.classList.add('h4'); elem.classList.add('h4');
elem.classList.add('h');
} else if (line.match(/^\s*###(\s|$)/i)) { } else if (line.match(/^\s*###(\s|$)/i)) {
token = /^(\s*###(\s|$))/i; token = /^(\s*###(\s|$))/i;
elem.classList.add('h3'); elem.classList.add('h3');
elem.classList.add('h');
} else if (line.match(/^\s*##(\s|$)/)) { } else if (line.match(/^\s*##(\s|$)/)) {
token = /^(\s*##(\s|$))/i; token = /^(\s*##(\s|$))/i;
elem.classList.add('h2'); elem.classList.add('h2');
elem.classList.add('h');
} else if (line.match(/^\s*#(\s|$)/i)) { } else if (line.match(/^\s*#(\s|$)/i)) {
token = /^(\s*#(\s|$))/i; token = /^(\s*#(\s|$))/i;
elem.classList.add('h1'); elem.classList.add('h1');
elem.classList.add('h');
} else if (line.match(/^\s*>\s*>\s*>(\s|$)/i)) { } else if (line.match(/^\s*>\s*>\s*>(\s|$)/i)) {
token = /^(\s*>\s*>\s*>(\s|$))/i; token = /^(\s*>\s*>\s*>(\s|$))/i;
elem.classList.add('bq3'); elem.classList.add('bq3');

Loading…
Cancel
Save