This commit is contained in:
noumantahir 2023-12-11 16:40:59 +05:00
parent bddd17902e
commit 468f41cc3f
11 changed files with 89 additions and 128 deletions

View File

@ -1,4 +1,4 @@
import { debounce, isArray, unionBy } from 'lodash';
import { debounce, isArray } from 'lodash';
import React, { useEffect, useState } from 'react';
import { useIntl } from 'react-intl';
import { FlatList, Text, View } from 'react-native';

View File

@ -42,7 +42,7 @@ export const MediaPreviewItem = ({
const _renderStatus = () =>
item.speakData && (
<View style={{...styles.statusContainer, right: isExpandedMode ? 8 : 0}}>
<View style={{ ...styles.statusContainer, right: isExpandedMode ? 8 : 0 }}>
<Text style={styles.statusText}>
{intl.formatMessage({ id: `uploads_modal.${item.speakData?.status}` })}
</Text>
@ -71,13 +71,11 @@ export const MediaPreviewItem = ({
const _renderLoading = () =>
(item.speakData?.status === ThreeSpeakStatus.PREPARING ||
item.speakData?.status === ThreeSpeakStatus.ENCODING) &&
(
item.speakData?.status === ThreeSpeakStatus.ENCODING) && (
<View style={styles.loadingContainer}>
<ActivityIndicator />
</View>
)
);
return (
<TouchableOpacity onPress={onPress} disabled={isDeleting}>

View File

@ -1,6 +1,6 @@
import React, { forwardRef, useImperativeHandle, useState } from 'react';
import { useRef } from 'react';
import { View, Text, TouchableOpacity, Image, Alert, _View } from 'react-native';
import { View, Text, TouchableOpacity, Image, Alert } from 'react-native';
import ActionSheet from 'react-native-actions-sheet';
import EStyleSheet from 'react-native-extended-stylesheet';
import { Video as VideoType } from 'react-native-image-crop-picker';
@ -9,24 +9,22 @@ import { createThumbnail } from 'react-native-create-thumbnail';
import { useQueryClient } from '@tanstack/react-query';
import ImagePicker, { Options } from 'react-native-image-crop-picker';
import { FlashList } from '@shopify/flash-list';
import * as Progress from 'react-native-progress';
import { useIntl } from 'react-intl';
import styles from '../styles/speakUploaderModal.styles';
import { MainButton } from '../../mainButton';
import { uploadFile, uploadVideoInfo } from '../../../providers/speak/speak';
import { useAppSelector } from '../../../hooks';
import QUERIES from '../../../providers/queries/queryKeys';
import Icon from '../../icon';
import * as Progress from 'react-native-progress';
import getWindowDimensions from '../../../utils/getWindowDimensions';
import { useIntl } from 'react-intl';
import { TextButton } from '../../buttons';
interface Props {
setIsUploading: (flag: boolean) => void;
isUploading: boolean;
}
export const SpeakUploaderModal = forwardRef(({ setIsUploading, isUploading }: Props, ref) => {
const intl = useIntl();
const sheetModalRef = useRef();
@ -58,6 +56,7 @@ export const SpeakUploaderModal = forwardRef(({ setIsUploading, isUploading }: P
const thumbs = [];
const _diff = _video.duration / 5;
for (let i = 0; i < 5; i++) {
// eslint-disable-next-line no-await-in-loop
const _thumb = await createThumbnail({
url: _video.sourceURL || _video.path,
timeStamp: i * _diff,
@ -119,10 +118,9 @@ export const SpeakUploaderModal = forwardRef(({ setIsUploading, isUploading }: P
setIsUploading(false);
};
const _onClosePress = () => {
sheetModalRef.current?.setModalVisible(false);
}
};
const _handleOpenImagePicker = () => {
const _options: Options = {
@ -139,12 +137,10 @@ export const SpeakUploaderModal = forwardRef(({ setIsUploading, isUploading }: P
setSelectedThumb(items[0]);
})
.catch((e) => {
Alert.alert('Fail', 'Thumb selection failed');
Alert.alert('Fail', `Thumb selection failed, ${e.message}`);
});
};
const _onClose = () => { };
const _renderThumbSelection = () => {
const _renderThumb = (uri, onPress) => (
<TouchableOpacity onPress={onPress} disabled={isUploading}>
@ -152,7 +148,7 @@ export const SpeakUploaderModal = forwardRef(({ setIsUploading, isUploading }: P
</TouchableOpacity>
);
const _renderThumbItem = ({ item, index }) => {
const _renderThumbItem = ({ item }) => {
const _onPress = () => {
setSelectedThumb(item);
};
@ -192,7 +188,6 @@ export const SpeakUploaderModal = forwardRef(({ setIsUploading, isUploading }: P
);
};
const _renderUploadProgress = () => {
return (
<Progress.Bar
@ -201,15 +196,16 @@ export const SpeakUploaderModal = forwardRef(({ setIsUploading, isUploading }: P
color={EStyleSheet.value('$primaryBlue')}
unfilledColor={EStyleSheet.value('$primaryLightBackground')}
width={getWindowDimensions().width - 40}
indeterminate={uploadProgress === 1 && isUploading} />
)
}
indeterminate={uploadProgress === 1 && isUploading}
/>
);
};
const _renderActionPanel = () => {
return (
<View style={styles.actionPanel}>
<TextButton
text={intl.formatMessage({id:'alert.close'})}
text={intl.formatMessage({ id: 'alert.close' })}
onPress={_onClosePress}
textStyle={styles.btnTxtClose}
style={styles.btnClose}
@ -218,14 +214,13 @@ export const SpeakUploaderModal = forwardRef(({ setIsUploading, isUploading }: P
style={{}}
onPress={_startUpload}
text={intl.formatMessage({
id: `uploads_modal.${isUploading ? 'uploading' : 'start_upload'}`
id: `uploads_modal.${isUploading ? 'uploading' : 'start_upload'}`,
})}
isDisable={isUploading}
/>
</View>
)
}
);
};
const _renderFormContent = () => {
return (
@ -247,7 +242,6 @@ export const SpeakUploaderModal = forwardRef(({ setIsUploading, isUploading }: P
{_renderThumbSelection()}
{_renderUploadProgress()}
{_renderActionPanel()}
</View>
);
};
@ -260,7 +254,6 @@ export const SpeakUploaderModal = forwardRef(({ setIsUploading, isUploading }: P
hideUnderlay
containerStyle={styles.sheetContent}
indicatorColor={EStyleSheet.value('$iconColor')}
onClose={_onClose}
>
{_renderFormContent()}
</ActionSheet>

View File

@ -26,7 +26,6 @@ import { Modes } from '../container/uploadsGalleryModal';
type Props = {
mode: Modes;
draftId?: string;
insertedMediaUrls: string[];
mediaUploads: MediaItem[];
isAddingToUploads: boolean;
@ -38,7 +37,6 @@ type Props = {
const UploadsGalleryContent = ({
mode,
draftId,
insertedMediaUrls,
mediaUploads,
isAddingToUploads,
@ -61,8 +59,10 @@ const UploadsGalleryContent = ({
const animatedHeightRef = useRef(new Animated.Value(COMPACT_HEIGHT));
const isDeleting = mode === Modes.MODE_IMAGE ?
deleteMediaMutation.isLoading : speakMutations.deleteVideoMutation.isLoading
const isDeleting =
mode === Modes.MODE_IMAGE
? deleteMediaMutation.isLoading
: speakMutations.deleteVideoMutation.isLoading;
useEffect(() => {
if (isExpandedMode) {
@ -71,13 +71,12 @@ const UploadsGalleryContent = ({
}, [isExpandedMode]);
const _deleteMedia = async () => {
const _options = {
onSettled: () => {
setIsDeleteMode(false);
setDeleteIds([]);
},
}
};
switch (mode) {
case Modes.MODE_VIDEO:
@ -85,16 +84,15 @@ const UploadsGalleryContent = ({
deleteIds.forEach((_id) => {
const mediaItem = mediaUploads.find((item) => item._id === _id);
if (mediaItem?.speakData) {
_permlinks.push(mediaItem.speakData.permlink)
_permlinks.push(mediaItem.speakData.permlink);
}
})
speakMutations.deleteVideoMutation.mutate(_permlinks, _options)
});
speakMutations.deleteVideoMutation.mutate(_permlinks, _options);
break;
default:
deleteMediaMutation.mutate(deleteIds, _options);
break;
}
};
const _onDeletePress = async () => {
@ -137,7 +135,6 @@ const UploadsGalleryContent = ({
const _onPress = () => {
if (isDeleteMode) {
const deleteId = item._id;
const idIndex = deleteIds.indexOf(deleteId);
@ -148,29 +145,28 @@ const UploadsGalleryContent = ({
}
setDeleteIds([...deleteIds]);
} else {
let insertError: Error | null = null;
if (item.speakData) {
switch (item.speakData.status) {
case ThreeSpeakStatus.READY:
//check if a ready video is already inserted
// check if a ready video is already inserted
insertedMediaUrls.forEach((url) => {
const _mediaItem = mediaUploads.find(
(item) => item.url === url && item.speakData?.status === ThreeSpeakStatus.READY,
);
if (_mediaItem) {
insertError = new Error("Can only have on unpublised speak speak per post");
insertError = new Error('Can only have on unpublised speak speak per post');
}
});
break;
case ThreeSpeakStatus.PREPARING:
case ThreeSpeakStatus.ENCODING:
//interupt video insertion is it's still under processing
insertError = new Error("Please wait while video is being processed")
// interupt video insertion is it's still under processing
insertError = new Error('Please wait while video is being processed');
break;
default:
console.log("Skipping corner check for published video")
console.log('Skipping corner check for published video');
break;
}
}
@ -178,9 +174,7 @@ const UploadsGalleryContent = ({
if (!insertError) {
insertMedia(new Map([[index, true]]));
} else {
dispatch(
toastNotification(insertError.message),
);
dispatch(toastNotification(insertError.message));
}
}
};
@ -215,7 +209,6 @@ const UploadsGalleryContent = ({
/>
</View>
<Icon
color={EStyleSheet.value('$primaryBlack')}
iconType="MaterialCommunityIcons"
@ -246,8 +239,8 @@ const UploadsGalleryContent = ({
{mode === Modes.MODE_IMAGE
? _renderSelectButtons
: isAddingToUploads
? _renderSelectButton('progress-upload', 'Uploading', handleOpenSpeakUploader)
: _renderSelectButtons}
? _renderSelectButton('progress-upload', 'Uploading', handleOpenSpeakUploader)
: _renderSelectButtons}
</View>
<View style={styles.pillBtnContainer}>
<IconButton
@ -275,7 +268,6 @@ const UploadsGalleryContent = ({
setDeleteIds([]);
}}
/>
</View>
{isAddingToUploads && (

View File

@ -242,12 +242,12 @@ export default EStyleSheet.create({
} as ViewStyle,
loadingContainer: {
position:'absolute',
top:0,
left:0,
right:0,
bottom:0,
justifyContent:'center',
alignItems:'center',
} as ViewStyle
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: 'center',
alignItems: 'center',
} as ViewStyle,
});

View File

@ -140,9 +140,6 @@ export const UploadsGalleryModal = forwardRef(
handleMediaInsert(pendingInserts.current);
pendingInserts.current = [];
}
}, [isEditing]);
useEffect(() => {

View File

@ -65,18 +65,18 @@ export default EStyleSheet.create({
marginTop: 10,
color: '$primaryDarkGray',
},
actionPanel:{
flexDirection:'row',
alignItems:'center',
actionPanel: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-end',
paddingHorizontal: 16,
} as ViewStyle,
btnTxtClose:{
color:'$iconColor',
fontSize:16,
btnTxtClose: {
color: '$iconColor',
fontSize: 16,
} as TextStyle,
btnClose:{
marginRight:12
btnClose: {
marginRight: 12,
} as ViewStyle,
uploadButton: {
marginBottom: 24,

View File

@ -45,9 +45,7 @@ const MainStack = createNativeStackNavigator();
const MainStackNavigator = () => {
// TODO: remove initialRoute before PR
return (
<MainStack.Navigator
screenOptions={{ headerShown: false, animation: 'slide_from_right' }}
>
<MainStack.Navigator screenOptions={{ headerShown: false, animation: 'slide_from_right' }}>
<MainStack.Screen name={ROUTES.DRAWER.MAIN} component={DrawerNavigator} />
<MainStack.Screen name={ROUTES.SCREENS.PROFILE} component={Profile} />
<MainStack.Screen name={ROUTES.SCREENS.PROFILE_EDIT} component={ProfileEdit} />

View File

@ -5,7 +5,12 @@ import { useDispatch } from 'react-redux';
import { useAppDispatch, useAppSelector } from '../../../hooks';
import { showActionModal, toastNotification } from '../../../redux/actions/uiAction';
import { MediaItem } from '../../ecency/ecency.types';
import { deleteVideo, getAllVideoStatuses, markAsPublished, updateSpeakVideoInfo } from '../../speak/speak';
import {
deleteVideo,
getAllVideoStatuses,
markAsPublished,
updateSpeakVideoInfo,
} from '../../speak/speak';
import QUERIES from '../queryKeys';
import { extract3SpeakIds } from '../../../utils/editor';
import { ThreeSpeakStatus, ThreeSpeakVideo } from '../../speak/speak.types';
@ -159,23 +164,11 @@ export const useSpeakMutations = () => {
},
};
//update info mutation
const _updateInfoMutationFn = async ({
id,
title,
body,
tags
}) => {
// update info mutation
const _updateInfoMutationFn = async ({ id, title, body, tags }) => {
try {
//TODO: update information
const response = await updateSpeakVideoInfo(
currentAccount,
pinCode,
body,
id,
title,
tags
)
// TODO: update information
const response = await updateSpeakVideoInfo(currentAccount, pinCode, body, id, title, tags);
console.log('Speak video marked as published', response);
return true;
@ -193,22 +186,18 @@ export const useSpeakMutations = () => {
onError: () => {
dispatch(toastNotification(intl.formatMessage({ id: 'alert.fail' })));
},
}
};
//delete mutation
// delete mutation
const _deleteMutationFn = async (permlinks: string[]) => {
try {
// eslint-disable-next-line no-restricted-syntax
for (const i in permlinks) {
// eslint-disable-next-line no-restricted-syntax
for (const i in permlinks) {
// eslint-disable-next-line no-await-in-loop
await deleteVideo(currentAccount, pinCode, permlinks[i]);
}
console.log('deleted speak videos', permlinks);
return true;
} catch (err) {
bugsnapInstance.notify(err);
}
@ -217,8 +206,7 @@ export const useSpeakMutations = () => {
const _deleteVideoOptions = {
retry: 3,
onSuccess: async (status, permlinks) => {
console.log('Success media deletion',status, permlinks);
console.log('Success media deletion', status, permlinks);
const data: MediaItem[] | undefined = queryClient.getQueryData([QUERIES.MEDIA.GET_VIDEOS]);
if (data) {
const _newData = data.filter((item) => !permlinks.includes(item.speakData?.permlink));
@ -228,22 +216,19 @@ export const useSpeakMutations = () => {
queryClient.invalidateQueries([QUERIES.MEDIA.GET_VIDEOS]);
},
onError: (err) => {
console.warn("delete failing", err);
console.warn('delete failing', err);
dispatch(toastNotification(intl.formatMessage({ id: 'alert.fail' })));
},
}
};
//init mutations
// init mutations
const markAsPublishedMutation = useMutation(_mutationFn, _options);
const updateInfoMutation = useMutation(_updateInfoMutationFn, _updateInfoOptions)
const deleteVideoMutation = useMutation(_deleteMutationFn, _deleteVideoOptions)
const updateInfoMutation = useMutation(_updateInfoMutationFn, _updateInfoOptions);
const deleteVideoMutation = useMutation(_deleteMutationFn, _deleteVideoOptions);
return {
markAsPublishedMutation,
updateInfoMutation,
deleteVideoMutation
deleteVideoMutation,
};
};

View File

@ -158,7 +158,7 @@ export const deleteVideo = async (currentAccount: any, pinHash: string, permlink
};
speakApi
.get(`${PATH_API}/video/${permlink}/delete`, {headers})
.get(`${PATH_API}/video/${permlink}/delete`, { headers })
.then((response) => {
console.log(response);
})
@ -167,8 +167,7 @@ export const deleteVideo = async (currentAccount: any, pinHash: string, permlink
});
};
export const uploadFile = (media: Video | Image, onProgress?:(progress:number)=>void) => {
export const uploadFile = (media: Video | Image, onProgress?: (progress: number) => void) => {
return new Promise((resolve, reject) => {
try {
const _path = Platform.select({
@ -194,8 +193,8 @@ export const uploadFile = (media: Video | Image, onProgress?:(progress:number)=>
},
onProgress: (uploaded, total) => {
if(onProgress){
onProgress((uploaded / total));
if (onProgress) {
onProgress(uploaded / total);
}
},
});

View File

@ -414,9 +414,7 @@ class EditorContainer extends Component<EditorContainerProps, any> {
const { draftId } = this.state;
const { beneficiariesMap } = this.props;
return (
beneficiariesMap[draftId || TEMP_BENEFICIARIES_ID] || []
);
return beneficiariesMap[draftId || TEMP_BENEFICIARIES_ID] || [];
};
_saveDraftToDB = async (fields, saveAsNew = false) => {
@ -650,12 +648,13 @@ class EditorContainer extends Component<EditorContainerProps, any> {
return;
}
if (scheduleDate && videoPublishMeta) {
dispatch(showActionModal({
title: intl.formatMessage({id:'alert.notice'}),
body: intl.formatMessage({id:'editor.schedule_video_unsupported'})
}))
dispatch(
showActionModal({
title: intl.formatMessage({ id: 'alert.notice' }),
body: intl.formatMessage({ id: 'editor.schedule_video_unsupported' }),
}),
);
return;
}
@ -755,11 +754,11 @@ class EditorContainer extends Component<EditorContainerProps, any> {
if (videoPublishMeta) {
console.log('marking inserted video as published');
speakMutations.updateInfoMutation.mutate({
id:videoPublishMeta._id,
title:fields.title,
body:fields.body,
tags:fields.tags
})
id: videoPublishMeta._id,
title: fields.title,
body: fields.body,
tags: fields.tags,
});
speakMutations.markAsPublishedMutation.mutate(videoPublishMeta._id);
}