misc #22
| @ -22,7 +22,12 @@ export default ()=> | |||||||
|         <Iso.Switch> |         <Iso.Switch> | ||||||
|             <Iso.Case value="page"> |             <Iso.Case value="page"> | ||||||
|                 <Iso.Switch> |                 <Iso.Switch> | ||||||
|                     <Iso.Case value="about-us">About us!</Iso.Case> |                     <Iso.Case value="about-us"> | ||||||
|  |                         <> | ||||||
|  |                             <Iso.Meta.Metas title="About US"/> | ||||||
|  |                             About us! | ||||||
|  |                         </> | ||||||
|  |                     </Iso.Case> | ||||||
|                     <Iso.Case default>sorry no page</Iso.Case> |                     <Iso.Case default>sorry no page</Iso.Case> | ||||||
|                 </Iso.Switch> |                 </Iso.Switch> | ||||||
|             </Iso.Case> |             </Iso.Case> | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ export default ()=> | |||||||
|     const [Data, Updating] = Iso.Fetch.Use(`https://catfact.ninja/fact`); |     const [Data, Updating] = Iso.Fetch.Use(`https://catfact.ninja/fact`); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     console.log("render!!") |     console.log("component.tsx render!!") | ||||||
| 
 | 
 | ||||||
|     return <div class="p-4 text-red-500"> |     return <div class="p-4 text-red-500"> | ||||||
|         <Iso.Meta.Metas title="Component!"/> |         <Iso.Meta.Metas title="Component!"/> | ||||||
|  | |||||||
							
								
								
									
										116
									
								
								lib/iso.tsx
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								lib/iso.tsx
									
									
									
									
									
								
							| @ -1,11 +1,14 @@ | |||||||
| import React from "react"; | import React from "react"; | ||||||
| 
 | 
 | ||||||
| type MetasInputs = { [Property in MetaKeys]?: string }; | 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 Meta = {title:string, description:string, keywords:string, image:string, canonical:string } | ||||||
| type MetaKeys = keyof Meta; | type MetaKeys = keyof Meta; | ||||||
| 
 | 
 | ||||||
| export const Meta = | export const Meta = | ||||||
| { | { | ||||||
|  |     Stack:[] as Array<MetasStackItem>, | ||||||
|     Meta: { |     Meta: { | ||||||
|         title:"", |         title:"", | ||||||
|         description:"", |         description:"", | ||||||
| @ -13,27 +16,98 @@ export const Meta = | |||||||
|         image:"", |         image:"", | ||||||
|         canonical:"" |         canonical:"" | ||||||
|     } as Meta, |     } as Meta, | ||||||
|     Context: React.createContext([{} as Meta, ()=>{}] as [Get:Meta, Set:React.StateUpdater<Meta>]), |     Context: React.createContext([[], ()=>{}] as [Get:MetasStackItem[], Set:React.StateUpdater<MetasStackItem[]>]), | ||||||
|     Provider({children}:{children:Children}) |     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 <Meta.Context.Provider value={binding}>{children}</Meta.Context.Provider>; |         return <Meta.Context.Provider value={binding}>{children}</Meta.Context.Provider>; | ||||||
|     }, |     }, | ||||||
|     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 id = React.useId(); | ||||||
|         const subtractive = props.dropUnlisted ? (key:MetaKeys)=> Meta.Meta[key] = "" : (key:MetaKeys)=> {}; |         const [, metasSet] = React.useContext(Meta.Context); | ||||||
|  |         const {depth} = React.useContext(SwitchContext); | ||||||
| 
 | 
 | ||||||
