1import AsyncStorage from '@react-native-async-storage/async-storage'; 2import mapValues from 'lodash/mapValues'; 3 4import * as Kernel from '../kernel/Kernel'; 5import addListenerWithNativeCallback from '../utils/addListenerWithNativeCallback'; 6 7type Settings = Record<string, any>; 8 9const Keys = mapValues( 10 { 11 Session: 'session', 12 History: 'history', 13 Settings: 'settings', 14 }, 15 value => `Exponent.${value}` 16); 17 18async function getSettingsAsync(): Promise<Settings> { 19 const json = await AsyncStorage.getItem(Keys.Settings); 20 if (!json) { 21 return {}; 22 } 23 24 try { 25 return JSON.parse(json); 26 } catch (e) { 27 return {}; 28 } 29} 30 31async function updateSettingsAsync(updatedSettings: Partial<Settings>): Promise<void> { 32 const currentSettings = await getSettingsAsync(); 33 const newSettings = { 34 ...currentSettings, 35 ...updatedSettings, 36 }; 37 38 await AsyncStorage.setItem(Keys.Settings, JSON.stringify(newSettings)); 39} 40 41async function getSessionAsync() { 42 let results = await Kernel.getSessionAsync(); 43 if (!results) { 44 // NOTE(2018-11-8): we are migrating to storing all session keys 45 // using the Kernel module instead of AsyncStorage, but we need to 46 // continue to check the old location for a little while 47 // until all clients in use have migrated over 48 const json = await AsyncStorage.getItem(Keys.Session); 49 if (json) { 50 try { 51 results = JSON.parse(json); 52 await saveSessionAsync(results); 53 await AsyncStorage.removeItem(Keys.Session); 54 } catch (e) { 55 return null; 56 } 57 } 58 } 59 60 return results; 61} 62 63async function saveSessionAsync(session): Promise<void> { 64 await Kernel.setSessionAsync(session); 65} 66 67async function getHistoryAsync() { 68 const jsonHistory = await AsyncStorage.getItem(Keys.History); 69 if (jsonHistory) { 70 try { 71 return JSON.parse(jsonHistory); 72 } catch (e) { 73 console.error(e); 74 } 75 } 76 return []; 77} 78 79async function saveHistoryAsync(history): Promise<void> { 80 await AsyncStorage.setItem(Keys.History, JSON.stringify(history)); 81} 82 83async function clearHistoryAsync(): Promise<void> { 84 await AsyncStorage.removeItem(Keys.History); 85} 86 87async function removeSessionAsync(): Promise<void> { 88 await Kernel.removeSessionAsync(); 89} 90 91// adds a hook for native code to query Home's history. 92// needed for routing push notifications in Home. 93addListenerWithNativeCallback('ExponentKernel.getHistoryUrlForExperienceId', async event => { 94 const { experienceId } = event; 95 let history = await getHistoryAsync(); 96 history = history.sort((item1, item2) => { 97 // date descending -- we want to pick the most recent experience with this id, 98 // in case there are multiple (e.g. somebody was developing against various URLs of the 99 // same app) 100 const item2time = item2.time ? item2.time : 0; 101 const item1time = item1.time ? item1.time : 0; 102 return item2time - item1time; 103 }); 104 const historyItem = history.find(item => item.manifest && item.manifest.id === experienceId); 105 if (historyItem) { 106 return { url: historyItem.url }; 107 } 108 return {}; 109}); 110 111export default { 112 clearHistoryAsync, 113 getSessionAsync, 114 getHistoryAsync, 115 getSettingsAsync, 116 saveHistoryAsync, 117 saveSessionAsync, 118 removeSessionAsync, 119 updateSettingsAsync, 120}; 121