Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat / Add new languages (nl/fr/de) #651

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions packages/common/src/utils/formatting.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
export const formatDurationTag = (seconds: number) => {
import type { DurationAbbreviation } from '../../types/i18n';

export const formatDurationTag = (seconds: number, { minutesAbbreviation }: Pick<DurationAbbreviation, 'minutesAbbreviation'>) => {
if (!seconds) return '';

const minutes = Math.ceil(seconds / 60);

return `${minutes} min`;
return `${minutes} ${minutesAbbreviation}`;
};

/**
Expand All @@ -16,14 +18,14 @@ export const formatDurationTag = (seconds: number) => {
* @returns string, such as '2hrs 24min' or '31min'
*/

export const formatDuration = (duration: number) => {
export const formatDuration = (duration: number, { hoursAbbreviation, minutesAbbreviation }: DurationAbbreviation) => {
if (!duration) return '';

const hours = Math.floor(duration / 3600);
const minutes = Math.round((duration - hours * 3600) / 60);

const hoursString = hours ? `${hours}hrs` : '';
const minutesString = minutes ? `${minutes}min` : '';
const hoursString = hours ? `${hours}${hoursAbbreviation}` : '';
const minutesString = minutes ? `${minutes}${minutesAbbreviation}` : '';

return [hoursString, minutesString].filter(Boolean).join(' ');
};
Expand Down
13 changes: 7 additions & 6 deletions packages/common/src/utils/metadata.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import type { Playlist, PlaylistItem } from '../../types/playlist';
import type { DurationAbbreviation } from '../../types/i18n';

import { formatDuration, formatVideoSchedule } from './formatting';

export const createVideoMetadata = (media: PlaylistItem, episodesLabel?: string) => {
export const createVideoMetadata = (media: PlaylistItem, i18n: DurationAbbreviation & { episodesLabel?: string }) => {
const metaData = [];
const duration = formatDuration(media.duration);
const duration = formatDuration(media.duration, i18n);

if (media.pubdate) metaData.push(String(new Date(media.pubdate * 1000).getFullYear()));
if (!episodesLabel && duration) metaData.push(duration);
if (episodesLabel) metaData.push(episodesLabel);
if (!i18n.episodesLabel && duration) metaData.push(duration);
if (i18n.episodesLabel) metaData.push(i18n.episodesLabel);
if (media.genre) metaData.push(media.genre);
if (media.rating) metaData.push(media.rating);

Expand All @@ -23,10 +24,10 @@ export const createPlaylistMetadata = (playlist: Playlist, episodesLabel?: strin

return metaData;
};
export const createLiveEventMetadata = (media: PlaylistItem, locale: string) => {
export const createLiveEventMetadata = (media: PlaylistItem, locale: string, i18n: DurationAbbreviation) => {
const metaData = [];
const scheduled = formatVideoSchedule(locale, media.scheduledStart, media.scheduledEnd);
const duration = formatDuration(media.duration);
const duration = formatDuration(media.duration, i18n);

if (scheduled) metaData.push(scheduled);
if (duration) metaData.push(duration);
Expand Down
5 changes: 5 additions & 0 deletions packages/common/types/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@ export type LanguageDefinition = {
code: string;
displayName: string;
};

export type DurationAbbreviation = {
hoursAbbreviation: string;
minutesAbbreviation: string;
};
2 changes: 1 addition & 1 deletion packages/ui-react/src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function Card({
} else if (episodeNumber) {
return <div className={styles.tag}>{formatSeriesMetaString(seasonNumber, episodeNumber)}</div>;
} else if (duration) {
return <div className={styles.tag}>{formatDurationTag(duration)}</div>;
return <div className={styles.tag}>{formatDurationTag(duration, { minutesAbbreviation: t('common:abbreviation.minutes') })}</div>;
} else if (isLive) {
return <div className={classNames(styles.tag, styles.live)}>{t('live')}</div>;
} else if (isScheduled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ exports[`<Card> > should render anchor tag 1`] = `
<div
class="_tag_d75732"
>
2 min
2 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ exports[`<CardGrid> > renders and matches snapshot 1`] = `
<div
class="_tag_d75732"
>
4 min
4 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down Expand Up @@ -90,7 +90,7 @@ exports[`<CardGrid> > renders and matches snapshot 1`] = `
<div
class="_tag_d75732"
>
10 min
10 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down Expand Up @@ -132,7 +132,7 @@ exports[`<CardGrid> > renders and matches snapshot 1`] = `
<div
class="_tag_d75732"
>
11 min
11 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ exports[`<CheckoutForm> > renders and matches snapshot 1`] = `
class="_label_86f2f5"
for="text-field_1235_cardnumber"
>
Card number
payment.credit_card_number
<span
aria-hidden="true"
>
Expand Down Expand Up @@ -163,7 +163,7 @@ exports[`<CheckoutForm> > renders and matches snapshot 1`] = `
class="_label_86f2f5"
for="text-field_1235_cardexpiry"
>
Expiry date
payment.credit_card_expiry_date
<span
aria-hidden="true"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ exports[`<Favorites> > renders and matches snapshot 1`] = `
<div
class="_tag_d75732"
>
2 min
2 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down Expand Up @@ -116,7 +116,7 @@ exports[`<Favorites> > renders and matches snapshot 1`] = `
<div
class="_tag_d75732"
>
3 min
3 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down Expand Up @@ -163,7 +163,7 @@ exports[`<Favorites> > renders and matches snapshot 1`] = `
<div
class="_tag_d75732"
>
13 min
13 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ exports[`Shelf Component tests > Featured shelf 1`] = `
<div
class="_tag_d75732"
>
21 min
21 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down Expand Up @@ -100,7 +100,7 @@ exports[`Shelf Component tests > Featured shelf 1`] = `
<div
class="_tag_d75732"
>
1 min
1 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down Expand Up @@ -136,7 +136,7 @@ exports[`Shelf Component tests > Featured shelf 1`] = `
<div
class="_tag_d75732"
>
1 min
1 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down Expand Up @@ -246,7 +246,7 @@ exports[`Shelf Component tests > Regular shelf 1`] = `
<div
class="_tag_d75732"
>
1 min
1 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down Expand Up @@ -286,7 +286,7 @@ exports[`Shelf Component tests > Regular shelf 1`] = `
<div
class="_tag_d75732"
>
1 min
1 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down Expand Up @@ -326,7 +326,7 @@ exports[`Shelf Component tests > Regular shelf 1`] = `
<div
class="_tag_d75732"
>
1 min
1 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down Expand Up @@ -366,7 +366,7 @@ exports[`Shelf Component tests > Regular shelf 1`] = `
<div
class="_tag_d75732"
>
21 min
21 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function VideoListItem({ onHover, progress, activeLabel, item, url, loading = fa
} else if (episodeNumber) {
return <div className={styles.tag}>{formatSeriesMetaString(seasonNumber, episodeNumber)}</div>;
} else if (duration) {
return <div className={styles.tag}>{formatDurationTag(duration)}</div>;
return <div className={styles.tag}>{formatDurationTag(duration, { minutesAbbreviation: t('common:abbreviation.minutes') })}</div>;
} else if (isLive) {
return <div className={classNames(styles.tag, styles.live)}>{t('live')}</div>;
} else if (isScheduled) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import { useTranslation } from 'react-i18next';

import TextField from '../TextField/TextField';

Expand All @@ -10,6 +11,7 @@ type Props = {
};

const CreditCardExpiryField: React.FC<Props> = ({ value, onChange, error, ...props }: Props) => {
const { t } = useTranslation('account');
const formatExpirationDate: React.ChangeEventHandler<HTMLInputElement> = (e) => {
let clearValue = e.target.value.replace(/\D+/g, '');

Expand All @@ -34,7 +36,7 @@ const CreditCardExpiryField: React.FC<Props> = ({ value, onChange, error, ...pro
};
return (
<TextField
label={`Expiry date`}
label={t('payment.credit_card_expiry_date')}
{...props}
name="cardExpiry"
className="directPostExpiryDate"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ exports[`<CreditCardExpiryField> > renders and matches snapshot 1`] = `
class="_label_86f2f5"
for="text-field_1235_cardexpiry"
>
Expiry date
payment.credit_card_expiry_date
<span
aria-hidden="true"
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import Payment from 'payment';

import TextField from '../TextField/TextField';
Expand All @@ -25,6 +26,7 @@ const cardIssuers: { [key: string]: string } = {
};

const CreditCardNumberField: React.FC<Props> = ({ value, error, onChange, onBlur, ...props }: Props) => {
const { t } = useTranslation('account');
const [cardIssuer, setCardIssuer] = useState<JSX.Element | null>(null);

const formatCreditCardNumber: React.ChangeEventHandler<HTMLInputElement> = (e) => {
Expand Down Expand Up @@ -62,7 +64,7 @@ const CreditCardNumberField: React.FC<Props> = ({ value, error, onChange, onBlur
<TextField
value={value}
name="cardNumber"
label={`Card number`}
label={t('payment.credit_card_number')}
className="directPostCreditCardNumber"
onChange={formatCreditCardNumber}
onBlur={onBlur}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ exports[`<CreditCardNumberField> > renders and matches snapshot 1`] = `
class="_label_86f2f5"
for="text-field_1235_cardnumber"
>
Card number
payment.credit_card_number
<span
aria-hidden="true"
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useLocation } from 'react-router';
import { useConfigStore } from '@jwp/ott-common/src/stores/ConfigStore';
import { shallow } from '@jwp/ott-common/src/utils/compare';
Expand All @@ -15,6 +16,7 @@ import HeaderActionButton from '../../components/Header/HeaderActionButton';
import styles from './HeaderSearch.module.scss';

const HeaderSearch = () => {
const { t } = useTranslation('menu');
const location = useLocation();
const searchInputRef = useRef<HTMLInputElement>(null) as React.MutableRefObject<HTMLInputElement>;

Expand Down Expand Up @@ -68,12 +70,12 @@ const HeaderSearch = () => {
inputRef={searchInputRef}
onClose={closeSearchButtonClickHandler}
/>
<HeaderActionButton aria-label="Close search" onClick={closeSearchButtonClickHandler}>
<HeaderActionButton aria-label={t('search_close')} onClick={closeSearchButtonClickHandler}>
<Icon icon={CloseIcon} />
</HeaderActionButton>
</div>
) : (
<HeaderActionButton aria-label="Open search" onClick={searchButtonClickHandler}>
<HeaderActionButton aria-label={t('search_open')} onClick={searchButtonClickHandler}>
<Icon icon={SearchIcon} />
</HeaderActionButton>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ exports[`Home Component tests > Home test 1`] = `
<div
class="_tag_d75732"
>
6 min
6 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down Expand Up @@ -113,7 +113,7 @@ exports[`Home Component tests > Home test 1`] = `
<div
class="_tag_d75732"
>
6 min
6 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down Expand Up @@ -192,7 +192,7 @@ exports[`Home Component tests > Home test 1`] = `
<div
class="_tag_d75732"
>
6 min
6 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down Expand Up @@ -232,7 +232,7 @@ exports[`Home Component tests > Home test 1`] = `
<div
class="_tag_d75732"
>
6 min
6 common:abbreviation.minutes
</div>
</div>
</div>
Expand Down
8 changes: 7 additions & 1 deletion packages/ui-react/src/pages/LegacySeries/LegacySeries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,13 @@ const LegacySeries = () => {
const backgroundImage = (selectedItem.backgroundImage as string) || undefined;

const primaryMetadata = episode ? (
<VideoMetaData attributes={createVideoMetadata(episode, t('video:total_episodes', { count: seriesPlaylist?.playlist?.length }))} />
<VideoMetaData
attributes={createVideoMetadata(episode, {
episodesLabel: t('video:total_episodes', { count: seriesPlaylist?.playlist?.length }),
hoursAbbreviation: t('common:abbreviation.hours'),
minutesAbbreviation: t('common:abbreviation.minutes'),
})}
/>
) : (
<VideoMetaData attributes={createPlaylistMetadata(seriesPlaylist, t('video:total_episodes', { count: seriesPlaylist?.playlist?.length }))} />
);
Expand Down
Loading
Loading