diff --git a/core/src/components/ConversationConstants.js b/core/src/components/ConversationConstants.js new file mode 100644 index 0000000000000..647b2454b0ea7 --- /dev/null +++ b/core/src/components/ConversationConstants.js @@ -0,0 +1,64 @@ +export const CONVERSATION = { + START_CALL: { + EVERYONE: 0, + USERS: 1, + MODERATORS: 2, + }, + + STATE: { + READ_WRITE: 0, + READ_ONLY: 1, + }, + + LISTABLE: { + NONE: 0, + USERS: 1, + ALL: 2, + }, + + TYPE: { + ONE_TO_ONE: 1, + GROUP: 2, + PUBLIC: 3, + CHANGELOG: 4, + ONE_TO_ONE_FORMER: 5, + NOTE_TO_SELF: 6, + }, + + BREAKOUT_ROOM_MODE: { + NOT_CONFIGURED: 0, + AUTOMATIC: 1, + MANUAL: 2, + FREE: 3, + }, + + BREAKOUT_ROOM_STATUS: { + // Main room + STOPPED: 0, + STARTED: 1, + // Breakout rooms + STATUS_ASSISTANCE_RESET: 0, + STATUS_ASSISTANCE_REQUESTED: 2, + }, + + OBJECT_TYPE: { + EMAIL: 'emails', + FILE: 'file', + PHONE: 'phone', + VIDEO_VERIFICATION: 'share:password', + BREAKOUT_ROOM: 'room', + DEFAULT: '', + }, +} + +export const AVATAR = { + SIZE: { + EXTRA_SMALL: 22, + SMALL: 32, + DEFAULT: 44, + MEDIUM: 64, + LARGE: 128, + EXTRA_LARGE: 180, + FULL: 512, + }, +} diff --git a/core/src/components/UnifiedSearch/ConversationIcon.vue b/core/src/components/UnifiedSearch/ConversationIcon.vue new file mode 100644 index 0000000000000..77e3877db4304 --- /dev/null +++ b/core/src/components/UnifiedSearch/ConversationIcon.vue @@ -0,0 +1,266 @@ + + + + + + + diff --git a/core/src/components/UnifiedSearch/ConversationsListModal.vue b/core/src/components/UnifiedSearch/ConversationsListModal.vue new file mode 100644 index 0000000000000..033025b87940c --- /dev/null +++ b/core/src/components/UnifiedSearch/ConversationsListModal.vue @@ -0,0 +1,200 @@ + + + + + diff --git a/core/src/services/TalkService.js b/core/src/services/TalkService.js new file mode 100644 index 0000000000000..f8dc79a5dcc32 --- /dev/null +++ b/core/src/services/TalkService.js @@ -0,0 +1,66 @@ +/** + * @copyright Copyright (c) 2024 Fon E. Noel NFEBE + * + * @author Fon E. Noel NFEBE + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +import axios from '@nextcloud/axios' +import { generateOcsUrl } from '@nextcloud/router' + +/** + * Fetches the conversations from the server. + * + * @param {object} options options + */ +const fetchConversations = async function(options) { + options = options || {} + options.params = options.params || {} + options.params.includeStatus = true + return await axios.get(generateOcsUrl('apps/spreed/api/v4/room'), options) +} + +/** + * Fetches a conversation from the server. + * + * @param {string} token The token of the conversation to be fetched. + */ +const fetchConversation = async function(token) { + return axios.get(generateOcsUrl('apps/spreed/api/v4/room/{token}', { token })) +} + +/** + * Fetch listed conversations + * + * @param {string} searchText The string that will be used in the search query. + * @param {object} options options + */ +const searchListedConversations = async function({ searchText }, options) { + return axios.get(generateOcsUrl('apps/spreed/api/v4/listed-room'), Object.assign(options, { + params: { + searchTerm: searchText, + }, + })) +} + + +export { + fetchConversations, + fetchConversation, + searchListedConversations, +} diff --git a/core/src/views/UnifiedSearchModal.vue b/core/src/views/UnifiedSearchModal.vue index 9c719d2bcf6a3..410b8e058ed9b 100644 --- a/core/src/views/UnifiedSearchModal.vue +++ b/core/src/views/UnifiedSearchModal.vue @@ -8,6 +8,10 @@ class="unified-search__date-range" @set:custom-date-range="setCustomDateRange" @update:is-open="showDateRangeModal = $event" /> +
@@ -18,7 +22,7 @@ :label="t('core', 'Search apps, files, tags, messages') + '...'" @update:value="debouncedFind" />
- + @@ -133,6 +137,7 @@ import ArrowRight from 'vue-material-design-icons/ArrowRight.vue' import AccountGroup from 'vue-material-design-icons/AccountGroup.vue' import CalendarRangeIcon from 'vue-material-design-icons/CalendarRange.vue' +import ConversationsListModal from '../components/UnifiedSearch/ConversationsListModal.vue' import CustomDateRangeModal from '../components/UnifiedSearch/CustomDateRangeModal.vue' import DotsHorizontalIcon from 'vue-material-design-icons/DotsHorizontal.vue' import FilterIcon from 'vue-material-design-icons/Filter.vue' @@ -160,6 +165,7 @@ export default { ArrowRight, AccountGroup, CalendarRangeIcon, + ConversationsListModal, CustomDateRangeModal, DotsHorizontalIcon, FilterIcon, @@ -193,6 +199,7 @@ export default { }, data() { return { + searchScope: 'everywhere', providers: [], providerActionMenuIsOpen: false, dateActionMenuIsOpen: false, @@ -212,6 +219,7 @@ export default { debouncedFind: debounce(this.find, 300), debouncedFilterContacts: debounce(this.filterContacts, 300), showDateRangeModal: false, + showConversationListModal: false, internalIsVisible: false, } }, @@ -252,6 +260,7 @@ export default { mounted() { getProviders().then((providers) => { this.providers = providers + this.providers.push({ icon: '/apps/spreed/img/app.svg', id: 'inConversation', name: 'In Conversation' }) console.debug('Search providers', this.providers) }) getContacts({ searchTerm: '' }).then((contacts) => { @@ -267,6 +276,16 @@ export default { this.searching = false return } + switch (this.searchScope) { + case 'everywhere': + // Code to execute if searchScope is 'everywhere' + break + case 'conversation': + // Code to execute if searchScope is 'conversation' + break + default: + // Code to execute if searchScope is neither 'everywhere' nor 'conversation' + } // Event should probably be refactored at some point to used nextcloud:unified-search.search emit('nextcloud:unified-search.search', { query }) const newResults = [] @@ -404,6 +423,9 @@ export default { }, addProviderFilter(providerFilter, loadMoreResultsForProvider = false) { if (!providerFilter.id) return + if (providerFilter.id === 'inConversation') { + this.showConversationListModal = true + } this.providerResultLimit = loadMoreResultsForProvider ? this.providerResultLimit : 5 this.providerActionMenuIsOpen = false const existingFilter = this.filteredProviders.find(existing => existing.id === providerFilter.id) @@ -527,6 +549,15 @@ export default { this.dateFilter.text = t('core', `Between ${this.dateFilter.startFrom.toLocaleDateString()} and ${this.dateFilter.endAt.toLocaleDateString()}`) this.updateDateFilter() }, + setSearchScopeToConversation(event) { + for (const provider of this.filteredProviders) { + if (provider.id === 'inConversation') { + provider.name = `Search in talk room : ${event.displayName}` + break + } + } + console.debug('Search scope set to conversation', event) + }, focusInput() { this.$refs.searchInput.$el.children[0].children[0].focus() }, @@ -549,7 +580,7 @@ export default { padding-block: 10px 0; // inline padding on direct children to make sure the scrollbar is on the modal container - > * { + >* { padding-inline: 20px; }