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