// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. import moment, {Moment} from 'moment-timezone'; import {NativeModules, Platform} 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): 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]; if (parameters[key] == null) { continue; } 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@domain.com addresses and multiple comma-separated addresses from being accepted return (/^[^ ,@]+@[^ ,@]+$/).test(email); } export function identity(arg: T): T { return arg; } export function safeParseJSON(rawJson: string | Record | 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; } export const pluckUnique = (key: string) => (array: Array<{[key: string]: unknown}>) => Array.from(new Set(array.map((obj) => obj[key]))); export function bottomSheetSnapPoint(itemsCount: number, itemHeight: number, bottomInset = 0) { return ((itemsCount + Platform.select({android: 1, default: 0})) * itemHeight) + (bottomInset * 2.5); } export function hasTrailingSpaces(term: string) { return term.length !== term.trimEnd().length; }