mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-04 18:59:08 +01:00
default url, default search, open in external browser (#794)
This commit is contained in:
parent
78f838439a
commit
047513bf3a
@ -1,8 +1,10 @@
|
|||||||
// Copyright 2024, Command Line Inc.
|
// Copyright 2024, Command Line Inc.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import { getApi, openLink } from "@/app/store/global";
|
import { getApi, openLink, useSettingsKeyAtom } from "@/app/store/global";
|
||||||
import { getSimpleControlShiftAtom } from "@/app/store/keymodel";
|
import { getSimpleControlShiftAtom } from "@/app/store/keymodel";
|
||||||
|
import { RpcApi } from "@/app/store/wshclientapi";
|
||||||
|
import { WindowRpcClient } from "@/app/store/wshrpcutil";
|
||||||
import { NodeModel } from "@/layout/index";
|
import { NodeModel } from "@/layout/index";
|
||||||
import { WOS, globalStore } from "@/store/global";
|
import { WOS, globalStore } from "@/store/global";
|
||||||
import * as services from "@/store/services";
|
import * as services from "@/store/services";
|
||||||
@ -30,6 +32,7 @@ export class WebViewModel implements ViewModel {
|
|||||||
webviewRef: React.RefObject<WebviewTag>;
|
webviewRef: React.RefObject<WebviewTag>;
|
||||||
urlInputRef: React.RefObject<HTMLInputElement>;
|
urlInputRef: React.RefObject<HTMLInputElement>;
|
||||||
nodeModel: NodeModel;
|
nodeModel: NodeModel;
|
||||||
|
endIconButtons?: jotai.Atom<IconButtonDecl[]>;
|
||||||
|
|
||||||
constructor(blockId: string, nodeModel: NodeModel) {
|
constructor(blockId: string, nodeModel: NodeModel) {
|
||||||
this.nodeModel = nodeModel;
|
this.nodeModel = nodeModel;
|
||||||
@ -48,7 +51,8 @@ export class WebViewModel implements ViewModel {
|
|||||||
this.webviewRef = React.createRef<WebviewTag>();
|
this.webviewRef = React.createRef<WebviewTag>();
|
||||||
|
|
||||||
this.viewText = jotai.atom((get) => {
|
this.viewText = jotai.atom((get) => {
|
||||||
let url = get(this.blockAtom)?.meta?.url || "";
|
const defaultUrlAtom = useSettingsKeyAtom("web:defaulturl");
|
||||||
|
let url = get(this.blockAtom)?.meta?.url || get(defaultUrlAtom);
|
||||||
const currUrl = get(this.url);
|
const currUrl = get(this.url);
|
||||||
if (currUrl !== undefined) {
|
if (currUrl !== undefined) {
|
||||||
url = currUrl;
|
url = currUrl;
|
||||||
@ -91,6 +95,22 @@ export class WebViewModel implements ViewModel {
|
|||||||
},
|
},
|
||||||
] as HeaderElem[];
|
] as HeaderElem[];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.endIconButtons = jotai.atom((get) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
elemtype: "iconbutton",
|
||||||
|
icon: "arrow-up-right-from-square",
|
||||||
|
title: "Open in External Browser",
|
||||||
|
click: () => {
|
||||||
|
const url = this.getUrl();
|
||||||
|
if (url != null && url != "") {
|
||||||
|
return getApi().openExternal(this.getUrl());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,7 +219,11 @@ export class WebViewModel implements ViewModel {
|
|||||||
globalStore.set(this.url, url);
|
globalStore.set(this.url, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
ensureUrlScheme(url: string) {
|
ensureUrlScheme(url: string, searchTemplate: string) {
|
||||||
|
if (url == null) {
|
||||||
|
url = "";
|
||||||
|
}
|
||||||
|
|
||||||
if (/^(http|https):/.test(url)) {
|
if (/^(http|https):/.test(url)) {
|
||||||
// If the URL starts with http: or https:, return it as is
|
// If the URL starts with http: or https:, return it as is
|
||||||
return url;
|
return url;
|
||||||
@ -223,8 +247,11 @@ export class WebViewModel implements ViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, treat it as a search query
|
// Otherwise, treat it as a search query
|
||||||
|
if (searchTemplate == null) {
|
||||||
return `https://www.google.com/search?q=${encodeURIComponent(url)}`;
|
return `https://www.google.com/search?q=${encodeURIComponent(url)}`;
|
||||||
}
|
}
|
||||||
|
return searchTemplate.replace("{query}", encodeURIComponent(url));
|
||||||
|
}
|
||||||
|
|
||||||
normalizeUrl(url: string) {
|
normalizeUrl(url: string) {
|
||||||
if (!url) {
|
if (!url) {
|
||||||
@ -247,7 +274,9 @@ export class WebViewModel implements ViewModel {
|
|||||||
* @param newUrl The new URL to load in the webview.
|
* @param newUrl The new URL to load in the webview.
|
||||||
*/
|
*/
|
||||||
loadUrl(newUrl: string, reason: string) {
|
loadUrl(newUrl: string, reason: string) {
|
||||||
const nextUrl = this.ensureUrlScheme(newUrl);
|
const defaultSearchAtom = useSettingsKeyAtom("web:defaultsearch");
|
||||||
|
const searchTemplate = globalStore.get(defaultSearchAtom);
|
||||||
|
const nextUrl = this.ensureUrlScheme(newUrl, searchTemplate);
|
||||||
console.log("webview loadUrl", reason, nextUrl, "cur=", this.webviewRef?.current.getURL());
|
console.log("webview loadUrl", reason, nextUrl, "cur=", this.webviewRef?.current.getURL());
|
||||||
if (newUrl != nextUrl) {
|
if (newUrl != nextUrl) {
|
||||||
globalStore.set(this.url, nextUrl);
|
globalStore.set(this.url, nextUrl);
|
||||||
@ -317,8 +346,20 @@ export class WebViewModel implements ViewModel {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getSettingsMenuItems() {
|
getSettingsMenuItems(): ContextMenuItem[] {
|
||||||
return [
|
return [
|
||||||
|
{
|
||||||
|
label: "Set Homepage",
|
||||||
|
click: async () => {
|
||||||
|
const url = this.getUrl();
|
||||||
|
if (url != null && url != "") {
|
||||||
|
RpcApi.SetConfigCommand(WindowRpcClient, { "web:defaulturl": url });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "separator",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: this.webviewRef.current?.isDevToolsOpened() ? "Close DevTools" : "Open DevTools",
|
label: this.webviewRef.current?.isDevToolsOpened() ? "Close DevTools" : "Open DevTools",
|
||||||
click: async () => {
|
click: async () => {
|
||||||
@ -347,7 +388,9 @@ interface WebViewProps {
|
|||||||
|
|
||||||
const WebView = memo(({ model }: WebViewProps) => {
|
const WebView = memo(({ model }: WebViewProps) => {
|
||||||
const blockData = jotai.useAtomValue(model.blockAtom);
|
const blockData = jotai.useAtomValue(model.blockAtom);
|
||||||
const metaUrl = blockData?.meta?.url;
|
const defaultUrlAtom = useSettingsKeyAtom("web:defaulturl");
|
||||||
|
const defaultUrl = jotai.useAtomValue(defaultUrlAtom);
|
||||||
|
const metaUrl = blockData?.meta?.url || defaultUrl;
|
||||||
const metaUrlRef = React.useRef(metaUrl);
|
const metaUrlRef = React.useRef(metaUrl);
|
||||||
|
|
||||||
// The initial value of the block metadata URL when the component first renders. Used to set the starting src value for the webview.
|
// The initial value of the block metadata URL when the component first renders. Used to set the starting src value for the webview.
|
||||||
|
2
frontend/types/gotypes.d.ts
vendored
2
frontend/types/gotypes.d.ts
vendored
@ -421,6 +421,8 @@ declare global {
|
|||||||
"editor:stickyscrollenabled"?: boolean;
|
"editor:stickyscrollenabled"?: boolean;
|
||||||
"web:*"?: boolean;
|
"web:*"?: boolean;
|
||||||
"web:openlinksinternally"?: boolean;
|
"web:openlinksinternally"?: boolean;
|
||||||
|
"web:defaulturl"?: string;
|
||||||
|
"web:defaultsearch"?: string;
|
||||||
"blockheader:*"?: boolean;
|
"blockheader:*"?: boolean;
|
||||||
"blockheader:showblockids"?: boolean;
|
"blockheader:showblockids"?: boolean;
|
||||||
"autoupdate:*"?: boolean;
|
"autoupdate:*"?: boolean;
|
||||||
|
@ -27,8 +27,7 @@
|
|||||||
"label": "web",
|
"label": "web",
|
||||||
"blockdef": {
|
"blockdef": {
|
||||||
"meta": {
|
"meta": {
|
||||||
"view": "web",
|
"view": "web"
|
||||||
"url": "https://waveterm.dev/"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
"autoupdate:installonquit": true,
|
"autoupdate:installonquit": true,
|
||||||
"autoupdate:intervalms": 3600000,
|
"autoupdate:intervalms": 3600000,
|
||||||
"editor:minimapenabled": true,
|
"editor:minimapenabled": true,
|
||||||
|
"web:defaulturl": "https://github.com/wavetermdev/waveterm",
|
||||||
|
"web:defaultsearch": "https://www.google.com/search?q={query}",
|
||||||
"window:tilegapsize": 3,
|
"window:tilegapsize": 3,
|
||||||
"telemetry:enabled": true
|
"telemetry:enabled": true
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ const (
|
|||||||
|
|
||||||
ConfigKey_WebClear = "web:*"
|
ConfigKey_WebClear = "web:*"
|
||||||
ConfigKey_WebOpenLinksInternally = "web:openlinksinternally"
|
ConfigKey_WebOpenLinksInternally = "web:openlinksinternally"
|
||||||
|
ConfigKey_WebDefaultUrl = "web:defaulturl"
|
||||||
|
ConfigKey_WebDefaultSearch = "web:defaultsearch"
|
||||||
|
|
||||||
ConfigKey_BlockHeaderClear = "blockheader:*"
|
ConfigKey_BlockHeaderClear = "blockheader:*"
|
||||||
ConfigKey_BlockHeaderShowBlockIds = "blockheader:showblockids"
|
ConfigKey_BlockHeaderShowBlockIds = "blockheader:showblockids"
|
||||||
|
@ -56,6 +56,8 @@ type SettingsType struct {
|
|||||||
|
|
||||||
WebClear bool `json:"web:*,omitempty"`
|
WebClear bool `json:"web:*,omitempty"`
|
||||||
WebOpenLinksInternally bool `json:"web:openlinksinternally,omitempty"`
|
WebOpenLinksInternally bool `json:"web:openlinksinternally,omitempty"`
|
||||||
|
WebDefaultUrl string `json:"web:defaulturl,omitempty"`
|
||||||
|
WebDefaultSearch string `json:"web:defaultsearch,omitempty"`
|
||||||
|
|
||||||
BlockHeaderClear bool `json:"blockheader:*,omitempty"`
|
BlockHeaderClear bool `json:"blockheader:*,omitempty"`
|
||||||
BlockHeaderShowBlockIds bool `json:"blockheader:showblockids,omitempty"`
|
BlockHeaderShowBlockIds bool `json:"blockheader:showblockids,omitempty"`
|
||||||
|
Loading…
Reference in New Issue
Block a user