Skip to content

Commit

Permalink
OI-2878: Implement mobile view for metadata viewer (#4322)
Browse files Browse the repository at this point in the history
* feat: implement mobile view for metadata viewer

* chore: fix formatting

* chore: add checkmark
- don't display null or zero data

* chore: CSS fixes
  • Loading branch information
moz-rotimib committed Jan 18, 2024
1 parent 6c94d31 commit 190c5fd
Show file tree
Hide file tree
Showing 9 changed files with 411 additions and 53 deletions.
5 changes: 5 additions & 0 deletions web/locales/en/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,11 @@ dataset-version = Version
sha256-checksum-copied = SHA256 Checksum Copied!
sha256-checksum-copied-error = Failed to copy SHA256 Checksum
clipboard-not-supported = Clipboard not supported
no-information-available = No information available
# dataset metadata
dataset-metadata-sex = Sex
# dataset metadata
dataset-metadata-age = Age
## Download Modal
download-title = Your download has started.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import classNames from 'classnames';
import * as React from 'react';
import { formatBytes, msToHours } from '../../../utility';
import { useLocale } from '../../locale-helpers';

import './dataset-corpus-download-table.css';

interface Props {
Expand Down Expand Up @@ -79,7 +80,7 @@ const DatasetCorpusDownloadTable = ({
const [locale] = useLocale();

return (
<table className="table dataset-table">
<table className="table dataset-table hidden-md-down">
<thead>
<tr>
{Object.values(COLUMNS).map(column => {
Expand Down
13 changes: 12 additions & 1 deletion web/src/components/pages/datasets/dataset-corpus-download.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
background: var(--lighter-grey);
display: flex;
justify-content: center;
.dataset-corpus-download-container{
.dataset-corpus-download-container {
@media (--xl-up) {
transform: translateY(-2%);
}
Expand Down Expand Up @@ -121,4 +121,15 @@
}
}
}

.table-metadata-container {
display: flex;

& .table-email-prompt-container {
display: flex;
width: 100%;
align-items: start;
flex-direction: column;
}
}
}
69 changes: 33 additions & 36 deletions web/src/components/pages/datasets/dataset-corpus-download.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,32 @@ import { LabeledSelect, Spinner } from '../../ui/ui';

import DatasetDownloadEmailPrompt from './dataset-download-email-prompt';

import './dataset-corpus-download.css';
import { useAPI } from '../../../hooks/store-hooks';
import DatasetCorpusDownloadTable from './dataset-corpus-download-table';
import PageHeading from '../../ui/page-heading';
import { formatBytes } from '../../../utility';
import { DeltaReadMoreLink } from '../../shared/links';
import { MobileDatasetMetadataViewer } from './metadata-viewer/mobile/metadata-viewer';

import { LanguageDataset } from './metadata-viewer/types';

import './dataset-corpus-download.css';

interface Props extends WithLocalizationProps {
languagesWithDatasets: { id: number; name: string }[];
initialLanguage: string;
isSubscribedToMailingList: boolean;
}

type LanguageDatasets = {
download_path: string;
id: number;
checksum: string;
size: number;
};

const DatasetCorpusDownload = ({
getString,
languagesWithDatasets,
initialLanguage,
isSubscribedToMailingList,
}: Props) => {
const [isLoading, setIsLoading] = useState(true);
const [selectedDataset, setSelectedDataset] = useState<LanguageDatasets>();
const [languageDatasets, setLanguageDatasets] = useState<LanguageDatasets[]>(
const [selectedDataset, setSelectedDataset] = useState<LanguageDataset>();
const [languageDatasets, setLanguageDatasets] = useState<LanguageDataset[]>(
[]
);
const api = useAPI();
Expand All @@ -63,7 +60,7 @@ const DatasetCorpusDownload = ({

api.getLanguageDatasetStats(locale).then(data => {
setLanguageDatasets(
data.filter((dataset: LanguageDatasets) => !!dataset.download_path)
data.filter((dataset: LanguageDataset) => !!dataset.download_path)
);
setSelectedDataset(data[0]);
setIsLoading(false);
Expand Down Expand Up @@ -101,32 +98,32 @@ const DatasetCorpusDownload = ({
))}
</LabeledSelect>
</div>
<div
style={{
display: 'flex',
width: '100%',
alignItems: 'start',
flexDirection: 'column',
}}>
{isLoading && <Spinner />}
{!isLoading && languageDatasets && (
<DatasetCorpusDownloadTable
onRowSelect={handleRowSelect}
releaseData={languageDatasets}
selectedId={selectedDataset?.id || languageDatasets[0].id}
/>
)}
<div className="table-metadata-container">
<div className="table-email-prompt-container">
{isLoading && <Spinner />}
{!isLoading && languageDatasets && (
<DatasetCorpusDownloadTable
onRowSelect={handleRowSelect}
releaseData={languageDatasets}
selectedId={selectedDataset?.id || languageDatasets[0].id}
/>
)}

{!isLoading && languageDatasets && (
<MobileDatasetMetadataViewer releaseData={languageDatasets} />
)}

{selectedDataset && selectedDataset.download_path && (
<DatasetDownloadEmailPrompt
selectedLocale={locale}
downloadPath={selectedDataset.download_path}
releaseId={selectedDataset.id.toString()}
checksum={selectedDataset.checksum}
size={formatBytes(selectedDataset.size, initialLanguage)}
isSubscribedToMailingList={isSubscribedToMailingList}
/>
)}
{selectedDataset && selectedDataset.download_path && (
<DatasetDownloadEmailPrompt
selectedLocale={locale}
downloadPath={selectedDataset.download_path}
releaseId={selectedDataset.id.toString()}
checksum={selectedDataset.checksum}
size={formatBytes(selectedDataset.size, initialLanguage)}
isSubscribedToMailingList={isSubscribedToMailingList}
/>
)}
</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import React from 'react'
import { Localized, useLocalization } from '@fluent/react'
import classNames from 'classnames'

import { CheckMark, ChevronDown } from '../../../../ui/icons'
import { LanguageDataset } from '../types'
import { formatBytes, msToHours } from '../../../../../utility'

type Props = {
releaseData: LanguageDataset
locale: string
onSelect: (selecteId: number) => void
selectedId: number
}

const AGE_MAPPING = {
'': 'No information available',
teens: '< 20',
twenties: '20 - 29',
thirties: '30 - 39',
fourties: '40 - 49',
fifties: '50 - 59',
sixties: '60 - 69',
seventies: '70 - 79',
eighties: '80 - 89',
nineties: '90 - 99',
}

export const MetaDataViewerItem = ({
releaseData,
locale,
onSelect,
selectedId,
}: Props) => {
const { l10n } = useLocalization()

const isItemSelected = releaseData.id === selectedId

const { splits: { age, gender } = {} } = releaseData

return (
<div className="metadata-viewer-item">
<div
className={classNames('md-metadata-info', {
selected: isItemSelected,
})}
onClick={() => onSelect(releaseData.id)}>
<p className="release-name">
{isItemSelected && <CheckMark />}
{releaseData.name}
</p>
<div>
<p className="dataset-release-date">
{Intl.DateTimeFormat(locale).format(
new Date(releaseData.release_date)
)}
</p>
<ChevronDown className={isItemSelected ? 'expanded' : ''} />
</div>
</div>
<div className={`expanded-box ${!isItemSelected ? 'collapsed' : ''}`}>
<div>
<p className="metadata">
{l10n.getString('size')}
<span>{formatBytes(releaseData.size, locale)}</span>
</p>
<p className="metadata">
{l10n.getString('validated-hours')}
<span>
{Intl.NumberFormat(locale).format(
msToHours(releaseData.valid_clips_duration)
)}
</span>
</p>
<p className="metadata">
{l10n.getString('number-of-voices')}
<span>
{releaseData.total_users.toLocaleString(locale, {
style: 'decimal',
})}
</span>
</p>
{releaseData?.splits?.age && (
<div className="age">
<Localized id="dataset-metadata-age">
<p className="metadata" />
</Localized>

<div className="age-splits">
{(Object.keys(AGE_MAPPING) as Array<keyof typeof age>).map(
el =>
el.length > 0 &&
age[el] > 0 && (
<p key={el}>
<span>{`${Math.round(age[el] * 100)}%`}</span>
{AGE_MAPPING[el]}
</p>
)
)}
</div>
</div>
)}
</div>
<div>
<p className="metadata">
{l10n.getString('recorded-hours')}
<span>
{Intl.NumberFormat(locale).format(
msToHours(releaseData.total_clips_duration)
)}
</span>
</p>
<p className="metadata">
{l10n.getString('cv-license')} <span>CC-0</span>
</p>
<p className="metadata">
{l10n.getString('audio-format')} <span>MP3</span>
</p>

{releaseData?.splits?.gender && (
<div className="sex">
<Localized id="dataset-metadata-sex">
<p className="metadata" />
</Localized>

<div className="gender-splits">
{(
Object.keys(releaseData.splits.gender) as Array<
keyof typeof gender
>
).map(
el =>
el.length > 0 &&
gender[el] > 0 && (
<p key={el} className="gender">
<span>{`${Math.round(gender[el] * 100)}%`}</span>
{el}
</p>
)
)}
</div>
</div>
)}
</div>
</div>
</div>
)
}
Loading

0 comments on commit 190c5fd

Please sign in to comment.