Fix 404 for docsite subpages when hard reloading app (#995)

This adds a custom resolver to the docsite server to fall back to .html
addresses when it gets a not found for a given path. This fixes an issue
where subpages would return a 404 after a hard reload of the frontend. I
also added an effect that will run on startup to resolve the latest
docsite url and set it in the metadata, since the backend port changes
on every run of the app. I also made it so that setting the default
homepage in the webview widget will also unset any block-specific
homepage.
This commit is contained in:
Evan Simkowitz 2024-10-09 15:42:33 -04:00 committed by GitHub
parent 1eb458dc16
commit b81ab63ddc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 53 additions and 13 deletions

View File

@ -4,7 +4,9 @@
import { getApi } from "@/app/store/global"; import { getApi } from "@/app/store/global";
import { WebView, WebViewModel } from "@/app/view/webview/webview"; import { WebView, WebViewModel } from "@/app/view/webview/webview";
import { NodeModel } from "@/layout/index"; import { NodeModel } from "@/layout/index";
import { atom } from "jotai"; import { fireAndForget } from "@/util/util";
import { atom, useAtomValue } from "jotai";
import { useEffect } from "react";
import "./helpview.less"; import "./helpview.less";
class HelpViewModel extends WebViewModel { class HelpViewModel extends WebViewModel {
@ -47,6 +49,17 @@ function makeHelpViewModel(blockId: string, nodeModel: NodeModel) {
} }
function HelpView({ model }: { model: HelpViewModel }) { function HelpView({ model }: { model: HelpViewModel }) {
const homepageUrl = useAtomValue(model.homepageUrl);
useEffect(
() =>
fireAndForget(async () => {
const curDocsiteUrl = getApi().getDocsiteUrl();
if (curDocsiteUrl !== homepageUrl) {
await model.setHomepageUrl(curDocsiteUrl, "block");
}
}),
[]
);
return ( return (
<div className="help-view"> <div className="help-view">
<WebView blockId={model.blockId} model={model} /> <WebView blockId={model.blockId} model={model} />

View File

@ -334,6 +334,26 @@ export class WebViewModel implements ViewModel {
globalStore.set(this.isLoading, isLoading); globalStore.set(this.isLoading, isLoading);
} }
async setHomepageUrl(url: string, scope: "global" | "block") {
if (url != null && url != "") {
switch (scope) {
case "block":
await RpcApi.SetMetaCommand(WindowRpcClient, {
oref: WOS.makeORef("block", this.blockId),
meta: { pinnedurl: url },
});
break;
case "global":
await RpcApi.SetMetaCommand(WindowRpcClient, {
oref: WOS.makeORef("block", this.blockId),
meta: { pinnedurl: "" },
});
await RpcApi.SetConfigCommand(WindowRpcClient, { "web:defaulturl": url });
break;
}
}
}
giveFocus(): boolean { giveFocus(): boolean {
const ctrlShiftState = globalStore.get(getSimpleControlShiftAtom()); const ctrlShiftState = globalStore.get(getSimpleControlShiftAtom());
if (ctrlShiftState) { if (ctrlShiftState) {
@ -380,22 +400,13 @@ export class WebViewModel implements ViewModel {
{ {
label: "Set Block Homepage", label: "Set Block Homepage",
click: async () => { click: async () => {
const url = this.getUrl(); await this.setHomepageUrl(this.getUrl(), "block");
if (url != null && url != "") {
await RpcApi.SetMetaCommand(WindowRpcClient, {
oref: WOS.makeORef("block", this.blockId),
meta: { pinnedurl: url },
});
}
}, },
}, },
{ {
label: "Set Default Homepage", label: "Set Default Homepage",
click: async () => { click: async () => {
const url = this.getUrl(); await this.setHomepageUrl(this.getUrl(), "global");
if (url != null && url != "") {
await RpcApi.SetConfigCommand(WindowRpcClient, { "web:defaulturl": url });
}
}, },
}, },
{ {

View File

@ -19,7 +19,7 @@ func GetDocsiteHandler() http.Handler {
log.Println("Docsite is nil, initializing") log.Println("Docsite is nil, initializing")
if err == nil && stat.IsDir() { if err == nil && stat.IsDir() {
log.Printf("Found static site at %s, serving\n", docsiteStaticPath) log.Printf("Found static site at %s, serving\n", docsiteStaticPath)
docsiteHandler = http.FileServer(http.Dir(docsiteStaticPath)) docsiteHandler = http.FileServer(HTMLDir{http.Dir(docsiteStaticPath)})
} else { } else {
log.Println("Did not find static site, serving not found handler") log.Println("Did not find static site, serving not found handler")
docsiteHandler = http.NotFoundHandler() docsiteHandler = http.NotFoundHandler()
@ -27,3 +27,19 @@ func GetDocsiteHandler() http.Handler {
} }
return docsiteHandler return docsiteHandler
} }
type HTMLDir struct {
d http.Dir
}
func (d HTMLDir) Open(name string) (http.File, error) {
// Try name as supplied
f, err := d.d.Open(name)
if os.IsNotExist(err) {
// Not found, try with .html
if f, err := d.d.Open(name + ".html"); err == nil {
return f, nil
}
}
return f, err
}