mirror of
https://github.com/0PandaDEV/Qopy.git
synced 2025-04-21 05:14:03 +02:00
feat: add Result component for displaying history items with dynamic content rendering
This commit is contained in:
parent
7b624bd352
commit
180664c0fd
3 changed files with 151 additions and 7 deletions
30
app.vue
30
app.vue
|
@ -1,5 +1,6 @@
|
|||
<template>
|
||||
<div style="pointer-events: auto">
|
||||
<div>
|
||||
<Noise />
|
||||
<NuxtPage />
|
||||
</div>
|
||||
</template>
|
||||
|
@ -12,7 +13,7 @@ import { onMounted } from "vue";
|
|||
import { keyboard } from "wrdu-keyboard";
|
||||
|
||||
const { $settings } = useNuxtApp();
|
||||
keyboard.init()
|
||||
keyboard.init();
|
||||
|
||||
onMounted(async () => {
|
||||
await listen("settings", async () => {
|
||||
|
@ -58,6 +59,24 @@ onMounted(async () => {
|
|||
src: url("~/assets/fonts/CommitMono.woff2") format("woff2");
|
||||
}
|
||||
|
||||
:root {
|
||||
--background: #2e2d2b;
|
||||
--accent: #feb453;
|
||||
--border: #ffffff0d;
|
||||
|
||||
--text: #e5dfd5;
|
||||
--text-secondary: #ada9a1;
|
||||
--text-muted: #78756f;
|
||||
|
||||
--sidebar-width: 286px;
|
||||
--bottom-bar-height: 39px;
|
||||
--info-panel-height: 160px;
|
||||
--content-view-height: calc(
|
||||
100% - var(--search-height) - var(--info-panel-height) -
|
||||
var(--bottom-bar-height)
|
||||
);
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
@ -66,9 +85,6 @@ onMounted(async () => {
|
|||
font-family: SFRoundedRegular;
|
||||
scroll-behavior: smooth;
|
||||
scrollbar-width: thin;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
--os-handle-bg: #ada9a1;
|
||||
--os-handle-bg-hover: #78756f;
|
||||
|
@ -80,8 +96,8 @@ body {
|
|||
background-color: transparent;
|
||||
width: 750px;
|
||||
height: 474px;
|
||||
user-select: none !important;
|
||||
pointer-events: none !important;
|
||||
z-index: -1;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.os-scrollbar-horizontal {
|
||||
|
|
121
components/Result.vue
Normal file
121
components/Result.vue
Normal file
|
@ -0,0 +1,121 @@
|
|||
<template>
|
||||
<div
|
||||
:class="['result clothoid-corner', { selected }]"
|
||||
@click="$emit('select')"
|
||||
:ref="el => { if (selected && el) $emit('setRef', el as HTMLElement) }">
|
||||
<template v-if="item.content_type === 'image'">
|
||||
<img
|
||||
v-if="imageUrl"
|
||||
:src="imageUrl"
|
||||
alt="Image"
|
||||
class="image"
|
||||
@error="$emit('imageError')" />
|
||||
<IconsImage v-else class="icon" />
|
||||
</template>
|
||||
<template v-else-if="hasFavicon(item.favicon ?? '')">
|
||||
<img
|
||||
v-if="item.favicon"
|
||||
:src="getFaviconFromDb(item.favicon)"
|
||||
alt="Favicon"
|
||||
class="favicon"
|
||||
@error="
|
||||
($event.target as HTMLImageElement).src = '/public/icons/Link.svg'
|
||||
" />
|
||||
<IconsLink v-else class="icon" />
|
||||
</template>
|
||||
<IconsFile
|
||||
class="icon"
|
||||
v-else-if="item.content_type === ContentType.File" />
|
||||
<IconsText
|
||||
class="icon"
|
||||
v-else-if="item.content_type === ContentType.Text" />
|
||||
<svg
|
||||
v-else-if="item.content_type === ContentType.Color"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 18 18"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<rect width="18" height="18" />
|
||||
<path
|
||||
d="M9 18C12.2154 18 15.1865 16.2846 16.7942 13.5C18.4019 10.7154 18.4019 7.28461 16.7942 4.5C15.1865 1.71539 12.2154 -1.22615e-06 9 0C5.78461 0 2.81347 1.71539 1.20577 4.5C-0.401925 7.28461 -0.401923 10.7154 1.20577 13.5C2.81347 16.2846 5.78461 18 9 18Z"
|
||||
fill="#E5DFD5" />
|
||||
<path
|
||||
d="M9 16C7.14348 16 5.36301 15.2625 4.05025 13.9497C2.7375 12.637 2 10.8565 2 9C2 7.14348 2.7375 5.36301 4.05025 4.05025C5.36301 2.7375 7.14348 2 9 2C10.8565 2 12.637 2.7375 13.9497 4.05025C15.2625 5.36301 16 7.14348 16 9C16 10.8565 15.2625 12.637 13.9497 13.9497C12.637 15.2625 10.8565 16 9 16Z"
|
||||
:fill="item.content" />
|
||||
</g>
|
||||
</svg>
|
||||
<IconsCode
|
||||
class="icon"
|
||||
v-else-if="item.content_type === ContentType.Code" />
|
||||
<span v-if="item.content_type === ContentType.Image">
|
||||
Image ({{ dimensions || "Loading..." }})
|
||||
</span>
|
||||
<span v-else>{{ truncateContent(item.content) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ContentType } from "~/types/types";
|
||||
import type { HistoryItem } from "~/types/types";
|
||||
|
||||
defineProps<{
|
||||
item: HistoryItem;
|
||||
selected: boolean;
|
||||
imageUrl?: string;
|
||||
dimensions?: string;
|
||||
}>();
|
||||
|
||||
defineEmits<{
|
||||
(e: "select"): void;
|
||||
(e: "imageError"): void;
|
||||
(e: "setRef", el: HTMLElement): void;
|
||||
}>();
|
||||
|
||||
const hasFavicon = (str: string): boolean => {
|
||||
return str.trim() !== "";
|
||||
};
|
||||
|
||||
const getFaviconFromDb = (favicon: string): string => {
|
||||
return `data:image/png;base64,${favicon}`;
|
||||
};
|
||||
|
||||
const truncateContent = (content: string): string => {
|
||||
const maxWidth = 284;
|
||||
const charWidth = 9;
|
||||
const maxChars = Math.floor(maxWidth / charWidth);
|
||||
return content.length > maxChars
|
||||
? content.slice(0, maxChars - 3) + "..."
|
||||
: content;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.result {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding: 11px;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
|
||||
&.selected {
|
||||
background-color: var(--border);
|
||||
}
|
||||
|
||||
.favicon,
|
||||
.image,
|
||||
.icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
span {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: var(--text);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -3,6 +3,13 @@ export default defineNuxtConfig({
|
|||
devtools: { enabled: false },
|
||||
compatibilityDate: "2024-07-04",
|
||||
ssr: false,
|
||||
app: {
|
||||
head: {
|
||||
charset: "utf-8",
|
||||
viewport:
|
||||
"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0",
|
||||
},
|
||||
},
|
||||
vite: {
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue