From 8a4a0543d5417e59464825cc33e73e2e674cfeaf Mon Sep 17 00:00:00 2001 From: thecodrr Date: Sat, 7 Mar 2020 12:32:17 +0500 Subject: [PATCH 1/7] feat: impl note locking and unlocking --- .../src/components/dialogs/password-dialog.js | 69 +++++++++++++++++++ apps/web/src/components/note/index.js | 15 +++- apps/web/src/stores/app-store.js | 18 +++++ apps/web/src/stores/note-store.js | 42 +++++++++++ apps/web/yarn.lock | 16 +---- 5 files changed, 144 insertions(+), 16 deletions(-) create mode 100644 apps/web/src/components/dialogs/password-dialog.js diff --git a/apps/web/src/components/dialogs/password-dialog.js b/apps/web/src/components/dialogs/password-dialog.js new file mode 100644 index 000000000..3a94aed84 --- /dev/null +++ b/apps/web/src/components/dialogs/password-dialog.js @@ -0,0 +1,69 @@ +import React from "react"; +import { Box } from "rebass"; +import { Input } from "@rebass/forms"; +import Dialog, { showDialog } from "./dialog"; +import * as Icon from "react-feather"; + +function PasswordDialog(props) { + let password = ""; + return ( + + (password = e.target.value)} + placeholder="Enter vault password" + /> + + } + positiveButton={{ + text: props.positiveButtonText, + onClick: () => props.onDone(password) + }} + negativeButton={{ text: "Cancel", onClick: props.onCancel }} + /> + ); +} + +function getDialogData(type) { + switch (type) { + case "create_vault": + return { + title: "Set Up Your Vault", + icon: Icon.Shield, + positiveButtonText: "Done" + }; + case "unlock_vault": + return { + title: "Unlock Vault", + icon: Icon.Unlock, + positiveButtonText: "Unlock" + }; + case "unlock_note": + return { + title: "Unlock Note", + icon: Icon.Unlock, + positiveButtonText: "Unlock" + }; + default: + return; + } +} + +export const showPasswordDialog = type => { + const { title, icon, positiveButtonText } = getDialogData(type); + return showDialog(perform => ( + perform()} + onDone={password => perform(password)} + /> + )); +}; diff --git a/apps/web/src/components/note/index.js b/apps/web/src/components/note/index.js index 4cd7b52aa..56fe64e6a 100644 --- a/apps/web/src/components/note/index.js +++ b/apps/web/src/components/note/index.js @@ -28,7 +28,17 @@ const menuItems = (note, index) => [ onClick: () => store.getState().favorite(note, index) }, { title: "Edit", onClick: () => editorStore.getState().openSession(note) }, - { title: note.locked ? "Remove lock" : "Lock" }, //TODO + { + title: note.locked ? "Unlock" : "Lock", + onClick: async () => { + const { unlock, lock } = store.getState(); + if (!note.locked) { + lock(note, index); + } else { + unlock(note, index); + } + } + }, { title: "Move to Trash", color: "red", @@ -85,6 +95,7 @@ export default React.memo(Note, function(prevProps, nextProps) { prevItem.pinned === nextItem.pinned && prevItem.favorite === nextItem.favorite && prevItem.headline === nextItem.headline && - prevItem.title === nextItem.title + prevItem.title === nextItem.title && + prevItem.locked === nextItem.locked ); }); diff --git a/apps/web/src/stores/app-store.js b/apps/web/src/stores/app-store.js index f4fc818a0..deb6d757c 100644 --- a/apps/web/src/stores/app-store.js +++ b/apps/web/src/stores/app-store.js @@ -1,5 +1,6 @@ import createStore from "../common/store"; import { db } from "../common"; +import { showPasswordDialog } from "../components/dialogs/passworddialog"; function appStore(set, get) { return { @@ -52,6 +53,23 @@ function appStore(set, get) { if (get().selectedItems.length <= 0) { get().exitSelectionMode(); } + }, + createVault: function() { + return showPasswordDialog("create_vault").then(password => { + if (!password) return false; + return db.vault.create(password); + }); + }, + unlockVault: function unlockVault() { + return showPasswordDialog("unlock_vault") + .then(password => { + if (!password) return false; + return db.vault.unlock(password); + }) + .catch(({ message }) => { + if (message === "ERR_WRNG_PWD") return unlockVault(); + else return false; + }); } }; } diff --git a/apps/web/src/stores/note-store.js b/apps/web/src/stores/note-store.js index b868d9a2d..959b7a89a 100644 --- a/apps/web/src/stores/note-store.js +++ b/apps/web/src/stores/note-store.js @@ -1,6 +1,8 @@ import { db } from "../common/index"; import createStore from "../common/store"; import { store as editorStore } from "./editor-store"; +import { store as appStore } from "./app-store"; +import { showPasswordDialog } from "../components/dialogs/passworddialog"; const LIST_TYPES = { fav: "favorites" @@ -89,6 +91,46 @@ function noteStore(set, get) { syncEditor(note, "favorite"); }); get().refreshList(LIST_TYPES.fav); + }, + unlock: function unlock(note, index) { + showPasswordDialog("unlock_note") + .then(password => { + if (!password) return; + return db.vault.remove(note.id, password); + }) + .then(() => { + set(state => { + state.notes.items[index].locked = false; + }); + }) + .catch(({ message }) => { + if (message === "ERR_WRNG_PWD") unlock(note, index); + else console.log(message); + }); + }, + lock: function lock(note, index) { + db.vault + .add(note.id) + .then(() => { + set(state => { + state.notes.items[index].locked = true; + }); + }) + .catch(async ({ message }) => { + switch (message) { + case "ERR_NO_VAULT": + return appStore.getState().createVault(); + case "ERR_VAULT_LOCKED": + return appStore.getState().unlockVault(); + default: + return false; + } + }) + .then(result => { + if (result === true) { + lock(note, index); + } + }); } }; } diff --git a/apps/web/yarn.lock b/apps/web/yarn.lock index 5c80ccf96..7a13107ee 100644 --- a/apps/web/yarn.lock +++ b/apps/web/yarn.lock @@ -6823,9 +6823,8 @@ normalize-url@^3.0.0, normalize-url@^3.0.1: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== -"notes-core@https://github.com/thecodrr/notes-core.git": +notes-core@../notes-core: version "1.2.0" - resolved "https://github.com/thecodrr/notes-core.git#5ee5dfbd5df2abb748cc1a6b8eae6bdad234dba3" dependencies: fast-sort "^2.0.1" fuzzysearch "^1.0.3" @@ -8275,18 +8274,7 @@ quill-markdown-shortcuts@^0.0.10: dependencies: quill "^1.3.1" -quill@^1.3.1: - version "1.3.7" - resolved "https://github.com/thecodrr/quill.git#a88a62366eeb52a3b4aa6c4f140426055d7b0bc9" - dependencies: - clone "^2.1.1" - deep-equal "^1.0.1" - eventemitter3 "^2.0.3" - extend "^3.0.2" - parchment "^1.1.4" - quill-delta "^3.6.2" - -"quill@https://github.com/thecodrr/quill.git#1.3.7": +quill@^1.3.1, "quill@https://github.com/thecodrr/quill.git#1.3.7": version "1.3.7" resolved "https://github.com/thecodrr/quill.git#4ff9cee6f27efb2a7bad5aef50b6af140b4629fb" dependencies: From dd024d2f03de596cc5108135225f62bfaca0fa83 Mon Sep 17 00:00:00 2001 From: thecodrr Date: Sat, 7 Mar 2020 12:35:00 +0500 Subject: [PATCH 2/7] feat: use upstream notes-core --- apps/web/yarn.lock | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/web/yarn.lock b/apps/web/yarn.lock index 7a13107ee..1b79e6748 100644 --- a/apps/web/yarn.lock +++ b/apps/web/yarn.lock @@ -6823,8 +6823,9 @@ normalize-url@^3.0.0, normalize-url@^3.0.1: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== -notes-core@../notes-core: +"notes-core@https://github.com/thecodrr/notes-core.git": version "1.2.0" + resolved "https://github.com/thecodrr/notes-core.git#ad90f7747165db301cff457b0f702a147977ca47" dependencies: fast-sort "^2.0.1" fuzzysearch "^1.0.3" From dd40d528702e016f9c6feaf95b1e48006cb8804b Mon Sep 17 00:00:00 2001 From: thecodrr Date: Sat, 7 Mar 2020 15:20:01 +0500 Subject: [PATCH 3/7] feat: impl wrong password prompt --- .../src/components/dialogs/password-dialog.js | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/apps/web/src/components/dialogs/password-dialog.js b/apps/web/src/components/dialogs/password-dialog.js index 3a94aed84..6e7af53f9 100644 --- a/apps/web/src/components/dialogs/password-dialog.js +++ b/apps/web/src/components/dialogs/password-dialog.js @@ -1,11 +1,21 @@ -import React from "react"; -import { Box } from "rebass"; +import React, { useState, useRef, useCallback } from "react"; +import { Box, Text, Flex } from "rebass"; import { Input } from "@rebass/forms"; import Dialog, { showDialog } from "./dialog"; import * as Icon from "react-feather"; function PasswordDialog(props) { let password = ""; + const [isWrong, setIsWrong] = useState(false); + const passwordRef = useRef(); + const submit = useCallback(async () => { + if (await props.validate(password)) { + props.onDone(); + } else { + setIsWrong(true); + passwordRef.current.focus(); + } + }, [setIsWrong, password, props]); return ( (password = e.target.value)} placeholder="Enter vault password" + onKeyUp={async e => { + if (e.key === "Enter") { + await submit(); + } else { + setIsWrong(false); + } + }} /> + {isWrong && ( + + + + Wrong password + + + )} } positiveButton={{ text: props.positiveButtonText, - onClick: () => props.onDone(password) + onClick: submit }} negativeButton={{ text: "Cancel", onClick: props.onCancel }} /> @@ -55,15 +82,16 @@ function getDialogData(type) { } } -export const showPasswordDialog = type => { +export const showPasswordDialog = (type, validate) => { const { title, icon, positiveButtonText } = getDialogData(type); return showDialog(perform => ( perform()} - onDone={password => perform(password)} + onCancel={() => perform(false)} + validate={validate} + onDone={() => perform(true)} /> )); }; From 6866fff35c8d84a4d90ab3aa2b695696823930ad Mon Sep 17 00:00:00 2001 From: thecodrr Date: Sat, 7 Mar 2020 15:20:19 +0500 Subject: [PATCH 4/7] feat: improve locking ux --- apps/web/src/stores/app-store.js | 24 ++++++++++-------------- apps/web/src/stores/editor-store.js | 28 +++++++++++++++++++++++----- apps/web/src/stores/note-store.js | 26 +++++++++++++------------- apps/web/src/utils/theme.js | 11 +++++++++++ 4 files changed, 57 insertions(+), 32 deletions(-) diff --git a/apps/web/src/stores/app-store.js b/apps/web/src/stores/app-store.js index deb6d757c..79e9062a5 100644 --- a/apps/web/src/stores/app-store.js +++ b/apps/web/src/stores/app-store.js @@ -55,21 +55,17 @@ function appStore(set, get) { } }, createVault: function() { - return showPasswordDialog("create_vault").then(password => { - if (!password) return false; - return db.vault.create(password); - }); + return showPasswordDialog("create_vault", password => + db.vault.create(password) + ); }, - unlockVault: function unlockVault() { - return showPasswordDialog("unlock_vault") - .then(password => { - if (!password) return false; - return db.vault.unlock(password); - }) - .catch(({ message }) => { - if (message === "ERR_WRNG_PWD") return unlockVault(); - else return false; - }); + unlockVault: function() { + return showPasswordDialog("unlock_vault", password => { + return db.vault + .unlock(password) + .then(() => true) + .catch(() => false); + }); } }; } diff --git a/apps/web/src/stores/editor-store.js b/apps/web/src/stores/editor-store.js index 3b1a99ead..42254981c 100644 --- a/apps/web/src/stores/editor-store.js +++ b/apps/web/src/stores/editor-store.js @@ -2,6 +2,7 @@ import createStore from "../common/store"; import { store as noteStore, LIST_TYPES } from "./note-store"; import { store as appStore } from "./app-store"; import { db } from "../common"; +import { showPasswordDialog } from "../components/dialogs/passworddialog"; const SESSION_STATES = { stale: "stale", @@ -42,10 +43,27 @@ function editorStore(set, get) { }, openSession: async function(note) { clearTimeout(get().session.timeout); - const content = { - text: note.content.text, - delta: await db.notes.note(note).delta() - }; + let content = {}; + if (!note.locked) { + content = { + text: note.content.text, + delta: await db.notes.note(note).delta() + }; + } else { + const result = await showPasswordDialog("unlock_note", password => { + return db.vault + .open(note.id, password) + .then(note => { + content = note.content; + return true; + }) + .catch(e => { + console.log(e); + return false; + }); + }); + if (!result) return; + } noteStore.getState().setSelectedNote(note.id); set(state => { state.session = { @@ -61,7 +79,7 @@ function editorStore(set, get) { state: SESSION_STATES.new }; }); - saveLastOpenedNote(note.id); + saveLastOpenedNote(!note.locked ? note.id : undefined); }, saveSession: function(oldSession) { set(state => { diff --git a/apps/web/src/stores/note-store.js b/apps/web/src/stores/note-store.js index 959b7a89a..81e5d2b11 100644 --- a/apps/web/src/stores/note-store.js +++ b/apps/web/src/stores/note-store.js @@ -88,25 +88,24 @@ function noteStore(set, get) { if (index < 0) return; } state.notes.items[index].favorite = !note.favorite; - syncEditor(note, "favorite"); }); + syncEditor(note, "favorite"); get().refreshList(LIST_TYPES.fav); }, - unlock: function unlock(note, index) { - showPasswordDialog("unlock_note") - .then(password => { - if (!password) return; - return db.vault.remove(note.id, password); - }) - .then(() => { + unlock: function(note, index) { + showPasswordDialog("unlock_note", password => { + return db.vault + .remove(note.id, password) + .then(() => true) + .catch(() => false); + }).then(res => { + if (res) { set(state => { state.notes.items[index].locked = false; }); - }) - .catch(({ message }) => { - if (message === "ERR_WRNG_PWD") unlock(note, index); - else console.log(message); - }); + syncEditor(note, "locked"); + } + }); }, lock: function lock(note, index) { db.vault @@ -115,6 +114,7 @@ function noteStore(set, get) { set(state => { state.notes.items[index].locked = true; }); + syncEditor(note, "locked"); }) .catch(async ({ message }) => { switch (message) { diff --git a/apps/web/src/utils/theme.js b/apps/web/src/utils/theme.js index 220892649..5990b06e6 100644 --- a/apps/web/src/utils/theme.js +++ b/apps/web/src/utils/theme.js @@ -95,6 +95,17 @@ const theme = (colors, shadows) => ({ outline: "none", boxShadow: 4 } + }, + error: { + variant: "forms.default", + borderColor: "red", + ":focus": { + outline: "none", + borderColor: "red" + }, + ":hover": { + borderColor: "red" + } } }, text: { From 8bc2580dafd874bff00b99f023e6803cb97ec77a Mon Sep 17 00:00:00 2001 From: thecodrr Date: Sat, 7 Mar 2020 19:41:22 +0500 Subject: [PATCH 5/7] feat: allow locking from everywhere --- apps/web/src/components/checkbox/index.js | 5 +- .../src/components/dialogs/password-dialog.js | 5 +- apps/web/src/components/note/index.js | 8 +-- apps/web/src/components/properties/index.js | 13 +++-- apps/web/src/stores/editor-store.js | 29 ++++++++-- apps/web/src/stores/note-store.js | 55 ++++++++++--------- apps/web/src/views/Home.js | 1 + apps/web/src/views/Notes.js | 5 +- 8 files changed, 77 insertions(+), 44 deletions(-) diff --git a/apps/web/src/components/checkbox/index.js b/apps/web/src/components/checkbox/index.js index 937b16a15..6ffcfc4fd 100644 --- a/apps/web/src/components/checkbox/index.js +++ b/apps/web/src/components/checkbox/index.js @@ -10,9 +10,12 @@ const CheckBox = props => { return ( { - setChecked(!checked); if (props.onChecked) { props.onChecked(!checked); + setChecked(!checked); + } + if (props.onClick) { + props.onClick(); } }} width="full" diff --git a/apps/web/src/components/dialogs/password-dialog.js b/apps/web/src/components/dialogs/password-dialog.js index 6e7af53f9..26755a4f4 100644 --- a/apps/web/src/components/dialogs/password-dialog.js +++ b/apps/web/src/components/dialogs/password-dialog.js @@ -5,17 +5,17 @@ import Dialog, { showDialog } from "./dialog"; import * as Icon from "react-feather"; function PasswordDialog(props) { - let password = ""; const [isWrong, setIsWrong] = useState(false); const passwordRef = useRef(); const submit = useCallback(async () => { + const password = passwordRef.current.value; if (await props.validate(password)) { props.onDone(); } else { setIsWrong(true); passwordRef.current.focus(); } - }, [setIsWrong, password, props]); + }, [setIsWrong, props]); return ( (password = e.target.value)} placeholder="Enter vault password" onKeyUp={async e => { if (e.key === "Enter") { diff --git a/apps/web/src/components/note/index.js b/apps/web/src/components/note/index.js index 56fe64e6a..1087b4bd6 100644 --- a/apps/web/src/components/note/index.js +++ b/apps/web/src/components/note/index.js @@ -25,7 +25,7 @@ const menuItems = (note, index) => [ }, { title: note.favorite ? "Unfavorite" : "Favorite", - onClick: () => store.getState().favorite(note, index) + onClick: () => store.getState().favorite(note) }, { title: "Edit", onClick: () => editorStore.getState().openSession(note) }, { @@ -33,9 +33,9 @@ const menuItems = (note, index) => [ onClick: async () => { const { unlock, lock } = store.getState(); if (!note.locked) { - lock(note, index); + lock(note.id); } else { - unlock(note, index); + unlock(note.id); } } }, @@ -80,7 +80,7 @@ function Note(props) { {note.favorite && } } - pinned={note.pinned} + pinned={props.pinnable && note.pinned} menuData={note} menuItems={menuItems(note, index)} dropdownRefs={dropdownRefs} diff --git a/apps/web/src/components/properties/index.js b/apps/web/src/components/properties/index.js index be73107cd..69f3f5a29 100644 --- a/apps/web/src/components/properties/index.js +++ b/apps/web/src/components/properties/index.js @@ -12,12 +12,15 @@ import { useStore as useAppStore } from "../../stores/app-store"; const Properties = props => { const pinned = useStore(store => store.session.pinned); const favorite = useStore(store => store.session.favorite); + const locked = useStore(store => store.session.locked); const colors = useStore(store => store.session.colors); const tags = useStore(store => store.session.tags); const setSession = useStore(store => store.setSession); const setColor = useStore(store => store.setColor); const setTag = useStore(store => store.setTag); + const toggleLocked = useStore(store => store.toggleLocked); + function changeState(prop, value) { setSession(state => { state.session[prop] = value; @@ -92,13 +95,13 @@ const Properties = props => { label="Pin" onChecked={state => changeState("pinned", state)} /> + changeState("favorite", state)} + icon={Icon.Lock} + label="Lock" + checked={locked} + onClick={toggleLocked} /> - Move to notebook diff --git a/apps/web/src/stores/editor-store.js b/apps/web/src/stores/editor-store.js index 42254981c..bfc81d227 100644 --- a/apps/web/src/stores/editor-store.js +++ b/apps/web/src/stores/editor-store.js @@ -17,6 +17,7 @@ const DEFAULT_SESSION = { id: "", pinned: false, favorite: false, + locked: false, tags: [], colors: [], dateEdited: 0, @@ -58,8 +59,8 @@ function editorStore(set, get) { return true; }) .catch(e => { - console.log(e); - return false; + if (e.message === "ERR_WRNG_PwD") return false; + else console.error(e); }); }); if (!result) return; @@ -73,6 +74,7 @@ function editorStore(set, get) { pinned: note.pinned, favorite: note.favorite, colors: note.colors, + locked: note.locked, tags: note.tags, dateEdited: note.dateEdited, content, @@ -86,7 +88,17 @@ function editorStore(set, get) { state.session.isSaving = true; }); const { session } = get(); - const { title, id, content, pinned, favorite, tags, colors } = session; + const { + title, + id, + content, + pinned, + favorite, + locked, + tags, + colors + } = session; + let note = { content, title, @@ -96,6 +108,7 @@ function editorStore(set, get) { tags, colors }; + db.notes.add(note).then(id => { if (tags.length > 0) updateContext("tags", tags); if (colors.length > 0) { @@ -113,7 +126,7 @@ function editorStore(set, get) { }); notesState.refresh(); - saveLastOpenedNote(id); + saveLastOpenedNote(locked ? undefined : id); // we update favorites only if favorite has changed if (!oldSession || oldSession.favorite !== session.favorite) { @@ -144,6 +157,14 @@ function editorStore(set, get) { saveLastOpenedNote(); noteStore.getState().setSelectedNote(0); }, + toggleLocked: function() { + const { session } = get(); + if (session.locked) { + noteStore.getState().unlock(session.id); + } else { + noteStore.getState().lock(session.id); + } + }, setColor: function(color) { setTagOrColor(get().session, "colors", color, "color", get().setSession); }, diff --git a/apps/web/src/stores/note-store.js b/apps/web/src/stores/note-store.js index 81e5d2b11..13095ccd3 100644 --- a/apps/web/src/stores/note-store.js +++ b/apps/web/src/stores/note-store.js @@ -36,6 +36,7 @@ function noteStore(set, get) { }); }, setSelectedContext: function(context) { + console.log("setting context"); let notes = []; switch (context.type) { case "tag": @@ -77,44 +78,34 @@ function noteStore(set, get) { await db.notes.note(note).pin(); set(state => { state.notes = db.notes.group(undefined, true); - syncEditor(note, "pinned"); }); + syncEditor(note.id, "pinned"); }, - favorite: async function(note, index) { + favorite: async function(note) { await db.notes.note(note).favorite(); - set(state => { - if (index < 0 || !index) { - index = state.notes.items.findIndex(n => n.id === note.id); - if (index < 0) return; - } - state.notes.items[index].favorite = !note.favorite; - }); - syncEditor(note, "favorite"); + setValue(set, note.id, "favorite", !note.favorite); get().refreshList(LIST_TYPES.fav); }, - unlock: function(note, index) { + unlock: function(noteId) { showPasswordDialog("unlock_note", password => { return db.vault - .remove(note.id, password) + .remove(noteId, password) .then(() => true) - .catch(() => false); + .catch(e => { + if (e.message === "ERR_WRNG_PWD") return false; + else console.error(e); + }); }).then(res => { if (res) { - set(state => { - state.notes.items[index].locked = false; - }); - syncEditor(note, "locked"); + setValue(set, noteId, "locked", false); } }); }, - lock: function lock(note, index) { + lock: function lock(noteId) { db.vault - .add(note.id) + .add(noteId) .then(() => { - set(state => { - state.notes.items[index].locked = true; - }); - syncEditor(note, "locked"); + setValue(set, noteId, "locked", true); }) .catch(async ({ message }) => { switch (message) { @@ -128,22 +119,34 @@ function noteStore(set, get) { }) .then(result => { if (result === true) { - lock(note, index); + lock(noteId); } }); } }; } -function syncEditor(note, action) { +function syncEditor(noteId, action) { const editorState = editorStore.getState(); - if (editorState.session.id === note.id) { + if (editorState.session.id === noteId) { editorState.setSession( state => (state.session[action] = !state.session[action]) ); } } +function setValue(set, noteId, prop, value) { + set(state => { + const arr = !state.selectedNotes.length + ? state.notes.items + : state.selectedNotes; + let index = arr.findIndex(n => n.id === noteId); + if (index < 0) return; + arr[index][prop] = value; + }); + syncEditor(noteId, prop); +} + const [useStore, store] = createStore(noteStore); export { useStore, store, LIST_TYPES }; diff --git a/apps/web/src/views/Home.js b/apps/web/src/views/Home.js index 14628b5bf..7c4aa6413 100644 --- a/apps/web/src/views/Home.js +++ b/apps/web/src/views/Home.js @@ -64,6 +64,7 @@ function Home() { notes.groupCounts[groupIndex] && ( diff --git a/apps/web/src/views/Notes.js b/apps/web/src/views/Notes.js index 0ab596fe6..25ece7634 100644 --- a/apps/web/src/views/Notes.js +++ b/apps/web/src/views/Notes.js @@ -16,9 +16,12 @@ const Notes = props => { clearSelectedContext(); }; }, [clearSelectedContext]); + console.log("refreshing notesssss", selectedNotes); return ( } + item={index => ( + + )} itemsLength={selectedNotes.length} button={{ content: "Make a new note", From 0c8f3006389b7519918ffa20602c299cc03a2cd3 Mon Sep 17 00:00:00 2001 From: thecodrr Date: Sat, 7 Mar 2020 19:54:15 +0500 Subject: [PATCH 6/7] fix: ask for password before deleting locked note --- apps/web/src/components/note/index.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/web/src/components/note/index.js b/apps/web/src/components/note/index.js index 1087b4bd6..032abf9fb 100644 --- a/apps/web/src/components/note/index.js +++ b/apps/web/src/components/note/index.js @@ -8,6 +8,8 @@ import { confirm } from "../dialogs/confirm"; import { showMoveNoteDialog } from "../dialogs/movenotedialog"; import { store, useStore } from "../../stores/note-store"; import { store as editorStore } from "../../stores/editor-store"; +import { showPasswordDialog } from "../dialogs/passworddialog"; +import { db } from "../../common"; const dropdownRefs = []; const menuItems = (note, index) => [ @@ -42,7 +44,16 @@ const menuItems = (note, index) => [ { title: "Move to Trash", color: "red", - onClick: () => { + onClick: async () => { + if (note.locked) { + const res = await showPasswordDialog("unlock_note", password => { + return db.vault + .unlock(password) + .then(() => true) + .catch(() => false); + }); + if (!res) return; + } confirm( Icon.Trash2, "Delete", From d644c08b7fd8a30b6ccf25df658438cf952b2ed9 Mon Sep 17 00:00:00 2001 From: thecodrr Date: Sun, 8 Mar 2020 11:34:32 +0500 Subject: [PATCH 7/7] feat: implement locked note editting --- apps/web/src/stores/editor-store.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/web/src/stores/editor-store.js b/apps/web/src/stores/editor-store.js index bfc81d227..e63592d46 100644 --- a/apps/web/src/stores/editor-store.js +++ b/apps/web/src/stores/editor-store.js @@ -109,7 +109,11 @@ function editorStore(set, get) { colors }; - db.notes.add(note).then(id => { + const func = locked + ? db.vault.save.bind(db.vault) + : db.notes.add.bind(db.notes); + + func(note).then(id => { if (tags.length > 0) updateContext("tags", tags); if (colors.length > 0) { updateContext("colors", colors);