tabSize: 4
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/prettierrc",
|
||||
"semi": false,
|
||||
"tabWidth": 2,
|
||||
"tabWidth": 4,
|
||||
"singleQuote": true,
|
||||
"printWidth": 100,
|
||||
"trailingComma": "none",
|
||||
|
||||
@@ -115,8 +115,8 @@ const topBarHeightWithSafeArea = computed(() => `calc(${topBarHeight}px + var(--
|
||||
<template #title>Enter your passphrase</template>
|
||||
<template #default="{ close }">
|
||||
<div>
|
||||
Your notes are encrypted. Please enter your encryption key passphrase to decrypt your cloud
|
||||
notes.
|
||||
Your notes are encrypted. Please enter your encryption key passphrase to decrypt
|
||||
your cloud notes.
|
||||
</div>
|
||||
<form @submit.prevent="submitPassphrase(close)">
|
||||
<UIInputText
|
||||
|
||||
@@ -124,7 +124,9 @@ export default defineComponent({
|
||||
const [major] = CKEDITOR_VERSION.split('.').map(Number)
|
||||
|
||||
if (major < 37) {
|
||||
console.warn('The <CKEditor> component requires using CKEditor 5 in version 37 or higher.')
|
||||
console.warn(
|
||||
'The <CKEditor> component requires using CKEditor 5 in version 37 or higher.'
|
||||
)
|
||||
}
|
||||
} else {
|
||||
console.warn('Cannot find the "CKEDITOR_VERSION" in the "window" scope.')
|
||||
|
||||
@@ -116,10 +116,16 @@ export default class ContextedLinkEditing extends Plugin {
|
||||
}
|
||||
model.enqueueChange((writer) => {
|
||||
const rangesToFormat = format.map((array) =>
|
||||
model.createRange(range.start.getShiftedBy(array[0]), range.start.getShiftedBy(array[1]))
|
||||
model.createRange(
|
||||
range.start.getShiftedBy(array[0]),
|
||||
range.start.getShiftedBy(array[1])
|
||||
)
|
||||
)
|
||||
|
||||
const validRanges = editor.model.schema.getValidRanges(rangesToFormat, 'contextedLink')
|
||||
const validRanges = editor.model.schema.getValidRanges(
|
||||
rangesToFormat,
|
||||
'contextedLink'
|
||||
)
|
||||
for (const range of validRanges) {
|
||||
for (const item of range.getItems()) {
|
||||
if ((item as any).data) {
|
||||
@@ -145,8 +151,8 @@ export default class ContextedLinkEditing extends Plugin {
|
||||
}
|
||||
const keyCodes = [...keyCodesConfirm, ...keyCodesCycle]
|
||||
const selection = editor.model.document.selection
|
||||
const selectionInContextedLink = ['contextedLink', 'autocomplete'].some((attribute) =>
|
||||
selection.hasAttribute(attribute)
|
||||
const selectionInContextedLink = ['contextedLink', 'autocomplete'].some(
|
||||
(attribute) => selection.hasAttribute(attribute)
|
||||
)
|
||||
if (selectionInContextedLink && keyCodes.includes(keyCode)) {
|
||||
if (selection.hasAttribute('contextedLink')) {
|
||||
@@ -216,7 +222,10 @@ function fireAutocompleteEvent(editor: any, show: boolean, autocompleteNode?: an
|
||||
event = {
|
||||
position: getNodePosition(
|
||||
editor,
|
||||
editor.model.createPositionFromPath(autocompleteNode.root, autocompleteNode.getPath())
|
||||
editor.model.createPositionFromPath(
|
||||
autocompleteNode.root,
|
||||
autocompleteNode.getPath()
|
||||
)
|
||||
),
|
||||
autocompleteText: autocompleteNode.data,
|
||||
domElement,
|
||||
|
||||
@@ -116,7 +116,11 @@ const signInWithEmail = () => {
|
||||
<i class="fa-fw mr-2" :class="provider.icon"></i>
|
||||
Sign in with {{ provider.name }}
|
||||
</UIButton>
|
||||
<UIButton class="mx-auto !block w-[225px] max-sm:w-full" size="sm" @click="signInWithEmail">
|
||||
<UIButton
|
||||
class="mx-auto !block w-[225px] max-sm:w-full"
|
||||
size="sm"
|
||||
@click="signInWithEmail"
|
||||
>
|
||||
<i class="fa-fw fa-regular fa-envelope mr-2"></i>
|
||||
Sign in with email
|
||||
</UIButton>
|
||||
|
||||
@@ -58,7 +58,12 @@ const openModal = async (open: () => void, modal: ModalOptions) => {
|
||||
<UIButtonGroup class="flex items-center" v-if="!props.note.isRoot">
|
||||
<UIModal v-for="confirmModal in confirmModals" :key="confirmModal.key">
|
||||
<template #activator="{ open }">
|
||||
<UIButton size="sm" @click="openModal(open, confirmModal)" @mousedown="vibrate" join>
|
||||
<UIButton
|
||||
size="sm"
|
||||
@click="openModal(open, confirmModal)"
|
||||
@mousedown="vibrate"
|
||||
join
|
||||
>
|
||||
<i :class="confirmModal.icon" />
|
||||
</UIButton>
|
||||
</template>
|
||||
@@ -69,7 +74,11 @@ const openModal = async (open: () => void, modal: ModalOptions) => {
|
||||
<template #default>{{ confirmModal.confirmOptions.message }}</template>
|
||||
<template #actions="{ close }">
|
||||
<UIButton size="sm" @click="close">Cancel</UIButton>
|
||||
<UIButton size="sm" color="primary" @click="emit('execute', confirmModal.key, close)">
|
||||
<UIButton
|
||||
size="sm"
|
||||
color="primary"
|
||||
@click="emit('execute', confirmModal.key, close)"
|
||||
>
|
||||
{{ confirmModal.confirmOptions.okButtonTitle }}
|
||||
</UIButton>
|
||||
</template>
|
||||
|
||||
@@ -42,7 +42,8 @@ const handleKeydown = (event: KeyboardEvent) => {
|
||||
if (index < 0) index = results.value.length - 1
|
||||
activeResult.value = results.value[index]
|
||||
const element = resultsRefs.value[index].$el
|
||||
if (['ArrowUp', 'ArrowDown', 'Tab'].includes(code)) element.scrollIntoView({ block: 'nearest' })
|
||||
if (['ArrowUp', 'ArrowDown', 'Tab'].includes(code))
|
||||
element.scrollIntoView({ block: 'nearest' })
|
||||
} else if (code === 'Enter' && activeResult.value) {
|
||||
goToNote(activeResult.value)
|
||||
} else if (code === 'Escape' && queryElem.value) {
|
||||
|
||||
@@ -8,7 +8,11 @@ const props = withDefaults(
|
||||
</script>
|
||||
<template>
|
||||
<div class="flex w-full animate-pulse flex-col">
|
||||
<div class="mt-1 h-[1.35rem] w-full rounded bg-secondary" v-for="i in props.n" :key="i"></div>
|
||||
<div
|
||||
class="mt-1 h-[1.35rem] w-full rounded bg-secondary"
|
||||
v-for="i in props.n"
|
||||
:key="i"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
|
||||
@@ -97,7 +97,12 @@ const toggleEncryption = async () => {
|
||||
<div class="w-full flex-row sm:flex">
|
||||
<div class="font-bold sm:w-4/12">Account creation date</div>
|
||||
<div>
|
||||
{{ format(Date.parse(user?.metadata?.creationTime || ''), 'dd/MM/yyyy') }}
|
||||
{{
|
||||
format(
|
||||
Date.parse(user?.metadata?.creationTime || ''),
|
||||
'dd/MM/yyyy'
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -115,7 +120,11 @@ const toggleEncryption = async () => {
|
||||
<div class="items-top w-full flex-row sm:flex sm:flex-grow">
|
||||
<div class="flex-shrink-0 font-bold sm:w-4/12">Delete account</div>
|
||||
<div>
|
||||
<UIButton size="sm" color="error" @click="showDeleteAccountDialog = true">
|
||||
<UIButton
|
||||
size="sm"
|
||||
color="error"
|
||||
@click="showDeleteAccountDialog = true"
|
||||
>
|
||||
<i class="fa-fw fa-solid fa-trash mr-2"></i>
|
||||
Delete account
|
||||
</UIButton>
|
||||
@@ -126,14 +135,23 @@ const toggleEncryption = async () => {
|
||||
v-if="showDeleteAccountDialog"
|
||||
>
|
||||
<div>
|
||||
Are you sure you want to delete your Contexted account? This action cannot be
|
||||
undone!
|
||||
Are you sure you want to delete your Contexted account? This
|
||||
action cannot be undone!
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<UIButton size="sm" variant="outline" color="primary" @click="deleteAccount">
|
||||
<UIButton
|
||||
size="sm"
|
||||
variant="outline"
|
||||
color="primary"
|
||||
@click="deleteAccount"
|
||||
>
|
||||
Delete account
|
||||
</UIButton>
|
||||
<UIButton size="sm" variant="outline" @click="showDeleteAccountDialog = false">
|
||||
<UIButton
|
||||
size="sm"
|
||||
variant="outline"
|
||||
@click="showDeleteAccountDialog = false"
|
||||
>
|
||||
Cancel
|
||||
</UIButton>
|
||||
</div>
|
||||
@@ -141,7 +159,9 @@ const toggleEncryption = async () => {
|
||||
</div>
|
||||
</div>
|
||||
<div class="items-top w-full flex-row sm:flex">
|
||||
<div class="flex-shrink-0 font-bold sm:w-4/12">End-to-end encryption</div>
|
||||
<div class="flex-shrink-0 font-bold sm:w-4/12">
|
||||
End-to-end encryption
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<template v-if="!encryptionEnabled">
|
||||
<UIButton
|
||||
@@ -163,7 +183,12 @@ const toggleEncryption = async () => {
|
||||
Disable end-to-end encryption
|
||||
</UIButton>
|
||||
</template>
|
||||
<UIAlert color="info" density="compact" class="text-sm" v-if="showEncryptionDialog">
|
||||
<UIAlert
|
||||
color="info"
|
||||
density="compact"
|
||||
class="text-sm"
|
||||
v-if="showEncryptionDialog"
|
||||
>
|
||||
<div class="w-full space-y-2">
|
||||
<div>
|
||||
Enter your passphrase to
|
||||
@@ -177,7 +202,11 @@ const toggleEncryption = async () => {
|
||||
v-model="passphrase"
|
||||
class="w-full !max-w-full"
|
||||
/>
|
||||
<UIAlert density="compact" color="error" v-if="toggleEncryptionError">
|
||||
<UIAlert
|
||||
density="compact"
|
||||
color="error"
|
||||
v-if="toggleEncryptionError"
|
||||
>
|
||||
<i class="fa-solid fa-triangle-exclamation"></i>
|
||||
{{ toggleEncryptionError }}
|
||||
</UIAlert>
|
||||
@@ -189,9 +218,16 @@ const toggleEncryption = async () => {
|
||||
color="primary"
|
||||
@click="toggleEncryption"
|
||||
>
|
||||
{{ encryptionEnabled ? 'Disable' : 'Enable' }} encryption
|
||||
{{
|
||||
encryptionEnabled ? 'Disable' : 'Enable'
|
||||
}}
|
||||
encryption
|
||||
</UIButton>
|
||||
<UIButton size="sm" variant="outline" @click="showEncryptionDialog = false">
|
||||
<UIButton
|
||||
size="sm"
|
||||
variant="outline"
|
||||
@click="showEncryptionDialog = false"
|
||||
>
|
||||
Cancel
|
||||
</UIButton>
|
||||
</div>
|
||||
|
||||
@@ -34,11 +34,14 @@ const deleteSelectedNotes = (closeModal: () => void) => {
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex items-center">
|
||||
<span class="whitespace-nowrap">
|
||||
{{ notesWithReferences.length }} {{ notesWithReferences.length === 1 ? 'note' : 'notes' }}
|
||||
{{ notesWithReferences.length }}
|
||||
{{ notesWithReferences.length === 1 ? 'note' : 'notes' }}
|
||||
</span>
|
||||
<template v-if="countSelectedNotes > 0">
|
||||
<span class="mx-1">|</span>
|
||||
<div class="whitespace-nowrap font-semibold">{{ countSelectedNotes }} selected</div>
|
||||
<div class="whitespace-nowrap font-semibold">
|
||||
{{ countSelectedNotes }} selected
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<UIModal v-if="countSelectedNotes > 0">
|
||||
|
||||
@@ -27,7 +27,9 @@ const renderMindmap = () => {
|
||||
const elements = {
|
||||
nodes: nodes.value,
|
||||
edges: [
|
||||
...links.value.map((link) => ({ data: { id: `${link.source}-${link.target}`, ...link } }))
|
||||
...links.value.map((link) => ({
|
||||
data: { id: `${link.source}-${link.target}`, ...link }
|
||||
}))
|
||||
]
|
||||
}
|
||||
const cy = cytoscape({
|
||||
@@ -195,11 +197,13 @@ interface Mindmap {
|
||||
}
|
||||
const selectedMindmap = ref<Mindmap>()
|
||||
const mindmaps = computed<Mindmap[]>(() => {
|
||||
const mindmaps = Object.entries(notesRelations.value).reduce((mindmaps, [noteId, relations]) => {
|
||||
const mindmaps = Object.entries(notesRelations.value).reduce(
|
||||
(mindmaps, [noteId, relations]) => {
|
||||
const atomicMindmap = [noteId, ...relations.to, ...relations.from]
|
||||
const indices = mindmaps
|
||||
.filter(
|
||||
(mindmap) => [...mindmap].filter((noteId) => atomicMindmap.includes(noteId)).length > 0
|
||||
(mindmap) =>
|
||||
[...mindmap].filter((noteId) => atomicMindmap.includes(noteId)).length > 0
|
||||
)
|
||||
.map((mindmap) => mindmaps.indexOf(mindmap))
|
||||
if (indices.length > 0) {
|
||||
@@ -218,13 +222,16 @@ const mindmaps = computed<Mindmap[]>(() => {
|
||||
mindmaps.push(atomicMindmap)
|
||||
}
|
||||
return mindmaps
|
||||
}, [] as string[][])
|
||||
},
|
||||
[] as string[][]
|
||||
)
|
||||
return mindmaps
|
||||
.filter((mindmap) => mindmap.length > 1)
|
||||
.sort((a, b) => b.length - a.length)
|
||||
.sort((a, b) => {
|
||||
return (
|
||||
Number(b.includes(rootNote.value?.id || '')) - Number(a.includes(rootNote.value?.id || ''))
|
||||
Number(b.includes(rootNote.value?.id || '')) -
|
||||
Number(a.includes(rootNote.value?.id || ''))
|
||||
)
|
||||
})
|
||||
.slice(0, 5)
|
||||
|
||||
@@ -51,7 +51,11 @@ const handleAction = async (action: 'delete' | 'setRoot', closeModal?: () => Pro
|
||||
class="fas fa-fw fa-home mr-2 text-base text-secondary opacity-40"
|
||||
v-if="props.note.isRoot"
|
||||
></i>
|
||||
<input type="text" class="w-full bg-transparent pb-1 outline-none" v-model="noteTitle" />
|
||||
<input
|
||||
type="text"
|
||||
class="w-full bg-transparent pb-1 outline-none"
|
||||
v-model="noteTitle"
|
||||
/>
|
||||
</template>
|
||||
</NoteToolbar>
|
||||
<NoteEditor
|
||||
|
||||
@@ -97,7 +97,10 @@ const decryptNote = (note: BaseNote, key: EncryptionKey) => {
|
||||
|
||||
export const decryptNotes = (notes: BaseNotes, encryptionKey: EncryptionKey) => {
|
||||
const decryptedNotes = Object.fromEntries(
|
||||
Object.entries(notes).map(([noteId, note]) => [noteId, { ...decryptNote(note, encryptionKey) }])
|
||||
Object.entries(notes).map(([noteId, note]) => [
|
||||
noteId,
|
||||
{ ...decryptNote(note, encryptionKey) }
|
||||
])
|
||||
)
|
||||
return decryptedNotes
|
||||
}
|
||||
@@ -112,7 +115,10 @@ const encryptNote = (note: BaseNote, key: EncryptionKey) => {
|
||||
|
||||
export const encryptNotes = (notes: BaseNotes, encryptionKey: EncryptionKey) => {
|
||||
const encryptedNotes = Object.fromEntries(
|
||||
Object.entries(notes).map(([noteId, note]) => [noteId, { ...encryptNote(note, encryptionKey) }])
|
||||
Object.entries(notes).map(([noteId, note]) => [
|
||||
noteId,
|
||||
{ ...encryptNote(note, encryptionKey) }
|
||||
])
|
||||
)
|
||||
return encryptedNotes
|
||||
}
|
||||
|
||||
@@ -151,7 +151,9 @@ export const findNotes = (query: string): Note[] => {
|
||||
}
|
||||
return notes.value.filter((note) => {
|
||||
const matchTitle = note.title.toLowerCase().includes(query.toLowerCase())
|
||||
const matchContent = removeMdFromText(note.content).toLowerCase().includes(query.toLowerCase())
|
||||
const matchContent = removeMdFromText(note.content)
|
||||
.toLowerCase()
|
||||
.includes(query.toLowerCase())
|
||||
return matchTitle || matchContent
|
||||
})
|
||||
}
|
||||
@@ -205,7 +207,9 @@ export const notesRelations = computed(() => {
|
||||
.map((noteRelations, _, notesRelations): NoteRelations => {
|
||||
const from = [...notesRelations]
|
||||
.map((noteRelation) =>
|
||||
noteRelation.to.filter((toId) => toId === noteRelations.id).map(() => noteRelation.id)
|
||||
noteRelation.to
|
||||
.filter((toId) => toId === noteRelations.id)
|
||||
.map(() => noteRelation.id)
|
||||
)
|
||||
.reduce((arr, elem) => arr.concat(elem), [])
|
||||
.filter((value, index, self) => self.indexOf(value) === index)
|
||||
@@ -262,7 +266,9 @@ export const getNotes = async () => {
|
||||
}
|
||||
} else if (activeNotesSource.value === 'firebase') {
|
||||
if (encryptionKey.value === undefined || !user.value || !db.value) return
|
||||
const firebaseNotes = (await getDoc(doc(db.value, 'pages', user.value.uid))).data() as BaseNotes
|
||||
const firebaseNotes = (
|
||||
await getDoc(doc(db.value, 'pages', user.value.uid))
|
||||
).data() as BaseNotes
|
||||
notes = encryptionKey.value
|
||||
? decryptNotes(firebaseNotes, encryptionKey.value)
|
||||
: firebaseNotes || {}
|
||||
|
||||
Reference in New Issue
Block a user