From 5cf59994f708cf6ced91cdf77e65b421ab76a010 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sun, 20 Mar 2016 13:29:20 +0000 Subject: [PATCH] Work in progress blog app. Added cork/uncork to the terminal so that I can suppress blinking. I think I accidentally fixed some output issues in here, too. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3174 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- core/core.js | 2 + core/terminal.js | 33 ++++++- packages/cory/blog/blog.js | 189 +++++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+), 3 deletions(-) create mode 100644 packages/cory/blog/blog.js diff --git a/core/core.js b/core/core.js index 2d70fc78f..063161c36 100644 --- a/core/core.js +++ b/core/core.js @@ -303,6 +303,8 @@ function getProcess(packageOwner, packageName, key, options) { 'split': process.terminal.split.bind(process.terminal), 'select': process.terminal.select.bind(process.terminal), 'postMessageToIframe': process.terminal.postMessageToIframe.bind(process.terminal), + 'cork': process.terminal.cork.bind(process.terminal), + 'uncork': process.terminal.uncork.bind(process.terminal), }; } if (manifest diff --git a/core/terminal.js b/core/terminal.js index 312f8ae45..044a582ad 100644 --- a/core/terminal.js +++ b/core/terminal.js @@ -23,6 +23,7 @@ function Terminal() { this._echo = true; this._readLine = null; this._selected = null; + this._corked = 0; return this; } @@ -30,11 +31,22 @@ Terminal.kBacklog = 64; Terminal.prototype.dispatch = function(data) { for (var i in this._waiting) { - this._waiting[i](data); + this.feedWaiting(this._waiting[i], data); } this._waiting.length = 0; } +Terminal.prototype.feedWaiting = function(waiting, data) { + var terminal = this; + var payload = terminal._lines.slice(Math.max(0, waiting.haveIndex + 1 - terminal._firstLine)); + if (data) { + payload.push(data); + } + if (waiting.haveIndex < terminal._index - 1 || data) { + waiting.resolve({index: terminal._index - 1, lines: payload}); + } +} + Terminal.prototype.print = function() { var data = arguments; if (this._selected) { @@ -49,7 +61,9 @@ Terminal.prototype.print = function() { this._firstLine = this._index - Terminal.kBacklog; this._lines = this._lines.slice(this._lines.length - Terminal.kBacklog); } - this.dispatch({index: this._index - 1, lines: [data]}); + if (this._corked == 0) { + this.dispatch(); + } this._lastWrite = new Date(); } @@ -106,7 +120,7 @@ Terminal.prototype.getOutput = function(haveIndex) { if (haveIndex < terminal._index - 1) { resolve({index: terminal._index - 1, lines: terminal._lines.slice(Math.max(0, haveIndex + 1 - terminal._firstLine))}); } else { - terminal._waiting.push(resolve); + terminal._waiting.push({haveIndex: haveIndex, resolve: resolve}); } }); } @@ -125,6 +139,19 @@ Terminal.prototype.readLine = function() { }); } +Terminal.prototype.cork = function() { + this._corked++; +} + +Terminal.prototype.uncork = function() { + if (--this._corked == 0) { + for (var i = 0; i < this._waiting.length; i++) { + this.feedWaiting(this._waiting[i]); + } + this._waiting.length = 0; + } +} + function invoke(handlers, argv) { var promises = []; if (handlers) { diff --git a/packages/cory/blog/blog.js b/packages/cory/blog/blog.js new file mode 100644 index 000000000..44aaef4e3 --- /dev/null +++ b/packages/cory/blog/blog.js @@ -0,0 +1,189 @@ +"use strict"; + +class Log { + constructor(name, capacity) { + this._name = name; + this._capacity = capacity || -1; + } + + 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 []; + } + }); + } + + 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(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"}); + } + + 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(); + } + }); +} + +var gNewPost; + +function submitNewPost() { + return gBlog.append(gNewPost); +} + +function startNewPost() { + core.register("onWindowMessage", function(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(); + }); + + terminal.split([ + { + type: "horizontal", + children: [ + {name: "left", grow: "0", shrink: "0", basis: "50%"}, + {name: "right", grow: "0", shrink: "0", basis: "50%"}, + ], + } + ]); + terminal.select("left"); + terminal.print({iframe: ` + + + + + + + + + `, style: "overflow: hidden; position: relative; left: 0; top: 0; right: 0; bottom: 0"}); + terminal.select("right"); +} + +renderBlog(); \ No newline at end of file