From ec5f4f34e6953917460a06762a953a230489f364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Poizat?= Date: Fri, 13 Dec 2024 11:58:33 +0100 Subject: [PATCH] feat: Delete old assistant and search components --- src/assistant/AssistantProvider.jsx | 134 ------------------ src/assistant/AssistantWrapperDesktop.jsx | 23 --- src/assistant/AssistantWrapperMobile.jsx | 54 ------- .../Conversations/ChatAssistantItem.jsx | 30 ---- .../Conversations/ChatConversation.jsx | 97 ------------- src/assistant/Conversations/ChatItem.jsx | 29 ---- src/assistant/Conversations/ChatItemLabel.jsx | 14 -- .../Conversations/ChatRealtimeAnswer.jsx | 25 ---- src/assistant/Conversations/ChatUserItem.jsx | 20 --- src/assistant/Conversations/Conversation.jsx | 26 ---- .../Conversations/ConversationBar.jsx | 115 --------------- .../Conversations/Sources/Sources.jsx | 91 ------------ .../Conversations/Sources/SourcesItem.jsx | 48 ------- .../Conversations/Sources/styles.styl | 5 - src/assistant/Conversations/styles.styl | 15 -- src/assistant/ResultMenu/ResultMenu.jsx | 30 ---- .../ResultMenu/ResultMenuContent.jsx | 78 ---------- src/assistant/ResultMenu/ResultMenuItem.jsx | 56 -------- .../SuggestionItemTextHighlighted.jsx | 119 ---------------- .../SuggestionItemTextSecondary.jsx | 46 ------ src/assistant/ResultMenu/styles.styl | 10 -- src/assistant/Search/EncryptedFolderIcon.jsx | 28 ---- src/assistant/Search/SearchBar.jsx | 45 ------ src/assistant/Search/SearchBarDesktop.jsx | 108 -------------- src/assistant/Search/SearchBarMobile.jsx | 49 ------- src/assistant/Search/SearchProvider.jsx | 58 -------- src/assistant/Search/SearchSubmitFab.jsx | 38 ----- .../Search/SuggestionsPlaceholder.jsx | 42 ------ src/assistant/Search/getFileMimetype.js | 37 ----- .../Search/getIconForSearchResult.js | 103 -------------- src/assistant/Search/styles.styl | 7 - src/assistant/Search/useFetchResult.jsx | 65 --------- src/assistant/Views/AssistantDialog.jsx | 50 ------- src/assistant/Views/SearchDialog.jsx | 68 --------- src/assistant/helpers.js | 21 --- src/assistant/queries.js | 39 ----- src/assistant/styles.styl | 18 --- src/locales/en.json | 17 --- src/locales/fr.json | 17 --- 39 files changed, 1875 deletions(-) delete mode 100644 src/assistant/AssistantProvider.jsx delete mode 100644 src/assistant/AssistantWrapperDesktop.jsx delete mode 100644 src/assistant/AssistantWrapperMobile.jsx delete mode 100644 src/assistant/Conversations/ChatAssistantItem.jsx delete mode 100644 src/assistant/Conversations/ChatConversation.jsx delete mode 100644 src/assistant/Conversations/ChatItem.jsx delete mode 100644 src/assistant/Conversations/ChatItemLabel.jsx delete mode 100644 src/assistant/Conversations/ChatRealtimeAnswer.jsx delete mode 100644 src/assistant/Conversations/ChatUserItem.jsx delete mode 100644 src/assistant/Conversations/Conversation.jsx delete mode 100644 src/assistant/Conversations/ConversationBar.jsx delete mode 100644 src/assistant/Conversations/Sources/Sources.jsx delete mode 100644 src/assistant/Conversations/Sources/SourcesItem.jsx delete mode 100644 src/assistant/Conversations/Sources/styles.styl delete mode 100644 src/assistant/Conversations/styles.styl delete mode 100644 src/assistant/ResultMenu/ResultMenu.jsx delete mode 100644 src/assistant/ResultMenu/ResultMenuContent.jsx delete mode 100644 src/assistant/ResultMenu/ResultMenuItem.jsx delete mode 100644 src/assistant/ResultMenu/SuggestionItemTextHighlighted.jsx delete mode 100644 src/assistant/ResultMenu/SuggestionItemTextSecondary.jsx delete mode 100644 src/assistant/ResultMenu/styles.styl delete mode 100644 src/assistant/Search/EncryptedFolderIcon.jsx delete mode 100644 src/assistant/Search/SearchBar.jsx delete mode 100644 src/assistant/Search/SearchBarDesktop.jsx delete mode 100644 src/assistant/Search/SearchBarMobile.jsx delete mode 100644 src/assistant/Search/SearchProvider.jsx delete mode 100644 src/assistant/Search/SearchSubmitFab.jsx delete mode 100644 src/assistant/Search/SuggestionsPlaceholder.jsx delete mode 100644 src/assistant/Search/getFileMimetype.js delete mode 100644 src/assistant/Search/getIconForSearchResult.js delete mode 100644 src/assistant/Search/styles.styl delete mode 100644 src/assistant/Search/useFetchResult.jsx delete mode 100644 src/assistant/Views/AssistantDialog.jsx delete mode 100644 src/assistant/Views/SearchDialog.jsx delete mode 100644 src/assistant/helpers.js delete mode 100644 src/assistant/queries.js delete mode 100644 src/assistant/styles.styl diff --git a/src/assistant/AssistantProvider.jsx b/src/assistant/AssistantProvider.jsx deleted file mode 100644 index 0ab25871b0..0000000000 --- a/src/assistant/AssistantProvider.jsx +++ /dev/null @@ -1,134 +0,0 @@ -import React, { useMemo, useContext, useState, useCallback } from 'react' -import { useParams } from 'react-router-dom' -import set from 'lodash/set' - -import { useClient } from 'cozy-client' -import useRealtime from 'cozy-realtime/dist/useRealtime' - -import { CHAT_EVENTS_DOCTYPE, CHAT_CONVERSATIONS_DOCTYPE } from './queries' -import { pushMessagesIdInState, isMessageForThisConversation } from './helpers' - -export const AssistantContext = React.createContext() - -export const useAssistant = () => { - const context = useContext(AssistantContext) - - if (!context) { - throw new Error('useAssistant must be used within a AssistantProvider') - } - return context -} - -const AssistantProvider = ({ children }) => { - const { conversationId } = useParams() - const client = useClient() - const [assistantState, setAssistantState] = useState({ - message: {}, - status: 'pending', - messagesId: [] - }) - - useRealtime( - client, - { - [CHAT_CONVERSATIONS_DOCTYPE]: { - created: res => { - pushMessagesIdInState(conversationId, res, setAssistantState) - }, - updated: res => { - pushMessagesIdInState(conversationId, res, setAssistantState) - } - } - }, - [] - ) - - useRealtime( - client, - { - [CHAT_EVENTS_DOCTYPE]: { - created: res => { - setAssistantState(prevState => { - // to exclude realtime messages if not relevant to the actual conversation - if (!isMessageForThisConversation(res, prevState.messagesId)) { - return prevState - } - - if (res.object === 'done') { - if (prevState.status !== 'idle') { - return { - ...prevState, - status: 'idle' - } - } - } - - if (res.object === 'delta') { - const message = set(prevState.message, res.position, res.content) - return { - ...prevState, - message, - status: 'writing' - } - } - - return prevState - }) - } - } - }, - [] - ) - - const clearAssistant = useCallback( - () => - setAssistantState({ - message: {}, - status: 'pending', - messagesId: [] - }), - [] - ) - - const onAssistantExecute = useCallback( - async ({ value, conversationId }, callback) => { - if (!value) return - - callback?.() - - clearAssistant() - - await client.stackClient.fetchJSON( - 'POST', - `/ai/chat/conversations/${conversationId}`, - { - q: value - } - ) - - setAssistantState(v => ({ - ...v, - status: 'pending' - })) - }, - [client, clearAssistant] - ) - - const value = useMemo( - () => ({ - assistantState, - setAssistantState, - clearAssistant, - onAssistantExecute - }), - [assistantState, clearAssistant, onAssistantExecute] - ) - - return ( - - {children} - - ) -} - -export default React.memo(AssistantProvider) diff --git a/src/assistant/AssistantWrapperDesktop.jsx b/src/assistant/AssistantWrapperDesktop.jsx deleted file mode 100644 index 7794bc7f11..0000000000 --- a/src/assistant/AssistantWrapperDesktop.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react' - -import CozyTheme from 'cozy-ui/transpiled/react/providers/CozyTheme' - -import SearchBar from './Search/SearchBar' -import SearchProvider from './Search/SearchProvider' -import AssistantProvider from './AssistantProvider' - -const AssistantWrapperDesktop = () => { - return ( - -
- - - - - -
-
- ) -} - -export default AssistantWrapperDesktop diff --git a/src/assistant/AssistantWrapperMobile.jsx b/src/assistant/AssistantWrapperMobile.jsx deleted file mode 100644 index ad9407e211..0000000000 --- a/src/assistant/AssistantWrapperMobile.jsx +++ /dev/null @@ -1,54 +0,0 @@ -import React from 'react' -import { useNavigate } from 'react-router-dom' -import flag from 'cozy-flags' -import cx from 'classnames' - -import { getFlagshipMetadata } from 'cozy-device-helper' -import CozyTheme, { - useCozyTheme -} from 'cozy-ui/transpiled/react/providers/CozyTheme' -import SearchBar from 'cozy-ui/transpiled/react/SearchBar' -import Icon from 'cozy-ui/transpiled/react/Icon' -import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' - -import AssistantIcon from 'assets/images/icon-assistant.png' -import { FLAG_FAB_BUTTON_ENABLED } from 'components/AddButton/helpers' -import { useWallpaperContext } from 'hooks/useWallpaperContext' - -import styles from './styles.styl' - -export const AssistantWrapperMobile = () => { - const { type } = useCozyTheme() - const { - data: { isCustomWallpaper } - } = useWallpaperContext() - const { t } = useI18n() - const navigate = useNavigate() - - return ( - -
- - } - type="button" - label={t('assistant.search.placeholder')} - onClick={() => navigate('connected/search')} - /> -
-
- ) -} - -export default AssistantWrapperMobile diff --git a/src/assistant/Conversations/ChatAssistantItem.jsx b/src/assistant/Conversations/ChatAssistantItem.jsx deleted file mode 100644 index 7dfc4e8c99..0000000000 --- a/src/assistant/Conversations/ChatAssistantItem.jsx +++ /dev/null @@ -1,30 +0,0 @@ -import React, { useMemo } from 'react' - -import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' -import Icon from 'cozy-ui/transpiled/react/Icon' - -import AssistantIcon from 'assets/images/icon-assistant.png' - -import Sources from './Sources/Sources' -import ChatItem from './ChatItem' - -const ChatAssistantItem = ({ className, id, label, sources, ...props }) => { - const { t } = useI18n() - // need memo to avoid rendering it everytime - const icon = useMemo(() => , []) - - return ( - <> - - {sources?.length > 0 && } - - ) -} - -export default ChatAssistantItem diff --git a/src/assistant/Conversations/ChatConversation.jsx b/src/assistant/Conversations/ChatConversation.jsx deleted file mode 100644 index 35c051777f..0000000000 --- a/src/assistant/Conversations/ChatConversation.jsx +++ /dev/null @@ -1,97 +0,0 @@ -import React, { useRef, useEffect } from 'react' - -import { useQuery, isQueryLoading } from 'cozy-client' - -import { buildChatConversationQueryById } from '../queries' -import { useAssistant } from '../AssistantProvider' -import { getInstantMessage } from '../helpers' -import ChatUserItem from './ChatUserItem' -import ChatAssistantItem from './ChatAssistantItem' -import ChatRealtimeAnswer from './ChatRealtimeAnswer' - -const ChatConversation = ({ conversation, myself }) => { - const { assistantState } = useAssistant() - const listRef = useRef() - const instantMessageKeysCount = Object.keys(assistantState.message).length - - // test on role === user to be sure the last response is inside io.cozy.ai.chat.conversations - const showRealtimeMessage = - assistantState.status !== 'idle' || - conversation?.messages?.[conversation?.messages?.length - 1]?.role === - 'user' - - useEffect(() => { - // force scroll down if new message of change in AI instant response - listRef.current?.lastElementChild?.scrollIntoView(false) - }, [ - conversation?.messages?.length, - assistantState.status, - instantMessageKeysCount - ]) - - return ( -
- {conversation?.messages.map((message, idx) => { - if (message.role === 'user') { - return ( - - ) - } - - if (idx !== conversation?.messages.length - 1) { - return ( - - ) - } - - if (showRealtimeMessage) { - return null - } - - return ( - - ) - })} - - {showRealtimeMessage && ( - - )} -
- ) -} - -const ChatConversationWithQuery = ({ id, myself }) => { - const chatConversationQuery = buildChatConversationQueryById(id) - const { data: chatConversation, ...queryResult } = useQuery( - chatConversationQuery.definition, - chatConversationQuery.options - ) - - const isLoading = isQueryLoading(queryResult) - - if (isLoading) return null - - return -} - -export default ChatConversationWithQuery diff --git a/src/assistant/Conversations/ChatItem.jsx b/src/assistant/Conversations/ChatItem.jsx deleted file mode 100644 index a768d7d37e..0000000000 --- a/src/assistant/Conversations/ChatItem.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react' - -import Typography from 'cozy-ui/transpiled/react/Typography' -import Box from 'cozy-ui/transpiled/react/Box' - -import ChatItemLabel from './ChatItemLabel' - -const ChatItem = ({ className, icon, name, label }) => { - return ( - <> - - {icon} - - {name} - - - - - - - ) -} - -export default ChatItem diff --git a/src/assistant/Conversations/ChatItemLabel.jsx b/src/assistant/Conversations/ChatItemLabel.jsx deleted file mode 100644 index 29335d7db9..0000000000 --- a/src/assistant/Conversations/ChatItemLabel.jsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react' - -import Markdown from 'cozy-ui/transpiled/react/Markdown' - -const ChatItemLabel = ({ label }) => { - if (typeof label === 'string') { - return - } - - return label -} - -// need memo to avoid rendering all label of all items -export default React.memo(ChatItemLabel) diff --git a/src/assistant/Conversations/ChatRealtimeAnswer.jsx b/src/assistant/Conversations/ChatRealtimeAnswer.jsx deleted file mode 100644 index 515c3a263b..0000000000 --- a/src/assistant/Conversations/ChatRealtimeAnswer.jsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react' - -import Skeleton from 'cozy-ui/transpiled/react/Skeleton' - -import ChatAssistantItem from './ChatAssistantItem' - -const ChatRealtimeAnswer = ({ isLoading, label }) => { - return ( - - - - - ) : ( - label - ) - } - /> - ) -} - -export default ChatRealtimeAnswer diff --git a/src/assistant/Conversations/ChatUserItem.jsx b/src/assistant/Conversations/ChatUserItem.jsx deleted file mode 100644 index 86caf86e64..0000000000 --- a/src/assistant/Conversations/ChatUserItem.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react' - -import { getDisplayName, getInitials } from 'cozy-client/dist/models/contact' -import Avatar from 'cozy-ui/transpiled/react/Avatar' - -import ChatItem from './ChatItem' - -const ChatUserItem = ({ className, label, myself, ...props }) => { - return ( - } - name={getDisplayName(myself)} - label={label} - /> - ) -} - -export default ChatUserItem diff --git a/src/assistant/Conversations/Conversation.jsx b/src/assistant/Conversations/Conversation.jsx deleted file mode 100644 index a1f64dc33e..0000000000 --- a/src/assistant/Conversations/Conversation.jsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' - -import { useQuery, isQueryLoading } from 'cozy-client' - -import { buildMyselfQuery } from '../queries' -import ChatConversation from './ChatConversation' - -const Conversation = ({ id }) => { - const myselfQuery = buildMyselfQuery() - const { data: myselves, ...queryMyselfResult } = useQuery( - myselfQuery.definition, - myselfQuery.options - ) - - const isLoading = isQueryLoading(queryMyselfResult) - - if (isLoading) return null - - return ( -
- -
- ) -} - -export default Conversation diff --git a/src/assistant/Conversations/ConversationBar.jsx b/src/assistant/Conversations/ConversationBar.jsx deleted file mode 100644 index 8e6de47218..0000000000 --- a/src/assistant/Conversations/ConversationBar.jsx +++ /dev/null @@ -1,115 +0,0 @@ -import React, { useState, useRef } from 'react' -import { useParams } from 'react-router-dom' - -import Icon from 'cozy-ui/transpiled/react/Icon' -import SearchBar from 'cozy-ui/transpiled/react/SearchBar' -import PaperplaneIcon from 'cozy-ui/transpiled/react/Icons/Paperplane' -import StopIcon from 'cozy-ui/transpiled/react/Icons/Stop' -import IconButton from 'cozy-ui/transpiled/react/IconButton' -import Button from 'cozy-ui/transpiled/react/Buttons' -import useEventListener from 'cozy-ui/transpiled/react/hooks/useEventListener' -import { useBreakpoints } from 'cozy-ui/transpiled/react/providers/Breakpoints' -import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' - -import { useAssistant } from '../AssistantProvider' - -import styles from './styles.styl' - -const ConversationBar = ({ assistantStatus }) => { - const { t } = useI18n() - const { isMobile } = useBreakpoints() - const { onAssistantExecute } = useAssistant() - const [inputValue, setInputValue] = useState('') - const inputRef = useRef() - const { conversationId } = useParams() - - // to adjust input height for multiline when typing in it - useEventListener(inputRef.current, 'input', () => { - inputRef.current.style.height = 'auto' // to resize input when emptying it - inputRef.current.style.height = `${inputRef.current.scrollHeight}px` - }) - - const handleClear = () => { - setInputValue('') - } - - const handleChange = ev => { - setInputValue(ev.target.value) - } - - const handleStop = () => { - // not supported right now - return - } - - const handleClick = () => - onAssistantExecute({ value: inputValue, conversationId }, () => { - handleClear() - inputRef.current.style.height = 'auto' - }) - - return ( -
- -
- ) -} - -export default ConversationBar diff --git a/src/assistant/Conversations/Sources/Sources.jsx b/src/assistant/Conversations/Sources/Sources.jsx deleted file mode 100644 index dbb92d924e..0000000000 --- a/src/assistant/Conversations/Sources/Sources.jsx +++ /dev/null @@ -1,91 +0,0 @@ -import React, { useState, useRef, useEffect } from 'react' - -import { useQuery, isQueryLoading } from 'cozy-client' - -import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' -import Icon from 'cozy-ui/transpiled/react/Icon' -import Chip from 'cozy-ui/transpiled/react/Chips' -import MultiFilesIcon from 'cozy-ui/transpiled/react/Icons/MultiFiles' -import RightIcon from 'cozy-ui/transpiled/react/Icons/Right' -import Box from 'cozy-ui/transpiled/react/Box' -import Grow from 'cozy-ui/transpiled/react/Grow' - -import { buildFilesByIds } from 'assistant/queries' -import SourcesItem from './SourcesItem' - -const Sources = ({ messageId, files }) => { - const [showSources, setShowSources] = useState(false) - const { t } = useI18n() - const ref = useRef() - - const handleShowSources = () => { - setShowSources(v => !v) - } - - // we want to scroll down to the sources button when it is displayed - useEffect(() => { - ref.current?.scrollIntoView(false) - }, []) - - useEffect(() => { - if (showSources) { - const sourcesBottom = ref.current.getBoundingClientRect().bottom - const innerContainer = - document.getElementsByClassName('cozyDialogContent')[0] - const innerContainerBottom = innerContainer.getBoundingClientRect().bottom - if (sourcesBottom > innerContainerBottom) { - ref.current.scrollIntoView(false) - } - } - }, [showSources]) - - return ( - - } - label={t('assistant.sources', files.length)} - deleteIcon={ - - } - clickable - onClick={handleShowSources} - onDelete={handleShowSources} - /> - -
- {files.map(file => ( - - ))} -
-
-
- ) -} - -const SourcesWithFilesQuery = ({ messageId, sources }) => { - const fileIds = sources.map(source => source.id) - - const filesByIds = buildFilesByIds(fileIds) - const { data: files, ...queryResult } = useQuery( - filesByIds.definition, - filesByIds.options - ) - - const isLoading = isQueryLoading(queryResult) - - if (isLoading || files.length === 0) return null - - return -} - -export default SourcesWithFilesQuery diff --git a/src/assistant/Conversations/Sources/SourcesItem.jsx b/src/assistant/Conversations/Sources/SourcesItem.jsx deleted file mode 100644 index cc0e328a9a..0000000000 --- a/src/assistant/Conversations/Sources/SourcesItem.jsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react' - -import { useClient, generateWebLink } from 'cozy-client' -import { isNote } from 'cozy-client/dist/models/file' -import Icon from 'cozy-ui/transpiled/react/Icon' -import ListItem from 'cozy-ui/transpiled/react/ListItem' -import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' -import ListItemText from 'cozy-ui/transpiled/react/ListItemText' - -import { getDriveMimeTypeIcon } from 'assistant/Search/getIconForSearchResult' - -import styles from './styles.styl' - -const SourcesItem = ({ file }) => { - const client = useClient() - - const docUrl = generateWebLink({ - slug: isNote(file) ? 'notes' : 'drive', - cozyUrl: client?.getStackClient().uri, - subDomainType: client?.getInstanceOptions().subdomain, - hash: isNote(file) - ? `/n/${file._id}` - : `/folder/${file.dir_id}/file/${file._id}` - }) - - return ( - - - - - - - ) -} - -export default SourcesItem diff --git a/src/assistant/Conversations/Sources/styles.styl b/src/assistant/Conversations/Sources/styles.styl deleted file mode 100644 index e6210102cf..0000000000 --- a/src/assistant/Conversations/Sources/styles.styl +++ /dev/null @@ -1,5 +0,0 @@ -.sourcesItem - // !important here to override Mui styles - margin-bottom 0.25rem !important - border 1px solid var(--borderMainColor) !important - border-radius 8px !important \ No newline at end of file diff --git a/src/assistant/Conversations/styles.styl b/src/assistant/Conversations/styles.styl deleted file mode 100644 index e7fe239cc4..0000000000 --- a/src/assistant/Conversations/styles.styl +++ /dev/null @@ -1,15 +0,0 @@ -@require 'settings/breakpoints.styl' - -.conversationBar - max-height 95px - min-height 48px - z-index calc(var(--zIndex-modal) + 15) - - +gt-mobile() - max-height 178px - -.conversationBar-input - max-height 80px - - +gt-mobile() - max-height 155px diff --git a/src/assistant/ResultMenu/ResultMenu.jsx b/src/assistant/ResultMenu/ResultMenu.jsx deleted file mode 100644 index 4595190641..0000000000 --- a/src/assistant/ResultMenu/ResultMenu.jsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' - -import Paper from 'cozy-ui/transpiled/react/Paper' -import Popper from 'cozy-ui/transpiled/react/Popper' - -import ResultMenuContent from './ResultMenuContent' - -import styles from './styles.styl' - -const ResultMenu = ({ anchorRef, listRef, onClick }) => { - return ( - - -
- -
-
-
- ) -} - -export default ResultMenu diff --git a/src/assistant/ResultMenu/ResultMenuContent.jsx b/src/assistant/ResultMenu/ResultMenuContent.jsx deleted file mode 100644 index e2b1856dcd..0000000000 --- a/src/assistant/ResultMenu/ResultMenuContent.jsx +++ /dev/null @@ -1,78 +0,0 @@ -import React, { forwardRef } from 'react' - -import flag from 'cozy-flags' -import List from 'cozy-ui/transpiled/react/List' -import Circle from 'cozy-ui/transpiled/react/Circle' -import PaperplaneIcon from 'cozy-ui/transpiled/react/Icons/Paperplane' -import Icon from 'cozy-ui/transpiled/react/Icon' -import ListItemSkeleton from 'cozy-ui/transpiled/react/Skeletons/ListItemSkeleton' -import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' -import { useBreakpoints } from 'cozy-ui/transpiled/react/providers/Breakpoints' - -import { useDataProxy } from 'dataproxy/DataProxyProvider' - -import { useSearch } from '../Search/SearchProvider' -import ResultMenuItem from './ResultMenuItem' - -const SearchResult = () => { - const { isLoading, results, selectedIndex, searchValue } = useSearch() - - if (isLoading && !results?.length) - return ( - <> - - - - - ) - - return results.map((result, idx) => ( - - )) -} - -const ResultMenuContent = forwardRef(({ onClick }, ref) => { - const { t } = useI18n() - const { isMobile } = useBreakpoints() - const { searchValue, selectedIndex } = useSearch() - const { dataProxyServicesAvailable } = useDataProxy() - - return ( - - {flag('cozy.assistant.enabled') && ( - - - - } - primaryText={searchValue} - query={searchValue} - secondaryText={t('assistant.search.result')} - selected={selectedIndex === 0} - onClick={onClick} - /> - )} - {dataProxyServicesAvailable && } - - ) -}) - -ResultMenuContent.displayName = 'ResultMenuContent' - -export default ResultMenuContent diff --git a/src/assistant/ResultMenu/ResultMenuItem.jsx b/src/assistant/ResultMenu/ResultMenuItem.jsx deleted file mode 100644 index ec80cec23f..0000000000 --- a/src/assistant/ResultMenu/ResultMenuItem.jsx +++ /dev/null @@ -1,56 +0,0 @@ -import React from 'react' - -import AppIcon from 'cozy-ui/transpiled/react/AppIcon' -import Icon from 'cozy-ui/transpiled/react/Icon' -import ListItem from 'cozy-ui/transpiled/react/ListItem' -import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' -import ListItemText from 'cozy-ui/transpiled/react/ListItemText' -import SuggestionItemTextHighlighted from './SuggestionItemTextHighlighted' -import SuggestionItemTextSecondary from './SuggestionItemTextSecondary' - -const ResultMenuItem = ({ - icon, - primaryText, - secondaryText, - secondaryUrl, - slug, - selected, - onClick, - query, - highlightQuery = false -}) => { - const iconComponent = - icon.type === 'component' ? ( - - ) : icon.type === 'app' ? ( - - ) : ( - icon - ) - - const primary = highlightQuery ? ( - - ) : ( - primaryText - ) - - const secondary = highlightQuery ? ( - - ) : ( - secondaryText - ) - - return ( - - {iconComponent} - - - ) -} - -export default ResultMenuItem diff --git a/src/assistant/ResultMenu/SuggestionItemTextHighlighted.jsx b/src/assistant/ResultMenu/SuggestionItemTextHighlighted.jsx deleted file mode 100644 index eca4b0075f..0000000000 --- a/src/assistant/ResultMenu/SuggestionItemTextHighlighted.jsx +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Code copied and adapted from cozy-drive - * - * See source: https://github.com/cozy/cozy-drive/blob/fbe2df67199683b23a40f476ccdacb00ee027459/src/modules/search/components/SuggestionItemTextHighlighted.jsx - */ - -import React from 'react' - -const normalizeString = str => - str - .toString() - .toLowerCase() - .replace(/\//g, ' ') - .normalize('NFD') - .replace(/[\u0300-\u036f]/g, '') - .split(' ') - -/** - * Add on part that equlas query into each result - * - * @param {Array} searchResult - list of results - * @param {string} query - search input - * @returns list of results with the query highlighted - */ -const highlightQueryTerms = (searchResult, query) => { - const normalizedQueryTerms = normalizeString(query) - const normalizedResultTerms = normalizeString(searchResult) - - const matchedIntervals = [] - const spacerLength = 1 - let currentIndex = 0 - - normalizedResultTerms.forEach(resultTerm => { - normalizedQueryTerms.forEach(queryTerm => { - const index = resultTerm.indexOf(queryTerm) - if (index >= 0) { - matchedIntervals.push({ - from: currentIndex + index, - to: currentIndex + index + queryTerm.length - }) - } - }) - - currentIndex += resultTerm.length + spacerLength - }) - - // matchedIntervals can overlap, so we merge them. - // - sort the intervals by starting index - // - add the first interval to the stack - // - for every interval, - // - - add it to the stack if it doesn't overlap with the stack top - // - - or extend the stack top if the start overlaps and the new interval's top is bigger - const mergedIntervals = matchedIntervals - .sort((intervalA, intervalB) => intervalA.from > intervalB.from) - .reduce((computedIntervals, newInterval) => { - if ( - computedIntervals.length === 0 || - computedIntervals[computedIntervals.length - 1].to < newInterval.from - ) { - computedIntervals.push(newInterval) - } else if ( - computedIntervals[computedIntervals.length - 1].to < newInterval.to - ) { - computedIntervals[computedIntervals.length - 1].to = newInterval.to - } - - return computedIntervals - }, []) - - // create an array containing the entire search result, with special characters, and the intervals surrounded y `` tags - const slicedOriginalResult = - mergedIntervals.length > 0 - ? [{searchResult.slice(0, mergedIntervals[0].from)}] - : searchResult - - for (let i = 0, l = mergedIntervals.length; i < l; ++i) { - slicedOriginalResult.push( - - {searchResult.slice(mergedIntervals[i].from, mergedIntervals[i].to)} - - ) - if (i + 1 < l) - slicedOriginalResult.push( - - {searchResult.slice( - mergedIntervals[i].to, - mergedIntervals[i + 1].from - )} - - ) - } - - if (mergedIntervals.length > 0) - slicedOriginalResult.push( - - {searchResult.slice( - mergedIntervals[mergedIntervals.length - 1].to, - searchResult.length - )} - - ) - - return slicedOriginalResult -} - -const SuggestionItemTextHighlighted = ({ text, query }) => { - if (!text) return null - - const textHighlighted = highlightQueryTerms(text, query) - if (Array.isArray(textHighlighted)) { - return textHighlighted.map((item, idx) => ({ - ...item, - key: idx - })) - } - return textHighlighted -} - -export default SuggestionItemTextHighlighted diff --git a/src/assistant/ResultMenu/SuggestionItemTextSecondary.jsx b/src/assistant/ResultMenu/SuggestionItemTextSecondary.jsx deleted file mode 100644 index a2e5522aab..0000000000 --- a/src/assistant/ResultMenu/SuggestionItemTextSecondary.jsx +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Code copied and adapted from cozy-drive - * - * See source: https://github.com/cozy/cozy-drive/blob/fbe2df67199683b23a40f476ccdacb00ee027459/src/modules/search/components/SuggestionItemTextSecondary.jsx - */ -import React from 'react' - -import AppLinker from 'cozy-ui/transpiled/react/AppLinker' -import SuggestionItemTextHighlighted from './SuggestionItemTextHighlighted' -import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints' -import Link from 'cozy-ui/transpiled/react/Link' - -const SuggestionItemTextSecondary = ({ text, query, url, slug }) => { - const { isMobile } = useBreakpoints() - - if (isMobile || !url) { - return - } - - const app = { slug } - return ( - - {({ href, onClick }) => ( - { - e.stopPropagation() - if (typeof onClick == 'function') { - onClick(e) - } - }} - > - - - )} - - ) -} - -export default SuggestionItemTextSecondary diff --git a/src/assistant/ResultMenu/styles.styl b/src/assistant/ResultMenu/styles.styl deleted file mode 100644 index 4c79c311eb..0000000000 --- a/src/assistant/ResultMenu/styles.styl +++ /dev/null @@ -1,10 +0,0 @@ -.resultMenu - overflow hidden - margin 0 auto - max-width 50rem - max-height 16.5rem - border-radius 0 0 28px 28px - - &-inner - max-height 16.5rem - overflow auto diff --git a/src/assistant/Search/EncryptedFolderIcon.jsx b/src/assistant/Search/EncryptedFolderIcon.jsx deleted file mode 100644 index ac87226b8c..0000000000 --- a/src/assistant/Search/EncryptedFolderIcon.jsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' - -const EncryptedFolderIcon = props => { - return ( - - - - - ) -} - -export default EncryptedFolderIcon diff --git a/src/assistant/Search/SearchBar.jsx b/src/assistant/Search/SearchBar.jsx deleted file mode 100644 index 017c8817e4..0000000000 --- a/src/assistant/Search/SearchBar.jsx +++ /dev/null @@ -1,45 +0,0 @@ -import React, { useState } from 'react' - -import { useBreakpoints } from 'cozy-ui/transpiled/react/providers/Breakpoints' - -import { useSearch } from './SearchProvider' - -import SearchBarMobile from './SearchBarMobile' -import SearchBarDesktop from './SearchBarDesktop' - -const SearchBar = () => { - const { isMobile } = useBreakpoints() - const [inputValue, setInputValue] = useState('') - const { clearSearch, setSelectedIndex, delayedSetSearchValue } = useSearch() - - const handleClear = () => { - setInputValue('') - clearSearch() - } - - const handleChange = ev => { - setSelectedIndex(0) - delayedSetSearchValue(ev.target.value) - setInputValue(ev.target.value) - } - - if (isMobile) { - return ( - - ) - } - - return ( - - ) -} - -export default SearchBar diff --git a/src/assistant/Search/SearchBarDesktop.jsx b/src/assistant/Search/SearchBarDesktop.jsx deleted file mode 100644 index e22846ed6c..0000000000 --- a/src/assistant/Search/SearchBarDesktop.jsx +++ /dev/null @@ -1,108 +0,0 @@ -import React, { useRef } from 'react' -import { useNavigate } from 'react-router-dom' - -import flag from 'cozy-flags' -import ClickAwayListener from 'cozy-ui/transpiled/react/ClickAwayListener' -import SearchBar from 'cozy-ui/transpiled/react/SearchBar' -import Icon from 'cozy-ui/transpiled/react/Icon' -import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' - -import AssistantIcon from 'assets/images/icon-assistant.png' - -import ResultMenu from '../ResultMenu/ResultMenu' -import { useAssistant } from '../AssistantProvider' -import { makeConversationId } from '../helpers' -import { useSearch } from './SearchProvider' - -import styles from './styles.styl' - -const SearchBarDesktop = ({ value, onClear, onChange }) => { - const { t } = useI18n() - const { searchValue, results, selectedIndex, setSelectedIndex } = useSearch() - const { onAssistantExecute } = useAssistant() - const navigate = useNavigate() - const searchRef = useRef() - const listRef = useRef() - - const handleClick = () => { - if (!flag('cozy.assistant.enabled')) return - - const conversationId = makeConversationId() - onAssistantExecute({ value, conversationId }) - navigate(`assistant/${conversationId}`) - // setTimeout usefull to prevent the field from emptying before the route is changed - // works because the modal appears on top of the view that carries the input and not instead of it. - setTimeout(() => { - onClear() - }, 100) - } - - const handleKeyDown = ev => { - const listElementCount = listRef.current?.childElementCount - - if (ev.key === 'ArrowDown') { - ev.preventDefault() - - if (selectedIndex === listElementCount - 1) { - setSelectedIndex(0) - } else { - setSelectedIndex(v => v + 1) - } - } - - if (ev.key === 'ArrowUp') { - ev.preventDefault() - - if (selectedIndex === 0) { - setSelectedIndex(listElementCount - 1) - } else { - setSelectedIndex(v => v - 1) - } - } - - if (ev.key === 'Escape') { - ev.preventDefault() - onClear() - } - - if (ev.key === 'Enter') { - ev.preventDefault() - if (selectedIndex) { - const onClickFn = results?.[selectedIndex - 1]?.onClick || handleClick - onClickFn() - } else if (value !== '') { - handleClick() - } - } - } - - return ( - - - } - placeholder={t('assistant.search.placeholder')} - value={value} - componentsProps={{ - inputBase: { onKeyDown: handleKeyDown } - }} - disabledClear - disabledFocus={value !== ''} - onChange={onChange} - /> - {searchValue && ( - - )} - - - ) -} - -export default SearchBarDesktop diff --git a/src/assistant/Search/SearchBarMobile.jsx b/src/assistant/Search/SearchBarMobile.jsx deleted file mode 100644 index e69f3989dc..0000000000 --- a/src/assistant/Search/SearchBarMobile.jsx +++ /dev/null @@ -1,49 +0,0 @@ -import React, { useRef } from 'react' - -import SearchBar from 'cozy-ui/transpiled/react/SearchBar' -import useEventListener from 'cozy-ui/transpiled/react/hooks/useEventListener' - -import SuggestionsPlaceholder from './SuggestionsPlaceholder' - -import styles from '../Conversations/styles.styl' - -const SearchBarMobile = ({ value, onClear, onChange }) => { - const inputRef = useRef() - - // to adjust input height for multiline when typing in it - useEventListener(inputRef.current, 'input', () => { - inputRef.current.style.height = 'auto' // to resize input when emptying it - inputRef.current.style.height = `${inputRef.current.scrollHeight}px` - }) - - const handleClear = () => { - onClear() - inputRef.current.style.height = 'auto' - } - - return ( - - } - }} - onChange={onChange} - onClear={handleClear} - /> - ) -} - -export default SearchBarMobile diff --git a/src/assistant/Search/SearchProvider.jsx b/src/assistant/Search/SearchProvider.jsx deleted file mode 100644 index 680bb35c7d..0000000000 --- a/src/assistant/Search/SearchProvider.jsx +++ /dev/null @@ -1,58 +0,0 @@ -import React, { useMemo, useContext, useState, useCallback } from 'react' -import debounce from 'lodash/debounce' - -import { useFetchResult } from './useFetchResult' - -export const SearchContext = React.createContext() - -export const useSearch = () => { - const context = useContext(SearchContext) - - if (!context) { - throw new Error('useSearch must be used within a SearchProvider') - } - return context -} - -const SearchProvider = ({ children }) => { - const [searchValue, setSearchValue] = useState('') - const [selectedIndex, setSelectedIndex] = useState() - const { isLoading, results } = useFetchResult(searchValue) - - const delayedSetSearchValue = useMemo( - () => debounce(setSearchValue, 250), - [setSearchValue] - ) - - const clearSearch = useCallback(() => { - setSearchValue('') - setSelectedIndex() - }, []) - - const value = useMemo( - () => ({ - searchValue, - setSearchValue, - delayedSetSearchValue, - isLoading, - clearSearch, - selectedIndex, - setSelectedIndex, - results - }), - [ - searchValue, - delayedSetSearchValue, - isLoading, - clearSearch, - selectedIndex, - results - ] - ) - - return ( - {children} - ) -} - -export default React.memo(SearchProvider) diff --git a/src/assistant/Search/SearchSubmitFab.jsx b/src/assistant/Search/SearchSubmitFab.jsx deleted file mode 100644 index e96e8eb666..0000000000 --- a/src/assistant/Search/SearchSubmitFab.jsx +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' - -import Fab from 'cozy-ui/transpiled/react/Fab' -import Icon from 'cozy-ui/transpiled/react/Icon' -import PaperplaneIcon from 'cozy-ui/transpiled/react/Icons/Paperplane' -import { makeStyles } from 'cozy-ui/transpiled/react/styles' -import { getFlagshipMetadata } from 'cozy-device-helper' -import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' - -const useStyles = makeStyles({ - root: { - right: '1rem', - bottom: '1rem', - position: 'fixed', - marginBottom: ({ immersive }) => - immersive ? 'var(--flagship-bottom-height)' : 0 - } -}) - -const SearchSubmitFab = ({ searchValue, onClick }) => { - const { t } = useI18n() - const styles = useStyles({ immersive: getFlagshipMetadata().immersive }) - - return ( - - - - ) -} - -export default SearchSubmitFab diff --git a/src/assistant/Search/SuggestionsPlaceholder.jsx b/src/assistant/Search/SuggestionsPlaceholder.jsx deleted file mode 100644 index 29b3369190..0000000000 --- a/src/assistant/Search/SuggestionsPlaceholder.jsx +++ /dev/null @@ -1,42 +0,0 @@ -import React, { useState } from 'react' -import { TypeAnimation } from 'react-type-animation' -import { useTimeoutWhen } from 'rooks' - -import Typography from 'cozy-ui/transpiled/react/Typography' -import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n' - -import styles from './styles.styl' - -const SuggestionsPlaceholder = () => { - const { t } = useI18n() - const [showSuggestions, setShowSuggestions] = useState(false) - - useTimeoutWhen(() => setShowSuggestions(true), 2500) - - return ( -
- - {showSuggestions ? ( - - ) : ( - t('assistant.search.placeholder') - )} - -
- ) -} - -export default SuggestionsPlaceholder diff --git a/src/assistant/Search/getFileMimetype.js b/src/assistant/Search/getFileMimetype.js deleted file mode 100644 index 7b36cb5de9..0000000000 --- a/src/assistant/Search/getFileMimetype.js +++ /dev/null @@ -1,37 +0,0 @@ -import mime from 'mime-types' - -const getMimetypeFromFilename = name => { - return mime.lookup(name) || 'application/octet-stream' -} - -const mappingMimetypeSubtype = { - word: 'text', - text: 'text', - zip: 'zip', - pdf: 'pdf', - spreadsheet: 'sheet', - excel: 'sheet', - sheet: 'sheet', - presentation: 'slide', - powerpoint: 'slide' -} - -export const getFileMimetype = - collection => - (mime = '', name = '') => { - const mimetype = - mime === 'application/octet-stream' - ? getMimetypeFromFilename(name.toLowerCase()) - : mime - const [type, subtype] = mimetype.split('/') - if (collection[type]) { - return type - } - if (type === 'application') { - const existingType = subtype.match( - Object.keys(mappingMimetypeSubtype).join('|') - ) - return existingType ? mappingMimetypeSubtype[existingType[0]] : undefined - } - return undefined - } diff --git a/src/assistant/Search/getIconForSearchResult.js b/src/assistant/Search/getIconForSearchResult.js deleted file mode 100644 index 4ddbaca60a..0000000000 --- a/src/assistant/Search/getIconForSearchResult.js +++ /dev/null @@ -1,103 +0,0 @@ -import get from 'lodash/get' - -import ContactsIcon from 'cozy-ui/transpiled/react/Icons/Contacts' -import IconAudio from 'cozy-ui/transpiled/react/Icons/FileTypeAudio' -import IconBin from 'cozy-ui/transpiled/react/Icons/FileTypeBin' -import IconCode from 'cozy-ui/transpiled/react/Icons/FileTypeCode' -import IconFiles from 'cozy-ui/transpiled/react/Icons/FileTypeFiles' -import IconFolder from 'cozy-ui/transpiled/react/Icons/FileTypeFolder' -import IconImage from 'cozy-ui/transpiled/react/Icons/FileTypeImage' -import IconNote from 'cozy-ui/transpiled/react/Icons/FileTypeNote' -import IconPdf from 'cozy-ui/transpiled/react/Icons/FileTypePdf' -import IconSheet from 'cozy-ui/transpiled/react/Icons/FileTypeSheet' -import IconSlide from 'cozy-ui/transpiled/react/Icons/FileTypeSlide' -import IconText from 'cozy-ui/transpiled/react/Icons/FileTypeText' -import IconVideo from 'cozy-ui/transpiled/react/Icons/FileTypeVideo' -import IconZip from 'cozy-ui/transpiled/react/Icons/FileTypeZip' - -import EncryptedFolderIcon from './EncryptedFolderIcon' -import { getFileMimetype } from './getFileMimetype' - -export const getIconForSearchResult = searchResult => { - if (searchResult.doc._type === 'io.cozy.apps') { - return { - type: 'app', - app: searchResult.doc - } - } - - if (searchResult.slug === 'notes') { - return { - type: 'component', - component: IconNote - } - } - - if (searchResult.slug === 'drive') { - return { - type: 'component', - component: getDriveMimeTypeIcon( - searchResult.doc.type === 'directory', - searchResult.doc.name, - searchResult.doc.mime - ) - } - } - - if (searchResult.slug === 'contacts') { - return { - type: 'component', - component: ContactsIcon - } - } - - return { - type: 'component', - component: IconFiles - } -} - -/** - * Returns the appropriate icon for a given file based on its mime type and other properties. - * - * This method has been copied from cozy-drive - * - * See source: https://github.com/cozy/cozy-drive/blob/fbe2df67199683b23a40f476ccdacb00ee027459/src/lib/getMimeTypeIcon.js - * - * @param {boolean} isDirectory - Indicates whether the file is a directory. - * @param {string} name - The name of the file. - * @param {string} mime - The mime type of the file. - * @param {Object} [options] - Additional options. - * @param {boolean} [options.isEncrypted] - Indicates whether the file is encrypted. Default is false. - * @returns {import('react').ReactNode} - The icon corresponding to the file's mime type. - */ -export const getDriveMimeTypeIcon = ( - isDirectory, - name, - mime, - { isEncrypted = false } = {} -) => { - if (isEncrypted) { - return EncryptedFolderIcon - } - if (isDirectory) { - return IconFolder - } else if (/\.cozy-note$/.test(name)) { - return IconNote - } else { - const iconsByMimeType = { - audio: IconAudio, - bin: IconBin, - code: IconCode, - image: IconImage, - pdf: IconPdf, - slide: IconSlide, - sheet: IconSheet, - text: IconText, - video: IconVideo, - zip: IconZip - } - const type = getFileMimetype(iconsByMimeType)(mime, name) - return get(iconsByMimeType, type, IconFiles) - } -} diff --git a/src/assistant/Search/styles.styl b/src/assistant/Search/styles.styl deleted file mode 100644 index 09eeab688c..0000000000 --- a/src/assistant/Search/styles.styl +++ /dev/null @@ -1,7 +0,0 @@ -.searchBarDesktop--result - border-radius 28px 28px 0 0 !important - -.suggestionsPlaceholder - position absolute - opacity 0.42 - pointer-events none diff --git a/src/assistant/Search/useFetchResult.jsx b/src/assistant/Search/useFetchResult.jsx deleted file mode 100644 index 9a88325799..0000000000 --- a/src/assistant/Search/useFetchResult.jsx +++ /dev/null @@ -1,65 +0,0 @@ -import { useEffect, useState } from 'react' - -import Minilog from 'cozy-minilog' - -import { useDataProxy } from 'dataproxy/DataProxyProvider' - -import { getIconForSearchResult } from './getIconForSearchResult' - -const log = Minilog('🔍 [useFetchResult]') - -export const useFetchResult = searchValue => { - const [state, setState] = useState({ - isLoading: true, - results: null, - searchValue: null - }) - const dataProxy = useDataProxy() - - useEffect(() => { - const fetch = async searchValue => { - if (!dataProxy.dataProxyServicesAvailable) { - log.log('DataProxy services are not available. Skipping search...') - return - } - - setState({ isLoading: true, results: null, searchValue }) - - const searchResults = await dataProxy.search(searchValue) - - const results = searchResults.map(r => { - // Begin Retrocompatibility code, to be removed when following PR is merged: https://github.com/cozy/cozy-web-data-proxy/pull/10 - r.slug = r.slug || r.type - r.subTitle = r.subTitle || r.name - // End Retrocompatibility code - const icon = getIconForSearchResult(r) - return { - id: r.doc._id, - icon: icon, - slug: r.slug, - secondaryUrl: r.secondaryUrl, - primary: r.title, - secondary: r.subTitle, - onClick: () => { - window.open(r.url) - } - } - }) - - setState({ isLoading: false, results, searchValue }) - } - - if (searchValue) { - if (searchValue !== state.searchValue) { - fetch(searchValue) - } - } else { - setState({ isLoading: true, results: null, searchValue: null }) - } - }, [dataProxy, searchValue, state.searchValue, setState]) - - return { - isLoading: state.isLoading, - results: state.results - } -} diff --git a/src/assistant/Views/AssistantDialog.jsx b/src/assistant/Views/AssistantDialog.jsx deleted file mode 100644 index 7d6e0a0694..0000000000 --- a/src/assistant/Views/AssistantDialog.jsx +++ /dev/null @@ -1,50 +0,0 @@ -import React from 'react' -import { useNavigate, useParams } from 'react-router-dom' - -import { FixedDialog } from 'cozy-ui/transpiled/react/CozyDialogs' -import CozyTheme from 'cozy-ui/transpiled/react/providers/CozyTheme' -import { useBreakpoints } from 'cozy-ui/transpiled/react/providers/Breakpoints' - -import Conversation from '../Conversations/Conversation' -import ConversationBar from '../Conversations/ConversationBar' -import AssistantProvider, { useAssistant } from '../AssistantProvider' - -const AssistantDialog = () => { - const { assistantState } = useAssistant() - const { isMobile } = useBreakpoints() - const navigate = useNavigate() - const { conversationId } = useParams() - - const onClose = () => { - navigate('..') - } - - return ( - } - actions={} - onClose={onClose} - /> - ) -} - -const AssistantDialogWithProviders = () => { - return ( - - - - - - ) -} - -export default AssistantDialogWithProviders diff --git a/src/assistant/Views/SearchDialog.jsx b/src/assistant/Views/SearchDialog.jsx deleted file mode 100644 index 15bac15817..0000000000 --- a/src/assistant/Views/SearchDialog.jsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react' -import { useNavigate } from 'react-router-dom' - -import flag from 'cozy-flags' -import { FixedDialog } from 'cozy-ui/transpiled/react/CozyDialogs' -import CozyTheme from 'cozy-ui/transpiled/react/providers/CozyTheme' - -import SearchProvider from '../Search/SearchProvider' -import AssistantProvider, { useAssistant } from '../AssistantProvider' -import { makeConversationId } from '../helpers' -import ResultMenuContent from '../ResultMenu/ResultMenuContent' -import { useSearch } from '../Search/SearchProvider' -import SearchBar from '../Search/SearchBar' -import SearchSubmitFab from '../Search/SearchSubmitFab' - -const SearchDialog = () => { - const { onAssistantExecute } = useAssistant() - const navigate = useNavigate() - const { searchValue } = useSearch() - - const handleClick = () => { - const conversationId = makeConversationId() - onAssistantExecute({ value: searchValue, conversationId }) - navigate(`../assistant/${conversationId}`, { replace: true }) - } - - const handleClose = () => { - navigate('..') - } - - return ( - } - content={ - <> - {searchValue && } - {flag('cozy.assistant.enabled') && ( - - )} - - } - onClose={handleClose} - /> - ) -} - -const SearchDialogWithProviders = () => { - return ( - - - - - - - - ) -} - -export default SearchDialogWithProviders diff --git a/src/assistant/helpers.js b/src/assistant/helpers.js deleted file mode 100644 index 6d53d54589..0000000000 --- a/src/assistant/helpers.js +++ /dev/null @@ -1,21 +0,0 @@ -export const getInstantMessage = assistantState => - Object.keys(assistantState.message) - .sort((a, b) => a - b) - .map(key => assistantState.message[key]) - .join('') - -export const makeConversationId = () => - `${Date.now()}-${Math.floor(Math.random() * 90000) + 10000}` - -export const pushMessagesIdInState = (id, res, setState) => { - if (id !== res._id) return - - const messagesId = res.messages.map(message => message.id) - setState(v => ({ - ...v, - messagesId - })) -} - -export const isMessageForThisConversation = (res, messagesId) => - messagesId.includes(res._id) diff --git a/src/assistant/queries.js b/src/assistant/queries.js deleted file mode 100644 index cf24beaf11..0000000000 --- a/src/assistant/queries.js +++ /dev/null @@ -1,39 +0,0 @@ -import { Q, fetchPolicies } from 'cozy-client' - -const CONTACTS_DOCTYPE = 'io.cozy.contacts' -export const CHAT_CONVERSATIONS_DOCTYPE = 'io.cozy.ai.chat.conversations' -export const CHAT_EVENTS_DOCTYPE = 'io.cozy.ai.chat.events' -export const FILES_DOCTYPE = 'io.cozy.files' - -const defaultFetchPolicy = fetchPolicies.olderThan(86_400_000) // 24 hours - -export const buildFilesByIds = ids => { - return { - definition: Q(FILES_DOCTYPE).getByIds(ids), - options: { - as: `${FILES_DOCTYPE}/${ids.join('')}`, - fetchPolicy: defaultFetchPolicy - } - } -} - -export const buildChatConversationQueryById = id => { - return { - definition: Q(CHAT_CONVERSATIONS_DOCTYPE).getById(id), - options: { - as: `${CHAT_CONVERSATIONS_DOCTYPE}/${id}`, - fetchPolicy: defaultFetchPolicy, - singleDocData: true - } - } -} - -export const buildMyselfQuery = () => { - return { - definition: Q(CONTACTS_DOCTYPE).where({ me: true }), - options: { - as: `${CONTACTS_DOCTYPE}/myself`, - fetchPolicy: defaultFetchPolicy - } - } -} diff --git a/src/assistant/styles.styl b/src/assistant/styles.styl deleted file mode 100644 index 9122897516..0000000000 --- a/src/assistant/styles.styl +++ /dev/null @@ -1,18 +0,0 @@ -.assistantWrapper-mobile - position fixed - bottom 0 - right 0 - left 0 - padding 1rem - - &--light - background-color #E9F4FF - - &--dark - background-color #142536 - - &--offset - padding-right 4.5rem - - &--immersive - padding-bottom calc(1rem + var(--flagship-bottom-height)) diff --git a/src/locales/en.json b/src/locales/en.json index 819d1240d6..80202a9de5 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1,21 +1,4 @@ { - "assistant": { - "search": { - "placeholder": "Any question?", - "send": "Send", - "result": "Ask the assistant" - }, - "dialog": { - "close": "Close" - }, - "name":"Cozy Assistant", - "sources":"%{smart_count} source |||| %{smart_count} sources", - "suggestions": { - "find_file": "Search a file", - "reimbursements": "Check my repayments", - "reorganise_files": "Reorganise my files" - } - }, "app": { "logo": { "alt": "%{name} logo" diff --git a/src/locales/fr.json b/src/locales/fr.json index 703de1321e..ae8b4f6cca 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -1,21 +1,4 @@ { - "assistant": { - "search": { - "placeholder": "Une question ?", - "send": "Envoyer", - "result": "Demander Ă  l'assistant" - }, - "dialog": { - "close": "Fermer" - }, - "name":"Assistant Cozy", - "sources":"%{smart_count} source |||| %{smart_count} sources", - "suggestions": { - "find_file": "Rechercher un fichier", - "reimbursements": "VĂ©rifier mes remboursements", - "reorganise_files": "RĂ©organiser mes fichiers" - } - }, "app": { "logo": { "alt": "Logo de %{name}"