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.
This means we also apply the collapsing to normal queries,
which might also collapse other things like joins / quits
which may be undesired by some
Fixes: https://github.com/thelounge/thelounge/issues/4583
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.
The only thing that cares about user colors is the user component.
Putting a class value on the chat component seems to be the wrong
place.
This also allows us to remove various css selectors so that we
don't need to be that specific.
After all whatever has that class needs to be colored, we don't
care where it is.
During a search, we get the results from oldest --> newest.
When we hit the more button, we get the results of the second batch
in the same order.
However, logically to the first batch everything is older, so we
need to prepend it to the result array, not
append.
msg DB logical ID
A 3 5
B 2 4
C 1 3
D 3 2
E 2 1
F 1 0
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.
Offset is eventually passed to sqlite as an OFFSET clause.
This works as follows:
sqlite> select num from seq limit 5 offset 0;
┌─────┐
│ num │
├─────┤
│ 1 │
│ 2 │
│ 3 │
│ 4 │
│ 5 │
└─────┘
sqlite> select num from seq limit 5 offset 5;
┌─────┐
│ num │
├─────┤
│ 6 │
│ 7 │
│ 8 │
│ 9 │
│ 10 │
└─────┘
However, the code currently emits a request for offset + 1, which ends
up skipping a message
sqlite> select num from seq limit 5 offset 5+1;
┌─────┐
│ num │
├─────┤
│ 7 │
│ 8 │
│ 9 │
│ 10 │
│ 11 │
└─────┘
Nachtalb put some infra in place that was never actually working.
It errors out when a user clicks on a message.
Remove the offending code, but keep it all in place so that we
can improve on it.
When we hit doSearch, we always reset the offset value to 0,
meaning we always hit the conditional (!0) and always set the
messageSearchInProgress flag to undefined.
This is wrong, we do want to set this flag when we initiate a search.
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