From c8fbebe351fec81a836de2faeda743beb15f4a74 Mon Sep 17 00:00:00 2001 From: Seth Trowbridge Date: Tue, 25 Apr 2023 20:41:22 -0400 Subject: [PATCH] fix meta ordering and rendering --- example/app.tsx | 7 ++- example/deep/component.tsx | 2 +- lib/iso.tsx | 120 ++++++++++++++++++++++++++++++------- server.tsx | 2 +- 4 files changed, 105 insertions(+), 26 deletions(-) diff --git a/example/app.tsx b/example/app.tsx index 5fd8d5a..996f759 100644 --- a/example/app.tsx +++ b/example/app.tsx @@ -22,7 +22,12 @@ export default ()=> - About us! + + <> + + About us! + + sorry no page diff --git a/example/deep/component.tsx b/example/deep/component.tsx index 6cc3a2c..39f4ed4 100644 --- a/example/deep/component.tsx +++ b/example/deep/component.tsx @@ -10,7 +10,7 @@ export default ()=> const [Data, Updating] = Iso.Fetch.Use(`https://catfact.ninja/fact`); - console.log("render!!") + console.log("component.tsx render!!") return
diff --git a/lib/iso.tsx b/lib/iso.tsx index f000e79..ade2f4e 100644 --- a/lib/iso.tsx +++ b/lib/iso.tsx @@ -1,11 +1,14 @@ import React from "react"; type MetasInputs = { [Property in MetaKeys]?: string }; +type MetasModeArgs = {concatListed?:boolean; dropUnlisted?:boolean}; +type MetasStackItem = MetasModeArgs&MetasInputs&{id:string, depth:number} type Meta = {title:string, description:string, keywords:string, image:string, canonical:string } type MetaKeys = keyof Meta; export const Meta = { + Stack:[] as Array, Meta: { title:"", description:"", @@ -13,27 +16,98 @@ export const Meta = image:"", canonical:"" } as Meta, - Context: React.createContext([{} as Meta, ()=>{}] as [Get:Meta, Set:React.StateUpdater]), + Context: React.createContext([[], ()=>{}] as [Get:MetasStackItem[], Set:React.StateUpdater]), Provider({children}:{children:Children}) { - const binding = React.useState(Meta.Meta); + const binding = React.useState([] as MetasStackItem[]); + + React.useEffect(()=>{ + const stack = binding[0]; + const last = stack[stack.length-1]; + console.log("updating page title", stack); + document.title = last?.title||""; + }) return {children}; }, - Metas(props:{concatListed?:boolean; dropUnlisted?:boolean}&MetasInputs):null + Metas({concatListed=false, dropUnlisted=false, ...props}:MetasModeArgs&MetasInputs):null { - const additive = props.concatListed ? (key:MetaKeys, value:string)=> Meta.Meta[key] += value : (key:MetaKeys, value:string)=> Meta.Meta[key] = value; - const subtractive = props.dropUnlisted ? (key:MetaKeys)=> Meta.Meta[key] = "" : (key:MetaKeys)=> {}; - - Object.keys(Meta).forEach((key)=>{ - const metaKey = key as MetaKeys; - const propValue = props[metaKey]||""; - propValue ? additive(metaKey, propValue) : subtractive(metaKey); - }) - if(window.innerWidth) - { - document.title = Meta.Meta.title; - } - + const id = React.useId(); + const [, metasSet] = React.useContext(Meta.Context); + const {depth} = React.useContext(SwitchContext); + + React.useEffect(()=>{ + metasSet((m)=>{ + console.log(`adding meta`, props, depth); + const clone = [...m]; + let i; + for(i=clone.length-1; i>-1; i--) + { + if(clone[i].depth <= depth) + { + + break; + } + } + clone.splice(i+1, 0, {id, depth, concatListed, dropUnlisted, ...props}); + return clone; + }); + return ()=> + { + metasSet((m)=>{ + const clone = [...m]; + const ind = clone.findIndex(i=>i.id === id); + if(ind > -1) + { + console.log(`removing meta`, props, depth); + clone.splice(ind, 1); + } + return clone; + }); + + }; + }, []); + + React.useEffect(()=>{ + metasSet((m)=>{ + const clone = [...m]; + const ind = clone.findIndex(i=>i.id === id); + if(ind > -1) + { + console.log(`updating meta`, props, depth); + clone[ind] = {...clone[ind], ...props}; + } + return clone; + }); + }, Object.keys(props).map( (key) => props[key as MetaKeys] )); + + /* + React.useEffect(()=>{ + + metasSet((m)=> + { + const metas = {...m}; + + const additive = concatListed ? (key:MetaKeys, value:string)=> metas[key] += value : (key:MetaKeys, value:string)=> metas[key] = value; + const subtractive = dropUnlisted ? (key:MetaKeys)=> metas[key] = "" : (key:MetaKeys)=> {}; + + Object.keys(metas).forEach((key)=>{ + const metaKey = key as MetaKeys; + const propValue = props[metaKey]||""; + propValue ? additive(metaKey, propValue) : subtractive(metaKey); + }); + + Meta.Meta = metas; + console.log(Meta.Meta); + + if(window.innerWidth) + { + document.title = metas.title; + } + + return metas; + }); + }, [props]); + */ return null; } }; @@ -163,7 +237,7 @@ export const Switch =({children}:{children:Children})=> } if(childCase?.props?.default && !fallback) { - console.log(routeSegment); + //console.log(routeSegment); fallback = childCaseChildren; } } @@ -202,7 +276,7 @@ export const Fetch = { inCheck.Promise = fetch(URL, Init?Init:undefined).then(resp=>resp.json()).then((json)=>{ inCheck.JSON = json; inCheck.CachedAt = new Date().getTime(); - console.log(`...cached!`); + //console.log(`...cached!`); return inCheck; }); return inCheck; @@ -213,7 +287,7 @@ export const Fetch = { // not in the cache // - listen - console.log(`making new cache record...`); + //console.log(`making new cache record...`); return [load({URL, CacheFor, CachedAt:0, CacheOnServer, DelaySSR, Seed}), false, true]; } else if(check.CachedAt == 0) @@ -222,26 +296,26 @@ export const Fetch = { // - listen // - possibly init if there is something in JSON - console.log(`currently being cached...`); + //console.log(`currently being cached...`); return [check, check.JSON ? true : false, true]; } else { - console.log(`found in cache...`); + //console.log(`found in cache...`); let secondsAge = (new Date().getTime() - check.CachedAt)/1000; if(secondsAge > check.CacheFor) { // cached but expired // - listen // - init - console.log(`...outdated...`); + //console.log(`...outdated...`); return [load(check), true, true]; } else { // cached and ready // - init - console.log(`...retrieved!`); + //console.log(`...retrieved!`); return [check, true, false]; } diff --git a/server.tsx b/server.tsx index e4992b3..af10b24 100644 --- a/server.tsx +++ b/server.tsx @@ -267,7 +267,7 @@ FileListen("${url.pathname}", reloadHandler);`; import {hydrate, createElement as H} from "react"; import * as Twind from "https://esm.sh/v115/@twind/core@1.1.3/es2022/core.mjs"; import {default as App, CSS} from "@eno/app"; - import {Router, Fetch} from "@eno/iso"; + import {Router, Fetch, Meta} from "@eno/iso"; Twind.install(CSS); Fetch.Seed(${JSON.stringify(seed)}); const hmrWrap = H( ()=>H(App) );