2021-07-08 09:34:21 +05:00
|
|
|
import KeepAwake from '@sayem314/react-native-keep-awake';
|
2022-06-30 09:45:28 +05:00
|
|
|
import React, { useEffect, useRef, useState } from 'react';
|
|
|
|
|
import { Modal, SafeAreaView, Text, View } from 'react-native';
|
2021-10-06 10:29:07 +05:00
|
|
|
import Animated from 'react-native-reanimated';
|
2022-01-22 12:57:05 +05:00
|
|
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
2022-06-30 09:45:28 +05:00
|
|
|
import Editor from '../../screens/editor';
|
2022-05-20 14:49:38 +05:00
|
|
|
import { editorController } from '../../screens/editor/tiptap/utils';
|
2022-02-28 23:25:18 +05:00
|
|
|
import { DDS } from '../../services/device-detection';
|
2022-06-30 09:45:28 +05:00
|
|
|
import { eSendEvent, eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
|
2022-02-28 23:25:18 +05:00
|
|
|
import Navigation from '../../services/navigation';
|
|
|
|
|
import Sync from '../../services/sync';
|
2022-05-20 14:49:38 +05:00
|
|
|
import { useThemeStore } from '../../stores/use-theme-store';
|
2022-01-22 12:57:05 +05:00
|
|
|
import { dHeight } from '../../utils';
|
|
|
|
|
import { db } from '../../utils/database';
|
2022-06-30 09:45:28 +05:00
|
|
|
import { eOnLoadNote, eShowMergeDialog } from '../../utils/events';
|
|
|
|
|
import { SIZE } from '../../utils/size';
|
2022-02-28 13:48:59 +05:00
|
|
|
import { timeConverter } from '../../utils/time';
|
|
|
|
|
import BaseDialog from '../dialog/base-dialog';
|
|
|
|
|
import DialogButtons from '../dialog/dialog-buttons';
|
|
|
|
|
import DialogContainer from '../dialog/dialog-container';
|
|
|
|
|
import DialogHeader from '../dialog/dialog-header';
|
2022-05-20 14:49:38 +05:00
|
|
|
import { Button } from '../ui/button';
|
|
|
|
|
import { IconButton } from '../ui/icon-button';
|
2022-02-28 13:48:59 +05:00
|
|
|
import Seperator from '../ui/seperator';
|
|
|
|
|
import Paragraph from '../ui/typography/paragraph';
|
2022-05-20 14:49:38 +05:00
|
|
|
|
2022-02-28 15:32:55 +05:00
|
|
|
const MergeConflicts = () => {
|
2022-02-28 23:25:18 +05:00
|
|
|
const colors = useThemeStore(state => state.colors);
|
2020-03-26 15:42:37 +05:00
|
|
|
const [visible, setVisible] = useState(false);
|
2022-06-30 09:45:28 +05:00
|
|
|
const [keep, setKeep] = useState(null);
|
|
|
|
|
const [copy, setCopy] = useState(null);
|
2020-11-29 13:23:46 +05:00
|
|
|
const [dialogVisible, setDialogVisible] = useState(false);
|
2020-11-29 12:21:36 +05:00
|
|
|
const insets = useSafeAreaInsets();
|
2022-06-30 09:45:28 +05:00
|
|
|
const content = useRef({});
|
|
|
|
|
const isKeepingConflicted = !keep?.conflicted;
|
|
|
|
|
const isKeeping = !!keep;
|
2020-03-26 13:39:04 +05:00
|
|
|
|
2020-03-26 15:42:37 +05:00
|
|
|
const applyChanges = async () => {
|
2022-06-30 09:45:28 +05:00
|
|
|
let _content = keep;
|
|
|
|
|
let note = db.notes.note(_content.noteId).data;
|
2021-10-06 10:29:07 +05:00
|
|
|
await db.notes.add({
|
|
|
|
|
id: note.id,
|
2021-12-31 11:05:42 +05:00
|
|
|
conflicted: false,
|
2022-06-30 09:45:28 +05:00
|
|
|
dateEdited: _content.dateEdited
|
2021-12-31 11:05:42 +05:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await db.content.add({
|
|
|
|
|
id: note.contentId,
|
2022-06-30 09:45:28 +05:00
|
|
|
data: _content.data,
|
|
|
|
|
type: _content.type,
|
|
|
|
|
dateResolved: content.current.conflicted.dateModified,
|
2021-12-31 11:05:42 +05:00
|
|
|
sessionId: Date.now(),
|
2021-10-06 10:29:07 +05:00
|
|
|
conflicted: false
|
|
|
|
|
});
|
2021-12-31 11:05:42 +05:00
|
|
|
|
2022-06-30 09:45:28 +05:00
|
|
|
if (copy) {
|
2020-03-26 15:42:37 +05:00
|
|
|
await db.notes.add({
|
2022-06-30 09:45:28 +05:00
|
|
|
title: note.title + ' (Copy)',
|
2020-03-26 15:42:37 +05:00
|
|
|
content: {
|
2022-06-30 09:45:28 +05:00
|
|
|
data: copy.data,
|
|
|
|
|
type: copy.type
|
|
|
|
|
}
|
2020-03-26 15:42:37 +05:00
|
|
|
});
|
|
|
|
|
}
|
2022-04-24 05:59:14 +05:00
|
|
|
Navigation.queueRoutesForUpdate(
|
|
|
|
|
'Notes',
|
|
|
|
|
'Favorites',
|
|
|
|
|
'ColoredNotes',
|
|
|
|
|
'TaggedNotes',
|
|
|
|
|
'TopicNotes'
|
|
|
|
|
);
|
2022-03-26 20:46:21 +05:00
|
|
|
if (editorController.current?.note?.id === note.id) {
|
2022-07-09 17:08:08 +05:00
|
|
|
// reload the note in editor
|
|
|
|
|
eSendEvent(eOnLoadNote, { ...editorController.current?.note, forced: true });
|
2021-07-03 12:47:19 +05:00
|
|
|
}
|
2020-03-26 15:42:37 +05:00
|
|
|
close();
|
2021-05-25 22:14:06 +05:00
|
|
|
await Sync.run();
|
2020-03-26 15:42:37 +05:00
|
|
|
};
|
|
|
|
|
|
2021-07-08 09:34:21 +05:00
|
|
|
const show = async item => {
|
2022-06-30 09:45:28 +05:00
|
|
|
let noteContent = await db.content.raw(item.contentId);
|
2022-07-07 19:09:47 +05:00
|
|
|
content.current = { ...noteContent };
|
|
|
|
|
if (!noteContent.conflicted) {
|
|
|
|
|
content.current.conflicted = { ...noteContent };
|
2021-07-08 09:34:21 +05:00
|
|
|
}
|
2020-04-11 11:11:42 +05:00
|
|
|
setVisible(true);
|
2020-03-26 13:39:04 +05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2020-03-26 15:42:37 +05:00
|
|
|
eSubscribeEvent(eShowMergeDialog, show);
|
2020-03-26 13:39:04 +05:00
|
|
|
return () => {
|
2020-03-26 15:42:37 +05:00
|
|
|
eUnSubscribeEvent(eShowMergeDialog, show);
|
2020-03-26 13:39:04 +05:00
|
|
|
};
|
2020-09-09 11:10:35 +05:00
|
|
|
}, []);
|
2020-03-26 13:39:04 +05:00
|
|
|
|
2020-03-26 15:42:37 +05:00
|
|
|
const close = () => {
|
|
|
|
|
setVisible(false);
|
2022-06-30 09:45:28 +05:00
|
|
|
setCopy(null);
|
|
|
|
|
setKeep(null);
|
2020-12-27 13:51:09 +05:00
|
|
|
setDialogVisible(false);
|
2021-10-06 10:29:07 +05:00
|
|
|
};
|
|
|
|
|
|
2022-06-30 09:45:28 +05:00
|
|
|
const ConfigBar = ({ isDiscarded, keeping, back, isCurrent, contentToKeep }) => {
|
|
|
|
|
return (
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
width: '100%',
|
|
|
|
|
height: 50,
|
|
|
|
|
flexDirection: 'row',
|
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
paddingHorizontal: 12,
|
|
|
|
|
paddingLeft: 6
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
flexDirection: 'row',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
|
flexShrink: 1
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{back && <IconButton onPress={close} color={colors.pri} name="arrow-left" />}
|
|
|
|
|
<Paragraph style={{ flexWrap: 'wrap' }} color={colors.icon} size={SIZE.xs}>
|
|
|
|
|
<Text style={{ color: isCurrent ? colors.accent : colors.red, fontWeight: 'bold' }}>
|
|
|
|
|
{isCurrent ? '(This Device)' : '(Incoming)'}
|
|
|
|
|
</Text>
|
|
|
|
|
{'\n'}
|
|
|
|
|
{timeConverter(contentToKeep.dateEdited)}
|
|
|
|
|
</Paragraph>
|
|
|
|
|
</View>
|
|
|
|
|
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
flexDirection: 'row',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
justifyContent: 'flex-end'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{isDiscarded ? (
|
|
|
|
|
<Button
|
|
|
|
|
onPress={() => {
|
|
|
|
|
setCopy(contentToKeep);
|
|
|
|
|
setDialogVisible(true);
|
|
|
|
|
}}
|
|
|
|
|
title="Save a copy"
|
|
|
|
|
type="grayBg"
|
|
|
|
|
height={30}
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 100,
|
|
|
|
|
paddingHorizontal: 12
|
|
|
|
|
}}
|
|
|
|
|
fontSize={SIZE.xs}
|
|
|
|
|
/>
|
|
|
|
|
) : null}
|
|
|
|
|
<View style={{ width: 10 }} />
|
|
|
|
|
{isDiscarded ? (
|
|
|
|
|
<Button
|
|
|
|
|
title="Discard"
|
|
|
|
|
type="accent"
|
|
|
|
|
accentColor="red"
|
|
|
|
|
height={30}
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 100,
|
|
|
|
|
paddingHorizontal: 12
|
|
|
|
|
}}
|
|
|
|
|
fontSize={SIZE.xs}
|
|
|
|
|
accentText="light"
|
|
|
|
|
color={colors.errorText}
|
|
|
|
|
onPress={() => {
|
|
|
|
|
setDialogVisible(true);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
) : null}
|
|
|
|
|
{isDiscarded ? null : (
|
|
|
|
|
<>
|
|
|
|
|
<Button
|
|
|
|
|
height={30}
|
|
|
|
|
style={{
|
|
|
|
|
borderRadius: 100,
|
|
|
|
|
paddingHorizontal: 12,
|
|
|
|
|
minWidth: 60,
|
|
|
|
|
marginLeft: 10
|
|
|
|
|
}}
|
|
|
|
|
type="accent"
|
|
|
|
|
fontSize={SIZE.xs}
|
|
|
|
|
title={keeping && !isDiscarded ? 'Undo' : 'Keep'}
|
|
|
|
|
onPress={() => {
|
|
|
|
|
setKeep(keeping && !isDiscarded ? null : contentToKeep);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
);
|
2020-03-26 15:42:37 +05:00
|
|
|
};
|
|
|
|
|
|
2020-11-23 12:32:33 +05:00
|
|
|
return !visible ? null : (
|
2020-11-29 12:21:36 +05:00
|
|
|
<Modal
|
|
|
|
|
statusBarTranslucent
|
|
|
|
|
transparent={false}
|
|
|
|
|
animationType="slide"
|
2021-07-08 09:34:21 +05:00
|
|
|
onRequestClose={() => {
|
|
|
|
|
close();
|
2021-04-19 10:58:32 +05:00
|
|
|
}}
|
2022-01-12 21:41:44 +05:00
|
|
|
supportedOrientations={[
|
|
|
|
|
'portrait',
|
|
|
|
|
'portrait-upside-down',
|
|
|
|
|
'landscape',
|
|
|
|
|
'landscape-left',
|
|
|
|
|
'landscape-right'
|
|
|
|
|
]}
|
2022-01-22 12:57:05 +05:00
|
|
|
visible={true}
|
|
|
|
|
>
|
2020-09-09 11:10:35 +05:00
|
|
|
<SafeAreaView
|
2020-03-26 13:39:04 +05:00
|
|
|
style={{
|
2021-01-20 10:54:06 +05:00
|
|
|
backgroundColor: colors.bg,
|
2021-10-06 10:29:07 +05:00
|
|
|
paddingTop: insets.top
|
2022-01-22 12:57:05 +05:00
|
|
|
}}
|
|
|
|
|
>
|
2021-01-03 12:40:59 +05:00
|
|
|
<KeepAwake />
|
2020-11-29 13:23:46 +05:00
|
|
|
{dialogVisible && (
|
|
|
|
|
<BaseDialog visible={true}>
|
|
|
|
|
<DialogContainer>
|
|
|
|
|
<DialogHeader
|
|
|
|
|
title="Apply Changes"
|
|
|
|
|
paragraph="Apply selected changes to note?"
|
2021-11-08 15:06:46 +05:00
|
|
|
padding={12}
|
2020-11-29 13:23:46 +05:00
|
|
|
/>
|
2021-12-31 11:05:42 +05:00
|
|
|
<Seperator />
|
2020-11-29 13:23:46 +05:00
|
|
|
<DialogButtons
|
|
|
|
|
positiveTitle="Apply"
|
|
|
|
|
negativeTitle="Cancel"
|
|
|
|
|
onPressNegative={() => setDialogVisible(false)}
|
|
|
|
|
onPressPositive={applyChanges}
|
|
|
|
|
/>
|
|
|
|
|
</DialogContainer>
|
|
|
|
|
</BaseDialog>
|
|
|
|
|
)}
|
|
|
|
|
|
2020-03-26 13:39:04 +05:00
|
|
|
<View
|
|
|
|
|
style={{
|
2020-09-09 11:10:35 +05:00
|
|
|
height: '100%',
|
2020-03-26 13:39:04 +05:00
|
|
|
width: '100%',
|
2021-10-06 10:29:07 +05:00
|
|
|
backgroundColor: DDS.isLargeTablet() ? 'rgba(0,0,0,0.3)' : null
|
2022-01-22 12:57:05 +05:00
|
|
|
}}
|
|
|
|
|
>
|
2022-06-30 09:45:28 +05:00
|
|
|
<ConfigBar
|
|
|
|
|
back={true}
|
|
|
|
|
isCurrent={true}
|
|
|
|
|
isDiscarded={isKeeping && isKeepingConflicted}
|
|
|
|
|
keeping={isKeeping}
|
|
|
|
|
contentToKeep={content.current}
|
|
|
|
|
/>
|
2020-03-26 13:39:04 +05:00
|
|
|
|
2020-09-09 11:10:35 +05:00
|
|
|
<Animated.View
|
2020-03-26 13:39:04 +05:00
|
|
|
style={{
|
2021-10-06 10:29:07 +05:00
|
|
|
height: dHeight / 2 - (50 + insets.top / 2),
|
2021-02-09 12:01:19 +05:00
|
|
|
backgroundColor: colors.bg,
|
2021-10-06 10:29:07 +05:00
|
|
|
borderBottomWidth: 1,
|
|
|
|
|
borderBottomColor: colors.nav
|
2022-01-22 12:57:05 +05:00
|
|
|
}}
|
|
|
|
|
>
|
2022-06-30 09:45:28 +05:00
|
|
|
<Editor
|
|
|
|
|
noHeader
|
|
|
|
|
noToolbar
|
|
|
|
|
readonly
|
|
|
|
|
editorId=":conflictPrimary"
|
|
|
|
|
onLoad={() => {
|
|
|
|
|
const note = db.notes.note(content.current?.noteId)?.data;
|
|
|
|
|
if (!note) return;
|
2022-07-08 18:30:20 +05:00
|
|
|
eSendEvent(eOnLoadNote + ':conflictPrimary', {
|
|
|
|
|
...note,
|
|
|
|
|
content: {
|
|
|
|
|
...content.current,
|
|
|
|
|
isPreview: true
|
|
|
|
|
}
|
|
|
|
|
});
|
2021-07-08 09:34:21 +05:00
|
|
|
}}
|
2020-09-09 11:10:35 +05:00
|
|
|
/>
|
|
|
|
|
</Animated.View>
|
2020-03-26 13:39:04 +05:00
|
|
|
|
2022-06-30 09:45:28 +05:00
|
|
|
<ConfigBar
|
|
|
|
|
back={false}
|
|
|
|
|
isCurrent={false}
|
|
|
|
|
isDiscarded={isKeeping && !isKeepingConflicted}
|
|
|
|
|
keeping={isKeeping}
|
|
|
|
|
contentToKeep={content.current.conflicted}
|
|
|
|
|
/>
|
2020-03-26 13:39:04 +05:00
|
|
|
|
2020-09-09 11:10:35 +05:00
|
|
|
<Animated.View
|
2020-03-26 13:39:04 +05:00
|
|
|
style={{
|
2021-10-06 10:29:07 +05:00
|
|
|
height: dHeight / 2 - (50 + insets.top / 2),
|
|
|
|
|
backgroundColor: colors.bg,
|
|
|
|
|
borderRadius: 10
|
2022-01-22 12:57:05 +05:00
|
|
|
}}
|
|
|
|
|
>
|
2022-06-30 09:45:28 +05:00
|
|
|
<Editor
|
|
|
|
|
noHeader
|
|
|
|
|
noToolbar
|
|
|
|
|
readonly
|
|
|
|
|
editorId=":conflictSecondary"
|
|
|
|
|
onLoad={() => {
|
|
|
|
|
const note = db.notes.note(content.current?.noteId)?.data;
|
|
|
|
|
if (!note) return;
|
|
|
|
|
eSendEvent(eOnLoadNote + ':conflictSecondary', {
|
|
|
|
|
...note,
|
2022-07-08 18:30:20 +05:00
|
|
|
content: { ...content.current.conflicted, isPreview: true }
|
2022-06-30 09:45:28 +05:00
|
|
|
});
|
2021-07-08 09:34:21 +05:00
|
|
|
}}
|
2020-09-09 11:10:35 +05:00
|
|
|
/>
|
|
|
|
|
</Animated.View>
|
|
|
|
|
</View>
|
|
|
|
|
</SafeAreaView>
|
2020-03-26 13:39:04 +05:00
|
|
|
</Modal>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-28 15:32:55 +05:00
|
|
|
export default MergeConflicts;
|