diff --git a/frontend/src/assets/icons/dark-mode.svg b/frontend/src/assets/icons/dark-mode.svg
new file mode 100644
index 0000000000..0efc8521fb
--- /dev/null
+++ b/frontend/src/assets/icons/dark-mode.svg
@@ -0,0 +1,14 @@
+
+
+
diff --git a/frontend/src/assets/icons/light-mode.svg b/frontend/src/assets/icons/light-mode.svg
new file mode 100644
index 0000000000..a00f2c876b
--- /dev/null
+++ b/frontend/src/assets/icons/light-mode.svg
@@ -0,0 +1,22 @@
+
+
+
diff --git a/frontend/src/assets/icons/notification.svg b/frontend/src/assets/icons/notification.svg
new file mode 100644
index 0000000000..971c081a4a
--- /dev/null
+++ b/frontend/src/assets/icons/notification.svg
@@ -0,0 +1,17 @@
+
+
+
diff --git a/frontend/src/components/common/notification.js b/frontend/src/components/common/notification.js
index 727b2b5af6..2e0260875b 100644
--- a/frontend/src/components/common/notification.js
+++ b/frontend/src/components/common/notification.js
@@ -5,6 +5,8 @@ import { gettext } from '../../utils/constants';
import NoticeItem from './notice-item';
import UserNotificationsDialog from '../../user-notifications';
import { Utils } from '../../utils/utils';
+import IconBtn from '../icon-btn';
+
import '../../css/notification.css';
class Notification extends React.Component {
@@ -176,7 +178,7 @@ class Notification extends React.Component {
return (
-
+
{totalUnseenCount}
{this.state.showNotice &&
diff --git a/frontend/src/components/icon-btn/index.css b/frontend/src/components/icon-btn/index.css
index 9015233369..f2dfd25bad 100644
--- a/frontend/src/components/icon-btn/index.css
+++ b/frontend/src/components/icon-btn/index.css
@@ -15,6 +15,11 @@
width: 24px;
}
+.seafile-multicolor-icon-btn-32 {
+ height: 32px;
+ width: 32px;
+}
+
.seafile-multicolor-icon-btn:hover {
cursor: pointer;
}
diff --git a/frontend/src/components/toolbar/common-toolbar.js b/frontend/src/components/toolbar/common-toolbar.js
index eb4b10557e..1cda149566 100644
--- a/frontend/src/components/toolbar/common-toolbar.js
+++ b/frontend/src/components/toolbar/common-toolbar.js
@@ -8,6 +8,8 @@ import Account from '../common/account';
import Logout from '../common/logout';
import { EVENT_BUS_TYPE } from '../common/event-bus-type';
import tagsAPI from '../../tag/api';
+import IconBtn from '../icon-btn';
+import { getColorScheme } from '../../utils/utils';
const propTypes = {
repoID: PropTypes.string,
@@ -35,6 +37,7 @@ class CommonToolbar extends React.Component {
currentRepoInfo: props.currentRepoInfo,
isTagEnabled: false,
tagsData: [],
+ colorMode: getColorScheme(),
};
}
@@ -79,6 +82,13 @@ class CommonToolbar extends React.Component {
}
};
+ onColorModeChange = () => {
+ const colorMode = this.state.colorMode === 'light' ? 'dark' : 'light';
+ this.setState({ colorMode });
+ localStorage.setItem('sf_color_mode', colorMode);
+ document.body.setAttribute('data-bs-theme', colorMode);
+ };
+
renderSearch = () => {
const { repoID, repoName, isLibView, path, isViewFile, isTagEnabled, tagsData } = this.state;
const { searchPlaceholder } = this.props;
@@ -110,9 +120,13 @@ class CommonToolbar extends React.Component {
render() {
const { showSearch = true } = this.props;
+ const { colorMode } = this.state;
+ const symbol = colorMode === 'light' ? 'dark-mode' : 'light-mode';
+ const title = colorMode === 'light' ? gettext('Dark mode') : gettext('Light mode');
return (
{showSearch && this.renderSearch()}
+
{showLogoutIcon && (
)}
diff --git a/frontend/src/css/notification.css b/frontend/src/css/notification.css
index 039fe7e9e2..fb784cc14e 100644
--- a/frontend/src/css/notification.css
+++ b/frontend/src/css/notification.css
@@ -21,11 +21,16 @@
font-weight: normal;
}
-#notifications .sf2-icon-bell {
- font-size: 24px;
+#notifications .sf-icon-bell {
+ font-size: 16px;
line-height: 1;
- color: #999;
+ color: #666;
vertical-align: middle;
+ border-radius: 4px;
+}
+
+#notifications .sf-icon-bell:hover {
+ background-color: var(--bs-hover-bg);
}
#notifications .num {
diff --git a/frontend/src/css/toolbar.css b/frontend/src/css/toolbar.css
index df8d76aee4..8f07a2c0e7 100644
--- a/frontend/src/css/toolbar.css
+++ b/frontend/src/css/toolbar.css
@@ -60,6 +60,16 @@
text-decoration: none;
color: var(--bs-icon-color);
}
+
+.common-toolbar .sf-icon-color-mode {
+ font-size: 16px;
+ color: #666;
+ border-radius: 4px;
+}
+
+.common-toolbar .sf-icon-color-mode:hover {
+ background-color: var(--bs-hover-bg);
+}
/* end common-toolbar */
/* begin path toolbar */
diff --git a/frontend/src/utils/utils.js b/frontend/src/utils/utils.js
index 7062f283ec..a2322cbf17 100644
--- a/frontend/src/utils/utils.js
+++ b/frontend/src/utils/utils.js
@@ -1995,3 +1995,9 @@ export const throttle = (func, delay) => {
export const getType = (value) => {
return Object.prototype.toString.call(value).slice(8, -1);
};
+
+export const getColorScheme = () => {
+ const manualMode = localStorage.getItem('sf_color_mode');
+ if (manualMode) return manualMode;
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
+};