11import { useNonInitialEffect } from '@jetstream/shared/ui-utils' ;
2- import { FunctionComponent , useState } from 'react' ;
2+ import { GoogleUserInfo , Maybe } from '@jetstream/types' ;
3+ import { FunctionComponent , useCallback , useState } from 'react' ;
4+ import z from 'zod' ;
35import GoogleFolderSelector from '../../form/file-selector/GoogleFolderSelector' ;
46import RadioButton from '../../form/radio/RadioButton' ;
57import RadioGroup from '../../form/radio/RadioGroup' ;
68import GoogleSignIn from '../../google/GoogleSignIn' ;
79import GridCol from '../../grid/GridCol' ;
810
11+ const WhichFolderSchema = z . enum ( [ 'root' , 'specified' ] ) ;
12+ type WhichFolder = z . infer < typeof WhichFolderSchema > ;
13+
14+ const FolderSelectionSchema = z . object ( { name : z . string ( ) , folderId : z . string ( ) } ) ;
15+ type FolderSelection = z . infer < typeof FolderSelectionSchema > ;
16+
17+ const LS_FOLDER_SELECTION_KEY = 'RECENT_GOOGLE_FOLDER_SELECTION' ;
18+ const LS_FOLDER_INFO_KEY = 'RECENT_GOOGLE_FOLDER' ;
19+
20+ function getWhichFolderFromStorage ( userInfo : Maybe < GoogleUserInfo > ) : WhichFolder {
21+ if ( ! userInfo ) {
22+ return WhichFolderSchema . enum . root ;
23+ }
24+ const key = `${ LS_FOLDER_SELECTION_KEY } :${ userInfo . id } ` ;
25+ const value = localStorage . getItem ( key ) ;
26+ if ( value ) {
27+ try {
28+ return WhichFolderSchema . parse ( value ) ;
29+ } catch {
30+ return WhichFolderSchema . enum . root ;
31+ }
32+ }
33+ return WhichFolderSchema . enum . root ;
34+ }
35+
36+ function getFolderSelectionFromStorage ( userInfo : Maybe < GoogleUserInfo > ) : Maybe < FolderSelection > {
37+ if ( ! userInfo ) {
38+ return null ;
39+ }
40+ const key = `${ LS_FOLDER_INFO_KEY } :${ userInfo . id } ` ;
41+ const value = localStorage . getItem ( key ) ;
42+ if ( value ) {
43+ try {
44+ return FolderSelectionSchema . parse ( JSON . parse ( value ) ) ;
45+ } catch {
46+ return null ;
47+ }
48+ }
49+ return null ;
50+ }
51+
52+ function saveWhichFolderToStorage ( userInfo : GoogleUserInfo , whichFolder : WhichFolder ) {
53+ if ( ! userInfo ) {
54+ return ;
55+ }
56+ const key = `${ LS_FOLDER_SELECTION_KEY } :${ userInfo . id } ` ;
57+ localStorage . setItem ( key , whichFolder ) ;
58+ }
59+
60+ function saveFolderSelectionToStorage ( userInfo : GoogleUserInfo , folder : Maybe < FolderSelection > ) {
61+ if ( ! userInfo ) {
62+ return ;
63+ }
64+ const key = `${ LS_FOLDER_INFO_KEY } :${ userInfo . id } ` ;
65+ if ( ! folder ) {
66+ localStorage . removeItem ( key ) ;
67+ } else {
68+ localStorage . setItem ( key , JSON . stringify ( folder ) ) ;
69+ }
70+ }
71+
972export interface FileDownloadGoogleProps {
1073 google_apiKey : string ;
1174 google_appId : string ;
@@ -25,37 +88,65 @@ export const FileDownloadGoogle: FunctionComponent<FileDownloadGoogleProps> = ({
2588 onFolderSelected,
2689 onSelectorVisible,
2790} ) => {
28- const [ googleFolder , setGoogleFolder ] = useState < { name : string ; folderId : string } > ( ) ;
91+ const [ userInfo , setUserInfo ] = useState < Maybe < GoogleUserInfo > > ( null ) ;
92+ const [ googleFolder , setGoogleFolder ] = useState < Maybe < FolderSelection > > ( null ) ;
2993 const [ whichFolder , setWhichFolder ] = useState < 'root' | 'specified' > ( 'root' ) ;
3094 const [ apiConfig ] = useState ( { apiKey : google_apiKey , appId : google_appId , clientId : google_clientId } ) ;
3195
3296 useNonInitialEffect ( ( ) => {
3397 onFolderSelected ( whichFolder === 'root' ? undefined : googleFolder ?. folderId ) ;
98+ // eslint-disable-next-line react-hooks/exhaustive-deps
3499 } , [ whichFolder , googleFolder ] ) ;
35100
101+ const handleUserInfoChange = useCallback ( ( user : Maybe < GoogleUserInfo > ) => {
102+ setUserInfo ( user ) ;
103+ if ( user ) {
104+ setWhichFolder ( getWhichFolderFromStorage ( user ) ) ;
105+ setGoogleFolder ( getFolderSelectionFromStorage ( user ) ) ;
106+ }
107+ } , [ ] ) ;
108+
36109 function handleGoogleFolderSelected ( data : google . picker . DocumentObject ) {
37- setGoogleFolder ( { name : data . name , folderId : data . id } ) ;
110+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
111+ const folderData = { name : data . name ! , folderId : data . id ! } ;
112+ setGoogleFolder ( folderData ) ;
113+ if ( userInfo ) {
114+ saveFolderSelectionToStorage ( userInfo , folderData ) ;
115+ }
38116 }
39117
40118 return (
41119 < div className = "slds-p-horizontal_medium slds-p-bottom_medium" >
42- < GoogleSignIn apiConfig = { apiConfig } onSignInChanged = { onSignInChanged } >
120+ < GoogleSignIn apiConfig = { apiConfig } onSignInChanged = { onSignInChanged } onUserInfoChange = { handleUserInfoChange } >
43121 < GridCol size = { 12 } >
44122 < RadioGroup label = "Which Google Drive folder would you like to save to?" isButtonGroup >
45123 < RadioButton
46124 name = "which-google-folder"
47125 label = "Do not store in a folder"
48126 value = "root"
49127 checked = { whichFolder === 'root' }
50- onChange = { ( value ) => setWhichFolder ( 'root' ) }
128+ onChange = { ( value ) => {
129+ setWhichFolder ( 'root' ) ;
130+ if ( userInfo ) {
131+ saveWhichFolderToStorage ( userInfo , 'root' ) ;
132+ }
133+ } }
51134 disabled = { disabled }
52135 />
53136 < RadioButton
54137 name = "which-google-folder"
55138 label = "Choose a folder"
56139 value = "specified"
57140 checked = { whichFolder === 'specified' }
58- onChange = { ( value ) => setWhichFolder ( 'specified' ) }
141+ onChange = { ( value ) => {
142+ setWhichFolder ( 'specified' ) ;
143+ if ( userInfo ) {
144+ saveWhichFolderToStorage ( userInfo , 'specified' ) ;
145+ if ( googleFolder ) {
146+ saveFolderSelectionToStorage ( userInfo , googleFolder ) ;
147+ }
148+ }
149+ } }
59150 disabled = { disabled }
60151 />
61152 </ RadioGroup >
0 commit comments