diff --git a/backend/build.gradle b/backend/build.gradle index a4dc69c..004675c 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -28,7 +28,7 @@ configurations { } dependencies { - implementation("me.shedaniel:linkie-core:1.0.101") + implementation("me.shedaniel:linkie-core:1.0.102") implementation("io.ktor:ktor-server-cors:2.0.1") implementation("io.ktor:ktor-server-content-negotiation:2.0.1") implementation("io.ktor:ktor-server-status-pages:2.0.1") diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 713283b..524e42a 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -100,4 +100,9 @@ export default defineComponent({ body { @apply bg-base-200 } + +.select { + outline: 0 !important; + border: 0 !important; +} diff --git a/frontend/src/app/backend.ts b/frontend/src/app/backend.ts index 8380e09..f2041a4 100644 --- a/frontend/src/app/backend.ts +++ b/frontend/src/app/backend.ts @@ -16,8 +16,10 @@ export function reqNamespaces(): Promise> { return HTTP.get(`/api/namespaces`) } -export function reqSearch(namespace: string, version: string, query: string, allowClasses: boolean, allowFields: boolean, allowMethods: boolean, limit: number = 50): Promise> { +export function reqSearch(namespace: string, version: string, query: string, allowClasses: boolean, allowFields: boolean, allowMethods: boolean, + abortController?: AbortController, limit: number = 50): Promise> { return HTTP.get(`/api/search`, { + signal: abortController?.signal, params: { namespace, query, diff --git a/frontend/src/components/mappings/MappingsSearchBlock.vue b/frontend/src/components/mappings/MappingsSearchBlock.vue index 3145e3e..eeb5c5d 100644 --- a/frontend/src/components/mappings/MappingsSearchBlock.vue +++ b/frontend/src/components/mappings/MappingsSearchBlock.vue @@ -39,7 +39,7 @@ export default defineComponent({ this.timer = setTimeout(() => { useMappingsStore().searchText = (event.target as any)?.value - }, 1000) + }, 300) }, }, }) @@ -48,5 +48,6 @@ export default defineComponent({ \ No newline at end of file diff --git a/frontend/src/main.ts b/frontend/src/main.ts index a68378c..32c1d7e 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -30,7 +30,9 @@ HTTP.interceptors.response.use(response => { NProgress.done() return response }, error => { - console.log(error) + if (!axios.isCancel(error)) { + console.log(error) + } return Promise.reject(error) }) diff --git a/frontend/src/routes/Dependencies.vue b/frontend/src/routes/Dependencies.vue index 7a4524a..a69d756 100644 --- a/frontend/src/routes/Dependencies.vue +++ b/frontend/src/routes/Dependencies.vue @@ -98,6 +98,7 @@ export default defineComponent({ formatMaven, formatDependency, tab, + reqVersionsPromise: undefined as Promise | undefined, } }, computed: { @@ -136,8 +137,8 @@ export default defineComponent({ }, methods: { updateDependencyData() { - if (Object.keys(this.searchData.versions).length == 0) { - reqVersions().then(value => { + if (Object.keys(this.searchData.versions).length == 0 && !this.reqVersionsPromise) { + this.reqVersionsPromise = reqVersions().then(value => { this.searchData.versions = value.data this.ensureDependencyData() }).catch(reason => { @@ -145,6 +146,8 @@ export default defineComponent({ type: "error", message: `Failed to fetch versions: ${reason.message}`, }) + }).finally(() => { + this.reqVersionsPromise = undefined }) } }, diff --git a/frontend/src/routes/Mappings.vue b/frontend/src/routes/Mappings.vue index 8540d2e..91d8d3a 100644 --- a/frontend/src/routes/Mappings.vue +++ b/frontend/src/routes/Mappings.vue @@ -23,6 +23,7 @@ import MappingsSearchBlock from "../components/mappings/MappingsSearchBlock.vue" import MappingsEntryBlock from "../components/mappings/MappingsEntryBlock.vue" import MappingsFilterBlock from "../components/mappings/MappingsFilterBlock.vue" import {VersionEntry} from "./Dependencies.vue" +import axios from "axios" export interface Namespace { id: string, @@ -78,6 +79,8 @@ export default defineComponent({ entries: [], fuzzy: false, } as InfoData, + reqNamespacesPromise: undefined as Promise | undefined, + searchController: undefined as AbortController | undefined, } }, computed: { @@ -137,8 +140,8 @@ export default defineComponent({ }, methods: { updateMappingsData() { - if (Object.keys(this.mappingsData.namespaces).length == 0) { - reqNamespaces().then(value => { + if (Object.keys(this.mappingsData.namespaces).length == 0 && !this.reqNamespacesPromise) { + this.reqNamespacesPromise = reqNamespaces().then(value => { this.mappingsData.namespaces = value.data this.ensureMappingsData() }).catch(reason => { @@ -146,6 +149,8 @@ export default defineComponent({ type: "error", message: `Failed to fetch namespaces: ${reason.message}`, }) + }).finally(() => { + this.reqNamespacesPromise = undefined }) } }, @@ -172,7 +177,11 @@ export default defineComponent({ if (namespace && version && searchText && (allowClasses || allowMethods || allowFields)) { if (this.infoData.namespace !== namespace || this.infoData.version !== version || this.infoData.query !== searchText || this.infoData.allowClasses !== allowClasses || this.infoData.allowFields !== allowFields || this.infoData.allowMethods !== allowMethods) { - reqSearch(namespace, version, searchText, allowClasses, allowFields, allowMethods).then(value => { + if (this.searchController) { + this.searchController.abort() + } + this.searchController = new AbortController() + reqSearch(namespace, version, searchText, allowClasses, allowFields, allowMethods, this.searchController).then(value => { if (value.data.error) { if (value.data.error !== "No results found!") { addAlert({ @@ -185,38 +194,26 @@ export default defineComponent({ return } this.infoData.fuzzy = value.data.fuzzy - this.infoData.entries = (value.data.entries as any[]).map(obj => { - let type: string - if (obj.t === "c") type = "class" - else if (obj.t === "f") type = "field" - else if (obj.t === "m") type = "method" - else type = obj.t - return { - obf: obj.o, - intermediary: obj.i, - named: obj.n, - descObf: obj.d, - descIntermediary: obj.e, - descNamed: obj.f, - ownerObf: obj.a, - ownerIntermediary: obj.b, - ownerNamed: obj.c, - type, - } as MappingEntry - }) + this.infoData.entries = this.mapEntriesToMappingEntry(value.data.entries as any[]) }).catch(reason => { - addAlert({ - type: "error", - message: `Failed to search: ${reason.message}`, - }) - this.infoData.entries = [] - this.infoData.fuzzy = false + if (!axios.isCancel(reason)) { + addAlert({ + type: "error", + message: `Failed to search: ${reason.message}`, + }) + this.infoData.entries = [] + this.infoData.fuzzy = false + } }) } } else { this.infoData.entries = [] this.infoData.fuzzy = false } + this.setInfoDataToCurrent() + }, + setInfoDataToCurrent() { + let {namespace, version, searchText, allowClasses, allowFields, allowMethods} = useMappingsStore() this.infoData.namespace = namespace this.infoData.version = version this.infoData.query = searchText @@ -224,6 +221,27 @@ export default defineComponent({ this.infoData.allowMethods = allowMethods this.infoData.allowFields = allowFields }, + mapEntriesToMappingEntry(entries: any[]) { + return entries.map(obj => { + let type: string + if (obj.t === "c") type = "class" + else if (obj.t === "f") type = "field" + else if (obj.t === "m") type = "method" + else type = obj.t + return { + obf: obj.o, + intermediary: obj.i, + named: obj.n, + descObf: obj.d, + descIntermediary: obj.e, + descNamed: obj.f, + ownerObf: obj.a, + ownerIntermediary: obj.b, + ownerNamed: obj.c, + type, + } as MappingEntry + }) + }, }, })