diff --git a/twake/frontend/src/app/components/search-popup/parts/recent/media-result.tsx b/twake/frontend/src/app/components/search-popup/parts/recent/media-result.tsx
index b61820c5e3..1a089e371c 100644
--- a/twake/frontend/src/app/components/search-popup/parts/recent/media-result.tsx
+++ b/twake/frontend/src/app/components/search-popup/parts/recent/media-result.tsx
@@ -1,10 +1,7 @@
import React from 'react';
-import { FileType } from 'features/files/types/file';
import { FileSearchResult } from 'features/messages/types/message';
import Logger from 'features/global/framework/logger-service';
-import {
- getFileMessageDownloadRoute,
-} from 'components/search-popup/parts/common';
+import { getFileMessageDownloadRoute } from 'components/search-popup/parts/common';
import assert from 'assert';
type PropsType = {
diff --git a/twake/frontend/src/app/components/search-popup/parts/users-result.tsx b/twake/frontend/src/app/components/search-popup/parts/users-result.tsx
index 662d1b3667..8c2a7341b4 100755
--- a/twake/frontend/src/app/components/search-popup/parts/users-result.tsx
+++ b/twake/frontend/src/app/components/search-popup/parts/users-result.tsx
@@ -15,6 +15,8 @@ type PropsType = {
export default ({ user, highlight, onClick }: PropsType): JSX.Element => {
const { openDiscussion } = useDirectChannels();
+ console.log(user.full_name);
+
const thumbnail =
User.getThumbnail(user) ||
'data:image/svg+xml;base64, PHN2ZyB3aWR0aD0iNTciIGhlaWdodD0iNTYiIHZpZXdCb3g9IjAgMCA1NyA1NiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iMjguOTk2MSIgY3k9IjI4IiByPSIyOCIgZmlsbD0idXJsKCNwYWludDBfbGluZWFyXzk1Ml82ODM4NSkiLz4KPGNpcmNsZSBjeD0iMjguOTk2MSIgY3k9IjI4IiByPSIyNy43NSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLW9wYWNpdHk9IjAuMDgiIHN0cm9rZS13aWR0aD0iMC41IiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfOTUyXzY4Mzg1IiB4MT0iMjguOTk2MSIgeTE9IjAiIHgyPSIyOC45OTYxIiB5Mj0iNTYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzZFRDFGQiIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyNkE0RjgiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K';
diff --git a/twake/frontend/src/app/components/search-popup/search-popup.js b/twake/frontend/src/app/components/search-popup/search-popup.js
index b3e04e78ae..391ffe4b6e 100755
--- a/twake/frontend/src/app/components/search-popup/search-popup.js
+++ b/twake/frontend/src/app/components/search-popup/search-popup.js
@@ -30,19 +30,11 @@ export default class SearchPopup extends React.Component {
const tabs = [
{ key: 'all', title: 'All' },
+ { key: 'chats', title: 'Chats' },
{ key: 'media', title: 'Media' },
{ key: 'files', title: 'Files' },
];
- const experimentalTabs = ['Chats'];
-
- for (let tabName of experimentalTabs) {
- const tabNameLC = tabName.toLowerCase();
- if (localStorage.getItem(`search-tabs-${tabNameLC}`)) {
- tabs.push({ key: tabNameLC, title: tabName });
- }
- }
-
this.tabs = tabs;
}
componentDidMount() {
diff --git a/twake/frontend/src/app/components/search-popup/search-popup.scss b/twake/frontend/src/app/components/search-popup/search-popup.scss
index 07483a1a6e..9777244762 100755
--- a/twake/frontend/src/app/components/search-popup/search-popup.scss
+++ b/twake/frontend/src/app/components/search-popup/search-popup.scss
@@ -117,7 +117,7 @@ input:focus {
//position: absolute;
width: 100vw;
- height: 100vh;
+ height: calc(100vh - 20px);
max-width: 1000px;
@@ -444,7 +444,7 @@ input:focus {
}
}
- .recent-results {
+ .search-results {
.result-items-channel {
padding: 4px;
display: flex;
@@ -534,7 +534,7 @@ input:focus {
.result-items-media {
display: flex;
flex-direction: row;
- height: 130px;
+ height: 128px;
.result-item {
//box-shadow: 1px 1px 3px #ccc;
padding: 4px;
@@ -542,8 +542,8 @@ input:focus {
img {
object-fit: cover;
cursor: pointer;
- width: 129px;
- height: 129px;
+ width: 120px;
+ height: 120px;
border-radius: 8px;
box-shadow: 1px 1px 3px #ccc;
transition: transform 0.15s;
diff --git a/twake/frontend/src/app/components/search-popup/tabs/all/recent.tsx b/twake/frontend/src/app/components/search-popup/tabs/all/recent.tsx
index 0d2aa7626f..2389862188 100644
--- a/twake/frontend/src/app/components/search-popup/tabs/all/recent.tsx
+++ b/twake/frontend/src/app/components/search-popup/tabs/all/recent.tsx
@@ -1,72 +1,17 @@
import React, { useEffect } from 'react';
+import RecentChannelsAndContacts from 'components/search-popup/parts/recent/channels-and-contacts';
+import Files from 'components/search-popup/parts/files';
+import Media from 'components/search-popup/parts/media';
import Search from 'features/global/services/search-service';
-import FilesResult from 'components/search-popup/parts/recent/files-result';
-import MediaResult from 'components/search-popup/parts/recent/media-result';
-import PerfectScrollbar from 'react-perfect-scrollbar';
-import { FileType } from 'features/files/types/file';
-import DriveService from 'deprecated/Apps/Drive/Drive';
-import FileUploadService from 'features/files/services/file-upload-service';
-import RecentChannelsAndContacts from 'components/search-popup/parts/recent-channels-and-contacts';
-import { FileSearchResult, MessageFileType } from 'features/messages/types/message';
-import Logger from 'features/global/framework/logger-service';
-import assert from 'assert';
-import { onFileDownloadClick, onFilePreviewClick } from 'components/search-popup/parts/common';
export default (): JSX.Element => {
useEffect(() => {}, []);
- // let logger = Logger.getLogger('SearchPopup:TabsRecent');
-
return (
-
- {
}
-
- {(Search.recent.files.length && (
-
-
Recent files
-
-
- {Search.recent.files.slice(0, 8).map(file => (
- {
- onFilePreviewClick(file);
- }}
- onDownloadClick={() => {
- onFileDownloadClick(file);
- }}
- />
- ))}
-
-
- )) ||
}
-
- {(Search.recent.media.length && (
-
-
Recent media
-
-
- {Search.recent.media.slice(0, 7).map(file => (
- {
- onFilePreviewClick(file);
- }}
- />
- ))}
-
-
- )) ||
}
+
+
+
+
);
};
diff --git a/twake/frontend/src/app/components/search-popup/tabs/all/search.tsx b/twake/frontend/src/app/components/search-popup/tabs/all/search.tsx
index 6d8f441dfd..4193c62e7a 100644
--- a/twake/frontend/src/app/components/search-popup/tabs/all/search.tsx
+++ b/twake/frontend/src/app/components/search-popup/tabs/all/search.tsx
@@ -1,71 +1,37 @@
import Search from 'features/global/services/search-service';
-import ChannelsResult from 'components/search-popup/parts/channels-result';
-import UsersResult from 'components/search-popup/parts/users-result';
-import MessagesResult from 'components/search-popup/parts/messages-result';
-import React, { useEffect, useState } from 'react';
+import React, { useState } from 'react';
+import ChannelsAndContacts from 'components/search-popup/parts/channels-and-contacts';
+import Discussions from 'components/search-popup/parts/discussions';
+import Files from 'components/search-popup/parts/files';
+import Media from 'components/search-popup/parts/media';
export default (): JSX.Element => {
const [notFound, setNotFound] = useState(false);
- useEffect(() => {
- setNotFound(
- Boolean(Search.value) &&
- !Search.searchInProgress &&
- !Search.results.channels.length &&
- !Search.results.users.length &&
- !Search.results.messages.length,
- );
- }, [Search.searchInProgress, Search.value]);
+ if (
+ Boolean(Search.value) &&
+ !Search.searchInProgress &&
+ !Search.results.channels.length &&
+ !Search.results.users.length &&
+ !Search.results.messages.length
+ ) {
+ return
Nothing found
;
+ }
return (
-
{notFound &&
Nothing found
}
-
- {((Search.results.channels.length || Search.results.users.length) && (
-
-
Channels and contacts
-
- {(Search.results.channels.length && (
-
- {Search.results.channels.map(channel => (
- Search.close()}
- />
- ))}
-
- )) ||
}
+ {((Search.results.channels?.length || Search.results.users?.length) && (
+
+ )) ||
}
+ {(Search.results.messages?.length && (
+
+ )) ||
}
- {(Search.results.users.length && (
-
- {Search.results.users.map(user => (
- Search.close()}
- />
- ))}
-
- )) ||
}
-
+ {(Search.results.files?.length && (
+
)) ||
}
- {(Search.results.messages.length && (
-
-
Discussions
-
- {Search.results.messages.map(message => (
- Search.close()}
- />
- ))}
-
-
+ {(Search.results.media?.length && (
+
)) ||
}
);
diff --git a/twake/frontend/src/app/components/search-popup/tabs/chats/index.tsx b/twake/frontend/src/app/components/search-popup/tabs/chats/index.tsx
index bab8601ce9..cfe0104108 100644
--- a/twake/frontend/src/app/components/search-popup/tabs/chats/index.tsx
+++ b/twake/frontend/src/app/components/search-popup/tabs/chats/index.tsx
@@ -1,38 +1,27 @@
-import React, { useEffect, useState } from 'react';
+import PerfectScrollbar from 'react-perfect-scrollbar';
import Search from 'features/global/services/search-service';
-import { FileType } from 'features/files/types/file';
-import DriveService from 'deprecated/Apps/Drive/Drive';
-import FileUploadService from 'features/files/services/file-upload-service';
-import RecentChannelsAndContacts from 'components/search-popup/parts/recent-channels-and-contacts';
+import React from 'react';
+import SearchComponent from './search';
+import RecentComponent from './recent';
-export default (): JSX.Element => {
- const [pageReady, setPageReady] = useState(false);
-
- const [searchMode, setSearchMode] = useState(false);
-
- useEffect(() => {
- setSearchMode(Boolean(Search.value));
- setPageReady(true);
- }, []);
-
- useEffect(() => {
- const newVal = Boolean(Search.value);
- if (searchMode !== newVal) {
- setSearchMode(newVal);
- }
- }, [Search.value]);
+type PropsType = { scroller: any };
+export default ({ scroller }: PropsType): JSX.Element => {
return (
- (pageReady && (
-
-
- {searchMode ||
}
-
- {(searchMode && (
-
Channels and conversations
- )) ||
Recent channels and conversations
}
-
-
- )) ||
+ (Search.value && (
+
{
+ scroller = node;
+ }}
+ >
+
+
+ )) ||
+ (Search.recentInProgress &&
loading recent...
) || (
+
+ )
);
};
diff --git a/twake/frontend/src/app/components/search-popup/tabs/chats/recent.tsx b/twake/frontend/src/app/components/search-popup/tabs/chats/recent.tsx
new file mode 100644
index 0000000000..dffbd6508f
--- /dev/null
+++ b/twake/frontend/src/app/components/search-popup/tabs/chats/recent.tsx
@@ -0,0 +1,36 @@
+import React, { useEffect } from 'react';
+import RecentChannelsAndContacts from 'components/search-popup/parts/recent/channels-and-contacts';
+import Search from 'features/global/services/search-service';
+import ChannelsAndContacts from 'components/search-popup/parts/channels-and-contacts';
+import { UserType } from 'features/users/types/user';
+
+export default (): JSX.Element => {
+ useEffect(() => {}, []);
+
+ if (!Search.recent.channels) {
+ return
;
+ }
+
+ const directChannels = Search.recent.channels.filter(a => a.visibility === 'direct');
+ const publicChannels = Search.recent.channels.filter(a => a.visibility === 'public');
+
+ const users = [] as UserType[];
+ const usedIds = new Set();
+
+ directChannels.forEach(ch => {
+ ch.users?.forEach(u => {
+ if (!usedIds.has(u.id)) {
+ users.push(u);
+ usedIds.add(u.id);
+ }
+ });
+ });
+
+ return (
+
+
+
+
+
+ );
+};
diff --git a/twake/frontend/src/app/components/search-popup/tabs/chats/search.tsx b/twake/frontend/src/app/components/search-popup/tabs/chats/search.tsx
new file mode 100644
index 0000000000..1ffcb6e0a4
--- /dev/null
+++ b/twake/frontend/src/app/components/search-popup/tabs/chats/search.tsx
@@ -0,0 +1,31 @@
+import Search from 'features/global/services/search-service';
+import React, { useEffect, useState } from 'react';
+import ChannelsAndContacts from 'components/search-popup/parts/channels-and-contacts';
+import Discussions from 'components/search-popup/parts/discussions';
+
+export default (): JSX.Element => {
+ const [notFound, setNotFound] = useState(false);
+
+ useEffect(() => {
+ setNotFound(
+ Boolean(Search.value) &&
+ !Search.searchInProgress &&
+ !Search.results.channels.length &&
+ !Search.results.users.length &&
+ !Search.results.messages.length,
+ );
+ }, [Search.searchInProgress, Search.value]);
+
+ return (
+
+
{notFound &&
Nothing found
}
+
+ {((Search.results.channels.length || Search.results.users.length) && (
+
+ )) ||
}
+ {(Search.results.messages.length &&
) || (
+
+ )}
+
+ );
+};
diff --git a/twake/frontend/src/app/components/search-popup/tabs/files/index.tsx b/twake/frontend/src/app/components/search-popup/tabs/files/index.tsx
index f59f7a4b50..de0d6cd9ee 100644
--- a/twake/frontend/src/app/components/search-popup/tabs/files/index.tsx
+++ b/twake/frontend/src/app/components/search-popup/tabs/files/index.tsx
@@ -1,65 +1,33 @@
-import React, { useEffect, useState } from 'react';
+import React, { useEffect } from 'react';
import Search from 'features/global/services/search-service';
-import PerfectScrollbar from 'react-perfect-scrollbar';
-import FilesResult from 'components/search-popup/parts/recent/files-result';
-import { onFileDownloadClick, onFilePreviewClick } from 'components/search-popup/parts/common';
-import { isEmpty } from 'lodash';
+import Files from 'components/search-popup/parts/files';
export default (): JSX.Element => {
- const [pageReady, setPageReady] = useState(false);
- const [searchMode, setSearchMode] = useState(false);
- const [notFound, setNotFound] = useState(false);
+ const isSearchMode = Boolean(Search.value);
- useEffect(() => {
- setSearchMode(Boolean(Search.value));
- setPageReady(true);
- }, []);
+ useEffect(() => {}, [Search.searchInProgress]);
- useEffect(() => {
- const newVal = Boolean(Search.value);
- if (searchMode !== newVal) {
- setSearchMode(newVal);
- }
- }, [Search.value]);
+ if (
+ isSearchMode &&
+ !Search.searchInProgress &&
+ (!Search.results.files || !Search.results.files.length)
+ ) {
+ return
Nothing found
;
+ }
- useEffect(() => {
- setPageReady(!Search.searchInProgress);
- setNotFound(Boolean(Search.value) && !Search.searchInProgress && isEmpty(Search.results.media));
- }, [Search.searchInProgress, Search.value]);
+ if (Search.recent.files === undefined) {
+ return
;
+ }
- useEffect(() => {}, [Search.results.files, Search.recent.files]);
+ const groupTitle = isSearchMode ? 'Files' : 'Recent files';
return (
- (pageReady && (
-
-
{notFound &&
Nothing found
}
-
-
- {(!searchMode &&
Recent files
) ||
- (!notFound && !Search.searchInProgress && (
-
Files
- ))}
-
-
- {(searchMode ? Search.results.files : Search.recent.files).map(file => (
- {
- onFilePreviewClick(file);
- }}
- onDownloadClick={() => {
- onFileDownloadClick(file);
- }}
- />
- ))}
-
-
-
- )) ||
+
+
+
);
};
diff --git a/twake/frontend/src/app/components/search-popup/tabs/media/index.tsx b/twake/frontend/src/app/components/search-popup/tabs/media/index.tsx
index 6bc8709f54..f9412d37e6 100644
--- a/twake/frontend/src/app/components/search-popup/tabs/media/index.tsx
+++ b/twake/frontend/src/app/components/search-popup/tabs/media/index.tsx
@@ -1,60 +1,33 @@
-import React, { useEffect, useState } from 'react';
+import React, { useEffect } from 'react';
import Search from 'features/global/services/search-service';
-import MediaResult from 'components/search-popup/parts/recent/media-result';
-import PerfectScrollbar from 'react-perfect-scrollbar';
-import { FileType } from 'features/files/types/file';
-import DriveService from 'deprecated/Apps/Drive/Drive';
-import FileUploadService from 'features/files/services/file-upload-service';
-import { onFilePreviewClick } from 'components/search-popup/parts/common';
-import { isEmpty } from 'lodash';
+import Media from 'components/search-popup/parts/media';
export default (): JSX.Element => {
- const [pageReady, setPageReady] = useState(false);
- const [searchMode, setSearchMode] = useState(false);
- const [notFound, setNotFound] = useState(false);
+ useEffect(() => {}, [Search.value, Search.searchInProgress]);
- useEffect(() => {
- setSearchMode(Boolean(Search.value));
- setPageReady(true);
- }, []);
+ const isSearchMode = Boolean(Search.value);
- useEffect(() => {
- const newVal = Boolean(Search.value);
- if (searchMode !== newVal) {
- setSearchMode(newVal);
- }
- }, [Search.value]);
+ if (
+ isSearchMode &&
+ !Search.searchInProgress &&
+ (!Search.results.media || !Search.results.media.length)
+ ) {
+ return
Nothing found
;
+ }
- useEffect(() => {
- setPageReady(!Search.searchInProgress);
- setNotFound(Boolean(Search.value) && !Search.searchInProgress && isEmpty(Search.results.media));
- }, [Search.searchInProgress, Search.value]);
+ if (Search.recent.media === undefined) {
+ return
;
+ }
- return (
- (pageReady && (
-
-
{notFound &&
Nothing found
}
-
- {(!searchMode &&
Recent media
) ||
- (!notFound &&
Media
)}
+ const groupTitle = isSearchMode ? 'Media' : 'Recent media';
-
- {(searchMode ? Search.results.media : Search.recent.media).map(file => (
- {
- onFilePreviewClick(file);
- }}
- />
- ))}
-
-
-
- )) ||
+ return (
+
+
+
);
};
diff --git a/twake/frontend/src/app/features/channels/api/channel-api-client.ts b/twake/frontend/src/app/features/channels/api/channel-api-client.ts
index 179ff9fa8d..f62163acc1 100644
--- a/twake/frontend/src/app/features/channels/api/channel-api-client.ts
+++ b/twake/frontend/src/app/features/channels/api/channel-api-client.ts
@@ -81,7 +81,10 @@ class ChannelAPIClientService {
}
}
- async search(searchString: string, options?: SearchOptions): Promise
{
+ async search(
+ searchString: string,
+ options?: SearchOptions,
+ ): Promise<{ resources: ChannelType[] }> {
const companyId = options?.company_id || Workspace.currentGroupId;
let query = `/internal/services/channels/v1/companies/${companyId}/search?q=${searchString}`;
let res = await Api.getWithParams<{ resources: ChannelType[] }>(query, options);
diff --git a/twake/frontend/src/app/features/global/services/search-service.ts b/twake/frontend/src/app/features/global/services/search-service.ts
index 9be416d7b5..4a3d62a32c 100644
--- a/twake/frontend/src/app/features/global/services/search-service.ts
+++ b/twake/frontend/src/app/features/global/services/search-service.ts
@@ -103,6 +103,7 @@ class SearchService extends Observable {
}
const res = await ChannelAPIClient.search(this.value, { limit });
this.results.channels = res.resources;
+ this.logger.debug('search channels, found', res.resources.length);
this.notify();
}
@@ -115,6 +116,7 @@ class SearchService extends Observable {
companyId: Workspaces.currentGroupId,
}).then(users => {
this.results.users = users;
+ this.logger.debug('search users, found', users.length);
this.notify();
});
}
@@ -223,7 +225,10 @@ class SearchService extends Observable {
];
break;
case 'chats':
- promises = [this.searchMessages(clearResult, 100)];
+ promises = [
+ this.searchContacts(clearResult, 12),
+ this.searchMessages(clearResult, 100),
+ ];
break;
case 'media':
promises = [this.searchMedia(clearResult, 100)];
diff --git a/twake/frontend/src/app/features/messages/types/message.ts b/twake/frontend/src/app/features/messages/types/message.ts
index 4b8a33411e..792408e4cb 100644
--- a/twake/frontend/src/app/features/messages/types/message.ts
+++ b/twake/frontend/src/app/features/messages/types/message.ts
@@ -33,6 +33,7 @@ export type MessageFileType = {
};
export type FileSearchResult = MessageFileType & {
+ created_at: number;
message: Message;
user: UserType;
};