Skip to content

Commit

Permalink
🛠 Fix July (4) (#2383)
Browse files Browse the repository at this point in the history
* Fix more stuff

* Speed up a bit

* Speed up recent requests

* Fix channels with no names
  • Loading branch information
RomaricMourgues authored and Labels Bot committed Jul 3, 2022
1 parent 6cd6e3e commit 384f0ca
Show file tree
Hide file tree
Showing 18 changed files with 138 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class MessageFilesCacheMigrator {
} as ExecutionContext,
);
messagesPagination = messagesList.nextPage;
messagesPagination.page_token = messagesList.getEntities()[0]?.id;

for (const message of messagesList.getEntities()) {
if (message.files && message.files.length > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ export class ChannelServiceImpl implements ChannelService {
if (!channel) {
channel = await this.channelRepository.findOne({ ...primaryKey, workspace_id: "direct" });
}
if (!channel) return null;

const last_activity = await this.getChannelActivity(channel);

if (channel.visibility === ChannelVisibility.DIRECT)
Expand Down Expand Up @@ -706,7 +708,7 @@ export class ChannelServiceImpl implements ChannelService {
channelWithUsers.name = users
.filter(u => u.id != excludeUserId)
.map(u => u.full_name?.trim())
.filter(a=>a)
.filter(a => a)
.join(", ");
}
return channelWithUsers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ export class ChannelMemberCrudController

for (const member of list) {
if (member) {
const user = await formatUser(await gr.services.users.get({ id: member.user_id }), {
const user = await formatUser(await gr.services.users.getCached({ id: member.user_id }), {
includeCompanies: true,
});
resources.push({ ...member, user });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,8 @@ export class ThreadMessagesService implements MessageThreadMessagesServiceAPI {
message.files.push(entity);
}

if (!_.isEqual(previousMessageFiles.sort(), message.files.sort())) didChange = true;
if (!_.isEqual(previousMessageFiles.map(a => a.id).sort(), message.files.map(a => a.id).sort()))
didChange = true;

if (didChange) {
await this.repository.save(message);
Expand Down
8 changes: 6 additions & 2 deletions twake/backend/node/src/services/messages/services/views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { MessageFile } from "../entities/message-files";
import { formatUser } from "../../../utils/users";
import { UserObject } from "../../user/web/types";
import { FileSearchResult } from "../web/controllers/views/search-files";
import _ from "lodash";

export class ViewsServiceImpl implements MessageViewsServiceAPI {
version: "1";
Expand Down Expand Up @@ -372,7 +373,10 @@ export class ViewsServiceImpl implements MessageViewsServiceAPI {
},
);

const messageFiles = (await Promise.all(messageFilePromises)).filter(a => a);
const messageFiles = _.uniqBy(
(await Promise.all(messageFilePromises)).filter(a => a),
a => a.metadata?.source + JSON.stringify(a.metadata?.external_id),
);

files = [...files, ...messageFiles.filter(a => a)].filter(ref => {
//Apply media filer
Expand All @@ -389,7 +393,7 @@ export class ViewsServiceImpl implements MessageViewsServiceAPI {
const fileWithUserAndMessagePromise: Promise<FileSearchResult>[] = files.map(
async file =>
({
user: await formatUser(await gr.services.users.get({ id: file.cache.user_id })),
user: await formatUser(await gr.services.users.getCached({ id: file.cache?.user_id })),
message: await gr.services.messages.messages.get({
id: file.message_id,
thread_id: file.thread_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ export default async (
const getChannelMember = await gr.services.channels.members.getChannelMember(
{ id: request.currentUser.id },
{
company_id: msgFile.cache.company_id,
workspace_id: msgFile.cache.workspace_id,
id: msgFile.cache.channel_id,
company_id: msgFile.cache?.company_id,
workspace_id: msgFile.cache?.workspace_id,
id: msgFile.cache?.channel_id,
},
50,
);
Expand All @@ -108,7 +108,9 @@ export default async (
thread_id: msgFile.thread_id,
id: msgFile.message_id,
});
const user = await formatUser(await gr.services.users.get({ id: msgFile.cache.user_id }));
const user = await formatUser(
await gr.services.users.getCached({ id: msgFile.cache?.user_id }),
);

messageFiles.push({ ...msgFile, user, message });
if (messageFiles.length == limit) {
Expand Down
13 changes: 10 additions & 3 deletions twake/backend/node/src/services/workspaces/services/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,15 @@ export class WorkspaceServiceImpl implements WorkspaceService {
);
}

async processPendingUser(user: User): Promise<void> {
const userCompanies = await gr.services.companies.getAllForUser(user.id);
async processPendingUser(user: User, companyId?: string): Promise<void> {
let userCompanies = [];
if (!companyId) {
userCompanies = await gr.services.companies.getAllForUser(user.id);
} else {
userCompanies = [
await gr.services.companies.getCompanyUser({ id: companyId }, { id: user.id }),
];
}
for (const userCompany of userCompanies) {
const workspaces = await this.getAllForCompany(userCompany.group_id);
for (const workspace of workspaces) {
Expand Down Expand Up @@ -437,7 +444,7 @@ export class WorkspaceServiceImpl implements WorkspaceService {
): Promise<WorkspaceUser[]> {
//Process pending invitation to workspace for this user
const user = await gr.services.users.get({ id: userId.userId });
await this.processPendingUser(user);
await this.processPendingUser(user, companyId?.id);

//Get all workspaces for this user
const allCompanyWorkspaces = await this.getAllForCompany(companyId.id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ export const SuggestionList = <T,>(props: Props<T>): JSX.Element => {
}
}, [props.position, position, props.id, id]);

useEffect(() => {
console.debug('Text which has been used for search:', `"${props.search}"`);
}, [props.search]);

useEffect(() => {
const totalWidth = window.document.body.offsetWidth;
if (x + suggestionWidth < totalWidth - suggestionMargin) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ type PropsType = {
};

export default ({ channel: _channel }: PropsType): JSX.Element => {
const channel = useChannel(_channel.id || '')?.channel || _channel;
const channel =
(_channel.visibility !== 'direct'
? useChannel(_channel.id || '', {
companyId: _channel.company_id || '',
workspaceId: _channel.workspace_id || '',
})?.channel
: undefined) || _channel;
const currentWorkspaceId = useRouterWorkspace();
const { setOpen } = useSearchModal();

Expand Down
62 changes: 47 additions & 15 deletions twake/frontend/src/app/features/global/utils/strings.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { isString } from 'lodash';

export default class Strings {
static verifyMail(email: string) {
const re =
Expand Down Expand Up @@ -84,10 +86,18 @@ export default class Strings {
* "a" a=1*0.15 flower=0 parasite=0 => 0.15
* "a bus" a=1*0.15 flower=0 parasite=1 => 0.15*(0.9^1parasite) => 0.14
*/
export const distanceFromQuery = (candidate: string, query: string) => {
export const distanceFromQuery = (
candidates: string | string[],
query: string,
options?: { booster: number[] },
) => {
let score = 0;
let parasites = 0;

if (isString(candidates)) {
candidates = [candidates];
}

//Step 1
Strings.removeAccents(query)
.toLocaleLowerCase()
Expand All @@ -97,26 +107,48 @@ export const distanceFromQuery = (candidate: string, query: string) => {
//Step 2
.forEach(queryWord => {
const queryWordImportance = queryWord.length / query.replace(/ /gm, '').length;
candidate.split(' ').map(field => {
if (field?.trim()) {
const sanitizedField = Strings.removeAccents(field).toLocaleLowerCase();
const match =
(sanitizedField.length - sanitizedField.replace(queryWord, '').length) /
sanitizedField.length;
if (match === 0) {
parasites += 1;
} else {
score += match * queryWordImportance;
}
}
});
let i = 0;

for (const candidate of candidates) {
const boost = options?.booster[i] || 1;
i++;
Strings.removeAccents(candidate)
.toLocaleLowerCase()
.replace(/[^a-z0-9]/gm, ' ')
.split(' ')
.map(sanitizedField => {
if (sanitizedField?.trim()) {
const match =
(sanitizedField.length - sanitizedField.replace(queryWord, '').length) /
sanitizedField.length;
if (match === 0) {
parasites += 1;
} else {
let prefixBoost = 1;
if (sanitizedField.indexOf(queryWord) === 0) {
prefixBoost = 2;
}
score += match * queryWordImportance * boost * prefixBoost;
}
}
});
}
});

//Step 3
score *= Math.pow(0.9, parasites);

//Step 4
if (candidate.replace(query, '').length !== candidate.length) score *= 1.1;
const candidateSanitized = Strings.removeAccents(candidates.join(' '))
.toLocaleLowerCase()
.replace(/[^a-z0-9]/gm, ' ');
if (
candidateSanitized.replace(/ /gm, '').replace(query, '').length !==
candidateSanitized.replace(/ /gm, '').length
)
score *= 1.1;

if (score > 6.4) console.log('candidate', query, candidates.join(' '), score);

return 0 - score;
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { SearchMediasResultsState } from '../state/search-medias-result';
import _ from 'lodash';
import { useGlobalEffect } from 'app/features/global/hooks/use-global-effect';
import useRouterCompany from 'app/features/router/hooks/use-router-company';
import { useSearchModal } from './use-search';

export const useSearchMessagesFilesLoading = () => {
return useRecoilValue(LoadingState('useSearchMessagesFilesOrMedias-' + 'files'));
Expand All @@ -24,6 +25,7 @@ let currentQuery = '';

export const useSearchMessagesFilesOrMedias = (mode: 'files' | 'medias') => {
const companyId = useRouterCompany();
const { open } = useSearchModal();
const searchInput = useRecoilValue(SearchInputState);
const [loading, setLoading] = useRecoilState(
LoadingState('useSearchMessagesFilesOrMedias-' + mode),
Expand Down Expand Up @@ -83,18 +85,19 @@ export const useSearchMessagesFilesOrMedias = (mode: 'files' | 'medias') => {
useGlobalEffect(
'useSearchFiles' + mode,
() => {
(async () => {
setLoading(true);
if (searchInput.query) {
delayRequest('useSearchFiles' + mode, async () => {
await refresh();
});
} else {
refresh();
}
})();
if (open)
(async () => {
setLoading(true);
if (searchInput.query) {
delayRequest('useSearchFiles' + mode, async () => {
await refresh();
});
} else {
refresh();
}
})();
},
[searchInput.query, searchInput.channelId, searchInput.workspaceId],
[searchInput.query, searchInput.channelId, searchInput.workspaceId, open],
);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ export const searchFrontend = (
let result = userList || getCurrentUserList() || [];

if (query) {
result = result
.filter(({ email, first_name, last_name, username }) =>
result = _.sortBy(
result.filter(({ email, first_name, last_name, username }) =>
query
.split(' ')
.every(
Expand All @@ -81,12 +81,12 @@ export const searchFrontend = (
.toLocaleLowerCase()
.indexOf(Strings.removeAccents(word).toLocaleLowerCase()) > -1,
),
)
.sort(
(a, b) =>
distanceFromQuery([a.last_name, a.first_name, a.email, a.username].join(' '), query) -
distanceFromQuery([b.last_name, b.first_name, b.email, b.username].join(' '), query),
);
),
a =>
distanceFromQuery([a.last_name, a.first_name, a.email, a.username].join(' '), query, {
booster: [10, 10, 2, 1],
}),
);
}

if (!query) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useEffect } from 'react';
import Languages from 'app/features/global/services/languages-service';
import { useEphemeralMessages } from 'app/features/messages/hooks/use-ephemeral-messages';
import useRouterCompany from 'app/features/router/hooks/use-router-company';
import MessageContent from '../../message/parts/MessageContent';
import { useEffect } from 'react';
import { MessageContext } from '../../message/message-with-replies';
import MessageContent from '../../message/parts/MessageContent';
import ThreadSection from '../../parts/thread-section';

type Props = {
Expand All @@ -16,6 +16,8 @@ type Props = {

export default (props: Props) => {
const companyId = useRouterCompany();
const workspaceId = props.workspaceId;
const channelId = props.channelId;
const { lastEphemeral, remove } = useEphemeralMessages({
companyId,
channelId: props.channelId,
Expand Down Expand Up @@ -54,7 +56,7 @@ export default (props: Props) => {
{Languages.t('scenes.apps.messages.just_you', [], 'Visible uniquement par vous')}
</div>

<MessageContext.Provider value={messageKey}>
<MessageContext.Provider value={{ ...messageKey, companyId, workspaceId, channelId }}>
<ThreadSection withAvatar head>
<MessageContent key={updatedKey} />
</ThreadSection>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export default (props: Props) => {

const JoinChanneBlock = ({ channelId }: { channelId: string }) => {
const [loading, setLoading] = useState(false);
const { channel } = useChannel(channelId);
const { channel, refresh } = useChannel(channelId);

if (!channel) {
return <></>;
Expand All @@ -86,6 +86,7 @@ const JoinChanneBlock = ({ channelId }: { channelId: string }) => {
channel.id || '',
UserService.getCurrentUserId(),
);
refresh();
setLoading(false);
}}
className="mb-4"
Expand Down
18 changes: 15 additions & 3 deletions twake/frontend/src/app/views/client/channels-bar/ChannelsBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,21 @@ export const ChannelLoading = () => {
return (
<div className="channels_view_loader ">
<div className="small-x-margin">
<Skeleton title={{ width: '50%' }} paragraph={{ rows: 3, width: '100%' }} />
<Skeleton title={{ width: '50%' }} paragraph={{ rows: 4, width: '100%' }} />
<Skeleton title={{ width: '50%' }} paragraph={{ rows: 4, width: '100%' }} />
<Skeleton
className="mt-8"
title={{ width: '50%' }}
paragraph={{ rows: 3, width: '100%' }}
/>
<Skeleton
className="mt-8"
title={{ width: '50%' }}
paragraph={{ rows: 4, width: '100%' }}
/>
<Skeleton
className="mt-8"
title={{ width: '50%' }}
paragraph={{ rows: 4, width: '100%' }}
/>
</div>
</div>
);
Expand Down
Loading

0 comments on commit 384f0ca

Please sign in to comment.