From da101b5cdcf8f806373382d82a85368c5c080977 Mon Sep 17 00:00:00 2001 From: Simon Hong Date: Wed, 24 Nov 2021 14:35:26 +0900 Subject: [PATCH] Migrate crypto widgets visibility in NTP fix https://github.com/brave/brave-browser/issues/19708 Migration is done once in the first NTP loading. For new users, all crypto widgets are hidden by default. For existing users, if current foremost widget is crypto widget, only it is visible and others are hidden. After migration, user can control crypto widget's visibility from gallery. To make all crypto widgets hidden by default, each pref's default value is not changed. Their default prefs is still "true". As their visibility are managed by prefs and widget order is managed in local storage, it's difficult to start migration from c++. If default is changed to false, it's very difficult to determine whether foremost widget is crypto or not in the NTP webui. --- browser/brave_profile_prefs.cc | 1 + .../brave_new_tab_message_handler.cc | 6 ++ common/pref_names.cc | 2 + common/pref_names.h | 1 + .../brave_new_tab_ui/api/preferences.ts | 4 + .../reducers/new_tab_reducer.ts | 1 + .../storage/new_tab_storage.ts | 96 +++++++++++++++++++ components/definitions/newTab.d.ts | 1 + 8 files changed, 112 insertions(+) diff --git a/browser/brave_profile_prefs.cc b/browser/brave_profile_prefs.cc index 223433ae2c05..7cbbe6b7e215 100644 --- a/browser/brave_profile_prefs.cc +++ b/browser/brave_profile_prefs.cc @@ -317,6 +317,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { registry->RegisterBooleanPref(kNewTabPageShowBraveTalk, false); registry->RegisterBooleanPref(kNewTabPageShowGemini, true); registry->RegisterBooleanPref(kNewTabPageHideAllWidgets, false); + registry->RegisterBooleanPref(kNewTabPageWidgetVisibilityMigrated, false); registry->RegisterIntegerPref( kNewTabPageShowsOptions, diff --git a/browser/ui/webui/new_tab_page/brave_new_tab_message_handler.cc b/browser/ui/webui/new_tab_page/brave_new_tab_message_handler.cc index e4da38787c7d..eb7d17c945a7 100644 --- a/browser/ui/webui/new_tab_page/brave_new_tab_message_handler.cc +++ b/browser/ui/webui/new_tab_page/brave_new_tab_message_handler.cc @@ -110,6 +110,8 @@ base::DictionaryValue GetPreferencesDictionary(PrefService* prefs) { pref_data.SetBoolean("showBraveTalk", prefs->GetBoolean(kNewTabPageShowBraveTalk)); pref_data.SetBoolean("showGemini", prefs->GetBoolean(kNewTabPageShowGemini)); + pref_data.SetBoolean("widgetVisibilityMigrated", + prefs->GetBoolean(kNewTabPageWidgetVisibilityMigrated)); #if BUILDFLAG(CRYPTO_DOT_COM_ENABLED) pref_data.SetBoolean( "showCryptoDotCom", @@ -501,6 +503,10 @@ void BraveNewTabMessageHandler::HandleSaveNewTabPagePref( settingsKey = kNewTabPageShowBraveTalk; } else if (settingsKeyInput == "showGemini") { settingsKey = kNewTabPageShowGemini; + } else if (settingsKeyInput == "saveWidgetVisibilityMigrated") { + // This prefs is set to true once. + DCHECK(settingsValueBool); + settingsKey = kNewTabPageWidgetVisibilityMigrated; #if BUILDFLAG(CRYPTO_DOT_COM_ENABLED) } else if (settingsKeyInput == "showCryptoDotCom") { settingsKey = kCryptoDotComNewTabPageShowCryptoDotCom; diff --git a/common/pref_names.cc b/common/pref_names.cc index afee071de500..6bbc55f938f4 100644 --- a/common/pref_names.cc +++ b/common/pref_names.cc @@ -64,6 +64,8 @@ const char kNewTabPageShowGemini[] = "brave.new_tab_page.show_gemini"; const char kNewTabPageShowBraveTalk[] = "brave.new_tab_page.show_together"; const char kNewTabPageHideAllWidgets[] = "brave.new_tab_page.hide_all_widgets"; const char kNewTabPageShowsOptions[] = "brave.new_tab_page.shows_options"; +const char kNewTabPageWidgetVisibilityMigrated[] = + "brave.new_tab_page.widget_visibility_migrated"; const char kBraveTodayIntroDismissed[] = "brave.today.intro_dismissed"; const char kBinanceAccessToken[] = "brave.binance.access_token"; const char kBinanceRefreshToken[] = "brave.binance.refresh_token"; diff --git a/common/pref_names.h b/common/pref_names.h index 4667b3d8bd87..6904492427a7 100644 --- a/common/pref_names.h +++ b/common/pref_names.h @@ -56,6 +56,7 @@ extern const char kNewTabPageShowGemini[]; extern const char kNewTabPageShowBraveTalk[]; extern const char kNewTabPageHideAllWidgets[]; extern const char kNewTabPageShowsOptions[]; +extern const char kNewTabPageWidgetVisibilityMigrated[]; extern const char kBraveTodayIntroDismissed[]; extern const char kAlwaysShowBookmarkBarOnNTP[]; extern const char kAutocompleteEnabled[]; diff --git a/components/brave_new_tab_ui/api/preferences.ts b/components/brave_new_tab_ui/api/preferences.ts index 94183ffad6bf..2fdadec29d06 100644 --- a/components/brave_new_tab_ui/api/preferences.ts +++ b/components/brave_new_tab_ui/api/preferences.ts @@ -22,6 +22,10 @@ function sendSavePref (key: string, value: any) { chrome.send('saveNewTabPagePref', [key, value]) } +export function saveWidgetVisibilityMigrated (): void { + sendSavePref('saveWidgetVisibilityMigrated', true) +} + export function saveShowBackgroundImage (value: boolean): void { sendSavePref('showBackgroundImage', value) } diff --git a/components/brave_new_tab_ui/reducers/new_tab_reducer.ts b/components/brave_new_tab_ui/reducers/new_tab_reducer.ts index 976173559e79..edebce79b454 100644 --- a/components/brave_new_tab_ui/reducers/new_tab_reducer.ts +++ b/components/brave_new_tab_ui/reducers/new_tab_reducer.ts @@ -92,6 +92,7 @@ export const newTabReducer: Reducer = (state: NewTab.S } state = storage.addNewStackWidget(state) state = storage.replaceStackWidgets(state) + state = storage.updateWidgetVisibility(state) break diff --git a/components/brave_new_tab_ui/storage/new_tab_storage.ts b/components/brave_new_tab_ui/storage/new_tab_storage.ts index cef58bdd9623..98ff87be10ff 100644 --- a/components/brave_new_tab_ui/storage/new_tab_storage.ts +++ b/components/brave_new_tab_ui/storage/new_tab_storage.ts @@ -4,6 +4,7 @@ // you can obtain one at http://mozilla.org/MPL/2.0/. // Utils +import { saveShowBinance, saveShowCryptoDotCom, saveShowFTX, saveShowGemini, saveWidgetVisibilityMigrated } from '../api/preferences' import { debounce } from '../../common/debounce' import { loadTimeData } from '../../common/loadTimeData' @@ -28,6 +29,7 @@ export const defaultState: NewTab.State = { showBitcoinDotCom: false, showCryptoDotCom: false, showFTX: false, + widgetVisibilityMigrated: false, hideAllWidgets: false, brandedWallpaperOptIn: false, isBrandedWallpaperNotificationDismissed: true, @@ -240,6 +242,100 @@ export const replaceStackWidgets = (state: NewTab.State) => { return state } +export const updateWidgetVisibility = (state: NewTab.State) => { + // Do visibility migration only once. + if (state.widgetVisibilityMigrated) { + return state + } + + const { + showRewards, + showBraveTalk, + braveTalkSupported, + showBinance, + binanceSupported, + showCryptoDotCom, + cryptoDotComSupported, + showFTX, + ftxSupported, + showGemini, + geminiSupported + } = state + + const displayLookup = { + 'braveTalk': { + display: braveTalkSupported && showBraveTalk, + isCrypto: false + }, + 'rewards': { + display: showRewards, + isCrypto: false + }, + 'binance': { + display: binanceSupported && showBinance, + isCrypto: true + }, + 'cryptoDotCom': { + display: cryptoDotComSupported && showCryptoDotCom, + isCrypto: true + }, + 'ftx': { + display: ftxSupported && showFTX, + isCrypto: true + }, + 'gemini': { + display: geminiSupported && showGemini, + isCrypto: true + } + } + + // Among the crypt widgets, only one crypto widget is visible + // if it's foremost widget in the stack. + let foremostVisibleCryptoWidget = '' + const lastIndex = state.widgetStackOrder.length - 1; + for (let i = lastIndex; i >= 0; --i) { + const widget = displayLookup[state.widgetStackOrder[i]] + if (!widget) { + console.error('Update above lookup table') + continue + } + + if (!widget.display) { + continue + } + + if (widget.isCrypto) { + foremostVisibleCryptoWidget = state.widgetStackOrder[i] + } + // Found visible foremost widget in the widget stack. Go out. + break + } + + const widgetsShowKey = { + 'binance': 'showBinance', + 'cryptoDotCom': 'showCryptoDotCom', + 'ftx': 'showFTX', + 'gemini': 'showGemini' + } + + // Hide all crypto widgets except foremost one. + for (let key in widgetsShowKey) { + if (key === foremostVisibleCryptoWidget) { + state[widgetsShowKey[key]] = true + continue + } + state[widgetsShowKey[key]] = false + } + + saveShowBinance(state.showBinance) + saveShowCryptoDotCom(state.showCryptoDotCom) + saveShowFTX(state.showFTX) + saveShowGemini(state.showGemini) + saveWidgetVisibilityMigrated() + + return state +} + const cleanData = (state: NewTab.State) => { const { rewardsState } = state diff --git a/components/definitions/newTab.d.ts b/components/definitions/newTab.d.ts index 10abbeb5c341..28212a165a0b 100644 --- a/components/definitions/newTab.d.ts +++ b/components/definitions/newTab.d.ts @@ -113,6 +113,7 @@ declare namespace NewTab { showBinance: boolean showGemini: boolean showCryptoDotCom: boolean + widgetVisibilityMigrated: boolean hideAllWidgets: boolean isBraveTodayOptedIn: boolean isBrandedWallpaperNotificationDismissed: boolean