Network.export() only writes the "type" key if it's a ChanType.QUERY;
so the config on disk has no "type".
This causes it to be undefined when loading, which breaks various other
checks, and then drops it the next time the config is saved.
Client and ClientManager deal with both 'dehydrated' channels/networks (ie. directly
from JSON configuration) and the 'rehydrated' ones (classes, with socket objects,
message arrays, etc.).
However, because their attributes are similar, both types were used interchangeably,
which becomes an issue when splitting Client's configuration loading into smaller
methods.
Prior to this, the search is still racy but one tends to notice
this only when the DB is large or network is involved.
The user can initiate a search, get bored, navigate to another chan
issue a different search.
Now however, the results of the first search come back in and
hilarity ensues as we are now confused with the state.
To avoid this, keep track of the last search done and any result
that comes in that isn't equal to the active query is garbage and
can be dropped.
The only reason we accepted a client was that so we have access
to the next message id when we need it.
So let's accept an id provider function instead.
The interface should not contain things that aren't the API of the
storage interface.
Further, rename ISqliteMessageStorage to SearchableMessageStorage,
as that's also an implementation detail.
We'll never have a second sqlite backend, so the name seems
strange.
TL is stupid and doesn't wait for message{Provider,Storage} to
settle before it starts using the store.
While this should be fixed globally, we can hack around the problem
by pushing everything onto the call stack and hope that we'll eventually
finish the setup before we blow the stack.
TS type assertions need to be avoided.
The following trivial example demonstrates why
```
type Person = {
name: string;
isBad: boolean;
};
function makePerson(): Person {
const p: Person = {name: 'whatever'} as Person
p.isBad = false
return p // theoretically we are now good, p is a Person
}
```
Should the type ever change though, TS will happily trot along
```
type Person = {
name: string;
isBad: boolean;
omgHowCouldYou: number;
};
function makePerson(): Person {
const p: Person = {name: 'whatever'} as Person
p.isBad = true
return p // p is *not* a Person, omgHowCouldYou is missing
}
```
But we pinky swore to the compiler that p is in fact a Person.
In other words, the types are now wrong and you will fail during
runtime.
Message stores are more complicated that a sync "fire and forget"
API allows for.
For starters, non trivial stores (say sqlite) can fail during init
and we want to be able to catch that.
Second, we really need to be able to run migrations and such, which
may block (and fail) the activation of the store.
On the plus side, this pushes error handling to the caller rather
than the stores, which is a good thing as that allows us to eventually
push this to the client in the UI, rather than just logging it in the
server on stdout
Currently the realname is set to an advertisement if it isn't explicitly
set by the user.
Some clients started to show the realname as a display name in their
UI, which makes this tedious as you'll end up with gazillion "The Lounge
User" entries.
To avoid this, set the realname to the nick on first connect, so that
it is useful.
Note that this isn't done on nick changes, but only on the initial
connect step.
Fixes: https://github.com/thelounge/thelounge/issues/4527
When a URL is prefixed with a TLS scheme, we should make sure
that the remote provides a valid cert, even just for prefetches.
Else MITM of such a site is trivial.
This probably breaks some people with self signed cert, but the
age where that was acceptable is past. We have free CAs now like
Let's Encrypt.