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: The `messagesByType()` queries don't let us sort by asserted
time, which means that we can get messages from a long time ago that
just ended up on our computer.
Solution: Use SSB-Query everywhere. The query syntax isn't really my
favorite but it lets us make declarative queries that respect the
asserted timestamp instead of just the received timestamp.
Problem: Until we have a way to change the view of each page, it seems
to me that each of the views that we're experimenting with should be on
their own page rather than modifying the existing pages to add more
functionality. I'm also noticing that I can't process all of the
information that's on the screen when the new horizontal layout is used,
and I think we would benefit from using the previous layout
consistently.
Solution: Move the summary view to its own page so that we can continue
to iterate on it without modifying the popular view, which is already
complex, and revert the style changes to maintain consistency with the
rest of the linear design (threads go downward, indentation denotes
sub-threads, etc).
Problem: When we couldn't figure out someone's name or description we
were using `null`, which got coerced to a string and ended up with us
calling people `"@null"`. Not ideal!
Solution: Support a use-case where someone doesn't have a profile
description or a name, and use the first 8 characters of their public
key for their name if they haven't set a name themselves.
Problem: The new custom publish was called 'Manual mode', which I'm
afraid isn't super easy to understand for people who don't already know
SSB. The custom publishing page didn't follow the same conventions as
other pages, either.
Solution: Hide the custom publish mode behind the publish page, with a
warning that it's for 'advanced users', and ensure that it uses the same
conventions and visual styles as other pages and code around the app.
Problem: Previously we were only counting likes from people you follow,
but showing messages from anyone. This was backward, and could
potentially show messages from blocked authors that were liked by people
you follow.
Solution: Move the `socialFilter()` invocation down the pipeline so that
it sorts the output messages, not the likes.
Problem: Any error thrown while looking for thread ancestors was
throwing a "message not found" error, which was incorrect and useless.
This error caused me to his refresh repeatedly, not understanding that I
was publishing multiple messages. Super bad. While investigating this I
found that there's a slightly different problem where someone can post
an *invalid* message link, which we don't currently have handling for.
Solution: Only show that error when it's actually happening, and add
support for just ignoring when we see an invalid message link as `root`
or `fork`.
Problem: In the old `cooler.read()` implementation, sources returned
promises, but that isn't the case in the native SSB-Client promise
impelementation. This means that in at least one place, there's a bug
where it tries to call `.then()` on a non-promise.
Solution: Remove promise-based code from streams, which don't require
any special handling anymore.
Problem: Your posts show up in Extended, which is unexpected because I'm
the center of my network, not some rando at the periphery.
Solution: Use the `socialFilter()` function to make sure that the
extended view only shows people in your extended network, not you. :)
Problem: We started using `cooler.get()` and `cooler.read()` because it
was impossible to use promises with SSB-Client.
Solution: I made some downstream pull requests into the MuxRPC module
and the SSB-Client module, which means that both of them now natively
support promises. This commit removes the weird convenience methods and
replaces them with the native promise support, which should hopefully
make the code easier to read and write.
Problem: There was one missing component that would filter out nicknames
from other people. This caused a problem where we could get a name for a
feed but it could've been assigned by a friend, which we don't want
right now.
Solution: Ensure that the subject of the message is the same as the
author of the message.
Problem: The SSB-About plugin is incompatible with our needs. More info
in the GitHub issue linked below and in the code comments.
Solution: Unfortunately, roll our own alternative to the SSB-About
plugin so that we can be 100% sure that it pulls the latest 'about'
published by an author about themselves and doesn't just skip `false`.
Problem: The `socialFilter()` function wasn't documented and contained a
bug where it wouldn't show your posts when `following = true`. This is
because you usually don't follow yourself, so `following = true` was
basically equivalent to `me = false`.
Solution: Add some documentation and resolve the bug by adding special
handling for when the message is from us *before* passing to the general
implementation for follow/block checking.
Resolves https://github.com/fraction/oasis/issues/155
Resolves https://github.com/fraction/oasis/issues/177
Problem: It's hard to show off Oasis or take screenshots without
respecting the `publicWebHosting` convention. While `publicWebHosting`
lacks a formal specification and I'm a bit confused about what its
boundaries are, it sounds like some of our friends would like to avoid
us publishing any of their content on the public web if we can avoid it.
Solution: Add --public option that turns Oasis into a public web viewer.
This makes it **slightly inconvenient** to see these public posts, but
should absolutely not be mistaken for a privacy guarantee. Only HTTP GET
endpoints are allowed, so random people can't publish or change
settings. The name, avatar, description, content warning, and message
contents are replaced with "Redacted", but again, this is all public
information that we can never provide real privacy for.
Resolves https://github.com/fraction/oasis/issues/48
Problem: The socialFilter was hiding posts published by the user, which
felt weird and uncanny.
Solution: Fix the default so that `{ me }` isn't hidden from a view
unless the model specifically wants that to happen.
Resolves https://github.com/fraction/oasis/issues/156
Problem: There was no way to onboard new users since we couldn't redeem
invites.
Solution: Add basic follow-back invites to the settings page. This takes
an invite string, runs it through invite.accept, and either returns the
error in full *or* redeems the invite quietly.
Problem: @masukomi pointed out that the 'latest' view doesn't show the
awesome slice of content that you'll see if you just look at root posts.
Solution: Let's experiment with them! This commit adds a 'Topics' page
that has the latest root posts from people you're following.
Problem: We shouldn't be showing any strangers on the popular or latest
pages. We shouldn't be showing anyone who's been blocked on any of those
feeds.
Solution: Don't show blocked people on any pages and don't show
strangers on the popular / latest pages.
Problem: If the user tries to see a thread and the link points to a
message we don't have, then we don't have any way to display anything in
the thread. How could we even know which thread it's in?
Solution: Throw the error but make it more useful and fix the "non-error
thrown" verbiage that we've inherited from a dependency trying to throw
a non-error.
Problem: It was impossible to do any internationalization because
strings were all embedded throughout Oasis.
Solution: Add an internationalization submodule that provides
language-specific strings for the text elements in views. In future
commits we can add language selection and fallbacks for when the
selected language doesn't support the text we need to have translated.
Problem: The 'Following' page was super slow because we were doing a
MuxRPC request on every single message.
Solution: Do one request to see who we have relationships with, filter
out the people we aren't following, and then check against that list
instead of doing a bunch of MuxRPC calls.
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|:---|---:|---:|---:|---:|
| `curl http://localhost:3000/public/latest/following` | 500.9 ± 163.4 | 392.1 | 881.4 | 1.00 |
| `curl http://localhost:3456/public/latest/following` | 4663.7 ± 184.6 | 4438.6 | 5075.2 | 9.31 ± 3.06 |
Problem: The model code was doing our Markdown rendering, which feels to
me like a layer violation because *generally* the model is meant to be a
thin abstraction over the underlying database without any concept of the
presentation layer.
Solution: Move the Markdown renderer to the view module and manage
Markdown rendering in the presentation layer.