Skip to content

Commit

Permalink
Merge branch 'qa' into self-hosting-setup
Browse files Browse the repository at this point in the history
  • Loading branch information
ddimaria authored Oct 30, 2024
2 parents 353a2d7 + da5996c commit ab44c0f
Show file tree
Hide file tree
Showing 34 changed files with 725 additions and 101 deletions.
10 changes: 5 additions & 5 deletions quadratic-client/src/app/gridGL/UI/Cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class Cursor extends Container {
const showInput = pixiAppSettings.input.show;

let { x, y, width, height } = sheet.getCellOffsets(cell.x, cell.y);
const color = colors.cursorCell;
const color = pixiApp.accentColor;
const codeCell = codeEditorState.codeCell;

// draw cursor but leave room for cursor indicator if needed
Expand Down Expand Up @@ -149,7 +149,7 @@ export class Cursor extends Container {

this.startCell = sheet.getCellOffsets(cursor.cursorPosition.x, cursor.cursorPosition.y);
if (cursor.multiCursor) {
drawMultiCursor(this.graphics, colors.cursorCell, FILL_ALPHA, cursor.multiCursor);
drawMultiCursor(this.graphics, pixiApp.accentColor, FILL_ALPHA, cursor.multiCursor);

// endCell is only interesting for one multiCursor since we use it to draw
// the indicator, which is only active for one multiCursor
Expand Down Expand Up @@ -190,12 +190,12 @@ export class Cursor extends Container {
this.indicator.y = y - indicatorSize / 2;
this.graphics.lineStyle(0);
// have cursor color match code editor mode
let color = colors.cursorCell;
let color = pixiApp.accentColor;
if (
inlineEditorHandler.getShowing(cell.x, cell.y) ||
(codeEditorState.showCodeEditor && codeCell.pos.x === cell.x && codeCell.pos.y === cell.y)
)
color = colors.cursorCell;
color = pixiApp.accentColor;
this.graphics.beginFill(color).drawShape(this.indicator).endFill();
}
}
Expand Down Expand Up @@ -259,7 +259,7 @@ export class Cursor extends Container {
drawColumnRowCursor({
g: this.graphics,
columnRow,
color: colors.cursorCell,
color: pixiApp.accentColor,
alpha: FILL_ALPHA,
cursorPosition: sheets.sheet.cursor.cursorPosition,
});
Expand Down
3 changes: 1 addition & 2 deletions quadratic-client/src/app/gridGL/UI/UICellMoving.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { sheets } from '@/app/grid/controller/Sheets';
import { pixiApp } from '@/app/gridGL/pixiApp/PixiApp';
import { colors } from '@/app/theme/colors';
import { BitmapText, Container, Graphics } from 'pixi.js';

const MOVING_THICKNESS = 3;
Expand All @@ -25,7 +24,7 @@ export class UICellMoving extends Container {
}
this.visible = true;
this.graphics.clear();
this.graphics.lineStyle(1, colors.movingCells, MOVING_THICKNESS);
this.graphics.lineStyle(1, pixiApp.accentColor, MOVING_THICKNESS);
const sheet = sheets.sheet;
const start = sheet.getCellOffsets(moving.toColumn, moving.toRow);
const end = sheet.getCellOffsets(moving.toColumn + moving.width - 1, moving.toRow + moving.height - 1);
Expand Down
4 changes: 2 additions & 2 deletions quadratic-client/src/app/gridGL/UI/boxCells.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class BoxCells extends Graphics {
this.dirty = false;
this.clear();
this.lineStyle({
color: colors.boxCellsColor,
color: pixiApp.accentColor,
alpha: colors.boxCellsAlpha,
width: thickness,
});
Expand All @@ -60,7 +60,7 @@ export class BoxCells extends Graphics {
this.moveTo(screenRectangle.x + screenRectangle.width, screenRectangle.y);
this.lineTo(screenRectangle.x + screenRectangle.width, screenRectangle.y + screenRectangle.height);
this.lineStyle({
color: colors.boxCellsColor,
color: pixiApp.accentColor,
alpha: colors.boxCellsAlpha,
width: thickness,
});
Expand Down
32 changes: 10 additions & 22 deletions quadratic-client/src/app/gridGL/UI/gridHeadings/GridHeadings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,21 +96,15 @@ export class GridHeadings extends Container {

// fill the entire viewport if all cells are selected
if (cursor.columnRow?.all) {
this.headingsGraphics.beginFill(
colors.headerSelectedRowColumnBackgroundColor,
colors.headerSelectedRowColumnBackgroundColorAlpha
);
this.headingsGraphics.beginFill(pixiApp.accentColor, colors.headerSelectedRowColumnBackgroundColorAlpha);
this.headingsGraphics.drawRect(viewport.left, viewport.top, viewport.screenWidthInWorldPixels, cellHeight);
this.headingsGraphics.endFill();
return 'all';
}

// dark fill headings if there is a columnRow selection
if (cursor.columnRow?.columns) {
this.headingsGraphics.beginFill(
colors.headerSelectedRowColumnBackgroundColor,
colors.headerSelectedRowColumnBackgroundColorAlpha
);
this.headingsGraphics.beginFill(pixiApp.accentColor, colors.headerSelectedRowColumnBackgroundColorAlpha);
cursor.columnRow.columns.forEach((column) => {
const offset = offsets.getColumnPlacement(column);
this.headingsGraphics.drawRect(offset.position, viewport.top, offset.size, cellHeight);
Expand All @@ -121,7 +115,7 @@ export class GridHeadings extends Container {

// if we're selecting rows, then show all columns as selected
if (cursor.columnRow?.rows) {
this.headingsGraphics.beginFill(colors.headerSelectedBackgroundColor, colors.headerSelectedBackgroundColorAlpha);
this.headingsGraphics.beginFill(pixiApp.accentColor, colors.headerSelectedBackgroundColorAlpha);
this.headingsGraphics.drawRect(viewport.left, viewport.top, viewport.screenWidthInWorldPixels, cellHeight);
this.headingsGraphics.endFill();
return 'all';
Expand All @@ -130,7 +124,7 @@ export class GridHeadings extends Container {
// selected cells based on multiCursor
else if (cursor.multiCursor) {
const selectedColumns = new Set<number>();
this.headingsGraphics.beginFill(colors.headerSelectedBackgroundColor, colors.headerSelectedBackgroundColorAlpha);
this.headingsGraphics.beginFill(pixiApp.accentColor, colors.headerSelectedBackgroundColorAlpha);
cursor.multiCursor.forEach((rectangle) => {
const start = offsets.getColumnPlacement(rectangle.left);
const end = offsets.getColumnPlacement(rectangle.right - 1);
Expand All @@ -151,7 +145,7 @@ export class GridHeadings extends Container {
// otherwise selected cursor is cursorPosition
else {
const offset = offsets.getColumnPlacement(cursor.cursorPosition.x);
this.headingsGraphics.beginFill(colors.headerSelectedBackgroundColor, colors.headerSelectedBackgroundColorAlpha);
this.headingsGraphics.beginFill(pixiApp.accentColor, colors.headerSelectedBackgroundColorAlpha);
this.headingsGraphics.drawRect(offset.position, viewport.top, offset.size, cellHeight);
this.headingsGraphics.endFill();
this.selectedColumns = [cursor.cursorPosition.x];
Expand Down Expand Up @@ -288,20 +282,14 @@ export class GridHeadings extends Container {

// fill the entire viewport if all cells are selected
if (cursor.columnRow?.all) {
this.headingsGraphics.beginFill(
colors.headerSelectedRowColumnBackgroundColor,
colors.headerSelectedRowColumnBackgroundColorAlpha
);
this.headingsGraphics.beginFill(pixiApp.accentColor, colors.headerSelectedRowColumnBackgroundColorAlpha);
this.headingsGraphics.drawRect(bounds.left, bounds.top, this.rowWidth, bounds.height);
this.headingsGraphics.endFill();
}

// dark fill headings if there is a columnRow selection
if (cursor.columnRow?.rows) {
this.headingsGraphics.beginFill(
colors.headerSelectedRowColumnBackgroundColor,
colors.headerSelectedRowColumnBackgroundColorAlpha
);
this.headingsGraphics.beginFill(pixiApp.accentColor, colors.headerSelectedRowColumnBackgroundColorAlpha);
cursor.columnRow.rows.forEach((row) => {
const offset = offsets.getRowPlacement(row);
this.headingsGraphics.drawRect(bounds.left, offset.position, this.rowWidth, offset.size);
Expand All @@ -311,15 +299,15 @@ export class GridHeadings extends Container {

// if we're selecting columns, then show all rows as selected
if (cursor.columnRow?.columns) {
this.headingsGraphics.beginFill(colors.headerSelectedBackgroundColor, colors.headerSelectedBackgroundColorAlpha);
this.headingsGraphics.beginFill(pixiApp.accentColor, colors.headerSelectedBackgroundColorAlpha);
this.headingsGraphics.drawRect(bounds.left, bounds.top, this.rowWidth, bounds.height);
this.headingsGraphics.endFill();
}

// selected cells based on multiCursor
if (cursor.multiCursor) {
const selectedRows = new Set<number>();
this.headingsGraphics.beginFill(colors.headerSelectedBackgroundColor, colors.headerSelectedBackgroundColorAlpha);
this.headingsGraphics.beginFill(pixiApp.accentColor, colors.headerSelectedBackgroundColorAlpha);
cursor.multiCursor.forEach((rectangle) => {
const start = offsets.getRowPlacement(rectangle.top);
const end = offsets.getRowPlacement(rectangle.bottom - 1);
Expand All @@ -340,7 +328,7 @@ export class GridHeadings extends Container {
// otherwise selected cursor is cursorPosition
if (!cursor.multiCursor && !cursor.columnRow) {
const offset = offsets.getRowPlacement(cursor.cursorPosition.y);
this.headingsGraphics.beginFill(colors.headerSelectedBackgroundColor, colors.headerSelectedBackgroundColorAlpha);
this.headingsGraphics.beginFill(pixiApp.accentColor, colors.headerSelectedBackgroundColorAlpha);
this.headingsGraphics.drawRect(bounds.left, offset.position, this.rowWidth, offset.size);
this.headingsGraphics.endFill();
this.selectedRows = [cursor.cursorPosition.y];
Expand Down
19 changes: 19 additions & 0 deletions quadratic-client/src/app/gridGL/pixiApp/PixiApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ import { Update } from '@/app/gridGL/pixiApp/Update';
import { Viewport } from '@/app/gridGL/pixiApp/Viewport';
import { urlParams } from '@/app/gridGL/pixiApp/urlParams/urlParams';
import { Coordinate } from '@/app/gridGL/types/size';
import { getCSSVariableTint } from '@/app/helpers/convertColor';
import { isEmbed } from '@/app/helpers/isEmbed';
import { colors } from '@/app/theme/colors';
import { multiplayer } from '@/app/web-workers/multiplayerWebWorker/multiplayer';
import { renderWebWorker } from '@/app/web-workers/renderWebWorker/renderWebWorker';
import { HEADING_SIZE } from '@/shared/constants/gridConstants';
import { sharedEvents } from '@/shared/sharedEvents';
import { Container, Graphics, Rectangle, Renderer, utils } from 'pixi.js';
import './pixiApp.css';

Expand Down Expand Up @@ -71,6 +74,8 @@ export class PixiApp {
destroyed = false;
paused = true;

accentColor = colors.cursorCell;

// for testing purposes
debug!: Graphics;

Expand Down Expand Up @@ -166,13 +171,15 @@ export class PixiApp {
}

private setupListeners() {
sharedEvents.on('changeThemeAccentColor', this.setAccentColor);
window.addEventListener('resize', this.resize);
document.addEventListener('copy', copyToClipboardEvent);
document.addEventListener('paste', pasteFromClipboardEvent);
document.addEventListener('cut', cutToClipboardEvent);
}

private removeListeners() {
sharedEvents.off('changeThemeAccentColor', this.setAccentColor);
window.removeEventListener('resize', this.resize);
document.removeEventListener('copy', copyToClipboardEvent);
document.removeEventListener('paste', pasteFromClipboardEvent);
Expand Down Expand Up @@ -217,6 +224,18 @@ export class PixiApp {
this.destroyed = true;
}

setAccentColor = (): void => {
// Pull the value from the current value as defined in CSS
const accentColor = getCSSVariableTint('primary');
this.accentColor = accentColor;
this.gridLines.dirty = true;
this.axesLines.dirty = true;
this.headings.dirty = true;
this.cursor.dirty = true;
this.cellHighlights.dirty = true;
this.render();
};

resize = (): void => {
if (!this.parent || this.destroyed) return;
const width = this.parent.offsetWidth;
Expand Down
21 changes: 20 additions & 1 deletion quadratic-client/src/app/helpers/convertColor.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as Sentry from '@sentry/react';
import Color from 'color';
import { ColorResult } from 'react-color';
import { colors } from '../theme/colors';
import { Rgba } from '../quadratic-core-types';
import { colors } from '../theme/colors';

export function convertReactColorToString(color: ColorResult): string {
const rgb = color.rgb;
Expand Down Expand Up @@ -72,3 +72,22 @@ export function convertRgbaToTint(rgba: Rgba): { tint: number; alpha: number } {
const rgb = { r: rgba.red, g: rgba.green, b: rgba.blue };
return { tint: Color(rgb).rgbNumber(), alpha: rgba.alpha };
}

/**
* Given the name of a CSS variable that maps to an HSL string, return the tint
* we can use in pixi.
* @param cssVariableName - CSS var without the `--` prefix
*/
export function getCSSVariableTint(cssVariableName: string): number {
if (cssVariableName.startsWith('--')) {
console.warn(
'`getCSSVariableTint` expects a CSS variable name without the `--` prefix. Are you sure you meant: `%s`',
cssVariableName
);
}

const hslColorString = getComputedStyle(document.documentElement).getPropertyValue(`--${cssVariableName}`).trim();
const parsed = Color.hsl(hslColorString.split(' ').map(parseFloat));
const out = parsed.rgbNumber();
return out;
}
7 changes: 6 additions & 1 deletion quadratic-client/src/app/ui/QuadraticSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { showCellTypeOutlinesAtom } from '@/app/atoms/gridSettingsAtom';
import { keyboardShortcutEnumToDisplay } from '@/app/helpers/keyboardShortcutsDisplay';
import { KeyboardSymbols } from '@/app/helpers/keyboardSymbols';
import { ThemePickerMenu } from '@/app/ui/components/ThemePickerMenu';
import { useIsAvailableArgs } from '@/app/ui/hooks/useIsAvailableArgs';
import { KernelMenu } from '@/app/ui/menus/BottomBar/KernelMenu';
import {
Expand Down Expand Up @@ -103,6 +104,9 @@ export const QuadraticSidebar = () => {
</SidebarToggle>
</SidebarTooltip>
</div>
<div className="mb-2 mt-auto flex flex-col items-center justify-end gap-1">
<ThemePickerMenu />
</div>
</nav>
);
};
Expand All @@ -114,7 +118,8 @@ export const SidebarToggle = React.forwardRef<HTMLButtonElement, React.Component
{...props}
ref={ref}
className={cn(
'relative h-8 w-8 rounded text-muted-foreground hover:bg-border hover:text-foreground aria-pressed:bg-border data-[state=open]:bg-border'
'relative h-8 w-8 rounded text-muted-foreground hover:bg-border hover:text-foreground aria-pressed:bg-border data-[state=open]:bg-border',
props.className
)}
>
{children}
Expand Down
61 changes: 61 additions & 0 deletions quadratic-client/src/app/ui/components/ThemePickerMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { focusGrid } from '@/app/helpers/focusGrid';
import { SidebarToggle, SidebarTooltip } from '@/app/ui/QuadraticSidebar';
import { ThemeIcon } from '@/shared/components/Icons';
import { ThemeAccentColors } from '@/shared/components/ThemeAccentColors';
import { ThemeAppearanceModes } from '@/shared/components/ThemeAppearanceModes';
import { useFeatureFlag } from '@/shared/hooks/useFeatureFlag';
import { Popover, PopoverContent, PopoverTrigger } from '@/shared/shadcn/ui/popover';
import { useState } from 'react';

export const ThemePickerMenu = () => {
const [featureFlagThemeAccentColor] = useFeatureFlag('themeAccentColor');
const [featureFlagThemeAppearanceMode] = useFeatureFlag('themeAppearanceMode');
const [showThemeMenu, setShowThemeMenu] = useState(false);

if (!(featureFlagThemeAccentColor || featureFlagThemeAppearanceMode)) {
return null;
}

return (
<Popover open={showThemeMenu} onOpenChange={setShowThemeMenu}>
<SidebarTooltip label="Theme">
<PopoverTrigger asChild>
<SidebarToggle pressed={showThemeMenu} onPressedChange={() => setShowThemeMenu(!showThemeMenu)}>
<ThemeIcon />
</SidebarToggle>
</PopoverTrigger>
</SidebarTooltip>

<PopoverContent
side="right"
align="end"
className="w-80"
onCloseAutoFocus={(e) => {
e.preventDefault();
focusGrid();
}}
>
<h2 className="text-md font-semibold">Theme customization</h2>
<p className="mb-4 text-xs text-muted-foreground">Pick a style that fits you</p>

{featureFlagThemeAccentColor && (
<>
<h3 className="mb-1 text-xs font-semibold">Accent color</h3>
<div className="grid grid-cols-3 gap-2">
<ThemeAccentColors />
</div>
</>
)}
{featureFlagThemeAppearanceMode && (
<>
<h3 className="mb-1 mt-4 text-xs font-semibold">Appearance</h3>

<div className="grid grid-cols-3 gap-2">
<ThemeAppearanceModes />
</div>
</>
)}
</PopoverContent>
</Popover>
);
};
12 changes: 6 additions & 6 deletions quadratic-client/src/app/ui/components/borderMenuStyles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,29 @@
}

.normalBorder {
border-top: 1px solid black;
border-top: 1px solid currentColor;
}

.doubleBorder {
border-top: 2px solid black;
border-top: 2px solid currentColor;
}

.tripleBorder {
border-top: 3px solid black;
border-top: 3px solid currentColor;
}

.dashedBorder {
border-top: 1px dashed black;
border-top: 1px dashed currentColor;
}

.dottedBorder {
border-top: 1px dotted black;
border-top: 1px dotted currentColor;
}

.twoLineBorder {
position: relative;
top: 2px;
border-top: 2px double black;
border-top: 2px double currentColor;
position: relative;
margin-bottom: 5px;
}
1 change: 1 addition & 0 deletions quadratic-client/src/app/ui/components/qColorPicker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,5 @@
.color-picker-submenu .szh-menu > div > div,
.color-picker-dropdown-menu > div > div {
box-shadow: none !important;
background: transparent !important;
}
Loading

0 comments on commit ab44c0f

Please sign in to comment.