UNPKG

stream-chat-react

Version:

React components to create chat conversations or livestream style chat

132 lines (131 loc) 5.4 kB
import { DEFAULT_UPLOAD_SIZE_LIMIT_BYTES } from '../../../constants/limits'; export const accentsMap = { a: 'á|à|ã|â|À|Á|Ã|Â', c: 'ç|Ç', e: 'é|è|ê|É|È|Ê', i: 'í|ì|î|Í|Ì|Î', n: 'ñ|Ñ', o: 'ó|ò|ô|ő|õ|Ó|Ò|Ô|Õ', u: 'ú|ù|û|ü|Ú|Ù|Û|Ü', }; export const removeDiacritics = (text) => { if (!text) return ''; return Object.keys(accentsMap).reduce((acc, current) => acc.replace(new RegExp(accentsMap[current], 'g'), current), text); }; export const calculateLevenshtein = (query, name) => { if (query.length === 0) return name.length; if (name.length === 0) return query.length; const matrix = []; let i; for (i = 0; i <= name.length; i++) { matrix[i] = [i]; } let j; for (j = 0; j <= query.length; j++) { matrix[0][j] = j; } for (i = 1; i <= name.length; i++) { for (j = 1; j <= query.length; j++) { if (name.charAt(i - 1) === query.charAt(j - 1)) { matrix[i][j] = matrix[i - 1][j - 1]; } else { matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution Math.min(matrix[i][j - 1] + 1, // insertion matrix[i - 1][j] + 1)); // deletion } } } return matrix[name.length][query.length]; }; export const searchLocalUsers = (params) => { const { ownUserId, query, text, useMentionsTransliteration, users } = params; const matchingUsers = users.filter((user) => { if (user.id === ownUserId) return false; if (!query) return true; let updatedId = removeDiacritics(user.id).toLowerCase(); let updatedName = removeDiacritics(user.name).toLowerCase(); let updatedQuery = removeDiacritics(query).toLowerCase(); if (useMentionsTransliteration) { (async () => { // eslint-disable-next-line import/no-extraneous-dependencies const { default: transliterate } = await import('@stream-io/transliterate'); updatedName = transliterate(user.name || '').toLowerCase(); updatedQuery = transliterate(query).toLowerCase(); updatedId = transliterate(user.id).toLowerCase(); })(); } const maxDistance = 3; const lastDigits = text.slice(-(maxDistance + 1)).includes('@'); if (updatedName) { const levenshtein = calculateLevenshtein(updatedQuery, updatedName); if (updatedName.includes(updatedQuery) || (levenshtein <= maxDistance && lastDigits)) { return true; } } const levenshtein = calculateLevenshtein(updatedQuery, updatedId); return updatedId.includes(updatedQuery) || (levenshtein <= maxDistance && lastDigits); }); return matchingUsers; }; export const checkUploadPermissions = async (params) => { const { addNotification, file, getAppSettings, t, uploadType } = params; let appSettings = null; appSettings = await getAppSettings(); const { allowed_file_extensions, allowed_mime_types, blocked_file_extensions, blocked_mime_types, size_limit, } = (uploadType === 'image' ? appSettings?.app?.image_upload_config : appSettings?.app?.file_upload_config) || {}; const sendNotAllowedErrorNotification = () => addNotification(t(`Upload type: "{{ type }}" is not allowed`, { type: file.type || 'unknown type', }), 'error'); if (allowed_file_extensions?.length) { const allowed = allowed_file_extensions.some((ext) => file.name.toLowerCase().endsWith(ext.toLowerCase())); if (!allowed) { sendNotAllowedErrorNotification(); return false; } } if (blocked_file_extensions?.length) { const blocked = blocked_file_extensions.some((ext) => file.name.toLowerCase().endsWith(ext.toLowerCase())); if (blocked) { sendNotAllowedErrorNotification(); return false; } } if (allowed_mime_types?.length) { const allowed = allowed_mime_types.some((type) => type.toLowerCase() === file.type?.toLowerCase()); if (!allowed) { sendNotAllowedErrorNotification(); return false; } } if (blocked_mime_types?.length) { const blocked = blocked_mime_types.some((type) => type.toLowerCase() === file.type?.toLowerCase()); if (blocked) { sendNotAllowedErrorNotification(); return false; } } const sizeLimit = size_limit || DEFAULT_UPLOAD_SIZE_LIMIT_BYTES; if (file.size && file.size > sizeLimit) { addNotification(t('File is too large: {{ size }}, maximum upload size is {{ limit }}', { limit: prettifyFileSize(sizeLimit), size: prettifyFileSize(file.size), }), 'error'); return false; } return true; }; export function prettifyFileSize(bytes, precision = 3) { const units = ['B', 'kB', 'MB', 'GB']; const exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1); const mantissa = bytes / 1024 ** exponent; const formattedMantissa = precision === 0 ? Math.round(mantissa).toString() : mantissa.toPrecision(precision); return `${formattedMantissa} ${units[exponent]}`; }