Skip to content

Commit

Permalink
feat: nexa integration, app - better loaders, service color hints, th…
Browse files Browse the repository at this point in the history
…eme customization

chore: v0.2.5 bump
  • Loading branch information
av committed Oct 3, 2024
1 parent e5a797f commit c0cdfa0
Show file tree
Hide file tree
Showing 29 changed files with 506 additions and 397 deletions.
2 changes: 1 addition & 1 deletion app/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@av/harbor-app",
"private": true,
"version": "0.2.4",
"version": "0.2.5",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
2 changes: 1 addition & 1 deletion app/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "harbor-app"
version = "0.2.4"
version = "0.2.5"
description = "A companion app for Harbor LLM toolkit"
authors = ["av"]
edition = "2021"
Expand Down
2 changes: 1 addition & 1 deletion app/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2.0.0-rc",
"productName": "Harbor",
"version": "0.2.4",
"version": "0.2.5",
"identifier": "com.harbor.app",
"build": {
"beforeDevCommand": "bun run dev",
Expand Down
2 changes: 1 addition & 1 deletion app/src/AppRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const ROUTES: Record<string, HarborRoute> = {
},
config: {
id: 'config',
name: <span className="flex items-center gap-2"><IconBolt/>Profiles</span>,
name: <span className="flex items-center gap-2"><IconBolt />Profiles</span>,
path: '/config',
element: <Config />,
},
Expand Down
22 changes: 0 additions & 22 deletions app/src/LinearLoading.tsx

This file was deleted.

32 changes: 32 additions & 0 deletions app/src/Loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useEffect, useState } from 'react';

export const TOGGLE_DELAY = 250;

export const LoaderElements = {
linear: <progress className="progress my-2 max-w-56"></progress>,
overlay: (
<div className="absolute inset-0 p-6 flex items-center justify-center bg-base-200/60 pointer-events-none rounded-box">
<progress className="progress"></progress>
</div>
),
}

export const Loader = ({ loading, loader = "linear" }: { loading: boolean, loader: keyof typeof LoaderElements }) => {
const [showLoader, setShowLoader] = useState(false);
const loaderComponent = LoaderElements[loader];

useEffect(() => {
let timer: number;

if (loading) {
timer = setTimeout(() => setShowLoader(true), TOGGLE_DELAY);
} else {
setShowLoader(false);
}
return () => clearTimeout(timer);
}, [loading]);

if (!showLoader) return null;

return loaderComponent;
};
4 changes: 2 additions & 2 deletions app/src/config/Config.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { FC } from "react";
import { useHarborConfig } from "./useHarborConfig";
import { ProfileSelector } from "../settings/ProfileSelector";
import { LinearLoader } from "../LinearLoading";
import { Loader } from "../Loading";
import { ScrollToTop } from "../ScrollToTop";

