diff --git a/app/soapbox/features/ui/components/navbar.tsx b/app/soapbox/features/ui/components/navbar.tsx
index 75b76a12c..d01b2fd27 100644
--- a/app/soapbox/features/ui/components/navbar.tsx
+++ b/app/soapbox/features/ui/components/navbar.tsx
@@ -6,6 +6,7 @@ import { Link } from 'react-router-dom';
import { Avatar, Button, Icon } from 'soapbox/components/ui';
import Search from 'soapbox/features/compose/components/search';
+import ThemeToggle from 'soapbox/features/ui/components/theme_toggle';
import { useOwnAccount, useSoapboxConfig, useSettings } from 'soapbox/hooks';
import { openSidebar } from '../../../actions/sidebar';
@@ -67,6 +68,10 @@ const Navbar = () => {
+ {settings.get('isDeveloper') && (
+
+ )}
+
{account ? (
diff --git a/app/soapbox/features/ui/components/theme_toggle.js b/app/soapbox/features/ui/components/theme_toggle.js
deleted file mode 100644
index c91c67c80..000000000
--- a/app/soapbox/features/ui/components/theme_toggle.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import PropTypes from 'prop-types';
-import React from 'react';
-import ImmutablePureComponent from 'react-immutable-pure-component';
-import { defineMessages } from 'react-intl';
-import Toggle from 'react-toggle';
-
-const messages = defineMessages({
- switchToLight: { id: 'tabs_bar.theme_toggle_light', defaultMessage: 'Switch to light theme' },
- switchToDark: { id: 'tabs_bar.theme_toggle_dark', defaultMessage: 'Switch to dark theme' },
-});
-
-export default class ThemeToggle extends ImmutablePureComponent {
-
- static propTypes = {
- intl: PropTypes.object.isRequired,
- themeMode: PropTypes.string.isRequired,
- onToggle: PropTypes.func.isRequired,
- showLabel: PropTypes.bool,
- };
-
- handleToggleTheme = () => {
- this.props.onToggle(this.props.themeMode === 'light' ? 'dark' : 'light');
- }
-
- render() {
- const { intl, themeMode, showLabel } = this.props;
- const id ='theme-toggle';
- const label = intl.formatMessage(themeMode === 'light' ? messages.switchToDark : messages.switchToLight);
-
- return (
-
-
-
- {showLabel && ()}
-
-
- );
- }
-
-}
diff --git a/app/soapbox/features/ui/components/theme_toggle.tsx b/app/soapbox/features/ui/components/theme_toggle.tsx
new file mode 100644
index 000000000..5f04be848
--- /dev/null
+++ b/app/soapbox/features/ui/components/theme_toggle.tsx
@@ -0,0 +1,51 @@
+import React from 'react';
+import { defineMessages, useIntl } from 'react-intl';
+import { useDispatch } from 'react-redux';
+import Toggle from 'react-toggle';
+import { v4 as uuidv4 } from 'uuid';
+
+import { changeSetting } from 'soapbox/actions/settings';
+import { Icon } from 'soapbox/components/ui';
+import { useSettings } from 'soapbox/hooks';
+
+const messages = defineMessages({
+ switchToLight: { id: 'tabs_bar.theme_toggle_light', defaultMessage: 'Switch to light theme' },
+ switchToDark: { id: 'tabs_bar.theme_toggle_dark', defaultMessage: 'Switch to dark theme' },
+});
+
+interface IThemeToggle {
+ showLabel?: boolean,
+}
+
+function ThemeToggle({ showLabel }: IThemeToggle) {
+ const intl = useIntl();
+ const dispatch = useDispatch();
+ const themeMode = useSettings().get('themeMode');
+
+ const id = uuidv4();
+ const label = intl.formatMessage(themeMode === 'light' ? messages.switchToDark : messages.switchToLight);
+
+ const onToggle = () => {
+ const setting = themeMode === 'light' ? 'dark' : 'light';
+ dispatch(changeSetting(['themeMode'], setting));
+ };
+
+ return (
+
+
+ ,
+ unchecked: ,
+ }}
+ onChange={onToggle}
+ />
+ {showLabel && ()}
+
+
+ );
+}
+
+export default ThemeToggle;
diff --git a/app/soapbox/features/ui/components/theme_toggle_container.js b/app/soapbox/features/ui/components/theme_toggle_container.js
deleted file mode 100644
index b000d1ba5..000000000
--- a/app/soapbox/features/ui/components/theme_toggle_container.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import { injectIntl } from 'react-intl';
-import { connect } from 'react-redux';
-
-import { changeSetting, getSettings } from 'soapbox/actions/settings';
-
-import ThemeToggle from './theme_toggle';
-
-const mapStateToProps = state => {
- return {
- themeMode: getSettings(state).get('themeMode'),
- };
-};
-
-const mapDispatchToProps = (dispatch) => ({
- onToggle(setting) {
- dispatch(changeSetting(['themeMode'], setting));
- },
-});
-
-export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ThemeToggle));
diff --git a/package.json b/package.json
index 4ec9a6372..42bc83259 100644
--- a/package.json
+++ b/package.json
@@ -72,6 +72,7 @@
"@types/lodash": "^4.14.180",
"@types/react-helmet": "^6.1.5",
"@types/react-router-dom": "^5.3.3",
+ "@types/react-toggle": "^4.0.3",
"@types/uuid": "^8.3.4",
"array-includes": "^3.0.3",
"autoprefixer": "^10.4.2",
diff --git a/yarn.lock b/yarn.lock
index 65de52edf..146c677b1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2129,6 +2129,13 @@
"@types/history" "^4.7.11"
"@types/react" "*"
+"@types/react-toggle@^4.0.3":
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/@types/react-toggle/-/react-toggle-4.0.3.tgz#8db98ac8d2c5e8c03c2d3a42027555c1cd2289da"
+ integrity sha512-57QdMWeeQdRjM2/p+udgYerxUbSkmeUIW18kwUttcci6GHkgxoqCsDZfRtsCsAHcvvM5VBQdtDUEgLWo2e87mA==
+ dependencies:
+ "@types/react" "*"
+
"@types/react@*", "@types/react@17":
version "17.0.21"
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.21.tgz#069c43177cd419afaab5ce26bb4e9056549f7ea6"