|
@@ -1,3 +1,148 @@
|
|
|
+<script setup lang="ts">
|
|
|
+// WIP
|
|
|
+import { onMounted, onUnmounted, ref, defineExpose } from "vue";
|
|
|
+import useDragBox from "@/components/useDragBox.js";
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ id: { type: String, default: null },
|
|
|
+ column: { type: Boolean, default: true },
|
|
|
+ title: { type: String, default: null },
|
|
|
+ persist: { type: Boolean, default: false },
|
|
|
+ initial: { type: String, default: "align-top" },
|
|
|
+ minWidth: { type: Number, default: 100 },
|
|
|
+ maxWidth: { type: Number, default: 1000 },
|
|
|
+ minHeight: { type: Number, default: 100 },
|
|
|
+ maxHeight: { type: Number, default: 1000 }
|
|
|
+});
|
|
|
+
|
|
|
+const {
|
|
|
+ dragBox,
|
|
|
+ setInitialBox,
|
|
|
+ onDragBox,
|
|
|
+ resetBoxPosition,
|
|
|
+ onWindowResizeDragBox
|
|
|
+} = useDragBox();
|
|
|
+let debounceTimeout;
|
|
|
+let shown = false;
|
|
|
+
|
|
|
+onMounted(async () => {
|
|
|
+ let initial = {
|
|
|
+ top: 10,
|
|
|
+ left: 10,
|
|
|
+ width: 200,
|
|
|
+ height: 400
|
|
|
+ };
|
|
|
+ if (props.id !== null && localStorage[`box:${props.id}`]) {
|
|
|
+ const json = JSON.parse(localStorage.getItem(`box:${props.id}`));
|
|
|
+ initial = { ...initial, ...json };
|
|
|
+ shown = json.shown;
|
|
|
+ } else {
|
|
|
+ initial.top =
|
|
|
+ props.initial === "align-bottom"
|
|
|
+ ? Math.max(document.body.clientHeight - 10 - initial.height, 0)
|
|
|
+ : 10;
|
|
|
+ }
|
|
|
+ setInitialBox(initial, true);
|
|
|
+ resetBoxPosition(true);
|
|
|
+});
|
|
|
+
|
|
|
+const saveBox = () => {
|
|
|
+ if (props.id === null) return;
|
|
|
+ localStorage.setItem(
|
|
|
+ `box:${props.id}`,
|
|
|
+ JSON.stringify({
|
|
|
+ height: dragBox.height,
|
|
|
+ width: dragBox.width,
|
|
|
+ top: dragBox.top,
|
|
|
+ left: dragBox.left,
|
|
|
+ shown
|
|
|
+ })
|
|
|
+ );
|
|
|
+ setInitialBox({
|
|
|
+ top:
|
|
|
+ props.initial === "align-bottom"
|
|
|
+ ? Math.max(document.body.clientHeight - 10 - dragBox.height, 0)
|
|
|
+ : 10,
|
|
|
+ left: 10
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const setBoxDimensions = (width, height) => {
|
|
|
+ dragBox.height = Math.min(
|
|
|
+ Math.max(height, props.minHeight),
|
|
|
+ props.maxHeight,
|
|
|
+ document.body.clientHeight
|
|
|
+ );
|
|
|
+
|
|
|
+ dragBox.width = Math.min(
|
|
|
+ Math.max(width, props.minWidth),
|
|
|
+ props.maxWidth,
|
|
|
+ document.body.clientWidth
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const onResizeBox = e => {
|
|
|
+ if (e.target !== ref("box")) return;
|
|
|
+
|
|
|
+ document.onmouseup = () => {
|
|
|
+ document.onmouseup = null;
|
|
|
+
|
|
|
+ const { width, height } = e.target.style;
|
|
|
+ setBoxDimensions(
|
|
|
+ width
|
|
|
+ .split("")
|
|
|
+ .splice(0, width.length - 2)
|
|
|
+ .join(""),
|
|
|
+ height
|
|
|
+ .split("")
|
|
|
+ .splice(0, height.length - 2)
|
|
|
+ .join("")
|
|
|
+ );
|
|
|
+
|
|
|
+ saveBox();
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+const toggleBox = () => {
|
|
|
+ shown = !shown;
|
|
|
+ saveBox();
|
|
|
+};
|
|
|
+
|
|
|
+const resetBox = () => {
|
|
|
+ resetBoxPosition();
|
|
|
+ setBoxDimensions(200, 200);
|
|
|
+ saveBox();
|
|
|
+};
|
|
|
+
|
|
|
+const onWindowResize = () => {
|
|
|
+ if (debounceTimeout) clearTimeout(debounceTimeout);
|
|
|
+
|
|
|
+ debounceTimeout = setTimeout(() => {
|
|
|
+ onWindowResizeDragBox();
|
|
|
+ const { width, height } = dragBox;
|
|
|
+ setBoxDimensions(width + 0, height + 0);
|
|
|
+ saveBox();
|
|
|
+ }, 50);
|
|
|
+};
|
|
|
+
|
|
|
+onWindowResize();
|
|
|
+window.addEventListener("resize", onWindowResize);
|
|
|
+
|
|
|
+// const onDragBoxUpdate = () => {
|
|
|
+// onWindowResize();
|
|
|
+// };
|
|
|
+
|
|
|
+onUnmounted(() => {
|
|
|
+ window.removeEventListener("resize", onWindowResize);
|
|
|
+ if (debounceTimeout) clearTimeout(debounceTimeout);
|
|
|
+});
|
|
|
+
|
|
|
+defineExpose({
|
|
|
+ resetBox,
|
|
|
+ toggleBox
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
<template>
|
|
|
<div
|
|
|
ref="box"
|
|
@@ -16,7 +161,7 @@
|
|
|
@mousedown.left="onResizeBox"
|
|
|
>
|
|
|
<div class="box-header item-draggable" @mousedown.left="onDragBox">
|
|
|
- <span class="drag material-icons" @dblclick="resetBoxPosition()"
|
|
|
+ <span class="drag material-icons" @dblclick="resetBox()"
|
|
|
>drag_indicator</span
|
|
|
>
|
|
|
<span v-if="title" class="box-title" :title="title">{{
|
|
@@ -35,143 +180,6 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
-<script>
|
|
|
-import DragBox from "@/mixins/DragBox.vue";
|
|
|
-
|
|
|
-export default {
|
|
|
- mixins: [DragBox],
|
|
|
- props: {
|
|
|
- id: { type: String, default: null },
|
|
|
- column: { type: Boolean, default: true },
|
|
|
- title: { type: String, default: null },
|
|
|
- persist: { type: Boolean, default: false },
|
|
|
- initial: { type: String, default: "align-top" },
|
|
|
- minWidth: { type: Number, default: 100 },
|
|
|
- maxWidth: { type: Number, default: 1000 },
|
|
|
- minHeight: { type: Number, default: 100 },
|
|
|
- maxHeight: { type: Number, default: 1000 }
|
|
|
- },
|
|
|
- data() {
|
|
|
- return {
|
|
|
- shown: false,
|
|
|
- debounceTimeout: null
|
|
|
- };
|
|
|
- },
|
|
|
- mounted() {
|
|
|
- let initial = {
|
|
|
- top: 10,
|
|
|
- left: 10,
|
|
|
- width: 200,
|
|
|
- height: 400
|
|
|
- };
|
|
|
- if (this.id !== null && localStorage[`box:${this.id}`]) {
|
|
|
- const json = JSON.parse(localStorage.getItem(`box:${this.id}`));
|
|
|
- initial = { ...initial, ...json };
|
|
|
- this.shown = json.shown;
|
|
|
- } else {
|
|
|
- initial.top =
|
|
|
- this.initial === "align-bottom"
|
|
|
- ? Math.max(
|
|
|
- document.body.clientHeight - 10 - initial.height,
|
|
|
- 0
|
|
|
- )
|
|
|
- : 10;
|
|
|
- }
|
|
|
- this.setInitialBox(initial, true);
|
|
|
-
|
|
|
- this.$nextTick(() => {
|
|
|
- this.onWindowResize();
|
|
|
- window.addEventListener("resize", this.onWindowResize);
|
|
|
- });
|
|
|
- },
|
|
|
- unmounted() {
|
|
|
- window.removeEventListener("resize", this.onWindowResize);
|
|
|
- if (this.debounceTimeout) clearTimeout(this.debounceTimeout);
|
|
|
- },
|
|
|
- methods: {
|
|
|
- setBoxDimensions(width, height) {
|
|
|
- this.dragBox.height = Math.min(
|
|
|
- Math.max(height, this.minHeight),
|
|
|
- this.maxHeight,
|
|
|
- document.body.clientHeight
|
|
|
- );
|
|
|
-
|
|
|
- this.dragBox.width = Math.min(
|
|
|
- Math.max(width, this.minWidth),
|
|
|
- this.maxWidth,
|
|
|
- document.body.clientWidth
|
|
|
- );
|
|
|
- },
|
|
|
- onResizeBox(e) {
|
|
|
- if (e.target !== this.$refs.box) return;
|
|
|
-
|
|
|
- document.onmouseup = () => {
|
|
|
- document.onmouseup = null;
|
|
|
-
|
|
|
- const { width, height } = e.target.style;
|
|
|
- this.setBoxDimensions(
|
|
|
- width
|
|
|
- .split("")
|
|
|
- .splice(0, width.length - 2)
|
|
|
- .join(""),
|
|
|
- height
|
|
|
- .split("")
|
|
|
- .splice(0, height.length - 2)
|
|
|
- .join("")
|
|
|
- );
|
|
|
-
|
|
|
- this.saveBox();
|
|
|
- };
|
|
|
- },
|
|
|
- toggleBox() {
|
|
|
- this.shown = !this.shown;
|
|
|
- this.saveBox();
|
|
|
- },
|
|
|
- resetBoxDimensions() {
|
|
|
- this.setBoxDimensions(200, 200);
|
|
|
- this.saveBox();
|
|
|
- },
|
|
|
- saveBox() {
|
|
|
- if (this.id === null) return;
|
|
|
- localStorage.setItem(
|
|
|
- `box:${this.id}`,
|
|
|
- JSON.stringify({
|
|
|
- height: this.dragBox.height,
|
|
|
- width: this.dragBox.width,
|
|
|
- top: this.dragBox.top,
|
|
|
- left: this.dragBox.left,
|
|
|
- shown: this.shown
|
|
|
- })
|
|
|
- );
|
|
|
- this.setInitialBox({
|
|
|
- top:
|
|
|
- this.initial === "align-bottom"
|
|
|
- ? Math.max(
|
|
|
- document.body.clientHeight -
|
|
|
- 10 -
|
|
|
- this.dragBox.height,
|
|
|
- 0
|
|
|
- )
|
|
|
- : 10,
|
|
|
- left: 10
|
|
|
- });
|
|
|
- },
|
|
|
- onDragBoxUpdate() {
|
|
|
- this.onWindowResize();
|
|
|
- },
|
|
|
- onWindowResize() {
|
|
|
- if (this.debounceTimeout) clearTimeout(this.debounceTimeout);
|
|
|
-
|
|
|
- this.debounceTimeout = setTimeout(() => {
|
|
|
- const { width, height } = this.dragBox;
|
|
|
- this.setBoxDimensions(width + 0, height + 0);
|
|
|
- this.saveBox();
|
|
|
- }, 50);
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
-</script>
|
|
|
-
|
|
|
<style lang="less">
|
|
|
.night-mode .floating-box {
|
|
|
background-color: var(--dark-grey-2) !important;
|