From 9bffe3efb470035813e296bda5556951441af209 Mon Sep 17 00:00:00 2001 From: Taher <8665427+nullhook@users.noreply.github.com> Date: Wed, 14 Dec 2022 23:31:35 -0800 Subject: [PATCH] Added select theme UI to the new onboarding flow (#16326) --- browser/ui/webui/brave_welcome_ui.cc | 9 +- .../components/loader/index.tsx | 12 +- .../components/select-theme/index.tsx | 132 ++++++++++++++ .../components/select-theme/style.ts | 168 ++++++++++++++++++ .../components/welcome/index.tsx | 14 +- .../brave_welcome_ui/main_container.tsx | 5 + .../brave_welcome_ui/state/component_types.ts | 1 + components/brave_welcome_ui/stories/locale.ts | 7 +- components/brave_welcome_ui/stories/story.tsx | 5 + .../resources/brave_welcome_strings.grdp | 20 +++ 10 files changed, 357 insertions(+), 16 deletions(-) create mode 100644 components/brave_welcome_ui/components/select-theme/index.tsx create mode 100644 components/brave_welcome_ui/components/select-theme/style.ts diff --git a/browser/ui/webui/brave_welcome_ui.cc b/browser/ui/webui/brave_welcome_ui.cc index 88b1a1271ed2..1a5f70e603aa 100644 --- a/browser/ui/webui/brave_welcome_ui.cc +++ b/browser/ui/webui/brave_welcome_ui.cc @@ -74,7 +74,14 @@ constexpr webui::LocalizedString kLocalizedStrings[] = { {"braveWelcomeSetupCompleteLabel", IDS_BRAVE_WELCOME_SETUP_COMPLETE_LABEL}, {"braveWelcomeChangeSettingsNote", IDS_BRAVE_WELCOME_CHANGE_SETTINGS_NOTE}, {"braveWelcomePrivacyPolicyNote", IDS_BRAVE_WELCOME_PRIVACY_POLICY_NOTE}, -}; + {"braveWelcomeSelectThemeLabel", IDS_BRAVE_WELCOME_SELECT_THEME_LABEL}, + {"braveWelcomeSelectThemeNote", IDS_BRAVE_WELCOME_SELECT_THEME_NOTE}, + {"braveWelcomeSelectThemeSystemLabel", + IDS_BRAVE_WELCOME_SELECT_THEME_SYSTEM_LABEL}, + {"braveWelcomeSelectThemeLightLabel", + IDS_BRAVE_WELCOME_SELECT_THEME_LIGHT_LABEL}, + {"braveWelcomeSelectThemeDarkLabel", + IDS_BRAVE_WELCOME_SELECT_THEME_DARK_LABEL}}; void OpenJapanWelcomePage(Profile* profile) { DCHECK(profile); diff --git a/components/brave_welcome_ui/components/loader/index.tsx b/components/brave_welcome_ui/components/loader/index.tsx index 7af23adca75f..9507a1ac8bb1 100644 --- a/components/brave_welcome_ui/components/loader/index.tsx +++ b/components/brave_welcome_ui/components/loader/index.tsx @@ -26,20 +26,10 @@ const Graphic = styled('div')` ` export default function Loader () { - const [show, setShow] = React.useState(false) - - React.useEffect(() => { - const timerId = setTimeout(() => setShow(true), 100) - - return () => { - clearTimeout(timerId) - } - }, []) - return ( - { show ? : null } + ) diff --git a/components/brave_welcome_ui/components/select-theme/index.tsx b/components/brave_welcome_ui/components/select-theme/index.tsx new file mode 100644 index 000000000000..f352d9a2f7b4 --- /dev/null +++ b/components/brave_welcome_ui/components/select-theme/index.tsx @@ -0,0 +1,132 @@ +// Copyright (c) 2022 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 https://mozilla.org/MPL/2.0/. + +import * as React from 'react' +import * as S from './style' + +import { getLocale } from '$web-common/locale' +import classnames from '$web-common/classnames' +import Button from '$web-components/button' + +import DataContext from '../../state/context' +import { ViewType } from '../../state/component_types' + +interface ThemeModeItemProps { + themeType: chrome.braveTheme.ThemeType + title: string + isActive: boolean + onChange?: (themeType: chrome.braveTheme.ThemeType) => void +} + +const themeList = [ + { themeType: 'System', title: getLocale('braveWelcomeSelectThemeSystemLabel') }, + { themeType: 'Light', title: getLocale('braveWelcomeSelectThemeLightLabel') }, + { themeType: 'Dark', title: getLocale('braveWelcomeSelectThemeDarkLabel') } +] + +function ThemeModeItem (props: ThemeModeItemProps) { + const handleClick = () => { + props.onChange?.(props.themeType) + } + + const buttonClass = classnames({ + 'theme-item': true, + 'is-selected': props.isActive + }) + + const logoBoxClass = classnames({ + 'logo': true, + 'dark-mode': props.themeType === 'Dark', + 'system-mode': props.themeType === 'System' + }) + + return ( + + + {props.isActive && ( + + + + )} + + + + {props.title} + + + ) +} + +function SelectTheme () { + const { setViewType, scenes } = React.useContext(DataContext) + const [currentSelectedTheme, setCurrentTheme] = React.useState('System') + + const handleSelectionChange = (themeType: chrome.braveTheme.ThemeType) => { + setCurrentTheme?.(themeType) + } + + const handleSkip = () => { + setViewType(ViewType.HelpImprove) + scenes?.s2.play() + } + + const handleNext = () => { + chrome.braveTheme.setBraveThemeType(currentSelectedTheme) + setViewType(ViewType.HelpImprove) + scenes?.s2.play() + } + + return ( + + + + + + {getLocale('braveWelcomeSelectThemeLabel')} + + + + + {themeList.map((entry, id) => { + return ( + + ) + })} + + + {getLocale('braveWelcomeSelectThemeNote')} + + + {getLocale('braveWelcomeSkipButtonLabel')} + + + {getLocale('braveWelcomeNextButtonLabel')} + + + + ) +} + +export default SelectTheme diff --git a/components/brave_welcome_ui/components/select-theme/style.ts b/components/brave_welcome_ui/components/select-theme/style.ts new file mode 100644 index 000000000000..59518c074f98 --- /dev/null +++ b/components/brave_welcome_ui/components/select-theme/style.ts @@ -0,0 +1,168 @@ +// Copyright (c) 2022 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 https://mozilla.org/MPL/2.0/. + +import styled from 'styled-components' + +export const Box = styled.div` + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(15px); + border-radius: 30px; + max-width: 800px; + color: white; + font-family: ${(p) => p.theme.fontFamily.heading}; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + + .view-header-box { + display: grid; + grid-template-columns: 0.2fr 1fr 0.2fr; + padding: 40px; + text-align: center; + } + + .view-details { + grid-column: 2; + } + + .view-title { + font-weight: 600; + font-size: 36px; + margin: 0 0 18px 0; + } + + .view-desc { + font-weight: 400; + font-size: 16px; + margin: 0; + } + + .view-note { + font-weight: 400; + font-size: 16px; + margin-bottom: 48px; + } +` + +export const ThemeListBox = styled.div` + --background-color: white; + --text-color: #212529; + --background-color-light: white; + --background-color-dark: #495057; + + @media (prefers-color-scheme: dark) { + --background-color: #1E2029; + --text-color: white; + --background-color-light: white; + --background-color-dark: #495057; + } + + .theme-list { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 56px; + grid-gap: 15px; + flex-wrap: wrap; + + &.is-selected-light { + --background-color: white; + --text-color: #212529; + --background-color-light: white; + --background-color-dark: #495057; + } + + &.is-selected-dark { + --background-color: #1E2029; + --text-color: white; + --background-color-light: white; + --background-color-dark: #495057; + } + } + + .theme-item { + --border-color: transparent; + + background: var(--background-color); + border-radius: 20px; + width: 132px; + height: 155px; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + color: var(--text-color); + border: 0; + box-shadow: 0 0 0 4px var(--border-color); + position: relative; + + &.is-selected { + --border-color: #737ADE; + } + } + + .theme-name { + font-weight: 400; + font-size: 14px; + line-height: 1.2; + margin: 0; + min-height: calc(2 * 14px * 1.2); // A min height of 2 lines + } + + .logo-box { + display: grid; + grid-template-rows: 50px 1fr; + gap: 10px; + width: 100%; + } + + .logo { + width: 48px; + height: 48px; + border-radius: 48px; + background: var(--background-color-light); + border: 1px solid #C2C4CF; + position: relative; + margin: 0 auto; + + &.dark-mode { + background: var(--background-color-dark); + } + + &.system-mode { + &::after { + content: ''; + position: absolute; + left: 0; + width: 40px; + height: 40px; + border: 23px solid var(--background-color-dark); + border-radius: 50%; + border-bottom-color: transparent; + border-left-color: transparent; + transform: rotate(90deg); + } + } + } + + .check-icon-box { + width: 16px; + height: 16px; + position: absolute; + top: 14px; + right: 14px; + } +` + +export const ActionBox = styled.div` + display: flex; + grid-gap: 10px; + margin-bottom: 40px; + + button { + color: white; + } +` diff --git a/components/brave_welcome_ui/components/welcome/index.tsx b/components/brave_welcome_ui/components/welcome/index.tsx index 1805f0b661b0..20b9f9ca56a8 100644 --- a/components/brave_welcome_ui/components/welcome/index.tsx +++ b/components/brave_welcome_ui/components/welcome/index.tsx @@ -20,19 +20,27 @@ import { shouldPlayAnimations } from '../../state/hooks' import braveLogoUrl from '../../assets/brave_logo_3d@2x.webp' function Welcome () { - const { setViewType, scenes } = React.useContext(DataContext) + const { setViewType, scenes, browserProfiles } = React.useContext(DataContext) const ref = React.useRef(null) + const goToImportThemeOrBrowser = () => { + if (!browserProfiles || browserProfiles.length === 0) { + setViewType(ViewType.ImportSelectTheme) + return + } + setViewType(ViewType.ImportSelectBrowser) + } + const handleSetAsDefaultBrowser = () => { WelcomeBrowserProxyImpl.getInstance().recordP3A({ currentScreen: ViewType.DefaultBrowser, isFinished: false, isSkipped: false }) DefaultBrowserBrowserProxyImpl.getInstance().setAsDefaultBrowser() - setViewType(ViewType.ImportSelectBrowser) + goToImportThemeOrBrowser() scenes?.s1.play() } const handleSkip = () => { WelcomeBrowserProxyImpl.getInstance().recordP3A({ currentScreen: ViewType.DefaultBrowser, isFinished: false, isSkipped: true }) - setViewType(ViewType.ImportSelectBrowser) + goToImportThemeOrBrowser() scenes?.s1.play() } diff --git a/components/brave_welcome_ui/main_container.tsx b/components/brave_welcome_ui/main_container.tsx index 421985a5e0d2..ef4c5e76e710 100644 --- a/components/brave_welcome_ui/main_container.tsx +++ b/components/brave_welcome_ui/main_container.tsx @@ -17,6 +17,7 @@ import Loader from './components/loader' const SelectBrowser = React.lazy(() => import('./components/select-browser')) const SelectProfile = React.lazy(() => import('./components/select-profile')) +const SelectTheme = React.lazy(() => import('./components/select-theme')) const SetupComplete = React.lazy(() => import('./components/setup-complete')) function MainContainer () { @@ -32,6 +33,10 @@ function MainContainer () { mainEl = } + if (viewType === ViewType.ImportSelectTheme) { + mainEl = + } + if (viewType === ViewType.ImportInProgress) { mainEl = } diff --git a/components/brave_welcome_ui/state/component_types.ts b/components/brave_welcome_ui/state/component_types.ts index 1a35f778febf..225b2dbfda04 100644 --- a/components/brave_welcome_ui/state/component_types.ts +++ b/components/brave_welcome_ui/state/component_types.ts @@ -8,6 +8,7 @@ import WebAnimationPlayer from '../api/web_animation_player' export enum ViewType { DefaultBrowser, // the welcome ui ImportSelectBrowser, + ImportSelectTheme, ImportSelectProfile, ImportInProgress, ImportSucceeded, diff --git a/components/brave_welcome_ui/stories/locale.ts b/components/brave_welcome_ui/stories/locale.ts index 035b897d02fa..4ce7062085c1 100644 --- a/components/brave_welcome_ui/stories/locale.ts +++ b/components/brave_welcome_ui/stories/locale.ts @@ -25,5 +25,10 @@ provideStrings({ braveWelcomeSendInsightsLabel: 'Share completely private and anonymous product insights about what features are being used by Brave\'s users. $1Learn more.$2', braveWelcomeSetupCompleteLabel: 'Setup complete', braveWelcomeChangeSettingsNote: ' Change these choices at any time in Brave at $1brave://settings/privacy$2.', - braveWelcomePrivacyPolicyNote: 'Read our full $1Privacy Policy$2' + braveWelcomePrivacyPolicyNote: 'Read our full $1Privacy Policy$2', + braveWelcomeSelectThemeLabel: 'Choose your theme', + braveWelcomeSelectThemeNote: 'You can change this at any time in Brave settings.', + braveWelcomeSelectThemeSystemLabel: 'Match system setting', + braveWelcomeSelectThemeLightLabel: 'Light mode', + braveWelcomeSelectThemeDarkLabel: 'Dark mode' }) diff --git a/components/brave_welcome_ui/stories/story.tsx b/components/brave_welcome_ui/stories/story.tsx index a8c23bb36a92..19f6dc7db33e 100644 --- a/components/brave_welcome_ui/stories/story.tsx +++ b/components/brave_welcome_ui/stories/story.tsx @@ -14,6 +14,7 @@ import './locale' import WelcomePage from './page/index' import SelectBrowser from '../components/select-browser' import SelectProfile from '../components/select-profile' +import SelectTheme from '../components/select-theme' import HelpImprove from '../components/help-improve' import ImportInProgress from '../components/import-in-progress' import SetupComplete from '../components/setup-complete' @@ -141,6 +142,10 @@ export const _SelectProfile = () => { return } +export const _SelectTheme = () => { + return +} + export const _HelpImprove = () => { return } diff --git a/components/resources/brave_welcome_strings.grdp b/components/resources/brave_welcome_strings.grdp index e9bfc9fb1e09..68453b2d4c04 100644 --- a/components/resources/brave_welcome_strings.grdp +++ b/components/resources/brave_welcome_strings.grdp @@ -79,4 +79,24 @@ Read our full $1Privacy Policy$2 + + + Choose your theme + + + + You can change this at any time in Brave settings. + + + + Match system setting + + + + Light mode + + + + Dark mode +
{props.title}