From dab7050899be0b7cadc5e04946e633f82fef6837 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sat, 21 Jan 2023 00:16:18 +0000 Subject: [PATCH] Experimenting with storing drafts. Fixed an old scary tfrpc bug which resulted in localStorageGet returning wrong values on subsequent calls. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4138 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- apps/cory/ssb.json | 2 +- apps/cory/ssb/tf-compose.js | 26 +++++++++++++++++--------- apps/cory/ssb/tf-message.js | 21 +++++++++++++-------- apps/cory/ssb/tf-news.js | 4 +++- apps/cory/ssb/tf-tab-news.js | 26 +++++++++++++++++++++++--- core/app.js | 14 +++++++------- core/client.js | 10 ++++++---- core/tfrpc.js | 31 ++++++++++++++----------------- 8 files changed, 84 insertions(+), 50 deletions(-) diff --git a/apps/cory/ssb.json b/apps/cory/ssb.json index 3432cf5b..b3536f9a 100644 --- a/apps/cory/ssb.json +++ b/apps/cory/ssb.json @@ -1 +1 @@ -{"type":"tildefriends-app","files":{"app.js":"&1HWTkyCc1doft6dyKF5FDxtRAErNeY25CBrfZbKPpyo=.sha256","lit-all.min.js":"&XKgdRySJuiZeZvchNFGjVWn0XOVhQFmG7/HTWYQ8s68=.sha256","index.html":"&TxhFekB9ov7tf/fmkAg7x5797i27oLidhgxEfDKC0T0=.sha256","script.js":"&G8puK9Q4MngHy3D4ppcKyT49WKbHD2OCeUcAw2ghTDE=.sha256","lit-all.min.js.map":"&lA9iFp1YbqSndxXZuwtgmrj7NDMkN71nJITbtjWL3VA=.sha256","tf-id-picker.js":"&maN8DUFrmRxW5nsVyOAMk5k1ekcz/pfzvSS99ac3jo8=.sha256","tf-app.js":"&7hclNu41CIoNk1JlXHiYmDPDyDIICZfMickJYtnF5eQ=.sha256","tf-message.js":"&oXFucwmn16nvKslQoGKTppO+71EoDZJE54z3WrlNUPI=.sha256","tf-user.js":"&bXTedgBudTQLXEBPY9R8OLfQ/ZLpo8YRU9Oq/wuGG3Y=.sha256","tf-utils.js":"&6RQUuxB3PkOhYEJr9+89Ptx7uijczjn0r035yCcQOQQ=.sha256","commonmark.min.js":"&bfBaMLU19d1p/vPBF9hlARqDX002KXG/UOfxOahZhe4=.sha256","tf-compose.js":"&ZFkTrACfSE3CeacnuHcpqysPuNm2TJ2ATVQfJv+qjzU=.sha256","emojis.json":"&h3P4pez+AI4aYdsN0dJ3pbUEFR0276t9AM20caj/W/s=.sha256","emojis.js":"&NC9VddNdX+ZpyIDUQJvH2y1u3ZczQub5+bNmN9ndj7I=.sha256","tf-styles.js":"&LFeL/vWgrv4N8q/mBrQAnhbaOI+dXNJYvH9bn1bXSqQ=.sha256","tf-profile.js":"&vRKjsnYvOiHCQahzEfznCvP5YDwUPtltlpWf+pxwZ1Y=.sha256","commonmark-linkify.js":"&X+hNNkmSRvKY86khyAun+cXksquXbMakZdINbGbx30g=.sha256","tf-tab-search.js":"&ESt2vMG19sH5j6ungKua/ZuvIGslyuWyb3juXdOCecg=.sha256","tf-tab-news.js":"&F7T3LVS867x7vsKhYRR7eLNdCFZmrZ3JzEMfJEEKRm0=.sha256","tf-tab-connections.js":"&ywqBz3w63R6naH09kZ+01A0SfmtuSfk8QPBXWsli0yg=.sha256","tf-news.js":"&gfG5LwXpugDkwDCOCOxQnNn0jLURZexSmvDu4SpQohA=.sha256","tribute.css":"&9FogMzZHKXCfGb7mlh7z+/wiNZzBsOB/tKoh6MfYJno=.sha256","tribute.esm.js":"&P1wKqCfYULpR/ahSB98JP8xaxfikuZwwtT6I/SAo7/Y=.sha256","commonmark-hashtag.js":"&H+V1OLA9GDdzycKclz276zAtSZLpT3rlNVa4+qQmp4o=.sha256"}} \ No newline at end of file +{"type":"tildefriends-app","files":{"app.js":"&1HWTkyCc1doft6dyKF5FDxtRAErNeY25CBrfZbKPpyo=.sha256","lit-all.min.js":"&XKgdRySJuiZeZvchNFGjVWn0XOVhQFmG7/HTWYQ8s68=.sha256","index.html":"&TxhFekB9ov7tf/fmkAg7x5797i27oLidhgxEfDKC0T0=.sha256","script.js":"&G8puK9Q4MngHy3D4ppcKyT49WKbHD2OCeUcAw2ghTDE=.sha256","lit-all.min.js.map":"&lA9iFp1YbqSndxXZuwtgmrj7NDMkN71nJITbtjWL3VA=.sha256","tf-id-picker.js":"&maN8DUFrmRxW5nsVyOAMk5k1ekcz/pfzvSS99ac3jo8=.sha256","tf-app.js":"&7hclNu41CIoNk1JlXHiYmDPDyDIICZfMickJYtnF5eQ=.sha256","tf-message.js":"&mEvBE2g6disBMLyaqu11wwGFGuBU2VmRJuwMBqORvfA=.sha256","tf-user.js":"&bXTedgBudTQLXEBPY9R8OLfQ/ZLpo8YRU9Oq/wuGG3Y=.sha256","tf-utils.js":"&6RQUuxB3PkOhYEJr9+89Ptx7uijczjn0r035yCcQOQQ=.sha256","commonmark.min.js":"&bfBaMLU19d1p/vPBF9hlARqDX002KXG/UOfxOahZhe4=.sha256","tf-compose.js":"&fTO3L8YlYTZ15ph7Sh54TY8YmAidkGjZa9rmT1YtVt4=.sha256","emojis.json":"&h3P4pez+AI4aYdsN0dJ3pbUEFR0276t9AM20caj/W/s=.sha256","emojis.js":"&NC9VddNdX+ZpyIDUQJvH2y1u3ZczQub5+bNmN9ndj7I=.sha256","tf-styles.js":"&LFeL/vWgrv4N8q/mBrQAnhbaOI+dXNJYvH9bn1bXSqQ=.sha256","tf-profile.js":"&vRKjsnYvOiHCQahzEfznCvP5YDwUPtltlpWf+pxwZ1Y=.sha256","commonmark-linkify.js":"&X+hNNkmSRvKY86khyAun+cXksquXbMakZdINbGbx30g=.sha256","tf-tab-search.js":"&ESt2vMG19sH5j6ungKua/ZuvIGslyuWyb3juXdOCecg=.sha256","tf-tab-news.js":"&+hexNqLjYcjPnpDsU962Hy4wWh++pNWVZHO4gI3f1C8=.sha256","tf-tab-connections.js":"&ywqBz3w63R6naH09kZ+01A0SfmtuSfk8QPBXWsli0yg=.sha256","tf-news.js":"&jPigwc9k+I5nMjsaw14Kdt89I/s6m9LVcKG/udR+LGw=.sha256","tribute.css":"&9FogMzZHKXCfGb7mlh7z+/wiNZzBsOB/tKoh6MfYJno=.sha256","tribute.esm.js":"&P1wKqCfYULpR/ahSB98JP8xaxfikuZwwtT6I/SAo7/Y=.sha256","commonmark-hashtag.js":"&H+V1OLA9GDdzycKclz276zAtSZLpT3rlNVa4+qQmp4o=.sha256"}} \ No newline at end of file diff --git a/apps/cory/ssb/tf-compose.js b/apps/cory/ssb/tf-compose.js index 9b266019..cee56567 100644 --- a/apps/cory/ssb/tf-compose.js +++ b/apps/cory/ssb/tf-compose.js @@ -1,4 +1,4 @@ -import {LitElement, html} from './lit-all.min.js'; +import {LitElement, html, unsafeHTML} from './lit-all.min.js'; import * as tfutils from './tf-utils.js'; import * as tfrpc from '/static/tfrpc.js'; import {styles} from './tf-styles.js'; @@ -13,6 +13,7 @@ class TfComposeElement extends LitElement { branch: {type: String}, mentions: {type: Object}, apps: {type: Object}, + drafts: {type: Object}, } } @@ -25,13 +26,13 @@ class TfComposeElement extends LitElement { this.branch = undefined; this.mentions = {}; this.apps = undefined; + this.drafts = {}; } - changed(event) { - let edit = this.renderRoot.getElementById('edit'); - let preview = this.renderRoot.getElementById('preview'); - let text = edit.value; - + process_text(text) { + if (!text) { + return ''; + } /* Update mentions. */ for (let match of text.matchAll(/\[([^\[]+)]\(([@&%][^\)]+)/g)) { let name = match[1]; @@ -57,8 +58,14 @@ class TfComposeElement extends LitElement { this.mentions[link].name = name.startsWith('@') ? name.substring(1) : name; this.mentions = Object.assign({}, this.mentions); } + return tfutils.markdown(text); + } - preview.innerHTML = tfutils.markdown(text); + changed(event) { + let edit = this.renderRoot.getElementById('edit'); + let preview = this.renderRoot.getElementById('preview'); + preview.innerHTML = this.process_text(edit.value); + this.dispatchEvent(new CustomEvent('tf-draft', {detail: {id: this.branch, draft: edit.value, bubbles: true}})); } convert_to_format(buffer, type, mime_type) { @@ -157,6 +164,7 @@ class TfComposeElement extends LitElement { edit.value = ''; self.mentions = {}; self.changed(); + this.dispatchEvent(new CustomEvent('tf-draft', {detail: {id: this.branch, discard: undefined}})); }).catch(function(error) { alert(error.message); }); @@ -166,7 +174,7 @@ class TfComposeElement extends LitElement { let edit = this.renderRoot.getElementById('edit'); edit.value = ''; this.changed(); - this.dispatchEvent(new CustomEvent('tf-discard')); + this.dispatchEvent(new CustomEvent('tf-draft', {bubble: true, composed: true, detail: {id: this.branch, discard: undefined}})); } attach() { @@ -258,7 +266,7 @@ class TfComposeElement extends LitElement { let self = this; let result = html`
- +
${Object.values(this.mentions).map(x => self.render_mention(x))} diff --git a/apps/cory/ssb/tf-message.js b/apps/cory/ssb/tf-message.js index f806e2e5..f6d68c82 100644 --- a/apps/cory/ssb/tf-message.js +++ b/apps/cory/ssb/tf-message.js @@ -10,7 +10,7 @@ class TfMessageElement extends LitElement { whoami: {type: String}, message: {type: Object}, users: {type: Object}, - reply: {type: Boolean}, + drafts: {type: Object}, raw: {type: Boolean}, collapsed: {type: Boolean}, content_warning_expanded: {type: Boolean}, @@ -27,13 +27,19 @@ class TfMessageElement extends LitElement { this.whoami = null; this.message = {}; this.users = {}; - this.reply = false; + this.drafts = {}; this.raw = false; this.collapsed = false; } show_reply() { - this.reply = true; + let event = new CustomEvent('tf-draft', {bubbles: true, composed: true, detail: {id: this.message?.id, draft: ''}}); + this.dispatchEvent(event); + } + + discard_reply() { + console.log('discard'); + this.dispatchEvent(new CustomEvent('tf-draft', {bubbles: true, composed: true, detail: {id: this.id, draft: undefined}})); } render_votes() { @@ -186,7 +192,7 @@ class TfMessageElement extends LitElement { if (this.collapsed) { return html` self.collapsed = false}>`; } else { - return html` self.collapsed = true}>${(this.message.child_messages || []).map(x => html``)}`; + return html` self.collapsed = true}>${(this.message.child_messages || []).map(x => html``)}`; } } } @@ -214,7 +220,7 @@ class TfMessageElement extends LitElement { ${this.message.id} (placeholder)
${this.render_votes()}
${(this.message.child_messages || []).map(x => html` - + `)} `; } else if (typeof(content?.type === 'string')) { @@ -258,14 +264,13 @@ class TfMessageElement extends LitElement { `); } else if (content.type == 'post') { - let reply = this.reply ? html` + let reply = (this.drafts[this.message?.id] !== undefined) ? html` this.reply = false}> + @tf-discard=${this.discard_reply}> ` : html` `; diff --git a/apps/cory/ssb/tf-news.js b/apps/cory/ssb/tf-news.js index 48448ad9..eb6cea5f 100644 --- a/apps/cory/ssb/tf-news.js +++ b/apps/cory/ssb/tf-news.js @@ -9,6 +9,7 @@ class TfNewsElement extends LitElement { users: {type: Object}, messages: {type: Array}, following: {type: Array}, + drafts: {type: Object}, } } @@ -21,6 +22,7 @@ class TfNewsElement extends LitElement { this.users = {}; this.messages = []; this.following = []; + this.drafts = {}; } process_messages(messages) { @@ -145,7 +147,7 @@ class TfNewsElement extends LitElement { let final_messages = this.finalize_messages(messages_by_id); return html`
- ${final_messages.map(x => html``)} + ${final_messages.map(x => html``)}
`; } diff --git a/apps/cory/ssb/tf-tab-news.js b/apps/cory/ssb/tf-tab-news.js index 5852af4d..08424bb5 100644 --- a/apps/cory/ssb/tf-tab-news.js +++ b/apps/cory/ssb/tf-tab-news.js @@ -10,6 +10,7 @@ class TfTabNewsFeedElement extends LitElement { hash: {type: String}, following: {type: Array}, messages: {type: Array}, + drafts: {type: Object}, } } @@ -22,6 +23,7 @@ class TfTabNewsFeedElement extends LitElement { this.users = {}; this.hash = '#'; this.following = []; + this.drafts = {}; } async fetch_messages() { @@ -102,7 +104,7 @@ class TfTabNewsFeedElement extends LitElement { alert(JSON.stringify(error, null, 2)); }); } - return html``; + return html``; } } @@ -114,6 +116,7 @@ class TfTabNewsElement extends LitElement { hash: {type: String}, unread: {type: Array}, following: {type: Array}, + drafts: {type: Object}, } } @@ -128,6 +131,10 @@ class TfTabNewsElement extends LitElement { this.unread = []; this.following = []; this.cache = {}; + this.drafts = {}; + tfrpc.rpc.localStorageGet('drafts').then(function(d) { + self.drafts = JSON.parse(d || '{}'); + }); } show_more() { @@ -156,6 +163,19 @@ class TfTabNewsElement extends LitElement { return 'Show New: ' + Object.keys(counts).sort().map(x => (counts[x].toString() + ' ' + x + 's')).join(', '); } + draft(event) { + let id = event.detail.id || ''; + if (event.detail.draft !== undefined) { + let draft = {}; + draft[id] = event.detail.draft; + this.drafts = Object.assign({}, this.drafts, draft); + } else { + delete this.drafts[id]; + this.drafts = Object.assign({}, this.drafts); + } + tfrpc.rpc.localStorageSet('drafts', JSON.stringify(this.drafts)); + } + render() { let profile = this.hash.startsWith('#@') ? html`` : undefined; @@ -163,9 +183,9 @@ class TfTabNewsElement extends LitElement {
🏠Home
Welcome, !
-
+
${profile} - + `; } } diff --git a/core/app.js b/core/app.js index 8f2c2ab6..7ab625a4 100644 --- a/core/app.js +++ b/core/app.js @@ -22,14 +22,14 @@ App.prototype.readOutput = function(callback) { App.prototype.makeFunction = function(api) { let self = this; - let id = g_next_id++; - while (!id || g_calls[id]) { - id = g_next_id++; - } - let promise = new Promise(function(resolve, reject) { - g_calls[id] = {resolve: resolve, reject: reject}; - }); let result = function() { + let id = g_next_id++; + while (!id || g_calls[id]) { + id = g_next_id++; + } + let promise = new Promise(function(resolve, reject) { + g_calls[id] = {resolve: resolve, reject: reject}; + }); let message = { message: 'tfrpc', method: api[0], diff --git a/core/client.js b/core/client.js index 9d6eb430..75555682 100644 --- a/core/client.js +++ b/core/client.js @@ -387,7 +387,7 @@ function api_localStorageSet(key, value) { window.localStorage.setItem('app:' + key, value); } -function api_localStorageGet(key, value) { +function api_localStorageGet(key) { return window.localStorage.getItem('app:' + key); } @@ -620,17 +620,19 @@ function _receive_websocket_message(message) { message.message === 'tfrpc' && message.method) { let api = k_api[message.method]; + let id = message.id; + let params = message.params; if (api) { - Promise.resolve(api.func(...message.params)).then(function(result) { + Promise.resolve(api.func(...params)).then(function(result) { send({ message: 'tfrpc', - id: message.id, + id: id, result: result, }); }).catch(function(error) { send({ message: 'tfrpc', - id: message.id, + id: id, error: error, }); }); diff --git a/core/tfrpc.js b/core/tfrpc.js index d187db4d..ac976c1e 100644 --- a/core/tfrpc.js +++ b/core/tfrpc.js @@ -14,7 +14,7 @@ if (k_is_browser) { function make_rpc(target, prop, receiver) { return function() { let id = g_next_id++; - while (!id || g_calls[id]) { + while (!id || g_calls[id] !== undefined) { id = g_next_id++; } let promise = new Promise(function(resolve, reject) { @@ -39,38 +39,35 @@ function send(response) { function call_rpc(message) { if (message && message.message === 'tfrpc') { + let method = g_api[message.method]; + let id = message.id; if (message.method) { - let method = g_api[message.method]; if (method) { - let response = {message: 'tfrpc', id: message.id}; try { Promise.resolve(method(...message.params)).then(function(result) { - response.result = result; - send(response); + send({message: 'tfrpc', id: id, result: result}); }).catch(function(error) { - response.error = error; - send(response); + send({message: 'tfrpc', id: id, error: error}); }); } catch (error) { - response.error = error; - send(response); + send({message: 'tfrpc', id: id, error: error}); } } else { throw new Error(message.method + ' not found.'); } } else if (message.error !== undefined) { - if (g_calls[message.id]) { - g_calls[message.id].reject(message.error); - delete g_calls[message.id]; + if (g_calls[id]) { + g_calls[id].reject(message.error); + delete g_calls[id]; } else { - throw new Error(message.id + ' not found to reply.'); + throw new Error(id + ' not found to reply.'); } } else { - if (g_calls[message.id]) { - g_calls[message.id].resolve(message.result); - delete g_calls[message.id]; + if (g_calls[id]) { + g_calls[id].resolve(message.result); + delete g_calls[id]; } else { - throw new Error(message.id + ' not found to reply.'); + throw new Error(id + ' not found to reply.'); } } }