Problem: Searching for a hashtag should bring you to the hashtag page,
and the hashtag page should have some useful information about which
page you're on instead of just showing you the messages.
Solution: Add code so that if you search for a hashtag you're brought to
that page, and display some useful help text at the top of the page
explaining the hashtag page. While ensuring that the hashtag page showed
posts from around the network (instead of only people you're following)
I fixed the popular page so that it has the same behavior again (fixing
a regression) and filtered out gatherings (fixing *another* regression)
on the popular page. These probably should've happened in another commit
but I got carried away. :/
Happy to split this commit into two if it hurts to bundle the popular
fixes with the hashtag fix, but I'm low on energy and want to at least
open a PR in case it doesn't bother anyone.
Problem: The previous code was printing debug output so that I could
ensure that my argument checking worked correctly, but we don't want to
distribute a binary that echoes back your arguments to you.
Solution: Remove the debug output and add lots of comments to document
all of my misunderstandings of how the current code works. :~)
Problem: I don't know what I'm doing and can't figure out how to
cross-compile this simple C program to macOS and Windows
Solution: @cryptix reminded me that Go makes cross-compiling easy, so I
took a stab at writing my first Go program. It seems to be working on
macOS and Linux, but I haven't tested on Windows.
Problem: Apparently one of the previous commits switched us to
shell-style argument expansion.
Solution: Use the appropriate solution on Windows, `%*`.
Problem: We were using `darwin` instead of `win`.
Solution: Replace `darwin` with `win` to ensure that we're using the
correct path in the batch file we produce.
Problem: The search results weren't hiding results from blocked feeds.
Solution: Add `socialFilter()` to ensure that all blocked feeds are
removed from search results as the first step in the stream processing.
Problem: Sometimes you try to run Oasis twice and the second time you
run the program it blows up in your face about the port being taken.
Most other software just focuses or reopens the window instead of
throwing errors at you.
Solution: Implement `/.well-known/oasis` as a sanity check to see
whether the thing listening on the HTTP port. If it replies "oasis" then
we can open the tab (unless `config.open === false`) and avoid throwing
the error.
Problem: An SSB client should allow you to declare your own name, but
Oasis didn't support that behavior at all.
Solution: Add a basic 'Edit Profile' page that lets you set your name
and description. This doesn't implement profile images because I had
limited time and didn't want to think about encoding formats, but it's
worth mentioning that I remember something about binary uploads with the
default form encoding actually send 3 times as much data because of
escapes or something? This might not effect us because we're on
localhost, but I want to make a note that this isn't implemented yet.
This also makes a small change regarding the `<label>` element --
previously we were writing them as siblings to the input and using the
`for` attribute to target the input, but while messing with the CSS I
tried putting them directly in the `label()` and it ends up having the
same effect with less code.
Problem: Trying to use the DTA index when using SSB-Query doesn't work,
because that index only exists on SSB-Backlinks.
Solution: Change the filter to ensure that we're sorted by the asserted
timestamp and ignoring messages from the future. The SSB-Backlinks
plugin was taking the minimum between `.value.timestamp` and `timestamp`
but since we're not using SSB-Backlinks in this query (or maybe at all?)
we get to make our own little hacky query. Cel taught me that the
`$sort` option causes problems here because it buffers the entire result
in memory before doing the sort. Boo. Instead we just need to reference
the property that we want to be sorted by with some operation, even if
it does nothing (like `{ $gt: null }`), but since we're filtering time
travelers we actually need `{ $lge: Date.now() }` there anyway.
Problem: When running the Darwin binary from another directory, the
script would look in the user's current working directory for both
`node` and `src`, which is wrong.
Solution: Set `BASEDIR` and use it so that we use the correct paths.
Problem: I've quickly learned that cross-compiling is a major headache
and that C programming lacks both rainbows and butterflies. It seems
that my executable only works on Linux, but probably not macOS or
Windows.
Solution: Use shell scripts on macOS, which work when you double-click
them, and batch scripts on Windows, which I *think* work when you
double-click them. I haven't tested this on a macOS device yet, but I
tested the previous shell script on macOS and it seemed to work fine.
Unless I've done something silly, this should work on macOS, but the
Windows batch script is just me writing code from memory and probably
doesn't work correcly. I'll probably beg @SoapDog to help me fix it.
Problem: Writing C in a heredoc is super janky and I think it's worth
avoiding whenever we can. We've also been getting compiler warnings that
we should probably resolve.
Solution: Move the C to its own file and resolve the compiler warnings.
Problem: The shell script didn't work on other platforms and the
AppImage hack ended up confusing people who tried to install it with
AppImageLauncher.
Solution: This feels absolutely ridiculous, but I've written the worst C
program in the world which does the equivalent of `exec ./node src "$@"`
and immediately gets out of our way. This ends up being an executable
that both Nautilus and Dolphin (GNOME and KDE file managers) let us
double-click, and should also work on macOS. It might even work on
Windows if we rename it as an `.exe`, but I'm not sure and *definitely*
haven't tested that.
Problem: We try to `require()` our native modules to ensure that they
work correctly, but when they don't work we need to produce an error
that will help us debug the problem.
Solution: Switch from `node -p` to `node -e` to avoid printing
unnecessary output and don't redirect output for mandatory modules so
that we can debug them.
Problem: The installer contained npm and npx and a bunch of code that we
really don't need unless we're building from source. Since we don't want
our end-users to build anything from source, we can remove these.
Solution: Use shell-check to make some small fixups to the code and
remove everything we're downloading via wget except the `node` binary.
This requires moving the "build from source" fallback, and also includes
the `.appimage` hack when building from Linux to get double-click
opening working.
Problem: The previous approach of having the installer run `npm install`
was hazardous at best and didn't work well offline.
Solution: Package all of the source code with the application and use
the installer to ensure that it works on the target device. The
installer should ensure that we can `require()` the module, and if that
doesn't work then it should choose between two options:
- If the module is optional, `rm -rf` it and don't worry about it.
- If the module is mandatory, try running `npm install` with some flags
to ensure that we stay offline and print the absolute minimal output.
This should never happen, because we should never be packaging Oasis
for architectures and platforms that we don't have prebuilds for, but
it's a fine fallback behavior for experimental hackery.
Problem: We load the default config with `require()`, which would allow
arbitrary JavaScript execution, are producing debug output everywhere
with `console.log()` statements, and don't have instructions for how to
write the config file. The config file is also `.config/**/config.json`,
and I think it would be helpful to specify that this is the **default**
config rather than any other kind of config.
Solution: Rename the config to `~/.config/oasis/default.json`, replace
the `require()` with `fs.readFile()`, remove `console.log()` for
debugging, and add some example JSON for how to use the config file.
Problem: Running `./oasis --version` should output the current version,
it shouldn't just start the server by default.
Solution: Pass through command-line arguments with `$@` so that we
respect what the user is asking us to do.
This should give pretty much expected behaviour. Each config value
can be set by three sources:
1. By command-line argument. If it is not given, then
2. By config file. Or, lastly
3. By default value in the source code.
I can't test that the config file is searched and read from the right
place on windows or macOS, but on linux it works.
Problem: Most people don't have npm installed and we probably shouldn't
force them to have a full development environment to use Oasis. It would
be nice to have a way to install Oasis without any development tools.
Solution: Add a build script that can create .zip files that work on
Unix systems like macOs and Linux. Users will need to download the zip,
extract it, and double-click the `oasis` script. This script will run
`npm start || npm install && npm start`, which uses binaries that we
ship in the zip file so that they don't need to have `node` or `npm`
installed.
Problem: We're doing tons of unnecessary cryptography by encrypting the
connection between the "client" and "server", which are often running in
the same process.
Solution: Instead of connecting to the SSB service over TCP and
encrypting the stream, just connect over a socket (supported on Windows,
macOS, and Linux) and don't bother encrypting anything. This is what
Patchwork and Patchbay do already, and since our secret is at
`~/.ssb/secret` then we should be comfortable with `~/.ssb/socket` being
a trusted file where access implies authentication.
Local tests suggest that when sodium-native is available, this commit
reduces the time to render the 'Popular (Day)' page by 17%, but when we
have to fall back to JavaScript cryptography the same page now takes 30%
less time to render. My intuition is that this improvement is more
dramatic on mobile, but requires further testing before we can pat
ourselves on the back too much. :)
Problem: I thought `--no-optional` would just ignore our top-level
optional dependencies, but it ends up ignoring deep optionl dependencies
like sodium-native. We really want these dependencies if we can build
them.
Solution: Remove the `--no-optional` suggestion and add a note about
what to do if Sharp doesn't install correctly, which is very likely
since Termux doesn't have libvips available.
Problem: The Termux install is new and exciting and there isn't any
documentation on how to experiment with it.
Solution: Add some documentation like we've done with systemd and
Docker so that we can collaborate and figure it out in the repo!
Problem: We've been using a workaround to filter the results of
SSB-Mentions, but that's just been fixed upstream and so we don't need
the workaround anymore.
Solution: Update the SSB-Mentions package and remove the workaround.
Problem: During the SSB-Query refactor I used `{ private: false }` in an
attempt to hide private messages, but apparently this option is only
available via SSB-Backlinks, so it was ignored without any warning (!).
This allowed private messages to be displayed in public views.
Solution: Remove the unused option and add a filter to public views that
ensures that private messages are always hidden.
Problem: Private messages should only be showing up in the Private page,
not the Mentions page, but right now they're showing up in Mentions.
Solution: Add a check to ensure that Mentions doesn't have any private
messages.
Problem: When the port was already taken by another process we've been
dumping a big esoteric error message that really isn't helpful for most
people.
Solution: Catch the error and give our users a friendly error message
with a suggestion on how to run Oasis on another port.
Problem: I added an image border to try to make it easier to see the
boundaries of images but it's not really necessary and at least one
person didn't love it, which is grounds for removal.
Solution: Get it out of here! This commit removes the image border and
also removes a random `console.log()` that shouldn't have been left in
`src/index.js`.
Problem: After publishing a message you were redirected to the Popular
view, which wasn't good feedback that your message had been published.
Solution: After publishing a new message, redirect to the Latest view.
Problem: It was impossible to tell which version of Oasis you're
running, which makes it hard to know when you need to update.
Solution: Put the version in the settings so it's easy to reference.