READ lets downstream clients share information between each other about
what messages have been read by other downstreams.
Each target/entity has an optional corresponding read receipt, which is
stored as a timestamp.
- When a downstream sends:
READ #chan timestamp=2020-01-01T01:23:45.000Z
the read receipt for that target is set to that date
- soju sends READ to downstreams:
- on JOIN, if the client uses the soju.im/read capability
- when the read receipt timestamp is set by any downstream
The read receipt date is clamped by the previous receipt date and the
current time.
Make Network.Nick optional, default to the user's username. This
will allow adding a global setting to set the nickname in the
future, just like we have for the real name.
References: https://todo.sr.ht/~emersion/soju/110
VARCHAR(n) is pointless in SQLite and is the same as TEXT. Don't
bother with a migration since they're equivalent.
Also remove some unnecessary DEFAULT NULL statements.
This is a mecanical change, which just lifts up the context.TODO()
calls from inside the DB implementations to the callers.
Future work involves properly wiring up the contexts when it makes
sense.
Since NULL = NULL is always FALSE, this query needs to use IS instead.
This should fix the flood of DeliveryReceipts in the DB.
See https://www.sqlite.org/lang_expr.html
> The IS and IS NOT operators work like = and != except when one or both
> of the operands are NULL. In this case, if both operands are NULL,
> then the IS operator evaluates to 1 (true) and the IS NOT operator
> evaluates to 0 (false). If one operand is NULL and the other is not,
> then the IS operator evaluates to 0 (false) and the IS NOT operator is
> 1 (true). It is not possible for an IS or IS NOT expression to
> evaluate to NULL.
This allows users to set a default realname used if the per-network
realname isn't set.
A new "user update" command is introduced and can be extended to edit
other user properties and other users in the future.