Skip to content

Commit

Permalink
Merge branch 'develop' into OWA-99/prevent-logout-after-password-reset
Browse files Browse the repository at this point in the history
  • Loading branch information
mirovladimitrovski authored Nov 25, 2024
2 parents 422711a + 9d4b6a3 commit c09f694
Show file tree
Hide file tree
Showing 31 changed files with 159 additions and 104 deletions.
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 @@ -9,12 +9,12 @@ exports[`<CardGrid> > renders and matches snapshot 1`] = `
role="grid"
>
<div
aria-rowindex="0"
aria-rowindex="1"
class="_row_19b484"
role="row"
>
<div
aria-colindex="0"
aria-colindex="1"
class="_cell_19b484"
id="layout_grid_0-0"
role="gridcell"
Expand Down Expand Up @@ -48,15 +48,15 @@ exports[`<CardGrid> > renders and matches snapshot 1`] = `
<div
class="_tag_d75732"
>
4 min
4 common:abbreviation.minutes
</div>
</div>
</div>
</div>
</a>
</div>
<div
aria-colindex="1"
aria-colindex="2"
class="_cell_19b484"
id="layout_grid_0-1"
role="gridcell"
Expand Down Expand Up @@ -90,15 +90,15 @@ exports[`<CardGrid> > renders and matches snapshot 1`] = `
<div
class="_tag_d75732"
>
10 min
10 common:abbreviation.minutes
</div>
</div>
</div>
</div>
</a>
</div>
<div
aria-colindex="2"
aria-colindex="3"
class="_cell_19b484"
id="layout_grid_0-2"
role="gridcell"
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 @@ -25,12 +25,12 @@ exports[`<Favorites> > renders and matches snapshot 1`] = `
role="grid"
>
<div
aria-rowindex="0"
aria-rowindex="1"
class="_row_19b484"
role="row"
>
<div
aria-colindex="0"
aria-colindex="1"
class="_cell_19b484"
id="layout_grid_0-0"
role="gridcell"
Expand Down Expand Up @@ -69,15 +69,15 @@ exports[`<Favorites> > renders and matches snapshot 1`] = `
<div
class="_tag_d75732"
>
2 min
2 common:abbreviation.minutes
</div>
</div>
</div>
</div>
</a>
</div>
<div
aria-colindex="1"
aria-colindex="2"
class="_cell_19b484"
id="layout_grid_0-1"
role="gridcell"
Expand Down Expand Up @@ -116,15 +116,15 @@ exports[`<Favorites> > renders and matches snapshot 1`] = `
<div
class="_tag_d75732"
>
3 min
3 common:abbreviation.minutes
</div>
</div>
</div>
</div>
</a>
</div>
<div
aria-colindex="2"
aria-colindex="3"
class="_cell_19b484"
id="layout_grid_0-2"
role="gridcell"
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 @@ -285,7 +285,7 @@ $mobile-landscape-height: 100vh;
}

&:hover {
transform: scale(1.2) translateY(-50%);;
transform: scale(1.2) translateY(-50%);
}

&:disabled {
Expand Down Expand Up @@ -361,7 +361,7 @@ $mobile-landscape-height: 100vh;
}
}

&[aria-hidden="true"] {
&[disabled] {
cursor: default;
}
}
Expand Down
82 changes: 42 additions & 40 deletions packages/ui-react/src/components/HeroShelf/HeroShelfPagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,53 +50,55 @@ const HeroShelfPagination = ({ playlist, index: indexIn, direction, nextIndex: n
}, [playlist.playlist, placeholderCount]);

