Skip to content

Commit

Permalink
Merge branch 'main' into releases/0.0.47
Browse files Browse the repository at this point in the history
  • Loading branch information
Kitenite committed Oct 19, 2024
2 parents e9b8ae9 + 1e6eef2 commit e15f2f7
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 45 deletions.
1 change: 1 addition & 0 deletions app/common/models/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ export interface RectDimension {
export enum WindowCommand {
MINIMIZE = 'minimize',
MAXIMIZE = 'maximize',
UNMAXIMIZE = 'unmaximize',
CLOSE = 'close',
}
3 changes: 3 additions & 0 deletions app/electron/main/events/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ function listenForGeneralMessages() {
case WindowCommand.MAXIMIZE:
window?.maximize();
break;
case WindowCommand.UNMAXIMIZE:
window?.unmaximize();
break;
case WindowCommand.CLOSE:
window?.close();
break;
Expand Down
22 changes: 15 additions & 7 deletions app/src/components/AppBar/WindowsControls.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,47 @@
import { Cross1Icon, MinusIcon, SquareIcon } from '@radix-ui/react-icons';
import { useState } from 'react';
import { CopyIcon, Cross1Icon, MinusIcon } from '@radix-ui/react-icons';
import { Button } from '../ui/button';
import { MainChannels } from '/common/constants';
import { WindowCommand } from '/common/models/project';

export const WindowsControls = () => {
const [isMaximized, setIsMaximized] = useState(true);

if (process.platform !== 'win32') {
return null;
}

function sendCommand(command: WindowCommand) {
window.api.invoke(MainChannels.SEND_WINDOW_COMMAND, command);
if (command === WindowCommand.MAXIMIZE || command === WindowCommand.UNMAXIMIZE) {
setIsMaximized(!isMaximized);
}
}

return (
<div className="flex mx-2 text-foreground-active">
<div className="flex text-foreground-active h-full">
<Button
onClick={() => sendCommand(WindowCommand.MINIMIZE)}
variant={'ghost'}
className="hover:bg-background-onlook/30 hover:text-foreground outline-border"
className="hover:bg-background-onlook/30 hover:text-foreground outline-border w-full h-full rounded-none"
aria-label="Minimize"
>
<MinusIcon className="h-3 w-3" />
</Button>
<Button
onClick={() => sendCommand(WindowCommand.MAXIMIZE)}
onClick={() =>
sendCommand(isMaximized ? WindowCommand.UNMAXIMIZE : WindowCommand.MAXIMIZE)
}
variant={'ghost'}
className="hover:bg-background-onlook/30 hover:text-foreground outline-border"
className="hover:bg-background-onlook/30 hover:text-foreground outline-border w-full h-full rounded-none"
aria-label="Maximize"
>
<SquareIcon className="h-3 w-3" />
<CopyIcon className="h-3 w-3 scale-x-[-1]" />
</Button>
<Button
onClick={() => sendCommand(WindowCommand.CLOSE)}
variant={'ghost'}
className="hover:bg-background-onlook/30 hover:text-foreground outline-border"
className="hover:bg-[#e81123] active:bg-[#e81123]/50 hover:text-foreground outline-border w-full h-full rounded-none"
aria-label="Close"
>
<Cross1Icon className="h-3 w-3" />
Expand Down
82 changes: 82 additions & 0 deletions app/src/routes/editor/TopBar/ProjectSelect/ProjectNameInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { useProjectsManager } from '@/components/Context';
import { Input } from '@/components/ui/input';
import { observer } from 'mobx-react-lite';
import React, { useEffect, useRef, useState } from 'react';

const ProjectNameInput = observer(() => {
const projectsManager = useProjectsManager();
const [projectName, setProjectName] = useState('');
const [isEditing, setIsEditing] = useState(false);
const [originalName, setOriginalName] = useState('');
const inputRef = useRef<HTMLInputElement>(null);

useEffect(() => {
if (projectsManager.project) {
setProjectName(projectsManager.project.name);
setOriginalName(projectsManager.project.name);
}
}, [projectsManager.project]);

useEffect(() => {
if (isEditing && inputRef.current) {
inputRef.current.focus();
inputRef.current.select();
}
}, [isEditing]);

const handleRenameProject = () => {
if (projectsManager.project && projectName.trim() !== '') {
projectsManager.updateProject({ ...projectsManager.project, name: projectName.trim() });

setIsEditing(false);
setOriginalName(projectName.trim());
} else {
cancelRename();
}
};

const cancelRename = () => {
setProjectName(originalName);
setIsEditing(false);
};

const handleStartEditing = () => {
setIsEditing(true);
setIsEditing(true);
setOriginalName(projectName);
};

const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
handleRenameProject();
} else if (e.key === 'Escape') {
cancelRename();
}
};

return (
<div className="flex items-center">
{isEditing ? (
<Input
ref={inputRef}
value={projectName}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setProjectName(e.target.value)
}
onKeyDown={handleKeyDown}
onBlur={handleRenameProject}
className="mx-0 max-w-[200px] px-1 py-0 h-6 text-foreground-onlook text-small"
/>
) : (
<span
className="mx-0 max-w-[60px] md:max-w-[100px] lg:max-w-[200px] px-0 text-foreground-onlook text-small truncate cursor-pointer"
onDoubleClick={handleStartEditing}
>
{projectsManager.project?.name}
</span>
)}
</div>
);
});

export default ProjectNameInput;
75 changes: 39 additions & 36 deletions app/src/routes/editor/TopBar/ProjectSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { ChevronDownIcon, FileIcon } from '@radix-ui/react-icons';
import { observer } from 'mobx-react-lite';
import ProjectNameInput from './ProjectNameInput';
import { MainChannels } from '/common/constants';

const ProjectBreadcrumb = observer(() => {
Expand Down Expand Up @@ -45,42 +46,44 @@ const ProjectBreadcrumb = observer(() => {
}

return (
<div className="mx-2 flex flex-row items-center text-small gap-2">
<Tooltip>
<TooltipTrigger asChild>
<Button
variant={'ghost'}
className="mx-0 px-0 text-foreground-onlook text-small hover:text-foreground-active hover:bg-transparent"
onClick={handleReturn}
>
<img
src={iconLogo}
className="w-6 h-6 mr-2 hidden md:block"
alt="Onlook logo"
/>
{'Onlook'}
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="pt-1 text-background bg-foreground">
Return to project selection
</TooltipContent>
</Tooltip>
<p className="mb-[2px] min-w-[4px] text-foreground-onlook">{'/'}</p>
<DropdownMenu>
<DropdownMenuTrigger className="group flex flex-row gap-2 items-center mx-0 max-w-[60px] md:max-w-[100px] lg:max-w-[200px] px-0 text-foreground-onlook text-small truncate hover:text-foreground-hover hover:bg-transparent">
{projectsManager.project?.name}
<ChevronDownIcon className="transition-all rotate-0 group-data-[state=open]:-rotate-180 duration-200 ease-in-out" />
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem onClick={handleOpenProjectFolder}>
<div className="flex row center items-center">
<FileIcon className="mr-2" />
{'Open Project Folder'}
</div>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
<>
<div className="mx-2 flex flex-row items-center text-small gap-2">
<Tooltip>
<TooltipTrigger asChild>
<Button
variant={'ghost'}
className="mx-0 px-0 text-foreground-onlook text-small hover:text-foreground-active hover:bg-transparent"
onClick={handleReturn}
>
<img
src={iconLogo}
className="w-6 h-6 mr-2 hidden md:block"
alt="Onlook logo"
/>
{'Onlook'}
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="pt-1 text-background bg-foreground">
Return to project selection
</TooltipContent>
</Tooltip>
<p className="mb-[2px] min-w-[4px] text-foreground-onlook">{'/'}</p>
<ProjectNameInput />
<DropdownMenu>
<DropdownMenuTrigger className="group flex flex-row gap-2 items-center mx-0 px-0 text-foreground-onlook text-small hover:text-foreground-hover hover:bg-transparent">
<ChevronDownIcon className="transition-all rotate-0 group-data-[state=open]:-rotate-180 duration-200 ease-in-out" />
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem onClick={handleOpenProjectFolder}>
<div className="flex row center items-center">
<FileIcon className="mr-2" />
{'Open Project Folder'}
</div>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</>
);
});

Expand Down
30 changes: 28 additions & 2 deletions app/src/routes/editor/WebviewArea/BrowserControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,22 @@ function BrowserControls({
}
}

function canGoBack() {
try {
return webviewRef.current?.canGoBack();
} catch (e) {
return false;
}
}

function canGoForward() {
try {
return webviewRef.current?.canGoForward();
} catch (e) {
return false;
}
}

return (
<div
className={clsx(
Expand All @@ -145,10 +161,20 @@ function BrowserControls({
onMouseOver={() => setHovered(true)}
onMouseOut={() => setHovered(false)}
>
<Button variant="outline" className="bg-background-secondary/60" onClick={goBack}>
<Button
variant="outline"
className="bg-background-secondary/60"
onClick={goBack}
disabled={!canGoBack()}
>
<ArrowLeftIcon />
</Button>
<Button variant="outline" className="bg-background-secondary/60" onClick={goForward}>
<Button
variant="outline"
className="bg-background-secondary/60"
onClick={goForward}
disabled={!canGoForward()}
>
<ArrowRightIcon />
</Button>
<Button variant="outline" className="bg-background-secondary/60" onClick={reload}>
Expand Down

0 comments on commit e15f2f7

Please sign in to comment.