You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			103 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			103 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			TypeScript
		
	
import React, { useState } from 'react';
 | 
						|
import classNames from 'classnames';
 | 
						|
import moment from 'moment';
 | 
						|
 | 
						|
import { formatRelativeTime } from '../../util/formatRelativeTime';
 | 
						|
import { useInterval } from '../../hooks/useInterval';
 | 
						|
import styled, { DefaultTheme } from 'styled-components';
 | 
						|
import { OpacityMetadataComponent } from './message/MessageMetadata';
 | 
						|
 | 
						|
type Props = {
 | 
						|
  timestamp?: number;
 | 
						|
  extended?: boolean;
 | 
						|
  module?: string;
 | 
						|
  withImageNoCaption?: boolean;
 | 
						|
  isConversationListItem?: boolean;
 | 
						|
  theme: DefaultTheme;
 | 
						|
};
 | 
						|
 | 
						|
const UPDATE_FREQUENCY = 60 * 1000;
 | 
						|
 | 
						|
const TimestampContainerListItem = styled(props => (
 | 
						|
  <OpacityMetadataComponent {...props} />
 | 
						|
))<{ color: string }>`
 | 
						|
  flex-shrink: 0;
 | 
						|
  margin-inline-start: 6px;
 | 
						|
  font-size: 11px;
 | 
						|
  line-height: 16px;
 | 
						|
  letter-spacing: 0.3px;
 | 
						|
  overflow-x: hidden;
 | 
						|
  white-space: nowrap;
 | 
						|
  text-overflow: ellipsis;
 | 
						|
  text-transform: uppercase;
 | 
						|
  color: ${props => props.theme.colors.textColor};
 | 
						|
`;
 | 
						|
 | 
						|
const TimestampContainerNotListItem = styled(props => (
 | 
						|
  <OpacityMetadataComponent {...props} />
 | 
						|
))<{ color: string }>`
 | 
						|
  font-size: 11px;
 | 
						|
  line-height: 16px;
 | 
						|
  letter-spacing: 0.3px;
 | 
						|
  text-transform: uppercase;
 | 
						|
  user-select: none;
 | 
						|
  color: ${props => props.timestampColor};
 | 
						|
`;
 | 
						|
 | 
						|
export const Timestamp = (props: Props) => {
 | 
						|
  const [lastUpdated, setLastUpdated] = useState(Date.now());
 | 
						|
  // this is kind of a hack, but we use lastUpdated just to trigger a refresh.
 | 
						|
  // formatRelativeTime() will print the correct moment.
 | 
						|
  const update = () => {
 | 
						|
    setLastUpdated(Date.now());
 | 
						|
  };
 | 
						|
 | 
						|
  useInterval(update, UPDATE_FREQUENCY);
 | 
						|
 | 
						|
  const { module, timestamp, withImageNoCaption, extended } = props;
 | 
						|
  const moduleName = module || 'module-timestamp';
 | 
						|
 | 
						|
  if (timestamp === null || timestamp === undefined) {
 | 
						|
    return null;
 | 
						|
  }
 | 
						|
 | 
						|
  // Use relative time for under 24hrs ago.
 | 
						|
  const now = Math.floor(Date.now());
 | 
						|
  const messageAgeInDays =
 | 
						|
    (now - timestamp) / (window.CONSTANTS.SECS_IN_DAY * 1000);
 | 
						|
  const daysBeforeRelativeTiming = 1;
 | 
						|
 | 
						|
  let dateString;
 | 
						|
  if (messageAgeInDays > daysBeforeRelativeTiming) {
 | 
						|
    dateString = formatRelativeTime(timestamp, { i18n: window.i18n, extended });
 | 
						|
  } else {
 | 
						|
    dateString = moment(timestamp).fromNow();
 | 
						|
    // Prevent times reading "NOW AGO"
 | 
						|
    if (dateString.startsWith('now') || dateString.startsWith('Now')) {
 | 
						|
      dateString = 'now';
 | 
						|
    }
 | 
						|
 | 
						|
    dateString = dateString.replace('minutes', 'mins').replace('minute', 'min');
 | 
						|
  }
 | 
						|
 | 
						|
  const timestampColor = withImageNoCaption
 | 
						|
    ? 'white'
 | 
						|
    : props.theme.colors.textColor;
 | 
						|
  const title = moment(timestamp).format('llll');
 | 
						|
  if (props.isConversationListItem) {
 | 
						|
    return (
 | 
						|
      <TimestampContainerListItem timestampColor={timestampColor} title={title}>
 | 
						|
        {dateString}
 | 
						|
      </TimestampContainerListItem>
 | 
						|
    );
 | 
						|
  }
 | 
						|
  return (
 | 
						|
    <TimestampContainerNotListItem
 | 
						|
      timestampColor={timestampColor}
 | 
						|
      title={title}
 | 
						|
    >
 | 
						|
      {dateString}
 | 
						|
    </TimestampContainerNotListItem>
 | 
						|
  );
 | 
						|
};
 |