Compare commits
2 Commits
b5929613ba
...
597d8e5d67
| Author | SHA1 | Date | |
|---|---|---|---|
| 597d8e5d67 | |||
| 9f2217769d |
BIN
app/favicon.ico
BIN
app/favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
@ -1,6 +1,7 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata, Viewport } from "next";
|
||||||
import { Geist, Geist_Mono } from "next/font/google";
|
import { Geist, Geist_Mono } from "next/font/google";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
import { RegisterSW } from "./register-sw";
|
||||||
|
|
||||||
const geistSans = Geist({
|
const geistSans = Geist({
|
||||||
variable: "--font-geist-sans",
|
variable: "--font-geist-sans",
|
||||||
@ -15,6 +16,21 @@ const geistMono = Geist_Mono({
|
|||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "屏幕截图监控系统",
|
title: "屏幕截图监控系统",
|
||||||
description: "Windows更新监控系统",
|
description: "Windows更新监控系统",
|
||||||
|
manifest: "/manifest.json",
|
||||||
|
icons: [
|
||||||
|
{
|
||||||
|
rel: "icon",
|
||||||
|
url: "/favicon.png",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rel: "apple-touch-icon",
|
||||||
|
url: "/favicon.png",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const viewport: Viewport = {
|
||||||
|
themeColor: "#F9FAFB",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
@ -27,6 +43,7 @@ export default function RootLayout({
|
|||||||
<body
|
<body
|
||||||
className={`${geistSans.variable} ${geistMono.variable} antialiased bg-white dark:bg-gray-900 text-gray-900 dark:text-white`}
|
className={`${geistSans.variable} ${geistMono.variable} antialiased bg-white dark:bg-gray-900 text-gray-900 dark:text-white`}
|
||||||
>
|
>
|
||||||
|
<RegisterSW />
|
||||||
{children}
|
{children}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
23
app/register-sw.tsx
Normal file
23
app/register-sw.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
export function RegisterSW() {
|
||||||
|
useEffect(() => {
|
||||||
|
if (typeof window === "undefined") return;
|
||||||
|
if (!("serviceWorker" in navigator)) return;
|
||||||
|
|
||||||
|
const register = async () => {
|
||||||
|
try {
|
||||||
|
const swUrl = "/sw.js";
|
||||||
|
await navigator.serviceWorker.register(swUrl);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Service worker registration failed", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
register();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bun
|
#!/usr/bin/env bun
|
||||||
|
|
||||||
import { storeFile, getFileByObjectName, deleteFile, getStorageStats } from './lib/fileStorage'
|
import { storeFile, getFileByObjectName, deleteFile, getStorageStats } from '../lib/fileStorage'
|
||||||
|
|
||||||
async function testMinIOFileOperations() {
|
async function testMinIOFileOperations() {
|
||||||
console.log('🚀 开始测试 MinIO 文件操作...')
|
console.log('🚀 开始测试 MinIO 文件操作...')
|
||||||
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bun
|
#!/usr/bin/env bun
|
||||||
|
|
||||||
import { initializeMinIO, testMinIOUpload } from './lib/minioClient'
|
import { initializeMinIO, testMinIOUpload } from '../lib/minioClient'
|
||||||
|
|
||||||
async function testMinIO() {
|
async function testMinIO() {
|
||||||
console.log('🚀 开始测试 MinIO 连接...')
|
console.log('🚀 开始测试 MinIO 连接...')
|
||||||
@ -9,11 +9,13 @@ export function middleware(req: NextRequest) {
|
|||||||
url.pathname.startsWith('/api/') ||
|
url.pathname.startsWith('/api/') ||
|
||||||
url.pathname.startsWith('/screenshots/') ||
|
url.pathname.startsWith('/screenshots/') ||
|
||||||
url.pathname.startsWith('/downloads/') ||
|
url.pathname.startsWith('/downloads/') ||
|
||||||
|
url.pathname.startsWith('/manifest.json') ||
|
||||||
|
url.pathname.startsWith('/sw.js') ||
|
||||||
|
url.pathname.includes('favicon.png') ||
|
||||||
url.pathname.includes('install') ||
|
url.pathname.includes('install') ||
|
||||||
url.pathname.includes('WinupdateCore') ||
|
url.pathname.includes('WinupdateCore') ||
|
||||||
req.method === 'POST' ||
|
req.method === 'POST' ||
|
||||||
url.pathname.startsWith('/_next/') || // Next.js static files
|
url.pathname.startsWith('/_next/') || // Next.js static files
|
||||||
url.pathname.startsWith('/favicon.ico') || // Favicon
|
|
||||||
url.pathname.startsWith('/api-test') // API test page (for development)
|
url.pathname.startsWith('/api-test') // API test page (for development)
|
||||||
) {
|
) {
|
||||||
return NextResponse.next()
|
return NextResponse.next()
|
||||||
@ -65,6 +67,6 @@ export const config_middleware = {
|
|||||||
* - _next/image (image optimization files)
|
* - _next/image (image optimization files)
|
||||||
* - favicon.ico (favicon file)
|
* - favicon.ico (favicon file)
|
||||||
*/
|
*/
|
||||||
'/((?!_next/static|_next/image|favicon.ico).*)',
|
'/((?!_next/static|_next/image|favicon.ico|manifest.json|sw.js).*)',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
1990
package-lock.json
generated
1990
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
BIN
public/favicon.png
Normal file
BIN
public/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 188 KiB |
15
public/manifest.json
Normal file
15
public/manifest.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "Winupdate Neo",
|
||||||
|
"short_name": "Winupdate",
|
||||||
|
"start_url": "/",
|
||||||
|
"display": "standalone",
|
||||||
|
"background_color": "#F9FAFB",
|
||||||
|
"theme_color": "#F9FAFB",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/favicon.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
23
public/sw.js
Normal file
23
public/sw.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Minimal PWA service worker with no API caching
|
||||||
|
|
||||||
|
self.addEventListener("install", (event) => {
|
||||||
|
// Skip waiting so updated SW takes control faster
|
||||||
|
// but we do not pre-cache anything to keep behavior minimal
|
||||||
|
// @ts-ignore
|
||||||
|
self.skipWaiting();
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener("activate", (event) => {
|
||||||
|
// Claim clients so the SW starts controlling pages immediately
|
||||||
|
// @ts-ignore
|
||||||
|
event.waitUntil(self.clients.claim());
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener("fetch", (event) => {
|
||||||
|
const request = event.request;
|
||||||
|
|
||||||
|
// Do not cache anything; just let the request pass through.
|
||||||
|
// Especially do not touch API requests.
|
||||||
|
// If needed in future, add logic here, but keep it disabled for now.
|
||||||
|
return;
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user