From 6b2e789d54501ebc066344906286b58efc49c559 Mon Sep 17 00:00:00 2001 From: Hugh Rundle Date: Sun, 12 Mar 2023 15:02:39 +1100 Subject: [PATCH] UI improvements and bug fixes fixes #5 fixes #6 fixes #7 --- server.js | 43 +++++++++++++++-------- static/style.css | 29 +++++++++++++++ templates/edit.spy | 9 +++-- templates/help.spy | 5 ++- templates/index.spy | 19 ++++------ templates/new.spy | 21 +++++++++++ templates/partials/header.spy | 6 ---- templates/published.spy | 7 +++- templates/settings.spy | 5 ++- utilities.js | 66 +++++++++++++++++++---------------- 10 files changed, 139 insertions(+), 71 deletions(-) create mode 100644 templates/new.spy delete mode 100644 templates/partials/header.spy diff --git a/server.js b/server.js index cc59d4f..8a7666d 100644 --- a/server.js +++ b/server.js @@ -48,18 +48,7 @@ app.set('view engine', 'spy'); // GET app.get('/', requireLoggedIn, (req, res) => { - let data = { - title: 'Home', - disabled: '', - message: getSavedFile(req.session.user.username) - } - let today = getNow().toISOString().slice(0,10) - let latestPost = req.session.user.latest_post - if (today === latestPost) { - data.disabled = 'disabled' - data.message = `Relax, ${req.session.user.username}, you have already posted today.` - } - res.render('index.spy', data) + res.render('index.spy', {title: 'Soyuz home', writeNew: getSavedFile(req.session.user.username)? 'Return to draft' : 'New'}) }) app.get('/login', (req, res) => { @@ -70,9 +59,33 @@ app.get('/login', (req, res) => { } }) +app.get('/new', requireLoggedIn, (req, res) => { + let message = getSavedFile(req.session.user.username) || "# Title of my note" + let data = { + title: 'New post', + disabled: '', + message: message + } + let today = getNow().toISOString().slice(0,10) + // check whether user has already posted today + return getLatestPost(req.session.user.directory, true, (dateString)=> { + if (today === dateString) { + data.disabled = 'disabled' + data.message = `Relax, ${req.session.user.username}, you have already posted today.` + } + res.render('new.spy', data) + }) +}) + app.get('/edit', requireLoggedIn, (req, res) => { - getLatestPost( req.session.user.directory, (data, path) => { - res.render('edit.spy', {data: data, path: path, title: 'Edit'}) + return getLatestPost(req.session.user.directory, true, (dateString) => { + if (dateString) { + return getLatestPost( req.session.user.directory, false, (message, path) => { + res.render('edit.spy', {message: message, path: path, title: 'Edit'}) + }) + } else { + res.redirect('/new') + } }) }) @@ -118,7 +131,7 @@ app.post('/publish', requireLoggedIn, (req, res) => { app.post('/save', requireLoggedIn, (req, res) => { saveFile(req.session.user.username, req.body.textarea, () => { - res.redirect('/') + res.redirect('/new') }) }) diff --git a/static/style.css b/static/style.css index afa4dee..e0f4080 100644 --- a/static/style.css +++ b/static/style.css @@ -77,11 +77,34 @@ main { text-decoration: none; } +.home-menu { + margin: auto; + padding: 0; + text-align: center; +} + +.home-button { + background: none; + color: inherit; + border: none; + padding: 0; + font: 2em sans-serif; + cursor: pointer; + outline: inherit; + text-decoration: none; + display: inline-block; + margin-bottom: 1em; +} + .disabled { background-color: #999; color: #000; } +section.disabled { + display: none; +} + .password-reset { width: 100%; margin-bottom: 1em; @@ -100,3 +123,9 @@ main { .menu-help { font-weight: bolder; } + +.alert { + margin: auto; + color: red; + font-weight: bold; +} diff --git a/templates/edit.spy b/templates/edit.spy index 7fb16de..dbf4466 100644 --- a/templates/edit.spy +++ b/templates/edit.spy @@ -1,13 +1,16 @@ << partials/head >> - << partials/header >> +
+ Home | + Settings | + Help +
- +
- |
diff --git a/templates/help.spy b/templates/help.spy index 319ffee..22dc8f3 100644 --- a/templates/help.spy +++ b/templates/help.spy @@ -1,6 +1,9 @@ << partials/head >> - << partials/header >> +
+ Home | + Settings +

Help

Soyuz is a web app for writing Gemini posts.

diff --git a/templates/index.spy b/templates/index.spy index e6c98fb..ae2f0c7 100644 --- a/templates/index.spy +++ b/templates/index.spy @@ -1,17 +1,10 @@ << partials/head >> - << partials/header >> - -
-
- -
- | - -
-
-
-
-
+ + {{ writeNew }}
+ Edit previous
+ Settings
+ Help +
diff --git a/templates/new.spy b/templates/new.spy new file mode 100644 index 0000000..9622ddc --- /dev/null +++ b/templates/new.spy @@ -0,0 +1,21 @@ +<< partials/head >> + +
+ Home | + Settings | + Help +
+
+
{{ alert }}
+
+ +
+ | + +
+
+
+
+
+ + diff --git a/templates/partials/header.spy b/templates/partials/header.spy deleted file mode 100644 index e23cff2..0000000 --- a/templates/partials/header.spy +++ /dev/null @@ -1,6 +0,0 @@ -
- New | - Edit | - Settings | - Help -
diff --git a/templates/published.spy b/templates/published.spy index ccddebc..c2c4699 100644 --- a/templates/published.spy +++ b/templates/published.spy @@ -1,7 +1,12 @@ << partials/head >>
- << partials/header >> +
+ Home | + Edit | + Settings | + Help +

