Merge branch 'searchFixTakeTwo'
This commit is contained in:
commit
7f3ac62e0d
@ -33,18 +33,19 @@
|
||||
<button
|
||||
ref="loadMoreButton"
|
||||
:disabled="
|
||||
store.state.messageSearchInProgress || !store.state.isConnected
|
||||
!!store.state.messageSearchPendingQuery ||
|
||||
!store.state.isConnected
|
||||
"
|
||||
class="btn"
|
||||
@click="onShowMoreClick"
|
||||
>
|
||||
<span v-if="store.state.messageSearchInProgress">Loading…</span>
|
||||
<span v-if="store.state.messageSearchPendingQuery">Loading…</span>
|
||||
<span v-else>Show older messages</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="store.state.messageSearchInProgress && !offset"
|
||||
v-if="store.state.messageSearchPendingQuery && !offset"
|
||||
class="search-status"
|
||||
>
|
||||
Searching…
|
||||
@ -105,6 +106,7 @@ import type {ClientMessage} from "../../js/types";
|
||||
import {useStore} from "../../js/store";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import {switchToChannel} from "../../js/router";
|
||||
import {SearchQuery} from "../../../server/plugins/messageStorage/types";
|
||||
|
||||
export default defineComponent({
|
||||
name: "SearchResults",
|
||||
@ -187,37 +189,44 @@ export default defineComponent({
|
||||
|
||||
const clearSearchState = () => {
|
||||
offset.value = 0;
|
||||
store.commit("messageSearchInProgress", false);
|
||||
store.commit("messageSearchResults", null);
|
||||
store.commit("messageSearchPendingQuery", null);
|
||||
};
|
||||
|
||||
const doSearch = () => {
|
||||
if (!network.value || !channel.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearSearchState(); // this is a new search, so we need to clear anything before that
|
||||
socket.emit("search", {
|
||||
networkUuid: network.value?.uuid,
|
||||
channelName: channel.value?.name,
|
||||
const query: SearchQuery = {
|
||||
networkUuid: network.value.uuid,
|
||||
channelName: channel.value.name,
|
||||
searchTerm: String(route.query.q || ""),
|
||||
offset: offset.value,
|
||||
});
|
||||
};
|
||||
store.commit("messageSearchPendingQuery", query);
|
||||
socket.emit("search", query);
|
||||
};
|
||||
|
||||
const onShowMoreClick = () => {
|
||||
if (!chat.value) {
|
||||
if (!chat.value || !network.value || !channel.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
offset.value += 100;
|
||||
store.commit("messageSearchInProgress", true);
|
||||
|
||||
oldScrollTop.value = chat.value.scrollTop;
|
||||
oldChatHeight.value = chat.value.scrollHeight;
|
||||
|
||||
socket.emit("search", {
|
||||
networkUuid: network.value?.uuid,
|
||||
channelName: channel.value?.name,
|
||||
const query: SearchQuery = {
|
||||
networkUuid: network.value.uuid,
|
||||
channelName: channel.value.name,
|
||||
searchTerm: String(route.query.q || ""),
|
||||
offset: offset.value,
|
||||
});
|
||||
};
|
||||
store.commit("messageSearchPendingQuery", query);
|
||||
socket.emit("search", query);
|
||||
};
|
||||
|
||||
const jumpToBottom = async () => {
|
||||
|
@ -2,12 +2,27 @@ import socket from "../socket";
|
||||
import {store} from "../store";
|
||||
|
||||
socket.on("search:results", (response) => {
|
||||
store.commit("messageSearchInProgress", false);
|
||||
const pendingQuery = store.state.messageSearchPendingQuery;
|
||||
|
||||
if (
|
||||
!pendingQuery ||
|
||||
pendingQuery.channelName !== response.channelName ||
|
||||
pendingQuery.networkUuid !== response.networkUuid ||
|
||||
pendingQuery.offset !== response.offset ||
|
||||
pendingQuery.searchTerm !== response.searchTerm
|
||||
) {
|
||||
// This is a response from a search that we are not interested in.
|
||||
// The user may have entered a different search while one was still in flight.
|
||||
// We can simply drop it on the floor.
|
||||
return;
|
||||
}
|
||||
|
||||
store.commit("messageSearchPendingQuery", null);
|
||||
|
||||
if (store.state.messageSearchResults) {
|
||||
store.commit("addMessageSearchResults", response);
|
||||
return;
|
||||
}
|
||||
|
||||
store.commit("messageSearchResults", response);
|
||||
store.commit("messageSearchResults", {results: response.results});
|
||||
});
|
||||
|
@ -15,6 +15,7 @@ import type {
|
||||
import type {InjectionKey} from "vue";
|
||||
|
||||
import {SettingsState} from "./settings";
|
||||
import {SearchQuery} from "../../server/plugins/messageStorage/types";
|
||||
|
||||
const appName = document.title;
|
||||
|
||||
@ -85,7 +86,7 @@ export type State = {
|
||||
messageSearchResults: {
|
||||
results: ClientMessage[];
|
||||
} | null;
|
||||
messageSearchInProgress: boolean;
|
||||
messageSearchPendingQuery: SearchQuery | null;
|
||||
searchEnabled: boolean;
|
||||
};
|
||||
|
||||
@ -111,7 +112,7 @@ const state = () =>
|
||||
versionDataExpired: false,
|
||||
serverHasSettings: false,
|
||||
messageSearchResults: null,
|
||||
messageSearchInProgress: false,
|
||||
messageSearchPendingQuery: null,
|
||||
searchEnabled: false,
|
||||
} as State);
|
||||
|
||||
@ -260,7 +261,7 @@ type Mutations = {
|
||||
versionStatus(state: State, payload: State["versionStatus"]): void;
|
||||
versionDataExpired(state: State, payload: State["versionDataExpired"]): void;
|
||||
serverHasSettings(state: State, value: State["serverHasSettings"]): void;
|
||||
messageSearchInProgress(state: State, value: State["messageSearchInProgress"]): void;
|
||||
messageSearchPendingQuery(state: State, value: State["messageSearchPendingQuery"]): void;
|
||||
messageSearchResults(state: State, value: State["messageSearchResults"]): void;
|
||||
addMessageSearchResults(state: State, value: NonNullable<State["messageSearchResults"]>): void;
|
||||
};
|
||||
@ -338,8 +339,8 @@ const mutations: Mutations = {
|
||||
serverHasSettings(state, value) {
|
||||
state.serverHasSettings = value;
|
||||
},
|
||||
messageSearchInProgress(state, value) {
|
||||
state.messageSearchInProgress = value;
|
||||
messageSearchPendingQuery(state, value) {
|
||||
state.messageSearchPendingQuery = value;
|
||||
},
|
||||
messageSearchResults(state, value) {
|
||||
state.messageSearchResults = value;
|
||||
|
@ -17,7 +17,7 @@ import SqliteMessageStorage from "./plugins/messageStorage/sqlite";
|
||||
import TextFileMessageStorage from "./plugins/messageStorage/text";
|
||||
import Network, {IgnoreListItem, NetworkWithIrcFramework} from "./models/network";
|
||||
import ClientManager from "./clientManager";
|
||||
import {MessageStorage, SearchQuery} from "./plugins/messageStorage/types";
|
||||
import {MessageStorage, SearchQuery, SearchResponse} from "./plugins/messageStorage/types";
|
||||
|
||||
type OrderItem = Chan["id"] | Network["uuid"];
|
||||
type Order = OrderItem[];
|
||||
@ -618,15 +618,12 @@ class Client {
|
||||
}
|
||||
}
|
||||
|
||||
search(query: SearchQuery) {
|
||||
async search(query: SearchQuery): Promise<SearchResponse> {
|
||||
if (!this.messageProvider?.isEnabled) {
|
||||
return Promise.resolve({
|
||||
return {
|
||||
...query,
|
||||
results: [],
|
||||
target: "",
|
||||
networkUuid: "",
|
||||
offset: 0,
|
||||
searchTerm: query?.searchTerm,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
return this.messageProvider.search(query);
|
||||
|
@ -259,15 +259,10 @@ class SqliteMessageStorage implements ISqliteMessageStorage {
|
||||
params.push(query.offset);
|
||||
|
||||
const rows = await this.serialize_fetchall(select, ...params);
|
||||
const response: SearchResponse = {
|
||||
searchTerm: query.searchTerm,
|
||||
target: query.channelName,
|
||||
networkUuid: query.networkUuid,
|
||||
offset: query.offset,
|
||||
return {
|
||||
...query,
|
||||
results: parseSearchRowsToMessages(query.offset, rows).reverse(),
|
||||
};
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
canProvideMessages() {
|
||||
|
9
server/plugins/messageStorage/types.d.ts
vendored
9
server/plugins/messageStorage/types.d.ts
vendored
@ -29,12 +29,9 @@ export type SearchQuery = {
|
||||
offset: number;
|
||||
};
|
||||
|
||||
export type SearchResponse =
|
||||
| Omit<SearchQuery, "channelName" | "offset"> & {
|
||||
results: Message[];
|
||||
target: string;
|
||||
offset: number;
|
||||
};
|
||||
export type SearchResponse = SearchQuery & {
|
||||
results: Message[];
|
||||
};
|
||||
|
||||
type SearchFunction = (query: SearchQuery) => Promise<SearchResponse>;
|
||||
|
||||
|
@ -760,9 +760,8 @@ function initializeClient(
|
||||
});
|
||||
|
||||
socket.on("search", async (query) => {
|
||||
await client.search(query).then((results) => {
|
||||
socket.emit("search:results", results);
|
||||
});
|
||||
const results = await client.search(query);
|
||||
socket.emit("search:results", results);
|
||||
});
|
||||
|
||||
socket.on("mute:change", ({target, setMutedTo}) => {
|
||||
|
2
server/types/socket-events.d.ts
vendored
2
server/types/socket-events.d.ts
vendored
@ -107,7 +107,7 @@ interface ServerToClientEvents {
|
||||
token: string;
|
||||
}) => void;
|
||||
|
||||
"search:results": (response: {results: ClientMessage[]}) => void;
|
||||
"search:results": (response: SearchResponse) => void;
|
||||
|
||||
quit: (args: {network: string}) => void;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user