Add support for database backups and enhance UI elements

Updates UI components and gitignore rules for database backups, adds
Facebook links to news org window, and improves desktop window title
handling.
This commit is contained in:
吳元皓 2025-05-15 10:54:39 +08:00
parent 67f574fc35
commit 94fbf1551d
8 changed files with 93 additions and 72 deletions

3
.gitignore vendored
View File

@ -29,3 +29,6 @@ __pycache__
# Sentry Config File
.env.sentry-build-plugin
*.sql
!database/*.sql

View File

@ -1,5 +1,6 @@
<script setup lang="ts">
import { GlobeAltIcon } from "@heroicons/vue/24/outline";
import { Facebook } from "lucide-vue-next";
import { gsap } from "gsap";
import { ScrambleTextPlugin } from "gsap/dist/ScrambleTextPlugin";
gsap.registerPlugin(ScrambleTextPlugin);
@ -17,7 +18,7 @@ const {
data: fetchNewsOrgInfo,
pending,
error,
} = useFetch("/api/cached/getData/fetchNewsOrgInfo", {
} = useFetch("/api/cached/getData/fetchNewsOrgInfo/2293", {
method: "POST",
headers: {
"Content-Type": "application/json",
@ -55,18 +56,23 @@ onMounted(() => {
<span class="text-ms m-1 mt-5 text-left text-wrap">{{
fetchNewsOrgInfo?.description
}}</span>
</div>
</div>
<div
class="gap-[3px] flex flex-row text-center align-center justify-center"
>
<a
:href="fetchNewsOrgInfo?.website"
target="_blank"
class="text-blue-200 hover:text-blue-300 transiton-all duration-100 flex flex-row"
class="text-gray-800 hover:text-gray-500 transiton-all duration-150 flex flex-row"
><GlobeAltIcon class="w-6 h-6" />網站</a
>
<a
:href="fetchNewsOrgInfo?.facebook"
target="_blank"
class="text-gray-800 hover:text-gray-500 transiton-all duration-150 flex flex-row"
><Facebook class="w-6 h-6" />Facebook
</a>
</div>
</div>
</div>
</div>
</div>

15
database/README.md Normal file
View File

@ -0,0 +1,15 @@
# Database contents
This is where I put the database schemas, that contains everything (the user account & password info is NOT avaiable in the backup.)
## How to import
Import the schema:
```bash
psql -d database -f database_dump.sql
```
## Hoe to create a database_dump
Type or copy This
```bash
pg_dump -U your_username -d your_database --schema-only > schema.sql
```

View File

@ -51,6 +51,7 @@
"Welcome": "Welcome",
"loading": "Loading...",
"app": {
"launchtext": "Cooking up the desktop...",
"hotnews": "Hot News",
"news": "News",
"sources": "Sources",

View File

@ -51,6 +51,7 @@
"Welcome": "歡迎",
"loading": "載入中...",
"app": {
"launchtext": "系統開機中...",
"hotnews": "熱門新聞",
"news": "新聞",
"sources": "資料來源",

View File

@ -242,16 +242,17 @@ onMounted(() => {
globalWindowVal.value.set(window.name, {
id: window.id,
title: window.title,
windowCount: 1
windowCount: 1,
});
});
})
});
const openWindow = (windowName?: string) => {
if (windowName === "leave") {
if (confirm("Are you sure?")) {
router.push(localePath("/home"));
} else {
return
return;
}
} else {
if (windowName) findAndOpenWindow(windowName);
@ -316,9 +317,13 @@ const findAndOpenWindow = (windowName: string) => {
});
currentOpenAppId.value++;
// Add to navbar
const windowNameVal2 = globalWindowVal.value.get(windowName).windowCount === 1 ? windowName : windowName + "(" + globalWindowVal.value.get(windowName).windowCount + ")"
console.log(globalWindowVal.value.get(windowName))
console.log(windowNameVal2)
const windowNameVal2 =
globalWindowVal.value.get(windowName).windowCount === 1
? windowName
: windowName +
"(" +
globalWindowVal.value.get(windowName).windowCount +
")";
currentNavBar.value.push({
name: windowNameVal2,
icon: "anything",
@ -327,7 +332,7 @@ const findAndOpenWindow = (windowName: string) => {
windowAssociated: abosluteId,
minimized: false,
});
globalWindowVal.value.get(windowName).windowCount++
globalWindowVal.value.get(windowName).windowCount++;
}
};
@ -338,7 +343,7 @@ const obtainTopWindowPosition = (windowId: string) => {
);
if (windowIndex !== -1) {
const [window] = activeWindows.value.splice(windowIndex, 1);
titleAppName.value = window.name;
titleAppName.value = window.title;
activeWindows.value.push(window);
}
}
@ -349,8 +354,8 @@ const closeWindow = (windowId: string, windowAID: string) => {
(window) => window.id !== windowId,
);
currentNavBar.value = currentNavBar.value.filter(
(window) => window.windowAssociated !== windowAID
)
(window) => window.windowAssociated !== windowAID,
);
console.log("activeWindows.value", activeWindows.value);
};
@ -366,9 +371,13 @@ const maxWindow = (windowId: string) => {};
// Title
useSeoMeta({
title: titleAppName.value + " - Desktop",
title: "Desktop",
});
watchEffect(() => {
useSeoMeta({
title: titleAppName.value + " - Desktop",
});
});
// Booting animation
onMounted(() => {
// booting animation bypass
@ -410,9 +419,7 @@ watchEffect((cleanupFn) => {
class="w-3/5 absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
/>
<br />
<span class="text-xl text-bold mt-3"
>Launching your fancy desktop...</span
>
<span class="text-xl text-bold mt-3">{{ t("app.launchtext") }}</span>
</div>
</div>
<div
@ -432,22 +439,22 @@ watchEffect((cleanupFn) => {
<button
class="flex flex-row items-center gap-x-2 text-gray-400 hover:text-gray-600 transition-all duration-100"
></button>
<div class="overflow-hidden overflow-x-auto overflow-y-hidden scrollbar-thin scrollbar-track-transparent scrollbar-thumb-white flex-nowrap whitespace-nowrap min-w-0">
<div
class="overflow-hidden overflow-x-auto overflow-y-hidden scrollbar-thin scrollbar-track-transparent scrollbar-thumb-white flex-nowrap whitespace-nowrap min-w-0"
>
<div class="flex flex-row flex-shrink-0 min-w-0">
<div
v-for="item in currentNavBar"
:key="item.name"
class="flex flex-row items-center gap-x-2 hover:bg-gray-100 transition-all duration-150 px-4 py-2 cursor-pointer group rounded-xl"
class="flex flex-row items-center gap-x-2 hover:bg-gray-100 transition-all duration-150 px-4 py-1 cursor-pointer group rounded-xl"
>
<button
@click="unMinWindow(item.windowAssociated)"
class="flex flex-row items-center gap-x-2 text-gray-400 hover:text-gray-600 transition-all duration-100"
>
<component :is="item.icon" v-if="item.icon"></component>
<span>{{ item.name }}</span>
</button>
</div>
</div>
</div>
</div>

View File

@ -1,12 +1,13 @@
export default defineEventHandler(async (event) => {
const slug = getRouterParam(event, "slug");
const body = await readBody(event);
return {
body: body,
title: "News Org 1",
slug: "taisounds",
website: "https://www.taisounds.com.tw",
website: "https://yuanhau.com",
description: "wah wah wah wah wah wah I dont fucking care",
facebook: "https://www.facebook.com/taisounds",
facebook: "https://www.facebook.csdkc",
logoUrl:
"https://cdn.discordapp.com/avatars/918723093646684180/4eecc27ac05ee8a701fa167808610c7a.jpg",
};

View File

@ -1,13 +0,0 @@
export default defineEventHandler(async (event) => {
const body = await readBody(event);
return {
0: {
id: "1",
image: "whatever",
tags: [],
title: "三立新聞",
lean: "left",
score: "40",
},
};
});