Skip to content

Commit

Permalink
Merge branch 'main' into l10n_main
Browse files Browse the repository at this point in the history
  • Loading branch information
DJDavid98 committed Nov 22, 2021
2 parents d5a13b2 + fcfe621 commit 24b70d5
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 117 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ English and Hungarian translations have been included, so no translators will be
- Arabic: Raphael Santiago (raphael.santiago.53)
- Brazilian Portuguese: LeonardoC06
- Dutch: Jesse (Jessuh)
- Polish: Dawid (MinerPL)
4 changes: 4 additions & 0 deletions public/locales/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
"nativeName": "Nederlands",
"countryCode": "NL"
},
"pl": {
"nativeName": "Polski",
"countryCode": "PL"
},
"pt-BR": {
"nativeName": "Português do Brasil",
"countryCode": "BR",
Expand Down
Binary file added public/social/pl.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions src/components/DateTimeInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ interface DateTimeInputProps {
className?: string;
onChange: ChangeEventHandler<HTMLInputElement>;
type: 'date' | 'time';
readOnly?: boolean;
}

export const DateTimeInput: VFC<DateTimeInputProps> = ({ id, value, icon, className, onChange, type }) => (
export const DateTimeInput: VFC<DateTimeInputProps> = ({ id, value, icon, className, onChange, type, readOnly }) => (
<InputGroup className={classNames(styles.dateInputGroup, className)}>
<InputGroupAddon addonType="prepend">
<InputGroupText tag="label" htmlFor={id} className={styles.inputAddon}>
<FontAwesomeIcon icon={icon} fixedWidth />
</InputGroupText>
</InputGroupAddon>
<Input type={type} bsSize="lg" id={id} value={value} onChange={onChange} />
<Input type={type} bsSize="lg" id={id} value={value} onChange={onChange} disabled={readOnly} tabIndex={readOnly ? -1 : undefined} />
</InputGroup>
);
22 changes: 19 additions & 3 deletions src/components/TimestampPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DateTimeInput } from 'components/DateTimeInput';
import { TFunction } from 'i18next';
import styles from 'modules/TimestampPicker.module.scss';
import { ChangeEventHandler, useCallback, useMemo, VFC } from 'react';
import React, { ChangeEventHandler, FC, useCallback, useMemo } from 'react';
import Select from 'react-select';
import { StylesConfig } from 'react-select/src/styles';
import { ThemeConfig } from 'react-select/src/theme';
Expand Down Expand Up @@ -69,6 +69,7 @@ const customStyles: StylesConfig<TimezoneOptionType, false> = {
interface PropTypes {
changeTimezone: (tz: null | string) => void;
dateString: string;
fixedTimestamp: boolean;
handleDateChange: (value: string | null) => void;
handleTimeChange: (value: string | null) => void;
t: TFunction;
Expand All @@ -77,15 +78,17 @@ interface PropTypes {
timezoneNames: TimezoneOptionType[];
}

export const TimestampPicker: VFC<PropTypes> = ({
export const TimestampPicker: FC<PropTypes> = ({
changeTimezone,
dateString,
fixedTimestamp,
handleDateChange: onDateChange,
handleTimeChange: onTimeChange,
t,
timeString,
timezone,
timezoneNames,
children,
}) => {
const handleTimezoneChange = useCallback(
(selected: TimezoneOptionType | null) => {
Expand Down Expand Up @@ -116,10 +119,18 @@ export const TimestampPicker: VFC<PropTypes> = ({
id={dateInputId}
icon="calendar"
onChange={handleDateChange}
readOnly={fixedTimestamp}
/>
</Col>
<Col xl={6}>
<DateTimeInput type="time" value={timeString} id={timeInputId} icon="clock" onChange={handleTimeChange} />
<DateTimeInput
type="time"
value={timeString}
id={timeInputId}
icon="clock"
onChange={handleTimeChange}
readOnly={fixedTimestamp}
/>
</Col>
</Row>
</FormGroup>
Expand All @@ -138,9 +149,14 @@ export const TimestampPicker: VFC<PropTypes> = ({
theme={customTheme}
styles={customStyles}
isClearable
isDisabled={fixedTimestamp}
/>
<div className="d-block d-xl-none mt-2">{children}</div>
</FormGroup>
</Col>
<Col xs="auto" className="d-none d-xl-flex flex-row align-items-end">
{children}
</Col>
</Row>
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/TimestampsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,12 @@ const CopySyntax: VoidFunctionComponent<{ syntax: string; className?: string }>

interface PropTypes {
timestamp: Moment | null;
timeInSeconds: string;
locale: string;
t: TFunction;
}

export const TimestampsTable: VFC<PropTypes> = ({ t, locale, timestamp }) => {
export const TimestampsTable: VFC<PropTypes> = ({ t, locale, timestamp, timeInSeconds }) => {
const [now, setNow] = useState(() => moment());

useEffect(() => {
Expand All @@ -89,7 +90,6 @@ export const TimestampsTable: VFC<PropTypes> = ({ t, locale, timestamp }) => {
return moment(value).locale(locale);
}, [timestamp, locale]);

const timeInSeconds = useMemo(() => String(timestamp?.unix() || '0'), [timestamp]);
const rows = useMemo<TimeValue[]>(() => {
const shortDate: TimeValue = {
example: localizedTs.format('L'),
Expand Down
17 changes: 16 additions & 1 deletion src/fontawesome.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import {
faCode,
faEye,
faGlobe,
faLock,
faTimes,
faTimesCircle,
faUserClock,
} from '@fortawesome/free-solid-svg-icons';

Expand All @@ -18,4 +20,17 @@ config.autoAddCss = false;
const brandIcons = [faGithub, faDiscord, faOsi];

// List of used icons - amend if new icons are needed
library.add(...brandIcons, faClipboard, faClock, fasCalendar, farCalendar, faGlobe, faTimes, faEye, faUserClock, faCode);
library.add(
...brandIcons,
faClipboard,
faClock,
fasCalendar,
farCalendar,
faGlobe,
faTimes,
faEye,
faUserClock,
faCode,
faTimesCircle,
faLock,
);
5 changes: 3 additions & 2 deletions src/moment-locales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import 'moment/locale/de';
import 'moment/locale/en-gb';
import 'moment/locale/fr';
import 'moment/locale/hu';
import 'moment/locale/ru';
import 'moment/locale/pt-br';
import 'moment/locale/nl';
import 'moment/locale/pl';
import 'moment/locale/pt-br';
import 'moment/locale/ru';
import moment from 'moment-timezone';
import latestTimezoneData from 'moment-timezone/data/packed/latest.json';

Expand Down
77 changes: 63 additions & 14 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { AppContainer } from 'components/AppContainer';
import { CustomIcon } from 'components/CustomIcon';
import { Layout } from 'components/Layout';
import { TimestampPicker } from 'components/TimestampPicker';
import { TimestampsTable } from 'components/TimestampsTable';
import { throttle } from 'lodash';
import { parseInt, throttle } from 'lodash';
import moment, { Moment } from 'moment-timezone';
import { GetStaticProps } from 'next';
import { SSRConfig, useTranslation } from 'next-i18next';
import { useCallback, useEffect, useMemo, useState, VFC } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/router';
import React, { useCallback, useEffect, useMemo, useState, VFC } from 'react';
import { Button, FormGroup } from 'reactstrap';
import { SITE_TITLE } from 'src/config';
import { useLocale } from 'src/util/common';
import { typedServerSideTranslations } from 'src/util/i18n-server';
Expand All @@ -17,7 +21,9 @@ interface IndexPageProps {
tzNames: string[];
}

const IndexPage: VFC<IndexPageProps> = ({ tzNames }) => {
const TS_QUERY_PARAM = 't';

export const IndexPage: VFC<IndexPageProps> = ({ tzNames }) => {
const {
t,
i18n: { language },
Expand All @@ -27,7 +33,19 @@ const IndexPage: VFC<IndexPageProps> = ({ tzNames }) => {
const [timezone, setTimezone] = useState<string>(() => timezoneNames[0].value);
const [timeString, setTimeString] = useState<string>('');
const [dateString, setDateString] = useState<string>('');
const router = useRouter();
const timestampQuery = router.query[TS_QUERY_PARAM];
const initialTimestamp = useMemo<number | null>(() => {
if (typeof timestampQuery === 'string') {
const timestampNumber = parseInt(timestampQuery, 10);
if (!isNaN(timestampNumber) && isFinite(timestampNumber)) {
return timestampNumber;
}
}
return null;
}, [timestampQuery]);
const [timestamp, setTimestamp] = useState<Moment | null>(null);
const timestampInSeconds = useMemo(() => String(timestamp?.unix() || '0'), [timestamp]);

const handleTimezoneChange = useMemo(
() =>
Expand All @@ -49,11 +67,20 @@ const IndexPage: VFC<IndexPageProps> = ({ tzNames }) => {
}, []);

useEffect(() => {
const clientMoment = moment().seconds(0).milliseconds(0);
let clientMoment: Moment | undefined;
let clientTimezone: string | null = null;
if (typeof initialTimestamp === 'number') {
const initialDate = moment.tz(initialTimestamp * 1000, 'GMT');
if (initialDate.isValid()) {
clientTimezone = 'GMT';
clientMoment = initialDate;
}
}
if (!clientMoment) clientMoment = moment().seconds(0).milliseconds(0);
setTimeString(clientMoment.format(isoTimeFormat));
setDateString(clientMoment.format(isoDateFormat));
handleTimezoneChange(null);
}, [handleTimezoneChange]);
handleTimezoneChange(clientTimezone);
}, [handleTimezoneChange, initialTimestamp]);

useEffect(() => {
if (!dateString || !timeString) return;
Expand All @@ -74,6 +101,8 @@ const IndexPage: VFC<IndexPageProps> = ({ tzNames }) => {
return originalText;
}, [locale, t]);

const fixedTimestamp = initialTimestamp !== null;

return (
<Layout>
<AppContainer bg="discord">
Expand All @@ -92,18 +121,38 @@ const IndexPage: VFC<IndexPageProps> = ({ tzNames }) => {
handleTimeChange={handleTimeChange}
timezone={timezone}
timezoneNames={timezoneNames}
/>
<TimestampsTable {...commonProps} timestamp={timestamp} />
fixedTimestamp={fixedTimestamp}
>
<FormGroup>
<Link href={fixedTimestamp ? '/' : `/?${TS_QUERY_PARAM}=${timestampInSeconds}`} passHref>
<Button tag="a" size="lg" color={fixedTimestamp ? 'danger' : 'info'}>
<FontAwesomeIcon icon={fixedTimestamp ? 'times-circle' : 'lock'} />
</Button>
</Link>
</FormGroup>
</TimestampPicker>
<TimestampsTable {...commonProps} timestamp={timestamp} timeInSeconds={timestampInSeconds} />
</AppContainer>
</Layout>
);
};

export default IndexPage;

export const getStaticProps: GetStaticProps<IndexPageProps & SSRConfig> = async ({ locale }) => ({
props: {
tzNames: getSortedNormalizedTimezoneNames(),
...(await typedServerSideTranslations(locale, ['common'])),
},
});
export const getStaticProps: GetStaticProps<IndexPageProps & SSRConfig> = async ({ locale, params }) => {
const timestamp = params?.timestamp;
let initialTimestamp: number | null = null;
if (typeof timestamp === 'string') {
const timestampNumber = parseInt(timestamp, 10);
if (!isNaN(timestampNumber) && isFinite(timestampNumber)) {
initialTimestamp = timestampNumber;
}
}
return {
props: {
initialTimestamp,
tzNames: getSortedNormalizedTimezoneNames(),
...(await typedServerSideTranslations(locale, ['common'])),
},
};
};
Loading

0 comments on commit 24b70d5

Please sign in to comment.