From b81ab63ddc8d12879111463ce62249c4ff2ec9de Mon Sep 17 00:00:00 2001 From: Evan Simkowitz Date: Wed, 9 Oct 2024 15:42:33 -0400 Subject: [PATCH] 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. --- frontend/app/view/helpview/helpview.tsx | 15 ++++++++++- frontend/app/view/webview/webview.tsx | 33 ++++++++++++++++--------- pkg/docsite/docsite.go | 18 +++++++++++++- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/frontend/app/view/helpview/helpview.tsx b/frontend/app/view/helpview/helpview.tsx index 724cdcfb5..ae4176101 100644 --- a/frontend/app/view/helpview/helpview.tsx +++ b/frontend/app/view/helpview/helpview.tsx @@ -4,7 +4,9 @@ import { getApi } from "@/app/store/global"; import { WebView, WebViewModel } from "@/app/view/webview/webview"; 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"; class HelpViewModel extends WebViewModel { @@ -47,6 +49,17 @@ function makeHelpViewModel(blockId: string, nodeModel: NodeModel) { } 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 (
diff --git a/frontend/app/view/webview/webview.tsx b/frontend/app/view/webview/webview.tsx index d92b2d83a..ceb2f5455 100644 --- a/frontend/app/view/webview/webview.tsx +++ b/frontend/app/view/webview/webview.tsx @@ -334,6 +334,26 @@ export class WebViewModel implements ViewModel { 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 { const ctrlShiftState = globalStore.get(getSimpleControlShiftAtom()); if (ctrlShiftState) { @@ -380,22 +400,13 @@ export class WebViewModel implements ViewModel { { label: "Set Block Homepage", click: async () => { - const url = this.getUrl(); - if (url != null && url != "") { - await RpcApi.SetMetaCommand(WindowRpcClient, { - oref: WOS.makeORef("block", this.blockId), - meta: { pinnedurl: url }, - }); - } + await this.setHomepageUrl(this.getUrl(), "block"); }, }, { label: "Set Default Homepage", click: async () => { - const url = this.getUrl(); - if (url != null && url != "") { - await RpcApi.SetConfigCommand(WindowRpcClient, { "web:defaulturl": url }); - } + await this.setHomepageUrl(this.getUrl(), "global"); }, }, { diff --git a/pkg/docsite/docsite.go b/pkg/docsite/docsite.go index f6b44676d..3e83fdfc8 100644 --- a/pkg/docsite/docsite.go +++ b/pkg/docsite/docsite.go @@ -19,7 +19,7 @@ func GetDocsiteHandler() http.Handler { log.Println("Docsite is nil, initializing") if err == nil && stat.IsDir() { log.Printf("Found static site at %s, serving\n", docsiteStaticPath) - docsiteHandler = http.FileServer(http.Dir(docsiteStaticPath)) + docsiteHandler = http.FileServer(HTMLDir{http.Dir(docsiteStaticPath)}) } else { log.Println("Did not find static site, serving not found handler") docsiteHandler = http.NotFoundHandler() @@ -27,3 +27,19 @@ func GetDocsiteHandler() http.Handler { } 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 +}