Merge pull request #2102 from ecency/nt/editor-settings-modal

Nt/editor settings modal
This commit is contained in:
Feruz M 2021-12-15 20:11:07 +02:00 committed by GitHub
commit 2ab58fc861
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 832 additions and 59 deletions

View File

@ -772,4 +772,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 9c48318ea254e2c78005a7a0c2d8bfc14ddd783d PODFILE CHECKSUM: 9c48318ea254e2c78005a7a0c2d8bfc14ddd783d
COCOAPODS: 1.10.1 COCOAPODS: 1.10.2

View File

@ -34,11 +34,9 @@ const BasicHeaderView = ({
isHasIcons, isHasIcons,
isHasSearch, isHasSearch,
isLoading, isLoading,
isLoggedIn,
isModalHeader, isModalHeader,
isPreviewActive, isPreviewActive,
isReply, isReply,
isEdit,
quickTitle, quickTitle,
rightButtonText, rightButtonText,
rightIconName, rightIconName,
@ -49,6 +47,7 @@ const BasicHeaderView = ({
handleRewardChange, handleRewardChange,
handleBeneficiaries, handleBeneficiaries,
enableViewModeToggle, enableViewModeToggle,
handleSettingsPress,
showThumbSelectionModal, showThumbSelectionModal,
}) => { }) => {
const [isInputVisible, setIsInputVisible] = useState(false); const [isInputVisible, setIsInputVisible] = useState(false);
@ -173,13 +172,13 @@ const BasicHeaderView = ({
onPress={() => (isModalHeader ? handleOnPressClose() : handleOnPressBackButton())} onPress={() => (isModalHeader ? handleOnPressClose() : handleOnPressBackButton())}
disabled={disabled} disabled={disabled}
/> />
{isHasIcons && !isReply && !isEdit && ( {isHasIcons && !isReply && (
<IconButton <IconButton
style={{ marginHorizontal: 20 }} style={{ marginHorizontal: 20 }}
iconStyle={[styles.backIcon, isModalHeader && styles.closeIcon]} iconStyle={[styles.backIcon, isModalHeader && styles.closeIcon]}
iconType="MaterialIcons" iconType="MaterialIcons"
name="settings" name="settings"
onPress={() => settingMenuRef.current.show()} onPress={handleSettingsPress && handleSettingsPress}
disabled={disabled} disabled={disabled}
/> />
)} )}

View File

@ -1,7 +1,7 @@
import React, { PureComponent, Fragment } from 'react'; import React, { PureComponent, Fragment } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withNavigation } from 'react-navigation'; import { withNavigation } from 'react-navigation';
import { Share, Alert } from 'react-native'; import { Share } from 'react-native';
import ActionSheet from 'react-native-actionsheet'; import ActionSheet from 'react-native-actionsheet';
import { injectIntl } from 'react-intl'; import { injectIntl } from 'react-intl';
import get from 'lodash/get'; import get from 'lodash/get';

View File

@ -281,7 +281,8 @@
"publish": "Publish", "publish": "Publish",
"search": "Search", "search": "Search",
"update": "Update", "update": "Update",
"reply": "Reply" "reply": "Reply",
"schedule":"Schedule"
}, },
"editor": { "editor": {
"title": "Title", "title": "Title",
@ -303,6 +304,7 @@
"limited_lastchar": "Tag must end with letter or number", "limited_lastchar": "Tag must end with letter or number",
"setting_schedule": "Scheduling Time", "setting_schedule": "Scheduling Time",
"setting_reward": "Reward", "setting_reward": "Reward",
"setting_reblog": "Reblog",
"setting_beneficiary": "Beneficiary", "setting_beneficiary": "Beneficiary",
"setting_thumb": "Set Thumbnail", "setting_thumb": "Set Thumbnail",
"reward_default": "Default 50% / 50%", "reward_default": "Default 50% / 50%",
@ -328,7 +330,11 @@
"draft_save_success":"Draft Saved", "draft_save_success":"Draft Saved",
"draft_save_fail":"Failed to save draft", "draft_save_fail":"Failed to save draft",
"select_thumb":"Select Post Thumbnail", "select_thumb":"Select Post Thumbnail",
"two_thumbs_required":"Add more images in your post before setting thumbnail" "two_thumbs_required":"Add more images in your post before setting thumbnail",
"scheduled_for":"Scheduled For",
"scheduled_immediate":"Immediate",
"scheduled_later":"Later",
"settings_title":"Post Settings"
}, },
"snippets":{ "snippets":{
"label_no_snippets":"No Snippets Found", "label_no_snippets":"No Snippets Found",
@ -671,7 +677,8 @@
"percent": "Percent", "percent": "Percent",
"username": "Username", "username": "Username",
"addAccount": "Add Account", "addAccount": "Add Account",
"save": "Save" "save": "Save",
"cancel":"Cancel"
}, },
"welcome":{ "welcome":{
"label":"Welcome to", "label":"Welcome to",

View File

@ -0,0 +1,291 @@
import React, { useState, useEffect } from 'react';
import { View, FlatList, Text } from 'react-native';
import { useIntl } from 'react-intl';
import { isArray, debounce } from 'lodash';
import styles from './styles';
import EStyleSheet from 'react-native-extended-stylesheet';
import { useAppSelector } from '../../../hooks';
import { FormInput, IconButton, TextButton } from '../../../components';
import { Beneficiary } from '../../../redux/reducers/editorReducer';
import { lookupAccounts } from '../../../providers/hive/dhive';
interface BeneficiarySelectionContent {
draftId:string,
handleOnSaveBeneficiaries:()=>void
}
const BeneficiarySelectionContent = ({handleOnSaveBeneficiaries, draftId }) => {
const intl = useIntl();
const beneficiariesMap = useAppSelector(state => state.editor.beneficiariesMap)
const username = useAppSelector(state=>state.account.currentAccount.name)
const [beneficiaries, setBeneficiaries] = useState<Beneficiary[]>([
{ account: username, weight: 10000, isValid: true},
]);
const [newUsername, setNewUsername] = useState('');
const [newWeight, setNewWeight] = useState(0);
const [isUsernameValid, setIsUsernameValid] = useState(false);
const [isWeightValid, setIsWeightValid] = useState(false);
const [newEditable, setNewEditable] = useState(false);
useEffect(() => {
readTempBeneficiaries();
}, [draftId]);
const readTempBeneficiaries = async () => {
if(beneficiariesMap){
const tempBeneficiaries = beneficiariesMap[draftId || 'temp-beneficiaries'];
if (isArray(tempBeneficiaries) && tempBeneficiaries.length > 0) {
let othersWeight = 0;
tempBeneficiaries.forEach((item, index) => {
item.isValid = true;
if(index > 0){
othersWeight += item.weight
}
});
tempBeneficiaries[0].weight = 10000 - othersWeight;
setBeneficiaries(tempBeneficiaries);
}
}
};
const _onSavePress = () => {
if(newEditable){
beneficiaries.push({
account:newUsername,
weight:newWeight
})
}
handleOnSaveBeneficiaries(beneficiaries);
_resetInputs();
}
const _addAccount = () => {
if(isUsernameValid && isWeightValid){
beneficiaries.push({
account:newUsername,
weight:newWeight,
})
setBeneficiaries([...beneficiaries]);
}
setIsUsernameValid(false);
setIsWeightValid(false);
setNewWeight(0);
setNewUsername('');
setNewEditable(true);
};
const _onWeightInputChange = (value) => {
let _value = (parseInt(value, 10) || 0) * 100;
const _diff = _value - newWeight;
beneficiaries[0].weight = beneficiaries[0].weight - _diff;
setNewWeight(_value)
setIsWeightValid(_value > 0 && _value <= 10000)
setBeneficiaries([...beneficiaries]);
};
const _lookupAccounts = debounce((username) => {
lookupAccounts(username).then((res) => {
const isValid = res.includes(username)
//check if username duplicates else lookup contacts, done here to avoid debounce and post call mismatch
const notExistAlready = !beneficiaries.find((item)=>item.account === username);
setIsUsernameValid(isValid && notExistAlready)
});
}, 1000)
const _onUsernameInputChange = (value) => {
setNewUsername(value);
_lookupAccounts(value);
};
const _resetInputs = () => {
if(newWeight){
beneficiaries[0].weight = beneficiaries[0].weight + newWeight;
setBeneficiaries([...beneficiaries])
setNewWeight(0);
}
setNewEditable(false);
setIsWeightValid(false);
setIsUsernameValid(false);
setNewUsername('');
}
const _renderHeader = () => (
<View style={styles.inputWrapper}>
<View style={{...styles.weightInput, marginTop:4}}>
<Text style={styles.contentLabel}>
{intl.formatMessage({
id: 'beneficiary_modal.percent',
})}
</Text>
</View>
<View style={{...styles.usernameInput, marginTop:4, marginLeft:28}}>
<Text style={styles.contentLabel}>
{intl.formatMessage({
id: 'beneficiary_modal.username',
})}
</Text>
</View>
</View>
)
const _renderInput = () => {
return (
<View style={styles.inputWrapper}>
<View style={styles.weightInput}>
<FormInput
isValid={isWeightValid}
value={`${newWeight / 100}`}
inputStyle={styles.weightFormInput}
wrapperStyle={styles.weightFormInputWrapper}
onChange={(value) => _onWeightInputChange(value)}
onBlur={() => {}}//_onBlur(item)}
keyboardType='numeric'
/>
</View>
<View style={styles.usernameInput}>
<FormInput
rightIconName="at"
iconType="MaterialCommunityIcons"
isValid={isUsernameValid}
onChange={(value) => _onUsernameInputChange(value.trim())}
placeholder={intl.formatMessage({
id: 'beneficiary_modal.username',
})}
type="username"
isFirstImage
value={newUsername}
inputStyle={styles.usernameInput}
wrapperStyle={styles.usernameFormInputWrapper}
/>
</View>
{isWeightValid && isUsernameValid ? (
<IconButton
name="check"
iconType="MaterialCommunityIcons"
color={EStyleSheet.value('$primaryBlack')}
size={24}
iconStyle={{paddingLeft:8}}
onPress={_onSavePress}
/>
) : <View style={{width:28}}/>}
</View>
);
};
const _renderFooter = () => (
<>
{newEditable && _renderInput()}
<View style={{marginTop: 20, marginBottom:32}}>
<TextButton
text={newEditable?intl.formatMessage({
id: 'beneficiary_modal.cancel'
}):intl.formatMessage({
id: 'beneficiary_modal.addAccount',
})}
onPress={newEditable?_resetInputs:_addAccount}
textStyle={{
color:EStyleSheet.value('$primaryBlue'),
fontWeight:'bold'
}}
/>
</View>
</>
)
const _renderItem = ({ item, index }) => {
const _isCurrentUser = item.account === username;
const _onRemovePress = () => {
beneficiaries[0].weight = beneficiaries[0].weight + item.weight;
beneficiaries.splice(index, 1);
setBeneficiaries([...beneficiaries]);
handleOnSaveBeneficiaries(beneficiaries);
}
return (
<View style={styles.inputWrapper}>
<View style={styles.weightInput}>
<FormInput
isValid={true}
isEditable={false}
value={`${item.weight / 100}`}
inputStyle={styles.weightFormInput}
wrapperStyle={styles.weightFormInputWrapper}
/>
</View>
<View style={styles.usernameInput}>
<FormInput
isValid={true}
isEditable={false}
type="username"
isFirstImage
value={item.account}
inputStyle={styles.usernameInput}
wrapperStyle={styles.usernameFormInputWrapper}
/>
</View>
{!_isCurrentUser ? (
<IconButton
name="close"
iconType="MaterialCommunityIcons"
size={24}
color={EStyleSheet.value('$primaryBlack')}
iconStyle={{paddingLeft:8}}
onPress={_onRemovePress}
/>
):(
<View style={{width:30}} />
)}
</View>
);
};
return (
<View style={styles.container}>
<Text style={styles.settingLabel}>{intl.formatMessage({id:'editor.beneficiaries'})}</Text>
<FlatList
data={beneficiaries}
renderItem={_renderItem}
ListHeaderComponent={_renderHeader}
showsVerticalScrollIndicator={false}
/>
{_renderFooter()}
</View>
);
};
export default BeneficiarySelectionContent;

View File

@ -0,0 +1,209 @@
import React, { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
import { useIntl } from 'react-intl';
import { View } from 'react-native';
import { DateTimePicker, Modal, SettingsItem } from '../../../components';
import styles from './editorSettingsModalStyles';
import ThumbSelectionContent from './thumbSelectionContent';
import {View as AnimatedView} from 'react-native-animatable';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import BeneficiarySelectionContent from './beneficiarySelectionContent';
import { Beneficiary } from '../../../redux/reducers/editorReducer';
const REWARD_TYPES = [
{
key:'default',
intlId:'editor.reward_default'
},
{
key:'sp',
intlId:'editor.reward_power_up'
},
{
key:'dp',
intlId:'editor.reward_decline'
},
]
export interface EditorSettingsModalRef {
showModal:()=>void;
}
interface EditorSettingsModalProps {
body:string;
draftId:string;
isEdit:boolean;
isCommunityPost:boolean;
handleRewardChange:(rewardType:string)=>void;
handleThumbSelection:(index:number)=>void;
handleScheduleChange:(datetime:string|null)=>void;
handleBeneficiariesChange:(beneficiaries:Beneficiary[])=>void;
handleShouldReblogChange:(shouldReblog:boolean)=>void;
}
const EditorSettingsModal = forwardRef(({
body,
draftId,
isEdit,
isCommunityPost,
handleRewardChange,
handleThumbSelection,
handleScheduleChange,
handleBeneficiariesChange,
handleShouldReblogChange,
}: EditorSettingsModalProps, ref) => {
const intl = useIntl();
const [showModal, setShowModal] = useState(false);
const [rewardTypeIndex, setRewardTypeIndex] = useState(0);
const [thumbIndex, setThumbIndex] = useState(0);
const [scheduleLater, setScheduleLater] = useState(false)
const [shouldReblog, setShouldReblog] = useState(false);
const [scheduledFor, setScheduledFor] = useState('');
useEffect(() => {
if(handleThumbSelection){
handleThumbSelection(thumbIndex);
}
}, [thumbIndex])
useEffect(()=>{
if(!scheduleLater){
handleScheduleChange(null)
}else if(scheduledFor) {
handleScheduleChange(scheduledFor)
}
}, [scheduleLater, scheduledFor])
useEffect(() => {
handleShouldReblogChange(shouldReblog)
}, [shouldReblog])
useEffect(() => {
if(!isCommunityPost && shouldReblog){
setShouldReblog(false);
}
}, [isCommunityPost])
useImperativeHandle(ref, () => ({
show: () => {
setShowModal(true);
},
}));
const _handleRewardChange = (index:number) => {
setRewardTypeIndex(index)
const rewardTypeKey = REWARD_TYPES[index].key
if (handleRewardChange) {
handleRewardChange(rewardTypeKey);
}
}
const _handleDatePickerChange = (date:string) => {
setScheduledFor(date);
}
const _renderContent = (
<KeyboardAwareScrollView contentContainerStyle={{flex:1}} >
<View style={styles.container}>
{!isEdit && (
<>
<SettingsItem
title={intl.formatMessage({id:'editor.scheduled_for'}) }
type="dropdown"
actionType="reward"
options={[
intl.formatMessage({id:"editor.scheduled_immediate"}),
intl.formatMessage({id:"editor.scheduled_later"}),
]}
selectedOptionIndex={scheduleLater ? 1 : 0}
handleOnChange={(index)=>{
setScheduleLater(index === 1)
}}
/>
{scheduleLater && (
<AnimatedView animation="flipInX" duration={700}>
<DateTimePicker
type="datetime"
onChanged={_handleDatePickerChange}
disabled={true}
/>
</AnimatedView>
)}
<SettingsItem
title={intl.formatMessage({
id: 'editor.setting_reward',
})}
type="dropdown"
actionType="reward"
options={
REWARD_TYPES.map((type)=>intl.formatMessage({ id: type.intlId}))
}
selectedOptionIndex={rewardTypeIndex}
handleOnChange={_handleRewardChange}
/>
{isCommunityPost && (
<SettingsItem
title={intl.formatMessage({
id: 'editor.setting_reblog',
})}
type="toggle"
actionType="reblog"
isOn={shouldReblog}
handleOnChange={setShouldReblog}
/>
)}
</>
)}
<ThumbSelectionContent
body={body}
thumbIndex={thumbIndex}
onThumbSelection={setThumbIndex}
/>
{!isEdit && (
<BeneficiarySelectionContent
handleOnSaveBeneficiaries={handleBeneficiariesChange}
draftId={draftId}
/>
)}
</View>
</KeyboardAwareScrollView>
)
return (
<Modal
isOpen={showModal}
handleOnModalClose={() => setShowModal(false)}
isFullScreen
isCloseButton
presentationStyle="formSheet"
title={intl.formatMessage({id:"editor.settings_title"})}
animationType="slide"
style={styles.modalStyle}
>
{_renderContent}
</Modal>
);
});
export default EditorSettingsModal

View File

@ -0,0 +1,106 @@
import { TextStyle, StyleSheet, ViewStyle, Dimensions, ImageStyle } from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet';
const gridItemWidth = ((Dimensions.get('window').width/2) - 32);
const gridItemHeight = (gridItemWidth * 500)/600
export default EStyleSheet.create({
modalStyle: {
flex: 1,
backgroundColor: '$primaryBackgroundColor',
margin: 0,
paddingTop: 32,
paddingBottom: 16,
},
container: {
flex: 1,
paddingVertical: 8,
paddingHorizontal: 32,
},
bodyWrapper: {
flex: 3,
paddingHorizontal:16
},
floatingContainer:{
position:'absolute',
bottom:0,
right:20,
justifyContent:'flex-end',
zIndex:10
} as ViewStyle,
mediaItem:{
margin:8,
height:gridItemHeight,
width:gridItemWidth,
borderRadius:16,
backgroundColor:'$primaryLightGray'
} as ImageStyle,
inputContainer:{
flex:1
} as ViewStyle,
titleInput:{
color: '$primaryBlack',
fontWeight: 'bold',
fontSize: 18,
textAlignVertical: 'top',
paddingVertical: 0,
backgroundColor:'$primaryBackgroundColor',
borderBottomWidth:StyleSheet.hairlineWidth,
borderBottomColor:'$primaryDarkGray'
} as TextStyle,
dateTimeModa:{
backgroundColor: 'white',
alignItems: 'center',
} as ViewStyle,
title: {
fontWeight: '700',
flex:1,
fontSize:16,
color:'$primaryBlack'
} as TextStyle,
btnText:{
color:'$pureWhite'
} as TextStyle,
saveButton:{
backgroundColor:'$primaryBlue',
width:150,
paddingVertical:16,
borderRadius:32,
justifyContent:'center',
alignItems:'center'
} as ViewStyle,
closeButton:{
marginRight:16,
paddingVertical:8,
borderRadius:16,
justifyContent:'center',
alignItems:'center'
} as ViewStyle,
actionPanel:{
flexDirection:'row',
justifyContent:'flex-end',
alignItems:'center',
marginBottom:16
} as ViewStyle,
itemIcon:{
color:'$white',
} as ViewStyle,
itemIconWrapper:{
justifyContent:'center',
alignItems:'center',
backgroundColor:'$primaryRed',
} as ViewStyle,
removeItemContainer:{
position:'absolute',
top:16,
right:16
} as ViewStyle
})

View File

@ -0,0 +1,53 @@
import EStyleSheet from 'react-native-extended-stylesheet';
import { getBottomSpace } from 'react-native-iphone-x-helper';
export default EStyleSheet.create({
sheetContent: {
backgroundColor: '$primaryBackgroundColor',
position:'absolute',
bottom:0,
left:0,
right:0,
zIndex:999
},
thumbStyle:{
width:72,
height:72,
marginVertical:8,
marginRight:8,
borderRadius:12,
backgroundColor:'$primaryLightGray'
},
selectedStyle:{
borderWidth:4,
borderColor:'$primaryBlack'
},
settingLabel:{
color: '$primaryDarkGray',
fontSize: 14,
fontWeight: 'bold',
flexGrow: 1,
},
listContainer:{
paddingBottom:getBottomSpace() + 16,
},
container:{
paddingVertical:16
},
bodyWrapper: { flex: 1, paddingTop: 20, paddingBottom:20},
inputWrapper: { flexDirection: 'row', alignItems: 'center' },
contentLabel: { color: '$iconColor', marginTop:4 },
weightInput: {width:80},
weightFormInput: { textAlign: 'center', color: '$primaryBlack' },
weightFormInputWrapper: { marginTop: 8 },
usernameInput: { flex:1, color: '$primaryBlack', marginLeft: 16 },
usernameFormInputWrapper: { marginTop: 8 },
footerWrapper: { paddingTop:16 },
saveButton: {
width: 140,
height: 44,
alignSelf: 'flex-end',
justifyContent: 'center',
},
});

View File

@ -0,0 +1,76 @@
import React, { useEffect, useState } from 'react';
import { useIntl } from 'react-intl';
import { Alert, Text, View } from 'react-native';
import FastImage from 'react-native-fast-image';
import { FlatList, TouchableOpacity } from 'react-native-gesture-handler';
import { extractImageUrls } from '../../../utils/editor';
import styles from './styles';
interface ThumbSelectionContentProps {
body:string;
thumbIndex:number;
onThumbSelection:(index:number)=>void;
}
const ThumbSelectionContent = ({body, thumbIndex, onThumbSelection}: ThumbSelectionContentProps) => {
const intl = useIntl();
const [imageUrls, setImageUrls] = useState<string[]>([]);
const [needMore, setNeedMore] = useState(true);
useEffect(() => {
const urls = extractImageUrls({body});
if(urls.length < 2){
setNeedMore(true);
onThumbSelection(0);
setImageUrls([])
}else{
setNeedMore(false);
setImageUrls(urls)
}
}, [body])
//VIEW_RENDERERS
const _renderImageItem = ({item, index}:{item:string, index:number}) => {
const _onPress = () => {
onThumbSelection(index);
}
const selectedStyle = index === thumbIndex ? styles.selectedStyle : null
return (
<TouchableOpacity onPress={_onPress} >
<FastImage
source={{uri:item}}
style={{...styles.thumbStyle, ...selectedStyle}}
resizeMode='cover'
/>
</TouchableOpacity>
)
}
return (
<View style={{marginTop:12}}>
<Text style={styles.settingLabel}>{intl.formatMessage({id:'editor.select_thumb'})}</Text>
{
needMore ? (
<Text style={styles.contentLabel}>Add more images to post</Text>
):(
<FlatList
data={imageUrls}
renderItem={_renderImageItem}
keyExtractor={(item, index)=>`${item}-${index}`}
horizontal={true}
contentContainerStyle={styles.listContainer}
showsHorizontalScrollIndicator={false}/>
)
}
</View>
);
};
export default ThumbSelectionContent;

View File

@ -2,13 +2,14 @@ import React, { useImperativeHandle, useRef, useState } from 'react';
import { FlatList, TouchableOpacity } from 'react-native-gesture-handler'; import { FlatList, TouchableOpacity } from 'react-native-gesture-handler';
import ActionSheet from 'react-native-actions-sheet'; import ActionSheet from 'react-native-actions-sheet';
import EStyleSheet from 'react-native-extended-stylesheet'; import EStyleSheet from 'react-native-extended-stylesheet';
import styles from './thumbSelectionModalStyles'; import styles from './styles';
import { extractImageUrls } from '../../../utils/editor'; import { extractImageUrls } from '../../../utils/editor';
import FastImage from 'react-native-fast-image'; import FastImage from 'react-native-fast-image';
import { forwardRef } from 'react'; import { forwardRef } from 'react';
import { View, Text, Alert } from 'react-native'; import { View, Text, Alert } from 'react-native';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
export interface ThumbSelectionModalProps { export interface ThumbSelectionModalProps {
thumbIndex:number; thumbIndex:number;
onThumbSelection:(index:number)=>void; onThumbSelection:(index:number)=>void;
@ -57,7 +58,6 @@ const ThumbSelectionModal = ({ onThumbSelection, thumbIndex }:ThumbSelectionModa
} }
const selectedStyle = index === thumbIndex ? styles.selectedStyle : null const selectedStyle = index === thumbIndex ? styles.selectedStyle : null
return ( return (
<TouchableOpacity onPress={_onPress} > <TouchableOpacity onPress={_onPress} >

View File

@ -1,36 +0,0 @@
import EStyleSheet from 'react-native-extended-stylesheet';
import { getBottomSpace } from 'react-native-iphone-x-helper';
export default EStyleSheet.create({
sheetContent: {
backgroundColor: '$primaryBackgroundColor',
position:'absolute',
bottom:0,
left:0,
right:0,
zIndex:999
},
thumbStyle:{
width:100,
height:100,
margin:8,
borderRadius:12,
backgroundColor:'$primaryLightGray'
},
selectedStyle:{
borderWidth:4,
borderColor:'$primaryBlack'
},
title:{
color: '$primaryBlack',
fontWeight: 'bold',
fontSize: 18,
padding: 16,
textAlign:'center'
},
listContainer:{
paddingHorizontal:8,
paddingBottom:getBottomSpace() + 16,
}
});

View File

@ -22,6 +22,7 @@ import {
getPurePost, getPurePost,
grantPostingPermission, grantPostingPermission,
signImage, signImage,
reblog,
} from '../../../providers/hive/dhive'; } from '../../../providers/hive/dhive';
import { setDraftPost, getDraftPost } from '../../../realm/realm'; import { setDraftPost, getDraftPost } from '../../../realm/realm';
@ -74,6 +75,7 @@ class EditorContainer extends Component {
sharedSnippetText: null, sharedSnippetText: null,
onLoadDraftPress: false, onLoadDraftPress: false,
thumbIndex: 0, thumbIndex: 0,
shouldReblog:false
}; };
} }
@ -573,6 +575,7 @@ class EditorContainer extends Component {
}; };
_submitPost = async ({ fields, scheduleDate }: { fields: any, scheduleDate?: string }) => { _submitPost = async ({ fields, scheduleDate }: { fields: any, scheduleDate?: string }) => {
const { const {
currentAccount, currentAccount,
dispatch, dispatch,
@ -581,7 +584,9 @@ class EditorContainer extends Component {
pinCode, pinCode,
// isDefaultFooter, // isDefaultFooter,
} = this.props; } = this.props;
const { rewardType, beneficiaries, isPostSending, thumbIndex, draftId } = this.state; const { rewardType, beneficiaries, isPostSending, thumbIndex, draftId, shouldReblog} = this.state;
if (isPostSending) { if (isPostSending) {
return; return;
@ -644,7 +649,24 @@ class EditorContainer extends Component {
options, options,
voteWeight, voteWeight,
) )
.then(async () => { .then((response) => {
console.log(response);
//reblog if flag is active
if(shouldReblog){
reblog(
currentAccount,
pinCode,
author,
permlink
).then((resp)=>{
console.log("Successfully reblogged post", resp)
}).catch((err)=>{
console.warn("Failed to reblog post", err)
})
}
//post publish updates //post publish updates
setDraftPost( setDraftPost(
{ {
@ -736,7 +758,7 @@ class EditorContainer extends Component {
_submitEdit = async (fields) => { _submitEdit = async (fields) => {
const { currentAccount, pinCode } = this.props; const { currentAccount, pinCode } = this.props;
const { post, isEdit, isPostSending } = this.state; const { post, isEdit, isPostSending, thumbIndex } = this.state;
if (isPostSending) { if (isPostSending) {
return; return;
@ -762,7 +784,7 @@ class EditorContainer extends Component {
newBody = patch; newBody = patch;
} }
const meta = extractMetadata(fields.body); const meta = extractMetadata(fields.body, thumbIndex);
let jsonMeta = {}; let jsonMeta = {};
@ -858,6 +880,7 @@ class EditorContainer extends Component {
const { isReply, isEdit } = this.state; const { isReply, isEdit } = this.state;
const { intl } = this.props; const { intl } = this.props;
if (isReply && !isEdit) { if (isReply && !isEdit) {
this._submitReply(form.fields); this._submitReply(form.fields);
} else if (isEdit) { } else if (isEdit) {
@ -925,7 +948,8 @@ class EditorContainer extends Component {
} }
}; };
_handleDatePickerChange = async (datePickerValue, fields) => {
_handleSchedulePress = async (datePickerValue, fields) => {
const { currentAccount, pinCode, intl } = this.props; const { currentAccount, pinCode, intl } = this.props;
if (fields.title === '' || fields.body === '') { if (fields.title === '' || fields.body === '') {
@ -1059,6 +1083,13 @@ class EditorContainer extends Component {
dispatch(setBeneficiaries(draftId || 'temp-beneficiaries', value)); dispatch(setBeneficiaries(draftId || 'temp-beneficiaries', value));
}; };
_handleShouldReblogChange = (value:boolean) => {
this.setState({
shouldReblog:value
})
}
_handleSetThumbIndex = (index: number) => { _handleSetThumbIndex = (index: number) => {
this.setState({ this.setState({
thumbIndex: index thumbIndex: index
@ -1094,7 +1125,8 @@ class EditorContainer extends Component {
draftPost={draftPost} draftPost={draftPost}
handleRewardChange={this._handleRewardChange} handleRewardChange={this._handleRewardChange}
handleBeneficiaries={this._handleBeneficiaries} handleBeneficiaries={this._handleBeneficiaries}
handleDatePickerChange={this._handleDatePickerChange} handleShouldReblogChange={this._handleShouldReblogChange}
handleSchedulePress={this._handleSchedulePress}
handleFormChanged={this._handleFormChanged} handleFormChanged={this._handleFormChanged}
handleOnBackPress={() => { }} handleOnBackPress={() => { }}
handleOnImagePicker={this._handleRoutingAction} handleOnImagePicker={this._handleRoutingAction}

View File

@ -32,6 +32,7 @@ import { isCommunity } from '../../../utils/communityValidation';
import styles from './editorScreenStyles'; import styles from './editorScreenStyles';
import ThumbSelectionModal from '../children/thumbSelectionModal'; import ThumbSelectionModal from '../children/thumbSelectionModal';
import EditorSettingsModal from '../children/editorSettingsModal';
class EditorScreen extends Component { class EditorScreen extends Component {
/* Props /* Props
@ -39,6 +40,7 @@ class EditorScreen extends Component {
* @prop { type } name - Description.... * @prop { type } name - Description....
*/ */
thumbSelectionModalRef = null; thumbSelectionModalRef = null;
editorSettingsModalRef = null;
constructor(props) { constructor(props) {
super(props); super(props);
@ -57,6 +59,7 @@ class EditorScreen extends Component {
isCommunitiesListModalOpen: false, isCommunitiesListModalOpen: false,
selectedCommunity: null, selectedCommunity: null,
selectedAccount: null, selectedAccount: null,
scheduledFor:null
}; };
} }
@ -164,8 +167,13 @@ class EditorScreen extends Component {
}; };
_handleOnSubmit = () => { _handleOnSubmit = () => {
const { handleOnSubmit } = this.props; const { handleOnSubmit, handleSchedulePress } = this.props;
const { fields } = this.state; const { fields, scheduledFor } = this.state;
if(scheduledFor && handleSchedulePress){
handleSchedulePress(scheduledFor, fields);
return;
}
if (handleOnSubmit) { if (handleOnSubmit) {
handleOnSubmit({ fields }); handleOnSubmit({ fields });
@ -186,6 +194,18 @@ class EditorScreen extends Component {
} }
}; };
_handleScheduleChange = (datetime:string|null) => {
this.setState({
scheduledFor:datetime
})
}
_handleSettingsPress = () => {
if(this.editorSettingsModalRef){
this.editorSettingsModalRef.show();
}
}
_handleIsFormValid = (bodyText) => { _handleIsFormValid = (bodyText) => {
const { fields } = this.state; const { fields } = this.state;
const { isReply, isLoggedIn } = this.props; const { isReply, isLoggedIn } = this.props;
@ -313,10 +333,10 @@ class EditorScreen extends Component {
isPreviewActive, isPreviewActive,
wordsCount, wordsCount,
isFormValid, isFormValid,
isRemoveTag,
isCommunitiesListModalOpen, isCommunitiesListModalOpen,
selectedCommunity, selectedCommunity,
selectedAccount, selectedAccount,
scheduledFor,
} = this.state; } = this.state;
const { const {
handleOnImagePicker, handleOnImagePicker,
@ -332,19 +352,22 @@ class EditorScreen extends Component {
post, post,
uploadedImage, uploadedImage,
handleOnBackPress, handleOnBackPress,
handleDatePickerChange, handleSchedulePress,
handleRewardChange, handleRewardChange,
handleBeneficiaries, handleBeneficiaries,
handleShouldReblogChange,
currentAccount, currentAccount,
autoFocusText, autoFocusText,
sharedSnippetText, sharedSnippetText,
onLoadDraftPress, onLoadDraftPress,
thumbIndex, thumbIndex,
} = this.props; } = this.props;
const rightButtonText = intl.formatMessage({ const rightButtonText = intl.formatMessage({
id: isEdit ? 'basic_header.update' : isReply ? 'basic_header.reply' : 'basic_header.publish', id: isEdit ? 'basic_header.update' : isReply ? 'basic_header.reply' : scheduledFor ? 'basic_header.schedule' : 'basic_header.publish',
}); });
const _renderCommunityModal = () => { const _renderCommunityModal = () => {
return ( return (
<Modal <Modal
@ -367,7 +390,7 @@ class EditorScreen extends Component {
return ( return (
<View style={globalStyles.defaultContainer}> <View style={globalStyles.defaultContainer}>
<BasicHeader <BasicHeader
handleDatePickerChange={(date) => handleDatePickerChange(date, fields)} handleSchedulePress={(date) => handleSchedulePress(date, fields)}
handleRewardChange={handleRewardChange} handleRewardChange={handleRewardChange}
handleBeneficiaries={handleBeneficiaries} handleBeneficiaries={handleBeneficiaries}
handleOnBackPress={handleOnBackPress} handleOnBackPress={handleOnBackPress}
@ -387,6 +410,7 @@ class EditorScreen extends Component {
quickTitle={wordsCount > 0 && `${wordsCount} words`} quickTitle={wordsCount > 0 && `${wordsCount} words`}
rightButtonText={rightButtonText} rightButtonText={rightButtonText}
showThumbSelectionModal={this._showThumbSelectionModal} showThumbSelectionModal={this._showThumbSelectionModal}
handleSettingsPress={this._handleSettingsPress}
/> />
<PostForm <PostForm
handleFormUpdate={this._handleFormUpdate} handleFormUpdate={this._handleFormUpdate}
@ -436,6 +460,18 @@ class EditorScreen extends Component {
thumbIndex={thumbIndex} thumbIndex={thumbIndex}
onThumbSelection={this._handleOnThumbSelection} onThumbSelection={this._handleOnThumbSelection}
/> />
<EditorSettingsModal
ref={(componentRef) => (this.editorSettingsModalRef = componentRef)}
body={fields.body}
draftId={draftId}
isEdit={isEdit}
isCommunityPost={selectedCommunity !== null}
handleThumbSelection={this._handleOnThumbSelection}
handleRewardChange={handleRewardChange}
handleScheduleChange={this._handleScheduleChange}
handleBeneficiariesChange={handleBeneficiaries}
handleShouldReblogChange={handleShouldReblogChange}
/>
</View> </View>
); );
} }