|         Object.keys(Meta).forEach((key)=>{ |         React.useEffect(()=>{ | ||||||
|             const metaKey = key as MetaKeys; |             metasSet((m)=>{ | ||||||
|             const propValue = props[metaKey]||""; |                 console.log(`adding meta`, props, depth); | ||||||
|             propValue ? additive(metaKey, propValue) : subtractive(metaKey); |                 const clone = [...m]; | ||||||
|         }) |                 let i; | ||||||
|         if(window.innerWidth) |                 for(i=clone.length-1; i>-1; i--) | ||||||
|         { |                 { | ||||||
|             document.title = Meta.Meta.title; |                     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; |         return null; | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| @ -163,7 +237,7 @@ export const Switch =({children}:{children:Children})=> | |||||||
|             } |             } | ||||||
|             if(childCase?.props?.default && !fallback) |             if(childCase?.props?.default && !fallback) | ||||||
|             { |             { | ||||||
|                 console.log(routeSegment); |                 //console.log(routeSegment);
 | ||||||
|                 fallback = childCaseChildren; |                 fallback = childCaseChildren; | ||||||
|             } |             } | ||||||
|         }  |         }  | ||||||
| @ -202,7 +276,7 @@ export const Fetch = { | |||||||
|             inCheck.Promise = fetch(URL, Init?Init:undefined).then(resp=>resp.json()).then((json)=>{ |             inCheck.Promise = fetch(URL, Init?Init:undefined).then(resp=>resp.json()).then((json)=>{ | ||||||
|                 inCheck.JSON = json; |                 inCheck.JSON = json; | ||||||
|                 inCheck.CachedAt = new Date().getTime(); |                 inCheck.CachedAt = new Date().getTime(); | ||||||
|                 console.log(`...cached!`); |                 //console.log(`...cached!`);
 | ||||||
|                 return inCheck; |                 return inCheck; | ||||||
|             }); |             }); | ||||||
|             return inCheck; |             return inCheck; | ||||||
| @ -213,7 +287,7 @@ export const Fetch = { | |||||||
|             // not in the cache
 |             // not in the cache
 | ||||||
|             // - listen
 |             // - listen
 | ||||||
| 
 | 
 | ||||||
|             console.log(`making new cache record...`); |             //console.log(`making new cache record...`);
 | ||||||
|             return [load({URL, CacheFor, CachedAt:0, CacheOnServer, DelaySSR, Seed}), false, true]; |             return [load({URL, CacheFor, CachedAt:0, CacheOnServer, DelaySSR, Seed}), false, true]; | ||||||
|         } |         } | ||||||
|         else if(check.CachedAt == 0) |         else if(check.CachedAt == 0) | ||||||
| @ -222,26 +296,26 @@ export const Fetch = { | |||||||
|             // - listen
 |             // - listen
 | ||||||
|             // - possibly init if there is something in JSON
 |             // - 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]; |             return [check, check.JSON ? true : false, true]; | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             console.log(`found in cache...`); |             //console.log(`found in cache...`);
 | ||||||
|             let secondsAge = (new Date().getTime() - check.CachedAt)/1000; |             let secondsAge = (new Date().getTime() - check.CachedAt)/1000; | ||||||
|             if(secondsAge > check.CacheFor) |             if(secondsAge > check.CacheFor) | ||||||
|             { |             { | ||||||
|                 // cached but expired
 |                 // cached but expired
 | ||||||
|                 // - listen
 |                 // - listen
 | ||||||
|                 // - init
 |                 // - init
 | ||||||
|                 console.log(`...outdated...`); |                 //console.log(`...outdated...`);
 | ||||||
|                 return [load(check), true, true]; |                 return [load(check), true, true]; | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 // cached and ready
 |                 // cached and ready
 | ||||||
|                 // - init
 |                 // - init
 | ||||||
|                 console.log(`...retrieved!`); |                 //console.log(`...retrieved!`);
 | ||||||
|                 return [check, true, false]; |                 return [check, true, false]; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -267,7 +267,7 @@ FileListen("${url.pathname}", reloadHandler);`; | |||||||
|             import {hydrate, createElement as H} from "react"; |             import {hydrate, createElement as H} from "react"; | ||||||
|             import * as Twind from "https://esm.sh/v115/@twind/core@1.1.3/es2022/core.mjs"; |             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 {default as App, CSS} from "@eno/app"; | ||||||
|             import {Router, Fetch} from "@eno/iso"; |             import {Router, Fetch, Meta} from "@eno/iso"; | ||||||
|             Twind.install(CSS); |             Twind.install(CSS); | ||||||
|             Fetch.Seed(${JSON.stringify(seed)}); |             Fetch.Seed(${JSON.stringify(seed)}); | ||||||
|             const hmrWrap = H( ()=>H(App) ); |             const hmrWrap = H( ()=>H(App) ); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user