You've already forked obsidian-visualiser
Change explorer pages structure to isolates them from there renderers allowing to fetch data outside of the renderers
This commit is contained in:
165
components/page/Canvas.vue
Normal file
165
components/page/Canvas.vue
Normal file
@@ -0,0 +1,165 @@
|
||||
<script lang="ts">
|
||||
function cancelEvent(e: Event)
|
||||
{
|
||||
e.preventDefault();
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useDrag, useHover, usePinch, useWheel } from '@vueuse/gesture';
|
||||
import type { CanvasContent } from '~/types/canvas';
|
||||
import { Icon } from '@iconify/vue/dist/iconify.js';
|
||||
import { clamp } from '#shared/general.utils';
|
||||
|
||||
type CanvasOverview = any;
|
||||
const { overview } = defineProps<{
|
||||
overview: CanvasOverview
|
||||
}>();
|
||||
|
||||
const { data: canvas, status } = await useFetch(`/api/file/content/${encodeURIComponent(overview.path)}`, {
|
||||
transform: (input) => input && input.content ? JSON.parse(input?.content) as CanvasContent : undefined
|
||||
});
|
||||
|
||||
const { user } = useUserSession();
|
||||
const isOwner = computed(() => user.value?.id === overview.owner);
|
||||
|
||||
const dispX = ref(0), dispY = ref(0), minZoom = ref(0.1), zoom = ref(0.5);
|
||||
const canvasRef = useTemplateRef('canvasRef');
|
||||
|
||||
const reset = (_: MouseEvent) => {
|
||||
zoom.value = minZoom.value;
|
||||
|
||||
dispX.value = 0;
|
||||
dispY.value = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
stroke-light-red
|
||||
stroke-light-orange
|
||||
stroke-light-yellow
|
||||
stroke-light-green
|
||||
stroke-light-cyan
|
||||
stroke-light-purple
|
||||
dark:stroke-dark-red
|
||||
dark:stroke-dark-orange
|
||||
dark:stroke-dark-yellow
|
||||
dark:stroke-dark-green
|
||||
dark:stroke-dark-cyan
|
||||
dark:stroke-dark-purple
|
||||
fill-light-red
|
||||
fill-light-orange
|
||||
fill-light-yellow
|
||||
fill-light-green
|
||||
fill-light-cyan
|
||||
fill-light-purple
|
||||
dark:fill-dark-red
|
||||
dark:fill-dark-orange
|
||||
dark:fill-dark-yellow
|
||||
dark:fill-dark-green
|
||||
dark:fill-dark-cyan
|
||||
dark:fill-dark-purple
|
||||
bg-light-red
|
||||
bg-light-orange
|
||||
bg-light-yellow
|
||||
bg-light-green
|
||||
bg-light-cyan
|
||||
bg-light-purple
|
||||
dark:bg-dark-red
|
||||
dark:bg-dark-orange
|
||||
dark:bg-dark-yellow
|
||||
dark:bg-dark-green
|
||||
dark:bg-dark-cyan
|
||||
dark:bg-dark-purple
|
||||
border-light-red
|
||||
border-light-orange
|
||||
border-light-yellow
|
||||
border-light-green
|
||||
border-light-cyan
|
||||
border-light-purple
|
||||
dark:border-dark-red
|
||||
dark:border-dark-orange
|
||||
dark:border-dark-yellow
|
||||
dark:border-dark-green
|
||||
dark:border-dark-cyan
|
||||
dark:border-dark-purple
|
||||
|
||||
*/
|
||||
|
||||
const cancelEvent = (e: Event) => e.preventDefault()
|
||||
useHover(({ hovering }) => {
|
||||
if (!hovering) {
|
||||
//@ts-ignore
|
||||
window.removeEventListener('wheel', cancelEvent, { passive: false });
|
||||
document.removeEventListener('gesturestart', cancelEvent)
|
||||
document.removeEventListener('gesturechange', cancelEvent)
|
||||
return
|
||||
}
|
||||
|
||||
window.addEventListener('wheel', cancelEvent, { passive: false });
|
||||
document.addEventListener('gesturestart', cancelEvent)
|
||||
document.addEventListener('gesturechange', cancelEvent)
|
||||
}, {
|
||||
domTarget: canvasRef,
|
||||
})
|
||||
|
||||
const dragHandler = useDrag(({ delta: [x, y] }: { delta: number[] }) => {
|
||||
dispX.value += x / zoom.value;
|
||||
dispY.value += y / zoom.value;
|
||||
}, {
|
||||
domTarget: canvasRef,
|
||||
passive: true,
|
||||
});
|
||||
const wheelHandler = useWheel(({ delta: [x, y] }: { delta: number[] }) => {
|
||||
zoom.value = clamp(zoom.value + y * -0.001, minZoom.value, 3);
|
||||
}, {
|
||||
domTarget: canvasRef,
|
||||
passive: true,
|
||||
});
|
||||
const pinchHandler = usePinch(({ offset: [z] }: { offset: number[] }) => {
|
||||
zoom.value = clamp(z / 2048, minZoom.value, 3);
|
||||
}, {
|
||||
domTarget: canvasRef,
|
||||
passive: true,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Loading v-if="status === 'pending'" />
|
||||
<div v-else-if="canvas">
|
||||
<div ref="canvasRef" class="absolute top-0 left-0 overflow-hidden w-full h-full touch-none" :style="{ '--zoom-multiplier': (1 / Math.pow(zoom, 0.7)) }">
|
||||
<div class="flex flex-col absolute sm:top-2 top-10 left-2 z-[35] overflow-hidden gap-4">
|
||||
<div class="border border-light-35 dark:border-dark-35 bg-light-10 dark:bg-dark-10">
|
||||
<Tooltip message="Zoom avant" side="right">
|
||||
<div @click="zoom = clamp(zoom * 1.1, minZoom, 3)" class="w-8 h-8 flex justify-center items-center p-2 hover:bg-light-30 dark:hover:bg-dark-30 cursor-pointer">
|
||||
<Icon icon="radix-icons:plus" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip message="Reset" side="right">
|
||||
<div @click="zoom = 1" class="w-8 h-8 flex justify-center items-center p-2 hover:bg-light-30 dark:hover:bg-dark-30 cursor-pointer">
|
||||
<Icon icon="radix-icons:reload" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip message="Tout contenir" side="right">
|
||||
<div @click="reset" class="w-8 h-8 flex justify-center items-center p-2 hover:bg-light-30 dark:hover:bg-dark-30 cursor-pointer">
|
||||
<Icon icon="radix-icons:corners" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip message="Zoom arrière" side="right">
|
||||
<div @click="zoom = clamp(zoom * 0.9, minZoom, 3)" class="w-8 h-8 flex justify-center items-center p-2 hover:bg-light-30 dark:hover:bg-dark-30 cursor-pointer">
|
||||
<Icon icon="radix-icons:minus" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div class="border border-light-35 dark:border-dark-35 bg-light-10 dark:bg-dark-10" v-if="isOwner">
|
||||
<Tooltip message="Modifier" side="right">
|
||||
<NuxtLink :to="{ name: 'explore-edit', hash: '#' + overview.path }" class="w-8 h-8 flex justify-center items-center p-2 hover:bg-light-30 dark:hover:bg-dark-30 cursor-pointer">
|
||||
<Icon icon="radix-icons:pencil-1" />
|
||||
</NuxtLink>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<CanvasRenderer :style="{transform: `scale(${zoom}) translate(${dispX}px, ${dispY}px)`}" :canvas="canvas" :zoom="zoom" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
26
components/page/Markdown.vue
Normal file
26
components/page/Markdown.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
type MarkdownOverview = any;
|
||||
const { overview } = defineProps<{
|
||||
overview: MarkdownOverview
|
||||
}>();
|
||||
|
||||
const { data: content, status } = await useFetch(`/api/file/content/${encodeURIComponent(overview.path)}`, { watch: [overview] });
|
||||
|
||||
const { user } = useUserSession();
|
||||
const isOwner = computed(() => user.value?.id === overview.owner);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-1 justify-start items-start flex-col xl:px-24 md:px-8 px-4 py-6">
|
||||
<Loading v-if="status === 'pending'" />
|
||||
<template v-else>
|
||||
<div class="flex flex-1 flex-row justify-between items-center">
|
||||
<ProseH1>{{ overview.title }}</ProseH1>
|
||||
<div class="flex gap-4">
|
||||
<NuxtLink :href="{ name: 'explore-edit', hash: '#' + overview.path }" v-if="isOwner"><Button>Modifier</Button></NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
<MarkdownRenderer v-if="content" :content="content.content" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user