{{ title }}

Hooray 🎉

diff --git a/templates/settings.spy b/templates/settings.spy index 15e5137..885c175 100644 --- a/templates/settings.spy +++ b/templates/settings.spy @@ -1,6 +1,9 @@ << partials/head >> - << partials/header >> +
+ Home | + Help +
diff --git a/utilities.js b/utilities.js index e66bd57..01f3476 100644 --- a/utilities.js +++ b/utilities.js @@ -35,7 +35,7 @@ const addUser = function(username, directory, callback){ let stmt = db.prepare( 'INSERT INTO users (username, directory, password, salt, saved_post) VALUES (?, ?, ?, ?, ?)' ); - stmt.run(username, directory, hash, salt, '# Title of my note'); + stmt.run(username, directory, hash, salt, null); return callback(password) }); } @@ -63,17 +63,6 @@ const resetPassword = function(username, pass, callback) { }); } -// update latest post in db -const updateLatestPostDate = function(username, callback) { - - let dateString = getNow().toISOString().slice(0,10) - let stmt = db.prepare( - 'UPDATE users SET latest_post = ? WHERE username = ?' - ); - stmt.run(dateString, username); - callback(dateString) -} - // AUTHORISATION MIDDLEWARE const verifyUser = function (req, res, next) { let username = req.body.username @@ -96,9 +85,8 @@ const verifyUser = function (req, res, next) { } req.session.user = { username: user.username, - directory: user.directory, - latest_post: user.latest_post, - }; + directory: user.directory + } next() }); } @@ -147,11 +135,8 @@ const publishNewPost = function(req, cb) { }) }) // clear any saved post now that it is published - saveFile(req.session.user.username, '# Title of my note', () => { - return updateLatestPostDate(req.session.user.username, datestring => { - req.session.user.latest_post = datestring - return cb() - }) + saveFile(req.session.user.username, null, () => { + return cb() }) } @@ -176,7 +161,6 @@ const publishNewPost = function(req, cb) { newlines.push(line) } } - lines[0] = '## Latest notes' newlines.unshift(`## Latest notes\n\n=> /${year}/${dateString}.gmi ${dateString} (${title})`) updated = newlines.join('\n') writeFile(indexFile, updated, (err) => { @@ -213,22 +197,38 @@ const publishNewPost = function(req, cb) { }) } -let getLatestPost = function(directory, callback) { +let getLatestPost = function(directory, dateOnly, callback) { // we check the index file because // a new post could have come from // somewhere other than the app // e.g. from a CLI on a laptop etc let indexFile = `${GEMINI_PATH}/${directory}/index.gmi` readFile(indexFile, {encoding: 'utf8'}, (err, data) => { - if (err) throw err; + if (err) { + if (err.code == 'ENOENT') { + return callback(null) + } + else { + throw err + } + } + + if (data.length == 0 || data == null) { + return callback(null) + } + let links = data.split('## Latest notes') let parts = links[1].split('\n')[2].split(' ') let filePath = `${GEMINI_PATH}/${directory}/${parts[1]}` - - readFile(filePath, {encoding: 'utf8'}, (err, file) => { - if (err) throw err; - return callback(file, filePath) - }) + if (dateOnly) { + let dateString = filePath.slice(-14,-4) + return callback(dateString) + } else { + readFile(filePath, {encoding: 'utf8'}, (err, file) => { + if (err) throw err; + return callback(file, filePath) + }) + } }) } @@ -237,9 +237,12 @@ let updatePost = function(req, callback) { let path = req.body.path let title = contents.split('\n')[0].split('# ')[1].trim() let year = getNow().toISOString().slice(0,4) - let dateString = getNow().toISOString().slice(0,10) let indexFile = `${GEMINI_PATH}/${req.session.user.directory}/index.gmi` let yearIndex = `${GEMINI_PATH}/${req.session.user.directory}/${year}/index.gmi` + let relative_path = path.slice(-20) + let post_date = relative_path.slice(6,16) + let prefix = `=> ${relative_path} ${post_date}` + let archivePrefix = `=> ${relative_path.slice(6)} ${post_date}` let updated = '' // we update the index and archive listings in case the title has changed @@ -250,7 +253,7 @@ let updatePost = function(req, callback) { let links = data.split('## Latest notes') let lines = links[1].split('\n') lines[0] = '## Latest notes' - lines[2] = `=> /${year}/${dateString}.gmi ${dateString} (${title})` + lines[2] = `${prefix} (${title})` updated = links[0] + lines.join('\n') // update index on homepage writeFile(indexFile, updated, (err) => { @@ -260,7 +263,7 @@ let updatePost = function(req, callback) { throw err } else { let lines = data.split('\n') - lines[2] = `=> ${dateString}.gmi ${dateString} (${title})` + lines[2] = `${archivePrefix} (${title})` updated = lines.join('\n') // update archive page writeFile(yearIndex, updated, (err) => { @@ -280,6 +283,7 @@ let updatePost = function(req, callback) { }) } +// NOTE: this refers to saving the file on the database, not publishing the file to the server let saveFile = function(user, text, callback) { let stmt = db.prepare( 'UPDATE users SET saved_post = ? WHERE username = ?'