Browse Source

joy-media upgrade

Leszek Wiesner 4 years ago
parent
commit
03bd123c9a
89 changed files with 801 additions and 573 deletions
  1. 3 1
      package.json
  2. 0 1
      pioneer/.eslintignore
  3. 3 0
      pioneer/packages/apps-routing/src/index.ts
  4. 15 0
      pioneer/packages/apps-routing/src/joy-media.ts
  5. 0 0
      pioneer/packages/apps/public/images/default-thumbnail.png
  6. 1 0
      pioneer/packages/apps/public/locales/en/index.json
  7. 4 1
      pioneer/packages/apps/public/locales/en/joy-utils.json
  8. 0 1
      pioneer/packages/apps/src/Content/index.tsx
  9. 3 0
      pioneer/packages/apps/webpack.base.config.js
  10. 0 0
      pioneer/packages/joy-media/.skip-build
  11. 2 0
      pioneer/packages/joy-media/aplayer.d.ts
  12. 2 0
      pioneer/packages/joy-media/dplayer.d.ts
  13. 4 4
      pioneer/packages/joy-media/package.json
  14. 1 1
      pioneer/packages/joy-media/src/DiscoveryProvider.tsx
  15. 8 4
      pioneer/packages/joy-media/src/MediaView.tsx
  16. 25 11
      pioneer/packages/joy-media/src/Upload.tsx
  17. 1 1
      pioneer/packages/joy-media/src/channels/ChannelAvatar.tsx
  18. 4 4
      pioneer/packages/joy-media/src/channels/ChannelPreview.tsx
  19. 4 3
      pioneer/packages/joy-media/src/channels/ChannelsByOwner.view.tsx
  20. 23 17
      pioneer/packages/joy-media/src/channels/CurationPanel.tsx
  21. 23 25
      pioneer/packages/joy-media/src/channels/EditChannel.tsx
  22. 4 3
      pioneer/packages/joy-media/src/channels/EditChannel.view.tsx
  23. 1 1
      pioneer/packages/joy-media/src/channels/ViewChannel.tsx
  24. 4 3
      pioneer/packages/joy-media/src/channels/ViewChannel.view.tsx
  25. 1 1
      pioneer/packages/joy-media/src/channels/ViewMusicChannel.tsx
  26. 1 1
      pioneer/packages/joy-media/src/channels/ViewVideoChannel.tsx
  27. 2 2
      pioneer/packages/joy-media/src/common/MediaForms.tsx
  28. 3 3
      pioneer/packages/joy-media/src/common/MediaPlayerView.tsx
  29. 5 22
      pioneer/packages/joy-media/src/common/MediaPlayerWithResolver.tsx
  30. 4 3
      pioneer/packages/joy-media/src/common/TypeHelpers.ts
  31. 2 0
      pioneer/packages/joy-media/src/common/images.tsx
  32. 0 0
      pioneer/packages/joy-media/src/common/index.scss
  33. 1 1
      pioneer/packages/joy-media/src/explore/AllChannels.tsx
  34. 1 1
      pioneer/packages/joy-media/src/explore/AllVideos.tsx
  35. 1 1
      pioneer/packages/joy-media/src/explore/ExploreContent.tsx
  36. 1 1
      pioneer/packages/joy-media/src/explore/PlayContent.tsx
  37. 5 3
      pioneer/packages/joy-media/src/index.scss
  38. 6 5
      pioneer/packages/joy-media/src/index.tsx
  39. 2 3
      pioneer/packages/joy-media/src/music/EditMusicAlbum.tsx
  40. 1 1
      pioneer/packages/joy-media/src/music/MusicAlbumPreview.tsx
  41. 1 1
      pioneer/packages/joy-media/src/music/MusicAlbumTracks.tsx
  42. 2 2
      pioneer/packages/joy-media/src/music/MyMusicTracks.tsx
  43. 14 14
      pioneer/packages/joy-media/src/schemas/channel/Channel.ts
  44. 1 1
      pioneer/packages/joy-media/src/stories/ExploreContent.stories.tsx
  45. 3 3
      pioneer/packages/joy-media/src/stories/MusicAlbumTracks.stories.tsx
  46. 1 1
      pioneer/packages/joy-media/src/stories/MusicChannel.stories.tsx
  47. 4 5
      pioneer/packages/joy-media/src/stories/MyChannels.stories.tsx
  48. 1 1
      pioneer/packages/joy-media/src/stories/MyMusicAlbums.stories.tsx
  49. 3 3
      pioneer/packages/joy-media/src/stories/Playback.stories.tsx
  50. 3 3
      pioneer/packages/joy-media/src/stories/UploadAudio.stories.tsx
  51. 3 3
      pioneer/packages/joy-media/src/stories/UploadVideo.stories.tsx
  52. 4 4
      pioneer/packages/joy-media/src/stories/data/AccountIdSamples.ts
  53. 7 9
      pioneer/packages/joy-media/src/stories/data/ChannelSamples.ts
  54. 15 14
      pioneer/packages/joy-media/src/transport.mock.ts
  55. 10 13
      pioneer/packages/joy-media/src/transport.substrate.ts
  56. 6 6
      pioneer/packages/joy-media/src/transport.ts
  57. 6 5
      pioneer/packages/joy-media/src/upload/EditVideo.view.tsx
  58. 2 3
      pioneer/packages/joy-media/src/upload/UploadAudio.tsx
  59. 26 24
      pioneer/packages/joy-media/src/upload/UploadVideo.tsx
  60. 4 2
      pioneer/packages/joy-media/src/video/PlayVideo.tsx
  61. 6 6
      pioneer/packages/joy-media/src/video/PlayVideo.view.tsx
  62. 2 2
      pioneer/packages/joy-media/src/video/VideoPreview.tsx
  63. 4 4
      pioneer/packages/joy-utils/src/react/components/InputFileAsync.tsx
  64. 1 1
      pioneer/packages/joy-utils/src/react/components/JoyStatus.tsx
  65. 0 0
      pioneer/packages/joy-utils/src/react/components/Pluralize.tsx
  66. 4 1
      pioneer/packages/joy-utils/src/react/components/index.tsx
  67. 111 6
      pioneer/packages/joy-utils/src/react/hocs/accounts.tsx
  68. 1 30
      pioneer/packages/joy-utils/src/react/hocs/guards.tsx
  69. 1 1
      pioneer/packages/joy-utils/src/react/hooks/proposals/useProposalSubscription.tsx
  70. 4 1
      pioneer/packages/joy-utils/src/transport/SimpleCache.ts
  71. 16 14
      pioneer/packages/joy-utils/src/transport/base.ts
  72. 14 12
      pioneer/packages/joy-utils/src/transport/mock/base.ts
  73. 4 0
      pioneer/packages/joy-utils/src/transport/workingGroups.ts
  74. 0 0
      pioneer/packages/joy-utils/src/types/ValidationConstraint.ts
  75. 0 17
      pioneer/packages/old-apps/apps-routing/src/joy-media.ts
  76. 0 1
      pioneer/packages/old-apps/apps/src/aplayer.d.ts
  77. 0 1
      pioneer/packages/old-apps/apps/src/dplayer.d.ts
  78. 5 0
      pioneer/packages/react-components/src/styles/joystream.ts
  79. 4 1
      pioneer/tsconfig.json
  80. 26 26
      types/augment-codec/augment-types.ts
  81. 20 20
      types/augment/all/defs.json
  82. 20 20
      types/augment/all/types.ts
  83. 0 50
      types/augment/augment-api-consts.ts
  84. 4 29
      types/augment/augment-api-query.ts
  85. 2 47
      types/augment/augment-api-tx.ts
  86. 6 6
      types/src/content-working-group/index.ts
  87. 1 1
      types/src/index.ts
  88. 2 2
      types/src/versioned-store/index.ts
  89. 256 28
      yarn.lock

+ 3 - 1
package.json

@@ -29,6 +29,7 @@
     "pioneer/packages/joy-election",
     "pioneer/packages/joy-election",
     "pioneer/packages/joy-proposals",
     "pioneer/packages/joy-proposals",
     "pioneer/packages/joy-roles",
     "pioneer/packages/joy-roles",
+    "pioneer/packages/joy-media",
     "utils/api-examples"
     "utils/api-examples"
   ],
   ],
   "resolutions": {
   "resolutions": {
@@ -40,7 +41,8 @@
     "@polkadot/util-crypto": "3.0.1",
     "@polkadot/util-crypto": "3.0.1",
     "@polkadot/wasm-crypto": "1.2.1",
     "@polkadot/wasm-crypto": "1.2.1",
     "babel-core": "^7.0.0-bridge.0",
     "babel-core": "^7.0.0-bridge.0",
-    "typescript": "^3.9.7"
+    "typescript": "^3.9.7",
+    "bn.js": "^5.1.2"
   },
   },
   "devDependencies": {
   "devDependencies": {
     "husky": "^4.2.5",
     "husky": "^4.2.5",

+ 0 - 1
pioneer/.eslintignore

@@ -4,7 +4,6 @@
 packages/old-apps/*
 packages/old-apps/*
 packages/joy-forum/*
 packages/joy-forum/*
 packages/joy-help/*
 packages/joy-help/*
-packages/joy-media/*
 packages/joy-settings/*
 packages/joy-settings/*
 packages/joy-utils-old/*
 packages/joy-utils-old/*
 .eslintrc.js
 .eslintrc.js

+ 3 - 0
pioneer/packages/apps-routing/src/index.ts

@@ -23,10 +23,12 @@ import { terms, privacyPolicy } from './joy-pages';
 import election from './joy-election';
 import election from './joy-election';
 import proposals from './joy-proposals';
 import proposals from './joy-proposals';
 import roles from './joy-roles';
 import roles from './joy-roles';
+import media from './joy-media';
 
 
 export default function create (t: <T = string> (key: string, text: string, options: { ns: string }) => T): Routes {
 export default function create (t: <T = string> (key: string, text: string, options: { ns: string }) => T): Routes {
   return appSettings.uiMode === 'light'
   return appSettings.uiMode === 'light'
     ? [
     ? [
+      media(t),
       members(t),
       members(t),
       roles(t),
       roles(t),
       election(t),
       election(t),
@@ -37,6 +39,7 @@ export default function create (t: <T = string> (key: string, text: string, opti
       settings(t)
       settings(t)
     ]
     ]
     : [
     : [
+      media(t),
       members(t),
       members(t),
       roles(t),
       roles(t),
       election(t),
       election(t),

+ 15 - 0
pioneer/packages/apps-routing/src/joy-media.ts

@@ -0,0 +1,15 @@
+import Media from '@polkadot/joy-media/index';
+
+import { Route } from './types';
+
+export default function create (t: <T = string> (key: string, text: string, options: { ns: string }) => T): Route {
+  return {
+    Component: Media,
+    display: {
+      needsApi: ['query.storageWorkingGroup.workerById', 'query.dataObjectStorageRegistry.relationshipsByContentId']
+    },
+    text: t<string>('nav.media', 'Media', { ns: 'apps-routing' }),
+    icon: 'play-circle',
+    name: 'media'
+  };
+}

+ 0 - 0
pioneer/packages/old-apps/apps/public/images/default-thumbnail.png → pioneer/packages/apps/public/images/default-thumbnail.png


+ 1 - 0
pioneer/packages/apps/public/locales/en/index.json

@@ -25,6 +25,7 @@
   "joy-media.json",
   "joy-media.json",
   "joy-members.json",
   "joy-members.json",
   "joy-roles.json",
   "joy-roles.json",
+  "joy-utils.json",
   "react-components.json",
   "react-components.json",
   "react-params.json",
   "react-params.json",
   "react-query.json",
   "react-query.json",

+ 4 - 1
pioneer/packages/apps/public/locales/en/joy-utils.json

@@ -1 +1,4 @@
-{}
+{
+  "click to select or drag and drop the file here": "click to select or drag and drop the file here",
+  "{{name}} ({{size}} bytes)": "{{name}} ({{size}} bytes)"
+}

+ 0 - 1
pioneer/packages/apps/src/Content/index.tsx

@@ -97,7 +97,6 @@ function Content ({ className }: Props): React.ReactElement<Props> {
 }
 }
 
 
 export default React.memo(styled(Content)`
 export default React.memo(styled(Content)`
-  background: rgba(250, 250, 250);
   padding: 0 1.5rem;
   padding: 0 1.5rem;
   position: relative;
   position: relative;
   width: 100%;
   width: 100%;

+ 3 - 0
pioneer/packages/apps/webpack.base.config.js

@@ -48,6 +48,9 @@ function createWebpack (ENV, context) {
     return alias;
     return alias;
   }, {});
   }, {});
 
 
+  // Add @joystream/types as alias to automatically process any changes:
+  alias['@joystream/types'] = path.resolve(context, `../../../types/src`);
+
   return {
   return {
     context,
     context,
     entry: ['@babel/polyfill', './src/index.tsx'],
     entry: ['@babel/polyfill', './src/index.tsx'],

+ 0 - 0
pioneer/packages/joy-media/.skip-build


+ 2 - 0
pioneer/packages/joy-media/aplayer.d.ts

@@ -0,0 +1,2 @@
+// No offical definitions available
+declare module 'react-aplayer';

+ 2 - 0
pioneer/packages/joy-media/dplayer.d.ts

@@ -0,0 +1,2 @@
+// No offical definitions available
+declare module 'react-dplayer';

+ 4 - 4
pioneer/packages/joy-media/package.json

@@ -7,14 +7,14 @@
   "author": "Joystream contributors",
   "author": "Joystream contributors",
   "maintainers": [],
   "maintainers": [],
   "dependencies": {
   "dependencies": {
-    "@babel/runtime": "^7.7.1",
+    "@babel/runtime": "^7.10.5",
     "@polkadot/joy-utils": "^0.1.1",
     "@polkadot/joy-utils": "^0.1.1",
-    "@polkadot/react-components": "0.37.0-beta.63",
-    "@polkadot/react-query": "0.37.0-beta.63",
+    "@polkadot/react-components": "0.51.1",
+    "@polkadot/react-query": "0.51.1",
     "@types/mime-types": "^2.1.0",
     "@types/mime-types": "^2.1.0",
     "@types/react-beautiful-dnd": "^11.0.3",
     "@types/react-beautiful-dnd": "^11.0.3",
     "aplayer": "^1.10.1",
     "aplayer": "^1.10.1",
-    "dplayer": "^1.25.0",
+    "dplayer": "1.25.0",
     "ipfs-only-hash": "^1.0.2",
     "ipfs-only-hash": "^1.0.2",
     "iso-639-1": "^2.1.0",
     "iso-639-1": "^2.1.0",
     "lodash": "^4.17.11",
     "lodash": "^4.17.11",

+ 1 - 1
pioneer/packages/joy-media/src/DiscoveryProvider.tsx

@@ -7,7 +7,7 @@ import { Vec } from '@polkadot/types';
 import { Url } from '@joystream/types/discovery';
 import { Url } from '@joystream/types/discovery';
 import ApiContext from '@polkadot/react-api/ApiContext';
 import ApiContext from '@polkadot/react-api/ApiContext';
 import { ApiProps } from '@polkadot/react-api/types';
 import { ApiProps } from '@polkadot/react-api/types';
-import { JoyInfo } from '@polkadot/joy-utils/JoyStatus';
+import { JoyInfo } from '@polkadot/joy-utils/react/components';
 import { componentName } from '@polkadot/joy-utils/react/helpers';
 import { componentName } from '@polkadot/joy-utils/react/helpers';
 
 
 export type BootstrapNodes = {
 export type BootstrapNodes = {

+ 8 - 4
pioneer/packages/joy-media/src/MediaView.tsx

@@ -1,9 +1,11 @@
 import React, { useState, useEffect } from 'react';
 import React, { useState, useEffect } from 'react';
 import { MediaTransport } from './transport';
 import { MediaTransport } from './transport';
 import { MemberId } from '@joystream/types/members';
 import { MemberId } from '@joystream/types/members';
-import { useMyMembership } from '@polkadot/joy-utils/MyMembershipContext';
+import { useMyMembership } from '@polkadot/joy-utils/react/hooks';
 import { useTransportContext } from './TransportContext';
 import { useTransportContext } from './TransportContext';
-import { withMembershipRequired } from '@polkadot/joy-utils/MyAccount';
+import { withMembershipRequired } from '@polkadot/joy-utils/react/hocs/guards';
+import { useApi } from '@polkadot/react-hooks';
+import { ApiPromise } from '@polkadot/api';
 
 
 type InitialPropsWithMembership<A> = A & {
 type InitialPropsWithMembership<A> = A & {
   myAddress?: string;
   myAddress?: string;
@@ -12,6 +14,7 @@ type InitialPropsWithMembership<A> = A & {
 
 
 type ResolverProps<A> = InitialPropsWithMembership<A> & {
 type ResolverProps<A> = InitialPropsWithMembership<A> & {
   transport: MediaTransport;
   transport: MediaTransport;
+  api: ApiPromise;
 }
 }
 
 
 type BaseProps<A, B> = {
 type BaseProps<A, B> = {
@@ -39,13 +42,14 @@ function serializeTrigger (val: any): any {
   }
   }
 }
 }
 
 
-export function MediaView<A = {}, B = {}> (baseProps: BaseProps<A, B>) {
+export function MediaView<A extends Record<string, unknown> = Record<string, unknown>, B extends Record<string, unknown> = Record<string, unknown>> (baseProps: BaseProps<A, B>) {
   function InnerView (initialProps: A & B) {
   function InnerView (initialProps: A & B) {
     const { component: Component, resolveProps, triggers = [], unresolvedView = null } = baseProps;
     const { component: Component, resolveProps, triggers = [], unresolvedView = null } = baseProps;
 
 
     const transport = useTransportContext();
     const transport = useTransportContext();
     const { myAddress, myMemberId } = useMyMembership();
     const { myAddress, myMemberId } = useMyMembership();
-    const resolverProps = { ...initialProps, transport, myAddress, myMemberId };
+    const { api } = useApi();
+    const resolverProps = { ...initialProps, transport, api, myAddress, myMemberId };
 
 
     const [resolvedProps, setResolvedProps] = useState({} as B);
     const [resolvedProps, setResolvedProps] = useState({} as B);
     const [propsResolved, setPropsResolved] = useState(false);
     const [propsResolved, setPropsResolved] = useState(false);

+ 25 - 11
pioneer/packages/joy-media/src/Upload.tsx

@@ -4,7 +4,8 @@ import axios, { CancelTokenSource } from 'axios';
 import { History } from 'history';
 import { History } from 'history';
 import { Progress, Message } from 'semantic-ui-react';
 import { Progress, Message } from 'semantic-ui-react';
 
 
-import { InputFileAsync } from '@polkadot/react-components/index';
+import { mockRegistry } from '@joystream/types';
+import { InputFileAsync } from '@polkadot/joy-utils/react/components';
 import { ApiProps } from '@polkadot/react-api/types';
 import { ApiProps } from '@polkadot/react-api/types';
 import { I18nProps } from '@polkadot/react-components/types';
 import { I18nProps } from '@polkadot/react-components/types';
 import { SubmittableResult } from '@polkadot/api';
 import { SubmittableResult } from '@polkadot/api';
@@ -15,15 +16,17 @@ import { formatNumber } from '@polkadot/util';
 import translate from './translate';
 import translate from './translate';
 import { fileNameWoExt } from './utils';
 import { fileNameWoExt } from './utils';
 import { ContentId, DataObject } from '@joystream/types/media';
 import { ContentId, DataObject } from '@joystream/types/media';
-import { withOnlyMembers, MyAccountProps } from '@polkadot/joy-utils/MyAccount';
+import { MyAccountProps } from '@polkadot/joy-utils/react/hocs/accounts';
+import { withOnlyMembers } from '@polkadot/joy-utils/react/hocs/guards';
 import { DiscoveryProviderProps, withDiscoveryProvider } from './DiscoveryProvider';
 import { DiscoveryProviderProps, withDiscoveryProvider } from './DiscoveryProvider';
-import TxButton from '@polkadot/joy-utils/TxButton';
+import { TxButton } from '@polkadot/joy-utils/react/components';
 import IpfsHash from 'ipfs-only-hash';
 import IpfsHash from 'ipfs-only-hash';
 import { ChannelId } from '@joystream/types/content-working-group';
 import { ChannelId } from '@joystream/types/content-working-group';
 import { EditVideoView } from './upload/EditVideo.view';
 import { EditVideoView } from './upload/EditVideo.view';
-import { JoyInfo } from '@polkadot/joy-utils/JoyStatus';
+import { JoyInfo } from '@polkadot/joy-utils/react/components';
 import { IterableFile } from './IterableFile';
 import { IterableFile } from './IterableFile';
 import { StorageProviderId } from '@joystream/types/working-group';
 import { StorageProviderId } from '@joystream/types/working-group';
+import { Loading } from '@polkadot/joy-utils/react/components';
 
 
 const MAX_FILE_SIZE_MB = 500;
 const MAX_FILE_SIZE_MB = 500;
 const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
 const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
@@ -46,6 +49,7 @@ type State = {
   newContentId: ContentId;
   newContentId: ContentId;
   discovering: boolean;
   discovering: boolean;
   uploading: boolean;
   uploading: boolean;
+  sendingTx: boolean;
   progress: number;
   progress: number;
   cancelSource: CancelTokenSource;
   cancelSource: CancelTokenSource;
 };
 };
@@ -55,9 +59,10 @@ const defaultState = (): State => ({
   file: undefined,
   file: undefined,
   computingHash: false,
   computingHash: false,
   ipfs_cid: undefined,
   ipfs_cid: undefined,
-  newContentId: ContentId.generate(),
+  newContentId: ContentId.generate(mockRegistry),
   discovering: false,
   discovering: false,
   uploading: false,
   uploading: false,
+  sendingTx: false,
   progress: 0,
   progress: 0,
   cancelSource: axios.CancelToken.source()
   cancelSource: axios.CancelToken.source()
 });
 });
@@ -84,12 +89,13 @@ class Upload extends React.PureComponent<Props, State> {
   }
   }
 
 
   private renderContent () {
   private renderContent () {
-    const { error, uploading, discovering, computingHash } = this.state;
+    const { error, uploading, discovering, computingHash, sendingTx } = this.state;
 
 
     if (error) return this.renderError();
     if (error) return this.renderError();
     else if (discovering) return this.renderDiscovering();
     else if (discovering) return this.renderDiscovering();
     else if (uploading) return this.renderUploading();
     else if (uploading) return this.renderUploading();
     else if (computingHash) return this.renderComputingHash();
     else if (computingHash) return this.renderComputingHash();
+    else if (sendingTx) return this.renderSendingTx();
     else return this.renderFileInput();
     else return this.renderFileInput();
   }
   }
 
 
@@ -117,13 +123,13 @@ class Upload extends React.PureComponent<Props, State> {
     if (!file || !file.name) return <JoyInfo title='Loading...' />;
     if (!file || !file.name) return <JoyInfo title='Loading...' />;
 
 
     const success = !error && progress >= 100;
     const success = !error && progress >= 100;
-    const { history, match: { params: { channelId } } } = this.props;
+    const { history, match: { params: { channelId } }, api } = this.props;
 
 
     return <div style={{ width: '100%' }}>
     return <div style={{ width: '100%' }}>
       {this.renderProgress()}
       {this.renderProgress()}
       {success &&
       {success &&
         <EditVideoView
         <EditVideoView
-          channelId={new ChannelId(channelId)}
+          channelId={api.createType('ChannelId', channelId)}
           contentId={newContentId}
           contentId={newContentId}
           fileName={fileNameWoExt(file.name)}
           fileName={fileNameWoExt(file.name)}
           history={history}
           history={history}
@@ -132,6 +138,10 @@ class Upload extends React.PureComponent<Props, State> {
     </div>;
     </div>;
   }
   }
 
 
+  private renderSendingTx () {
+    return <JoyInfo title="Please wait..."><Loading text="Waiting for the transaction confirmation..." /></JoyInfo>
+  }
+
   private renderDiscovering () {
   private renderDiscovering () {
     return <JoyInfo title={'Please wait...'}>Contacting storage provider.</JoyInfo>;
     return <JoyInfo title={'Please wait...'}>Contacting storage provider.</JoyInfo>;
   }
   }
@@ -184,12 +194,16 @@ class Upload extends React.PureComponent<Props, State> {
       />
       />
       {file_name && <div className='UploadButtonBox'>
       {file_name && <div className='UploadButtonBox'>
         <TxButton
         <TxButton
-          size='large'
           label={'Upload'}
           label={'Upload'}
           isDisabled={!file_name}
           isDisabled={!file_name}
           tx={'dataDirectory.addContent'}
           tx={'dataDirectory.addContent'}
           params={this.buildTxParams()}
           params={this.buildTxParams()}
-          txSuccessCb={this.onDataObjectCreated}
+          onClick={(sendTx) => {
+            this.setState({ sendingTx: true });
+            sendTx();
+          }}
+          txSuccessCb={ this.onDataObjectCreated }
+          txFailedCb={() => { this.setState({ sendingTx: false }) }}
         />
         />
       </div>}
       </div>}
     </div>;
     </div>;
@@ -253,7 +267,7 @@ class Upload extends React.PureComponent<Props, State> {
   }
   }
 
 
   private onDataObjectCreated = async (_txResult: SubmittableResult) => {
   private onDataObjectCreated = async (_txResult: SubmittableResult) => {
-    this.setState({ discovering: true });
+    this.setState({ sendingTx: false, discovering: true });
 
 
     const { api } = this.props;
     const { api } = this.props;
     const { newContentId } = this.state;
     const { newContentId } = this.state;

+ 1 - 1
pioneer/packages/joy-media/src/channels/ChannelAvatar.tsx

@@ -2,7 +2,7 @@ import React from 'react';
 import { Link } from 'react-router-dom';
 import { Link } from 'react-router-dom';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { BgImg } from '../common/BgImg';
 import { BgImg } from '../common/BgImg';
-import { DEFAULT_THUMBNAIL_URL } from '@polkadot/joy-utils/images';
+import { DEFAULT_THUMBNAIL_URL } from '../common/images';
 
 
 const defaultSizePx = 75;
 const defaultSizePx = 75;
 
 

+ 4 - 4
pioneer/packages/joy-media/src/channels/ChannelPreview.tsx

@@ -6,8 +6,8 @@ import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelAvatar, ChannelAvatarSize } from './ChannelAvatar';
 import { ChannelAvatar, ChannelAvatarSize } from './ChannelAvatar';
 import { isPublicChannel, isMusicChannel, isVideoChannel, isAccountAChannelOwner, isVerifiedChannel } from './ChannelHelpers';
 import { isPublicChannel, isMusicChannel, isVideoChannel, isAccountAChannelOwner, isVerifiedChannel } from './ChannelHelpers';
 
 
-import { useMyMembership } from '@polkadot/joy-utils/MyMembershipContext';
-import { nonEmptyStr } from '@polkadot/joy-utils/index';
+import { useMyMembership } from '@polkadot/joy-utils/react/hooks';
+import { nonEmptyStr } from '@polkadot/joy-utils/functions/misc';
 import { CurationPanel } from './CurationPanel';
 import { CurationPanel } from './CurationPanel';
 import { ChannelNameAsLink } from './ChannelNameAsLink';
 import { ChannelNameAsLink } from './ChannelNameAsLink';
 
 
@@ -52,8 +52,6 @@ export const ChannelPreview = (props: ChannelPreviewProps) => {
         <h3 className='ChannelTitle' style={{ display: 'block' }}>
         <h3 className='ChannelTitle' style={{ display: 'block' }}>
           <ChannelNameAsLink channel={channel} style={{ marginRight: '1rem' }} />
           <ChannelNameAsLink channel={channel} style={{ marginRight: '1rem' }} />
 
 
-          <CurationPanel channel={channel} />
-
           {isAccountAChannelOwner(channel, myAccountId) &&
           {isAccountAChannelOwner(channel, myAccountId) &&
             <div style={{ float: 'right' }}>
             <div style={{ float: 'right' }}>
 
 
@@ -101,6 +99,8 @@ export const ChannelPreview = (props: ChannelPreviewProps) => {
           }
           }
         </div>
         </div>
 
 
+        <CurationPanel channel={channel} />
+
         {withDescription && nonEmptyStr(channel.description) &&
         {withDescription && nonEmptyStr(channel.description) &&
           <ReactMarkdown className='JoyMemo--full ChannelDesc' source={channel.description} linkTarget='_blank' />
           <ReactMarkdown className='JoyMemo--full ChannelDesc' source={channel.description} linkTarget='_blank' />
         }
         }

+ 4 - 3
pioneer/packages/joy-media/src/channels/ChannelsByOwner.view.tsx

@@ -1,10 +1,10 @@
 import React from 'react';
 import React from 'react';
 import { RouteComponentProps } from 'react-router';
 import { RouteComponentProps } from 'react-router';
 
 
-import { GenericAccountId } from '@polkadot/types';
 import { MediaView } from '../MediaView';
 import { MediaView } from '../MediaView';
 import { ChannelsByOwnerProps, ChannelsByOwner } from './ChannelsByOwner';
 import { ChannelsByOwnerProps, ChannelsByOwner } from './ChannelsByOwner';
-import { JoyError } from '@polkadot/joy-utils/JoyStatus';
+import { JoyError } from '@polkadot/joy-utils/react/components';
+import { useApi } from '@polkadot/react-hooks';
 
 
 type Props = ChannelsByOwnerProps;
 type Props = ChannelsByOwnerProps;
 
 
@@ -19,10 +19,11 @@ export const ChannelsByOwnerView = MediaView<Props>({
 
 
 export const ChannelsByOwnerWithRouter = (props: Props & RouteComponentProps<any>) => {
 export const ChannelsByOwnerWithRouter = (props: Props & RouteComponentProps<any>) => {
   const { match: { params: { account } } } = props;
   const { match: { params: { account } } } = props;
+  const { api } = useApi();
 
 
   if (account) {
   if (account) {
     try {
     try {
-      return <ChannelsByOwnerView {...props} accountId={new GenericAccountId(account)} />;
+      return <ChannelsByOwnerView {...props} accountId={api.createType('AccountId', account)} />;
     } catch (err) {
     } catch (err) {
       console.log('ChannelsByOwnerWithRouter failed:', err);
       console.log('ChannelsByOwnerWithRouter failed:', err);
     }
     }

+ 23 - 17
pioneer/packages/joy-media/src/channels/CurationPanel.tsx

@@ -1,16 +1,18 @@
 import React from 'react';
 import React from 'react';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { isVerifiedChannel, isCensoredChannel } from './ChannelHelpers';
 import { isVerifiedChannel, isCensoredChannel } from './ChannelHelpers';
-import { useMyMembership } from '@polkadot/joy-utils/MyMembershipContext';
-import TxButton from '@polkadot/joy-utils/TxButton';
-import { ChannelCurationStatus } from '@joystream/types/content-working-group';
+import { useMyMembership } from '@polkadot/joy-utils/react/hooks';
+import { SemanticTxButton } from '@polkadot/joy-utils/react/components/TxButton';
 import { AccountId } from '@polkadot/types/interfaces';
 import { AccountId } from '@polkadot/types/interfaces';
+import { useApi } from '@polkadot/react-hooks';
+import { Icon } from 'semantic-ui-react';
 
 
 type ChannelCurationPanelProps = {
 type ChannelCurationPanelProps = {
   channel: ChannelEntity;
   channel: ChannelEntity;
 };
 };
 
 
 export const CurationPanel = (props: ChannelCurationPanelProps) => {
 export const CurationPanel = (props: ChannelCurationPanelProps) => {
+  const { api } = useApi();
   const { curationActor, allAccounts } = useMyMembership();
   const { curationActor, allAccounts } = useMyMembership();
   const { channel } = props;
   const { channel } = props;
 
 
@@ -34,17 +36,16 @@ export const CurationPanel = (props: ChannelCurationPanelProps) => {
 
 
     const isCensored = isCensoredChannel(channel);
     const isCensored = isCensoredChannel(channel);
 
 
-    const new_curation_status = new ChannelCurationStatus(
+    const new_curation_status = api.createType('ChannelCurationStatus',
       isCensored ? 'Normal' : 'Censored'
       isCensored ? 'Normal' : 'Censored'
     );
     );
 
 
-    return <TxButton
+    return <SemanticTxButton
       accountId={role_account.toString()}
       accountId={role_account.toString()}
       type='submit'
       type='submit'
-      size='medium'
-      icon={isCensored ? 'x' : 'warning'}
-      isDisabled={!accountAvailable}
-      label={isCensored ? 'Un-Censor' : 'Censor'}
+      size='small'
+      color={isCensored ? undefined : 'red'}
+      disabled={!accountAvailable}
       params={[
       params={[
         curation_actor,
         curation_actor,
         channel.id,
         channel.id,
@@ -52,7 +53,10 @@ export const CurationPanel = (props: ChannelCurationPanelProps) => {
         new_curation_status // toggled curation status
         new_curation_status // toggled curation status
       ]}
       ]}
       tx={'contentWorkingGroup.updateChannelAsCurationActor'}
       tx={'contentWorkingGroup.updateChannelAsCurationActor'}
-    />;
+    >
+      <Icon name={isCensored ? 'x' : 'warning'}/>
+      { isCensored ? 'Un-Censor' : 'Censor' }
+    </SemanticTxButton>;
   };
   };
 
 
   const renderToggleVerifiedButton = () => {
   const renderToggleVerifiedButton = () => {
@@ -62,13 +66,12 @@ export const CurationPanel = (props: ChannelCurationPanelProps) => {
     const accountAvailable = canUseAccount(role_account);
     const accountAvailable = canUseAccount(role_account);
     const isVerified = isVerifiedChannel(channel);
     const isVerified = isVerifiedChannel(channel);
 
 
-    return <TxButton
+    return <SemanticTxButton
       accountId={role_account.toString()}
       accountId={role_account.toString()}
       type='submit'
       type='submit'
-      size='medium'
-      icon={isVerified ? 'x' : 'checkmark'}
-      isDisabled={!accountAvailable}
-      label={isVerified ? 'Remove Verification' : 'Verify'}
+      size='small'
+      color={isVerified ? undefined : 'green'}
+      disabled={!accountAvailable}
       params={[
       params={[
         curation_actor,
         curation_actor,
         channel.id,
         channel.id,
@@ -76,11 +79,14 @@ export const CurationPanel = (props: ChannelCurationPanelProps) => {
         null // not changing curation status
         null // not changing curation status
       ]}
       ]}
       tx={'contentWorkingGroup.updateChannelAsCurationActor'}
       tx={'contentWorkingGroup.updateChannelAsCurationActor'}
-    />;
+    >
+      <Icon name={isVerified ? 'x' : 'checkmark'}/>
+      { isVerified ? 'Remove Verification' : 'Verify' }
+    </SemanticTxButton>;
   };
   };
 
 
   return <>
   return <>
-    <div style={{ float: 'right' }}>
+    <div style={{ display: 'flex', float: 'right', margin: '0.5em', marginRight: 0 }}>
       {renderToggleCensorshipButton()}
       {renderToggleCensorshipButton()}
       {renderToggleVerifiedButton()}
       {renderToggleVerifiedButton()}
     </div>
     </div>

+ 23 - 25
pioneer/packages/joy-media/src/channels/EditChannel.tsx

@@ -3,21 +3,22 @@ import { Button } from 'semantic-ui-react';
 import { Form, withFormik } from 'formik';
 import { Form, withFormik } from 'formik';
 import { History } from 'history';
 import { History } from 'history';
 
 
-import { Text, Option } from '@polkadot/types';
-import TxButton from '@polkadot/joy-utils/TxButton';
-import { onImageError } from '@polkadot/joy-utils/images';
+import { Option } from '@polkadot/types';
+import { TxButton } from '@polkadot/joy-utils/react/components';
+import { onImageError } from '../common/images';
 import { withMediaForm, MediaFormProps } from '../common/MediaForms';
 import { withMediaForm, MediaFormProps } from '../common/MediaForms';
 import { ChannelType, ChannelClass as Fields, buildChannelValidationSchema, ChannelFormValues, ChannelToFormValues, ChannelGenericProp } from '../schemas/channel/Channel';
 import { ChannelType, ChannelClass as Fields, buildChannelValidationSchema, ChannelFormValues, ChannelToFormValues, ChannelGenericProp } from '../schemas/channel/Channel';
 import { MediaDropdownOptions } from '../common/MediaDropdownOptions';
 import { MediaDropdownOptions } from '../common/MediaDropdownOptions';
-import { ChannelId, ChannelContentType, ChannelPublicationStatus, OptionalText } from '@joystream/types/content-working-group';
-import { newOptionalText, findFirstParamOfSubstrateEvent } from '@polkadot/joy-utils/index';
-import { useMyMembership } from '@polkadot/joy-utils/MyMembershipContext';
+import { ChannelId, OptionalText } from '@joystream/types/content-working-group';
+import { findFirstParamOfSubstrateEvent } from '@polkadot/joy-utils/functions/misc';
+import { useMyMembership } from '@polkadot/joy-utils/react/hooks';
 import { ChannelPublicationStatusDropdownOptions, isAccountAChannelOwner } from './ChannelHelpers';
 import { ChannelPublicationStatusDropdownOptions, isAccountAChannelOwner } from './ChannelHelpers';
 import { TxCallback } from '@polkadot/react-components/Status/types';
 import { TxCallback } from '@polkadot/react-components/Status/types';
 import { SubmittableResult } from '@polkadot/api';
 import { SubmittableResult } from '@polkadot/api';
 import { ChannelValidationConstraints } from '../transport';
 import { ChannelValidationConstraints } from '../transport';
-import { JoyError } from '@polkadot/joy-utils/JoyStatus';
-import Section from '@polkadot/joy-utils/Section';
+import { JoyError } from '@polkadot/joy-utils/react/components';
+import { Section } from '@polkadot/joy-utils/react/components';
+import { useApi } from '@polkadot/react-hooks';
 
 
 export type OuterProps = {
 export type OuterProps = {
   history?: History;
   history?: History;
@@ -56,6 +57,7 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
   } = props;
   } = props;
 
 
   const { myAccountId, myMemberId } = useMyMembership();
   const { myAccountId, myMemberId } = useMyMembership();
+  const { api } = useApi();
 
 
   if (entity && !isAccountAChannelOwner(entity, myAccountId)) {
   if (entity && !isAccountAChannelOwner(entity, myAccountId)) {
     return <JoyError title={'Only owner can edit channel'} />;
     return <JoyError title={'Only owner can edit channel'} />;
@@ -83,52 +85,49 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
   const buildTxParams = () => {
   const buildTxParams = () => {
     if (!isValid) return [];
     if (!isValid) return [];
 
 
-    // TODO get value from the form:
-    const publicationStatus = new ChannelPublicationStatus('Public');
-
     if (!entity) {
     if (!entity) {
       // Create a new channel
       // Create a new channel
 
 
       const channelOwner = myMemberId;
       const channelOwner = myMemberId;
       const roleAccount = myAccountId;
       const roleAccount = myAccountId;
-      const contentType = new ChannelContentType(values.content);
+      const contentType = api.createType('ChannelContentType', values.content);
 
 
       return [
       return [
         channelOwner,
         channelOwner,
         roleAccount,
         roleAccount,
         contentType,
         contentType,
-        new Text(values.handle),
-        newOptionalText(values.title),
-        newOptionalText(values.description),
-        newOptionalText(values.avatar),
-        newOptionalText(values.banner),
-        publicationStatus
+        values.handle,
+        values.title || null,
+        values.description || null,
+        values.avatar || null,
+        values.banner || null,
+        values.publicationStatus
       ];
       ];
     } else {
     } else {
       // Update an existing channel
       // Update an existing channel
 
 
       const updOptText = (field: ChannelGenericProp): Option<OptionalText> => {
       const updOptText = (field: ChannelGenericProp): Option<OptionalText> => {
-        return new Option(OptionalText,
+        return api.createType('Option<OptionalText>',
           isFieldChanged(field)
           isFieldChanged(field)
-            ? newOptionalText(values[field.id])
+            ? api.createType('Option<Text>', values[field.id])
             : null
             : null
         );
         );
       };
       };
 
 
-      const updHandle = new Option(Text,
+      const updHandle = api.createType('Option<Text>',
         isFieldChanged(Fields.handle)
         isFieldChanged(Fields.handle)
           ? values[Fields.handle.id]
           ? values[Fields.handle.id]
           : null
           : null
       );
       );
 
 
-      const updPublicationStatus = new Option(ChannelPublicationStatus,
+      const updPublicationStatus = api.createType('Option<ChannelPublicationStatus>',
         isFieldChanged(Fields.publicationStatus)
         isFieldChanged(Fields.publicationStatus)
-          ? new ChannelPublicationStatus(values[Fields.publicationStatus.id] as any)
+          ? api.createType('ChannelPublicationStatus', values[Fields.publicationStatus.id])
           : null
           : null
       );
       );
 
 
       return [
       return [
-        new ChannelId(entity.id),
+        entity.id,
         updHandle,
         updHandle,
         updOptText(Fields.title),
         updOptText(Fields.title),
         updOptText(Fields.description),
         updOptText(Fields.description),
@@ -156,7 +155,6 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
   const renderMainButton = () =>
   const renderMainButton = () =>
     <TxButton
     <TxButton
       type='submit'
       type='submit'
-      size='large'
       isDisabled={!dirty || isSubmitting}
       isDisabled={!dirty || isSubmitting}
       label={isNew
       label={isNew
         ? 'Create channel'
         ? 'Create channel'

+ 4 - 3
pioneer/packages/joy-media/src/channels/EditChannel.view.tsx

@@ -2,8 +2,8 @@ import React from 'react';
 import { RouteComponentProps } from 'react-router';
 import { RouteComponentProps } from 'react-router';
 import { MediaView } from '../MediaView';
 import { MediaView } from '../MediaView';
 import { OuterProps, EditForm } from './EditChannel';
 import { OuterProps, EditForm } from './EditChannel';
-import { ChannelId } from '@joystream/types/content-working-group';
-import { JoyError } from '@polkadot/joy-utils/JoyStatus';
+import { JoyError } from '@polkadot/joy-utils/react/components';
+import { useApi } from '@polkadot/react-hooks';
 
 
 type Props = OuterProps;
 type Props = OuterProps;
 
 
@@ -23,10 +23,11 @@ type WithRouterProps = Props & RouteComponentProps<any>
 
 
 export const EditChannelWithRouter = (props: WithRouterProps) => {
 export const EditChannelWithRouter = (props: WithRouterProps) => {
   const { match: { params: { id } } } = props;
   const { match: { params: { id } } } = props;
+  const { api } = useApi();
 
 
   if (id) {
   if (id) {
     try {
     try {
-      return <EditChannelView {...props} id={new ChannelId(id)} />;
+      return <EditChannelView {...props} id={api.createType('ChannelId', id)} />;
     } catch (err) {
     } catch (err) {
       console.log('EditChannelWithRouter failed:', err);
       console.log('EditChannelWithRouter failed:', err);
     }
     }

+ 1 - 1
pioneer/packages/joy-media/src/channels/ViewChannel.tsx

@@ -8,7 +8,7 @@ import { ViewVideoChannel } from './ViewVideoChannel';
 import { ViewMusicChannel } from './ViewMusicChannel';
 import { ViewMusicChannel } from './ViewMusicChannel';
 import { toVideoPreviews } from '../video/VideoPreview';
 import { toVideoPreviews } from '../video/VideoPreview';
 import { isVideoChannel, isMusicChannel } from './ChannelHelpers';
 import { isVideoChannel, isMusicChannel } from './ChannelHelpers';
-import { JoyError } from '@polkadot/joy-utils/JoyStatus';
+import { JoyError } from '@polkadot/joy-utils/react/components';
 
 
 export type ViewChannelProps = {
 export type ViewChannelProps = {
   id: ChannelId;
   id: ChannelId;

+ 4 - 3
pioneer/packages/joy-media/src/channels/ViewChannel.view.tsx

@@ -2,8 +2,8 @@ import React from 'react';
 import { RouteComponentProps } from 'react-router';
 import { RouteComponentProps } from 'react-router';
 import { MediaView } from '../MediaView';
 import { MediaView } from '../MediaView';
 import { ViewChannelProps, ViewChannel } from './ViewChannel';
 import { ViewChannelProps, ViewChannel } from './ViewChannel';
-import { ChannelId } from '@joystream/types/content-working-group';
-import { JoyError } from '@polkadot/joy-utils/JoyStatus';
+import { JoyError } from '@polkadot/joy-utils/react/components';
+import { useApi } from '@polkadot/react-hooks';
 
 
 type Props = ViewChannelProps;
 type Props = ViewChannelProps;
 
 
@@ -20,10 +20,11 @@ export const ViewChannelView = MediaView<Props>({
 
 
 export const ViewChannelWithRouter = (props: Props & RouteComponentProps<any>) => {
 export const ViewChannelWithRouter = (props: Props & RouteComponentProps<any>) => {
   const { match: { params: { id } } } = props;
   const { match: { params: { id } } } = props;
+  const { api } = useApi();
 
 
   if (id) {
   if (id) {
     try {
     try {
-      return <ViewChannelView {...props} id={new ChannelId(id)} />;
+      return <ViewChannelView {...props} id={api.createType('ChannelId', id)} />;
     } catch (err) {
     } catch (err) {
       console.log('ViewChannelWithRouter failed:', err);
       console.log('ViewChannelWithRouter failed:', err);
     }
     }

+ 1 - 1
pioneer/packages/joy-media/src/channels/ViewMusicChannel.tsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import React from 'react';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelEntity } from '../entities/ChannelEntity';
-import Section from '@polkadot/joy-utils/Section';
+import { Section } from '@polkadot/joy-utils/react/components';
 import { ChannelHeader } from './ChannelHeader';
 import { ChannelHeader } from './ChannelHeader';
 import { MusicAlbumPreviewProps, MusicAlbumPreview } from '../music/MusicAlbumPreview';
 import { MusicAlbumPreviewProps, MusicAlbumPreview } from '../music/MusicAlbumPreview';
 import { MusicTrackReaderPreview, MusicTrackReaderPreviewProps } from '../music/MusicTrackReaderPreview';
 import { MusicTrackReaderPreview, MusicTrackReaderPreviewProps } from '../music/MusicTrackReaderPreview';

+ 1 - 1
pioneer/packages/joy-media/src/channels/ViewVideoChannel.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
 import React from 'react';
-import Section from '@polkadot/joy-utils/Section';
+import { Section } from '@polkadot/joy-utils/react/components';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelHeader } from './ChannelHeader';
 import { ChannelHeader } from './ChannelHeader';
 import { VideoPreview, VideoPreviewProps } from '../video/VideoPreview';
 import { VideoPreview, VideoPreviewProps } from '../video/VideoPreview';

+ 2 - 2
pioneer/packages/joy-media/src/common/MediaForms.tsx

@@ -1,11 +1,11 @@
 import React from 'react';
 import React from 'react';
 import { Dropdown, DropdownItemProps, DropdownProps } from 'semantic-ui-react';
 import { Dropdown, DropdownItemProps, DropdownProps } from 'semantic-ui-react';
 import { FormikProps, Field } from 'formik';
 import { FormikProps, Field } from 'formik';
-import * as JoyForms from '@polkadot/joy-utils/forms';
+import * as JoyForms from '@polkadot/joy-utils/react/components/forms';
 import { SubmittableResult } from '@polkadot/api';
 import { SubmittableResult } from '@polkadot/api';
 import { TxFailedCallback, TxCallback } from '@polkadot/react-components/Status/types';
 import { TxFailedCallback, TxCallback } from '@polkadot/react-components/Status/types';
 import { MediaDropdownOptions } from './MediaDropdownOptions';
 import { MediaDropdownOptions } from './MediaDropdownOptions';
-import { OnTxButtonClick } from '@polkadot/joy-utils/TxButton';
+import { OnTxButtonClick } from '@polkadot/joy-utils/react/components/TxButton';
 import isEqual from 'lodash/isEqual';
 import isEqual from 'lodash/isEqual';
 import { componentName } from '@polkadot/joy-utils/react/helpers';
 import { componentName } from '@polkadot/joy-utils/react/helpers';
 
 

+ 3 - 3
pioneer/packages/joy-media/src/common/MediaPlayerView.tsx

@@ -5,7 +5,7 @@ import APlayer from 'react-aplayer';
 
 
 import { ApiProps } from '@polkadot/react-api/types';
 import { ApiProps } from '@polkadot/react-api/types';
 import { I18nProps } from '@polkadot/react-components/types';
 import { I18nProps } from '@polkadot/react-components/types';
-import { withCalls, withMulti } from '@polkadot/react-api/with';
+import { withCalls, withMulti } from '@polkadot/react-api/hoc';
 import { Option } from '@polkadot/types/codec';
 import { Option } from '@polkadot/types/codec';
 
 
 import translate from '../translate';
 import translate from '../translate';
@@ -14,8 +14,8 @@ import { DataObject, ContentId } from '@joystream/types/media';
 import { VideoType } from '../schemas/video/Video';
 import { VideoType } from '../schemas/video/Video';
 import { isAccountAChannelOwner } from '../channels/ChannelHelpers';
 import { isAccountAChannelOwner } from '../channels/ChannelHelpers';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelEntity } from '../entities/ChannelEntity';
-import { useMyMembership } from '@polkadot/joy-utils/MyMembershipContext';
-import { JoyError } from '@polkadot/joy-utils/JoyStatus';
+import { useMyMembership } from '@polkadot/joy-utils/react/hooks';
+import { JoyError } from '@polkadot/joy-utils/react/components';
 
 
 const PLAYER_COMMON_PARAMS = {
 const PLAYER_COMMON_PARAMS = {
   lang: 'en',
   lang: 'en',

+ 5 - 22
pioneer/packages/joy-media/src/common/MediaPlayerWithResolver.tsx

@@ -4,17 +4,16 @@ import _ from 'lodash';
 
 
 import { ApiProps } from '@polkadot/react-api/types';
 import { ApiProps } from '@polkadot/react-api/types';
 import { I18nProps } from '@polkadot/react-components/types';
 import { I18nProps } from '@polkadot/react-components/types';
-import { withMulti } from '@polkadot/react-api/with';
+import { withMulti } from '@polkadot/react-api/hoc';
 import { Option } from '@polkadot/types/codec';
 import { Option } from '@polkadot/types/codec';
-import { StorageProviderId, Worker } from '@joystream/types/working-group';
 
 
 import translate from '../translate';
 import translate from '../translate';
 import { DiscoveryProviderProps, withDiscoveryProvider } from '../DiscoveryProvider';
 import { DiscoveryProviderProps, withDiscoveryProvider } from '../DiscoveryProvider';
 import { DataObjectStorageRelationshipId, DataObjectStorageRelationship } from '@joystream/types/media';
 import { DataObjectStorageRelationshipId, DataObjectStorageRelationship } from '@joystream/types/media';
 import { Message } from 'semantic-ui-react';
 import { Message } from 'semantic-ui-react';
 import { MediaPlayerView, RequiredMediaPlayerProps } from './MediaPlayerView';
 import { MediaPlayerView, RequiredMediaPlayerProps } from './MediaPlayerView';
-import { JoyInfo } from '@polkadot/joy-utils/JoyStatus';
-import { MultipleLinkedMapEntry } from '@polkadot/joy-utils/index';
+import { JoyInfo } from '@polkadot/joy-utils/react/components';
+import { useTransport } from '@polkadot/joy-utils/react/hooks';
 
 
 type Props = ApiProps & I18nProps & DiscoveryProviderProps & RequiredMediaPlayerProps;
 type Props = ApiProps & I18nProps & DiscoveryProviderProps & RequiredMediaPlayerProps;
 
 
@@ -24,29 +23,13 @@ function newCancelSource (): CancelTokenSource {
 
 
 function InnerComponent (props: Props) {
 function InnerComponent (props: Props) {
   const { contentId, api, discoveryProvider } = props;
   const { contentId, api, discoveryProvider } = props;
+  const transport = useTransport();
 
 
   const [error, setError] = useState<Error>();
   const [error, setError] = useState<Error>();
   const [resolvedAssetUrl, setResolvedAssetUrl] = useState<string>();
   const [resolvedAssetUrl, setResolvedAssetUrl] = useState<string>();
   const [contentType, setContentType] = useState<string>();
   const [contentType, setContentType] = useState<string>();
   const [cancelSource, setCancelSource] = useState<CancelTokenSource>(newCancelSource());
   const [cancelSource, setCancelSource] = useState<CancelTokenSource>(newCancelSource());
 
 
-  const getActiveStorageProviderIds = async (): Promise<StorageProviderId[]> => {
-    const nextId = await api.query.storageWorkingGroup.nextWorkerId() as StorageProviderId;
-    // This is chain specfic, but if next id is still 0, it means no workers have been added,
-    // so the workerById is empty
-    if (nextId.eq(0)) {
-      return [];
-    }
-
-    const workers = new MultipleLinkedMapEntry<StorageProviderId, Worker>(
-      StorageProviderId,
-      Worker,
-      await api.query.storageWorkingGroup.workerById()
-    );
-
-    return workers.linked_keys;
-  };
-
   const resolveAsset = async () => {
   const resolveAsset = async () => {
     setError(undefined);
     setError(undefined);
     setCancelSource(newCancelSource());
     setCancelSource(newCancelSource());
@@ -68,9 +51,9 @@ function InnerComponent (props: Props) {
       return;
       return;
     }
     }
 
 
+    const activeProviders = (await transport.workingGroups.allWorkers('Storage')).map(([id]) => id);
     // filter out providers no longer active - relationships of providers that have left
     // filter out providers no longer active - relationships of providers that have left
     // are not pruned onchain.
     // are not pruned onchain.
-    const activeProviders = await getActiveStorageProviderIds();
     readyProviders = _.intersectionBy(activeProviders, readyProviders, provider => provider.toString());
     readyProviders = _.intersectionBy(activeProviders, readyProviders, provider => provider.toString());
 
 
     console.log(`Found ${readyProviders.length} providers ready to serve content: ${readyProviders}`);
     console.log(`Found ${readyProviders.length} providers ready to serve content: ${readyProviders}`);

+ 4 - 3
pioneer/packages/joy-media/src/common/TypeHelpers.ts

@@ -1,4 +1,5 @@
 import BN from 'bn.js';
 import BN from 'bn.js';
+import { createMock } from '@joystream/types';
 import { ChannelId } from '@joystream/types/content-working-group';
 import { ChannelId } from '@joystream/types/content-working-group';
 import { EntityId, ClassId } from '@joystream/types/versioned-store';
 import { EntityId, ClassId } from '@joystream/types/versioned-store';
 
 
@@ -16,7 +17,7 @@ export function asChannelId (id: AnyChannelId): ChannelId {
   if (id instanceof ChannelId) {
   if (id instanceof ChannelId) {
     return id;
     return id;
   } else if (canBeId(id)) {
   } else if (canBeId(id)) {
-    return new ChannelId(id);
+    return createMock('ChannelId', id);
   } else {
   } else {
     throw new Error(`Not supported format for Channel id: ${id}`);
     throw new Error(`Not supported format for Channel id: ${id}`);
   }
   }
@@ -26,7 +27,7 @@ export function asEntityId (id: AnyEntityId): EntityId {
   if (id instanceof EntityId) {
   if (id instanceof EntityId) {
     return id;
     return id;
   } else if (canBeId(id)) {
   } else if (canBeId(id)) {
-    return new EntityId(id);
+    return createMock('EntityId', id);
   } else {
   } else {
     throw new Error(`Not supported format for Entity id: ${id}`);
     throw new Error(`Not supported format for Entity id: ${id}`);
   }
   }
@@ -36,7 +37,7 @@ export function asClassId (id: AnyClassId): ClassId {
   if (id instanceof ClassId) {
   if (id instanceof ClassId) {
     return id;
     return id;
   } else if (canBeId(id)) {
   } else if (canBeId(id)) {
-    return new ClassId(id);
+    return createMock('ClassId', id);
   } else {
   } else {
     throw new Error(`Not supported format for Class id: ${id}`);
     throw new Error(`Not supported format for Class id: ${id}`);
   }
   }

+ 2 - 0
pioneer/packages/joy-utils-old/src/images.ts → pioneer/packages/joy-media/src/common/images.tsx

@@ -1,3 +1,5 @@
+import React from 'react';
+
 export const DEFAULT_THUMBNAIL_URL = 'images/default-thumbnail.png';
 export const DEFAULT_THUMBNAIL_URL = 'images/default-thumbnail.png';
 
 
 // This is a hack to just satisfy TypeScript compiler.
 // This is a hack to just satisfy TypeScript compiler.

+ 0 - 0
pioneer/packages/joy-media/src/common/index.css → pioneer/packages/joy-media/src/common/index.scss


+ 1 - 1
pioneer/packages/joy-media/src/explore/AllChannels.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
 import React from 'react';
-import Section from '@polkadot/joy-utils/Section';
+import { Section } from '@polkadot/joy-utils/react/components';
 import { MediaView } from '../MediaView';
 import { MediaView } from '../MediaView';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelPreview } from '../channels/ChannelPreview';
 import { ChannelPreview } from '../channels/ChannelPreview';

+ 1 - 1
pioneer/packages/joy-media/src/explore/AllVideos.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
 import React from 'react';
-import Section from '@polkadot/joy-utils/Section';
+import { Section } from '@polkadot/joy-utils/react/components';
 import { VideoPreviewProps, VideoPreview } from '../video/VideoPreview';
 import { VideoPreviewProps, VideoPreview } from '../video/VideoPreview';
 import { MediaView } from '../MediaView';
 import { MediaView } from '../MediaView';
 
 

+ 1 - 1
pioneer/packages/joy-media/src/explore/ExploreContent.tsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import React from 'react';
 import { Link } from 'react-router-dom';
 import { Link } from 'react-router-dom';
-import Section from '@polkadot/joy-utils/Section';
+import { Section } from '@polkadot/joy-utils/react/components';
 import { VideoPreviewProps, VideoPreview } from '../video/VideoPreview';
 import { VideoPreviewProps, VideoPreview } from '../video/VideoPreview';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelPreview } from '../channels/ChannelPreview';
 import { ChannelPreview } from '../channels/ChannelPreview';

+ 1 - 1
pioneer/packages/joy-media/src/explore/PlayContent.tsx

@@ -1,7 +1,7 @@
 import React, { useState } from 'react';
 import React, { useState } from 'react';
 import { MusicAlbumPreviewProps, MusicAlbumPreview } from '../music/MusicAlbumPreview';
 import { MusicAlbumPreviewProps, MusicAlbumPreview } from '../music/MusicAlbumPreview';
 import { MusicTrackReaderPreviewProps, MusicTrackReaderPreview } from '../music/MusicTrackReaderPreview';
 import { MusicTrackReaderPreviewProps, MusicTrackReaderPreview } from '../music/MusicTrackReaderPreview';
-import { Pluralize } from '@polkadot/joy-utils/Pluralize';
+import { Pluralize } from '@polkadot/joy-utils/react/components';
 import { Table } from 'semantic-ui-react';
 import { Table } from 'semantic-ui-react';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelPreview } from '../channels/ChannelPreview';
 import { ChannelPreview } from '../channels/ChannelPreview';

+ 5 - 3
pioneer/packages/joy-media/src/index.css → pioneer/packages/joy-media/src/index.scss

@@ -41,6 +41,11 @@
     width: 100%;
     width: 100%;
     max-width: 600px;
     max-width: 600px;
   }
   }
+
+  .EditMetaForm {
+    flex-grow: 1;
+    max-width: 600px;
+  }
 }
 }
 
 
 .PlayBox {
 .PlayBox {
@@ -72,9 +77,6 @@
   .MediaCell {
   .MediaCell {
     width: 25%;
     width: 25%;
 
 
-    &.MyContent {
-      /* background-color: #fff8e1; */
-    }
     &:hover {
     &:hover {
       background-color: #deeffc;
       background-color: #deeffc;
     }
     }

+ 6 - 5
pioneer/packages/joy-media/src/index.tsx

@@ -3,15 +3,16 @@ import React from 'react';
 import { Route, Switch } from 'react-router';
 import { Route, Switch } from 'react-router';
 
 
 import { AppProps, I18nProps } from '@polkadot/react-components/types';
 import { AppProps, I18nProps } from '@polkadot/react-components/types';
-import Tabs, { TabItem } from '@polkadot/react-components/Tabs';
+import Tabs from '@polkadot/react-components/Tabs';
+import { TabItem } from '@polkadot/react-components/Tabs/types';
 import { ApiProps } from '@polkadot/react-api/types';
 import { ApiProps } from '@polkadot/react-api/types';
-import { withMulti } from '@polkadot/react-api/with';
+import { withMulti } from '@polkadot/react-api/hoc';
 
 
-import './index.css';
-import './common/index.css';
+import './index.scss';
+import './common/index.scss';
 
 
 import translate from './translate';
 import translate from './translate';
-import { useMyAccount } from '@polkadot/joy-utils/MyAccountContext';
+import { useMyAccount } from '@polkadot/joy-utils/react/hooks';
 import { UploadWithRouter } from './Upload';
 import { UploadWithRouter } from './Upload';
 import { DiscoveryProviderProps, DiscoveryProviderProvider } from './DiscoveryProvider';
 import { DiscoveryProviderProps, DiscoveryProviderProvider } from './DiscoveryProvider';
 import { SubstrateTransportProvider } from './TransportContext';
 import { SubstrateTransportProvider } from './TransportContext';

+ 2 - 3
pioneer/packages/joy-media/src/music/EditMusicAlbum.tsx

@@ -3,8 +3,8 @@ import { Button, Tab } from 'semantic-ui-react';
 import { Form, withFormik } from 'formik';
 import { Form, withFormik } from 'formik';
 import { History } from 'history';
 import { History } from 'history';
 
 
-import TxButton from '@polkadot/joy-utils/TxButton';
-import { onImageError } from '@polkadot/joy-utils/images';
+import { TxButton } from '@polkadot/joy-utils/react/components';
+import { onImageError } from '../common/images';
 import { ReorderableTracks } from './ReorderableTracks';
 import { ReorderableTracks } from './ReorderableTracks';
 import { MusicAlbumValidationSchema, MusicAlbumType, MusicAlbumClass as Fields, MusicAlbumFormValues, MusicAlbumToFormValues } from '../schemas/music/MusicAlbum';
 import { MusicAlbumValidationSchema, MusicAlbumType, MusicAlbumClass as Fields, MusicAlbumFormValues, MusicAlbumToFormValues } from '../schemas/music/MusicAlbum';
 import { withMediaForm, MediaFormProps, datePlaceholder } from '../common/MediaForms';
 import { withMediaForm, MediaFormProps, datePlaceholder } from '../common/MediaForms';
@@ -123,7 +123,6 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
   const renderMainButton = () =>
   const renderMainButton = () =>
     <TxButton
     <TxButton
       type='submit'
       type='submit'
-      size='large'
       isDisabled={!dirty || isSubmitting}
       isDisabled={!dirty || isSubmitting}
       label={isNew
       label={isNew
         ? 'Publish'
         ? 'Publish'

+ 1 - 1
pioneer/packages/joy-media/src/music/MusicAlbumPreview.tsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import React from 'react';
 import { Button } from 'semantic-ui-react';
 import { Button } from 'semantic-ui-react';
-import { Pluralize } from '@polkadot/joy-utils/Pluralize';
+import { Pluralize } from '@polkadot/joy-utils/react/components';
 import { BgImg } from '../common/BgImg';
 import { BgImg } from '../common/BgImg';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelEntity } from '../entities/ChannelEntity';
 
 

+ 1 - 1
pioneer/packages/joy-media/src/music/MusicAlbumTracks.tsx

@@ -1,6 +1,6 @@
 import React, { useState } from 'react';
 import React, { useState } from 'react';
 import { Button, CheckboxProps } from 'semantic-ui-react';
 import { Button, CheckboxProps } from 'semantic-ui-react';
-import { Pluralize } from '@polkadot/joy-utils/Pluralize';
+import { Pluralize } from '@polkadot/joy-utils/react/components';
 import { EditableMusicTrackPreviewProps, MusicTrackPreview } from './MusicTrackPreview';
 import { EditableMusicTrackPreviewProps, MusicTrackPreview } from './MusicTrackPreview';
 import { MusicAlbumPreviewProps, MusicAlbumPreview } from './MusicAlbumPreview';
 import { MusicAlbumPreviewProps, MusicAlbumPreview } from './MusicAlbumPreview';
 
 

+ 2 - 2
pioneer/packages/joy-media/src/music/MyMusicTracks.tsx

@@ -1,8 +1,8 @@
 import React, { useState } from 'react';
 import React, { useState } from 'react';
 import { Button, CheckboxProps, Dropdown, Message } from 'semantic-ui-react';
 import { Button, CheckboxProps, Dropdown, Message } from 'semantic-ui-react';
 
 
-import { Pluralize } from '@polkadot/joy-utils/Pluralize';
-import Section from '@polkadot/joy-utils/Section';
+import { Pluralize } from '@polkadot/joy-utils/react/components';
+import { Section } from '@polkadot/joy-utils/react/components';
 import { EditableMusicTrackPreviewProps, MusicTrackPreview } from './MusicTrackPreview';
 import { EditableMusicTrackPreviewProps, MusicTrackPreview } from './MusicTrackPreview';
 import { ReorderableTracks } from './ReorderableTracks';
 import { ReorderableTracks } from './ReorderableTracks';
 import { MusicAlbumPreviewProps } from './MusicAlbumPreview';
 import { MusicAlbumPreviewProps } from './MusicAlbumPreview';

+ 14 - 14
pioneer/packages/joy-media/src/schemas/channel/Channel.ts

@@ -4,7 +4,7 @@ import { BlockNumber, AccountId } from '@polkadot/types/interfaces';
 import { ChannelContentTypeValue, PrincipalId, Channel, ChannelId, ChannelPublicationStatusValue, ChannelCurationStatusValue } from '@joystream/types/content-working-group';
 import { ChannelContentTypeValue, PrincipalId, Channel, ChannelId, ChannelPublicationStatusValue, ChannelCurationStatusValue } from '@joystream/types/content-working-group';
 import { MemberId } from '@joystream/types/members';
 import { MemberId } from '@joystream/types/members';
 import { ChannelValidationConstraints } from '@polkadot/joy-media/transport';
 import { ChannelValidationConstraints } from '@polkadot/joy-media/transport';
-import { ValidationConstraint } from '@polkadot/joy-utils/ValidationConstraint';
+import { ValidationConstraint } from '@polkadot/joy-utils/types/ValidationConstraint';
 
 
 function textValidation (constraint?: ValidationConstraint) {
 function textValidation (constraint?: ValidationConstraint) {
   if (!constraint) {
   if (!constraint) {
@@ -56,19 +56,19 @@ export class ChannelCodec {
   static fromSubstrate (id: ChannelId, sub: Channel): ChannelType {
   static fromSubstrate (id: ChannelId, sub: Channel): ChannelType {
     return {
     return {
       id: id.toNumber(),
       id: id.toNumber(),
-      verified: sub.getBoolean('verified'),
-      handle: sub.getString('handle'),
-      title: sub.getOptionalString('title'),
-      description: sub.getOptionalString('description'),
-      avatar: sub.getOptionalString('avatar'),
-      banner: sub.getOptionalString('banner'),
-      content: sub.getEnumAsString<ChannelContentTypeValue>('content'),
-      owner: sub.getField('owner'),
-      roleAccount: sub.getField('role_account'),
-      publicationStatus: sub.getEnumAsString<ChannelPublicationStatusValue>('publication_status'),
-      curationStatus: sub.getEnumAsString<ChannelCurationStatusValue>('curation_status'),
-      created: sub.getField('created'),
-      principalId: sub.getField('principal_id')
+      verified: sub.verified.valueOf(),
+      handle: sub.handle.toString(),
+      title: sub.title.unwrapOr(undefined)?.toString(),
+      description: sub.description.unwrapOr(undefined)?.toString(),
+      avatar: sub.avatar.unwrapOr(undefined)?.toString(),
+      banner: sub.banner.unwrapOr(undefined)?.toString(),
+      content: sub.content.type,
+      owner: sub.owner,
+      roleAccount: sub.role_account,
+      publicationStatus: sub.publication_status.type,
+      curationStatus: sub.curation_status.type,
+      created: sub.created,
+      principalId: sub.principal_id
     };
     };
   }
   }
 }
 }

+ 1 - 1
pioneer/packages/joy-media/src/stories/ExploreContent.stories.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
 import React from 'react';
-import '../common/index.css';
+import '../common/index.scss';
 
 
 import { ExploreContent } from '../explore/ExploreContent';
 import { ExploreContent } from '../explore/ExploreContent';
 import { withMockTransport } from './withMockTransport';
 import { withMockTransport } from './withMockTransport';

+ 3 - 3
pioneer/packages/joy-media/src/stories/MusicAlbumTracks.stories.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
 import React from 'react';
-import '../common/index.css';
+import '../common/index.scss';
 
 
 import { EditForm } from '../music/EditMusicAlbum';
 import { EditForm } from '../music/EditMusicAlbum';
 import { MyMusicTracks } from '../music/MyMusicTracks';
 import { MyMusicTracks } from '../music/MyMusicTracks';
@@ -7,7 +7,7 @@ import { MusicAlbumSamples } from './data/MusicAlbumSamples';
 import { albumTracks, AllMusicTrackSamples } from './data/MusicTrackSamples';
 import { albumTracks, AllMusicTrackSamples } from './data/MusicTrackSamples';
 import { withMockTransport } from './withMockTransport';
 import { withMockTransport } from './withMockTransport';
 import { EditMusicAlbumView } from '../music/EditMusicAlbum.view';
 import { EditMusicAlbumView } from '../music/EditMusicAlbum.view';
-import EntityId from '@joystream/types/versioned-store/EntityId';
+import { createMock } from '@joystream/types';
 
 
 export default {
 export default {
   title: 'Media | My music tracks',
   title: 'Media | My music tracks',
@@ -19,7 +19,7 @@ export const DefaultState = () =>
 
 
 export const MockEditAlbumView = () =>
 export const MockEditAlbumView = () =>
   <EditMusicAlbumView
   <EditMusicAlbumView
-    id={new EntityId(1)}
+    id={createMock('EntityId', 1)}
     tracks={albumTracks}
     tracks={albumTracks}
   />;
   />;
 
 

+ 1 - 1
pioneer/packages/joy-media/src/stories/MusicChannel.stories.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
 import React from 'react';
-import '../common/index.css';
+import '../common/index.scss';
 
 
 import { MockMusicChannel } from './data/ChannelSamples';
 import { MockMusicChannel } from './data/ChannelSamples';
 import { ViewMusicChannel } from '../channels/ViewMusicChannel';
 import { ViewMusicChannel } from '../channels/ViewMusicChannel';

+ 4 - 5
pioneer/packages/joy-media/src/stories/MyChannels.stories.tsx

@@ -1,14 +1,13 @@
 import React from 'react';
 import React from 'react';
-import '../common/index.css';
+import '../common/index.scss';
 
 
-import { GenericAccountId } from '@polkadot/types';
 import { ChannelsByOwner } from '../channels/ChannelsByOwner';
 import { ChannelsByOwner } from '../channels/ChannelsByOwner';
 import { AllMockChannels } from './data/ChannelSamples';
 import { AllMockChannels } from './data/ChannelSamples';
 import { withMockTransport } from './withMockTransport';
 import { withMockTransport } from './withMockTransport';
 import EditForm from '../channels/EditChannel';
 import EditForm from '../channels/EditChannel';
 import { EditChannelView } from '../channels/EditChannel.view';
 import { EditChannelView } from '../channels/EditChannel.view';
-import { ChannelId } from '@joystream/types/content-working-group';
 import { AccountIdSamples } from './data/AccountIdSamples';
 import { AccountIdSamples } from './data/AccountIdSamples';
+import { createMock } from '@joystream/types';
 
 
 export default {
 export default {
   title: 'Media | My channels',
   title: 'Media | My channels',
@@ -16,7 +15,7 @@ export default {
 };
 };
 
 
 // TODO pass to mocked MyMembershipContext provider via Stories decorators:
 // TODO pass to mocked MyMembershipContext provider via Stories decorators:
-const accountId = new GenericAccountId(AccountIdSamples.Alice);
+const accountId = createMock('AccountId', AccountIdSamples.Alice);
 
 
 export const DefaultState = () =>
 export const DefaultState = () =>
   <ChannelsByOwner accountId={accountId} />;
   <ChannelsByOwner accountId={accountId} />;
@@ -31,4 +30,4 @@ export const DefaultEditForm = () =>
   <EditForm />;
   <EditForm />;
 
 
 export const MockEditFormView = () =>
 export const MockEditFormView = () =>
-  <EditChannelView id={new ChannelId(1)} />;
+  <EditChannelView id={createMock('ChannelId', 1)} />;

+ 1 - 1
pioneer/packages/joy-media/src/stories/MyMusicAlbums.stories.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
 import React from 'react';
-import '../common/index.css';
+import '../common/index.scss';
 
 
 import { MyMusicAlbums } from '../music/MyMusicAlbums';
 import { MyMusicAlbums } from '../music/MyMusicAlbums';
 import { MusicAlbumSamples } from './data/MusicAlbumSamples';
 import { MusicAlbumSamples } from './data/MusicAlbumSamples';

+ 3 - 3
pioneer/packages/joy-media/src/stories/Playback.stories.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
 import React from 'react';
-import '../common/index.css';
+import '../common/index.scss';
 
 
 import { PlayContent } from '../explore/PlayContent';
 import { PlayContent } from '../explore/PlayContent';
 import { PlayVideo } from '../video/PlayVideo';
 import { PlayVideo } from '../video/PlayVideo';
@@ -8,7 +8,7 @@ import { Album1TrackSamples } from './data/MusicTrackSamples';
 import { MockMusicChannel, MockVideoChannel } from './data/ChannelSamples';
 import { MockMusicChannel, MockVideoChannel } from './data/ChannelSamples';
 import { withMockTransport } from './withMockTransport';
 import { withMockTransport } from './withMockTransport';
 import { Video } from '../mocks';
 import { Video } from '../mocks';
-import { EntityId } from '@joystream/types/versioned-store';
+import { createMock } from '@joystream/types';
 
 
 export default {
 export default {
   title: 'Media | Playback',
   title: 'Media | Playback',
@@ -17,7 +17,7 @@ export default {
 
 
 export const PlayVideoStory = () =>
 export const PlayVideoStory = () =>
   <PlayVideo
   <PlayVideo
-    id={new EntityId(Video.id)}
+    id={createMock('EntityId', Video.id)}
     video={Video}
     video={Video}
     channel={MockVideoChannel}
     channel={MockVideoChannel}
   />;
   />;

+ 3 - 3
pioneer/packages/joy-media/src/stories/UploadAudio.stories.tsx

@@ -3,16 +3,16 @@ import { EditForm } from '../upload/UploadAudio';
 import '../index.css';
 import '../index.css';
 
 
 import { ContentId } from '@joystream/types/media';
 import { ContentId } from '@joystream/types/media';
-import EntityId from '@joystream/types/versioned-store/EntityId';
 import { UploadAudioView } from '../upload/UploadAudio.view';
 import { UploadAudioView } from '../upload/UploadAudio.view';
 import { withMockTransport } from './withMockTransport';
 import { withMockTransport } from './withMockTransport';
+import { mockRegistry, createMock } from '@joystream/types';
 
 
 export default {
 export default {
   title: 'Media | Upload audio',
   title: 'Media | Upload audio',
   decorators: [withMockTransport]
   decorators: [withMockTransport]
 };
 };
 
 
-const contentId = ContentId.generate();
+const contentId = ContentId.generate(mockRegistry);
 
 
 export const DefaultState = () =>
 export const DefaultState = () =>
   <EditForm
   <EditForm
@@ -22,5 +22,5 @@ export const DefaultState = () =>
 export const MockEditFormView = () =>
 export const MockEditFormView = () =>
   <UploadAudioView
   <UploadAudioView
     contentId={contentId}
     contentId={contentId}
-    id={new EntityId(1)}
+    id={createMock('EntityId', 1)}
   />;
   />;

+ 3 - 3
pioneer/packages/joy-media/src/stories/UploadVideo.stories.tsx

@@ -5,14 +5,14 @@ import '../index.css';
 import { ContentId } from '@joystream/types/media';
 import { ContentId } from '@joystream/types/media';
 import { withMockTransport } from './withMockTransport';
 import { withMockTransport } from './withMockTransport';
 import EditVideoView from '../upload/EditVideo.view';
 import EditVideoView from '../upload/EditVideo.view';
-import EntityId from '@joystream/types/versioned-store/EntityId';
+import { createMock, mockRegistry } from '@joystream/types';
 
 
 export default {
 export default {
   title: 'Media | Upload video',
   title: 'Media | Upload video',
   decorators: [withMockTransport]
   decorators: [withMockTransport]
 };
 };
 
 
-const contentId = ContentId.generate();
+const contentId = ContentId.generate(mockRegistry);
 
 
 export const DefaultState = () =>
 export const DefaultState = () =>
   <EditForm
   <EditForm
@@ -22,5 +22,5 @@ export const DefaultState = () =>
 export const MockEditFormView = () =>
 export const MockEditFormView = () =>
   <EditVideoView
   <EditVideoView
     contentId={contentId}
     contentId={contentId}
-    id={new EntityId(1)}
+    id={createMock('EntityId', 1)}
   />;
   />;

+ 4 - 4
pioneer/packages/joy-media/src/stories/data/AccountIdSamples.ts

@@ -1,7 +1,7 @@
-import { GenericAccountId } from '@polkadot/types';
+import { createMock } from '@joystream/types';
 
 
 export const AccountIdSamples = {
 export const AccountIdSamples = {
-  Alice: new GenericAccountId('5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY'),
-  Bob: new GenericAccountId('5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'),
-  Charlie: new GenericAccountId('5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y')
+  Alice: createMock('AccountId', '5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY'),
+  Bob: createMock('AccountId', '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'),
+  Charlie: createMock('AccountId', '5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y')
 };
 };

+ 7 - 9
pioneer/packages/joy-media/src/stories/data/ChannelSamples.ts

@@ -1,9 +1,7 @@
 import BN from 'bn.js';
 import BN from 'bn.js';
 import { ChannelEntity } from '@polkadot/joy-media/entities/ChannelEntity';
 import { ChannelEntity } from '@polkadot/joy-media/entities/ChannelEntity';
-import { u32 } from '@polkadot/types';
 import { AccountIdSamples } from './AccountIdSamples';
 import { AccountIdSamples } from './AccountIdSamples';
-import { MemberId } from '@joystream/types/members';
-import { PrincipalId } from '@joystream/types/content-working-group';
+import { createMock } from '@joystream/types';
 
 
 let id = 0;
 let id = 0;
 const nextId = () => ++id;
 const nextId = () => ++id;
@@ -22,10 +20,10 @@ export const MockMusicChannel: ChannelEntity =
 
 
   publicationStatus: 'Unlisted',
   publicationStatus: 'Unlisted',
   curationStatus: 'Censored',
   curationStatus: 'Censored',
-  owner: new MemberId(1),
+  owner: createMock('MemberId', 1),
   roleAccount: AccountIdSamples.Alice,
   roleAccount: AccountIdSamples.Alice,
-  principalId: new PrincipalId(1),
-  created: new u32(123456),
+  principalId: createMock('PrincipalId', 1),
+  created: createMock('u32', 123456),
 
 
   rewardEarned: new BN('4587'),
   rewardEarned: new BN('4587'),
   contentItemsCount: 57
   contentItemsCount: 57
@@ -45,10 +43,10 @@ export const MockVideoChannel: ChannelEntity =
 
 
   publicationStatus: 'Public',
   publicationStatus: 'Public',
   curationStatus: 'Normal',
   curationStatus: 'Normal',
-  owner: new MemberId(1),
+  owner: createMock('MemberId', 1),
   roleAccount: AccountIdSamples.Alice,
   roleAccount: AccountIdSamples.Alice,
-  principalId: new PrincipalId(1),
-  created: new u32(123456),
+  principalId: createMock('PrincipalId', 1),
+  created: createMock('u32', 123456),
 
 
   rewardEarned: new BN('1820021'),
   rewardEarned: new BN('1820021'),
   contentItemsCount: 1529
   contentItemsCount: 1529

+ 15 - 14
pioneer/packages/joy-media/src/transport.mock.ts

@@ -17,6 +17,7 @@ import { PublicationStatusType } from './schemas/general/PublicationStatus';
 import { VideoCategoryType } from './schemas/video/VideoCategory';
 import { VideoCategoryType } from './schemas/video/VideoCategory';
 import { ChannelEntity } from './entities/ChannelEntity';
 import { ChannelEntity } from './entities/ChannelEntity';
 import { AllMockChannels } from './stories/data/ChannelSamples';
 import { AllMockChannels } from './stories/data/ChannelSamples';
+import { mockPromise } from '@polkadot/joy-utils/transport/mock/base';
 
 
 export class MockTransport extends MediaTransport {
 export class MockTransport extends MediaTransport {
   constructor () {
   constructor () {
@@ -29,7 +30,7 @@ export class MockTransport extends MediaTransport {
   }
   }
 
 
   allChannels (): Promise<ChannelEntity[]> {
   allChannels (): Promise<ChannelEntity[]> {
-    return this.promise(AllMockChannels);
+    return mockPromise(AllMockChannels);
   }
   }
 
 
   channelValidationConstraints (): Promise<ChannelValidationConstraints> {
   channelValidationConstraints (): Promise<ChannelValidationConstraints> {
@@ -45,54 +46,54 @@ export class MockTransport extends MediaTransport {
   }
   }
 
 
   allVideos (): Promise<VideoType[]> {
   allVideos (): Promise<VideoType[]> {
-    return this.promise(mocks.AllVideos);
+    return mockPromise(mocks.AllVideos);
   }
   }
 
 
   allMusicTracks (): Promise<MusicTrackType[]> {
   allMusicTracks (): Promise<MusicTrackType[]> {
-    return this.promise(mocks.AllMusicTracks);
+    return mockPromise(mocks.AllMusicTracks);
   }
   }
 
 
   allMusicAlbums (): Promise<MusicAlbumType[]> {
   allMusicAlbums (): Promise<MusicAlbumType[]> {
-    return this.promise(mocks.AllMusicAlbums);
+    return mockPromise(mocks.AllMusicAlbums);
   }
   }
 
 
   featuredContent (): Promise<FeaturedContentType | undefined> {
   featuredContent (): Promise<FeaturedContentType | undefined> {
-    return this.promise(mocks.FeaturedContent);
+    return mockPromise(mocks.FeaturedContent);
   }
   }
 
 
   allContentLicenses (): Promise<ContentLicenseType[]> {
   allContentLicenses (): Promise<ContentLicenseType[]> {
-    return this.promise(mocks.AllContentLicenses);
+    return mockPromise(mocks.AllContentLicenses);
   }
   }
 
 
   allCurationStatuses (): Promise<CurationStatusType[]> {
   allCurationStatuses (): Promise<CurationStatusType[]> {
-    return this.promise(mocks.AllCurationStatuses);
+    return mockPromise(mocks.AllCurationStatuses);
   }
   }
 
 
   allLanguages (): Promise<LanguageType[]> {
   allLanguages (): Promise<LanguageType[]> {
-    return this.promise(mocks.AllLanguages);
+    return mockPromise(mocks.AllLanguages);
   }
   }
 
 
   allMediaObjects (): Promise<MediaObjectType[]> {
   allMediaObjects (): Promise<MediaObjectType[]> {
-    return this.promise(mocks.AllMediaObjects);
+    return mockPromise(mocks.AllMediaObjects);
   }
   }
 
 
   allMusicGenres (): Promise<MusicGenreType[]> {
   allMusicGenres (): Promise<MusicGenreType[]> {
-    return this.promise(mocks.AllMusicGenres);
+    return mockPromise(mocks.AllMusicGenres);
   }
   }
 
 
   allMusicMoods (): Promise<MusicMoodType[]> {
   allMusicMoods (): Promise<MusicMoodType[]> {
-    return this.promise(mocks.AllMusicMoods);
+    return mockPromise(mocks.AllMusicMoods);
   }
   }
 
 
   allMusicThemes (): Promise<MusicThemeType[]> {
   allMusicThemes (): Promise<MusicThemeType[]> {
-    return this.promise(mocks.AllMusicThemes);
+    return mockPromise(mocks.AllMusicThemes);
   }
   }
 
 
   allPublicationStatuses (): Promise<PublicationStatusType[]> {
   allPublicationStatuses (): Promise<PublicationStatusType[]> {
-    return this.promise(mocks.AllPublicationStatuses);
+    return mockPromise(mocks.AllPublicationStatuses);
   }
   }
 
 
   allVideoCategories (): Promise<VideoCategoryType[]> {
   allVideoCategories (): Promise<VideoCategoryType[]> {
-    return this.promise(mocks.AllVideoCategories);
+    return mockPromise(mocks.AllVideoCategories);
   }
   }
 }
 }

+ 10 - 13
pioneer/packages/joy-media/src/transport.substrate.ts

@@ -19,13 +19,11 @@ import { ChannelEntity } from './entities/ChannelEntity';
 import { ChannelId, Channel } from '@joystream/types/content-working-group';
 import { ChannelId, Channel } from '@joystream/types/content-working-group';
 import { ApiPromise } from '@polkadot/api/index';
 import { ApiPromise } from '@polkadot/api/index';
 import { ApiProps } from '@polkadot/react-api/types';
 import { ApiProps } from '@polkadot/react-api/types';
-import { Vec } from '@polkadot/types';
-import { LinkageResult } from '@polkadot/types/codec/Linkage';
 import { ChannelCodec } from './schemas/channel/Channel';
 import { ChannelCodec } from './schemas/channel/Channel';
 import { FeaturedContentType } from './schemas/general/FeaturedContent';
 import { FeaturedContentType } from './schemas/general/FeaturedContent';
-import { AnyChannelId, asChannelId, AnyClassId, AnyEntityId } from './common/TypeHelpers';
-import { SimpleCache } from '@polkadot/joy-utils/SimpleCache';
-import { ValidationConstraint } from '@polkadot/joy-utils/ValidationConstraint';
+import { AnyChannelId, AnyClassId, AnyEntityId, asChannelId } from './common/TypeHelpers';
+import { SimpleCache } from '@polkadot/joy-utils/transport/SimpleCache';
+import { ValidationConstraint } from '@polkadot/joy-utils/types/ValidationConstraint';
 
 
 const FIRST_CHANNEL_ID = 1;
 const FIRST_CHANNEL_ID = 1;
 const FIRST_CLASS_ID = 1;
 const FIRST_CLASS_ID = 1;
@@ -130,17 +128,16 @@ export class SubstrateTransport extends MediaTransport {
 
 
     const allIds: ChannelId[] = [];
     const allIds: ChannelId[] = [];
     for (let id = FIRST_CHANNEL_ID; id < nextId; id++) {
     for (let id = FIRST_CHANNEL_ID; id < nextId; id++) {
-      allIds.push(new ChannelId(id));
+      allIds.push(this.api.createType('ChannelId', id));
     }
     }
 
 
     return allIds;
     return allIds;
   }
   }
 
 
   async loadChannelsByIds (ids: AnyChannelId[]): Promise<ChannelEntity[]> {
   async loadChannelsByIds (ids: AnyChannelId[]): Promise<ChannelEntity[]> {
-    const channelTuples = await this.cwgQuery().channelById.multi<LinkageResult>(ids);
+    const channels = await this.cwgQuery().channelById.multi<Channel>(ids);
 
 
-    return channelTuples.map((tuple, i) => {
-      const channel = tuple[0] as Channel;
+    return channels.map((channel, i) => {
       const id = asChannelId(ids[i]);
       const id = asChannelId(ids[i]);
       const plain = ChannelCodec.fromSubstrate(id, channel);
       const plain = ChannelCodec.fromSubstrate(id, channel);
 
 
@@ -200,14 +197,14 @@ export class SubstrateTransport extends MediaTransport {
 
 
     const allIds: ClassId[] = [];
     const allIds: ClassId[] = [];
     for (let id = FIRST_CLASS_ID; id < nextId; id++) {
     for (let id = FIRST_CLASS_ID; id < nextId; id++) {
-      allIds.push(new ClassId(id));
+      allIds.push(this.api.createType('ClassId', id));
     }
     }
 
 
     return allIds;
     return allIds;
   }
   }
 
 
   async loadClassesByIds (ids: AnyClassId[]): Promise<Class[]> {
   async loadClassesByIds (ids: AnyClassId[]): Promise<Class[]> {
-    return await this.vsQuery().classById.multi<Vec<Class>>(ids) as unknown as Class[];
+    return await this.vsQuery().classById.multi<Class>(ids);
   }
   }
 
 
   async allClasses (): Promise<Class[]> {
   async allClasses (): Promise<Class[]> {
@@ -246,7 +243,7 @@ export class SubstrateTransport extends MediaTransport {
 
 
     const allIds: EntityId[] = [];
     const allIds: EntityId[] = [];
     for (let id = FIRST_ENTITY_ID; id < nextId; id++) {
     for (let id = FIRST_ENTITY_ID; id < nextId; id++) {
-      allIds.push(new EntityId(id));
+      allIds.push(this.api.createType('EntityId', id));
     }
     }
 
 
     return allIds;
     return allIds;
@@ -255,7 +252,7 @@ export class SubstrateTransport extends MediaTransport {
   private async loadEntitiesByIds (ids: AnyEntityId[]): Promise<Entity[]> {
   private async loadEntitiesByIds (ids: AnyEntityId[]): Promise<Entity[]> {
     if (!ids || ids.length === 0) return [];
     if (!ids || ids.length === 0) return [];
 
 
-    return await this.vsQuery().entityById.multi<Vec<Entity>>(ids) as unknown as Entity[];
+    return await this.vsQuery().entityById.multi<Entity>(ids);
   }
   }
 
 
   // TODO try to cache this func
   // TODO try to cache this func

+ 6 - 6
pioneer/packages/joy-media/src/transport.ts

@@ -1,4 +1,3 @@
-import { Transport } from '@polkadot/joy-utils/index';
 import { AccountId } from '@polkadot/types/interfaces';
 import { AccountId } from '@polkadot/types/interfaces';
 import { EntityId, Class, ClassName, unifyClassName, ClassIdByNameMap } from '@joystream/types/versioned-store';
 import { EntityId, Class, ClassName, unifyClassName, ClassIdByNameMap } from '@joystream/types/versioned-store';
 import { MusicTrackType, MusicTrackCodec } from './schemas/music/MusicTrack';
 import { MusicTrackType, MusicTrackCodec } from './schemas/music/MusicTrack';
@@ -18,7 +17,8 @@ import { MediaDropdownOptions } from './common/MediaDropdownOptions';
 import { ChannelEntity } from './entities/ChannelEntity';
 import { ChannelEntity } from './entities/ChannelEntity';
 import { ChannelId } from '@joystream/types/content-working-group';
 import { ChannelId } from '@joystream/types/content-working-group';
 import { isVideoChannel, isPublicChannel } from './channels/ChannelHelpers';
 import { isVideoChannel, isPublicChannel } from './channels/ChannelHelpers';
-import { ValidationConstraint } from '@polkadot/joy-utils/ValidationConstraint';
+import { ValidationConstraint } from '@polkadot/joy-utils/types/ValidationConstraint';
+import { createMock } from '@joystream/types';
 
 
 export interface ChannelValidationConstraints {
 export interface ChannelValidationConstraints {
   handle: ValidationConstraint;
   handle: ValidationConstraint;
@@ -60,7 +60,7 @@ function insensitiveEq (text1: string, text2: string): boolean {
   return prepare(text1) === prepare(text2);
   return prepare(text1) === prepare(text2);
 }
 }
 
 
-export abstract class MediaTransport extends Transport {
+export abstract class MediaTransport {
   protected cachedClassIdByNameMap: ClassIdByNameMap | undefined
   protected cachedClassIdByNameMap: ClassIdByNameMap | undefined
 
 
   protected sessionId = 0
   protected sessionId = 0
@@ -128,14 +128,14 @@ export abstract class MediaTransport extends Transport {
   async topVideo (): Promise<VideoType | undefined> {
   async topVideo (): Promise<VideoType | undefined> {
     const content = await this.featuredContent();
     const content = await this.featuredContent();
     const topVideoId = content?.topVideo as unknown as number | undefined;
     const topVideoId = content?.topVideo as unknown as number | undefined;
-    return !topVideoId ? undefined : await this.videoById(new EntityId(topVideoId));
+    return !topVideoId ? undefined : await this.videoById(createMock('EntityId', topVideoId));
   }
   }
 
 
   async featuredVideos (): Promise<VideoType[]> {
   async featuredVideos (): Promise<VideoType[]> {
     const content = await this.featuredContent();
     const content = await this.featuredContent();
     const videoIds = (content?.featuredVideos || []) as unknown as number[];
     const videoIds = (content?.featuredVideos || []) as unknown as number[];
     const videos = await Promise.all(videoIds.map((id) =>
     const videos = await Promise.all(videoIds.map((id) =>
-      this.videoById(new EntityId(id))));
+      this.videoById(createMock('EntityId', id))));
     return videos.filter(x => x !== undefined) as VideoType[];
     return videos.filter(x => x !== undefined) as VideoType[];
   }
   }
 
 
@@ -143,7 +143,7 @@ export abstract class MediaTransport extends Transport {
     const content = await this.featuredContent();
     const content = await this.featuredContent();
     const albumIds = (content?.featuredAlbums || []) as unknown as EntityId[];
     const albumIds = (content?.featuredAlbums || []) as unknown as EntityId[];
     const albums = await Promise.all(albumIds.map((id) =>
     const albums = await Promise.all(albumIds.map((id) =>
-      this.musicAlbumById(new EntityId(id))));
+      this.musicAlbumById(createMock('EntityId', id))));
     return albums.filter(x => x !== undefined) as MusicAlbumType[];
     return albums.filter(x => x !== undefined) as MusicAlbumType[];
   }
   }
 
 

+ 6 - 5
pioneer/packages/joy-media/src/upload/EditVideo.view.tsx

@@ -2,9 +2,8 @@ import React from 'react';
 import { RouteComponentProps } from 'react-router';
 import { RouteComponentProps } from 'react-router';
 import { MediaView } from '../MediaView';
 import { MediaView } from '../MediaView';
 import { OuterProps, EditForm } from './UploadVideo';
 import { OuterProps, EditForm } from './UploadVideo';
-import EntityId from '@joystream/types/versioned-store/EntityId';
-import { ChannelId } from '@joystream/types/content-working-group';
-import { JoyError } from '@polkadot/joy-utils/JoyStatus';
+import { JoyError } from '@polkadot/joy-utils/react/components';
+import { useApi } from '@polkadot/react-hooks';
 
 
 type Props = OuterProps;
 type Props = OuterProps;
 
 
@@ -27,10 +26,11 @@ type WithRouterProps = Props & RouteComponentProps<any>
 
 
 export const UploadVideoWithRouter = (props: WithRouterProps) => {
 export const UploadVideoWithRouter = (props: WithRouterProps) => {
   const { match: { params: { channelId } } } = props;
   const { match: { params: { channelId } } } = props;
+  const { api } = useApi();
 
 
   if (channelId) {
   if (channelId) {
     try {
     try {
-      return <EditVideoView {...props} channelId={new ChannelId(channelId)} />;
+      return <EditVideoView {...props} channelId={api.createType('ChannelId', channelId)} />;
     } catch (err) {
     } catch (err) {
       console.log('UploadVideoWithRouter failed:', err);
       console.log('UploadVideoWithRouter failed:', err);
     }
     }
@@ -41,10 +41,11 @@ export const UploadVideoWithRouter = (props: WithRouterProps) => {
 
 
 export const EditVideoWithRouter = (props: WithRouterProps) => {
 export const EditVideoWithRouter = (props: WithRouterProps) => {
   const { match: { params: { id } } } = props;
   const { match: { params: { id } } } = props;
+  const { api } = useApi();
 
 
   if (id) {
   if (id) {
     try {
     try {
-      return <EditVideoView {...props} id={new EntityId(id)} />;
+      return <EditVideoView {...props} id={api.createType('EntityId', id)} />;
     } catch (err) {
     } catch (err) {
       console.log('EditVideoWithRouter failed:', err);
       console.log('EditVideoWithRouter failed:', err);
     }
     }

+ 2 - 3
pioneer/packages/joy-media/src/upload/UploadAudio.tsx

@@ -3,9 +3,9 @@ import { Button, Tab } from 'semantic-ui-react';
 import { Form, withFormik } from 'formik';
 import { Form, withFormik } from 'formik';
 import { History } from 'history';
 import { History } from 'history';
 
 
-import TxButton from '@polkadot/joy-utils/TxButton';
+import { TxButton } from '@polkadot/joy-utils/react/components';
 import { ContentId } from '@joystream/types/media';
 import { ContentId } from '@joystream/types/media';
-import { onImageError } from '@polkadot/joy-utils/images';
+import { onImageError } from '../common/images';
 import { MusicTrackValidationSchema, MusicTrackType, MusicTrackClass as Fields, MusicTrackFormValues, MusicTrackToFormValues } from '../schemas/music/MusicTrack';
 import { MusicTrackValidationSchema, MusicTrackType, MusicTrackClass as Fields, MusicTrackFormValues, MusicTrackToFormValues } from '../schemas/music/MusicTrack';
 import { withMediaForm, MediaFormProps, datePlaceholder } from '../common/MediaForms';
 import { withMediaForm, MediaFormProps, datePlaceholder } from '../common/MediaForms';
 import EntityId from '@joystream/types/versioned-store/EntityId';
 import EntityId from '@joystream/types/versioned-store/EntityId';
@@ -113,7 +113,6 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
   const renderMainButton = () =>
   const renderMainButton = () =>
     <TxButton
     <TxButton
       type='submit'
       type='submit'
-      size='large'
       isDisabled={!dirty || isSubmitting}
       isDisabled={!dirty || isSubmitting}
       label={isNew
       label={isNew
         ? 'Publish'
         ? 'Publish'

+ 26 - 24
pioneer/packages/joy-media/src/upload/UploadVideo.tsx

@@ -4,9 +4,10 @@ import { Form, withFormik } from 'formik';
 import { History } from 'history';
 import { History } from 'history';
 import moment from 'moment';
 import moment from 'moment';
 
 
-import TxButton, { OnTxButtonClick } from '@polkadot/joy-utils/TxButton';
+import TxButton, { OnTxButtonClick } from '@polkadot/joy-utils/react/components/TxButton';
 import { ContentId } from '@joystream/types/media';
 import { ContentId } from '@joystream/types/media';
-import { onImageError } from '@polkadot/joy-utils/images';
+import { onImageError } from '../common/images';
+import { nonEmptyStr, filterSubstrateEventsAndExtractData } from '@polkadot/joy-utils/functions/misc';
 import { VideoValidationSchema, VideoType, VideoClass as Fields, VideoFormValues, VideoToFormValues, VideoCodec, VideoPropId } from '../schemas/video/Video';
 import { VideoValidationSchema, VideoType, VideoClass as Fields, VideoFormValues, VideoToFormValues, VideoCodec, VideoPropId } from '../schemas/video/Video';
 import { MediaFormProps, withMediaForm, datePlaceholder } from '../common/MediaForms';
 import { MediaFormProps, withMediaForm, datePlaceholder } from '../common/MediaForms';
 import EntityId from '@joystream/types/versioned-store/EntityId';
 import EntityId from '@joystream/types/versioned-store/EntityId';
@@ -14,23 +15,20 @@ import { MediaDropdownOptions } from '../common/MediaDropdownOptions';
 import { FormTabs } from '../common/FormTabs';
 import { FormTabs } from '../common/FormTabs';
 import { ChannelId } from '@joystream/types/content-working-group';
 import { ChannelId } from '@joystream/types/content-working-group';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelEntity } from '../entities/ChannelEntity';
-import { Credential } from '@joystream/types/common';
 import { Class, VecClassPropertyValue } from '@joystream/types/versioned-store';
 import { Class, VecClassPropertyValue } from '@joystream/types/versioned-store';
 import { TxCallback } from '@polkadot/react-components/Status/types';
 import { TxCallback } from '@polkadot/react-components/Status/types';
 import { SubmittableResult } from '@polkadot/api';
 import { SubmittableResult } from '@polkadot/api';
-import { nonEmptyStr, filterSubstrateEventsAndExtractData } from '@polkadot/joy-utils/index';
-import { u16, u32, bool, Option, Vec } from '@polkadot/types';
 import { isInternalProp } from '@joystream/types/versioned-store/EntityCodec';
 import { isInternalProp } from '@joystream/types/versioned-store/EntityCodec';
 import { MediaObjectCodec } from '../schemas/general/MediaObject';
 import { MediaObjectCodec } from '../schemas/general/MediaObject';
-import { Operation } from '@joystream/types/versioned-store/permissions/batching';
 import { OperationType } from '@joystream/types/versioned-store/permissions/batching/operation-types';
 import { OperationType } from '@joystream/types/versioned-store/permissions/batching/operation-types';
 import { ParametrizedEntity } from '@joystream/types/versioned-store/permissions/batching/parametrized-entity';
 import { ParametrizedEntity } from '@joystream/types/versioned-store/permissions/batching/parametrized-entity';
 import ParametrizedClassPropertyValue from '@joystream/types/versioned-store/permissions/batching/ParametrizedClassPropertyValue';
 import ParametrizedClassPropertyValue from '@joystream/types/versioned-store/permissions/batching/ParametrizedClassPropertyValue';
 import { ParametrizedPropertyValue } from '@joystream/types/versioned-store/permissions/batching/parametrized-property-value';
 import { ParametrizedPropertyValue } from '@joystream/types/versioned-store/permissions/batching/parametrized-property-value';
 import { ParameterizedClassPropertyValues } from '@joystream/types/versioned-store/permissions/batching/operations';
 import { ParameterizedClassPropertyValues } from '@joystream/types/versioned-store/permissions/batching/operations';
-import { useMyMembership } from '@polkadot/joy-utils/MyMembershipContext';
+import { useMyMembership } from '@polkadot/joy-utils/react/hooks';
 import { isAccountAChannelOwner } from '../channels/ChannelHelpers';
 import { isAccountAChannelOwner } from '../channels/ChannelHelpers';
-import { JoyError } from '@polkadot/joy-utils/JoyStatus';
+import { JoyError } from '@polkadot/joy-utils/react/components';
+import { useApi } from '@polkadot/react-hooks';
 
 
 /** Example: "2019-01-23" -> 1548201600 */
 /** Example: "2019-01-23" -> 1548201600 */
 function humanDateToUnixTs (humanFriendlyDate: string): number | undefined {
 function humanDateToUnixTs (humanFriendlyDate: string): number | undefined {
@@ -87,6 +85,7 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
   } = props;
   } = props;
 
 
   const { myAccountId } = useMyMembership();
   const { myAccountId } = useMyMembership();
+  const { api } = useApi();
 
 
   const { thumbnail } = values;
   const { thumbnail } = values;
 
 
@@ -103,9 +102,9 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
   }
   }
 
 
   // Next consts are used in tx params:
   // Next consts are used in tx params:
-  const with_credential = new Option<Credential>(Credential, new Credential(2));
-  const as_entity_maintainer = new bool(false);
-  const schema_id = new u16(0);
+  const with_credential = api.createType('Option<Credential>', 2);
+  const as_entity_maintainer = api.createType('bool', false);
+  const schema_id = api.createType('u16', 0);
 
 
   const entityCodec = new VideoCodec(entityClass);
   const entityCodec = new VideoCodec(entityClass);
   const mediaObjectCodec = new MediaObjectCodec(mediaObjectClass);
   const mediaObjectCodec = new MediaObjectCodec(mediaObjectClass);
@@ -155,15 +154,15 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
     return res;
     return res;
   };
   };
 
 
-  const indexOfCreateMediaObjectOperation = new u32(0);
+  const indexOfCreateMediaObjectOperation = api.createType('u32', 0);
 
 
-  const indexOfCreateVideoEntityOperation = new u32(2);
+  const indexOfCreateVideoEntityOperation = api.createType('u32', 2);
 
 
   const referToIdOfCreatedMediaObjectEntity = () =>
   const referToIdOfCreatedMediaObjectEntity = () =>
-    ParametrizedEntity.InternalEntityJustAdded(indexOfCreateMediaObjectOperation);
+    ParametrizedEntity.InternalEntityJustAdded(api.registry, indexOfCreateMediaObjectOperation);
 
 
   const referToIdOfCreatedVideoEntity = () =>
   const referToIdOfCreatedVideoEntity = () =>
-    ParametrizedEntity.InternalEntityJustAdded(indexOfCreateVideoEntityOperation);
+    ParametrizedEntity.InternalEntityJustAdded(api.registry, indexOfCreateVideoEntityOperation);
 
 
   const newlyCreatedMediaObjectProp = () => {
   const newlyCreatedMediaObjectProp = () => {
     const inClassIndexOfMediaObject = entityCodec.inClassIndexOfProp(Fields.object.id);
     const inClassIndexOfMediaObject = entityCodec.inClassIndexOfProp(Fields.object.id);
@@ -171,9 +170,10 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
       throw new Error('Cannot not find an in-class index of "object" prop on Video entity.');
       throw new Error('Cannot not find an in-class index of "object" prop on Video entity.');
     }
     }
 
 
-    return new ParametrizedClassPropertyValue({
-      in_class_index: new u16(inClassIndexOfMediaObject),
+    return api.createType('ParametrizedClassPropertyValue', {
+      in_class_index: inClassIndexOfMediaObject,
       value: ParametrizedPropertyValue.InternalEntityJustAdded(
       value: ParametrizedPropertyValue.InternalEntityJustAdded(
+        api.registry,
         indexOfCreateMediaObjectOperation
         indexOfCreateMediaObjectOperation
       )
       )
     });
     });
@@ -185,9 +185,9 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
   ): ParameterizedClassPropertyValues => {
   ): ParameterizedClassPropertyValues => {
     const parametrizedProps = props.map(p => {
     const parametrizedProps = props.map(p => {
       const { in_class_index, value } = p;
       const { in_class_index, value } = p;
-      return new ParametrizedClassPropertyValue({
+      return api.createType('ParametrizedClassPropertyValue', {
         in_class_index,
         in_class_index,
-        value: new ParametrizedPropertyValue({ PropertyValue: value })
+        value: api.createType('ParametrizedPropertyValue', { PropertyValue: value })
       });
       });
     });
     });
 
 
@@ -195,11 +195,11 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
       extra.forEach(x => parametrizedProps.push(x));
       extra.forEach(x => parametrizedProps.push(x));
     }
     }
 
 
-    return new ParameterizedClassPropertyValues(parametrizedProps);
+    return api.createType('Vec<ParametrizedClassPropertyValue>', parametrizedProps);
   };
   };
 
 
   const newEntityOperation = (operation_type: OperationType) => {
   const newEntityOperation = (operation_type: OperationType) => {
-    return new Operation({
+    return api.createType('Operation', {
       with_credential,
       with_credential,
       as_entity_maintainer,
       as_entity_maintainer,
       operation_type
       operation_type
@@ -209,6 +209,7 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
   const prepareTxParamsForCreateMediaObject = () => {
   const prepareTxParamsForCreateMediaObject = () => {
     return newEntityOperation(
     return newEntityOperation(
       OperationType.CreateEntity(
       OperationType.CreateEntity(
+        api.registry,
         mediaObjectClass.id
         mediaObjectClass.id
       )
       )
     );
     );
@@ -224,6 +225,7 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
 
 
     return newEntityOperation(
     return newEntityOperation(
       OperationType.AddSchemaSupportToEntity(
       OperationType.AddSchemaSupportToEntity(
+        api.registry,
         referToIdOfCreatedMediaObjectEntity(),
         referToIdOfCreatedMediaObjectEntity(),
         schema_id,
         schema_id,
         propValues
         propValues
@@ -234,6 +236,7 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
   const prepareTxParamsForCreateEntity = () => {
   const prepareTxParamsForCreateEntity = () => {
     return newEntityOperation(
     return newEntityOperation(
       OperationType.CreateEntity(
       OperationType.CreateEntity(
+        api.registry,
         entityClass.id
         entityClass.id
       )
       )
     );
     );
@@ -249,6 +252,7 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
 
 
     return newEntityOperation(
     return newEntityOperation(
       OperationType.AddSchemaSupportToEntity(
       OperationType.AddSchemaSupportToEntity(
+        api.registry,
         referToIdOfCreatedVideoEntity(),
         referToIdOfCreatedVideoEntity(),
         schema_id,
         schema_id,
         propValues
         propValues
@@ -272,7 +276,7 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
     // Use for debug:
     // Use for debug:
     // console.log('Batch entity operations:', ops)
     // console.log('Batch entity operations:', ops)
 
 
-    return [new Vec(Operation, ops)];
+    return [api.createType('Vec<Operation>', ops)];
   };
   };
 
 
   const buildUpdateEntityTxParams = () => {
   const buildUpdateEntityTxParams = () => {
@@ -376,7 +380,6 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
   const renderTransactionButton = () =>
   const renderTransactionButton = () =>
     <TxButton
     <TxButton
       type='submit'
       type='submit'
-      size='large'
       isDisabled={!canSubmitTx()}
       isDisabled={!canSubmitTx()}
       label='Publish video'
       label='Publish video'
       tx='versionedStorePermissions.transaction'
       tx='versionedStorePermissions.transaction'
@@ -389,7 +392,6 @@ const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
   const renderUpdateEntityButton = () =>
   const renderUpdateEntityButton = () =>
     <TxButton
     <TxButton
       type='submit'
       type='submit'
-      size='large'
       isDisabled={!canSubmitTx()}
       isDisabled={!canSubmitTx()}
       label='Update video'
       label='Update video'
       tx='versionedStorePermissions.updateEntityPropertyValues'
       tx='versionedStorePermissions.updateEntityPropertyValues'

+ 4 - 2
pioneer/packages/joy-media/src/video/PlayVideo.tsx

@@ -12,7 +12,8 @@ import { printExplicit, printReleaseDate, printLanguage } from '../entities/Enti
 import { MediaObjectType } from '../schemas/general/MediaObject';
 import { MediaObjectType } from '../schemas/general/MediaObject';
 import { MediaPlayerWithResolver } from '../common/MediaPlayerWithResolver';
 import { MediaPlayerWithResolver } from '../common/MediaPlayerWithResolver';
 import { ContentId } from '@joystream/types/media';
 import { ContentId } from '@joystream/types/media';
-import { JoyError } from '@polkadot/joy-utils/JoyStatus';
+import { JoyError } from '@polkadot/joy-utils/react/components';
+import { useApi } from '@polkadot/react-hooks';
 
 
 export type PlayVideoProps = {
 export type PlayVideoProps = {
   channel?: ChannelEntity;
   channel?: ChannelEntity;
@@ -36,6 +37,7 @@ function VertialListOfVideoPreviews (props: ListOfVideoPreviewProps) {
 
 
 export function PlayVideo (props: PlayVideoProps) {
 export function PlayVideo (props: PlayVideoProps) {
   const { channel, mediaObject, video, moreChannelVideos = [], featuredVideos = [] } = props;
   const { channel, mediaObject, video, moreChannelVideos = [], featuredVideos = [] } = props;
+  const { api } = useApi();
 
 
   if (!mediaObject || !video) {
   if (!mediaObject || !video) {
     return <JoyError title={'Video was not found'} />;
     return <JoyError title={'Video was not found'} />;
@@ -80,7 +82,7 @@ export function PlayVideo (props: PlayVideoProps) {
   // TODO show video only to its owner, if the video is not public.
   // TODO show video only to its owner, if the video is not public.
   // see isPublicVideo() function.
   // see isPublicVideo() function.
 
 
-  const contentId = ContentId.decode(mediaObject.value);
+  const contentId = ContentId.decode(api.registry, mediaObject.value);
 
 
   // console.log('PlayVideo: props', props)
   // console.log('PlayVideo: props', props)
 
 

+ 6 - 6
pioneer/packages/joy-media/src/video/PlayVideo.view.tsx

@@ -2,9 +2,8 @@ import React from 'react';
 import { RouteComponentProps } from 'react-router';
 import { RouteComponentProps } from 'react-router';
 import { MediaView } from '../MediaView';
 import { MediaView } from '../MediaView';
 import { PlayVideoProps, PlayVideo } from './PlayVideo';
 import { PlayVideoProps, PlayVideo } from './PlayVideo';
-import { ChannelId } from '@joystream/types/content-working-group';
-import { EntityId } from '@joystream/types/versioned-store';
-import { JoyError } from '@polkadot/joy-utils/JoyStatus';
+import { JoyError } from '@polkadot/joy-utils/react/components';
+import { useApi } from '@polkadot/react-hooks';
 
 
 type Props = PlayVideoProps;
 type Props = PlayVideoProps;
 
 
@@ -12,12 +11,12 @@ export const PlayVideoView = MediaView<Props>({
   component: PlayVideo,
   component: PlayVideo,
   triggers: ['id'],
   triggers: ['id'],
   resolveProps: async (props) => {
   resolveProps: async (props) => {
-    const { transport, id } = props;
+    const { transport, api, id } = props;
 
 
     const video = await transport.videoById(id);
     const video = await transport.videoById(id);
     if (!video) return {};
     if (!video) return {};
 
 
-    const channelId = new ChannelId(video.channelId);
+    const channelId = api.createType('ChannelId', video.channelId);
     const channel = await transport.channelById(channelId);
     const channel = await transport.channelById(channelId);
     const moreChannelVideos = (await transport.videosByChannelId(channelId, 5, x => x.id !== video.id));
     const moreChannelVideos = (await transport.videosByChannelId(channelId, 5, x => x.id !== video.id));
     const featuredVideos = await transport.featuredVideos();
     const featuredVideos = await transport.featuredVideos();
@@ -29,10 +28,11 @@ export const PlayVideoView = MediaView<Props>({
 
 
 export const PlayVideoWithRouter = (props: Props & RouteComponentProps<any>) => {
 export const PlayVideoWithRouter = (props: Props & RouteComponentProps<any>) => {
   const { match: { params: { id } } } = props;
   const { match: { params: { id } } } = props;
+  const { api } = useApi();
 
 
   if (id) {
   if (id) {
     try {
     try {
-      return <PlayVideoView {...props} id={new EntityId(id)} />;
+      return <PlayVideoView {...props} id={api.createType('EntityId', id)} />;
     } catch (err) {
     } catch (err) {
       console.log('PlayVideoWithRouter failed:', err);
       console.log('PlayVideoWithRouter failed:', err);
     }
     }

+ 2 - 2
pioneer/packages/joy-media/src/video/VideoPreview.tsx

@@ -2,7 +2,7 @@ import React, { CSSProperties } from 'react';
 import { Link } from 'react-router-dom';
 import { Link } from 'react-router-dom';
 import { BgImg } from '../common/BgImg';
 import { BgImg } from '../common/BgImg';
 import { VideoType } from '../schemas/video/Video';
 import { VideoType } from '../schemas/video/Video';
-import { useMyMembership } from '@polkadot/joy-utils/MyMembershipContext';
+import { useMyMembership } from '@polkadot/joy-utils/react/hooks';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { ChannelEntity } from '../entities/ChannelEntity';
 import { isAccountAChannelOwner } from '../channels/ChannelHelpers';
 import { isAccountAChannelOwner } from '../channels/ChannelHelpers';
 import { ChannelAvatarAndName } from '../channels/ChannelAvatarAndName';
 import { ChannelAvatarAndName } from '../channels/ChannelAvatarAndName';
@@ -64,7 +64,7 @@ export function VideoPreview (props: VideoPreviewProps) {
         }
         }
 
 
         {iAmOwner &&
         {iAmOwner &&
-          <div>
+          <div style={{ marginTop: '0.5em' }}>
             <Link to={`/media/videos/${id}/edit`} className='ui button basic small'>
             <Link to={`/media/videos/${id}/edit`} className='ui button basic small'>
               <i className='icon pencil' />
               <i className='icon pencil' />
               Edit
               Edit

+ 4 - 4
pioneer/packages/old-apps/react-components/src/InputFileAsync.tsx → pioneer/packages/joy-utils/src/react/components/InputFileAsync.tsx

@@ -3,16 +3,16 @@
 // of the Apache-2.0 license. See the LICENSE file for details.
 // of the Apache-2.0 license. See the LICENSE file for details.
 
 
 import { WithTranslation } from 'react-i18next';
 import { WithTranslation } from 'react-i18next';
-import { BareProps } from './types';
+import { BareProps } from '@polkadot/react-components/types';
 
 
 import React, { useState, createRef } from 'react';
 import React, { useState, createRef } from 'react';
 import Dropzone, { DropzoneRef } from 'react-dropzone';
 import Dropzone, { DropzoneRef } from 'react-dropzone';
 import styled from 'styled-components';
 import styled from 'styled-components';
 import { formatNumber } from '@polkadot/util';
 import { formatNumber } from '@polkadot/util';
 
 
-import { classes } from './util';
-import Labelled from './Labelled';
-import translate from './translate';
+import { classes } from '@polkadot/react-components/util';
+import Labelled from '@polkadot/react-components/Labelled';
+import translate from '@polkadot/react-components/translate';
 
 
 interface Props extends BareProps, WithTranslation {
 interface Props extends BareProps, WithTranslation {
   // Reference Example Usage: https://github.com/react-dropzone/react-dropzone/tree/master/examples/Accept
   // Reference Example Usage: https://github.com/react-dropzone/react-dropzone/tree/master/examples/Accept

+ 1 - 1
pioneer/packages/joy-utils-old/src/JoyStatus.tsx → pioneer/packages/joy-utils/src/react/components/JoyStatus.tsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import React from 'react';
 import { Message } from 'semantic-ui-react';
 import { Message } from 'semantic-ui-react';
-import { nonEmptyStr } from '.';
+import { nonEmptyStr } from '../../functions/misc';
 
 
 type BaseProps = {
 type BaseProps = {
   title?: React.ReactNode;
   title?: React.ReactNode;

+ 0 - 0
pioneer/packages/joy-utils-old/src/Pluralize.tsx → pioneer/packages/joy-utils/src/react/components/Pluralize.tsx


+ 4 - 1
pioneer/packages/joy-utils/src/react/components/index.tsx

@@ -2,10 +2,13 @@ export { default as Section } from './Section';
 export { default as TxButton } from './TxButton';
 export { default as TxButton } from './TxButton';
 export { MutedSpan, MutedDiv } from './MutedText';
 export { MutedSpan, MutedDiv } from './MutedText';
 export { FlexCenter } from './FlexCenter';
 export { FlexCenter } from './FlexCenter';
-export { default as PromiseComponent } from './PromiseComponent';
+export { default as PromiseComponent, Error, Loading } from './PromiseComponent';
 export { default as MemberByAccountPreview } from './MemberByAccountPreview';
 export { default as MemberByAccountPreview } from './MemberByAccountPreview';
 export { default as MemberProfilePreview } from './MemberProfilePreview';
 export { default as MemberProfilePreview } from './MemberProfilePreview';
 export { default as MembersDropdown } from './MembersDropdown';
 export { default as MembersDropdown } from './MembersDropdown';
 export { default as InputStake } from './InputStake';
 export { default as InputStake } from './InputStake';
 export { ApplicationsDetails, ApplicationsDetailsByIds } from './working-groups/ApplicationDetails';
 export { ApplicationsDetails, ApplicationsDetailsByIds } from './working-groups/ApplicationDetails';
 export { LeadInfo, LeadInfoFromId } from './working-groups/LeadInfo';
 export { LeadInfo, LeadInfoFromId } from './working-groups/LeadInfo';
+export { JoyStatus, JoyError, JoyInfo, JoySuccess, JoyWarn } from './JoyStatus';
+export { Pluralize } from './Pluralize';
+export { default as InputFileAsync } from './InputFileAsync';

+ 111 - 6
pioneer/packages/joy-utils/src/react/hocs/accounts.tsx

@@ -7,11 +7,17 @@ import { withCalls, withMulti, withObservable, ApiContext } from '@polkadot/reac
 import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
 import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
 
 
 import { MemberId, Membership } from '@joystream/types/members';
 import { MemberId, Membership } from '@joystream/types/members';
-import { LeadId } from '@joystream/types/content-working-group';
+import { LeadId, Lead } from '@joystream/types/content-working-group';
 
 
 import { queryMembershipToProp } from '@polkadot/joy-members/utils';
 import { queryMembershipToProp } from '@polkadot/joy-members/utils';
 import useMyAccount from '../hooks/useMyAccount';
 import useMyAccount from '../hooks/useMyAccount';
 import { componentName } from '../helpers';
 import { componentName } from '../helpers';
+import { queryToProp } from '@polkadot/joy-utils/functions/misc';
+import { entriesByIds } from '@polkadot/joy-utils/transport/base';
+import { CuratorId, Curator } from '@joystream/types/content-working-group';
+import { useApi } from '@polkadot/react-hooks';
+import usePromise from '../hooks/usePromise';
+import { Error } from '../components/PromiseComponent';
 
 
 export type MyAddressProps = {
 export type MyAddressProps = {
   myAddress?: string;
   myAddress?: string;
@@ -27,10 +33,9 @@ export type MyAccountProps = MyAddressProps & {
   myMembership?: Membership | null;
   myMembership?: Membership | null;
 
 
   // Content Working Group
   // Content Working Group
-  curatorEntries?: any; // entire linked_map: CuratorId => Curator
   isLeadSet?: Option<LeadId>;
   isLeadSet?: Option<LeadId>;
   contentLeadId?: LeadId;
   contentLeadId?: LeadId;
-  contentLeadEntry?: any; // linked_map value
+  contentLead?: Lead; // linked_map value
 
 
   curationActor?: any;
   curationActor?: any;
   allAccounts?: SubjectInfo;
   allAccounts?: SubjectInfo;
@@ -103,6 +108,106 @@ function resolveMyProfile<P extends { myMembership?: Membership | null }> (Compo
   return ResultComponent;
   return ResultComponent;
 }
 }
 
 
+/* Content Working Group */
+function resolveLead<P extends MyAccountProps> (Component: React.ComponentType<P>) {
+  const ResultComponent: React.FunctionComponent<P> = (props: P) => {
+    const { isLeadSet } = props;
+
+    const newProps = {
+      contentLeadId: isLeadSet?.unwrapOr(undefined)
+    };
+
+    return <Component {...props} {...newProps} />;
+  };
+  ResultComponent.displayName = `resolveLead(${componentName(Component)})`;
+  return ResultComponent;
+}
+
+const resolveLeadEntry = withCalls<MyAccountProps>(
+  queryToProp('query.contentWorkingGroup.leadById', { propName: 'contentLead', paramName: 'contentLeadId' })
+);
+
+const withContentWorkingGroupDetails = withCalls<MyAccountProps>(
+  queryToProp('query.contentWorkingGroup.currentLeadId', { propName: 'isLeadSet' })
+);
+
+const withContentWorkingGroup = <P extends MyAccountProps>(Component: React.ComponentType<P>) =>
+  withMulti(Component, withContentWorkingGroupDetails, resolveLead, resolveLeadEntry);
+
+
+function withCurationActor<P extends MyAccountProps> (Component: React.ComponentType<P>) {
+  const ResultComponent: React.FunctionComponent<P> = (props: P) => {
+    const {
+      myAccountId,
+      isLeadSet,
+      contentLead,
+      allAccounts
+    } = props;
+    const { isApiReady, api } = useApi();
+    const [ curatorEntries, curatorsError, curatorsLoading ] = usePromise<[CuratorId, Curator][]>(
+      () => isApiReady
+        ? entriesByIds<CuratorId, Curator>(api.query.contentWorkingGroup.curatorById)
+        : new Promise(resolve => resolve([])),
+      [],
+      [isApiReady]
+    );
+
+    if (curatorsError) {
+      return <Error error={curatorsError} />;
+    }
+
+    if (!isApiReady || curatorsLoading || !myAccountId || !isLeadSet || !allAccounts) {
+      return <Component {...props} />;
+    }
+
+    const lead = isLeadSet.isSome && contentLead?.stage.isOfType('Active') ? contentLead : null;
+
+    const curationActorByAccount = (accountId: AccountId | string) => {
+      if (lead && lead.role_account.toString() === accountId.toString()) {
+        return api.createType('CurationActor', { Lead: null });
+      }
+
+      const matchingCuratorEntry = curatorEntries.find(([id, curator]) =>
+        curator.is_active && accountId.toString() === curator.role_account.toString()
+      );
+
+      return matchingCuratorEntry
+        ? api.createType('CurationActor', {
+          Curator: matchingCuratorEntry[0]
+        })
+        : null;
+    };
+
+    // First priority - currently selected account
+    let actor = curationActorByAccount(myAccountId);
+    let actorKey: AccountId | null = myAccountId;
+    // Second priority - check other keys and find best role
+    // TODO: Prioritize current member?
+    // TODO: Perhaps just don't do that at all and force the user to select the correct key to avoid confision?
+    if (!actor) {
+      const allActorsWithKeys = Object.keys(allAccounts).map(accKey => ({
+        actor: curationActorByAccount(allAccounts[accKey].json.address),
+        key: api.createType('AccountId', allAccounts[accKey].json.address)
+      }));
+      let actorWithKey = allActorsWithKeys.find(({ actor }) => actor?.isOfType('Lead'));
+      if (!actorWithKey) {
+        actorWithKey = allActorsWithKeys.find(({ actor }) => actor?.isOfType('Curator'));
+      }
+      actor = actorWithKey?.actor || null;
+      actorKey = actorWithKey?.key || null;
+    }
+
+    if (actor && actorKey) {
+      return <Component {...props} curationActor={[actor, actorKey]} />;
+    } else {
+      // we don't have any key that can fulfill a curation action
+      return <Component {...props} />;
+    }
+  };
+  ResultComponent.displayName = `withCurationActor(${componentName(Component)})`;
+  return ResultComponent;
+}
+
 const withMyProfileCall = withCalls<MyAccountProps>(queryMembershipToProp('membershipById', {
 const withMyProfileCall = withCalls<MyAccountProps>(queryMembershipToProp('membershipById', {
   paramName: 'myMemberId',
   paramName: 'myMemberId',
   propName: 'myMembership'
   propName: 'myMembership'
@@ -118,7 +223,7 @@ export const withMyAccount = <P extends MyAccountProps>(Component: React.Compone
     withMyAddress,
     withMyAddress,
     withMyMemberIds,
     withMyMemberIds,
     withMyMembership,
     withMyMembership,
-    withMyProfile
-    // withContentWorkingGroup,
-    // withCurationActor
+    withMyProfile,
+    withContentWorkingGroup,
+    withCurationActor
   );
   );

+ 1 - 30
pioneer/packages/joy-utils/src/react/hocs/guards.tsx

@@ -2,39 +2,10 @@ import React from 'react';
 import { Message } from 'semantic-ui-react';
 import { Message } from 'semantic-ui-react';
 import { Link } from 'react-router-dom';
 import { Link } from 'react-router-dom';
 
 
-import { AccountId } from '@polkadot/types/interfaces';
-import { Vec, Option } from '@polkadot/types';
 import { withMulti } from '@polkadot/react-api/index';
 import { withMulti } from '@polkadot/react-api/index';
-import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
-
-import { MemberId, Membership } from '@joystream/types/members';
-import { LeadId } from '@joystream/types/content-working-group';
 import { useMyMembership } from '../hooks';
 import { useMyMembership } from '../hooks';
 import { componentName } from '../helpers';
 import { componentName } from '../helpers';
-import { withMyAccount } from './accounts';
-
-export type MyAddressProps = {
-  myAddress?: string;
-};
-
-export type MyAccountProps = MyAddressProps & {
-  myAccountId?: AccountId;
-  myMemberId?: MemberId;
-  memberIdsByRootAccountId?: Vec<MemberId>;
-  memberIdsByControllerAccountId?: Vec<MemberId>;
-  myMemberIdChecked?: boolean;
-  iAmMember?: boolean;
-  myMembership?: Membership | null;
-
-  // Content Working Group
-  curatorEntries?: any; // entire linked_map: CuratorId => Curator
-  isLeadSet?: Option<LeadId>;
-  contentLeadId?: LeadId;
-  contentLeadEntry?: any; // linked_map value
-
-  curationActor?: any;
-  allAccounts?: SubjectInfo;
-};
+import { withMyAccount, MyAccountProps } from './accounts';
 
 
 export function MembershipRequired<P extends Record<string, unknown>> (Component: React.ComponentType<P>): React.ComponentType<P> {
 export function MembershipRequired<P extends Record<string, unknown>> (Component: React.ComponentType<P>): React.ComponentType<P> {
   const ResultComponent: React.FunctionComponent<P> = (props: P) => {
   const ResultComponent: React.FunctionComponent<P> = (props: P) => {

+ 1 - 1
pioneer/packages/joy-utils/src/react/hooks/proposals/useProposalSubscription.tsx

@@ -1,5 +1,5 @@
 import { useState, useEffect } from 'react';
 import { useState, useEffect } from 'react';
-import { useTransport } from '../';
+import useTransport from '../useTransport';
 import { ProposalId } from '@joystream/types/proposals';
 import { ProposalId } from '@joystream/types/proposals';
 import { ParsedProposal } from '@polkadot/joy-utils/types/proposals';
 import { ParsedProposal } from '@polkadot/joy-utils/types/proposals';
 import { normalizeError } from '@polkadot/joy-utils/functions/misc';
 import { normalizeError } from '@polkadot/joy-utils/functions/misc';

+ 4 - 1
pioneer/packages/joy-utils-old/src/SimpleCache.ts → pioneer/packages/joy-utils/src/transport/SimpleCache.ts

@@ -1,5 +1,8 @@
 import BN from 'bn.js';
 import BN from 'bn.js';
-import { IdLike, HasId } from './IdLike';
+
+export type IdLike = { toString: () => string } | number
+export type HasId = { id: IdLike }
+export type MayHaveId = { id?: IdLike }
 
 
 type LoadObjectsByIdsFn<Id extends IdLike, Obj extends HasId> =
 type LoadObjectsByIdsFn<Id extends IdLike, Obj extends HasId> =
   (ids: Id[]) => Promise<Obj[]>
   (ids: Id[]) => Promise<Obj[]>

+ 16 - 14
pioneer/packages/joy-utils/src/transport/base.ts

@@ -4,7 +4,21 @@ import { Codec, CodecArg } from '@polkadot/types/types';
 import { QueryableStorageEntry } from '@polkadot/api/types/storage';
 import { QueryableStorageEntry } from '@polkadot/api/types/storage';
 import { APIQueryCache } from './APIQueryCache';
 import { APIQueryCache } from './APIQueryCache';
 
 
-export default abstract class BaseTransport {
+export async function entriesByIds<IDType extends UInt, ValueType extends Codec> (
+  apiMethod: QueryableStorageEntry<'promise'>,
+  firstKey?: CodecArg // First key in case of double maps
+): Promise<[IDType, ValueType][]> {
+  const entries: [IDType, ValueType][] = (await apiMethod.entries<ValueType>(firstKey))
+    .map(([storageKey, value]) => ([
+      // If double-map (first key is provided), we map entries by second key
+      storageKey.args[firstKey !== undefined ? 1 : 0] as IDType,
+      value
+    ]));
+
+  return entries.sort((a, b) => a[0].toNumber() - b[0].toNumber());
+}
+
+export default class BaseTransport {
   protected api: ApiPromise;
   protected api: ApiPromise;
   protected cacheApi: APIQueryCache;
   protected cacheApi: APIQueryCache;
 
 
@@ -67,17 +81,5 @@ export default abstract class BaseTransport {
     return this.api.query[module][method];
     return this.api.query[module][method];
   }
   }
 
 
-  protected async entriesByIds<IDType extends UInt, ValueType extends Codec> (
-    apiMethod: QueryableStorageEntry<'promise'>,
-    firstKey?: CodecArg // First key in case of double maps
-  ): Promise<[IDType, ValueType][]> {
-    const entries: [IDType, ValueType][] = (await apiMethod.entries<ValueType>(firstKey))
-      .map(([storageKey, value]) => ([
-        // If double-map (first key is provided), we map entries by second key
-        storageKey.args[firstKey !== undefined ? 1 : 0] as IDType,
-        value
-      ]));
-
-    return entries.sort((a, b) => a[0].toNumber() - b[0].toNumber());
-  }
+  protected entriesByIds = entriesByIds
 }
 }

+ 14 - 12
pioneer/packages/joy-utils/src/transport/mock/base.ts

@@ -1,15 +1,17 @@
-export default abstract class BaseTransport {
-  protected promise<T> (value: T, timeout?: number): Promise<T> {
-    return new Promise<T>((resolve, reject) => {
-      if (timeout) {
-        (new Promise((resolve) => setTimeout(resolve, timeout)))
-          .then(() => resolve(value))
-          .catch((e) => { throw e; });
-      } else {
-        resolve(value);
-      }
-    });
-  }
+export function mockPromise<T> (value: T, timeout?: number): Promise<T> {
+  return new Promise<T>((resolve, reject) => {
+    if (timeout) {
+      (new Promise((resolve) => setTimeout(resolve, timeout)))
+        .then(() => resolve(value))
+        .catch((e) => { throw e; });
+    } else {
+      resolve(value);
+    }
+  });
+}
+
+export default class BaseTransport {
+  protected promise = mockPromise
 
 
   protected simulateApiResponse<T> (value: T): Promise<T> {
   protected simulateApiResponse<T> (value: T): Promise<T> {
     return this.promise<T>(value, this.randomTimeout());
     return this.promise<T>(value, this.randomTimeout());

+ 4 - 0
pioneer/packages/joy-utils/src/transport/workingGroups.ts

@@ -153,4 +153,8 @@ export default class WorkingGroupsTransport extends BaseTransport {
     return (await this.openingApplications(group, wgOpeningId))
     return (await this.openingApplications(group, wgOpeningId))
       .filter((a) => a.stage.isOfType('Active'));
       .filter((a) => a.stage.isOfType('Active'));
   }
   }
+
+  async allWorkers (group: WorkingGroupKey) {
+    return this.entriesByIds<WorkerId, Worker>(this.apiQueryByGroup(group).workerById);
+  }
 }
 }

+ 0 - 0
pioneer/packages/joy-utils-old/src/ValidationConstraint.ts → pioneer/packages/joy-utils/src/types/ValidationConstraint.ts


+ 0 - 17
pioneer/packages/old-apps/apps-routing/src/joy-media.ts

@@ -1,17 +0,0 @@
-import { Routes } from './types';
-
-import Media from '@polkadot/joy-media/index';
-
-export default ([
-  {
-    Component: Media,
-    display: {
-      needsApi: []
-    },
-    i18n: {
-      defaultValue: 'Media'
-    },
-    icon: 'play circle outline',
-    name: 'media'
-  }
-] as Routes);

+ 0 - 1
pioneer/packages/old-apps/apps/src/aplayer.d.ts

@@ -1 +0,0 @@
-declare module 'react-aplayer';

+ 0 - 1
pioneer/packages/old-apps/apps/src/dplayer.d.ts

@@ -1 +0,0 @@
-declare module 'react-dplayer';

+ 5 - 0
pioneer/packages/react-components/src/styles/joystream.ts

@@ -131,6 +131,11 @@ export default css`
     color: #3b83c0;
     color: #3b83c0;
   }
   }
 
 
+  /* Main apps bg */
+  .apps-Main {
+    background: rgba(250,250,250);
+  }
+
   /* Remove IdentityIcon border (not working well for members list) */
   /* Remove IdentityIcon border (not working well for members list) */
   .ui--IdentityIcon {
   .ui--IdentityIcon {
     border: none !important;
     border: none !important;

+ 4 - 1
pioneer/tsconfig.json

@@ -6,7 +6,6 @@
     "packages/old-apps/**",
     "packages/old-apps/**",
     "packages/joy-forum/**/*",
     "packages/joy-forum/**/*",
     "packages/joy-help/**/*",
     "packages/joy-help/**/*",
-    "packages/joy-media/**/*",
     "packages/joy-settings/**/*",
     "packages/joy-settings/**/*",
     "packages/joy-utils-old/**/*"
     "packages/joy-utils-old/**/*"
   ],
   ],
@@ -17,6 +16,8 @@
     "resolveJsonModule": true,
     "resolveJsonModule": true,
     "baseUrl": ".",
     "baseUrl": ".",
     "paths": {
     "paths": {
+      "@joystream/types/": [ "../types/src/" ],
+      "@joystream/types/*": [ "../types/src/*" ],
       "@polkadot/types/augment": [ "../types/augment-codec/augment-types.ts" ],
       "@polkadot/types/augment": [ "../types/augment-codec/augment-types.ts" ],
       "@polkadot/joy-election/": [ "packages/joy-election/src/" ],
       "@polkadot/joy-election/": [ "packages/joy-election/src/" ],
       "@polkadot/joy-election/*": [ "packages/joy-election/src/*" ],
       "@polkadot/joy-election/*": [ "packages/joy-election/src/*" ],
@@ -30,6 +31,8 @@
       "@polkadot/joy-roles/*": [ "packages/joy-roles/src/*" ],
       "@polkadot/joy-roles/*": [ "packages/joy-roles/src/*" ],
       "@polkadot/joy-utils/": [ "packages/joy-utils/src/" ],
       "@polkadot/joy-utils/": [ "packages/joy-utils/src/" ],
       "@polkadot/joy-utils/*": [ "packages/joy-utils/src/*" ],
       "@polkadot/joy-utils/*": [ "packages/joy-utils/src/*" ],
+      "@polkadot/joy-media/": [ "packages/joy-media/src/" ],
+      "@polkadot/joy-media/*": [ "packages/joy-media/src/*" ],
       "@polkadot/apps/*": ["packages/apps/src/*"],
       "@polkadot/apps/*": ["packages/apps/src/*"],
       "@polkadot/apps": ["packages/apps/src"],
       "@polkadot/apps": ["packages/apps/src"],
       "@polkadot/apps-config/*": [ "packages/apps-config/src/*" ],
       "@polkadot/apps-config/*": [ "packages/apps-config/src/*" ],

+ 26 - 26
types/augment-codec/augment-types.ts

@@ -11,9 +11,9 @@ import { Stake as Stake, StakingStatus as StakingStatus, Staked as Staked, Stake
 import { Mint as Mint, NextAdjustment as NextAdjustment, AdjustOnInterval as AdjustOnInterval, AdjustCapacityBy as AdjustCapacityBy } from '../mint'
 import { Mint as Mint, NextAdjustment as NextAdjustment, AdjustOnInterval as AdjustOnInterval, AdjustCapacityBy as AdjustCapacityBy } from '../mint'
 import { Recipient as Recipient, RewardRelationship as RewardRelationship } from '../recurring-rewards'
 import { Recipient as Recipient, RewardRelationship as RewardRelationship } from '../recurring-rewards'
 import { Application as Application, ApplicationStage as ApplicationStage, ActivateOpeningAt as ActivateOpeningAt, ApplicationRationingPolicy as ApplicationRationingPolicy, OpeningStage as OpeningStage, StakingPolicy as StakingPolicy, Opening as Opening, WaitingToBeingOpeningStageVariant as WaitingToBeingOpeningStageVariant, ActiveOpeningStageVariant as ActiveOpeningStageVariant, ActiveOpeningStage as ActiveOpeningStage, AcceptingApplications as AcceptingApplications, ReviewPeriod as ReviewPeriod, Deactivated as Deactivated, OpeningDeactivationCause as OpeningDeactivationCause, InactiveApplicationStage as InactiveApplicationStage, UnstakingApplicationStage as UnstakingApplicationStage, ApplicationDeactivationCause as ApplicationDeactivationCause, StakingAmountLimitMode as StakingAmountLimitMode } from '../hiring'
 import { Application as Application, ApplicationStage as ApplicationStage, ActivateOpeningAt as ActivateOpeningAt, ApplicationRationingPolicy as ApplicationRationingPolicy, OpeningStage as OpeningStage, StakingPolicy as StakingPolicy, Opening as Opening, WaitingToBeingOpeningStageVariant as WaitingToBeingOpeningStageVariant, ActiveOpeningStageVariant as ActiveOpeningStageVariant, ActiveOpeningStage as ActiveOpeningStage, AcceptingApplications as AcceptingApplications, ReviewPeriod as ReviewPeriod, Deactivated as Deactivated, OpeningDeactivationCause as OpeningDeactivationCause, InactiveApplicationStage as InactiveApplicationStage, UnstakingApplicationStage as UnstakingApplicationStage, ApplicationDeactivationCause as ApplicationDeactivationCause, StakingAmountLimitMode as StakingAmountLimitMode } from '../hiring'
-import { Class as Class, Entity as Entity, ClassSchema as ClassSchema, Property as Property, PropertyType as PropertyType, PropertyValue as PropertyValue, ClassPropertyValue as ClassPropertyValue } from '../versioned-store'
+import { ClassId as ClassId, EntityId as EntityId, Class as Class, Entity as Entity, ClassSchema as ClassSchema, Property as Property, PropertyType as PropertyType, PropertyValue as PropertyValue, ClassPropertyValue as ClassPropertyValue } from '../versioned-store'
 import { EntityPermissions as EntityPermissions, ReferenceConstraint as ReferenceConstraint, ClassPermissionsType as ClassPermissionsType, Operation as Operation, OperationType as OperationType, CreateEntity as CreateEntity, UpdatePropertyValues as UpdatePropertyValues, AddSchemaSupportToEntity as AddSchemaSupportToEntity, ParametrizedEntity as ParametrizedEntity, ParametrizedClassPropertyValue as ParametrizedClassPropertyValue, ParametrizedPropertyValue as ParametrizedPropertyValue, PropertyOfClass as PropertyOfClass } from '../versioned-store/permissions'
 import { EntityPermissions as EntityPermissions, ReferenceConstraint as ReferenceConstraint, ClassPermissionsType as ClassPermissionsType, Operation as Operation, OperationType as OperationType, CreateEntity as CreateEntity, UpdatePropertyValues as UpdatePropertyValues, AddSchemaSupportToEntity as AddSchemaSupportToEntity, ParametrizedEntity as ParametrizedEntity, ParametrizedClassPropertyValue as ParametrizedClassPropertyValue, ParametrizedPropertyValue as ParametrizedPropertyValue, PropertyOfClass as PropertyOfClass } from '../versioned-store/permissions'
-import { OptionalText as OptionalText, Channel as Channel, ChannelContentType as ChannelContentType, ChannelCurationStatus as ChannelCurationStatus, ChannelPublicationStatus as ChannelPublicationStatus, CurationActor as CurationActor, Curator as Curator, CuratorApplication as CuratorApplication, CuratorOpening as CuratorOpening, Lead as Lead, OpeningPolicyCommitment as OpeningPolicyCommitment, Principal as Principal, WorkingGroupUnstaker as WorkingGroupUnstaker, CuratorApplicationIdToCuratorIdMap as CuratorApplicationIdToCuratorIdMap, CuratorApplicationIdSet as CuratorApplicationIdSet, CuratorRoleStakeProfile as CuratorRoleStakeProfile, CuratorRoleStage as CuratorRoleStage, CuratorExitSummary as CuratorExitSummary, CuratorExitInitiationOrigin as CuratorExitInitiationOrigin, LeadRoleState as LeadRoleState, ExitedLeadRole as ExitedLeadRole, CuratorInduction as CuratorInduction } from '../content-working-group'
+import { ChannelId as ChannelId, CuratorId as CuratorId, CuratorOpeningId as CuratorOpeningId, CuratorApplicationId as CuratorApplicationId, LeadId as LeadId, PrincipalId as PrincipalId, OptionalText as OptionalText, Channel as Channel, ChannelContentType as ChannelContentType, ChannelCurationStatus as ChannelCurationStatus, ChannelPublicationStatus as ChannelPublicationStatus, CurationActor as CurationActor, Curator as Curator, CuratorApplication as CuratorApplication, CuratorOpening as CuratorOpening, Lead as Lead, OpeningPolicyCommitment as OpeningPolicyCommitment, Principal as Principal, WorkingGroupUnstaker as WorkingGroupUnstaker, CuratorApplicationIdToCuratorIdMap as CuratorApplicationIdToCuratorIdMap, CuratorApplicationIdSet as CuratorApplicationIdSet, CuratorRoleStakeProfile as CuratorRoleStakeProfile, CuratorRoleStage as CuratorRoleStage, CuratorExitSummary as CuratorExitSummary, CuratorExitInitiationOrigin as CuratorExitInitiationOrigin, LeadRoleState as LeadRoleState, ExitedLeadRole as ExitedLeadRole, CuratorInduction as CuratorInduction } from '../content-working-group'
 import { RationaleText as RationaleText, Application as ApplicationOf, ApplicationIdSet as ApplicationIdSet, ApplicationIdToWorkerIdMap as ApplicationIdToWorkerIdMap, WorkerId as WorkerId, Worker as WorkerOf, Opening as OpeningOf, StorageProviderId as StorageProviderId, OpeningType as OpeningType, ApplicationId as HiringApplicationId, RewardPolicy as RewardPolicy, WorkingGroupOpeningPolicyCommitment as WorkingGroupOpeningPolicyCommitment, RoleStakeProfile as RoleStakeProfile } from '../working-group'
 import { RationaleText as RationaleText, Application as ApplicationOf, ApplicationIdSet as ApplicationIdSet, ApplicationIdToWorkerIdMap as ApplicationIdToWorkerIdMap, WorkerId as WorkerId, Worker as WorkerOf, Opening as OpeningOf, StorageProviderId as StorageProviderId, OpeningType as OpeningType, ApplicationId as HiringApplicationId, RewardPolicy as RewardPolicy, WorkingGroupOpeningPolicyCommitment as WorkingGroupOpeningPolicyCommitment, RoleStakeProfile as RoleStakeProfile } from '../working-group'
 import { Url as Url, IPNSIdentity as IPNSIdentity, ServiceProviderRecord as ServiceProviderRecord } from '../discovery'
 import { Url as Url, IPNSIdentity as IPNSIdentity, ServiceProviderRecord as ServiceProviderRecord } from '../discovery'
 import { ContentId as ContentId, LiaisonJudgement as LiaisonJudgement, DataObject as DataObject, DataObjectStorageRelationshipId as DataObjectStorageRelationshipId, DataObjectStorageRelationship as DataObjectStorageRelationship, DataObjectTypeId as DataObjectTypeId, DataObjectType as DataObjectType, DataObjectsMap as DataObjectsMap } from '../media'
 import { ContentId as ContentId, LiaisonJudgement as LiaisonJudgement, DataObject as DataObject, DataObjectStorageRelationshipId as DataObjectStorageRelationshipId, DataObjectStorageRelationship as DataObjectStorageRelationship, DataObjectTypeId as DataObjectTypeId, DataObjectType as DataObjectType, DataObjectsMap as DataObjectsMap } from '../media'
@@ -286,12 +286,12 @@ declare module '@polkadot/types/types/registry' {
     "StakingAmountLimitMode": StakingAmountLimitMode;
     "StakingAmountLimitMode": StakingAmountLimitMode;
     "Option<StakingAmountLimitMode>": Option<StakingAmountLimitMode>;
     "Option<StakingAmountLimitMode>": Option<StakingAmountLimitMode>;
     "Vec<StakingAmountLimitMode>": Vec<StakingAmountLimitMode>;
     "Vec<StakingAmountLimitMode>": Vec<StakingAmountLimitMode>;
-    "ClassId": u64;
-    "Option<ClassId>": Option<u64>;
-    "Vec<ClassId>": Vec<u64>;
-    "EntityId": u64;
-    "Option<EntityId>": Option<u64>;
-    "Vec<EntityId>": Vec<u64>;
+    "ClassId": ClassId;
+    "Option<ClassId>": Option<ClassId>;
+    "Vec<ClassId>": Vec<ClassId>;
+    "EntityId": EntityId;
+    "Option<EntityId>": Option<EntityId>;
+    "Vec<EntityId>": Vec<EntityId>;
     "Class": Class;
     "Class": Class;
     "Option<Class>": Option<Class>;
     "Option<Class>": Option<Class>;
     "Vec<Class>": Vec<Class>;
     "Vec<Class>": Vec<Class>;
@@ -349,24 +349,24 @@ declare module '@polkadot/types/types/registry' {
     "PropertyOfClass": PropertyOfClass;
     "PropertyOfClass": PropertyOfClass;
     "Option<PropertyOfClass>": Option<PropertyOfClass>;
     "Option<PropertyOfClass>": Option<PropertyOfClass>;
     "Vec<PropertyOfClass>": Vec<PropertyOfClass>;
     "Vec<PropertyOfClass>": Vec<PropertyOfClass>;
-    "ChannelId": u64;
-    "Option<ChannelId>": Option<u64>;
-    "Vec<ChannelId>": Vec<u64>;
-    "CuratorId": u64;
-    "Option<CuratorId>": Option<u64>;
-    "Vec<CuratorId>": Vec<u64>;
-    "CuratorOpeningId": u64;
-    "Option<CuratorOpeningId>": Option<u64>;
-    "Vec<CuratorOpeningId>": Vec<u64>;
-    "CuratorApplicationId": u64;
-    "Option<CuratorApplicationId>": Option<u64>;
-    "Vec<CuratorApplicationId>": Vec<u64>;
-    "LeadId": u64;
-    "Option<LeadId>": Option<u64>;
-    "Vec<LeadId>": Vec<u64>;
-    "PrincipalId": u64;
-    "Option<PrincipalId>": Option<u64>;
-    "Vec<PrincipalId>": Vec<u64>;
+    "ChannelId": ChannelId;
+    "Option<ChannelId>": Option<ChannelId>;
+    "Vec<ChannelId>": Vec<ChannelId>;
+    "CuratorId": CuratorId;
+    "Option<CuratorId>": Option<CuratorId>;
+    "Vec<CuratorId>": Vec<CuratorId>;
+    "CuratorOpeningId": CuratorOpeningId;
+    "Option<CuratorOpeningId>": Option<CuratorOpeningId>;
+    "Vec<CuratorOpeningId>": Vec<CuratorOpeningId>;
+    "CuratorApplicationId": CuratorApplicationId;
+    "Option<CuratorApplicationId>": Option<CuratorApplicationId>;
+    "Vec<CuratorApplicationId>": Vec<CuratorApplicationId>;
+    "LeadId": LeadId;
+    "Option<LeadId>": Option<LeadId>;
+    "Vec<LeadId>": Vec<LeadId>;
+    "PrincipalId": PrincipalId;
+    "Option<PrincipalId>": Option<PrincipalId>;
+    "Vec<PrincipalId>": Vec<PrincipalId>;
     "OptionalText": OptionalText;
     "OptionalText": OptionalText;
     "Option<OptionalText>": Option<OptionalText>;
     "Option<OptionalText>": Option<OptionalText>;
     "Vec<OptionalText>": Vec<OptionalText>;
     "Vec<OptionalText>": Vec<OptionalText>;

+ 20 - 20
types/augment/all/defs.json

@@ -353,15 +353,15 @@
     "ClassId": "u64",
     "ClassId": "u64",
     "EntityId": "u64",
     "EntityId": "u64",
     "Class": {
     "Class": {
-        "id": "u64",
+        "id": "ClassId",
         "properties": "Vec<Property>",
         "properties": "Vec<Property>",
         "schemas": "Vec<ClassSchema>",
         "schemas": "Vec<ClassSchema>",
         "name": "Text",
         "name": "Text",
         "description": "Text"
         "description": "Text"
     },
     },
     "Entity": {
     "Entity": {
-        "id": "u64",
-        "class_id": "u64",
+        "id": "EntityId",
+        "class_id": "ClassId",
         "in_class_schema_indexes": "Vec<u16>"
         "in_class_schema_indexes": "Vec<u16>"
     },
     },
     "ClassSchema": {
     "ClassSchema": {
@@ -393,7 +393,7 @@
             "Int32Vec": "u16",
             "Int32Vec": "u16",
             "Int64Vec": "u16",
             "Int64Vec": "u16",
             "TextVec": "(u16,u16)",
             "TextVec": "(u16,u16)",
-            "InternalVec": "(u16,u64)"
+            "InternalVec": "(u16,ClassId)"
         }
         }
     },
     },
     "PropertyValue": {
     "PropertyValue": {
@@ -416,7 +416,7 @@
             "Int32Vec": "Vec<i32>",
             "Int32Vec": "Vec<i32>",
             "Int64Vec": "Vec<i64>",
             "Int64Vec": "Vec<i64>",
             "TextVec": "Vec<Text>",
             "TextVec": "Vec<Text>",
-            "InternalVec": "Vec<u64>"
+            "InternalVec": "Vec<EntityId>"
         }
         }
     },
     },
     "ClassPropertyValue": {
     "ClassPropertyValue": {
@@ -456,7 +456,7 @@
         }
         }
     },
     },
     "CreateEntity": {
     "CreateEntity": {
-        "class_id": "u64"
+        "class_id": "ClassId"
     },
     },
     "UpdatePropertyValues": {
     "UpdatePropertyValues": {
         "entity_id": "ParametrizedEntity",
         "entity_id": "ParametrizedEntity",
@@ -485,7 +485,7 @@
         }
         }
     },
     },
     "PropertyOfClass": {
     "PropertyOfClass": {
-        "class_id": "u64",
+        "class_id": "ClassId",
         "property_index": "u16"
         "property_index": "u16"
     },
     },
     "ChannelId": "u64",
     "ChannelId": "u64",
@@ -508,7 +508,7 @@
         "publication_status": "ChannelPublicationStatus",
         "publication_status": "ChannelPublicationStatus",
         "curation_status": "ChannelCurationStatus",
         "curation_status": "ChannelCurationStatus",
         "created": "u32",
         "created": "u32",
-        "principal_id": "u64"
+        "principal_id": "PrincipalId"
     },
     },
     "ChannelContentType": {
     "ChannelContentType": {
         "_enum": [
         "_enum": [
@@ -532,7 +532,7 @@
     "CurationActor": {
     "CurationActor": {
         "_enum": {
         "_enum": {
             "Lead": "Null",
             "Lead": "Null",
-            "Curator": "u64"
+            "Curator": "CuratorId"
         }
         }
     },
     },
     "Curator": {
     "Curator": {
@@ -541,17 +541,17 @@
         "role_stake_profile": "Option<CuratorRoleStakeProfile>",
         "role_stake_profile": "Option<CuratorRoleStakeProfile>",
         "stage": "CuratorRoleStage",
         "stage": "CuratorRoleStage",
         "induction": "CuratorInduction",
         "induction": "CuratorInduction",
-        "principal_id": "u64"
+        "principal_id": "PrincipalId"
     },
     },
     "CuratorApplication": {
     "CuratorApplication": {
         "role_account": "GenericAccountId",
         "role_account": "GenericAccountId",
-        "curator_opening_id": "u64",
+        "curator_opening_id": "CuratorOpeningId",
         "member_id": "MemberId",
         "member_id": "MemberId",
         "application_id": "HiringApplicationId"
         "application_id": "HiringApplicationId"
     },
     },
     "CuratorOpening": {
     "CuratorOpening": {
         "opening_id": "u64",
         "opening_id": "u64",
-        "curator_applications": "Vec<u64>",
+        "curator_applications": "Vec<CuratorApplicationId>",
         "policy_commitment": "OpeningPolicyCommitment"
         "policy_commitment": "OpeningPolicyCommitment"
     },
     },
     "Lead": {
     "Lead": {
@@ -578,18 +578,18 @@
     "Principal": {
     "Principal": {
         "_enum": {
         "_enum": {
             "Lead": "Null",
             "Lead": "Null",
-            "Curator": "u64",
-            "ChannelOwner": "u64"
+            "Curator": "CuratorId",
+            "ChannelOwner": "ChannelId"
         }
         }
     },
     },
     "WorkingGroupUnstaker": {
     "WorkingGroupUnstaker": {
         "_enum": {
         "_enum": {
-            "Lead": "u64",
-            "Curator": "u64"
+            "Lead": "LeadId",
+            "Curator": "CuratorId"
         }
         }
     },
     },
-    "CuratorApplicationIdToCuratorIdMap": "BTreeMap<HiringApplicationId,u64>",
-    "CuratorApplicationIdSet": "Vec<u64>",
+    "CuratorApplicationIdToCuratorIdMap": "BTreeMap<HiringApplicationId,CuratorId>",
+    "CuratorApplicationIdSet": "Vec<CuratorApplicationId>",
     "CuratorRoleStakeProfile": {
     "CuratorRoleStakeProfile": {
         "stake_id": "u64",
         "stake_id": "u64",
         "termination_unstaking_period": "Option<u32>",
         "termination_unstaking_period": "Option<u32>",
@@ -623,8 +623,8 @@
         "initiated_at_block_number": "u32"
         "initiated_at_block_number": "u32"
     },
     },
     "CuratorInduction": {
     "CuratorInduction": {
-        "lead": "u64",
-        "curator_application_id": "u64",
+        "lead": "LeadId",
+        "curator_application_id": "CuratorApplicationId",
         "at_block": "u32"
         "at_block": "u32"
     },
     },
     "RationaleText": "Bytes",
     "RationaleText": "Bytes",

+ 20 - 20
types/augment/all/types.ts

@@ -192,7 +192,7 @@ export interface Channel extends Struct {
   readonly publication_status: ChannelPublicationStatus;
   readonly publication_status: ChannelPublicationStatus;
   readonly curation_status: ChannelCurationStatus;
   readonly curation_status: ChannelCurationStatus;
   readonly created: u32;
   readonly created: u32;
-  readonly principal_id: u64;
+  readonly principal_id: PrincipalId;
 }
 }
 
 
 /** @name ChannelContentType */
 /** @name ChannelContentType */
@@ -225,7 +225,7 @@ export interface ChildPositionInParentCategory extends Struct {
 
 
 /** @name Class */
 /** @name Class */
 export interface Class extends Struct {
 export interface Class extends Struct {
-  readonly id: u64;
+  readonly id: ClassId;
   readonly properties: Vec<Property>;
   readonly properties: Vec<Property>;
   readonly schemas: Vec<ClassSchema>;
   readonly schemas: Vec<ClassSchema>;
   readonly name: Text;
   readonly name: Text;
@@ -262,7 +262,7 @@ export interface ContentId extends U8aFixed {}
 
 
 /** @name CreateEntity */
 /** @name CreateEntity */
 export interface CreateEntity extends Struct {
 export interface CreateEntity extends Struct {
-  readonly class_id: u64;
+  readonly class_id: ClassId;
 }
 }
 
 
 /** @name Credential */
 /** @name Credential */
@@ -275,7 +275,7 @@ export interface CredentialSet extends Vec<Credential> {}
 export interface CurationActor extends Enum {
 export interface CurationActor extends Enum {
   readonly isLead: boolean;
   readonly isLead: boolean;
   readonly isCurator: boolean;
   readonly isCurator: boolean;
-  readonly asCurator: u64;
+  readonly asCurator: CuratorId;
 }
 }
 
 
 /** @name Curator */
 /** @name Curator */
@@ -285,13 +285,13 @@ export interface Curator extends Struct {
   readonly role_stake_profile: Option<CuratorRoleStakeProfile>;
   readonly role_stake_profile: Option<CuratorRoleStakeProfile>;
   readonly stage: CuratorRoleStage;
   readonly stage: CuratorRoleStage;
   readonly induction: CuratorInduction;
   readonly induction: CuratorInduction;
-  readonly principal_id: u64;
+  readonly principal_id: PrincipalId;
 }
 }
 
 
 /** @name CuratorApplication */
 /** @name CuratorApplication */
 export interface CuratorApplication extends Struct {
 export interface CuratorApplication extends Struct {
   readonly role_account: GenericAccountId;
   readonly role_account: GenericAccountId;
-  readonly curator_opening_id: u64;
+  readonly curator_opening_id: CuratorOpeningId;
   readonly member_id: MemberId;
   readonly member_id: MemberId;
   readonly application_id: HiringApplicationId;
   readonly application_id: HiringApplicationId;
 }
 }
@@ -300,10 +300,10 @@ export interface CuratorApplication extends Struct {
 export interface CuratorApplicationId extends u64 {}
 export interface CuratorApplicationId extends u64 {}
 
 
 /** @name CuratorApplicationIdSet */
 /** @name CuratorApplicationIdSet */
-export interface CuratorApplicationIdSet extends Vec<u64> {}
+export interface CuratorApplicationIdSet extends Vec<CuratorApplicationId> {}
 
 
 /** @name CuratorApplicationIdToCuratorIdMap */
 /** @name CuratorApplicationIdToCuratorIdMap */
-export interface CuratorApplicationIdToCuratorIdMap extends BTreeMap<HiringApplicationId, u64> {}
+export interface CuratorApplicationIdToCuratorIdMap extends BTreeMap<HiringApplicationId, CuratorId> {}
 
 
 /** @name CuratorExitInitiationOrigin */
 /** @name CuratorExitInitiationOrigin */
 export interface CuratorExitInitiationOrigin extends Enum {
 export interface CuratorExitInitiationOrigin extends Enum {
@@ -323,15 +323,15 @@ export interface CuratorId extends u64 {}
 
 
 /** @name CuratorInduction */
 /** @name CuratorInduction */
 export interface CuratorInduction extends Struct {
 export interface CuratorInduction extends Struct {
-  readonly lead: u64;
-  readonly curator_application_id: u64;
+  readonly lead: LeadId;
+  readonly curator_application_id: CuratorApplicationId;
   readonly at_block: u32;
   readonly at_block: u32;
 }
 }
 
 
 /** @name CuratorOpening */
 /** @name CuratorOpening */
 export interface CuratorOpening extends Struct {
 export interface CuratorOpening extends Struct {
   readonly opening_id: u64;
   readonly opening_id: u64;
-  readonly curator_applications: Vec<u64>;
+  readonly curator_applications: Vec<CuratorApplicationId>;
   readonly policy_commitment: OpeningPolicyCommitment;
   readonly policy_commitment: OpeningPolicyCommitment;
 }
 }
 
 
@@ -441,8 +441,8 @@ export interface ElectionStake extends Struct {
 
 
 /** @name Entity */
 /** @name Entity */
 export interface Entity extends Struct {
 export interface Entity extends Struct {
-  readonly id: u64;
-  readonly class_id: u64;
+  readonly id: EntityId;
+  readonly class_id: ClassId;
   readonly in_class_schema_indexes: Vec<u16>;
   readonly in_class_schema_indexes: Vec<u16>;
 }
 }
 
 
@@ -724,9 +724,9 @@ export interface PostTextChange extends Struct {
 export interface Principal extends Enum {
 export interface Principal extends Enum {
   readonly isLead: boolean;
   readonly isLead: boolean;
   readonly isCurator: boolean;
   readonly isCurator: boolean;
-  readonly asCurator: u64;
+  readonly asCurator: CuratorId;
   readonly isChannelOwner: boolean;
   readonly isChannelOwner: boolean;
-  readonly asChannelOwner: u64;
+  readonly asChannelOwner: ChannelId;
 }
 }
 
 
 /** @name PrincipalId */
 /** @name PrincipalId */
@@ -742,7 +742,7 @@ export interface Property extends Struct {
 
 
 /** @name PropertyOfClass */
 /** @name PropertyOfClass */
 export interface PropertyOfClass extends Struct {
 export interface PropertyOfClass extends Struct {
-  readonly class_id: u64;
+  readonly class_id: ClassId;
   readonly property_index: u16;
   readonly property_index: u16;
 }
 }
 
 
@@ -777,7 +777,7 @@ export interface PropertyType extends Enum {
   readonly isTextVec: boolean;
   readonly isTextVec: boolean;
   readonly asTextVec: ITuple<[u16, u16]>;
   readonly asTextVec: ITuple<[u16, u16]>;
   readonly isInternalVec: boolean;
   readonly isInternalVec: boolean;
-  readonly asInternalVec: ITuple<[u16, u64]>;
+  readonly asInternalVec: ITuple<[u16, ClassId]>;
 }
 }
 
 
 /** @name PropertyValue */
 /** @name PropertyValue */
@@ -818,7 +818,7 @@ export interface PropertyValue extends Enum {
   readonly isTextVec: boolean;
   readonly isTextVec: boolean;
   readonly asTextVec: Vec<Text>;
   readonly asTextVec: Vec<Text>;
   readonly isInternalVec: boolean;
   readonly isInternalVec: boolean;
-  readonly asInternalVec: Vec<u64>;
+  readonly asInternalVec: Vec<EntityId>;
 }
 }
 
 
 /** @name ProposalDecisionStatus */
 /** @name ProposalDecisionStatus */
@@ -1234,9 +1234,9 @@ export interface WorkingGroupOpeningPolicyCommitment extends Struct {
 /** @name WorkingGroupUnstaker */
 /** @name WorkingGroupUnstaker */
 export interface WorkingGroupUnstaker extends Enum {
 export interface WorkingGroupUnstaker extends Enum {
   readonly isLead: boolean;
   readonly isLead: boolean;
-  readonly asLead: u64;
+  readonly asLead: LeadId;
   readonly isCurator: boolean;
   readonly isCurator: boolean;
-  readonly asCurator: u64;
+  readonly asCurator: CuratorId;
 }
 }
 
 
 export type PHANTOM_ALL = 'all';
 export type PHANTOM_ALL = 'all';

+ 0 - 50
types/augment/augment-api-consts.ts

@@ -31,56 +31,6 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
        **/
        **/
       existentialDeposit: AugmentedConst<Balance>;
       existentialDeposit: AugmentedConst<Balance>;
     };
     };
-    contracts: {
-      /**
-       * The maximum nesting level of a call/instantiate stack. A reasonable default
-       * value is 100.
-       **/
-      maxDepth: AugmentedConst<u32>;
-      /**
-       * The maximum size of a storage value in bytes. A reasonable default is 16 KiB.
-       **/
-      maxValueSize: AugmentedConst<u32>;
-      /**
-       * Price of a byte of storage per one block interval. Should be greater than 0.
-       **/
-      rentByteFee: AugmentedConst<BalanceOf>;
-      /**
-       * The amount of funds a contract should deposit in order to offset
-       * the cost of one byte.
-       * 
-       * Let's suppose the deposit is 1,000 BU (balance units)/byte and the rent is 1 BU/byte/day,
-       * then a contract with 1,000,000 BU that uses 1,000 bytes of storage would pay no rent.
-       * But if the balance reduced to 500,000 BU and the storage stayed the same at 1,000,
-       * then it would pay 500 BU/day.
-       **/
-      rentDepositOffset: AugmentedConst<BalanceOf>;
-      /**
-       * Number of block delay an extrinsic claim surcharge has.
-       * 
-       * When claim surcharge is called by an extrinsic the rent is checked
-       * for current_block - delay
-       **/
-      signedClaimHandicap: AugmentedConst<BlockNumber>;
-      /**
-       * A size offset for an contract. A just created account with untouched storage will have that
-       * much of storage from the perspective of the state rent.
-       * 
-       * This is a simple way to ensure that contracts with empty storage eventually get deleted
-       * by making them pay rent. This creates an incentive to remove them early in order to save
-       * rent.
-       **/
-      storageSizeOffset: AugmentedConst<u32>;
-      /**
-       * Reward that is received by the party whose touch has led
-       * to removal of a contract.
-       **/
-      surchargeReward: AugmentedConst<BalanceOf>;
-      /**
-       * The minimum amount required to generate a tombstone.
-       **/
-      tombstoneDeposit: AugmentedConst<BalanceOf>;
-    };
     dataDirectory: {
     dataDirectory: {
       /**
       /**
        * Maximum objects allowed per inject_data_objects() transaction
        * Maximum objects allowed per inject_data_objects() transaction

+ 4 - 29
types/augment/augment-api-query.ts

@@ -4,12 +4,11 @@
 import { AnyNumber, ITuple, Observable } from '@polkadot/types/types';
 import { AnyNumber, ITuple, Observable } from '@polkadot/types/types';
 import { Option, Vec } from '@polkadot/types/codec';
 import { Option, Vec } from '@polkadot/types/codec';
 import { Bytes, bool, u32, u64 } from '@polkadot/types/primitive';
 import { Bytes, bool, u32, u64 } from '@polkadot/types/primitive';
-import { Application, ApplicationId, ApplicationOf, Category, CategoryId, Channel, ChannelId, Class, ClassId, ClassPermissionsType, ContentId, Credential, Curator, CuratorApplication, CuratorApplicationId, CuratorId, CuratorOpening, CuratorOpeningId, DataObject, DataObjectStorageRelationship, DataObjectStorageRelationshipId, DataObjectType, DataObjectTypeId, DiscussionPost, DiscussionThread, ElectionStage, ElectionStake, Entity, EntityId, HiringApplicationId, InputValidationLengthConstraint, Lead, LeadId, MemberId, Membership, MemoText, Mint, MintId, Opening, OpeningId, OpeningOf, PaidMembershipTerms, PaidTermId, Post, PostId, Principal, PrincipalId, ProposalDetailsOf, ProposalId, ProposalOf, Recipient, RecipientId, RewardRelationship, RewardRelationshipId, SealedVote, Seats, Stake, StakeId, StorageProviderId, Thread, ThreadCounter, ThreadId, TransferableStake, Url, VoteKind, WorkerId, WorkerOf, WorkingGroupUnstaker } from './all';
+import { Application, ApplicationId, ApplicationOf, Category, CategoryId, Channel, ChannelId, Class, ClassId, ClassPermissionsType, ContentId, Credential, Curator, CuratorApplication, CuratorApplicationId, CuratorId, CuratorOpening, CuratorOpeningId, DataObject, DataObjectStorageRelationship, DataObjectStorageRelationshipId, DataObjectType, DataObjectTypeId, DiscussionPost, DiscussionThread, ElectionStage, ElectionStake, Entity, EntityId, HiringApplicationId, InputValidationLengthConstraint, Lead, LeadId, MemberId, Membership, MemoText, Mint, MintId, Opening, OpeningId, OpeningOf, PaidMembershipTerms, PaidTermId, Post, PostId, Principal, PrincipalId, ProposalDetailsOf, ProposalId, ProposalOf, Recipient, RecipientId, RewardRelationship, RewardRelationshipId, SealedVote, Seats, ServiceProviderRecord, Stake, StakeId, StorageProviderId, Thread, ThreadCounter, ThreadId, TransferableStake, Url, VoteKind, WorkerId, WorkerOf, WorkingGroupUnstaker } from './all';
 import { UncleEntryItem } from '@polkadot/types/interfaces/authorship';
 import { UncleEntryItem } from '@polkadot/types/interfaces/authorship';
 import { BabeAuthorityWeight, MaybeRandomness, NextConfigDescriptor, Randomness } from '@polkadot/types/interfaces/babe';
 import { BabeAuthorityWeight, MaybeRandomness, NextConfigDescriptor, Randomness } from '@polkadot/types/interfaces/babe';
 import { AccountData, BalanceLock } from '@polkadot/types/interfaces/balances';
 import { AccountData, BalanceLock } from '@polkadot/types/interfaces/balances';
 import { AuthorityId } from '@polkadot/types/interfaces/consensus';
 import { AuthorityId } from '@polkadot/types/interfaces/consensus';
-import { CodeHash, ContractInfo, PrefabWasmModule, Schedule } from '@polkadot/types/interfaces/contracts';
 import { SetId, StoredPendingChange, StoredState } from '@polkadot/types/interfaces/grandpa';
 import { SetId, StoredPendingChange, StoredState } from '@polkadot/types/interfaces/grandpa';
 import { AuthIndex } from '@polkadot/types/interfaces/imOnline';
 import { AuthIndex } from '@polkadot/types/interfaces/imOnline';
 import { DeferredOffenceOf, Kind, OffenceDetails, OpaqueTimeSlot, ReportIdOf } from '@polkadot/types/interfaces/offences';
 import { DeferredOffenceOf, Kind, OffenceDetails, OpaqueTimeSlot, ReportIdOf } from '@polkadot/types/interfaces/offences';
@@ -208,30 +207,6 @@ declare module '@polkadot/api/types/storage' {
        **/
        **/
       unstakerByStakeId: AugmentedQuery<ApiType, (arg: StakeId | AnyNumber | Uint8Array) => Observable<WorkingGroupUnstaker>>;
       unstakerByStakeId: AugmentedQuery<ApiType, (arg: StakeId | AnyNumber | Uint8Array) => Observable<WorkingGroupUnstaker>>;
     };
     };
-    contracts: {
-      /**
-       * The subtrie counter.
-       **/
-      accountCounter: AugmentedQuery<ApiType, () => Observable<u64>>;
-      /**
-       * A mapping between an original code hash and instrumented wasm code, ready for execution.
-       **/
-      codeStorage: AugmentedQuery<ApiType, (arg: CodeHash | string | Uint8Array) => Observable<Option<PrefabWasmModule>>>;
-      /**
-       * The code associated with a given account.
-       * 
-       * TWOX-NOTE: SAFE since `AccountId` is a secure hash.
-       **/
-      contractInfoOf: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Option<ContractInfo>>>;
-      /**
-       * Current cost schedule for contracts.
-       **/
-      currentSchedule: AugmentedQuery<ApiType, () => Observable<Schedule>>;
-      /**
-       * A mapping from an original code hash to the original code, untouched by instrumentation.
-       **/
-      pristineCode: AugmentedQuery<ApiType, (arg: CodeHash | string | Uint8Array) => Observable<Option<Bytes>>>;
-    };
     council: {
     council: {
       activeCouncil: AugmentedQuery<ApiType, () => Observable<Seats>>;
       activeCouncil: AugmentedQuery<ApiType, () => Observable<Seats>>;
       /**
       /**
@@ -323,15 +298,15 @@ declare module '@polkadot/api/types/storage' {
     };
     };
     discovery: {
     discovery: {
       /**
       /**
-       * Mapping of service providers' storage provider id to their AccountInfo
+       * Mapping of service providers' storage provider id to their ServiceProviderRecord
        **/
        **/
-      accountInfoByStorageProviderId: AugmentedQuery<ApiType, (arg: StorageProviderId | AnyNumber | Uint8Array) => Observable<AccountInfo>>;
+      accountInfoByStorageProviderId: AugmentedQuery<ApiType, (arg: StorageProviderId | AnyNumber | Uint8Array) => Observable<ServiceProviderRecord>>;
       /**
       /**
        * Bootstrap endpoints maintained by root
        * Bootstrap endpoints maintained by root
        **/
        **/
       bootstrapEndpoints: AugmentedQuery<ApiType, () => Observable<Vec<Url>>>;
       bootstrapEndpoints: AugmentedQuery<ApiType, () => Observable<Vec<Url>>>;
       /**
       /**
-       * Lifetime of an AccountInfo record in AccountInfoByAccountId map
+       * Lifetime of an ServiceProviderRecord record in AccountInfoByAccountId map
        **/
        **/
       defaultLifetime: AugmentedQuery<ApiType, () => Observable<BlockNumber>>;
       defaultLifetime: AugmentedQuery<ApiType, () => Observable<BlockNumber>>;
     };
     };

+ 2 - 47
types/augment/augment-api-tx.ts

@@ -5,7 +5,6 @@ import { AnyNumber, ITuple } from '@polkadot/types/types';
 import { Compact, Option, Vec } from '@polkadot/types/codec';
 import { Compact, Option, Vec } from '@polkadot/types/codec';
 import { Bytes, bool, u16, u32, u64 } from '@polkadot/types/primitive';
 import { Bytes, bool, u16, u32, u64 } from '@polkadot/types/primitive';
 import { ActivateOpeningAt, AddOpeningParameters, ApplicationId, ApplicationIdSet, BalanceOfMint, CategoryId, ChannelContentType, ChannelCurationStatus, ChannelId, ChannelPublicationStatus, ClassId, ClassPermissionsType, ClassPropertyValue, ContentId, Credential, CredentialSet, CurationActor, CuratorApplicationId, CuratorApplicationIdSet, CuratorId, CuratorOpeningId, DataObjectStorageRelationshipId, DataObjectType, DataObjectTypeId, DataObjectsMap, ElectionParameters, EntityId, EntityPermissions, FillOpeningParameters, MemberId, MemoText, OpeningId, OpeningPolicyCommitment, OpeningType, Operation, OptionalText, PaidTermId, PostId, Property, ProposalId, ReferenceConstraint, RewardPolicy, StorageProviderId, TerminateRoleParameters, ThreadId, Url, VoteKind, WorkerId, WorkingGroup } from './all';
 import { ActivateOpeningAt, AddOpeningParameters, ApplicationId, ApplicationIdSet, BalanceOfMint, CategoryId, ChannelContentType, ChannelCurationStatus, ChannelId, ChannelPublicationStatus, ClassId, ClassPermissionsType, ClassPropertyValue, ContentId, Credential, CredentialSet, CurationActor, CuratorApplicationId, CuratorApplicationIdSet, CuratorId, CuratorOpeningId, DataObjectStorageRelationshipId, DataObjectType, DataObjectTypeId, DataObjectsMap, ElectionParameters, EntityId, EntityPermissions, FillOpeningParameters, MemberId, MemoText, OpeningId, OpeningPolicyCommitment, OpeningType, Operation, OptionalText, PaidTermId, PostId, Property, ProposalId, ReferenceConstraint, RewardPolicy, StorageProviderId, TerminateRoleParameters, ThreadId, Url, VoteKind, WorkerId, WorkingGroup } from './all';
-import { CodeHash, Gas, Schedule } from '@polkadot/types/interfaces/contracts';
 import { Extrinsic, Signature } from '@polkadot/types/interfaces/extrinsics';
 import { Extrinsic, Signature } from '@polkadot/types/interfaces/extrinsics';
 import { GrandpaEquivocationProof, KeyOwnerProof } from '@polkadot/types/interfaces/grandpa';
 import { GrandpaEquivocationProof, KeyOwnerProof } from '@polkadot/types/interfaces/grandpa';
 import { Heartbeat } from '@polkadot/types/interfaces/imOnline';
 import { Heartbeat } from '@polkadot/types/interfaces/imOnline';
@@ -186,50 +185,6 @@ declare module '@polkadot/api/types/submittable' {
       updateCuratorRoleAccount: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, curatorId: CuratorId | AnyNumber | Uint8Array, newRoleAccount: AccountId | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       updateCuratorRoleAccount: AugmentedSubmittable<(memberId: MemberId | AnyNumber | Uint8Array, curatorId: CuratorId | AnyNumber | Uint8Array, newRoleAccount: AccountId | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       withdrawCuratorApplication: AugmentedSubmittable<(curatorApplicationId: CuratorApplicationId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       withdrawCuratorApplication: AugmentedSubmittable<(curatorApplicationId: CuratorApplicationId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
     };
     };
-    contracts: {
-      /**
-       * Makes a call to an account, optionally transferring some balance.
-       * 
-       * * If the account is a smart-contract account, the associated code will be
-       * executed and any value will be transferred.
-       * * If the account is a regular account, any value will be transferred.
-       * * If no account exists and the call value is not less than `existential_deposit`,
-       * a regular account will be created and any value will be transferred.
-       **/
-      call: AugmentedSubmittable<(dest: LookupSource | string | Uint8Array, value: Compact<BalanceOf> | AnyNumber | Uint8Array, gasLimit: Compact<Gas> | AnyNumber | Uint8Array, data: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
-      /**
-       * Allows block producers to claim a small reward for evicting a contract. If a block producer
-       * fails to do so, a regular users will be allowed to claim the reward.
-       * 
-       * If contract is not evicted as a result of this call, no actions are taken and
-       * the sender is not eligible for the reward.
-       **/
-      claimSurcharge: AugmentedSubmittable<(dest: AccountId | string | Uint8Array, auxSender: Option<AccountId> | null | object | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
-      /**
-       * Instantiates a new contract from the `codehash` generated by `put_code`, optionally transferring some balance.
-       * 
-       * Instantiation is executed as follows:
-       * 
-       * - The destination address is computed based on the sender and hash of the code.
-       * - The smart-contract account is created at the computed address.
-       * - The `ctor_code` is executed in the context of the newly-created account. Buffer returned
-       * after the execution is saved as the `code` of the account. That code will be invoked
-       * upon any call received by this account.
-       * - The contract is initialized.
-       **/
-      instantiate: AugmentedSubmittable<(endowment: Compact<BalanceOf> | AnyNumber | Uint8Array, gasLimit: Compact<Gas> | AnyNumber | Uint8Array, codeHash: CodeHash | string | Uint8Array, data: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
-      /**
-       * Stores the given binary Wasm code into the chain's storage and returns its `codehash`.
-       * You can instantiate contracts only with stored code.
-       **/
-      putCode: AugmentedSubmittable<(code: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
-      /**
-       * Updates the schedule for metering contracts.
-       * 
-       * The schedule must have a greater version than the stored schedule.
-       **/
-      updateSchedule: AugmentedSubmittable<(schedule: Schedule | { version?: any; putCodePerByteCost?: any; growMemCost?: any; regularOpCost?: any; returnDataPerByteCost?: any; eventDataPerByteCost?: any; eventPerTopicCost?: any; eventBaseCost?: any; sandboxDataReadCost?: any; sandboxDataWriteCost?: any; transferCost?: any; maxEventTopics?: any; maxStackHeight?: any; maxMemoryPages?: any; enablePrintln?: any; maxSubjectLen?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
-    };
     council: {
     council: {
       /**
       /**
        * Adds a zero staked council member. A member added in this way does not get a recurring reward.
        * Adds a zero staked council member. A member added in this way does not get a recurring reward.
@@ -357,12 +312,12 @@ declare module '@polkadot/api/types/submittable' {
        **/
        **/
       setDefaultLifetime: AugmentedSubmittable<(lifetime: BlockNumber | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       setDefaultLifetime: AugmentedSubmittable<(lifetime: BlockNumber | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       /**
       /**
-       * Creates the AccountInfo to save an IPNS identity for the storage provider.
+       * Creates the ServiceProviderRecord to save an IPNS identity for the storage provider.
        * Requires signed storage provider credentials.
        * Requires signed storage provider credentials.
        **/
        **/
       setIpnsId: AugmentedSubmittable<(storageProviderId: StorageProviderId | AnyNumber | Uint8Array, id: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       setIpnsId: AugmentedSubmittable<(storageProviderId: StorageProviderId | AnyNumber | Uint8Array, id: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       /**
       /**
-       * Deletes the AccountInfo with the IPNS identity for the storage provider.
+       * Deletes the ServiceProviderRecord with the IPNS identity for the storage provider.
        * Requires signed storage provider credentials.
        * Requires signed storage provider credentials.
        **/
        **/
       unsetIpnsId: AugmentedSubmittable<(storageProviderId: StorageProviderId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
       unsetIpnsId: AugmentedSubmittable<(storageProviderId: StorageProviderId | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;

+ 6 - 6
types/src/content-working-group/index.ts

@@ -300,12 +300,12 @@ export class CuratorApplicationIdToCuratorIdMap extends BTreeMap.with(Applicatio
 export class CuratorApplicationIdSet extends Vec.with(CuratorApplicationId) {}
 export class CuratorApplicationIdSet extends Vec.with(CuratorApplicationId) {}
 
 
 export const contentWorkingGroupTypes = {
 export const contentWorkingGroupTypes = {
-  ChannelId: 'u64',
-  CuratorId: 'u64',
-  CuratorOpeningId: 'u64',
-  CuratorApplicationId: 'u64',
-  LeadId: 'u64',
-  PrincipalId: 'u64',
+  ChannelId,
+  CuratorId,
+  CuratorOpeningId,
+  CuratorApplicationId,
+  LeadId,
+  PrincipalId,
   OptionalText,
   OptionalText,
   Channel,
   Channel,
   ChannelContentType,
   ChannelContentType,

+ 1 - 1
types/src/index.ts

@@ -62,7 +62,7 @@ export const types: RegistryTypes = {
 }
 }
 
 
 // Allows creating types without api instance (it's not a recommended way though, so should be used just for mocks)
 // Allows creating types without api instance (it's not a recommended way though, so should be used just for mocks)
-const mockRegistry = new TypeRegistry()
+export const mockRegistry = new TypeRegistry()
 mockRegistry.register(types)
 mockRegistry.register(types)
 
 
 export function createMock<TypeName extends keyof InterfaceTypes>(
 export function createMock<TypeName extends keyof InterfaceTypes>(

+ 2 - 2
types/src/versioned-store/index.ts

@@ -156,8 +156,8 @@ export function unifyPropName(propName: string): string {
 }
 }
 
 
 export const versionedStoreTypes: RegistryTypes = {
 export const versionedStoreTypes: RegistryTypes = {
-  ClassId: 'u64',
-  EntityId: 'u64',
+  ClassId,
+  EntityId,
   Class,
   Class,
   Entity,
   Entity,
   ClassSchema,
   ClassSchema,

+ 256 - 28
yarn.lock

@@ -1383,6 +1383,14 @@
     pirates "^4.0.0"
     pirates "^4.0.0"
     source-map-support "^0.5.16"
     source-map-support "^0.5.16"
 
 
+"@babel/runtime-corejs2@^7.6.3":
+  version "7.11.2"
+  resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.11.2.tgz#700a03945ebad0d31ba6690fc8a6bcc9040faa47"
+  integrity sha512-AC/ciV28adSSpEkBglONBWq4/Lvm6GAZuxIoyVtsnUpZMl0bxLtoChEnYAkP+47KyOCayZanojtflUEUJtR/6Q==
+  dependencies:
+    core-js "^2.6.5"
+    regenerator-runtime "^0.13.4"
+
 "@babel/runtime@7.0.0":
 "@babel/runtime@7.0.0":
   version "7.0.0"
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0.tgz#adeb78fedfc855aa05bc041640f3f6f98e85424c"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0.tgz#adeb78fedfc855aa05bc041640f3f6f98e85424c"
@@ -4567,6 +4575,11 @@
   resolved "https://registry.yarnpkg.com/@types/memoizee/-/memoizee-0.4.4.tgz#a8a5e917ef70c79523b8b8d57f529e49616a760c"
   resolved "https://registry.yarnpkg.com/@types/memoizee/-/memoizee-0.4.4.tgz#a8a5e917ef70c79523b8b8d57f529e49616a760c"
   integrity sha512-c9+1g6+6vEqcw5UuM0RbfQV0mssmZcoG9+hNC5ptDCsv4G+XJW1Z4pE13wV5zbc9e0+YrDydALBTiD3nWG1a3g==
   integrity sha512-c9+1g6+6vEqcw5UuM0RbfQV0mssmZcoG9+hNC5ptDCsv4G+XJW1Z4pE13wV5zbc9e0+YrDydALBTiD3nWG1a3g==
 
 
+"@types/mime-types@^2.1.0":
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/@types/mime-types/-/mime-types-2.1.0.tgz#9ca52cda363f699c69466c2a6ccdaad913ea7a73"
+  integrity sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM=
+
 "@types/minimatch@*":
 "@types/minimatch@*":
   version "3.0.3"
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
   resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
@@ -4664,6 +4677,13 @@
     "@types/history" "*"
     "@types/history" "*"
     "@types/react" "*"
     "@types/react" "*"
 
 
+"@types/react-beautiful-dnd@^11.0.3":
+  version "11.0.5"
+  resolved "https://registry.yarnpkg.com/@types/react-beautiful-dnd/-/react-beautiful-dnd-11.0.5.tgz#2f5bc733dd46da28312c8ee0c126ab7202b90247"
+  integrity sha512-idvycolYX3IxwIln8yahzQj3EBgYq4KimPHSP0a2lNHiz2OZSskGg2dLmq1VxTGvvTtdG+Za8p596D/dalRlrA==
+  dependencies:
+    "@types/react" "*"
+
 "@types/react-beautiful-dnd@^13.0.0":
 "@types/react-beautiful-dnd@^13.0.0":
   version "13.0.0"
   version "13.0.0"
   resolved "https://registry.yarnpkg.com/@types/react-beautiful-dnd/-/react-beautiful-dnd-13.0.0.tgz#e60d3d965312fcf1516894af92dc3e9249587db4"
   resolved "https://registry.yarnpkg.com/@types/react-beautiful-dnd/-/react-beautiful-dnd-13.0.0.tgz#e60d3d965312fcf1516894af92dc3e9249587db4"
@@ -5884,6 +5904,15 @@ anymatch@^3.0.3, anymatch@~3.1.1:
     normalize-path "^3.0.0"
     normalize-path "^3.0.0"
     picomatch "^2.0.4"
     picomatch "^2.0.4"
 
 
+aplayer@^1.10.0, aplayer@^1.10.1:
+  version "1.10.1"
+  resolved "https://registry.yarnpkg.com/aplayer/-/aplayer-1.10.1.tgz#318289206107452cc39e8f552fa6cc6cb459a90c"
+  integrity sha512-HAfyxgCUTLAqtYlxzzK9Fyqg6y+kZ9CqT1WfeWE8FSzwspT6oBqWOZHANPHF3RGTtC33IsyEgrfthPDzU5r9kQ==
+  dependencies:
+    balloon-css "^0.5.0"
+    promise-polyfill "7.1.0"
+    smoothscroll "0.4.0"
+
 app-builder-bin@3.5.9:
 app-builder-bin@3.5.9:
   version "3.5.9"
   version "3.5.9"
   resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.5.9.tgz#a3ac0c25286bac68357321cb2eaf7128b0bc0a4f"
   resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.5.9.tgz#a3ac0c25286bac68357321cb2eaf7128b0bc0a4f"
@@ -6333,21 +6362,29 @@ aws4@^1.8.0:
   resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.0.tgz#24390e6ad61386b0a747265754d2a17219de862c"
   resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.0.tgz#24390e6ad61386b0a747265754d2a17219de862c"
   integrity sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==
   integrity sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==
 
 
-axios@^0.18.0, axios@^0.18.1:
-  version "0.18.1"
-  resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.1.tgz#ff3f0de2e7b5d180e757ad98000f1081b87bcea3"
-  integrity sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==
+axios@0.18.0:
+  version "0.18.0"
+  resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102"
+  integrity sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=
   dependencies:
   dependencies:
-    follow-redirects "1.5.10"
-    is-buffer "^2.0.2"
+    follow-redirects "^1.3.0"
+    is-buffer "^1.1.5"
 
 
-axios@^0.19.0, axios@^0.19.2:
+axios@0.19.2, axios@^0.19.0, axios@^0.19.2:
   version "0.19.2"
   version "0.19.2"
   resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
   resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
   integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
   integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
   dependencies:
   dependencies:
     follow-redirects "1.5.10"
     follow-redirects "1.5.10"
 
 
+axios@^0.18.0, axios@^0.18.1:
+  version "0.18.1"
+  resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.1.tgz#ff3f0de2e7b5d180e757ad98000f1081b87bcea3"
+  integrity sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==
+  dependencies:
+    follow-redirects "1.5.10"
+    is-buffer "^2.0.2"
+
 babel-code-frame@^6.22.0:
 babel-code-frame@^6.22.0:
   version "6.26.0"
   version "6.26.0"
   resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
   resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
@@ -6761,6 +6798,16 @@ balanced-match@^1.0.0:
   resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
   resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
   integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
   integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
 
 
+balloon-css@^0.5.0:
+  version "0.5.2"
+  resolved "https://registry.yarnpkg.com/balloon-css/-/balloon-css-0.5.2.tgz#9e2163565a136c9d4aa20e8400772ce3b738d3ff"
+  integrity sha512-zheJpzwyNrG4t39vusA67v3BYg1HTVXOF8cErPEHzWK88PEOFwgo6Ea9VHOgOWNMgeuOtFVtB73NE2NWl9uDyQ==
+
+balloon-css@^1.0.3:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/balloon-css/-/balloon-css-1.2.0.tgz#53d3fb4051264a278a58713bed6865845dbcaf4b"
+  integrity sha512-urXwkHgwp6GsXVF+it01485Z2Cj4pnW02ICnM0TemOlkKmCNnDLmyy+ZZiRXBpwldUXO+aRNr7Hdia4CBvXJ5A==
+
 base-path-converter@^1.0.2:
 base-path-converter@^1.0.2:
   version "1.0.2"
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/base-path-converter/-/base-path-converter-1.0.2.tgz#e80b4b4f31c7b1561e632158e00774b6f2f27978"
   resolved "https://registry.yarnpkg.com/base-path-converter/-/base-path-converter-1.0.2.tgz#e80b4b4f31c7b1561e632158e00774b6f2f27978"
@@ -6951,17 +6998,7 @@ bluebird@^3.1.1, bluebird@^3.3.5, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.
   resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
   resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
   integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
   integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
 
 
-bn.js@^4.0.0, bn.js@^4.11.8, bn.js@^4.4.0:
-  version "4.11.8"
-  resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
-  integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==
-
-bn.js@^4.1.0, bn.js@^4.1.1:
-  version "4.11.9"
-  resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828"
-  integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==
-
-bn.js@^5.1.2:
+bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.8, bn.js@^4.4.0, bn.js@^5.1.2:
   version "5.1.2"
   version "5.1.2"
   resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.2.tgz#c9686902d3c9a27729f43ab10f9d79c2004da7b0"
   resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.2.tgz#c9686902d3c9a27729f43ab10f9d79c2004da7b0"
   integrity sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==
   integrity sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==
@@ -10124,6 +10161,26 @@ dotenv@^8.0.0, dotenv@^8.2.0:
   resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
   resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
   integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
   integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
 
 
+dplayer@1.25.0:
+  version "1.25.0"
+  resolved "https://registry.yarnpkg.com/dplayer/-/dplayer-1.25.0.tgz#10afb3416b42125b8926d9b157aae594c84945fb"
+  integrity sha512-TG2IKT4IXH5trE3DKeeOqmGlewheHT5R30ya4jhMrjysc1rrCPMJYnmsBfiTS8h6613YZeriFIDHZHEEi/rs3Q==
+  dependencies:
+    axios "0.18.0"
+    balloon-css "^0.5.0"
+    mini-css-extract-plugin "0.4.0"
+    promise-polyfill "8.0.0"
+    webpack-cli "3.0.4"
+
+dplayer@^1.24.0:
+  version "1.26.0"
+  resolved "https://registry.yarnpkg.com/dplayer/-/dplayer-1.26.0.tgz#d366200b1962bd09e91226066f2aadea6f35c71b"
+  integrity sha512-uOE0w/WdlX7N9d0ppIEcAYrcnUjY52TMX+MBL4lj9Mj+JMljVuaEc5w88HkZp5Q11VqvN/jxnM8ktx2Dr7/MgA==
+  dependencies:
+    axios "0.19.2"
+    balloon-css "^1.0.3"
+    promise-polyfill "8.1.3"
+
 drbg.js@^1.0.1:
 drbg.js@^1.0.1:
   version "1.0.1"
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b"
   resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b"
@@ -11999,6 +12056,11 @@ follow-redirects@^1.0.0:
   dependencies:
   dependencies:
     debug "^3.0.0"
     debug "^3.0.0"
 
 
+follow-redirects@^1.3.0:
+  version "1.13.0"
+  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db"
+  integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==
+
 for-in@^0.1.3:
 for-in@^0.1.3:
   version "0.1.8"
   version "0.1.8"
   resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
   resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
@@ -12664,6 +12726,11 @@ global-dirs@^2.0.1:
   dependencies:
   dependencies:
     ini "^1.3.5"
     ini "^1.3.5"
 
 
+global-modules-path@^2.1.0:
+  version "2.3.1"
+  resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.1.tgz#e541f4c800a1a8514a990477b267ac67525b9931"
+  integrity sha512-y+shkf4InI7mPRHSo2b/k6ix6+NLDtyccYv86whhxrSGX9wjPX1VMITmrDbE1eh7zkzhiWtW2sHklJYoQ62Cxg==
+
 global-modules@2.0.0, global-modules@^2.0.0:
 global-modules@2.0.0, global-modules@^2.0.0:
   version "2.0.0"
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
   resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
@@ -13816,6 +13883,14 @@ import-lazy@^4.0.0:
   resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153"
   resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153"
   integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==
   integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==
 
 
+import-local@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc"
+  integrity sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==
+  dependencies:
+    pkg-dir "^2.0.0"
+    resolve-cwd "^2.0.0"
+
 import-local@^2.0.0:
 import-local@^2.0.0:
   version "2.0.0"
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d"
   resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d"
@@ -13959,7 +14034,7 @@ inquirer@6.5.0:
     strip-ansi "^5.1.0"
     strip-ansi "^5.1.0"
     through "^2.3.6"
     through "^2.3.6"
 
 
-inquirer@^6.2.0:
+inquirer@^6.0.0, inquirer@^6.2.0:
   version "6.5.2"
   version "6.5.2"
   resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca"
   resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca"
   integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==
   integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==
@@ -14050,7 +14125,7 @@ interpret@^1.0.0:
   resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
   resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
   integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
   integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
 
 
-interpret@^1.4.0:
+interpret@^1.1.0, interpret@^1.4.0:
   version "1.4.0"
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
   resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
   integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
   integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
@@ -14072,6 +14147,11 @@ invert-kv@^1.0.0:
   resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
   resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
   integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY=
   integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY=
 
 
+invert-kv@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
+  integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
+
 ip-regex@^2.0.0, ip-regex@^2.1.0:
 ip-regex@^2.0.0, ip-regex@^2.1.0:
   version "2.1.0"
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
   resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
@@ -15049,6 +15129,11 @@ isexe@^2.0.0:
   resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
   resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
   integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
   integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
 
 
+iso-639-1@^2.1.0:
+  version "2.1.4"
+  resolved "https://registry.yarnpkg.com/iso-639-1/-/iso-639-1-2.1.4.tgz#c08b3d43a1c18945b05e26a257991ae6e36693ee"
+  integrity sha512-pwJRHnpz1sCR5saQ+Hm1E2YESw2eLGKP5TzsYKXuQ7SIfvKWMRb9CHhptqunYpCIcRCpq3LgLuhYG5hiLPRbFQ==
+
 iso-random-stream@^1.1.0:
 iso-random-stream@^1.1.0:
   version "1.1.1"
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/iso-random-stream/-/iso-random-stream-1.1.1.tgz#83824bba77fbb3480dd6b35fbb06de7f9e93e80f"
   resolved "https://registry.yarnpkg.com/iso-random-stream/-/iso-random-stream-1.1.1.tgz#83824bba77fbb3480dd6b35fbb06de7f9e93e80f"
@@ -16500,6 +16585,13 @@ lcid@^1.0.0:
   dependencies:
   dependencies:
     invert-kv "^1.0.0"
     invert-kv "^1.0.0"
 
 
+lcid@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf"
+  integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==
+  dependencies:
+    invert-kv "^2.0.0"
+
 lcov-parse@^1.0.0:
 lcov-parse@^1.0.0:
   version "1.0.0"
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0"
   resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0"
@@ -17210,6 +17302,13 @@ makeerror@1.0.x:
   dependencies:
   dependencies:
     tmpl "1.0.x"
     tmpl "1.0.x"
 
 
+map-age-cleaner@^0.1.1:
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a"
+  integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==
+  dependencies:
+    p-defer "^1.0.0"
+
 map-cache@^0.2.2:
 map-cache@^0.2.2:
   version "0.2.2"
   version "0.2.2"
   resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
   resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
@@ -17397,6 +17496,15 @@ mem@^1.1.0:
   dependencies:
   dependencies:
     mimic-fn "^1.0.0"
     mimic-fn "^1.0.0"
 
 
+mem@^4.0.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178"
+  integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==
+  dependencies:
+    map-age-cleaner "^0.1.1"
+    mimic-fn "^2.0.0"
+    p-is-promise "^2.0.0"
+
 memoize-one@^5.0.0, memoize-one@^5.1.1:
 memoize-one@^5.0.0, memoize-one@^5.1.1:
   version "5.1.1"
   version "5.1.1"
   resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0"
   resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0"
@@ -17623,7 +17731,7 @@ mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24:
   dependencies:
   dependencies:
     mime-db "1.42.0"
     mime-db "1.42.0"
 
 
-mime-types@^2.1.18, mime-types@^2.1.26, mime-types@~2.1.17:
+mime-types@^2.1.18, mime-types@^2.1.22, mime-types@^2.1.26, mime-types@~2.1.17:
   version "2.1.27"
   version "2.1.27"
   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f"
   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f"
   integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==
   integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==
@@ -17645,7 +17753,7 @@ mimic-fn@^1.0.0:
   resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
   resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
   integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
   integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
 
 
-mimic-fn@^2.1.0:
+mimic-fn@^2.0.0, mimic-fn@^2.1.0:
   version "2.1.0"
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
   resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
   integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
   integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
@@ -17680,6 +17788,14 @@ mini-create-react-context@^0.4.0:
     "@babel/runtime" "^7.5.5"
     "@babel/runtime" "^7.5.5"
     tiny-warning "^1.0.3"
     tiny-warning "^1.0.3"
 
 
+mini-css-extract-plugin@0.4.0:
+  version "0.4.0"
+  resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.0.tgz#ff3bf08bee96e618e177c16ca6131bfecef707f9"
+  integrity sha512-2Zik6PhUZ/MbiboG6SDS9UTPL4XXy4qnyGjSdCIWRrr8xb6PwLtHE+AYOjkXJWdF0OG8vo/yrJ8CgS5WbMpzIg==
+  dependencies:
+    loader-utils "^1.1.0"
+    webpack-sources "^1.1.0"
+
 mini-css-extract-plugin@0.6.0:
 mini-css-extract-plugin@0.6.0:
   version "0.6.0"
   version "0.6.0"
   resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.6.0.tgz#a3f13372d6fcde912f3ee4cd039665704801e3b9"
   resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.6.0.tgz#a3f13372d6fcde912f3ee4cd039665704801e3b9"
@@ -19199,6 +19315,15 @@ os-locale@^2.0.0:
     lcid "^1.0.0"
     lcid "^1.0.0"
     mem "^1.1.0"
     mem "^1.1.0"
 
 
+os-locale@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a"
+  integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==
+  dependencies:
+    execa "^1.0.0"
+    lcid "^2.0.0"
+    mem "^4.0.0"
+
 os-name@^3.1.0:
 os-name@^3.1.0:
   version "3.1.0"
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801"
   resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801"
@@ -19237,6 +19362,11 @@ p-cancelable@^1.0.0:
   resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
   resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
   integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
   integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
 
 
+p-defer@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c"
+  integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=
+
 p-defer@^3.0.0:
 p-defer@^3.0.0:
   version "3.0.0"
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-3.0.0.tgz#d1dceb4ee9b2b604b1d94ffec83760175d4e6f83"
   resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-3.0.0.tgz#d1dceb4ee9b2b604b1d94ffec83760175d4e6f83"
@@ -19257,6 +19387,11 @@ p-finally@^2.0.0:
   resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561"
   resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561"
   integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==
   integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==
 
 
+p-is-promise@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e"
+  integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==
+
 p-limit@^1.1.0:
 p-limit@^1.1.0:
   version "1.3.0"
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
   resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
@@ -20515,6 +20650,21 @@ promise-inflight@^1.0.1:
   resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
   resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
   integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
   integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
 
 
+promise-polyfill@7.1.0:
+  version "7.1.0"
+  resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-7.1.0.tgz#4d749485b44577c14137591c6f36e5d7e2dd3378"
+  integrity sha512-P6NJ2wU/8fac44ENORsuqT8TiolKGB2u0fEClPtXezn7w5cmLIjM/7mhPlTebke2EPr6tmqZbXvnX0TxwykGrg==
+
+promise-polyfill@8.0.0:
+  version "8.0.0"
+  resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.0.0.tgz#b47c7fc74052cc5b2132b703cca144f1a5eb56ef"
+  integrity sha512-QGmPnw2hDEaRS6freHynJ7nfS1nDg0/P0c/CGglA43utoJjYQMiY9ojEpK0HaJ4wbUztdmwqQRlEfGWdsEQ5uQ==
+
+promise-polyfill@8.1.3:
+  version "8.1.3"
+  resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.1.3.tgz#8c99b3cf53f3a91c68226ffde7bde81d7f904116"
+  integrity sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==
+
 promise-retry@^1.1.1:
 promise-retry@^1.1.1:
   version "1.1.1"
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d"
   resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d"
@@ -21005,6 +21155,28 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8:
     minimist "^1.2.0"
     minimist "^1.2.0"
     strip-json-comments "~2.0.1"
     strip-json-comments "~2.0.1"
 
 
+react-aplayer@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/react-aplayer/-/react-aplayer-1.0.0.tgz#ff8bae803c01d479126b072980783242294fae94"
+  integrity sha512-jGoNhjT8cEieakK5fwXVn2J849RAa4JAx+subEtrAr/34DWpEF8KZohedceyAzsJygSmBWVjX3plNoOMBbPlhA==
+  dependencies:
+    aplayer "^1.10.0"
+    prop-types "^15.6.1"
+    react "^16.2.0"
+
+react-beautiful-dnd@^12.0.0:
+  version "12.2.0"
+  resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-12.2.0.tgz#e5f6222f9e7934c6ed4ee09024547f9e353ae423"
+  integrity sha512-s5UrOXNDgeEC+sx65IgbeFlqKKgK3c0UfbrJLWufP34WBheyu5kJ741DtJbsSgPKyNLkqfswpMYr0P8lRj42cA==
+  dependencies:
+    "@babel/runtime-corejs2" "^7.6.3"
+    css-box-model "^1.2.0"
+    memoize-one "^5.1.1"
+    raf-schd "^4.0.2"
+    react-redux "^7.1.1"
+    redux "^4.0.4"
+    use-memo-one "^1.1.1"
+
 react-beautiful-dnd@^13.0.0:
 react-beautiful-dnd@^13.0.0:
   version "13.0.0"
   version "13.0.0"
   resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-13.0.0.tgz#f70cc8ff82b84bc718f8af157c9f95757a6c3b40"
   resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-13.0.0.tgz#f70cc8ff82b84bc718f8af157c9f95757a6c3b40"
@@ -21118,6 +21290,15 @@ react-dom@^16.13.1, react-dom@^16.8.3:
     prop-types "^15.6.2"
     prop-types "^15.6.2"
     scheduler "^0.19.1"
     scheduler "^0.19.1"
 
 
+react-dplayer@^0.2.3:
+  version "0.2.3"
+  resolved "https://registry.yarnpkg.com/react-dplayer/-/react-dplayer-0.2.3.tgz#45d46ef256df4e69f642a900e8f607c98cb1b8cf"
+  integrity sha512-CcZCeolaGqxfiKF+Fnb8sUYt2gauxXpivZkr3X0Um9l5c/qMsZ2K0fQEV5nGBdTWMQEz2dh01c9vHk5pN3klGg==
+  dependencies:
+    classnames "^2.2.6"
+    dplayer "^1.24.0"
+    prop-types "^15.6.2"
+
 react-draggable@^4.0.3:
 react-draggable@^4.0.3:
   version "4.4.3"
   version "4.4.3"
   resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.3.tgz#0727f2cae5813e36b0e4962bf11b2f9ef2b406f3"
   resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.3.tgz#0727f2cae5813e36b0e4962bf11b2f9ef2b406f3"
@@ -21400,7 +21581,7 @@ react@^16.12.0:
     object-assign "^4.1.1"
     object-assign "^4.1.1"
     prop-types "^15.6.2"
     prop-types "^15.6.2"
 
 
-react@^16.13.1, react@^16.8.3:
+react@^16.13.1, react@^16.2.0, react@^16.8.3:
   version "16.13.1"
   version "16.13.1"
   resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
   resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
   integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==
   integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==
@@ -23062,6 +23243,11 @@ smoothscroll-polyfill@^0.4.3:
   resolved "https://registry.yarnpkg.com/smoothscroll-polyfill/-/smoothscroll-polyfill-0.4.4.tgz#3a259131dc6930e6ca80003e1cb03b603b69abf8"
   resolved "https://registry.yarnpkg.com/smoothscroll-polyfill/-/smoothscroll-polyfill-0.4.4.tgz#3a259131dc6930e6ca80003e1cb03b603b69abf8"
   integrity sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg==
   integrity sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg==
 
 
+smoothscroll@0.4.0:
+  version "0.4.0"
+  resolved "https://registry.yarnpkg.com/smoothscroll/-/smoothscroll-0.4.0.tgz#40e507b46461408ba1b787d0081e1e883c4124a5"
+  integrity sha512-sggQ3U2Un38b3+q/j1P4Y4fCboCtoUIaBYoge+Lb6Xg1H8RTIif/hugVr+ErMtIDpvBbhQfTjtiTeYAfbw1ZGQ==
+
 snapdragon-node@^2.0.1:
 snapdragon-node@^2.0.1:
   version "2.1.1"
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
   resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
@@ -25684,16 +25870,16 @@ uuid@^8.2.0, uuid@^8.3.0:
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea"
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea"
   integrity sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==
   integrity sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==
 
 
+v8-compile-cache@^2.0.0, v8-compile-cache@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745"
+  integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==
+
 v8-compile-cache@^2.0.3:
 v8-compile-cache@^2.0.3:
   version "2.1.0"
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e"
   resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e"
   integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==
   integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==
 
 
-v8-compile-cache@^2.1.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745"
-  integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==
-
 v8-to-istanbul@^4.1.3:
 v8-to-istanbul@^4.1.3:
   version "4.1.4"
   version "4.1.4"
   resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz#b97936f21c0e2d9996d4985e5c5156e9d4e49cd6"
   resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz#b97936f21c0e2d9996d4985e5c5156e9d4e49cd6"
@@ -26091,6 +26277,23 @@ webpack-chain@^6.0.0:
     deepmerge "^1.5.2"
     deepmerge "^1.5.2"
     javascript-stringify "^2.0.1"
     javascript-stringify "^2.0.1"
 
 
+webpack-cli@3.0.4:
+  version "3.0.4"
+  resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.0.4.tgz#55d6ad2cdd608de8c0f757dde5bc4bf5bd2dec68"
+  integrity sha512-r5R0hMck4GxUS6a3TXClwi1KhQfnHZRtIfXqsSytQZG4kawKMhTtd5//uNZGoGks/h61Zv5jMnR6jwx15Qf8dA==
+  dependencies:
+    chalk "^2.4.1"
+    cross-spawn "^6.0.5"
+    enhanced-resolve "^4.0.0"
+    global-modules-path "^2.1.0"
+    import-local "^1.0.0"
+    inquirer "^6.0.0"
+    interpret "^1.1.0"
+    loader-utils "^1.1.0"
+    supports-color "^5.4.0"
+    v8-compile-cache "^2.0.0"
+    yargs "^11.1.0"
+
 webpack-cli@^3.3.12:
 webpack-cli@^3.3.12:
   version "3.3.12"
   version "3.3.12"
   resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.12.tgz#94e9ada081453cd0aa609c99e500012fd3ad2d4a"
   resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.12.tgz#94e9ada081453cd0aa609c99e500012fd3ad2d4a"
@@ -26719,6 +26922,13 @@ yargs-parser@^8.1.0:
   dependencies:
   dependencies:
     camelcase "^4.1.0"
     camelcase "^4.1.0"
 
 
+yargs-parser@^9.0.2:
+  version "9.0.2"
+  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077"
+  integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=
+  dependencies:
+    camelcase "^4.1.0"
+
 yargs@^10.0.3:
 yargs@^10.0.3:
   version "10.1.2"
   version "10.1.2"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.1.2.tgz#454d074c2b16a51a43e2fb7807e4f9de69ccb5c5"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.1.2.tgz#454d074c2b16a51a43e2fb7807e4f9de69ccb5c5"
@@ -26737,6 +26947,24 @@ yargs@^10.0.3:
     y18n "^3.2.1"
     y18n "^3.2.1"
     yargs-parser "^8.1.0"
     yargs-parser "^8.1.0"
 
 
+yargs@^11.1.0:
+  version "11.1.1"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.1.tgz#5052efe3446a4df5ed669c995886cc0f13702766"
+  integrity sha512-PRU7gJrJaXv3q3yQZ/+/X6KBswZiaQ+zOmdprZcouPYtQgvNU35i+68M4b1ZHLZtYFT5QObFLV+ZkmJYcwKdiw==
+  dependencies:
+    cliui "^4.0.0"
+    decamelize "^1.1.1"
+    find-up "^2.1.0"
+    get-caller-file "^1.0.1"
+    os-locale "^3.1.0"
+    require-directory "^2.1.1"
+    require-main-filename "^1.0.1"
+    set-blocking "^2.0.0"
+    string-width "^2.0.0"
+    which-module "^2.0.0"
+    y18n "^3.2.1"
+    yargs-parser "^9.0.2"
+
 yargs@^13.2.2, yargs@^13.3.2:
 yargs@^13.2.2, yargs@^13.3.2:
   version "13.3.2"
   version "13.3.2"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd"