UploadAudio.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import React from 'react';
  2. import { Button, Tab } from 'semantic-ui-react';
  3. import { Form, withFormik } from 'formik';
  4. import { History } from 'history';
  5. import TxButton from '@polkadot/joy-utils/TxButton';
  6. import { ContentId } from '@joystream/types/media';
  7. import { onImageError } from '@polkadot/joy-utils/images';
  8. import { MusicTrackValidationSchema, MusicTrackType, MusicTrackClass as Fields, MusicTrackFormValues, MusicTrackToFormValues } from '../schemas/music/MusicTrack';
  9. import { withMediaForm, MediaFormProps, datePlaceholder } from '../common/MediaForms';
  10. import EntityId from '@joystream/types/versioned-store/EntityId';
  11. import { MediaDropdownOptions } from '../common/MediaDropdownOptions';
  12. import { FormTabs } from '../common/FormTabs';
  13. export type OuterProps = {
  14. history?: History,
  15. contentId: ContentId,
  16. fileName?: string,
  17. id?: EntityId,
  18. entity?: MusicTrackType
  19. opts?: MediaDropdownOptions
  20. };
  21. type FormValues = MusicTrackFormValues;
  22. const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
  23. const {
  24. // React components for form fields:
  25. MediaText,
  26. MediaDropdown,
  27. LabelledField,
  28. // Callbacks:
  29. onSubmit,
  30. onTxSuccess,
  31. onTxFailed,
  32. // history,
  33. // contentId,
  34. entity,
  35. opts = MediaDropdownOptions.Empty,
  36. // Formik stuff:
  37. values,
  38. dirty,
  39. errors,
  40. isValid,
  41. isSubmitting,
  42. resetForm
  43. } = props;
  44. const { thumbnail } = values;
  45. const isNew = !entity;
  46. const buildTxParams = () => {
  47. if (!isValid) return [];
  48. return [ /* TODO save entity to versioned store */ ];
  49. };
  50. const basicInfoTab = () => <Tab.Pane as='div'>
  51. <MediaText field={Fields.title} {...props} />
  52. <MediaText field={Fields.artist} {...props} />
  53. <MediaText field={Fields.thumbnail} {...props} />
  54. <MediaText field={Fields.firstReleased} placeholder={datePlaceholder} {...props} />
  55. <MediaText field={Fields.explicit} {...props} />
  56. <MediaDropdown field={Fields.license} options={opts.contentLicenseOptions} {...props} />
  57. <MediaDropdown field={Fields.publicationStatus} options={opts.publicationStatusOptions} {...props} />
  58. </Tab.Pane>
  59. const additionalTab = () => <Tab.Pane as='div'>
  60. <MediaText field={Fields.description} textarea {...props} />
  61. <MediaText field={Fields.composerOrSongwriter} {...props} />
  62. <MediaDropdown field={Fields.genre} options={opts.musicGenreOptions} {...props} />
  63. <MediaDropdown field={Fields.mood} options={opts.musicMoodOptions} {...props} />
  64. <MediaDropdown field={Fields.theme} options={opts.musicThemeOptions} {...props} />
  65. <MediaDropdown field={Fields.language} options={opts.languageOptions} {...props} />
  66. <MediaText field={Fields.lyrics} {...props} />
  67. <MediaText field={Fields.attribution} {...props} />
  68. </Tab.Pane>
  69. const tabs = <FormTabs errors={errors} panes={[
  70. {
  71. id: 'Basic info',
  72. render: basicInfoTab,
  73. fields: [
  74. Fields.title,
  75. Fields.artist,
  76. Fields.thumbnail,
  77. Fields.firstReleased,
  78. Fields.explicit,
  79. Fields.license,
  80. Fields.publicationStatus,
  81. ]
  82. },
  83. {
  84. id: 'Additional',
  85. render: additionalTab,
  86. fields: [
  87. Fields.description,
  88. Fields.composerOrSongwriter,
  89. Fields.genre,
  90. Fields.mood,
  91. Fields.theme,
  92. Fields.language,
  93. Fields.lyrics,
  94. Fields.attribution,
  95. ]
  96. }
  97. ]} />;
  98. const renderMainButton = () =>
  99. <TxButton
  100. type='submit'
  101. size='large'
  102. isDisabled={!dirty || isSubmitting}
  103. label={isNew
  104. ? 'Publish'
  105. : 'Update'
  106. }
  107. params={buildTxParams()}
  108. tx={isNew
  109. ? 'dataDirectory.addMetadata'
  110. : 'dataDirectory.updateMetadata'
  111. }
  112. onClick={onSubmit}
  113. txFailedCb={onTxFailed}
  114. txSuccessCb={onTxSuccess}
  115. />
  116. return <div className='EditMetaBox'>
  117. <div className='EditMetaThumb'>
  118. {thumbnail && <img src={thumbnail} onError={onImageError} />}
  119. </div>
  120. <Form className='ui form JoyForm EditMetaForm'>
  121. {tabs}
  122. <LabelledField style={{ marginTop: '1rem' }} {...props}>
  123. {renderMainButton()}
  124. <Button
  125. type='button'
  126. size='large'
  127. disabled={!dirty || isSubmitting}
  128. onClick={() => resetForm()}
  129. content='Reset form'
  130. />
  131. </LabelledField>
  132. </Form>
  133. </div>;
  134. };
  135. export const EditForm = withFormik<OuterProps, FormValues>({
  136. // Transform outer props into form values
  137. mapPropsToValues: (props): FormValues => {
  138. const { entity, fileName } = props;
  139. const res = MusicTrackToFormValues(entity);
  140. if (!res.title && fileName) {
  141. res.title = fileName;
  142. }
  143. return res;
  144. },
  145. validationSchema: () => MusicTrackValidationSchema,
  146. handleSubmit: () => {
  147. // do submitting things
  148. }
  149. })(withMediaForm(InnerForm) as any);
  150. export default EditForm;