github.com/tilt-dev/tilt@v0.36.0/web/src/StarredResourcesContext.tsx (about) 1 import React, { 2 PropsWithChildren, 3 useContext, 4 useEffect, 5 useState, 6 } from "react" 7 import { usePersistentState } from "./BrowserStorage" 8 9 export type StarredResourcesContext = { 10 starredResources: string[] 11 starResource: (name: string) => void 12 unstarResource: (name: string) => void 13 toggleStarResource: (name: string) => void 14 } 15 16 const starredResourceContext = React.createContext<StarredResourcesContext>({ 17 starredResources: [], 18 starResource: (s) => {}, 19 unstarResource: (s) => {}, 20 toggleStarResource: (s) => {}, 21 }) 22 23 export function useStarredResources(): StarredResourcesContext { 24 return useContext(starredResourceContext) 25 } 26 27 export function StarredResourceMemoryProvider( 28 props: PropsWithChildren<{ initialValueForTesting?: string[] }> 29 ) { 30 const [starredResources, setStarredResources] = useState<Array<string>>( 31 props.initialValueForTesting || [] 32 ) 33 34 function starResource(name: string) { 35 setStarredResources((prevState) => { 36 return prevState.includes(name) ? prevState : [...prevState, name] 37 }) 38 } 39 40 function unstarResource(name: string) { 41 setStarredResources((prevState) => { 42 return prevState.filter((s) => s !== name) 43 }) 44 } 45 46 function toggleStarResource(name: string) { 47 if (starredResources.includes(name)) { 48 unstarResource(name) 49 } else { 50 starResource(name) 51 } 52 } 53 54 return ( 55 <starredResourceContext.Provider 56 value={{ 57 starredResources: starredResources, 58 starResource: starResource, 59 unstarResource: unstarResource, 60 toggleStarResource: toggleStarResource, 61 }} 62 > 63 {props.children} 64 </starredResourceContext.Provider> 65 ) 66 } 67 68 export function StarredResourcesContextProvider( 69 props: PropsWithChildren<{ initialValueForTesting?: string[] }> 70 ) { 71 // we renamed pins to stars but kept the local storage name "pinned-resources" 72 // so that user's pinned resources show up as starred 73 let [starredResources, setStarredResources] = usePersistentState<string[]>( 74 "pinned-resources", 75 props.initialValueForTesting ?? [] 76 ) 77 78 useEffect(() => {}, []) 79 80 function starResource(name: string) { 81 setStarredResources((prevState) => { 82 const ret = prevState.includes(name) ? prevState : [...prevState, name] 83 return ret 84 }) 85 } 86 87 function unstarResource(name: string) { 88 setStarredResources((prevState) => { 89 const ret = prevState.filter((n) => n !== name) 90 return ret 91 }) 92 } 93 94 function toggleStarResource(name: string) { 95 if (starredResources.includes(name)) { 96 unstarResource(name) 97 } else { 98 starResource(name) 99 } 100 } 101 102 return ( 103 <starredResourceContext.Provider 104 value={{ 105 starredResources: starredResources, 106 starResource: starResource, 107 unstarResource: unstarResource, 108 toggleStarResource: toggleStarResource, 109 }} 110 > 111 {props.children} 112 </starredResourceContext.Provider> 113 ) 114 }