forked from Ivasoft/mattermost-mobile
* [Gekidou]: MM-39757 - Recent mentions * Refactor channel_info to a separate component * Fixes schema tests * Fixes channel_info theme color * Removes RECEIVED_MENTIONS table and model Removes RECEIVED_MENTIONS table and model and saves recent_mentions in the SYSTEM table under the recentMentions ID. * Cleanup recent_mentions handler * Adds i18n in recent_mentions screen * Observe changes on the post messages * Addresses review comments * Batches records * Addresses review comments * Addresses review comments * Addresses review comments * Addresses review comments * Fetches channels and users needed for mentions Fetching mentions from all teams might result in missing info like user profiles, and channels missing from the DB. This commit fetches all missing users and channels. * Adds empty state for recent mentions * Prepares all missing models for channels * Addresses review comments * Fixes mention keys for recent mentions User mention keys when asking for mentions should not include general purpose ones, like @channel, @all, @here. Fixes ActivityIndicator color in recent mentions screen. * Removes top margin of mention message * Addresses review comments * Fixes group.name undefined
140 lines
4.1 KiB
TypeScript
140 lines
4.1 KiB
TypeScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
import moment, {Moment} from 'moment-timezone';
|
|
import {NativeModules} from 'react-native';
|
|
|
|
import {Device} from '@constants';
|
|
import {CUSTOM_STATUS_TIME_PICKER_INTERVALS_IN_MINUTES} from '@constants/custom_status';
|
|
|
|
const {MattermostManaged} = NativeModules;
|
|
const isRunningInSplitView = MattermostManaged.isRunningInSplitView;
|
|
|
|
// isMinimumServerVersion will return true if currentVersion is equal to higher or than
|
|
// the provided minimum version. A non-equal major version will ignore minor and dot
|
|
// versions, and a non-equal minor version will ignore dot version.
|
|
// currentVersion is a string, e.g '4.6.0'
|
|
// minMajorVersion, minMinorVersion, minDotVersion are integers
|
|
export const isMinimumServerVersion = (currentVersion: string, minMajorVersion = 0, minMinorVersion = 0, minDotVersion = 0): boolean => {
|
|
if (!currentVersion || typeof currentVersion !== 'string') {
|
|
return false;
|
|
}
|
|
|
|
const split = currentVersion.split('.');
|
|
|
|
const major = parseInt(split[0], 10);
|
|
const minor = parseInt(split[1] || '0', 10);
|
|
const dot = parseInt(split[2] || '0', 10);
|
|
|
|
if (major > minMajorVersion) {
|
|
return true;
|
|
}
|
|
if (major < minMajorVersion) {
|
|
return false;
|
|
}
|
|
|
|
// Major version is equal, check minor
|
|
if (minor > minMinorVersion) {
|
|
return true;
|
|
}
|
|
if (minor < minMinorVersion) {
|
|
return false;
|
|
}
|
|
|
|
// Minor version is equal, check dot
|
|
if (dot > minDotVersion) {
|
|
return true;
|
|
}
|
|
if (dot < minDotVersion) {
|
|
return false;
|
|
}
|
|
|
|
// Dot version is equal
|
|
return true;
|
|
};
|
|
|
|
export function buildQueryString(parameters: Dictionary<any>): string {
|
|
const keys = Object.keys(parameters);
|
|
if (keys.length === 0) {
|
|
return '';
|
|
}
|
|
|
|
let query = '?';
|
|
for (let i = 0; i < keys.length; i++) {
|
|
const key = keys[i];
|
|
query += key + '=' + encodeURIComponent(parameters[key]);
|
|
|
|
if (i < keys.length - 1) {
|
|
query += '&';
|
|
}
|
|
}
|
|
|
|
return query;
|
|
}
|
|
|
|
export function isEmail(email: string): boolean {
|
|
// writing a regex to match all valid email addresses is really, really hard. (see http://stackoverflow.com/a/201378)
|
|
// this regex ensures:
|
|
// - at least one character that is not a space, comma, or @ symbol
|
|
// - followed by a single @ symbol
|
|
// - followed by at least one character that is not a space, comma, or @ symbol
|
|
// this prevents <Outlook Style> outlook.style@domain.com addresses and multiple comma-separated addresses from being accepted
|
|
return (/^[^ ,@]+@[^ ,@]+$/).test(email);
|
|
}
|
|
|
|
export function identity<T>(arg: T): T {
|
|
return arg;
|
|
}
|
|
|
|
export function safeParseJSON(rawJson: string | Record<string, unknown> | unknown[]) {
|
|
let data = rawJson;
|
|
try {
|
|
if (typeof rawJson == 'string') {
|
|
data = JSON.parse(rawJson);
|
|
}
|
|
} catch {
|
|
// Do nothing
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
export function getCurrentMomentForTimezone(timezone: string | null) {
|
|
return timezone ? moment.tz(timezone) : moment();
|
|
}
|
|
|
|
export function getUtcOffsetForTimeZone(timezone: string) {
|
|
return moment.tz(timezone).utcOffset();
|
|
}
|
|
|
|
export function isCustomStatusExpirySupported(version: string) {
|
|
return isMinimumServerVersion(version, 5, 37);
|
|
}
|
|
|
|
export function toTitleCase(str: string) {
|
|
function doTitleCase(txt: string) {
|
|
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
|
}
|
|
return str.replace(/\w\S*/g, doTitleCase);
|
|
}
|
|
|
|
export function getRoundedTime(value: Moment) {
|
|
const roundedTo = CUSTOM_STATUS_TIME_PICKER_INTERVALS_IN_MINUTES;
|
|
const start = moment(value);
|
|
const diff = start.minute() % roundedTo;
|
|
if (diff === 0) {
|
|
return value;
|
|
}
|
|
const remainder = roundedTo - diff;
|
|
return start.add(remainder, 'm').seconds(0).milliseconds(0);
|
|
}
|
|
|
|
export async function isTablet() {
|
|
if (Device.IS_TABLET) {
|
|
const {isSplitView} = await isRunningInSplitView();
|
|
return !isSplitView;
|
|
}
|
|
|
|
return false;
|
|
}
|