Fix relative-date translation #4172
5 changed files with 48 additions and 33 deletions
|
@ -15,7 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Channel selector alignment on creator analytics page _community pr!_ ([#4157](https://github.com/lbryio/lbry-desktop/pull/4157))
|
- Channel selector alignment on creator analytics page _community pr!_ ([#4157](https://github.com/lbryio/lbry-desktop/pull/4157))
|
||||||
|
- Fix inconsistent relative-date string for claims, comments, etc. ([#4172](https://github.com/lbryio/lbry-desktop/pull/4172))
|
||||||
## [0.45.1] - [2020-05-06]
|
## [0.45.1] - [2020-05-06]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -1202,5 +1202,17 @@
|
||||||
"File preview": "File preview",
|
"File preview": "File preview",
|
||||||
"Go Home": "Go Home",
|
"Go Home": "Go Home",
|
||||||
"Uploading (%progress%%) ": "Uploading (%progress%%) ",
|
"Uploading (%progress%%) ": "Uploading (%progress%%) ",
|
||||||
"Confirming": "Confirming"
|
"Confirming": "Confirming",
|
||||||
|
"%duration% years ago": "%duration% years ago",
|
||||||
|
"%duration% year ago": "%duration% year ago",
|
||||||
|
"%duration% months ago": "%duration% months ago",
|
||||||
|
"%duration% month ago": "%duration% month ago",
|
||||||
|
"%duration% days ago": "%duration% days ago",
|
||||||
|
"%duration% day ago": "%duration% day ago",
|
||||||
|
"%duration% hours ago": "%duration% hours ago",
|
||||||
|
"%duration% hour ago": "%duration% hour ago",
|
||||||
|
"%duration% minutes ago": "%duration% minutes ago",
|
||||||
|
"%duration% minute ago": "%duration% minute ago",
|
||||||
|
"%duration% seconds ago": "%duration% seconds ago",
|
||||||
|
"%duration% second ago": "%duration% second ago"
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { isEmpty } from 'util/object';
|
import { isEmpty } from 'util/object';
|
||||||
import relativeDate from 'tiny-relative-date';
|
import DateTime from 'component/dateTime';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import Expandable from 'component/expandable';
|
import Expandable from 'component/expandable';
|
||||||
import MarkdownPreview from 'component/common/markdown-preview';
|
import MarkdownPreview from 'component/common/markdown-preview';
|
||||||
|
@ -147,7 +147,7 @@ function Comment(props: Props) {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<time className="comment__time" dateTime={timePosted}>
|
<time className="comment__time" dateTime={timePosted}>
|
||||||
{relativeDate(timePosted)}
|
{DateTime.getTimeAgoStr(timePosted)}
|
||||||
</time>
|
</time>
|
||||||
</div>
|
</div>
|
||||||
<div className="comment__menu">
|
<div className="comment__menu">
|
||||||
|
|
|
@ -14,6 +14,32 @@ class DateTime extends React.PureComponent<Props> {
|
||||||
static SHOW_TIME = 'time';
|
static SHOW_TIME = 'time';
|
||||||
static SHOW_BOTH = 'both';
|
static SHOW_BOTH = 'both';
|
||||||
|
|
||||||
|
static getTimeAgoStr(date: any) {
|
||||||
|
const suffixList = ['years', 'months', 'days', 'hours', 'minutes', 'seconds', ''];
|
||||||
|
var duration = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < suffixList.length; ++i) {
|
||||||
|
// moment() is very liberal with it's rounding.
|
||||||
|
// Always round down dates for better youtube parity.
|
||||||
|
duration = Math.floor(moment().diff(date, suffixList[i]));
|
||||||
|
if (duration > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i === suffixList.length) {
|
||||||
|
// This should never happen since we are handling up to 'seconds' now,
|
||||||
|
// but display the English version just in case it does.
|
||||||
|
return moment(date).from(moment());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip off the 's' for the singular suffix, construct the string ID,
|
||||||
|
// then load the localized version.
|
||||||
|
const suffix = duration === 1 ? suffixList[i].substr(0, suffixList[i].length - 1) : suffixList[i];
|
||||||
|
const strId = '%duration% ' + suffix + ' ago';
|
||||||
|
return __(strId, { duration });
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { date, timeAgo } = this.props;
|
const { date, timeAgo } = this.props;
|
||||||
const show = this.props.show || DateTime.SHOW_BOTH;
|
const show = this.props.show || DateTime.SHOW_BOTH;
|
||||||
|
@ -23,32 +49,7 @@ class DateTime extends React.PureComponent<Props> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moment is very liberal with it's rounding
|
return <span>{DateTime.getTimeAgoStr(date)}</span>;
|
||||||
// Wait to show "two years ago" until it's actually been two years (or higher)
|
|
||||||
const numberOfYearsSincePublish = Math.floor(moment().diff(date, 'years'));
|
|
||||||
|
|
||||||
if (numberOfYearsSincePublish === 1) {
|
|
||||||
return <span>{__('%numberOfYearsSincePublish% year ago', { numberOfYearsSincePublish })}</span>;
|
|
||||||
} else if (numberOfYearsSincePublish > 1) {
|
|
||||||
return <span>{__('%numberOfYearsSincePublish% years ago', { numberOfYearsSincePublish })}</span>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const numberOfMonthsSincePublish = Math.floor(moment().diff(date, 'months'));
|
|
||||||
if (numberOfMonthsSincePublish === 1) {
|
|
||||||
return <span>{__('%numberOfMonthsSincePublish% month ago', { numberOfMonthsSincePublish })}</span>;
|
|
||||||
} else if (numberOfMonthsSincePublish > 1) {
|
|
||||||
return <span>{__('%numberOfMonthsSincePublish% months ago', { numberOfMonthsSincePublish })}</span>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const numberOfDaysSincePublish = Math.floor(moment().diff(date, 'days'));
|
|
||||||
if (numberOfDaysSincePublish === 1) {
|
|
||||||
return <span>{__('%numberOfDaysSincePublish% day ago', { numberOfDaysSincePublish })}</span>;
|
|
||||||
} else if (numberOfDaysSincePublish > 1) {
|
|
||||||
return <span>{__('%numberOfDaysSincePublish% days ago', { numberOfDaysSincePublish })}</span>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// "just now", "a few minutes ago"
|
|
||||||
return <span>{moment(date).from(moment())}</span>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -24,7 +24,7 @@ import Icon from 'component/common/icon';
|
||||||
import HelpLink from 'component/common/help-link';
|
import HelpLink from 'component/common/help-link';
|
||||||
import { DEBOUNCE_WAIT_DURATION_MS } from 'constants/search';
|
import { DEBOUNCE_WAIT_DURATION_MS } from 'constants/search';
|
||||||
import ClaimList from 'component/claimList';
|
import ClaimList from 'component/claimList';
|
||||||
import relativeDate from 'tiny-relative-date';
|
import DateTime from 'component/dateTime';
|
||||||
|
|
||||||
const PAGE_VIEW_QUERY = `view`;
|
const PAGE_VIEW_QUERY = `view`;
|
||||||
const ABOUT_PAGE = `about`;
|
const ABOUT_PAGE = `about`;
|
||||||
|
@ -193,7 +193,9 @@ function ChannelPage(props: Props) {
|
||||||
{lastYtSyncDate && (
|
{lastYtSyncDate && (
|
||||||
<div className="media__uri--right">
|
<div className="media__uri--right">
|
||||||
<Icon icon={ICONS.VALIDATED} size={12} />
|
<Icon icon={ICONS.VALIDATED} size={12} />
|
||||||
{__('Official YouTube Creator - Last updated %time_ago%', { time_ago: relativeDate(lastYtSyncDate) })}
|
{__('Official YouTube Creator - Last updated %time_ago%', {
|
||||||
|
time_ago: DateTime.getTimeAgoStr(lastYtSyncDate),
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<header className="channel-cover">
|
<header className="channel-cover">
|
||||||
|
|
Loading…
Reference in a new issue