From bc696ca59ffdf1b4b88d088e8343e71ce2b630f8 Mon Sep 17 00:00:00 2001 From: qier222 Date: Sun, 17 Apr 2022 12:46:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=92=8C=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=BC=BA=E8=B0=83=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- postcss.config.js | 45 ++++- scripts/generate.accent.color.css.js | 48 +++++ src/renderer/components/Avatar.tsx | 39 ++++ src/renderer/components/Topbar.tsx | 34 +--- src/renderer/main.tsx | 2 + src/renderer/pages/Settings.tsx | 5 - src/renderer/pages/Settings/Appearance.tsx | 53 +++++ src/renderer/pages/Settings/Settings.tsx | 80 ++++++++ src/renderer/pages/Settings/Sidebar.tsx | 0 src/renderer/pages/Settings/index.ts | 3 + src/renderer/store.ts | 2 + src/renderer/styles/accentColor.scss | 220 +++++++++++++++++++++ src/renderer/utils/theme.ts | 8 + tailwind.config.js | 1 + 14 files changed, 499 insertions(+), 41 deletions(-) create mode 100644 scripts/generate.accent.color.css.js create mode 100644 src/renderer/components/Avatar.tsx delete mode 100644 src/renderer/pages/Settings.tsx create mode 100644 src/renderer/pages/Settings/Appearance.tsx create mode 100644 src/renderer/pages/Settings/Settings.tsx create mode 100644 src/renderer/pages/Settings/Sidebar.tsx create mode 100644 src/renderer/pages/Settings/index.ts create mode 100644 src/renderer/styles/accentColor.scss create mode 100644 src/renderer/utils/theme.ts diff --git a/postcss.config.js b/postcss.config.js index 33ad091..80917b6 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,41 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, +/* eslint-disable @typescript-eslint/no-var-requires */ +const { colord } = require('colord') +const colors = require('tailwindcss/colors') + +const replaceBrandColorWithCssVar = () => { + const blues = Object.entries(colors.blue).map(([key, value]) => { + const c = colord(value).toRgb() + return { + key, + rgb: `${c.r} ${c.g} ${c.b}`, + } + }) + return { + postcssPlugin: 'replaceBrandColorWithCssVar', + Declaration(decl) { + let value = decl.value + blues.forEach(blue => { + value = value.replace( + `rgb(${blue.rgb}`, + `rgb(var(--brand-color-${blue.key})` + ) + }) + // if (decl.value !== value) { + // console.log({ + // before: decl.value, + // after: value, + // }) + // } + decl.value = value + }, + } +} +replaceBrandColorWithCssVar.postcss = true + +module.exports = { + plugins: [ + require('tailwindcss'), + require('autoprefixer'), + replaceBrandColorWithCssVar, + ], } diff --git a/scripts/generate.accent.color.css.js b/scripts/generate.accent.color.css.js new file mode 100644 index 0000000..cfbe278 --- /dev/null +++ b/scripts/generate.accent.color.css.js @@ -0,0 +1,48 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ +const colors = require('tailwindcss/colors') +const { colord } = require('colord') +const prettier = require('prettier') +const fs = require('fs') +const prettierConfig = require('../prettier.config.js') + +const pickedColors = { + blue: colors.blue, + red: colors.red, + orange: colors.orange, + amber: colors.amber, + yellow: colors.yellow, + lime: colors.lime, + green: colors.green, + emerald: colors.emerald, + teal: colors.teal, + cyan: colors.cyan, + sky: colors.sky, + indigo: colors.indigo, + violet: colors.violet, + purple: colors.purple, + fuchsia: colors.fuchsia, + pink: colors.pink, + rose: colors.rose, +} + +const colorsCss = {} +Object.entries(pickedColors).forEach(([name, colors]) => { + let tmp = '' + Object.entries(colors).map(([key, value]) => { + const c = colord(value).toRgb() + tmp = `${tmp} +--brand-color-${key}: ${c.r} ${c.g} ${c.b};` + }) + colorsCss[name] = tmp +}) + +let css = '' +Object.entries(colorsCss).forEach(([name, color]) => { + css = `${css} +${name === 'blue' ? ':root' : `[data-accent-color='${name}']`} {${color} +} +` +}) + +const formatted = prettier.format(css, { ...prettierConfig, parser: 'css' }) +fs.writeFileSync('./src/renderer/styles/accentColor.scss', formatted) diff --git a/src/renderer/components/Avatar.tsx b/src/renderer/components/Avatar.tsx new file mode 100644 index 0000000..24b754b --- /dev/null +++ b/src/renderer/components/Avatar.tsx @@ -0,0 +1,39 @@ +import { resizeImage } from '../utils/common' +import useUser from '../hooks/useUser' +import SvgIcon from './SvgIcon' + +const Avatar = ({ size }: { size?: string }) => { + const navigate = useNavigate() + const { data: user } = useUser() + + const avatarUrl = user?.profile?.avatarUrl + ? resizeImage(user?.profile?.avatarUrl ?? '', 'sm') + : '' + + return ( + <> + {avatarUrl ? ( + navigate('/login')} + className={classNames( + 'app-region-no-drag rounded-full bg-gray-100 dark:bg-gray-700', + size || 'h-9 w-9' + )} + /> + ) : ( +
navigate('/login')}> + +
+ )} + + ) +} + +export default Avatar diff --git a/src/renderer/components/Topbar.tsx b/src/renderer/components/Topbar.tsx index 8f5718e..fe9e023 100644 --- a/src/renderer/components/Topbar.tsx +++ b/src/renderer/components/Topbar.tsx @@ -1,7 +1,6 @@ import SvgIcon from '@/renderer/components/SvgIcon' import useScroll from '@/renderer/hooks/useScroll' -import useUser from '@/renderer/hooks/useUser' -import { resizeImage } from '@/renderer/utils/common' +import Avatar from './Avatar' const NavigationButtons = () => { const navigate = useNavigate() @@ -67,9 +66,10 @@ const SearchBox = () => { } const Settings = () => { + const navigate = useNavigate() return (
toast('施工中...')} + onClick={() => navigate('/settings')} className='app-region-no-drag btn-hover-animation rounded-lg p-2.5 text-gray-500 transition duration-300 after:rounded-full after:bg-black/[.06] hover:text-gray-900 dark:text-gray-300 dark:after:bg-white/10 dark:hover:text-gray-200' > @@ -77,34 +77,6 @@ const Settings = () => { ) } -const Avatar = () => { - const navigate = useNavigate() - const { data: user } = useUser() - - const avatarUrl = user?.profile?.avatarUrl - ? resizeImage(user?.profile?.avatarUrl ?? '', 'sm') - : '' - - return ( - <> - {avatarUrl ? ( - navigate('/login')} - className='app-region-no-drag h-9 w-9 rounded-full bg-gray-100 dark:bg-gray-700' - /> - ) : ( -
navigate('/login')}> - -
- )} - - ) -} - const Topbar = () => { /** * Show topbar background when scroll down diff --git a/src/renderer/main.tsx b/src/renderer/main.tsx index 1d519e1..aa596aa 100644 --- a/src/renderer/main.tsx +++ b/src/renderer/main.tsx @@ -1,4 +1,5 @@ import './utils/initLog' +import './utils/theme' import { StrictMode } from 'react' import * as ReactDOMClient from 'react-dom/client' import { BrowserRouter } from 'react-router-dom' @@ -6,6 +7,7 @@ import * as Sentry from '@sentry/react' import { BrowserTracing } from '@sentry/tracing' import 'virtual:svg-icons-register' import './styles/global.scss' +import './styles/accentColor.scss' import App from './App' import pkg from '../../package.json' import ReactGA from 'react-ga4' diff --git a/src/renderer/pages/Settings.tsx b/src/renderer/pages/Settings.tsx deleted file mode 100644 index ce9bc33..0000000 --- a/src/renderer/pages/Settings.tsx +++ /dev/null @@ -1,5 +0,0 @@ -const Settings = () => { - return
-} - -export default Settings diff --git a/src/renderer/pages/Settings/Appearance.tsx b/src/renderer/pages/Settings/Appearance.tsx new file mode 100644 index 0000000..b11a315 --- /dev/null +++ b/src/renderer/pages/Settings/Appearance.tsx @@ -0,0 +1,53 @@ +import { state } from '@/renderer/store' +import { changeAccentColor } from '@/renderer/utils/theme' + +const AccentColor = () => { + const colors = { + red: 'bg-red-500', + orange: 'bg-orange-500', + amber: 'bg-amber-500', + yellow: 'bg-yellow-500', + lime: 'bg-lime-500', + green: 'bg-green-500', + emerald: 'bg-emerald-500', + teal: 'bg-teal-500', + cyan: 'bg-cyan-500', + sky: 'bg-sky-500', + blue: 'bg-blue-500', + indigo: 'bg-indigo-500', + violet: 'bg-violet-500', + purple: 'bg-purple-500', + fuchsia: 'bg-fuchsia-500', + pink: 'bg-pink-500', + rose: 'bg-rose-500', + } + + const changeColor = (color: string) => { + state.settings.accentColor = color + changeAccentColor(color) + } + return ( +
+ {Object.entries(colors).map(([color, bg]) => ( +
changeColor(color)} + >
+ ))} +
+ ) +} + +const Appearance = () => { + return ( +
+
主题
+
+ + +
+ ) +} + +export default Appearance diff --git a/src/renderer/pages/Settings/Settings.tsx b/src/renderer/pages/Settings/Settings.tsx new file mode 100644 index 0000000..ebb9dca --- /dev/null +++ b/src/renderer/pages/Settings/Settings.tsx @@ -0,0 +1,80 @@ +import Avatar from '@/renderer/components/Avatar' +import SvgIcon from '@/renderer/components/SvgIcon' +import useUser from '@/renderer/hooks/useUser' +import Appearance from './Appearance' + +const UserCard = () => { + const { data: user } = useUser() + + return ( +
+
+ +
+
+ {user?.profile?.nickname ?? '未登录'} +
+ {(user?.profile?.signature || user?.profile?.vipType) && ( +
+ {user?.profile?.vipType ? ( + + ) : null} + {user?.profile?.signature} +
+ )} +
+
+ +
+ +
+
+ ) +} + +const Sidebar = () => { + const categories = ['外观', '播放', '歌词', '其他', '试验性功能'] + const active = '外观' + return ( +
+ {categories.map(category => ( +
+ {category} +
+ ))} +
+ ) +} + +const Settings = () => { + return ( +
+ + +
+ +
+ +
+
+
+ ) +} + +export default Settings diff --git a/src/renderer/pages/Settings/Sidebar.tsx b/src/renderer/pages/Settings/Sidebar.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/renderer/pages/Settings/index.ts b/src/renderer/pages/Settings/index.ts new file mode 100644 index 0000000..d04fd35 --- /dev/null +++ b/src/renderer/pages/Settings/index.ts @@ -0,0 +1,3 @@ +import Settings from './Settings' + +export default Settings diff --git a/src/renderer/store.ts b/src/renderer/store.ts index 6e3c352..e2aa757 100644 --- a/src/renderer/store.ts +++ b/src/renderer/store.ts @@ -9,6 +9,7 @@ interface Store { } settings: { showSidebar: boolean + accentColor: string } } @@ -19,6 +20,7 @@ const initialState: Store = { }, settings: { showSidebar: true, + accentColor: 'blue', }, } diff --git a/src/renderer/styles/accentColor.scss b/src/renderer/styles/accentColor.scss new file mode 100644 index 0000000..de57185 --- /dev/null +++ b/src/renderer/styles/accentColor.scss @@ -0,0 +1,220 @@ +:root { + --brand-color-50: 239 246 255; + --brand-color-100: 219 234 254; + --brand-color-200: 191 219 254; + --brand-color-300: 147 197 253; + --brand-color-400: 96 165 250; + --brand-color-500: 59 130 246; + --brand-color-600: 37 99 235; + --brand-color-700: 29 78 216; + --brand-color-800: 30 64 175; + --brand-color-900: 30 58 138; +} + +[data-accent-color='red'] { + --brand-color-50: 254 242 242; + --brand-color-100: 254 226 226; + --brand-color-200: 254 202 202; + --brand-color-300: 252 165 165; + --brand-color-400: 248 113 113; + --brand-color-500: 239 68 68; + --brand-color-600: 220 38 38; + --brand-color-700: 185 28 28; + --brand-color-800: 153 27 27; + --brand-color-900: 127 29 29; +} + +[data-accent-color='orange'] { + --brand-color-50: 255 247 237; + --brand-color-100: 255 237 213; + --brand-color-200: 254 215 170; + --brand-color-300: 253 186 116; + --brand-color-400: 251 146 60; + --brand-color-500: 249 115 22; + --brand-color-600: 234 88 12; + --brand-color-700: 194 65 12; + --brand-color-800: 154 52 18; + --brand-color-900: 124 45 18; +} + +[data-accent-color='amber'] { + --brand-color-50: 255 251 235; + --brand-color-100: 254 243 199; + --brand-color-200: 253 230 138; + --brand-color-300: 252 211 77; + --brand-color-400: 251 191 36; + --brand-color-500: 245 158 11; + --brand-color-600: 217 119 6; + --brand-color-700: 180 83 9; + --brand-color-800: 146 64 14; + --brand-color-900: 120 53 15; +} + +[data-accent-color='yellow'] { + --brand-color-50: 254 252 232; + --brand-color-100: 254 249 195; + --brand-color-200: 254 240 138; + --brand-color-300: 253 224 71; + --brand-color-400: 250 204 21; + --brand-color-500: 234 179 8; + --brand-color-600: 202 138 4; + --brand-color-700: 161 98 7; + --brand-color-800: 133 77 14; + --brand-color-900: 113 63 18; +} + +[data-accent-color='lime'] { + --brand-color-50: 247 254 231; + --brand-color-100: 236 252 203; + --brand-color-200: 217 249 157; + --brand-color-300: 190 242 100; + --brand-color-400: 163 230 53; + --brand-color-500: 132 204 22; + --brand-color-600: 101 163 13; + --brand-color-700: 77 124 15; + --brand-color-800: 63 98 18; + --brand-color-900: 54 83 20; +} + +[data-accent-color='green'] { + --brand-color-50: 240 253 244; + --brand-color-100: 220 252 231; + --brand-color-200: 187 247 208; + --brand-color-300: 134 239 172; + --brand-color-400: 74 222 128; + --brand-color-500: 34 197 94; + --brand-color-600: 22 163 74; + --brand-color-700: 21 128 61; + --brand-color-800: 22 101 52; + --brand-color-900: 20 83 45; +} + +[data-accent-color='emerald'] { + --brand-color-50: 236 253 245; + --brand-color-100: 209 250 229; + --brand-color-200: 167 243 208; + --brand-color-300: 110 231 183; + --brand-color-400: 52 211 153; + --brand-color-500: 16 185 129; + --brand-color-600: 5 150 105; + --brand-color-700: 4 120 87; + --brand-color-800: 6 95 70; + --brand-color-900: 6 78 59; +} + +[data-accent-color='teal'] { + --brand-color-50: 240 253 250; + --brand-color-100: 204 251 241; + --brand-color-200: 153 246 228; + --brand-color-300: 94 234 212; + --brand-color-400: 45 212 191; + --brand-color-500: 20 184 166; + --brand-color-600: 13 148 136; + --brand-color-700: 15 118 110; + --brand-color-800: 17 94 89; + --brand-color-900: 19 78 74; +} + +[data-accent-color='cyan'] { + --brand-color-50: 236 254 255; + --brand-color-100: 207 250 254; + --brand-color-200: 165 243 252; + --brand-color-300: 103 232 249; + --brand-color-400: 34 211 238; + --brand-color-500: 6 182 212; + --brand-color-600: 8 145 178; + --brand-color-700: 14 116 144; + --brand-color-800: 21 94 117; + --brand-color-900: 22 78 99; +} + +[data-accent-color='sky'] { + --brand-color-50: 240 249 255; + --brand-color-100: 224 242 254; + --brand-color-200: 186 230 253; + --brand-color-300: 125 211 252; + --brand-color-400: 56 189 248; + --brand-color-500: 14 165 233; + --brand-color-600: 2 132 199; + --brand-color-700: 3 105 161; + --brand-color-800: 7 89 133; + --brand-color-900: 12 74 110; +} + +[data-accent-color='indigo'] { + --brand-color-50: 238 242 255; + --brand-color-100: 224 231 255; + --brand-color-200: 199 210 254; + --brand-color-300: 165 180 252; + --brand-color-400: 129 140 248; + --brand-color-500: 99 102 241; + --brand-color-600: 79 70 229; + --brand-color-700: 67 56 202; + --brand-color-800: 55 48 163; + --brand-color-900: 49 46 129; +} + +[data-accent-color='violet'] { + --brand-color-50: 245 243 255; + --brand-color-100: 237 233 254; + --brand-color-200: 221 214 254; + --brand-color-300: 196 181 253; + --brand-color-400: 167 139 250; + --brand-color-500: 139 92 246; + --brand-color-600: 124 58 237; + --brand-color-700: 109 40 217; + --brand-color-800: 91 33 182; + --brand-color-900: 76 29 149; +} + +[data-accent-color='purple'] { + --brand-color-50: 250 245 255; + --brand-color-100: 243 232 255; + --brand-color-200: 233 213 255; + --brand-color-300: 216 180 254; + --brand-color-400: 192 132 252; + --brand-color-500: 168 85 247; + --brand-color-600: 147 51 234; + --brand-color-700: 126 34 206; + --brand-color-800: 107 33 168; + --brand-color-900: 88 28 135; +} + +[data-accent-color='fuchsia'] { + --brand-color-50: 253 244 255; + --brand-color-100: 250 232 255; + --brand-color-200: 245 208 254; + --brand-color-300: 240 171 252; + --brand-color-400: 232 121 249; + --brand-color-500: 217 70 239; + --brand-color-600: 192 38 211; + --brand-color-700: 162 28 175; + --brand-color-800: 134 25 143; + --brand-color-900: 112 26 117; +} + +[data-accent-color='pink'] { + --brand-color-50: 253 242 248; + --brand-color-100: 252 231 243; + --brand-color-200: 251 207 232; + --brand-color-300: 249 168 212; + --brand-color-400: 244 114 182; + --brand-color-500: 236 72 153; + --brand-color-600: 219 39 119; + --brand-color-700: 190 24 93; + --brand-color-800: 157 23 77; + --brand-color-900: 131 24 67; +} + +[data-accent-color='rose'] { + --brand-color-50: 255 241 242; + --brand-color-100: 255 228 230; + --brand-color-200: 254 205 211; + --brand-color-300: 253 164 175; + --brand-color-400: 251 113 133; + --brand-color-500: 244 63 94; + --brand-color-600: 225 29 72; + --brand-color-700: 190 18 60; + --brand-color-800: 159 18 57; + --brand-color-900: 136 19 55; +} diff --git a/src/renderer/utils/theme.ts b/src/renderer/utils/theme.ts new file mode 100644 index 0000000..e30e175 --- /dev/null +++ b/src/renderer/utils/theme.ts @@ -0,0 +1,8 @@ +export const changeAccentColor = (color: string) => { + document.body.setAttribute('data-accent-color', color) +} + +const stateString = localStorage.getItem('state') +const state = stateString ? JSON.parse(stateString) : {} + +changeAccentColor(state.settings.accentColor || 'blue') diff --git a/tailwind.config.js b/tailwind.config.js index 9cb771c..2a8057b 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -10,6 +10,7 @@ module.exports = { theme: { extend: { colors: { + ...colors, brand: colors.blue, gray: colors.neutral, },