add journal-detail-panel

This commit is contained in:
Timi
2025-12-10 16:45:29 +08:00
parent a5fb1d752b
commit 1e54782600
12 changed files with 496 additions and 527 deletions

View File

@ -1,9 +1,8 @@
{
"usingComponents": {
"t-icon": "tdesign-miniprogram/icon/icon",
"t-popup": "tdesign-miniprogram/popup/popup",
"t-navbar": "tdesign-miniprogram/navbar/navbar",
"calendar": "/components/calendar/index"
"calendar": "/components/calendar/index",
"journal-detail-panel": "/components/journal-detail-panel/index"
},
"navigationStyle": "custom"
}

View File

@ -22,153 +22,3 @@
}
}
}
.date-detail {
height: 61.8vh;
display: flex;
border-radius: 24rpx 24rpx 0 0;
flex-direction: column;
.detail-content {
flex: 1;
display: flex;
overflow: hidden;
flex-direction: column;
.header {
display: flex;
padding: 24rpx 24rpx 4rpx;
flex-shrink: 0;
align-items: flex-start;
justify-content: space-between;
.info {
flex: 1;
display: flex;
flex-direction: column;
.date {
color: var(--theme-text);
font-size: 32rpx;
font-weight: 600;
margin-bottom: 8rpx;
}
.count {
color: var(--theme-text-secondary);
font-size: 26rpx;
}
}
.actions {
gap: 16rpx;
display: flex;
flex-shrink: 0;
align-items: center;
.indicator {
color: var(--theme-text-secondary);
padding: 8rpx 16rpx;
font-size: 24rpx;
border-radius: 24rpx;
background: var(--theme-bg);
}
}
}
.journals-swiper {
flex: 1;
.swiper-item-wrapper {
height: 100%;
display: flex;
padding: 0 24rpx;
box-sizing: border-box;
.journal-item {
flex: 1;
display: flex;
background: var(--theme-bg);
flex-direction: column;
.journal-header {
display: flex;
margin-top: 16rpx;
flex-shrink: 0;
align-items: center;
justify-content: space-between;
.location {
flex: 1;
color: var(--theme-text);
overflow: hidden;
font-size: 28rpx;
white-space: nowrap;
text-overflow: ellipsis;
}
.time {
color: var(--theme-text-secondary);
font-size: 24rpx;
margin-left: 16rpx;
flex-shrink: 0;
}
}
.idea {
color: var(--theme-text);
display: block;
font-size: 28rpx;
line-height: 1.6;
flex-shrink: 0;
}
.items-scroll {
flex: 1;
height: 0;
margin-top: 16rpx;
.items {
.wrapper {
position: relative;
column-gap: 8rpx;
column-count: 3;
.item {
overflow: hidden;
break-inside: avoid;
margin-bottom: 8rpx;
background: var(--theme-bg-card);
&.thumbnail {
width: 100%;
display: block;
}
&.video {
position: relative;
&::after {
top: 50%;
left: 53%;
width: 0;
height: 0;
content: "";
position: absolute;
transform: translate(-50%, -50%);
border-top: 16rpx solid transparent;
border-left: 24rpx solid rgba(255, 255, 255, .9);
border-bottom: 16rpx solid transparent;
pointer-events: none;
}
}
}
}
}
}
}
}
}
}
}

View File

