Skip to content

Commit

Permalink
[C-2675][C-2692] Add multi track navigation sidebar and form controls (
Browse files Browse the repository at this point in the history
  • Loading branch information
amendelsohn committed Aug 3, 2023
1 parent ee38400 commit af62892
Show file tree
Hide file tree
Showing 18 changed files with 437 additions and 66 deletions.
Expand Up @@ -212,6 +212,17 @@
--text-color: var(--background-white);
}

/* Plain */
.plain {
--button-color: transparent;
--text-color: var(--neutral);
background: transparent;
border: none;
border-radius: 0;
padding: 0;
height: 100%;
}

.secondary.disabled,
.tertiary.disabled,
.destructive.disabled,
Expand Down
Expand Up @@ -36,7 +36,8 @@ const TYPE_STYLE_MAP: { [k in HarmonyButtonType]: string } = {
[HarmonyButtonType.SECONDARY]: styles.secondary,
[HarmonyButtonType.TERTIARY]: styles.tertiary,
[HarmonyButtonType.DESTRUCTIVE]: styles.destructive,
[HarmonyButtonType.GHOST]: styles.ghost
[HarmonyButtonType.GHOST]: styles.ghost,
[HarmonyButtonType.PLAIN]: styles.plain
}

/**
Expand Down
3 changes: 2 additions & 1 deletion packages/stems/src/components/HarmonyButton/types.ts
Expand Up @@ -9,7 +9,8 @@ export enum HarmonyButtonType {
SECONDARY = 'secondary',
TERTIARY = 'tertiary',
DESTRUCTIVE = 'destructive',
GHOST = 'ghost'
GHOST = 'ghost',
PLAIN = 'plain'
}

export enum HarmonyButtonSize {
Expand Down
3 changes: 3 additions & 0 deletions packages/web/src/assets/img/iconTrash.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/web/src/components/Icon/Icon.tsx
Expand Up @@ -6,6 +6,7 @@ import cn from 'classnames'
import styles from './Icon.module.css'

type IconSize =
| 'xxSmall' // 12
| 'xSmall' // 14
| 'small' // 16
| 'medium' // 20
Expand Down
9 changes: 6 additions & 3 deletions packages/web/src/components/layout/layout.module.css
Expand Up @@ -12,15 +12,18 @@
.gap1 {
gap: var(--unit-1);
}

.gap2 {
gap: var(--unit-2);
}

.gap3 {
gap: var(--unit-3);
}
.gap4 {
gap: var(--unit-4);
}

.gap5 {
gap: var(--unit-5);
}
.gap6 {
gap: var(--unit-6);
}
@@ -1,12 +1,15 @@
.editForm {
.formContainer {
width: 100%;
background-color: var(--white);

display: flex;
flex-direction: column;
padding: var(--unit-4);
border-radius: 8px;
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.04), 0px 8px 16px rgba(0, 0, 0, 0.08);
box-shadow: var(--shadow-far);
}

.trackEditForm {
padding: var(--unit-4);
}

.continue {
Expand All @@ -18,3 +21,22 @@
font-weight: var(--font-bold);
font-size: var(--font-l);
}

.multiTrackHeader {
padding: var(--unit-4);
border-radius: 8px 8px 0px 0px;
border-bottom: 1px solid var(--border-strong);
background: var(--background-surface-1);
}

.multiTrackFooter {
padding: var(--unit-4);
border-radius: 0px 0px 8px 8px;
border-top: 1px solid var(--border-strong);
background: var(--background-surface-1);
justify-content: space-between;
}

.multiTrackFooter .disabled {
opacity: 0.5;
}
124 changes: 98 additions & 26 deletions packages/web/src/pages/upload-page/components/EditPageNew.tsx
@@ -1,12 +1,19 @@
import { useCallback, useMemo } from 'react'

import { HarmonyButton, HarmonyButtonType, IconArrow } from '@audius/stems'
import {
HarmonyButton,
HarmonyButtonType,
IconArrow,
IconCaretRight
} from '@audius/stems'
import cn from 'classnames'
import { Form, Formik } from 'formik'
import { Form, Formik, FormikProps, useField } from 'formik'
import moment from 'moment'
import * as Yup from 'yup'

import { ReactComponent as IconCaretLeft } from 'assets/img/iconCaretLeft.svg'
import layoutStyles from 'components/layout/layout.module.css'
import { Text } from 'components/typography'
import PreviewButton from 'components/upload/PreviewButton'

import { MultiTrackSidebar } from '../fields/MultiTrackSidebar'
Expand All @@ -21,7 +28,11 @@ import { TrackForUpload } from './types'
const messages = {
titleError: 'Your track must have a name',
artworkError: 'Artwork is required',
genreError: 'Genre is required'
genreError: 'Genre is required',
multiTrackCount: (index: number, total: number) =>
`TRACK ${index} of ${total}`,
prev: 'Prev',
next: 'Next Track'
}

type EditPageProps = {
Expand Down Expand Up @@ -78,35 +89,96 @@ export const EditPageNew = (props: EditPageProps) => {
[onContinue, setTracks, tracks]
)

const isMultiTrack = tracks.length > 1

return (
<Formik<TrackEditFormValues>
initialValues={initialValues}
onSubmit={onSubmit}
validationSchema={EditTrackSchema}
>
{() => (
<Form>
<div className={cn(layoutStyles.row, layoutStyles.gap2)}>
<div className={styles.editForm}>
<TrackMetadataFields playing={false} />
<TrackModalArray />
<PreviewButton playing={false} onClick={() => {}} />
</div>
{isMultiTrack ? <MultiTrackSidebar tracks={tracks} /> : null}
</div>
<div className={styles.continue}>
<HarmonyButton
variant={HarmonyButtonType.PRIMARY}
text='Continue'
name='continue'
iconRight={IconArrow}
className={styles.continueButton}
/>
</div>
</Form>
)}
{TrackEditForm}
</Formik>
)
}

const TrackEditForm = (props: FormikProps<TrackEditFormValues>) => {
const { values } = props
const isMultiTrack = values.trackMetadatas.length > 1

return (
<Form>
<div className={cn(layoutStyles.row, layoutStyles.gap2)}>
<div className={styles.formContainer}>
{isMultiTrack ? <MultiTrackHeader /> : null}
<div className={styles.trackEditForm}>
<TrackMetadataFields playing={false} />
<TrackModalArray />
<PreviewButton playing={false} onClick={() => {}} />
</div>
{isMultiTrack ? <MultiTrackFooter /> : null}
</div>
{isMultiTrack ? <MultiTrackSidebar /> : null}
</div>
{!isMultiTrack ? (
<div className={styles.continue}>
<HarmonyButton
variant={HarmonyButtonType.PRIMARY}
text='Continue'
name='continue'
iconRight={IconArrow}
className={styles.continueButton}
/>
</div>
) : null}
</Form>
)
}

const MultiTrackHeader = () => {
const [{ value: index }] = useField('trackMetadatasIndex')
const [{ value: trackMetadatas }] = useField('trackMetadatas')

return (
<div className={styles.multiTrackHeader}>
<Text variant='title' size='xSmall'>
{messages.multiTrackCount(index + 1, trackMetadatas.length)}
</Text>
</div>
)
}

const MultiTrackFooter = () => {
const [{ value: index }, , { setValue: setIndex }] = useField(
'trackMetadatasIndex'
)
const [{ value: trackMetadatas }] = useField('trackMetadatas')

const goPrev = useCallback(() => {
setIndex(Math.max(index - 1, 0))
}, [index, setIndex])
const goNext = useCallback(() => {
setIndex(Math.min(index + 1, trackMetadatas.length - 1))
}, [index, setIndex, trackMetadatas.length])

const prevDisabled = index === 0
const nextDisabled = index === trackMetadatas.length - 1
return (
<div className={cn(styles.multiTrackFooter, layoutStyles.row)}>
<HarmonyButton
className={cn({ [styles.disabled]: prevDisabled })}
variant={HarmonyButtonType.PLAIN}
text={messages.prev}
iconLeft={IconCaretLeft}
onClick={goPrev}
disabled={prevDisabled}
/>
<HarmonyButton
className={cn({ [styles.disabled]: nextDisabled })}
variant={HarmonyButtonType.PLAIN}
text={messages.next}
iconRight={IconCaretRight}
onClick={goNext}
disabled={nextDisabled}
/>
</div>
)
}
Expand Up @@ -7,7 +7,7 @@
padding: var(--unit-4) var(--unit-6);
gap: var(--unit-4);

border: 1px solid var(--neutral-light-8);
border: 1px solid var(--border-strong);
border-radius: 8px;
}

Expand Down
107 changes: 107 additions & 0 deletions packages/web/src/pages/upload-page/fields/MultiTrackSidebar.module.css
@@ -0,0 +1,107 @@
.root {
position: sticky;
top: 152px;
align-self: flex-start;
border-radius: 8px;

flex-shrink: 0;
width: 320px;
background: var(--background-surface-1);
box-shadow: var(--shadow-far);
}

.title {
padding: var(--unit-4);
border-radius: 8px 8px 0px 0px;
border-bottom: 1px solid var(--border-strong);
}

.body {
padding: var(--unit-4);
border-radius: 0px 0px 8px 8px;
background: var(--white);
}

.iconError {
height: 12px;
width: 12px;
}

/* Track */
.tracks {
margin: 0 calc(-1 * var(--unit-4));
}

.track {
justify-content: space-between;
}

.trackRoot {
cursor: pointer;
position: relative;
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
}
.trackRoot:hover {
background: var(--neutral-light-9);
border-top: 1px solid var(--border-strong);
border-bottom: 1px solid var(--border-strong);
}

.trackInfo {
width: 100%;
padding: var(--unit-2) var(--unit-4);
}
.trackInfo.selected {
color: var(--secondary);
}
.trackInfo.error {
color: var(--accent-red);
}

.trackTitleContainer {
min-width: 0;
flex-grow: 1;
}
.trackTitleContainer > * {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}

.selectedIndicator {
width: 4px;
height: 42px;
position: absolute;
top: 6px;
border-radius: 0px 8px 8px 0px;
background: var(--secondary);
}

.trackIndex {
padding: var(--unit-2);
}

.artwork {
width: 40px;
height: 40px;
border-radius: 4px;
border: 1px solid var(--border-strong);
background: lightgray 50% / cover no-repeat;
border: 1px solid var(--border-strong);
transition: border ease-in-out 0.1s;
}

.trackInfo .iconError {
height: 16px;
width: 16px;
margin: var(--unit-1);
}

.iconRemove {
padding-right: 8px;
display: none;
}
.trackRoot:hover .iconRemove {
display: flex;
}

0 comments on commit af62892

Please sign in to comment.