export const Config: FC = () => {
const { configs: profiles, loading } = useHarborConfig();

return (
<>
<LinearLoader loading={loading} />
<Loader loading={loading} />
<ProfileSelector configs={profiles} />
<ScrollToTop />
</>
Expand Down
4 changes: 2 additions & 2 deletions app/src/home/Doctor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMemo } from "react";
import { Section } from "../Section";
import { useHarbor } from "../useHarbor";
import { LinearLoader } from "../LinearLoading";
import { Loader } from "../Loading";
import { IconButton } from "../IconButton";
import { IconRotateCW } from "../Icons";

Expand Down Expand Up @@ -56,7 +56,7 @@ export const Doctor = () => {
}
children={
<>
<LinearLoader loading={loading} />
<Loader loading={loading} />
{error && <span>{error.message}</span>}
<span>{output}</span>
</>
Expand Down
9 changes: 6 additions & 3 deletions app/src/home/ServiceCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
IconBandage,
IconExternalLink,
} from "../Icons";
import { ACTION_ICONS, HarborService, HST } from "../serviceMetadata";
import { ACTION_ICONS, HarborService, HST, HSTColorOpts, HSTColors } from "../serviceMetadata";
import { runHarbor } from "../useHarbor";
import { toasted } from "../utils";

Expand Down Expand Up @@ -40,7 +40,7 @@ export const ServiceCard = (
const toggleService = () => {
const msg = (str: string) => (
<span>
<span className="kbd kbd-sm mr-2">{service.handle}</span>
<span className="font-bold mr-2">{service.handle}</span>
<span>{str}</span>
</span>
);
Expand Down Expand Up @@ -75,9 +75,12 @@ export const ServiceCard = (
: ACTION_ICONS.up;

const canLaunch = !service.tags.includes(HST.cli);
const gradientTag = service.tags.find(t => HSTColorOpts.includes(t as HST));

const gradientClass = gradientTag ? `bg-gradient-to-tr from-0% to-50% ${HSTColors[gradientTag]}` : "";

return (
<div className="p-4 rounded-box cursor-default bg-base-300/35">
<div className={`p-4 rounded-box cursor-default bg-base-200/50 relative ${gradientClass}`}>
<h2 className="flex items-center gap-1 text-2xl pb-2">
<span className="font-bold">{service.handle}</span>

Expand Down
8 changes: 4 additions & 4 deletions app/src/home/ServiceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Section } from "../Section";
import { ServiceCard } from "./ServiceCard";
import { useServiceList } from "./useServiceList";
import { useArrayState } from "../useArrayState";
import { LinearLoader } from "../LinearLoading";
import { Loader } from "../Loading";
import { IconButton } from "../IconButton";
import { ACTION_ICONS, HarborService, HST } from "../serviceMetadata";
import { runHarbor } from "../useHarbor";
Expand Down Expand Up @@ -122,8 +122,8 @@ export const ServiceList = () => {
</div>
}
children={
<>
<LinearLoader loading={loading} />
<div className='relative rounded-box'>
<Loader loading={loading} loader='overlay' />
{error && <div className="my-2">{error.message}</div>}
{services && (
<ul className="flex gap-4 flex-wrap">
Expand All @@ -142,7 +142,7 @@ export const ServiceList = () => {
})}
</ul>
)}
</>
</div>
}
/>
);
Expand Down
4 changes: 2 additions & 2 deletions app/src/home/Version.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LinearLoader } from "../LinearLoading";
import { Loader } from "../Loading";
import { Section } from "../Section";
import { useHarbor } from "../useHarbor";

Expand All @@ -11,7 +11,7 @@ export const Version = () => {
header="Version"
children={
<>
<LinearLoader loading={loading} />
<Loader loading={loading} />
{error && <span>{error.message}</span>}
<span>{result?.stdout}</span>
</>
Expand Down
15 changes: 13 additions & 2 deletions app/src/serviceMetadata.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IconPlaneLanding, IconRocketLaunch } from "./Icons";

export const ACTION_ICONS = {
loading: <span className="loading loading-ring loading-xs"></span>,
loading: <span className="loading loading-spinner loading-xs"></span>,
up: <IconRocketLaunch />,
down: <IconPlaneLanding />,
};
Expand All @@ -19,6 +19,14 @@ export enum HST {
audio = 'Audio',
};

export const HSTColors: Partial<Record<HST, string>> = {
[HST.backend]: 'from-primary/10',
[HST.frontend]: 'from-secondary/10',
[HST.satellite]: 'from-accent/10',
};

export const HSTColorOpts = Object.keys(HSTColors) as HST[];

export type HarborService = {
handle: string;
isRunning: boolean;
Expand Down Expand Up @@ -176,5 +184,8 @@ export const serviceMetadata: Record<string, Partial<HarborService>> = {
},
anythingllm: {
tags: [HST.frontend, HST.partial]
}
},
nexa: {
tags: [HST.backend, HST.partial],
},
};
112 changes: 90 additions & 22 deletions app/src/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { THEMES, useTheme } from "../theme";
import { useAutostart } from "../useAutostart";

