Compare commits

...

3 Commits

Author SHA1 Message Date
199d1ed6ef add raindrop background 2025-12-05 18:21:09 +08:00
99ad931059 resize "love" font 2025-12-05 18:20:46 +08:00
b33ce05d52 support dark mode 2025-12-05 12:40:19 +08:00
43 changed files with 443 additions and 123 deletions

5
.gitignore vendored
View File

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

View File

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

View File

@ -1,2 +1,3 @@
/**app.wxss**/
@import "./theme.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

@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

View File

@ -0,0 +1,35 @@
/* components/background/raindrop/index.wxss */
page {
width: 100%;
height: 100%;
position: fixed;
}
.raindrops {
width: 100%;
height: 100%;
z-index: -1;
overflow: hidden;
position: absolute;
transform: rotate(3deg);
@keyframes rainFall {
from {
transform: translateY(-10px);
}
to {
transform: translateY(100vh);
}
}
.raindrop {
top: 0;
width: 2px;
height: 30px;
opacity: .6;
position: absolute;
animation: rainFall linear infinite;
background: linear-gradient(180deg, transparent, var(--theme-content-rain));
}
}

View File

@ -0,0 +1,59 @@
// components/background/raindrop/index.ts
import Toolkit from "../../../utils/Toolkit";
interface Raindrop {
x: number;
length: number;
speed: number;
}
Component({
data: {
raindrops: [] as Raindrop[],
timer: undefined as number | undefined,
docWidth: 375,
docHeight: 667,
},
methods: {
createRaindrop() {
const raindrop = {
x: Toolkit.random(0, this.data.docWidth),
length: Toolkit.random(20, 40),
speed: Toolkit.random(1, 2)
};
this.setData({
raindrops: [...this.data.raindrops, raindrop]
});
}
},
lifetimes: {
attached() {
const systemInfo = wx.getWindowInfo();
this.setData({
docWidth: systemInfo.windowWidth,
docHeight: systemInfo.windowHeight,
timer: setInterval(() => {
this.createRaindrop();
if (60 < this.data.raindrops.length) {
if (this.data.timer) {
clearInterval(this.data.timer);
}
this.setData({
timer: undefined
})
}
}, 100)
});
},
detached() {
if (this.data.timer) {
clearInterval(this.data.timer);
this.setData({
timer: undefined
})
}
}
}
})

View File

@ -0,0 +1,9 @@
<!--components/background/raindrop/index.wxml-->
<view class="raindrops" style="width: {{docWidth}}px; height: {{docHeight}}px;">
<view
class="raindrop"
wx:for="{{raindrops}}"
wx:key="index"
style="left: {{item.x}}px; height: {{item.length}}px; animation-duration: {{item.speed}}s;"
></view>
</view>

View File

@ -1,14 +1,4 @@
/* components/background/snow/index.wxss */
@keyframes fall {
from {
transform: translateY(-10px) rotate(0);
}
to {
transform: translateY(100vh) rotate(1800deg);
}
}
page {
width: 100%;
height: 100%;
@ -22,18 +12,29 @@ page {
overflow: hidden;
position: absolute;
@keyframes snowflakeFall {
from {
transform: translateY(-10px) rotate(0);
}
to {
transform: translateY(100vh) rotate(1800deg);
}
}
.snowflake {
width: 10px;
height: 10px;
display: block;
position: absolute;
animation: fall linear infinite;
animation: snowflakeFall linear infinite;
&::before,
&::after {
content: '';
position: absolute;
background: rgba(255, 122, 155, .8);
background: var(--theme-brand-gao);
opacity: .8;
}
&::before {

View File

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

View File

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

View File

@ -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 {

View File

@ -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;
font-size: 1.25rem;
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;

View File

@ -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 {

View File

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

View File

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

View File

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

View File

@ -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 {

View File

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

View File

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

View File

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

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

95
miniprogram/theme.wxss Normal file
View File

@ -0,0 +1,95 @@
/**
* 全局主题变量定义
* 支持浅色和深色两种模式
*/
/* 浅色模式变量 */
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);
/* 内容颜色 */
--theme-content-rain: rgb(108, 221, 255, .7);
}
/* 深色模式变量 */
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);
/* 内容颜色 */
--theme-content-rain: rgba(235, 250, 255, .7);
}

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