Skip to content

Commit

Permalink
[FAI-13977] Support light theme colors (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
meldiner authored Nov 12, 2024
1 parent 28b1caf commit 7608f13
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 31 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "faros-vscode-extension",
"displayName": "Faros AI",
"description": "Faros AI's Visual Studio Code extension",
"version": "0.1.1",
"version": "0.1.2",
"publisher": "farosai",
"icon": "images/logo.png",
"engines": {
Expand Down
14 changes: 11 additions & 3 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import * as path from "path";
import FarosPanel from "./panel";

let statusBarItem: vscode.StatusBarItem;
let ev: vscode.Disposable | null = null;
let changeTextDocumentListener: vscode.Disposable | null = null;
let themeChangedListener: vscode.Disposable | null = null;
let suggestionsCount = 0;
let charCount = 0;
let previousText = "";
Expand Down Expand Up @@ -73,8 +74,8 @@ function registerSuggestionListener() {
statusBarItem.show();
}

if (ev === null) {
ev = vscode.workspace.onDidChangeTextDocument((event) => {
if (changeTextDocumentListener === null) {
changeTextDocumentListener = vscode.workspace.onDidChangeTextDocument((event) => {
const activeEditor = vscode.window.activeTextEditor;
if (!activeEditor || event.document !== activeEditor.document) {
return;
Expand Down Expand Up @@ -123,6 +124,12 @@ function registerSuggestionListener() {
previousText = updatedText;
});
}

if (themeChangedListener === null) {
themeChangedListener = vscode.window.onDidChangeActiveColorTheme((event) => {
farosPanel?.setTheme(event.kind);
});
}
}

// This method is called when your extension is activated
Expand All @@ -136,6 +143,7 @@ export function activate(context: vscode.ExtensionContext) {
registerSuggestionListener();

farosPanel = new FarosPanel(context.extensionUri);
farosPanel.setTheme(vscode.window.activeColorTheme.kind);
context.subscriptions.push(
vscode.window.registerWebviewViewProvider(
FarosPanel.viewType,
Expand Down
11 changes: 11 additions & 0 deletions src/panel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as vscode from "vscode";
import { calculateAutoCompletionStats, calculateRatios, getTopRepositories } from "./stats";
import { ThemeType } from "./webview/components/types";

export default class FarosPanel implements vscode.WebviewViewProvider {
public static readonly viewType = "farosPanel";
Expand All @@ -22,6 +23,13 @@ export default class FarosPanel implements vscode.WebviewViewProvider {
});
}

public setTheme(theme: vscode.ColorThemeKind) {
this.webview?.postMessage({
command: "themeChanged",
theme: theme === vscode.ColorThemeKind.Dark || theme === vscode.ColorThemeKind.HighContrast ? "Dark" : "Light" as ThemeType,
});
}

public resolveWebviewView(
webviewView: vscode.WebviewView,
context: vscode.WebviewViewResolveContext,
Expand All @@ -36,6 +44,9 @@ export default class FarosPanel implements vscode.WebviewViewProvider {
case "refresh":
this.refresh();
break;
case "themeChanged":
this.setTheme(msg.theme);
break;
}
},
null,
Expand Down
12 changes: 8 additions & 4 deletions src/webview/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
percentageIcon,
chevronIcon,
} from "./Icons";

import {detailsCollapseButtonStyle, detailsGridStyle, gridItemStyle, overviewGridStyle, panelStyle, subtitleStyle, titleStyle } from "./Styles";
import { ThemeType } from "./types";

const App = () => {
const [stats, setStats] = React.useState<{
Expand Down Expand Up @@ -42,7 +42,8 @@ const App = () => {
}[]
>([]);
const [showDetailedBreakdown, setShowDetailedBreakdown] = React.useState(false);

const [theme, setTheme] = React.useState<ThemeType>("Dark");

React.useEffect(() => {
window.addEventListener("message", (event) => {
const message = event.data; // The json data that the extension sent
Expand All @@ -57,6 +58,9 @@ const App = () => {
setRatios(message.ratios);
setTopRepositories(message.topRepositories);
break;
case "themeChanged":
setTheme(message.theme as ThemeType);
break;
}
});
});
Expand All @@ -79,14 +83,14 @@ const App = () => {
<div style={overviewGridStyle()}>
<div style={gridItemStyle()}>{eventsCountIcon}Total Auto-completions</div><div style={gridItemStyle({justifyContent: "flex-end"})}>{stats.total.count}</div>
<div style={gridItemStyle()}>{timeSavedIcon}Time saved</div><div style={gridItemStyle({justifyContent: "flex-end"})}>{formatTimeSaved(stats.total.timeSaved)}</div>
<div style={gridItemStyle()}>{percentageIcon}Auto-completed ratio</div><div style={gridItemStyle({justifyContent: "flex-end"})}>{formatPercentage(ratios.total)}</div>
<div style={gridItemStyle({gap: "5px"})}>{percentageIcon}Auto-completed ratio</div><div style={gridItemStyle({justifyContent: "flex-end"})}>{formatPercentage(ratios.total)}</div>
</div>
<div style={{display: "flex", alignItems: "center", gap: "4px"}}>
{chevronIcon(showDetailedBreakdown)}
<a style={detailsCollapseButtonStyle} onClick={() => setShowDetailedBreakdown(!showDetailedBreakdown)}>Detailed Breakdown</a>
</div>
{showDetailedBreakdown && (
<div style={detailsGridStyle()}>
<div style={detailsGridStyle(theme)}>
<div style={gridItemStyle({marginRight: "16px"})}>{calendarDayIcon}1d</div>
<div style={gridItemStyle({marginRight: "16px"})}>{eventsCountIcon}{stats.today.count}</div>
<div style={gridItemStyle({marginRight: "16px"})}>{timeSavedIcon}{formatTimeSaved(stats.today.timeSaved)}</div>
Expand Down
93 changes: 77 additions & 16 deletions src/webview/components/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ export const calendarWeekIcon = (
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M15.3278 2.94087H13.7422V1.88379H12.6851V2.94087H4.22839V1.88379H3.1713V2.94087H1.58567L1.05713 3.46942V16.1544L1.58567 16.683H15.3278L15.8563 16.1544V3.46942L15.3278 2.94087ZM14.7992 15.6259H2.11421V6.11213H14.7992V15.6259ZM14.7992 5.05505H2.11421V3.99796H14.7992V5.05505ZM4.22834 9.28334H3.17126V10.3404H4.22834V9.28334ZM3.17126 11.3975H4.22834V12.4546H3.17126V11.3975ZM4.22834 13.5117H3.17126V14.5688H4.22834V13.5117ZM6.34251 9.28334H7.3996V10.3404H6.34251V9.28334ZM7.3996 11.3975H6.34251V12.4546H7.3996V11.3975ZM6.34251 13.5117H7.3996V14.5688H6.34251V13.5117ZM7.3996 7.16917H6.34251V8.22626H7.3996V7.16917ZM9.51377 9.28334H10.5709V10.3404H9.51377V9.28334ZM10.5709 11.3975H9.51377V12.4546H10.5709V11.3975ZM9.51377 13.5117H10.5709V14.5688H9.51377V13.5117ZM10.5709 7.16917H9.51377V8.22626H10.5709V7.16917ZM12.685 9.28334H13.7421V10.3404H12.685V9.28334ZM13.7421 11.3975H12.685V12.4546H13.7421V11.3975ZM12.685 7.16917H13.7421V8.22626H12.685V7.16917Z"
fill="#0097FB"
d="M15.3278 3.02754H13.7421V1.97046H12.685V3.02754H4.22835V1.97046H3.17127V3.02754H1.58564L1.0571 3.55609V16.2411L1.58564 16.7697H15.3278L15.8563 16.2411V3.55609L15.3278 3.02754ZM14.7992 15.7126H2.11418V6.1988H14.7992V15.7126ZM14.7992 5.14172H2.11418V4.08463H14.7992V5.14172ZM4.22831 9.37001H3.17123V10.4271H4.22831V9.37001ZM6.34248 9.37001H7.39957V10.4271H6.34248V9.37001ZM10.5708 9.37001H9.51374V10.4271H10.5708V9.37001ZM12.685 9.37001H13.7421V10.4271H12.685V9.37001Z"
fill="#3794FF"
/>
</svg>
);
Expand All @@ -52,8 +52,19 @@ export const calendarMonthIcon = (
);

export const eventsCountIcon = (
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="15" viewBox="0 0 14 15" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.7551 7.69021L0.6825 8.7692L0 8.09545L1.82875 6.28419L2.49375 6.29295L4.3225 8.14795L3.6575 8.81295L2.63679 7.78037C2.80245 10.0455 4.69263 11.8317 7 11.8317C8.6718 11.8317 10.1246 10.894 10.8611 9.51582L11.5727 10.0378C10.6714 11.6312 8.96128 12.7067 7 12.7067C4.17876 12.7067 1.87728 10.4813 1.7551 7.69021ZM11.3716 7.28211L10.29 6.18796L9.625 6.85296L11.4537 8.69921L12.1187 8.70796L13.9475 6.89671L13.2912 6.23171L12.2465 7.2642C12.1453 4.45387 9.83506 2.20667 7 2.20667C5.10761 2.20667 3.44907 3.2079 2.52523 4.70954L3.23368 5.22923C3.99566 3.94359 5.39717 3.08167 7 3.08167C9.35779 3.08167 11.28 4.94679 11.3716 7.28211Z" fill="#519ABA"/>
<svg
xmlns="http://www.w3.org/2000/svg"
width="14"
height="15"
viewBox="0 0 14 15"
fill="none"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M1.7551 7.69021L0.6825 8.7692L0 8.09545L1.82875 6.28419L2.49375 6.29295L4.3225 8.14795L3.6575 8.81295L2.63679 7.78037C2.80245 10.0455 4.69263 11.8317 7 11.8317C8.6718 11.8317 10.1246 10.894 10.8611 9.51582L11.5727 10.0378C10.6714 11.6312 8.96128 12.7067 7 12.7067C4.17876 12.7067 1.87728 10.4813 1.7551 7.69021ZM11.3716 7.28211L10.29 6.18796L9.625 6.85296L11.4537 8.69921L12.1187 8.70796L13.9475 6.89671L13.2912 6.23171L12.2465 7.2642C12.1453 4.45387 9.83506 2.20667 7 2.20667C5.10761 2.20667 3.44907 3.2079 2.52523 4.70954L3.23368 5.22923C3.99566 3.94359 5.39717 3.08167 7 3.08167C9.35779 3.08167 11.28 4.94679 11.3716 7.28211Z"
fill="#519ABA"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
Expand All @@ -64,15 +75,38 @@ export const eventsCountIcon = (
);

export const timeSavedIcon = (
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="15" viewBox="0 0 14 15" fill="none">
<path d="M6.5625 8.33167H8.3125V7.45667H7V5.26917H6.125V7.89417L6.5625 8.33167Z" fill="#8DC149"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.8125 3.66699C3.50481 4.42343 2.625 5.8373 2.625 7.45667C2.625 9.07603 3.50481 10.4899 4.8125 11.2463V13.1442L5.25 13.5817H8.75L9.1875 13.1442V11.2463C10.4952 10.4899 11.375 9.07603 11.375 7.45667C11.375 5.8373 10.4952 4.42343 9.1875 3.66699V1.76917L8.75 1.33167H5.25L4.8125 1.76917V3.66699ZM10.5 7.45667C10.5 9.38963 8.93302 10.9567 7 10.9567C5.06698 10.9567 3.5 9.38963 3.5 7.45667C3.5 5.5237 5.06698 3.95667 7 3.95667C8.93302 3.95667 10.5 5.5237 10.5 7.45667Z" fill="#8DC149"/>
<svg
xmlns="http://www.w3.org/2000/svg"
width="14"
height="15"
viewBox="0 0 14 15"
fill="none"
>
<path
d="M6.5625 8.33167H8.3125V7.45667H7V5.26917H6.125V7.89417L6.5625 8.33167Z"
fill="#8DC149"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M4.8125 3.66699C3.50481 4.42343 2.625 5.8373 2.625 7.45667C2.625 9.07603 3.50481 10.4899 4.8125 11.2463V13.1442L5.25 13.5817H8.75L9.1875 13.1442V11.2463C10.4952 10.4899 11.375 9.07603 11.375 7.45667C11.375 5.8373 10.4952 4.42343 9.1875 3.66699V1.76917L8.75 1.33167H5.25L4.8125 1.76917V3.66699ZM10.5 7.45667C10.5 9.38963 8.93302 10.9567 7 10.9567C5.06698 10.9567 3.5 9.38963 3.5 7.45667C3.5 5.5237 5.06698 3.95667 7 3.95667C8.93302 3.95667 10.5 5.5237 10.5 7.45667Z"
fill="#8DC149"
/>
</svg>
);

export const percentageIcon = (
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="11" viewBox="0 0 10 11" fill="none">
< path d="M4.44444 2.67889C4.44444 3.90619 3.44952 4.90111 2.22222 4.90111C0.994923 4.90111 0 3.90619 0 2.67889C0 1.45159 0.994923 0.456665 2.22222 0.456665C3.44952 0.456665 4.44444 1.45159 4.44444 2.67889ZM3.33333 2.67889C3.33333 2.06524 2.83587 1.56778 2.22222 1.56778C1.60857 1.56778 1.11111 2.06524 1.11111 2.67889C1.11111 3.29254 1.60857 3.79 2.22222 3.79C2.83587 3.79 3.33333 3.29254 3.33333 2.67889ZM10 8.23444C10 9.46174 9.00508 10.4567 7.77778 10.4567C6.55048 10.4567 5.55556 9.46174 5.55556 8.23444C5.55556 7.00714 6.55048 6.01222 7.77778 6.01222C9.00508 6.01222 10 7.00714 10 8.23444ZM8.88889 8.23444C8.88889 7.62079 8.39143 7.12333 7.77778 7.12333C7.16413 7.12333 6.66667 7.62079 6.66667 8.23444C6.66667 8.84809 7.16413 9.34555 7.77778 9.34555C8.39143 9.34555 8.88889 8.84809 8.88889 8.23444ZM8.72617 1.73049C8.94313 1.94745 8.94313 2.29921 8.72617 2.51617L2.0595 9.18284C1.84255 9.3998 1.49079 9.3998 1.27383 9.18284C1.05687 8.96588 1.05687 8.61412 1.27383 8.39716L7.9405 1.73049C8.15745 1.51354 8.50921 1.51354 8.72617 1.73049Z" fill="#E37933"/>
<svg
xmlns="http://www.w3.org/2000/svg"
width="10"
height="11"
viewBox="0 0 10 11"
fill="none"
>
<path
d="M4.44444 2.67889C4.44444 3.90619 3.44952 4.90111 2.22222 4.90111C0.994923 4.90111 0 3.90619 0 2.67889C0 1.45159 0.994923 0.456665 2.22222 0.456665C3.44952 0.456665 4.44444 1.45159 4.44444 2.67889ZM3.33333 2.67889C3.33333 2.06524 2.83587 1.56778 2.22222 1.56778C1.60857 1.56778 1.11111 2.06524 1.11111 2.67889C1.11111 3.29254 1.60857 3.79 2.22222 3.79C2.83587 3.79 3.33333 3.29254 3.33333 2.67889ZM10 8.23444C10 9.46174 9.00508 10.4567 7.77778 10.4567C6.55048 10.4567 5.55556 9.46174 5.55556 8.23444C5.55556 7.00714 6.55048 6.01222 7.77778 6.01222C9.00508 6.01222 10 7.00714 10 8.23444ZM8.88889 8.23444C8.88889 7.62079 8.39143 7.12333 7.77778 7.12333C7.16413 7.12333 6.66667 7.62079 6.66667 8.23444C6.66667 8.84809 7.16413 9.34555 7.77778 9.34555C8.39143 9.34555 8.88889 8.84809 8.88889 8.23444ZM8.72617 1.73049C8.94313 1.94745 8.94313 2.29921 8.72617 2.51617L2.0595 9.18284C1.84255 9.3998 1.49079 9.3998 1.27383 9.18284C1.05687 8.96588 1.05687 8.61412 1.27383 8.39716L7.9405 1.73049C8.15745 1.51354 8.50921 1.51354 8.72617 1.73049Z"
fill="#E37933"
/>
</svg>
);

Expand All @@ -88,17 +122,44 @@ export const repositoryIcon = (fillIndex: number) => (
fill-rule="evenodd"
clip-rule="evenodd"
d="M14.7994 11.3111V2.32591L14.2708 1.79736H3.95368C3.71124 1.80005 3.47129 1.8466 3.24544 1.93478C3.01778 2.03596 2.81261 2.18158 2.64198 2.3631C2.47135 2.54462 2.33869 2.75839 2.25178 2.99187C2.16531 3.19979 2.1187 3.42212 2.11436 3.64726V13.6896C2.11182 13.9325 2.15856 14.1735 2.25178 14.3978C2.43904 14.8496 2.79571 15.21 3.24544 15.4021C3.47129 15.4902 3.71124 15.5368 3.95368 15.5395H4.22853V14.4824H3.95368C3.84821 14.4827 3.74382 14.4611 3.64713 14.419C3.45575 14.3396 3.30368 14.1875 3.2243 13.9961C3.19052 13.8974 3.17268 13.7939 3.17144 13.6896V13.161C3.17268 13.0567 3.19052 12.9532 3.2243 12.8545C3.30368 12.6631 3.45575 12.511 3.64713 12.4316C3.74382 12.3895 3.84821 12.3679 3.95368 12.3682H13.7423V14.4824H9.51395V15.5395H14.2708L14.7994 15.0109V12.3682V11.3111ZM13.7423 2.85445V11.3111H4.22844V2.85445H13.7423ZM5.28552 3.91149H6.34261V4.96858H5.28552V3.91149ZM5.28552 6.02566H6.34261V7.08275H5.28552V6.02566ZM6.34261 8.13983H5.28552V9.19692H6.34261V8.13983ZM6.87115 15.0003L5.5815 16.5965H5.28552V13.4253H8.45678V16.5965H8.16079L6.87115 15.0003Z"
fill={fillIndex === 0 ? "#FFCC00" : fillIndex === 1 ? "#75BEFF" : fillIndex === 2 ? "#F48771" : "#C5C5C5"}
fill={
fillIndex === 0
? "#FFCC00"
: fillIndex === 1
? "#75BEFF"
: fillIndex === 2
? "#F48771"
: "#C5C5C5"
}
/>
</svg>
);

export const chevronIcon = (collapsed: boolean) => (collapsed ? (
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="currentColor" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708"/>
export const chevronIcon = (collapsed: boolean) =>
collapsed ? (
<svg
xmlns="http://www.w3.org/2000/svg"
width="10"
height="10"
fill="currentColor"
viewBox="0 0 16 16"
>
<path
fill-rule="evenodd"
d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708"
/>
</svg>
) : (
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="currentColor" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708"/>
<svg
xmlns="http://www.w3.org/2000/svg"
width="10"
height="10"
fill="currentColor"
viewBox="0 0 16 16"
>
<path
fill-rule="evenodd"
d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708"
/>
</svg>
));
);
12 changes: 7 additions & 5 deletions src/webview/components/Styles.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ThemeType } from "./types";

export const panelStyle = {
borderBottom: "1px solid #606060",
padding: "20px 12px 20px 20px",
Expand Down Expand Up @@ -39,19 +41,19 @@ export const gridStyle = (customizations = {}) => ({
export const overviewGridStyle = (customizations = {}) => ({
...gridStyle({
gridTemplateColumns: "auto auto",
width: "250px",
width: "255px",
...customizations,
}),
});

export const detailsGridStyle = (customizations = {}) => ({
export const detailsGridStyle = (theme: ThemeType, customizations = {}) => ({
...gridStyle({
gridTemplateColumns: "auto auto auto auto",
borderRadius: "3px",
border: "1px solid #3C3C3C",
background: "#1E1E1E",
border: `1px solid ${theme === "Dark" ? "#3C3C3C" : "#E0E0E0"}`,
background: theme === "Dark" ? "#1E1E1E" : "#FFFFFF",
padding: "8px 16px",
width: "220px",
width: "225px",
...customizations,
}),
});
Expand Down
1 change: 1 addition & 0 deletions src/webview/components/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type ThemeType = "Dark" | "Light";

0 comments on commit 7608f13

Please sign in to comment.