ui updates

This commit is contained in:
nicwands
2026-04-02 12:05:44 -04:00
parent ad961fd31a
commit 9cd936c256
6 changed files with 46 additions and 44 deletions

View File

@@ -1,6 +1,6 @@
<template> <template>
<div :class="['note-row', { 'move-active': moveActive }]"> <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"> <div class="title-actions">
<button class="title bold" @click="openNote(note.id)"> <button class="title bold" @click="openNote(note.id)">
{{ note.title }} {{ note.title }}
@@ -18,7 +18,6 @@
<script setup> <script setup>
import useOpenNote from '@/composables/useOpenNote' import useOpenNote from '@/composables/useOpenNote'
import useState from '@/composables/useState'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { computed } from 'vue' import { computed } from 'vue'
import { format } from 'fecha' import { format } from 'fecha'

View File

@@ -1,5 +1,5 @@
<template> <template>
<div v-if="showScrollBar" class="scroll-bar"> <div v-if="showScrollBar" :class="['scroll-bar', { active: isDragging }]">
<div class="inner" ref="inner"> <div class="inner" ref="inner">
<div class="handle" ref="handle" /> <div class="handle" ref="handle" />
</div> </div>
@@ -7,10 +7,14 @@
</template> </template>
<script setup> <script setup>
import { ref, onBeforeUnmount, computed, watch } from 'vue' import {
import { useElementSize, useWindowScroll, useWindowSize } from '@vueuse/core' useElementSize,
import Tempus from 'tempus' useWindowScroll,
useWindowSize,
useEventListener,
} from '@vueuse/core'
import { useDragControls } from '@/composables/useDragControls' import { useDragControls } from '@/composables/useDragControls'
import { ref, computed } from 'vue'
const inner = ref() const inner = ref()
const handle = ref() const handle = ref()
@@ -23,12 +27,13 @@ const { height: innerHeight } = useElementSize(inner)
const { height: handleHeight } = useElementSize(handle) const { height: handleHeight } = useElementSize(handle)
// Drag controls // Drag controls
// useDragControls({ const { isDragging } = useDragControls({
// target: handle, target: inner,
// onUpdate: ({ y }) => { onUpdate: ({ y }) => {
// console.log(y.value) if (!handle.value) return
// }, window.scrollTo(0, y.value * (documentHeight.value - wHeight.value))
// }) },
})
const updateScrollbar = () => { const updateScrollbar = () => {
const scrollHeight = documentHeight.value const scrollHeight = documentHeight.value
@@ -46,27 +51,11 @@ const updateScrollbar = () => {
} }
} }
useEventListener(window, 'scroll', updateScrollbar)
const showScrollBar = computed(() => { const showScrollBar = computed(() => {
return documentHeight.value > wHeight.value 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> </script>
<style lang="scss"> <style lang="scss">
@@ -79,6 +68,7 @@ watch(
will-change: transform; will-change: transform;
border-left: 1px solid var(--grey-100); border-left: 1px solid var(--grey-100);
background: var(--theme-bg); background: var(--theme-bg);
cursor: grab;
.inner { .inner {
height: 100%; height: 100%;
@@ -86,7 +76,7 @@ watch(
.handle { .handle {
width: 100%; width: 100%;
height: 388px; height: 70vh;
background: var(--grey-100); background: var(--grey-100);
border-radius: 20px; border-radius: 20px;
position: absolute; position: absolute;
@@ -94,5 +84,8 @@ watch(
will-change: transform; will-change: transform;
} }
} }
&.active {
cursor: grabbing;
}
} }
</style> </style>

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="note-download"> <div class="note-download">
<button @click="download"> <button v-if="noteTitle && props.editor" @click="download">
<span class="title-text">{{ noteTitle }}</span> <span class="title-text">{{ noteTitle }}</span>
<span class="extension">.md </span> <span class="extension">.md </span>
</button> </button>

View File

@@ -37,8 +37,8 @@ import EditorMenu from './Menu.vue'
const TITLE_CHAR_LIMIT = 100 const TITLE_CHAR_LIMIT = 100
const props = defineProps({ const props = defineProps({
id: { note: {
type: String, type: Object,
required: true, required: true,
}, },
}) })
@@ -53,23 +53,20 @@ const onUpdate = _debounce(async ({ editor }) => {
const json = editor.getJSON() const json = editor.getJSON()
const text = editor.getText() const text = editor.getText()
await updateNote(props.id, { await updateNote(props.note.id, {
content: json, content: json,
plainText: text, plainText: text,
}) })
}, 500) }, 500)
onMounted(async () => { onMounted(async () => {
const note = await loadNote(props.id) if (props.note.title !== 'Untitled') {
if (!note) return title.value = props.note.title || ''
if (note.title !== 'Untitled') {
title.value = note.title || ''
} }
editor.value = new Editor({ editor.value = new Editor({
extensions, extensions,
content: note.content || [], content: props.note.content || [],
onUpdate: onUpdate, onUpdate: onUpdate,
}) })
@@ -95,7 +92,7 @@ watch(title, async (newVal) => {
} }
}) })
const updateTitle = _debounce((title) => { const updateTitle = _debounce((title) => {
updateNote(props.id, { updateNote(props.note.id, {
title: title === '' ? 'Untitled' : title, title: title === '' ? 'Untitled' : title,
}) })
}, 500) }, 500)

View File

@@ -9,6 +9,9 @@ export function useDragControls(options = {}) {
const isDragging = ref(false) const isDragging = ref(false)
let bounds = null let bounds = null
let cleanupSelectListener = null
const disableSelect = (e) => e.preventDefault()
const updateBounds = () => { const updateBounds = () => {
if (target) { if (target) {
@@ -35,6 +38,9 @@ export function useDragControls(options = {}) {
isDragging.value = true isDragging.value = true
updateBounds() updateBounds()
move(e) move(e)
// Disable text selection
cleanupSelectListener = useEventListener('selectstart', disableSelect)
} }
const move = (e) => { const move = (e) => {
@@ -49,6 +55,8 @@ export function useDragControls(options = {}) {
const end = () => { const end = () => {
isDragging.value = false isDragging.value = false
cleanupSelectListener?.()
} }
onMounted(() => { onMounted(() => {

View File

@@ -1,13 +1,13 @@
<template> <template>
<main class="note layout-block"> <main class="note layout-block">
<note-download :title="editorRef?.title" :editor="editorRef?.editor" /> <note-download :title="note.title" :editor="editorRef?.editor" />
<note-find <note-find
:editor="editorRef?.editor" :editor="editorRef?.editor"
:visible="findVisible" :visible="findVisible"
@close="findVisible = false" @close="findVisible = false"
/> />
<note-editor ref="editorRef" :id="id" /> <note-editor :note="note" ref="editorRef" />
</main> </main>
</template> </template>
@@ -15,6 +15,7 @@
import { ref, watchEffect } from 'vue' import { ref, watchEffect } from 'vue'
import { useMagicKeys } from '@vueuse/core' import { useMagicKeys } from '@vueuse/core'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import useNotes from '@/composables/useNotes'
import NoteEditor from '@/components/note/Editor.vue' import NoteEditor from '@/components/note/Editor.vue'
import NoteFind from '@/components/note/Find.vue' import NoteFind from '@/components/note/Find.vue'
import NoteDownload from '@/components/note/Download.vue' import NoteDownload from '@/components/note/Download.vue'
@@ -22,9 +23,13 @@ import NoteDownload from '@/components/note/Download.vue'
const route = useRoute() const route = useRoute()
const id = route.params.id const id = route.params.id
const { loadNote } = useNotes()
const note = await loadNote(id)
const editorRef = ref(null) const editorRef = ref(null)
const findVisible = ref(false) const findVisible = ref(false)
// Find shortcut
const { ctrl, f } = useMagicKeys() const { ctrl, f } = useMagicKeys()
watchEffect(() => { watchEffect(() => {
if (ctrl.value && f.value) { if (ctrl.value && f.value) {