feat: [frontend / backend] update git urls, update userid watermark, authenticate image proxy and url previews
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { $i } from "@/i.js";
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import { computed, onMounted, onUnmounted, ref } from "vue";
|
||||
|
||||
const generateRandomClass = () => {
|
||||
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
@@ -14,10 +14,27 @@ const generateRandomClass = () => {
|
||||
const gridClass = ref(generateRandomClass());
|
||||
const itemClasses = ref<string[]>([]);
|
||||
const recreationKey = ref(0);
|
||||
const gridItemCount = ref(600);
|
||||
let regenerationInterval: ReturnType<typeof setInterval> | null = null;
|
||||
let styleElement: HTMLStyleElement | null = null;
|
||||
let allCreatedClasses: string[] = [];
|
||||
|
||||
// Calculate grid items based on screen resolution
|
||||
const calculateGridItemCount = () => {
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
|
||||
// Grid cell size: 80px width + 10px gap, 16px height + 10px gap (more concise)
|
||||
const itemWidth = 80 + 10;
|
||||
const itemHeight = 16 + 10;
|
||||
|
||||
const columns = Math.ceil(width / itemWidth);
|
||||
const rows = Math.ceil(height / itemHeight);
|
||||
|
||||
// Add some buffer (20%) to ensure coverage during animations/scrolling
|
||||
return Math.ceil(columns * rows * 1.2);
|
||||
};
|
||||
|
||||
const encodeTextToPath = (text: string) => {
|
||||
const charPaths: { [key: string]: string } = {
|
||||
a: "M2,8 L4,2 L6,2 L8,8 M3,6 L7,6",
|
||||
@@ -77,7 +94,7 @@ const encodeTextToPath = (text: string) => {
|
||||
);
|
||||
path += translatedPath + " ";
|
||||
}
|
||||
xOffset += 10;
|
||||
xOffset += 7; // Reduced from 10 to 7 for tighter spacing
|
||||
});
|
||||
|
||||
return path.trim();
|
||||
@@ -95,7 +112,9 @@ const regenerateWatermark = () => {
|
||||
cleanupOldElements();
|
||||
|
||||
gridClass.value = generateRandomClass();
|
||||
itemClasses.value = generateItemClasses(600);
|
||||
const count = calculateGridItemCount();
|
||||
gridItemCount.value = count;
|
||||
itemClasses.value = generateItemClasses(count);
|
||||
recreationKey.value++;
|
||||
|
||||
allCreatedClasses.push(gridClass.value, ...itemClasses.value);
|
||||
@@ -140,13 +159,13 @@ const createStyleElement = () => {
|
||||
.${className} svg {
|
||||
opacity: 0.02 !important;
|
||||
width: auto !important;
|
||||
height: 12px !important;
|
||||
height: 10px !important;
|
||||
}
|
||||
|
||||
.${className} svg path {
|
||||
stroke: var(--MI_THEME-fg) !important;
|
||||
fill: none !important;
|
||||
stroke-width: 1 !important;
|
||||
stroke-width: 0.8 !important;
|
||||
}
|
||||
`,
|
||||
)
|
||||
@@ -160,10 +179,10 @@ const createStyleElement = () => {
|
||||
width: 100vw !important;
|
||||
height: 100vh !important;
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)) !important;
|
||||
grid-template-rows: repeat(auto-fill, minmax(20px, 1fr)) !important;
|
||||
gap: 20px !important;
|
||||
padding: 20px !important;
|
||||
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)) !important;
|
||||
grid-template-rows: repeat(auto-fill, minmax(16px, 1fr)) !important;
|
||||
gap: 10px !important;
|
||||
padding: 10px !important;
|
||||
pointer-events: none !important;
|
||||
z-index: 999999999 !important;
|
||||
overflow: hidden !important;
|
||||
@@ -177,24 +196,51 @@ const createStyleElement = () => {
|
||||
|
||||
const watermarkText = computed(() => $i?.id || "not signed in");
|
||||
const pathData = computed(() => encodeTextToPath(watermarkText.value));
|
||||
const textWidth = computed(() => watermarkText.value.length * 10 + 10);
|
||||
const textWidth = computed(() => watermarkText.value.length * 7 + 10); // Adjusted for tighter spacing
|
||||
|
||||
let resizeTimeout: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
const handleResize = () => {
|
||||
if (resizeTimeout) clearTimeout(resizeTimeout);
|
||||
|
||||
// Debounce resize to avoid excessive recalculations
|
||||
resizeTimeout = setTimeout(() => {
|
||||
regenerateWatermark();
|
||||
}, 250);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
itemClasses.value = generateItemClasses(600);
|
||||
const count = calculateGridItemCount();
|
||||
gridItemCount.value = count;
|
||||
itemClasses.value = generateItemClasses(count);
|
||||
allCreatedClasses.push(gridClass.value, ...itemClasses.value);
|
||||
createStyleElement();
|
||||
|
||||
regenerationInterval = setInterval(() => {
|
||||
itemClasses.value = generateItemClasses(600);
|
||||
const count = calculateGridItemCount();
|
||||
gridItemCount.value = count;
|
||||
itemClasses.value = generateItemClasses(count);
|
||||
allCreatedClasses.push(gridClass.value, ...itemClasses.value);
|
||||
regenerateWatermark();
|
||||
}, 5000);
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (regenerationInterval) clearInterval(regenerationInterval);
|
||||
if (resizeTimeout) clearTimeout(resizeTimeout);
|
||||
window.removeEventListener("resize", handleResize);
|
||||
cleanupOldElements();
|
||||
if (styleElement && styleElement.parentNode) {
|
||||
styleElement.parentNode.removeChild(styleElement);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :key="`watermark-${recreationKey}`" :class="gridClass">
|
||||
<div v-for="n in 600" :key="n" :class="itemClasses[n]">
|
||||
<div v-for="n in gridItemCount" :key="n" :class="itemClasses[n]">
|
||||
<svg :viewBox="`0 0 ${textWidth} 10`" xmlns="http://www.w3.org/2000/svg">
|
||||
<path :d="pathData" />
|
||||
</svg>
|
||||
|
||||
Reference in New Issue
Block a user