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 @@ + + + + +dark-mode + + + + 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 @@ + + + + +light-mode + + + + 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 @@ + + + + +notification + + + + 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'; +};