diff --git a/.gitignore b/.gitignore index b92f0ab..00a8080 100644 --- a/.gitignore +++ b/.gitignore @@ -58,4 +58,6 @@ cloudfunctions/**/*.log .Spotlight-V100 .Trashes ehthumbs.db -[Tt]humbs.db \ No newline at end of file +[Tt]humbs.db + +CLAUDE.md \ No newline at end of file diff --git a/miniprogram/app.json b/miniprogram/app.json index 15f2879..a4a0015 100644 --- a/miniprogram/app.json +++ b/miniprogram/app.json @@ -10,6 +10,8 @@ "pages/main/moment/index", "pages/main/journal-list/index" ], + "darkmode": true, + "themeLocation": "theme.json", "window": { "navigationStyle": "custom", "navigationBarTextStyle": "black", @@ -17,40 +19,40 @@ }, "lazyCodeLoading": "requiredComponents", "tabBar": { - "color": "#8a8a8a", - "selectedColor": "#07C160", - "backgroundColor": "#ffffff", - "borderStyle": "white", + "color": "@tabBarColor", + "selectedColor": "@tabBarSelectedColor", + "backgroundColor": "@tabBarBackgroundColor", + "borderStyle": "@tabBarBorderStyle", "list": [ { "text": "归档", "pagePath": "pages/main/journal/index", - "iconPath": "assets/icon/journal.png", - "selectedIconPath": "assets/icon/journal_active.png" + "iconPath": "@tabBarIconJournal", + "selectedIconPath": "@tabBarIconJournalActive" }, { "text": "专拍", "pagePath": "pages/main/portfolio/index", - "iconPath": "assets/icon/portfolio.png", - "selectedIconPath": "assets/icon/portfolio_active.png" + "iconPath": "@tabBarIconPortfolio", + "selectedIconPath": "@tabBarIconPortfolioActive" }, { "text": "瞬间", "pagePath": "pages/main/moment/index", - "iconPath": "assets/icon/moment.png", - "selectedIconPath": "assets/icon/moment_active.png" + "iconPath": "@tabBarIconMoment", + "selectedIconPath": "@tabBarIconMomentActive" }, { "text": "旅行", "pagePath": "pages/main/travel/index", - "iconPath": "assets/icon/travel.png", - "selectedIconPath": "assets/icon/travel_active.png" + "iconPath": "@tabBarIconTravel", + "selectedIconPath": "@tabBarIconTravelActive" }, { "text": "关于", "pagePath": "pages/main/about/index", - "iconPath": "assets/icon/info.png", - "selectedIconPath": "assets/icon/info_active.png" + "iconPath": "@tabBarIconInfo", + "selectedIconPath": "@tabBarIconInfoActive" } ] }, diff --git a/miniprogram/app.wxss b/miniprogram/app.wxss index 099cf50..a4856d8 100644 --- a/miniprogram/app.wxss +++ b/miniprogram/app.wxss @@ -1,2 +1,3 @@ /**app.wxss**/ +@import "./theme.wxss"; @import "./tdesign.wxss"; \ No newline at end of file diff --git a/miniprogram/assets/icon/dark/info.png b/miniprogram/assets/icon/dark/info.png new file mode 100644 index 0000000..7582c17 Binary files /dev/null and b/miniprogram/assets/icon/dark/info.png differ diff --git a/miniprogram/assets/icon/dark/info_active.png b/miniprogram/assets/icon/dark/info_active.png new file mode 100644 index 0000000..04e20d6 Binary files /dev/null and b/miniprogram/assets/icon/dark/info_active.png differ diff --git a/miniprogram/assets/icon/dark/journal.png b/miniprogram/assets/icon/dark/journal.png new file mode 100644 index 0000000..64b8c7d Binary files /dev/null and b/miniprogram/assets/icon/dark/journal.png differ diff --git a/miniprogram/assets/icon/dark/journal_active.png b/miniprogram/assets/icon/dark/journal_active.png new file mode 100644 index 0000000..c0211c7 Binary files /dev/null and b/miniprogram/assets/icon/dark/journal_active.png differ diff --git a/miniprogram/assets/icon/dark/moment.png b/miniprogram/assets/icon/dark/moment.png new file mode 100644 index 0000000..913b155 Binary files /dev/null and b/miniprogram/assets/icon/dark/moment.png differ diff --git a/miniprogram/assets/icon/dark/moment_active.png b/miniprogram/assets/icon/dark/moment_active.png new file mode 100644 index 0000000..220c3ee Binary files /dev/null and b/miniprogram/assets/icon/dark/moment_active.png differ diff --git a/miniprogram/assets/icon/dark/portfolio.png b/miniprogram/assets/icon/dark/portfolio.png new file mode 100644 index 0000000..81c6572 Binary files /dev/null and b/miniprogram/assets/icon/dark/portfolio.png differ diff --git a/miniprogram/assets/icon/dark/portfolio_active.png b/miniprogram/assets/icon/dark/portfolio_active.png new file mode 100644 index 0000000..6dd6e9f Binary files /dev/null and b/miniprogram/assets/icon/dark/portfolio_active.png differ diff --git a/miniprogram/assets/icon/dark/travel.png b/miniprogram/assets/icon/dark/travel.png new file mode 100644 index 0000000..64a19b2 Binary files /dev/null and b/miniprogram/assets/icon/dark/travel.png differ diff --git a/miniprogram/assets/icon/dark/travel_active.png b/miniprogram/assets/icon/dark/travel_active.png new file mode 100644 index 0000000..72ba0d6 Binary files /dev/null and b/miniprogram/assets/icon/dark/travel_active.png differ diff --git a/miniprogram/assets/icon/info.png b/miniprogram/assets/icon/light/info.png similarity index 100% rename from miniprogram/assets/icon/info.png rename to miniprogram/assets/icon/light/info.png diff --git a/miniprogram/assets/icon/info_active.png b/miniprogram/assets/icon/light/info_active.png similarity index 100% rename from miniprogram/assets/icon/info_active.png rename to miniprogram/assets/icon/light/info_active.png diff --git a/miniprogram/assets/icon/journal.png b/miniprogram/assets/icon/light/journal.png similarity index 100% rename from miniprogram/assets/icon/journal.png rename to miniprogram/assets/icon/light/journal.png diff --git a/miniprogram/assets/icon/journal_active.png b/miniprogram/assets/icon/light/journal_active.png similarity index 100% rename from miniprogram/assets/icon/journal_active.png rename to miniprogram/assets/icon/light/journal_active.png diff --git a/miniprogram/assets/icon/moment.png b/miniprogram/assets/icon/light/moment.png similarity index 100% rename from miniprogram/assets/icon/moment.png rename to miniprogram/assets/icon/light/moment.png diff --git a/miniprogram/assets/icon/moment_active.png b/miniprogram/assets/icon/light/moment_active.png similarity index 100% rename from miniprogram/assets/icon/moment_active.png rename to miniprogram/assets/icon/light/moment_active.png diff --git a/miniprogram/assets/icon/portfolio.png b/miniprogram/assets/icon/light/portfolio.png similarity index 100% rename from miniprogram/assets/icon/portfolio.png rename to miniprogram/assets/icon/light/portfolio.png diff --git a/miniprogram/assets/icon/portfolio_active.png b/miniprogram/assets/icon/light/portfolio_active.png similarity index 100% rename from miniprogram/assets/icon/portfolio_active.png rename to miniprogram/assets/icon/light/portfolio_active.png diff --git a/miniprogram/assets/icon/travel.png b/miniprogram/assets/icon/light/travel.png similarity index 100% rename from miniprogram/assets/icon/travel.png rename to miniprogram/assets/icon/light/travel.png diff --git a/miniprogram/assets/icon/travel_active.png b/miniprogram/assets/icon/light/travel_active.png similarity index 100% rename from miniprogram/assets/icon/travel_active.png rename to miniprogram/assets/icon/light/travel_active.png diff --git a/miniprogram/components/background/snowflake/index.less b/miniprogram/components/background/snowflake/index.less index 4e3e09d..dcb05c8 100644 --- a/miniprogram/components/background/snowflake/index.less +++ b/miniprogram/components/background/snowflake/index.less @@ -28,12 +28,13 @@ page { display: block; position: absolute; animation: fall linear infinite; - + &::before, &::after { content: ''; position: absolute; - background: rgba(255, 122, 155, .8); + background: var(--theme-brand-gao); + opacity: .8; } &::before { diff --git a/miniprogram/components/background/snowflake/index.ts b/miniprogram/components/background/snowflake/index.ts index 9f1d0bf..0c47e33 100644 --- a/miniprogram/components/background/snowflake/index.ts +++ b/miniprogram/components/background/snowflake/index.ts @@ -36,8 +36,6 @@ Component({ docHeight: systemInfo.windowHeight, timer: setInterval(() => { this.createSnowflake(); - console.log(this.data.snowflakes); - if (40 < this.data.snowflakes.length) { if (this.data.timer) { clearInterval(this.data.timer); diff --git a/miniprogram/config/index.ts b/miniprogram/config/index.ts index 1c64fb6..b1ff8d6 100644 --- a/miniprogram/config/index.ts +++ b/miniprogram/config/index.ts @@ -1,6 +1,6 @@ const envArgs = { develop: { - url: "http://localhost:8091" + url: "https://api.imyeyu.com" }, trial: { url: "https://api.imyeyu.com" diff --git a/miniprogram/pages/index/index.less b/miniprogram/pages/index/index.less index 7f7fdc2..23e0809 100644 --- a/miniprogram/pages/index/index.less +++ b/miniprogram/pages/index/index.less @@ -29,28 +29,28 @@ page { height: 128px; display: block; border-radius: 4px; - box-shadow: 2px 2px 8px rgba(0, 0, 0, .2); + box-shadow: 2px 2px 8px var(--theme-shadow-medium); margin-bottom: 1rem; } - + .name { margin: 0 .5rem; display: inline-block; - + &.gao { - color: #FF7A9B; + color: var(--theme-brand-gao); } - + &.yeyu { - color: #7A9BFF; + color: var(--theme-brand-yeyu); } } } .password { width: 20rem; - border-top: 1px solid rgba(0, 0, 0, .1); - border-bottom: 1px solid rgba(0, 0, 0, .1); + border-top: 1px solid var(--theme-border-light); + border-bottom: 1px solid var(--theme-border-light); } .enter { diff --git a/miniprogram/pages/main/about/index.less b/miniprogram/pages/main/about/index.less index 543101b..e28985e 100644 --- a/miniprogram/pages/main/about/index.less +++ b/miniprogram/pages/main/about/index.less @@ -29,35 +29,35 @@ page { height: 128px; display: block; border-radius: 4px; - box-shadow: 2px 2px 8px rgba(0, 0, 0, .2); + box-shadow: 2px 2px 8px var(--theme-shadow-medium); margin-bottom: 1rem; } - + .name { margin: 0 .5rem; display: inline-block; - + &.gao { - color: #FF7A9B; + color: var(--theme-brand-gao); } - + &.yeyu { - color: #7A9BFF; + color: var(--theme-brand-yeyu); } } } .text { - color: #777; + color: var(--theme-text-secondary); font-size: 12px; text-align: center; .love { color: transparent; font-size: 1rem; - animation: loveGradient 1500ms linear infinite; + animation: loveGradient 1000ms linear infinite; text-align: center; - background: linear-gradient(90deg, #FFB5C7, #FF7A9B, #FF3A6B, #FF7A9B, #FFB5C7); + background: linear-gradient(90deg, var(--theme-brand-gao-light), var(--theme-brand-gao), var(--theme-brand-gao-dark), var(--theme-brand-gao), var(--theme-brand-gao-light)); font-weight: bold; font-family: "Arial", sans-serif; margin-bottom: 1rem; @@ -66,7 +66,7 @@ page { -webkit-background-clip: text; -webkit-text-fill-color: transparent; } - + @keyframes loveGradient { 0% { background-position: 0% 50%; @@ -83,19 +83,19 @@ page { flex-direction: column; .exit { - color: #E64340; + color: var(--theme-error); width: 10rem; margin-bottom: 1rem; } - + .item { font-size: 14px; text-align: center; - + .label { - color: #777; + color: var(--theme-text-secondary); } - + &.copyright { display: flex; font-size: 12px; diff --git a/miniprogram/pages/main/journal-creater/index.less b/miniprogram/pages/main/journal-creater/index.less index a4c399e..fbf53a8 100644 --- a/miniprogram/pages/main/journal-creater/index.less +++ b/miniprogram/pages/main/journal-creater/index.less @@ -10,7 +10,7 @@ flex-direction: column; .label { - color: #777; + color: var(--theme-text-secondary); } .section { @@ -47,8 +47,8 @@ height: 200rpx; position: relative; overflow: hidden; - background: #FFF; - box-shadow: 1px 1px 6px rgba(0, 0, 0, .1); + background: var(--theme-bg-card); + box-shadow: 1px 1px 6px var(--theme-shadow-light); border-radius: 2rpx; .thumbnail { diff --git a/miniprogram/pages/main/journal/index.less b/miniprogram/pages/main/journal/index.less index b670f84..7c6fb21 100644 --- a/miniprogram/pages/main/journal/index.less +++ b/miniprogram/pages/main/journal/index.less @@ -1,55 +1,20 @@ .custom-navbar { - .more { - width: 24px; - height: 18px; - position: relative; - - &::before { - content: ""; - top: calc(50% - 1px); - width: 100%; - height: 2px; - position: absolute; - background: rgba(0, 0, 0, .8); - } - - &::after { - content: ""; - top: 0; - width: 100%; - height: calc(100% - 4px); - position: absolute; - border-top: 2px solid rgba(0, 0, 0, .8); - border-bottom: 2px solid rgba(0, 0, 0, .8); - } - } - .more-menu { top: 0; left: 0; width: 100%; height: 100%; position: fixed; - background: rgba(0, 0, 0, .1); + background: var(--theme-bg-overlay); .content { - margin: 200rpx 0 0 12rpx; + margin: 190rpx 0 0 12rpx; z-index: 1; position: fixed; - background: rgba(255, 255, 255, .95); + background: var(--theme-bg-menu); + box-shadow: 0 0 12px var(--theme-shadow-medium); border-radius: 2px; - box-shadow: 0 0 12px rgba(0, 0, 0, .2); - - &::before { - content: ""; - margin: -10rpx 0 0 24rpx; - border-top: 24rpx solid rgba(255, 255, 255, .95); - border-left: 24rpx solid transparent; - z-index: 1; - position: fixed; - transform: rotate(-45deg); - } } } } @@ -86,8 +51,8 @@ padding: 8px 16px; margin: .5rem 1rem 1rem 1rem; position: relative; - background: #FFF8E1; - box-shadow: 0 2px 10px rgba(0, 0, 0, .2); + background: var(--theme-bg-journal); + box-shadow: 0 2px 10px var(--theme-shadow-medium); border-radius: 2px; // 纸张纹理效果 @@ -100,17 +65,17 @@ bottom: 0; background: linear-gradient(90deg, - rgba(255, 255, 255, 0) 0%, - rgba(255, 255, 255, 0.3) 50%, - rgba(255, 255, 255, 0) 100%), - linear-gradient(rgba(0, 0, 0, 0.03) 1px, transparent 1px), - linear-gradient(90deg, rgba(0, 0, 0, 0.03) 1px, transparent 1px); + var(--theme-texture-light) 0%, + var(--theme-texture-bright) 50%, + var(--theme-texture-light) 100%), + linear-gradient(var(--theme-texture-line) 1px, transparent 1px), + linear-gradient(90deg, var(--theme-texture-line) 1px, transparent 1px); pointer-events: none; background-size: 100% 100%, 10px 10px, 10px 10px; } .location { - color: #777; + color: var(--theme-text-secondary); text-align: right; } } @@ -122,7 +87,7 @@ .item { overflow: hidden; - background: #FFF; + background: var(--theme-bg-card); break-inside: avoid; margin-bottom: .25rem; @@ -144,7 +109,7 @@ position: absolute; transform: translate(-50%, -50%); border-top: 16px solid transparent; - border-left: 24px solid rgba(255, 255, 255, .9); + border-left: 24px solid var(--theme-video-play); border-bottom: 16px solid transparent; pointer-events: none; } @@ -154,7 +119,7 @@ } .start { - color: #777; + color: var(--theme-text-secondary); padding: 1rem 0; font-size: 12px; text-align: center; diff --git a/miniprogram/pages/main/journal/index.ts b/miniprogram/pages/main/journal/index.ts index 36e6313..3142f1a 100644 --- a/miniprogram/pages/main/journal/index.ts +++ b/miniprogram/pages/main/journal/index.ts @@ -3,7 +3,6 @@ import Time from "../../../utils/Time"; import config from "../../../config/index" import Events from "../../../utils/Events"; -import Toolkit from "../../../utils/Toolkit"; export type Journal = { date: string; diff --git a/miniprogram/pages/main/journal/index.wxml b/miniprogram/pages/main/journal/index.wxml index 1daa159..b885197 100644 --- a/miniprogram/pages/main/journal/index.wxml +++ b/miniprogram/pages/main/journal/index.wxml @@ -1,6 +1,7 @@ + diff --git a/miniprogram/pages/main/moment/index.less b/miniprogram/pages/main/moment/index.less index ff876b9..c6681c5 100644 --- a/miniprogram/pages/main/moment/index.less +++ b/miniprogram/pages/main/moment/index.less @@ -36,7 +36,7 @@ } .text { - color: #777; + color: var(--theme-text-secondary); display: flex; font-size: .8rem; justify-content: space-between; @@ -55,14 +55,14 @@ width: 100%; display: block; overflow: hidden; - background: #FFF; + background: var(--theme-bg-card); break-inside: avoid; margin-bottom: .25rem; &.video { height: auto; position: relative; - + &::after { content: ""; top: 50%; @@ -72,7 +72,7 @@ position: absolute; transform: translate(-50%, -50%); border-top: 16px solid transparent; - border-left: 24px solid rgba(255, 255, 255, .9); + border-left: 24px solid var(--theme-video-play); border-bottom: 16px solid transparent; pointer-events: none; } @@ -95,7 +95,7 @@ height: 16px; z-index: 1; position: absolute; - background: #FFF; + background: var(--theme-bg-card); border-radius: 50%; } } @@ -131,7 +131,7 @@ } &.confirm { - color: #07C160; + color: var(--theme-success); } } } @@ -144,7 +144,7 @@ margin-top: 1.5rem; .label { - color: #777; + color: var(--theme-text-secondary); } &.type { diff --git a/miniprogram/pages/main/portfolio/index.less b/miniprogram/pages/main/portfolio/index.less index 165c649..39d5cd6 100644 --- a/miniprogram/pages/main/portfolio/index.less +++ b/miniprogram/pages/main/portfolio/index.less @@ -11,7 +11,7 @@ .item { overflow: hidden; - background: #FFF; + background: var(--theme-bg-card); break-inside: avoid; margin-bottom: .25rem; diff --git a/miniprogram/pages/main/travel/index.less b/miniprogram/pages/main/travel/index.less index d22de1c..a3a74d9 100644 --- a/miniprogram/pages/main/travel/index.less +++ b/miniprogram/pages/main/travel/index.less @@ -15,7 +15,7 @@ width: 100%; display: block; overflow: hidden; - background: #FFF; + background: var(--theme-bg-card); break-inside: avoid; margin-bottom: .25rem; } diff --git a/miniprogram/pages/main/travel/luggage/index.less b/miniprogram/pages/main/travel/luggage/index.less index 05dfea5..1ad6ed1 100644 --- a/miniprogram/pages/main/travel/luggage/index.less +++ b/miniprogram/pages/main/travel/luggage/index.less @@ -1,7 +1,7 @@ .luggage { .tips { - color: #777; + color: var(--theme-text-secondary); margin: .5rem 0; font-size: 12px; text-align: center; @@ -19,7 +19,7 @@ flex: 1; margin: 0; - border: 3rpx solid #CCC; + border: 3rpx solid var(--theme-text-disabled); position: relative; overflow: hidden; box-sizing: border-box; @@ -68,13 +68,13 @@ .add-container { left: 0; right: 0; - color: #333; + color: var(--theme-text-primary); bottom: 0; display: flex; padding: 20rpx; position: fixed; - border-top: 1px solid rgba(0, 0, 0, .1); - background: rgba(240, 240, 240, .8); + border-top: 1px solid var(--theme-border-light); + background: var(--theme-bg-secondary); box-sizing: border-box; align-items: center; padding-bottom: calc(20rpx + env(safe-area-inset-bottom)); diff --git a/miniprogram/theme.json b/miniprogram/theme.json new file mode 100644 index 0000000..3dfaf9b --- /dev/null +++ b/miniprogram/theme.json @@ -0,0 +1,46 @@ +{ + "light": { + "navigationBarBackgroundColor": "#FFFFFF", + "navigationBarTextStyle": "black", + "backgroundColor": "#FFFFFF", + "backgroundTextStyle": "dark", + "backgroundColorTop": "#FFFFFF", + "backgroundColorBottom": "#FFFFFF", + "tabBarColor": "#8a8a8a", + "tabBarSelectedColor": "#07C160", + "tabBarBackgroundColor": "#ffffff", + "tabBarBorderStyle": "white", + "tabBarIconJournal": "assets/icon/light/journal.png", + "tabBarIconJournalActive": "assets/icon/light/journal_active.png", + "tabBarIconPortfolio": "assets/icon/light/portfolio.png", + "tabBarIconPortfolioActive": "assets/icon/light/portfolio_active.png", + "tabBarIconMoment": "assets/icon/light/moment.png", + "tabBarIconMomentActive": "assets/icon/light/moment_active.png", + "tabBarIconTravel": "assets/icon/light/travel.png", + "tabBarIconTravelActive": "assets/icon/light/travel_active.png", + "tabBarIconInfo": "assets/icon/light/info.png", + "tabBarIconInfoActive": "assets/icon/light/info_active.png" + }, + "dark": { + "navigationBarBackgroundColor": "#1A1A1A", + "navigationBarTextStyle": "white", + "backgroundColor": "#1A1A1A", + "backgroundTextStyle": "light", + "backgroundColorTop": "#1A1A1A", + "backgroundColorBottom": "#1A1A1A", + "tabBarColor": "#aaaaaa", + "tabBarSelectedColor": "#07C160", + "tabBarBackgroundColor": "#1A1A1A", + "tabBarBorderStyle": "black", + "tabBarIconJournal": "assets/icon/dark/journal.png", + "tabBarIconJournalActive": "assets/icon/dark/journal_active.png", + "tabBarIconPortfolio": "assets/icon/dark/portfolio.png", + "tabBarIconPortfolioActive": "assets/icon/dark/portfolio_active.png", + "tabBarIconMoment": "assets/icon/dark/moment.png", + "tabBarIconMomentActive": "assets/icon/dark/moment_active.png", + "tabBarIconTravel": "assets/icon/dark/travel.png", + "tabBarIconTravelActive": "assets/icon/dark/travel_active.png", + "tabBarIconInfo": "assets/icon/dark/info.png", + "tabBarIconInfoActive": "assets/icon/dark/info_active.png" + } +} diff --git a/miniprogram/theme.wxss b/miniprogram/theme.wxss new file mode 100644 index 0000000..e654787 --- /dev/null +++ b/miniprogram/theme.wxss @@ -0,0 +1,89 @@ +/** + * 全局主题变量定义 + * 支持浅色和深色两种模式 + */ + +/* 浅色模式变量 */ +page { + /* === 背景色 === */ + --theme-bg-primary: #FFFFFF; + --theme-bg-secondary: #F5F5F5; + --theme-bg-card: #FFFFFF; + --theme-bg-journal: #FFF8E1; + --theme-bg-overlay: rgba(0, 0, 0, .1); + --theme-bg-menu: rgba(255, 255, 255, .95); + + /* === 文字颜色 === */ + --theme-text-primary: #000000; + --theme-text-secondary: #777777; + --theme-text-tertiary: #999999; + --theme-text-disabled: #CCCCCC; + + /* === 边框颜色 === */ + --theme-border-light: rgba(0, 0, 0, .1); + --theme-border-medium: rgba(0, 0, 0, .2); + --theme-border-dark: rgba(0, 0, 0, .8); + + /* === 阴影颜色 === */ + --theme-shadow-light: rgba(0, 0, 0, .1); + --theme-shadow-medium: rgba(0, 0, 0, .2); + --theme-shadow-dark: rgba(0, 0, 0, .3); + + /* === 品牌色(不随主题改变) === */ + --theme-brand-gao: #FF7A9B; + --theme-brand-yeyu: #7A9BFF; + --theme-brand-gao-light: #FFB5C7; + --theme-brand-gao-dark: #FF3A6B; + + /* === 功能色 === */ + --theme-error: #E64340; + --theme-success: #07C160; + --theme-warning: #FFC107; + + /* === 纸张纹理效果 === */ + --theme-texture-light: rgba(255, 255, 255, 0); + --theme-texture-bright: rgba(255, 255, 255, .3); + --theme-texture-line: rgba(0, 0, 0, .03); + + /* === 视频播放按钮 === */ + --theme-video-play: rgba(255, 255, 255, .9); +} + +/* 深色模式变量 */ +page[data-weui-theme="dark"] { + /* === 背景色 === */ + --theme-bg-primary: #1A1A1A; + --theme-bg-secondary: #2A2A2A; + --theme-bg-card: #2C2C2C; + --theme-bg-journal: #3A3A2E; + --theme-bg-overlay: rgba(0, 0, 0, .3); + --theme-bg-menu: rgba(40, 40, 40, .95); + + /* === 文字颜色 === */ + --theme-text-primary: #FFFFFF; + --theme-text-secondary: #AAAAAA; + --theme-text-tertiary: #888888; + --theme-text-disabled: #666666; + + /* === 边框颜色 === */ + --theme-border-light: rgba(255, 255, 255, .1); + --theme-border-medium: rgba(255, 255, 255, .2); + --theme-border-dark: rgba(255, 255, 255, .6); + + /* === 阴影颜色 === */ + --theme-shadow-light: rgba(0, 0, 0, .3); + --theme-shadow-medium: rgba(0, 0, 0, .5); + --theme-shadow-dark: rgba(0, 0, 0, .7); + + /* === 品牌色保持不变 === */ + + /* === 功能色保持不变 === */ + + /* === 纸张纹理效果(深色模式调整) === */ + --theme-texture-light: rgba(0, 0, 0, 0); + --theme-texture-bright: rgba(255, 255, 255, .05); + --theme-texture-line: rgba(255, 255, 255, .02); + + /* === 视频播放按钮 === */ + --theme-video-play: rgba(200, 200, 200, .8); +} diff --git a/miniprogram/utils/Theme.ts b/miniprogram/utils/Theme.ts new file mode 100644 index 0000000..7f39edf --- /dev/null +++ b/miniprogram/utils/Theme.ts @@ -0,0 +1,102 @@ +/** + * 主题管理工具类 + * 负责主题切换、主题状态监听和主题信息获取 + */ + +/** 主题模式枚举 */ +export enum ThemeMode { + /** 浅色模式 */ + LIGHT = 'light', + /** 深色模式 */ + DARK = 'dark' +} + +/** 主题变化回调函数类型 */ +type ThemeChangeCallback = (theme: ThemeMode) => void + +class Theme { + /** 主题变化监听器列表 */ + private listeners: ThemeChangeCallback[] = [] + + /** 当前主题模式 */ + private currentTheme: ThemeMode = ThemeMode.LIGHT + + constructor() { + this.init() + } + + /** + * 初始化主题管理器 + * 获取系统当前主题并监听主题变化 + */ + private init(): void { + // 获取系统信息,判断当前主题 + const systemInfo = wx.getSystemInfoSync() + this.currentTheme = systemInfo.theme === 'dark' ? ThemeMode.DARK : ThemeMode.LIGHT + + // 监听主题变化事件 + wx.onThemeChange((result) => { + const newTheme = result.theme === 'dark' ? ThemeMode.DARK : ThemeMode.LIGHT + this.currentTheme = newTheme + this.notifyListeners(newTheme) + }) + } + + /** + * 获取当前主题模式 + * @returns 当前主题模式 + */ + getTheme(): ThemeMode { + return this.currentTheme + } + + /** + * 判断是否为深色模式 + * @returns 是否为深色模式 + */ + isDark(): boolean { + return this.currentTheme === ThemeMode.DARK + } + + /** + * 判断是否为浅色模式 + * @returns 是否为浅色模式 + */ + isLight(): boolean { + return this.currentTheme === ThemeMode.LIGHT + } + + /** + * 监听主题变化 + * @param callback 主题变化时的回调函数 + * @returns 取消监听的函数 + */ + onChange(callback: ThemeChangeCallback): () => void { + this.listeners.push(callback) + + // 返回取消监听的函数 + return () => { + const index = this.listeners.indexOf(callback) + if (index > -1) { + this.listeners.splice(index, 1) + } + } + } + + /** + * 通知所有监听器主题已变化 + * @param theme 新的主题模式 + */ + private notifyListeners(theme: ThemeMode): void { + this.listeners.forEach(callback => { + try { + callback(theme) + } catch (error) { + console.error('主题变化监听器执行出错:', error) + } + }) + } +} + +// 导出单例 +export default new Theme()