feat: implement DraggableWindow component and update index.vue layout; enhance scraping scripts for better error handling and content extraction

This commit is contained in:
yuanhau 2025-05-12 00:39:28 +08:00
parent 8b07d4b3be
commit b461e81360
8 changed files with 522 additions and 174 deletions

View file

@ -0,0 +1,87 @@
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
const props = defineProps<{
title: string
initialX?: number
initialY?: number
width?: string
height?: string
}>()
const emit = defineEmits(['close'])
const isDragging = ref(false)
const position = ref({
x: props.initialX || 100,
y: props.initialY || 100
})
const offset = ref({ x: 0, y: 0 })
const startDrag = (e: MouseEvent) => {
isDragging.value = true
offset.value = {
x: e.clientX - position.value.x,
y: e.clientY - position.value.y
}
}
const doDrag = (e: MouseEvent) => {
if (isDragging.value) {
position.value = {
x: e.clientX - offset.value.x,
y: e.clientY - offset.value.y
}
}
}
const stopDrag = () => {
isDragging.value = false
}
onMounted(() => {
document.addEventListener('mousemove', doDrag)
document.addEventListener('mouseup', stopDrag)
})
onUnmounted(() => {
document.removeEventListener('mousemove', doDrag)
document.removeEventListener('mouseup', stopDrag)
})
</script>
<template>
<div
:style="{
left: `${position.x}px`,
top: `${position.y}px`,
width: props.width || '400px',
height: props.height || '300px'
}"
class="fixed bg-white dark:bg-gray-800 rounded-lg shadow-lg overflow-hidden"
>
<div
@mousedown="startDrag"
class="bg-gray-700 p-2 cursor-move flex justify-between items-center"
>
<h3 class="font-semibold">{{ title }}</h3>
<div class="flex flex-row gap-1">
<button
@click="emit('close')"
class="p-1 hover:bg-gray-300 dark:hover:bg-gray-600 rounded"
>
</button>
<button
@click="emit('close')"
class="p-1 rounded bg-red-500 text-white hover:bg-red-600 transition duration-200"
>
</button>
</div>
</div>
<div class="p-4 text-black">
<slot></slot>
</div>
</div>
</template>