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  }