Merge branch 'master' into add-profile-image-upload

This commit is contained in:
Cinnamon 2020-03-11 17:20:47 -07:00 committed by GitHub
commit dba544c9b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 592 additions and 225 deletions

View File

@ -3,6 +3,7 @@
"language": "en",
"words": [
"AGPL",
"EACCESS",
"Argyris",
"Hintjens",
"Kata",

View File

@ -1,3 +1,5 @@
**What's the problem you want solved?**
## What's the problem you want solved?
**Is there a solution you'd like to recommend?**
## Is there a solution you'd like to recommend?
## What version or commit of Oasis are you using?

View File

@ -1,3 +1,3 @@
**What's the problem you solved?**
## What's the problem you solved?
**What solution are you recommending?**
## What solution are you recommending?

100
README.md
View File

@ -6,87 +6,69 @@ you follow friends and discover new ones on [Secure Scuttlebutt (SSB)][ssb].
**🦀 Powered by SSB.**
You're the center of your own distributed network. Online or offline, SSB works
anywhere that you are. Follow the people you want to see and never worry about
spam again. Migrate your data to another SSB app any time you want.
spam again. Switch to any SSB app you want at any time.
**🌐 Bring your own browser.**
Use your favorite web browser to read and write messages to the people you care
about. Oasis runs over HTTP, so you don't need to worry about adding another
Electron app to your computer.
about. Oasis runs a small HTTP server on your own computer, so you don't need
to worry about adding another Electron app to your computer.
**🏰 Just HTML and CSS.**
No browser JavaScript! Oasis has strict security rules that prevent any
JavaScript from running in your browser, which helps us make Oasis accessible
and easy to improve.
## Example
After installing, launch Oasis from the command line by running:
```sh
oasis
```
It will then pop open a browser window for you.
![Screenshot of Oasis](./docs/screenshot.png)
## Usage
Start Oasis from a command-line interface with the `oasis` command.
```console
$ oasis --help
Usage: oasis [options]
Options:
--version Show version number [boolean]
-h, --help Show help [boolean]
--open Automatically open app in web browser. Use --no-open to disable.
[boolean] [default: true]
--offline Don't try to connect to scuttlebutt peers or pubs. This can be
changed on the 'settings' page while Oasis is running.
[boolean] [default: false]
--host Hostname for web app to listen on [string] [default: "localhost"]
--port Port for web app to listen on [number] [default: 3000]
--debug Use verbose output for debugging [boolean] [default: false]
-c --config Show current default configuration [boolean] [default: false]
```
## Configuration
The above options can be permanently set with a configuration file found in a
standard folder for configuration, depending on your operating system:
- Linux: `$XDG_CONFIG_HOME/oasis/default.json`.
Usually this is `/home/<your username>/.config/oasis/default.json`
<!-- cspell:disable-next-line -->
- Windows `%APPDATA%\oasis\default.json`.
- Mac OS, `/Users/<your username>/Library/Preferences/oasis/default.json`
The configuration file can override any or all of the command-line _defaults_.
Here is an example customizing the port number and the "open" settings:
```json
{
"open": false,
"port": 19192
}
```
### Configuration Semantics
Which value is given is decided like this:
1. If an argument is given on the command-line, use that value.
2. Otherwise, use the value from the configuration file if present.
3. If neither command-line nor configuration file are given, use the built-in default value.
Use `oasis --help` to get configuration options. You can change the default
values with a custom [configuration](./docs/configuring.md).
## Installation
Most people should install stable releases with [npm](https://npmjs.org/) and
Node.js [**current** or **active LTS** release](https://nodejs.org/en/about/releases/).
First, you'll need Node.js and npm on your computer. Run `node --version` to see if you have it. If not, or if it's older than the [**current** or **active LTS** version](https://nodejs.org/en/about/releases/), you should [download Node.js](https://nodejs.org/en/about/releases/) first.
Then you can install the stable version of Oasis:
```shell
npm --global install 'fraction/oasis#semver:*'
npm -g install fraction/oasis#semver:
```
For faster updates and less stability, install from GitHub and upgrade often.
Or, for faster updates and less stability, install Oasis from GitHub and upgrade often.
```shell
npm --global install fraction/oasis
npm -g install fraction/oasis
```
Want more? Check out [`install.md`](https://github.com/fraction/oasis/blob/master/docs/install.md).
Check out [`install.md`](https://github.com/fraction/oasis/blob/master/docs/install.md)
for more information.
## FAQ
### Can I use the same profile from multiple computers?
No, this is a limitation of SSB. You'll need to make a separate profile on each device. There is a workaround [we'd like to implement](https://github.com/fraction/oasis/issues/267) which ties your multiple profiles together.
### Can I run this at the same time as Patchwork and other SSB apps?
Yes! They will both use the same data and profile. You can either run them one at a time or simultaneously. If you run them at the same time, start Patchwork first, then Oasis.
Details: SSB apps have two parts: a "server" that manages the database (on your own computer), and a user interface that gets things from the server to display. Only one server can run at a time, but multiple apps can use it.
| App | Runs its own SSB server | Can use SSB server of another app |
| --------- | ---------------------------------- | ---------------------------------------------- |
| Oasis | Yes, unless one is already running | Yes |
| Patchwork | Yes | No, only uses its own server |
| Patchfox | No | Yes, depends on other apps to provide a server |
## Resources

View File

@ -1 +1,2 @@
Christian Bundy <christianbundy@fraction.io>
Cinnamon <cinnamon_oasis@fastmail.com>

28
docs/configuring.md Normal file
View File

@ -0,0 +1,28 @@
# Configuring
The default options can be permanently set with a configuration file found in a
standard folder for configuration, depending on your operating system:
- Linux: `$XDG_CONFIG_HOME/oasis/default.json`.
Usually this is `/home/<your username>/.config/oasis/default.json`
<!-- cspell:disable-next-line -->
- Windows `%APPDATA%\oasis\default.json`.
- Mac OS, `/Users/<your username>/Library/Preferences/oasis/default.json`
The configuration file can override any or all of the command-line _defaults_.
Here is an example customizing the port number and the "open" settings:
```json
{
"open": false,
"port": 19192
}
```
## Semantics
Which value is given is decided like this:
1. If an argument is given on the command-line, use that value.
2. Otherwise, use the value from the configuration file if present.
3. If neither command-line nor configuration file are given, use the built-in default value.

View File

@ -12,40 +12,35 @@ If you want to run Oasis on Android via Termux, see [`with-termux.md`](./with-te
## Download
### HTTPS
Most people should download Oasis over HTTPS.
Download Oasis from GitHub over HTTPS.
```shell
git clone https://github.com/fraction/oasis.git
```
### SSH
If you already have SSH, you may prefer to download over SSH instead.
```shell
git clone git@github.com:fraction/oasis.git
```
## Install
## Install dependencies
Most people should build and install Oasis with npm.
```shell
cd oasis
npm install
npm --global install .
npm install --only=prod
```
## Start
You did it! Oasis should now be installed.
You can try Oasis without installing with:
```shell
oasis --help
node .
```
If you have problems, read the documentation on [downloading and installing
packages globally](https://docs.npmjs.com/downloading-and-installing-packages-globally)
or [get some help](https://github.com/fraction/oasis/issues/new/choose).
## Install globally
If you want to install to make `oasis` available globally:
```shell
npm -g install .
```
If you see a permission error, see [resolving EACCESS permission errors](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally). If you any other problems, please [reach out for help](https://github.com/fraction/oasis/issues/new).

149
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "@fraction/oasis",
"version": "2.13.1",
"version": "2.14.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -183,17 +183,17 @@
"integrity": "sha512-Lnle0J8t+Z+jFg78GFFnGo+Fphxaco9K9SppeBDsI27QBRBumxeGAMeOg5wt6XbAuj5pQWmAEWWEwPz4PYGMHw=="
},
"@fraction/flotilla": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@fraction/flotilla/-/flotilla-4.0.0.tgz",
"integrity": "sha512-n1CmZff4MfXexv6eX8HLojLBrVZa3zpkEndwtRYpjJMZIZPmX9belPFCeutzMupEY7D/0we2gsJ6C030h63zYA==",
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@fraction/flotilla/-/flotilla-4.0.1.tgz",
"integrity": "sha512-ZSRHLVT79Z1OrGLvMm4LyDVw7x0puIS1s8VxExmeHZUVjlwZUwWgzeLZs3x82XQn7xtUIkU+aIrNs5gAHyLM5Q==",
"requires": {
"lodash.shuffle": "^4.2.0",
"secret-stack": "^6.3.0",
"ssb-about": "^2.0.1",
"ssb-backlinks": "^0.7.3",
"ssb-backlinks": "^1.0.0",
"ssb-blobs": "^1.2.2",
"ssb-conn": "^0.15.2",
"ssb-db": "^19.3.0",
"ssb-conn": "^0.16.0",
"ssb-db": "^19.4.0",
"ssb-ebt": "^5.6.7",
"ssb-friends": "^4.1.4",
"ssb-invite": "^2.1.3",
@ -206,7 +206,7 @@
"ssb-plugins": "^1.0.2",
"ssb-query": "^2.4.3",
"ssb-replicate": "^1.3.0",
"ssb-room": "^1.1.1",
"ssb-room": "^1.2.2",
"ssb-search": "^1.2.1",
"ssb-tangle": "^1.0.1",
"ssb-unix-socket": "^1.0.0",
@ -355,9 +355,9 @@
}
},
"acorn": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
"integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ=="
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
"integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg=="
},
"acorn-jsx": {
"version": "5.1.0",
@ -3467,9 +3467,9 @@
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
},
"ipaddr.js": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
"integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
},
"is-alphabetical": {
"version": "1.0.4",
@ -4129,9 +4129,9 @@
},
"dependencies": {
"readable-stream": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.5.0.tgz",
"integrity": "sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==",
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@ -4283,9 +4283,9 @@
}
},
"leveldown": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.4.1.tgz",
"integrity": "sha512-3lMPc7eU3yj5g+qF1qlALInzIYnkySIosR1AsUKFjL9D8fYbTLuENBAeDRZXIG4qeWOAyqRItOoLu2v2avWiMA==",
"version": "5.5.1",
"resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.5.1.tgz",
"integrity": "sha512-GoC455/ncfg4yLLItr192HuXpA+CcQ2q9GncXJhewvvlpsBBEegChn5tMPP+kGvJt7u2LuXAd8fY2moQxFD+sQ==",
"requires": {
"abstract-leveldown": "~6.2.1",
"napi-macros": "~2.0.0",
@ -4852,9 +4852,9 @@
"dev": true
},
"muxrpc": {
"version": "6.4.8",
"resolved": "https://registry.npmjs.org/muxrpc/-/muxrpc-6.4.8.tgz",
"integrity": "sha512-9oLoLbiAWZAhgxQzquApj0eSfiTYPWLq4AV5mvCBjsicJKWOJlxAAxypHdlnmHeUbOxrPRweneHI7l+nzY/+aQ==",
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/muxrpc/-/muxrpc-6.5.0.tgz",
"integrity": "sha512-8kCo33LTYPYWAJGi2Ag2ukcluoNqJIe6Ay9QtGf7EXAUlTuMSA0HqR7jCbXt7DQPR4Alu/T3/mOguuERpDMGcw==",
"requires": {
"explain-error": "^1.0.1",
"packet-stream": "~2.0.0",
@ -5724,12 +5724,12 @@
"integrity": "sha1-m0fiyyrkl+seutwsQZHWTRXJSdE="
},
"proxy-addr": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
"integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
"requires": {
"forwarded": "~0.1.2",
"ipaddr.js": "1.9.0"
"ipaddr.js": "1.9.1"
}
},
"prr": {
@ -6994,17 +6994,15 @@
}
},
"ssb-backlinks": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/ssb-backlinks/-/ssb-backlinks-0.7.3.tgz",
"integrity": "sha512-84s5phSVyZsYV0FTmBJvICPgOMuu8ouzukG8Gz2XtuOui95GBP/G7UIBURgYVS82XA6g9xPA/jf38fsMxid38Q==",
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/ssb-backlinks/-/ssb-backlinks-1.0.0.tgz",
"integrity": "sha512-cgBfw+5oQMmFWX5czTHonZboZC9rRgZZlC2TwkSZvOZMWNxZKr98zvb56lRFiO4Et6DcEh3hXsyZyMyo6jN0WA==",
"requires": {
"base64-url": "^2.2.0",
"deep-equal": "^1.0.1",
"flumeview-query": "^6.2.0",
"pull-stream": "^3.6.7",
"ssb-keys": "^7.0.14",
"ssb-ref": "^2.9.0",
"xtend": "^4.0.1"
"ssb-ref": "^2.9.0"
}
},
"ssb-blobs": {
@ -7042,18 +7040,6 @@
"ssb-keys": "^7.2.1"
},
"dependencies": {
"muxrpc": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/muxrpc/-/muxrpc-6.5.0.tgz",
"integrity": "sha512-8kCo33LTYPYWAJGi2Ag2ukcluoNqJIe6Ay9QtGf7EXAUlTuMSA0HqR7jCbXt7DQPR4Alu/T3/mOguuERpDMGcw==",
"requires": {
"explain-error": "^1.0.1",
"packet-stream": "~2.0.0",
"packet-stream-codec": "^1.1.1",
"pull-goodbye": "0.0.2",
"pull-stream": "^3.6.10"
}
},
"ssb-keys": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/ssb-keys/-/ssb-keys-7.2.2.tgz",
@ -7081,9 +7067,9 @@
}
},
"ssb-conn": {
"version": "0.15.2",
"resolved": "https://registry.npmjs.org/ssb-conn/-/ssb-conn-0.15.2.tgz",
"integrity": "sha512-QTdyOobC1ybnz0DHG1U0IrypRI9skd47HKXT6spQ2dnF8S4UQr29YOBWt4dWXfgnBP5a7WHMg07MY90XszwbGg==",
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/ssb-conn/-/ssb-conn-0.16.2.tgz",
"integrity": "sha512-KinjdF3tOMmlcjKK4bnTso0x6GYfL+9tE2gSacRDldaLui73nDLxSwjnSoE188wDXUEumJU0LvOff4AHm2XyLQ==",
"requires": {
"debug": "~4.1.1",
"has-network2": "0.0.1",
@ -7163,13 +7149,11 @@
}
},
"ssb-db": {
"version": "19.3.2",
"resolved": "https://registry.npmjs.org/ssb-db/-/ssb-db-19.3.2.tgz",
"integrity": "sha512-abbJ5Z9nMP6dHk0cLrTlDqsjJwVX3oiE+UaM0B5NYDIZtBUPM9M7cHt6kjI1COLHJA3+Pm7zDGeLax9okcADbw==",
"version": "19.4.0",
"resolved": "https://registry.npmjs.org/ssb-db/-/ssb-db-19.4.0.tgz",
"integrity": "sha512-b6Q/UuGqxeyPAMJc2a/Q4clCR7UxTVIkrRw/6FEypn4p0LgWIOaqMdhyuJugzMb1k8dIEdlMdfEPq/FrTeLXkg==",
"requires": {
"async-write": "^2.1.0",
"cont": "~1.0.0",
"explain-error": "~1.0.1",
"flumedb": "^1.1.0",
"flumelog-offset": "^3.4.2",
"flumeview-level": "^3.0.13",
@ -7187,7 +7171,6 @@
"ssb-msgs": "^5.0.0",
"ssb-ref": "^2.12.0",
"ssb-validate": "^4.0.0",
"typewiselite": "^1.0.0",
"zerr": "^1.0.0"
}
},
@ -7272,9 +7255,9 @@
}
},
"ssb-markdown": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/ssb-markdown/-/ssb-markdown-6.0.3.tgz",
"integrity": "sha512-pVOStAcoBzQ/KvV1OyE7yREuhi/qUd10gLbKcnldELBwniSovuia867s2F67dPfRr3ASLXjfm+Zz5dnPXE/jVw==",
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/ssb-markdown/-/ssb-markdown-6.0.4.tgz",
"integrity": "sha512-MdmHnev7259wzGcCSBo6A93kR/3iIx5sWrrzFTuyDmAAgHLycvotS6tbcge15AlPZDNRmo2N3MyHKTYb+SYbUA==",
"requires": {
"emoji-regex": "^8.0.0",
"hashtag-regex": "^2.1.0",
@ -7433,9 +7416,9 @@
}
},
"ssb-room": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/ssb-room/-/ssb-room-1.2.0.tgz",
"integrity": "sha512-WuBwYr5szFP9c7M1wk6WW/J+ByHB9MIpus4qVSFEes9NCmwStnLRJGeQZf6DnJe0M4rwddrwb6UUh4M/bApNNQ==",
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/ssb-room/-/ssb-room-1.2.2.tgz",
"integrity": "sha512-oPduyTzzGOeCs+wE77XjQfqNhNC3mOV98MS61cRRkXH2hGd6s+UM0KItQ0o10fcHZ4+32IeTDy7C66s2Dfyb3Q==",
"requires": {
"body-parser": "^1.16.0",
"debug": "~4.1.1",
@ -7566,9 +7549,9 @@
}
},
"ssb-typescript": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/ssb-typescript/-/ssb-typescript-1.5.0.tgz",
"integrity": "sha512-I4oe7BDYmk3kopVZC4BrXuKfugpJphLcZTmheofW2Dwanm6VutLfzLgz6juqt7aYKeIH5Ps3sJvZWQLw3MvUMQ=="
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/ssb-typescript/-/ssb-typescript-1.7.0.tgz",
"integrity": "sha512-BuU8Buzm/TCA8WEUEX4mOO6AkgCPnrtoJQE7K4JY9eOvShEtA6qjvzKuNG4ZwivIwfGy+eF9fl5WFkaihqnj4A=="
},
"ssb-unix-socket": {
"version": "1.0.0",
@ -8060,9 +8043,9 @@
}
},
"tape": {
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/tape/-/tape-4.13.0.tgz",
"integrity": "sha512-J/hvA+GJnuWJ0Sj8Z0dmu3JgMNU+MmusvkCT7+SN4/2TklW18FNCp/UuHIEhPZwHfy4sXfKYgC7kypKg4umbOw==",
"version": "4.13.2",
"resolved": "https://registry.npmjs.org/tape/-/tape-4.13.2.tgz",
"integrity": "sha512-waWwC/OqYVE9TS6r1IynlP2sEdk4Lfo6jazlgkuNkPTHIbuG2BTABIaKdlQWwPeB6Oo4ksZ1j33Yt0NTOAlYMQ==",
"requires": {
"deep-equal": "~1.1.1",
"defined": "~1.0.0",
@ -8075,16 +8058,16 @@
"is-regex": "~1.0.5",
"minimist": "~1.2.0",
"object-inspect": "~1.7.0",
"resolve": "~1.14.2",
"resolve": "~1.15.1",
"resumer": "~0.0.0",
"string.prototype.trim": "~1.2.1",
"through": "~2.3.8"
},
"dependencies": {
"resolve": {
"version": "1.14.2",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.2.tgz",
"integrity": "sha512-EjlOBLBO1kxsUxsKjLt7TAECyKW6fOh1VRkykQkKGzcBbjjPIxBqGh0jf7GJ3k/f5mxMqW3htMD3WdTUVtW8HQ==",
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
"integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
"requires": {
"path-parse": "^1.0.6"
}
@ -8924,9 +8907,9 @@
}
},
"yargs": {
"version": "15.1.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz",
"integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==",
"version": "15.3.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.0.tgz",
"integrity": "sha512-g/QCnmjgOl1YJjGsnUg2SatC7NUYEiLXJqxNOQU9qSpjzGtGXda9b+OKccr1kLTy8BN9yqEyqfq5lxlwdc13TA==",
"requires": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
@ -8938,9 +8921,14 @@
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^16.1.0"
"yargs-parser": "^18.1.0"
},
"dependencies": {
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
},
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
@ -8985,6 +8973,15 @@
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.0"
}
},
"yargs-parser": {
"version": "18.1.0",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.0.tgz",
"integrity": "sha512-o/Jr6JBOv6Yx3pL+5naWSoIA2jJ+ZkMYQG/ie9qFbukBe4uzmBatlXFOiu/tNKRWEtyf+n5w7jc/O16ufqOTdQ==",
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
}
}
},
@ -8992,6 +8989,7 @@
"version": "16.1.0",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz",
"integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
@ -9000,7 +8998,8 @@
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
}
}
},

