Browse Source

Add commit sha to footer. (#636)

* feat: added commit sha to footer.

* added translation

* added padding

* updated styling
pull/637/head
Dan Ditomaso 1 year ago
committed by GitHub
parent
commit
df036d3904
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      package.json
  2. 229
      src/components/DeviceInfoPanel.tsx
  3. 2
      src/components/PageLayout.tsx
  4. 4
      src/components/Sidebar.tsx
  5. 13
      src/components/UI/Footer.tsx
  6. 4
      src/components/UI/Sidebar/SidebarButton.tsx
  7. 3
      src/i18n/locales/en/ui.json

2
package.json

@ -11,7 +11,7 @@
"lint:fix": "deno lint --fix src/",
"format": "deno fmt src/",
"dev": "deno task dev:ui",
"dev:ui": "deno run -A npm:vite dev",
"dev:ui": "VITE_APP_VERSION=development deno run -A npm:vite dev",
"test": "deno run -A npm:vitest",
"preview": "deno run -A npm:vite preview",
"package": "gzipper c -i html,js,css,png,ico,svg,webmanifest,txt dist dist/output && tar -cvf dist/build.tar -C ./dist/output/ ."

229
src/components/DeviceInfoPanel.tsx

@ -2,7 +2,7 @@ import { cn } from "@core/utils/cn.ts";
import {
CpuIcon,
Languages,
LucideIcon,
type LucideIcon,
Palette,
PenLine,
Search as SearchIcon,
@ -11,7 +11,7 @@ import {
import BatteryStatus from "./BatteryStatus.tsx";
import { Subtle } from "./UI/Typography/Subtle.tsx";
import { Avatar } from "./UI/Avatar.tsx";
import { DeviceMetrics } from "./types.ts";
import type { DeviceMetrics } from "./types.ts";
import { Button } from "./UI/Button.tsx";
import React, { Fragment } from "react";
import { useTranslation } from "react-i18next";
@ -110,131 +110,130 @@ export const DeviceInfoPanel = ({
];
return (
<div className="p-1">
<div className="flex flex-col">
<div
className={cn(
"flex items-center gap-3 p-1",
isCollapsed && "justify-center",
)}
>
<Avatar
text={user.shortName}
className={cn("flex-shrink-0", isCollapsed && "")}
size="sm"
/>
{!isCollapsed && (
<p
className={cn(
"text-sm font-medium text-gray-800 dark:text-gray-200",
"transition-opacity duration-300 ease-in-out",
)}
>
{user.longName}
</p>
)}
</div>
<>
<div
className={cn(
"flex items-center gap-3 p-1 flex-shrink-0",
isCollapsed && "justify-center",
)}
>
<Avatar
text={user.shortName}
className={cn("flex-shrink-0", isCollapsed && "")}
size="sm"
/>
{!isCollapsed && (
<div className="my-2 h-px bg-gray-200 dark:bg-gray-700"></div>
<p
className={cn(
"text-sm font-medium text-gray-800 dark:text-gray-200",
"transition-opacity duration-300 ease-in-out truncate",
)}
>
{user.longName}
</p>
)}
</div>
<div
className={cn(
"flex flex-col gap-2 mt-1",
"transition-all duration-300 ease-in-out",
isCollapsed
? "opacity-0 max-w-0 h-0 invisible pointer-events-none"
: "opacity-100 max-w-xs h-auto visible",
)}
>
{deviceInfoItems.map((item) => {
const IconComponent = item.icon;
return (
<div
key={item.id}
className="flex items-center gap-2.5 text-sm"
>
{IconComponent && (
<IconComponent
size={16}
className="text-gray-500 dark:text-gray-400 w-4 flex-shrink-0"
/>
)}
{item.customComponent}
{item.id !== "battery" && (
<Subtle className="text-gray-600 dark:text-gray-300">
{item.label}: {item.value}
</Subtle>
)}
</div>
);
})}
{!isCollapsed && (
<div className="my-2 h-px bg-gray-200 dark:bg-gray-700 flex-shrink-0">
</div>
)}
{!isCollapsed && (
<div className="my-2 h-px bg-gray-200 dark:bg-gray-700"></div>
<div
className={cn(
"flex flex-col gap-2 mt-1",
"transition-all duration-300 ease-in-out",
isCollapsed
? "opacity-0 max-w-0 h-0 invisible pointer-events-none"
: "opacity-100 max-w-xs h-auto visible",
)}
>
{deviceInfoItems.map((item) => {
const IconComponent = item.icon;
return (
<div
key={item.id}
className="flex items-center gap-2.5 text-sm"
>
{IconComponent && (
<IconComponent
size={16}
className="text-gray-500 dark:text-gray-400 w-4 flex-shrink-0"
/>
)}
{item.customComponent}
{item.id !== "battery" && (
<Subtle className="text-gray-600 dark:text-gray-300">
{item.label}: {item.value}
</Subtle>
)}
</div>
);
})}
</div>
<div
className={cn(
"flex flex-col gap-1 mt-1",
"transition-all duration-300 ease-in-out",
isCollapsed
? "opacity-0 max-w-0 h-0 invisible pointer-events-none"
: "opacity-100 max-w-xs visible",
)}
>
{actionButtons.map((buttonItem) => {
const Icon = buttonItem.icon;
if (buttonItem.render) {
return (
<Fragment key={buttonItem.id}>
{buttonItem.render()}
</Fragment>
);
}
{!isCollapsed && (
<div className="my-2 h-px bg-gray-200 dark:bg-gray-700 flex-shrink-0">
</div>
)}
<div
className={cn(
"flex flex-col gap-1 mt-1",
"transition-all duration-300 ease-in-out",
isCollapsed
? "opacity-0 max-w-0 h-0 invisible pointer-events-none"
: "opacity-100 max-w-xs visible",
)}
>
{actionButtons.map((buttonItem) => {
const Icon = buttonItem.icon;
if (buttonItem.render) {
return (
<Button
key={buttonItem.id}
variant="ghost"
aria-label={buttonItem.label}
onClick={buttonItem.onClick}
<Fragment key={buttonItem.id}>
{buttonItem.render()}
</Fragment>
);
}
return (
<Button
key={buttonItem.id}
variant="ghost"
aria-label={buttonItem.label}
onClick={buttonItem.onClick}
className={cn(
"group",
"flex w-full items-center justify-start text-sm p-1.5 rounded-md",
"gap-2.5",
"transition-colors duration-150",
!disableHover && "hover:bg-gray-100 dark:hover:bg-gray-700",
)}
>
<Icon
size={16}
className={cn(
"group",
"flex w-full items-center justify-start text-sm p-1.5 rounded-md",
"gap-2.5",
"flex-shrink-0 w-4",
"text-gray-500 dark:text-gray-400",
"transition-colors duration-150",
!disableHover && "hover:bg-gray-100 dark:hover:bg-gray-700",
!disableHover &&
"group-hover:text-gray-700 dark:group-hover:text-gray-200",
)}
/>
<Subtle
className={cn(
"text-sm",
"text-gray-600 dark:text-gray-300",
"transition-colors duration-150",
!disableHover &&
"group-hover:text-gray-800 dark:group-hover:text-gray-100",
)}
>
<Icon
size={16}
className={cn(
"flex-shrink-0 w-4",
"text-gray-500 dark:text-gray-400",
"transition-colors duration-150",
!disableHover &&
"group-hover:text-gray-700 dark:group-hover:text-gray-200",
)}
/>
<Subtle
className={cn(
"text-sm",
"text-gray-600 dark:text-gray-300",
"transition-colors duration-150",
!disableHover &&
"group-hover:text-gray-800 dark:group-hover:text-gray-100",
)}
>
{buttonItem.label}
</Subtle>
</Button>
);
})}
{/* <Code>{import.meta.env.COMMIT_HASH}</Code> */}
</div>
{buttonItem.label}
</Subtle>
</Button>
);
})}
</div>
</div>
</>
);
};

2
src/components/PageLayout.tsx

@ -111,7 +111,7 @@ export const PageLayout = ({
{rightBar && (
<aside
className={cn(
"w-48 lg:w-[270px] shrink-0 border-l border-slate-300 dark:border-slate-700 px-2 overflow-hidden",
"w-56 lg:w-[270px] text-balance shrink-0 border-l border-slate-300 dark:border-slate-700 px-2 overflow-hidden",
rightBarClassName,
)}
>

4
src/components/Sidebar.tsx

@ -128,7 +128,7 @@ export const Sidebar = ({ children }: SidebarProps) => {
className={cn(
"relative border-slate-300 dark:border-slate-700",
"transition-all duration-300 ease-in-out flex-shrink-0",
isCollapsed ? "w-24" : "w-46 lg:w-64",
isCollapsed ? "w-24" : "w-52 lg:w-64",
)}
>
<CollapseToggleButton />
@ -188,7 +188,7 @@ export const Sidebar = ({ children }: SidebarProps) => {
{children}
</div>
<div className="pt-4 border-t-[0.5px] bg-background-primary border-slate-300 dark:border-slate-700 flex-shrink-0">
<div className=" pt-4 border-t-[0.5px] bg-background-primary border-slate-300 dark:border-slate-700 h-full flex-1">
{myNode === undefined
? (
<div className="flex flex-col items-center justify-center py-6">

13
src/components/UI/Footer.tsx

@ -1,11 +1,13 @@
import { cn } from "@core/utils/cn.ts";
import { Trans } from "react-i18next";
import { Trans, useTranslation } from "react-i18next";
type FooterProps = {
className?: string;
};
const Footer = ({ className, ...props }: FooterProps) => {
const { t } = useTranslation();
return (
<footer
className={cn(
@ -14,7 +16,14 @@ const Footer = ({ className, ...props }: FooterProps) => {
)}
{...props}
>
<p>
<div className="justify-start px-2">
<span className="font-semibold text-gray-500/40 dark:text-gray-400/40">
{t("footer.commitSha", {
sha: String(import.meta.env.VITE_COMMIT_HASH)?.toUpperCase(),
})}
</span>
</div>
<p className="ml-auto mr-auto text-gray-500 dark:text-gray-400">
<Trans
i18nKey="footer.text"
components={[

4
src/components/UI/Sidebar/SidebarButton.tsx

@ -52,13 +52,13 @@ export const SidebarButton = ({
<span
className={cn(
"flex flex-wrap justify-start text-left text-wrap break-all",
"flex flex-wrap justify-start text-left text-balance break-all",
"min-w-0",
"px-1",
"transition-all duration-300 ease-in-out",
isButtonCollapsed
? "opacity-0 max-w-0 invisible w-0 overflow-hidden"
: "opacity-100 max-w-full visible flex-1 whitespace-normal",
: "opacity-100 max-w-full visible whitespace-normal",
)}
>
{label}

3
src/i18n/locales/en/ui.json

@ -157,6 +157,7 @@
"changeTheme": "Change Color Scheme"
},
"footer": {
"text": "Powered by <0>▲ Vercel</0> | Meshtastic® is a registered trademark of Meshtastic LLC. | <1>Legal Information</1>"
"text": "Powered by <0>▲ Vercel</0> | Meshtastic® is a registered trademark of Meshtastic LLC. | <1>Legal Information</1>",
"commitSha": "Commit SHA: {{sha}}"
}
}

Loading…
Cancel
Save