diff --git a/browser/ui/webui/brave_webui_source.cc b/browser/ui/webui/brave_webui_source.cc index 8986ea44d4cc..85c59cbc8941 100644 --- a/browser/ui/webui/brave_webui_source.cc +++ b/browser/ui/webui/brave_webui_source.cc @@ -134,6 +134,8 @@ void CustomizeWebUIHTMLSource(const std::string &name, { "preferencesPageTitle", IDS_BRAVE_NEW_TAB_PREFERENCES_PAGE_TITLE }, { "bookmarksPageTitle", IDS_BRAVE_NEW_TAB_BOOKMARKS_PAGE_TITLE }, { "historyPageTitle", IDS_BRAVE_NEW_TAB_HISTORY_PAGE_TITLE }, + { "dashboardSettingsTitle", IDS_BRAVE_NEW_TAB_DASHBOARD_SETTINGS_TITLE }, + { "showBackgroundImage", IDS_BRAVE_NEW_TAB_SHOW_BACKGROUND_IMAGE }, // Private Tab - General { "learnMore", IDS_BRAVE_PRIVATE_NEW_TAB_LEARN_MORE }, diff --git a/components/brave_new_tab_ui/actions/new_tab_actions.ts b/components/brave_new_tab_ui/actions/new_tab_actions.ts index 740c7de9df48..22720b0fd209 100644 --- a/components/brave_new_tab_ui/actions/new_tab_actions.ts +++ b/components/brave_new_tab_ui/actions/new_tab_actions.ts @@ -66,3 +66,9 @@ export const statsUpdated = () => action(types.NEW_TAB_STATS_UPDATED) export const changePrivateSearchEngine = (shouldUse: boolean) => action(types.NEW_TAB_USE_ALTERNATIVE_PRIVATE_SEARCH_ENGINE, { shouldUse }) + +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) diff --git a/components/brave_new_tab_ui/components/newTab/footerInfo.tsx b/components/brave_new_tab_ui/components/newTab/footerInfo.tsx index 13eec65ad7b7..2d62185a34a3 100644 --- a/components/brave_new_tab_ui/components/newTab/footerInfo.tsx +++ b/components/brave_new_tab_ui/components/newTab/footerInfo.tsx @@ -8,18 +8,26 @@ import * as React from 'react' import { Link, Navigation, IconLink, PhotoName } from 'brave-ui/features/newTab/default' // Icons -import { SettingsAdvancedIcon, BookmarkBook, HistoryIcon } from 'brave-ui/components/icons' +import { SettingsAdvancedIcon, BookmarkBook, HistoryIcon, SettingsIcon } from 'brave-ui/components/icons' // Helpers import { getLocale } from '../../../common/locale' interface Props { backgroundImageInfo: NewTab.Image | undefined + onClickSettings: () => void + isSettingsMenuOpen: boolean + showPhotoInfo: boolean } export default class FooterInfo extends React.Component { render () { - const { backgroundImageInfo } = this.props + const { + backgroundImageInfo, + onClickSettings, + isSettingsMenuOpen, + showPhotoInfo + } = this.props if (!backgroundImageInfo) { return null @@ -28,14 +36,18 @@ export default class FooterInfo extends React.Component { return ( <>
+ {showPhotoInfo && {`${getLocale('photoBy')} `} {backgroundImageInfo.author} - + }
+ + + diff --git a/components/brave_new_tab_ui/components/newTab/index.tsx b/components/brave_new_tab_ui/components/newTab/index.tsx index aaaab0be3ce0..245d583470dd 100644 --- a/components/brave_new_tab_ui/components/newTab/index.tsx +++ b/components/brave_new_tab_ui/components/newTab/index.tsx @@ -17,6 +17,7 @@ import { } from 'brave-ui/features/newTab/default' // Components +import Settings from './settings' import Stats from './stats' import Block from './block' import FooterInfo from './footerInfo' @@ -61,6 +62,18 @@ class NewTabPage extends React.Component { this.props.actions.siteIgnored(site.url) } + toggleShowBackgroundImage = () => { + this.props.actions.toggleShowBackgroundImage() + } + + showSettings = () => { + this.props.actions.showSettingsMenu() + } + + closeSettings = () => { + this.props.actions.closeSettingsMenu() + } + render () { const { newTabData, actions } = this.props @@ -69,8 +82,8 @@ class NewTabPage extends React.Component { } return ( - - + + {newTabData.showBackgroundImage && }
@@ -104,8 +117,21 @@ class NewTabPage extends React.Component { }
+ { + newTabData.showSettings && + + }
- +
diff --git a/components/brave_new_tab_ui/components/newTab/settings.tsx b/components/brave_new_tab_ui/components/newTab/settings.tsx new file mode 100644 index 000000000000..88fa83842f67 --- /dev/null +++ b/components/brave_new_tab_ui/components/newTab/settings.tsx @@ -0,0 +1,58 @@ +/* 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 { SettingsMenu, SettingsRow, SettingsText, SettingsTitle, SettingsWrapper } from 'brave-ui/features/newTab/default' + +import { Toggle } from 'brave-ui/features/newTab/toggle' + +import { getLocale } from '../../../common/locale' + +export interface Props { + onClickOutside: () => void + toggleShowBackgroundImage: () => void + showBackgroundImage: boolean +} + +export default class Settings extends React.PureComponent { + settingsMenuRef: React.RefObject + constructor (props: Props) { + super(props) + this.settingsMenuRef = React.createRef() + } + + handleClickOutside = (event: Event) => { + if (this.settingsMenuRef && !this.settingsMenuRef.current.contains(event.target)) { + this.props.onClickOutside() + } + } + + componentDidMount () { + document.addEventListener('mousedown', this.handleClickOutside) + } + + componentWillUnmount () { + document.removeEventListener('mousedown', this.handleClickOutside) + } + + render () { + const { toggleShowBackgroundImage, showBackgroundImage } = this.props + return ( + + + {getLocale('dashboardSettingsTitle')} + + {getLocale('showBackgroundImage')} + + + + + ) + } +} diff --git a/components/brave_new_tab_ui/constants/new_tab_types.ts b/components/brave_new_tab_ui/constants/new_tab_types.ts index a943876fd10b..4bc9788ed2c5 100644 --- a/components/brave_new_tab_ui/constants/new_tab_types.ts +++ b/components/brave_new_tab_ui/constants/new_tab_types.ts @@ -17,5 +17,8 @@ export const enum types { NEW_TAB_BOOKMARK_INFO_AVAILABLE = '@@newtab/NEW_TAB_BOOKMARK_INFO_AVAILABLE', NEW_TAB_GRID_SITES_UPDATED = '@@newtab/NEW_TAB_GRID_SITES_UPDATED', NEW_TAB_STATS_UPDATED = '@@newtab/NEW_TAB_STATS_UPDATED', - NEW_TAB_USE_ALTERNATIVE_PRIVATE_SEARCH_ENGINE = '@@newtab/NEW_TAB_USE_ALTERNATIVE_PRIVATE_SEARCH_ENGINE' + 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' } diff --git a/components/brave_new_tab_ui/reducers/new_tab_reducer.tsx b/components/brave_new_tab_ui/reducers/new_tab_reducer.tsx index f83ece463260..1e2ebd015479 100644 --- a/components/brave_new_tab_ui/reducers/new_tab_reducer.tsx +++ b/components/brave_new_tab_ui/reducers/new_tab_reducer.tsx @@ -26,6 +26,18 @@ export const newTabReducer: Reducer = (state: NewTab.S const startingState = state const payload = action.payload switch (action.type) { + case types.NEW_TAB_SHOW_SETTINGS_MENU: + state = { ...state, showSettings: true } + break + + case types.NEW_TAB_CLOSE_SETTINGS_MENU: + state = { ...state, showSettings: false } + break + + case types.NEW_TAB_TOGGLE_SHOW_BACKGROUND_IMAGE: + state = { ...state, showBackgroundImage: !state.showBackgroundImage } + break + case types.BOOKMARK_ADDED: const topSite: NewTab.Site | undefined = state.topSites.find((site) => site.url === payload.url) if (topSite) { diff --git a/components/brave_new_tab_ui/storage.ts b/components/brave_new_tab_ui/storage.ts index 82b5cfaa75aa..49c9c7d05977 100644 --- a/components/brave_new_tab_ui/storage.ts +++ b/components/brave_new_tab_ui/storage.ts @@ -10,6 +10,8 @@ import { debounce } from '../common/debounce' const keyName = 'new-tab-data' const defaultState: NewTab.State = { + showBackgroundImage: false, + showSettings: false, topSites: [], ignoredTopSites: [], pinnedTopSites: [], diff --git a/components/definitions/newTab.d.ts b/components/definitions/newTab.d.ts index 73a233a9aa7b..9a1df53e0b37 100644 --- a/components/definitions/newTab.d.ts +++ b/components/definitions/newTab.d.ts @@ -55,5 +55,7 @@ declare namespace NewTab { backgroundImage?: Image gridLayoutSize?: 'small' showSiteRemovalNotification?: boolean + showBackgroundImage: boolean + showSettings: boolean } } diff --git a/components/resources/brave_components_strings.grd b/components/resources/brave_components_strings.grd index 42339c34328b..1a999e278ade 100644 --- a/components/resources/brave_components_strings.grd +++ b/components/resources/brave_components_strings.grd @@ -138,6 +138,8 @@ Edit Preferences View and Manage Bookmarks View your browsing history + Dashboard Settings + Show background image Learn more diff --git a/components/test/brave_new_tab_ui/actions/new_tab_actions_test.ts b/components/test/brave_new_tab_ui/actions/new_tab_actions_test.ts index d55a4d78dd8c..3321ea5337f0 100644 --- a/components/test/brave_new_tab_ui/actions/new_tab_actions_test.ts +++ b/components/test/brave_new_tab_ui/actions/new_tab_actions_test.ts @@ -144,4 +144,19 @@ describe('newTabActions', () => { payload: { shouldUse } }) }) + it('showSettingsMenu', () => { + expect(actions.showSettingsMenu()).toEqual({ + type: types.NEW_TAB_SHOW_SETTINGS_MENU + }) + }) + it('closeSettingsMenu', () => { + expect(actions.showSettingsMenu()).toEqual({ + type: types.NEW_TAB_SHOW_SETTINGS_MENU + }) + }) + it('toggleShowBackgroundImage', () => { + expect(actions.toggleShowBackgroundImage()).toEqual({ + type: types.NEW_TAB_TOGGLE_SHOW_BACKGROUND_IMAGE + }) + }) }) diff --git a/components/test/brave_new_tab_ui/components/settings_test.tsx b/components/test/brave_new_tab_ui/components/settings_test.tsx new file mode 100644 index 000000000000..f4e1a9991057 --- /dev/null +++ b/components/test/brave_new_tab_ui/components/settings_test.tsx @@ -0,0 +1,22 @@ +import * as React from 'react' +import { shallow } from 'enzyme' +import { SettingsMenu, SettingsWrapper } from 'brave-ui/features/newTab/default' +import Settings, { Props } from '../../../../components/brave_new_tab_ui/components/newTab/settings' + +describe('settings component tests', () => { + const mockProps: Props = { + onClickOutside: () => null, + toggleShowBackgroundImage: () => null, + showBackgroundImage: true + } + it('should render the component properly', () => { + const wrapper = shallow( + ) + expect(wrapper.find(SettingsMenu)).toHaveLength(1) + expect(wrapper.find(SettingsWrapper)).toHaveLength(1) + }) +}) diff --git a/components/test/brave_new_tab_ui/reducers/new_tab_reducer_test.ts b/components/test/brave_new_tab_ui/reducers/new_tab_reducer_test.ts index 08278e0665bd..3619603ef248 100644 --- a/components/test/brave_new_tab_ui/reducers/new_tab_reducer_test.ts +++ b/components/test/brave_new_tab_ui/reducers/new_tab_reducer_test.ts @@ -324,4 +324,43 @@ describe('newTabReducer', () => { }) }) }) + + describe('NEW_TAB_SHOW_SETTINGS_MENU', () => { + it('should set show settings to true', () => { + const mockState = { ...fakeState, showSettings: false } + const assertion = newTabReducer(mockState, { + type: types.NEW_TAB_SHOW_SETTINGS_MENU + }) + const expected = { + ...mockState, + showSettings: true + } + expect(assertion).toEqual(expected) + }) + }) + + describe('NEW_TAB_CLOSE_SETTINGS_MENU', () => { + it('should set show settings to false', () => { + const mockState = { ...fakeState, showSettings: true } + const assertion = newTabReducer(mockState, { + type: types.NEW_TAB_CLOSE_SETTINGS_MENU + }) + const expected = { + ...mockState, + showSettings: false + } + expect(assertion).toEqual(expected) + }) + }) + + describe('NEW_TAB_TOGGLE_SHOW_BACKGROUND_IMAGE', () => { + it('should toggle showBackgroundimage status to be true', () => { + const mockState = { ...fakeState, showBackgroundImage: false } + const expected = { ...mockState, showBackgroundImage: true } + const assertion = newTabReducer(mockState, { + type: types.NEW_TAB_TOGGLE_SHOW_BACKGROUND_IMAGE + }) + expect(assertion).toEqual(expected) + }) + }) }) diff --git a/components/test/testData.ts b/components/test/testData.ts index be2d3625f729..4ef5e0e84da1 100644 --- a/components/test/testData.ts +++ b/components/test/testData.ts @@ -41,6 +41,8 @@ export const syncInitialState: Sync.ApplicationState = { syncData } export const newTabInitialState: NewTab.ApplicationState = { newTabData: { + showBackgroundImage: false, + showSettings: false, topSites: [], ignoredTopSites: [], pinnedTopSites: [], diff --git a/package-lock.json b/package-lock.json index 39129ee89265..6afc0ddff43b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1597,8 +1597,8 @@ } }, "brave-ui": { - "version": "github:brave/brave-ui#624be474ee7d3e4dc3409712ac9ec56e33ef9b04", - "from": "github:brave/brave-ui#624be474ee7d3e4dc3409712ac9ec56e33ef9b04", + "version": "github:brave/brave-ui#77b4e9f2687aa3032479b322e382f82a7fdd29b2", + "from": "github:brave/brave-ui#77b4e9f2687aa3032479b322e382f82a7fdd29b2", "dev": true, "requires": { "@ctrl/tinycolor": "^2.2.1", diff --git a/package.json b/package.json index 3a3984a283a4..3f7412c61cca 100644 --- a/package.json +++ b/package.json @@ -277,7 +277,7 @@ "@types/react-redux": "6.0.4", "@types/redux-logger": "^3.0.7", "awesome-typescript-loader": "^5.2.1", - "brave-ui": "github:brave/brave-ui#624be474ee7d3e4dc3409712ac9ec56e33ef9b04", + "brave-ui": "github:brave/brave-ui#77b4e9f2687aa3032479b322e382f82a7fdd29b2", "css-loader": "^2.1.1", "csstype": "^2.5.5", "deep-freeze-node": "^1.1.3",