import { Link } from "react-router"; import { MdConnectWithoutContact } from "react-icons/md"; import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react"; import { LuEllipsisVertical } from "react-icons/lu"; import semver from "semver"; import { useMemo } from "react"; import Card from "@components/Card"; import { Button, LinkButton } from "@components/Button"; import { m } from "@localizations/messages.js"; function getRelativeTimeString(date: Date | number, lang = navigator.language): string { // Allow dates or times to be passed const timeMs = typeof date === "number" ? date : date.getTime(); // Get the amount of seconds between the given date and now const deltaSeconds = Math.round((timeMs - Date.now()) / 1000); // Array representing one minute, hour, day, week, month, etc in seconds const cutoffs = [60, 3600, 86400, 86400 * 7, 86400 * 30, 86400 * 365, Infinity]; // Array equivalent to the above but in the string representation of the units const units: Intl.RelativeTimeFormatUnit[] = [ "second", "minute", "hour", "day", "week", "month", "year", ]; // Grab the ideal cutoff unit const unitIndex = cutoffs.findIndex(cutoff => cutoff > Math.abs(deltaSeconds)); // Get the divisor to divide from the seconds. E.g. if our unit is "day" our divisor // is one day in seconds, so we can divide our seconds by this to get the # of days const divisor = unitIndex ? cutoffs[unitIndex - 1] : 1; // Intl.RelativeTimeFormat do its magic const rtf = new Intl.RelativeTimeFormat(lang, { numeric: "auto" }); return rtf.format(Math.floor(deltaSeconds / divisor), units[unitIndex]); } export default function KvmCard({ title, id, online, lastSeen, appVersion, }: { title: string; id: string; online: boolean; lastSeen: Date | null; appVersion?: string; }) { /** * Constructs the URL for connecting to this KVM device's interface. * * Version 0.4.91 is the last backwards-compatible UI that works with older devices. * Devices on v0.4.91 or below are served that version, while newer devices get * their actual version. Unparseable versions fall back to 0.4.91 for safety. */ const kvmUrl = useMemo(() => { const BACKWARDS_COMPATIBLE_VERSION = "0.5.0"; // Use device version if valid and >= 0.5.0, otherwise fall back to backwards-compatible version let version = BACKWARDS_COMPATIBLE_VERSION; if (appVersion && semver.valid(appVersion) && semver.gte(appVersion, BACKWARDS_COMPATIBLE_VERSION)) { version = appVersion; } return new URL(`/v/${version}/devices/${id}`, window.location.origin).toString(); }, [appVersion, id]); return (
{title}
{online ? (
{m.online()}
) : (
{lastSeen ? ( <>{m.last_online({ time: getRelativeTimeString(lastSeen) })} ) : ( <>{m.never_seen_online()} )}
)}
{online ? ( ) : (
{m.rename_device()}
{m.deregister_from_cloud()}
); }