ui updates
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div :class="['note-row', { 'move-active': moveActive }]">
|
||||
<span class="date">{{ formatDate(note.createdAt) }}</span>
|
||||
<span class="date">{{ formatDate(note.updatedAt) }}</span>
|
||||
<div class="title-actions">
|
||||
<button class="title bold" @click="openNote(note.id)">
|
||||
{{ note.title }}
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
<script setup>
|
||||
import useOpenNote from '@/composables/useOpenNote'
|
||||
import useState from '@/composables/useState'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { computed } from 'vue'
|
||||
import { format } from 'fecha'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-if="showScrollBar" class="scroll-bar">
|
||||
<div v-if="showScrollBar" :class="['scroll-bar', { active: isDragging }]">
|
||||
<div class="inner" ref="inner">
|
||||
<div class="handle" ref="handle" />
|
||||
</div>
|
||||
@@ -7,10 +7,14 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onBeforeUnmount, computed, watch } from 'vue'
|
||||
import { useElementSize, useWindowScroll, useWindowSize } from '@vueuse/core'
|
||||
import Tempus from 'tempus'
|
||||
import {
|
||||
useElementSize,
|
||||
useWindowScroll,
|
||||
useWindowSize,
|
||||
useEventListener,
|
||||
} from '@vueuse/core'
|
||||
import { useDragControls } from '@/composables/useDragControls'
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
const inner = ref()
|
||||
const handle = ref()
|
||||
@@ -23,12 +27,13 @@ const { height: innerHeight } = useElementSize(inner)
|
||||
const { height: handleHeight } = useElementSize(handle)
|
||||
|
||||
// Drag controls
|
||||
// useDragControls({
|
||||
// target: handle,
|
||||
// onUpdate: ({ y }) => {
|
||||
// console.log(y.value)
|
||||
// },
|
||||
// })
|
||||
const { isDragging } = useDragControls({
|
||||
target: inner,
|
||||
onUpdate: ({ y }) => {
|
||||
if (!handle.value) return
|
||||
window.scrollTo(0, y.value * (documentHeight.value - wHeight.value))
|
||||
},
|
||||
})
|
||||
|
||||
const updateScrollbar = () => {
|
||||
const scrollHeight = documentHeight.value
|
||||
@@ -46,27 +51,11 @@ const updateScrollbar = () => {
|
||||
}
|
||||
}
|
||||
|
||||
useEventListener(window, 'scroll', updateScrollbar)
|
||||
|
||||
const showScrollBar = computed(() => {
|
||||
return documentHeight.value > wHeight.value
|
||||
})
|
||||
|
||||
// RAF
|
||||
const removeRaf = ref()
|
||||
const addRaf = () => (removeRaf.value = Tempus.add(updateScrollbar))
|
||||
onBeforeUnmount(() => {
|
||||
removeRaf.value?.()
|
||||
})
|
||||
watch(
|
||||
showScrollBar,
|
||||
(show) => {
|
||||
if (show) {
|
||||
addRaf()
|
||||
} else {
|
||||
removeRaf.value?.()
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -79,6 +68,7 @@ watch(
|
||||
will-change: transform;
|
||||
border-left: 1px solid var(--grey-100);
|
||||
background: var(--theme-bg);
|
||||
cursor: grab;
|
||||
|
||||
.inner {
|
||||
height: 100%;
|
||||
@@ -86,7 +76,7 @@ watch(
|
||||
|
||||
.handle {
|
||||
width: 100%;
|
||||
height: 388px;
|
||||
height: 70vh;
|
||||
background: var(--grey-100);
|
||||
border-radius: 20px;
|
||||
position: absolute;
|
||||
@@ -94,5 +84,8 @@ watch(
|
||||
will-change: transform;
|
||||
}
|
||||
}
|
||||
&.active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="note-download">
|
||||
<button @click="download">
|
||||
<button v-if="noteTitle && props.editor" @click="download">
|
||||
<span class="title-text">{{ noteTitle }}</span>
|
||||
<span class="extension">.md ↓</span>
|
||||
</button>
|
||||
|
||||
@@ -37,8 +37,8 @@ import EditorMenu from './Menu.vue'
|
||||
const TITLE_CHAR_LIMIT = 100
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
note: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
@@ -53,23 +53,20 @@ const onUpdate = _debounce(async ({ editor }) => {
|
||||
const json = editor.getJSON()
|
||||
const text = editor.getText()
|
||||
|
||||
await updateNote(props.id, {
|
||||
await updateNote(props.note.id, {
|
||||
content: json,
|
||||
plainText: text,
|
||||
})
|
||||
}, 500)
|
||||
|
||||
onMounted(async () => {
|
||||
const note = await loadNote(props.id)
|
||||
if (!note) return
|
||||
|
||||
if (note.title !== 'Untitled') {
|
||||
title.value = note.title || ''
|
||||
if (props.note.title !== 'Untitled') {
|
||||
title.value = props.note.title || ''
|
||||
}
|
||||
|
||||
editor.value = new Editor({
|
||||
extensions,
|
||||
content: note.content || [],
|
||||
content: props.note.content || [],
|
||||
onUpdate: onUpdate,
|
||||
})
|
||||
|
||||
@@ -95,7 +92,7 @@ watch(title, async (newVal) => {
|
||||
}
|
||||
})
|
||||
const updateTitle = _debounce((title) => {
|
||||
updateNote(props.id, {
|
||||
updateNote(props.note.id, {
|
||||
title: title === '' ? 'Untitled' : title,
|
||||
})
|
||||
}, 500)
|
||||
|
||||
@@ -9,6 +9,9 @@ export function useDragControls(options = {}) {
|
||||
const isDragging = ref(false)
|
||||
|
||||
let bounds = null
|
||||
let cleanupSelectListener = null
|
||||
|
||||
const disableSelect = (e) => e.preventDefault()
|
||||
|
||||
const updateBounds = () => {
|
||||
if (target) {
|
||||
@@ -35,6 +38,9 @@ export function useDragControls(options = {}) {
|
||||
isDragging.value = true
|
||||
updateBounds()
|
||||
move(e)
|
||||
|
||||
// Disable text selection
|
||||
cleanupSelectListener = useEventListener('selectstart', disableSelect)
|
||||
}
|
||||
|
||||
const move = (e) => {
|
||||
@@ -49,6 +55,8 @@ export function useDragControls(options = {}) {
|
||||
|
||||
const end = () => {
|
||||
isDragging.value = false
|
||||
|
||||
cleanupSelectListener?.()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<main class="note layout-block">
|
||||
<note-download :title="editorRef?.title" :editor="editorRef?.editor" />
|
||||
<note-download :title="note.title" :editor="editorRef?.editor" />
|
||||
|
||||
<note-find
|
||||
:editor="editorRef?.editor"
|
||||
:visible="findVisible"
|
||||
@close="findVisible = false"
|
||||
/>
|
||||
<note-editor ref="editorRef" :id="id" />
|
||||
<note-editor :note="note" ref="editorRef" />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
import { ref, watchEffect } from 'vue'
|
||||
import { useMagicKeys } from '@vueuse/core'
|
||||
import { useRoute } from 'vue-router'
|
||||
import useNotes from '@/composables/useNotes'
|
||||
import NoteEditor from '@/components/note/Editor.vue'
|
||||
import NoteFind from '@/components/note/Find.vue'
|
||||
import NoteDownload from '@/components/note/Download.vue'
|
||||
@@ -22,9 +23,13 @@ import NoteDownload from '@/components/note/Download.vue'
|
||||
const route = useRoute()
|
||||
const id = route.params.id
|
||||
|
||||
const { loadNote } = useNotes()
|
||||
const note = await loadNote(id)
|
||||
|
||||
const editorRef = ref(null)
|
||||
const findVisible = ref(false)
|
||||
|
||||
// Find shortcut
|
||||
const { ctrl, f } = useMagicKeys()
|
||||
watchEffect(() => {
|
||||
if (ctrl.value && f.value) {
|
||||
|
||||
Reference in New Issue
Block a user