From e73553dca726703f83e5085560377bfaa202a5f9 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Mon, 18 Jan 2021 15:26:08 +0200 Subject: wip --- src/modules/statuses.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/modules/statuses.js') diff --git a/src/modules/statuses.js b/src/modules/statuses.js index 33c68c57..d5343cd4 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -317,6 +317,10 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot notification.status = notification.status && addStatusToGlobalStorage(state, notification.status).item } + if (notification.type === 'pleroma:report') { + dispatch('addReport', notification.report) + } + if (notification.type === 'pleroma:emoji_reaction') { dispatch('fetchEmojiReactionsBy', notification.status.id) } -- cgit v1.2.3-70-g09d2 From 1a333aabba759fb68449ead9c47e986f456e8c8c Mon Sep 17 00:00:00 2001 From: Sean King Date: Tue, 7 Jun 2022 21:31:48 -0600 Subject: Add edit status functionality --- CONTRIBUTORS.md | 1 + src/App.js | 2 + src/App.vue | 1 + .../edit_status_modal/edit_status_modal.js | 75 ++++++++++++++++++ .../edit_status_modal/edit_status_modal.vue | 48 ++++++++++++ src/components/extra_buttons/extra_buttons.js | 13 ++++ src/components/extra_buttons/extra_buttons.vue | 11 +++ .../post_status_form/post_status_form.js | 45 ++++++++--- .../post_status_form/post_status_form.vue | 1 + src/i18n/en.json | 2 + src/main.js | 3 + src/modules/api.js | 2 + src/modules/editStatus.js | 25 ++++++ src/modules/statuses.js | 6 ++ src/services/api/api.service.js | 88 +++++++++++++++++++++- .../entity_normalizer/entity_normalizer.service.js | 12 +++ .../status_poster/status_poster.service.js | 42 +++++++++++ 17 files changed, 365 insertions(+), 12 deletions(-) create mode 100644 src/components/edit_status_modal/edit_status_modal.js create mode 100644 src/components/edit_status_modal/edit_status_modal.vue create mode 100644 src/modules/editStatus.js (limited to 'src/modules/statuses.js') diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index f666a4ef..18f4a930 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -10,3 +10,4 @@ Contributors of this project. - shpuld (shpuld@shitposter.club): CSS and styling - Vincent Guth (https://unsplash.com/photos/XrwVIFy6rTw): Background images. - hj (hj@shigusegubu.club): Code +- Sean King (seanking@freespeechextremist.com): Code diff --git a/src/App.js b/src/App.js index f01f8788..6e0e34a8 100644 --- a/src/App.js +++ b/src/App.js @@ -11,6 +11,7 @@ import MobilePostStatusButton from './components/mobile_post_status_button/mobil import MobileNav from './components/mobile_nav/mobile_nav.vue' import DesktopNav from './components/desktop_nav/desktop_nav.vue' import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue' +import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue' import PostStatusModal from './components/post_status_modal/post_status_modal.vue' import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue' import { windowWidth, windowHeight } from './services/window_utils/window_utils' @@ -35,6 +36,7 @@ export default { SettingsModal, UserReportingModal, PostStatusModal, + EditStatusModal, GlobalNoticeList }, data: () => ({ diff --git a/src/App.vue b/src/App.vue index 5b448972..9484f993 100644 --- a/src/App.vue +++ b/src/App.vue @@ -52,6 +52,7 @@ + +
  • + +
    + +
    +
  • +
  • + + + +
  • +
  • + + {{ $t('settings.lists_navigation') }} + +
  • +
  • +

    {{ $t('settings.columns') }}

    +
  • +
  • + + {{ $t('settings.disable_sticky_headers') }} + +
  • +
  • + + {{ $t('settings.show_scrollbars') }} + +
  • +
  • + + {{ $t('settings.right_sidebar') }} + +
  • +
  • + + {{ $t('settings.third_column_mode') }} + +
  • +
  • + {{ $t('settings.column_sizes') }} +
    + + {{ $t('settings.column_sizes_' + column) }} + +
    +
  • diff --git a/src/components/side_drawer/side_drawer.js b/src/components/side_drawer/side_drawer.js index f45f8def..913fa695 100644 --- a/src/components/side_drawer/side_drawer.js +++ b/src/components/side_drawer/side_drawer.js @@ -14,7 +14,8 @@ import { faSearch, faTachometerAlt, faCog, - faInfoCircle + faInfoCircle, + faList } from '@fortawesome/free-solid-svg-icons' library.add( @@ -28,7 +29,8 @@ library.add( faSearch, faTachometerAlt, faCog, - faInfoCircle + faInfoCircle, + faList ) const SideDrawer = { diff --git a/src/components/side_drawer/side_drawer.vue b/src/components/side_drawer/side_drawer.vue index 7547fb08..7d9d36d7 100644 --- a/src/components/side_drawer/side_drawer.vue +++ b/src/components/side_drawer/side_drawer.vue @@ -55,6 +55,18 @@ /> {{ $t("nav.timelines") }} +
  • + + {{ $t("nav.lists") }} + +
  • { if (statuses && statuses.length === 0) { diff --git a/src/components/timeline_menu/timeline_menu.js b/src/components/timeline_menu/timeline_menu.js index a11e7b7e..0792dc13 100644 --- a/src/components/timeline_menu/timeline_menu.js +++ b/src/components/timeline_menu/timeline_menu.js @@ -58,6 +58,9 @@ const TimelineMenu = { if (route === 'tag-timeline') { return '#' + this.$route.params.tag } + if (route === 'list-timeline') { + return this.$store.getters.findListTitle(this.$route.params.id) + } const i18nkey = timelineNames()[this.$route.name] return i18nkey ? this.$t(i18nkey) : route } diff --git a/src/i18n/en.json b/src/i18n/en.json index a10b271a..2f9c372e 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -146,7 +146,8 @@ "who_to_follow": "Who to follow", "preferences": "Preferences", "timelines": "Timelines", - "chats": "Chats" + "chats": "Chats", + "lists": "Lists" }, "notifications": { "broken_favorite": "Unknown status, searching for it…", @@ -298,6 +299,7 @@ "desc": "To enable two-factor authentication, enter the code from your two-factor app:" } }, + "lists_navigation": "Show lists in navigation", "allow_following_move": "Allow auto-follow when following account moves", "attachmentRadius": "Attachments", "attachments": "Attachments", @@ -948,6 +950,16 @@ "error_sending_message": "Something went wrong when sending the message.", "empty_chat_list_placeholder": "You don't have any chats yet. Start a new chat!" }, + "lists": { + "lists": "Lists", + "new": "New List", + "title": "List title", + "search": "Search users", + "create": "Create", + "save": "Save changes", + "delete": "Delete list", + "following_only": "Limit to Following" + }, "file_type": { "audio": "Audio", "video": "Video", diff --git a/src/main.js b/src/main.js index eacd554c..7d2c82cb 100644 --- a/src/main.js +++ b/src/main.js @@ -6,6 +6,7 @@ import './lib/event_target_polyfill.js' import interfaceModule from './modules/interface.js' import instanceModule from './modules/instance.js' import statusesModule from './modules/statuses.js' +import listsModule from './modules/lists.js' import usersModule from './modules/users.js' import apiModule from './modules/api.js' import configModule from './modules/config.js' @@ -70,6 +71,7 @@ const persistedStateOptions = { // TODO refactor users/statuses modules, they depend on each other users: usersModule, statuses: statusesModule, + lists: listsModule, api: apiModule, config: configModule, serverSideConfig: serverSideConfigModule, diff --git a/src/modules/api.js b/src/modules/api.js index 28f2076e..80a978f9 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -191,12 +191,13 @@ const api = { startFetchingTimeline (store, { timeline = 'friends', tag = false, - userId = false + userId = false, + listId = false }) { if (store.state.fetchers[timeline]) return const fetcher = store.state.backendInteractor.startFetchingTimeline({ - timeline, store, userId, tag + timeline, store, userId, listId, tag }) store.commit('addFetcher', { fetcherName: timeline, fetcher }) }, @@ -248,6 +249,18 @@ const api = { store.commit('setFollowRequests', requests) }, + // Lists + startFetchingLists (store) { + if (store.state.fetchers.lists) return + const fetcher = store.state.backendInteractor.startFetchingLists({ store }) + store.commit('addFetcher', { fetcherName: 'lists', fetcher }) + }, + stopFetchingLists (store) { + const fetcher = store.state.fetchers.lists + if (!fetcher) return + store.commit('removeFetcher', { fetcherName: 'lists', fetcher }) + }, + // Pleroma websocket setWsToken (store, token) { store.commit('setWsToken', token) diff --git a/src/modules/config.js b/src/modules/config.js index eaf67a91..910fb172 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -83,6 +83,10 @@ export const defaultState = { showScrollbars: false, userPopoverZoom: false, userPopoverOverlay: true, + sidebarColumnWidth: '25rem', + contentColumnWidth: '45rem', + notifsColumnWidth: '25rem', + listsNavigation: false, greentext: undefined, // instance default useAtIcon: undefined, // instance default mentionLinkDisplay: undefined, // instance default diff --git a/src/modules/lists.js b/src/modules/lists.js new file mode 100644 index 00000000..58700f41 --- /dev/null +++ b/src/modules/lists.js @@ -0,0 +1,94 @@ +import { remove, find } from 'lodash' + +export const defaultState = { + allLists: [], + allListsObject: {} +} + +export const mutations = { + setLists (state, value) { + state.allLists = value + }, + setList (state, { id, title }) { + if (!state.allListsObject[id]) { + state.allListsObject[id] = {} + } + state.allListsObject[id].title = title + + if (!find(state.allLists, { id })) { + state.allLists.push({ id, title }) + } else { + find(state.allLists, { id }).title = title + } + }, + setListAccounts (state, { id, accountIds }) { + if (!state.allListsObject[id]) { + state.allListsObject[id] = {} + } + state.allListsObject[id].accountIds = accountIds + }, + deleteList (state, { id }) { + delete state.allListsObject[id] + remove(state.allLists, list => list.id === id) + } +} + +const actions = { + setLists ({ commit }, value) { + commit('setLists', value) + }, + createList ({ rootState, commit }, { title }) { + return rootState.api.backendInteractor.createList({ title }) + .then((list) => { + commit('setList', { id: list.id, title }) + return list + }) + }, + fetchList ({ rootState, commit }, { id }) { + return rootState.api.backendInteractor.getList({ id }) + .then((list) => commit('setList', { id: list.id, title: list.title })) + }, + fetchListAccounts ({ rootState, commit }, { id }) { + return rootState.api.backendInteractor.getListAccounts({ id }) + .then((accountIds) => commit('setListAccounts', { id, accountIds })) + }, + setList ({ rootState, commit }, { id, title }) { + rootState.api.backendInteractor.updateList({ id, title }) + commit('setList', { id, title }) + }, + setListAccounts ({ rootState, commit }, { id, accountIds }) { + const saved = rootState.lists.allListsObject[id].accountIds + const added = accountIds.filter(id => !saved.includes(id)) + const removed = saved.filter(id => !accountIds.includes(id)) + commit('setListAccounts', { id, accountIds }) + if (added.length > 0) { + rootState.api.backendInteractor.addAccountsToList({ id, accountIds: added }) + } + if (removed.length > 0) { + rootState.api.backendInteractor.removeAccountsFromList({ id, accountIds: removed }) + } + }, + deleteList ({ rootState, commit }, { id }) { + rootState.api.backendInteractor.deleteList({ id }) + commit('deleteList', { id }) + } +} + +export const getters = { + findListTitle: state => id => { + if (!state.allListsObject[id]) return + return state.allListsObject[id].title + }, + findListAccounts: state => id => { + return [...state.allListsObject[id].accountIds] + } +} + +const lists = { + state: defaultState, + mutations, + actions, + getters +} + +export default lists diff --git a/src/modules/statuses.js b/src/modules/statuses.js index 62251b0b..c4475005 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -62,7 +62,8 @@ export const defaultState = () => ({ friends: emptyTl(), tag: emptyTl(), dms: emptyTl(), - bookmarks: emptyTl() + bookmarks: emptyTl(), + list: emptyTl() } }) diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 7b7fbefd..86d9eaf4 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -52,6 +52,9 @@ const MASTODON_STATUS_CONTEXT_URL = id => `/api/v1/statuses/${id}/context` const MASTODON_USER_URL = '/api/v1/accounts' const MASTODON_USER_RELATIONSHIPS_URL = '/api/v1/accounts/relationships' const MASTODON_USER_TIMELINE_URL = id => `/api/v1/accounts/${id}/statuses` +const MASTODON_LIST_URL = id => `/api/v1/lists/${id}` +const MASTODON_LIST_TIMELINE_URL = id => `/api/v1/timelines/list/${id}` +const MASTODON_LIST_ACCOUNTS_URL = id => `/api/v1/lists/${id}/accounts` const MASTODON_TAG_TIMELINE_URL = tag => `/api/v1/timelines/tag/${tag}` const MASTODON_BOOKMARK_TIMELINE_URL = '/api/v1/bookmarks' const MASTODON_USER_BLOCKS_URL = '/api/v1/blocks/' @@ -79,6 +82,7 @@ const MASTODON_UNMUTE_CONVERSATION = id => `/api/v1/statuses/${id}/unmute` const MASTODON_SEARCH_2 = '/api/v2/search' const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search' const MASTODON_DOMAIN_BLOCKS_URL = '/api/v1/domain_blocks' +const MASTODON_LISTS_URL = '/api/v1/lists' const MASTODON_STREAMING = '/api/v1/streaming' const MASTODON_KNOWN_DOMAIN_LIST_URL = '/api/v1/instance/peers' const PLEROMA_EMOJI_REACTIONS_URL = id => `/api/v1/pleroma/statuses/${id}/reactions` @@ -385,6 +389,81 @@ const fetchFollowRequests = ({ credentials }) => { .then((data) => data.map(parseUser)) } +const fetchLists = ({ credentials }) => { + const url = MASTODON_LISTS_URL + return fetch(url, { headers: authHeaders(credentials) }) + .then((data) => data.json()) +} + +const createList = ({ title, credentials }) => { + const url = MASTODON_LISTS_URL + const headers = authHeaders(credentials) + headers['Content-Type'] = 'application/json' + + return fetch(url, { + headers, + method: 'POST', + body: JSON.stringify({ title }) + }).then((data) => data.json()) +} + +const getList = ({ id, credentials }) => { + const url = MASTODON_LIST_URL(id) + return fetch(url, { headers: authHeaders(credentials) }) + .then((data) => data.json()) +} + +const updateList = ({ id, title, credentials }) => { + const url = MASTODON_LIST_URL(id) + const headers = authHeaders(credentials) + headers['Content-Type'] = 'application/json' + + return fetch(url, { + headers, + method: 'PUT', + body: JSON.stringify({ title }) + }) +} + +const getListAccounts = ({ id, credentials }) => { + const url = MASTODON_LIST_ACCOUNTS_URL(id) + return fetch(url, { headers: authHeaders(credentials) }) + .then((data) => data.json()) + .then((data) => data.map(({ id }) => id)) +} + +const addAccountsToList = ({ id, accountIds, credentials }) => { + const url = MASTODON_LIST_ACCOUNTS_URL(id) + const headers = authHeaders(credentials) + headers['Content-Type'] = 'application/json' + + return fetch(url, { + headers, + method: 'POST', + body: JSON.stringify({ account_ids: accountIds }) + }) +} + +const removeAccountsFromList = ({ id, accountIds, credentials }) => { + const url = MASTODON_LIST_ACCOUNTS_URL(id) + const headers = authHeaders(credentials) + headers['Content-Type'] = 'application/json' + + return fetch(url, { + headers, + method: 'DELETE', + body: JSON.stringify({ account_ids: accountIds }) + }) +} + +const deleteList = ({ id, credentials }) => { + const url = MASTODON_LIST_URL(id) + return fetch(url, { + method: 'DELETE', + headers: authHeaders(credentials) + }) +} + const fetchConversation = ({ id, credentials }) => { const urlContext = MASTODON_STATUS_CONTEXT_URL(id) return fetch(urlContext, { headers: authHeaders(credentials) }) @@ -506,6 +585,7 @@ const fetchTimeline = ({ since = false, until = false, userId = false, + listId = false, tag = false, withMuted = false, replyVisibility = 'all' @@ -518,6 +598,7 @@ const fetchTimeline = ({ publicAndExternal: MASTODON_PUBLIC_TIMELINE, user: MASTODON_USER_TIMELINE_URL, media: MASTODON_USER_TIMELINE_URL, + list: MASTODON_LIST_TIMELINE_URL, favorites: MASTODON_USER_FAVORITES_TIMELINE_URL, tag: MASTODON_TAG_TIMELINE_URL, bookmarks: MASTODON_BOOKMARK_TIMELINE_URL @@ -531,6 +612,10 @@ const fetchTimeline = ({ url = url(userId) } + if (timeline === 'list') { + url = url(listId) + } + if (since) { params.push(['since_id', since]) } @@ -1405,6 +1490,14 @@ const apiService = { addBackup, listBackups, fetchFollowRequests, + fetchLists, + createList, + getList, + updateList, + getListAccounts, + addAccountsToList, + removeAccountsFromList, + deleteList, approveUser, denyUser, suggestions, diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index 4a40f5b5..62ee8549 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -2,10 +2,11 @@ import apiService, { getMastodonSocketURI, ProcessedWS } from '../api/api.servic import timelineFetcher from '../timeline_fetcher/timeline_fetcher.service.js' import notificationsFetcher from '../notifications_fetcher/notifications_fetcher.service.js' import followRequestFetcher from '../../services/follow_request_fetcher/follow_request_fetcher.service' +import listsFetcher from '../../services/lists_fetcher/lists_fetcher.service.js' const backendInteractorService = credentials => ({ - startFetchingTimeline ({ timeline, store, userId = false, tag }) { - return timelineFetcher.startFetching({ timeline, store, credentials, userId, tag }) + startFetchingTimeline ({ timeline, store, userId = false, listId = false, tag }) { + return timelineFetcher.startFetching({ timeline, store, credentials, userId, listId, tag }) }, fetchTimeline (args) { @@ -24,6 +25,10 @@ const backendInteractorService = credentials => ({ return followRequestFetcher.startFetching({ store, credentials }) }, + startFetchingLists ({ store }) { + return listsFetcher.startFetching({ store, credentials }) + }, + startUserSocket ({ store }) { const serv = store.rootState.instance.server.replace('http', 'ws') const url = serv + getMastodonSocketURI({ credentials, stream: 'user' }) diff --git a/src/services/lists_fetcher/lists_fetcher.service.js b/src/services/lists_fetcher/lists_fetcher.service.js new file mode 100644 index 00000000..8d9dae66 --- /dev/null +++ b/src/services/lists_fetcher/lists_fetcher.service.js @@ -0,0 +1,22 @@ +import apiService from '../api/api.service.js' +import { promiseInterval } from '../promise_interval/promise_interval.js' + +const fetchAndUpdate = ({ store, credentials }) => { + return apiService.fetchLists({ credentials }) + .then(lists => { + store.commit('setLists', lists) + }, () => {}) + .catch(() => {}) +} + +const startFetching = ({ credentials, store }) => { + const boundFetchAndUpdate = () => fetchAndUpdate({ credentials, store }) + boundFetchAndUpdate() + return promiseInterval(boundFetchAndUpdate, 240000) +} + +const listsFetcher = { + startFetching +} + +export default listsFetcher diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js index 7ba138e0..8501907e 100644 --- a/src/services/timeline_fetcher/timeline_fetcher.service.js +++ b/src/services/timeline_fetcher/timeline_fetcher.service.js @@ -3,12 +3,13 @@ import { camelCase } from 'lodash' import apiService from '../api/api.service.js' import { promiseInterval } from '../promise_interval/promise_interval.js' -const update = ({ store, statuses, timeline, showImmediately, userId, pagination }) => { +const update = ({ store, statuses, timeline, showImmediately, userId, listId, pagination }) => { const ccTimeline = camelCase(timeline) store.dispatch('addNewStatuses', { timeline: ccTimeline, userId, + listId, statuses, showImmediately, pagination @@ -22,6 +23,7 @@ const fetchAndUpdate = ({ older = false, showImmediately = false, userId = false, + listId = false, tag = false, until, since @@ -44,6 +46,7 @@ const fetchAndUpdate = ({ } args.userId = userId + args.listId = listId args.tag = tag args.withMuted = !hideMutedPosts if (loggedIn && ['friends', 'public', 'publicAndExternal'].includes(timeline)) { @@ -62,7 +65,7 @@ const fetchAndUpdate = ({ if (!older && statuses.length >= 20 && !timelineData.loading && numStatusesBeforeFetch > 0) { store.dispatch('queueFlush', { timeline, id: timelineData.maxId }) } - update({ store, statuses, timeline, showImmediately, userId, pagination }) + update({ store, statuses, timeline, showImmediately, userId, listId, pagination }) return { statuses, pagination } }) .catch((error) => { @@ -75,14 +78,15 @@ const fetchAndUpdate = ({ }) } -const startFetching = ({ timeline = 'friends', credentials, store, userId = false, tag = false }) => { +const startFetching = ({ timeline = 'friends', credentials, store, userId = false, listId = false, tag = false }) => { const rootState = store.rootState || store.state const timelineData = rootState.statuses.timelines[camelCase(timeline)] const showImmediately = timelineData.visibleStatuses.length === 0 timelineData.userId = userId - fetchAndUpdate({ timeline, credentials, store, showImmediately, userId, tag }) + timelineData.listId = listId + fetchAndUpdate({ timeline, credentials, store, showImmediately, userId, listId, tag }) const boundFetchAndUpdate = () => - fetchAndUpdate({ timeline, credentials, store, userId, tag }) + fetchAndUpdate({ timeline, credentials, store, userId, listId, tag }) return promiseInterval(boundFetchAndUpdate, 10000) } const timelineFetcher = { diff --git a/test/unit/specs/boot/routes.spec.js b/test/unit/specs/boot/routes.spec.js index 5cffefbb..4c387567 100644 --- a/test/unit/specs/boot/routes.spec.js +++ b/test/unit/specs/boot/routes.spec.js @@ -40,4 +40,28 @@ describe('routes', () => { // eslint-disable-next-line no-prototype-builtins expect(matchedComponents[0].components.default.components.hasOwnProperty('UserCard')).to.eql(true) }) + + it('list view', async () => { + await router.push('/lists') + + const matchedComponents = router.currentRoute.value.matched + + expect(matchedComponents[0].components.default.components.hasOwnProperty('ListsCard')).to.eql(true) + }) + + it('list timeline', async () => { + await router.push('/lists/1') + + const matchedComponents = router.currentRoute.value.matched + + expect(matchedComponents[0].components.default.components.hasOwnProperty('Timeline')).to.eql(true) + }) + + it('list edit', async () => { + await router.push('/lists/1/edit') + + const matchedComponents = router.currentRoute.value.matched + + expect(matchedComponents[0].components.default.components.hasOwnProperty('BasicUserCard')).to.eql(true) + }) }) diff --git a/test/unit/specs/modules/lists.spec.js b/test/unit/specs/modules/lists.spec.js new file mode 100644 index 00000000..ac9af1b6 --- /dev/null +++ b/test/unit/specs/modules/lists.spec.js @@ -0,0 +1,83 @@ +import { cloneDeep } from 'lodash' +import { defaultState, mutations, getters } from '../../../../src/modules/lists.js' + +describe('The lists module', () => { + describe('mutations', () => { + it('updates array of all lists', () => { + const state = cloneDeep(defaultState) + const list = { id: '1', title: 'testList' } + + mutations.setLists(state, [list]) + expect(state.allLists).to.have.length(1) + expect(state.allLists).to.eql([list]) + }) + + it('adds a new list with a title, updating the title for existing lists', () => { + const state = cloneDeep(defaultState) + const list = { id: '1', title: 'testList' } + const modList = { id: '1', title: 'anotherTestTitle' } + + mutations.setList(state, list) + expect(state.allListsObject[list.id]).to.eql({ title: list.title }) + expect(state.allLists).to.have.length(1) + expect(state.allLists[0]).to.eql(list) + + mutations.setList(state, modList) + expect(state.allListsObject[modList.id]).to.eql({ title: modList.title }) + expect(state.allLists).to.have.length(1) + expect(state.allLists[0]).to.eql(modList) + }) + + it('adds a new list with an array of IDs, updating the IDs for existing lists', () => { + const state = cloneDeep(defaultState) + const list = { id: '1', accountIds: ['1', '2', '3'] } + const modList = { id: '1', accountIds: ['3', '4', '5'] } + + mutations.setListAccounts(state, list) + expect(state.allListsObject[list.id]).to.eql({ accountIds: list.accountIds }) + + mutations.setListAccounts(state, modList) + expect(state.allListsObject[modList.id]).to.eql({ accountIds: modList.accountIds }) + }) + + it('deletes a list', () => { + const state = { + allLists: [{ id: '1', title: 'testList' }], + allListsObject: { + 1: { title: 'testList', accountIds: ['1', '2', '3'] } + } + } + const id = '1' + + mutations.deleteList(state, { id }) + expect(state.allLists).to.have.length(0) + expect(state.allListsObject).to.eql({}) + }) + }) + + describe('getters', () => { + it('returns list title', () => { + const state = { + allLists: [{ id: '1', title: 'testList' }], + allListsObject: { + 1: { title: 'testList', accountIds: ['1', '2', '3'] } + } + } + const id = '1' + + expect(getters.findListTitle(state)(id)).to.eql('testList') + }) + + it('returns list accounts', () => { + const state = { + allLists: [{ id: '1', title: 'testList' }], + allListsObject: { + 1: { title: 'testList', accountIds: ['1', '2', '3'] } + } + } + const id = '1' + + expect(getters.findListAccounts(state)(id)).to.eql(['1', '2', '3']) + }) + }) +}) -- cgit v1.2.3-70-g09d2 From 10af09280002cc347e7b033e1a99ece072b4d804 Mon Sep 17 00:00:00 2001 From: tusooa Date: Sun, 15 Jan 2023 00:08:59 -0500 Subject: Add status authors from search results to store --- src/modules/statuses.js | 1 + 1 file changed, 1 insertion(+) (limited to 'src/modules/statuses.js') diff --git a/src/modules/statuses.js b/src/modules/statuses.js index 5a5c7b1b..77dd7e1c 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -765,6 +765,7 @@ const statuses = { return store.rootState.api.backendInteractor.search2({ q, resolve, limit, offset, following, type }) .then((data) => { store.commit('addNewUsers', data.accounts) + store.commit('addNewUsers', data.statuses.map(s => s.user).filter(u => u)) store.commit('addNewStatuses', { statuses: data.statuses }) return data }) -- cgit v1.2.3-70-g09d2