tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }