소스 검색

Remove joy-media

Leszek Wiesner 4 년 전
부모
커밋
cdc0d08b6b
100개의 변경된 파일1개의 추가작업 그리고 6785개의 파일을 삭제
  1. 0 1
      pioneer/.eslintignore
  2. 1 2
      pioneer/packages/apps/public/locales/en/index.json
  3. 0 5
      pioneer/packages/apps/public/locales/en/joy-media.json
  4. 0 0
      pioneer/packages/joy-media/.skip-build
  5. 0 3
      pioneer/packages/joy-media/README.md
  6. 0 2
      pioneer/packages/joy-media/aplayer.d.ts
  7. 0 2
      pioneer/packages/joy-media/dplayer.d.ts
  8. 0 26
      pioneer/packages/joy-media/package.json
  9. 0 204
      pioneer/packages/joy-media/src/DiscoveryProvider.tsx
  10. 0 62
      pioneer/packages/joy-media/src/IterableFile.ts
  11. 0 98
      pioneer/packages/joy-media/src/MediaView.tsx
  12. 0 40
      pioneer/packages/joy-media/src/TransportContext.tsx
  13. 0 400
      pioneer/packages/joy-media/src/Upload.tsx
  14. 0 37
      pioneer/packages/joy-media/src/channels/ChannelAvatar.tsx
  15. 0 23
      pioneer/packages/joy-media/src/channels/ChannelAvatarAndName.tsx
  16. 0 20
      pioneer/packages/joy-media/src/channels/ChannelHeader.tsx
  17. 0 34
      pioneer/packages/joy-media/src/channels/ChannelHelpers.ts
  18. 0 19
      pioneer/packages/joy-media/src/channels/ChannelNameAsLink.tsx
  19. 0 114
      pioneer/packages/joy-media/src/channels/ChannelPreview.tsx
  20. 0 43
      pioneer/packages/joy-media/src/channels/ChannelPreviewStats.tsx
  21. 0 79
      pioneer/packages/joy-media/src/channels/ChannelsByOwner.tsx
  22. 0 34
      pioneer/packages/joy-media/src/channels/ChannelsByOwner.view.tsx
  23. 0 94
      pioneer/packages/joy-media/src/channels/CurationPanel.tsx
  24. 0 219
      pioneer/packages/joy-media/src/channels/EditChannel.tsx
  25. 0 38
      pioneer/packages/joy-media/src/channels/EditChannel.view.tsx
  26. 0 41
      pioneer/packages/joy-media/src/channels/ViewChannel.tsx
  27. 0 35
      pioneer/packages/joy-media/src/channels/ViewChannel.view.tsx
  28. 0 47
      pioneer/packages/joy-media/src/channels/ViewMusicChannel.tsx
  29. 0 34
      pioneer/packages/joy-media/src/channels/ViewVideoChannel.tsx
  30. 0 51
      pioneer/packages/joy-media/src/channels/YouHaveNoChannels.tsx
  31. 0 43
      pioneer/packages/joy-media/src/common/BgImg.tsx
  32. 0 59
      pioneer/packages/joy-media/src/common/FormTabs.tsx
  33. 0 44
      pioneer/packages/joy-media/src/common/MediaDropdownOptions.tsx
  34. 0 202
      pioneer/packages/joy-media/src/common/MediaForms.tsx
  35. 0 145
      pioneer/packages/joy-media/src/common/MediaPlayerView.tsx
  36. 0 159
      pioneer/packages/joy-media/src/common/MediaPlayerWithResolver.tsx
  37. 0 7
      pioneer/packages/joy-media/src/common/NoContentYet.tsx
  38. 0 44
      pioneer/packages/joy-media/src/common/TypeHelpers.ts
  39. 0 17
      pioneer/packages/joy-media/src/common/images.tsx
  40. 0 405
      pioneer/packages/joy-media/src/common/index.scss
  41. 0 10
      pioneer/packages/joy-media/src/entities/ChannelEntity.ts
  42. 0 15
      pioneer/packages/joy-media/src/entities/EntityHelpers.ts
  43. 0 26
      pioneer/packages/joy-media/src/entities/MusicAlbumEntity.ts
  44. 0 18
      pioneer/packages/joy-media/src/entities/MusicTrackEntity.ts
  45. 0 28
      pioneer/packages/joy-media/src/explore/AllChannels.tsx
  46. 0 27
      pioneer/packages/joy-media/src/explore/AllVideos.tsx
  47. 0 54
      pioneer/packages/joy-media/src/explore/ExploreContent.tsx
  48. 0 23
      pioneer/packages/joy-media/src/explore/ExploreContent.view.tsx
  49. 0 92
      pioneer/packages/joy-media/src/explore/PlayContent.tsx
  50. 0 133
      pioneer/packages/joy-media/src/index.scss
  51. 0 82
      pioneer/packages/joy-media/src/index.tsx
  52. 0 14
      pioneer/packages/joy-media/src/mocks/ContentLicense.mock.ts
  53. 0 18
      pioneer/packages/joy-media/src/mocks/CurationStatus.mock.ts
  54. 0 9
      pioneer/packages/joy-media/src/mocks/EntityId.mock.ts
  55. 0 10
      pioneer/packages/joy-media/src/mocks/FeaturedContent.mock.ts
  56. 0 11
      pioneer/packages/joy-media/src/mocks/Language.mock.ts
  57. 0 17
      pioneer/packages/joy-media/src/mocks/MediaObject.mock.ts
  58. 0 34
      pioneer/packages/joy-media/src/mocks/MusicAlbum.mock.ts
  59. 0 31
      pioneer/packages/joy-media/src/mocks/MusicGenre.mock.ts
  60. 0 299
      pioneer/packages/joy-media/src/mocks/MusicMood.mock.ts
  61. 0 192
      pioneer/packages/joy-media/src/mocks/MusicTheme.mock.ts
  62. 0 33
      pioneer/packages/joy-media/src/mocks/MusicTrack.mock.ts
  63. 0 16
      pioneer/packages/joy-media/src/mocks/PublicationStatus.mock.ts
  64. 0 53
      pioneer/packages/joy-media/src/mocks/Video.mock.ts
  65. 0 25
      pioneer/packages/joy-media/src/mocks/VideoCategory.mock.ts
  66. 0 14
      pioneer/packages/joy-media/src/mocks/index.ts
  67. 0 14
      pioneer/packages/joy-media/src/music/EditAlbumModal.tsx
  68. 0 180
      pioneer/packages/joy-media/src/music/EditMusicAlbum.tsx
  69. 0 16
      pioneer/packages/joy-media/src/music/EditMusicAlbum.view.tsx
  70. 0 40
      pioneer/packages/joy-media/src/music/MusicAlbumPreview.tsx
  71. 0 59
      pioneer/packages/joy-media/src/music/MusicAlbumTracks.tsx
  72. 0 59
      pioneer/packages/joy-media/src/music/MusicTrackPreview.tsx
  73. 0 31
      pioneer/packages/joy-media/src/music/MusicTrackReaderPreview.tsx
  74. 0 27
      pioneer/packages/joy-media/src/music/MyMusicAlbums.tsx
  75. 0 164
      pioneer/packages/joy-media/src/music/MyMusicTracks.tsx
  76. 0 91
      pioneer/packages/joy-media/src/music/ReorderableTracks.tsx
  77. 0 168
      pioneer/packages/joy-media/src/schemas/channel/Channel.ts
  78. 0 60
      pioneer/packages/joy-media/src/schemas/general/ContentLicense.ts
  79. 0 60
      pioneer/packages/joy-media/src/schemas/general/CurationStatus.ts
  80. 0 83
      pioneer/packages/joy-media/src/schemas/general/FeaturedContent.ts
  81. 0 60
      pioneer/packages/joy-media/src/schemas/general/Language.ts
  82. 0 60
      pioneer/packages/joy-media/src/schemas/general/MediaObject.ts
  83. 0 60
      pioneer/packages/joy-media/src/schemas/general/PublicationStatus.ts
  84. 0 308
      pioneer/packages/joy-media/src/schemas/music/MusicAlbum.ts
  85. 0 60
      pioneer/packages/joy-media/src/schemas/music/MusicGenre.ts
  86. 0 60
      pioneer/packages/joy-media/src/schemas/music/MusicMood.ts
  87. 0 60
      pioneer/packages/joy-media/src/schemas/music/MusicTheme.ts
  88. 0 292
      pioneer/packages/joy-media/src/schemas/music/MusicTrack.ts
  89. 0 230
      pioneer/packages/joy-media/src/schemas/video/Video.ts
  90. 0 60
      pioneer/packages/joy-media/src/schemas/video/VideoCategory.ts
  91. 0 13
      pioneer/packages/joy-media/src/stories/ExploreContent.stories.tsx
  92. 0 30
      pioneer/packages/joy-media/src/stories/MusicAlbumTracks.stories.tsx
  93. 0 26
      pioneer/packages/joy-media/src/stories/MusicChannel.stories.tsx
  94. 0 33
      pioneer/packages/joy-media/src/stories/MyChannels.stories.tsx
  95. 0 17
      pioneer/packages/joy-media/src/stories/MyMusicAlbums.stories.tsx
  96. 0 31
      pioneer/packages/joy-media/src/stories/Playback.stories.tsx
  97. 0 26
      pioneer/packages/joy-media/src/stories/UploadAudio.stories.tsx
  98. 0 26
      pioneer/packages/joy-media/src/stories/UploadVideo.stories.tsx
  99. 0 7
      pioneer/packages/joy-media/src/stories/data/AccountIdSamples.ts
  100. 0 58
      pioneer/packages/joy-media/src/stories/data/ChannelSamples.ts

+ 0 - 1
pioneer/.eslintignore

@@ -1,6 +1,5 @@
 **/build/*
 **/coverage/*
 **/node_modules/*
-packages/joy-media/**
 .eslintrc.js
 i18next-scanner.config.js

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

@@ -22,7 +22,6 @@
   "apps-routing.json",
   "apps.json",
   "joy-election.json",
-  "joy-media.json",
   "joy-members.json",
   "joy-proposals.json",
   "joy-roles.json",
@@ -32,4 +31,4 @@
   "react-params.json",
   "react-query.json",
   "react-signer.json"
-]
+]

+ 0 - 5
pioneer/packages/apps/public/locales/en/joy-media.json

@@ -1,5 +0,0 @@
-{
-  "Explore": "Explore",
-  "My channels": "My channels",
-  "My videos": "My videos"
-}

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


+ 0 - 3
pioneer/packages/joy-media/README.md

@@ -1,3 +0,0 @@
-# Media content module for Joystream node
-
-This module works with multi-media content such as audio and video.

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

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

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

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

+ 0 - 26
pioneer/packages/joy-media/package.json

@@ -1,26 +0,0 @@
-{
-  "name": "@polkadot/joy-media",
-  "version": "0.1.1",
-  "description": "Media content module for Joystream node",
-  "main": "index.js",
-  "scripts": {},
-  "author": "Joystream contributors",
-  "maintainers": [],
-  "dependencies": {
-    "@babel/runtime": "^7.10.5",
-    "@polkadot/joy-utils": "^0.1.1",
-    "@polkadot/react-components": "0.51.1",
-    "@polkadot/react-query": "0.51.1",
-    "@types/mime-types": "^2.1.0",
-    "@types/react-beautiful-dnd": "^11.0.3",
-    "aplayer": "^1.10.1",
-    "dplayer": "1.25.0",
-    "ipfs-only-hash": "^1.0.2",
-    "iso-639-1": "^2.1.0",
-    "lodash": "^4.17.11",
-    "mime-types": "^2.1.22",
-    "react-aplayer": "^1.0.0",
-    "react-beautiful-dnd": "^12.0.0",
-    "react-dplayer": "^0.2.3"
-  }
-}

+ 0 - 204
pioneer/packages/joy-media/src/DiscoveryProvider.tsx

@@ -1,204 +0,0 @@
-import React, { useState, useEffect, useContext, createContext } from 'react';
-import { Message } from 'semantic-ui-react';
-import axios, { CancelToken } from 'axios';
-
-import { StorageProviderId } from '@joystream/types/working-group';
-import { Vec } from '@polkadot/types';
-import { Url } from '@joystream/types/discovery';
-import ApiContext from '@polkadot/react-api/ApiContext';
-import { ApiProps } from '@polkadot/react-api/types';
-import { JoyInfo } from '@polkadot/joy-utils/react/components';
-import { componentName } from '@polkadot/joy-utils/react/helpers';
-import { isObjectWithProperties } from '@polkadot/joy-utils/functions/misc';
-
-export type BootstrapNodes = {
-  bootstrapNodes?: Url[];
-};
-
-export type DiscoveryProvider = {
-  resolveAssetEndpoint: (provider: StorageProviderId, contentId?: string, cancelToken?: CancelToken) => Promise<string>;
-  reportUnreachable: (provider: StorageProviderId) => void;
-};
-
-export type DiscoveryProviderProps = {
-  discoveryProvider: DiscoveryProvider;
-};
-
-// return string Url with last `/` removed
-function normalizeUrl (url: string | Url): string {
-  const st: string = url.toString();
-
-  if (st.endsWith('/')) {
-    return st.substring(0, st.length - 1);
-  }
-
-  return st.toString();
-}
-
-type ProviderStats = {
-  assetApiEndpoint: string;
-  unreachableReports: number;
-  resolvedAt: number;
-}
-
-function newDiscoveryProvider ({ bootstrapNodes }: BootstrapNodes): DiscoveryProvider {
-  const stats = new Map<string, ProviderStats>();
-
-  const resolveAssetEndpoint = async (
-    storageProvider: StorageProviderId,
-    contentId?: string,
-    cancelToken?: CancelToken
-  ) => {
-    const providerKey = storageProvider.toString();
-
-    let stat = stats.get(providerKey);
-
-    if (
-      (!stat || (stat && (Date.now() > (stat.resolvedAt + (10 * 60 * 1000))))) &&
-      bootstrapNodes
-    ) {
-      for (let n = 0; n < bootstrapNodes.length; n++) {
-        const discoveryUrl = normalizeUrl(bootstrapNodes[n]);
-
-        try {
-          // eslint-disable-next-line no-new
-          new URL(discoveryUrl);
-        } catch (err) {
-          continue;
-        }
-
-        const serviceInfoQuery = `${discoveryUrl}/discover/v0/${storageProvider.toString()}`;
-
-        try {
-          console.log(`Resolving ${providerKey} using ${discoveryUrl}`);
-
-          const serviceInfo = await axios.get<unknown>(serviceInfoQuery, { cancelToken });
-
-          if (!serviceInfo) {
-            continue;
-          }
-
-          const { data } = serviceInfo;
-
-          if (!isObjectWithProperties(data, 'serialized') || typeof data.serialized !== 'string') {
-            continue;
-          }
-
-          const dataParsed = JSON.parse(data.serialized) as unknown;
-
-          if (
-            !isObjectWithProperties(dataParsed, 'asset') ||
-            !isObjectWithProperties(dataParsed.asset, 'endpoint') ||
-            typeof dataParsed.asset.endpoint !== 'string'
-          ) {
-            continue;
-          }
-
-          stats.set(providerKey, {
-            assetApiEndpoint: normalizeUrl(dataParsed.asset.endpoint),
-            unreachableReports: 0,
-            resolvedAt: Date.now()
-          });
-          break;
-        } catch (err) {
-          console.log(err);
-
-          if (axios.isCancel(err)) {
-            throw err;
-          }
-
-          continue;
-        }
-      }
-    }
-
-    stat = stats.get(providerKey);
-
-    console.log(stat);
-
-    if (stat) {
-      return `${stat.assetApiEndpoint}/asset/v0/${contentId || ''}`;
-    }
-
-    throw new Error('Resolving failed.');
-  };
-
-  const reportUnreachable = (provider: StorageProviderId) => {
-    const key = provider.toString();
-    const stat = stats.get(key);
-
-    if (stat) {
-      stat.unreachableReports = stat.unreachableReports + 1;
-    }
-  };
-
-  return { resolveAssetEndpoint, reportUnreachable };
-}
-
-const DiscoveryProviderContext = createContext<DiscoveryProvider>(undefined as unknown as DiscoveryProvider);
-
-export const DiscoveryProviderProvider = (props: React.PropsWithChildren<Record<any, unknown>>) => {
-  const api: ApiProps = useContext(ApiContext);
-  const [provider, setProvider] = useState<DiscoveryProvider | undefined>();
-  const [loaded, setLoaded] = useState<boolean | undefined>();
-
-  useEffect(() => {
-    const load = async () => {
-      if (loaded || !api) return;
-
-      console.log('Discovery Provider: Loading bootstrap node from Substrate...');
-      const bootstrapNodes = await api.api.query.discovery.bootstrapEndpoints() as Vec<Url>;
-
-      setProvider(newDiscoveryProvider({ bootstrapNodes }));
-      setLoaded(true);
-      console.log('Discovery Provider: Initialized');
-    };
-
-    void load();
-  }, [loaded]);
-
-  if (!api || !api.isApiReady) {
-    // Substrate API is not ready yet.
-    return null;
-  }
-
-  if (!provider) {
-    return (
-      <Message info className='JoyMainStatus'>
-        <Message.Header>Initializing Content Discovery Provider</Message.Header>
-        <div style={{ marginTop: '1rem' }}>
-          Loading bootstrap nodes... Please wait.
-        </div>
-      </Message>
-    );
-  }
-
-  return (
-    <DiscoveryProviderContext.Provider value={provider}>
-      {props.children}
-    </DiscoveryProviderContext.Provider>
-  );
-};
-
-export const useDiscoveryProvider = () =>
-  useContext(DiscoveryProviderContext);
-
-export function withDiscoveryProvider (Component: React.ComponentType<DiscoveryProviderProps>) {
-  const ResultComponent: React.FunctionComponent<Record<any, unknown>> = (props: React.PropsWithChildren<Record<any, unknown>>) => {
-    const discoveryProvider = useDiscoveryProvider();
-
-    if (!discoveryProvider) {
-      return <JoyInfo title={'Please wait...'}>Loading discovery provider.</JoyInfo>;
-    }
-
-    return (
-      <Component {...props} discoveryProvider={discoveryProvider}>
-        {props.children}
-      </Component>
-    );
-  };
-
-  ResultComponent.displayName = `withDiscoveryProvider(${componentName(Component)})`;
-
-  return ResultComponent;
-}

+ 0 - 62
pioneer/packages/joy-media/src/IterableFile.ts

@@ -1,62 +0,0 @@
-// Based on
-// https://gist.github.com/grishgrigoryan/bf6222d16d72cb28620399d27e83eb22
-
-interface IConfig{
-  chunkSize: number;
-}
-
-const DEFAULT_CHUNK_SIZE: number = 64 * 1024; // 64K
-
-export class IterableFile implements AsyncIterable<Buffer> {
-  private reader: FileReader;
-  private file: File
-  private config: IConfig = { chunkSize: DEFAULT_CHUNK_SIZE }
-
-  constructor (file: File, config: Partial<IConfig> = {}) {
-    this.file = file;
-    this.reader = new FileReader();
-    Object.assign(this.config, config);
-  }
-
-  [Symbol.asyncIterator] () {
-    return this.readFile();
-  }
-
-  get chunkSize () {
-    return this.config.chunkSize;
-  }
-
-  get fileSize () {
-    return this.file.size;
-  }
-
-  readBlobAsBuffer (blob: Blob): Promise<Buffer> {
-    return new Promise((resolve, reject) => {
-      this.reader.onload = (e) => {
-        e.target?.result && resolve(typeof e.target.result === 'string' ? Buffer.from(e.target.result) : Buffer.from(e.target.result));
-        e.target?.error && reject(e.target.error);
-      };
-
-      this.reader.readAsArrayBuffer(blob);
-    });
-  }
-
-  async * readFile () {
-    let offset = 0;
-    let blob;
-    let result;
-
-    while (offset < this.fileSize) {
-      blob = this.file.slice(offset, this.chunkSize + offset);
-      result = await this.readBlobAsBuffer(blob);
-      offset += result.length;
-      yield result;
-    }
-  }
-}
-
-// Usage:
-//  let iterableFile = new IterableFile(file)
-//  for await (const chunk: Buffer of iterableFile) {
-//      doSomethingWithBuffer(chunk)
-//  }

+ 0 - 98
pioneer/packages/joy-media/src/MediaView.tsx

@@ -1,98 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import { MediaTransport } from './transport';
-import { MemberId } from '@joystream/types/members';
-import { useMyMembership } from '@polkadot/joy-utils/react/hooks';
-import { useTransportContext } from './TransportContext';
-import { withMembershipRequired } from '@polkadot/joy-utils/react/hocs/guards';
-import { useApi } from '@polkadot/react-hooks';
-import { ApiPromise } from '@polkadot/api';
-import { isObjectWithProperties } from '@polkadot/joy-utils/functions/misc';
-
-type InitialPropsWithMembership<A> = A & {
-  myAddress?: string;
-  myMemberId?: MemberId;
-}
-
-type ResolverProps<A> = InitialPropsWithMembership<A> & {
-  transport: MediaTransport;
-  api: ApiPromise;
-}
-
-type BaseProps<A, B> = {
-  component: React.ComponentType<A & B>;
-  unresolvedView?: React.ReactElement;
-  resolveProps?: (props: ResolverProps<A>) => Promise<B>;
-
-  /**
-   * Array of property names that can trigger re-render of the view,
-   * if values of such properties changed.
-   */
-  triggers?: (keyof A)[];
-
-  /** Set `true` if only members should have access to this component. `false` by default. */
-  membersOnly?: boolean;
-}
-
-function serializeTrigger (val: unknown): number | boolean | string | undefined {
-  if (['number', 'boolean', 'string'].includes(typeof val)) {
-    return val as number | boolean | string;
-  } else if (isObjectWithProperties(val, 'toString') && typeof val.toString === 'function') {
-    return val.toString() as string;
-  } else {
-    return undefined;
-  }
-}
-
-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) {
-    const { component: Component, resolveProps, triggers = [], unresolvedView = null } = baseProps;
-
-    const transport = useTransportContext();
-    const { myAddress, myMemberId } = useMyMembership();
-    const { api } = useApi();
-    const resolverProps = { ...initialProps, transport, api, myAddress, myMemberId };
-
-    const [resolvedProps, setResolvedProps] = useState({} as B);
-    const [propsResolved, setPropsResolved] = useState(false);
-
-    const initialDeps = triggers.map((propName) => serializeTrigger(initialProps[propName]));
-    const rerenderDeps = [...initialDeps, myAddress];
-
-    useEffect(() => {
-      async function doResolveProps () {
-        if (typeof resolveProps !== 'function') return;
-
-        console.log('Resolving props of media view');
-
-        // Transport session allows us to cache loaded channels, entites and classes
-        // during the render of this view:
-        transport.openSession();
-        setResolvedProps(await resolveProps(resolverProps));
-        transport.closeSession();
-        setPropsResolved(true);
-      }
-
-      if (!transport) {
-        console.error('Transport is not defined');
-      } else {
-        void doResolveProps();
-      }
-    }, rerenderDeps);
-
-    console.log('Rerender deps of Media View:', rerenderDeps);
-
-    const renderResolving = () => {
-      return unresolvedView || <div className='ui active centered inline loader' />;
-    };
-
-    return propsResolved
-      ? <Component {...initialProps} {...resolvedProps} />
-      : renderResolving();
-  }
-
-  const { membersOnly = false } = baseProps;
-
-  return membersOnly
-    ? withMembershipRequired(InnerView)
-    : InnerView;
-}

+ 0 - 40
pioneer/packages/joy-media/src/TransportContext.tsx

@@ -1,40 +0,0 @@
-import React, { useEffect, useState, useContext, createContext } from 'react';
-import { MediaTransport } from './transport';
-import { MockTransport } from './transport.mock';
-import { SubstrateTransport } from './transport.substrate';
-import ApiContext from '@polkadot/react-api/ApiContext';
-import { ApiProps } from '@polkadot/react-api/types';
-
-export const TransportContext = createContext<MediaTransport>(undefined as unknown as MediaTransport);
-
-export const useTransportContext = () =>
-  useContext(TransportContext);
-
-export const MockTransportProvider = (props: React.PropsWithChildren<Record<any, unknown>>) =>
-  <TransportContext.Provider value={new MockTransport()}>
-    {props.children}
-  </TransportContext.Provider>;
-
-export const SubstrateTransportProvider = (props: React.PropsWithChildren<Record<any, unknown>>) => {
-  const api: ApiProps = useContext(ApiContext);
-  const [transport, setTransport] = useState<SubstrateTransport>();
-  const [loaded, setLoaded] = useState<boolean>();
-
-  useEffect(() => {
-    if (!loaded && api && api.isApiReady) {
-      setTransport(new SubstrateTransport(api));
-      setLoaded(true);
-    }
-  }, [loaded]);
-
-  if (!transport) {
-    // Substrate API is not ready yet.
-    return null;
-  }
-
-  return (
-    <TransportContext.Provider value={transport}>
-      {props.children}
-    </TransportContext.Provider>
-  );
-};

+ 0 - 400
pioneer/packages/joy-media/src/Upload.tsx

