Skip to content
This repository has been archived by the owner on Nov 10, 2023. It is now read-only.

Feature: dark mode #3264

Merged
merged 3 commits into from
Jan 12, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/AppLayout/Header/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const Layout = ({ classes, providerDetails, providerInfo }) => {
<Row className={classes.summary}>
<Col className={classes.logo} middle="xs" start="xs">
<Link to={WELCOME_ROUTE}>
<Img alt="Gnosis Safe" height={36} src={SafeLogo} testId="heading-gnosis-logo" />
<Img alt="Gnosis Safe" height={36} src={SafeLogo} testId="heading-gnosis-logo" id="safe-logo" />
</Link>
</Col>

Expand Down
2 changes: 2 additions & 0 deletions src/components/AppLayout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Footer from './Footer'
import Sidebar from './Sidebar'
import { MobileNotSupported } from './MobileNotSupported'
import { SAFE_ROUTES, WELCOME_ROUTE } from 'src/routes/routes'
import useDarkMode from 'src/logic/hooks/useDarkMode'

const Container = styled.div`
height: 100vh;
Expand Down Expand Up @@ -92,6 +93,7 @@ const Layout: React.FC<Props> = ({
}): React.ReactElement => {
const [mobileNotSupportedClosed, setMobileNotSupportedClosed] = useState(false)
const { pathname } = useLocation()
useDarkMode()

const closeMobileNotSupported = () => setMobileNotSupportedClosed(true)

Expand Down
8 changes: 7 additions & 1 deletion src/components/Root/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,10 @@ body {
body > div:first-child {
display: flex;
min-height: 100%;
}
}

html[class="darkMode"],
html[class="darkMode"] div[style*="background-image"],
html[class="darkMode"] img:not([id="safe-logo"]) {
filter: invert(1) hue-rotate(180deg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't necessarily agree with this because it is not interfacing with the theme. It is more 'high contrast mode'.

@liliiaorlenko wanted to put together a dark palette and then we actually use the dark theme in MUI.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so should I already provide the palette?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a dark theme that uses MUI will need to be done incrementally. We will need the palette though to do so.

I don't know what the final decision should be on this ticket as it merely inverts colours. It won't need the palette here though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@liliiaorlenko no, no rush, it was just a quick experiment.

@iamacook it's good enough for me personally, easier on the eyes, but I agree it's not a good long-term solution.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iamacook renamed to hi-contrast:
Screenshot 2022-01-10 at 17 41 55

}
18 changes: 18 additions & 0 deletions src/logic/hooks/useDarkMode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useEffect } from 'react'
import useCachedState from 'src/utils/storage/useCachedState'

const useDarkMode = (): [boolean, (mode: boolean) => void] => {
const [darkMode = false, setDarkMode] = useCachedState<boolean>('darkMode')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should probably default to user preference to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if this is just an experimental feature?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I didn't consider that. Perhaps not then.


const toggleDarkMode = (toggle: boolean): void => {
document.documentElement.className = toggle ? 'darkMode' : ''
}

useEffect(() => {
toggleDarkMode(darkMode)
}, [darkMode])

return [darkMode, setDarkMode]
}

export default useDarkMode
44 changes: 29 additions & 15 deletions src/routes/safe/components/Settings/Appearance/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { setCopyShortName } from 'src/logic/appearance/actions/setCopyShortName'
import { extractSafeAddress } from 'src/routes/routes'
import PrefixedEthHashInfo from 'src/components/PrefixedEthHashInfo'
import { useAnalytics, SETTINGS_EVENTS } from 'src/utils/googleAnalytics'
import useDarkMode from 'src/logic/hooks/useDarkMode'

// Other settings sections use MUI createStyles .container
// will adjust that during dark mode implementation
Expand All @@ -31,6 +32,7 @@ const Appearance = (): ReactElement => {
const copyShortName = useSelector(copyShortNameSelector)
const showShortName = useSelector(showShortNameSelector)
const safeAddress = extractSafeAddress()
const [darkMode, setDarkMode] = useDarkMode()

const { trackEvent } = useAnalytics()

Expand All @@ -48,21 +50,33 @@ const Appearance = (): ReactElement => {
dispatch(setCopyShortName({ copyShortName: checked }))

return (
<Container>
<Heading tag="h2">Use Chain-Specific Addresses</Heading>
<Paragraph>You can choose whether to prepend EIP-3770 short chain names accross Safes.</Paragraph>
<StyledPrefixedEthHashInfo hash={safeAddress} />
<FormGroup>
<FormControlLabel
control={<Checkbox checked={showShortName} onChange={handleShowChange} name="showShortName" />}
label="Prepend addresses with chain prefix."
/>
<FormControlLabel
control={<Checkbox checked={copyShortName} onChange={handleCopyChange} name="copyShortName" />}
label="Copy addresses with chain prefix."
/>
</FormGroup>
</Container>
<>
<Container>
<Heading tag="h2">Use Chain-Specific Addresses</Heading>
<Paragraph>You can choose whether to prepend EIP-3770 short chain names accross Safes.</Paragraph>
<StyledPrefixedEthHashInfo hash={safeAddress} />
<FormGroup>
<FormControlLabel
control={<Checkbox checked={showShortName} onChange={handleShowChange} name="showShortName" />}
label="Prepend addresses with chain prefix."
/>
<FormControlLabel
control={<Checkbox checked={copyShortName} onChange={handleCopyChange} name="copyShortName" />}
label="Copy addresses with chain prefix."
/>
</FormGroup>
</Container>

<Container>
<Heading tag="h2">Dark mode (experimental)</Heading>
<FormGroup>
<FormControlLabel
control={<Checkbox checked={darkMode} onChange={() => setDarkMode(!darkMode)} name="showShortName" />}
label="Dark mode"
/>
</FormGroup>
</Container>
</>
)
}

Expand Down