View File

@ -1,6 +1,6 @@
{
"name": "@fraction/oasis",
"version": "2.13.1",
"version": "2.14.0",
"description": "friendly neighborhood scuttlebutt interface",
"repository": {
"type": "git",
@ -22,7 +22,7 @@
},
"dependencies": {
"@fraction/base16-css": "^1.1.0",
"@fraction/flotilla": "^4.0.0",
"@fraction/flotilla": "^4.0.1",
"debug": "^4.1.1",
"env-paths": "^2.2.0",
"highlight.js": "^9.18.1",
@ -34,6 +34,7 @@
"koa-router": "^7.4.0",
"koa-static": "^5.0.0",
"lodash": "^4.17.11",
"markdown-it": "^8.4.2",
"open": "7.0.0",
"pretty-ms": "^5.0.0",
"pull-paramap": "^1.2.2",
@ -43,13 +44,13 @@
"sharp": "^0.23.0",
"ssb-client": "^4.9.0",
"ssb-config": "^3.4.4",
"ssb-markdown": "^6.0.3",
"ssb-markdown": "^6.0.4",
"ssb-mentions": "^0.5.2",
"ssb-msgs": "^5.2.0",
"ssb-ref": "^2.13.9",
"ssb-tangle": "^1.0.1",
"ssb-thread-schema": "^1.1.1",
"yargs": "^15.0.0"
"yargs": "^15.3.0"
},
"devDependencies": {
"changelog-version": "^1.0.1",

View File

@ -16,8 +16,8 @@ module.exports = ({ host, port, middleware }) => {
app.on("error", err => {
// Output full error objects
err.message = err.stack;
err.expose = true;
console.error(err);
err.expose = true;
return null;
});

View File

@ -2,28 +2,18 @@
"use strict";
// Koa application to provide HTTP interface.
const fs = require("fs");
const envPaths = require("env-paths");
// Minimum required to get config
const path = require("path");
const nodeHttp = require("http");
const debug = require("debug")("oasis");
const envPaths = require("env-paths");
const cli = require("./cli");
const fs = require("fs");
const defaultConfig = {};
const defaultConfigFile = path.join(
envPaths("oasis", { suffix: "" }).config,
"/default.json"
);
const log = (...args) => {
const isDebugEnabled = debug.enabled;
debug.enabled = true;
debug(...args);
debug.enabled = isDebugEnabled;
};
const defaultConfig = {};
var haveConfig;
let haveConfig;
try {
const defaultConfigOverride = fs.readFileSync(defaultConfigFile, "utf8");
@ -40,8 +30,21 @@ try {
}
}
const cli = require("./cli");
const config = cli(defaultConfig, defaultConfigFile);
if (config.debug) {
process.env.DEBUG = "oasis,oasis:*";
}
const nodeHttp = require("http");
const debug = require("debug")("oasis");
const log = (...args) => {
const isDebugEnabled = debug.enabled;
debug.enabled = true;
debug(...args);
debug.enabled = isDebugEnabled;
};
delete config._;
delete config.$0;
@ -49,26 +52,17 @@ const { host } = config;
const { port } = config;
const url = `http://${host}:${port}`;
console.log();
if (haveConfig) {
console.log(`Configuration read defaults from ${defaultConfigFile}`);
log(`Configuration read defaults from ${defaultConfigFile}`);
} else {
console.log(
`No configuration file found at ${defaultConfigFile}. ` +
"Using built-in default values."
log(
`No configuration file found at ${defaultConfigFile}, using built-in default values.`
);
}
console.log("Current configuration:");
console.log();
console.log(JSON.stringify(config, null, 2));
console.log();
console.log(`Note: You can save the above to ${defaultConfigFile} to make \
these settings the default. See the readme for details.`);
console.log();
if (config.debug) {
process.env.DEBUG = "oasis,oasis:*";
}
debug("Current configuration: %O", config);
debug(`You can save the above to ${defaultConfigFile} to make \
these settings the default. See the readme for details.`);
const oasisCheckPath = "/.well-known/oasis";
@ -213,7 +207,7 @@ router
return next();
})
.get("/", async ctx => {
ctx.redirect("/public/popular/day");
ctx.redirect("/mentions");
})
.get("/robots.txt", ctx => {
ctx.body = "User-agent: *\nDisallow: /";
@ -763,6 +757,30 @@ const middleware = [
setLanguage(selectedLanguage);
await next();
},
async (ctx, next) => {
const ssb = await cooler.open();
const status = await ssb.status();
const values = Object.values(status.sync.plugins);
const totalCurrent = Object.values(status.sync.plugins).reduce(
(acc, cur) => acc + cur,
0
);
const totalTarget = status.sync.since * values.length;
const left = totalTarget - totalCurrent;
// Weird trick to get percentage with 1 decimal place (e.g. 78.9)
const percent = Math.floor((totalCurrent / totalTarget) * 1000) / 10;
const mebibyte = 1024 * 1024;
if (left > mebibyte) {
throw new Error(`Sorry, Oasis has only processed ${percent}% of the messages and needs to catch up.
Thanks for your patience, please wait for a moment and refresh this page to try again.`);
} else {
await next();
}
},
routes
];

View File

@ -64,16 +64,19 @@ module.exports = {
likedBy: "'s likes",
// composer
publish: "Publish",
contentWarningPlaceholder: "Optional content warning for this post",
publishCustomDescription: [
"Publish a custom message by entering ",
a({ href: "https://en.wikipedia.org/wiki/JSON" }, "JSON"),
" below. This may be useful for prototyping or publishing messages that Oasis doesn't support. This message cannot be edited or deleted."
],
commentWarning: [
" Messages cannot be edited or deleted. To respond to an individual message, select ",
" Comments cannot be edited or deleted. To respond to an individual message, select ",
strong("reply"),
" instead."
],
commentPublic: "public",
commentPrivate: "private",
commentLabel: ({ publicOrPrivate, markdownUrl }) => [
"Write a ",
strong(`${publicOrPrivate} comment`),
@ -82,7 +85,7 @@ module.exports = {
"."
],
publishLabel: ({ markdownUrl, linkTarget }) => [
"Write a new message in ",
"Write a new public post in ",
a(
{
href: markdownUrl,
@ -90,7 +93,7 @@ module.exports = {
},
"Markdown"
),
". Messages cannot be edited or deleted."
". Posts cannot be edited or deleted."
],
publishCustomInfo: ({ href }) => [
"If you're an advanced user, you can also ",
@ -99,7 +102,7 @@ module.exports = {
],
publishBasicInfo: ({ href }) => [
"If you're not an advanced user, you should ",
a({ href }, "publish a basic post"),
a({ href }, "publish a post"),
"."
],
publishCustom: "Publish custom",
@ -160,7 +163,7 @@ module.exports = {
submit: "Submit",
editProfile: "Edit profile",
editProfileDescription:
"Edit your profile with Markdown. Messages cannot be edited or deleted. Old versions of your profile information still exist and are public information, but most SSB apps don't show it.",
"Edit your profile with Markdown. Old versions of your profile information still exist and can't be deleted, but most SSB apps don't show them.",
profileName: "Profile name (text)",
profileImage: "Profile image",
profileDescription: "Profile description (Markdown)",
@ -169,10 +172,340 @@ module.exports = {
},
/* spell-checker: disable */
es: {
popular: "Popular",
latest: "Nuevo",
profile: "Pagina",
latest: "Novedades",
profile: "Mi Perfil",
search: "Buscar",
settings: "Reglas"
settings: "Configuración",
// navbar items
extended: "Red extendida",
extendedDescription: [
"Publicaciones de ",
strong("personas que no seguís"),
", ordenadas por las más recientes. Quando seguís una persona poderás descargar publicaciones de otras personas que esta siga y esos mensajes aparecen aquí."
],
popular: "Populares",
popularDescription: [
"Publicaciones de personas de tu red, ordenadas por cantidad de ",
strong("Me Gusta"),
" en determinados periodos. Se cuentan los Me Gusta de ",
em("todos"),
", incluindo aquellos que no seguís. Esta es una lista de publicaciones más populares de tu red de contacto."
],
latestDescription:
"Publicaciones que aquellos que seguís, ordenadas por las más recientes.",
topics: "Topicos",
topicsDescription: [
strong("Topicos"),
" de las personas que seguís, ordenadas por las más recientes. Seleccioná la hora de una publicación para leer el hilo completo."
],
summaries: "Resumen",
summariesDescription: [
strong("Topicos y algunos comentarios"),
" de las personas que seguís, ordenadas por las más recientes. Seleccioná la hora de una publicación para leer el hilo completo."
],
manualMode: "Modo manual",
mentions: "Menciones",
mentionsDescription: [
strong("Publicaciones de "),
strong("cualquier persona"),
" que te mencionan, ordenadas por las más recientes. Solo figuran menciones en el formato @mención."
],
private: "Privado",
privateDescription: [
"Los comentarios más recientes de ",
strong("hilos privados que te incluyen"),
". Las publicaciones privadas están encriptadas para tu llave privada, y contienen el máximo de 7 destinatarios. No se podrán adicionar nuevos destinarios después que empieze el hilo. Seleccioná la hora de una publicación para leer el hilo completo."
],
// post actions
comment: "Comentar",
reply: "Responder",
json: "JSON",
// relationships
unfollow: "Dejar de seguir",
follow: "Seguir",
relationshipFollowing: "Siguiendo",
relationshipYou: "Vos",
relationshipBlocking: "Bloqueado",
relationshipNone: "No estás siguiendo ni bloqueando",
relationshipConflict: "De alguna forma le estás siguiendo y bloqueando",
// author view
viewLikes: "Ver Me Gusta ",
// likes view
likedBy: "le gusta",
// composer
publish: "Publicar",
contentWarningPlaceholder: "Advertencia opcional para esta publicación",
publishCustomDescription: [
"Compone un mensaje custom usando ",
a({ href: "https://en.wikipedia.org/wiki/JSON" }, "JSON"),
". Esto puede ser util para prototipar o componer tipos de mensaje que Oasis aún no soporta. Este mensaje no podrá ser editado o borrado."
],
commentWarning: [
" Los mensajes no podrán ser editados o borrados. Para responde a mensajes, seleccione ",
strong("Responder"),
"."
],
commentPublic: "publico",
commentPrivate: "privado",
commentLabel: ({ publicOrPrivate, markdownUrl }) => [
"Escribí un ",
strong(`${publicOrPrivate} comentário`),
" con ",
a({ href: markdownUrl }, "Markdown"),
" en este hilo."
],
publishLabel: ({ markdownUrl, linkTarget }) => [
"Escribí mensaje publico con ",
a(
{
href: markdownUrl,
target: linkTarget
},
"Markdown"
),
". Los mensajes no podrán ser editados o borrados."
],
publishCustomInfo: ({ href }) => [
"Si sos un usário avanzado, podrás ",
a({ href }, "publicar un mensaje custom"),
"."
],
publishBasicInfo: ({ href }) => [
"Si no sos un usuário avanzado, podés ",
a({ href }, "publicar un mensaje basico."),
"."
],
publishCustom: "Publicar custom",
replyLabel: ({ markdownUrl }) => [
"Escribí una ",
strong("respuesta publica"),
" a este mensaje con ",
a({ href: markdownUrl }, "Markdown"),
". Los mensajes no podrán ser editados o borrados. Para responder a todo un hilo, seleccioná ",
strong("comentário"),
"."
],
// settings
settingsIntro: ({ readmeUrl, version }) => [
`Estás usando Oasis ${version}. Leé `,
a({ href: readmeUrl }, "el Readme"),
", configura un tema, o consultá información de debug abajo."
],
theme: "Tema",
themeIntro:
"Eligí un tema. Atelier-SulphurPool-Light és el tema por defecto.",
setTheme: "Eligí el tema",
language: "Idioma",
languageDescription:
"Sí queres usar Oasis en otro idioma, eligí acá. Atención, que esta funcionalidad és aún nueva y básica. Necesitamos ayuda con traducciones para otros idiomas y formatos.",
setLanguage: "Seleccionar idioma",
status: "Status",
peerConnections: "Conexiones de pares 💻⚡️💻",
connectionsIntro:
"Tu computadora está sincronizando con las siguientes computadoras. Se conectará con cualquier par de scuttlebutt que encuentre a medida que busque informacion de tus amigos, mismo que no hayas establecido una relación prévia.",
noConnections: "Sin pares conectados.",
connectionActionIntro:
"Podrás decidir cuando conectar tu computadora a la red de pares. Podrás arrancar, detener o reiniciar las conexiones siempre que quieras.",
startNetworking: "Arrancar las conexiones",
stopNetworking: "Detener las conexiones",
restartNetworking: "Reiniciar las conexiones",
indexes: "Indices",
invites: "Invitaciones",
invitesDescription:
"Utilizá una invitación pegando abajo. Sí funcionar, empezarás a seguir esa persona y ella te seguirá a vós también.",
acceptInvite: "Aceptar la invitación",
// search page
searchLabel:
"Buscá las siguientes palabras por los mensajes que tenés descargados.",
// posts and comments
commentDescription: ({ parentUrl }) => [
"comentado en el hilo ",
a({ href: parentUrl }, "")
],
replyDescription: ({ parentUrl }) => [
"respondido al mensaje ",
a({ href: parentUrl }, "")
],
mysteryDescription: "publicó un mensaje misterioso",
// misc
oasisDescription: "Interface del vecinario amistoso scuttlebutt",
submit: "Enviar",
editProfile: "Editar perfil",
editProfileDescription:
"Editá tu perfil con Markdown. Los mensajes no podrán ser editados o borrados. La información en tu perfil será siempre publico, mismo aquella de versiones antiguas. La mayoria de los clientes de ssb no presentarán versiones antiguas de tu perfil",
profileName: "Nombre de perfil (texto)",
profileImage: "Imagen de perfil",
profileDescription: "Descripción de perfil (Markdown)",
hashtagDescription:
"Publicaciones de personas en tu red que mencionan este hashtag, ordenadas por las más recientes."
},
de: {
extended: "Erweitert",
extendedDescription: [
"Beiträge von ",
strong("Leuten denen du nicht folgst"),
", sortiert nach Aktualität. Wenn du jemandem folgst lädst du eventuell auch Beiträge von Leuten herunter denen diese Person folgt, hier erscheinen diese Beiträge."
],
popular: "Beliebt",
popularDescription: [
"Beiträge von Leuten in deinem Netzwerk, sortiert nach ",
strong("Herzen"),
" in der angegebenen Periode. Herzen werden von ",
em("jedem"),
" gezählt, auch von Personen denen du nicht folgst. D.h. hier werden Beiträge von deinen Freund*innen angezeigt die in deinem erweiterten Netzwerk populär sind."
],
latest: "Aktuell",
latestDescription:
"Beiträge von Leuten denen du folgst, sortiert nach Aktualität.",
topics: "Themen",
topicsDescription: [
strong("Themen"),
" von Leuten denen du folgst, sortiert nach Aktualität. Klicke auf den Zeitstempel eines Beitrages um den Rest des Threads zu sehen."
],
summaries: "Übersicht",
summariesDescription: [
strong("Themen und einige Kommentare"),
" von Leuten denen du folgst, sortiert nach Aktualität. Klicke auf den Zeitstempel eines Beitrages um den Rest des Threads zu sehen."
],
profile: "Profil",
manualMode: "Manueller Modus",
mentions: "Erwähnungen",
mentionsDescription: [
strong("Beiträge in denen du erwähnt wirst"),
" von ",
strong("allen"),
", sortiert nach Aktualität. Manchmal vergessen Leute dich zu @erwähnen, diese Beiträge werden hier nicht erscheinen."
],
private: "Privat",
privateDescription: [
"Die letzten Kommentare aus ",
strong("privaten Threads die dich beinhalten"),
", sortiert nach Aktualität. Private Beiträge werden mit deinem öffentlichen Schlüssel verschlüsselt und haben maximal 7 Empfänger*innen. Empfänger*innen können nicht hinzugefügt werden nachdem ein Thread gestartet wurde. Klicke auf den Zeitstämpel um einen komplette Thread anzuzeigen."
],
search: "Suche",
settings: "Einstellungen",
// post actions
comment: "Kommentieren",
reply: "Antworten",
json: "JSON",
// relationships
unfollow: "Entfolgen",
follow: "Folgen",
relationshipFollowing: "Du folgst",
relationshipYou: "Das bist du",
relationshipBlocking: "Du blockierst",
relationshipNone: "Weder folgst noch blockst du",
relationshipConflict: "Irgendwie folgst und blockst du gleichzeitig",
// author view
viewLikes: "Likes ansehen",
// likes view
likedBy: "'s Likes",
// composer
publish: "Veröffentlichen",
contentWarningPlaceholder: "Optionale Inhaltswarnung für diesen Beitrag",
publishCustomDescription: [
"Veröffentliche eine benutzerdefinierte Nachricht durch das Eingeben von ",
a({ href: "https://en.wikipedia.org/wiki/JSON" }, "JSON"),
" unten. Dies kann zum Prototyping oder dem veröffentlichen von Nachrichten die Oasis nicht unterstützt nützlich sein. Diese Nachricht kann nicht bearbeitet oder gelöscht werden."
],
commentWarning: [
" Nachrichten können nicht bearbeitet oder gelöscht werden. Um auf eine einzelne Nachricht zu antworten, wähle ",
strong("antworten"),
" stattdessen."
],
commentPublic: "öffentlichen",
commentPrivate: "privaten",
commentLabel: ({ publicOrPrivate, markdownUrl }) => [
"Verfasse einen ",
strong(`${publicOrPrivate} Kommentar`),
" in diesem Thread mit ",
a({ href: markdownUrl }, "Markdown"),
"."
],
publishLabel: ({ markdownUrl, linkTarget }) => [
"Verfasse einen neuen öffentlichen Beitrag in ",
a(
{
href: markdownUrl,
target: linkTarget
},
"Markdown"
),
". Beiträge können nicht bearbeitet oder gelöscht werden."
],
publishCustomInfo: ({ href }) => [
"Wenn du ein erfahrener Benutzer bist kannst du auch ",
a({ href }, "eine benutzerdefinierte Nachricht veröffentlichen"),
"."
],
publishBasicInfo: ({ href }) => [
"Wenn du kein erfahrener Benutzer bist, solltest du ",
a({ href }, "einen einfachen Beitrag veröffentlichen"),
"."
],
publishCustom: "Benutzerdefinierte Veröffentlichung",
replyLabel: ({ markdownUrl }) => [
"Verfasse eine ",
strong("öffentliche Antwort"),
" zu dieser Nachricht mit ",
a({ href: markdownUrl }, "Markdown"),
". Nachrichten können nicht bearbeitet oder gelöscht werden. Um auf einen kompletten Thread zu antworten, klicke auf ",
strong("kommentieren"),
" stattdessen."
],
// settings
settingsIntro: ({ readmeUrl, version }) => [
`Du verwendest Oasis ${version}. Lese `,
a({ href: readmeUrl }, "die Readme"),
", konfiguriere dein Theme oder schaue dir Debugging-Informationen weiter unten an."
],
theme: "Theme",
themeIntro:
"Wähle ein Theme das dir gefällt. Das Standard-Theme ist Atelier-SulphurPool-Light.",
setTheme: "Theme einstellen",
language: "Sprache",
languageDescription:
"Wenn du Oasis in einer anderen Sprache nutzen möchtest, wähle unten eine aus. Bitte beachte, dass dies sehr neu und noch am Anfang ist. Wir freuen uns über deine Hilfe bei der Übersetzung von Oasis in andere Sprachen.",
setLanguage: "Sprache einstellen",
status: "Status",
peerConnections: "Verbindungen zu Peers 💻⚡️💻",
connectionsIntro:
"Dein Computer synchronisiert Daten mit diesen anderen Computern. Auf der Suche nach Daten von deinen Freund*innen werden Verbindungen zu allen Scuttlebutt Pubs und Peers aufgenommen die gefunden werden, auch wenn du keine Beziehung mit diesen hast.",
noConnections: "Keine Peers verbunden.",
connectionActionIntro:
"Du kannst entscheiden wann dein Computer mit Peers netzwerken soll. Du kannst das Netzwerken starten, stoppen oder neustarten wann immer du willst.",
startNetworking: "Netzwerken starten",
stopNetworking: "Netzwerken stoppen",
restartNetworking: "Netzwerken neustarten",
indexes: "Indizes",
invites: "Einladungen",
invitesDescription:
"Löse eine Einladung durch einfügen unten ein. Wenn es geklappt hat wirst du dem Feed folgen und sie werden dir folgen.",
acceptInvite: "Einladung annehmen",
// search page
searchLabel:
"Füge Wörte hinzu nach denen in heruntergeladenen Nachrichten gesucht werden soll.",
// posts and comments
commentDescription: ({ parentUrl }) => [
"kommentierte auf ",
a({ href: parentUrl }, " Thread")
],
replyDescription: ({ parentUrl }) => [
"antwortete auf ",
a({ href: parentUrl }, " Nachricht")
],
mysteryDescription: "veröffentlichte eine mysteriöse Nachricht",
// misc
oasisDescription: "Freundliches Scuttlebutt Interface",
submit: "Abschicken",
editProfile: "Profil bearbeiten",
editProfileDescription:
"Bearbeite dein Profil mit Markdown. Nachrichten können nicht bearbeitet oder gelöscht werden. Alte Versionen deiner Profilinformationen bleiben existieren und sind öffentliche Informationen, aber die meisten SSB-Apps zeigen diese nicht an.",
profileName: "Profilname (Text)",
profileDescription: "Profilbeschreibung (Markdown)",
hashtagDescription:
"Beiträge von Leuten in deinem Netzwerk die dieses Hashtag referenzieren, sortiert nach Aktualität."
}
};

View File

@ -1,9 +1,10 @@
"use strict";
const debug = require("debug")("oasis");
const ssbMarkdown = require("ssb-markdown");
const highlightJs = require("highlight.js");
const MarkdownIt = require("markdown-it");
const {
a,
article,
@ -16,7 +17,6 @@ const {
form,
h1,
h2,
h3,
head,
header,
html,
@ -44,6 +44,8 @@ const {
const lodash = require("lodash");
const markdown = require("./markdown");
const md = new MarkdownIt();
const i18nBase = require("./i18n");
let i18n = null;
let selectedLanguage = null;
@ -101,7 +103,11 @@ const template = (...elements) => {
emoji: "🗺️",
text: i18n.extended
}),
navLink({ href: "/", emoji: "📣", text: i18n.popular }),
navLink({
href: "/public/popular/day",
emoji: "📣",
text: i18n.popular
}),
navLink({ href: "/public/latest", emoji: "🐇", text: i18n.latest }),
navLink({
href: "/public/latest/topics",
@ -615,7 +621,7 @@ exports.commentView = async ({ messages, myFeedId, parentMessage }) => {
const isPrivate = parentMessage.value.meta.private;
const publicOrPrivate = isPrivate ? "private" : "public";
const publicOrPrivate = isPrivate ? i18n.commentPrivate : i18n.commentPublic;
const maybeReplyText = isPrivate ? [null] : i18n.commentWarning;
return template(
@ -697,7 +703,7 @@ exports.threadView = ({ messages }) =>
template(messages.map(msg => post({ msg })));
exports.markdownView = ({ text }) => {
const rawHtml = ssbMarkdown.block(text);
const rawHtml = md.render(text);
return template(section({ class: "message" }, { innerHTML: rawHtml }));
};
@ -720,7 +726,7 @@ exports.publishView = () => {
name: "contentWarning",
type: "text",
class: "contentWarning",
placeholder: "Optional warning for the post"
placeholder: i18n.contentWarningPlaceholder
})
),
button({ type: "submit" }, i18n.submit)
@ -819,6 +825,18 @@ exports.settingsView = ({ status, peers, theme, themeNames, version }) => {
{ class: "message" },
h1(i18n.settings),
p(i18n.settingsIntro({ readmeUrl: "/settings/readme", version })),
h2(i18n.peerConnections),
p(i18n.connectionsIntro),
peerList.length > 0 ? ul(peerList) : i18n.noConnections,
p(i18n.connectionActionIntro),
connButtons,
h2(i18n.invites),
p(i18n.invitesDescription),
form(
{ action: "/settings/invite/accept", method: "post" },
input({ name: "invite", type: "text" }),
button({ type: "submit" }, i18n.acceptInvite)
),
h2(i18n.theme),
p(i18n.themeIntro),
form(
@ -833,24 +851,13 @@ exports.settingsView = ({ status, peers, theme, themeNames, version }) => {
{ action: "/language", method: "post" },
select({ name: "language" }, [
languageOption("en", "English"),
languageOption("es", "Español")
languageOption("es", "Español"),
/* cspell:disable-next-line */
languageOption("de", "Deutsch")
]),
button({ type: "submit" }, i18n.setLanguage)
),
h2(i18n.status),
h3(i18n.peerConnections),
p(i18n.connectionsIntro),
peerList.length > 0 ? ul(peerList) : i18n.noConnections,
p(i18n.connectionActionIntro),
connButtons,
h3(i18n.invites),
p(i18n.invitesDescription),
form(
{ action: "/settings/invite/accept", method: "post" },
input({ name: "invite", type: "text" }),
button({ type: "submit" }, i18n.acceptInvite)
),
h3(i18n.indexes),
h2(i18n.indexes),
progressElements
)
);