testing new default header

This commit is contained in:
sawka 2024-07-05 15:47:35 -07:00
parent a382d5d41e
commit 15cc681b4b
4 changed files with 252 additions and 25 deletions

View File

@ -11,6 +11,8 @@
overflow: hidden;
min-height: 0;
position: relative;
border-radius: 8px;
background-color: rgba(255, 255, 255, 0.1);
.block-frame-icon {
margin-right: 0.5em;
@ -53,6 +55,88 @@
}
}
&.block-frame-default {
border: 2px solid transparent;
&.block-focused {
border: 2px solid var(--accent-color);
&.block-no-highlight,
&.block-preview {
border: 2px solid transparent;
}
}
.block-frame-default-header {
display: flex;
height: 26px;
padding-left: 6px;
align-items: center;
gap: 8px;
align-self: stretch;
font: var(--header-font);
background-color: #262626;
border-radius: 8px 8px 0 0;
.block-frame-default-header-iconview {
display: flex;
align-items: center;
gap: 8px;
color: var(--main-text-color);
.block-frame-view-icon {
font-size: var(--header-icon-size);
opacity: 0.5;
width: var(--header-icon-width);
i {
margin-right: 0;
}
}
.block-frame-view-type {
line-height: 12px;
font-weight: 700;
}
.block-frame-blockid {
opacity: 0.5;
}
}
.block-frame-end-icons {
display: flex;
align-items: center;
.block-frame-settings {
display: flex;
width: 24px;
padding: 6px;
justify-content: center;
align-items: center;
opacity: 0.5;
&:hover {
opacity: 1;
}
}
.block-frame-default-close {
display: flex;
justify-content: center;
align-items: center;
opacity: 0.5;
font-size: 11px;
width: 24px;
padding: 4px 6px;
&:hover {
opacity: 1;
}
}
}
}
}
&.block-frame-tech {
border: 2px solid var(--border-color);
border-radius: 7px;
@ -62,6 +146,11 @@
width: 100%;
overflow: visible;
.block-header-icon {
font-size: 14px;
padding: 0 0;
}
&.block-preview {
background-color: var(--main-bg-color);

View File

@ -95,6 +95,26 @@ function processTitleString(titleString: string): React.ReactNode[] {
return partsStack[0];
}
function getBlockHeaderIcon(blockIcon: string, blockData: Block): React.ReactNode {
let blockIconElem: React.ReactNode = null;
if (util.isBlank(blockIcon)) {
blockIcon = "square";
}
let iconColor = blockData?.meta?.["icon:color"];
if (iconColor && !iconColor.match(colorRegex)) {
iconColor = null;
}
let iconStyle = null;
if (!util.isBlank(iconColor)) {
iconStyle = { color: iconColor };
}
const iconClass = util.makeIconClass(blockIcon, true);
if (iconClass != null) {
blockIconElem = <i key="icon" style={iconStyle} className={clsx(`block-frame-icon`, iconClass)} />;
}
return blockIconElem;
}
function getBlockHeaderText(blockIcon: string, blockData: Block, settings: SettingsConfigType): React.ReactNode {
if (!blockData) {
return "no block data";
@ -103,21 +123,7 @@ function getBlockHeaderText(blockIcon: string, blockData: Block, settings: Setti
if (settings?.blockheader?.showblockids) {
blockIdStr = ` [${blockData.oid.substring(0, 8)}]`;
}
let blockIconElem: React.ReactNode = null;
if (!util.isBlank(blockIcon)) {
let iconColor = blockData?.meta?.["icon:color"];
if (iconColor && !iconColor.match(colorRegex)) {
iconColor = null;
}
let iconStyle = null;
if (!util.isBlank(iconColor)) {
iconStyle = { color: iconColor };
}
const iconClass = util.makeIconClass(blockIcon, false);
if (iconClass != null) {
blockIconElem = <i key="icon" style={iconStyle} className={clsx(`block-frame-icon`, iconClass)} />;
}
}
let blockIconElem = getBlockHeaderIcon(blockIcon, blockData);
if (!util.isBlank(blockData?.meta?.title)) {
try {
const rtn = processTitleString(blockData.meta.title) ?? [];
@ -207,6 +213,7 @@ interface BlockFrameProps {
onClick?: () => void;
onFocusCapture?: React.FocusEventHandler<HTMLDivElement>;
preview: boolean;
numBlocksInTab?: number;
children?: React.ReactNode;
blockRef?: React.RefObject<HTMLDivElement>;
dragHandleRef?: React.RefObject<HTMLDivElement>;
@ -272,6 +279,117 @@ const BlockFrame_Tech_Component = ({
const BlockFrame_Tech = React.memo(BlockFrame_Tech_Component) as typeof BlockFrame_Tech_Component;
const BlockFrame_Default_Component = ({
blockId,
onClose,
onClick,
preview,
blockRef,
dragHandleRef,
numBlocksInTab,
onFocusCapture,
children,
}: BlockFrameProps) => {
const [blockData] = WOS.useWaveObjectValue<Block>(WOS.makeORef("block", blockId));
const settingsConfig = jotai.useAtomValue(atoms.settingsConfigAtom);
const isFocusedAtom = useBlockAtom<boolean>(blockId, "isFocused", () => {
return jotai.atom((get) => {
const winData = get(atoms.waveWindow);
return winData?.activeblockid === blockId;
});
});
let isFocused = jotai.useAtomValue(isFocusedAtom);
const blockIcon = useBlockIcon(blockId);
if (preview) {
isFocused = true;
}
let style: React.CSSProperties = {};
if (!isFocused && blockData?.meta?.["frame:bordercolor"]) {
style.borderColor = blockData.meta["frame:bordercolor"];
}
if (isFocused && blockData?.meta?.["frame:bordercolor:focused"]) {
style.borderColor = blockData.meta["frame:bordercolor:focused"];
}
let handleSettings = (e: React.MouseEvent<any>) => {
let menuItems: ContextMenuItem[] = [];
menuItems.push({
label: "Focus Block",
click: () => {
alert("Not Implemented");
},
});
menuItems.push({ label: "Minimize" });
menuItems.push({ type: "separator" });
menuItems.push({
label: "Move to New Window",
click: () => {
let currentTabId = globalStore.get(atoms.activeTabId);
try {
services.WindowService.MoveBlockToNewWindow(currentTabId, blockData.oid);
} catch (e) {
console.error("error moving block to new window", e);
}
},
});
menuItems.push({ type: "separator" });
menuItems.push({
label: "Copy BlockId",
click: () => {
navigator.clipboard.writeText(blockData.oid);
},
});
menuItems.push({ type: "separator" });
menuItems.push({ label: "Close", click: onClose });
ContextMenuModel.showContextMenu(menuItems, e);
};
if (preview) {
handleSettings = null;
}
return (
<div
className={clsx(
"block",
"block-frame-default",
isFocused ? "block-focused" : null,
preview ? "block-preview" : null,
numBlocksInTab == 1 ? "block-no-highlight" : null
)}
onClick={onClick}
onFocusCapture={onFocusCapture}
ref={blockRef}
style={style}
>
<div
className="block-frame-default-header"
ref={dragHandleRef}
onContextMenu={(e) => handleHeaderContextMenu(e, blockData, onClose)}
>
<div className="block-frame-default-header-iconview">
<div className="block-frame-view-icon">{getBlockHeaderIcon(blockIcon, blockData)}</div>
<div className="block-frame-view-type">{blockViewToName(blockData?.view)}</div>
{settingsConfig?.blockheader?.showblockids && (
<div className="block-frame-blockid">[{blockId.substring(0, 8)}]</div>
)}
</div>
<div className="flex-spacer"></div>
<div className="block-frame-end-icons">
<div className="block-frame-settings" onClick={handleSettings}>
<i className="fa fa-solid fa-cog fa-fw" />
</div>
<div className={clsx("block-frame-default-close")} onClick={onClose}>
<i className="fa fa-solid fa-xmark-large fa-fw" />
</div>
</div>
</div>
{preview ? <div className="block-frame-preview" /> : children}
</div>
);
};
const BlockFrame_Default = React.memo(BlockFrame_Default_Component) as typeof BlockFrame_Default_Component;
const BlockFrame_Frameless = ({
blockId,
onClose,
@ -354,27 +472,27 @@ const BlockFrame = React.memo((props: BlockFrameProps) => {
if (!blockId || !blockData) {
return null;
}
let FrameElem = BlockFrame_Tech;
let FrameElem = BlockFrame_Default;
const numBlocks = tabData?.blockids?.length ?? 0;
// Preview should always render as the full tech frame
if (!props.preview) {
// if 0 or 1 blocks, use frameless, otherwise use tech
const numBlocks = tabData?.blockids?.length ?? 0;
if (numBlocks <= 1) {
FrameElem = BlockFrame_Frameless;
}
// if (numBlocks <= 1) {
// FrameElem = BlockFrame_Frameless;
// }
if (blockData?.meta?.["frame"] === "tech") {
FrameElem = BlockFrame_Tech;
} else if (blockData?.meta?.["frame"] === "frameless") {
FrameElem = BlockFrame_Frameless;
}
}
return <FrameElem {...props} />;
return <FrameElem {...props} numBlocksInTab={numBlocks} />;
});
function blockViewToIcon(view: string): string {
console.log("blockViewToIcon", view);
if (view == "term") {
return "square-terminal";
return "terminal";
}
if (view == "preview") {
return "file";
@ -388,6 +506,22 @@ function blockViewToIcon(view: string): string {
return null;
}
function blockViewToName(view: string): string {
if (view == "term") {
return "Terminal";
}
if (view == "preview") {
return "Preview";
}
if (view == "web") {
return "Web";
}
if (view == "waveai") {
return "WaveAI";
}
return view;
}
function useBlockIcon(blockId: string): string {
const blockIconOverrideAtom = useBlockAtom<string>(blockId, "blockicon:override", () => {
return jotai.atom<string>(null);

View File

@ -8,7 +8,7 @@
--grey-text-color: #666;
--main-bg-color: #000000;
--border-color: #333333;
--base-font: normal 15px / normal "Inter", sans-serif;
--base-font: normal 14px / normal "Inter", sans-serif;
--fixed-font: normal 12px / normal "Hack", monospace;
--accent-color: rgb(88, 193, 66);
--panel-bg-color: rgba(31, 33, 31, 1);
@ -25,6 +25,10 @@
--scrollbar-thumb-hover-color: rgba(255, 255, 255, 0.5);
--scrollbar-thumb-active-color: rgba(255, 255, 255, 0.6);
--header-font: 700 11px / normal "Inter", sans-serif;
--header-icon-size: 14px;
--header-icon-width: 16px;
--tab-green: rgb(88, 193, 66);
/* z-index values */

View File

@ -262,10 +262,10 @@ const TerminalView = ({ blockId }: { blockId: string }) => {
shellProcStatusRef.current = status;
if (status == "running") {
termRef.current?.setIsRunning(true);
globalStore.set(blockIconOverrideAtom, "square-terminal");
globalStore.set(blockIconOverrideAtom, "terminal");
} else {
termRef.current?.setIsRunning(false);
globalStore.set(blockIconOverrideAtom, "regular@square-terminal");
globalStore.set(blockIconOverrideAtom, "regular@terminal");
}
}
const initialRTStatus = services.BlockService.GetControllerStatus(blockId);