Skip to content

tab updates #1134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions frontend/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ async function getClipboardURL(): Promise<URL> {
return null;
}
const url = new URL(clipboardText);
if (!url.protocol.startsWith("http")) {
return null;
}
return url;
} catch (e) {
return null;
Expand Down
3 changes: 3 additions & 0 deletions frontend/app/element/quicktips.less
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
align-items: center;
margin-left: 5px;
margin-right: 5px;
align-self: flex-start;

&:first-child {
margin-left: 0;
Expand All @@ -57,6 +58,7 @@
border-radius: 4px;
border: 1px solid var(--keybinding-border-color);
box-shadow: none;
white-space: nowrap;
}

.icon-wrap {
Expand All @@ -66,6 +68,7 @@
font-size: 12px;
border-radius: 2px;
margin-right: 5px;
align-self: flex-start;

svg {
position: relative;
Expand Down
40 changes: 35 additions & 5 deletions frontend/app/element/quicktips.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,44 @@ const QuickTips = () => {
</div>
</div>

<div className="tip-section-header">More Tips</div>
<div className="tip">
<div className="icon-wrap">
<i className="fa-solid fa-sharp fa-computer-mouse fa-fw" />
</div>
Right click the tabs to change backgrounds or rename.
</div>
<div className="tip">
<div className="icon-wrap">
<i className="fa-solid fa-sharp fa-cog fa-fw" />
</div>
Click the gear in the web view to set your homepage
</div>
<div className="tip">
<div className="icon-wrap">
<i className="fa-solid fa-sharp fa-cog fa-fw" />
</div>
Click the gear in the terminal to set your terminal theme and font size
</div>
<div className="tip-section-header">Need More Help?</div>
<div className="tip">
<div className="icon-wrap">
<i className="fa-brands fa-discord fa-fw" />
</div>
<div>
<div>
<a target="_blank" href="https://discord.gg/XfvZ334gwU" rel="noopener">
Join Our Discord
</a>
</div>
<a target="_blank" href="https://discord.gg/XfvZ334gwU" rel="noopener">
Join Our Discord
</a>
</div>
</div>
<div className="tip">
<div className="icon-wrap">
<i className="fa-solid fa-sharp fa-sliders fa-fw" />
</div>
<div>
<a target="_blank" href="https://docs.waveterm.dev/config" rel="noopener">
Configuration Options
</a>
</div>
</div>
</div>
Expand Down
12 changes: 11 additions & 1 deletion frontend/app/store/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,19 @@ function getBlockComponentModel(blockId: string): BlockComponentModel {
return blockComponentModelMap.get(blockId);
}

function getFocusedBlockId(): string {
const layoutModel = getLayoutModelForStaticTab();
const focusedLayoutNode = globalStore.get(layoutModel.focusedNode);
return focusedLayoutNode?.data?.blockId;
}

// pass null to refocus the currently focused block
function refocusNode(blockId: string) {
if (blockId == null) {
return;
blockId = getFocusedBlockId();
if (blockId == null) {
return;
}
}
const layoutModel = getLayoutModelForStaticTab();
const layoutNodeId = layoutModel.getNodeByBlockId(blockId);
Expand Down
12 changes: 7 additions & 5 deletions frontend/app/tab/tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { clsx } from "clsx";
import * as React from "react";
import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from "react";

import { atoms, globalStore } from "@/app/store/global";
import { atoms, globalStore, refocusNode } from "@/app/store/global";
import "./tab.less";

interface TabProps {
Expand Down Expand Up @@ -69,8 +69,8 @@ const Tab = React.memo(
};
}, []);

const handleDoubleClick = (event) => {
event.stopPropagation();
const handleRenameTab = (event) => {
event?.stopPropagation();
setIsEditable(true);
editableTimeoutRef.current = setTimeout(() => {
if (editableRef.current) {
Expand All @@ -86,6 +86,7 @@ const Tab = React.memo(
editableRef.current.innerText = newText;
setIsEditable(false);
services.ObjectService.UpdateTabName(id, newText);
setTimeout(() => refocusNode(null), 10);
};

const handleKeyDown = (event) => {
Expand Down Expand Up @@ -114,7 +115,7 @@ const Tab = React.memo(
editableRef.current.blur();
event.preventDefault();
event.stopPropagation();
} else if (curLen >= 10 && !["Backspace", "Delete", "ArrowLeft", "ArrowRight"].includes(event.key)) {
} else if (curLen >= 14 && !["Backspace", "Delete", "ArrowLeft", "ArrowRight"].includes(event.key)) {
event.preventDefault();
event.stopPropagation();
}
Expand Down Expand Up @@ -155,6 +156,7 @@ const Tab = React.memo(
const bOrder = fullConfig.presets[b]["display:order"] ?? 0;
return aOrder - bOrder;
});
menu.push({ label: "Rename Tab", click: () => handleRenameTab(null) });
menu.push({ label: "Copy TabId", click: () => navigator.clipboard.writeText(id) });
menu.push({ type: "separator" });
if (bgPresets.length > 0) {
Expand Down Expand Up @@ -198,7 +200,7 @@ const Tab = React.memo(
ref={editableRef}
className={clsx("name", { focused: isEditable })}
contentEditable={isEditable}
onDoubleClick={handleDoubleClick}
onDoubleClick={handleRenameTab}
onBlur={handleBlur}
onKeyDown={handleKeyDown}
suppressContentEditableWarning={true}
Expand Down
1 change: 1 addition & 0 deletions frontend/types/gotypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ declare global {
windowids: string[];
tosagreed?: number;
hasoldhistory?: boolean;
nexttabid?: number;
};

// windowservice.CloseTabRtnType
Expand Down
1 change: 1 addition & 0 deletions pkg/waveobj/wtype.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ type Client struct {
Meta MetaMapType `json:"meta"`
TosAgreed int64 `json:"tosagreed,omitempty"`
HasOldHistory bool `json:"hasoldhistory,omitempty"`
NextTabId int `json:"nexttabid,omitempty"`
}

func (*Client) GetOType() string {
Expand Down
27 changes: 22 additions & 5 deletions pkg/wcore/wcore.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,16 @@ func CreateTab(ctx context.Context, windowId string, tabName string, activateTab
return "", fmt.Errorf("error getting window: %w", err)
}
if tabName == "" {
ws, err := wstore.DBMustGet[*waveobj.Workspace](ctx, windowData.WorkspaceId)
client, err := wstore.DBGetSingleton[*waveobj.Client](ctx)
if err != nil {
return "", fmt.Errorf("error getting workspace: %w", err)
return "", fmt.Errorf("error getting client: %w", err)
}
tabName = "T" + fmt.Sprint(client.NextTabId)
client.NextTabId++
err = wstore.DBUpdate(ctx, client)
if err != nil {
return "", fmt.Errorf("error updating client: %w", err)
}
tabName = "T" + fmt.Sprint(len(ws.TabIds)+1)
}
tab, err := wstore.CreateTab(ctx, windowData.WorkspaceId, tabName)
if err != nil {
Expand Down Expand Up @@ -143,7 +148,7 @@ func CreateWindow(ctx context.Context, winSize *waveobj.WinSize) (*waveobj.Windo
if err != nil {
return nil, fmt.Errorf("error inserting workspace: %w", err)
}
_, err = CreateTab(ctx, windowId, "T1", true)
_, err = CreateTab(ctx, windowId, "", true)
if err != nil {
return nil, fmt.Errorf("error inserting tab: %w", err)
}
Expand Down Expand Up @@ -172,7 +177,7 @@ func checkAndFixWindow(ctx context.Context, windowId string) {
}
if len(workspace.TabIds) == 0 {
log.Printf("fixing workspace with no tabs %q (in checkAndFixWindow)\n", workspace.OID)
_, err = CreateTab(ctx, windowId, "T1", true)
_, err = CreateTab(ctx, windowId, "", true)
if err != nil {
log.Printf("error creating tab (in checkAndFixWindow): %v\n", err)
}
Expand All @@ -193,6 +198,17 @@ func EnsureInitialData() (*waveobj.Window, bool, error) {
}
firstRun = true
}
if client.NextTabId == 0 {
tabCount, err := wstore.DBGetCount[*waveobj.Tab](ctx)
if err != nil {
return nil, false, fmt.Errorf("error getting tab count: %w", err)
}
client.NextTabId = tabCount + 1
err = wstore.DBUpdate(ctx, client)
if err != nil {
return nil, false, fmt.Errorf("error updating client: %w", err)
}
}
log.Printf("clientid: %s\n", client.OID)
if len(client.WindowIds) == 1 {
checkAndFixWindow(ctx, client.WindowIds[0])
Expand All @@ -211,6 +227,7 @@ func CreateClient(ctx context.Context) (*waveobj.Client, error) {
client := &waveobj.Client{
OID: uuid.NewString(),
WindowIds: []string{},
NextTabId: 1,
}
err := wstore.DBInsert(ctx, client)
if err != nil {
Expand Down