2024-08-01 07:22:52 +02:00
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
2024-10-26 03:36:09 +02:00
import { BlockNodeModel } from "@/app/block/blocktypes" ;
2024-10-04 05:28:05 +02:00
import { getApi } from "@/app/store/global" ;
2024-10-08 02:20:18 +02:00
import { WebView , WebViewModel } from "@/app/view/webview/webview" ;
2024-10-09 21:42:33 +02:00
import { fireAndForget } from "@/util/util" ;
import { atom , useAtomValue } from "jotai" ;
2024-10-18 01:03:17 +02:00
import { useCallback } from "react" ;
2024-11-22 01:05:04 +01:00
import "./helpview.scss" ;
2024-08-01 07:22:52 +02:00
2024-11-14 20:03:10 +01:00
const docsiteWebUrl = "https://docs.waveterm.dev/" ;
const baseUrlRegex = /http[s]?:\/\/([^:\/])+(:\d+)?/ ;
2024-10-08 02:20:18 +02:00
class HelpViewModel extends WebViewModel {
2024-10-26 03:36:09 +02:00
constructor ( blockId : string , nodeModel : BlockNodeModel ) {
2024-10-08 02:20:18 +02:00
super ( blockId , nodeModel ) ;
2024-10-09 01:54:41 +02:00
this . viewText = atom ( ( get ) = > {
// force a dependency on meta.url so we re-render the buttons when the url changes
2024-11-14 20:03:10 +01:00
get ( this . blockAtom ) ? . meta ? . url || get ( this . homepageUrl ) ;
2024-10-09 01:54:41 +02:00
return [
{
elemtype : "iconbutton" ,
icon : "chevron-left" ,
click : this.handleBack.bind ( this ) ,
disabled : this.shouldDisableBackButton ( ) ,
} ,
{
elemtype : "iconbutton" ,
icon : "chevron-right" ,
click : this.handleForward.bind ( this ) ,
disabled : this.shouldDisableForwardButton ( ) ,
} ,
{
elemtype : "iconbutton" ,
icon : "house" ,
click : this.handleHome.bind ( this ) ,
disabled : this.shouldDisableHomeButton ( ) ,
} ,
] ;
} ) ;
2024-10-08 02:20:18 +02:00
this . homepageUrl = atom ( getApi ( ) . getDocsiteUrl ( ) ) ;
2024-09-05 06:15:39 +02:00
this . viewType = "help" ;
2024-10-08 02:20:18 +02:00
this . viewIcon = atom ( "circle-question" ) ;
this . viewName = atom ( "Help" ) ;
2024-11-14 20:03:10 +01:00
/ *
Add callback to take the current embedded docsite url and return the equivalent page in the public docsite .
The port used by the embedded docsite changes every time the app runs and the current page may be cached from a previous run so we can ' t trust that it matches the current embedded url .
We have a regex at the top of this file that can extract the base part of the url ( i . e . http : //127.0.0.1:53288). We'll use this regex to strip the base part of the url from both the current
page and the embedded docsite url . Because we host the embedded docsite at a subdirectory , we also need to strip that ( hence the second replace ) . Then , we can build the public url from whatever ' s left .
* /
this . modifyExternalUrl = ( url : string ) = > {
const strippedDocsiteUrl = getApi ( ) . getDocsiteUrl ( ) . replace ( baseUrlRegex , "" ) ;
const strippedCurUrl = url . replace ( baseUrlRegex , "" ) . replace ( strippedDocsiteUrl , "" ) ;
const newUrl = docsiteWebUrl + strippedCurUrl ;
2024-12-12 01:09:47 +01:00
console . log ( "modify-external-url" , url , newUrl ) ;
2024-11-14 20:03:10 +01:00
return newUrl ;
} ;
2024-09-05 06:15:39 +02:00
}
2024-11-26 03:07:29 +01:00
getSettingsMenuItems ( ) : ContextMenuItem [ ] {
return [
{
label : this.webviewRef.current?.isDevToolsOpened ( ) ? "Close DevTools" : "Open DevTools" ,
click : async ( ) = > {
if ( this . webviewRef . current ) {
if ( this . webviewRef . current . isDevToolsOpened ( ) ) {
this . webviewRef . current . closeDevTools ( ) ;
} else {
this . webviewRef . current . openDevTools ( ) ;
}
}
} ,
} ,
] ;
}
2024-09-05 06:15:39 +02:00
}
2024-10-26 03:36:09 +02:00
function makeHelpViewModel ( blockId : string , nodeModel : BlockNodeModel ) {
2024-10-08 02:20:18 +02:00
return new HelpViewModel ( blockId , nodeModel ) ;
2024-09-05 06:15:39 +02:00
}
2024-10-06 22:55:26 +02:00
function HelpView ( { model } : { model : HelpViewModel } ) {
2024-10-09 21:42:33 +02:00
const homepageUrl = useAtomValue ( model . homepageUrl ) ;
2024-10-18 00:38:42 +02:00
// Effect to update the docsite base url when the app restarts, since the webserver port is dynamic
2024-10-18 01:03:17 +02:00
const onFailLoad = useCallback (
( url : string ) = >
2024-10-09 21:42:33 +02:00
fireAndForget ( async ( ) = > {
2024-10-18 01:03:17 +02:00
const newDocsiteUrl = getApi ( ) . getDocsiteUrl ( ) ;
// Correct the homepage URL, if necessary
if ( newDocsiteUrl !== homepageUrl ) {
await model . setHomepageUrl ( newDocsiteUrl , "block" ) ;
}
// Correct the base URL of the current page, if necessary
const newBaseUrl = baseUrlRegex . exec ( newDocsiteUrl ) ? . [ 0 ] ;
const curBaseUrl = baseUrlRegex . exec ( url ) ? . [ 0 ] ;
if ( curBaseUrl && newBaseUrl && curBaseUrl !== newBaseUrl ) {
model . loadUrl ( url . replace ( curBaseUrl , newBaseUrl ) , "fix-fail-load" ) ;
2024-10-09 21:42:33 +02:00
}
} ) ,
2024-10-18 01:03:17 +02:00
[ homepageUrl ]
2024-10-09 21:42:33 +02:00
) ;
2024-10-04 05:28:05 +02:00
return (
< div className = "help-view" >
2024-10-18 01:03:17 +02:00
< WebView blockId = { model . blockId } model = { model } onFailLoad = { onFailLoad } / >
2024-10-04 05:28:05 +02:00
< / div >
) ;
2024-08-01 07:22:52 +02:00
}
2024-09-05 06:15:39 +02:00
export { HelpView , HelpViewModel , makeHelpViewModel } ;