From 9e45228823cd0fa7eb9388b0eb7780b9609edf66 Mon Sep 17 00:00:00 2001 From: marcin mikołajczak Date: Mon, 23 Sep 2024 23:10:32 +0200 Subject: Bookmark folders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- src/modules/api.js | 17 +++++++++-- src/modules/bookmark_folders.js | 66 +++++++++++++++++++++++++++++++++++++++++ src/modules/instance.js | 1 + src/modules/users.js | 2 ++ 4 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 src/modules/bookmark_folders.js (limited to 'src/modules') diff --git a/src/modules/api.js b/src/modules/api.js index 3dbead5b..23364fcd 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -203,12 +203,13 @@ const api = { tag = false, userId = false, listId = false, - statusId = false + statusId = false, + bookmarkFolderId = false }) { if (store.state.fetchers[timeline]) return const fetcher = store.state.backendInteractor.startFetchingTimeline({ - timeline, store, userId, listId, statusId, tag + timeline, store, userId, listId, statusId, bookmarkFolderId, tag }) store.commit('addFetcher', { fetcherName: timeline, fetcher }) }, @@ -272,6 +273,18 @@ const api = { store.commit('removeFetcher', { fetcherName: 'lists', fetcher }) }, + // Bookmark folders + startFetchingBookmarkFolders (store) { + if (store.state.fetchers.bookmarkFolders) return + const fetcher = store.state.backendInteractor.startFetchingBookmarkFolders({ store }) + store.commit('addFetcher', { fetcherName: 'bookmarkFolders', fetcher }) + }, + stopFetchingBookmarkFolders (store) { + const fetcher = store.state.fetchers.bookmarkFolders + if (!fetcher) return + store.commit('removeFetcher', { fetcherName: 'bookmarkFolders', fetcher }) + }, + // Pleroma websocket setWsToken (store, token) { store.commit('setWsToken', token) diff --git a/src/modules/bookmark_folders.js b/src/modules/bookmark_folders.js new file mode 100644 index 00000000..e5f25791 --- /dev/null +++ b/src/modules/bookmark_folders.js @@ -0,0 +1,66 @@ +import { remove, find } from 'lodash' + +export const defaultState = { + allFolders: [] +} + +export const mutations = { + setBookmarkFolders (state, value) { + state.allFolders = value + }, + setBookmarkFolder (state, { folderId, name, emoji, emojiUrl }) { + const entry = find(state.allFolders, { id: name }) + if (!entry) { + state.allFolders.push({ id: folderId, name, emoji, emojiUrl }) + } else { + entry.name = name + entry.emoji = emoji + entry.emojiUrl = emojiUrl + } + }, + deleteBookmarkFolder (state, { folderId }) { + remove(state.allFolders, folder => folder.id === folderId) + } +} + +const actions = { + setBookmarkFolders ({ commit }, value) { + commit('setBookmarkFolders', value) + }, + createBookmarkFolder ({ rootState, commit }, { name, emoji }) { + return rootState.api.backendInteractor.createBookmarkFolder({ name, emoji }) + .then((folder) => { + commit('setBookmarkFolder', folder) + return folder + }) + }, + setBookmarkFolder ({ rootState, commit }, { folderId, name, emoji }) { + return rootState.api.backendInteractor.updateBookmarkFolder({ folderId, name, emoji }) + .then((folder) => { + commit('setBookmarkFolder', folder) + return folder + }) + }, + deleteBookmarkFolder ({ rootState, commit }, { folderId }) { + rootState.api.backendInteractor.deleteBookmarkFolder({ folderId }) + commit('deleteBookmarkFolder', { folderId }) + } +} + +export const getters = { + findBookmarkFolderName: state => id => { + const folder = state.allFolders.find(folder => folder.id === id) + + if (!folder) return + return folder.name + } +} + +const bookmarkFolders = { + state: defaultState, + mutations, + actions, + getters +} + +export default bookmarkFolders diff --git a/src/modules/instance.js b/src/modules/instance.js index 994f60a5..dac16793 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -140,6 +140,7 @@ const defaultState = { shoutAvailable: false, pleromaChatMessagesAvailable: false, pleromaCustomEmojiReactionsAvailable: false, + pleromaBookmarkFoldersAvailable: false, gopherAvailable: false, mediaProxyAvailable: false, suggestionsEnabled: false, diff --git a/src/modules/users.js b/src/modules/users.js index b8f49f15..47b43c6f 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -579,6 +579,7 @@ const users = { store.commit('setBackendInteractor', backendInteractorService(store.getters.getToken())) store.dispatch('stopFetchingNotifications') store.dispatch('stopFetchingLists') + store.dispatch('stopFetchingBookmarkFolders') store.dispatch('stopFetchingFollowRequests') store.commit('clearNotifications') store.commit('resetStatuses') @@ -635,6 +636,7 @@ const users = { } dispatch('startFetchingLists') + dispatch('startFetchingBookmarkFolders') if (user.locked) { dispatch('startFetchingFollowRequests') -- cgit v1.2.3-70-g09d2 From 89fbaa159f29a7d175a5323eded29e20c9f3a752 Mon Sep 17 00:00:00 2001 From: marcin mikołajczak Date: Tue, 24 Sep 2024 00:05:33 +0200 Subject: Allow adding bookmarks to folders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- src/components/extra_buttons/extra_buttons.js | 7 +++- src/components/extra_buttons/extra_buttons.vue | 4 +++ .../status_bookmark_folder_menu.js | 40 ++++++++++++++++++++++ .../status_bookmark_folder_menu.vue | 38 ++++++++++++++++++++ src/i18n/en.json | 3 +- src/modules/statuses.js | 4 ++- src/services/api/api.service.js | 7 ++-- .../entity_normalizer/entity_normalizer.service.js | 1 + 8 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.js create mode 100644 src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.vue (limited to 'src/modules') diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js index e2c88ceb..b3e1cb2b 100644 --- a/src/components/extra_buttons/extra_buttons.js +++ b/src/components/extra_buttons/extra_buttons.js @@ -1,6 +1,7 @@ import Popover from '../popover/popover.vue' import genRandomSeed from '../../services/random_seed/random_seed.service.js' import ConfirmModal from '../confirm_modal/confirm_modal.vue' +import StatusBookmarkFolderMenu from '../status_bookmark_folder_menu/status_bookmark_folder_menu.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { faEllipsisH, @@ -36,7 +37,8 @@ const ExtraButtons = { props: ['status'], components: { Popover, - ConfirmModal + ConfirmModal, + StatusBookmarkFolderMenu }, data () { return { @@ -145,6 +147,9 @@ const ExtraButtons = { canBookmark () { return !!this.currentUser }, + bookmarkFolders () { + return this.$store.state.instance.pleromaBookmarkFoldersAvailable + }, statusLink () { return `${this.$store.state.instance.server}${this.$router.resolve({ name: 'conversation', params: { id: this.status.id } }).href}` }, diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue index 7b38d974..c030de0c 100644 --- a/src/components/extra_buttons/extra_buttons.vue +++ b/src/components/extra_buttons/extra_buttons.vue @@ -87,6 +87,10 @@ icon="bookmark" />{{ $t("status.unbookmark") }} + + +
- {{ ' ' }} -
@@ -97,9 +130,49 @@ } .panel-body { + display: flex; + gap: 0.5em; + } + + .emoji-picker-panel { + position: absolute; + z-index: 20; + margin-top: 2px; + + &.hide { + display: none; + } + } + + .input-emoji { + height: 2.5em; + width: 2.5em; + padding: 0; + + .iconEmoji { + display: inline-block; + text-align: center; + object-fit: contain; + vertical-align: middle; + height: 2.5em; + width: 2.5em; + + > span { + font-size: 1.5rem; + line-height: 2.5rem; + } + } + + img.iconEmoji { + padding: 0.25em; + box-sizing: border-box; + } + } + + .input-wrap { display: flex; flex-direction: column; - overflow: hidden; + gap: 0.5em; } .go-back-button { diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 9ea5c877..d3d6563a 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -180,7 +180,7 @@ const EmojiPicker = { if (!this.keepOpen) { this.$refs.popover.hidePopover() } - this.$emit('emoji', { insertion: value, keepOpen: this.keepOpen }) + this.$emit('emoji', { insertion: value, insertionUrl: emoji.imageUrl, keepOpen: this.keepOpen }) }, onScroll (startIndex, endIndex, visibleStartIndex, visibleEndIndex) { const target = this.$refs['emoji-groups'].$el diff --git a/src/i18n/en.json b/src/i18n/en.json index 5a9bee32..cc55a6d0 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -1409,15 +1409,16 @@ "tooltip": "This domain contains non-ascii characters." }, "bookmark_folders": { - "create": "Create folder", + "select_folder": "Select bookmark folder", "creating_folder": "Creating bookmark folder", - "delete": "Delete folder", "editing_folder": "Editing folder {folderName}", - "error": "Error manipulating bookmark folders: {0}", + "emoji": "Emoji", "name": "Folder name", "new": "New Folder", + "create": "Create folder", + "delete": "Delete folder", + "update_folder": "Save changes", "really_delete": "Do you really want to delete the folder?", - "select_folder": "Select bookmark folder", - "update_folder": "Save changes" + "error": "Error manipulating bookmark folders: {0}" } } diff --git a/src/modules/bookmark_folders.js b/src/modules/bookmark_folders.js index 5dde58a7..c276adf4 100644 --- a/src/modules/bookmark_folders.js +++ b/src/modules/bookmark_folders.js @@ -8,14 +8,14 @@ export const mutations = { setBookmarkFolders (state, value) { state.allFolders = value }, - setBookmarkFolder (state, { id, name, emoji, emojiUrl }) { + setBookmarkFolder (state, { id, name, emoji, emoji_url: emojiUrl }) { const entry = find(state.allFolders, { id }) if (!entry) { - state.allFolders.push({ id, name, emoji, emojiUrl }) + state.allFolders.push({ id, name, emoji, emoji_url: emojiUrl }) } else { entry.name = name entry.emoji = emoji - entry.emojiUrl = emojiUrl + entry.emoji_url = emojiUrl } }, deleteBookmarkFolder (state, { folderId }) { -- cgit v1.2.3-70-g09d2