diff --git a/apps/mobile/android/app/src/main/assets/plaineditor.html b/apps/mobile/android/app/src/main/assets/plaineditor.html
index c972282cc..91788463b 100644
--- a/apps/mobile/android/app/src/main/assets/plaineditor.html
+++ b/apps/mobile/android/app/src/main/assets/plaineditor.html
@@ -79,6 +79,7 @@
.htmldiff_div {
padding: 12px !important;
+ padding-top: 0px !important;
overflow-x: hidden;
overflow-y: scroll;
min-height: 150px;
diff --git a/apps/mobile/html/Web.bundle/site/plaineditor.html b/apps/mobile/html/Web.bundle/site/plaineditor.html
index c972282cc..91788463b 100644
--- a/apps/mobile/html/Web.bundle/site/plaineditor.html
+++ b/apps/mobile/html/Web.bundle/site/plaineditor.html
@@ -79,6 +79,7 @@
.htmldiff_div {
padding: 12px !important;
+ padding-top: 0px !important;
overflow-x: hidden;
overflow-y: scroll;
min-height: 150px;
diff --git a/apps/mobile/src/components/ActionSheetComponent/index.js b/apps/mobile/src/components/ActionSheetComponent/index.js
index e9cb1bcd8..c177bc5c2 100644
--- a/apps/mobile/src/components/ActionSheetComponent/index.js
+++ b/apps/mobile/src/components/ActionSheetComponent/index.js
@@ -1,5 +1,4 @@
import Clipboard from '@react-native-clipboard/clipboard';
-
import React, {useEffect, useState} from 'react';
import {
Dimensions,
@@ -29,6 +28,7 @@ import {
eSubscribeEvent,
eUnSubscribeEvent,
openVault,
+ presentSheet,
ToastEvent
} from '../../services/EventManager';
import Navigation from '../../services/Navigation';
@@ -58,6 +58,7 @@ import {SIZE} from '../../utils/SizeUtils';
import {sleep, timeConverter} from '../../utils/TimeUtils';
import {Button} from '../Button';
import {presentDialog} from '../Dialog/functions';
+import NoteHistory from '../NoteHistory';
import {PressableButton} from '../PressableButton';
import Heading from '../Typography/Heading';
import Paragraph from '../Typography/Paragraph';
@@ -657,6 +658,20 @@ export const ActionSheetComponent = ({
positiveType: 'errorShade'
});
}
+ },
+ {
+ name: 'History',
+ title: 'History',
+ icon: 'history',
+ func: async () => {
+ close();
+ await sleep(300);
+ presentSheet({
+ noProgress: true,
+ noIcon: true,
+ component: ref =>
+ });
+ }
}
];
diff --git a/apps/mobile/src/components/GeneralSheet/index.js b/apps/mobile/src/components/GeneralSheet/index.js
index c0b50aa17..2fbd755df 100644
--- a/apps/mobile/src/components/GeneralSheet/index.js
+++ b/apps/mobile/src/components/GeneralSheet/index.js
@@ -42,7 +42,10 @@ const GeneralSheet = ({context}) => {
actionSheetRef.current?.setModalVisible(true);
};
- const close = () => {
+ const close = ctx => {
+ if ((ctx && !context) || (ctx && ctx !== context)) {
+ return;
+ }
actionSheetRef.current?.setModalVisible(false);
};
diff --git a/apps/mobile/src/components/NoteHistory/index.js b/apps/mobile/src/components/NoteHistory/index.js
new file mode 100644
index 000000000..53ece2896
--- /dev/null
+++ b/apps/mobile/src/components/NoteHistory/index.js
@@ -0,0 +1,97 @@
+import React, {useCallback, useEffect, useState} from 'react';
+import {View} from 'react-native';
+import {FlatList} from 'react-native-gesture-handler';
+import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
+import {useTracked} from '../../provider';
+import {presentSheet} from '../../services/EventManager';
+import {db} from '../../utils/database';
+import {timeConverter} from '../../utils/TimeUtils';
+import DialogHeader from '../Dialog/dialog-header';
+import GeneralSheet from '../GeneralSheet';
+import {PressableButton} from '../PressableButton';
+import Seperator from '../Seperator';
+import Paragraph from '../Typography/Paragraph';
+import NotePreview from './preview';
+
+export default function NoteHistory({note, ref}) {
+ const [history, setHistory] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [state] = useTracked();
+ const {colors} = state;
+
+ useEffect(() => {
+ (async () => {
+ console.log(note.id);
+ console.log(await db.noteHistory.get(note.id));
+
+ setHistory([...(await db.noteHistory.get(note.id))].reverse());
+ setLoading(false);
+ })();
+ }, []);
+
+ async function preview(item) {
+ let content = await db.noteHistory.content(item.sessionContentId);
+
+ presentSheet({
+ component: ,
+ context: 'note_history',
+ noProgress: true,
+ noIcon: true
+ });
+ }
+
+ const renderItem = useCallback(
+ ({item, index}) => (
+ preview(item)}
+ customStyle={{
+ justifyContent: 'center',
+ alignItems: 'flex-start',
+ paddingHorizontal: 12,
+ height: 45,
+ marginBottom: 10
+ }}>
+ {timeConverter(item.dateEdited)}
+
+ ),
+ []
+ );
+
+ return (
+
+
+
+
+
+
+ {
+ ref?.current?.handleChildScrollEnd();
+ }}
+ style={{
+ paddingHorizontal: 12
+ }}
+ keyExtractor={item => item.id}
+ data={history}
+ ListEmptyComponent={
+
+
+ No note history found.
+
+ }
+ renderItem={renderItem}
+ />
+
+ );
+}
diff --git a/apps/mobile/src/components/NoteHistory/preview.js b/apps/mobile/src/components/NoteHistory/preview.js
new file mode 100644
index 000000000..e02a17f74
--- /dev/null
+++ b/apps/mobile/src/components/NoteHistory/preview.js
@@ -0,0 +1,119 @@
+import React, {useRef} from 'react';
+import {View} from 'react-native';
+import WebView from 'react-native-webview';
+import {useTracked} from '../../provider';
+import {eSendEvent, ToastEvent} from '../../services/EventManager';
+import Navigation from '../../services/Navigation';
+import {dHeight} from '../../utils';
+import {db} from '../../utils/database';
+import {eCloseProgressDialog} from '../../utils/Events';
+import {normalize} from '../../utils/SizeUtils';
+import {timeConverter} from '../../utils/TimeUtils';
+import {sourceUri} from '../../views/Editor/Functions';
+import {Button} from '../Button';
+import DialogHeader from '../Dialog/dialog-header';
+
+export default function NotePreview({session, content}) {
+ const [state] = useTracked();
+ const {colors} = state;
+ const webviewRef = useRef();
+
+ const onLoad = async () => {
+ console.log(content);
+ let preview = await db.content.insertPlaceholders(
+ content,
+ 'placeholder.svg'
+ );
+ console.log(preview, 'preview');
+ postMessage('htmldiff', preview?.data);
+ let theme = {...colors};
+ theme.factor = normalize(1);
+ postMessage('theme', JSON.stringify(theme));
+ };
+
+ function postMessage(type, value = null) {
+ let message = {
+ type: type,
+ value
+ };
+ webviewRef.current?.postMessage(JSON.stringify(message));
+ }
+
+ const _onShouldStartLoadWithRequest = request => {
+ if (request.url.includes('http')) {
+ openLinkInBrowser(request.url, colors)
+ .catch(e =>
+ ToastEvent.show({
+ title: 'Failed to open link',
+ message: e.message,
+ type: 'success',
+ context: 'local'
+ })
+ )
+ .then(r => {
+ console.log('closed');
+ });
+
+ return false;
+ } else {
+ return true;
+ }
+ };
+
+ async function restore() {
+ await db.noteHistory.restore(session.id);
+ eSendEvent(eCloseProgressDialog, 'note_history');
+ eSendEvent(eCloseProgressDialog);
+ Navigation.setRoutesToUpdate([
+ Navigation.routeNames.NotesPage,
+ Navigation.routeNames.Favorites,
+ Navigation.routeNames.Notes
+ ]);
+ ToastEvent.show({
+ heading: 'Note restored successfully',
+ type: 'success'
+ });
+ }
+
+ return (
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/apps/mobile/src/components/NoteItem/index.js b/apps/mobile/src/components/NoteItem/index.js
index 744f69291..fc5a3c78d 100644
--- a/apps/mobile/src/components/NoteItem/index.js
+++ b/apps/mobile/src/components/NoteItem/index.js
@@ -67,6 +67,7 @@ const showActionSheet = (item, isTrash) => {
'Vault',
'Delete',
'RemoveTopic',
+ "History",
...android
]
);
diff --git a/apps/mobile/src/components/SimpleList/sectionheader.js b/apps/mobile/src/components/SimpleList/sectionheader.js
index a2531d1d1..30701f64c 100644
--- a/apps/mobile/src/components/SimpleList/sectionheader.js
+++ b/apps/mobile/src/components/SimpleList/sectionheader.js
@@ -39,7 +39,6 @@ export const SectionHeader = ({item, index, type, color, screen}) => {
: groupBy.slice(0, 1).toUpperCase() + groupBy.slice(1, groupBy.length);
const onUpdate = () => {
- console.log(groupOptions);
setGroupOptions({...db.settings?.getGroupOptions(type)});
};
diff --git a/apps/mobile/src/provider/stores.ts b/apps/mobile/src/provider/stores.ts
index bab48517d..d4c0389a6 100644
--- a/apps/mobile/src/provider/stores.ts
+++ b/apps/mobile/src/provider/stores.ts
@@ -381,7 +381,6 @@ export const useMessageStore = create((set, get) => ({
set({announcements: []});
} finally {
let all = await getFiltered(announcements);
- console.log("all", all)
set({
announcements: all.filter(a => a.type === 'inline'),
dialogs: all.filter(a => a.type === 'dialog')
diff --git a/apps/mobile/src/services/Navigation.js b/apps/mobile/src/services/Navigation.js
index e1060f2ac..2fad18a11 100755
--- a/apps/mobile/src/services/Navigation.js
+++ b/apps/mobile/src/services/Navigation.js
@@ -64,14 +64,11 @@ function routeNeedsUpdate(routeName, callback) {
* @param {array} routes
*/
function setRoutesToUpdate(routes) {
- console.log(currentScreen, 'current');
if (routes.indexOf(currentScreen) > -1) {
- console.log('updating screen', currentScreen);
if (
currentScreen === routeNames.NotesPage ||
currentScreen === routeNames.Notebook
) {
- console.log(currentScreen, 'CURRENT');
eSendEvent(
currentScreen === routeNames.NotesPage
? refreshNotesPage
diff --git a/apps/mobile/src/views/Editor/Functions.js b/apps/mobile/src/views/Editor/Functions.js
index 6d786fad4..7e470395b 100644
--- a/apps/mobile/src/views/Editor/Functions.js
+++ b/apps/mobile/src/views/Editor/Functions.js
@@ -61,6 +61,7 @@ let waitForContent = false;
let prevNoteContent = null;
let timerForEditor = null;
let sessionId = null;
+let historySessionId = null;
export function startClosingSession() {
closingSession = true;
@@ -228,6 +229,7 @@ function clearNote() {
note = null;
title = '';
noteEdited = false;
+ historySessionId = null;
prevNoteContent = content.data;
isSaving = false;
id = null;
@@ -817,10 +819,36 @@ export async function saveNote(preventUpdate) {
);
tiny.call(EditorWebView, tiny.updateSavingState(!n ? '' : 'Saved'));
}
+
+ await updateSessionHistory(id, noteData.content);
} catch (e) {}
isSaving = false;
}
+async function updateSessionHistory(id, content) {
+ let note = db.notes.note(id)?.data;
+ if (!note) return;
+ if (!historySessionId) {
+ historySessionId = `${id}_${note.dateEdited}`;
+ }
+
+ if (!historySessionId.includes(id)) {
+ historySessionId = null;
+ return;
+ }
+ if (!note.locked) {
+ console.log('saving session with id: ',historySessionId);
+ await db.noteHistory.add(id, historySessionId, content);
+ } else {
+ let content = await db.content.get(note.contentId);
+
+ await db.noteHistory.add(id, historySessionId, {
+ data: content.data,
+ type: content.type
+ });
+ }
+}
+
export async function onWebViewLoad(premium, colors) {
setTimeout(() => {
if (premium) {
diff --git a/apps/mobile/src/views/Settings/backuprestore.js b/apps/mobile/src/views/Settings/backuprestore.js
index 945938f82..ddcadddcb 100644
--- a/apps/mobile/src/views/Settings/backuprestore.js
+++ b/apps/mobile/src/views/Settings/backuprestore.js
@@ -1,9 +1,9 @@
-import React, {useEffect, useState} from 'react';
-import {Platform, TouchableOpacity, View} from 'react-native';
+import React, { useEffect, useState } from 'react';
+import { Platform, TouchableOpacity, View } from 'react-native';
import ToggleSwitch from 'toggle-switch-react-native';
import Paragraph from '../../components/Typography/Paragraph';
-import {useTracked} from '../../provider';
-import {useSettingStore, useUserStore} from '../../provider/stores';
+import { useTracked } from '../../provider';
+import { useSettingStore, useUserStore } from '../../provider/stores';
import Backup from '../../services/Backup';
import {
eSendEvent,
@@ -17,14 +17,13 @@ import {
eOpenLoginDialog,
eOpenRestoreDialog
} from '../../utils/Events';
-import {openLinkInBrowser} from '../../utils/functions';
-import {MMKV} from '../../utils/mmkv';
-import {SIZE} from '../../utils/SizeUtils';
-import {sleep} from '../../utils/TimeUtils';
-import {CustomButton} from './button';
-import {verifyUser} from './functions';
+import { openLinkInBrowser } from '../../utils/functions';
+import { MMKV } from '../../utils/mmkv';
+import { SIZE } from '../../utils/SizeUtils';
+import { sleep } from '../../utils/TimeUtils';
+import { CustomButton } from './button';
+import { verifyUser } from './functions';
import SectionHeader from './section-header';
-import * as ScopedStorage from 'react-native-scoped-storage';
const SettingsBackupAndRestore = ({isSheet}) => {
const [state] = useTracked();