@@ -1,400 +0,0 @@
-import React from 'react';
-import BN from 'bn.js';
-import axios, { CancelTokenSource, AxiosError, AxiosRequestConfig } from 'axios';
-import { History } from 'history';
-import { Progress, Message } from 'semantic-ui-react';
-
-import { registry } from '@joystream/types';
-import { InputFileAsync, TxButton, JoyInfo, Loading } from '@polkadot/joy-utils/react/components';
-import { ApiProps } from '@polkadot/react-api/types';
-import { I18nProps } from '@polkadot/react-components/types';
-import { SubmittableResult } from '@polkadot/api';
-import { Option } from '@polkadot/types/codec';
-import { withMulti, withApi } from '@polkadot/react-api';
-import { formatNumber } from '@polkadot/util';
-
-import translate from './translate';
-import { fileNameWoExt } from './utils';
-import { ContentId, DataObject } from '@joystream/types/media';
-import { MyAccountProps } from '@polkadot/joy-utils/react/hocs/accounts';
-import { withOnlyMembers } from '@polkadot/joy-utils/react/hocs/guards';
-import { DiscoveryProviderProps, withDiscoveryProvider } from './DiscoveryProvider';
-
-import IpfsHash from 'ipfs-only-hash';
-import { ChannelId } from '@joystream/types/content-working-group';
-import { EditVideoView } from './upload/EditVideo.view';
-
-import { IterableFile } from './IterableFile';
-import { StorageProviderId } from '@joystream/types/working-group';
-import { normalizeError, isObjectWithProperties } from '@polkadot/joy-utils/functions/misc';
-
-const MAX_FILE_SIZE_MB = 500;
-const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
-
-type Props = ApiProps & I18nProps & DiscoveryProviderProps & MyAccountProps & {
-  channelId: ChannelId;
-  history?: History;
-  match: {
-    params: {
-      channelId: string;
-    };
-  };
-};
-
-type State = {
-  error?: string;
-  file?: File;
-  computingHash: boolean;
-  ipfs_cid?: string;
-  newContentId: ContentId;
-  discovering: boolean;
-  uploading: boolean;
-  sendingTx: boolean;
-  progress: number;
-  cancelSource: CancelTokenSource;
-};
-
-const defaultState = (): State => ({
-  error: undefined,
-  file: undefined,
-  computingHash: false,
-  ipfs_cid: undefined,
-  newContentId: ContentId.generate(registry),
-  discovering: false,
-  uploading: false,
-  sendingTx: false,
-  progress: 0,
-  cancelSource: axios.CancelToken.source()
-});
-
-class Upload extends React.PureComponent<Props, State> {
-  state = defaultState();
-
-  componentWillUnmount () {
-    this.setState({
-      discovering: false,
-      uploading: false
-    });
-
-    const { cancelSource } = this.state;
-
-    cancelSource.cancel('unmounting');
-  }
-
-  render () {
-    return (
-      <div className='UploadBox'>
-        {this.renderContent()}
-      </div>
-    );
-  }
-
-  private renderContent () {
-    const { error, uploading, discovering, computingHash, sendingTx } = this.state;
-
-    if (error) return this.renderError(error);
-    else if (discovering) return this.renderDiscovering();
-    else if (uploading) return this.renderUploading();
-    else if (computingHash) return this.renderComputingHash();
-    else if (sendingTx) return this.renderSendingTx();
-    else return this.renderFileInput();
-  }
-
-  private renderError (error: string) {
-    return (
-      <Message error className='JoyMainStatus'>
-        <Message.Header>Failed to upload your file</Message.Header>
-        <p>{error}</p>
-        <button className='ui button' onClick={this.resetForm}>Start over</button>
-      </Message>
-    );
-  }
-
-  private resetForm = () => {
-    const { cancelSource } = this.state;
-
-    this.setState({
-      ...defaultState(),
-      cancelSource
-    });
-  }
-
-  private renderUploading () {
-    const { file, newContentId, progress, error } = this.state;
-
-    if (!file || !file.name) return <JoyInfo title='Loading...' />;
-
-    const success = !error && progress >= 100;
-    const { history, match: { params: { channelId } }, api } = this.props;
-
-    return <div style={{ width: '100%' }}>
-      {this.renderProgress()}
-      {success &&
-        <EditVideoView
-          channelId={api.createType('ChannelId', channelId)}
-          contentId={newContentId}
-          fileName={fileNameWoExt(file.name)}
-          history={history}
-        />
-      }
-    </div>;
-  }
-
-  private renderSendingTx () {
-    return <JoyInfo title='Please wait...'><Loading text='Waiting for the transaction confirmation...' /></JoyInfo>;
-  }
-
-  private renderDiscovering () {
-    return <JoyInfo title={'Please wait...'}>Contacting storage provider.</JoyInfo>;
-  }
-
-  private renderProgress () {
-    const { progress, error } = this.state;
-    const active = !error && progress < 100;
-    const success = !error && progress >= 100;
-
-    let label = '';
-
-    if (active) {
-      label = 'Your file is uploading. Please keep this page open until it\'s done.';
-    } else if (success) {
-      label = 'Uploaded! Click "Publish" button to make your file live.';
-    }
-
-    return <Progress
-      className='UploadProgress'
-      progress={success}
-      percent={progress}
-      active={active}
-      success={success}
-      label={label}
-    />;
-  }
-
-  private renderFileInput () {
-    const { file } = this.state;
-    const file_size = file ? file.size : 0;
-    const file_name = file ? file.name : '';
-
-    return <div className='UploadSelectForm'>
-      <InputFileAsync
-        label=''
-        withLabel={false}
-        className={`UploadInputFile ${file_name ? 'FileSelected' : ''}`}
-        placeholder={
-          <div>
-            <div><i className='cloud upload icon'></i></div>
-            <div>{file_name
-              ? `${file_name} (${formatNumber(file_size)} bytes)`
-              : <>
-                <div>Drag and drop either video or audio file here.</div>
-                <div>Your file should not be more than {MAX_FILE_SIZE_MB} MB.</div>
-              </>
-            }</div>
-          </div>
-        }
-        onChange={this.onFileSelected}
-      />
-      {file_name && <div className='UploadButtonBox'>
-        <TxButton
-          label={'Upload'}
-          isDisabled={!file_name}
-          tx={'dataDirectory.addContent'}
-          params={this.buildTxParams()}
-          onClick={(sendTx) => {
-            this.setState({ sendingTx: true });
-            sendTx();
-          }}
-          txSuccessCb={ this.onDataObjectCreated }
-          txFailedCb={() => { this.setState({ sendingTx: false }); }}
-        />
-      </div>}
-    </div>;
-  }
-
-  private onFileSelected = (file: File) => {
-    if (!file.size) {
-      this.setState({ error: 'You cannot upload an empty file.' });
-    } else if (file.size > MAX_FILE_SIZE_BYTES) {
-      this.setState({
-        error:
-        `You can't upload files larger than ${MAX_FILE_SIZE_MB} MBytes in size.`
-      });
-    } else {
-      this.setState({ file, computingHash: true });
-      void this.startComputingHash();
-    }
-  }
-
-  private async startComputingHash () {
-    const { file } = this.state;
-
-    if (!file) {
-      return this.hashComputationComplete(undefined, 'No file passed to hasher');
-    }
-
-    try {
-      const iterableFile = new IterableFile(file, { chunkSize: 65535 });
-      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call
-      const ipfs_cid = (await IpfsHash.of(iterableFile)) as string;
-
-      this.hashComputationComplete(ipfs_cid);
-    } catch (err) {
-      return this.hashComputationComplete(undefined, err);
-    }
-  }
-
-  private hashComputationComplete (ipfs_cid: string | undefined, error?: string) {
-    if (!error) {
-      console.log('Computed IPFS hash:', ipfs_cid);
-    }
-
-    this.setState({
-      computingHash: false,
-      ipfs_cid,
-      error
-    });
-  }
-
-  private renderComputingHash () {
-    return <JoyInfo title='Processing your file. Please wait...' />;
-  }
-
-  private buildTxParams = () => {
-    const { file, newContentId, ipfs_cid } = this.state;
-
-    if (!file || !ipfs_cid) return [];
-
-    // TODO get corresponding data type id based on file content
-    const dataObjectTypeId = new BN(1);
-    const { myMemberId } = this.props;
-
-    return [myMemberId, newContentId, dataObjectTypeId, new BN(file.size), ipfs_cid];
-  }
-
-  private onDataObjectCreated = async (_txResult: SubmittableResult) => {
-    this.setState({ sendingTx: false, discovering: true });
-
-    const { api } = this.props;
-    const { newContentId } = this.state;
-    let dataObject: Option<DataObject>;
-
-    try {
-      dataObject = await api.query.dataDirectory.dataObjectByContentId(newContentId) as Option<DataObject>;
-    } catch (err) {
-      this.setState({
-        error: normalizeError(err),
-        discovering: false
-      });
-
-      return;
-    }
-
-    const { discovering } = this.state;
-
-    if (!discovering) {
-      return;
-    }
-
-    if (dataObject.isSome) {
-      const storageProvider = dataObject.unwrap().liaison;
-
-      void this.uploadFileTo(storageProvider);
-    } else {
-      this.setState({
-        error: 'No Storage Provider assigned to process upload',
-        discovering: false
-      });
-    }
-  }
-
-  private uploadFileTo = async (storageProvider: StorageProviderId) => {
-    const { file, newContentId, cancelSource } = this.state;
-
-    if (!file || !file.size) {
-      this.setState({
-        error: 'No file to upload!',
-        discovering: false
-      });
-
-      return;
-    }
-
-    const contentId = newContentId.encode();
-    const config: AxiosRequestConfig = {
-      headers: {
-        // TODO uncomment this once the issue fixed:
-        // https://github.com/Joystream/storage-node-joystream/issues/16
-        // 'Content-Type': file.type
-        'Content-Type': '' // <-- this is a temporary hack
-      },
-      cancelToken: cancelSource.token,
-      onUploadProgress: (progressEvent: unknown) => {
-        if (
-          !isObjectWithProperties(progressEvent, 'loaded', 'total') ||
-          typeof progressEvent.loaded !== 'number' ||
-          typeof progressEvent.total !== 'number'
-        ) {
-          return;
-        }
-
-        const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
-
-        this.setState({
-          progress: percentCompleted
-        });
-      }
-    };
-
-    const { discoveryProvider } = this.props;
-    let url: string;
-
-    try {
-      url = await discoveryProvider.resolveAssetEndpoint(storageProvider, contentId, cancelSource.token);
-    } catch (err) {
-      return this.setState({
-        error: `Failed to contact storage provider: ${normalizeError(err)}`,
-        discovering: false
-      });
-    }
-
-    const { discovering } = this.state;
-
-    if (!discovering) {
-      return;
-    }
-
-    // TODO: validate url .. must start with http
-
-    this.setState({ discovering: false, uploading: true, progress: 0 });
-
-    try {
-      await axios.put<{ message: string }>(url, file, config);
-    } catch (e) {
-      const err = e as unknown;
-
-      this.setState({ progress: 0, error: normalizeError(err), uploading: false });
-
-      if (axios.isCancel(err)) {
-        return;
-      }
-
-      const response = isObjectWithProperties(err, 'response')
-        ? (err as AxiosError).response
-        : undefined;
-
-      if (!response || (response.status >= 500 && response.status <= 504)) {
-        // network connection error
-        discoveryProvider.reportUnreachable(storageProvider);
-      }
-    }
-  }
-}
-
-export const UploadWithRouter = withMulti(
-  Upload,
-  translate,
-  withApi,
-  withOnlyMembers,
-  withDiscoveryProvider
-);

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

@@ -1,37 +0,0 @@
-import React from 'react';
-import { Link } from 'react-router-dom';
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { BgImg } from '../common/BgImg';
-import { DEFAULT_THUMBNAIL_URL } from '../common/images';
-
-const defaultSizePx = 75;
-
-export type ChannelAvatarSize = 'big' | 'default' | 'small';
-
-type Props = {
-  channel: ChannelEntity;
-  size?: ChannelAvatarSize;
-}
-
-function sizeToPx (size: ChannelAvatarSize): number {
-  switch (size) {
-    case 'big': return 100;
-    case 'small': return 35;
-    case 'default': return defaultSizePx;
-    default: return defaultSizePx;
-  }
-}
-
-export function ChannelAvatar (props: Props) {
-  const { channel, size = 'default' } = props;
-
-  return (
-    <Link to={`/media/channels/${channel.id}`}>
-      <BgImg
-        className={'ChannelAvatar ' + size}
-        url={channel.avatar || DEFAULT_THUMBNAIL_URL}
-        size={sizeToPx(size)}
-      />
-    </Link>
-  );
-}

+ 0 - 23
pioneer/packages/joy-media/src/channels/ChannelAvatarAndName.tsx

@@ -1,23 +0,0 @@
-import React from 'react';
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { ChannelAvatar } from './ChannelAvatar';
-import { ChannelNameAsLink } from './ChannelNameAsLink';
-
-type Props = {
-  channel: ChannelEntity;
-}
-
-export const ChannelAvatarAndName = (props: Props) => {
-  const { channel } = props;
-
-  return (
-    <div className={'ChannelPreview small'}>
-      <ChannelAvatar channel={channel} size='small' />
-      <div className='ChannelDetails'>
-        <h3 className='ChannelTitle' style={{ display: 'block' }}>
-          <ChannelNameAsLink channel={channel} />
-        </h3>
-      </div>
-    </div>
-  );
-};

+ 0 - 20
pioneer/packages/joy-media/src/channels/ChannelHeader.tsx

@@ -1,20 +0,0 @@
-import React from 'react';
-import { BgImg } from '../common/BgImg';
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { ChannelPreview } from './ChannelPreview';
-
-type Props = {
-  channel: ChannelEntity;
-}
-
-export function ChannelHeader (props: Props) {
-  const { channel } = props;
-  const { banner } = channel;
-
-  return (
-    <div className='ChannelHeader'>
-      {banner && <BgImg className='ChannelCover' url={banner} />}
-      <ChannelPreview channel={channel} size='big' withDescription />
-    </div>
-  );
-}

+ 0 - 34
pioneer/packages/joy-media/src/channels/ChannelHelpers.ts

@@ -1,34 +0,0 @@
-import { AccountId } from '@polkadot/types/interfaces';
-import { ChannelType } from '../schemas/channel/Channel';
-import { ChannelPublicationStatusAllValues } from '@joystream/types/content-working-group';
-
-export const ChannelPublicationStatusDropdownOptions =
-  ChannelPublicationStatusAllValues
-    .map((x) => ({ key: x, value: x, text: x }));
-
-export const isVideoChannel = (channel: ChannelType) => {
-  return channel.content === 'Video';
-};
-
-export const isMusicChannel = (channel: ChannelType) => {
-  return channel.content === 'Music';
-};
-
-export const isAccountAChannelOwner = (channel?: ChannelType, account?: AccountId | string): boolean => {
-  return (channel && account) ? channel.roleAccount.eq(account) : false;
-};
-
-export function isPublicChannel (channel: ChannelType): boolean {
-  return (
-    channel.publicationStatus === 'Public' &&
-    channel.curationStatus !== 'Censored'
-  );
-}
-
-export function isCensoredChannel (channel: ChannelType): boolean {
-  return channel.curationStatus === 'Censored';
-}
-
-export function isVerifiedChannel (channel: ChannelType): boolean {
-  return channel.verified;
-}

+ 0 - 19
pioneer/packages/joy-media/src/channels/ChannelNameAsLink.tsx

@@ -1,19 +0,0 @@
-import React from 'react';
-import { Link } from 'react-router-dom';
-import { ChannelEntity } from '../entities/ChannelEntity';
-
-type Props = {
-  channel: ChannelEntity;
-  className?: string;
-  style?: React.CSSProperties;
-}
-
-export const ChannelNameAsLink = (props: Props) => {
-  const { channel, className, style } = props;
-
-  return (
-    <Link to={`/media/channels/${channel.id}`} className={className} style={style}>
-      {channel.title || channel.handle}
-    </Link>
-  );
-};

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

@@ -1,114 +0,0 @@
-import React from 'react';
-import { Link } from 'react-router-dom';
-import ReactMarkdown from 'react-markdown';
-import { Icon, Label, SemanticICONS, SemanticCOLORS } from 'semantic-ui-react';
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { ChannelAvatar, ChannelAvatarSize } from './ChannelAvatar';
-import { isPublicChannel, isMusicChannel, isVideoChannel, isAccountAChannelOwner, isVerifiedChannel } from './ChannelHelpers';
-
-import { useMyMembership } from '@polkadot/joy-utils/react/hooks';
-import { nonEmptyStr } from '@polkadot/joy-utils/functions/misc';
-import { CurationPanel } from './CurationPanel';
-import { ChannelNameAsLink } from './ChannelNameAsLink';
-
-type ChannelPreviewProps = {
-  channel: ChannelEntity;
-  size?: ChannelAvatarSize;
-  withSubtitle?: boolean;
-  withDescription?: boolean;
-};
-
-export const ChannelPreview = (props: ChannelPreviewProps) => {
-  const { myAccountId } = useMyMembership();
-  const { channel, size, withSubtitle = true, withDescription } = props;
-
-  let subtitle: string | undefined;
-  let icon: 'music' | 'film' | undefined;
-
-  if (isMusicChannel(channel)) {
-    subtitle = 'Music channel';
-    icon = 'music';
-  } else if (isVideoChannel(channel)) {
-    subtitle = 'Video channel';
-    icon = 'film';
-  }
-
-  let visibilityIcon: SemanticICONS = 'eye';
-  let visibilityColor: SemanticCOLORS = 'green';
-  let visibilityText = 'Public';
-
-  if (!isPublicChannel(channel)) {
-    visibilityIcon = 'eye slash';
-    visibilityColor = 'orange';
-    visibilityText = 'Unlisted';
-  }
-
-  return <>
-    <div className={`ChannelPreview ${size || ''}`}>
-
-      <ChannelAvatar channel={channel} size={size} />
-
-      <div className='ChannelDetails'>
-        <h3 className='ChannelTitle' style={{ display: 'block' }}>
-          <ChannelNameAsLink channel={channel} style={{ marginRight: '1rem' }} />
-
-          {isAccountAChannelOwner(channel, myAccountId) &&
-            <div style={{ float: 'right' }}>
-
-              <Link to={`/media/channels/${channel.id}/edit`} className='ui button basic' style={{ marginRight: '1rem' }}>
-                <i className='icon pencil' />
-                Edit
-              </Link>
-
-              <Link to={`/media/channels/${channel.id}/upload`} className='ui button basic primary'>
-                <i className='icon upload' />
-                Upload {channel.content}
-              </Link>
-
-            </div>
-          }
-        </h3>
-
-        <div className='ChannelSubtitle'>
-
-          {withSubtitle && subtitle &&
-            <span style={{ marginRight: '1rem' }}>
-              {icon && <i className={`icon ${icon}`} />}
-              {subtitle}
-            </span>
-          }
-
-          <Label basic color={visibilityColor} style={{ marginRight: '1rem' }}>
-            <Icon name={visibilityIcon} />
-            {visibilityText}
-          </Label>
-
-          {channel.curationStatus !== 'Normal' &&
-            <Label basic color='red'>
-              <Icon name='dont' />
-              Channel {channel.curationStatus}
-              {' '}<Icon name='question circle outline' size='small' />
-            </Label>
-          }
-
-          {isVerifiedChannel(channel) &&
-            <Label basic color='blue'>
-              <i className='icon checkmark'/>
-              Verified
-            </Label>
-          }
-        </div>
-
-        <CurationPanel channel={channel} />
-
-        {withDescription && nonEmptyStr(channel.description) &&
-          <ReactMarkdown className='JoyMemo--full ChannelDesc' source={channel.description} linkTarget='_blank' />
-        }
-      </div>
-
-      {/* // TODO uncomment when we calculate reward and count of videos in channel: */}
-      {/* <ChannelStats channel={channel} /> */}
-
-    </div>
-  </>;
-};

+ 0 - 43
pioneer/packages/joy-media/src/channels/ChannelPreviewStats.tsx

@@ -1,43 +0,0 @@
-import React from 'react';
-import { Statistic } from 'semantic-ui-react';
-
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { formatNumber } from '@polkadot/util';
-
-type Props = {
-  channel: ChannelEntity;
-};
-
-export const ChannelPreviewStats = (props: Props) => {
-  const { channel } = props;
-  const statSize = 'tiny';
-
-  let itemsPublishedLabel = '';
-
-  if (channel.content === 'Video') {
-    itemsPublishedLabel = 'Videos';
-  } else if (channel.content === 'Music') {
-    itemsPublishedLabel = 'Music tracks';
-  }
-
-  return (
-    <div className='ChannelStats'>
-      <div>
-        <Statistic size={statSize}>
-          <Statistic.Label>Reward earned</Statistic.Label>
-          <Statistic.Value>
-            {formatNumber(channel.rewardEarned)}
-            &nbsp;<span style={{ fontSize: '1.5rem' }}>JOY</span>
-          </Statistic.Value>
-        </Statistic>
-      </div>
-
-      <div style={{ marginTop: '1rem' }}>
-        <Statistic size={statSize}>
-          <Statistic.Label>{itemsPublishedLabel}</Statistic.Label>
-          <Statistic.Value>{formatNumber(channel.contentItemsCount)}</Statistic.Value>
-        </Statistic>
-      </div>
-    </div>
-  );
-};

+ 0 - 79
pioneer/packages/joy-media/src/channels/ChannelsByOwner.tsx

@@ -1,79 +0,0 @@
-import React, { useState } from 'react';
-import { Link } from 'react-router-dom';
-import { Segment, Tab } from 'semantic-ui-react';
-import { AccountId } from '@polkadot/types/interfaces';
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { YouHaveNoChannels } from './YouHaveNoChannels';
-import { ChannelContentTypeValue } from '@joystream/types/content-working-group';
-import { ChannelPreview } from './ChannelPreview';
-
-export type ChannelsByOwnerProps = {
-  accountId: AccountId;
-  suspended?: boolean;
-  channels?: ChannelEntity[];
-};
-
-const TabsAndChannels = (props: ChannelsByOwnerProps) => {
-  const { channels: allChannels = [] } = props;
-  const [channels, setChannels] = useState(allChannels);
-
-  let videoChannelsCount = 0;
-  let musicChannelsCount = 0;
-
-  allChannels.forEach((x) => {
-    if (x.content === 'Video') {
-      videoChannelsCount++;
-    } else if (x.content === 'Music') {
-      musicChannelsCount++;
-    }
-  });
-
-  const panes = [
-    { menuItem: `All channels (${allChannels.length})` },
-    { menuItem: `Video channels (${videoChannelsCount})` },
-    { menuItem: `Music channels (${musicChannelsCount})` }
-  ];
-
-  const contentTypeByTabIndex: Array<ChannelContentTypeValue | undefined> =
-    [undefined, 'Video', 'Music'];
-
-  const switchTab = (activeIndex: number) => {
-    const activeContentType = contentTypeByTabIndex[activeIndex];
-
-    if (activeContentType === undefined) {
-      setChannels(allChannels);
-    } else {
-      setChannels(allChannels.filter(
-        (x) => x.content === activeContentType)
-      );
-    }
-  };
-
-  return <>
-    <Tab
-      panes={panes}
-      menu={{ secondary: true }}
-      style={{ display: 'inline-flex', margin: '0 2rem 1rem 0' }}
-      onTabChange={(_e, data) => switchTab(data.activeIndex as number)}
-    />
-    <Link to={'/media/channels/new'} className='ui button'>
-      <i className='icon plus' />
-      Create Channel
-    </Link>
-    {channels.map((channel) =>
-      <Segment key={channel.id} padded style={{ backgroundColor: '#fff' }}>
-        <ChannelPreview channel={channel} withDescription />
-      </Segment>
-    )}
-  </>;
-};
-
-export function ChannelsByOwner (props: ChannelsByOwnerProps) {
-  const { suspended = false, channels = [] } = props;
-
-  return <div className='JoyChannels'>
-    {!channels.length
-      ? <YouHaveNoChannels suspended={suspended} />
-      : <TabsAndChannels {...props} />
-    }</div>;
-}

+ 0 - 34
pioneer/packages/joy-media/src/channels/ChannelsByOwner.view.tsx

@@ -1,34 +0,0 @@
-import React from 'react';
-import { RouteComponentProps } from 'react-router';
-
-import { MediaView } from '../MediaView';
-import { ChannelsByOwnerProps, ChannelsByOwner } from './ChannelsByOwner';
-import { JoyError } from '@polkadot/joy-utils/react/components';
-import { useApi } from '@polkadot/react-hooks';
-
-type Props = ChannelsByOwnerProps;
-
-export const ChannelsByOwnerView = MediaView<Props>({
-  component: ChannelsByOwner,
-  resolveProps: async (props) => {
-    const { transport, accountId } = props;
-    const channels = await transport.channelsByAccount(accountId);
-
-    return { channels };
-  }
-});
-
-export const ChannelsByOwnerWithRouter = (props: Props & RouteComponentProps<Record<string, string | undefined>>) => {
-  const { match: { params: { account } } } = props;
-  const { api } = useApi();
-
-  if (account) {
-    try {
-      return <ChannelsByOwnerView {...props} accountId={api.createType('AccountId', account)} />;
-    } catch (err) {
-      console.log('ChannelsByOwnerWithRouter failed:', err);
-    }
-  }
-
-  return <JoyError title={'Invalid account address in URL'}>{account}</JoyError>;
-};

+ 0 - 94
pioneer/packages/joy-media/src/channels/CurationPanel.tsx

@@ -1,94 +0,0 @@
-import React from 'react';
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { isVerifiedChannel, isCensoredChannel } from './ChannelHelpers';
-import { useMyMembership } from '@polkadot/joy-utils/react/hooks';
-import { SemanticTxButton } from '@polkadot/joy-utils/react/components/TxButton';
-import { AccountId } from '@polkadot/types/interfaces';
-import { useApi } from '@polkadot/react-hooks';
-import { Icon } from 'semantic-ui-react';
-
-type ChannelCurationPanelProps = {
-  channel: ChannelEntity;
-};
-
-export const CurationPanel = (props: ChannelCurationPanelProps) => {
-  const { api } = useApi();
-  const { curationActor, allAccounts } = useMyMembership();
-  const { channel } = props;
-
-  const canUseAccount = (account: AccountId) => {
-    if (!allAccounts || !Object.keys(allAccounts).length) {
-      return false;
-    }
-
-    const ix = Object.keys(allAccounts).findIndex((key) => {
-      return account.eq(allAccounts[key].json.address);
-    });
-
-    return ix !== -1;
-  };
-
-  const renderToggleCensorshipButton = () => {
-    if (!curationActor) { return null; }
-
-    const [curation_actor, role_account] = curationActor;
-    const accountAvailable = canUseAccount(role_account);
-
-    const isCensored = isCensoredChannel(channel);
-
-    const new_curation_status = api.createType('ChannelCurationStatus',
-      isCensored ? 'Normal' : 'Censored'
-    );
-
-    return <SemanticTxButton
-      accountId={role_account.toString()}
-      type='submit'
-      size='small'
-      color={isCensored ? undefined : 'red'}
-      disabled={!accountAvailable}
-      params={[
-        curation_actor,
-        channel.id,
-        null, // not changing verified status
-        new_curation_status // toggled curation status
-      ]}
-      tx={'contentWorkingGroup.updateChannelAsCurationActor'}
-    >
-      <Icon name={isCensored ? 'x' : 'warning'}/>
-      { isCensored ? 'Un-Censor' : 'Censor' }
-    </SemanticTxButton>;
-  };
-
-  const renderToggleVerifiedButton = () => {
-    if (!curationActor) { return null; }
-
-    const [curation_actor, role_account] = curationActor;
-    const accountAvailable = canUseAccount(role_account);
-    const isVerified = isVerifiedChannel(channel);
-
-    return <SemanticTxButton
-      accountId={role_account.toString()}
-      type='submit'
-      size='small'
-      color={isVerified ? undefined : 'green'}
-      disabled={!accountAvailable}
-      params={[
-        curation_actor,
-        channel.id,
-        !isVerified, // toggle verified
-        null // not changing curation status
-      ]}
-      tx={'contentWorkingGroup.updateChannelAsCurationActor'}
-    >
-      <Icon name={isVerified ? 'x' : 'checkmark'}/>
-      { isVerified ? 'Remove Verification' : 'Verify' }
-    </SemanticTxButton>;
-  };
-
-  return <>
-    <div style={{ display: 'flex', float: 'right', margin: '0.5em', marginRight: 0 }}>
-      {renderToggleCensorshipButton()}
-      {renderToggleVerifiedButton()}
-    </div>
-  </>;
-};

+ 0 - 219
pioneer/packages/joy-media/src/channels/EditChannel.tsx

