Rx JS индикатор загрузки видео - PullRequest
1 голос
/ 30 марта 2020

Я пытаюсь реализовать индикатор загрузки видео в vimeo. Сначала я получаю билет на загрузку, а затем хочу установить прогресс в онлайн-магазине. Каков наилучший подход для решения этой проблемы?

Вот мой эпи c:

return action$.pipe(
    ofType(VideoActionsTypes.ADD_VIDEO),
    switchMap(({ payload }) => {
      return apiService.post('/video/upload-ticket', {
        title: payload.title,
        fileSize: payload.video.size,
      }).pipe(
        map((response: { url: string; }) => {
          const upload = new tus.Upload(payload.video, {
            endpoint: 'none',
            chunkSize: 128000000,
            retryDelays: [0, 1000, 3000, 5000],
            onProgress: (bytes_uploaded: number, bytes_total: number) => {
              const percentage = bytes_uploaded / bytes_total * 100;

              setProgressStatus({ status: percentage }); // another action
            },
          });

          upload.url = response.url;

          upload.start();
        }),
      )

1 Ответ

1 голос
/ 01 апреля 2020

Мой совет - написать функцию, которая принимает те же аргументы, что и конструктор объекта загрузки, и возвращает новую наблюдаемую информацию, которая генерирует прогресс.

const uploadAndTrackProgress = (config) => {
  return new Observable((observer) => {
    const upload = new tus.Upload(config.video, {
      endpoint: config.endpoint,
      chunkSize: config.chunkSize,
      retryDelays: config.retryDelays,

      onProgress: (bytesUploaded, bytesTotal) => {
        const progress = (bytesUploaded / bytesTotal) * 100;
        observer.next(progress);
        if (progress === 100) {
          observer.complete();
        }
      },
    });

    upload.url = config.url;
    upload.start();
  });
};

Теперь ваш epi c выглядит следующим образом:

action$.pipe(
  ofType(VideoActionsTypes.ADD_VIDEO),
  switchMap(({ payload }) =>
    apiService
      .post('/video/upload-ticket', {
        title: payload.title,
        fileSize: payload.video.size,
      })
      .pipe(
        concatMap((response) =>
          uploadAndTrackProgress({
            video: payload.video,
            url: response.url,
            endpoint: 'none',
            chunkSize: 128000000,
            retryDelays: [0, 1000, 3000, 5000],
          })
        ),
        map((percentage) => ({
          type: 'SET_PROGRESS_STATUS',
          status: percentage,
        }))
      )
  )
);
...