mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-21 16:38:23 +01:00
Add button to mute audio when media is playing in webview (#1036)
![image](https://github.com/user-attachments/assets/202636dc-aab5-4164-9729-fecd0cc804ae) Also fixes atom usage for the url bar so it will properly update when any upstream atom states change
This commit is contained in:
parent
359974d505
commit
69c99dd13a
@ -221,15 +221,6 @@
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.block-frame-div-url,
|
|
||||||
.block-frame-div-search {
|
|
||||||
background: rgba(255, 255, 255, 0.1);
|
|
||||||
|
|
||||||
input {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.block-frame-end-icons {
|
.block-frame-end-icons {
|
||||||
|
@ -15,3 +15,16 @@
|
|||||||
transform: translate3d(0, 0, 0);
|
transform: translate3d(0, 0, 0);
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.block-frame-div-url {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
|
||||||
|
input {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconbutton {
|
||||||
|
width: fit-content !important;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -46,6 +46,8 @@ export class WebViewModel implements ViewModel {
|
|||||||
urlInputRef: React.RefObject<HTMLInputElement>;
|
urlInputRef: React.RefObject<HTMLInputElement>;
|
||||||
nodeModel: NodeModel;
|
nodeModel: NodeModel;
|
||||||
endIconButtons?: Atom<IconButtonDecl[]>;
|
endIconButtons?: Atom<IconButtonDecl[]>;
|
||||||
|
mediaPlaying: PrimitiveAtom<boolean>;
|
||||||
|
mediaMuted: PrimitiveAtom<boolean>;
|
||||||
|
|
||||||
constructor(blockId: string, nodeModel: NodeModel) {
|
constructor(blockId: string, nodeModel: NodeModel) {
|
||||||
this.nodeModel = nodeModel;
|
this.nodeModel = nodeModel;
|
||||||
@ -70,12 +72,18 @@ export class WebViewModel implements ViewModel {
|
|||||||
this.urlInputRef = React.createRef<HTMLInputElement>();
|
this.urlInputRef = React.createRef<HTMLInputElement>();
|
||||||
this.webviewRef = React.createRef<WebviewTag>();
|
this.webviewRef = React.createRef<WebviewTag>();
|
||||||
|
|
||||||
|
this.mediaPlaying = atom(false);
|
||||||
|
this.mediaMuted = atom(false);
|
||||||
|
|
||||||
this.viewText = atom((get) => {
|
this.viewText = atom((get) => {
|
||||||
let url = get(this.blockAtom)?.meta?.url || get(this.homepageUrl);
|
const homepageUrl = get(this.homepageUrl);
|
||||||
|
const metaUrl = get(this.blockAtom)?.meta?.url;
|
||||||
const currUrl = get(this.url);
|
const currUrl = get(this.url);
|
||||||
if (currUrl !== undefined) {
|
const urlWrapperClassName = get(this.urlWrapperClassName);
|
||||||
url = currUrl;
|
const refreshIcon = get(this.refreshIcon);
|
||||||
}
|
const mediaPlaying = get(this.mediaPlaying);
|
||||||
|
const mediaMuted = get(this.mediaMuted);
|
||||||
|
const url = currUrl ?? metaUrl ?? homepageUrl;
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
elemtype: "iconbutton",
|
elemtype: "iconbutton",
|
||||||
@ -97,7 +105,7 @@ export class WebViewModel implements ViewModel {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
elemtype: "div",
|
elemtype: "div",
|
||||||
className: clsx("block-frame-div-url", get(this.urlWrapperClassName)),
|
className: clsx("block-frame-div-url", urlWrapperClassName),
|
||||||
onMouseOver: this.handleUrlWrapperMouseOver.bind(this),
|
onMouseOver: this.handleUrlWrapperMouseOver.bind(this),
|
||||||
onMouseOut: this.handleUrlWrapperMouseOut.bind(this),
|
onMouseOut: this.handleUrlWrapperMouseOut.bind(this),
|
||||||
children: [
|
children: [
|
||||||
@ -111,26 +119,31 @@ export class WebViewModel implements ViewModel {
|
|||||||
onFocus: this.handleFocus.bind(this),
|
onFocus: this.handleFocus.bind(this),
|
||||||
onBlur: this.handleBlur.bind(this),
|
onBlur: this.handleBlur.bind(this),
|
||||||
},
|
},
|
||||||
|
mediaPlaying && {
|
||||||
|
elemtype: "iconbutton",
|
||||||
|
icon: mediaMuted ? "volume-slash" : "volume",
|
||||||
|
click: this.handleMuteChange.bind(this),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
elemtype: "iconbutton",
|
elemtype: "iconbutton",
|
||||||
icon: get(this.refreshIcon),
|
icon: refreshIcon,
|
||||||
click: this.handleRefresh.bind(this),
|
click: this.handleRefresh.bind(this),
|
||||||
},
|
},
|
||||||
],
|
].filter((v) => v),
|
||||||
},
|
},
|
||||||
] as HeaderElem[];
|
] as HeaderElem[];
|
||||||
});
|
});
|
||||||
|
|
||||||
this.endIconButtons = atom((get) => {
|
this.endIconButtons = atom((get) => {
|
||||||
|
const url = get(this.url);
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
elemtype: "iconbutton",
|
elemtype: "iconbutton",
|
||||||
icon: "arrow-up-right-from-square",
|
icon: "arrow-up-right-from-square",
|
||||||
title: "Open in External Browser",
|
title: "Open in External Browser",
|
||||||
click: () => {
|
click: () => {
|
||||||
const url = this.getUrl();
|
|
||||||
if (url != null && url != "") {
|
if (url != null && url != "") {
|
||||||
return getApi().openExternal(this.getUrl());
|
return getApi().openExternal(url);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -180,6 +193,25 @@ export class WebViewModel implements ViewModel {
|
|||||||
this.loadUrl(globalStore.get(this.homepageUrl), "home");
|
this.loadUrl(globalStore.get(this.homepageUrl), "home");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setMediaPlaying(isPlaying: boolean) {
|
||||||
|
console.log("setMediaPlaying", isPlaying);
|
||||||
|
globalStore.set(this.mediaPlaying, isPlaying);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMuteChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||||
|
if (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const newMutedVal = !this.webviewRef.current?.isAudioMuted();
|
||||||
|
globalStore.set(this.mediaMuted, newMutedVal);
|
||||||
|
this.webviewRef.current?.setAudioMuted(newMutedVal);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to change mute value", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleUrlWrapperMouseOver(e: React.MouseEvent<HTMLDivElement, MouseEvent>) {
|
handleUrlWrapperMouseOver(e: React.MouseEvent<HTMLDivElement, MouseEvent>) {
|
||||||
const urlInputFocused = globalStore.get(this.urlInputFocused);
|
const urlInputFocused = globalStore.get(this.urlInputFocused);
|
||||||
if (e.type === "mouseover" && !urlInputFocused) {
|
if (e.type === "mouseover" && !urlInputFocused) {
|
||||||
@ -536,6 +568,12 @@ const WebView = memo(({ model }: WebViewProps) => {
|
|||||||
setDomReady(true);
|
setDomReady(true);
|
||||||
setBgColor();
|
setBgColor();
|
||||||
};
|
};
|
||||||
|
const handleMediaPlaying = () => {
|
||||||
|
model.setMediaPlaying(true);
|
||||||
|
};
|
||||||
|
const handleMediaPaused = () => {
|
||||||
|
model.setMediaPlaying(false);
|
||||||
|
};
|
||||||
|
|
||||||
webview.addEventListener("did-navigate-in-page", navigateListener);
|
webview.addEventListener("did-navigate-in-page", navigateListener);
|
||||||
webview.addEventListener("did-navigate", navigateListener);
|
webview.addEventListener("did-navigate", navigateListener);
|
||||||
@ -546,6 +584,8 @@ const WebView = memo(({ model }: WebViewProps) => {
|
|||||||
webview.addEventListener("focus", webviewFocus);
|
webview.addEventListener("focus", webviewFocus);
|
||||||
webview.addEventListener("blur", webviewBlur);
|
webview.addEventListener("blur", webviewBlur);
|
||||||
webview.addEventListener("dom-ready", handleDomReady);
|
webview.addEventListener("dom-ready", handleDomReady);
|
||||||
|
webview.addEventListener("media-started-playing", handleMediaPlaying);
|
||||||
|
webview.addEventListener("media-paused", handleMediaPaused);
|
||||||
|
|
||||||
// Clean up event listeners on component unmount
|
// Clean up event listeners on component unmount
|
||||||
return () => {
|
return () => {
|
||||||
@ -558,6 +598,8 @@ const WebView = memo(({ model }: WebViewProps) => {
|
|||||||
webview.removeEventListener("focus", webviewFocus);
|
webview.removeEventListener("focus", webviewFocus);
|
||||||
webview.removeEventListener("blur", webviewBlur);
|
webview.removeEventListener("blur", webviewBlur);
|
||||||
webview.removeEventListener("dom-ready", handleDomReady);
|
webview.removeEventListener("dom-ready", handleDomReady);
|
||||||
|
webview.removeEventListener("media-started-playing", handleMediaPlaying);
|
||||||
|
webview.removeEventListener("media-paused", handleMediaPaused);
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user