@ -27,9 +27,7 @@ interface JournalDateData {
journalMap: Record<string, number[]>; // 存储每个日期的日记 id 列表
selectedDate: SelectedDateInfo | null;
isLoading: boolean;
currentJournalIndex: number; // 当前日记索引
popupVisible: boolean; // popup 显示状态
swiperNextMargin: string; // swiper 的 next-margin 值
}
Page({
@ -37,9 +35,7 @@ Page({
journalMap: {},
selectedDate: null,
isLoading: true,
currentJournalIndex: 0,
popupVisible: false,
swiperNextMargin: "0"
popupVisible: false
},
async onLoad() {
@ -170,9 +166,7 @@ Page({
displayDate,
journals
},
currentJournalIndex: 0, // 重置索引
popupVisible: true, // 显示 popup
swiperNextMargin: journals.length > 1 ? "128rpx" : "0" // 设置初始 margin
popupVisible: true // 显示 popup
});
wx.hideLoading();
@ -188,57 +182,8 @@ Page({
/** 关闭详情 */
closeDetail() {
this.setData({
popupVisible: false
});
},
/** popup 显示状态变化 */
onPopupVisibleChange(e: WechatMiniprogram.CustomEvent) {
const { visible } = e.detail;
this.setData({
popupVisible: visible
});
// 关闭时清空数据
if (!visible) {
this.setData({
selectedDate: null,
currentJournalIndex: 0
});
}
},
/** swiper 切换事件 */
onSwiperChange(e: WechatMiniprogram.SwiperChange) {
this.setData({
currentJournalIndex: e.detail.current
});
},
/** swiper 动画完成事件 */
onSwiperAnimationFinish(e: WechatMiniprogram.SwiperAnimationFinish) {
if (!this.data.selectedDate) return;
const current = e.detail.current;
const total = this.data.selectedDate.journals.length;
// 动画完成后更新 margin确保过渡流畅
const nextMargin = total > 1 && current < total - 1 ? "128rpx" : "0";
this.setData({
swiperNextMargin: nextMargin
});
},
/** 预览媒体 */
previewMedia(e: WechatMiniprogram.BaseEvent) {
const { mediaIndex } = e.currentTarget.dataset;
if (!this.data.selectedDate) return;
// 使用当前 swiper 的索引
const journal = this.data.selectedDate.journals[this.data.currentJournalIndex];
const sources = journal.items.map((item: any) => ({
url: item.sourceURL,
type: item.type === 0 ? "image" : "video"
}));
wx.previewMedia({
current: mediaIndex,
sources: sources as WechatMiniprogram.MediaSource[]
popupVisible: false,
selectedDate: null
});
}
});

View File

@ -9,61 +9,11 @@
</view>
</view>
<!-- 详情面板 -->
<t-popup
class="popup"
<journal-detail-panel
visible="{{popupVisible}}"
placement="bottom"
bind:visible-change="onPopupVisibleChange"
>
<view class="date-detail">
<view class="detail-content">
<view class="header">
<view class="info">
<view class="date">{{selectedDate.displayDate}}</view>
<view class="count">{{selectedDate.journals.length}} 条日记</view>
</view>
<view class="actions">
<view wx:if="{{selectedDate.journals.length > 1}}" class="indicator">
{{currentJournalIndex + 1}}/{{selectedDate.journals.length}}
</view>
<t-icon name="close" catchtap="closeDetail" size="48rpx" />
</view>
</view>
<swiper
class="journals-swiper"
current="{{currentJournalIndex}}"
bindchange="onSwiperChange"
bindanimationfinish="onSwiperAnimationFinish"
previous-margin="{{0}}"
next-margin="{{swiperNextMargin}}"
>
<block wx:for="{{selectedDate.journals}}" wx:key="id">
<swiper-item class="swiper-item-wrapper">
<view class="journal-item" data-id="{{item.id}}">
<view class="journal-header">
<view wx:if="{{item.location}}" class="location">📍 {{item.location}}</view>
<view class="time">{{item.time}}</view>
</view>
<view wx:if="{{item.idea}}" class="idea">{{item.idea}}</view>
<scroll-view wx:if="{{item.items && item.items.length > 0}}" scroll-y class="items-scroll">
<view class="items">
<view class="wrapper">
<block wx:for="{{item.items}}" wx:key="mongoId" wx:for-item="media">
<image
class="item thumbnail {{media.type === 1 ? 'video' : 'image'}}"
src="{{media.thumbURL}}"
mode="widthFix"
catchtap="previewMedia"
data-media-index="{{mediaIndex}}"
/>
</block>
</view>
</view>
</scroll-view>
</view>
</swiper-item>
</block>
</swiper>
</view>
</view>
</t-popup>
title="{{selectedDate.displayDate}}"
journals="{{selectedDate.journals}}"
show-journal-date="{{false}}"
show-journal-location="{{true}}"
bind:close="closeDetail"
/>