From 4a0be19607a61a3c5167caaf59742d2c31fdaa7b Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 8 Jun 2026 14:24:18 +0300 Subject: [PATCH] i changed my mind, fetch logic does belong in --- src/components/list/list.js | 78 ++++++++++++------- src/components/list/list.vue | 4 +- .../settings_modal/admin_tabs/admin_card.js | 4 +- .../settings_modal/admin_tabs/users_tab.js | 35 ++------- .../settings_modal/admin_tabs/users_tab.vue | 8 +- .../tabs/mutes_and_blocks_tab.js | 20 +---- .../tabs/mutes_and_blocks_tab.vue | 21 ++--- src/components/user_profile/user_profile.js | 30 ++----- src/components/user_profile/user_profile.vue | 14 +--- 9 files changed, 77 insertions(+), 137 deletions(-) diff --git a/src/components/list/list.js b/src/components/list/list.js index 61002c21b..aac0c4891 100644 --- a/src/components/list/list.js +++ b/src/components/list/list.js @@ -1,3 +1,5 @@ +import { isEmpty } from 'lodash' + import Checkbox from 'src/components/checkbox/checkbox.vue' const List = { @@ -6,21 +8,13 @@ const List = { type: Boolean, default: false, }, - items: { - type: Array, - default: [], - }, fetchFunction: { type: Function, default: null, }, - itemsFunction: { - type: Function, - default: null, - }, getKey: { type: Function, - default: (item) => item.id, + default: (item) => item, }, getClass: { type: Function, @@ -38,16 +32,8 @@ const List = { type: Boolean, default: false, }, - loading: { - type: Boolean, - default: true, - }, - bottomedOut: { - type: Boolean, - default: false, - }, - error: { - type: String, + externalItems: { + type: Array, default: null, }, }, @@ -57,25 +43,34 @@ const List = { }, data() { return { - selected: [], + items: [], + selected: new Set([]), + loading: false, + bottomedOut: true, + error: null, + page: 1, + total: null, } }, computed: { allKeys() { - return this.items.map(this.getKey) + return new Set(this.finalItems.map(this.getKey)) }, filteredSelected() { - return this.allKeys.filter((key) => this.selected.indexOf(key) !== -1) + return [ ...this.allKeys.values().filter((key) => this.selected.has(key))] }, allSelected() { - return this.filteredSelected.length === this.items.length + return this.selected.size === this.finalItems.length }, noneSelected() { - return this.filteredSelected.length === 0 + return this.selected.size === 0 }, someSelected() { return !this.allSelected && !this.noneSelected }, + finalItems() { + return this.externalItems || this.items + } }, created() { window.addEventListener('scroll', this.scrollLoad) @@ -89,7 +84,32 @@ const List = { }, methods: { fetchEntries() { - this.$emit('fetchRequested') + if (this.loading) return + + this.loading = true + this.error = null + + this.fetchFunction(this.page) + .then((result) => { + this.loading = false + this.bottomedOut = isEmpty(result.items) + if (this.externalItems) return + this.page += 1 + this.total = result.count + this.items.push(...result.items) + }) + .catch((error) => { + this.loading = false + this.error = error + }) + }, + reset() { + this.items = [] + this.page = 1 + this.total = null + this.error = null + this.loading = false + this.fetchEntries() }, scrollLoad(e) { if (this.fetchFunction) { @@ -111,18 +131,18 @@ const List = { const oldChecked = this.isSelected(key) if (checked !== oldChecked) { if (checked) { - this.selected.push(key) + this.selected.add(key) } else { - this.selected.splice(this.selected.indexOf(key), 1) + this.selected.delete(key) } } this.$emit('selected', this.selected) }, toggleAll(value) { if (value) { - this.selected = this.allKeys.slice(0) + this.selected = new Set([...this.allKeys]) } else { - this.selected = [] + this.selected = new Set([]) } this.$emit('selected', this.selected) }, diff --git a/src/components/list/list.vue b/src/components/list/list.vue index ab916dfe6..ff6259422 100644 --- a/src/components/list/list.vue +++ b/src/components/list/list.vue @@ -28,7 +28,7 @@ role="list" >
diff --git a/src/components/settings_modal/admin_tabs/admin_card.js b/src/components/settings_modal/admin_tabs/admin_card.js index d33e3c7e0..53525f1cd 100644 --- a/src/components/settings_modal/admin_tabs/admin_card.js +++ b/src/components/settings_modal/admin_tabs/admin_card.js @@ -2,7 +2,7 @@ import Checkbox from 'src/components/checkbox/checkbox.vue' import GenericConfirm from 'src/components/confirm_modal/generic_confirm.vue' import TextConfirm from 'src/components/confirm_modal/text_confirm.vue' import Modal from 'src/components/modal/modal.vue' -import PageList from 'src/components/page_list/page_list.vue' +import List from 'src/components/list/list.vue' import Popover from 'src/components/popover/popover.vue' import Select from 'src/components/select/select.vue' import AdminStatusCard from 'src/components/settings_modal/admin_tabs/admin_status_card.vue' @@ -132,7 +132,7 @@ const AdminCard = { components: { BasicUserCard, Checkbox, - PageList, + List, AdminStatusCard, Modal, Popover, diff --git a/src/components/settings_modal/admin_tabs/users_tab.js b/src/components/settings_modal/admin_tabs/users_tab.js index 47e7f8fb4..2b7a078c4 100644 --- a/src/components/settings_modal/admin_tabs/users_tab.js +++ b/src/components/settings_modal/admin_tabs/users_tab.js @@ -28,12 +28,6 @@ const UsersTab = { filtersName: '', filtersEmail: '', expandedUser: null, - loading: false, - error: null, - bottomedOut: false, - users: [], - page: 1, - total: null, } }, computed: { @@ -118,29 +112,14 @@ const UsersTab = { GenericConfirm, }, methods: { - fetchPage() { - if (this.loading) return - - this.loading = true - this.error = null - - this.$store + fetchUsers(page) { + console.log(page) + return this.$store .dispatch('fetchAdminUsers', { ...this.fetchOptions, - page: this.page, - }) - .then((result) => { - console.log('RESULT', result) - this.loading = false - this.bottomedOut = isEmpty(result.users) - this.page += 1 - this.total = result.count - this.users.push(...result.users) - }) - .catch((error) => { - this.loading = false - this.error = error + page, }) + .then(({ count, users }) => ({ count, items: users })) }, /** * show the confirmation box for bulk actions. @@ -170,9 +149,7 @@ const UsersTab = { }, watch: { fetchOptions () { - this.page = 1 - this.users = [] - this.fetchPage() + this.$refs.usersList.reset() } } } diff --git a/src/components/settings_modal/admin_tabs/users_tab.vue b/src/components/settings_modal/admin_tabs/users_tab.vue index 77006f61c..a9ffdfba9 100644 --- a/src/components/settings_modal/admin_tabs/users_tab.vue +++ b/src/components/settings_modal/admin_tabs/users_tab.vue @@ -121,12 +121,8 @@
diff --git a/src/components/settings_modal/tabs/mutes_and_blocks_tab.js b/src/components/settings_modal/tabs/mutes_and_blocks_tab.js index a4fc6ecb0..34529b3f3 100644 --- a/src/components/settings_modal/tabs/mutes_and_blocks_tab.js +++ b/src/components/settings_modal/tabs/mutes_and_blocks_tab.js @@ -7,7 +7,6 @@ import DomainMuteCard from 'src/components/domain_mute_card/domain_mute_card.vue import List from 'src/components/list/list.vue' import MuteCard from 'src/components/mute_card/mute_card.vue' import ProgressButton from 'src/components/progress_button/progress_button.vue' -import SelectableList from 'src/components/selectable_list/selectable_list.vue' import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' import { useInstanceStore } from 'src/stores/instance.js' @@ -61,24 +60,7 @@ const MutesAndBlocks = { }, methods: { fetchItems(group) { - if (this[group + 'Loading']) return - - const capGroup = group[0].toUpperCase() + group.slice(1) - - this[group + 'Loading'] = true - this[group + 'Error'] = null - - this.$store - .dispatch('fetch' + capGroup, this.userId) - .then((newEntries) => { - this[group + 'Loading'] = false - this[group + 'BottomedOut'] = isEmpty(newEntries) - return newEntries - }) - .catch((error) => { - this[group + 'Loading'] = false - this[group + 'Error'] = error - }) + return () => this.$store.dispatch('fetch' + group, this.userId) }, importFollows(file) { return this.$store.state.api.backendInteractor diff --git a/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue b/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue index 743e9d2ff..1bc446ffb 100644 --- a/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue +++ b/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue @@ -22,11 +22,8 @@ @@ -79,11 +76,8 @@ @@ -136,11 +130,8 @@ diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js index b4394f01e..b2a2ccdfd 100644 --- a/src/components/user_profile/user_profile.js +++ b/src/components/user_profile/user_profile.js @@ -1,4 +1,4 @@ -import { get, isEmpty } from 'lodash' +import { get } from 'lodash' import { mapState } from 'pinia' import Conversation from 'src/components/conversation/conversation.vue' @@ -27,12 +27,6 @@ const UserProfile = { userId: null, tab: defaultTabKey, footerRef: null, - friendsLoading: false, - friendsError: null, - friendsBottomedOut: false, - followersLoading: false, - followersError: null, - followersBottomedOut: false, } }, created() { @@ -109,24 +103,10 @@ const UserProfile = { this.footerRef = el }, fetchUsers(group) { - if (this[group + 'Loading']) return - - const capGroup = group[0].toUpperCase() + group.slice(1) - - this[group + 'Loading'] = true - this[group + 'Error'] = null - - this.$store - .dispatch('fetch' + capGroup, this.userId) - .then((newEntries) => { - this[group + 'Loading'] = false - this[group + 'BottomedOut'] = isEmpty(newEntries) - return newEntries - }) - .catch((error) => { - this[group + 'Loading'] = false - this[group + 'Error'] = error - }) + return () => this + .$store + .dispatch('fetch' + group, this.userId) + .then((result) => ({ items: result })) }, load(userNameOrId) { const startFetchingTimeline = (timeline, userId) => { diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue index 749fc56a7..51ac73a7a 100644 --- a/src/components/user_profile/user_profile.vue +++ b/src/components/user_profile/user_profile.vue @@ -40,11 +40,8 @@ :disabled="!user.friends_count" >