mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-27 02:33:48 +02:00
improve search tab
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
import { describe, expect, it, vi, beforeEach } from 'vitest';
|
||||
const mocks = vi.hoisted(() => ({
|
||||
avatarRemoteDatabase: require('vue').ref(true),
|
||||
searchText: require('vue').ref(''),
|
||||
lookupAvatars: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('pinia', () => ({
|
||||
storeToRefs: (store) => store
|
||||
}));
|
||||
|
||||
vi.mock('../../../../stores', () => ({
|
||||
useAdvancedSettingsStore: () => ({
|
||||
avatarRemoteDatabase: mocks.avatarRemoteDatabase
|
||||
}),
|
||||
useSearchStore: () => ({
|
||||
searchText: mocks.searchText
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('../../../../coordinators/avatarCoordinator', () => ({
|
||||
lookupAvatars: (...args) => mocks.lookupAvatars(...args)
|
||||
}));
|
||||
|
||||
import { useSearchAvatar } from '../useSearchAvatar';
|
||||
|
||||
describe('useSearchAvatar', () => {
|
||||
beforeEach(() => {
|
||||
mocks.avatarRemoteDatabase.value = true;
|
||||
mocks.searchText.value = '';
|
||||
mocks.lookupAvatars.mockReset();
|
||||
});
|
||||
|
||||
it('queries remote avatars and builds first page', async () => {
|
||||
mocks.searchText.value = 'alice';
|
||||
mocks.lookupAvatars.mockResolvedValue([
|
||||
{ id: 'avtr_1', name: 'A' },
|
||||
{ id: 'avtr_1', name: 'A-dup' },
|
||||
{ id: 'avtr_2', name: 'B' }
|
||||
]);
|
||||
|
||||
const api = useSearchAvatar();
|
||||
await api.searchAvatar();
|
||||
|
||||
expect(mocks.lookupAvatars).toHaveBeenCalledWith('search', 'alice');
|
||||
expect(api.searchAvatarResults.value.map((x) => x.id)).toEqual(['avtr_1', 'avtr_2']);
|
||||
expect(api.searchAvatarPage.value.map((x) => x.id)).toEqual(['avtr_1', 'avtr_2']);
|
||||
expect(api.searchAvatarPageNum.value).toBe(0);
|
||||
});
|
||||
|
||||
it('skips remote query when text is too short', async () => {
|
||||
mocks.searchText.value = 'ab';
|
||||
const api = useSearchAvatar();
|
||||
|
||||
await api.searchAvatar();
|
||||
|
||||
expect(mocks.lookupAvatars).not.toHaveBeenCalled();
|
||||
expect(api.searchAvatarResults.value).toEqual([]);
|
||||
});
|
||||
|
||||
it('paginates results by 10 items', () => {
|
||||
const api = useSearchAvatar();
|
||||
api.searchAvatarResults.value = Array.from({ length: 25 }, (_, i) => ({ id: `avtr_${i}` }));
|
||||
api.searchAvatarPage.value = api.searchAvatarResults.value.slice(0, 10);
|
||||
|
||||
api.moreSearchAvatar(1);
|
||||
expect(api.searchAvatarPageNum.value).toBe(1);
|
||||
expect(api.searchAvatarPage.value.map((x) => x.id)).toEqual(
|
||||
Array.from({ length: 10 }, (_, i) => `avtr_${i + 10}`)
|
||||
);
|
||||
|
||||
api.moreSearchAvatar(-1);
|
||||
expect(api.searchAvatarPageNum.value).toBe(0);
|
||||
expect(api.searchAvatarPage.value.map((x) => x.id)).toEqual(
|
||||
Array.from({ length: 10 }, (_, i) => `avtr_${i}`)
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
const mocks = vi.hoisted(() => ({
|
||||
searchText: require('vue').ref(''),
|
||||
replaceBioSymbols: vi.fn((text) => text),
|
||||
groupSearch: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('pinia', () => ({
|
||||
storeToRefs: (store) => store
|
||||
}));
|
||||
|
||||
vi.mock('../../../../stores', () => ({
|
||||
useSearchStore: () => ({
|
||||
searchText: mocks.searchText
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('../../../../shared/utils', () => ({
|
||||
replaceBioSymbols: (...args) => mocks.replaceBioSymbols(...args)
|
||||
}));
|
||||
|
||||
vi.mock('../../../../api', () => ({
|
||||
groupRequest: {
|
||||
groupSearch: (...args) => mocks.groupSearch(...args)
|
||||
}
|
||||
}));
|
||||
|
||||
import { useSearchGroup } from '../useSearchGroup';
|
||||
|
||||
describe('useSearchGroup', () => {
|
||||
beforeEach(() => {
|
||||
mocks.searchText.value = '';
|
||||
mocks.replaceBioSymbols.mockReset();
|
||||
mocks.replaceBioSymbols.mockImplementation((text) => text);
|
||||
mocks.groupSearch.mockReset();
|
||||
});
|
||||
|
||||
it('starts group search with normalized query', async () => {
|
||||
mocks.searchText.value = 'group+name';
|
||||
mocks.replaceBioSymbols.mockReturnValue('group name');
|
||||
mocks.groupSearch.mockResolvedValue({ json: [{ id: 'grp_1' }, { id: 'grp_1' }, { id: 'grp_2' }] });
|
||||
|
||||
const api = useSearchGroup();
|
||||
await api.searchGroup();
|
||||
|
||||
expect(mocks.replaceBioSymbols).toHaveBeenCalledWith('group+name');
|
||||
expect(mocks.groupSearch).toHaveBeenCalledWith({
|
||||
n: 10,
|
||||
offset: 0,
|
||||
query: 'group name'
|
||||
});
|
||||
expect(api.searchGroupResults.value.map((x) => x.id)).toEqual(['grp_1', 'grp_2']);
|
||||
});
|
||||
|
||||
it('moves backward paging offset without going below zero', async () => {
|
||||
mocks.groupSearch.mockResolvedValue({ json: [] });
|
||||
const api = useSearchGroup();
|
||||
api.searchGroupParams.value = { n: 10, offset: 5, query: 'abc' };
|
||||
|
||||
await api.moreSearchGroup(-1);
|
||||
|
||||
expect(mocks.groupSearch).toHaveBeenCalledWith({ n: 10, offset: 0, query: 'abc' });
|
||||
});
|
||||
});
|
||||
53
src/views/Search/composables/__tests__/useSearchUser.test.js
Normal file
53
src/views/Search/composables/__tests__/useSearchUser.test.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
const mocks = vi.hoisted(() => ({
|
||||
searchText: require('vue').ref(''),
|
||||
moreSearchUser: vi.fn(() => Promise.resolve())
|
||||
}));
|
||||
|
||||
vi.mock('pinia', () => ({
|
||||
storeToRefs: (store) => store
|
||||
}));
|
||||
|
||||
vi.mock('../../../../stores', () => ({
|
||||
useSearchStore: () => ({
|
||||
searchText: mocks.searchText,
|
||||
moreSearchUser: (...args) => mocks.moreSearchUser(...args)
|
||||
})
|
||||
}));
|
||||
|
||||
import { useSearchUser } from '../useSearchUser';
|
||||
|
||||
describe('useSearchUser', () => {
|
||||
beforeEach(() => {
|
||||
mocks.searchText.value = '';
|
||||
mocks.moreSearchUser.mockReset();
|
||||
mocks.moreSearchUser.mockResolvedValue(undefined);
|
||||
});
|
||||
|
||||
it('builds search params and requests first page', async () => {
|
||||
mocks.searchText.value = 'Alice';
|
||||
const api = useSearchUser();
|
||||
api.searchUserByBio.value = true;
|
||||
api.searchUserSortByLastLoggedIn.value = true;
|
||||
|
||||
await api.searchUser();
|
||||
|
||||
expect(mocks.moreSearchUser).toHaveBeenCalledWith(null, {
|
||||
n: 10,
|
||||
offset: 0,
|
||||
search: 'Alice',
|
||||
customFields: 'bio',
|
||||
sort: 'last_login'
|
||||
});
|
||||
expect(api.isSearchUserLoading.value).toBe(false);
|
||||
});
|
||||
|
||||
it('passes page direction into handleMoreSearchUser', async () => {
|
||||
const api = useSearchUser();
|
||||
api.searchUserParams.value = { n: 10, offset: 10, search: 'Alice', customFields: 'displayName', sort: 'relevance' };
|
||||
|
||||
await api.handleMoreSearchUser(-1);
|
||||
|
||||
expect(mocks.moreSearchUser).toHaveBeenCalledWith(-1, api.searchUserParams.value);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,97 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
const mocks = vi.hoisted(() => ({
|
||||
searchText: require('vue').ref(''),
|
||||
cachedConfig: require('vue').ref({ dynamicWorldRows: [] }),
|
||||
cachedWorlds: new Map(),
|
||||
replaceBioSymbols: vi.fn((text) => text),
|
||||
getWorlds: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('pinia', () => ({
|
||||
storeToRefs: (store) => store
|
||||
}));
|
||||
|
||||
vi.mock('../../../../stores', () => ({
|
||||
useSearchStore: () => ({
|
||||
searchText: mocks.searchText
|
||||
}),
|
||||
useAuthStore: () => ({
|
||||
cachedConfig: mocks.cachedConfig
|
||||
}),
|
||||
useWorldStore: () => ({
|
||||
cachedWorlds: mocks.cachedWorlds
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('../../../../shared/utils', () => ({
|
||||
replaceBioSymbols: (...args) => mocks.replaceBioSymbols(...args)
|
||||
}));
|
||||
|
||||
vi.mock('../../../../api', () => ({
|
||||
worldRequest: {
|
||||
getWorlds: (...args) => mocks.getWorlds(...args)
|
||||
}
|
||||
}));
|
||||
|
||||
import { useSearchWorld } from '../useSearchWorld';
|
||||
|
||||
describe('useSearchWorld', () => {
|
||||
beforeEach(() => {
|
||||
mocks.searchText.value = '';
|
||||
mocks.cachedConfig.value = { dynamicWorldRows: [] };
|
||||
mocks.cachedWorlds.clear();
|
||||
mocks.replaceBioSymbols.mockReset();
|
||||
mocks.replaceBioSymbols.mockImplementation((text) => text);
|
||||
mocks.getWorlds.mockReset();
|
||||
});
|
||||
|
||||
it('creates relevance params and appends system_approved tag', async () => {
|
||||
mocks.searchText.value = 'home world';
|
||||
mocks.replaceBioSymbols.mockReturnValue('home world');
|
||||
mocks.cachedWorlds.set('wrld_1', { id: 'wrld_1', name: 'World One' });
|
||||
mocks.getWorlds.mockResolvedValue({ json: [{ id: 'wrld_1' }, { id: 'wrld_missing' }] });
|
||||
|
||||
const api = useSearchWorld();
|
||||
api.searchWorld({});
|
||||
await Promise.resolve();
|
||||
await Promise.resolve();
|
||||
|
||||
expect(mocks.getWorlds).toHaveBeenCalledWith(
|
||||
{
|
||||
n: 10,
|
||||
offset: 0,
|
||||
sort: 'relevance',
|
||||
search: 'home world',
|
||||
order: 'descending',
|
||||
tag: 'system_approved'
|
||||
},
|
||||
''
|
||||
);
|
||||
expect(api.searchWorldParams.value.search).toBe('home world');
|
||||
});
|
||||
|
||||
it('selects category row and uses row sort settings', async () => {
|
||||
mocks.cachedConfig.value = {
|
||||
dynamicWorldRows: [{ index: 2, sortHeading: 'featured', sortOrder: 'ascending', tag: 'party' }]
|
||||
};
|
||||
mocks.getWorlds.mockResolvedValue({ json: [] });
|
||||
|
||||
const api = useSearchWorld();
|
||||
api.handleSearchWorldCategorySelect(2);
|
||||
await Promise.resolve();
|
||||
await Promise.resolve();
|
||||
|
||||
expect(api.searchWorldCategoryIndex.value).toBe(2);
|
||||
expect(mocks.getWorlds).toHaveBeenCalledWith(
|
||||
{
|
||||
n: 10,
|
||||
offset: 0,
|
||||
sort: 'order',
|
||||
featured: 'true',
|
||||
order: 'ascending',
|
||||
tag: 'party,system_approved'
|
||||
},
|
||||
''
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,29 +1,17 @@
|
||||
import { ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
import {
|
||||
compareByCreatedAt,
|
||||
compareByName,
|
||||
compareByUpdatedAt
|
||||
} from '../../../shared/utils';
|
||||
import {
|
||||
useAdvancedSettingsStore,
|
||||
useAvatarStore,
|
||||
useSearchStore
|
||||
} from '../../../stores';
|
||||
import { useAdvancedSettingsStore, useSearchStore } from '../../../stores';
|
||||
import { lookupAvatars } from '../../../coordinators/avatarCoordinator';
|
||||
|
||||
/**
|
||||
* Avatar search composable for Search view.
|
||||
* Manages avatar search state, local/remote filtering, sorting, and pagination.
|
||||
* Searches remote avatar databases only (local avatar browsing is handled by My Avatars page).
|
||||
*/
|
||||
export function useSearchAvatar() {
|
||||
const { avatarRemoteDatabase } = storeToRefs(useAdvancedSettingsStore());
|
||||
const { lookupAvatars, cachedAvatars } = useAvatarStore();
|
||||
const { searchText } = storeToRefs(useSearchStore());
|
||||
|
||||
const searchAvatarFilter = ref('');
|
||||
const searchAvatarSort = ref('');
|
||||
const searchAvatarFilterRemote = ref('');
|
||||
const searchAvatarPageNum = ref(0);
|
||||
const searchAvatarResults = ref([]);
|
||||
const searchAvatarPage = ref([]);
|
||||
@@ -33,111 +21,26 @@ export function useSearchAvatar() {
|
||||
*
|
||||
*/
|
||||
async function searchAvatar() {
|
||||
let ref;
|
||||
isSearchAvatarLoading.value = true;
|
||||
if (!searchAvatarFilter.value) {
|
||||
searchAvatarFilter.value = 'all';
|
||||
}
|
||||
if (!searchAvatarSort.value) {
|
||||
searchAvatarSort.value = 'name';
|
||||
}
|
||||
if (!searchAvatarFilterRemote.value) {
|
||||
searchAvatarFilterRemote.value = 'all';
|
||||
}
|
||||
if (searchAvatarFilterRemote.value !== 'local') {
|
||||
searchAvatarSort.value = 'name';
|
||||
}
|
||||
const avatars = new Map();
|
||||
const query = searchText.value;
|
||||
const queryUpper = query.toUpperCase();
|
||||
if (!query) {
|
||||
for (ref of cachedAvatars.values()) {
|
||||
switch (searchAvatarFilter.value) {
|
||||
case 'all':
|
||||
avatars.set(ref.id, ref);
|
||||
break;
|
||||
case 'public':
|
||||
if (ref.releaseStatus === 'public') {
|
||||
avatars.set(ref.id, ref);
|
||||
}
|
||||
break;
|
||||
case 'private':
|
||||
if (ref.releaseStatus === 'private') {
|
||||
avatars.set(ref.id, ref);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (query && query.length >= 3 && avatarRemoteDatabase.value) {
|
||||
const data = await lookupAvatars('search', query);
|
||||
if (data && typeof data === 'object') {
|
||||
data.forEach((avatar) => {
|
||||
avatars.set(avatar.id, avatar);
|
||||
});
|
||||
}
|
||||
isSearchAvatarLoading.value = false;
|
||||
} else {
|
||||
if (
|
||||
searchAvatarFilterRemote.value === 'all' ||
|
||||
searchAvatarFilterRemote.value === 'local'
|
||||
) {
|
||||
for (ref of cachedAvatars.values()) {
|
||||
let match = ref.name.toUpperCase().includes(queryUpper);
|
||||
if (!match && ref.description) {
|
||||
match = ref.description
|
||||
.toUpperCase()
|
||||
.includes(queryUpper);
|
||||
}
|
||||
if (!match && ref.authorName) {
|
||||
match = ref.authorName
|
||||
.toUpperCase()
|
||||
.includes(queryUpper);
|
||||
}
|
||||
if (match) {
|
||||
switch (searchAvatarFilter.value) {
|
||||
case 'all':
|
||||
avatars.set(ref.id, ref);
|
||||
break;
|
||||
case 'public':
|
||||
if (ref.releaseStatus === 'public') {
|
||||
avatars.set(ref.id, ref);
|
||||
}
|
||||
break;
|
||||
case 'private':
|
||||
if (ref.releaseStatus === 'private') {
|
||||
avatars.set(ref.id, ref);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (
|
||||
(searchAvatarFilterRemote.value === 'all' ||
|
||||
searchAvatarFilterRemote.value === 'remote') &&
|
||||
avatarRemoteDatabase.value &&
|
||||
query.length >= 3
|
||||
) {
|
||||
const data = await lookupAvatars('search', query);
|
||||
if (data && typeof data === 'object') {
|
||||
data.forEach((avatar) => {
|
||||
avatars.set(avatar.id, avatar);
|
||||
});
|
||||
}
|
||||
}
|
||||
isSearchAvatarLoading.value = false;
|
||||
}
|
||||
|
||||
isSearchAvatarLoading.value = false;
|
||||
const avatarsArray = Array.from(avatars.values());
|
||||
if (searchAvatarFilterRemote.value === 'local') {
|
||||
switch (searchAvatarSort.value) {
|
||||
case 'updated':
|
||||
avatarsArray.sort(compareByUpdatedAt);
|
||||
break;
|
||||
case 'created':
|
||||
avatarsArray.sort(compareByCreatedAt);
|
||||
break;
|
||||
case 'name':
|
||||
avatarsArray.sort(compareByName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
searchAvatarPageNum.value = 0;
|
||||
searchAvatarResults.value = avatarsArray;
|
||||
searchAvatarPage.value = avatarsArray.slice(0, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param n
|
||||
@@ -158,33 +61,6 @@ export function useSearchAvatar() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
function handleSearchAvatarFilterChange(value) {
|
||||
searchAvatarFilter.value = value;
|
||||
searchAvatar();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
function handleSearchAvatarFilterRemoteChange(value) {
|
||||
searchAvatarFilterRemote.value = value;
|
||||
searchAvatar();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
function handleSearchAvatarSortChange(value) {
|
||||
searchAvatarSort.value = value;
|
||||
searchAvatar();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -195,18 +71,12 @@ export function useSearchAvatar() {
|
||||
}
|
||||
|
||||
return {
|
||||
searchAvatarFilter,
|
||||
searchAvatarSort,
|
||||
searchAvatarFilterRemote,
|
||||
searchAvatarPageNum,
|
||||
searchAvatarResults,
|
||||
searchAvatarPage,
|
||||
isSearchAvatarLoading,
|
||||
searchAvatar,
|
||||
moreSearchAvatar,
|
||||
handleSearchAvatarFilterChange,
|
||||
handleSearchAvatarFilterRemoteChange,
|
||||
handleSearchAvatarSortChange,
|
||||
clearAvatarSearch
|
||||
};
|
||||
}
|
||||
|
||||
75
src/views/Search/composables/useSearchGroup.js
Normal file
75
src/views/Search/composables/useSearchGroup.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import { ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
import { useSearchStore } from '../../../stores';
|
||||
import { replaceBioSymbols } from '../../../shared/utils';
|
||||
import { groupRequest } from '../../../api';
|
||||
|
||||
/**
|
||||
* Group search composable for Search view.
|
||||
* Manages group search state and pagination.
|
||||
*/
|
||||
export function useSearchGroup() {
|
||||
const { searchText } = storeToRefs(useSearchStore());
|
||||
|
||||
const searchGroupParams = ref({});
|
||||
const searchGroupResults = ref([]);
|
||||
const isSearchGroupLoading = ref(false);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function searchGroup() {
|
||||
searchGroupParams.value = {
|
||||
n: 10,
|
||||
offset: 0,
|
||||
query: replaceBioSymbols(searchText.value)
|
||||
};
|
||||
await moreSearchGroup();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param go
|
||||
*/
|
||||
async function moreSearchGroup(go) {
|
||||
const params = searchGroupParams.value;
|
||||
if (go) {
|
||||
params.offset += params.n * go;
|
||||
if (params.offset < 0) {
|
||||
params.offset = 0;
|
||||
}
|
||||
}
|
||||
isSearchGroupLoading.value = true;
|
||||
await groupRequest
|
||||
.groupSearch(params)
|
||||
.finally(() => {
|
||||
isSearchGroupLoading.value = false;
|
||||
})
|
||||
.then((args) => {
|
||||
const map = new Map();
|
||||
for (const json of args.json) {
|
||||
map.set(json.id, json);
|
||||
}
|
||||
searchGroupResults.value = Array.from(map.values());
|
||||
return args;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function clearGroupSearch() {
|
||||
searchGroupParams.value = {};
|
||||
searchGroupResults.value = [];
|
||||
}
|
||||
|
||||
return {
|
||||
searchGroupParams,
|
||||
searchGroupResults,
|
||||
isSearchGroupLoading,
|
||||
searchGroup,
|
||||
moreSearchGroup,
|
||||
clearGroupSearch
|
||||
};
|
||||
}
|
||||
61
src/views/Search/composables/useSearchUser.js
Normal file
61
src/views/Search/composables/useSearchUser.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import { ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
import { useSearchStore } from '../../../stores';
|
||||
|
||||
/**
|
||||
* User search composable for Search view.
|
||||
* Manages user search state, filters, and pagination.
|
||||
*/
|
||||
export function useSearchUser() {
|
||||
const { searchText } = storeToRefs(useSearchStore());
|
||||
const { moreSearchUser } = useSearchStore();
|
||||
|
||||
const searchUserParams = ref({});
|
||||
const searchUserByBio = ref(false);
|
||||
const searchUserSortByLastLoggedIn = ref(false);
|
||||
const isSearchUserLoading = ref(false);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function searchUser() {
|
||||
searchUserParams.value = {
|
||||
n: 10,
|
||||
offset: 0,
|
||||
search: searchText.value,
|
||||
customFields: searchUserByBio.value ? 'bio' : 'displayName',
|
||||
sort: searchUserSortByLastLoggedIn.value
|
||||
? 'last_login'
|
||||
: 'relevance'
|
||||
};
|
||||
await handleMoreSearchUser();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param go
|
||||
*/
|
||||
async function handleMoreSearchUser(go = null) {
|
||||
isSearchUserLoading.value = true;
|
||||
await moreSearchUser(go, searchUserParams.value);
|
||||
isSearchUserLoading.value = false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function clearUserSearch() {
|
||||
searchUserParams.value = {};
|
||||
}
|
||||
|
||||
return {
|
||||
searchUserParams,
|
||||
searchUserByBio,
|
||||
searchUserSortByLastLoggedIn,
|
||||
isSearchUserLoading,
|
||||
searchUser,
|
||||
handleMoreSearchUser,
|
||||
clearUserSearch
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user