Compare commits

...

7 Commits

Author SHA1 Message Date
hamster1963
ac5c7e801d update: v1.6.8 2024-12-03 18:27:36 +08:00
hamster1963
950a20f60c fix: sort 2024-12-03 18:27:08 +08:00
hamster1963
1f4c58457d update: v1.6.7-fix 2024-12-03 17:12:28 +08:00
hamster1963
c40e3706cd style(overview): speed text 2024-12-03 17:12:05 +08:00
hamster1963
3671da354b update: v1.6.7 2024-12-03 16:25:38 +08:00
hamster1963
ccc875fb04 refactor(overview): sort by speed 2024-12-03 16:24:12 +08:00
hamster1963
34f29420df feat: live speed 2024-12-03 16:15:55 +08:00
14 changed files with 77 additions and 48 deletions

View File

@ -62,7 +62,7 @@ jobs:
uses: oven-sh/setup-bun@v1 uses: oven-sh/setup-bun@v1
with: with:
bun-version: "latest" bun-version: "latest"
- name: Changelog - name: Changelog
run: bun x changelogithub run: bun x changelogithub
env: env:

View File

@ -107,12 +107,14 @@ export default function ServerListClient() {
: filteredServersByStatus.filter((server) => server.tag === tag); : filteredServersByStatus.filter((server) => server.tag === tag);
if (filter) { if (filter) {
// 根据使用流量进行从高到低排序
filteredServers.sort((a, b) => { filteredServers.sort((a, b) => {
if (!a.online_status && b.online_status) return 1;
if (a.online_status && !b.online_status) return -1;
if (!a.online_status && !b.online_status) return 0;
return ( return (
b.status.NetInTransfer + b.status.NetInSpeed +
b.status.NetOutTransfer - b.status.NetOutSpeed -
(a.status.NetInTransfer + b.status.NetOutTransfer) (a.status.NetInSpeed + a.status.NetOutSpeed)
); );
}); });
} }

View File

@ -3,6 +3,7 @@
import { ServerApi } from "@/app/types/nezha-api"; import { ServerApi } from "@/app/types/nezha-api";
import { Loader } from "@/components/loading/Loader"; import { Loader } from "@/components/loading/Loader";
import { Card, CardContent } from "@/components/ui/card"; import { Card, CardContent } from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
import getEnv from "@/lib/env-entry"; import getEnv from "@/lib/env-entry";
import { useFilter } from "@/lib/network-filter-context"; import { useFilter } from "@/lib/network-filter-context";
import { useStatus } from "@/lib/status-context"; import { useStatus } from "@/lib/status-context";
@ -48,11 +49,14 @@ export default function ServerOverviewClient() {
setStatus("all"); setStatus("all");
} }
}} }}
className={cn("cursor-pointer hover:border-blue-500 transition-all", { className={cn(
"pointer-events-none": global, "cursor-pointer hover:border-blue-500 transition-all min-h-[94px]",
})} {
"pointer-events-none": global,
},
)}
> >
<CardContent className="px-6 py-3"> <CardContent className="flex h-full items-center px-6 py-3">
<section className="flex flex-col gap-1"> <section className="flex flex-col gap-1">
<p className="text-sm font-medium md:text-base"> <p className="text-sm font-medium md:text-base">
{t("p_816-881_Totalservers")} {t("p_816-881_Totalservers")}
@ -82,7 +86,7 @@ export default function ServerOverviewClient() {
} }
}} }}
className={cn( className={cn(
"cursor-pointer hover:ring-green-500 ring-1 ring-transparent transition-all", "cursor-pointer hover:ring-green-500 ring-1 ring-transparent transition-all min-h-[94px]",
{ {
"ring-green-500 ring-2 border-transparent": status === "online", "ring-green-500 ring-2 border-transparent": status === "online",
}, },
@ -91,7 +95,7 @@ export default function ServerOverviewClient() {
}, },
)} )}
> >
<CardContent className="px-6 py-3"> <CardContent className="flex h-full items-center px-6 py-3">
<section className="flex flex-col gap-1"> <section className="flex flex-col gap-1">
<p className="text-sm font-medium md:text-base"> <p className="text-sm font-medium md:text-base">
{t("p_1610-1676_Onlineservers")} {t("p_1610-1676_Onlineservers")}
@ -122,7 +126,7 @@ export default function ServerOverviewClient() {
} }
}} }}
className={cn( className={cn(
"cursor-pointer hover:ring-red-500 ring-1 ring-transparent transition-all", "cursor-pointer hover:ring-red-500 ring-1 ring-transparent transition-all min-h-[94px]",
{ {
"ring-red-500 ring-2 border-transparent": status === "offline", "ring-red-500 ring-2 border-transparent": status === "offline",
}, },
@ -131,7 +135,7 @@ export default function ServerOverviewClient() {
}, },
)} )}
> >
<CardContent className="px-6 py-3"> <CardContent className="flex h-full items-center px-6 py-3">
<section className="flex flex-col gap-1"> <section className="flex flex-col gap-1">
<p className="text-sm font-medium md:text-base"> <p className="text-sm font-medium md:text-base">
{t("p_2532-2599_Offlineservers")} {t("p_2532-2599_Offlineservers")}
@ -162,7 +166,7 @@ export default function ServerOverviewClient() {
} }
}} }}
className={cn( className={cn(
"cursor-pointer hover:ring-purple-500 ring-1 ring-transparent transition-all", "cursor-pointer hover:ring-purple-500 ring-1 ring-transparent transition-all min-h-[94px]",
{ {
"ring-purple-500 ring-2 border-transparent": filter === true, "ring-purple-500 ring-2 border-transparent": filter === true,
}, },
@ -171,20 +175,34 @@ export default function ServerOverviewClient() {
}, },
)} )}
> >
<CardContent className="relative px-6 py-3"> <CardContent className="flex h-full items-center relative px-3 py-1 pr-0 sm:px-6 sm:py-3">
<section className="flex flex-col gap-1"> <section className="flex flex-col gap-1">
<p className="text-sm font-medium md:text-base"> <div className="flex items-center gap-1">
{t("p_3463-3530_Totalbandwidth")} <p className="text-sm font-medium md:text-base">
</p> {t("p_3463-3530_Totalbandwidth")}
</p>
<Separator orientation="vertical" className="h-4 w-[1px]" />
<p className="text-sm font-medium md:text-base">{t("speed")}</p>
</div>
{data?.result ? ( {data?.result ? (
<section className="flex flex-col sm:flex-row pt-[8px] sm:items-center items-start gap-1"> <>
<p className="text-[12px] text-nowrap font-semibold"> <section className="flex flex-row sm:items-center items-start gap-1">
{formatBytes(data?.total_out_bandwidth)} <p className="sm:text-[12px] text-[10px] text-stone-400 text-nowrap font-medium">
</p> {formatBytes(data?.total_out_bandwidth)}
<p className="text-[12px] text-nowrap font-semibold"> </p>
{formatBytes(data?.total_in_bandwidth)} <p className="sm:text-[12px] text-[10px] text-stone-400 text-nowrap font-medium">
</p> {formatBytes(data?.total_in_bandwidth)}
</section> </p>
</section>
<section className="flex flex-row -mt-1 -mr-1 sm:items-center items-start gap-1">
<p className="sm:text-[12px] text-[10px] text-nowrap font-semibold">
{formatBytes(data?.total_out_speed)}/s
</p>
<p className="sm:text-[12px] text-[10px] text-nowrap font-semibold">
{formatBytes(data?.total_in_speed)}/s
</p>
</section>
</>
) : ( ) : (
<div className="flex h-7 items-center"> <div className="flex h-7 items-center">
<Loader visible={true} /> <Loader visible={true} />

View File

@ -5,8 +5,6 @@ import { Suspense } from "react";
import ServerGlobal from "./ClientComponents/Global"; import ServerGlobal from "./ClientComponents/Global";
import GlobalLoading from "./ClientComponents/GlobalLoading"; import GlobalLoading from "./ClientComponents/GlobalLoading";
export const runtime = "edge";
export default async function Home({ export default async function Home({
searchParams, searchParams,
}: { }: {

View File

@ -1,6 +1,6 @@
// @auto-i18n-check. Please do not delete the line. // @auto-i18n-check. Please do not delete the line.
import { MotionProvider } from "@/components/motion/motion-provider";
import { ThemeColorManager } from "@/components/ThemeColorManager"; import { ThemeColorManager } from "@/components/ThemeColorManager";
import { MotionProvider } from "@/components/motion/motion-provider";
import getEnv from "@/lib/env-entry"; import getEnv from "@/lib/env-entry";
import { FilterProvider } from "@/lib/network-filter-context"; import { FilterProvider } from "@/lib/network-filter-context";
import { StatusProvider } from "@/lib/status-context"; import { StatusProvider } from "@/lib/status-context";

View File

@ -4,8 +4,6 @@ import Link from "next/link";
import Footer from "./(main)/footer"; import Footer from "./(main)/footer";
import Header from "./(main)/header"; import Header from "./(main)/header";
export const runtime = "edge";
export default function NotFoundPage() { export default function NotFoundPage() {
const t = useTranslations("NotFoundPage"); const t = useTranslations("NotFoundPage");
return ( return (

View File

@ -3,6 +3,8 @@ export type ServerApi = {
offline_servers: number; offline_servers: number;
total_out_bandwidth: number; total_out_bandwidth: number;
total_in_bandwidth: number; total_in_bandwidth: number;
total_out_speed: number;
total_in_speed: number;
result: NezhaAPISafe[]; result: NezhaAPISafe[];
}; };

View File

@ -1,37 +1,40 @@
'use client'; "use client";
import { useEffect } from 'react'; import { useTheme } from "next-themes";
import { useTheme } from 'next-themes'; import { useEffect } from "react";
export function ThemeColorManager() { export function ThemeColorManager() {
const { theme, systemTheme } = useTheme(); const { theme, systemTheme } = useTheme();
useEffect(() => { useEffect(() => {
const updateThemeColor = () => { const updateThemeColor = () => {
const currentTheme = theme === 'system' ? systemTheme : theme; const currentTheme = theme === "system" ? systemTheme : theme;
const meta = document.querySelector('meta[name="theme-color"]'); const meta = document.querySelector('meta[name="theme-color"]');
if (!meta) { if (!meta) {
const newMeta = document.createElement('meta'); const newMeta = document.createElement("meta");
newMeta.name = 'theme-color'; newMeta.name = "theme-color";
document.head.appendChild(newMeta); document.head.appendChild(newMeta);
} }
const themeColor = currentTheme === 'dark' const themeColor =
? 'hsl(30 15% 8%)' // 深色模式背景色 currentTheme === "dark"
: 'hsl(0 0% 98%)'; // 浅色模式背景色 ? "hsl(30 15% 8%)" // 深色模式背景色
: "hsl(0 0% 98%)"; // 浅色模式背景色
document.querySelector('meta[name="theme-color"]')?.setAttribute('content', themeColor);
document
.querySelector('meta[name="theme-color"]')
?.setAttribute("content", themeColor);
}; };
// Update on mount and theme change // Update on mount and theme change
updateThemeColor(); updateThemeColor();
// Listen for system theme changes // Listen for system theme changes
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
mediaQuery.addEventListener('change', updateThemeColor); mediaQuery.addEventListener("change", updateThemeColor);
return () => mediaQuery.removeEventListener('change', updateThemeColor); return () => mediaQuery.removeEventListener("change", updateThemeColor);
}, [theme, systemTheme]); }, [theme, systemTheme]);
return null; return null;

View File

@ -44,6 +44,8 @@ export async function GetNezhaData() {
offline_servers: 0, offline_servers: 0,
total_out_bandwidth: 0, total_out_bandwidth: 0,
total_in_bandwidth: 0, total_in_bandwidth: 0,
total_in_speed: 0,
total_out_speed: 0,
result: [], result: [],
}; };
@ -66,6 +68,8 @@ export async function GetNezhaData() {
data.total_out_bandwidth += element.status.NetOutTransfer; data.total_out_bandwidth += element.status.NetOutTransfer;
data.total_in_bandwidth += element.status.NetInTransfer; data.total_in_bandwidth += element.status.NetInTransfer;
data.total_in_speed += element.status.NetInSpeed;
data.total_out_speed += element.status.NetOutSpeed;
// Remove unwanted properties // Remove unwanted properties
delete element.ipv4; delete element.ipv4;

View File

@ -4,6 +4,7 @@
"p_1610-1676_Onlineservers": "Online servers", "p_1610-1676_Onlineservers": "Online servers",
"p_2532-2599_Offlineservers": "Offline servers", "p_2532-2599_Offlineservers": "Offline servers",
"p_3463-3530_Totalbandwidth": "Total bandwidth", "p_3463-3530_Totalbandwidth": "Total bandwidth",
"speed": "speed",
"error_message": "Please check your environment variables and review the server console", "error_message": "Please check your environment variables and review the server console",
"no_data_message": "No data" "no_data_message": "No data"
}, },

View File

@ -4,6 +4,7 @@
"p_1610-1676_Onlineservers": "オンラインサーバー", "p_1610-1676_Onlineservers": "オンラインサーバー",
"p_2532-2599_Offlineservers": "オフラインサーバー", "p_2532-2599_Offlineservers": "オフラインサーバー",
"p_3463-3530_Totalbandwidth": "総流量", "p_3463-3530_Totalbandwidth": "総流量",
"speed": "速度",
"error_message": "環境変数を確認し、サーバーコンソールを確認してください", "error_message": "環境変数を確認し、サーバーコンソールを確認してください",
"no_data_message": "データなし" "no_data_message": "データなし"
}, },

View File

@ -4,6 +4,7 @@
"p_1610-1676_Onlineservers": "在線伺服器", "p_1610-1676_Onlineservers": "在線伺服器",
"p_2532-2599_Offlineservers": "離線伺服器", "p_2532-2599_Offlineservers": "離線伺服器",
"p_3463-3530_Totalbandwidth": "總流量", "p_3463-3530_Totalbandwidth": "總流量",
"speed": "速率",
"error_message": "請檢查您的環境變數並檢查伺服器控制台", "error_message": "請檢查您的環境變數並檢查伺服器控制台",
"no_data_message": "無資料" "no_data_message": "無資料"
}, },

View File

@ -4,6 +4,7 @@
"p_1610-1676_Onlineservers": "在线服务器", "p_1610-1676_Onlineservers": "在线服务器",
"p_2532-2599_Offlineservers": "离线服务器", "p_2532-2599_Offlineservers": "离线服务器",
"p_3463-3530_Totalbandwidth": "总流量", "p_3463-3530_Totalbandwidth": "总流量",
"speed": "速率",
"error_message": "请检查您的环境变量并检查服务器控制台", "error_message": "请检查您的环境变量并检查服务器控制台",
"no_data_message": "无数据" "no_data_message": "无数据"
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "nezha-dash", "name": "nezha-dash",
"version": "1.6.6", "version": "1.6.8",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev -p 3040", "dev": "next dev -p 3040",