Skip to content
This repository has been archived by the owner on Sep 9, 2024. It is now read-only.

Commit

Permalink
add drag feature
Browse files Browse the repository at this point in the history
  • Loading branch information
zmh-program committed Aug 5, 2023
1 parent 94d5496 commit 3e27c4a
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 13 deletions.
1 change: 1 addition & 0 deletions public/tool/add.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion src/assets/script/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ export const storage = reactive(readDictConfig({
{ "type": ToolTypes.BUILTIN, "name": "OpenAI", "link": "https://chat.openai.com", "icon": "/tool/openai.svg" },
{ "type": ToolTypes.BUILTIN, "name": "Stack Overflow", "link": "https://stackoverflow.com", "icon": "/tool/stackoverflow.svg" },
{ "type": ToolTypes.BUILTIN, "name": "Light Notes", "link": "https://notes.lightxi.com", "icon": "/tool/lightnotes.ico" },
{ "type": ToolTypes.BUILTIN, "name": "Twitter", "link": "https://twitter.com", "icon": "/tool/twitter.svg" },
{ "type": ToolTypes.BUILTIN, "name": "Cloudflare", "link": "https://dash.cloudflare.com", "icon": "/tool/cloudflare.svg" },
{ "type": ToolTypes.BUILTIN, "name": "Vercel", "link": "https://vercel.com", "icon": "/tool/vercel.svg" },
{ "type": ToolTypes.BUILTIN, "name": "Codepen", "link": "https://codepen.io", "icon": "/tool/codepen.svg" },
Expand Down
4 changes: 4 additions & 0 deletions src/assets/script/utils/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export function contains(els: Element[], target: HTMLElement): boolean {
return els.some((el: Element) => contain(el, target));
}

export function swap<T>(arr: T[], i: number, j: number) {
[arr[i], arr[j]] = [arr[j], arr[i]];
}

export function clipboard(text: string) {
const el = document.createElement("textarea");
el.value = text;
Expand Down
9 changes: 9 additions & 0 deletions src/components/InputBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ window.addEventListener('keydown', function (e) {
toggle();
}
});
window.addEventListener('contextmenu', function (e) {
e.preventDefault();
const target = e.target as HTMLElement;
const status = contains([
document.getElementById('input') as HTMLElement,
], target);
emit('update:modelValue', status);
});
</script>

<template>
Expand Down
96 changes: 85 additions & 11 deletions src/components/ToolBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import {storage} from "@/assets/script/storage";
import GithubCard from "@/components/cards/GithubCard.vue";
import {contextTool} from "@/assets/script/tool";
import Delete from "@/components/icons/delete.vue";
import {useI18n} from "vue-i18n";
import Edit from "@/components/icons/edit.vue";
import {swap} from "@/assets/script/utils/base";
const { t } = useI18n();
const props = defineProps<{
focus: boolean,
}>();
Expand Down Expand Up @@ -37,17 +41,22 @@ window.addEventListener('contextmenu', (e: MouseEvent) => {
if (!props.focus) {
e.preventDefault();
const idx = contextTool(e.target as HTMLElement);
if (!context.value && idx !== -1) {
if (!context.value && idx >= 0) {
const x = e.clientX, y = e.clientY;
let target = popupEl.value;
if (target === null) return;
target.style.left = x + 'px';
target.style.top = y + 'px';
target.style.transform = 'scale(1.03)';
setTimeout(() => target && (target.style.transform = 'scale(1)'), 250);
popupIdx.value = idx;
popup.value = true;
return;
} else if (idx === -2) {
return;
}
context.value = !context.value;
Expand All @@ -71,6 +80,7 @@ watch(popup, () => {
if (!popup.value) {
requestAnimationFrame(() => {
popupIdx.value = -1;
popupEl.value && (popupEl.value.style.transform = 'scale(.5)');
setTimeout(() => {
let target = popupEl.value;
if (target === null) return;
Expand All @@ -87,17 +97,44 @@ function redirect(uri: string) {
function remove() {
const idx = popupIdx.value;
if (idx === -1) return;
if (idx < 0) return;
storage.tools.splice(idx, 1);
popup.value = false;
}
const toolContainer = ref<HTMLElement | null>(null);
onMounted(function () {
for (const draggable of document.querySelectorAll('.draggable') as NodeListOf<HTMLElement>) {
draggable.addEventListener('dragstart', function (e: DragEvent) {
if (!e.dataTransfer) return;
e.dataTransfer.setData('text/plain', draggable.getAttribute("fy-index") as string);
e.dataTransfer.dropEffect = 'move';
});
draggable.addEventListener('dragover', function (e: DragEvent) {
e.preventDefault();
});
draggable.addEventListener('drop', function (e: DragEvent) {
if (!e.dataTransfer) return;
e.preventDefault();
const before: number = parseInt(e.dataTransfer.getData('text/plain'));
const after: number = parseInt(draggable.getAttribute("fy-index") as string);
(!(before === after || [before, after].includes(-2))) &&
swap(storage.tools, before, after);
});
}
})
</script>

<template>
<div class="popup" :class="{'active': popup}" ref="popupEl">
<div class="row" @click="">
<edit /><span>编辑</span>
</div>
<div class="row" @click="remove">
<delete />
<span>删除</span>
<delete /><span>删除</span>
</div>
</div>
<div class="scroll" ref="element">
Expand All @@ -106,16 +143,44 @@ function remove() {
<WeatherCard />
<GithubCard />
</div>
<div class="tool-container" :class="{'focus': props.focus}" v-show="!context">
<a class="tool" v-for="(tool, idx) in storage.tools" @click="redirect(tool.link)" :key="idx"
:fy-index="idx">
<img :src="tool.icon" :alt="tool.name" />
<div class="tool-container" ref="toolContainer" :class="{'focus': props.focus}" v-show="!context">
<a class="tool draggable" v-for="(tool, idx) in storage.tools" @click="redirect(tool.link)" :key="idx"
:fy-index="idx" draggable="true">
<img :src="tool.icon" :alt="tool.name" />
<div>{{ tool.name }}</div>
</a>
<a class="tool add" :fy-index="-2">
<img src="/tool/add.svg" alt="add" />
<div>{{ t('add') }}</div>
</a>
</div>
</div>
</template>

<i18n>
{
"zh": {
"add": "添加工具",
},
"en": {
"add": "Add Tool",
},
"tw": {
"add": "添加工具",
},
"ru": {
"add": "Добавить инструмент",
},
"de": {
"add": "Werkzeug hinzufügen",
},
"fr": {
"add": "Ajouter un outil",
},
"ja": {
"add": "ツールを追加",
}
}
</i18n>
<style>
.scroll {
position: absolute;
Expand All @@ -135,12 +200,14 @@ function remove() {
background: rgb(30,30,30);
border-radius: 6px;
box-shadow: 0 0 10px rgba(0,0,0,.2);
transition: .25s;
transition: .25s cubic-bezier(.60,.05,.1,1);
transform-origin: top left;
opacity: 0;
pointer-events: none;
user-select: none;
z-index: -64;
padding: 4px;
transform: scale(.5);
}
.popup .row {
Expand All @@ -161,7 +228,8 @@ function remove() {
}
.popup .row svg {
fill: #fff;
stroke: #fff;
stroke-width: 32;
width: 16px;
height: 16px;
}
Expand Down Expand Up @@ -247,6 +315,12 @@ function remove() {
padding: 20px;
fill: rgba(255,255,255,0.85);
transition: .2s;
backdrop-filter: blur(4px);
}
.tool.add img {
background: rgba(0,0,0,0.5);
fill: rgba(255,255,255,0.85);
}
.tool div {
Expand Down
2 changes: 1 addition & 1 deletion src/components/icons/delete.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M112 112l20 320c.95 18.49 14.4 32 32 32h184c17.67 0 30.87-13.51 32-32l20-320" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M80 112h352"/><path d="M192 112V72h0a23.93 23.93 0 0124-24h80a23.93 23.93 0 0124 24h0v40M256 176v224M184 176l8 224M328 176l-8 224" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M112 112l20 320c.95 18.49 14.4 32 32 32h184c17.67 0 30.87-13.51 32-32l20-320" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/><path stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M80 112h352"/><path d="M192 112V72h0a23.93 23.93 0 0124-24h80a23.93 23.93 0 0124 24h0v40M256 176v224M184 176l8 224M328 176l-8 224" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/></svg>
</template>
3 changes: 3 additions & 0 deletions src/components/icons/edit.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M208 352h-64a96 96 0 010-192h64M304 160h64a96 96 0 010 192h-64M163.29 256h187.42" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="36"/></svg>
</template>

1 comment on commit 3e27c4a

@vercel
Copy link

@vercel vercel bot commented on 3e27c4a Aug 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.