Merge pull request #36 from streetwriters/develop

version 1.3.1
This commit is contained in:
Ammar Ahmed
2021-02-27 13:24:06 +05:00
committed by GitHub
35 changed files with 654 additions and 500 deletions

View File

@@ -1,12 +1,10 @@
import React, {useEffect, useState} from 'react';
import {View} from 'react-native';
import React, {useEffect} from 'react';
import Orientation from 'react-native-orientation';
import Animated, {Easing} from 'react-native-reanimated';
import AnimatedProgress from 'react-native-reanimated-progress-bar';
import {SafeAreaProvider} from 'react-native-safe-area-context';
import SplashScreen from 'react-native-splash-screen';
import {AppRootEvents} from './AppRootEvents';
import {RootView} from './initializer.root';
import AppLoader from './src/components/AppLoader';
import {useTracked} from './src/provider';
import {Actions} from './src/provider/Actions';
import {DDS} from './src/services/DeviceDetection';
@@ -15,19 +13,11 @@ import {
eSubscribeEvent,
eUnSubscribeEvent,
} from './src/services/EventManager';
import Navigation from './src/services/Navigation';
import SettingsService from './src/services/SettingsService';
import {
changeAppScale,
changeContainerScale,
ContainerScale,
} from './src/utils/Animations';
import {db} from './src/utils/DB';
import {eDispatchAction, eOpenSideMenu} from './src/utils/Events';
import {sleep} from './src/utils/TimeUtils';
import EditorRoot from './src/views/Editor/EditorRoot';
let initStatus = false;
const App = () => {
const [, dispatch] = useTracked();
@@ -35,8 +25,6 @@ const App = () => {
useEffect(() => {
(async () => {
try {
scaleV.setValue(0.95);
opacityV.setValue(1);
Orientation.getOrientation((e, r) => {
DDS.checkSmallTab(r);
dispatch({
@@ -84,95 +72,9 @@ const App = () => {
<RootView />
<EditorRoot />
<AppRootEvents />
<Overlay onLoad={loadMainApp} />
<AppLoader onLoad={loadMainApp} />
</SafeAreaProvider>
);
};
export default App;
const scaleV = new Animated.Value(0.95);
const opacityV = new Animated.Value(1);
const Overlay = ({onLoad}) => {
const [state, dispatch] = useTracked();
const colors = state.colors;
const [loading, setLoading] = useState(true);
const [progress, setProgress] = useState(4);
const [opacity, setOpacity] = useState(true);
const load = async () => {
db.notes.init().then(() => {
init = true;
dispatch({type: Actions.NOTES});
dispatch({type: Actions.FAVORITES});
dispatch({type: Actions.LOADING, loading: false});
eSendEvent(eOpenSideMenu);
});
setOpacity(false);
await sleep(150);
eSendEvent(eOpenSideMenu);
Animated.timing(opacityV, {
toValue: 0,
duration: 150,
easing: Easing.out(Easing.ease),
}).start();
Animated.timing(scaleV, {
toValue: 1,
duration: 150,
easing: Easing.out(Easing.ease),
}).start();
changeContainerScale(ContainerScale, 1, 500);
await sleep(150);
setLoading(false);
animation = false;
};
useEffect(() => {
eSubscribeEvent('load_overlay', load);
onLoad();
return () => {
eUnSubscribeEvent('load_overlay', load);
};
}, []);
return (
loading && (
<Animated.View
style={{
backgroundColor: opacity ? colors.bg : 'rgba(0,0,0,0)',
width: '100%',
height: '100%',
position: 'absolute',
zIndex: 999,
borderRadius: 10,
}}>
<Animated.View
onTouchStart={() => {
setLoading(false);
}}
style={{
backgroundColor: colors.bg,
width: '100%',
height: '100%',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10,
opacity: opacityV,
}}>
<View
style={{
height: 10,
flexDirection: 'row',
width: 100,
}}>
<AnimatedProgress
fill={colors.accent}
current={progress}
total={4}
/>
</View>
</Animated.View>
</Animated.View>
)
);
};

File diff suppressed because one or more lines are too long

View File

@@ -22,55 +22,54 @@ let pageTheme = {
};
const markdownPatterns = [
{ start: "*", end: "*", format: "italic" },
{ start: "**", end: "**", format: "bold" },
{ start: "`", end: "`", format: "code" },
{ start: "#", format: "h1" },
{ start: "##", format: "h2" },
{ start: "###", format: "h3" },
{ start: "####", format: "h4" },
{ start: "#####", format: "h5" },
{ start: "######", format: "h6" },
{ start: "* ", cmd: "InsertUnorderedList" },
{ start: "- ", cmd: "InsertUnorderedList" },
{ start: "> ", format: "blockquote" },
{start: '*', end: '*', format: 'italic'},
{start: '**', end: '**', format: 'bold'},
{start: '`', end: '`', format: 'code'},
{start: '#', format: 'h1'},
{start: '##', format: 'h2'},
{start: '###', format: 'h3'},
{start: '####', format: 'h4'},
{start: '#####', format: 'h5'},
{start: '######', format: 'h6'},
{start: '* ', cmd: 'InsertUnorderedList'},
{start: '- ', cmd: 'InsertUnorderedList'},
{start: '> ', format: 'blockquote'},
{
start: "1. ",
cmd: "InsertOrderedList",
value: { "list-style-type": "decimal" },
start: '1. ',
cmd: 'InsertOrderedList',
value: {'list-style-type': 'decimal'},
},
{
start: "1) ",
cmd: "InsertOrderedList",
value: { "list-style-type": "decimal" },
start: '1) ',
cmd: 'InsertOrderedList',
value: {'list-style-type': 'decimal'},
},
{
start: "a. ",
cmd: "InsertOrderedList",
value: { "list-style-type": "lower-alpha" },
start: 'a. ',
cmd: 'InsertOrderedList',
value: {'list-style-type': 'lower-alpha'},
},
{
start: "a) ",
cmd: "InsertOrderedList",
value: { "list-style-type": "lower-alpha" },
start: 'a) ',
cmd: 'InsertOrderedList',
value: {'list-style-type': 'lower-alpha'},
},
{
start: "i. ",
cmd: "InsertOrderedList",
value: { "list-style-type": "lower-roman" },
start: 'i. ',
cmd: 'InsertOrderedList',
value: {'list-style-type': 'lower-roman'},
},
{
start: "i) ",
cmd: "InsertOrderedList",
value: { "list-style-type": "lower-roman" },
start: 'i) ',
cmd: 'InsertOrderedList',
value: {'list-style-type': 'lower-roman'},
},
{ start: "---", replacement: "<hr/>" },
{ start: "--", replacement: "—" },
{ start: "-", replacement: "—" },
{ start: "(c)", replacement: "©" },
{start: '---', replacement: '<hr/>'},
{start: '--', replacement: '—'},
{start: '-', replacement: '—'},
{start: '(c)', replacement: '©'},
];
function dark() {
if (!tinymce.activeEditor) return;
tinymce.activeEditor.dom.styleSheetLoader.unload(
@@ -144,22 +143,24 @@ var minifyImg = function (
resolve,
imageArguments = 0.7,
) {
var image, oldWidth, oldHeight, newHeight, canvas, ctx, newDataUrl;
new Promise(function (resolve) {
image = new Image();
image.src = dataUrl;
resolve('Done : ');
}).then((d) => {
oldWidth = image.width;
oldHeight = image.height;
newHeight = Math.floor((oldHeight / oldWidth) * newWidth);
canvas = document.createElement('canvas');
canvas.width = newWidth;
canvas.height = newHeight;
ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0, newWidth, newHeight);
newDataUrl = canvas.toDataURL(undefined, imageArguments);
resolve(newDataUrl);
fetch(dataUrl).then(async (res) => {
let blob = await res.blob();
new Compressor(blob, {
quality: imageArguments,
width: newWidth,
mimeType:imageType,
success: (result) => {
let fileReader = new FileReader();
fileReader.onloadend = function () {
resolve(fileReader.result);
fileReader.onloadend = null;
};
fileReader.readAsDataURL(result);
},
error: (err) => {
console.log(err.message);
},
});
});
};
@@ -173,13 +174,13 @@ function loadImage() {
console.log(e, 'loaded error');
minifyImg(
reader.result,
600,
1024,
'image/jpeg',
(r) => {
var content = `<img style="max-width:100% !important;" src="${r}">`;
editor.insertContent(content);
},
0.7,
0.6,
);
fileInput.removeEventListener('change', listener);
reader.removeEventListener('load', load);

View File

@@ -25,19 +25,19 @@
<a href="https://www.tiny.cloud/" target="_blank" id="infosaved">Powered by Tiny</a>
</div>
</div>
<textarea id="tiny_textarea"></textarea>
<textarea hidden id="tiny_textarea"></textarea>
</div>
<script>
let editor = null;
let isLoading = true;
let regex = /\n/gm;
</script>
<script src="./compressor.min.js"></script>
<script src="./listeners.js"></script>
<script src="./dist/main.js"></script>
<script src="./constants.js"></script>
<script src="./init.js"></script>
<script>
init_tiny("calc(100vh - 55px)");
</script>

View File

@@ -21,15 +21,15 @@ function init_tiny(size) {
skin_url: 'dist/skins/notesnook',
content_css: 'dist/skins/notesnook',
plugins: [
"mychecklist advlist autolink textpattern hr lists link noneditable image",
"searchreplace mycode",
"media imagetools table paste wordcount autoresize directionality",
'mychecklist advlist autolink textpattern hr lists link noneditable image',
'searchreplace mycode',
'media imagetools table paste wordcount autoresize directionality',
],
toolbar: false,
paste_data_images: true,
images_upload_handler: function (blobInfo, success, failure) {
/* images_upload_handler: function (blobInfo, success, failure) {
success('data:' + blobInfo.blob().type + ';base64,' + blobInfo.base64());
},
}, */
statusbar: false,
textpattern_patterns: markdownPatterns,
contextmenu: false,
@@ -43,6 +43,24 @@ function init_tiny(size) {
pre.codeblock {
overflow-x:auto;
}
img {
max-width:100% !important;
height:auto !important;
}
iframe {
max-width:100% !important;
}
table {
display: block !important;
overflow-x: auto !important;
white-space: nowrap !important;
max-width:100% !important;
width:100% !important;
height:auto !important;
}
td {
min-width:20vw !important;
}
`,
browser_spellcheck: true,
autoresize_bottom_margin: 120,
@@ -74,7 +92,7 @@ function init_tiny(size) {
editor.on('SetContent', (event) => {
if (!event.paste) {
reactNativeEventHandler('noteLoaded', true);
}
}
if (event.paste) {
isLoading = false;
onChange(event);
@@ -95,10 +113,8 @@ function init_tiny(size) {
}
window.prevContent = "";
const onChange = (event) => {
if (event.type === "nodechange" && !event.selectionChange) return;
if (editor.getContent() === window.prevContent) return;
window.prevContent = editor.getContent();
if (event.type === 'nodechange' && !event.selectionChange) return;
if (isLoading) {
isLoading = false;
return;

File diff suppressed because one or more lines are too long

View File

@@ -136,7 +136,6 @@ function setTheme() {
css.appendChild(document.createTextNode(node));
document.getElementsByTagName('head')[0].appendChild(css);
}
var minifyImg = function (
dataUrl,
newWidth,
@@ -144,22 +143,24 @@ var minifyImg = function (
resolve,
imageArguments = 0.7,
) {
var image, oldWidth, oldHeight, newHeight, canvas, ctx, newDataUrl;
new Promise(function (resolve) {
image = new Image();
image.src = dataUrl;
resolve('Done : ');
}).then((d) => {
oldWidth = image.width;
oldHeight = image.height;
newHeight = Math.floor((oldHeight / oldWidth) * newWidth);
canvas = document.createElement('canvas');
canvas.width = newWidth;
canvas.height = newHeight;
ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0, newWidth, newHeight);
newDataUrl = canvas.toDataURL(undefined, imageArguments);
resolve(newDataUrl);
fetch(dataUrl).then(async (res) => {
let blob = await res.blob();
new Compressor(blob, {
quality: imageArguments,
width: newWidth,
mimeType:imageType,
success: (result) => {
let fileReader = new FileReader();
fileReader.onloadend = function () {
resolve(fileReader.result);
fileReader.onloadend = null;
};
fileReader.readAsDataURL(result);
},
error: (err) => {
console.log(err.message);
},
});
});
};
@@ -173,13 +174,13 @@ function loadImage() {
console.log(e, 'loaded error');
minifyImg(
reader.result,
600,
1024,
'image/jpeg',
(r) => {
var content = `<img style="max-width:100% !important;" src="${r}">`;
editor.insertContent(content);
},
0.7,
0.8,
);
fileInput.removeEventListener('change', listener);
reader.removeEventListener('load', load);

View File

@@ -25,13 +25,14 @@
<a href="https://www.tiny.cloud/" target="_blank" id="infosaved">Powered by Tiny</a>
</div>
</div>
<textarea id="tiny_textarea"></textarea>
<textarea hidden id="tiny_textarea"></textarea>
</div>
<script>
let editor = null;
let isLoading = true;
let regex = /\n/gm;
</script>
<script src="./compressor.min.js"></script>
<script src="./listeners.js"></script>
<script src="./dist/main.js"></script>
<script src="./constants.js"></script>

View File

@@ -27,9 +27,9 @@ function init_tiny(size) {
],
toolbar: false,
paste_data_images: true,
images_upload_handler: function (blobInfo, success, failure) {
success('data:' + blobInfo.blob().type + ';base64,' + blobInfo.base64());
},
// images_upload_handler: function (blobInfo, success, failure) {
// success('data:' + blobInfo.blob().type + ';base64,' + blobInfo.base64());
// },
statusbar: false,
textpattern_patterns: markdownPatterns,
contextmenu: false,
@@ -43,6 +43,24 @@ function init_tiny(size) {
pre.codeblock {
overflow-x:auto;
}
img {
max-width:100% !important;
height:auto !important;
}
iframe {
max-width:100% !important;
}
table {
display: block !important;
overflow-x: auto !important;
white-space: nowrap !important;
max-width:100% !important;
width:100% !important;
height:auto !important;
}
td {
min-width:20vw !important;
}
`,
browser_spellcheck: true,
autoresize_bottom_margin: 120,
@@ -96,8 +114,7 @@ function init_tiny(size) {
window.prevContent = "";
const onChange = (event) => {
if (event.type === "nodechange" && !event.selectionChange) return;
if (editor.getContent() === window.prevContent) return;
window.prevContent = editor.getContent();
if (isLoading) {
isLoading = false;

View File

@@ -48,7 +48,7 @@ const onChangeTab = async (obj) => {
currentTab = 1;
activateKeepAwake();
eSendEvent('navigate');
eSendEvent(eClearEditor, 'addHandler');
if (!editing.currentlyEditing || !getNote()) {
eSendEvent(eOnLoadNote, {type: 'new'});
editing.currentlyEditing = true;
@@ -60,6 +60,7 @@ const onChangeTab = async (obj) => {
if (obj.from === 1) {
updateStatusBarColor();
deactivateKeepAwake();
eSendEvent(eClearEditor, 'removeHandler');
if (getNote()?.locked) {
eSendEvent(eClearEditor);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -74,7 +74,7 @@ const ActionSheetWrapper = ({
return (
<ActionSheet
ref={fwdRef}
hideUnderlay={largeTablet || smallTablet ? true : false}
hideUnderlay={true}
containerStyle={style}
gestureEnabled={gestureEnabled}
extraScroll={largeTablet ? 50 : 0}

View File

@@ -60,10 +60,17 @@ export const ActionSheetComponent = ({
getRef,
}) => {
const [state, dispatch] = useTracked();
const {colors, premiumUser, user} = state;
const {colors, user} = state;
const [refreshing, setRefreshing] = useState(false);
const [isPinnedToMenu, setIsPinnedToMenu] = useState(false);
const [note, setNote] = useState(item);
const [noteInTopic, setNoteInTopic] = useState(
editing.actionAfterFirstSave.type === 'topic' &&
db.notebooks
.notebook(editing.actionAfterFirstSave.notebook)
.topics.topic(editing.actionAfterFirstSave.id)
.has(item.id),
);
function changeColorScheme(colors = COLOR_SCHEME, accent = ACCENT) {
let newColors = setColorScheme(colors, accent);
@@ -138,12 +145,12 @@ export const ActionSheetComponent = ({
name: 'Add to',
icon: 'book-outline',
func: () => {
close();
dispatch({type: Actions.CLEAR_SELECTION});
dispatch({type: Actions.SELECTED_ITEMS, item: note});
close();
setTimeout(() => {
eSendEvent(eOpenMoveNoteDialog, note);
}, 400);
}, 300);
},
},
{
@@ -151,6 +158,7 @@ export const ActionSheetComponent = ({
icon: 'share-variant',
func: async () => {
if (note.locked) {
close();
openVault({
item: item,
novault: true,
@@ -181,8 +189,9 @@ export const ActionSheetComponent = ({
name: 'Delete',
icon: 'delete',
func: async () => {
close();
if (note.locked) {
close();
await sleep(300);
openVault({
deleteNote: true,
@@ -194,12 +203,12 @@ export const ActionSheetComponent = ({
});
} else {
try {
close();
await deleteItems(note);
} catch (e) {
//console.log(e);
}
}
close();
},
},
{
@@ -246,6 +255,7 @@ export const ActionSheetComponent = ({
name: 'Restore',
icon: 'delete-restore',
func: async () => {
close();
await db.trash.restore(note.id);
Navigation.setRoutesToUpdate([
Navigation.routeNames.Tags,
@@ -264,7 +274,7 @@ export const ActionSheetComponent = ({
: 'Notebook restored from trash',
type: 'success',
});
close();
},
},
{
@@ -300,6 +310,7 @@ export const ActionSheetComponent = ({
icon: 'pin',
func: async () => {
if (!note.id) return;
close();
if (note.type === 'note') {
if (db.notes.pinned.length === 3 && !note.pinned) {
ToastEvent.show({
@@ -322,7 +333,7 @@ export const ActionSheetComponent = ({
await db.notebooks.notebook(note.id).pin();
}
localRefresh(item.type);
close();
},
close: false,
check: true,
@@ -335,6 +346,7 @@ export const ActionSheetComponent = ({
icon: 'star',
func: async () => {
if (!note.id) return;
close();
if (note.type === 'note') {
await db.notes.note(note.id).favorite();
} else {
@@ -346,7 +358,7 @@ export const ActionSheetComponent = ({
forced: true,
});
localRefresh(item.type, true);
close();
},
close: false,
check: true,
@@ -361,6 +373,7 @@ export const ActionSheetComponent = ({
: 'Add Shortcut to Menu',
icon: isPinnedToMenu ? 'link-variant-remove' : 'link-variant',
func: async () => {
close();
try {
if (isPinnedToMenu) {
await db.settings.unpin(note.id);
@@ -377,6 +390,7 @@ export const ActionSheetComponent = ({
setIsPinnedToMenu(db.settings.isPinned(note.id));
dispatch({type: Actions.MENU_PINS});
} catch (e) {}
},
close: false,
check: true,
@@ -724,11 +738,7 @@ export const ActionSheetComponent = ({
</PressableButton>
) : null}
{editing.actionAfterFirstSave.type === 'topic' &&
note.notebooks?.length > 0 &&
note?.notebooks?.findIndex(
(o) => o.topics.indexOf(editing.actionAfterFirstSave.id) > -1,
) > -1 ? (
{noteInTopic ? (
<PressableButton
type="accent"
accentColor="red"

View File

@@ -0,0 +1,96 @@
import React, {useEffect, useState} from 'react';
import {View} from 'react-native';
import Animated, {Easing} from 'react-native-reanimated';
import AnimatedProgress from 'react-native-reanimated-progress-bar';
import {useTracked} from '../../provider';
import {Actions} from '../../provider/Actions';
import {
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent,
} from '../../services/EventManager';
import {changeContainerScale, ContainerScale} from '../../utils/Animations';
import { db } from '../../utils/DB';
import {eOpenSideMenu} from '../../utils/Events';
import { sleep } from '../../utils/TimeUtils';
const scaleV = new Animated.Value(0.95);
const opacityV = new Animated.Value(1);
const AppLoader = ({onLoad}) => {
const [state, dispatch] = useTracked();
const colors = state.colors;
const [loading, setLoading] = useState(true);
const [opacity, setOpacity] = useState(true);
const load = async () => {
eSendEvent(eOpenSideMenu);
setOpacity(false);
await sleep(2);
Animated.timing(opacityV, {
toValue: 0,
duration: 150,
easing: Easing.out(Easing.ease),
}).start();
db.notes.init().then(() => {
dispatch({type: Actions.NOTES});
dispatch({type: Actions.FAVORITES});
dispatch({type: Actions.LOADING, loading: false});
eSendEvent(eOpenSideMenu);
});
changeContainerScale(ContainerScale, 1, 600);
await sleep(150);
setLoading(false);
animation = false;
};
useEffect(() => {
eSubscribeEvent('load_overlay', load);
onLoad();
return () => {
eUnSubscribeEvent('load_overlay', load);
};
}, []);
return (
loading && (
<Animated.View
style={{
backgroundColor: opacity ? colors.bg : 'rgba(0,0,0,0)',
width: '100%',
height: '100%',
position: 'absolute',
zIndex: 999,
borderRadius: 10,
}}>
<Animated.View
onTouchStart={() => {
setLoading(false);
}}
style={{
backgroundColor: colors.bg,
width: '100%',
height: '100%',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10,
opacity: opacityV,
}}>
<View
style={{
height: 10,
flexDirection: 'row',
width: 100,
}}>
<AnimatedProgress
fill={colors.accent}
current={4}
total={4}
/>
</View>
</Animated.View>
</Animated.View>
)
);
};
export default AppLoader;

View File

@@ -11,17 +11,15 @@ import {normalize, SIZE} from '../../utils/SizeUtils';
import {PressableButton} from '../PressableButton';
import RNTooltips from 'react-native-tooltips';
const translateY = new Animated.Value(0);
//const translateY = new Animated.Value(0);
export const ContainerBottomButton = ({
title,
onPress,
color = 'accent',
shouldShow = false,
}) => {
const [state] = useTracked();
const {colors} = state;
const insets = useSafeAreaInsets();
/*
function animate(translate) {
Animated.timing(translateY, {
toValue: translate,
@@ -48,7 +46,7 @@ export const ContainerBottomButton = ({
Keyboard.removeListener('keyboardDidHide', onKeyboardHide);
};
}, []);
*/
return DDS.isLargeTablet() && !shouldShow ? null : (
<Animated.View
style={{
@@ -59,14 +57,14 @@ export const ContainerBottomButton = ({
? insets.bottom - 10
: insets.bottom + 12,
zIndex: 10,
transform: [
/* transform: [
{
translateY: translateY,
},
{
translateX: translateY,
},
],
], */
}}>
<PressableButton
testID={notesnook.ids.default.addBtn}

View File

@@ -13,7 +13,7 @@ export const Container = ({children, root}) => {
return (
<KeyboardAvoidingView behavior="padding" enabled={Platform.OS === 'ios'}
style={{
backgroundColor:colors.nav,
backgroundColor:colors.bg,
width:"100%",
height:"100%"
}}

View File

@@ -54,6 +54,9 @@ export const HeaderLeftMenu = () => {
marginLeft: -5,
marginRight:DDS.isLargeTablet()? 10 : 25,
}}
left={40}
top={40}
right={DDS.isLargeTablet()? 10 : 25}
onPress={onLeftButtonPress}
onLongPress={() => {
Navigation.popToTop();

View File

@@ -12,6 +12,7 @@ import {
ToastEvent,
} from '../../services/EventManager';
import Navigation from '../../services/Navigation';
import { getTotalNotes } from '../../utils';
import {db} from '../../utils/DB';
import {eOpenMoveNoteDialog} from '../../utils/Events';
import {pv, SIZE} from '../../utils/SizeUtils';
@@ -81,7 +82,7 @@ const MoveNoteComponent = ({close, note, setNote}) => {
const [expanded, setExpanded] = useState('');
const [notebookInputFocused, setNotebookInputFocused] = useState(false);
const [topicInputFocused, setTopicInputFocused] = useState(false);
const [noteExists, setNoteExists] = useState([]);
const addNewNotebook = async () => {
if (!newNotebookTitle || newNotebookTitle.trim().length === 0)
return ToastEvent.show({
@@ -117,14 +118,7 @@ const MoveNoteComponent = ({close, note, setNote}) => {
};
const handlePress = async (item, index) => {
if (
note?.notebooks?.findIndex(
(o) =>
o.topics.findIndex((i) => {
return i === item.id;
}) > -1,
) > -1
) {
if (note && item.notes.indexOf(note.id) > -1) {
await db.notebooks
.notebook(item.notebookId)
.topics.topic(item.id)
@@ -163,6 +157,19 @@ const MoveNoteComponent = ({close, note, setNote}) => {
dispatch({type: Actions.NOTEBOOKS});
};
useEffect(() => {
if (!note?.id) return;
let ids = [];
for (let i = 0; i < notebooks.length; i++) {
for (let t = 0; t < notebooks[i].topics.length; t++) {
if (notebooks[i].topics[t].notes.indexOf(note.id) > -1) {
ids.push(notebooks[i].id);
}
}
}
setNoteExists(ids);
}, []);
return (
<>
<View>
@@ -290,7 +297,9 @@ const MoveNoteComponent = ({close, note, setNote}) => {
marginBottom: 5,
borderBottomWidth: 1,
borderBottomColor:
expanded === item.id ? colors.accent : colors.nav,
expanded === item.id || noteExists.indexOf(item.id) > -1
? colors.accent
: colors.nav,
}}>
<View
style={{
@@ -303,13 +312,16 @@ const MoveNoteComponent = ({close, note, setNote}) => {
}}>
<View>
<Heading
color={expanded === item.id ? colors.accent : null}
color={
expanded === item.id || noteExists.indexOf(item.id) > -1
? colors.accent
: null
}
size={SIZE.md}>
{item.title}
</Heading>
<Paragraph size={SIZE.xs} color={colors.icon}>
Notebook{' '}
{item.totalNotes +
{getTotalNotes(item) +
' notes' +
' & ' +
item.topics.length +
@@ -431,12 +443,10 @@ const MoveNoteComponent = ({close, note, setNote}) => {
{item.title}
</Paragraph>
<Paragraph color={colors.icon} size={SIZE.xs}>
{item.totalNotes + ' notes'}
{item.notes.length + ' notes'}
</Paragraph>
</View>
{note?.notebooks?.findIndex(
(o) => o.topics.indexOf(item.id) > -1,
) > -1 ? (
{note && item.notes.indexOf(note.id) > -1 ? (
<Button
onPress={() => handlePress(item, index)}
title="Remove note"

View File

@@ -1,11 +1,11 @@
import React from 'react';
import { useWindowDimensions } from 'react-native';
import {useWindowDimensions} from 'react-native';
import {TouchableOpacity, View} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {notesnook} from '../../../e2e/test.ids';
import {useTracked} from '../../provider';
import Navigation from '../../services/Navigation';
import { history } from '../../utils';
import {getTotalNotes, history} from '../../utils';
import {pv, SIZE} from '../../utils/SizeUtils';
import {ActionIcon} from '../ActionIcon';
import {ActionSheetEvent} from '../DialogManager/recievers';
@@ -22,6 +22,7 @@ export const NotebookItem = ({
const [state] = useTracked();
const {colors} = state;
const {fontScale} = useWindowDimensions();
const totalNotes = getTotalNotes(item);
const showActionSheet = () => {
let rowItems = isTrash
? ['Restore', 'Remove']
@@ -192,10 +193,10 @@ export const NotebookItem = ({
style={{
marginRight: 10,
}}>
{item && item.totalNotes && item.totalNotes > 1
? item.totalNotes + ' Notes'
: item.totalNotes === 1
? item.totalNotes + ' Note'
{item && totalNotes > 1
? totalNotes + ' Notes'
: totalNotes === 1
? totalNotes + ' Note'
: '0 Notes'}
</Paragraph>

View File

@@ -1,5 +1,6 @@
import React, {useEffect, useState} from 'react';
import {ActivityIndicator, useWindowDimensions, View} from 'react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {useTracked} from '../../provider';
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/EventManager';
@@ -11,7 +12,7 @@ import Seperator from '../Seperator';
import Heading from '../Typography/Heading';
import Paragraph from '../Typography/Paragraph';
export const Empty = ({loading = true, placeholderData}) => {
export const Empty = ({loading = true, placeholderData,absolute}) => {
const [state] = useTracked();
const {colors} = state;
const [headerTextState, setHeaderTextState] = useState(
@@ -36,7 +37,9 @@ export const Empty = ({loading = true, placeholderData}) => {
style={[
{
backgroundColor: colors.bg,
height: height - 250 - insets.top,
position: absolute? "absolute" : 'relative',
zIndex:absolute? 10 : null,
height: (height - 250) - insets.top,
width: '100%',
},
]}>

View File

@@ -2,5 +2,5 @@ import React from 'react';
import {View} from 'react-native';
export const Footer = () => {
return <View style={{height: 300}} />;
return <View style={{height: 150}} />;
};

View File

@@ -1,4 +1,5 @@
import React, {useEffect, useState} from 'react';
import {View} from 'react-native';
import {RefreshControl, useWindowDimensions} from 'react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {DataProvider, LayoutProvider, RecyclerListView} from 'recyclerlistview';
@@ -8,6 +9,7 @@ import {eSendEvent} from '../../services/EventManager';
import Sync from '../../services/Sync';
import {dHeight} from '../../utils';
import {eScrollEvent} from '../../utils/Events';
import {sleep} from '../../utils/TimeUtils';
import {NotebookWrapper} from '../NotebookItem/wrapper';
import {NoteWrapper} from '../NoteItem/wrapper';
import TagItem from '../TagItem';
@@ -19,9 +21,6 @@ import {SectionHeader} from './section-header';
const header = {
type: 'MAIN_HEADER',
};
const emptyData = new DataProvider((r1, r2) => {
return r1 !== r2;
}).cloneWithRows([header, {type: 'empty'}]);
const SimpleList = ({
listData,
@@ -41,14 +40,11 @@ const SimpleList = ({
const [state] = useTracked();
const {colors, deviceMode, messageBoardState} = state;
const [_loading, setLoading] = useState(true);
const [loaded, setLoaded] = useState(false);
const [dataProvider, setDataProvider] = useState(
new DataProvider((r1, r2) => {
return r1 !== r2;
}).cloneWithRows(
!listData || listData.length === 0
? [header, {type: 'empty'}]
: [header].concat(listData),
),
}),
);
const insets = useSafeAreaInsets();
@@ -57,15 +53,23 @@ const SimpleList = ({
const dataType = type;
useEffect(() => {
setDataProvider(
dataProvider.cloneWithRows(
!listData || listData.length === 0
? [header, {type: 'empty'}]
: [header].concat(listData),
),
);
setLoading(false);
}, [listData, deviceMode]);
if (loading) {
setDataProvider(dataProvider.cloneWithRows([header, {type: 'empty'}]));
setLoaded(false);
}
if (!loading) {
setDataProvider(
dataProvider.cloneWithRows(
!listData || listData.length === 0
? [header, {type: 'empty'}]
: [header].concat(listData),
),
);
setLoading(false);
sleep(100).then(() => setLoaded(true));
}
}, [listData, deviceMode, loading]);
const _onRefresh = async () => {
await Sync.run();
@@ -80,28 +84,6 @@ const SimpleList = ({
eSendEvent(eScrollEvent, y);
};
const emptyLayoutProvider = new LayoutProvider(
(index) => {
return emptyData.getDataForIndex(index).type;
},
(type, dim) => {
switch (type) {
case 'empty':
dim.width = width;
dim.height = dHeight - 250 - insets.top;
break;
case 'MAIN_HEADER':
dim.width = width;
dim.height =
dataType === 'search' ? 0 : DDS.isLargeTablet() ? 50 : 195;
break;
default:
dim.width = width;
dim.height = 0;
}
},
);
const _layoutProvider = new LayoutProvider(
(index) => {
return dataProvider.getDataForIndex(index).type;
@@ -243,19 +225,44 @@ const SimpleList = ({
width: '100%',
};
return (
<RecyclerListView
ref={scrollRef}
layoutProvider={
loading || _loading ? emptyLayoutProvider : _layoutProvider
}
dataProvider={loading || _loading ? emptyData : dataProvider}
rowRenderer={_renderRow}
onScroll={_onScroll}
canChangeSize={true}
renderFooter={Footer}
scrollViewProps={scrollProps}
style={styles}
/>
<>
{loaded && !loading ? null : (
<>
<View
style={{
position: 'absolute',
width: '100%',
height: '100%',
backgroundColor: colors.bg,
zIndex: 999,
}}>
<Header
title={headerProps.heading}
paragraph={headerProps.paragraph}
onPress={headerProps.onPress}
icon={headerProps.icon}
type={dataType}
index={0}
/>
<Empty loading={true} placeholderData={placeholderData} />
</View>
</>
)}
{_loading ? null : (
<RecyclerListView
ref={scrollRef}
layoutProvider={_layoutProvider}
dataProvider={dataProvider}
rowRenderer={_renderRow}
onScroll={_onScroll}
canChangeSize={true}
renderFooter={listData.length === 0 ? null : Footer}
scrollViewProps={scrollProps}
style={styles}
/>
)}
</>
);
};

View File

@@ -30,11 +30,11 @@ const onStateChange = (state) => {
const onNavigatorStateChange = (e) => {
if (e.history.find((i) => i.type === 'drawer')) {
changeContainerScale(ContainerScale, 0.95, 250);
changeContainerScale(DrawerScale, 1, 250);
//changeContainerScale(ContainerScale, 0.95, 250);
//changeContainerScale(DrawerScale, 1, 250);
} else {
changeContainerScale(DrawerScale, 0.95, 250);
changeContainerScale(ContainerScale, 1, 250);
//changeContainerScale(DrawerScale, 0.95, 250);
//changeContainerScale(ContainerScale, 1, 250);
}
}

View File

@@ -92,6 +92,17 @@ export const NavigatorStack = React.memo(
const updateRender = async () => {
if (!render) {
setRender(true);
Navigation.navigate(
SettingsService.get().homepage,
{
menu: true,
},
{
heading: SettingsService.get().homepage,
id: SettingsService.get().homepage.toLowerCase() + '_navigation',
},
);
}
};

View File

@@ -68,7 +68,7 @@ export const AppScale = new Animated.Value(0.95);
export const AppBorders = new Animated.Value(10);
export const ContainerScale = new Animated.Value(0.95);
export const EditorScalee = new Animated.Value(1);
export const DrawerScale = new Animated.Value(0.95);
export const DrawerScale = new Animated.Value(1);
export function changeContainerScale(op, scale, duration = 500, callback) {
timing(op, {

View File

@@ -11,10 +11,10 @@ import {tabBarRef} from './Refs';
import {SIZE} from './SizeUtils';
export const InteractionManager = {
runAfterInteractions: (func, time = 500) => setTimeout(func, time),
runAfterInteractions: (func, time = 150) => setTimeout(func, time),
};
export const APP_VERSION = 1300;
export const APP_VERSION = 1310;
export async function setSetting(settings, name, value) {
let s = {...settings};
@@ -108,6 +108,15 @@ export function setWidthHeight(size) {
dHeight = size.height;
}
export function getTotalNotes(notebook) {
if (notebook.type === 'topic') {
return notebook.notes.length;
}
return notebook.topics.reduce((sum, topic) => {
return sum + topic.notes.length;
}, 0);
}
export const itemSkus = Platform.select({
ios: ['com.streetwriters.notesnook.sub.mo'],
android: ['com.streetwriters.notesnook.sub.mo'],
@@ -152,7 +161,7 @@ export const SUBSCRIPTION_STATUS = {
export const SUBSCRIPTION_STATUS_STRINGS = {
0: 'Basic',
1: 'Trial',
2: Platform.OS === "ios" ? "Pro" : 'Beta',
2: Platform.OS === 'ios' ? 'Pro' : 'Beta',
5: 'Pro',
6: 'Expired',
7: 'Pro',

View File

@@ -1,23 +1,22 @@
import React, {useEffect} from 'react';
import {Keyboard, Platform, View} from 'react-native';
import RNExitApp from 'react-native-exit-app';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {notesnook} from '../../../e2e/test.ids';
import {ActionIcon} from '../../components/ActionIcon';
import {ActionSheetEvent} from '../../components/DialogManager/recievers';
import {useTracked} from '../../provider';
import {DDS} from '../../services/DeviceDetection';
import {eSendEvent, ToastEvent} from '../../services/EventManager';
import React, { useEffect } from 'react';
import { Keyboard, Platform, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { notesnook } from '../../../e2e/test.ids';
import { ActionIcon } from '../../components/ActionIcon';
import { ActionSheetEvent } from '../../components/DialogManager/recievers';
import { useTracked } from '../../provider';
import { DDS } from '../../services/DeviceDetection';
import { eSendEvent, ToastEvent } from '../../services/EventManager';
import Navigation from '../../services/Navigation';
import {editing} from '../../utils';
import {db} from '../../utils/DB';
import { editing } from '../../utils';
import { db } from '../../utils/DB';
import {
eCloseFullscreenEditor,
eOpenFullscreenEditor,
eOpenFullscreenEditor
} from '../../utils/Events';
import {sideMenuRef, tabBarRef} from '../../utils/Refs';
import {sleep} from '../../utils/TimeUtils';
import {EditorTitle} from './EditorTitle';
import { tabBarRef } from '../../utils/Refs';
import { sleep } from '../../utils/TimeUtils';
import { EditorTitle } from './EditorTitle';
import {
checkNote,
clearEditor,
@@ -26,16 +25,12 @@ import {
isNotedEdited,
loadNote,
post,
saveNote,
setColors,
setIntent,
setColors
} from './Functions';
import HistoryComponent from './HistoryComponent';
import tiny from './tiny/tiny';
import {toolbarRef} from './tiny/toolbar/constants';
let handleBack;
let tapCount = 0;
import { toolbarRef } from './tiny/toolbar/constants';
const EditorHeader = () => {
const [state] = useTracked();
@@ -81,10 +76,7 @@ const EditorHeader = () => {
}
post('keyboard');
});
if (handleBack) {
handleBack.remove();
handleBack = null;
}
}
};
@@ -115,6 +107,8 @@ const EditorHeader = () => {
await _onBackPress();
Navigation.popToTop();
}}
top={50}
left={50}
testID={notesnook.ids.default.header.buttons.back}
name="arrow-left"
color={colors.heading}
@@ -140,6 +134,7 @@ const EditorHeader = () => {
marginLeft: 10,
borderRadius: 5,
}}
top={50}
onPress={async () => {
await loadNote({type: 'new'});
}}
@@ -152,6 +147,7 @@ const EditorHeader = () => {
customStyle={{
marginLeft: 10,
}}
top={50}
onPress={() => {
eSendEvent(eOpenFullscreenEditor);
editing.isFullscreen = true;
@@ -166,6 +162,8 @@ const EditorHeader = () => {
customStyle={{
marginLeft: 10,
}}
top={50}
right={50}
onPress={async () => {
let note = getNote() && db.notes.note(getNote().id).data;
if (editing.isFocused) {

View File

@@ -1,18 +1,17 @@
import React, {useEffect, useState} from 'react';
import {View} from 'react-native';
import Animated, {Easing, timing, useValue} from 'react-native-reanimated';
import AnimatedProgress from 'react-native-reanimated-progress-bar';
import {Button} from '../../components/Button';
import React, { useEffect, useState } from 'react';
import { View } from 'react-native';
import Animated, { Easing, timing, useValue } from 'react-native-reanimated';
import { Button } from '../../components/Button';
import Heading from '../../components/Typography/Heading';
import Paragraph from '../../components/Typography/Paragraph';
import {useTracked} from '../../provider';
import { useTracked } from '../../provider';
import {
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent,
eUnSubscribeEvent
} from '../../services/EventManager';
import {SIZE} from '../../utils/SizeUtils';
import {sleep, timeConverter} from '../../utils/TimeUtils';
import { SIZE } from '../../utils/SizeUtils';
import { sleep, timeConverter } from '../../utils/TimeUtils';
let timer = null;
let timerError = null;
@@ -29,15 +28,13 @@ const EditorOverlay = () => {
clearTimeout(timerError);
setProgress(2);
if (_loading) {
timer = setTimeout(() => {
setLoading(_loading);
timerError = setTimeout(() => {
setError(true);
}, 3000);
},1000)
setLoading(_loading);
timerError = setTimeout(() => {
setError(true);
}, 4000);
} else {
setProgress(4);
await sleep(10);
await sleep(1);
setError(false);
timing(opacity, {
toValue: 0,
@@ -47,9 +44,9 @@ const EditorOverlay = () => {
await sleep(150);
setProgress(1);
opacity.setValue(1);
setLoading(false);
clearTimeout(timer);
clearTimeout(timerError);
setLoading(false);
});
}
};
@@ -71,7 +68,7 @@ const EditorOverlay = () => {
justifyContent: 'center',
alignItems: 'center',
opacity: opacity,
top: loading ? 0 : 6000,
top: loading? 0 : 6000,
zIndex: 100,
}}>
<View
@@ -89,11 +86,17 @@ const EditorOverlay = () => {
height: 10,
width: 100,
marginBottom: 15,
borderRadius: 5,
overflow: 'hidden',
backgroundColor:colors.nav
}}>
<AnimatedProgress
fill={error ? 'red' : colors.accent}
total={4}
current={progress}
<Animated.View
style={{
height: 10,
borderRadius: 5,
width:100,
backgroundColor:colors.accent
}}
/>
</View>
@@ -101,16 +104,18 @@ const EditorOverlay = () => {
textBreakStrategy="balanced"
style={{textAlign: 'center', marginBottom: 5}}
size={SIZE.lg}>
{loading?.title ? loading.title : 'Loading Note'}
{loading?.title ? loading.title : 'Loading editor'}
</Heading>
<Paragraph
textBreakStrategy="balanced"
style={{textAlign: 'center'}}
color={colors.icon}
size={SIZE.sm}>
{loading && timeConverter(loading.dateEdited)}
</Paragraph>
{loading?.dateEdited ? (
<Paragraph
textBreakStrategy="balanced"
style={{textAlign: 'center'}}
color={colors.icon}
size={SIZE.sm}>
{timeConverter(loading.dateEdited)}
</Paragraph>
) : null}
</View>
{error && (

View File

@@ -28,7 +28,7 @@ import {
saveNote,
setIntent,
} from './Functions';
import { toolbarRef } from './tiny/toolbar/constants';
import {toolbarRef} from './tiny/toolbar/constants';
let handleBack;
let tapCount = 0;
@@ -67,7 +67,6 @@ const EditorRoot = () => {
await loadNote(item);
InteractionManager.runAfterInteractions(() => {
Keyboard.addListener('keyboardDidShow', () => {
if (!editing.movedAway) {
editing.isFocused = true;
}
@@ -82,7 +81,26 @@ const EditorRoot = () => {
});
};
const onCallClear = async () => {
const onCallClear = async (value) => {
if (value === 'removeHandler') {
if (handleBack) {
handleBack.remove();
handleBack = null;
}
return;
}
if (value === 'addHandler') {
if (handleBack) {
handleBack.remove();
handleBack = null;
}
handleBack = BackHandler.addEventListener(
'hardwareBackPress',
_onHardwareBackPress,
);
return;
}
if (editing.currentlyEditing) {
await _onBackPress();
}
@@ -96,12 +114,12 @@ const EditorRoot = () => {
};
const _onBackPress = async () => {
eSendEvent("showTooltip");
eSendEvent('showTooltip');
toolbarRef.current?.scrollTo({
x:0,
y:0,
animated:false
})
x: 0,
y: 0,
animated: false,
});
editing.currentlyEditing = false;
if (DDS.isLargeTablet()) {
if (fullscreen) {

View File

@@ -1,20 +1,20 @@
import {createRef} from 'react';
import {Platform} from 'react-native';
import {updateEvent} from '../../components/DialogManager/recievers';
import {Actions} from '../../provider/Actions';
import {DDS} from '../../services/DeviceDetection';
import {eSendEvent, sendNoteEditedEvent} from '../../services/EventManager';
import { createRef } from 'react';
import { Platform } from 'react-native';
import { updateEvent } from '../../components/DialogManager/recievers';
import { Actions } from '../../provider/Actions';
import { DDS } from '../../services/DeviceDetection';
import { eSendEvent, sendNoteEditedEvent } from '../../services/EventManager';
import Navigation from '../../services/Navigation';
import {editing} from '../../utils';
import {COLORS_NOTE, COLOR_SCHEME} from '../../utils/Colors';
import {hexToRGBA} from '../../utils/ColorUtils';
import {db} from '../../utils/DB';
import {eOnLoadNote, eShowGetPremium} from '../../utils/Events';
import {openLinkInBrowser} from '../../utils/functions';
import {MMKV} from '../../utils/mmkv';
import {tabBarRef} from '../../utils/Refs';
import {normalize} from '../../utils/SizeUtils';
import {sleep, timeConverter} from '../../utils/TimeUtils';
import { editing } from '../../utils';
import { COLORS_NOTE, COLOR_SCHEME } from '../../utils/Colors';
import { hexToRGBA } from '../../utils/ColorUtils';
import { db } from '../../utils/DB';
import { eOnLoadNote, eShowGetPremium } from '../../utils/Events';
import { openLinkInBrowser } from '../../utils/functions';
import { MMKV } from '../../utils/mmkv';
import { tabBarRef } from '../../utils/Refs';
import { normalize } from '../../utils/SizeUtils';
import { sleep, timeConverter } from '../../utils/TimeUtils';
import tiny from './tiny/tiny';
export let EditorWebView = createRef();
@@ -121,9 +121,7 @@ export const _onShouldStartLoadWithRequest = async (request) => {
if (request.url.includes('https')) {
openLinkInBrowser(request.url, appColors)
.catch((e) => {})
.then((r) => {
console.log('closed');
});
.then((r) => {});
return false;
} else {
@@ -146,8 +144,13 @@ async function setNote(item) {
content.type = note.content.type;
} else {
let data = await db.content.raw(note.contentId);
content.data = data.data;
content.type = data.type;
if (!data) {
content.data = '';
content.type = 'tiny';
} else {
content.data = data.data;
content.type = data.type;
}
}
}
@@ -191,6 +194,8 @@ export const loadNote = async (item) => {
return;
}
eSendEvent('loadingNote', item);
eSendEvent('webviewreset');
webviewInit = false;
editing.isFocused = false;
clearTimer();
await setNote(item);
@@ -216,14 +221,13 @@ const checkStatus = (reset = false) => {
if (!webviewOK) {
if (!reset) {
checkStatus(true);
console.log('checking again');
return;
}
webviewInit = false;
EditorWebView = createRef();
eSendEvent('webviewreset');
} else {
console.log('webview is running', webviewOK);
}
}, 3500);
};
@@ -251,20 +255,25 @@ export const _onMessage = async (evt) => {
eSendEvent('historyEvent', message.value);
break;
case 'tiny':
content = {
type: message.type,
data: message.value,
};
onNoteChange();
if (message.value !== content.data) {
content = {
type: message.type,
data: message.value,
};
onNoteChange();
} else {
console.log('not saving');
}
break;
case 'title':
console.log('TITLE', message.value);
noteEdited = true;
title = message.value;
eSendEvent('editorScroll', {
title: message.value,
});
onNoteChange();
if (message.value !== title) {
title = message.value;
eSendEvent('editorScroll', {
title: message.value,
});
onNoteChange();
}
break;
case 'scroll':
eSendEvent('editorScroll', message);
@@ -296,7 +305,6 @@ export const _onMessage = async (evt) => {
webviewOK = true;
break;
case 'focus':
console.log('focus gained', message.value);
editing.focusType = message.value;
break;
case 'selectionchange':
@@ -322,9 +330,13 @@ function onNoteChange() {
export async function clearEditor() {
tiny.call(EditorWebView, tiny.reset, true);
clearTimer();
if (noteEdited && id) {
await saveNote(false);
if (
(content?.data && content.data?.trim().length > 0) ||
(title && title.trim().length > 0)
) {
await saveNote();
}
clearNote();
editing.focusType = null;
updateEvent({type: Actions.CURRENT_EDITING_NOTE, id: null});
sendNoteEditedEvent({
@@ -338,8 +350,6 @@ export async function clearEditor() {
saveCounter = 0;
tiny.call(EditorWebView, tiny.updateDateEdited(''), true);
tiny.call(EditorWebView, tiny.updateSavingState(''), true);
clearNote();
}
async function setNoteInEditorAfterSaving(oldId, currentId) {
@@ -411,7 +421,7 @@ export async function saveNote() {
clearNote();
return;
}
console.log('saving note is called here');
let locked = id ? db.notes.note(id).data.locked : null;
let noteData = {
@@ -423,8 +433,6 @@ export async function saveNote() {
id: id,
};
console.log(noteData);
if (!locked) {
let noteId = await db.notes.add(noteData);
if (!id || saveCounter < 3) {
@@ -452,9 +460,7 @@ export async function saveNote() {
let n = db.notes.note(id)?.data?.dateEdited;
tiny.call(EditorWebView, tiny.updateDateEdited(timeConverter(n)));
tiny.call(EditorWebView, tiny.updateSavingState('Saved'));
} catch (e) {
console.log(e, 'error in saving');
}
} catch (e) {}
}
export async function onWebViewLoad(premium, colors) {
@@ -484,10 +490,25 @@ const loadNoteInEditor = async () => {
if (!webviewInit) return;
saveCounter = 0;
if (note?.id) {
console.log(content.data);
tiny.call(EditorWebView, tiny.setTitle(title));
intent = false;
tiny.call(EditorWebView, tiny.html(content.data));
if (!content || !content.data || content?.data?.length === 0) {
tiny.call(
EditorWebView,
`
window.ReactNativeWebView.postMessage(
JSON.stringify({
type: 'noteLoaded',
value: true,
}),
);
`,
);
} else {
tiny.call(EditorWebView, tiny.html(content.data));
}
setColors();
tiny.call(
EditorWebView,

View File

@@ -2,14 +2,18 @@ import React, {useEffect, useState} from 'react';
import {Platform, ScrollView, TextInput} from 'react-native';
import WebView from 'react-native-webview';
import {notesnook} from '../../../e2e/test.ids';
import {Loading} from '../../components/Loading';
import {useTracked} from '../../provider';
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/EventManager';
import {
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent,
} from '../../services/EventManager';
import {getCurrentColors} from '../../utils/Colors';
import {sleep} from '../../utils/TimeUtils';
import EditorHeader from './EditorHeader';
import {
EditorWebView,
getNote,
injectedJS,
onWebViewLoad,
sourceUri,
@@ -40,18 +44,19 @@ const Editor = React.memo(
const [state] = useTracked();
const {premiumUser} = state;
const [resetting, setResetting] = useState(false);
const [localLoading, setLocalLoading] = useState(false);
const onLoad = async () => {
await onWebViewLoad(premiumUser, getCurrentColors());
};
const onResetRequested = async () => {
setLocalLoading(true);
const onResetRequested = async (noload) => {
!noload && eSendEvent('loadingNote', getNote()?.id ? getNote() : {});
setResetting(true);
await sleep(10);
await sleep(30);
setResetting(false);
await sleep(1000);
setLocalLoading(false);
if (!getNote()) {
await sleep(10);
eSendEvent('loadingNote', null);
}
};
useEffect(() => {
@@ -62,15 +67,8 @@ const Editor = React.memo(
};
}, []);
return resetting ? (
<Loading
tagline={resetting ? 'Reloading Editor' : 'Loading Editor'}
height="100%"
/>
) : (
return resetting ? null : (
<>
{localLoading && <Loading tagline="Loading Editor" height="100%" />}
<TextInput
ref={textInput}
style={{height: 1, padding: 0, width: 1, position: 'absolute'}}
@@ -88,7 +86,6 @@ const Editor = React.memo(
height: '100%',
width: '100%',
}}
nestedScrollEnabled
contentContainerStyle={{
width: '100%',
@@ -120,6 +117,7 @@ const Editor = React.memo(
originWhitelist={['*']}
source={source}
style={style}
autoManageStatusBarEnabled={false}
onMessage={_onMessage}
/>
</ScrollView>

View File

@@ -1,4 +1,4 @@
import {EditorWebView, getWebviewInit} from '../Functions';
import { getWebviewInit } from '../Functions';
const reset = `
isLoading = true;

View File

@@ -60,13 +60,13 @@ export const execCommands = {
formatSelection(`
minifyImg(
"${b64}",
600,
1024,
'image/jpeg',
(r) => {
var content = "<img style=" + "max-width:100% !important;" + "src=" + r + ">";
editor.undoManager.transact(() => editor.execCommand("mceInsertContent",false,content));
},
0.7,
0.6,
);
`);
});

View File

@@ -16,6 +16,7 @@ import {
eOpenAddTopicDialog,
eScrollEvent,
} from '../../utils/Events';
import {sleep} from '../../utils/TimeUtils';
export const Notebook = ({route, navigation}) => {
const [topics, setTopics] = useState(route.params.notebook.topics);
@@ -25,15 +26,18 @@ export const Notebook = ({route, navigation}) => {
let ranAfterInteractions = false;
const runAfterInteractions = (time = 300) => {
const runAfterInteractions = (time = 150) => {
InteractionManager.runAfterInteractions(() => {
let notebook = db.notebooks.notebook(params.notebook?.id).data;
params.notebook = notebook;
params.title = params.notebook.title
params.title = params.notebook.title;
setTopics(notebook.topics);
if (loading) {
setLoading(false);
}
sleep(10).then((r) => {
if (loading) {
setLoading(false);
}
});
Navigation.routeNeedsUpdate('Notebook', () => {
onLoad();
});
@@ -51,15 +55,15 @@ export const Notebook = ({route, navigation}) => {
}
updateSearch();
ranAfterInteractions = false;
},time);
}, time);
};
const onLoad = (data) => {
if (data) {
setLoading(true);
params = data;
}
console.log('calling on load')
runAfterInteractions(data? 500 : 1);
runAfterInteractions(data ? 150 : 1);
};
useEffect(() => {

View File

@@ -22,6 +22,7 @@ import {
refreshNotesPage,
} from '../../utils/Events';
import {tabBarRef} from '../../utils/Refs';
import {sleep} from '../../utils/TimeUtils';
export const Notes = ({route, navigation}) => {
const [state, dispatch] = useTracked();
@@ -32,15 +33,33 @@ export const Notes = ({route, navigation}) => {
let pageIsLoaded = false;
let ranAfterInteractions = false;
const runAfterInteractions = (time = 300) => {
const runAfterInteractions = (time = 150) => {
InteractionManager.runAfterInteractions(() => {
if (localLoad) {
setLocalLoad(false);
}
Navigation.routeNeedsUpdate('NotesPage', () => {
init();
});
let _notes = [];
if (params.type === 'tag') {
_notes = db.notes.tagged(params.tag?.id);
} else if (params.type === 'color') {
_notes = db.notes.colored(params.color?.id);
} else {
_notes = db.notebooks
.notebook(params.notebookId)
.topics.topic(params.id).all;
}
if (
(params.type === 'tag' || params.type === 'color') &&
(!_notes || _notes.length === 0)
) {
Navigation.goBack();
}
setNotes(_notes);
if (localLoad) {
sleep(10).then((r) => {
setLocalLoad(false);
});
}
if (params.menu) {
navigation.setOptions({
animationEnabled: false,
@@ -52,26 +71,6 @@ export const Notes = ({route, navigation}) => {
gestureEnabled: Platform.OS === 'ios',
});
}
let _notes = [];
if (params.type === 'tag') {
_notes = db.notes.tagged(params.tag?.id);
} else if (params.type === 'color') {
_notes = db.notes.colored(params.color?.id);
} else {
_notes = db.notebooks
.notebook(params.notebookId)
.topics.topic(params.id).all;
}
if (
(params.type === 'tag' || params.type === 'color') &&
(!_notes || _notes.length === 0)
) {
Navigation.goBack();
}
setNotes([..._notes]);
updateSearch();
dispatch({
type: Actions.CONTAINER_BOTTOM_BUTTON,
@@ -100,7 +99,6 @@ export const Notes = ({route, navigation}) => {
}, []);
const setActionAfterFirstSave = () => {
console.log('setting action after first save',params);
if (params.type === 'tag') {
editing.actionAfterFirstSave = {
type: 'tag',
@@ -124,12 +122,11 @@ export const Notes = ({route, navigation}) => {
if (data) {
setLocalLoad(true);
params = data;
}
setActionAfterFirstSave();
if (!ranAfterInteractions) {
ranAfterInteractions = true;
runAfterInteractions(data ? 500 : 1);
runAfterInteractions(data ? 150 : 1);
}
if (!pageIsLoaded) {
@@ -222,47 +219,53 @@ export const Notes = ({route, navigation}) => {
}
};
const headerProps = {
heading:
params.type === 'tag'
? '#' + params.title
: params.title.slice(0, 1).toUpperCase() + params.title.slice(1),
color: params.type === 'color' ? params.title.toLowerCase() : null,
paragraph:
route.params.type === 'topic' && route.params.title !== 'General'
? 'Edit topic'
: null,
onPress: () => {
if (route.params.type !== 'topic') return;
eSendEvent(eOpenAddTopicDialog, {
notebookId: route.params.notebookId,
toEdit: route.params,
});
},
icon: 'pencil',
};
const _refreshCallback = () => {
init();
};
const placeholderData = {
heading: 'Your notes',
paragraph: 'You have not added any notes yet.',
button: 'Add your first Note',
action: _onPressBottomButton,
loading: 'Loading your notes.',
};
const isFocused = () => navigation.isFocused();
return (
<>
<SimpleList
listData={notes.reverse()}
type="notes"
refreshCallback={() => {
init();
}}
headerProps={{
heading:
params.type === 'tag'
? '#' + params.title
: params.title.slice(0, 1).toUpperCase() + params.title.slice(1),
color: params.type === 'color' ? params.title.toLowerCase() : null,
paragraph:
route.params.type === 'topic' && route.params.title !== 'General'
? 'Edit topic'
: null,
onPress: () => {
console.log(route.params);
if (route.params.type !== 'topic') return;
eSendEvent(eOpenAddTopicDialog, {
notebookId: route.params.notebookId,
toEdit: route.params,
});
},
icon: 'pencil',
}}
refreshCallback={_refreshCallback}
headerProps={headerProps}
loading={loading || localLoad}
focused={() => navigation.isFocused()}
focused={isFocused}
placeholderText={`Add some notes to this" ${
params.type ? params.type : 'topic.'
}`}
placeholderData={{
heading: 'Your notes',
paragraph: 'You have not added any notes yet.',
button: 'Add your first Note',
action: _onPressBottomButton,
loading: 'Loading your notes.',
}}
placeholderData={placeholderData}
/>
<ContainerBottomButton
title="Create a new note"