Merge branch 'master' into comicbook-reader
This commit is contained in:
commit
4eb0131f83
16 changed files with 1406 additions and 1185 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,5 +6,6 @@
|
||||||
/static/locales
|
/static/locales
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
.transifexrc
|
||||||
.idea/
|
.idea/
|
||||||
/build/daemon*
|
/build/daemon*
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
[main]
|
[main]
|
||||||
host = https://www.transifex.com
|
host = https://www.transifex.com
|
||||||
|
|
||||||
[lbry-deskop.app-strings]
|
[lbry-desktop.app-strings]
|
||||||
file_filter = dist/locales/<lang>.json
|
file_filter = static/locales/<lang>.json
|
||||||
source_file = dist/locales/en.json
|
source_file = static/locales/en.json
|
||||||
source_lang = en
|
source_lang = en
|
||||||
type = KEYVALUEJSON
|
type = KEYVALUEJSON
|
||||||
|
|
21
CHANGELOG.md
21
CHANGELOG.md
|
@ -4,14 +4,31 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
## [0.32.0] - [Unreleased]
|
## [0.32.2] - [2019-5-20]
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- Upgraded LBRY SDK to 0.37.0 for better network stability
|
||||||
|
- Better error logging
|
||||||
|
|
||||||
|
## [0.32.1] - [2019-5-14]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix analytics on desktop ([#2480](https://github.com/lbryio/lbry-desktop/pull/2480))
|
||||||
|
- Fix text wrapping on file page ([#2480](https://github.com/lbryio/lbry-desktop/pull/2480))
|
||||||
|
|
||||||
|
## [0.32.0] - [2019-5-14]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Updating claims after they are tipped
|
||||||
|
- Opening html, markdown, and other text documents
|
||||||
|
- Opening links from open.lbry.com
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- New routing setup to allow lbry.tv to use the browser url bar for navigation ([#2408](https://github.com/lbryio/lbry-desktop/pull/2408))
|
- New routing setup to allow lbry.tv to use the browser url bar for navigation ([#2408](https://github.com/lbryio/lbry-desktop/pull/2408))
|
||||||
- New audio player ([#2406](https://github.com/lbryio/lbry-desktop/pull/2406))
|
|
||||||
- Always show new suggested subscriptions ([#2541](https://github.com/lbryio/lbry-desktop/pull/2451))
|
- Always show new suggested subscriptions ([#2541](https://github.com/lbryio/lbry-desktop/pull/2451))
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
13
package.json
13
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "LBRY",
|
"name": "LBRY",
|
||||||
"version": "0.32.1",
|
"version": "0.32.2",
|
||||||
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
|
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"lbry"
|
"lbry"
|
||||||
|
@ -40,8 +40,6 @@
|
||||||
"postinstall": "electron-builder install-app-deps && node build/downloadDaemon.js"
|
"postinstall": "electron-builder install-app-deps && node build/downloadDaemon.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@reach/rect": "^0.2.1",
|
|
||||||
"@reach/tabs": "^0.1.5",
|
|
||||||
"electron-dl": "^1.11.0",
|
"electron-dl": "^1.11.0",
|
||||||
"electron-log": "^2.2.12",
|
"electron-log": "^2.2.12",
|
||||||
"electron-updater": "^4.0.6",
|
"electron-updater": "^4.0.6",
|
||||||
|
@ -63,6 +61,8 @@
|
||||||
"@hot-loader/react-dom": "16.8",
|
"@hot-loader/react-dom": "16.8",
|
||||||
"@lbry/color": "^1.0.2",
|
"@lbry/color": "^1.0.2",
|
||||||
"@lbry/components": "^2.7.0",
|
"@lbry/components": "^2.7.0",
|
||||||
|
"@reach/rect": "^0.2.1",
|
||||||
|
"@reach/tabs": "^0.1.5",
|
||||||
"@types/three": "^0.93.1",
|
"@types/three": "^0.93.1",
|
||||||
"async-exit-hook": "^2.0.1",
|
"async-exit-hook": "^2.0.1",
|
||||||
"babel-eslint": "^10.0.1",
|
"babel-eslint": "^10.0.1",
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
"chalk": "^2.4.2",
|
"chalk": "^2.4.2",
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
"codemirror": "^5.39.2",
|
"codemirror": "^5.39.2",
|
||||||
"connected-react-router": "^6.3.2",
|
"connected-react-router": "^6.4.0",
|
||||||
"cookie": "^0.3.1",
|
"cookie": "^0.3.1",
|
||||||
"copy-webpack-plugin": "^4.6.0",
|
"copy-webpack-plugin": "^4.6.0",
|
||||||
"country-data": "^0.0.31",
|
"country-data": "^0.0.31",
|
||||||
|
@ -89,7 +89,7 @@
|
||||||
"devtron": "^1.4.0",
|
"devtron": "^1.4.0",
|
||||||
"dom-scroll-into-view": "^1.2.1",
|
"dom-scroll-into-view": "^1.2.1",
|
||||||
"electron": "4.1.0",
|
"electron": "4.1.0",
|
||||||
"electron-builder": "^20.39.0",
|
"electron-builder": "^20.41.0",
|
||||||
"electron-devtools-installer": "^2.2.4",
|
"electron-devtools-installer": "^2.2.4",
|
||||||
"electron-is-dev": "^0.3.0",
|
"electron-is-dev": "^0.3.0",
|
||||||
"electron-publisher-s3": "^20.8.1",
|
"electron-publisher-s3": "^20.8.1",
|
||||||
|
@ -149,6 +149,7 @@
|
||||||
"react-paginate": "^5.2.1",
|
"react-paginate": "^5.2.1",
|
||||||
"react-pose": "^4.0.5",
|
"react-pose": "^4.0.5",
|
||||||
"react-redux": "^6.0.1",
|
"react-redux": "^6.0.1",
|
||||||
|
"react-router": "^5.0.0",
|
||||||
"react-router-dom": "^5.0.0",
|
"react-router-dom": "^5.0.0",
|
||||||
"react-simplemde-editor": "^4.0.0",
|
"react-simplemde-editor": "^4.0.0",
|
||||||
"react-toggle": "^4.0.2",
|
"react-toggle": "^4.0.2",
|
||||||
|
@ -189,7 +190,7 @@
|
||||||
"yarn": "^1.3"
|
"yarn": "^1.3"
|
||||||
},
|
},
|
||||||
"lbrySettings": {
|
"lbrySettings": {
|
||||||
"lbrynetDaemonVersion": "0.37.0",
|
"lbrynetDaemonVersion": "0.37.1",
|
||||||
"lbrynetDaemonUrlTemplate": "https://github.com/lbryio/lbry/releases/download/vDAEMONVER/lbrynet-OSNAME.zip",
|
"lbrynetDaemonUrlTemplate": "https://github.com/lbryio/lbry/releases/download/vDAEMONVER/lbrynet-OSNAME.zip",
|
||||||
"lbrynetDaemonDir": "static/daemon",
|
"lbrynetDaemonDir": "static/daemon",
|
||||||
"lbrynetDaemonFileName": "lbrynet"
|
"lbrynetDaemonFileName": "lbrynet"
|
||||||
|
|
|
@ -4,6 +4,7 @@ import * as React from 'react';
|
||||||
import Yrbl from 'component/yrbl';
|
import Yrbl from 'component/yrbl';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
|
import Native from 'native';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
children: React.Node,
|
children: React.Node,
|
||||||
|
@ -29,15 +30,28 @@ class ErrorBoundary extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidCatch(error: { stack: string }) {
|
componentDidCatch(error: { stack: string }) {
|
||||||
|
let errorMessage = '\n';
|
||||||
|
|
||||||
|
// @if TARGET='web'
|
||||||
|
errorMessage += 'lbry.tv error\n';
|
||||||
|
errorMessage += window.location.pathname + window.location.search;
|
||||||
|
this.log(errorMessage);
|
||||||
|
// @endif
|
||||||
|
// @if TARGET='app'
|
||||||
|
Native.getAppVersionInfo().then(({ localVersion }) => {
|
||||||
|
errorMessage += `version: ${localVersion}\n`;
|
||||||
|
errorMessage += `page: ${window.location.href.split('.html')[1]}\n`;
|
||||||
|
errorMessage += `${error.stack}`;
|
||||||
|
|
||||||
|
this.log(errorMessage);
|
||||||
|
});
|
||||||
|
// @endif
|
||||||
|
}
|
||||||
|
|
||||||
|
log(message) {
|
||||||
declare var app: { env: string };
|
declare var app: { env: string };
|
||||||
|
|
||||||
const errorMessage = `
|
|
||||||
${window.location.pathname + window.location.search}\n
|
|
||||||
${error.stack}
|
|
||||||
`;
|
|
||||||
|
|
||||||
if (app.env === 'production') {
|
if (app.env === 'production') {
|
||||||
Lbryio.call('event', 'desktop_error', { error_message: errorMessage });
|
Lbryio.call('event', 'desktop_error', { error_message: message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
import 'babel-polyfill';
|
import '@babel/polyfill';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
// @if TARGET='app'
|
// @if TARGET='app'
|
||||||
import { remote } from 'electron';
|
import { remote } from 'electron';
|
||||||
|
|
|
@ -407,6 +407,7 @@ class PublishForm extends React.PureComponent<Props> {
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<SelectThumbnail
|
<SelectThumbnail
|
||||||
|
filePath={filePath}
|
||||||
thumbnailPath={thumbnailPath}
|
thumbnailPath={thumbnailPath}
|
||||||
thumbnail={thumbnail}
|
thumbnail={thumbnail}
|
||||||
uploadThumbnailStatus={uploadThumbnailStatus}
|
uploadThumbnailStatus={uploadThumbnailStatus}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import * as MODALS from 'constants/modal_types';
|
import * as MODALS from 'constants/modal_types';
|
||||||
import { THUMBNAIL_STATUSES } from 'lbry-redux';
|
import { THUMBNAIL_STATUSES } from 'lbry-redux';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import getMediaType from 'util/get-media-type';
|
||||||
import { FormField } from 'component/common/form';
|
import { FormField } from 'component/common/form';
|
||||||
import FileSelector from 'component/common/file-selector';
|
import FileSelector from 'component/common/file-selector';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
@ -9,6 +10,7 @@ import ThumbnailMissingImage from './thumbnail-missing.png';
|
||||||
import ThumbnailBrokenImage from './thumbnail-broken.png';
|
import ThumbnailBrokenImage from './thumbnail-broken.png';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
filePath: ?string,
|
||||||
thumbnail: ?string,
|
thumbnail: ?string,
|
||||||
formDisabled: boolean,
|
formDisabled: boolean,
|
||||||
uploadThumbnailStatus: string,
|
uploadThumbnailStatus: string,
|
||||||
|
@ -50,6 +52,7 @@ class SelectThumbnail extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
|
filePath,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
formDisabled,
|
formDisabled,
|
||||||
uploadThumbnailStatus: status,
|
uploadThumbnailStatus: status,
|
||||||
|
@ -61,6 +64,8 @@ class SelectThumbnail extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
const { thumbnailError } = this.state;
|
const { thumbnailError } = this.state;
|
||||||
|
|
||||||
|
const isSupportedVideo = getMediaType(null, filePath) === 'video';
|
||||||
|
|
||||||
let thumbnailSrc;
|
let thumbnailSrc;
|
||||||
if (!thumbnail) {
|
if (!thumbnail) {
|
||||||
thumbnailSrc = ThumbnailMissingImage;
|
thumbnailSrc = ThumbnailMissingImage;
|
||||||
|
@ -141,9 +146,16 @@ class SelectThumbnail extends React.PureComponent<Props, State> {
|
||||||
<div className="card__actions">
|
<div className="card__actions">
|
||||||
<Button
|
<Button
|
||||||
button="link"
|
button="link"
|
||||||
label={__('Or enter a URL manually')}
|
label={__('Enter a thumbnail URL')}
|
||||||
onClick={() => updatePublishForm({ uploadThumbnailStatus: THUMBNAIL_STATUSES.MANUAL })}
|
onClick={() => updatePublishForm({ uploadThumbnailStatus: THUMBNAIL_STATUSES.MANUAL })}
|
||||||
/>
|
/>
|
||||||
|
{isSupportedVideo && (
|
||||||
|
<Button
|
||||||
|
button="link"
|
||||||
|
label={__('Take a snapshot from your video')}
|
||||||
|
onClick={() => openModal(MODALS.AUTO_GENERATE_THUMBNAIL, { filePath })}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,10 @@ class AudioVideoViewer extends React.PureComponent<Props> {
|
||||||
const { contentType, poster, claim } = this.props;
|
const { contentType, poster, claim } = this.props;
|
||||||
const { name, claim_id: claimId, txid, nout } = claim;
|
const { name, claim_id: claimId, txid, nout } = claim;
|
||||||
|
|
||||||
|
// Quick fix to get file view events on lbry.tv
|
||||||
|
// Will need to be changed to include time to start
|
||||||
|
analytics.apiLogView(`${name}#${claimId}`, `${txid}:${nout}`, claimId);
|
||||||
|
|
||||||
const path = `https://api.piratebay.com/content/claims/${claim.name}/${claim.claim_id}/stream.mp4`;
|
const path = `https://api.piratebay.com/content/claims/${claim.name}/${claim.claim_id}/stream.mp4`;
|
||||||
const sources = [
|
const sources = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,6 +3,7 @@ export const CONFIRM_EXTERNAL_RESOURCE = 'confirm_external_resource';
|
||||||
export const INCOMPATIBLE_DAEMON = 'incompatible_daemon';
|
export const INCOMPATIBLE_DAEMON = 'incompatible_daemon';
|
||||||
export const FILE_TIMEOUT = 'file_timeout';
|
export const FILE_TIMEOUT = 'file_timeout';
|
||||||
export const DOWNLOADING = 'downloading';
|
export const DOWNLOADING = 'downloading';
|
||||||
|
export const AUTO_GENERATE_THUMBNAIL = 'auto_generate_thumbnail';
|
||||||
export const AUTO_UPDATE_DOWNLOADED = 'auto_update_downloaded';
|
export const AUTO_UPDATE_DOWNLOADED = 'auto_update_downloaded';
|
||||||
export const AUTO_UPDATE_CONFIRM = 'auto_update_confirm';
|
export const AUTO_UPDATE_CONFIRM = 'auto_update_confirm';
|
||||||
export const ERROR = 'error';
|
export const ERROR = 'error';
|
||||||
|
|
|
@ -3,7 +3,7 @@ import y18n from 'y18n';
|
||||||
|
|
||||||
const i18n = y18n({
|
const i18n = y18n({
|
||||||
directory: `static/locales`.replace(/\\/g, '\\\\'),
|
directory: `static/locales`.replace(/\\/g, '\\\\'),
|
||||||
updateFiles: false,
|
updateFiles: true,
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
});
|
});
|
||||||
// @endif
|
// @endif
|
||||||
|
|
16
src/ui/modal/modalAutoGenerateThumbnail/index.js
Normal file
16
src/ui/modal/modalAutoGenerateThumbnail/index.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { doHideModal } from 'redux/actions/app';
|
||||||
|
import { doUploadThumbnail } from 'redux/actions/publish';
|
||||||
|
import { doToast } from 'lbry-redux';
|
||||||
|
import ModalAutoGenerateThumbnail from './view';
|
||||||
|
|
||||||
|
const perform = dispatch => ({
|
||||||
|
closeModal: () => dispatch(doHideModal()),
|
||||||
|
upload: buffer => dispatch(doUploadThumbnail(null, buffer)),
|
||||||
|
showToast: options => dispatch(doToast(options)),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
null,
|
||||||
|
perform
|
||||||
|
)(ModalAutoGenerateThumbnail);
|
84
src/ui/modal/modalAutoGenerateThumbnail/view.jsx
Normal file
84
src/ui/modal/modalAutoGenerateThumbnail/view.jsx
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
// @flow
|
||||||
|
import React, { useRef } from 'react';
|
||||||
|
import { Modal } from 'modal/modal';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
upload: Buffer => void,
|
||||||
|
filePath: string,
|
||||||
|
closeModal: () => void,
|
||||||
|
showToast: ({}) => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
function ModalAutoGenerateThumbnail(props: Props) {
|
||||||
|
const { closeModal, filePath, upload, showToast } = props;
|
||||||
|
const playerRef = useRef();
|
||||||
|
|
||||||
|
let src = filePath.replace(/\\/g, '/');
|
||||||
|
src = src[0] !== '/' ? `/${src}` : src;
|
||||||
|
src = encodeURI(`file://${src}`).replace(/[?#]/g, encodeURIComponent);
|
||||||
|
|
||||||
|
function uploadImage() {
|
||||||
|
const imageBuffer = captureSnapshot();
|
||||||
|
if (imageBuffer) {
|
||||||
|
upload(imageBuffer);
|
||||||
|
closeModal();
|
||||||
|
} else {
|
||||||
|
onError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function captureSnapshot(): ?Buffer {
|
||||||
|
const player = playerRef.current;
|
||||||
|
if (!player) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.width = player.videoWidth;
|
||||||
|
canvas.height = player.videoHeight;
|
||||||
|
const context = canvas.getContext('2d');
|
||||||
|
context.drawImage(player, 0, 0, canvas.width, canvas.height);
|
||||||
|
const dataURL = canvas.toDataURL();
|
||||||
|
const rawData = dataURL.replace(/data:image\/\w+;base64,/i, '');
|
||||||
|
canvas.remove();
|
||||||
|
return Buffer.from(rawData, 'base64');
|
||||||
|
}
|
||||||
|
|
||||||
|
function resize(): void {
|
||||||
|
const player = playerRef.current;
|
||||||
|
if (!player) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('resized');
|
||||||
|
|
||||||
|
const fixedWidth = 450;
|
||||||
|
const videoWidth = player.videoWidth;
|
||||||
|
const videoHeight = player.videoHeight;
|
||||||
|
player.width = fixedWidth;
|
||||||
|
player.height = Math.floor(videoHeight * (fixedWidth / videoWidth));
|
||||||
|
}
|
||||||
|
|
||||||
|
function onError(): void {
|
||||||
|
showToast({ isError: true, message: __("Something didn't work. Please try again.") });
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
isOpen
|
||||||
|
title={__('Upload Thumbnail')}
|
||||||
|
contentLabel={__('Confirm Thumbnail Upload')}
|
||||||
|
type="confirm"
|
||||||
|
confirmButtonLabel={__('Upload')}
|
||||||
|
onConfirmed={uploadImage}
|
||||||
|
onAborted={closeModal}
|
||||||
|
>
|
||||||
|
<section className="card__content">
|
||||||
|
<p className="card__subtitle">{__('Pause at any time to select a thumbnail from your video')}.</p>
|
||||||
|
<video ref={playerRef} src={src} onLoadedMetadata={resize} onError={onError} controls />
|
||||||
|
</section>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ModalAutoGenerateThumbnail;
|
|
@ -4,6 +4,7 @@ import * as MODALS from 'constants/modal_types';
|
||||||
import ModalError from 'modal/modalError';
|
import ModalError from 'modal/modalError';
|
||||||
import ModalAuthFailure from 'modal/modalAuthFailure';
|
import ModalAuthFailure from 'modal/modalAuthFailure';
|
||||||
import ModalDownloading from 'modal/modalDownloading';
|
import ModalDownloading from 'modal/modalDownloading';
|
||||||
|
import ModalAutoGenerateThumbnail from 'modal/modalAutoGenerateThumbnail';
|
||||||
import ModalAutoUpdateDownloaded from 'modal/modalAutoUpdateDownloaded';
|
import ModalAutoUpdateDownloaded from 'modal/modalAutoUpdateDownloaded';
|
||||||
import ModalAutoUpdateConfirm from 'modal/modalAutoUpdateConfirm';
|
import ModalAutoUpdateConfirm from 'modal/modalAutoUpdateConfirm';
|
||||||
import ModalUpgrade from 'modal/modalUpgrade';
|
import ModalUpgrade from 'modal/modalUpgrade';
|
||||||
|
@ -51,6 +52,8 @@ function ModalRouter(props: Props) {
|
||||||
return <ModalUpgrade {...modalProps} />;
|
return <ModalUpgrade {...modalProps} />;
|
||||||
case MODALS.DOWNLOADING:
|
case MODALS.DOWNLOADING:
|
||||||
return <ModalDownloading {...modalProps} />;
|
return <ModalDownloading {...modalProps} />;
|
||||||
|
case MODALS.AUTO_GENERATE_THUMBNAIL:
|
||||||
|
return <ModalAutoGenerateThumbnail {...modalProps} />;
|
||||||
case MODALS.AUTO_UPDATE_DOWNLOADED:
|
case MODALS.AUTO_UPDATE_DOWNLOADED:
|
||||||
return <ModalAutoUpdateDownloaded {...modalProps} />;
|
return <ModalAutoUpdateDownloaded {...modalProps} />;
|
||||||
case MODALS.AUTO_UPDATE_CONFIRM:
|
case MODALS.AUTO_UPDATE_CONFIRM:
|
||||||
|
|
|
@ -68,10 +68,22 @@ export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) =>
|
||||||
data: { ...publishFormValue },
|
data: { ...publishFormValue },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const doUploadThumbnail = (filePath: string) => (dispatch: Dispatch) => {
|
export const doUploadThumbnail = (filePath: string, thumbnailBuffer: Uint8Array) => (dispatch: Dispatch) => {
|
||||||
const thumbnail = fs.readFileSync(filePath);
|
let thumbnail, fileExt, fileName, fileType;
|
||||||
const fileExt = path.extname(filePath);
|
|
||||||
const fileName = path.basename(filePath);
|
if (filePath) {
|
||||||
|
thumbnail = fs.readFileSync(filePath);
|
||||||
|
fileExt = path.extname(filePath);
|
||||||
|
fileName = path.basename(filePath);
|
||||||
|
fileType = `image/${fileExt.slice(1)}`;
|
||||||
|
} else if (thumbnailBuffer) {
|
||||||
|
thumbnail = thumbnailBuffer;
|
||||||
|
fileExt = '.png';
|
||||||
|
fileName = 'thumbnail.png';
|
||||||
|
fileType = 'image/png';
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const makeid = () => {
|
const makeid = () => {
|
||||||
let text = '';
|
let text = '';
|
||||||
|
@ -102,7 +114,7 @@ export const doUploadThumbnail = (filePath: string) => (dispatch: Dispatch) => {
|
||||||
|
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
const name = makeid();
|
const name = makeid();
|
||||||
const file = new File([thumbnail], fileName, { type: `image/${fileExt.slice(1)}` });
|
const file = new File([thumbnail], fileName, { type: fileType });
|
||||||
data.append('name', name);
|
data.append('name', name);
|
||||||
data.append('file', file);
|
data.append('file', file);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue