diff --git a/src/components/DataTable.vue b/src/components/DataTable.vue index 4c372289..13ea46c7 100644 --- a/src/components/DataTable.vue +++ b/src/components/DataTable.vue @@ -17,7 +17,7 @@ ({ layout: 'sizes, prev, pager, next, total', - pageSizes: [10, 15, 20, 25, 50, 100], - ...paginationProps.value + ...paginationProps.value, + pageSizes: paginationProps.value?.pageSizes ?? appearanceSettingsStore.tablePageSizes })); + const effectivePageSize = computed(() => { + return props.pageSizeLinked ? appearanceSettingsStore.tablePageSize : internalPageSize.value; + }); + const applyFilter = function (row, filter) { if (Array.isArray(filter.prop)) { return filter.prop.some((propItem) => applyFilter(row, { prop: propItem, value: filter.value })); @@ -175,8 +179,8 @@ return filteredData.value; } - const start = (internalCurrentPage.value - 1) * internalPageSize.value; - const end = start + internalPageSize.value; + const start = (internalCurrentPage.value - 1) * effectivePageSize.value; + const end = start + effectivePageSize.value; return filteredData.value.slice(start, end); }); @@ -202,6 +206,7 @@ const handleSizeChange = (size) => { if (props.pageSizeLinked) { appearanceSettingsStore.setTablePageSize(size); + return; } internalPageSize.value = size; }; @@ -234,6 +239,7 @@ return { internalCurrentPage, internalPageSize, + effectivePageSize, showPagination, mergedTableProps, mergedPaginationProps, diff --git a/src/components/dialogs/GroupDialog/GroupMemberModerationDialog.vue b/src/components/dialogs/GroupDialog/GroupMemberModerationDialog.vue index 1eb9a946..e712a44b 100644 --- a/src/components/dialogs/GroupDialog/GroupMemberModerationDialog.vue +++ b/src/components/dialogs/GroupDialog/GroupMemberModerationDialog.vue @@ -31,8 +31,8 @@ :disabled=" Boolean( isGroupMembersLoading || - memberSearch.length || - !hasGroupPermission(groupMemberModeration.groupRef, 'group-bans-manage') + memberSearch.length || + !hasGroupPermission(groupMemberModeration.groupRef, 'group-bans-manage') ) "> @@ -60,8 +60,8 @@ :disabled=" Boolean( isGroupMembersLoading || - memberSearch.length || - !hasGroupPermission(groupMemberModeration.groupRef, 'group-bans-manage') + memberSearch.length || + !hasGroupPermission(groupMemberModeration.groupRef, 'group-bans-manage') ) "> @@ -398,10 +398,7 @@ :disabled=" Boolean( progressCurrent || - !hasGroupPermission( - groupMemberModeration.groupRef, - 'group-invites-manage' - ) + !hasGroupPermission(groupMemberModeration.groupRef, 'group-invites-manage') ) " @click="groupMembersDeleteSentInvite" @@ -483,10 +480,7 @@ :disabled=" Boolean( progressCurrent || - !hasGroupPermission( - groupMemberModeration.groupRef, - 'group-invites-manage' - ) + !hasGroupPermission(groupMemberModeration.groupRef, 'group-invites-manage') ) " @click="groupMembersAcceptInviteRequest" @@ -496,10 +490,7 @@ :disabled=" Boolean( progressCurrent || - !hasGroupPermission( - groupMemberModeration.groupRef, - 'group-invites-manage' - ) + !hasGroupPermission(groupMemberModeration.groupRef, 'group-invites-manage') ) " @click="groupMembersRejectInviteRequest" @@ -509,10 +500,7 @@ :disabled=" Boolean( progressCurrent || - !hasGroupPermission( - groupMemberModeration.groupRef, - 'group-invites-manage' - ) + !hasGroupPermission(groupMemberModeration.groupRef, 'group-invites-manage') ) " @click="groupMembersBlockJoinRequest" @@ -594,10 +582,7 @@ :disabled=" Boolean( progressCurrent || - !hasGroupPermission( - groupMemberModeration.groupRef, - 'group-invites-manage' - ) + !hasGroupPermission(groupMemberModeration.groupRef, 'group-invites-manage') ) " @click="groupMembersDeleteBlockedRequest" @@ -800,8 +785,8 @@ :disabled=" Boolean( !selectedRoles.length || - progressCurrent || - !hasGroupPermission(groupMemberModeration.groupRef, 'group-roles-assign') + progressCurrent || + !hasGroupPermission(groupMemberModeration.groupRef, 'group-roles-assign') ) " @click="groupMembersAddRoles" @@ -811,8 +796,8 @@ :disabled=" Boolean( !selectedRoles.length || - progressCurrent || - !hasGroupPermission(groupMemberModeration.groupRef, 'group-roles-assign') + progressCurrent || + !hasGroupPermission(groupMemberModeration.groupRef, 'group-roles-assign') ) " @click="groupMembersRemoveRoles" @@ -947,8 +932,7 @@ tableProps: { stripe: true, size: 'small' }, pageSize: 15, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 15, 20, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' } }); const groupJoinRequestsModerationTable = reactive({ @@ -956,8 +940,7 @@ tableProps: { stripe: true, size: 'small' }, pageSize: 15, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 15, 20, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' } }); const groupBlockedModerationTable = reactive({ @@ -966,8 +949,7 @@ pageSize: 15, paginationProps: { small: true, - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 15, 20, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' } }); const groupLogsModerationTable = reactive({ @@ -976,8 +958,7 @@ tableProps: { stripe: true, size: 'small' }, pageSize: 15, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 15, 20, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' } }); const groupBansModerationTable = reactive({ @@ -986,8 +967,7 @@ tableProps: { stripe: true, size: 'small' }, pageSize: 15, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 15, 20, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' } }); const groupMemberModerationTable = reactive({ @@ -995,8 +975,7 @@ tableProps: { stripe: true, size: 'small' }, pageSize: 15, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 15, 20, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' } }); diff --git a/src/components/dialogs/PreviousInstancesDialog/PreviousInstancesGroupDialog.vue b/src/components/dialogs/PreviousInstancesDialog/PreviousInstancesGroupDialog.vue index af537539..79c0be5f 100644 --- a/src/components/dialogs/PreviousInstancesDialog/PreviousInstancesGroupDialog.vue +++ b/src/components/dialogs/PreviousInstancesDialog/PreviousInstancesGroupDialog.vue @@ -94,7 +94,7 @@ defaultSort: { prop: 'created_at', order: 'descending' } }, pageSize: 10, - paginationProps: { layout: 'sizes,prev,pager,next,total', pageSizes: [10, 25, 50, 100] } + paginationProps: { layout: 'sizes,prev,pager,next,total' } }); const props = defineProps({ diff --git a/src/components/dialogs/PreviousInstancesDialog/PreviousInstancesInfoDialog.vue b/src/components/dialogs/PreviousInstancesDialog/PreviousInstancesInfoDialog.vue index 4662471b..092044b2 100644 --- a/src/components/dialogs/PreviousInstancesDialog/PreviousInstancesInfoDialog.vue +++ b/src/components/dialogs/PreviousInstancesDialog/PreviousInstancesInfoDialog.vue @@ -118,8 +118,7 @@ }, pageSize: 10, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' } }); const fullscreen = ref(false); diff --git a/src/components/dialogs/PreviousInstancesDialog/PreviousInstancesWorldDialog.vue b/src/components/dialogs/PreviousInstancesDialog/PreviousInstancesWorldDialog.vue index c5aabacc..368c29a0 100644 --- a/src/components/dialogs/PreviousInstancesDialog/PreviousInstancesWorldDialog.vue +++ b/src/components/dialogs/PreviousInstancesDialog/PreviousInstancesWorldDialog.vue @@ -110,8 +110,7 @@ }, pageSize: 10, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' } }); const loading = ref(false); diff --git a/src/components/dialogs/UserDialog/PreviousInstancesUserDialog.vue b/src/components/dialogs/UserDialog/PreviousInstancesUserDialog.vue index 594a6567..81d8f4b7 100644 --- a/src/components/dialogs/UserDialog/PreviousInstancesUserDialog.vue +++ b/src/components/dialogs/UserDialog/PreviousInstancesUserDialog.vue @@ -119,8 +119,7 @@ }, pageSize: 10, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' } }); diff --git a/src/localization/en.json b/src/localization/en.json index ba0361af..78c0623d 100644 --- a/src/localization/en.json +++ b/src/localization/en.json @@ -557,6 +557,8 @@ "sort_instance_users_by_time": "time", "sort_instance_users_by_alphabet": "alphabetical", "table_max_size": "Table Max Size", + "table_page_sizes": "Table Page Sizes", + "table_page_sizes_error": "Page size must be a number between 1 and 1000", "show_notification_icon_dot": "Show Tray Notification Dot" }, "timedate": { diff --git a/src/stores/feed.js b/src/stores/feed.js index 604c259d..28142c77 100644 --- a/src/stores/feed.js +++ b/src/stores/feed.js @@ -36,8 +36,7 @@ export const useFeedStore = defineStore('Feed', () => { pageSize: 20, pageSizeLinked: true, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 15, 20, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' } }); diff --git a/src/stores/friend.js b/src/stores/friend.js index d42f3c93..e78302b4 100644 --- a/src/stores/friend.js +++ b/src/stores/friend.js @@ -98,8 +98,7 @@ export const useFriendStore = defineStore('Friend', () => { pageSize: 20, pageSizeLinked: true, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 15, 20, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' } }); diff --git a/src/stores/gameLog.js b/src/stores/gameLog.js index 42d2de83..22be3f11 100644 --- a/src/stores/gameLog.js +++ b/src/stores/gameLog.js @@ -75,8 +75,7 @@ export const useGameLogStore = defineStore('GameLog', () => { pageSize: 20, pageSizeLinked: true, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 15, 20, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' }, vip: false }); diff --git a/src/stores/moderation.js b/src/stores/moderation.js index 728c5349..7d121db6 100644 --- a/src/stores/moderation.js +++ b/src/stores/moderation.js @@ -37,8 +37,7 @@ export const useModerationStore = defineStore('Moderation', () => { pageSize: 20, pageSizeLinked: true, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 15, 20, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' } }); diff --git a/src/stores/notification.js b/src/stores/notification.js index 93d5c44a..c2b5d2b6 100644 --- a/src/stores/notification.js +++ b/src/stores/notification.js @@ -77,8 +77,7 @@ export const useNotificationStore = defineStore('Notification', () => { pageSize: 20, pageSizeLinked: true, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [10, 15, 20, 25, 50, 100] + layout: 'sizes,prev,pager,next,total' } }); const unseenNotifications = ref([]); diff --git a/src/stores/photon.js b/src/stores/photon.js index 764df1f1..e38c6620 100644 --- a/src/stores/photon.js +++ b/src/stores/photon.js @@ -107,8 +107,7 @@ export const usePhotonStore = defineStore('Photon', () => { }, pageSize: 10, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [5, 10, 15, 25, 50] + layout: 'sizes,prev,pager,next,total' } }); const photonEventTablePrevious = ref({ @@ -129,8 +128,7 @@ export const usePhotonStore = defineStore('Photon', () => { }, pageSize: 10, paginationProps: { - layout: 'sizes,prev,pager,next,total', - pageSizes: [5, 10, 15, 25, 50] + layout: 'sizes,prev,pager,next,total' } }); const chatboxUserBlacklist = ref(new Map()); diff --git a/src/stores/settings/appearance.js b/src/stores/settings/appearance.js index 29f056d8..1d8b001e 100644 --- a/src/stores/settings/appearance.js +++ b/src/stores/settings/appearance.js @@ -15,10 +15,7 @@ import { import { database } from '../../service/database'; import { getNameColour } from '../../shared/utils'; import { useFeedStore } from '../feed'; -import { useFriendStore } from '../friend'; import { useGameLogStore } from '../gameLog'; -import { useModerationStore } from '../moderation'; -import { useNotificationStore } from '../notification'; import { useUiStore } from '../ui'; import { useUserStore } from '../user'; import { useVrStore } from '../vr'; @@ -31,11 +28,8 @@ export const useAppearanceSettingsStore = defineStore( 'AppearanceSettings', () => { - const friendStore = useFriendStore(); const vrStore = useVrStore(); - const notificationStore = useNotificationStore(); const feedStore = useFeedStore(); - const moderationStore = useModerationStore(); const gameLogStore = useGameLogStore(); const vrcxStore = useVrcxStore(); const userStore = useUserStore(); @@ -44,6 +38,9 @@ export const useAppearanceSettingsStore = defineStore( const { t, availableLocales, locale } = useI18n(); + const MAX_TABLE_PAGE_SIZE = 1000; + const DEFAULT_TABLE_PAGE_SIZES = [10, 15, 20, 25, 50, 100]; + const appLanguage = ref('en'); const themeMode = ref(''); const isDarkMode = ref(false); @@ -53,6 +50,7 @@ export const useAppearanceSettingsStore = defineStore( const sortFavorites = ref(true); const instanceUsersSortAlphabetical = ref(false); const tablePageSize = ref(15); + const tablePageSizes = ref([...DEFAULT_TABLE_PAGE_SIZES]); const dtHour12 = ref(false); const dtIsoFormat = ref(false); const sidebarSortMethod1 = ref('Sort Private to Bottom'); @@ -91,6 +89,11 @@ export const useAppearanceSettingsStore = defineStore( ); }); + const clampInt = (value, min, max) => { + const n = parseInt(value, 10); + return Math.min(max, Math.max(min, n)); + }; + async function initAppearanceSettings() { const [ appLanguageConfig, @@ -101,6 +104,7 @@ export const useAppearanceSettingsStore = defineStore( sortFavoritesConfig, instanceUsersSortAlphabeticalConfig, tablePageSizeConfig, + tablePageSizesConfig, dtHour12Config, dtIsoFormatConfig, sidebarSortMethodsConfig, @@ -129,6 +133,10 @@ export const useAppearanceSettingsStore = defineStore( false ), configRepository.getInt('VRCX_tablePageSize', 20), + configRepository.getString( + 'VRCX_tablePageSizes', + JSON.stringify(DEFAULT_TABLE_PAGE_SIZES) + ), configRepository.getBool('VRCX_dtHour12', false), configRepository.getBool('VRCX_dtIsoFormat', false), configRepository.getString( @@ -193,6 +201,10 @@ export const useAppearanceSettingsStore = defineStore( instanceUsersSortAlphabetical.value = instanceUsersSortAlphabeticalConfig; + tablePageSizes.value = normalizeTablePageSizes( + JSON.parse(tablePageSizesConfig) + ); + setTablePageSize(tablePageSizeConfig); dtHour12.value = dtHour12Config; @@ -462,18 +474,42 @@ export const useAppearanceSettingsStore = defineStore( instanceUsersSortAlphabetical.value ); } - /** - * @param {number} size - */ - function setTablePageSize(size) { - feedStore.feedTable.pageSize = size; - gameLogStore.gameLogTable.pageSize = size; - friendStore.friendLogTable.pageSize = size; - moderationStore.playerModerationTable.pageSize = size; - notificationStore.notificationTable.pageSize = size; - tablePageSize.value = size; - configRepository.setInt('VRCX_tablePageSize', size); + function setTablePageSize(size) { + const processedSize = clampInt(size, 1, MAX_TABLE_PAGE_SIZE); + tablePageSize.value = processedSize; + configRepository.setInt('VRCX_tablePageSize', processedSize); + + return processedSize; + } + + function normalizeTablePageSizes(input) { + const values = ( + Array.isArray(input) ? input : DEFAULT_TABLE_PAGE_SIZES + ) + .map((v) => parseInt(v, 10)) + .filter((v) => v > 0 && v <= MAX_TABLE_PAGE_SIZE); + const uniqueSorted = Array.from(new Set(values)).sort( + (a, b) => a - b + ); + return uniqueSorted.length + ? uniqueSorted + : [...DEFAULT_TABLE_PAGE_SIZES]; + } + + /** + * @param {Array} sizes + */ + function setTablePageSizes(sizes) { + tablePageSizes.value = normalizeTablePageSizes(sizes); + configRepository.setString( + 'VRCX_tablePageSizes', + JSON.stringify(tablePageSizes.value) + ); + + if (!tablePageSizes.value.includes(tablePageSize.value)) { + setTablePageSize(tablePageSizes.value[0]); + } } function setDtHour12() { dtHour12.value = !dtHour12.value; @@ -708,6 +744,7 @@ export const useAppearanceSettingsStore = defineStore( sortFavorites, instanceUsersSortAlphabetical, tablePageSize, + tablePageSizes, dtHour12, dtIsoFormat, sidebarSortMethod1, @@ -734,6 +771,7 @@ export const useAppearanceSettingsStore = defineStore( setSortFavorites, setInstanceUsersSortAlphabetical, setTablePageSize, + setTablePageSizes, setDtHour12, setDtIsoFormat, setSidebarSortMethod1, diff --git a/src/views/Settings/components/Tabs/AppearanceTab.vue b/src/views/Settings/components/Tabs/AppearanceTab.vue index 59e1506a..c9172447 100644 --- a/src/views/Settings/components/Tabs/AppearanceTab.vue +++ b/src/views/Settings/components/Tabs/AppearanceTab.vue @@ -101,12 +101,26 @@ }} + +
+ {{ t('view.settings.appearance.appearance.table_page_sizes') }} + + + +
{{ t('view.settings.appearance.appearance.table_max_size') }}
-
{{ t('view.settings.appearance.timedate.header') }} @@ -365,6 +379,7 @@