diff --git a/apps/cory/docs.json b/apps/cory/docs.json index 519f81b2..85370dd0 100644 --- a/apps/cory/docs.json +++ b/apps/cory/docs.json @@ -1 +1 @@ -{"type":"tildefriends-app","files":{"app.js":"&WEvJYebSMi5d2eXgUwJJmvR/Q4slFg3zHYB8Q2mXJII=.sha256","index.md":"&Pi0NTJn9/w76yIUKqRRuSvUPSpqkxdYynmjeOBbF3K8=.sha256","todo.md":"&d8Kq8yuOn8SL3tJVy9BiDXHAe/jverpBj5AMLWLtmFM=.sha256","structure.md":"&T+CBfT9XP6ooKFvD1ZCI9hsutqsNIamfBxtAho0HtlU=.sha256","guide.md":"&SgnGL0+rjetY2o9A2+lVRbNvHIkqKwMnZr9gXWneIlc=.sha256","ssb.md":"&ouqT3XzTGfBNpOP/uEdOw7K1F9BeLZgQCx24XTvhyXU=.sha256"}} \ No newline at end of file +{"type":"tildefriends-app","files":{"app.js":"&WEvJYebSMi5d2eXgUwJJmvR/Q4slFg3zHYB8Q2mXJII=.sha256","index.md":"&79+ntX4sRvg+MboV5nMFz01BSicxsWIQRx719VHS8uk=.sha256","todo.md":"&vLL7JVe1FcqOcYmd22KMkIw3T2IrEbxyonMw5rdICjA=.sha256","structure.md":"&jph8x/fMXKOd4I0ZiUVb0ZLTfPQ7gBWoxJPrvtX6vtw=.sha256","guide.md":"&SgnGL0+rjetY2o9A2+lVRbNvHIkqKwMnZr9gXWneIlc=.sha256","ssb.md":"&JH1JfoTaCcUifCpnAwhImKBACI0PHoLhoOw1WAnWpLw=.sha256","vision.md":"&v2wu2MGlhNvaALQQ9rGna7ZeEQWSghFgQcDfD5xEyE0=.sha256"}} \ No newline at end of file diff --git a/apps/cory/docs/index.md b/apps/cory/docs/index.md index 703c6aeb..ab9514d1 100644 --- a/apps/cory/docs/index.md +++ b/apps/cory/docs/index.md @@ -2,9 +2,10 @@ Tilde Friends is a participating member of a greater social network, [Secure Scuttlebutt](https://scuttlebutt.nz/), -augmenting it with a way to safely and securely write, share, -and run code. +adding a way to safely and securely write, share, +and run code in the form of server-side web applications. +- [Tilde Friends Vision](#vision) - [Secure Scuttlebutt from Scratch](#ssb) - [Structure](#structure) - [Guide](#guide) diff --git a/apps/cory/docs/ssb.md b/apps/cory/docs/ssb.md index a6371f3f..512c3b5c 100644 --- a/apps/cory/docs/ssb.md +++ b/apps/cory/docs/ssb.md @@ -16,6 +16,8 @@ IPv4 addresses. So be prepared to accept variations. +There also an undocumented "new" style of discovery message. + ## Secret Handshake, Box Stream, and RPC Protocol Now that two clients are aware of eachother, they need to complete a secret handshake. The [programming guide](https://ssbc.github.io/scuttlebutt-protocol-guide/#handshake) @@ -26,12 +28,14 @@ The box stream and RPC protocol can both be implemented from the without surprises. ## Synchronizing Data -So now you're discovering other clients on the local network, connecting, performing -a secret handshake, and making remote procedure calls over box streams. The next step -is to start synchronizing feeds over the network. The goal, after all, is to author -messages in your local append-only log and have them show up in distant clients, or -vice versa. + +... `ebt.replicate` or `createHistoryStream` ... + +## Rooms + +TODO ## References * [https://ssbc.github.io/scuttlebutt-protocol-guide/](https://ssbc.github.io/scuttlebutt-protocol-guide/) -* [https://dev.planetary.social/](https://dev.planetary.social/) \ No newline at end of file +* [https://dev.planetary.social/](https://dev.planetary.social/) +* [https://dev.scuttlebutt.nz/#/golang/?id=muxrpc-endpoints](https://dev.scuttlebutt.nz/#/golang/?id=muxrpc-endpoints) \ No newline at end of file diff --git a/apps/cory/docs/structure.md b/apps/cory/docs/structure.md index 7a680960..4e321e5a 100644 --- a/apps/cory/docs/structure.md +++ b/apps/cory/docs/structure.md @@ -21,7 +21,7 @@ In combines the following key components: are mediated through the core process. When run with no arguments, it starts a web server on -[http://localhost:12345/](http://localhost:12345/) and an SSB server. +[http://localhost:12345/](http://localhost:12345/) and an SSB node. ## Web Interface The Tilde Friends web server provides access to Tilde Friends applications, diff --git a/apps/cory/docs/todo.md b/apps/cory/docs/todo.md index 01ccf551..14a35c35 100644 --- a/apps/cory/docs/todo.md +++ b/apps/cory/docs/todo.md @@ -5,8 +5,6 @@ - Sync status (problem feeds, messages/seconds stats, ...) - app: wiki - app: public blog -- app: build archive -- app: todo - Content-Disposition: download - remove SSB credentials - export SSB credentials @@ -22,7 +20,6 @@ - fix weird HTTP warnings - ssb from child process? - channels -- image downsample - placeholder/missing images - no denial of service - package standalone executable @@ -30,12 +27,16 @@ - editor without app iframe - sequence_before_author -> flags - linkify ssb: links +- perfect rooms support ## MVP2 - connections 2.0 - make a better connections API ## Maybe Done +- image downsample +- app: todo +- app: build archive - update README - administrators config - apps name characters diff --git a/apps/cory/docs/vision.md b/apps/cory/docs/vision.md new file mode 100644 index 00000000..da6dfc3d --- /dev/null +++ b/apps/cory/docs/vision.md @@ -0,0 +1,62 @@ +# Tilde Friends Vision +[Back to index](#index) + +Tilde Friends is a tool for making and sharing. + +It is both a peer-to-peer social network client, participating in Secure +Scuttlebutt, and an environment for creating and running web applications. + +## Why + +This is a thing that I wanted to exist and wanted to work on. No other reason. +There is not a business model. I believe it is interesting and unique. + +## Goals +1. Make it **easy and fun** to run all sorts of web applications. + +2. Provide **security** that is easy to understand and protects your data. + +3. Make **creating and sharing** web applications accessible to anyone with a + browser. + +## Ways to Use Tilde Friends +1. **Social Network User**: This is a social network first. You are just here, + because your friends are. Or you like how we limit your message length or + short videos or whatever the trend is. If you are ambitious, you click links + and see interactive experiences (apps) that you wouldn't see elsewhere. + +2. **Web Visitor**: You get links from a friend to meeting invites, polls, games, + lists, wiki pages, ..., and you interact with them as though they were + cloud-hosted by a megacorporation. They just work, and you don't think twice. + +3. **Group leader**: You host or use a small public instance, installing apps for + a group of friends to use as web visitors. + +4. **Developer**: You like to write code and make or improve apps for fun or to + solve problems. When you encounter a Tilde Friends app on a strange server, + you know you can trivially modify it or download it to your own instance. + +## Future Goals / Endgame +1. Mobile apps. This can run on your old phone. Maybe you won't be hosting + the web interface publicly, but you can sync, install and edit apps, and + otherwise get the full experience from a tiny touch screen. + +2. The universal application runtime. The web browser is the universal + platform, but even for the simplest application that you might want to host + for your friends, cloud hosting, containers, and complicated dependencies might + all enter the mix. Tilde Friends, though it is yet another thing to host, + includes everything you need out of the box to run a vast variety of interesting + apps. + + Tilde Friends will be built out, gradually providing safe access to host + resources and client resources the same way web browsers extended access to + resources like GPU, persistent storage, cameras, ... over the years. + + Not much effort has been put forward yet to having a robust, long-lasting API, + but since the client side longevity is already handled by web browsers, it + seems possible that the server-side API can be managed in a similar way. + +3. An awesome development environment. Right now it runs JavaScript from the + first embeddable text editor I could poorly configure enough to edit code, + but it could incorporate a debugger, source control integration a la ssb-git, + merge tools, and transpiling from all sorts of different languages. \ No newline at end of file diff --git a/apps/cory/ssb.json b/apps/cory/ssb.json index 9afe136f..0b61129e 100644 --- a/apps/cory/ssb.json +++ b/apps/cory/ssb.json @@ -1 +1 @@ -{"type":"tildefriends-app","files":{"app.js":"&gxOJaVf/HdjVJVC9NvZ9n3/825OD1xMMHdF/dFQwe24=.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":"&y+Q47tdm60Od1UzuRu7OOLwineyQCL1LIb3KP5IwHTY=.sha256","emojis.json":"&h3P4pez+AI4aYdsN0dJ3pbUEFR0276t9AM20caj/W/s=.sha256","emojis.js":"&pqYLDE/13PyEt2ceeFqvnwZ8NqWfPfpDBt4vP8SeHbs=.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":"&Ftt5RnkrhndV2lwC7XXUZX8JiUODqPjqEVgSTJQD6JU=.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":"&gxOJaVf/HdjVJVC9NvZ9n3/825OD1xMMHdF/dFQwe24=.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":"&iIQ8FAqBiaOfjLvXwL8X1ewkhBqiZNo2jwnlSzui+bY=.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":"&Ftt5RnkrhndV2lwC7XXUZX8JiUODqPjqEVgSTJQD6JU=.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 diff --git a/apps/cory/ssb/emojis.js b/apps/cory/ssb/emojis.js index 7b61f7ea..7881a3e6 100644 --- a/apps/cory/ssb/emojis.js +++ b/apps/cory/ssb/emojis.js @@ -24,20 +24,41 @@ export function picker(callback, anchor) { div.style.border = '1px solid #000'; div.style.display = 'block'; div.style.position = 'absolute'; + div.style.minWidth = '16em'; + div.style.width = '16em'; div.style.maxWidth = '16em'; div.style.maxHeight = '16em'; div.style.overflow = 'scroll'; div.style.fontWeight = 'bold'; + div.style.fontSize = 'xx-large'; let input = document.createElement('input'); input.type = 'text'; + input.style.display = 'block'; + input.style.boxSizing = 'border-box'; + input.style.width = '100%'; + input.style.margin = '0'; + input.style.position = 'relative'; div.appendChild(input); let list = document.createElement('div'); div.appendChild(list); + + function cleanup() { + div.parentElement.removeChild(div); + window.removeEventListener('keydown', key_down); + } + + function key_down(event) { + if (event.key == 'Escape') { + cleanup(); + } + } + function refresh() { while (list.firstChild) { list.removeChild(list.firstChild); } let search = input.value; + let any_at_all = false; Object.entries(json).forEach(function(row) { let header = document.createElement('div'); header.appendChild(document.createTextNode(row[0])); @@ -51,28 +72,25 @@ export function picker(callback, anchor) { } let emoji = document.createElement('span'); const k_size = '1.25em'; - emoji.style.width = k_size; - emoji.style.maxWidth = k_size; - emoji.style.minWidth = k_size; - emoji.style.height = k_size; - emoji.style.maxHeight = k_size; - emoji.style.minHeight = k_size; emoji.style.display = 'inline-block'; emoji.style.overflow = 'hidden'; emoji.style.cursor = 'pointer'; emoji.onclick = function() { callback(entry); - div.parentElement.removeChild(div); } emoji.title = entry.name; emoji.appendChild(document.createTextNode(entry.emoji)); list.appendChild(emoji); any = true; + any_at_all = true; } if (!any) { list.removeChild(header); } }); + if (!any_at_all) { + list.appendChild(document.createTextNode('No matches found.')); + } } refresh(); input.oninput = refresh; @@ -81,5 +99,7 @@ export function picker(callback, anchor) { div.style.top = '50%'; div.style.left = '50%'; div.style.transform = 'translate(-50%, -50%)'; + input.focus(); + window.addEventListener('keydown', key_down); }); } \ No newline at end of file diff --git a/apps/cory/ssb/tf-compose.js b/apps/cory/ssb/tf-compose.js index 357578e8..ed3bfd8d 100644 --- a/apps/cory/ssb/tf-compose.js +++ b/apps/cory/ssb/tf-compose.js @@ -61,7 +61,7 @@ class TfComposeElement extends LitElement { preview.innerHTML = tfutils.markdown(text); } - convert_to_webp(buffer, type) { + convert_to_format(buffer, type, mime_type) { return new Promise(function(resolve, reject) { let img = new Image(); img.onload = function() { @@ -73,7 +73,7 @@ class TfComposeElement extends LitElement { canvas.height = img.height * scale; let context = canvas.getContext('2d'); context.drawImage(img, 0, 0, canvas.width, canvas.height); - let data_url = canvas.toDataURL('image/webp'); + let data_url = canvas.toDataURL(mime_type); let result = atob(data_url.split(',')[1]).split('').map(x => x.charCodeAt(0)); resolve(result); } @@ -92,8 +92,18 @@ class TfComposeElement extends LitElement { let buffer = await file.arrayBuffer(); let type = file.type; if (type.startsWith('image/')) { - buffer = await self.convert_to_webp(buffer, file.type); - type = 'image/webp'; + let best_buffer; + let best_type; + for (let format of ['image/png', 'image/jpeg']) { + let test_buffer = await self.convert_to_format(buffer, file.type, format); + console.log(format, test_buffer.length); + if (!best_buffer || test_buffer.length < best_buffer.length) { + best_buffer = test_buffer; + best_type = format; + } + } + buffer = best_buffer; + type = best_type; } else { buffer = Array.from(new Uint8Array(buffer)); }