@@ -1,219 +0,0 @@
-import React from 'react';
-import { Button } from 'semantic-ui-react';
-import { Form, withFormik } from 'formik';
-import { History } from 'history';
-
-import { Option } from '@polkadot/types';
-import { TxButton, JoyError, Section } from '@polkadot/joy-utils/react/components';
-import { onImageError } from '../common/images';
-import { withMediaForm, MediaFormProps } from '../common/MediaForms';
-import { ChannelType, ChannelClass as Fields, buildChannelValidationSchema, ChannelFormValues, ChannelToFormValues, ChannelGenericProp } from '../schemas/channel/Channel';
-import { MediaDropdownOptions } from '../common/MediaDropdownOptions';
-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 { TxCallback } from '@polkadot/react-components/Status/types';
-import { SubmittableResult } from '@polkadot/api';
-import { ChannelValidationConstraints } from '../transport';
-
-import { useApi } from '@polkadot/react-hooks';
-
-export type OuterProps = {
-  history?: History;
-  id?: ChannelId;
-  entity?: ChannelType;
-  constraints?: ChannelValidationConstraints;
-  opts?: MediaDropdownOptions;
-};
-
-type FormValues = ChannelFormValues;
-
-const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
-  const {
-    // React components for form fields:
-    MediaText,
-    MediaDropdown,
-    LabelledField,
-
-    // Callbacks:
-    onSubmit,
-    // onTxSuccess,
-    onTxFailed,
-
-    history,
-    id: existingId,
-    entity,
-    isFieldChanged,
-
-    // Formik stuff:
-    values,
-    dirty,
-    isValid,
-    isSubmitting,
-    setSubmitting,
-    resetForm
-  } = props;
-
-  const { myAccountId, myMemberId } = useMyMembership();
-  const { api } = useApi();
-
-  if (entity && !isAccountAChannelOwner(entity, myAccountId)) {
-    return <JoyError title={'Only owner can edit channel'} />;
-  }
-
-  const { avatar } = values;
-  const isNew = !entity;
-
-  // if user is not the channel owner don't render the edit form
-  // return null
-
-  const onTxSuccess: TxCallback = (txResult: SubmittableResult) => {
-    setSubmitting(false);
-    if (!history) return;
-
-    const id = existingId || findFirstParamOfSubstrateEvent<ChannelId>(txResult, 'ChannelCreated');
-
-    console.log('Channel id:', id?.toString());
-
-    if (id) {
-      history.push('/media/channels/' + id.toString());
-    }
-  };
-
-  const buildTxParams = () => {
-    if (!isValid) return [];
-
-    if (!entity) {
-      // Create a new channel
-
-      const channelOwner = myMemberId;
-      const roleAccount = myAccountId;
-      const contentType = api.createType('ChannelContentType', values.content);
-
-      return [
-        channelOwner,
-        roleAccount,
-        contentType,
-        values.handle,
-        values.title || null,
-        values.description || null,
-        values.avatar || null,
-        values.banner || null,
-        values.publicationStatus
-      ];
-    } else {
-      // Update an existing channel
-
-      const updOptText = (field: ChannelGenericProp): Option<OptionalText> => {
-        return api.createType('Option<OptionalText>',
-          isFieldChanged(field)
-            ? api.createType('Option<Text>', values[field.id])
-            : null
-        );
-      };
-
-      const updHandle = api.createType('Option<Text>',
-        isFieldChanged(Fields.handle)
-          ? values[Fields.handle.id]
-          : null
-      );
-
-      const updPublicationStatus = api.createType('Option<ChannelPublicationStatus>',
-        isFieldChanged(Fields.publicationStatus)
-          ? api.createType('ChannelPublicationStatus', values[Fields.publicationStatus.id])
-          : null
-      );
-
-      return [
-        entity.id,
-        updHandle,
-        updOptText(Fields.title),
-        updOptText(Fields.description),
-        updOptText(Fields.avatar),
-        updOptText(Fields.banner),
-        updPublicationStatus
-      ];
-    }
-  };
-
-  const formFields = () => <>
-    <MediaText field={Fields.handle} {...props} />
-    <MediaText field={Fields.title} {...props} />
-    <MediaText field={Fields.avatar} {...props} />
-    <MediaText field={Fields.banner} {...props} />
-    <MediaText field={Fields.description} textarea {...props} />
-
-    <MediaDropdown
-      {...props}
-      field={Fields.publicationStatus}
-      options={ChannelPublicationStatusDropdownOptions}
-    />
-  </>;
-
-  const renderMainButton = () =>
-    <TxButton
-      type='submit'
-      isDisabled={!dirty || isSubmitting}
-      label={isNew
-        ? 'Create channel'
-        : 'Update channel'
-      }
-      params={buildTxParams()}
-      tx={isNew
-        ? 'contentWorkingGroup.createChannel'
-        : 'contentWorkingGroup.updateChannelAsOwner'
-      }
-      onClick={onSubmit}
-      txFailedCb={onTxFailed}
-      txSuccessCb={onTxSuccess}
-    />;
-
-  return <div className='EditMetaBox'>
-    <div className='EditMetaThumb'>
-      {avatar && <img src={avatar} onError={onImageError} />}
-    </div>
-
-    <Section title={isNew ? 'Create a channel' : 'Edit a channel'}>
-      <Form className='ui form JoyForm EditMetaForm'>
-
-        {formFields()}
-
-        <LabelledField style={{ marginTop: '1rem' }} {...props} flex>
-          {renderMainButton()}
-          <Button
-            type='button'
-            size='large'
-            disabled={!dirty || isSubmitting}
-            onClick={() => resetForm()}
-            content='Reset form'
-          />
-        </LabelledField>
-      </Form>
-    </Section>
-  </div>;
-};
-
-export const EditForm = withFormik<OuterProps, FormValues>({
-
-  // Transform outer props into form values
-  mapPropsToValues: (props): FormValues => {
-    const { entity } = props;
-
-    return ChannelToFormValues(entity);
-  },
-
-  validationSchema: (props: OuterProps): any => {
-    const { constraints } = props;
-
-    if (!constraints) return null;
-
-    return buildChannelValidationSchema(constraints);
-  },
-
-  handleSubmit: () => {
-    // do submitting things
-  }
-})(withMediaForm(InnerForm) as any);
-
-export default EditForm;

+ 0 - 38
pioneer/packages/joy-media/src/channels/EditChannel.view.tsx

@@ -1,38 +0,0 @@
-import React from 'react';
-import { RouteComponentProps } from 'react-router';
-import { MediaView } from '../MediaView';
-import { OuterProps, EditForm } from './EditChannel';
-import { JoyError } from '@polkadot/joy-utils/react/components';
-import { useApi } from '@polkadot/react-hooks';
-
-type Props = OuterProps;
-
-export const EditChannelView = MediaView<Props>({
-  component: EditForm,
-  membersOnly: true,
-  triggers: ['id'],
-  resolveProps: async (props) => {
-    const { transport, id } = props;
-    const entity = id && await transport.channelById(id);
-    const constraints = await transport.channelValidationConstraints();
-
-    return { entity, constraints };
-  }
-});
-
-type WithRouterProps = Props & RouteComponentProps<Record<string, string | undefined>>
-
-export const EditChannelWithRouter = (props: WithRouterProps) => {
-  const { match: { params: { id } } } = props;
-  const { api } = useApi();
-
-  if (id) {
-    try {
-      return <EditChannelView {...props} id={api.createType('ChannelId', id)} />;
-    } catch (err) {
-      console.log('EditChannelWithRouter failed:', err);
-    }
-  }
-
-  return <JoyError title={'Invalid channel id in URL'}>{id}</JoyError>;
-};

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

@@ -1,41 +0,0 @@
-import React from 'react';
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { ChannelId } from '@joystream/types/content-working-group';
-import { VideoType } from '../schemas/video/Video';
-import { MusicAlbumPreviewProps } from '../music/MusicAlbumPreview';
-import { MusicTrackReaderPreviewProps } from '../music/MusicTrackReaderPreview';
-import { ViewVideoChannel } from './ViewVideoChannel';
-import { ViewMusicChannel } from './ViewMusicChannel';
-import { toVideoPreviews } from '../video/VideoPreview';
-import { isVideoChannel, isMusicChannel } from './ChannelHelpers';
-import { JoyError } from '@polkadot/joy-utils/react/components';
-
-export type ViewChannelProps = {
-  id: ChannelId;
-  channel?: ChannelEntity;
-
-  // Video channel specific:
-  videos?: VideoType[];
-
-  // Music channel specific:
-  albums?: MusicAlbumPreviewProps[];
-  tracks?: MusicTrackReaderPreviewProps[];
-}
-
-export function ViewChannel (props: ViewChannelProps) {
-  const { channel, videos = [], albums = [], tracks = [] } = props;
-
-  if (!channel) {
-    return <JoyError title={'Channel was not found'} />;
-  }
-
-  if (isVideoChannel(channel)) {
-    const previews = toVideoPreviews(videos);
-
-    return <ViewVideoChannel channel={channel} videos={previews} />;
-  } else if (isMusicChannel(channel)) {
-    return <ViewMusicChannel channel={channel} albums={albums} tracks={tracks} />;
-  } else {
-    return <JoyError title={'Unsupported channel type'}>{channel.content}</JoyError>;
-  }
-}

+ 0 - 35
pioneer/packages/joy-media/src/channels/ViewChannel.view.tsx

@@ -1,35 +0,0 @@
-import React from 'react';
-import { RouteComponentProps } from 'react-router';
-import { MediaView } from '../MediaView';
-import { ViewChannelProps, ViewChannel } from './ViewChannel';
-import { JoyError } from '@polkadot/joy-utils/react/components';
-import { useApi } from '@polkadot/react-hooks';
-
-type Props = ViewChannelProps;
-
-export const ViewChannelView = MediaView<Props>({
-  component: ViewChannel,
-  triggers: ['id'],
-  resolveProps: async (props) => {
-    const { transport, id } = props;
-    const channel = await transport.channelById(id);
-    const videos = await transport.videosByChannelId(id);
-
-    return { channel, videos };
-  }
-});
-
-export const ViewChannelWithRouter = (props: Props & RouteComponentProps<Record<string, string | undefined>>) => {
-  const { match: { params: { id } } } = props;
-  const { api } = useApi();
-
-  if (id) {
-    try {
-      return <ViewChannelView {...props} id={api.createType('ChannelId', id)} />;
-    } catch (err) {
-      console.log('ViewChannelWithRouter failed:', err);
-    }
-  }
-
-  return <JoyError title={'Invalid channel id in URL'}>{id}</JoyError>;
-};

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

@@ -1,47 +0,0 @@
-import React from 'react';
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { Section } from '@polkadot/joy-utils/react/components';
-import { ChannelHeader } from './ChannelHeader';
-import { MusicAlbumPreviewProps, MusicAlbumPreview } from '../music/MusicAlbumPreview';
-import { MusicTrackReaderPreview, MusicTrackReaderPreviewProps } from '../music/MusicTrackReaderPreview';
-import NoContentYet from '../common/NoContentYet';
-
-type Props = {
-  channel: ChannelEntity;
-  albums?: MusicAlbumPreviewProps[];
-  tracks?: MusicTrackReaderPreviewProps[];
-};
-
-function NoAlbums () {
-  return <NoContentYet>Channel has no music albums yet.</NoContentYet>;
-}
-
-function NoTracks () {
-  return <NoContentYet>Channel has no music tracks yet.</NoContentYet>;
-}
-
-export function ViewMusicChannel (props: Props) {
-  const { channel, albums = [], tracks = [] } = props;
-
-  const renderAlbumsSection = () => (
-    !albums.length
-      ? <NoAlbums />
-      : <Section title={'Music albums'}>
-        {albums.map((x) => <MusicAlbumPreview key={x.id} {...x} />)}
-      </Section>
-  );
-
-  const renderTracksSection = () => (
-    !tracks.length
-      ? <NoTracks />
-      : <Section title={'Music tracks'}>
-        {tracks.map((x) => <MusicTrackReaderPreview key={x.id} {...x} />)}
-      </Section>
-  );
-
-  return <div className='JoyViewChannel'>
-    <ChannelHeader channel={channel} />
-    {renderAlbumsSection()}
-    {renderTracksSection()}
-  </div>;
-}

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

@@ -1,34 +0,0 @@
-import React from 'react';
-import { Section } from '@polkadot/joy-utils/react/components';
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { ChannelHeader } from './ChannelHeader';
-import { VideoPreview, VideoPreviewProps } from '../video/VideoPreview';
-import NoContentYet from '../common/NoContentYet';
-
-type Props = {
-  channel: ChannelEntity;
-  videos?: VideoPreviewProps[];
-};
-
-function NoVideosYet () {
-  return <NoContentYet>Channel has no videos yet.</NoContentYet>;
-}
-
-export function ViewVideoChannel (props: Props) {
-  const { channel, videos = [] } = props;
-
-  const renderVideosSection = () => (
-    !videos.length
-      ? <NoVideosYet />
-      : <Section title={'Videos'}>
-        {videos.map((x) =>
-          <VideoPreview key={x.id.toString()} {...x} channel={channel} />
-        )}
-      </Section>
-  );
-
-  return <div className='JoyViewChannel'>
-    <ChannelHeader channel={channel} />
-    {renderVideosSection()}
-  </div>;
-}

+ 0 - 51
pioneer/packages/joy-media/src/channels/YouHaveNoChannels.tsx

@@ -1,51 +0,0 @@
-import React from 'react';
-import { Link } from 'react-router-dom';
-import { Message } from 'semantic-ui-react';
-
-type Props = {
-  suspended?: boolean;
-};
-
-export function YouHaveNoChannels (props: Props) {
-  const { suspended = false } = props;
-
-  const renderSuspendedAlert = () => (
-    <Message
-      compact
-      error
-      icon='warning sign'
-      header='Channel Creation Suspended'
-      content='Please try again later'
-      className='JoyInlineMsg'
-    />
-  );
-
-  const renderCreateButton = () => (
-    <Link to={'/media/channels/new'}>
-      <Message
-        compact
-        success
-        icon='plus circle'
-        header='Create Channel'
-        content='and start publishing'
-        className='JoyInlineMsg CreateBtn'
-      />
-    </Link>
-  );
-
-  return <>
-    <h2 style={{ marginTop: '2rem', marginBottom: '.5rem' }}>
-      Build your following on Joystream
-    </h2>
-
-    <p style={{ marginBottom: '2rem' }}>
-      A channel is a way to organize related content for the benefit
-      of both the publisher and the audience.
-    </p>
-
-    {suspended
-      ? renderSuspendedAlert()
-      : renderCreateButton()
-    }
-  </>;
-}

+ 0 - 43
pioneer/packages/joy-media/src/common/BgImg.tsx

@@ -1,43 +0,0 @@
-import React, { CSSProperties } from 'react';
-
-type Props = {
-  url: string;
-  size?: number;
-  width?: number;
-  height?: number;
-  circle?: boolean;
-  className?: string;
-  style?: CSSProperties;
-};
-
-export function BgImg (props: Props) {
-  let { url, width, height, size, circle, className, style } = props;
-
-  const fullClass = `JoyBgImg ${className || ''}`;
-
-  let fullStyle: CSSProperties = {
-    backgroundImage: `url(${url})`
-  };
-
-  if (!width || !height) {
-    width = size;
-    height = size;
-  }
-
-  fullStyle = Object.assign(fullStyle, {
-    width,
-    height,
-    minWidth: width,
-    minHeight: height
-  });
-
-  if (circle) {
-    fullStyle = Object.assign(fullStyle, {
-      borderRadius: '50%'
-    });
-  }
-
-  fullStyle = Object.assign(fullStyle, style);
-
-  return <div className={fullClass} style={fullStyle} />;
-}

+ 0 - 59
pioneer/packages/joy-media/src/common/FormTabs.tsx

@@ -1,59 +0,0 @@
-import React from 'react';
-import { Menu, Label, Tab } from 'semantic-ui-react';
-import { FormikErrors } from 'formik';
-import { GenericMediaProp } from './MediaForms';
-
-type FormTab<FormValues> = {
-  id: string;
-  fields?: GenericMediaProp<FormValues>[];
-  renderTitle?: () => React.ReactNode;
-  render?: () => React.ReactNode;
-}
-
-type FormTabsProps<FormValues> = {
-  errors: FormikErrors<FormValues>;
-  panes: FormTab<FormValues>[];
-}
-
-export function FormTabs <FormValues> (props: FormTabsProps<FormValues>) {
-  const { panes, errors } = props;
-
-  return <Tab
-    menu={{ secondary: true, pointing: true, color: 'blue' }}
-    panes={panes.map((tab) => {
-      const {
-        id,
-        fields = [],
-        renderTitle = () => id,
-        render = () => null
-      } = tab;
-
-      const tabErrors: any[] = [];
-
-      fields.forEach((f) => {
-        const err = errors[f.id];
-
-        if (err) {
-          tabErrors.push(err);
-        }
-      });
-
-      // Currently we don't show error counter because it's markup is broken:
-      // a red circle with a number is shifted quite far from the right border of its tab.
-      const showErrorCounter = false;
-
-      const errCount = tabErrors.length;
-      const errTooltip = 'Number of errors on this tab';
-
-      const menuItem =
-        <Menu.Item key={id}>
-          {renderTitle()}
-          {showErrorCounter && errCount > 0 &&
-            <Label color='red' circular floating title={errTooltip}>{errCount}</Label>
-          }
-        </Menu.Item>;
-
-      return { menuItem, render };
-    })}
-  />;
-}

+ 0 - 44
pioneer/packages/joy-media/src/common/MediaDropdownOptions.tsx

@@ -1,44 +0,0 @@
-import ISO6391 from 'iso-639-1';
-import { DropdownItemProps } from 'semantic-ui-react';
-import { LanguageType } from '../schemas/general/Language';
-import { TextValueEntity } from '@joystream/types/versioned-store/EntityCodec';
-import { InternalEntities } from '../transport';
-
-const buildOptions = (entities: TextValueEntity[]): DropdownItemProps[] =>
-  entities.map((x) => ({ key: x.id, value: x.id, text: x.value }));
-
-const buildLanguageOptions = (entities: LanguageType[]): DropdownItemProps[] =>
-  entities.map((x) => ({ key: x.id, value: x.id, text: ISO6391.getName(x.value) }));
-
-export class MediaDropdownOptions {
-  public languageOptions: DropdownItemProps[]
-  public contentLicenseOptions: DropdownItemProps[]
-  public curationStatusOptions: DropdownItemProps[]
-  public musicGenreOptions: DropdownItemProps[]
-  public musicMoodOptions: DropdownItemProps[]
-  public musicThemeOptions: DropdownItemProps[]
-  public publicationStatusOptions: DropdownItemProps[]
-  public videoCategoryOptions: DropdownItemProps[]
-
-  constructor (props: InternalEntities) {
-    this.languageOptions = buildLanguageOptions(props.languages);
-    this.contentLicenseOptions = buildOptions(props.contentLicenses);
-    this.curationStatusOptions = buildOptions(props.curationStatuses);
-    this.musicGenreOptions = buildOptions(props.musicGenres);
-    this.musicMoodOptions = buildOptions(props.musicMoods);
-    this.musicThemeOptions = buildOptions(props.musicThemes);
-    this.publicationStatusOptions = buildOptions(props.publicationStatuses);
-    this.videoCategoryOptions = buildOptions(props.videoCategories);
-  }
-
-  static Empty = new MediaDropdownOptions({
-    languages: [],
-    contentLicenses: [],
-    curationStatuses: [],
-    musicGenres: [],
-    musicMoods: [],
-    musicThemes: [],
-    publicationStatuses: [],
-    videoCategories: []
-  });
-}

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

@@ -1,202 +0,0 @@
-import React from 'react';
-import { Dropdown, DropdownItemProps, DropdownProps } from 'semantic-ui-react';
-import { FormikProps, Field } from 'formik';
-import * as JoyForms from '@polkadot/joy-utils/react/components/forms';
-import { SubmittableResult } from '@polkadot/api';
-import { TxFailedCallback, TxCallback } from '@polkadot/react-components/Status/types';
-import { MediaDropdownOptions } from './MediaDropdownOptions';
-import { OnTxButtonClick } from '@polkadot/joy-utils/react/components/TxButton';
-import isEqual from 'lodash/isEqual';
-import { componentName } from '@polkadot/joy-utils/react/helpers';
-
-export const datePlaceholder = 'Date in format yyyy-mm-dd';
-
-export const boolOptions: DropdownItemProps[] = [
-  { value: 'true', text: 'Yes' },
-  { value: 'false', text: 'No' }
-];
-
-export type FormCallbacks = {
-  onSubmit: OnTxButtonClick;
-  onTxSuccess: TxCallback;
-  onTxFailed: TxFailedCallback;
-};
-
-export type GenericMediaProp<FormValues> = {
-  id: keyof FormValues;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  minItems?: number;
-  maxItems?: number;
-  minTextLength?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type BaseFieldProps<OuterProps, FormValues> = OuterProps & FormikProps<FormValues> & {
-  field: GenericMediaProp<FormValues>;
-};
-
-type MediaTextProps<OuterProps, FormValues> =
-  BaseFieldProps<OuterProps, FormValues> & JoyForms.LabelledProps<FormValues>;
-
-type MediaFieldProps<OuterProps, FormValues> =
-  BaseFieldProps<OuterProps, FormValues> &
-  JoyForms.LabelledProps<FormValues> & {
-    fieldProps: Record<string, unknown>;
-  }
-
-type MediaDropdownProps<OuterProps, FormValues> =
-  BaseFieldProps<OuterProps, FormValues> &
-  {
-    options: DropdownItemProps[];
-  };
-
-type FormFields<OuterProps, FormValues> = {
-  LabelledText: React.FunctionComponent<JoyForms.LabelledProps<FormValues>>;
-  LabelledField: React.FunctionComponent<JoyForms.LabelledProps<FormValues>>;
-  MediaText: React.FunctionComponent<MediaTextProps<OuterProps, FormValues>>;
-  MediaField: React.FunctionComponent<MediaFieldProps<OuterProps, FormValues>>;
-  MediaDropdown: React.FunctionComponent<MediaDropdownProps<OuterProps, FormValues>>;
-};
-
-export type MediaFormProps<OuterProps, FormValues> =
-  OuterProps &
-  FormikProps<FormValues> &
-  FormFields<OuterProps, FormValues> &
-  FormCallbacks & {
-    opts: MediaDropdownOptions;
-    isFieldChanged: (field: keyof FormValues | GenericMediaProp<FormValues>) => boolean;
-  };
-
-export function withMediaForm<OuterProps, FormValues>
-(Component: React.ComponentType<MediaFormProps<OuterProps, FormValues>>) {
-  type FieldName = keyof FormValues
-
-  type FieldObject = GenericMediaProp<FormValues>
-
-  const LabelledText = JoyForms.LabelledText<FormValues>();
-
-  const LabelledField = JoyForms.LabelledField<FormValues>();
-
-  function MediaText (props: MediaTextProps<OuterProps, FormValues>) {
-    const { field: f } = props;
-
-    return !f ? null : <LabelledText name={f.id} label={f.name} tooltip={f.description} required={f.required} {...props} />;
-  }
-
-  const MediaField = (props: MediaFieldProps<OuterProps, FormValues>) => {
-    const { field: f, fieldProps = {}, placeholder, className, style, ...otherProps } = props;
-
-    const { id } = f;
-
-    const allFieldProps = {
-      name: id,
-      id,
-      placeholder,
-      className,
-      style,
-      disabled: otherProps.isSubmitting,
-      ...fieldProps
-    };
-
-    return !f ? null : (
-      <LabelledField name={id} label={f.name} tooltip={f.description} required={f.required} {...props}>
-        <Field {...allFieldProps} />
-      </LabelledField>
-    );
-  };
-
-  const MediaDropdown = (props: MediaDropdownProps<OuterProps, FormValues>) => {
-    const { field: f, options = [] } = props;
-    const id = f.id;
-    const value = props.values[id] || '';
-
-    return <MediaField {...props} fieldProps={{
-      component: Dropdown,
-      selection: true,
-      search: true,
-      options,
-      value,
-      onBlur: (_event: any, _data: DropdownProps) => {
-        props.setFieldTouched(id as string, true);
-      },
-      onChange: (_event: any, data: DropdownProps) => {
-        props.setFieldValue(id as string, data.value);
-      }
-    }} />;
-  };
-
-  const ResultComponent: React.FunctionComponent<MediaFormProps<OuterProps, FormValues>> =
-    (props: MediaFormProps<OuterProps, FormValues>) => {
-      const {
-        initialValues,
-        values,
-        dirty,
-        touched,
-        errors,
-        isValid,
-        setSubmitting,
-        opts = MediaDropdownOptions.Empty
-      } = props;
-
-      const isFieldChanged = (field: FieldName | FieldObject): boolean => {
-        const fieldName = typeof field === 'string' ? field : (field as FieldObject).id;
-
-        return (
-          dirty &&
-          touched[fieldName] === true &&
-          !isEqual(values[fieldName], initialValues[fieldName])
-        );
-      };
-
-      const onSubmit = (sendTx: () => void) => {
-        if (isValid) {
-          sendTx();
-        } else {
-          console.log('Form is invalid. Errors:', errors);
-        }
-      };
-
-      const onTxSuccess: TxCallback = (_txResult: SubmittableResult) => {
-        setSubmitting(false);
-      };
-
-      const onTxFailed: TxFailedCallback = (txResult: SubmittableResult | null) => {
-        setSubmitting(false);
-
-        if (txResult === null) {
-          // Tx cancelled
-
-        }
-      };
-
-      const allProps = {
-        ...props,
-
-        // Callbacks:
-        onSubmit,
-        onTxSuccess,
-        onTxFailed,
-
-        // Components:
-        LabelledText,
-        LabelledField,
-        MediaText,
-        MediaField,
-        MediaDropdown,
-
-        // Other
-        opts,
-        isFieldChanged
-      };
-
-      return <Component {...allProps} />;
-    };
-
-  ResultComponent.displayName = `withMediaForm(${componentName(Component)})`;
-
-  return ResultComponent;
-}

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

@@ -1,145 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import { Link } from 'react-router-dom';
-import DPlayer from 'react-dplayer';
-import APlayer from 'react-aplayer';
-
-import { ApiProps } from '@polkadot/react-api/types';
-import { I18nProps } from '@polkadot/react-components/types';
-import { withCalls, withMulti } from '@polkadot/react-api/hoc';
-import { Option } from '@polkadot/types/codec';
-
-import translate from '../translate';
-import { DiscoveryProviderProps } from '../DiscoveryProvider';
-import { DataObject, ContentId } from '@joystream/types/media';
-import { VideoType } from '../schemas/video/Video';
-import { isAccountAChannelOwner } from '../channels/ChannelHelpers';
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { useMyMembership } from '@polkadot/joy-utils/react/hooks';
-import { JoyError } from '@polkadot/joy-utils/react/components';
-
-const PLAYER_COMMON_PARAMS = {
-  lang: 'en',
-  autoplay: true,
-  theme: '#2185d0'
-};
-
-// This is just a part of Player's methods that are used in this component.
-// To see all the methods available on APlayer and DPlayer visit the next URLs:
-// http://aplayer.js.org/#/home?id=api
-// http://dplayer.js.org/#/home?id=api
-interface PartOfPlayer {
-  pause: () => void;
-  destroy: () => void;
-}
-
-export type RequiredMediaPlayerProps = {
-  channel: ChannelEntity;
-  video: VideoType;
-  contentId: ContentId;
-}
-
-type ContentProps = {
-  contentType?: string;
-  dataObjectOpt?: Option<DataObject>;
-  resolvedAssetUrl: string;
-}
-
-type MediaPlayerViewProps = ApiProps & I18nProps &
-DiscoveryProviderProps & RequiredMediaPlayerProps & ContentProps
-
-type PlayerProps = RequiredMediaPlayerProps & ContentProps
-
-function Player (props: PlayerProps) {
-  const { video, resolvedAssetUrl: url, contentType = 'video/video' } = props;
-  const { thumbnail: cover } = video;
-  const prefix = contentType.substring(0, contentType.indexOf('/'));
-
-  const [player, setPlayer] = useState<PartOfPlayer>();
-
-  const onPlayerCreated = (newPlayer: PartOfPlayer) => {
-    console.log('onPlayerCreated:', newPlayer);
-    setPlayer(newPlayer);
-  };
-
-  const destroyPlayer = () => {
-    if (!player) return;
-
-    console.log('Destroy the current player');
-    player.pause();
-    player.destroy();
-    setPlayer(undefined);
-  };
-
-  useEffect(() => {
-    return () => {
-      destroyPlayer();
-    };
-  }, [url]);
-
-  if (prefix === 'video') {
-    const video = { url, name, pic: cover };
-
-    return <DPlayer
-      video={video}
-      {...PLAYER_COMMON_PARAMS}
-      loop={false}
-      onLoad={onPlayerCreated} // Note that DPlayer has onLoad, but APlayer - onInit.
-    />;
-  } else if (prefix === 'audio') {
-    const audio = { url, name, cover };
-
-    return <APlayer
-      audio={audio}
-      {...PLAYER_COMMON_PARAMS}
-      loop='none'
-      onInit={onPlayerCreated} // Note that APlayer has onInit, but DPlayer - onLoad.
-    />;
-  }
-
-  return <JoyError title={'Unsupported type of content'}>{contentType}</JoyError>;
-}
-
-function InnerComponent (props: MediaPlayerViewProps) {
-  const { video, resolvedAssetUrl: url } = props;
-
-  const { dataObjectOpt, channel } = props;
-  const { myAccountId } = useMyMembership();
-
-  if (!dataObjectOpt || dataObjectOpt.isNone) {
-    return null;
-  }
-
-  // TODO extract and show the next info from dataObject:
-  // {"owner":"5GSMNn8Sy8k64mGUWPDafjMZu9bQNX26GujbBQ1LeJpNbrfg","added_at":{"block":2781,"time":1582750854000},"type_id":1,"size":3664485,"liaison":"5HN528fspu4Jg3KXWm7Pu7aUK64RSBz2ZSbwo1XKR9iz3hdY","liaison_judgement":1,"ipfs_content_id":"QmNk4QczoJyPTAKdfoQna6KhAz3FwfjpKyRBXAZHG5djYZ"}
-  const iAmOwner = isAccountAChannelOwner(channel, myAccountId);
-
-  return (
-    <div className='PlayBox'>
-
-      {/* Note that here we use a 'key' prop to force Player component to rerender */}
-      <Player {...props} key={url} />
-
-      <div className='ContentHeader'>
-        <a className='ui button outline DownloadBtn' href={`${url}?download`}><i className='cloud download icon'></i> Download</a>
-
-        {iAmOwner &&
-          <Link to={`/media/videos/${video.id}/edit`} className='ui button' style={{ float: 'right' }}>
-            <i className='pencil alternate icon'></i>
-            Edit
-          </Link>
-        }
-
-        <h1>{video.title}</h1>
-      </div>
-    </div>
-  );
-}
-
-export const MediaPlayerView = withMulti(
-  InnerComponent,
-  translate,
-  withCalls<MediaPlayerViewProps>(
-    ['query.dataDirectory.dataObjectByContentId',
-      { paramName: 'contentId', propName: 'dataObjectOpt' }]
-  )
-);

+ 0 - 159
pioneer/packages/joy-media/src/common/MediaPlayerWithResolver.tsx

@@ -1,159 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import axios, { CancelTokenSource, AxiosError } from 'axios';
-import _ from 'lodash';
-
-import { ApiProps } from '@polkadot/react-api/types';
-import { I18nProps } from '@polkadot/react-components/types';
-import { withMulti } from '@polkadot/react-api/hoc';
-import { Option, Vec } from '@polkadot/types/codec';
-
-import translate from '../translate';
-import { DiscoveryProviderProps, withDiscoveryProvider } from '../DiscoveryProvider';
-import { DataObjectStorageRelationshipId, DataObjectStorageRelationship } from '@joystream/types/media';
-import { Message } from 'semantic-ui-react';
-import { MediaPlayerView, RequiredMediaPlayerProps } from './MediaPlayerView';
-import { JoyInfo } from '@polkadot/joy-utils/react/components';
-import { useTransport } from '@polkadot/joy-utils/react/hooks';
-import { isObjectWithProperties } from '@polkadot/joy-utils/functions/misc';
-
-type Props = ApiProps & I18nProps & DiscoveryProviderProps & RequiredMediaPlayerProps;
-
-function newCancelSource (): CancelTokenSource {
-  return axios.CancelToken.source();
-}
-
-function InnerComponent (props: Props) {
-  const { contentId, api, discoveryProvider } = props;
-  const transport = useTransport();
-
-  const [error, setError] = useState<Error>();
-  const [resolvedAssetUrl, setResolvedAssetUrl] = useState<string>();
-  const [contentType, setContentType] = useState<string>();
-  const [cancelSource, setCancelSource] = useState<CancelTokenSource>(newCancelSource());
-
-  const resolveAsset = async () => {
-    setError(undefined);
-    setCancelSource(newCancelSource());
-
-    const rids = await api.query.dataObjectStorageRegistry.relationshipsByContentId<Vec<DataObjectStorageRelationshipId>>(contentId);
-
-    const allRelationships = await Promise.all(
-      rids.map((id) =>
-        api.query.dataObjectStorageRegistry.relationships<Option<DataObjectStorageRelationship>>(id)
-      )
-    );
-
-    // Providers that have signalled onchain that they have the asset
-    let readyProviders = allRelationships.filter((r) => r.isSome).map((r) => r.unwrap())
-      .filter((r) => r.ready)
-      .map((r) => r.storage_provider);
-
-    // runtime doesn't currently guarantee unique set
-    readyProviders = _.uniqBy(readyProviders, (provider) => provider.toString());
-
-    if (!readyProviders.length) {
-      setError(new Error('No Storage Providers found storing this content'));
-
-      return;
-    }
-
-    const activeProviders = (await transport.workingGroups.allWorkers('Storage')).map(([id]) => id);
-
-    // filter out providers no longer active - relationships of providers that have left
-    // are not pruned onchain.
-    readyProviders = _.intersectionBy(activeProviders, readyProviders, (provider) => provider.toString());
-
-    console.log(`Found ${readyProviders.length} providers ready to serve content: ${readyProviders.join(', ')}`);
-
-    // shuffle to spread the load
-    readyProviders = _.shuffle(readyProviders);
-
-    // TODO: prioritize already resolved providers, least reported unreachable, closest
-    // by geography etc..
-
-    // loop over providers until we find one that responds
-    while (readyProviders.length) {
-      const provider = readyProviders.shift();
-
-      if (!provider) continue;
-
-      let assetUrl: string | undefined;
-
-      try {
-        assetUrl = await discoveryProvider.resolveAssetEndpoint(provider, contentId.encode(), cancelSource.token);
-      } catch (err) {
-        if (axios.isCancel(err)) {
-          return;
-        } else {
-          continue;
-        }
-      }
-
-      try {
-        console.log('Check URL of resolved asset:', assetUrl);
-        const response = await axios.head(assetUrl, { cancelToken: cancelSource.token });
-        const headers = response.headers as Record<string, string | undefined>;
-
-        setContentType(headers['content-type'] || 'video/video');
-        setResolvedAssetUrl(assetUrl);
-
-        return;
-      } catch (e) {
-        const err = e as unknown;
-
-        if (axios.isCancel(err)) {
-          return;
-        } else {
-          const response = isObjectWithProperties(err, 'response')
-            ? (err as AxiosError).response
-            : undefined;
-
-          if (!response || (response.status >= 500 && response.status <= 504)) {
-            // network connection error
-            discoveryProvider.reportUnreachable(provider);
-          }
-
-          // try next provider
-          continue;
-        }
-      }
-    }
-
-    setError(new Error('Unable to reach any provider serving this content'));
-  };
-
-  useEffect(() => {
-    void resolveAsset();
-
-    return () => {
-      cancelSource.cancel();
-    };
-  }, [contentId.encode()]);
-
-  console.log('Content id:', contentId.encode());
-  console.log('Resolved asset URL:', resolvedAssetUrl);
-
-  if (error) {
-    return (
-      <Message error className='JoyMainStatus'>
-        <Message.Header>Error loading media content</Message.Header>
-        <p>{error.toString()}</p>
-        <button className='ui button' onClick={resolveAsset}>Try again</button>
-      </Message>
-    );
-  }
-
-  if (!resolvedAssetUrl) {
-    return <JoyInfo title={'Please wait...'}>Resolving media content.</JoyInfo>;
-  }
-
-  const playerProps = { ...props, contentType, resolvedAssetUrl };
-
-  return <MediaPlayerView {...playerProps} />;
-}
-
-export const MediaPlayerWithResolver = withMulti(
-  InnerComponent,
-  translate,
-  withDiscoveryProvider
-);

+ 0 - 7
pioneer/packages/joy-media/src/common/NoContentYet.tsx

@@ -1,7 +0,0 @@
-import React from 'react';
-
-const NoContentYet: React.FunctionComponent = (props) => {
-  return <div className='NoContentYet'>{props.children}</div>;
-};
-
-export default NoContentYet;

+ 0 - 44
pioneer/packages/joy-media/src/common/TypeHelpers.ts

@@ -1,44 +0,0 @@
-import BN from 'bn.js';
-import { createType } from '@joystream/types';
-import { ChannelId } from '@joystream/types/content-working-group';
-import { EntityId, ClassId } from '@joystream/types/versioned-store';
-
-export type AnyChannelId = ChannelId | BN | number | string
-
-export type AnyEntityId = EntityId | BN | number | string
-
-export type AnyClassId = ClassId | BN | number | string
-
-function canBeId (id: BN | number | string): boolean {
-  return id instanceof BN || typeof id === 'number' || typeof id === 'string';
-}
-
-export function asChannelId (id: AnyChannelId): ChannelId {
-  if (id instanceof ChannelId) {
-    return id;
-  } else if (canBeId(id)) {
-    return createType('ChannelId', id);
-  } else {
-    throw new Error(`Not supported format for Channel id: ${typeof id === 'object' ? id.constructor.name : id}`);
-  }
-}
-
-export function asEntityId (id: AnyEntityId): EntityId {
-  if (id instanceof EntityId) {
-    return id;
-  } else if (canBeId(id)) {
-    return createType('EntityId', id);
-  } else {
-    throw new Error(`Not supported format for Entity id: ${typeof id === 'object' ? id.constructor.name : id}`);
-  }
-}
-
-export function asClassId (id: AnyClassId): ClassId {
-  if (id instanceof ClassId) {
-    return id;
-  } else if (canBeId(id)) {
-    return createType('ClassId', id);
-  } else {
-    throw new Error(`Not supported format for Class id: ${typeof id === 'object' ? id.constructor.name : id}`);
-  }
-}

+ 0 - 17
pioneer/packages/joy-media/src/common/images.tsx

@@ -1,17 +0,0 @@
-import React from 'react';
-
-export const DEFAULT_THUMBNAIL_URL = 'images/default-thumbnail.png';
-
-// This is a hack to just satisfy TypeScript compiler.
-type ImageOnErrorEvent = EventTarget & {
-  src: string;
-  onerror?: (e: any) => void;
-};
-
-export function onImageError (event: React.SyntheticEvent<HTMLImageElement, Event>) {
-  const target = event.target as ImageOnErrorEvent;
-
-  // Set onerror callback to undefined to prevent infinite callbacks when image src path fails:
-  target.onerror = undefined;
-  target.src = DEFAULT_THUMBNAIL_URL;
-}

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

@@ -1,405 +0,0 @@
-$blackFont: #222;
-$grayFont: #999;
-
-$bgHover: #f2f2f2;
-$bgSelected: #c7e7fa;
-
-$borderColor: #e4e4e4;
-
-.NoContentYet {
-  padding: 2rem 0;
-  color: $grayFont;
-}
-
-.JoyBgImg {
-  background-color: #ccc;
-  background-size: cover;
-  background-position: center;
-}
-
-.JoySection {
-  .ViewAllLink {
-    float: right;
-    font-size: 1rem;
-    font-weight: normal;
-    text-transform: uppercase;
-    margin-left: 1rem;
-  }
-}
-.Ellipsis {
-  text-overflow: ellipsis;
-  overflow: hidden;
-  white-space: nowrap;
-}
-
-.JoyTopActionBar {
-  margin: 1rem 0;
-
-  .button {
-    margin-right: .5rem;
-  }
-}
-
-.JoyListOfPreviews {
-  background-color: #ddd;
-
-  .CheckboxCell {
-    padding-left: 1rem;
-  }
-
-  .NoItems {
-    display: block;
-    background-color: #fafafa;
-    padding: 1rem 0;
-  }
-}
-
-.JoyMusicAlbumPreview,
-.JoyMusicTrackPreview {
-  display: flex;
-
-  &.vertical {
-    flex-direction: column;
-  }
-
-  &.horizontal {
-    flex-direction: row;
-
-    .AlbumCover {
-      margin-right: 1rem;
-    }
-  }
-
-  .JoyListOfPreviews & {
-    background-color: #fafafa;
-    margin-top: 1px;
-    padding: .5rem 0;
-
-    &:hover {
-      background-color: $bgHover;
-    }
-
-    &.DraggableItem,
-    &.SelectedItem {
-      background-color: $bgSelected;
-    }
-  }
-
-  .AlbumNumber {
-    color: $grayFont;
-    width: 3.5rem;
-    text-align: right;
-    padding-right: 1rem;
-  }
-
-  .AlbumCover {
-    text-align: right;
-    white-space: nowrap;
-
-    $size: 60px;
-    width: $size;
-
-    img {
-      max-width: $size;
-      max-height: $size;
-    }
-  }
-
-  .AlbumDescription {
-    padding: 0 1rem;
-    width: 100%;
-
-    .AlbumTitle {
-      font-size: 1rem;
-      font-weight: bold;
-      color: $blackFont;
-      margin-top: 0;
-      margin-bottom: 0.5rem;
-    }
-
-    .AlbumArtist,
-    .AlbumTracksCount {
-      color: $grayFont;
-      font-size: .9rem;
-    }
-  }
-
-  .AlbumActions {
-    white-space: nowrap;
-    opacity: 0;
-
-    .button {
-      margin-right: .5rem;
-    }
-  }
-  &:hover .AlbumActions {
-    opacity: 1;
-  }
-}
-
-/* Music Album */
-/* ------------------------------------------------------ */
-
-.JoyMusicAlbumPreview {
-  display: inline-flex;
-  flex-direction: column;
-  padding: 0 1rem 1rem 0;
-  $size: 200px;
-
-  .AlbumDescription {
-    text-align: left;
-    padding: 0;
-  }
-
-  .AlbumCover {
-    width: $size;
-    height: $size;
-    min-width: $size;
-    min-height: $size;
-  }
-
-  .AlbumTitle {
-    @extend .Ellipsis;
-
-    font-size: 1rem;
-    font-weight: bold;
-    color: $blackFont;
-    margin-top: 0;
-    margin-bottom: 0.5rem;
-  }
-  &.vertical {
-    .AlbumTitle {
-      margin-top: 0.5rem;
-    }
-  }
-
-  .AlbumArtist {
-    color: $grayFont;
-    font-size: 1rem;
-  }
-
-  .AlbumActions {
-    opacity: 1;
-  }
-}
-
-/* Channels */
-/* ------------------------------------------------------ */
-
-.ChannelTitle {
-  color: $blackFont;
-  display: flex;
-}
-
-.ChannelAvatar {
-  display: table;
-  border-radius: 50%;
-  margin-right: 1rem;
-
-  &.big {
-    margin-right: 2rem;
-  }
-}
-
-.JoyChannels {
-
-  .ui.message.JoyInlineMsg {
-    display: inline-flex;
-    width: auto;
-    margin-top: 0;
-
-    &.CreateBtn {
-      cursor: pointer;
-
-      /* Disable text selection by user: */
-      -webkit-touch-callout: none; /* iOS Safari */
-      -webkit-user-select: none; /* Safari */
-       -khtml-user-select: none; /* Konqueror HTML */
-         -moz-user-select: none; /* Old versions of Firefox */
-          -ms-user-select: none; /* Internet Explorer/Edge */
-              user-select: none; /* Non-prefixed version, currently
-                                    supported by Chrome, Opera and Firefox */
-
-      &:hover,
-      &:focus {
-        background-color: #f3fce0;
-      }
-      &:active {
-        background-color: #e0f4b7;
-      }
-    }
-  }
-
-  .ChannelPreview {
-    display: flex;
-
-    .ChannelStats {
-      margin-left: 3rem;
-      text-align: right;
-
-      .statistic {
-        .label,
-        .value {
-          text-align: right;
-          white-space: nowrap;
-        }
-        .label {
-          color: $grayFont;
-          font-weight: normal;
-          font-size: .9rem;
-        }
-      }
-    }
-  }
-}
-
-.JoyViewChannel {
-  .ChannelHeader {
-    margin-bottom: 1rem;
-  }
-  .ChannelCover {
-    background-size: cover;
-    margin-bottom: 2rem;
-    height: 200px;
-  }
-}
-
-.ChannelPreview {
-  display: flex;
-  align-items: normal;
-
-  .ListOfChannels & {
-    margin-bottom: 1rem;
-  }
-
-  .JoyPlayAlbum & {
-    margin: .5rem 0;
-  }
-
-  .ChannelDetails {
-    width: 100%;
-  }
-
-  .ChannelTitle {
-    font-size: 1.5rem;
-    font-weight: 500;
-    margin: 0;
-    margin-top: .75rem;
-
-    .ChannelHeader & {
-      margin-top: 1rem;
-    }
-  }
-  
-  &.small {
-    align-items: center;
-
-    .ChannelTitle {
-      margin-top: 0;
-      font-size: 1rem;
-      a {
-        color: $blackFont;
-      }
-    }
-    .ChannelAvatar {
-      margin-right: .5rem;
-    }
-  }
-
-  &.big {
-    .ChannelTitle {
-      font-size: 2rem;
-    }
-  }
-
-  .ChannelSubtitle {
-    color: $grayFont;
-    font-size: .9rem;
-    text-transform: uppercase;
-    margin-top: .5rem;
-
-    .icon {
-      margin-right: .5rem;
-    }
-  }
-
-  .ChannelDesc {
-    margin-top: .75rem;
-  }
-}
-
-/* Play Album, Video */
-/* ------------------------------------------------------ */
-
-.JoyPlayAlbum {
-  display: flex;
-  flex-direction: row;
-
-  .JoyPlayAlbum_Main {
-    display: flex;
-    flex-direction: row;
-    margin-right: 1rem;
-
-    .JoyPlayAlbum_CurrentTrack {
-      margin-right: 1rem;
-
-      .AlbumTitle {
-        font-size: 1.5rem;
-        margin-top: 1rem;
-      }
-      .AlbumArtist {
-        font-size: 1.15rem;
-      }
-    }
-
-    .JoyPlayAlbum_AlbumTracks {
-      .TrackRow {
-        cursor: pointer;
-
-        &.Current {
-          background-color: $bgSelected;
-        }
-
-        .JoyMusicAlbumPreview {
-          padding: 0;
-        }
-        .TrackNumber {
-          color: $grayFont;
-          width: 2rem;
-          padding-left: .5rem !important;
-        }
-        .TrackTitle {
-          padding-right: .5rem !important;
-        }
-        .AlbumDescription {
-          max-width: 300px;
-        }
-      }
-    }
-
-    .JoyPlayAlbum_AlbumTracks,
-    .JoyPlayAlbum_MetaInfo {
-      td:first-child {
-        font-weight: bold;
-        color: $grayFont;
-      }
-    }
-  }
-
-  .JoyPlayAlbum_RightSidePanel {
-    max-width: 450px;
-  }
-}
-
-.ContentHeader {
-  border-bottom: 1px solid $borderColor;
-  padding-bottom: 1rem;
-  margin-bottom: 1rem;
-}
-
-.PlayVideoDetails {
-  border-top: 1px solid $borderColor;
-  padding-top: 1rem;
-  margin-top: 1rem;
-  margin-bottom: 2rem;
-}

+ 0 - 10
pioneer/packages/joy-media/src/entities/ChannelEntity.ts

@@ -1,10 +0,0 @@
-import BN from 'bn.js';
-import { ChannelType } from '../schemas/channel/Channel';
-
-// TODO rename to EnrichedChannelType
-export type ChannelEntity = ChannelType & {
-
-  // Stats:
-  rewardEarned: BN;
-  contentItemsCount: number;
-};

+ 0 - 15
pioneer/packages/joy-media/src/entities/EntityHelpers.ts

@@ -1,15 +0,0 @@
-import moment from 'moment';
-import ISO6391 from 'iso-639-1';
-import { LanguageType } from '../schemas/general/Language';
-
-export function printExplicit (explicit?: boolean): string {
-  return explicit === true ? 'Yes' : 'No';
-}
-
-export function printReleaseDate (linuxTimestamp?: number): string {
-  return !linuxTimestamp ? '' : moment(linuxTimestamp * 1000).format('YYYY-MM-DD');
-}
-
-export function printLanguage (language?: LanguageType): string {
-  return !language ? '' : ISO6391.getName(language.value);
-}

+ 0 - 26
pioneer/packages/joy-media/src/entities/MusicAlbumEntity.ts

@@ -1,26 +0,0 @@
-export type MusicAlbumEntity = {
-  title: string;
-  artist: string;
-  thumbnail: string;
-  description: string;
-
-  explicit: boolean;
-  license: string;
-
-  year: number;
-  month?: number;
-  date?: number;
-
-  genre?: string;
-  mood?: string;
-  theme?: string;
-
-  language?: string;
-  links?: string[];
-  lyrics?: string;
-  composer?: string;
-  reviews?: string;
-
-  // publicationStatus: ...
-  // curationStatus: ...
-};

+ 0 - 18
pioneer/packages/joy-media/src/entities/MusicTrackEntity.ts

@@ -1,18 +0,0 @@
-export type MusicTrackEntity = {
-
-  // Basic:
-  title: string;
-  description?: string;
-  thumbnail?: string;
-  visibility?: string;
-  album?: string;
-
-  // Additional:
-  artist?: string;
-  composer?: string;
-  genre?: string;
-  mood?: string;
-  theme?: string;
-  explicit?: boolean;
-  license?: string;
-};

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

@@ -1,28 +0,0 @@
-import React from 'react';
-import { Section } from '@polkadot/joy-utils/react/components';
-import { MediaView } from '../MediaView';
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { ChannelPreview } from '../channels/ChannelPreview';
-
-export type Props = {
-  channels?: ChannelEntity[];
-}
-
-export function AllChannels (props: Props) {
-  const { channels = [] } = props;
-
-  return channels.length === 0
-    ? <em>No channels found</em>
-    : <Section title={`All channels (${channels.length})`} className='ListOfChannels'>
-      {channels.map((x) =>
-        <ChannelPreview key={x.id} channel={x} withSubtitle={false} />
-      )}
-    </Section>;
-}
-
-export const AllChannelsView = MediaView<Props>({
-  component: AllChannels,
-  resolveProps: async ({ transport }) => ({
-    channels: await transport.allPublicVideoChannels()
-  })
-});

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

@@ -1,27 +0,0 @@
-import React from 'react';
-import { Section } from '@polkadot/joy-utils/react/components';
-import { VideoPreviewProps, VideoPreview } from '../video/VideoPreview';
-import { MediaView } from '../MediaView';
-
-export type Props = {
-  videos?: VideoPreviewProps[];
-}
-
-export function AllVideos (props: Props) {
-  const { videos = [] } = props;
-
-  return videos.length === 0
-    ? <em>No videos found</em>
-    : <Section title={`All videos (${videos.length})`} className='ListOfVideos'>
-      {videos.map((x) =>
-        <VideoPreview key={x.id} {...x} withChannel />
-      )}
-    </Section>;
-}
-
-export const AllVideosView = MediaView<Props>({
-  component: AllVideos,
-  resolveProps: async ({ transport }) => ({
-    videos: await transport.allPublicVideos()
-  })
-});

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

@@ -1,54 +0,0 @@
-import React from 'react';
-import { Link } from 'react-router-dom';
-import { Section } from '@polkadot/joy-utils/react/components';
-import { VideoPreviewProps, VideoPreview } from '../video/VideoPreview';
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { ChannelPreview } from '../channels/ChannelPreview';
-
-const LatestVideosTitle = () => (
-  <div>
-    Latest videos
-    <Link to={'/media/videos'} className='ViewAllLink'>All videos</Link>
-  </div>
-);
-
-const LatestChannelsTitle = () => (
-  <div>
-    Latest video channels
-    <Link to={'/media/channels'} className='ViewAllLink'>All channels</Link>
-  </div>
-);
-
-export type ExploreContentProps = {
-  featuredVideos?: VideoPreviewProps[];
-  latestVideos?: VideoPreviewProps[];
-  latestVideoChannels?: ChannelEntity[];
-}
-
-export function ExploreContent (props: ExploreContentProps) {
-  const { featuredVideos = [], latestVideos = [], latestVideoChannels = [] } = props;
-
-  return <div>
-    {featuredVideos.length > 0 &&
-      <Section title={'Featured videos'} className='ListOfVideos'>
-        {featuredVideos.map((x) =>
-          <VideoPreview key={x.id} {...x} withChannel />
-        )}
-      </Section>
-    }
-    {latestVideos.length > 0 &&
-      <Section className='ListOfVideos' title={<LatestVideosTitle />}>
-        {latestVideos.map((x) =>
-          <VideoPreview key={x.id} {...x} withChannel />
-        )}
-      </Section>
-    }
-    {latestVideoChannels.length > 0 &&
-      <Section className='ListOfChannels' title={<LatestChannelsTitle />}>
-        {latestVideoChannels.map((x) =>
-          <ChannelPreview key={x.id} channel={x} withSubtitle={false} />
-        )}
-      </Section>
-    }
-  </div>;
-}

+ 0 - 23
pioneer/packages/joy-media/src/explore/ExploreContent.view.tsx

@@ -1,23 +0,0 @@
-import { MediaView } from '../MediaView';
-import { ExploreContentProps, ExploreContent } from './ExploreContent';
-
-export const ExploreContentView = MediaView<ExploreContentProps>({
-  component: ExploreContent,
-  resolveProps: async (props) => {
-    const { transport } = props;
-
-    const [
-      latestVideoChannels,
-      latestVideos,
-      featuredVideos
-    ] = await Promise.all([
-      transport.latestPublicVideoChannels(),
-      transport.latestPublicVideos(),
-      transport.featuredVideos()
-    ]);
-
-    return { featuredVideos, latestVideos, latestVideoChannels };
-  }
-});
-
-export default ExploreContentView;

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

@@ -1,92 +0,0 @@
-import React, { useState } from 'react';
-import { MusicAlbumPreviewProps, MusicAlbumPreview } from '../music/MusicAlbumPreview';
-import { MusicTrackReaderPreviewProps, MusicTrackReaderPreview } from '../music/MusicTrackReaderPreview';
-import { Pluralize } from '@polkadot/joy-utils/react/components';
-import { Table } from 'semantic-ui-react';
-import { ChannelEntity } from '../entities/ChannelEntity';
-import { ChannelPreview } from '../channels/ChannelPreview';
-
-type Props = {
-  channel: ChannelEntity;
-  tracks: MusicTrackReaderPreviewProps[];
-  currentTrackIndex?: number;
-  featuredAlbums?: MusicAlbumPreviewProps[];
-};
-
-// TODO get meta from track item
-const meta = {
-  artist: 'Berlin Philharmonic',
-  composer: 'Wolfgang Amadeus Mozart',
-  genre: 'Classical Music',
-  mood: 'Relaxing',
-  theme: 'Dark',
-  explicit: false,
-  license: 'Public Domain'
-};
-
-export function PlayContent (props: Props) {
-  const { channel, tracks = [], currentTrackIndex = 0, featuredAlbums = [] } = props;
-
-  const [currentTrack, setCurrentTrack] = useState(tracks[currentTrackIndex]);
-
-  const metaField = (label: React.ReactNode, value: React.ReactNode) =>
-    <Table.Row>
-      <Table.Cell width={2}>{label}</Table.Cell>
-      <Table.Cell>{value}</Table.Cell>
-    </Table.Row>;
-
-  const metaTable = <>
-    <h3>Track Info</h3>
-    <Table basic='very' compact className='JoyPlayAlbum_MetaInfo'>
-      <Table.Body>
-        {metaField('Artist', meta.artist)}
-        {metaField('Composer', meta.composer)}
-        {metaField('Genre', meta.genre)}
-        {metaField('Mood', meta.mood)}
-        {metaField('Theme', meta.theme)}
-        {metaField('Explicit', meta.explicit ? 'Yes' : 'No')}
-        {metaField('License', meta.license)}
-      </Table.Body>
-    </Table>
-  </>;
-
-  const albumTracks = (
-    <div className='JoyPlayAlbum_AlbumTracks'>
-      <h3><Pluralize count={tracks.length} singularText='Track' /></h3>
-      <Table basic='very' compact>
-        <Table.Body>
-          {tracks.map((x, i) => {
-            const isCurrent = x.id === currentTrack.id;
-            const className = 'TrackRow ' + (isCurrent ? 'Current' : '');
-
-            return (
-              <Table.Row key={x.id} className={className} onClick={() => setCurrentTrack(x)}>
-                <Table.Cell className='TrackNumber' width={1}>{i + 1}</Table.Cell>
-                <Table.Cell className='TrackTitle'>{x.title}</Table.Cell>
-              </Table.Row>
-            );
-          })}
-        </Table.Body>
-      </Table>
-    </div>
-  );
-
-  return <div className='JoyPlayAlbum'>
-    <div className='JoyPlayAlbum_Main'>
-      <div className='JoyPlayAlbum_CurrentTrack'>
-        <MusicTrackReaderPreview {...currentTrack} size={400} />
-        <ChannelPreview channel={channel} />
-      </div>
-      <div>
-        {albumTracks}
-        {metaTable}
-      </div>
-    </div>
-    {featuredAlbums.length > 0 &&
-      <div className='JoyPlayAlbum_RightSidePanel'>
-        <h3>Featured albums</h3>
-        {featuredAlbums.map((x) => <MusicAlbumPreview key={x.id} {...x} size={170} />)}
-      </div>
-    }
-  </div>;
-}

+ 0 - 133
pioneer/packages/joy-media/src/index.scss

@@ -1,133 +0,0 @@
-.JoyPaperWidth {
-  max-width: 900px;
-  margin: 0 auto;
-}
-
-.UploadBox {
-  display: flex;
-  flex-direction: row;
-  justify-content: center;
-
-  .UploadSelectForm {
-    max-width: 500px;
-    width: 100%;
-  }
-
-  .UploadInputFile {
-    padding: 2rem 3rem;
-    margin-bottom: 1rem;
-    text-align: center;
-    height: auto;
-
-    &:hover,
-    &.FileSelected {
-      border: 1px solid #2185d0 !important;
-      .label {
-        color: #2185d0 !important;
-      }
-    }
-
-    i.cloud.icon {
-      font-size: 3rem;
-    }
-  }
-
-  .UploadButtonBox {
-    text-align: center;
-  }
-
-  .UploadProgress {
-    margin-left: calc(210px + 1rem) !important;
-    width: 100%;
-    max-width: 600px;
-  }
-
-  .EditMetaForm {
-    flex-grow: 1;
-    max-width: 600px;
-  }
-}
-
-.PlayBox {
-  max-width: 700px;
-  margin-bottom: 1rem;
-  h1, h2 {
-    text-transform: none;
-    margin: 0;
-  }
-  .ContentHeader {
-    margin-top: 1.5rem;
-    margin-bottom: .5rem;
-  }
-  .DownloadBtn {
-    float: right;
-    margin-left: .5rem;
-  }
-  .ContentDesc {
-    margin-top: 1rem;
-  }
-}
-
-.MediaGrid {
-  display: flex;
-  flex-direction: row;
-  flex-wrap: wrap;
-  width: 880px;
-
-  .MediaCell {
-    width: 25%;
-
-    &:hover {
-      background-color: #deeffc;
-    }
-    .CellContent {
-      padding: 5px;
-      margin-bottom: 15px;
-      overflow: hidden;
-
-      h3 {
-        font-size: 1rem;
-        font-weight: bold;
-        margin: 1rem 0 .5rem 0;
-      }
-    }
-
-    .ThumbBox {
-      display: flex;
-      flex-direction: row;
-      justify-content: center;
-      margin-bottom: 5px;
-
-      .ThumbImg {
-        width: 210px;
-        max-height: 118px;
-        display: block;
-      }
-    }
-  }
-}
-
-.EditMetaBox {
-  display: flex;
-  flex-direction: row;
-  flex-wrap: wrap;
-  /* width: 880px; */
-
-  .EditMetaThumb {
-    width: 100%;
-    max-width: 210px;
-    max-height: 118px;
-    margin-right: 1rem;
-
-    img {
-      width: 100%;
-      max-width: 210px;
-      max-height: 118px;
-    }
-  }
-
-  .JoySection {
-    width: 100%;
-    max-width: 600px;
-  }
-}

+ 0 - 82
pioneer/packages/joy-media/src/index.tsx

@@ -1,82 +0,0 @@
-
-import React from 'react';
-import { Route, Switch } from 'react-router';
-
-import { AppProps, I18nProps } from '@polkadot/react-components/types';
-import Tabs from '@polkadot/react-components/Tabs';
-import { TabItem } from '@polkadot/react-components/Tabs/types';
-import { ApiProps } from '@polkadot/react-api/types';
-import { withMulti } from '@polkadot/react-api/hoc';
-
-import './index.scss';
-import './common/index.scss';
-
-import translate from './translate';
-import { useMyAccount } from '@polkadot/joy-utils/react/hooks';
-import { UploadWithRouter } from './Upload';
-import { DiscoveryProviderProps, DiscoveryProviderProvider } from './DiscoveryProvider';
-import { SubstrateTransportProvider } from './TransportContext';
-import { ChannelsByOwnerWithRouter } from './channels/ChannelsByOwner.view';
-import { EditChannelView, EditChannelWithRouter } from './channels/EditChannel.view';
-import { ExploreContentView } from './explore/ExploreContent.view';
-import { ViewChannelWithRouter } from './channels/ViewChannel.view';
-import { EditVideoWithRouter } from './upload/EditVideo.view';
-import { PlayVideoWithRouter } from './video/PlayVideo.view';
-import { AllVideosView } from './explore/AllVideos';
-import { AllChannelsView } from './explore/AllChannels';
-// import { VideosByOwner } from './video/VideosByOwner';
-
-type Props = AppProps & I18nProps & ApiProps & DiscoveryProviderProps;
-
-function App (props: Props) {
-  const { t, basePath } = props;
-  const { state: { address: myAddress } } = useMyAccount();
-
-  const tabs: TabItem[] = [
-    {
-      isRoot: true,
-      name: 'explore',
-      text: t('Explore')
-    },
-    !myAddress ? undefined : {
-      name: `account/${myAddress}/channels`,
-      text: t('My channels')
-    }
-    // !myAddress ? undefined : {
-    //   name: `account/${myAddress}/videos`,
-    //   text: t('My videos')
-    // }
-  ].filter((x) => x !== undefined) as TabItem[];
-
-  return (
-    <SubstrateTransportProvider>
-      <DiscoveryProviderProvider>
-        <main className='media--App'>
-          <header>
-            <Tabs basePath={basePath} items={tabs} />
-          </header>
-          <Switch>
-            <Route path={`${basePath}/account/:account/channels`} component={ChannelsByOwnerWithRouter} />
-            <Route path={`${basePath}/channels/new`} component={EditChannelView} />
-            <Route path={`${basePath}/channels/:id/edit`} component={EditChannelWithRouter} />
-            <Route path={`${basePath}/channels/:channelId/upload`} component={UploadWithRouter} />
-            <Route path={`${basePath}/channels/:id`} component={ViewChannelWithRouter} />
-            <Route path={`${basePath}/channels/:id`} component={ViewChannelWithRouter} />
-            <Route path={`${basePath}/channels`} component={AllChannelsView} />
-            {/* <Route path={`${basePath}/videos/my`} component={VideosByOwnerView} /> */}
-            <Route path={`${basePath}/videos/:id/edit`} component={EditVideoWithRouter} />
-            <Route path={`${basePath}/videos/:id`} component={PlayVideoWithRouter} />
-            <Route path={`${basePath}/videos`} component={AllVideosView} />
-            <Route path={`${basePath}/explore`} component={ExploreContentView} />
-            <Route component={ExploreContentView} />
-          </Switch>
-        </main>
-      </DiscoveryProviderProvider>
-    </SubstrateTransportProvider>
-  );
-}
-
-export default withMulti(
-  App,
-  translate
-);

+ 0 - 14
pioneer/packages/joy-media/src/mocks/ContentLicense.mock.ts

@@ -1,14 +0,0 @@
-import { newEntityId } from './EntityId.mock';
-import { ContentLicenseType } from '../schemas/general/ContentLicense';
-
-const values = [
-  'Public Domain',
-  'Share Alike',
-  'No Derivatives',
-  'No Commercial'
-];
-
-export const AllContentLicenses: ContentLicenseType[] =
-  values.map((value) => ({ id: newEntityId(), value })) as unknown as ContentLicenseType[]; // A hack to fix TS compilation.
-
-export const ContentLicense = AllContentLicenses[0];

+ 0 - 18
pioneer/packages/joy-media/src/mocks/CurationStatus.mock.ts

@@ -1,18 +0,0 @@
-import { newEntityId } from './EntityId.mock';
-import { CurationStatusType } from '../schemas/general/CurationStatus';
-
-function newEntity (value: string): CurationStatusType {
-  return { id: newEntityId(), value } as unknown as CurationStatusType; // A hack to fix TS compilation.
-}
-
-export const CurationStatus = {
-  Edited: newEntity('Edited'),
-  UpdatedSchema: newEntity('Updated schema'),
-  UnderReview: newEntity('Under review'),
-  Removed: newEntity('Removed')
-};
-
-export const AllCurationStatuses: CurationStatusType[] =
-  Object.values(CurationStatus);
-
-export const DefaultCurationStatus = CurationStatus.Edited;

+ 0 - 9
pioneer/packages/joy-media/src/mocks/EntityId.mock.ts

@@ -1,9 +0,0 @@
-let value = 1;
-
-export function nextEntityId (): number {
-  return value;
-}
-
-export function newEntityId (): number {
-  return value++;
-}

+ 0 - 10
pioneer/packages/joy-media/src/mocks/FeaturedContent.mock.ts

@@ -1,10 +0,0 @@
-import { newEntityId } from './EntityId.mock';
-import { FeaturedContentType } from '../schemas/general/FeaturedContent';
-import { AllVideos, AllMusicAlbums, Video } from '.';
-
-export const FeaturedContent: FeaturedContentType = {
-  id: newEntityId(),
-  topVideo: Video,
-  featuredVideos: AllVideos,
-  featuredAlbums: AllMusicAlbums
-} as unknown as FeaturedContentType; // A hack to fix TS compilation.

+ 0 - 11
pioneer/packages/joy-media/src/mocks/Language.mock.ts

@@ -1,11 +0,0 @@
-import { newEntityId } from './EntityId.mock';
-import { LanguageType } from '../schemas/general/Language';
-
-const values = [
-  'aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar', 'as', 'av', 'ay', 'az', 'ba', 'be', 'bg', 'bh', 'bi', 'bm', 'bn', 'bo', 'br', 'bs', 'ca', 'ce', 'ch', 'co', 'cr', 'cs', 'cu', 'cv', 'cy', 'da', 'de', 'dv', 'dz', 'ee', 'el', 'en', 'eo', 'es', 'et', 'eu', 'fa', 'ff', 'fi', 'fj', 'fo', 'fr', 'fy', 'ga', 'gd', 'gl', 'gn', 'gu', 'gv', 'ha', 'he', 'hi', 'ho', 'hr', 'ht', 'hu', 'hy', 'hz', 'ia', 'id', 'ie', 'ig', 'ii', 'ik', 'io', 'is', 'it', 'iu', 'ja', 'jv', 'ka', 'kg', 'ki', 'kj', 'kk', 'kl', 'km', 'kn', 'ko', 'kr', 'ks', 'ku', 'kv', 'kw', 'ky', 'la', 'lb', 'lg', 'li', 'ln', 'lo', 'lt', 'lu', 'lv', 'mg', 'mh', 'mi', 'mk', 'ml', 'mn', 'mr', 'ms', 'mt', 'my', 'na', 'nb', 'nd', 'ne', 'ng', 'nl', 'nn', 'no', 'nr', 'nv', 'ny', 'oc', 'oj', 'om', 'or', 'os', 'pa', 'pi', 'pl', 'ps', 'pt', 'qu', 'rm', 'rn', 'ro', 'ru', 'rw', 'sa', 'sc', 'sd', 'se', 'sg', 'si', 'sk', 'sl', 'sm', 'sn', 'so', 'sq', 'sr', 'ss', 'st', 'su', 'sv', 'sw', 'ta', 'te', 'tg', 'th', 'ti', 'tk', 'tl', 'tn', 'to', 'tr', 'ts', 'tt', 'tw', 'ty', 'ug', 'uk', 'ur', 'uz', 've', 'vi', 'vo', 'wa', 'wo', 'xh', 'yi', 'yo', 'za', 'zh', 'zu'
-];
-
-export const AllLanguages: LanguageType[] =
-  values.map((value) => ({ id: newEntityId(), value })) as unknown as LanguageType[]; // A hack to fix TS compilation.
-
-export const Language = AllLanguages[0];

+ 0 - 17
pioneer/packages/joy-media/src/mocks/MediaObject.mock.ts

@@ -1,17 +0,0 @@
-import { newEntityId } from './EntityId.mock';
-import { MediaObjectType } from '../schemas/general/MediaObject';
-
-const values = [
-  '5Gm2XPvDm1RhYW2CEbVvrMbRFguL4TMmzP3tm72wvhCZdx5G',
-  '5GTGqmWTurJhYY5UoHzFrAqAxL5ry4Jegw9pmjKniQ3KWWww',
-  '5CbyRopmCNwLYyRCwHrmovoQ15MMCau9v9cmazbWuQjY9DG2',
-  '5GTXWLWgfCM6GpsBkeJQZvF6RFvZh3SjCsH8aGUY1WwV5YGU',
-  '5CSBeDZR5baBcnLYZsP839P1uqZKfz3D9Uip43uvhUd56XAq',
-  '5EXsnf4sS6wVsgjqQmT2jchP2LdGXLxZZSJijjTiUxcLm7Vg',
-  '5HRieqw8oRZfwc6paio4TrBeYvmdTstGB2KoKE9gL5qLnAQY'
-];
-
-export const AllMediaObjects: MediaObjectType[] =
-  values.map((value) => ({ id: newEntityId(), value })) as unknown as MediaObjectType[]; // A hack to fix TS compilation.
-
-export const MediaObject = AllMediaObjects[0];

+ 0 - 34
pioneer/packages/joy-media/src/mocks/MusicAlbum.mock.ts

@@ -1,34 +0,0 @@
-import { newEntityId } from './EntityId.mock';
-import { MusicAlbumType } from '../schemas/music/MusicAlbum';
-import { MusicGenre } from './MusicGenre.mock';
-import { MusicMood } from './MusicMood.mock';
-import { MusicTheme } from './MusicTheme.mock';
-import { DefaultPublicationStatus } from './PublicationStatus.mock';
-import { DefaultCurationStatus } from './CurationStatus.mock';
-import { ContentLicense } from './ContentLicense.mock';
-import { Language } from './Language.mock';
-
-export const MusicAlbum: MusicAlbumType = {
-  id: newEntityId(),
-  title: 'Riddle',
-  artist: 'Liquid Stone',
-  thumbnail: 'https://images.unsplash.com/photo-1484352491158-830ef5692bb3?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60',
-  description: 'Building material is any material which is used for construction purposes. Many naturally occurring substances, such as clay, rocks, sand, and wood, even twigs and leaves, have been used to construct buildings.\n\nApart from naturally occurring materials, many man-made products are in use, some more and some less synthetic.',
-  firstReleased: 567425123, // 1987 year.
-  genre: MusicGenre,
-  mood: MusicMood,
-  theme: MusicTheme,
-  tracks: [],
-  language: Language,
-  link: [],
-  lyrics: undefined,
-  composerOrSongwriter: 'Massive Sand',
-  reviews: [],
-  publicationStatus: DefaultPublicationStatus,
-  curationStatus: DefaultCurationStatus,
-  explicit: false,
-  license: ContentLicense,
-  attribution: undefined
-} as unknown as MusicAlbumType; // A hack to fix TS compilation.
-
-export const AllMusicAlbums: MusicAlbumType[] = [MusicAlbum];

+ 0 - 31
pioneer/packages/joy-media/src/mocks/MusicGenre.mock.ts

@@ -1,31 +0,0 @@
-import { newEntityId } from './EntityId.mock';
-import { MusicGenreType } from '../schemas/music/MusicGenre';
-
-const values = [
-  'Avant-Garde',
-  'Blues',
-  'Children\'s',
-  'Classical',
-  'Comedy/Spoken',
-  'Country',
-  'Easy Listening',
-  'Electronic',
-  'Folk',
-  'Holiday',
-  'International',
-  'Jazz',
-  'Latin',
-  'New Age',
-  'Pop/Rock',
-  'R&B',
-  'Rap',
-  'Reggae',
-  'Religious',
-  'Stage & Screen',
-  'Vocal'
-];
-
-export const AllMusicGenres: MusicGenreType[] =
-  values.map((value) => ({ id: newEntityId(), value })) as unknown as MusicGenreType[]; // A hack to fix TS compilation.
-
-export const MusicGenre = AllMusicGenres[0];

+ 0 - 299
pioneer/packages/joy-media/src/mocks/MusicMood.mock.ts

@@ -1,299 +0,0 @@
-import { newEntityId } from './EntityId.mock';
-import { MusicMoodType } from '../schemas/music/MusicMood';
-
-const values = [
-  'Acerbic',
-  'Aggressive',
-  'Agreeable',
-  'Airy',
-  'Ambitious',
-  'Amiable/Good-Natured',
-  'Angry',
-  'Angst-Ridden',
-  'Anguished/Distraught',
-  'Angular',
-  'Animated',
-  'Apocalyptic',
-  'Arid',
-  'Athletic',
-  'Atmospheric',
-  'Austere',
-  'Autumnal',
-  'Belligerent',
-  'Benevolent',
-  'Bitter',
-  'Bittersweet',
-  'Bleak',
-  'Boisterous',
-  'Bombastic',
-  'Brash',
-  'Brassy',
-  'Bravado',
-  'Bright',
-  'Brittle',
-  'Brooding',
-  'Calm/Peaceful',
-  'Campy',
-  'Capricious',
-  'Carefree',
-  'Cartoonish',
-  'Cathartic',
-  'Celebratory',
-  'Cerebral',
-  'Cheerful',
-  'Child-like',
-  'Circular',
-  'Clinical',
-  'Cold',
-  'Comic',
-  'Complex',
-  'Concise',
-  'Confident',
-  'Confrontational',
-  'Cosmopolitan',
-  'Crunchy',
-  'Cynical/Sarcastic',
-  'Dark',
-  'Declamatory',
-  'Defiant',
-  'Delicate',
-  'Demonic',
-  'Desperate',
-  'Detached',
-  'Devotional',
-  'Difficult',
-  'Dignified/Noble',
-  'Dramatic',
-  'Dreamy',
-  'Driving',
-  'Druggy',
-  'Earnest',
-  'Earthy',
-  'Ebullient',
-  'Eccentric',
-  'Ecstatic',
-  'Eerie',
-  'Effervescent',
-  'Elaborate',
-  'Elegant',
-  'Elegiac',
-  'Energetic',
-  'Enigmatic',
-  'Epic',
-  'Erotic',
-  'Ethereal',
-  'Euphoric',
-  'Exciting',
-  'Exotic',
-  'Explosive',
-  'Extroverted',
-  'Exuberant',
-  'Fantastic/Fantasy-like',
-  'Feral',
-  'Feverish',
-  'Fierce',
-  'Fiery',
-  'Flashy',
-  'Flowing',
-  'Fractured',
-  'Freewheeling',
-  'Fun',
-  'Funereal',
-  'Gentle',
-  'Giddy',
-  'Gleeful',
-  'Gloomy',
-  'Graceful',
-  'Greasy',
-  'Grim',
-  'Gritty',
-  'Gutsy',
-  'Happy',
-  'Harsh',
-  'Hedonistic',
-  'Heroic',
-  'Hostile',
-  'Humorous',
-  'Hungry',
-  'Hymn-like',
-  'Hyper',
-  'Hypnotic',
-  'Improvisatory',
-  'Indulgent',
-  'Innocent',
-  'Insular',
-  'Intense',
-  'Intimate',
-  'Introspective',
-  'Ironic',
-  'Irreverent',
-  'Jovial',
-  'Joyous',
-  'Kinetic',
-  'Knotty',
-  'Laid-Back/Mellow',
-  'Languid',
-  'Lazy',
-  'Light',
-  'Literate',
-  'Lively',
-  'Lonely',
-  'Lush',
-  'Lyrical',
-  'Macabre',
-  'Magical',
-  'Majestic',
-  'Malevolent',
-  'Manic',
-  'Marching',
-  'Martial',
-  'Meandering',
-  'Mechanical',
-  'Meditative',
-  'Melancholy',
-  'Menacing',
-  'Messy',
-  'Mighty',
-  'Monastic',
-  'Monumental',
-  'Motoric',
-  'Mysterious',
-  'Mystical',
-  'Naive',
-  'Narcotic',
-  'Narrative',
-  'Negative',
-  'Nervous/Jittery',
-  'Nihilistic',
-  'Nocturnal',
-  'Nostalgic',
-  'Ominous',
-  'Optimistic',
-  'Opulent',
-  'Organic',
-  'Ornate',
-  'Outraged',
-  'Outrageous',
-  'Paranoid',
-  'Passionate',
-  'Pastoral',
-  'Patriotic',
-  'Perky',
-  'Philosophical',
-  'Plain',
-  'Plaintive',
-  'Playful',
-  'Poignant',
-  'Positive',
-  'Powerful',
-  'Precious',
-  'Provocative',
-  'Pulsing',
-  'Pure',
-  'Quirky',
-  'Rambunctious',
-  'Ramshackle',
-  'Raucous',
-  'Reassuring/Consoling',
-  'Rebellious',
-  'Reckless',
-  'Refined',
-  'Reflective',
-  'Regretful',
-  'Relaxed',
-  'Reserved',
-  'Resolute',
-  'Restrained',
-  'Reverent',
-  'Rhapsodic',
-  'Rollicking',
-  'Romantic',
-  'Rousing',
-  'Rowdy',
-  'Rustic',
-  'Sacred',
-  'Sad',
-  'Sarcastic',
-  'Sardonic',
-  'Satirical',
-  'Savage',
-  'Scary',
-  'Scattered',
-  'Searching',
-  'Self-Conscious',
-  'Sensual',
-  'Sentimental',
-  'Serious',
-  'Severe',
-  'Sexual',
-  'Sexy',
-  'Shimmering',
-  'Silly',
-  'Sleazy',
-  'Slick',
-  'Smooth',
-  'Snide',
-  'Soft/Quiet',
-  'Somber',
-  'Soothing',
-  'Sophisticated',
-  'Spacey',
-  'Sparkling',
-  'Sparse',
-  'Spicy',
-  'Spiritual',
-  'Spontaneous',
-  'Spooky',
-  'Sprawling',
-  'Sprightly',
-  'Springlike',
-  'Stately',
-  'Street-Smart',
-  'Striding',
-  'Strong',
-  'Stylish',
-  'Suffocating',
-  'Sugary',
-  'Summery',
-  'Suspenseful',
-  'Swaggering',
-  'Sweet',
-  'Swinging',
-  'Technical',
-  'Tender',
-  'Tense/Anxious',
-  'Theatrical',
-  'Thoughtful',
-  'Threatening',
-  'Thrilling',
-  'Thuggish',
-  'Tragic',
-  'Transparent/Translucent',
-  'Trashy',
-  'Trippy',
-  'Triumphant',
-  'Tuneful',
-  'Turbulent',
-  'Uncompromising',
-  'Understated',
-  'Unsettling',
-  'Uplifting',
-  'Urgent',
-  'Virile',
-  'Visceral',
-  'Volatile',
-  'Vulgar',
-  'Warm',
-  'Weary',
-  'Whimsical',
-  'Wintry',
-  'Wistful',
-  'Witty',
-  'Wry',
-  'Yearning'
-];
-
-export const AllMusicMoods: MusicMoodType[] =
-  values.map((value) => ({ id: newEntityId(), value })) as unknown as MusicMoodType[]; // A hack to fix TS compilation.
-
-export const MusicMood = AllMusicMoods[0];

+ 0 - 192
pioneer/packages/joy-media/src/mocks/MusicTheme.mock.ts

@@ -1,192 +0,0 @@
-import { newEntityId } from './EntityId.mock';
-import { MusicThemeType } from '../schemas/music/MusicTheme';
-
-const values = [
-  'Adventure',
-  'Affection/Fondness',
-  'Affirmation',
-  'Anger/Hostility',
-  'Animals',
-  'Anniversary',
-  'Argument',
-  'At the Beach',
-  'At the Office',
-  'Autumn',
-  'Award Winners',
-  'Awareness',
-  'Background Music',
-  'Biographical',
-  'Birth',
-  'Birthday',
-  'Breakup',
-  'Cars',
-  'Celebration',
-  'Celebrities',
-  'Children',
-  'Christmas',
-  'Christmas Party',
-  'City Life',
-  'Classy Gatherings',
-  'Club',
-  'Comfort',
-  'Conflict',
-  'Cool & Cocky',
-  'Country Life',
-  'Crime',
-  'D-I-V-O-R-C-E',
-  'Dance Party',
-  'Day Driving',
-  'Daydreaming',
-  'Death',
-  'Despair',
-  'Destiny',
-  'Dinner Ambiance',
-  'Disappointment',
-  'Dreaming',
-  'Drinking',
-  'Drugs',
-  'Early Morning',
-  'Easter',
-  'Empowering',
-  'Everyday Life',
-  'Exercise/Workout',
-  'Family',
-  'Family Gatherings',
-  'Fantasy',
-  'Fear',
-  'Feeling Blue',
-  'Flying',
-  'Food/Eating',
-  'Forgiveness',
-  'Fourth of July',
-  'Freedom',
-  'Friendship',
-  'Funeral',
-  'Girls Night Out',
-  'Good Times',
-  'Goodbyes',
-  'Graduation',
-  'Guys Night Out',
-  'Halloween',
-  'Hanging Out',
-  'Happiness',
-  'Healing/Comfort',
-  'Heartache',
-  'Heartbreak',
-  'High School',
-  'Historical Events',
-  'Holidays',
-  'Home',
-  'Homecoming',
-  'Hope',
-  'Housework',
-  'Illness',
-  'In Love',
-  'Introspection',
-  'Jealousy',
-  'Joy',
-  'Late Night',
-  'Lifecycle',
-  'Loneliness',
-  'Long Walk',
-  'Loss/Grief',
-  'Lying',
-  'Magic',
-  'Maverick',
-  'Meditation',
-  'Memorial',
-  'Military',
-  'Mischievous',
-  'Monday Morning',
-  'Money',
-  'Moon',
-  'Morning',
-  'Motivation',
-  'Music',
-  'Myths & Legends',
-  'Nature',
-  'New Love',
-  'Night Driving',
-  'Nighttime',
-  'Open Road',
-  'Other Times & Places',
-  'Pain',
-  'Parenthood',
-  'Partying',
-  'Passion',
-  'Patriotism',
-  'Peace',
-  'Picnic',
-  'Playful',
-  'Poetry',
-  'Politics/Society',
-  'Pool Party',
-  'Prom',
-  'Promises',
-  'Protest',
-  'Rainy Day',
-  'Reflection',
-  'Regret',
-  'Relationships',
-  'Relaxation',
-  'Religion',
-  'Reminiscing',
-  'Reunion',
-  'Revolutionary',
-  'Road Trip',
-  'Romance',
-  'Romantic Evening',
-  'Scary Music',
-  'School',
-  'Science',
-  'SciFi',
-  'Seduction',
-  'Separation',
-  'Sex',
-  'Slow Dance',
-  'Small Gathering',
-  'Solitude',
-  'Sorrow',
-  'Sports',
-  'Spring',
-  'Starry Sky',
-  'Starting Out',
-  'Stay in Bed',
-  'Storms',
-  'Street Life',
-  'Summer',
-  'Sun',
-  'Sunday Afternoon',
-  'Sweet Dreams',
-  'Teenagers',
-  'Temptation',
-  'TGIF',
-  'Thanksgiving',
-  'The Creative Side',
-  'The Great Outdoors',
-  'Theme',
-  'Tragedy',
-  'Travel',
-  'Truth',
-  'Vacation',
-  'Victory',
-  'Violence',
-  'Visions',
-  'War',
-  'Water',
-  'Weather',
-  'Wedding',
-  'Winter',
-  'Wisdom',
-  'Word Play',
-  'Work',
-  'World View',
-  'Yearning',
-  'Youth',
-  'Zeitgeist'
-];
-
-export const AllMusicThemes: MusicThemeType[] =
-  values.map((value) => ({ id: newEntityId(), value })) as unknown as MusicThemeType[]; // A hack to fix TS compilation.
-
-export const MusicTheme = AllMusicThemes[0];

+ 0 - 33
pioneer/packages/joy-media/src/mocks/MusicTrack.mock.ts

@@ -1,33 +0,0 @@
-import { newEntityId } from './EntityId.mock';
-import { MusicTrackType } from '../schemas/music/MusicTrack';
-import { MusicGenre } from './MusicGenre.mock';
-import { MusicMood } from './MusicMood.mock';
-import { MusicTheme } from './MusicTheme.mock';
-import { DefaultPublicationStatus } from './PublicationStatus.mock';
-import { DefaultCurationStatus } from './CurationStatus.mock';
-import { ContentLicense } from './ContentLicense.mock';
-import { Language } from './Language.mock';
-
-export const MusicTrack: MusicTrackType = {
-  id: newEntityId(),
-  title: 'Requiem (Mozart)',
-  artist: 'Berlin Philharmonic',
-  thumbnail: 'https://assets.classicfm.com/2017/36/mozart-1504532179-list-handheld-0.jpg',
-  description: 'The Requiem in D minor, K. 626, is a requiem mass by Wolfgang Amadeus Mozart (1756–1791). Mozart composed part of the Requiem in Vienna in late 1791, but it was unfinished at his death on 5 December the same year.',
-  language: Language,
-  firstReleased: 567425967, // 1987 year.
-  genre: MusicGenre,
-  mood: MusicMood,
-  theme: MusicTheme,
-  link: [],
-  composerOrSongwriter: 'Mozart',
-  lyrics: undefined,
-  object: undefined,
-  publicationStatus: DefaultPublicationStatus,
-  curationStatus: DefaultCurationStatus,
-  explicit: false,
-  license: ContentLicense,
-  attribution: undefined
-} as unknown as MusicTrackType; // A hack to fix TS compilation.
-
-export const AllMusicTracks: MusicTrackType[] = [MusicTrack];

+ 0 - 16
pioneer/packages/joy-media/src/mocks/PublicationStatus.mock.ts

@@ -1,16 +0,0 @@
-import { newEntityId } from './EntityId.mock';
-import { PublicationStatusType } from '../schemas/general/PublicationStatus';
-
-function newEntity (value: string): PublicationStatusType {
-  return { id: newEntityId(), value } as unknown as PublicationStatusType; // A hack to fix TS compilation.
-}
-
-export const PublicationStatus = {
-  Publiс: newEntity('Public'),
-  Unlisted: newEntity('Unlisted')
-};
-
-export const AllPublicationStatuses: PublicationStatusType[] =
-  Object.values(PublicationStatus);
-
-export const DefaultPublicationStatus = PublicationStatus.Publiс;

+ 0 - 53
pioneer/packages/joy-media/src/mocks/Video.mock.ts

@@ -1,53 +0,0 @@
-import { newEntityId } from './EntityId.mock';
-import { VideoType } from '../schemas/video/Video';
-import { Language } from './Language.mock';
-import { VideoCategory } from './VideoCategory.mock';
-import { DefaultPublicationStatus } from './PublicationStatus.mock';
-import { DefaultCurationStatus } from './CurationStatus.mock';
-import { ContentLicense } from './ContentLicense.mock';
-
-const titles = [
-  'Arborvitae (Thuja occidentalis)',
-  'Black Ash (Fraxinus nigra)',
-  'White Ash (Fraxinus americana)',
-  'Bigtooth Aspen (Populus grandidentata)',
-  'Quaking Aspen (Populus tremuloides)',
-  'Basswood (Tilia americana)',
-  'American Beech (Fagus grandifolia)',
-  'Black Birch (Betula lenta)',
-  'Gray Birch (Betula populifolia)',
-  'Paper Birch (Betula papyrifera)',
-  'Yellow Birch (Betula alleghaniensis)',
-  'Butternut (Juglans cinerea)',
-  'Black Cherry (Prunus serotina)',
-  'Pin Cherry (Prunus pensylvanica)'
-];
-
-const thumbnails = [
-  'https://images.unsplash.com/photo-1477414348463-c0eb7f1359b6?ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=60',
-  'https://images.unsplash.com/photo-1484352491158-830ef5692bb3?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60',
-  'https://images.unsplash.com/photo-1543467091-5f0406620f8b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=200&q=60',
-  'https://images.unsplash.com/photo-1526749837599-b4eba9fd855e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=200&q=60',
-  'https://images.unsplash.com/photo-1504567961542-e24d9439a724?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=200&q=60',
-  'https://images.unsplash.com/photo-1543716091-a840c05249ec?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=200&q=60',
-  'https://images.unsplash.com/photo-1444465693019-aa0b6392460d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=200&q=60'
-];
-
-export const AllVideos: VideoType[] = thumbnails.map((thumbnail, i) => ({
-  id: newEntityId(),
-  title: titles[i],
-  thumbnail,
-  description: 'Nature, in the broadest sense, is the natural, physical, or material world or universe. "Nature" can refer to the phenomena of the physical world, and also to life in general. The study of nature is a large, if not the only, part of science. Although humans are part of nature, human activity is often understood as a separate category from other natural phenomena.',
-  language: Language,
-  firstReleased: 567425543, // 1987 year.
-  category: VideoCategory,
-  link: [],
-  object: undefined,
-  publicationStatus: DefaultPublicationStatus,
-  curationStatus: DefaultCurationStatus,
-  explicit: true,
-  license: ContentLicense,
-  attribution: undefined
-})) as unknown as VideoType[]; // A hack to fix TS compilation.
-
-export const Video = AllVideos[0];

+ 0 - 25
pioneer/packages/joy-media/src/mocks/VideoCategory.mock.ts

@@ -1,25 +0,0 @@
-import { newEntityId } from './EntityId.mock';
-import { VideoCategoryType } from '../schemas/video/VideoCategory';
-
-const values = [
-  'Film & Animation',
-  'Autos & Vehicles',
-  'Music',
-  'Pets & Animals',
-  'Sports',
-  'Travel & Events',
-  'Gaming',
-  'People & Blogs',
-  'Comedy',
-  'Entertainment',
-  'News & Politics',
-  'Howto & Style',
-  'Education',
-  'Science & Technology',
-  'Nonprofits & Activism'
-];
-
-export const AllVideoCategories: VideoCategoryType[] =
-  values.map((value) => ({ id: newEntityId(), value })) as unknown as VideoCategoryType[]; // A hack to fix TS compilation.
-
-export const VideoCategory = AllVideoCategories[0];

+ 0 - 14
pioneer/packages/joy-media/src/mocks/index.ts

@@ -1,14 +0,0 @@
-export * from './ContentLicense.mock';
-export * from './CurationStatus.mock';
-export * from './EntityId.mock';
-export * from './FeaturedContent.mock';
-export * from './Language.mock';
-export * from './MediaObject.mock';
-export * from './MusicAlbum.mock';
-export * from './MusicGenre.mock';
-export * from './MusicMood.mock';
-export * from './MusicTheme.mock';
-export * from './MusicTrack.mock';
-export * from './PublicationStatus.mock';
-export * from './Video.mock';
-export * from './VideoCategory.mock';

+ 0 - 14
pioneer/packages/joy-media/src/music/EditAlbumModal.tsx

@@ -1,14 +0,0 @@
-import React from 'react';
-import { Button, Modal } from 'semantic-ui-react';
-import { TracksOfMyMusicAlbumProps, TracksOfMyMusicAlbum } from './MusicAlbumTracks';
-
-export const EditAlbumModal = (props: TracksOfMyMusicAlbumProps) => {
-  return <Modal trigger={<Button icon='pencil'>Edit album</Button>} centered={false}>
-    <Modal.Header>Edit My Album</Modal.Header>
-    <Modal.Content image>
-      <Modal.Description>
-        <TracksOfMyMusicAlbum {...props} />
-      </Modal.Description>
-    </Modal.Content>
-  </Modal>;
-};

+ 0 - 180
pioneer/packages/joy-media/src/music/EditMusicAlbum.tsx

@@ -1,180 +0,0 @@
-import React from 'react';
-import { Button, Tab } from 'semantic-ui-react';
-import { Form, withFormik } from 'formik';
-import { History } from 'history';
-
-import { TxButton } from '@polkadot/joy-utils/react/components';
-import { onImageError } from '../common/images';
-import { ReorderableTracks } from './ReorderableTracks';
-import { MusicAlbumValidationSchema, MusicAlbumType, MusicAlbumClass as Fields, MusicAlbumFormValues, MusicAlbumToFormValues } from '../schemas/music/MusicAlbum';
-import { withMediaForm, MediaFormProps, datePlaceholder } from '../common/MediaForms';
-import EntityId from '@joystream/types/versioned-store/EntityId';
-import { MediaDropdownOptions } from '../common/MediaDropdownOptions';
-import { MusicTrackReaderPreviewProps } from './MusicTrackReaderPreview';
-import { FormTabs } from '../common/FormTabs';
-
-export type OuterProps = {
-  history?: History;
-  id?: EntityId;
-  entity?: MusicAlbumType;
-  tracks?: MusicTrackReaderPreviewProps[];
-  opts?: MediaDropdownOptions;
-};
-
-type FormValues = MusicAlbumFormValues;
-
-const InnerForm = (props: MediaFormProps<OuterProps, FormValues>) => {
-  const {
-    // React components for form fields:
-    MediaText,
-    MediaDropdown,
-    LabelledField,
-
-    // Callbacks:
-    onSubmit,
-    onTxSuccess,
-    onTxFailed,
-
-    // history,
-    entity,
-    tracks = [],
-    opts = MediaDropdownOptions.Empty,
-
-    values,
-    dirty,
-    errors,
-    isValid,
-    isSubmitting,
-    resetForm
-  } = props;
-
-  const { thumbnail } = values;
-
-  const isNew = !entity;
-
-  const buildTxParams = () => {
-    if (!isValid) return [];
-
-    return [];
-  };
-
-  const basicInfoTab = () => <Tab.Pane as='div'>
-    <MediaText field={Fields.title} {...props} />
-    <MediaText field={Fields.artist} {...props} />
-    <MediaText field={Fields.thumbnail} {...props} />
-    <MediaText field={Fields.description} textarea {...props} />
-    <MediaText field={Fields.firstReleased} placeholder={datePlaceholder} {...props} />
-    <MediaText field={Fields.explicit} {...props} />
-    <MediaDropdown field={Fields.license} options={opts.contentLicenseOptions} {...props} />
-    <MediaDropdown field={Fields.publicationStatus} options={opts.publicationStatusOptions} {...props} />
-  </Tab.Pane>;
-
-  const additionalTab = () => <Tab.Pane as='div'>
-    <MediaText field={Fields.composerOrSongwriter} {...props} />
-    <MediaDropdown field={Fields.genre} options={opts.musicGenreOptions} {...props} />
-    <MediaDropdown field={Fields.mood} options={opts.musicMoodOptions} {...props} />
-    <MediaDropdown field={Fields.theme} options={opts.musicThemeOptions} {...props} />
-    <MediaDropdown field={Fields.language} options={opts.languageOptions} {...props} />
-    <MediaText field={Fields.lyrics} {...props} />
-    <MediaText field={Fields.attribution} {...props} />
-  </Tab.Pane>;
-
-  const tracksTab = () => <Tab.Pane as='div'>
-    <ReorderableTracks
-      tracks={tracks}
-      noTracksView={<em style={{ padding: '1rem 0', display: 'block' }}>This album has no tracks yet.</em>}
-    />
-  </Tab.Pane>;
-
-  const tabs = <FormTabs errors={errors} panes={[
-    {
-      id: 'Basic info',
-      render: basicInfoTab,
-      fields: [
-        Fields.title,
-        Fields.artist,
-        Fields.thumbnail,
-        Fields.description,
-        Fields.firstReleased,
-        Fields.explicit,
-        Fields.license,
-        Fields.publicationStatus
-      ]
-    },
-    {
-      id: 'Additional',
-      render: additionalTab,
-      fields: [
-        Fields.composerOrSongwriter,
-        Fields.genre,
-        Fields.mood,
-        Fields.theme,
-        Fields.language,
-        Fields.lyrics,
-        Fields.attribution
-      ]
-    },
-    {
-      id: `Tracks (${tracks.length})`,
-      render: tracksTab
-    }
-  ]} />;
-
-  const renderMainButton = () =>
-    <TxButton
-      type='submit'
-      isDisabled={!dirty || isSubmitting}
-      label={isNew
-        ? 'Publish'
-        : 'Update'
-      }
-      params={buildTxParams()}
-      tx={isNew
-        ? 'dataDirectory.addMetadata'
-        : 'dataDirectory.updateMetadata'
-      }
-      onClick={onSubmit}
-      txFailedCb={onTxFailed}
-      txSuccessCb={onTxSuccess}
-    />;
-
-  return <div className='EditMetaBox'>
-    <div className='EditMetaThumb'>
-      {thumbnail && <img src={thumbnail} onError={onImageError} />}
-    </div>
-
-    <Form className='ui form JoyForm EditMetaForm'>
-
-      {tabs}
-
-      <LabelledField style={{ marginTop: '1rem' }} {...props} flex>
-        {renderMainButton()}
-        <Button
-          type='button'
-          size='large'
-          disabled={!dirty || isSubmitting}
-          onClick={() => resetForm()}
-          content='Reset form'
-        />
-      </LabelledField>
-    </Form>
-  </div>;
-};
-
-export const EditForm = withFormik<OuterProps, FormValues>({
-
-  // Transform outer props into form values
-  mapPropsToValues: (props): FormValues => {
-    const { entity } = props;
-
-    return MusicAlbumToFormValues(entity);
-  },
-
-  validationSchema: MusicAlbumValidationSchema,
-
-  handleSubmit: () => {
-    // do submitting things
-  }
-})(withMediaForm(InnerForm) as any);
-
-export default EditForm;

+ 0 - 16
pioneer/packages/joy-media/src/music/EditMusicAlbum.view.tsx

@@ -1,16 +0,0 @@
-import { MediaView } from '../MediaView';
-import { OuterProps, EditForm } from './EditMusicAlbum';
-
-export const EditMusicAlbumView = MediaView<OuterProps>({
-  component: EditForm,
-  triggers: ['id'],
-  resolveProps: async (props) => {
-    const { transport, id } = props;
-    const entity = id ? await transport.musicAlbumById(id) : undefined;
-    const opts = await transport.dropdownOptions();
-
-    return { entity, opts };
-  }
-});
-
-export default EditMusicAlbumView;

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

@@ -1,40 +0,0 @@
-import React from 'react';
-import { Button } from 'semantic-ui-react';
-import { Pluralize } from '@polkadot/joy-utils/react/components';
-import { BgImg } from '../common/BgImg';
-import { ChannelEntity } from '../entities/ChannelEntity';
-
-export type MusicAlbumPreviewProps = {
-  id: string;
-  title: string;
-  artist: string;
-  cover: string;
-  tracksCount: number;
-
-  // Extra props:
-  channel?: ChannelEntity;
-  size?: number;
-  withActions?: boolean;
-};
-
-export function MusicAlbumPreview (props: MusicAlbumPreviewProps) {
-  const { size = 200 } = props;
-
-  // TODO show the channel this album belongs to.
-
-  return <div className='JoyMusicAlbumPreview'>
-
-    <BgImg className='AlbumCover' url={props.cover} size={size} />
-
-    <div className='AlbumDescription' style={{ maxWidth: size }}>
-      <h3 className='AlbumTitle'>{props.title}</h3>
-      <div className='AlbumArtist'>{props.artist}</div>
-      <div className='AlbumTracksCount'><Pluralize count={props.tracksCount} singularText='track' /></div>
-    </div>
-
-    {props.withActions && <div className='AlbumActions'>
-      <Button content='Edit' icon='pencil' />
-      <Button content='Add track' icon='plus' />
-    </div>}
-  </div>;
-}

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

@@ -1,59 +0,0 @@
-import React, { useState } from 'react';
-import { Button, CheckboxProps } from 'semantic-ui-react';
-import { Pluralize } from '@polkadot/joy-utils/react/components';
-import { EditableMusicTrackPreviewProps, MusicTrackPreview } from './MusicTrackPreview';
-import { MusicAlbumPreviewProps, MusicAlbumPreview } from './MusicAlbumPreview';
-
-export type TracksOfMyMusicAlbumProps = {
-  album: MusicAlbumPreviewProps;
-  tracks?: EditableMusicTrackPreviewProps[];
-};
-
-export function TracksOfMyMusicAlbum (props: TracksOfMyMusicAlbumProps) {
-  const [idxsOfSelectedTracks, setIdxsOfSelectedTracks] = useState(new Set<number>());
-
-  const { album, tracks = [] } = props;
-  const tracksCount = (tracks && tracks.length) || 0;
-
-  const onTrackSelect = (
-    trackIdx: number,
-    _event: React.FormEvent<HTMLInputElement>,
-    data: CheckboxProps
-  ) => {
-    const set = new Set(idxsOfSelectedTracks);
-
-    data.checked
-      ? set.add(trackIdx)
-      : set.delete(trackIdx)
-    ;
-    setIdxsOfSelectedTracks(set);
-  };
-
-  const selectedCount = idxsOfSelectedTracks.size;
-
-  const removeButtonText = <span>Remove <Pluralize count={selectedCount} singularText='track' /> from album</span>;
-
-  return <>
-    <MusicAlbumPreview {...album} tracksCount={tracksCount} />
-
-    <div className='JoyTopActionBar'>
-      <Button content='Add track' icon='plus' />
-      {selectedCount > 0 && <Button content={removeButtonText} icon='trash' />}
-    </div>
-
-    <div className='JoyListOfPreviews'>
-      {tracksCount === 0
-        ? <em className='NoItems'>This album has no tracks yet</em>
-        : tracks.map((track, i) =>
-          <MusicTrackPreview
-            key={i}
-            {...track}
-            position={i + 1}
-            onSelect={(e, d) => onTrackSelect(i, e, d)}
-            withRemoveButton
-          />
-        )
-      }
-    </div>
-  </>;
-}

+ 0 - 59
pioneer/packages/joy-media/src/music/MusicTrackPreview.tsx

@@ -1,59 +0,0 @@
-import React, { useState } from 'react';
-import { Button, Checkbox, CheckboxProps } from 'semantic-ui-react';
-
-type OnCheckboxChange = (event: React.FormEvent<HTMLInputElement>, data: CheckboxProps) => void;
-
-export type EditableMusicTrackPreviewProps = {
-  id: string;
-  title: string;
-  artist: string;
-  thumbnail: string;
-  position?: number;
-  selected?: boolean;
-  onSelect?: OnCheckboxChange;
-  onEdit?: () => void;
-  onRemove?: () => void;
-  withEditButton?: boolean;
-  withRemoveButton?: boolean;
-  withActionLabels?: boolean;
-  isDraggable?: boolean;
-};
-
-export function MusicTrackPreview (props: EditableMusicTrackPreviewProps) {
-  const {
-    withActionLabels = false,
-    selected = false,
-    onEdit = () => { /* do nothing */ },
-    onRemove = () => { /* do nothing */ }
-  } = props;
-
-  const [checked, setChecked] = useState(selected);
-
-  const onChange: OnCheckboxChange = (e, d) => {
-    try {
-      props.onSelect && props.onSelect(e, d);
-    } catch (err) {
-      console.log('Error during checkbox change:', err);
-    }
-
-    setChecked(d.checked || false);
-  };
-
-  return <div className={`JoyMusicTrackPreview ${checked ? 'SelectedItem' : ''} ${props.isDraggable ? 'DraggableItem' : ''}`}>
-    {props.onSelect && <div className='CheckboxCell'>
-      <Checkbox checked={checked} onChange={onChange} />
-    </div>}
-    {props.position && <div className='AlbumNumber'>{props.position}</div>}
-    <div className='AlbumCover'>
-      <img src={props.thumbnail} />
-    </div>
-    <div className='AlbumDescription'>
-      <h3 className='AlbumTitle'>{props.title}</h3>
-      <div className='AlbumArtist'>{props.artist}</div>
-    </div>
-    <div className='AlbumActions'>
-      {props.withEditButton && <Button icon='pencil' content={withActionLabels ? 'Edit' : null} onClick={onEdit} />}
-      {props.withRemoveButton && <Button icon='trash' content={withActionLabels ? 'Remove' : null} onClick={onRemove} />}
-    </div>
-  </div>;
-}

+ 0 - 31
pioneer/packages/joy-media/src/music/MusicTrackReaderPreview.tsx

@@ -1,31 +0,0 @@
-import React, { CSSProperties } from 'react';
-import { BgImg } from '../common/BgImg';
-
-export type MusicTrackReaderPreviewProps = {
-  id: string;
-  title: string;
-  artist: string;
-  thumbnail: string;
-  size?: number;
-  orientation?: 'vertical' | 'horizontal';
-};
-
-export function MusicTrackReaderPreview (props: MusicTrackReaderPreviewProps) {
-  const { size = 200, orientation = 'vertical' } = props;
-
-  const descStyle: CSSProperties = {};
-
-  if (orientation === 'vertical') {
-    descStyle.maxWidth = size;
-  }
-
-  return <div className={'JoyMusicAlbumPreview ' + orientation}>
-
-    <BgImg className='AlbumCover' url={props.thumbnail} size={size} />
-
-    <div className='AlbumDescription' style={descStyle}>
-      <h3 className='AlbumTitle'>{props.title}</h3>
-      <div className='AlbumArtist'>{props.artist}</div>
-    </div>
-  </div>;
-}

+ 0 - 27
pioneer/packages/joy-media/src/music/MyMusicAlbums.tsx

@@ -1,27 +0,0 @@
-import React from 'react';
-import { Button } from 'semantic-ui-react';
-import { MusicAlbumPreviewProps, MusicAlbumPreview } from './MusicAlbumPreview';
-
-export type MyMusicAlbumsProps = {
-  albums?: MusicAlbumPreviewProps[];
-};
-
-export function MyMusicAlbums (props: MyMusicAlbumsProps) {
-  const { albums = [] } = props;
-  const albumCount = (albums && albums.length) || 0;
-
-  return <>
-    <h2>{`My music albums (${albumCount})`}</h2>
-    <div className='JoyTopActionBar'>
-      <Button content='New album' icon='plus' />
-    </div>
-    <div>
-      {albumCount === 0
-        ? <em className='NoItems'>{'You don\'t have music albums yet'}</em>
-        : albums.map((album, i) =>
-          <MusicAlbumPreview key={i} {...album} />
-        )
-      }
-    </div>
-  </>;
-}

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

@@ -1,164 +0,0 @@
-import React, { useState } from 'react';
-import { Button, CheckboxProps, Dropdown, Message } from 'semantic-ui-react';
-
-import { Pluralize, Section } from '@polkadot/joy-utils/react/components';
-
-import { EditableMusicTrackPreviewProps, MusicTrackPreview } from './MusicTrackPreview';
-import { ReorderableTracks } from './ReorderableTracks';
-import { MusicAlbumPreviewProps } from './MusicAlbumPreview';
-
-export type MyMusicTracksProps = {
-  albums?: MusicAlbumPreviewProps[];
-  tracks?: EditableMusicTrackPreviewProps[];
-};
-
-export function MyMusicTracks (props: MyMusicTracksProps) {
-  const [idsOfSelectedTracks, setIdsOfSelectedTracks] = useState(new Set<string>());
-
-  const onTrackSelect = (
-    track: EditableMusicTrackPreviewProps,
-    _event: React.FormEvent<HTMLInputElement>,
-    data: CheckboxProps
-  ) => {
-    const { id } = track;
-    const set = new Set(idsOfSelectedTracks);
-
-    data.checked
-      ? set.add(id)
-      : set.delete(id)
-    ;
-    setIdsOfSelectedTracks(set);
-  };
-
-  const { albums = [], tracks = [] } = props;
-  const albumsCount = albums.length;
-  const tracksCount = tracks.length;
-  const selectedCount = idsOfSelectedTracks.size;
-
-  let longestAlbumName = '';
-
-  albums.forEach((x) => {
-    if (longestAlbumName.length < x.title.length) {
-      longestAlbumName = x.title;
-    }
-  });
-
-  const albumsDropdownOptions = albums.map((x) => {
-    const { id } = x;
-
-    return {
-      key: id,
-      value: id,
-      text: x.title,
-      image: x.cover
-    };
-  });
-
-  const [showSecondScreen, setShowSecondScreen] = useState(false);
-  const [albumName, setAlbumName] = useState<string | undefined>();
-
-  const AlbumDropdown = () => {
-    const style = {
-      display: 'inline-block',
-      opacity: selectedCount ? 1 : 0,
-
-      // This is a required hack to fit every dropdown items on a single line:
-      minWidth: `${longestAlbumName.length / 1.5}rem`
-    };
-
-    return <div style={style}>
-      <Dropdown
-        onChange={(_e, { value: id }) => {
-          const selectedAlbum = albums.find((x) => x.id === id);
-
-          if (selectedAlbum) {
-            setAlbumName(selectedAlbum.title);
-            setShowSecondScreen(true);
-          }
-        }}
-        options={albumsDropdownOptions}
-        placeholder='Select an album'
-        search
-        selection
-        value={albumName}
-      />
-    </div>;
-  };
-
-  const AddTracksText = () => albumsCount
-    ? <span style={{ marginRight: '1rem' }}>
-        Add <Pluralize count={selectedCount} singularText='track' /> to
-    </span>
-    : <em>
-        You have no albums.
-      <Button content='Create first album' icon='plus' />
-    </em>;
-
-  const goBack = () => {
-    setAlbumName('');
-    setShowSecondScreen(false);
-  };
-
-  const renderAllTracks = () => {
-    return <Section title={`My Music Tracks (${tracksCount})`}>
-
-      <div className='JoyTopActionBar'>
-        {selectedCount
-          ? <><AddTracksText /></>
-          : <span>Select tracks to add them to your album</span>
-        }
-        <AlbumDropdown />
-      </div>
-
-      <div className='JoyListOfPreviews'>
-        {tracksCount === 0
-          ? <em className='NoItems'>You have no music tracks yet</em>
-          : tracks.map((track, i) =>
-            <MusicTrackPreview
-              key={i}
-              {...track}
-              position={i + 1}
-              selected={idsOfSelectedTracks.has(track.id)}
-              onSelect={(e, d) => onTrackSelect(track, e, d)}
-              withEditButton
-            />
-          )
-        }
-      </div>
-    </Section>;
-  };
-
-  const selectedTracks = tracks.filter((track) => idsOfSelectedTracks.has(track.id));
-
-  const renderReorderTracks = () => {
-    return <Section title={`Add tracks to album "${albumName || ''}"`}>
-
-      <Message
-        info
-        icon='info'
-        content='You can reorder tracks before adding them to this album.'
-      />
-
-      <ReorderableTracks
-        tracks={selectedTracks}
-        onRemove={(track) => {
-          const set = new Set(idsOfSelectedTracks);
-
-          set.delete(track.id);
-          setIdsOfSelectedTracks(set);
-        }}
-      />
-
-      <div style={{ marginTop: '1rem' }}>
-        <Button size='large' onClick={goBack}>&lt; Back to my tracks</Button>
-        <Button size='large' primary style={{ float: 'right' }} onClick={() => alert('Not implemented yet')}>Add to album &gt;</Button>
-      </div>
-    </Section>;
-  };
-
-  return <div className='JoyPaperWidth'>{
-    !showSecondScreen
-      ? renderAllTracks()
-      : renderReorderTracks()
-  }</div>;
-}

+ 0 - 91
pioneer/packages/joy-media/src/music/ReorderableTracks.tsx

@@ -1,91 +0,0 @@
-import React, { useState } from 'react';
-import { DragDropContext, Droppable, Draggable, DropResult } from 'react-beautiful-dnd';
-import { EditableMusicTrackPreviewProps, MusicTrackPreview } from './MusicTrackPreview';
-
-// A little function to help us with reordering the result
-const reorder = (list: OrderableItem[], startIndex: number, endIndex: number) => {
-  const result = Array.from(list);
-  const [removed] = result.splice(startIndex, 1);
-
-  result.splice(endIndex, 0, removed);
-
-  return result;
-};
-
-type Props = {
-  tracks: EditableMusicTrackPreviewProps[];
-  onRemove?: (track: EditableMusicTrackPreviewProps) => void;
-  noTracksView?: React.ReactElement;
-}
-
-type OrderableItem = EditableMusicTrackPreviewProps;
-
-export const ReorderableTracks = (props: Props) => {
-  const { tracks = [], onRemove = () => { /* do nothing */ }, noTracksView = null } = props;
-
-  const [items, setItems] = useState(tracks);
-
-  if (!items.length) {
-    return noTracksView;
-  }
-
-  const onDragEnd = (result: DropResult) => {
-    // Dropped outside the list
-    if (!result.destination) {
-      return;
-    }
-
-    const reorderedItems = reorder(
-      items,
-      result.source.index,
-      result.destination.index
-    );
-
-    setItems(reorderedItems);
-  };
-
-  // Normally you would want to split things out into separate components.
-  // But in this example everything is just done in one place for simplicity
-  return (
-    <DragDropContext onDragEnd={onDragEnd}>
-      <Droppable droppableId='droppable'>
-        {(provided, _snapshot) => (
-          <div
-            {...provided.droppableProps}
-            // eslint-disable-next-line @typescript-eslint/unbound-method
-            ref={provided.innerRef}
-            className='JoyListOfPreviews'
-          >
-            {items.map((item, index) => (
-              <Draggable key={item.id} draggableId={item.id} index={index}>
-                {(provided, snapshot) => (
-                  <div
-                    // eslint-disable-next-line @typescript-eslint/unbound-method
-                    ref={provided.innerRef}
-                    {...provided.draggableProps}
-                    {...provided.dragHandleProps}
-                  >
-                    <MusicTrackPreview
-                      key={index}
-                      {...item}
-                      position={index + 1}
-                      isDraggable={snapshot.isDragging}
-                      withRemoveButton
-                      onRemove={() => {
-                        onRemove(item);
-                        const lessItems = items.filter((x) => x.id !== item.id);
-
-                        setItems(lessItems);
-                      }}
-                    />
-                  </div>
-                )}
-              </Draggable>
-            ))}
-            {provided.placeholder}
-          </div>
-        )}
-      </Droppable>
-    </DragDropContext>
-  );
-};

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

@@ -1,168 +0,0 @@
-
-import * as Yup from 'yup';
-import { BlockNumber, AccountId } from '@polkadot/types/interfaces';
-import { ChannelContentTypeValue, PrincipalId, Channel, ChannelId, ChannelPublicationStatusValue, ChannelCurationStatusValue } from '@joystream/types/content-working-group';
-import { MemberId } from '@joystream/types/members';
-import { ChannelValidationConstraints } from '@polkadot/joy-media/transport';
-import { ValidationConstraint } from '@polkadot/joy-utils/types/ValidationConstraint';
-
-function textValidation (constraint?: ValidationConstraint) {
-  if (!constraint) {
-    return Yup.string();
-  }
-
-  const { min, max } = constraint;
-
-  return Yup.string()
-    .min(min, `Text is too short. Minimum length is ${min} chars.`)
-    .max(max, `Text is too long. Maximum length is ${max} chars.`);
-}
-
-export const buildChannelValidationSchema = (constraints?: ChannelValidationConstraints) =>
-  Yup.object().shape({
-    handle: textValidation(constraints?.handle).required('This field is required'),
-    title: textValidation(constraints?.title),
-    description: textValidation(constraints?.description),
-    avatar: textValidation(constraints?.avatar),
-    banner: textValidation(constraints?.banner)
-  });
-
-export type ChannelFormValues = {
-  content: ChannelContentTypeValue;
-  handle: string;
-  title: string;
-  description: string;
-  avatar: string;
-  banner: string;
-  publicationStatus: ChannelPublicationStatusValue;
-};
-
-export type ChannelType = {
-  id: number;
-  verified: boolean;
-  handle: string;
-  title?: string;
-  description?: string;
-  avatar?: string;
-  banner?: string;
-  content: ChannelContentTypeValue;
-  owner: MemberId;
-  roleAccount: AccountId;
-  publicationStatus: ChannelPublicationStatusValue;
-  curationStatus: ChannelCurationStatusValue;
-  created: BlockNumber;
-  principalId: PrincipalId;
-};
-
-export class ChannelCodec {
-  static fromSubstrate (id: ChannelId, sub: Channel): ChannelType {
-    return {
-      id: id.toNumber(),
-      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
-    };
-  }
-}
-
-export function ChannelToFormValues (entity?: ChannelType): ChannelFormValues {
-  return {
-    content: (entity && entity.content) || 'Video',
-    handle: (entity && entity.handle) || '',
-    title: (entity && entity.title) || '',
-    description: (entity && entity.description) || '',
-    avatar: (entity && entity.avatar) || '',
-    banner: (entity && entity.banner) || '',
-    publicationStatus: (entity && entity.publicationStatus) || 'Public'
-  };
-}
-
-export type ChannelPropId =
-  'content' |
-  'handle' |
-  'title' |
-  'description' |
-  'avatar' |
-  'banner' |
-  'publicationStatus'
-  ;
-
-export type ChannelGenericProp = {
-  id: ChannelPropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type ChannelClassType = {
-  [id in ChannelPropId]: ChannelGenericProp
-};
-
-export const ChannelClass: ChannelClassType = {
-  content: {
-    id: 'content',
-    name: 'Content',
-    description: 'The type of channel.',
-    type: 'Text',
-    required: true,
-    maxTextLength: 100
-  },
-  handle: {
-    id: 'handle',
-    name: 'Handle',
-    description: 'Unique URL handle of channel.',
-    type: 'Text',
-    required: true,
-    maxTextLength: 40
-  },
-  title: {
-    id: 'title',
-    name: 'Title',
-    description: 'Human readable title of channel.',
-    type: 'Text',
-    maxTextLength: 100
-  },
-  description: {
-    id: 'description',
-    name: 'Description',
-    description: 'Human readable description of channel purpose and scope.',
-    type: 'Text',
-    maxTextLength: 4000
-  },
-  avatar: {
-    id: 'avatar',
-    name: 'Avatar',
-    description: 'URL to avatar (logo) iamge: NOTE: Should be an https link to a square image.',
-    type: 'Text',
-    maxTextLength: 1000
-  },
-  banner: {
-    id: 'banner',
-    name: 'Banner',
-    description: 'URL to banner image: NOTE: Should be an https link to a rectangular image, between 1400x1400 and 3000x3000 pixels, in JPEG or PNG format.',
-    type: 'Text',
-    maxTextLength: 1000
-  },
-  publicationStatus: {
-    id: 'publicationStatus',
-    name: 'Publication Status',
-    description: 'The publication status of the channel.',
-    required: true,
-    type: 'Internal',
-    classId: 'Publication Status'
-  }
-};

+ 0 - 60
pioneer/packages/joy-media/src/schemas/general/ContentLicense.ts

@@ -1,60 +0,0 @@
-
-/** This file is generated based on JSON schema. Do not modify. */
-
-import * as Yup from 'yup';
-import { EntityCodec } from '@joystream/types/versioned-store/EntityCodec';
-
-export const ContentLicenseValidationSchema = Yup.object().shape({
-  value: Yup.string()
-    .required('This field is required')
-    .max(200, 'Text is too long. Maximum length is 200 chars.')
-});
-
-export type ContentLicenseFormValues = {
-  value: string;
-};
-
-export type ContentLicenseType = {
-  classId: number;
-  inClassSchemaIndexes: number[];
-  id: number;
-  value: string;
-};
-
-export class ContentLicenseCodec extends EntityCodec<ContentLicenseType> { }
-
-export function ContentLicenseToFormValues (entity?: ContentLicenseType): ContentLicenseFormValues {
-  return {
-    value: (entity && entity.value) || ''
-  };
-}
-
-export type ContentLicensePropId =
-  'value'
-  ;
-
-export type ContentLicenseGenericProp = {
-  id: ContentLicensePropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type ContentLicenseClassType = {
-  [id in ContentLicensePropId]: ContentLicenseGenericProp
-};
-
-export const ContentLicenseClass: ContentLicenseClassType = {
-  value: {
-    id: 'value',
-    name: 'Value',
-    description: 'The license of which the content is originally published under.',
-    type: 'Text',
-    required: true,
-    maxTextLength: 200
-  }
-};

+ 0 - 60
pioneer/packages/joy-media/src/schemas/general/CurationStatus.ts

@@ -1,60 +0,0 @@
-
-/** This file is generated based on JSON schema. Do not modify. */
-
-import * as Yup from 'yup';
-import { EntityCodec } from '@joystream/types/versioned-store/EntityCodec';
-
-export const CurationStatusValidationSchema = Yup.object().shape({
-  value: Yup.string()
-    .required('This field is required')
-    .max(255, 'Text is too long. Maximum length is 255 chars.')
-});
-
-export type CurationStatusFormValues = {
-  value: string;
-};
-
-export type CurationStatusType = {
-  classId: number;
-  inClassSchemaIndexes: number[];
-  id: number;
-  value: string;
-};
-
-export class CurationStatusCodec extends EntityCodec<CurationStatusType> { }
-
-export function CurationStatusToFormValues (entity?: CurationStatusType): CurationStatusFormValues {
-  return {
-    value: (entity && entity.value) || ''
-  };
-}
-
-export type CurationStatusPropId =
-  'value'
-  ;
-
-export type CurationStatusGenericProp = {
-  id: CurationStatusPropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type CurationStatusClassType = {
-  [id in CurationStatusPropId]: CurationStatusGenericProp
-};
-
-export const CurationStatusClass: CurationStatusClassType = {
-  value: {
-    id: 'value',
-    name: 'Value',
-    description: 'The curator publication status of the content in the content directory.',
-    required: true,
-    type: 'Text',
-    maxTextLength: 255
-  }
-};

+ 0 - 83
pioneer/packages/joy-media/src/schemas/general/FeaturedContent.ts

@@ -1,83 +0,0 @@
-
-/** This file is generated based on JSON schema. Do not modify. */
-
-import * as Yup from 'yup';
-import { EntityCodec } from '@joystream/types/versioned-store/EntityCodec';
-import { VideoType } from '../video/Video';
-import { MusicAlbumType } from '../music/MusicAlbum';
-
-export const FeaturedContentValidationSchema = Yup.object().shape({
-  // No validation rules.
-});
-
-export type FeaturedContentFormValues = {
-  topVideo: number;
-  featuredVideos: number[];
-  featuredAlbums: number[];
-};
-
-export type FeaturedContentType = {
-  classId: number;
-  inClassSchemaIndexes: number[];
-  id: number;
-  topVideo?: VideoType;
-  featuredVideos?: VideoType[];
-  featuredAlbums?: MusicAlbumType[];
-};
-
-export class FeaturedContentCodec extends EntityCodec<FeaturedContentType> { }
-
-export function FeaturedContentToFormValues (entity?: FeaturedContentType): FeaturedContentFormValues {
-  return {
-    topVideo: (entity && entity.topVideo?.id) || 0,
-    featuredVideos: (entity && entity.featuredVideos?.map((x) => x.id)) || [],
-    featuredAlbums: (entity && entity.featuredAlbums?.map((x) => x.id)) || []
-  };
-}
-
-export type FeaturedContentPropId =
-  'topVideo' |
-  'featuredVideos' |
-  'featuredAlbums'
-  ;
-
-export type FeaturedContentGenericProp = {
-  id: FeaturedContentPropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type FeaturedContentClassType = {
-  [id in FeaturedContentPropId]: FeaturedContentGenericProp
-};
-
-export const FeaturedContentClass: FeaturedContentClassType = {
-  topVideo: {
-    id: 'topVideo',
-    name: 'Top Video',
-    description: 'The video that has the most prominent position(s) on the platform.',
-    type: 'Internal',
-    classId: 'Video'
-  },
-  featuredVideos: {
-    id: 'featuredVideos',
-    name: 'Featured Videos',
-    description: 'Videos featured in the Video tab.',
-    type: 'InternalVec',
-    maxItems: 12,
-    classId: 'Video'
-  },
-  featuredAlbums: {
-    id: 'featuredAlbums',
-    name: 'Featured Albums',
-    description: 'Music albums featured in the Music tab.',
-    type: 'InternalVec',
-    maxItems: 12,
-    classId: 'Music Album'
-  }
-};

+ 0 - 60
pioneer/packages/joy-media/src/schemas/general/Language.ts

@@ -1,60 +0,0 @@
-
-/** This file is generated based on JSON schema. Do not modify. */
-
-import * as Yup from 'yup';
-import { EntityCodec } from '@joystream/types/versioned-store/EntityCodec';
-
-export const LanguageValidationSchema = Yup.object().shape({
-  value: Yup.string()
-    .required('This field is required')
-    .max(2, 'Text is too long. Maximum length is 2 chars.')
-});
-
-export type LanguageFormValues = {
-  value: string;
-};
-
-export type LanguageType = {
-  classId: number;
-  inClassSchemaIndexes: number[];
-  id: number;
-  value: string;
-};
-
-export class LanguageCodec extends EntityCodec<LanguageType> { }
-
-export function LanguageToFormValues (entity?: LanguageType): LanguageFormValues {
-  return {
-    value: (entity && entity.value) || ''
-  };
-}
-
-export type LanguagePropId =
-  'value'
-  ;
-
-export type LanguageGenericProp = {
-  id: LanguagePropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type LanguageClassType = {
-  [id in LanguagePropId]: LanguageGenericProp
-};
-
-export const LanguageClass: LanguageClassType = {
-  value: {
-    id: 'value',
-    name: 'Value',
-    description: 'Language code following the ISO 639-1 two letter standard.',
-    type: 'Text',
-    required: true,
-    maxTextLength: 2
-  }
-};

+ 0 - 60
pioneer/packages/joy-media/src/schemas/general/MediaObject.ts

@@ -1,60 +0,0 @@
-
-/** This file is generated based on JSON schema. Do not modify. */
-
-import * as Yup from 'yup';
-import { EntityCodec } from '@joystream/types/versioned-store/EntityCodec';
-
-export const MediaObjectValidationSchema = Yup.object().shape({
-  value: Yup.string()
-    .required('This field is required')
-    .max(66, 'Text is too long. Maximum length is 66 chars.')
-});
-
-export type MediaObjectFormValues = {
-  value: string;
-};
-
-export type MediaObjectType = {
-  classId: number;
-  inClassSchemaIndexes: number[];
-  id: number;
-  value: string;
-};
-
-export class MediaObjectCodec extends EntityCodec<MediaObjectType> { }
-
-export function MediaObjectToFormValues (entity?: MediaObjectType): MediaObjectFormValues {
-  return {
-    value: (entity && entity.value) || ''
-  };
-}
-
-export type MediaObjectPropId =
-  'value'
-  ;
-
-export type MediaObjectGenericProp = {
-  id: MediaObjectPropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type MediaObjectClassType = {
-  [id in MediaObjectPropId]: MediaObjectGenericProp
-};
-
-export const MediaObjectClass: MediaObjectClassType = {
-  value: {
-    id: 'value',
-    name: 'Value',
-    description: 'Content id of object in the data directory.',
-    type: 'Text',
-    required: true,
-    maxTextLength: 48
-  }
-};

+ 0 - 60
pioneer/packages/joy-media/src/schemas/general/PublicationStatus.ts

@@ -1,60 +0,0 @@
-
-/** This file is generated based on JSON schema. Do not modify. */
-
-import * as Yup from 'yup';
-import { EntityCodec } from '@joystream/types/versioned-store/EntityCodec';
-
-export const PublicationStatusValidationSchema = Yup.object().shape({
-  value: Yup.string()
-    .required('This field is required')
-    .max(50, 'Text is too long. Maximum length is 50 chars.')
-});
-
-export type PublicationStatusFormValues = {
-  value: string;
-};
-
-export type PublicationStatusType = {
-  classId: number;
-  inClassSchemaIndexes: number[];
-  id: number;
-  value: string;
-};
-
-export class PublicationStatusCodec extends EntityCodec<PublicationStatusType> { }
-
-export function PublicationStatusToFormValues (entity?: PublicationStatusType): PublicationStatusFormValues {
-  return {
-    value: (entity && entity.value) || ''
-  };
-}
-
-export type PublicationStatusPropId =
-  'value'
-  ;
-
-export type PublicationStatusGenericProp = {
-  id: PublicationStatusPropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type PublicationStatusClassType = {
-  [id in PublicationStatusPropId]: PublicationStatusGenericProp
-};
-
-export const PublicationStatusClass: PublicationStatusClassType = {
-  value: {
-    id: 'value',
-    name: 'Value',
-    description: 'The publication status of the content in the content directory.',
-    required: true,
-    type: 'Text',
-    maxTextLength: 50
-  }
-};

+ 0 - 308
pioneer/packages/joy-media/src/schemas/music/MusicAlbum.ts

@@ -1,308 +0,0 @@
-
-/** This file is generated based on JSON schema. Do not modify. */
-
-import * as Yup from 'yup';
-import { EntityCodec } from '@joystream/types/versioned-store/EntityCodec';
-import moment from 'moment';
-import { MusicGenreType } from './MusicGenre';
-import { MusicMoodType } from './MusicMood';
-import { MusicThemeType } from './MusicTheme';
-import { MusicTrackType } from './MusicTrack';
-import { LanguageType } from '../general/Language';
-import { PublicationStatusType } from '../general/PublicationStatus';
-import { CurationStatusType } from '../general/CurationStatus';
-import { ContentLicenseType } from '../general/ContentLicense';
-import { ChannelEntity } from '@polkadot/joy-media/entities/ChannelEntity';
-
-export const MusicAlbumValidationSchema = Yup.object().shape({
-  title: Yup.string()
-    .required('This field is required')
-    .max(255, 'Text is too long. Maximum length is 255 chars.'),
-  artist: Yup.string()
-    .required('This field is required')
-    .max(255, 'Text is too long. Maximum length is 255 chars.'),
-  thumbnail: Yup.string()
-    .required('This field is required')
-    .max(255, 'Text is too long. Maximum length is 255 chars.'),
-  description: Yup.string()
-    .required('This field is required')
-    .max(4000, 'Text is too long. Maximum length is 4000 chars.'),
-  firstReleased: Yup.string()
-    .required('This field is required')
-    .test('valid-date', 'Invalid date. Valid date formats are yyyy-mm-dd or yyyy-mm or yyyy.', (val?: any) => {
-      return moment(val).isValid();
-    }),
-  lyrics: Yup.string()
-    .max(255, 'Text is too long. Maximum length is 255 chars.'),
-  composerOrSongwriter: Yup.string()
-    .max(255, 'Text is too long. Maximum length is 255 chars.'),
-  attribution: Yup.string()
-    .max(255, 'Text is too long. Maximum length is 255 chars.')
-});
-
-export type MusicAlbumFormValues = {
-  title: string;
-  artist: string;
-  thumbnail: string;
-  description: string;
-  firstReleased: string;
-  genre: number;
-  mood: number;
-  theme: number;
-  tracks: number[];
-  language: number;
-  links: string[];
-  lyrics: string;
-  composerOrSongwriter: string;
-  reviews: string[];
-  publicationStatus: number;
-  curationStatus: number;
-  explicit: boolean;
-  license: number;
-  attribution: string;
-  channelId: number;
-};
-
-export type MusicAlbumType = {
-  classId: number;
-  inClassSchemaIndexes: number[];
-  id: number;
-  title: string;
-  artist: string;
-  thumbnail: string;
-  description: string;
-  firstReleased: number;
-  genre?: MusicGenreType;
-  mood?: MusicMoodType;
-  theme?: MusicThemeType;
-  tracks?: MusicTrackType[];
-  language?: LanguageType;
-  links?: string[];
-  lyrics?: string;
-  composerOrSongwriter?: string;
-  reviews?: string[];
-  publicationStatus: PublicationStatusType;
-  curationStatus?: CurationStatusType;
-  explicit: boolean;
-  license: ContentLicenseType;
-  attribution?: string;
-  channelId?: number;
-  channel?: ChannelEntity;
-};
-
-export class MusicAlbumCodec extends EntityCodec<MusicAlbumType> { }
-
-export function MusicAlbumToFormValues (entity?: MusicAlbumType): MusicAlbumFormValues {
-  return {
-    title: (entity && entity.title) || '',
-    artist: (entity && entity.artist) || '',
-    thumbnail: (entity && entity.thumbnail) || '',
-    description: (entity && entity.description) || '',
-    firstReleased: (entity && moment(entity.firstReleased * 1000).format('YYYY-MM-DD')) || '',
-    genre: (entity && entity.genre?.id) || 0,
-    mood: (entity && entity.mood?.id) || 0,
-    theme: (entity && entity.theme?.id) || 0,
-    tracks: (entity && entity.tracks?.map((x) => x.id)) || [],
-    language: (entity && entity.language?.id) || 0,
-    links: (entity && entity.links) || [],
-    lyrics: (entity && entity.lyrics) || '',
-    composerOrSongwriter: (entity && entity.composerOrSongwriter) || '',
-    reviews: (entity && entity.reviews) || [],
-    publicationStatus: (entity && entity.publicationStatus.id) || 0,
-    curationStatus: (entity && entity.curationStatus?.id) || 0,
-    explicit: (entity && entity.explicit) || false,
-    license: (entity && entity.license?.id) || 0,
-    attribution: (entity && entity.attribution) || '',
-    channelId: (entity && entity.channelId) || 0
-  };
-}
-
-export type MusicAlbumPropId =
-  'title' |
-  'artist' |
-  'thumbnail' |
-  'description' |
-  'firstReleased' |
-  'genre' |
-  'mood' |
-  'theme' |
-  'tracks' |
-  'language' |
-  'links' |
-  'lyrics' |
-  'composerOrSongwriter' |
-  'reviews' |
-  'publicationStatus' |
-  'curationStatus' |
-  'explicit' |
-  'license' |
-  'attribution' |
-  'channelId'
-  ;
-
-export type MusicAlbumGenericProp = {
-  id: MusicAlbumPropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type MusicAlbumClassType = {
-  [id in MusicAlbumPropId]: MusicAlbumGenericProp
-};
-
-export const MusicAlbumClass: MusicAlbumClassType = {
-  title: {
-    id: 'title',
-    name: 'Title',
-    description: 'The title of the album',
-    type: 'Text',
-    required: true,
-    maxTextLength: 255
-  },
-  artist: {
-    id: 'artist',
-    name: 'Artist',
-    description: 'The artist, composer, band or group that published the album.',
-    type: 'Text',
-    required: true,
-    maxTextLength: 255
-  },
-  thumbnail: {
-    id: 'thumbnail',
-    name: 'Thumbnail',
-    description: 'URL to album cover art thumbnail: NOTE: Should be an https link to a square image, between 1400x1400 and 3000x3000 pixels, in JPEG or PNG format.',
-    required: true,
-    type: 'Text',
-    maxTextLength: 255
-  },
-  description: {
-    id: 'description',
-    name: 'Description',
-    description: 'Information about the album and artist.',
-    required: true,
-    type: 'Text',
-    maxTextLength: 4000
-  },
-  firstReleased: {
-    id: 'firstReleased',
-    name: 'First Released',
-    description: 'When the album was first released',
-    required: true,
-    type: 'Int64'
-  },
-  genre: {
-    id: 'genre',
-    name: 'Genre',
-    description: 'The genre of the album.',
-    type: 'Internal',
-    classId: 'Music Genre'
-  },
-  mood: {
-    id: 'mood',
-    name: 'Mood',
-    description: 'The mood of the album.',
-    type: 'Internal',
-    classId: 'Music Mood'
-  },
-  theme: {
-    id: 'theme',
-    name: 'Theme',
-    description: 'The theme of the album.',
-    type: 'Internal',
-    classId: 'Music Theme'
-  },
-  tracks: {
-    id: 'tracks',
-    name: 'Tracks',
-    description: 'The tracks of the album.',
-    type: 'InternalVec',
-    maxItems: 100,
-    classId: 'Music Track'
-  },
-  language: {
-    id: 'language',
-    name: 'Language',
-    description: 'The language of the song lyrics in the album.',
-    required: false,
-    type: 'Internal',
-    classId: 'Language'
-  },
-  links: {
-    id: 'links',
-    name: 'Links',
-    description: 'Links to the artist or album site, or social media pages.',
-    type: 'TextVec',
-    maxItems: 5,
-    maxTextLength: 255
-  },
-  lyrics: {
-    id: 'lyrics',
-    name: 'Lyrics',
-    description: 'Link to the album tracks lyrics.',
-    type: 'Text',
-    maxTextLength: 255
-  },
-  composerOrSongwriter: {
-    id: 'composerOrSongwriter',
-    name: 'Composer or songwriter',
-    description: 'The composer(s) and/or songwriter(s) of the album.',
-    type: 'Text',
-    maxTextLength: 255
-  },
-  reviews: {
-    id: 'reviews',
-    name: 'Reviews',
-    description: 'Links to reviews of the album.',
-    type: 'TextVec',
-    maxItems: 5,
-    maxTextLength: 255
-  },
-  publicationStatus: {
-    id: 'publicationStatus',
-    name: 'Publication Status',
-    description: 'The publication status of the album.',
-    required: true,
-    type: 'Internal',
-    classId: 'Publication Status'
-  },
-  curationStatus: {
-    id: 'curationStatus',
-    name: 'Curation Status',
-    description: 'The publication status of the album set by the a content curator on the platform.',
-    type: 'Internal',
-    classId: 'Curation Status'
-  },
-  explicit: {
-    id: 'explicit',
-    name: 'Explicit',
-    description: 'Indicates whether the album contains explicit material.',
-    required: true,
-    type: 'Bool'
-  },
-  license: {
-    id: 'license',
-    name: 'License',
-    description: 'The license of which the album is released under.',
-    required: true,
-    type: 'Internal',
-    classId: 'Content License'
-  },
-  attribution: {
-    id: 'attribution',
-    name: 'Attribution',
-    description: 'If the License requires attribution, add this here.',
-    type: 'Text',
-    maxTextLength: 255
-  },
-  channelId: {
-    id: 'channelId',
-    name: 'Channel Id',
-    description: 'Id of the channel this album is published under.',
-    type: 'Uint64'
-  }
-};

+ 0 - 60
pioneer/packages/joy-media/src/schemas/music/MusicGenre.ts

@@ -1,60 +0,0 @@
-
-/** This file is generated based on JSON schema. Do not modify. */
-
-import * as Yup from 'yup';
-import { EntityCodec } from '@joystream/types/versioned-store/EntityCodec';
-
-export const MusicGenreValidationSchema = Yup.object().shape({
-  value: Yup.string()
-    .required('This field is required')
-    .max(100, 'Text is too long. Maximum length is 100 chars.')
-});
-
-export type MusicGenreFormValues = {
-  value: string;
-};
-
-export type MusicGenreType = {
-  classId: number;
-  inClassSchemaIndexes: number[];
-  id: number;
-  value: string;
-};
-
-export class MusicGenreCodec extends EntityCodec<MusicGenreType> { }
-
-export function MusicGenreToFormValues (entity?: MusicGenreType): MusicGenreFormValues {
-  return {
-    value: (entity && entity.value) || ''
-  };
-}
-
-export type MusicGenrePropId =
-  'value'
-  ;
-
-export type MusicGenreGenericProp = {
-  id: MusicGenrePropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type MusicGenreClassType = {
-  [id in MusicGenrePropId]: MusicGenreGenericProp
-};
-
-export const MusicGenreClass: MusicGenreClassType = {
-  value: {
-    id: 'value',
-    name: 'Value',
-    description: 'Genres for music.',
-    required: true,
-    type: 'Text',
-    maxTextLength: 100
-  }
-};

+ 0 - 60
pioneer/packages/joy-media/src/schemas/music/MusicMood.ts

@@ -1,60 +0,0 @@
-
-/** This file is generated based on JSON schema. Do not modify. */
-
-import * as Yup from 'yup';
-import { EntityCodec } from '@joystream/types/versioned-store/EntityCodec';
-
-export const MusicMoodValidationSchema = Yup.object().shape({
-  value: Yup.string()
-    .required('This field is required')
-    .max(100, 'Text is too long. Maximum length is 100 chars.')
-});
-
-export type MusicMoodFormValues = {
-  value: string;
-};
-
-export type MusicMoodType = {
-  classId: number;
-  inClassSchemaIndexes: number[];
-  id: number;
-  value: string;
-};
-
-export class MusicMoodCodec extends EntityCodec<MusicMoodType> { }
-
-export function MusicMoodToFormValues (entity?: MusicMoodType): MusicMoodFormValues {
-  return {
-    value: (entity && entity.value) || ''
-  };
-}
-
-export type MusicMoodPropId =
-  'value'
-  ;
-
-export type MusicMoodGenericProp = {
-  id: MusicMoodPropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type MusicMoodClassType = {
-  [id in MusicMoodPropId]: MusicMoodGenericProp
-};
-
-export const MusicMoodClass: MusicMoodClassType = {
-  value: {
-    id: 'value',
-    name: 'Value',
-    description: 'Moods for music.',
-    required: true,
-    type: 'Text',
-    maxTextLength: 100
-  }
-};

+ 0 - 60
pioneer/packages/joy-media/src/schemas/music/MusicTheme.ts

@@ -1,60 +0,0 @@
-
-/** This file is generated based on JSON schema. Do not modify. */
-
-import * as Yup from 'yup';
-import { EntityCodec } from '@joystream/types/versioned-store/EntityCodec';
-
-export const MusicThemeValidationSchema = Yup.object().shape({
-  value: Yup.string()
-    .required('This field is required')
-    .max(100, 'Text is too long. Maximum length is 100 chars.')
-});
-
-export type MusicThemeFormValues = {
-  value: string;
-};
-
-export type MusicThemeType = {
-  classId: number;
-  inClassSchemaIndexes: number[];
-  id: number;
-  value: string;
-};
-
-export class MusicThemeCodec extends EntityCodec<MusicThemeType> { }
-
-export function MusicThemeToFormValues (entity?: MusicThemeType): MusicThemeFormValues {
-  return {
-    value: (entity && entity.value) || ''
-  };
-}
-
-export type MusicThemePropId =
-  'value'
-  ;
-
-export type MusicThemeGenericProp = {
-  id: MusicThemePropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type MusicThemeClassType = {
-  [id in MusicThemePropId]: MusicThemeGenericProp
-};
-
-export const MusicThemeClass: MusicThemeClassType = {
-  value: {
-    id: 'value',
-    name: 'Value',
-    description: 'Themes for music.',
-    required: true,
-    type: 'Text',
-    maxTextLength: 100
-  }
-};

+ 0 - 292
pioneer/packages/joy-media/src/schemas/music/MusicTrack.ts

@@ -1,292 +0,0 @@
-
-/** This file is generated based on JSON schema. Do not modify. */
-
-import * as Yup from 'yup';
-import { EntityCodec } from '@joystream/types/versioned-store/EntityCodec';
-import moment from 'moment';
-import { LanguageType } from '../general/Language';
-import { MusicGenreType } from './MusicGenre';
-import { MusicMoodType } from './MusicMood';
-import { MusicThemeType } from './MusicTheme';
-import { MediaObjectType } from '../general/MediaObject';
-import { PublicationStatusType } from '../general/PublicationStatus';
-import { CurationStatusType } from '../general/CurationStatus';
-import { ContentLicenseType } from '../general/ContentLicense';
-import { ChannelEntity } from '@polkadot/joy-media/entities/ChannelEntity';
-
-export const MusicTrackValidationSchema = Yup.object().shape({
-  title: Yup.string()
-    .required('This field is required')
-    .max(255, 'Text is too long. Maximum length is 255 chars.'),
-  artist: Yup.string()
-    .required('This field is required')
-    .max(255, 'Text is too long. Maximum length is 255 chars.'),
-  thumbnail: Yup.string()
-    .required('This field is required')
-    .max(255, 'Text is too long. Maximum length is 255 chars.'),
-  description: Yup.string()
-    .max(255, 'Text is too long. Maximum length is 255 chars.'),
-  firstReleased: Yup.string()
-    .required('This field is required')
-    .test('valid-date', 'Invalid date. Valid date formats are yyyy-mm-dd or yyyy-mm or yyyy.', (val?: any) => {
-      return moment(val).isValid();
-    }),
-  composerOrSongwriter: Yup.string()
-    .max(255, 'Text is too long. Maximum length is 255 chars.'),
-  lyrics: Yup.string()
-    .max(255, 'Text is too long. Maximum length is 255 chars.'),
-  attribution: Yup.string()
-    .max(255, 'Text is too long. Maximum length is 255 chars.')
-});
-
-export type MusicTrackFormValues = {
-  title: string;
-  artist: string;
-  thumbnail: string;
-  description: string;
-  language: number;
-  firstReleased: string;
-  genre: number;
-  mood: number;
-  theme: number;
-  links: string[];
-  composerOrSongwriter: string;
-  lyrics: string;
-  object: number;
-  publicationStatus: number;
-  curationStatus: number;
-  explicit: boolean;
-  license: number;
-  attribution: string;
-  channelId: number;
-};
-
-export type MusicTrackType = {
-  classId: number;
-  inClassSchemaIndexes: number[];
-  id: number;
-  title: string;
-  artist: string;
-  thumbnail: string;
-  description?: string;
-  language?: LanguageType;
-  firstReleased: number;
-  genre?: MusicGenreType;
-  mood?: MusicMoodType;
-  theme?: MusicThemeType;
-  links?: string[];
-  composerOrSongwriter?: string;
-  lyrics?: string;
-  object?: MediaObjectType;
-  publicationStatus: PublicationStatusType;
-  curationStatus?: CurationStatusType;
-  explicit: boolean;
-  license: ContentLicenseType;
-  attribution?: string;
-  channelId?: number;
-  channel?: ChannelEntity;
-};
-
-export class MusicTrackCodec extends EntityCodec<MusicTrackType> { }
-
-export function MusicTrackToFormValues (entity?: MusicTrackType): MusicTrackFormValues {
-  return {
-    title: (entity && entity.title) || '',
-    artist: (entity && entity.artist) || '',
-    thumbnail: (entity && entity.thumbnail) || '',
-    description: (entity && entity.description) || '',
-    language: (entity && entity.language?.id) || 0,
-    firstReleased: (entity && moment(entity.firstReleased * 1000).format('YYYY-MM-DD')) || '',
-    genre: (entity && entity.genre?.id) || 0,
-    mood: (entity && entity.mood?.id) || 0,
-    theme: (entity && entity.theme?.id) || 0,
-    links: (entity && entity.links) || [],
-    composerOrSongwriter: (entity && entity.composerOrSongwriter) || '',
-    lyrics: (entity && entity.lyrics) || '',
-    object: (entity && entity.object?.id) || 0,
-    publicationStatus: (entity && entity.publicationStatus?.id) || 0,
-    curationStatus: (entity && entity.curationStatus?.id) || 0,
-    explicit: (entity && entity.explicit) || false,
-    license: (entity && entity.license?.id) || 0,
-    attribution: (entity && entity.attribution) || '',
-    channelId: (entity && entity.channelId) || 0
-  };
-}
-
-export type MusicTrackPropId =
-  'title' |
-  'artist' |
-  'thumbnail' |
-  'description' |
-  'language' |
-  'firstReleased' |
-  'genre' |
-  'mood' |
-  'theme' |
-  'links' |
-  'composerOrSongwriter' |
-  'lyrics' |
-  'object' |
-  'publicationStatus' |
-  'curationStatus' |
-  'explicit' |
-  'license' |
-  'attribution' |
-  'channelId'
-  ;
-
-export type MusicTrackGenericProp = {
-  id: MusicTrackPropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type MusicTrackClassType = {
-  [id in MusicTrackPropId]: MusicTrackGenericProp
-};
-
-export const MusicTrackClass: MusicTrackClassType = {
-  title: {
-    id: 'title',
-    name: 'Title',
-    description: 'The title of the track',
-    type: 'Text',
-    required: true,
-    maxTextLength: 255
-  },
-  artist: {
-    id: 'artist',
-    name: 'Artist',
-    description: 'The artist, composer, band or group that published the track.',
-    type: 'Text',
-    required: true,
-    maxTextLength: 255
-  },
-  thumbnail: {
-    id: 'thumbnail',
-    name: 'Thumbnail',
-    description: 'URL to track cover art: NOTE: Should be an https link to a square image, between 1400x1400 and 3000x3000 pixels, in JPEG or PNG format.',
-    required: true,
-    type: 'Text',
-    maxTextLength: 255
-  },
-  description: {
-    id: 'description',
-    name: 'Description',
-    description: 'Information about the track.',
-    type: 'Text',
-    maxTextLength: 255
-  },
-  language: {
-    id: 'language',
-    name: 'Language',
-    description: 'The language of the lyrics in the track.',
-    type: 'Internal',
-    classId: 'Language'
-  },
-  firstReleased: {
-    id: 'firstReleased',
-    name: 'First Released',
-    description: 'When the track was first released',
-    required: true,
-    type: 'Int64'
-  },
-  genre: {
-    id: 'genre',
-    name: 'Genre',
-    description: 'The genre of the track.',
-    type: 'Internal',
-    classId: 'Music Genre'
-  },
-  mood: {
-    id: 'mood',
-    name: 'Mood',
-    description: 'The mood of the track.',
-    type: 'Internal',
-    classId: 'Music Mood'
-  },
-  theme: {
-    id: 'theme',
-    name: 'Theme',
-    description: 'The theme of the track.',
-    type: 'Internal',
-    classId: 'Music Theme'
-  },
-  links: {
-    id: 'links',
-    name: 'Links',
-    description: 'Links to the artist site or social media pages.',
-    type: 'TextVec',
-    maxItems: 5,
-    maxTextLength: 255
-  },
-  composerOrSongwriter: {
-    id: 'composerOrSongwriter',
-    name: 'Composer or songwriter',
-    description: 'The composer(s) and/or songwriter(s) of the track.',
-    type: 'Text',
-    maxTextLength: 255
-  },
-  lyrics: {
-    id: 'lyrics',
-    name: 'Lyrics',
-    description: 'Link to the track lyrics.',
-    type: 'Text',
-    maxTextLength: 255
-  },
-  object: {
-    id: 'object',
-    name: 'Object',
-    description: 'The entityId of the object in the data directory.',
-    type: 'Internal',
-    classId: 'Media Object'
-  },
-  publicationStatus: {
-    id: 'publicationStatus',
-    name: 'Publication Status',
-    description: 'The publication status of the track.',
-    required: true,
-    type: 'Internal',
-    classId: 'Publication Status'
-  },
-  curationStatus: {
-    id: 'curationStatus',
-    name: 'Curation Status',
-    description: 'The publication status of the track set by the a content curator on the platform.',
-    type: 'Internal',
-    classId: 'Curation Status'
-  },
-  explicit: {
-    id: 'explicit',
-    name: 'Explicit',
-    description: 'Indicates whether the track contains explicit material.',
-    required: true,
-    type: 'Bool'
-  },
-  license: {
-    id: 'license',
-    name: 'License',
-    description: 'The license of which the track is released under.',
-    required: true,
-    type: 'Internal',
-    classId: 'Content License'
-  },
-  attribution: {
-    id: 'attribution',
-    name: 'Attribution',
-    description: 'If the License requires attribution, add this here.',
-    type: 'Text',
-    maxTextLength: 255
-  },
-  channelId: {
-    id: 'channelId',
-    name: 'Channel Id',
-    description: 'Id of the channel this track is published under.',
-    type: 'Uint64'
-  }
-};

+ 0 - 230
pioneer/packages/joy-media/src/schemas/video/Video.ts

@@ -1,230 +0,0 @@
-
-/** This file is generated based on JSON schema. Do not modify. */
-
-import * as Yup from 'yup';
-import { EntityCodec } from '@joystream/types/versioned-store/EntityCodec';
-import moment from 'moment';
-import { LanguageType } from '../general/Language';
-import { VideoCategoryType } from './VideoCategory';
-import { MediaObjectType } from '../general/MediaObject';
-import { PublicationStatusType } from '../general/PublicationStatus';
-import { CurationStatusType } from '../general/CurationStatus';
-import { ContentLicenseType } from '../general/ContentLicense';
-import { ChannelEntity } from '@polkadot/joy-media/entities/ChannelEntity';
-
-export const VideoValidationSchema = Yup.object().shape({
-  title: Yup.string()
-    .required('This field is required')
-    .max(255, 'Text is too long. Maximum length is 255 chars.'),
-  thumbnail: Yup.string()
-    .required('This field is required')
-    .max(255, 'Text is too long. Maximum length is 255 chars.'),
-  description: Yup.string()
-    .required('This field is required')
-    .max(4000, 'Text is too long. Maximum length is 4000 chars.'),
-  firstReleased: Yup.string()
-    .required('This field is required')
-    .test('valid-date', 'Invalid date. Valid date formats are yyyy-mm-dd or yyyy-mm or yyyy.', (val?: any) => {
-      return moment(val).isValid();
-    }),
-  attribution: Yup.string()
-    .max(255, 'Text is too long. Maximum length is 255 chars.')
-});
-
-export type VideoFormValues = {
-  title: string;
-  thumbnail: string;
-  description: string;
-  language: number;
-  firstReleased: string;
-  category: number;
-  links: string[];
-  object: number;
-  publicationStatus: number;
-  curationStatus: number;
-  explicit: 'true' | 'false';
-  license: number;
-  attribution: string;
-  channelId: number;
-};
-
-export type VideoType = {
-  classId: number;
-  inClassSchemaIndexes: number[];
-  id: number;
-  title: string;
-  thumbnail: string;
-  description: string;
-  language: LanguageType;
-  firstReleased: number;
-  category?: VideoCategoryType;
-  links?: string[];
-  object?: MediaObjectType;
-  publicationStatus: PublicationStatusType;
-  curationStatus?: CurationStatusType;
-  explicit: boolean;
-  license: ContentLicenseType;
-  attribution?: string;
-  channelId?: number;
-  channel?: ChannelEntity;
-};
-
-export class VideoCodec extends EntityCodec<VideoType> { }
-
-export function VideoToFormValues (entity?: VideoType): VideoFormValues {
-  return {
-    title: (entity && entity.title) || '',
-    thumbnail: (entity && entity.thumbnail) || '',
-    description: (entity && entity.description) || '',
-    language: (entity && entity.language?.id) || 0,
-    firstReleased: (entity && moment(entity.firstReleased * 1000).format('YYYY-MM-DD')) || '',
-    category: (entity && entity.category?.id) || 0,
-    links: (entity && entity.links) || [],
-    object: (entity && entity.object?.id) || 0,
-    publicationStatus: (entity && entity.publicationStatus?.id) || 0,
-    curationStatus: (entity && entity.curationStatus?.id) || 0,
-    explicit: (entity && entity.explicit) ? 'true' : 'false',
-    license: (entity && entity.license?.id) || 0,
-    attribution: (entity && entity.attribution) || '',
-    channelId: (entity && entity.channelId) || 0
-  };
-}
-
-export type VideoPropId =
-  'title' |
-  'thumbnail' |
-  'description' |
-  'language' |
-  'firstReleased' |
-  'category' |
-  'links' |
-  'object' |
-  'publicationStatus' |
-  'curationStatus' |
-  'explicit' |
-  'license' |
-  'attribution' |
-  'channelId'
-  ;
-
-export type VideoGenericProp = {
-  id: VideoPropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type VideoClassType = {
-  [id in VideoPropId]: VideoGenericProp
-};
-
-export const VideoClass: VideoClassType = {
-  title: {
-    id: 'title',
-    name: 'Title',
-    description: 'The title of the video',
-    type: 'Text',
-    required: true,
-    maxTextLength: 255
-  },
-  thumbnail: {
-    id: 'thumbnail',
-    name: 'Thumbnail',
-    description: 'URL to video thumbnail: NOTE: Should be an https link to an image of ratio 16:9, ideally 1280 pixels wide by 720 pixels tall, with a minimum width of 640 pixels, in JPEG or PNG format.',
-    required: true,
-    type: 'Text',
-    maxTextLength: 255
-  },
-  description: {
-    id: 'description',
-    name: 'Description',
-    description: 'Information about the video.',
-    required: true,
-    type: 'Text',
-    maxTextLength: 4000
-  },
-  language: {
-    id: 'language',
-    name: 'Language',
-    description: 'The main language used in the video.',
-    required: true,
-    type: 'Internal',
-    classId: 'Language'
-  },
-  firstReleased: {
-    id: 'firstReleased',
-    name: 'First Released',
-    description: 'When the video was first released',
-    required: true,
-    type: 'Int64'
-  },
-  category: {
-    id: 'category',
-    name: 'Category',
-    description: 'The category of the video.',
-    type: 'Internal',
-    classId: 'Video Category'
-  },
-  links: {
-    id: 'links',
-    name: 'Link',
-    description: 'A link to the creators page.',
-    type: 'TextVec',
-    maxItems: 5,
-    maxTextLength: 255
-  },
-  object: {
-    id: 'object',
-    name: 'Object',
-    description: 'The entityId of the object in the data directory.',
-    type: 'Internal',
-    classId: 'Media Object'
-  },
-  publicationStatus: {
-    id: 'publicationStatus',
-    name: 'Publication Status',
-    description: 'The publication status of the video.',
-    required: true,
-    type: 'Internal',
-    classId: 'Publication Status'
-  },
-  curationStatus: {
-    id: 'curationStatus',
-    name: 'Curation Status',
-    description: 'The publication status of the video set by the a content curator on the platform.',
-    type: 'Internal',
-    classId: 'Curation Status'
-  },
-  explicit: {
-    id: 'explicit',
-    name: 'Explicit',
-    description: 'Indicates whether the video contains explicit material.',
-    required: true,
-    type: 'Bool'
-  },
-  license: {
-    id: 'license',
-    name: 'License',
-    description: 'The license of which the video is released under.',
-    required: true,
-    type: 'Internal',
-    classId: 'Content License'
-  },
-  attribution: {
-    id: 'attribution',
-    name: 'Attribution',
-    description: 'If the License requires attribution, add this here.',
-    type: 'Text',
-    maxTextLength: 255
-  },
-  channelId: {
-    id: 'channelId',
-    name: 'Channel Id',
-    description: 'Id of the channel this video is published under.',
-    type: 'Uint64'
-  }
-};

+ 0 - 60
pioneer/packages/joy-media/src/schemas/video/VideoCategory.ts

@@ -1,60 +0,0 @@
-
-/** This file is generated based on JSON schema. Do not modify. */
-
-import * as Yup from 'yup';
-import { EntityCodec } from '@joystream/types/versioned-store/EntityCodec';
-
-export const VideoCategoryValidationSchema = Yup.object().shape({
-  value: Yup.string()
-    .required('This field is required')
-    .max(255, 'Text is too long. Maximum length is 255 chars.')
-});
-
-export type VideoCategoryFormValues = {
-  value: string;
-};
-
-export type VideoCategoryType = {
-  classId: number;
-  inClassSchemaIndexes: number[];
-  id: number;
-  value: string;
-};
-
-export class VideoCategoryCodec extends EntityCodec<VideoCategoryType> { }
-
-export function VideoCategoryToFormValues (entity?: VideoCategoryType): VideoCategoryFormValues {
-  return {
-    value: (entity && entity.value) || ''
-  };
-}
-
-export type VideoCategoryPropId =
-  'value'
-  ;
-
-export type VideoCategoryGenericProp = {
-  id: VideoCategoryPropId;
-  type: string;
-  name: string;
-  description?: string;
-  required?: boolean;
-  maxItems?: number;
-  maxTextLength?: number;
-  classId?: any;
-};
-
-type VideoCategoryClassType = {
-  [id in VideoCategoryPropId]: VideoCategoryGenericProp
-};
-
-export const VideoCategoryClass: VideoCategoryClassType = {
-  value: {
-    id: 'value',
-    name: 'Value',
-    description: 'Categories for videos.',
-    type: 'Text',
-    required: true,
-    maxTextLength: 255
-  }
-};

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

@@ -1,13 +0,0 @@
-import React from 'react';
-import '../common/index.scss';
-
-import ExploreContent from '../explore/ExploreContent.view';
-import { withMockTransport } from './withMockTransport';
-
-export default {
-  title: 'Media | Explore',
-  decorators: [withMockTransport]
-};
-
-export const DefaultState = () =>
-  <ExploreContent />;

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

@@ -1,30 +0,0 @@
-import React from 'react';
-import '../common/index.scss';
-
-import { EditForm } from '../music/EditMusicAlbum';
-import { MyMusicTracks } from '../music/MyMusicTracks';
-import { MusicAlbumSamples } from './data/MusicAlbumSamples';
-import { albumTracks, AllMusicTrackSamples } from './data/MusicTrackSamples';
-import { withMockTransport } from './withMockTransport';
-import { EditMusicAlbumView } from '../music/EditMusicAlbum.view';
-import { createType } from '@joystream/types';
-
-export default {
-  title: 'Media | My music tracks',
-  decorators: [withMockTransport]
-};
-
-export const DefaultState = () =>
-  <EditForm />;
-
-export const MockEditAlbumView = () =>
-  <EditMusicAlbumView
-    id={createType('EntityId', 1)}
-    tracks={albumTracks}
-  />;
-
-export const MyMusicTracksStory = () =>
-  <MyMusicTracks
-    albums={MusicAlbumSamples}
-    tracks={AllMusicTrackSamples}
-  />;

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

@@ -1,26 +0,0 @@
-import React from 'react';
-import '../common/index.scss';
-
-import { MockMusicChannel } from './data/ChannelSamples';
-import { ViewMusicChannel } from '../channels/ViewMusicChannel';
-import { MusicAlbumSamples } from './data/MusicAlbumSamples';
-import { AllMusicTrackSamples } from './data/MusicTrackSamples';
-import { withMockTransport } from './withMockTransport';
-
-export default {
-  title: 'Media | Music channel',
-  decorators: [withMockTransport]
-};
-
-export const EmptyMusicChannel = () =>
-  <ViewMusicChannel channel={MockMusicChannel} />;
-
-export const MusicChannelWithAlbumsOnly = () =>
-  <ViewMusicChannel channel={MockMusicChannel} albums={MusicAlbumSamples} />;
-
-export const MusicChannelWithAlbumAndTracks = () =>
-  <ViewMusicChannel
-    channel={MockMusicChannel}
-    albums={MusicAlbumSamples}
-    tracks={AllMusicTrackSamples}
-  />;

+ 0 - 33
pioneer/packages/joy-media/src/stories/MyChannels.stories.tsx

@@ -1,33 +0,0 @@
-import React from 'react';
-import '../common/index.scss';
-
-import { ChannelsByOwner } from '../channels/ChannelsByOwner';
-import { AllMockChannels } from './data/ChannelSamples';
-import { withMockTransport } from './withMockTransport';
-import EditForm from '../channels/EditChannel';
-import { EditChannelView } from '../channels/EditChannel.view';
-import { AccountIdSamples } from './data/AccountIdSamples';
-import { createType } from '@joystream/types';
-
-export default {
-  title: 'Media | My channels',
-  decorators: [withMockTransport]
-};
-
-// TODO pass to mocked MyMembershipContext provider via Stories decorators:
-const accountId = createType('AccountId', AccountIdSamples.Alice);
-
-export const DefaultState = () =>
-  <ChannelsByOwner accountId={accountId} />;
-
-export const ChannelCreationSuspended = () =>
-  <ChannelsByOwner accountId={accountId} suspended={true} />;
-
-export const YouHaveChannels = () =>
-  <ChannelsByOwner accountId={accountId} channels={AllMockChannels} />;
-
-export const DefaultEditForm = () =>
-  <EditForm />;
-
-export const MockEditFormView = () =>
-  <EditChannelView id={createType('ChannelId', 1)} />;

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

@@ -1,17 +0,0 @@
-import React from 'react';
-import '../common/index.scss';
-
-import { MyMusicAlbums } from '../music/MyMusicAlbums';
-import { MusicAlbumSamples } from './data/MusicAlbumSamples';
-import { withMockTransport } from './withMockTransport';
-
-export default {
-  title: 'Media | My music albums',
-  decorators: [withMockTransport]
-};
-
-export const DefaultState = () =>
-  <MyMusicAlbums />;
-
-export const WithState = () =>
-  <MyMusicAlbums albums={MusicAlbumSamples} />;

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

@@ -1,31 +0,0 @@
-import React from 'react';
-import '../common/index.scss';
-
-import { PlayContent } from '../explore/PlayContent';
-import { PlayVideo } from '../video/PlayVideo';
-import { FeaturedAlbums } from './data/MusicAlbumSamples';
-import { Album1TrackSamples } from './data/MusicTrackSamples';
-import { MockMusicChannel, MockVideoChannel } from './data/ChannelSamples';
-import { withMockTransport } from './withMockTransport';
-import { Video } from '../mocks';
-import { createType } from '@joystream/types';
-
-export default {
-  title: 'Media | Playback',
-  decorators: [withMockTransport]
-};
-
-export const PlayVideoStory = () =>
-  <PlayVideo
-    id={createType('EntityId', Video.id)}
-    video={Video}
-    channel={MockVideoChannel}
-  />;
-
-export const PlayAlbumStory = () =>
-  <PlayContent
-    channel={MockMusicChannel}
-    featuredAlbums={FeaturedAlbums}
-    tracks={Album1TrackSamples}
-    currentTrackIndex={3}
-  />;

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

@@ -1,26 +0,0 @@
-import React from 'react';
-import { EditForm } from '../upload/UploadAudio';
-import '../index.scss';
-
-import { ContentId } from '@joystream/types/media';
-import { UploadAudioView } from '../upload/UploadAudio.view';
-import { withMockTransport } from './withMockTransport';
-import { registry, createType } from '@joystream/types';
-
-export default {
-  title: 'Media | Upload audio',
-  decorators: [withMockTransport]
-};
-
-const contentId = ContentId.generate(registry);
-
-export const DefaultState = () =>
-  <EditForm
-    contentId={contentId}
-  />;
-
-export const MockEditFormView = () =>
-  <UploadAudioView
-    contentId={contentId}
-    id={createType('EntityId', 1)}
-  />;

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

@@ -1,26 +0,0 @@
-import React from 'react';
-import { EditForm } from '../upload/UploadVideo';
-import '../index.scss';
-
-import { ContentId } from '@joystream/types/media';
-import { withMockTransport } from './withMockTransport';
-import EditVideoView from '../upload/EditVideo.view';
-import { createType, registry } from '@joystream/types';
-
-export default {
-  title: 'Media | Upload video',
-  decorators: [withMockTransport]
-};
-
-const contentId = ContentId.generate(registry);
-
-export const DefaultState = () =>
-  <EditForm
-    contentId={contentId}
-  />;
-
-export const MockEditFormView = () =>
-  <EditVideoView
-    contentId={contentId}
-    id={createType('EntityId', 1)}
-  />;

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

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

+ 0 - 58
pioneer/packages/joy-media/src/stories/data/ChannelSamples.ts

@@ -1,58 +0,0 @@
-import BN from 'bn.js';
-import { ChannelEntity } from '@polkadot/joy-media/entities/ChannelEntity';
-import { AccountIdSamples } from './AccountIdSamples';
-import { createType } from '@joystream/types';
-
-let id = 0;
-const nextId = () => ++id;
-
-export const MockMusicChannel: ChannelEntity =
-{
-  id: nextId(),
-  verified: true,
-  content: 'Music',
-  handle: 'easy_notes',
-  title: 'Easy Notes',
-  description: 'A fortepiano is an early piano. In principle, the word "fortepiano" can designate any piano dating from the invention of the instrument by Bartolomeo Cristofori around 1700 up to the early 19th century. Most typically, however, it is used to refer to the late-18th to early-19th century instruments for which Haydn, Mozart, and the younger Beethoven wrote their piano music.',
-
-  avatar: 'https://images.unsplash.com/photo-1485561222814-e6c50477491b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=200&q=60',
-  banner: 'https://images.unsplash.com/photo-1514119412350-e174d90d280e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=900&q=80',
-
-  publicationStatus: 'Unlisted',
-  curationStatus: 'Censored',
-  owner: createType('MemberId', 1),
-  roleAccount: AccountIdSamples.Alice,
-  principalId: createType('PrincipalId', 1),
-  created: createType('u32', 123456),
-
-  rewardEarned: new BN('4587'),
-  contentItemsCount: 57
-};
-
-export const MockVideoChannel: ChannelEntity =
-{
-  id: nextId(),
-  verified: true,
-  content: 'Video',
-  handle: 'bicycles_rocknroll',
-  title: 'Bicycles and Rock-n-Roll',
-  description: 'A bicycle, also called a cycle or bike, is a human-powered or motor-powered, pedal-driven, single-track vehicle, having two wheels attached to a frame, one behind the other. A is called a cyclist, or bicyclist.',
-
-  avatar: 'https://images.unsplash.com/photo-1485965120184-e220f721d03e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=200&q=60',
-  banner: 'https://images.unsplash.com/photo-1494488802316-82250d81cfcc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=900&q=60',
-
-  publicationStatus: 'Public',
-  curationStatus: 'Normal',
-  owner: createType('MemberId', 1),
-  roleAccount: AccountIdSamples.Alice,
-  principalId: createType('PrincipalId', 1),
-  created: createType('u32', 123456),
-
-  rewardEarned: new BN('1820021'),
-  contentItemsCount: 1529
-};
-
-export const AllMockChannels: ChannelEntity[] = [
-  MockVideoChannel,
-  MockMusicChannel
-];

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.