diff --git a/ui/component/publishFile/view.jsx b/ui/component/publishFile/view.jsx
index 3882efae3..cfc9c5232 100644
--- a/ui/component/publishFile/view.jsx
+++ b/ui/component/publishFile/view.jsx
@@ -18,6 +18,7 @@ type Props = {
name: ?string,
title: ?string,
filePath: string | WebFile,
+ fileMimeType: ?string,
isStillEditing: boolean,
balance: number,
updatePublishForm: ({}) => void,
@@ -43,6 +44,7 @@ function PublishFile(props: Props) {
title,
balance,
filePath,
+ fileMimeType,
isStillEditing,
updatePublishForm,
disabled,
@@ -343,6 +345,7 @@ function PublishFile(props: Props) {
label={__('Story content')}
uri={uri}
disabled={disabled}
+ fileMimeType={fileMimeType}
setPrevFileText={setPrevFileText}
setCurrentFileType={setCurrentFileType}
/>
diff --git a/ui/component/publishForm/view.jsx b/ui/component/publishForm/view.jsx
index 4cd321be1..c662a6775 100644
--- a/ui/component/publishForm/view.jsx
+++ b/ui/component/publishForm/view.jsx
@@ -120,9 +120,12 @@ function PublishForm(props: Props) {
const TAGS_LIMIT = 5;
const fileFormDisabled = mode === PUBLISH_MODES.FILE && !filePath;
- const storyFormDisabled = mode === PUBLISH_MODES.STORY && (!fileText || fileText === '');
- const formDisabled = ((fileFormDisabled || storyFormDisabled) && !editingURI) || publishing;
+ const emptyStoryError = mode === PUBLISH_MODES.STORY && (!fileText || fileText.trim() === '');
+ const formDisabled = (fileFormDisabled && !editingURI) || emptyStoryError || publishing;
const isInProgress = filePath || editingURI || name || title;
+ // Editing content info
+ const uri = myClaimForUri ? myClaimForUri.permanent_url : undefined;
+ const fileMimeType = myClaimForUri ? myClaimForUri.value.source.media_type : undefined;
// If they are editing, they don't need a new file chosen
const formValidLessFile =
@@ -131,6 +134,7 @@ function PublishForm(props: Props) {
title &&
bid &&
!bidError &&
+ !emptyStoryError &&
!(uploadThumbnailStatus === THUMBNAIL_STATUSES.IN_PROGRESS);
const isOverwritingExistingClaim = !editingURI && myClaimForUri;
@@ -280,19 +284,16 @@ function PublishForm(props: Props) {
// Update mode on editing
useEffect(() => {
if (autoSwitchMode && editingURI && myClaimForUri) {
- const { media_type: mediaType } = myClaimForUri.value.source;
// Change publish mode to "story" if editing content type is markdown
- if (mediaType === 'text/markdown' && mode !== PUBLISH_MODES.STORY) {
+ if (fileMimeType === 'text/markdown' && mode !== PUBLISH_MODES.STORY) {
setMode(PUBLISH_MODES.STORY);
// Prevent forced mode
setAutoSwitchMode(false);
}
}
- }, [autoSwitchMode, editingURI, myClaimForUri, mode, setMode, setAutoSwitchMode]);
+ }, [autoSwitchMode, editingURI, fileMimeType, myClaimForUri, mode, setMode, setAutoSwitchMode]);
// Editing claim uri
- const uri = myClaimForUri ? myClaimForUri.permanent_url : undefined;
-
return (
@@ -312,6 +313,7 @@ function PublishForm(props: Props) {
({
bid: makeSelectPublishFormValue('bid')(state),
name: makeSelectPublishFormValue('name')(state),
title: makeSelectPublishFormValue('title')(state),
- fileText: makeSelectPublishFormValue('fileText')(state),
bidError: makeSelectPublishFormValue('bidError')(state),
editingUri: makeSelectPublishFormValue('editingUri')(state),
uploadThumbnailStatus: makeSelectPublishFormValue('uploadThumbnailStatus')(state),
diff --git a/ui/component/publishFormErrors/view.jsx b/ui/component/publishFormErrors/view.jsx
index f0f601931..1d949910d 100644
--- a/ui/component/publishFormErrors/view.jsx
+++ b/ui/component/publishFormErrors/view.jsx
@@ -2,35 +2,20 @@
import React from 'react';
import { THUMBNAIL_STATUSES, isNameValid } from 'lbry-redux';
import { INVALID_NAME_ERROR } from 'constants/claim';
-import * as PUBLISH_MODES from 'constants/publish_types';
type Props = {
- mode: ?string,
title: ?string,
name: ?string,
bid: ?string,
bidError: ?string,
editingURI: ?string,
filePath: ?string,
- fileText: ?string,
isStillEditing: boolean,
uploadThumbnailStatus: string,
};
function PublishFormErrors(props: Props) {
- const {
- name,
- mode,
- title,
- bid,
- bidError,
- editingURI,
- filePath,
- fileText,
- isStillEditing,
- uploadThumbnailStatus,
- } = props;
- const emptyStoryError = mode === PUBLISH_MODES.STORY && (!fileText || fileText.trim() === '');
+ const { name, title, bid, bidError, editingURI, filePath, isStillEditing, uploadThumbnailStatus } = props;
// These are extra help
// If there is an error it will be presented as an inline error as well
return (
@@ -40,7 +25,6 @@ function PublishFormErrors(props: Props) {
{!isNameValid(name, false) && INVALID_NAME_ERROR}
{!bid && {__('A deposit amount is required')}
}
{bidError && {__('Please check your deposit amount.')}
}
- {emptyStoryError && {__("Can't publish an empty story")}
}
{uploadThumbnailStatus === THUMBNAIL_STATUSES.IN_PROGRESS && (
{__('Please wait for thumbnail to finish uploading')}
)}
diff --git a/ui/component/storyEditor/index.js b/ui/component/storyEditor/index.js
index 2d72f50e0..a09a8c695 100644
--- a/ui/component/storyEditor/index.js
+++ b/ui/component/storyEditor/index.js
@@ -1,18 +1,10 @@
import { connect } from 'react-redux';
-import {
- selectIsStillEditing,
- makeSelectPublishFormValue,
- doUpdatePublishForm,
- makeSelectFileInfoForUri,
- makeSelectStreamingUrlForUri,
-} from 'lbry-redux';
+import { selectIsStillEditing, makeSelectPublishFormValue, doUpdatePublishForm } from 'lbry-redux';
import StoryEditor from './view';
const select = (state, props) => ({
- fileInfo: makeSelectFileInfoForUri(props.uri)(state),
filePath: makeSelectPublishFormValue('filePath')(state),
fileText: makeSelectPublishFormValue('fileText')(state),
- streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state),
isStillEditing: selectIsStillEditing(state),
});
diff --git a/ui/component/storyEditor/view.jsx b/ui/component/storyEditor/view.jsx
index 9437a3e60..0001e4e79 100644
--- a/ui/component/storyEditor/view.jsx
+++ b/ui/component/storyEditor/view.jsx
@@ -4,15 +4,15 @@ import { SIMPLE_SITE } from 'config';
import { FF_MAX_CHARS_IN_DESCRIPTION } from 'constants/form-field';
import { FormField } from 'component/common/form';
import usePersistedState from 'effects/use-persisted-state';
+import useFetchStreamingUrl from 'effects/use-fetch-streaming-url';
type Props = {
uri: ?string,
label: ?string,
disabled: ?boolean,
- fileInfo: FileListItem,
filePath: string | WebFile,
fileText: ?string,
- streamingUrl: ?string,
+ fileMimeType: ?string,
isStillEditing: boolean,
setPrevFileText: string => void,
updatePublishForm: ({}) => void,
@@ -24,32 +24,43 @@ function StoryEditor(props: Props) {
uri,
label,
disabled,
- fileInfo,
filePath,
fileText,
- streamingUrl,
+ fileMimeType,
isStillEditing,
setPrevFileText,
updatePublishForm,
setCurrentFileType,
} = props;
- const [isLoadign, setIsLoadign] = React.useState(false);
+ const editing = isStillEditing && uri;
+
+ const [ready, setReady] = React.useState(!editing);
+ const [loading, setLoading] = React.useState(false);
const [advancedEditor, setAdvancedEditor] = usePersistedState('publish-form-story-mode', false);
+ const { streamingUrl } = useFetchStreamingUrl(uri);
function toggleMarkdown() {
setAdvancedEditor(!advancedEditor);
}
+ // Ready to edit content
useEffect(() => {
- if (fileText && isLoadign) {
- setIsLoadign(false);
+ if (!ready && !loading && fileText && streamingUrl) {
+ setReady(true);
}
- }, [fileText, isLoadign, setIsLoadign]);
+ }, [ready, loading, fileText, streamingUrl]);
+
+ useEffect(() => {
+ if (fileText && loading) {
+ setLoading(false);
+ } else if (!fileText && loading) {
+ setLoading(true);
+ }
+ }, [fileText, loading, setLoading]);
useEffect(() => {
function readFileStream(url) {
- setIsLoadign(true);
return fetch(url).then(res => res.text());
}
@@ -67,24 +78,21 @@ function StoryEditor(props: Props) {
}
}
- const isEditingFile = isStillEditing && uri && fileInfo;
-
- if (isEditingFile) {
- const { mime_type: mimeType } = fileInfo;
+ if (editing) {
// Editing same file (previously published)
// User can use a different file to replace the content
- if (!filePath && !fileText && streamingUrl && mimeType === 'text/markdown') {
- setCurrentFileType(mimeType);
+ if (!ready && !filePath && !fileText && streamingUrl && fileMimeType === 'text/markdown') {
+ setCurrentFileType(fileMimeType);
updateEditorText(streamingUrl);
}
}
}, [
- uri,
+ ready,
+ editing,
fileText,
filePath,
- fileInfo,
+ fileMimeType,
streamingUrl,
- isStillEditing,
setPrevFileText,
updatePublishForm,
setCurrentFileType,
@@ -95,9 +103,9 @@ function StoryEditor(props: Props) {
type={!SIMPLE_SITE && advancedEditor ? 'markdown' : 'textarea'}
name="content_story"
label={label}
- placeholder={isLoadign ? __('Loadign...') : __('My content for this story...')}
- value={fileText}
- disabled={isLoadign || disabled}
+ placeholder={__('My content for this story...')}
+ value={ready ? fileText : __('Loading...')}
+ disabled={!ready || disabled}
onChange={value => updatePublishForm({ fileText: advancedEditor ? value : value.target.value })}
quickActionLabel={!SIMPLE_SITE && (advancedEditor ? __('Simple Editor') : __('Advanced Editor'))}
quickActionHandler={toggleMarkdown}
diff --git a/ui/effects/use-fetch-streaming-url.js b/ui/effects/use-fetch-streaming-url.js
new file mode 100644
index 000000000..374b8784d
--- /dev/null
+++ b/ui/effects/use-fetch-streaming-url.js
@@ -0,0 +1,38 @@
+import React from 'react';
+import { Lbry } from 'lbry-redux';
+import useIsMounted from 'effects/use-is-mounted';
+
+// Fetch streaming url
+export default function useFetchStreamingUrl(uri) {
+ const isMounted = useIsMounted();
+
+ const [state, setState] = React.useState({
+ error: false,
+ fetching: false,
+ streamingUrl: null,
+ });
+
+ React.useEffect(() => {
+ async function fetchClaim(claimUri) {
+ try {
+ setState({ fetching: true });
+ const data = await Lbry.get({ uri: claimUri });
+
+ if (data && isMounted.current) {
+ const { streaming_url: streamingUrl } = data;
+ setState({ fetching: false, streamingUrl });
+ }
+ } catch (error) {
+ if (isMounted.current) {
+ setState({ error, fetching: false });
+ }
+ }
+ }
+
+ if (uri && !state.error && !state.fetching && !state.streamingUrl) {
+ fetchClaim(uri);
+ }
+ }, [uri, state]);
+
+ return state;
+}