199 lines
6.9 KiB
JavaScript
199 lines
6.9 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
import {
|
|
actionCreators as ac,
|
|
actionTypes as at,
|
|
} from "resource://newtab/common/Actions.mjs";
|
|
|
|
const PREF_SPOCS_STARTUPCACHE_ENABLED =
|
|
"discoverystream.spocs.startupCache.enabled";
|
|
const PREF_STARTUPCACHE_FEED = "feeds.startupcacheinit";
|
|
|
|
/**
|
|
* StartupCacheInit - Startup cache hydrates from a previous state.
|
|
* However, weather, sponsored content, and custom wallpapers
|
|
* are not cached.
|
|
* Weather sponsored content, or custom wallpapers
|
|
* can update before we fully hydrate.
|
|
* So this feed watches these feeds and updates later after we hydrate.
|
|
* We render this feed inert after hydrating from cache or not.
|
|
*/
|
|
export class StartupCacheInit {
|
|
constructor() {
|
|
// Internal state for checking if we've intialized this feed.
|
|
this.loaded = false;
|
|
this.TopsitesUpdatedReply = false;
|
|
this.DiscoveryStreamSpocsUpdateReply = false;
|
|
this.WeatherUpdateReply = false;
|
|
this.CustomWallpaperUpdateReply = false;
|
|
this.PrefChangesReply = new Map();
|
|
}
|
|
|
|
stateRequestReply(target) {
|
|
// Reply with any updates if we have them.
|
|
if (this.TopsitesUpdatedReply) {
|
|
this.sendTopsitesUpdatedReply(target);
|
|
}
|
|
// Reply with any updates if we have them.
|
|
if (this.DiscoveryStreamSpocsUpdateReply) {
|
|
this.sendDiscoveryStreamSpocsUpdateReply(target);
|
|
}
|
|
// Reply with any updates if we have them.
|
|
if (this.WeatherUpdateReply) {
|
|
this.sendWeatherUpdateReply(target);
|
|
}
|
|
// Reply with any updates if we have them.
|
|
if (this.CustomWallpaperUpdateReply) {
|
|
this.sendCustomWallpaperUpdateReply(target);
|
|
}
|
|
// Reply with any pref changes if we have them.
|
|
if (this.PrefChangesReply.size > 0) {
|
|
this.sendPrefChangesReply(target);
|
|
}
|
|
}
|
|
|
|
// This grabs the current main reducer state for TopSites rows,
|
|
// and sends it to the startup cache content reducer.
|
|
sendTopsitesUpdatedReply(target) {
|
|
const links = this.store.getState().TopSites.rows;
|
|
const action = {
|
|
type: at.TOP_SITES_UPDATED,
|
|
data: {
|
|
links,
|
|
},
|
|
};
|
|
this.store.dispatch(ac.OnlyToOneContent(action, target));
|
|
}
|
|
|
|
// This grabs the current main reducer state for DiscoveryStream spocs,
|
|
// and sends it to the startup cache content reducer.
|
|
sendDiscoveryStreamSpocsUpdateReply(target) {
|
|
const spocsState = this.store.getState().DiscoveryStream.spocs;
|
|
const action = {
|
|
type: at.DISCOVERY_STREAM_SPOCS_UPDATE,
|
|
data: {
|
|
lastUpdated: spocsState.lastUpdated,
|
|
spocs: spocsState.data,
|
|
spocsOnDemand: spocsState.onDemand.enabled,
|
|
spocsCacheUpdateTime: spocsState.cacheUpdateTime,
|
|
},
|
|
};
|
|
this.store.dispatch(ac.OnlyToOneContent(action, target));
|
|
}
|
|
|
|
// This grabs the current main reducer state for TopSites rows,
|
|
// and sends it to the startup cache content reducer.
|
|
sendWeatherUpdateReply(target) {
|
|
const { Weather } = this.store.getState();
|
|
const action = {
|
|
type: at.WEATHER_UPDATE,
|
|
data: {
|
|
suggestions: Weather.suggestions,
|
|
lastUpdated: Weather.lastUpdated,
|
|
locationData: Weather.locationData,
|
|
},
|
|
};
|
|
this.store.dispatch(ac.OnlyToOneContent(action, target));
|
|
}
|
|
|
|
// This grabs the current main reducer state for Wallpapers uploaded wallpaper,
|
|
// and sends it to the startup cache content reducer.
|
|
sendCustomWallpaperUpdateReply(target) {
|
|
const { Wallpapers } = this.store.getState();
|
|
const action = {
|
|
type: at.WALLPAPERS_CUSTOM_SET,
|
|
data: Wallpapers.uploadedWallpaper,
|
|
};
|
|
this.store.dispatch(ac.OnlyToOneContent(action, target));
|
|
}
|
|
|
|
// Sends queued preference changes to the startup cache content process.
|
|
sendPrefChangesReply(target) {
|
|
for (const [name, value] of this.PrefChangesReply) {
|
|
const action = {
|
|
type: at.PREF_CHANGED,
|
|
data: { name, value },
|
|
};
|
|
this.store.dispatch(ac.OnlyToOneContent(action, target));
|
|
}
|
|
}
|
|
|
|
uninitFeed() {
|
|
this.store.uninitFeed(PREF_STARTUPCACHE_FEED, { type: at.UNINIT });
|
|
}
|
|
|
|
async onAction(action) {
|
|
switch (action.type) {
|
|
case at.INIT:
|
|
this.loaded = true;
|
|
break;
|
|
case at.UNINIT:
|
|
this.loaded = false;
|
|
this.TopsitesUpdatedReply = false;
|
|
this.DiscoveryStreamSpocsUpdateReply = false;
|
|
this.WeatherUpdateReply = false;
|
|
this.CustomWallpaperUpdateReply = false;
|
|
this.PrefChangesReply.clear();
|
|
break;
|
|
// We either get NEW_TAB_STATE_REQUEST_STARTUPCACHE
|
|
// or NEW_TAB_STATE_REQUEST_WITHOUT_STARTUPCACHE
|
|
// but not both.
|
|
case at.NEW_TAB_STATE_REQUEST_STARTUPCACHE:
|
|
// Reply if we have not yet replied, and are receiving a request.
|
|
if (this.loaded) {
|
|
this.stateRequestReply(action.meta.fromTarget);
|
|
// If we replied, we can turn off this feed.
|
|
this.uninitFeed();
|
|
}
|
|
break;
|
|
case at.NEW_TAB_STATE_REQUEST_WITHOUT_STARTUPCACHE:
|
|
if (this.loaded) {
|
|
// If we rendered without startup cache, we can turn off this feed.
|
|
this.uninitFeed();
|
|
}
|
|
break;
|
|
case at.TOP_SITES_UPDATED:
|
|
// We are receiving a TopSites event and have not yet replied, store this and reply later.
|
|
if (this.loaded) {
|
|
this.TopsitesUpdatedReply = true;
|
|
}
|
|
break;
|
|
case at.DISCOVERY_STREAM_SPOCS_UPDATE:
|
|
if (this.loaded) {
|
|
// Turn this off if startupcache for spocs is on.
|
|
const spocsStartupCacheEnabled =
|
|
this.store.getState().Prefs.values[PREF_SPOCS_STARTUPCACHE_ENABLED];
|
|
if (!spocsStartupCacheEnabled) {
|
|
// We are receiving a DiscoveryStream event and have not yet replied,
|
|
// store this and reply later.
|
|
this.DiscoveryStreamSpocsUpdateReply = true;
|
|
}
|
|
}
|
|
break;
|
|
case at.WEATHER_UPDATE:
|
|
if (this.loaded) {
|
|
// We are receiving a Weather event and have not yet replied, store this and reply later.
|
|
this.WeatherUpdateReply = true;
|
|
}
|
|
break;
|
|
case at.WALLPAPERS_CUSTOM_SET:
|
|
if (this.loaded) {
|
|
// We are receiving a Custom Wallpaper event and have not yet replied, store this and reply later.
|
|
this.CustomWallpaperUpdateReply = true;
|
|
}
|
|
break;
|
|
case at.PREF_CHANGED:
|
|
if (this.loaded && action.data) {
|
|
// Queue preference changes that may need to be sent to the startup cache.
|
|
// This is particularly important for activation window state changes that
|
|
// can occur after the cache has loaded but before it requests state.
|
|
const { name, value } = action.data;
|
|
this.PrefChangesReply.set(name, value);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|