mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-02 18:39:05 +01:00
testing new default header
This commit is contained in:
parent
a382d5d41e
commit
15cc681b4b
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user