Files
contexted-v3/src/App.vue
2023-05-23 13:18:43 +02:00

112 lines
3.6 KiB
Vue

<script setup lang="ts">
import { activeNote, updateNote, notes, activeNotesSource } from '@/composables/useNotes'
import { viewModes, activeViewMode } from '@/composables/useViewMode'
import {
getClientKey,
getEncryptionKey,
setClientKey,
passphraseRequired
} from '@/composables/useEncryption'
import { windowIsMobile } from '@/utils/helpers'
import firebase from 'firebase/compat/app'
import * as firebaseui from 'firebaseui'
const sideBarCollapsed = ref<boolean>(windowIsMobile())
// const Note = defineAsyncComponent(() => import('@/components/ViewModes/Note.vue'))
// const ListView = defineAsyncComponent(() => import('@/components/ViewModes/ListView.vue'))
// const Mindmap = defineAsyncComponent(() => import('@/components/ViewModes/Mindmap.vue'))
const firebaseAuthUI =
firebaseui.auth.AuthUI.getInstance() || new firebaseui.auth.AuthUI(firebase.auth())
provide('firebaseAuthUI', firebaseAuthUI)
watch(
activeNotesSource,
() => {
if (activeNotesSource.value === 'firebase') {
getClientKey()
getEncryptionKey()
}
},
{ immediate: true }
)
const passphrase = ref('')
const submitPassphrase = (close: () => void) => {
const passphraseValid = setClientKey(passphrase.value)
if (!passphraseValid) {
console.log('passphrase is invalid')
} else {
close()
}
}
const loading = computed(() => notes.value.length === 0 || passphraseRequired.value)
provide('loading', loading)
</script>
<template>
<TopBar
:side-bar-collapsed="sideBarCollapsed"
@toggle-side-bar="sideBarCollapsed = !sideBarCollapsed"
/>
<div class="mx-auto flex w-full max-w-app flex-grow">
<Transition name="sidebar">
<SideBar
:view-modes="viewModes"
:active-view-mode="activeViewMode"
@set-view-mode="(viewMode) => (activeViewMode = viewMode)"
@collapse="(collapse) => (sideBarCollapsed = collapse)"
class="mt-[50px] bg-gray-100 px-3 py-6 transition-[width] delay-200 duration-0 max-sm:z-50 max-sm:border-x-[1px] max-sm:py-3 max-sm:transition-transform max-sm:delay-0 max-sm:duration-200"
v-if="!sideBarCollapsed"
/>
</Transition>
<main
class="transition[margin-left] z-10 mt-[50px] w-full border-x-[1px] bg-white px-10 py-6 duration-200 ease-out max-sm:px-4 max-sm:py-3"
:class="sideBarCollapsed ? 'ml-0' : 'sm:ml-sidebar'"
>
<Transition name="overlay">
<div
class="absolute bottom-0 left-0 right-0 top-0 bg-neutral-800 bg-opacity-60 transition-opacity duration-200 sm:hidden"
v-if="!sideBarCollapsed"
/>
</Transition>
<template v-if="!loading">
<Note
v-if="activeViewMode.name === 'Note' && activeNote"
:key="activeNote.id"
:note="activeNote"
class=""
@update="(note) => updateNote(note.id, note)"
/>
<ListView v-else-if="activeViewMode.name === 'List'" />
<Mindmap v-else-if="activeViewMode.name === 'Mindmap'" />
</template>
<SkeletonNote v-else />
</main>
</div>
<Modal :open="passphraseRequired" :persistent="true">
<template #default>
<p>
Your notes are encrypted. Please enter your encryption key passphrase to decrypt your notes.
</p>
<input type="password" class="input-bordered input mt-4 w-full" v-model="passphrase" />
</template>
<template #actions="{ close }">
<button class="btn-primary btn-sm btn" @click="submitPassphrase(close)">Submit</button>
</template>
</Modal>
</template>
<style scoped>
.sidebar-enter-from,
.sidebar-leave-to {
@apply max-sm:-translate-x-full;
}
.overlay-enter-from,
.overlay-leave-to {
@apply opacity-0;
}
</style>