mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-22 14:39:34 +01:00
add note merging ui flow
This commit is contained in:
15203
apps/mobile/android/app/src/main/assets/plaineditor.html
Normal file
15203
apps/mobile/android/app/src/main/assets/plaineditor.html
Normal file
File diff suppressed because one or more lines are too long
15204
apps/mobile/html/Web.bundle/site/plaineditor.html
Normal file
15204
apps/mobile/html/Web.bundle/site/plaineditor.html
Normal file
File diff suppressed because one or more lines are too long
@@ -8,6 +8,7 @@ import {
|
|||||||
eClearEditor,
|
eClearEditor,
|
||||||
eCloseFullscreenEditor,
|
eCloseFullscreenEditor,
|
||||||
eOnNewTopicAdded,
|
eOnNewTopicAdded,
|
||||||
|
eApplyChanges,
|
||||||
} from '../../services/events';
|
} from '../../services/events';
|
||||||
import NavigationService from '../../services/NavigationService';
|
import NavigationService from '../../services/NavigationService';
|
||||||
import {db, DDS, getElevation, history, ToastEvent} from '../../utils/utils';
|
import {db, DDS, getElevation, history, ToastEvent} from '../../utils/utils';
|
||||||
@@ -118,6 +119,11 @@ export class Dialog extends Component {
|
|||||||
this.hide();
|
this.hide();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case dialogActions.ACTION_APPLY_CHANGES: {
|
||||||
|
eSendEvent(eApplyChanges);
|
||||||
|
this.hide();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ export const dialogActions = {
|
|||||||
ACTION_EXIT_FULLSCREEN: 514,
|
ACTION_EXIT_FULLSCREEN: 514,
|
||||||
ACTION_TRASH: 515,
|
ACTION_TRASH: 515,
|
||||||
ACTION_PERMANANT_DELETE: 516,
|
ACTION_PERMANANT_DELETE: 516,
|
||||||
|
ACTION_APPLY_CHANGES: 517,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import {hexToRGBA, DDS} from '../../utils/utils';
|
|||||||
import {Platform} from 'react-native';
|
import {Platform} from 'react-native';
|
||||||
import {TEMPLATE_DELETE, TEMPLATE_PERMANANT_DELETE} from './templates';
|
import {TEMPLATE_DELETE, TEMPLATE_PERMANANT_DELETE} from './templates';
|
||||||
import {moveNoteEvent} from './recievers';
|
import {moveNoteEvent} from './recievers';
|
||||||
|
import MergeEditor from '../MergeEditor';
|
||||||
|
|
||||||
export class DialogManager extends Component {
|
export class DialogManager extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -343,6 +344,8 @@ export class DialogManager extends Component {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<LoginDialog colors={colors} ref={ref => (this.loginDialog = ref)} />
|
<LoginDialog colors={colors} ref={ref => (this.loginDialog = ref)} />
|
||||||
|
|
||||||
|
<MergeEditor />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,15 @@ export const TEMPLATE_TRASH = type => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const TEMPLATE_APPLY_CHANGES = {
|
||||||
|
title: `Apply Changes`,
|
||||||
|
paragraph: `Apply selected changes to note?`,
|
||||||
|
positiveText: 'Apply',
|
||||||
|
negativeText: 'Cancel',
|
||||||
|
action: dialogActions.ACTION_APPLY_CHANGES,
|
||||||
|
icon: 'check',
|
||||||
|
};
|
||||||
|
|
||||||
export const TEMPLATE_EXIT_FULLSCREEN = () => {
|
export const TEMPLATE_EXIT_FULLSCREEN = () => {
|
||||||
return {
|
return {
|
||||||
title: `Exit fullscreen editor?`,
|
title: `Exit fullscreen editor?`,
|
||||||
|
|||||||
592
apps/mobile/src/components/MergeEditor/index.js
Normal file
592
apps/mobile/src/components/MergeEditor/index.js
Normal file
@@ -0,0 +1,592 @@
|
|||||||
|
import React, {useState, createRef, useEffect} from 'react';
|
||||||
|
import {Modal, View, TouchableOpacity, Text} from 'react-native';
|
||||||
|
import WebView from 'react-native-webview';
|
||||||
|
import {h, getElevation} from '../../utils/utils';
|
||||||
|
import {useTracked} from '../../provider';
|
||||||
|
import {SIZE, WEIGHT, normalize} from '../../common/common';
|
||||||
|
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||||
|
import Animated, {Easing} from 'react-native-reanimated';
|
||||||
|
import {
|
||||||
|
eSubscribeEvent,
|
||||||
|
eUnSubscribeEvent,
|
||||||
|
eSendEvent,
|
||||||
|
} from '../../services/eventManager';
|
||||||
|
import {eApplyChanges, eOpenSimpleDialog} from '../../services/events';
|
||||||
|
import {TEMPLATE_APPLY_CHANGES} from '../DialogManager/templates';
|
||||||
|
import {simpleDialogEvent} from '../DialogManager/recievers';
|
||||||
|
|
||||||
|
const {Value, timing} = Animated;
|
||||||
|
const firstWebViewHeight = new Value(h * 0.5 - 50);
|
||||||
|
const secondWebViewHeight = new Value(h * 0.5 - 50);
|
||||||
|
|
||||||
|
const primaryWebView = createRef();
|
||||||
|
const secondaryWebView = createRef();
|
||||||
|
|
||||||
|
export function openEditorAnimation(
|
||||||
|
heightToAnimate,
|
||||||
|
extendedHeight = null,
|
||||||
|
siblingStatus,
|
||||||
|
) {
|
||||||
|
let openConfig = {
|
||||||
|
duration: 300,
|
||||||
|
toValue: !siblingStatus ? h - 100 : h * 0.5 - 50,
|
||||||
|
easing: Easing.inOut(Easing.ease),
|
||||||
|
};
|
||||||
|
|
||||||
|
let extendConfig = {
|
||||||
|
duration: 300,
|
||||||
|
toValue: h * 0.5 - 50,
|
||||||
|
easing: Easing.inOut(Easing.ease),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (extendedHeight) {
|
||||||
|
timing(extendedHeight, extendConfig).start();
|
||||||
|
}
|
||||||
|
timing(heightToAnimate, openConfig).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function closeEditorAnimation(heightToAnimate, heightToExtend = null) {
|
||||||
|
let closeConfig = {
|
||||||
|
duration: 300,
|
||||||
|
toValue: 0,
|
||||||
|
easing: Easing.inOut(Easing.ease),
|
||||||
|
};
|
||||||
|
|
||||||
|
let extendConfig = {
|
||||||
|
duration: 300,
|
||||||
|
toValue: h - 100,
|
||||||
|
easing: Easing.inOut(Easing.ease),
|
||||||
|
};
|
||||||
|
if (heightToExtend) {
|
||||||
|
timing(heightToExtend, extendConfig).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
timing(heightToAnimate, closeConfig).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
let primaryDelta = null;
|
||||||
|
let primaryText = 'Hello world, I am primary text conflict';
|
||||||
|
|
||||||
|
let secondaryDelta = null;
|
||||||
|
let secondaryText = 'Hello world, I am secondary text confilict';
|
||||||
|
|
||||||
|
const MergeEditor = () => {
|
||||||
|
const [state, dispatch] = useTracked();
|
||||||
|
const {colors} = state;
|
||||||
|
const [visible, setVisible] = useState(true);
|
||||||
|
const [primary, setPrimary] = useState(true);
|
||||||
|
const [secondary, setSecondary] = useState(true);
|
||||||
|
const [keepContentFrom, setKeepContentFrom] = useState(null);
|
||||||
|
const [copyToSave, setCopyToSave] = useState(null);
|
||||||
|
const [disardedContent, setDiscardedContent] = useState(null);
|
||||||
|
|
||||||
|
const postMessageToPrimaryWebView = message =>
|
||||||
|
primaryWebView.current?.postMessage(JSON.stringify(message));
|
||||||
|
|
||||||
|
const postMessageToSecondaryWebView = message =>
|
||||||
|
secondaryWebView.current?.postMessage(JSON.stringify(message));
|
||||||
|
|
||||||
|
const onPrimaryWebViewLoad = () => {
|
||||||
|
postMessageToPrimaryWebView({
|
||||||
|
type: 'text',
|
||||||
|
value: primaryText,
|
||||||
|
});
|
||||||
|
let c = {...colors};
|
||||||
|
c.factor = normalize(1);
|
||||||
|
postMessageToPrimaryWebView({
|
||||||
|
type: 'theme',
|
||||||
|
value: c,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSecondaryWebViewLoad = () => {
|
||||||
|
postMessageToSecondaryWebView({
|
||||||
|
type: 'text',
|
||||||
|
value: secondaryText,
|
||||||
|
});
|
||||||
|
let c = {...colors};
|
||||||
|
c.factor = normalize(1);
|
||||||
|
postMessageToSecondaryWebView({
|
||||||
|
type: 'theme',
|
||||||
|
value: c,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const _onShouldStartLoadWithRequest = request => {
|
||||||
|
if (request.url.includes('https')) {
|
||||||
|
Linking.openURL(request.url);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMessageFromPrimaryWebView = evt => {
|
||||||
|
if (evt.nativeEvent.data === 'loaded') {
|
||||||
|
} else if (
|
||||||
|
evt.nativeEvent.data !== '' &&
|
||||||
|
evt.nativeEvent.data !== 'loaded'
|
||||||
|
) {
|
||||||
|
let data = JSON.parse(evt.nativeEvent.data);
|
||||||
|
primaryDelta = data.delta;
|
||||||
|
primaryText = data.text;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMessageFromSecondaryWebView = evt => {
|
||||||
|
if (evt.nativeEvent.data === 'loaded') {
|
||||||
|
} else if (
|
||||||
|
evt.nativeEvent.data !== '' &&
|
||||||
|
evt.nativeEvent.data !== 'loaded'
|
||||||
|
) {
|
||||||
|
let data = JSON.parse(evt.nativeEvent.data);
|
||||||
|
secondaryDelta = data.delta;
|
||||||
|
secondaryText = data.text;
|
||||||
|
//Handle Here
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const applyChanges = () => {
|
||||||
|
alert('hello');
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
eSubscribeEvent(eApplyChanges, applyChanges);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
eUnSubscribeEvent(eApplyChanges, applyChanges);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const onPressKeepFromPrimaryWebView = () => {
|
||||||
|
if (keepContentFrom == 'primary') {
|
||||||
|
setKeepContentFrom(null);
|
||||||
|
openEditorAnimation(firstWebViewHeight, secondWebViewHeight);
|
||||||
|
} else {
|
||||||
|
setKeepContentFrom('primary');
|
||||||
|
closeEditorAnimation(firstWebViewHeight, secondWebViewHeight);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPressSaveCopyFromPrimaryWebView = () => {
|
||||||
|
setCopyToSave('primary');
|
||||||
|
simpleDialogEvent(TEMPLATE_APPLY_CHANGES);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPressKeepFromSecondaryWebView = () => {
|
||||||
|
if (keepContentFrom == 'secondary') {
|
||||||
|
setKeepContentFrom(null);
|
||||||
|
openEditorAnimation(secondWebViewHeight, firstWebViewHeight);
|
||||||
|
} else {
|
||||||
|
setKeepContentFrom('secondary');
|
||||||
|
closeEditorAnimation(secondWebViewHeight, firstWebViewHeight);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPressSaveCopyFromSecondaryWebView = () => {
|
||||||
|
setCopyToSave('secondary');
|
||||||
|
simpleDialogEvent(TEMPLATE_APPLY_CHANGES);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPressDiscardFromPrimaryWebView = () => {
|
||||||
|
setDiscardedContent('primary');
|
||||||
|
simpleDialogEvent(TEMPLATE_APPLY_CHANGES);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPressDiscardFromSecondaryWebView = () => {
|
||||||
|
setDiscardedContent('secondary');
|
||||||
|
simpleDialogEvent(TEMPLATE_APPLY_CHANGES);
|
||||||
|
};
|
||||||
|
|
||||||
|
const params = 'platform=' + Platform.OS;
|
||||||
|
const sourceUri =
|
||||||
|
(Platform.OS === 'android' ? 'file:///android_asset/' : '') +
|
||||||
|
'Web.bundle/loader.html';
|
||||||
|
const injectedJS = `if (!window.location.search) {
|
||||||
|
var link = document.getElementById('progress-bar');
|
||||||
|
link.href = './site2/plaineditor.html?${params}';
|
||||||
|
link.click();
|
||||||
|
}`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal transparent={true} animated animationType="fade" visible={visible}>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
height: '100%',
|
||||||
|
width: '100%',
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.3)',
|
||||||
|
}}>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
backgroundColor: '#f0f0f0',
|
||||||
|
width: '100%',
|
||||||
|
height: 50,
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
}}>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}>
|
||||||
|
<Icon
|
||||||
|
style={{
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
textAlign: 'center',
|
||||||
|
textAlignVertical: 'center',
|
||||||
|
marginLeft: -8,
|
||||||
|
}}
|
||||||
|
size={SIZE.xxl}
|
||||||
|
name="chevron-left"
|
||||||
|
/>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
if (keepContentFrom === 'primary') return;
|
||||||
|
if (!primary) {
|
||||||
|
openEditorAnimation(
|
||||||
|
firstWebViewHeight,
|
||||||
|
secondary && keepContentFrom !== 'secondary'
|
||||||
|
? secondWebViewHeight
|
||||||
|
: null,
|
||||||
|
secondary && keepContentFrom !== 'secondary',
|
||||||
|
);
|
||||||
|
setPrimary(true);
|
||||||
|
} else {
|
||||||
|
closeEditorAnimation(
|
||||||
|
firstWebViewHeight,
|
||||||
|
secondary && keepContentFrom !== 'secondary'
|
||||||
|
? secondWebViewHeight
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
setPrimary(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: colors.icon,
|
||||||
|
fontSize: SIZE.xxs,
|
||||||
|
}}>
|
||||||
|
Saved on 10/10/20 {'\n'}
|
||||||
|
12:30pm on Tablet
|
||||||
|
</Text>
|
||||||
|
<Icon
|
||||||
|
size={SIZE.lg}
|
||||||
|
name={primary ? 'chevron-up' : 'chevron-down'}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}>
|
||||||
|
{keepContentFrom === 'secondary' ? (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={onPressSaveCopyFromPrimaryWebView}
|
||||||
|
style={{
|
||||||
|
...getElevation(5),
|
||||||
|
height: 35,
|
||||||
|
backgroundColor: colors.accent,
|
||||||
|
borderRadius: 5,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
marginRight: 10,
|
||||||
|
}}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: 'white',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontFamily: WEIGHT.regular,
|
||||||
|
fontSize: SIZE.sm - 2,
|
||||||
|
}}>
|
||||||
|
Save as a copy
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{keepContentFrom === 'secondary' ? (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={onPressDiscardFromPrimaryWebView}
|
||||||
|
style={{
|
||||||
|
...getElevation(5),
|
||||||
|
height: 35,
|
||||||
|
backgroundColor: colors.errorText,
|
||||||
|
borderRadius: 5,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: 'white',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontFamily: WEIGHT.regular,
|
||||||
|
fontSize: SIZE.sm - 2,
|
||||||
|
}}>
|
||||||
|
Discard
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{keepContentFrom === 'secondary' ? null : (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={onPressKeepFromPrimaryWebView}
|
||||||
|
style={{
|
||||||
|
...getElevation(5),
|
||||||
|
height: 35,
|
||||||
|
backgroundColor:
|
||||||
|
keepContentFrom === 'primary'
|
||||||
|
? colors.errorText
|
||||||
|
: colors.accent,
|
||||||
|
borderRadius: 5,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: 'white',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontFamily: WEIGHT.regular,
|
||||||
|
fontSize: SIZE.sm - 2,
|
||||||
|
}}>
|
||||||
|
{keepContentFrom === 'primary' ? 'Undo' : 'Keep'}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Animated.View
|
||||||
|
style={{
|
||||||
|
height: firstWebViewHeight,
|
||||||
|
}}>
|
||||||
|
<WebView
|
||||||
|
onLoad={onPrimaryWebViewLoad}
|
||||||
|
ref={primaryWebView}
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
}}
|
||||||
|
injectedJavaScript={Platform.OS === 'ios' ? injectedJS : null}
|
||||||
|
onShouldStartLoadWithRequest={_onShouldStartLoadWithRequest}
|
||||||
|
cacheMode="LOAD_DEFAULT"
|
||||||
|
domStorageEnabled={true}
|
||||||
|
scrollEnabled={false}
|
||||||
|
bounces={false}
|
||||||
|
allowFileAccess={true}
|
||||||
|
scalesPageToFit={true}
|
||||||
|
allowingReadAccessToURL={Platform.OS === 'android' ? true : null}
|
||||||
|
allowFileAccessFromFileURLs={true}
|
||||||
|
allowUniversalAccessFromFileURLs={true}
|
||||||
|
originWhitelist={['*']}
|
||||||
|
javaScriptEnabled={true}
|
||||||
|
cacheEnabled={true}
|
||||||
|
onMessage={onMessageFromPrimaryWebView}
|
||||||
|
source={
|
||||||
|
Platform.OS === 'ios'
|
||||||
|
? {uri: sourceUri}
|
||||||
|
: {
|
||||||
|
uri: 'file:///android_asset/plaineditor.html',
|
||||||
|
baseUrl: 'file:///android_asset/',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Animated.View>
|
||||||
|
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
backgroundColor: '#f0f0f0',
|
||||||
|
width: '100%',
|
||||||
|
height: 50,
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
}}>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
if (keepContentFrom === 'secondary') return;
|
||||||
|
if (!secondary) {
|
||||||
|
openEditorAnimation(
|
||||||
|
secondWebViewHeight,
|
||||||
|
primary && keepContentFrom !== 'primary'
|
||||||
|
? firstWebViewHeight
|
||||||
|
: null,
|
||||||
|
primary && keepContentFrom !== 'primary',
|
||||||
|
);
|
||||||
|
setSecondary(true);
|
||||||
|
} else {
|
||||||
|
closeEditorAnimation(
|
||||||
|
secondWebViewHeight,
|
||||||
|
primary && keepContentFrom !== 'primary'
|
||||||
|
? firstWebViewHeight
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
setSecondary(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: colors.icon,
|
||||||
|
fontSize: SIZE.xxs,
|
||||||
|
}}>
|
||||||
|
Saved on 10/10/20 {'\n'}
|
||||||
|
12:30pm on Tablet
|
||||||
|
</Text>
|
||||||
|
<Icon
|
||||||
|
size={SIZE.lg}
|
||||||
|
name={secondary ? 'chevron-up' : 'chevron-down'}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}>
|
||||||
|
{keepContentFrom === 'primary' ? (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={onPressSaveCopyFromSecondaryWebView}
|
||||||
|
style={{
|
||||||
|
...getElevation(5),
|
||||||
|
height: 35,
|
||||||
|
backgroundColor: colors.accent,
|
||||||
|
borderRadius: 5,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
marginRight: 10,
|
||||||
|
}}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: 'white',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontFamily: WEIGHT.regular,
|
||||||
|
fontSize: SIZE.sm - 2,
|
||||||
|
}}>
|
||||||
|
Save as a copy
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{keepContentFrom === 'primary' ? (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={onPressDiscardFromSecondaryWebView}
|
||||||
|
style={{
|
||||||
|
...getElevation(5),
|
||||||
|
height: 35,
|
||||||
|
backgroundColor: colors.errorText,
|
||||||
|
borderRadius: 5,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: 'white',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontFamily: WEIGHT.regular,
|
||||||
|
fontSize: SIZE.sm - 2,
|
||||||
|
}}>
|
||||||
|
Discard
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{keepContentFrom === 'primary' ? null : (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={onPressKeepFromSecondaryWebView}
|
||||||
|
style={{
|
||||||
|
...getElevation(5),
|
||||||
|
height: 35,
|
||||||
|
backgroundColor:
|
||||||
|
keepContentFrom === 'secondary'
|
||||||
|
? colors.errorText
|
||||||
|
: colors.accent,
|
||||||
|
borderRadius: 5,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: 'white',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontFamily: WEIGHT.regular,
|
||||||
|
fontSize: SIZE.sm - 2,
|
||||||
|
}}>
|
||||||
|
{keepContentFrom === 'secondary' ? 'Undo' : 'Keep'}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Animated.View
|
||||||
|
style={{
|
||||||
|
height: secondWebViewHeight,
|
||||||
|
}}>
|
||||||
|
<WebView
|
||||||
|
onLoad={onSecondaryWebViewLoad}
|
||||||
|
ref={secondaryWebView}
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
}}
|
||||||
|
injectedJavaScript={Platform.OS === 'ios' ? injectedJS : null}
|
||||||
|
onShouldStartLoadWithRequest={_onShouldStartLoadWithRequest}
|
||||||
|
cacheMode="LOAD_DEFAULT"
|
||||||
|
domStorageEnabled={true}
|
||||||
|
scrollEnabled={false}
|
||||||
|
bounces={false}
|
||||||
|
allowFileAccess={true}
|
||||||
|
scalesPageToFit={true}
|
||||||
|
allowingReadAccessToURL={Platform.OS === 'android' ? true : null}
|
||||||
|
allowFileAccessFromFileURLs={true}
|
||||||
|
allowUniversalAccessFromFileURLs={true}
|
||||||
|
originWhitelist={['*']}
|
||||||
|
javaScriptEnabled={true}
|
||||||
|
cacheEnabled={true}
|
||||||
|
onMessage={onMessageFromSecondaryWebView}
|
||||||
|
source={
|
||||||
|
Platform.OS === 'ios'
|
||||||
|
? {uri: sourceUri}
|
||||||
|
: {
|
||||||
|
uri: 'file:///android_asset/plaineditor.html',
|
||||||
|
baseUrl: 'file:///android_asset/',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Animated.View>
|
||||||
|
</View>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MergeEditor;
|
||||||
@@ -67,3 +67,5 @@ export const refreshNotesPage = '532';
|
|||||||
export const eClearSearch = '533';
|
export const eClearSearch = '533';
|
||||||
|
|
||||||
export const eClearEditor = '534';
|
export const eClearEditor = '534';
|
||||||
|
|
||||||
|
export const eApplyChanges = '535';
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ const Editor = ({noMenu}) => {
|
|||||||
c.factor = normalize(1);
|
c.factor = normalize(1);
|
||||||
post({
|
post({
|
||||||
type: 'theme',
|
type: 'theme',
|
||||||
value: colors,
|
value: c,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -357,10 +357,6 @@ const Editor = ({noMenu}) => {
|
|||||||
id = note.id;
|
id = note.id;
|
||||||
setDateEdited(note.dateEdited);
|
setDateEdited(note.dateEdited);
|
||||||
content = {...note.content};
|
content = {...note.content};
|
||||||
if (!note.locked) {
|
|
||||||
content.delta = await db.notes.note(id).delta();
|
|
||||||
}
|
|
||||||
|
|
||||||
saveCounter = 0;
|
saveCounter = 0;
|
||||||
|
|
||||||
if (title !== null || title === '') {
|
if (title !== null || title === '') {
|
||||||
@@ -383,10 +379,10 @@ const Editor = ({noMenu}) => {
|
|||||||
post({
|
post({
|
||||||
type: 'clearEditor',
|
type: 'clearEditor',
|
||||||
});
|
});
|
||||||
} else if (content.delta) {
|
} else if (note.content.delta) {
|
||||||
let delta;
|
let delta;
|
||||||
if (typeof content.delta !== 'string') {
|
if (typeof note.content.delta !== 'string') {
|
||||||
delta = content.delta;
|
delta = note.content.delta;
|
||||||
} else {
|
} else {
|
||||||
delta = await db.notes.note(id).delta();
|
delta = await db.notes.note(id).delta();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user