return (
<nav className={styles.dots}>
<>
<div aria-live="polite" className="hidden">
{t('slide_indicator', { page: indexIn + 1, pages: playlist.playlist.length })}
</div>
<ul className={styles.dotsList}>
{playlistWithPlaceholders.map((current, itemIndex) => {
if (itemIndex < index - range - 1 || itemIndex > index + range + 1) {
return null;
}
if (!current) {
return <div className={classNames(styles.dotPlaceholder)} key={itemIndex} aria-hidden="true" />;
}
<nav className={styles.dots}>
<ul className={styles.dotsList}>
{playlistWithPlaceholders.map((current, itemIndex) => {
if (itemIndex < index - range - 1 || itemIndex > index + range + 1) {
return null;
}
if (!current) {
return <li className={classNames(styles.dotPlaceholder)} key={itemIndex} aria-hidden="true" />;
}

const movementBase = 22; // dot width (10) + gap(12)
const movementTotal = Math.abs(index - nextIndex) * movementBase;
const movement = direction === 'left' ? movementTotal : direction === 'right' ? 0 - movementTotal : 0;
const transform = `translateX(${movement}px)`;
const transition = direction
? `transform ${animationDuration}ms ease-out ${animationDuration / 3}ms, width ${animationDuration / 2}ms ease-out ${animationDuration / 3}ms`
: '';
const movementBase = 22; // dot width (10) + gap(12)
const movementTotal = Math.abs(index - nextIndex) * movementBase;
const movement = direction === 'left' ? movementTotal : direction === 'right' ? 0 - movementTotal : 0;
const transform = `translateX(${movement}px)`;
const transition = direction
? `transform ${animationDuration}ms ease-out ${animationDuration / 3}ms, width ${animationDuration / 2}ms ease-out ${animationDuration / 3}ms`
: '';

const size = calculateDotSize(direction, itemIndex, index, range, 0.6);
const transformDiv = `scale(${size})`;
const transitionDiv = direction
? `width ${animationDuration}ms ease-out, height ${animationDuration}ms ease-out, transform ${animationDuration}ms ease-out`
: '';
const size = calculateDotSize(direction, itemIndex, index, range, 0.6);
const transformDiv = `scale(${size})`;
const transitionDiv = direction
? `width ${animationDuration}ms ease-out, height ${animationDuration}ms ease-out, transform ${animationDuration}ms ease-out`
: '';

const isCurrent = itemIndex === index;
const hidden = size !== 1;
const ariaLabel = hidden ? undefined : t('slide_to', { item: itemIndex - placeholderCount + 1, items: playlist.playlist.length });
const isCurrent = itemIndex === index;
const hidden = size !== 1;
const ariaLabel = hidden ? undefined : t('slide_to', { item: itemIndex - placeholderCount + 1, items: playlist.playlist.length });

return (
<button
key={current?.mediaid}
className={classNames(styles.dot, itemIndex === nextIndex && styles.dotActive, !direction && itemIndex === index && styles.dotActive)}
style={{ transform, transition }}
aria-label={ariaLabel}
aria-hidden={hidden ? 'true' : undefined}
aria-current={isCurrent ? 'true' : undefined}
onClick={hidden || isCurrent ? undefined : () => setIndex(itemIndex - placeholderCount)}
>
<div style={{ transform: transformDiv, transition: transitionDiv }} />
</button>
);
})}
</ul>
</nav>
return (
<li key={current?.mediaid} aria-hidden={hidden || undefined} aria-current={isCurrent || undefined}>
<button
className={classNames(styles.dot, itemIndex === nextIndex && styles.dotActive, !direction && itemIndex === index && styles.dotActive)}
style={{ transform, transition }}
aria-label={ariaLabel}
disabled={hidden || undefined}
onClick={hidden || isCurrent ? undefined : () => setIndex(itemIndex - placeholderCount)}
>
<div style={{ transform: transformDiv, transition: transitionDiv }} />
</button>
</li>
);
})}
</ul>
</nav>
</>
);
};

Expand Down
4 changes: 2 additions & 2 deletions packages/ui-react/src/components/LayoutGrid/LayoutGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,13 @@ const LayoutGrid = <Item extends object>({ className, columnCount, data, renderC
return (
<div role="grid" ref={gridRef} aria-rowcount={rowCount} className={className} onKeyDown={handleKeyDown}>
{Array.from({ length: rowCount }).map((_, rowIndex) => (
<div role="row" key={rowIndex} aria-rowindex={rowIndex} className={styles.row}>
<div role="row" key={rowIndex} aria-rowindex={rowIndex + 1} className={styles.row}>
{data.slice(rowIndex * columnCount, rowIndex * columnCount + columnCount).map((item, columnIndex) => (
<div
role="gridcell"
id={`layout_grid_${rowIndex}-${columnIndex}`}
key={getCellKey(item)}
aria-colindex={columnIndex}
aria-colindex={columnIndex + 1}
className={styles.cell}
style={gridCellStyle}
>
Expand Down
Loading

0 comments on commit c09f694

Please sign in to comment.