diff --git a/web/ui/src/YBFeed/Components/YBBreadCrumbComponent.tsx b/web/ui/src/YBFeed/Components/YBBreadCrumbComponent.tsx index 75776ad..60c8db3 100644 --- a/web/ui/src/YBFeed/Components/YBBreadCrumbComponent.tsx +++ b/web/ui/src/YBFeed/Components/YBBreadCrumbComponent.tsx @@ -1,4 +1,5 @@ import { Breadcrumbs, Anchor } from '@mantine/core'; +import { Link } from 'react-router-dom'; export function YBBreadCrumbComponent() { const p = window.location.pathname.split("/") @@ -18,7 +19,7 @@ export function YBBreadCrumbComponent() { const items = crumbItems.map((item,index) => (item.href === "")?item.title: - + {item.title} ) diff --git a/web/ui/src/YBFeed/Components/YBFeedItemsComponent.tsx b/web/ui/src/YBFeed/Components/YBFeedItemsComponent.tsx index 27fe4ae..65b94bb 100644 --- a/web/ui/src/YBFeed/Components/YBFeedItemsComponent.tsx +++ b/web/ui/src/YBFeed/Components/YBFeedItemsComponent.tsx @@ -26,40 +26,66 @@ export function YBFeedItemsComponent(props: YBFeedItemsComponentProps) { } useEffect(() => { - ws.current = new WebSocket(window.location.protocol.replace("http","ws") + "//" + window.location.host + "/ws/" + feedName + "?secret=" + secret) - if (ws.current === null) { - return - } - ws.current.onopen = () => { - ws.current?.send("feed") - } + const webSocketURL = window.location.protocol.replace("http","ws") + "//" + window.location.host + "/ws/" + feedName + "?secret=" + secret - ws.current.onmessage = (m:WebSocketEventMap["message"]) => { - const message_data = JSON.parse(m.data) - if (message_data) { - if (Object.prototype.hasOwnProperty.call(message_data, "items")) { - const f = (message_data as YBFeed) - setFeedItems(f.items) - - } - if (Object.prototype.hasOwnProperty.call(message_data, "action")) { - interface ActionMessage { - action: string, - item: YBFeedItem + function connect() { + ws.current = new WebSocket(webSocketURL) + if (ws.current === null) { + return + } + ws.current.onopen = () => { + console.log("websocket connected") + ws.current?.send("feed") + } + + ws.current.onmessage = (m:WebSocketEventMap["message"]) => { + const message_data = JSON.parse(m.data) + if (message_data) { + if (Object.prototype.hasOwnProperty.call(message_data, "items")) { + const f = (message_data as YBFeed) + setFeedItems(f.items) + } - const am = (message_data as ActionMessage) - if (am.action === "remove") { - setFeedItems((items) => items.filter((i) => i.name !== am.item.name)) - } else if (am.action === "add") { - setFeedItems((items) => [am.item].concat(items)) - } else if (am.action === "empty") { - setFeedItems([]) + if (Object.prototype.hasOwnProperty.call(message_data, "action")) { + interface ActionMessage { + action: string, + item: YBFeedItem + } + const am = (message_data as ActionMessage) + if (am.action === "remove") { + setFeedItems((items) => items.filter((i) => i.name !== am.item.name)) + } else if (am.action === "add") { + setFeedItems((items) => [am.item].concat(items)) + } else if (am.action === "empty") { + setFeedItems([]) + } } } } + + ws.current.onclose = () => { + console.log("websocket closed") + + // Try to reconnect + ws.current = null + setTimeout(() => { + console.log("reconnecting") + connect() + },1000) + } } + + connect() + return () => { - ws.current?.close() + const w=ws.current + if (!w) { + console.log("no websocket to close") + return + } + console.log("closing websocket") + w.onclose = null + w.close() } },[]) diff --git a/web/ui/src/YBFeed/YBFeedFeed.tsx b/web/ui/src/YBFeed/YBFeedFeed.tsx index 949f6a5..a5a4ed0 100644 --- a/web/ui/src/YBFeed/YBFeedFeed.tsx +++ b/web/ui/src/YBFeed/YBFeedFeed.tsx @@ -22,10 +22,8 @@ export function YBFeedFeed() { const navigate = useNavigate() const location = useLocation() const [searchParams] = useSearchParams() - // const navigate = useNavigate() const [secret,setSecret] = useState("") - // const [goTo,setGoTo] = useState(undefined) const [pinModalOpen,setPinModalOpen] = useState(false) const [authenticated,setAuthenticated] = useState(undefined) const [vapid, setVapid] = useState(undefined) @@ -38,8 +36,10 @@ export function YBFeedFeed() { return } - // If secret is sent as part of the URL params, set secret state and - // redirect to the URL omitting the secret + // If secret is sent as part of the URL params, authenticate the feed and + // redirect to the URL without secret + // Authenticating the feed will set the authorization cookie in browser + // so subsequent calls will be authenticated useEffect(() => { const s=searchParams.get("secret") if (s) { @@ -76,19 +76,6 @@ export function YBFeedFeed() { } },[secret,feedName,location]) - // useEffect(() => { - // if (readyState === ReadyState.OPEN) { - // setFatal(false) - // sendMessage("feed") - // } - // else if (readyState === ReadyState.CLOSED){ - // setFatal(true) - // } - // },[readyState,sendMessage]) - - // - // Creating links to feed - // const copyLink = () => { const link = window.location.href + "?secret=" + secret navigator.clipboard.writeText(link)