Skip to content

Commit

Permalink
New Tab Page WebUI: Use Profile Preferences to store page options ins…
Browse files Browse the repository at this point in the history
…tead of localStorage

Fixes brave/brave-browser#5064

This allows:
- Surfacing these preferences outside of the NTP
- Syncing / migrating the preferences
- Making the change immediately for all open NTP

Use FireWebUIListener to push data to javascript event subscribers.
Still uses render_view_host->SetWebUIProperty (like the existing NTP data), which we may port in the future to a DataSource Dictionary like the other WebUI in chromium.

Provides any data retreived or updated to redux store via redux action, but does not use redux actions to ask for a data change.
  • Loading branch information
petemill authored and bsclifton committed Jun 28, 2019
1 parent 801a983 commit 541ae05
Show file tree
Hide file tree
Showing 17 changed files with 224 additions and 101 deletions.
6 changes: 6 additions & 0 deletions browser/brave_profile_prefs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {

// IPFS companion extension
registry->RegisterBooleanPref(kIPFSCompanionEnabled, false);

// New Tab Page
registry->RegisterBooleanPref(kNewTabPageShowBackgroundImage, true);
registry->RegisterBooleanPref(kNewTabPageShowClock, true);
registry->RegisterBooleanPref(kNewTabPageShowTopSites, true);
registry->RegisterBooleanPref(kNewTabPageShowStats, true);
}

} // namespace brave
58 changes: 58 additions & 0 deletions browser/ui/webui/brave_new_tab_message_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include "brave/browser/ui/webui/brave_new_tab_message_handler.h"

#include <string>

#include "base/bind.h"
#include "base/values.h"
#include "brave/browser/ui/webui/brave_new_tab_ui.h"
Expand Down Expand Up @@ -40,6 +42,19 @@ void BraveNewTabMessageHandler::OnJavascriptAllowed() {
pref_change_registrar_.Add(kAlternativeSearchEngineProviderInTor,
base::Bind(&BraveNewTabMessageHandler::OnPrivatePropertiesChanged,
base::Unretained(this)));
// New Tab Page preferences
pref_change_registrar_.Add(kNewTabPageShowBackgroundImage,
base::Bind(&BraveNewTabMessageHandler::OnPreferencesChanged,
base::Unretained(this)));
pref_change_registrar_.Add(kNewTabPageShowClock,
base::Bind(&BraveNewTabMessageHandler::OnPreferencesChanged,
base::Unretained(this)));
pref_change_registrar_.Add(kNewTabPageShowStats,
base::Bind(&BraveNewTabMessageHandler::OnPreferencesChanged,
base::Unretained(this)));
pref_change_registrar_.Add(kNewTabPageShowTopSites,
base::Bind(&BraveNewTabMessageHandler::OnPreferencesChanged,
base::Unretained(this)));
}

