support dark mode

This commit is contained in:
Timi
2025-12-05 12:40:19 +08:00
parent 99eb470625
commit b33ce05d52
39 changed files with 317 additions and 111 deletions

4
.gitignore vendored
View File

@ -58,4 +58,6 @@ cloudfunctions/**/*.log
.Spotlight-V100 .Spotlight-V100
.Trashes .Trashes
ehthumbs.db ehthumbs.db
[Tt]humbs.db [Tt]humbs.db
CLAUDE.md

View File

@ -10,6 +10,8 @@
"pages/main/moment/index", "pages/main/moment/index",
"pages/main/journal-list/index" "pages/main/journal-list/index"
], ],
"darkmode": true,
"themeLocation": "theme.json",
"window": { "window": {
"navigationStyle": "custom", "navigationStyle": "custom",
"navigationBarTextStyle": "black", "navigationBarTextStyle": "black",
@ -17,40 +19,40 @@
}, },
"lazyCodeLoading": "requiredComponents", "lazyCodeLoading": "requiredComponents",
"tabBar": { "tabBar": {
"color": "#8a8a8a", "color": "@tabBarColor",
"selectedColor": "#07C160", "selectedColor": "@tabBarSelectedColor",
"backgroundColor": "#ffffff", "backgroundColor": "@tabBarBackgroundColor",
"borderStyle": "white", "borderStyle": "@tabBarBorderStyle",
"list": [ "list": [
{ {
"text": "归档", "text": "归档",
"pagePath": "pages/main/journal/index", "pagePath": "pages/main/journal/index",
"iconPath": "assets/icon/journal.png", "iconPath": "@tabBarIconJournal",
"selectedIconPath": "assets/icon/journal_active.png" "selectedIconPath": "@tabBarIconJournalActive"
}, },
{ {
"text": "专拍", "text": "专拍",
"pagePath": "pages/main/portfolio/index", "pagePath": "pages/main/portfolio/index",
"iconPath": "assets/icon/portfolio.png", "iconPath": "@tabBarIconPortfolio",
"selectedIconPath": "assets/icon/portfolio_active.png" "selectedIconPath": "@tabBarIconPortfolioActive"
}, },
{ {
"text": "瞬间", "text": "瞬间",
"pagePath": "pages/main/moment/index", "pagePath": "pages/main/moment/index",
"iconPath": "assets/icon/moment.png", "iconPath": "@tabBarIconMoment",
"selectedIconPath": "assets/icon/moment_active.png" "selectedIconPath": "@tabBarIconMomentActive"
}, },
{ {
"text": "旅行", "text": "旅行",
"pagePath": "pages/main/travel/index", "pagePath": "pages/main/travel/index",
"iconPath": "assets/icon/travel.png", "iconPath": "@tabBarIconTravel",
"selectedIconPath": "assets/icon/travel_active.png" "selectedIconPath": "@tabBarIconTravelActive"
}, },
{ {
"text": "关于", "text": "关于",
"pagePath": "pages/main/about/index", "pagePath": "pages/main/about/index",
"iconPath": "assets/icon/info.png", "iconPath": "@tabBarIconInfo",
"selectedIconPath": "assets/icon/info_active.png" "selectedIconPath": "@tabBarIconInfoActive"
} }
] ]
}, },

View File

@ -1,2 +1,3 @@
/**app.wxss**/ /**app.wxss**/
@import "./theme.wxss";
@import "./tdesign.wxss"; @import "./tdesign.wxss";

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 699 B

After

Width:  |  Height:  |  Size: 699 B

View File

Before

Width:  |  Height:  |  Size: 762 B

After

Width:  |  Height:  |  Size: 762 B

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -28,12 +28,13 @@ page {
display: block; display: block;
position: absolute; position: absolute;
animation: fall linear infinite; animation: fall linear infinite;
&::before, &::before,
&::after { &::after {
content: ''; content: '';
position: absolute; position: absolute;
background: rgba(255, 122, 155, .8); background: var(--theme-brand-gao);
opacity: .8;
} }
&::before { &::before {

View File

@ -36,8 +36,6 @@ Component({
docHeight: systemInfo.windowHeight, docHeight: systemInfo.windowHeight,
timer: setInterval(() => { timer: setInterval(() => {
this.createSnowflake(); this.createSnowflake();
console.log(this.data.snowflakes);
if (40 < this.data.snowflakes.length) { if (40 < this.data.snowflakes.length) {
if (this.data.timer) { if (this.data.timer) {
clearInterval(this.data.timer); clearInterval(this.data.timer);

View File

@ -1,6 +1,6 @@
const envArgs = { const envArgs = {
develop: { develop: {
url: "http://localhost:8091" url: "https://api.imyeyu.com"
}, },
trial: { trial: {
url: "https://api.imyeyu.com" url: "https://api.imyeyu.com"

View File

@ -29,28 +29,28 @@ page {
height: 128px; height: 128px;
display: block; display: block;
border-radius: 4px; 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; margin-bottom: 1rem;
} }
.name { .name {
margin: 0 .5rem; margin: 0 .5rem;
display: inline-block; display: inline-block;
&.gao { &.gao {
color: #FF7A9B; color: var(--theme-brand-gao);
} }
&.yeyu { &.yeyu {
color: #7A9BFF; color: var(--theme-brand-yeyu);
} }
} }
} }
.password { .password {
width: 20rem; width: 20rem;
border-top: 1px solid rgba(0, 0, 0, .1); border-top: 1px solid var(--theme-border-light);
border-bottom: 1px solid rgba(0, 0, 0, .1); border-bottom: 1px solid var(--theme-border-light);
} }
.enter { .enter {

View File

@ -29,35 +29,35 @@ page {
height: 128px; height: 128px;
display: block; display: block;
border-radius: 4px; 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; margin-bottom: 1rem;
} }
.name { .name {
margin: 0 .5rem; margin: 0 .5rem;
display: inline-block; display: inline-block;
&.gao { &.gao {
color: #FF7A9B; color: var(--theme-brand-gao);
} }
&.yeyu { &.yeyu {
color: #7A9BFF; color: var(--theme-brand-yeyu);
} }
} }
} }
.text { .text {
color: #777; color: var(--theme-text-secondary);
font-size: 12px; font-size: 12px;
text-align: center; text-align: center;
.love { .love {
color: transparent; color: transparent;
font-size: 1rem; font-size: 1rem;
animation: loveGradient 1500ms linear infinite; animation: loveGradient 1000ms linear infinite;
text-align: center; 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-weight: bold;
font-family: "Arial", sans-serif; font-family: "Arial", sans-serif;
margin-bottom: 1rem; margin-bottom: 1rem;
@ -66,7 +66,7 @@ page {
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
} }
@keyframes loveGradient { @keyframes loveGradient {
0% { 0% {
background-position: 0% 50%; background-position: 0% 50%;
@ -83,19 +83,19 @@ page {
flex-direction: column; flex-direction: column;
.exit { .exit {
color: #E64340; color: var(--theme-error);
width: 10rem; width: 10rem;
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.item { .item {
font-size: 14px; font-size: 14px;
text-align: center; text-align: center;
.label { .label {
color: #777; color: var(--theme-text-secondary);
} }
&.copyright { &.copyright {
display: flex; display: flex;
font-size: 12px; font-size: 12px;

View File

@ -10,7 +10,7 @@
flex-direction: column; flex-direction: column;
.label { .label {
color: #777; color: var(--theme-text-secondary);
} }
.section { .section {
@ -47,8 +47,8 @@
height: 200rpx; height: 200rpx;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
background: #FFF; background: var(--theme-bg-card);
box-shadow: 1px 1px 6px rgba(0, 0, 0, .1); box-shadow: 1px 1px 6px var(--theme-shadow-light);
border-radius: 2rpx; border-radius: 2rpx;
.thumbnail { .thumbnail {

View File

@ -1,55 +1,20 @@
.custom-navbar { .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 { .more-menu {
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
position: fixed; position: fixed;
background: rgba(0, 0, 0, .1); background: var(--theme-bg-overlay);
.content { .content {
margin: 200rpx 0 0 12rpx; margin: 190rpx 0 0 12rpx;
z-index: 1; z-index: 1;
position: fixed; 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; 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; padding: 8px 16px;
margin: .5rem 1rem 1rem 1rem; margin: .5rem 1rem 1rem 1rem;
position: relative; position: relative;
background: #FFF8E1; background: var(--theme-bg-journal);
box-shadow: 0 2px 10px rgba(0, 0, 0, .2); box-shadow: 0 2px 10px var(--theme-shadow-medium);
border-radius: 2px; border-radius: 2px;
// 纸张纹理效果 // 纸张纹理效果
@ -100,17 +65,17 @@
bottom: 0; bottom: 0;
background: background:
linear-gradient(90deg, linear-gradient(90deg,
rgba(255, 255, 255, 0) 0%, var(--theme-texture-light) 0%,
rgba(255, 255, 255, 0.3) 50%, var(--theme-texture-bright) 50%,
rgba(255, 255, 255, 0) 100%), var(--theme-texture-light) 100%),
linear-gradient(rgba(0, 0, 0, 0.03) 1px, transparent 1px), linear-gradient(var(--theme-texture-line) 1px, transparent 1px),
linear-gradient(90deg, rgba(0, 0, 0, 0.03) 1px, transparent 1px); linear-gradient(90deg, var(--theme-texture-line) 1px, transparent 1px);
pointer-events: none; pointer-events: none;
background-size: 100% 100%, 10px 10px, 10px 10px; background-size: 100% 100%, 10px 10px, 10px 10px;
} }
.location { .location {
color: #777; color: var(--theme-text-secondary);
text-align: right; text-align: right;
} }
} }
@ -122,7 +87,7 @@
.item { .item {
overflow: hidden; overflow: hidden;
background: #FFF; background: var(--theme-bg-card);
break-inside: avoid; break-inside: avoid;
margin-bottom: .25rem; margin-bottom: .25rem;
@ -144,7 +109,7 @@
position: absolute; position: absolute;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
border-top: 16px solid transparent; 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; border-bottom: 16px solid transparent;
pointer-events: none; pointer-events: none;
} }
@ -154,7 +119,7 @@
} }
.start { .start {
color: #777; color: var(--theme-text-secondary);
padding: 1rem 0; padding: 1rem 0;
font-size: 12px; font-size: 12px;
text-align: center; text-align: center;

View File

@ -3,7 +3,6 @@
import Time from "../../../utils/Time"; import Time from "../../../utils/Time";
import config from "../../../config/index" import config from "../../../config/index"
import Events from "../../../utils/Events"; import Events from "../../../utils/Events";
import Toolkit from "../../../utils/Toolkit";
export type Journal = { export type Journal = {
date: string; date: string;

View File

@ -1,6 +1,7 @@
<view class="custom-navbar"> <view class="custom-navbar">
<t-navbar title="我们的记录"> <t-navbar title="我们的记录">
<view slot="left" class="more" bind:tap="toggleMoreMenu"> <view slot="left" class="more" bind:tap="toggleMoreMenu">
<t-icon name="view-list" size="24px" />
<view wx:if="{{isShowMoreMenu}}" class="more-menu"> <view wx:if="{{isShowMoreMenu}}" class="more-menu">
<t-cell-group class="content" theme="card"> <t-cell-group class="content" theme="card">
<t-cell title="新纪录" leftIcon="add" bind:tap="toCreater" /> <t-cell title="新纪录" leftIcon="add" bind:tap="toCreater" />

View File

@ -36,7 +36,7 @@
} }
.text { .text {
color: #777; color: var(--theme-text-secondary);
display: flex; display: flex;
font-size: .8rem; font-size: .8rem;
justify-content: space-between; justify-content: space-between;
@ -55,14 +55,14 @@
width: 100%; width: 100%;
display: block; display: block;
overflow: hidden; overflow: hidden;
background: #FFF; background: var(--theme-bg-card);
break-inside: avoid; break-inside: avoid;
margin-bottom: .25rem; margin-bottom: .25rem;
&.video { &.video {
height: auto; height: auto;
position: relative; position: relative;
&::after { &::after {
content: ""; content: "";
top: 50%; top: 50%;
@ -72,7 +72,7 @@
position: absolute; position: absolute;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
border-top: 16px solid transparent; 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; border-bottom: 16px solid transparent;
pointer-events: none; pointer-events: none;
} }
@ -95,7 +95,7 @@
height: 16px; height: 16px;
z-index: 1; z-index: 1;
position: absolute; position: absolute;
background: #FFF; background: var(--theme-bg-card);
border-radius: 50%; border-radius: 50%;
} }
} }
@ -131,7 +131,7 @@
} }
&.confirm { &.confirm {
color: #07C160; color: var(--theme-success);
} }
} }
} }
@ -144,7 +144,7 @@
margin-top: 1.5rem; margin-top: 1.5rem;
.label { .label {
color: #777; color: var(--theme-text-secondary);
} }
&.type { &.type {

View File

@ -11,7 +11,7 @@
.item { .item {
overflow: hidden; overflow: hidden;
background: #FFF; background: var(--theme-bg-card);
break-inside: avoid; break-inside: avoid;
margin-bottom: .25rem; margin-bottom: .25rem;

View File

@ -15,7 +15,7 @@
width: 100%; width: 100%;
display: block; display: block;
overflow: hidden; overflow: hidden;
background: #FFF; background: var(--theme-bg-card);
break-inside: avoid; break-inside: avoid;
margin-bottom: .25rem; margin-bottom: .25rem;
} }

View File

@ -1,7 +1,7 @@
.luggage { .luggage {
.tips { .tips {
color: #777; color: var(--theme-text-secondary);
margin: .5rem 0; margin: .5rem 0;
font-size: 12px; font-size: 12px;
text-align: center; text-align: center;
@ -19,7 +19,7 @@
flex: 1; flex: 1;
margin: 0; margin: 0;
border: 3rpx solid #CCC; border: 3rpx solid var(--theme-text-disabled);
position: relative; position: relative;
overflow: hidden; overflow: hidden;
box-sizing: border-box; box-sizing: border-box;
@ -68,13 +68,13 @@
.add-container { .add-container {
left: 0; left: 0;
right: 0; right: 0;
color: #333; color: var(--theme-text-primary);
bottom: 0; bottom: 0;
display: flex; display: flex;
padding: 20rpx; padding: 20rpx;
position: fixed; position: fixed;
border-top: 1px solid rgba(0, 0, 0, .1); border-top: 1px solid var(--theme-border-light);
background: rgba(240, 240, 240, .8); background: var(--theme-bg-secondary);
box-sizing: border-box; box-sizing: border-box;
align-items: center; align-items: center;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom)); padding-bottom: calc(20rpx + env(safe-area-inset-bottom));

46
miniprogram/theme.json Normal file
View File

@ -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"
}
}

89
miniprogram/theme.wxss Normal file
View File

@ -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);
}

102
miniprogram/utils/Theme.ts Normal file
View File

@ -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()