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.');
}
}
}