import {Fragment} from 'react'; import styled from '@emotion/styled'; import moment from 'moment-timezone'; import {t} from 'sentry/locale'; import plugins from 'sentry/plugins'; import ConfigStore from 'sentry/stores/configStore'; import space from 'sentry/styles/space'; import {defined} from 'sentry/utils'; const CONTEXT_TYPES = { default: require('sentry/components/events/contexts/default').default, app: require('sentry/components/events/contexts/app/app').default, device: require('sentry/components/events/contexts/device/device').default, os: require('sentry/components/events/contexts/operatingSystem/operatingSystem') .default, runtime: require('sentry/components/events/contexts/runtime/runtime').default, browser: require('sentry/components/events/contexts/browser/browser').default, user: require('sentry/components/events/contexts/user').default, gpu: require('sentry/components/events/contexts/gpu/gpu').default, trace: require('sentry/components/events/contexts/trace/trace').default, // 'redux.state' will be replaced with more generic context called 'state' 'redux.state': require('sentry/components/events/contexts/redux').default, state: require('sentry/components/events/contexts/state').default, }; export function getContextComponent(type: string) { return CONTEXT_TYPES[type] || plugins.contexts[type] || CONTEXT_TYPES.default; } export function getSourcePlugin(pluginContexts: Array, contextType: string) { if (CONTEXT_TYPES[contextType]) { return null; } for (const plugin of pluginContexts) { if (plugin.contexts.indexOf(contextType) >= 0) { return plugin; } } return null; } export function getRelativeTimeFromEventDateCreated( eventDateCreated: string, timestamp?: string, showTimestamp = true ) { if (!defined(timestamp)) { return timestamp; } const dateTime = moment(timestamp); if (!dateTime.isValid()) { return timestamp; } const relativeTime = `(${dateTime.from(eventDateCreated, true)} ${t( 'before this event' )})`; if (!showTimestamp) { return {relativeTime}; } return ( {timestamp} {relativeTime} ); } // Typescript doesn't have types for DisplayNames yet and that's why the type assertion "any" is needed below. // There is currently an open PR that intends to introduce the types https://github.com/microsoft/TypeScript/pull/44022 export function getFullLanguageDescription(locale: string) { const sentryAppLanguageCode = ConfigStore.get('languageCode'); const [languageAbbreviation, countryAbbreviation] = locale.includes('_') ? locale.split('_') : locale.split('-'); try { const languageNames = new (Intl as any).DisplayNames(sentryAppLanguageCode, { type: 'language', }); const languageName = languageNames.of(languageAbbreviation); if (countryAbbreviation) { const regionNames = new (Intl as any).DisplayNames(sentryAppLanguageCode, { type: 'region', }); const countryName = regionNames.of(countryAbbreviation.toUpperCase()); return `${languageName} (${countryName})`; } return languageName; } catch { return locale; } } const RelativeTime = styled('span')` color: ${p => p.theme.subText}; margin-left: ${space(0.5)}; `;