StartupCacheInit.sys.mjs (6104B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 5 import { 6 actionCreators as ac, 7 actionTypes as at, 8 } from "resource://newtab/common/Actions.mjs"; 9 10 const PREF_SPOCS_STARTUPCACHE_ENABLED = 11 "discoverystream.spocs.startupCache.enabled"; 12 const PREF_STARTUPCACHE_FEED = "feeds.startupcacheinit"; 13 14 /** 15 * StartupCacheInit - Startup cache hydrates from a previous state. 16 * However, weather, sponsored content, and custom wallpapers 17 * are not cached. 18 * Weather sponsored content, or custom wallpapers 19 * can update before we fully hydrate. 20 * So this feed watches these feeds and updates later after we hydrate. 21 * We render this feed inert after hydrating from cache or not. 22 */ 23 export class StartupCacheInit { 24 constructor() { 25 // Internal state for checking if we've intialized this feed. 26 this.loaded = false; 27 this.TopsitesUpdatedReply = false; 28 this.DiscoveryStreamSpocsUpdateReply = false; 29 this.WeatherUpdateReply = false; 30 this.CustomWallpaperUpdateReply = false; 31 } 32 33 stateRequestReply(target) { 34 // Reply with any updates if we have them. 35 if (this.TopsitesUpdatedReply) { 36 this.sendTopsitesUpdatedReply(target); 37 } 38 // Reply with any updates if we have them. 39 if (this.DiscoveryStreamSpocsUpdateReply) { 40 this.sendDiscoveryStreamSpocsUpdateReply(target); 41 } 42 // Reply with any updates if we have them. 43 if (this.WeatherUpdateReply) { 44 this.sendWeatherUpdateReply(target); 45 } 46 // Reply with any updates if we have them. 47 if (this.CustomWallpaperUpdateReply) { 48 this.sendCustomWallpaperUpdateReply(target); 49 } 50 } 51 52 // This grabs the current main reducer state for TopSites rows, 53 // and sends it to the startup cache content reducer. 54 sendTopsitesUpdatedReply(target) { 55 const links = this.store.getState().TopSites.rows; 56 const action = { 57 type: at.TOP_SITES_UPDATED, 58 data: { 59 links, 60 }, 61 }; 62 this.store.dispatch(ac.OnlyToOneContent(action, target)); 63 } 64 65 // This grabs the current main reducer state for DiscoveryStream spocs, 66 // and sends it to the startup cache content reducer. 67 sendDiscoveryStreamSpocsUpdateReply(target) { 68 const spocsState = this.store.getState().DiscoveryStream.spocs; 69 const action = { 70 type: at.DISCOVERY_STREAM_SPOCS_UPDATE, 71 data: { 72 lastUpdated: spocsState.lastUpdated, 73 spocs: spocsState.data, 74 spocsOnDemand: spocsState.onDemand.enabled, 75 spocsCacheUpdateTime: spocsState.cacheUpdateTime, 76 }, 77 }; 78 this.store.dispatch(ac.OnlyToOneContent(action, target)); 79 } 80 81 // This grabs the current main reducer state for TopSites rows, 82 // and sends it to the startup cache content reducer. 83 sendWeatherUpdateReply(target) { 84 const { Weather } = this.store.getState(); 85 const action = { 86 type: at.WEATHER_UPDATE, 87 data: { 88 suggestions: Weather.suggestions, 89 lastUpdated: Weather.lastUpdated, 90 locationData: Weather.locationData, 91 }, 92 }; 93 this.store.dispatch(ac.OnlyToOneContent(action, target)); 94 } 95 96 // This grabs the current main reducer state for Wallpapers uploaded wallpaper, 97 // and sends it to the startup cache content reducer. 98 sendCustomWallpaperUpdateReply(target) { 99 const { Wallpapers } = this.store.getState(); 100 const action = { 101 type: at.WALLPAPERS_CUSTOM_SET, 102 data: Wallpapers.uploadedWallpaper, 103 }; 104 this.store.dispatch(ac.OnlyToOneContent(action, target)); 105 } 106 107 uninitFeed() { 108 this.store.uninitFeed(PREF_STARTUPCACHE_FEED, { type: at.UNINIT }); 109 } 110 111 async onAction(action) { 112 switch (action.type) { 113 case at.INIT: 114 this.loaded = true; 115 break; 116 case at.UNINIT: 117 this.loaded = false; 118 this.TopsitesUpdatedReply = false; 119 this.DiscoveryStreamSpocsUpdateReply = false; 120 this.WeatherUpdateReply = false; 121 this.CustomWallpaperUpdateReply = false; 122 break; 123 // We either get NEW_TAB_STATE_REQUEST_STARTUPCACHE 124 // or NEW_TAB_STATE_REQUEST_WITHOUT_STARTUPCACHE 125 // but not both. 126 case at.NEW_TAB_STATE_REQUEST_STARTUPCACHE: 127 // Reply if we have not yet replied, and are receiving a request. 128 if (this.loaded) { 129 this.stateRequestReply(action.meta.fromTarget); 130 // If we replied, we can turn off this feed. 131 this.uninitFeed(); 132 } 133 break; 134 case at.NEW_TAB_STATE_REQUEST_WITHOUT_STARTUPCACHE: 135 if (this.loaded) { 136 // If we rendered without startup cache, we can turn off this feed. 137 this.uninitFeed(); 138 } 139 break; 140 case at.TOP_SITES_UPDATED: 141 // We are receiving a TopSites event and have not yet replied, store this and reply later. 142 if (this.loaded) { 143 this.TopsitesUpdatedReply = true; 144 } 145 break; 146 case at.DISCOVERY_STREAM_SPOCS_UPDATE: 147 if (this.loaded) { 148 // Turn this off if startupcache for spocs is on. 149 const spocsStartupCacheEnabled = 150 this.store.getState().Prefs.values[PREF_SPOCS_STARTUPCACHE_ENABLED]; 151 if (!spocsStartupCacheEnabled) { 152 // We are receiving a DiscoveryStream event and have not yet replied, 153 // store this and reply later. 154 this.DiscoveryStreamSpocsUpdateReply = true; 155 } 156 } 157 break; 158 case at.WEATHER_UPDATE: 159 if (this.loaded) { 160 // We are receiving a Weather event and have not yet replied, store this and reply later. 161 this.WeatherUpdateReply = true; 162 } 163 break; 164 case at.WALLPAPERS_CUSTOM_SET: 165 if (this.loaded) { 166 // We are receiving a Custom Wallpaper event and have not yet replied, store this and reply later. 167 this.CustomWallpaperUpdateReply = true; 168 } 169 break; 170 } 171 } 172 }