void BraveNewTabMessageHandler::OnJavascriptDisallowed() {
Expand All @@ -57,6 +72,11 @@ void BraveNewTabMessageHandler::RegisterMessages() {
base::BindRepeating(
&BraveNewTabMessageHandler::HandleToggleAlternativeSearchEngineProvider,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"saveNewTabPagePref",
base::BindRepeating(
&BraveNewTabMessageHandler::HandleSaveNewTabPagePref,
base::Unretained(this)));
}

void BraveNewTabMessageHandler::HandleInitialized(const base::ListValue* args) {
Expand All @@ -69,6 +89,39 @@ void BraveNewTabMessageHandler::HandleToggleAlternativeSearchEngineProvider(
Profile::FromWebUI(web_ui()));
}

void BraveNewTabMessageHandler::HandleSaveNewTabPagePref(
const base::ListValue* args) {
if (args->GetSize() != 2) {
LOG(ERROR) << "Invalid input";
return;
}
PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
std::string settingsKeyInput = args->GetList()[0].GetString();
auto settingsValue = args->GetList()[1].Clone();
// Check valid value type
// Note: if we introduce any non-bool settings values
// then perform this type check within the appropriate key conditionals.
if (!settingsValue.is_bool()) {
LOG(ERROR) << "Invalid value type";
return;
}
const auto settingsValueBool = settingsValue.GetBool();
std::string settingsKey;
if (settingsKeyInput == "showBackgroundImage") {
settingsKey = kNewTabPageShowBackgroundImage;
} else if (settingsKeyInput == "showClock") {
settingsKey = kNewTabPageShowClock;
} else if (settingsKeyInput == "showTopSites") {
settingsKey = kNewTabPageShowTopSites;
} else if (settingsKeyInput == "showStats") {
settingsKey = kNewTabPageShowStats;
} else {
LOG(ERROR) << "Invalid setting key";
return;
}
prefs->SetBoolean(settingsKey, settingsValueBool);
}

void BraveNewTabMessageHandler::OnPrivatePropertiesChanged() {
new_tab_web_ui_->OnPrivatePropertiesChanged();
}
Expand All @@ -77,3 +130,8 @@ void BraveNewTabMessageHandler::OnStatsChanged() {
new_tab_web_ui_->OnStatsChanged();
FireWebUIListener("stats-updated");
}

void BraveNewTabMessageHandler::OnPreferencesChanged() {
new_tab_web_ui_->OnPreferencesChanged();
FireWebUIListener("preferences-changed");
}
2 changes: 2 additions & 0 deletions browser/ui/webui/brave_new_tab_message_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class BraveNewTabMessageHandler : public content::WebUIMessageHandler {
explicit BraveNewTabMessageHandler(BraveNewTabUI* web_ui);
~BraveNewTabMessageHandler() override;
void OnStatsChanged();
void OnPreferencesChanged();
void OnPrivatePropertiesChanged();

private:
Expand All @@ -27,6 +28,7 @@ class BraveNewTabMessageHandler : public content::WebUIMessageHandler {
void OnJavascriptDisallowed() override;

void HandleInitialized(const base::ListValue* args);
void HandleSaveNewTabPagePref(const base::ListValue* args);
void HandleToggleAlternativeSearchEngineProvider(
const base::ListValue* args);

Expand Down
33 changes: 33 additions & 0 deletions browser/ui/webui/brave_new_tab_ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ void BraveNewTabUI::UpdateWebUIProperties() {
auto* render_view_host = GetRenderViewHost();
SetStatsWebUIProperties(render_view_host);
SetPrivateWebUIProperties(render_view_host);
SetPreferencesWebUIProperties(render_view_host);
}

void BraveNewTabUI::SetStatsWebUIProperties(
Expand Down Expand Up @@ -86,6 +87,38 @@ void BraveNewTabUI::SetPrivateWebUIProperties(
}
}

void BraveNewTabUI::SetPreferencesWebUIProperties(
content::RenderViewHost* render_view_host) {
DCHECK(IsSafeToSetWebUIProperties());
Profile* profile = Profile::FromWebUI(web_ui());
PrefService* prefs = profile->GetPrefs();
if (render_view_host) {
render_view_host->SetWebUIProperty(
"showBackgroundImage",
prefs->GetBoolean(kNewTabPageShowBackgroundImage) ? "true"
: "false");
render_view_host->SetWebUIProperty(
"showClock",
prefs->GetBoolean(kNewTabPageShowClock) ? "true"
: "false");
render_view_host->SetWebUIProperty(
"showTopSites",
prefs->GetBoolean(kNewTabPageShowTopSites) ? "true"
: "false");
render_view_host->SetWebUIProperty(
"showStats",
prefs->GetBoolean(kNewTabPageShowStats) ? "true"
: "false");
}
}


void BraveNewTabUI::OnPreferencesChanged() {
if (IsSafeToSetWebUIProperties()) {
SetPreferencesWebUIProperties(GetRenderViewHost());
}
}

void BraveNewTabUI::OnPrivatePropertiesChanged() {
if (IsSafeToSetWebUIProperties()) {
SetPrivateWebUIProperties(GetRenderViewHost());
Expand Down
1 change: 1 addition & 0 deletions browser/ui/webui/brave_new_tab_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class BraveNewTabUI : public BasicUI {
private:
// BasicUI overrides
void UpdateWebUIProperties() override;
void SetPreferencesWebUIProperties(content::RenderViewHost* render_view_host);
void SetStatsWebUIProperties(content::RenderViewHost* render_view_host);
void SetPrivateWebUIProperties(content::RenderViewHost* render_view_host);

Expand Down
5 changes: 5 additions & 0 deletions common/pref_names.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,8 @@ const char kWebTorrentEnabled[] = "brave.webtorrent_enabled";
const char kHangoutsEnabled[] = "brave.hangouts_enabled";
const char kHideBraveRewardsButton[] = "brave.hide_brave_rewards_button";
const char kIPFSCompanionEnabled[] = "brave.ipfs_companion_enabled";
const char kNewTabPageShowBackgroundImage[] =
"brave.new_tab_page.show_background_image";
const char kNewTabPageShowClock[] = "brave.new_tab_page.show_clock";
const char kNewTabPageShowTopSites[] = "brave.new_tab_page.show_top_sites";
const char kNewTabPageShowStats[] = "brave.new_tab_page.show_stats";
4 changes: 4 additions & 0 deletions common/pref_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,9 @@ extern const char kWebTorrentEnabled[];
extern const char kHangoutsEnabled[];
extern const char kHideBraveRewardsButton[];
extern const char kIPFSCompanionEnabled[];
extern const char kNewTabPageShowBackgroundImage[];
extern const char kNewTabPageShowClock[];
extern const char kNewTabPageShowTopSites[];
extern const char kNewTabPageShowStats[];

#endif // BRAVE_COMMON_PREF_NAMES_H_
10 changes: 3 additions & 7 deletions components/brave_new_tab_ui/actions/new_tab_actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,6 @@ export const showSettingsMenu = () => action(types.NEW_TAB_SHOW_SETTINGS_MENU)

export const closeSettingsMenu = () => action(types.NEW_TAB_CLOSE_SETTINGS_MENU)

export const toggleShowBackgroundImage = () => action(types.NEW_TAB_TOGGLE_SHOW_BACKGROUND_IMAGE)

export const toggleShowStats = () => action(types.NEW_TAB_TOGGLE_SHOW_STATS)

export const toggleShowClock = () => action(types.NEW_TAB_TOGGLE_SHOW_CLOCK)

export const toggleShowTopSites = () => action(types.NEW_TAB_TOGGLE_SHOW_TOP_SITES)
export const preferencesUpdated = (prefs: any) => action(types.NEW_TAB_PREFERENCES_UPDATED, {
prefs
})
59 changes: 59 additions & 0 deletions components/brave_new_tab_ui/api/preferences.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) 2019 The Brave Authors. All rights reserved.
// 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 http://mozilla.org/MPL/2.0/.

//
// Manages get and set of NTP preference data
// Ensures everything to do with communication
// with the WebUI backend is all in 1 place,
// especially string keys.
//

type Preferences = {
showBackgroundImage: boolean
showStats: boolean
showClock: boolean
showTopSites: boolean
}

function getWebUIBooleanVal(key: string): boolean {
return (chrome.getVariableValue(key).toLowerCase() === 'true')
}

export function getPreferences (): Promise<Preferences> {
// Note(petemill): Returning as promise allows this
// to be async even though it isn't right now.
// Enforces practice of not setting directly
// in a redux reducer.
return Promise.resolve({
showBackgroundImage: getWebUIBooleanVal('showBackgroundImage'),
showStats: getWebUIBooleanVal('showStats'),
showClock: getWebUIBooleanVal('showClock'),
showTopSites: getWebUIBooleanVal('showTopSites')
})
}

function sendSavePref(key: string, value: any) {
chrome.send('saveNewTabPagePref', [key, value])
}

export function saveShowBackgroundImage (value: boolean): void {
sendSavePref('showBackgroundImage', value)
}

export function saveShowClock (value: boolean): void {
sendSavePref('showClock', value)
}

export function saveShowTopSites (value: boolean): void {
sendSavePref('showTopSites', value)
}

export function saveShowStats (value: boolean): void {
sendSavePref('showStats', value)
}

export function addChangeListener (listener: () => void): void {
window.cr.addWebUIListener('preferences-changed', listener)
}
10 changes: 10 additions & 0 deletions components/brave_new_tab_ui/brave_new_tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { Provider } from 'react-redux'
import Theme from 'brave-ui/theme/brave-default'
import { ThemeProvider } from 'brave-ui/theme'
import * as dataFetchAPI from './api/dataFetch'
import * as preferencesAPI from './api/preferences'


// Components
import App from './components/app'
Expand All @@ -32,6 +34,13 @@ function initialize () {
)
window.i18nTemplate.process(window.document, window.loadTimeData)
handleAPIEvents()
updatePrefs()
}

async function updatePrefs() {
const prefs = await preferencesAPI.getPreferences()
const actions = dataFetchAPI.getActions()
actions.preferencesUpdated(prefs)
}

function updateStats() {
Expand All @@ -42,6 +51,7 @@ function updateStats() {
function handleAPIEvents () {
chrome.send('newTabPageInitialized', [])
window.cr.addWebUIListener('stats-updated', updateStats)
preferencesAPI.addChangeListener(updatePrefs)
}

document.addEventListener('DOMContentLoaded', initialize)
17 changes: 13 additions & 4 deletions components/brave_new_tab_ui/components/app.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* 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 http://mozilla.org/MPL/2.0/. */
// Copyright (c) 2019 The Brave Authors. All rights reserved.
// 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 http://mozilla.org/MPL/2.0/.

import * as React from 'react'
import { bindActionCreators, Dispatch } from 'redux'
Expand All @@ -12,6 +13,7 @@ import NewTabPage from './newTab'

// Utils
import * as newTabActions from '../actions/new_tab_actions'
import * as PreferencesAPI from '../api/preferences'

interface Props {
actions: any
Expand All @@ -29,7 +31,14 @@ class DefaultPage extends React.Component<Props, {}> {

return this.props.newTabData.isIncognito
? <NewPrivateTabPage newTabData={newTabData} actions={actions} />
: <NewTabPage newTabData={newTabData} actions={actions} />
: <NewTabPage
newTabData={newTabData}
actions={actions}
saveShowBackgroundImage={PreferencesAPI.saveShowBackgroundImage}
saveShowClock={PreferencesAPI.saveShowClock}
saveShowStats={PreferencesAPI.saveShowStats}
saveShowTopSites={PreferencesAPI.saveShowTopSites}
/>
}
}

Expand Down
22 changes: 17 additions & 5 deletions components/brave_new_tab_ui/components/newTab/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ import FooterInfo from './footerInfo'
import SiteRemovalNotification from './notification'

interface Props {
actions: any
newTabData: NewTab.State
actions: any
saveShowBackgroundImage: (value: boolean) => void
saveShowClock: (value: boolean) => void
saveShowTopSites: (value: boolean) => void
saveShowStats: (value: boolean) => void
}

class NewTabPage extends React.Component<Props, {}> {
Expand Down Expand Up @@ -63,19 +67,27 @@ class NewTabPage extends React.Component<Props, {}> {
}

toggleShowBackgroundImage = () => {
this.props.actions.toggleShowBackgroundImage()
this.props.saveShowBackgroundImage(
!this.props.newTabData.showBackgroundImage
)
}

toggleShowClock = () => {
this.props.actions.toggleShowClock()
this.props.saveShowClock(
!this.props.newTabData.showClock
)
}

toggleShowStats = () => {
this.props.actions.toggleShowStats()
this.props.saveShowStats(
!this.props.newTabData.showStats
)
}

toggleShowTopSites = () => {
this.props.actions.toggleShowTopSites()
this.props.saveShowTopSites(
!this.props.newTabData.showTopSites
)
}

showSettings = () => {
Expand Down
5 changes: 1 addition & 4 deletions components/brave_new_tab_ui/constants/new_tab_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,5 @@ export const enum types {
NEW_TAB_USE_ALTERNATIVE_PRIVATE_SEARCH_ENGINE = '@@newtab/NEW_TAB_USE_ALTERNATIVE_PRIVATE_SEARCH_ENGINE',
NEW_TAB_SHOW_SETTINGS_MENU = '@@newtab/NEW_TAB_SHOW_SETTINGS_MENU',
NEW_TAB_CLOSE_SETTINGS_MENU = '@@newtab/NEW_TAB_CLOSE_SETTINGS_MENU',
NEW_TAB_TOGGLE_SHOW_BACKGROUND_IMAGE = '@@newtab/NEW_TAB_TOGGLE_SHOW_BACKGROUND_IMAGE',
NEW_TAB_TOGGLE_SHOW_STATS = '@@newtab/NEW_TAB_TOGGLE_SHOW_STATS',
NEW_TAB_TOGGLE_SHOW_CLOCK = '@@newtab/NEW_TAB_TOGGLE_SHOW_CLOCK',
NEW_TAB_TOGGLE_SHOW_TOP_SITES = '@@newtab/NEW_TAB_TOGGLE_SHOW_TOP_SITES'
NEW_TAB_PREFERENCES_UPDATED = '@@newtab/NEW_TAB_PREFERENCES_UPDATED'
}
Loading

0 comments on commit 541ae05

Please sign in to comment.