diff --git a/core/client.js b/core/client.js index b430e0c0..f9ccc6d5 100644 --- a/core/client.js +++ b/core/client.js @@ -11,7 +11,7 @@ var gGeolocatorWatch; var kMaxCommandHistory = 16; -function enter(event) { +function keydown(event) { if (event.keyCode == 13) { gCommandHistory.push(document.getElementById("input").value); if (gCommandHistory.length > kMaxCommandHistory) { @@ -19,20 +19,23 @@ function enter(event) { } send(); event.preventDefault(); - } else if (event.keyCode == 38) { + } else if (event.keyCode == 38 && !event.altKey) { if (gCommandHistory.length) { var input = document.getElementById("input"); gCommandHistory.unshift(input.value); input.value = gCommandHistory.pop(); event.preventDefault(); } - } else if (event.keyCode == 40) { + } else if (event.keyCode == 40 && !event.altKey) { if (gCommandHistory.length) { var input = document.getElementById("input"); gCommandHistory.push(input.value); input.value = gCommandHistory.shift(); event.preventDefault(); } + } else if (event.keyCode == 69 && event.altKey) { + window.location.href = url() + "/edit"; + event.preventDefault(); } } @@ -576,7 +579,7 @@ window.addEventListener("load", function() { Notification.requestPermission(); } var input = document.getElementById("input"); - input.addEventListener("keydown", enter); + input.addEventListener("keydown", keydown); input.focus(); window.addEventListener("hashchange", hashChange); window.addEventListener("focus", focus); diff --git a/core/editor.js b/core/editor.js index 2ed622a8..db9c2a10 100644 --- a/core/editor.js +++ b/core/editor.js @@ -11,6 +11,15 @@ window.addEventListener("load", function() { 'showTrailingSpace': true, }); gBackup = gEditor.getValue(); + gEditor.focus(); +}); + +window.addEventListener("keydown", function(event) { + if (event.keyCode == 83 && event.altKey) { + save(); + } else if (event.keyCode == 66 && event.altKey) { + back(); + } }); function explodePath() { diff --git a/packages/cory/blog/blog.js b/packages/cory/blog/blog.js index 63766109..1ca80ae8 100644 --- a/packages/cory/blog/blog.js +++ b/packages/cory/blog/blog.js @@ -1,195 +1,195 @@ "use strict"; -//! {"category": "work in progress"} +//! {"category": "work in progress", "require": ["libdocument", "liblist", "ui"]} -class Log { - constructor(name, capacity) { - this._name = name; - this._capacity = capacity || -1; +let libdocument = require("libdocument"); +let liblist = require("liblist"); +let libui = require("ui"); + +class Blog { + constructor() { + this._list = liblist.ListStore("blog:list"); + this._documents = libdocument.DocumentStore("blog:posts"); } - append(item) { - var log = this; - return database.get(log._name + "_head").catch(function(error) { - return 0; - }).then(function(head) { - var newHead = (parseInt(head) || 0) + 1; - var actions = [ - database.set(log._name + "_" + newHead.toString(), JSON.stringify(item)), - database.set(log._name + "_head", newHead), - ]; - if (log._capacity >= 0) { - actions.push(log.truncate(newHead - log._capacity)); - } - return Promise.all(actions); - }); - } - - truncate(end) { - var log = this; - return database.get(log._name + "_" + end.toString()).then(function(item) { - if (item) { - return database.remove(log._name + "_" + end.toString()).then(function() { - return log.truncate(end - 1); - }); - } - }); - } - - get(count, start, result) { - var log = this; - if (!count) { - count = 10; - } - - if (!start) { - return database.get(log._name + "_head").then(function(head) { - if (head !== undefined) { - return log.get(count, parseInt(head)); - } else { - return []; + async renderIndex() { + terminal.cork(); + try { + terminal.split([{name: "terminal"}]); + terminal.clear(); + let posts = await this._list.get(-1, -10); + for (let i = 0; i < posts.length; i++) { + let post = await this._documents.get(posts[i]); + if (post) { + let formatted = this.formatPost(post); + for (let j in formatted) { + terminal.print(formatted[j]); + } } - }); + } + if (core.user.credentials.permissions.administration) { + terminal.print({command: JSON.stringify({action: "new"}), value: "new post"}); + } + } finally { + terminal.uncork(); } - - var promises = []; - promises.length = count; - for (var i = 0; i < count; i++) { - promises[i] = database.get(log._name + "_" + (start - i).toString()); - } - return Promise.all(promises); - } -}; - -/* - -if (imports.terminal) { - core.register("onSubmit", function(message) { - core.broadcast(message); - }); - - core.register("onMessage", function(from, message) { - terminal.print(JSON.stringify(message)); - }); - - terminal.print("Hello, world!"); - var log = new Log("events"); - - function dump() { - return log.get().then(function(data) { - terminal.print(JSON.stringify(data)); - }).catch(function(error) { - terminal.print(error); - }); } - core.register("onInput", function(input) { - log.append({message: input}).then(dump); - }); -} - -core.register("onAtom", function(query) { - return "hello, world!"; -}); - -*/ - -terminal.setEcho(false); - -var gBlog = new Log("blog"); - -core.register("onInput", function(input) { - if (input == "new post") { - startNewPost(); - } else if (input == "submit") { - submitNewPost().then(function() { - core.unregister("onWindowMessage", onWindowMessage); - renderBlog(); - }); - } -}); - -function renderBlog() { - terminal.split([ - {name: "terminal"}, - ]); - terminal.select("terminal"); - - terminal.print("Blog Test"); - if (core.user.credentials.permissions.authenticated) { - terminal.print({command: "new post"}); + formatPost(post) { + let result = [ + [{style: "font-size: xx-large", value: post.title}], + [{style: "font-size: x-small", value: post.author}, " ", {style: "font-size: x-small", value: post.created}], + post.body, + ]; + if (core.user.credentials.permissions.administration) { + result[0].push({command: JSON.stringify({action: "edit", post: post.name}), value: "edit"}); + } + return result; } - gBlog.get(10).then(function(entries) { - for (var i = 0; i < entries.length; i++) { - var entry = JSON.parse(entries[i]); - terminal.print({style: "font-weight: bold", value: entry.title}); - terminal.print(entry.entry); - terminal.print(); + async submitPost(post) { + let now = new Date(); + let oldPost = await this._documents.get(post.name); + if (!oldPost) { + post.created = now; + post.author = core.user.name; + this._list.push(post.name); + } else { + for (let key in oldPost) { + if (!post[key]) { + post[key] = oldPost[key]; + } + } } - }); -} + post.modified = now; + await this._documents.set(post.name, post); + } -var gNewPost; + async deletePost(name) { + await this._documents.set(name, null); + } -function submitNewPost() { - return gBlog.append(gNewPost); -} - -function onWindowMessage(message) { - gNewPost = message.message; - terminal.cork(); - terminal.select("right"); - terminal.clear(); - terminal.print({style: "font-width: x-large", value: message.message.title}); - terminal.print(message.message.entry); - terminal.print({command: "submit"}); - terminal.uncork(); -} - -function startNewPost() { - core.register("onWindowMessage", onWindowMessage); - terminal.split([ - { - type: "horizontal", - children: [ - {name: "left", grow: "0", shrink: "0", basis: "50%"}, - {name: "right", grow: "0", shrink: "0", basis: "50%"}, - ], + async handleCommand(command) { + if (command.action == "edit") { + await this.edit(command.post); + } else if (command.action == "new") { + await this.edit(null); + } else if (command.action == "delete") { + await this.deletePost(command.post); } - ]); - terminal.select("left"); - terminal.print({iframe: ` -
+ } + + async edit(page) { + terminal.cork(); + try { + let self = this; + self._post = await this._documents.get(page); + + if (!this._onWindowMessage) { + this._onWindowMessage = function(event) { + let message = event.message; + if (message == "load") { + terminal.postMessageToIframe("iframe", self._post); + } else if (message.action == "save") { + self.submitPost(message.post).then(self.renderIndex.bind(self)).catch(terminal.print); + } else if (message.action == "delete") { + self.deletePost(message.post).then(self.renderIndex.bind(self)).catch(terminal.print); + } else if (message.action == "back") { + self.renderIndex.bind(self)().catch(terminal.print); + } + } + core.register("onWindowMessage", this._onWindowMessage); + } + + terminal.split([{name: "terminal", type: "vertical"}]); + terminal.clear(); + terminal.print({iframe: ` + + + + + - - - - - - - `, style: "overflow: hidden; position: relative; left: 0; top: 0; right: 0; bottom: 0"}); - terminal.select("right"); + body: gEditor.getValue(), + }, + }, "*"); + } + function deletePost() { + parent.postMessage({ + action: "delete", + post: document.getElementById("name").value, + }, "*"); + } + + + +`, name: "iframe", style: "flex: 1 1 auto; width: 100%; margin: 0; border: 0; padding: 0;"}); + } finally { + terminal.uncork(); + } + } } -renderBlog(); \ No newline at end of file +terminal.setEcho(false); +let blog = new Blog(); +blog.renderIndex().catch(terminal.print); + +core.register("onInput", async function(input) { + try { + await blog.handleCommand(JSON.parse(input)); + } catch (error) { + terminal.print(error); + } +}); \ No newline at end of file