export const Settings = () => {
const [theme, setTheme] = useTheme();
const theme = useTheme();
const autostart = useAutostart();

const handleAutostartChange = (e: React.ChangeEvent<HTMLInputElement>) => {
Expand All @@ -16,14 +16,38 @@ export const Settings = () => {
<Section
header=""
children={
<div className="flex flex-col gap-4">
<h2 className="text-2xl font-bold">Theme</h2>
<p className="text-base-content/50">Saved automatically.</p>
<div className="flex flex-col gap-6">
<div>
<h2 className="text-2xl font-bold mt-4">Auto Start</h2>
<p className="text-base-content/50">
Launch Harbor App when your system starts.
</p>

<div className="form-control w-52">
<label className="label cursor-pointer">
<span className="label-text">Enable Auto Start</span>
<input
type="checkbox"
className="toggle"
checked={autostart.enabled}
disabled={autostart.loading}
onChange={handleAutostartChange}
/>
</label>
</div>
</div>

<div>
<h2 className="text-2xl font-bold">Theme</h2>
<p className="text-base-content/50">
Customize the look and feel of Harbor App.
</p>
</div>

<div className="flex items-center gap-4 z-10">
<div className="dropdown">
<div tabIndex={0} role="button" className="btn m-1 capitalize">
{theme}
{theme.theme}
<IconChevronDown />
</div>
<ul
Expand All @@ -32,7 +56,7 @@ export const Settings = () => {
>
{THEMES.map((t) => {
return (
<li onClick={() => setTheme(t)} key={t} value={t}>
<li onClick={() => theme.setTheme(t)} key={t} value={t}>
<a className="capitalize">{t}</a>
</li>
);
Expand All @@ -50,24 +74,68 @@ export const Settings = () => {
<div className="badge badge-warning"></div>
<div className="badge badge-error"></div>
</div>

<button className="btn btn-sm" onClick={() => theme.reset()}>Reset</button>
</div>

<h2 className="text-2xl font-bold mt-4">Auto Start</h2>
<p className="text-base-content/50">
Launch Harbor App when your system starts.
</p>

<div className="form-control w-52">
<label className="label cursor-pointer">
<span className="label-text">Enable Auto Start</span>
<input
type="checkbox"
className="toggle"
checked={autostart.enabled}
disabled={autostart.loading}
onChange={handleAutostartChange}
/>
</label>
<div className="max-w-xl">
<h2 className="text-2xl font-bold">Hue</h2>
<p className="text-base-content/50 mb-4">
Adjust the hue of the theme color.
</p>

<input
type="range" min="0" max="360" value={theme.hue}
className="range" onChange={(e) => theme.setHue(parseInt(e.target.value))}
/>
</div>

<div className="max-w-xl">
<h2 className="text-2xl font-bold">Saturation</h2>
<p className="text-base-content/50 mb-4">
How vibrant the colors are.
</p>

<input
type="range" min="0" max="100" value={theme.saturation}
className="range" onChange={(e) => theme.setSaturation(parseInt(e.target.value))}
/>
</div>

<div className="max-w-xl">
<h2 className="text-2xl font-bold">Contrast</h2>
<p className="text-base-content/50 mb-4">
The difference between the lightest and darkest colors.
</p>

<input
type="range" min="0" max="200" value={theme.contrast}
className="range" onChange={(e) => theme.setContrast(parseInt(e.target.value))}
/>
</div>

<div className="max-w-xl">
<h2 className="text-2xl font-bold">Brightness</h2>
<p className="text-base-content/50 mb-4">
The overall lightness or darkness of the theme.
</p>

<input
type="range" min="10" max="100" value={theme.brightness}
className="range" onChange={(e) => theme.setBrightness(parseInt(e.target.value))}
/>
</div>

<div className="max-w-xl">
<h2 className="text-2xl font-bold">Invert</h2>
<p className="text-base-content/50 mb-4">
Change the colors to their opposites.
</p>

<input
type="range" min="0" max="100" value={theme.invert}
className="range" onChange={(e) => theme.setInvert(parseInt(e.target.value))}
/>
</div>
</div>
}
Expand Down
Loading

0 comments on commit c0cdfa0

Please sign in to comment.