更新最新代码
This commit is contained in:
@@ -0,0 +1,279 @@
|
||||
const { itemsOf, totalOf, mergeUnique } = require('../../utils/list-pagination');
|
||||
const { withDataCache } = require('../../utils/page-cache');
|
||||
const { getLayout } = require('../../utils/layout');
|
||||
const { api, getImageUrl } = require('../../utils/request');
|
||||
Page(withDataCache({
|
||||
noop: function() {},
|
||||
onResize: function() { this.setData(getLayout()); },
|
||||
data: { loadError: false,
|
||||
diary: null,
|
||||
loading: true,
|
||||
comments: [],
|
||||
commentPage: 1, commentsLoadingMore: false, commentsMoreError: false, commentsTotal: 0,
|
||||
hasMoreComments: true,
|
||||
showCommentInput: false,
|
||||
commentText: '',
|
||||
commentInitialText: '',
|
||||
commentLength: 0,
|
||||
commentFocus: false,
|
||||
commentKeyboardHeight: 0,
|
||||
commentEditorHeight: 56,
|
||||
commentSending: false,
|
||||
replyTo: null,
|
||||
coverSwiperIndex: 0,
|
||||
previewImages: [],
|
||||
previewIndex: 0,
|
||||
showPreview: false,
|
||||
myUid: 0
|
||||
},
|
||||
|
||||
onLoad: function(options) {
|
||||
this.setData(getLayout());
|
||||
var diaryId = options.id;
|
||||
if (!diaryId) { wx.showToast({ title: '参数错误', icon: 'none' }); return; }
|
||||
this.setData({ diaryId: parseInt(diaryId), myUid: wx.getStorageSync('userId') || 0 });
|
||||
this.loadDiary();
|
||||
this.loadComments();
|
||||
},
|
||||
|
||||
onShow: function() {
|
||||
if (this.data.diaryId) { this.loadDiary(); this.loadComments(); }
|
||||
},
|
||||
|
||||
loadDiary: async function() {
|
||||
if (this._pageLoading) return;
|
||||
this._pageLoading = true;
|
||||
this.setData({loading: !this._hasCachedData, loadError:false});
|
||||
try {
|
||||
var data = await api.diaryDetail(this.data.diaryId);
|
||||
data = this._formatDiary(data);
|
||||
this.setData({ diary: data, myUid: wx.getStorageSync('userId') || 0, loading: false });
|
||||
} catch (e) {
|
||||
this.setData({loadError:true});
|
||||
wx.showToast({ title: '加载失败', icon: 'none' });
|
||||
this.setData({ loading: false });
|
||||
}
|
||||
finally { this._pageLoading = false; this.setData({loading:false}); }
|
||||
},
|
||||
|
||||
_formatDiary: function(data) {
|
||||
var myUid = wx.getStorageSync('userId') || 0;
|
||||
data.creator_name = data.creator_name || (data.created_by == myUid ? '我' : 'TA');
|
||||
data.creator_avatar = getImageUrl(data.creator_avatar);
|
||||
data.created_time = data.created_at ? data.created_at.substring(0, 16).replace('T', ' ') : '';
|
||||
var imgs = data.images || [];
|
||||
if (typeof imgs === 'string') {
|
||||
try { imgs = JSON.parse(imgs); } catch(e) { imgs = []; }
|
||||
}
|
||||
if (!Array.isArray(imgs)) imgs = [];
|
||||
data.imageUrls = imgs.map(function(p) { return getImageUrl(p); });
|
||||
data.comment_count = data.comment_count || 0;
|
||||
// 地理位置:优先显示地址名称,其次显示经纬度(经纬度为0的不显示)
|
||||
data.location_text = '';
|
||||
var hasCoord = data.lat && data.lng && parseFloat(data.lat) !== 0 && parseFloat(data.lng) !== 0;
|
||||
if (data.location) {
|
||||
data.location_text = data.location;
|
||||
} else if (hasCoord) {
|
||||
data.location_text = data.lat + ', ' + data.lng;
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
loadComments: function() { return this._loadCommentsPage(1); },
|
||||
_loadCommentsPage: async function(page) {
|
||||
page = Number(page) || 1;
|
||||
if (this._commentsFirst || (page > 1 && (this.data.commentsLoadingMore || !this.data.hasMoreComments))) return;
|
||||
if (page === 1) { this._commentsFirst = true; this._commentsGeneration = (this._commentsGeneration || 0) + 1; }
|
||||
var generation = this._commentsGeneration;
|
||||
this.setData(page === 1 ? {commentsError:false,commentsMoreError:false,commentsLoadingMore:false} : {commentsLoadingMore:true,commentsMoreError:false});
|
||||
try {
|
||||
var result = await api.diaryCommentList({diary_id:this.data.diaryId,page:page,page_size:20});
|
||||
if (generation !== this._commentsGeneration) return;
|
||||
var added = itemsOf(result).map(function(comment) {
|
||||
return Object.assign({}, comment, {_time:String(comment.created_at || comment.create_time || '').slice(0,16).replace('T',' ')});
|
||||
});
|
||||
this.setData({comments:page===1?added:mergeUnique(this.data.comments,added),commentPage:page,commentsTotal:totalOf(result),hasMoreComments:!Array.isArray(result)&&(result.has_more != null?!!result.has_more:page*20<totalOf(result))});
|
||||
} catch(e) {
|
||||
if (generation === this._commentsGeneration) this.setData(page===1?{commentsError:true}:{commentsMoreError:true});
|
||||
} finally {
|
||||
if (generation === this._commentsGeneration) { this._commentsFirst=false;this.setData({commentsLoadingMore:false}); }
|
||||
}
|
||||
},
|
||||
loadMoreComments: function() { return this._loadCommentsPage(this.data.commentPage+1); },
|
||||
|
||||
|
||||
onShareTap: function() {
|
||||
wx.showActionSheet({
|
||||
itemList: ['分享给微信好友', '分享到朋友圈', '生成分享海报'],
|
||||
success: function(res) {
|
||||
if (res.tapIndex === 0) {
|
||||
wx.shareAppMessage ? wx.shareAppMessage() : wx.showToast({ title: '请点击右上角分享', icon: 'none' });
|
||||
} else if (res.tapIndex === 1) {
|
||||
wx.showToast({ title: '请点击右上角分享到朋友圈', icon: 'none' });
|
||||
} else {
|
||||
wx.showToast({ title: '功能开发中', icon: 'none' });
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onCoverSwiperChange: function(e) {
|
||||
this.setData({ coverSwiperIndex: e.detail.current });
|
||||
},
|
||||
|
||||
onImageTap: function(e) {
|
||||
var idx = this.data.coverSwiperIndex;
|
||||
var imgs = this.data.diary.imageUrls || [];
|
||||
this.setData({ showPreview: true, previewIndex: idx, previewImages: imgs });
|
||||
},
|
||||
closePreview: function() { this.setData({ showPreview: false }); },
|
||||
onPreviewSwiperChange: function(e) { this.setData({ previewIndex: e.detail.current }); },
|
||||
|
||||
onCommentTap: function() {
|
||||
this.openComment(null);
|
||||
},
|
||||
onReplyTap: function(e) {
|
||||
var item = e.currentTarget.dataset.item;
|
||||
this.openComment({ id: item.id, user_id: item.user_id, nickname: item.nickname });
|
||||
},
|
||||
openComment: function(replyTo) {
|
||||
var sameTarget = (!replyTo && !this.data.replyTo) ||
|
||||
(replyTo && this.data.replyTo && replyTo.id === this.data.replyTo.id);
|
||||
var text = sameTarget ? this.data.commentText : '';
|
||||
this.setData({ showCommentInput: true, replyTo: replyTo, commentText: text,
|
||||
commentInitialText: text, commentLength: text.length, commentFocus: true,
|
||||
commentKeyboardHeight: 0, commentEditorHeight: 56 });
|
||||
},
|
||||
onCommentInput: function(e) {
|
||||
// 不把正文反复写回原生输入框,避免中文输入时光标跳动。
|
||||
this.data.commentText = e.detail.value || '';
|
||||
this.setData({ commentLength: this.data.commentText.length });
|
||||
},
|
||||
onCommentKeyboardHeight: function(e) {
|
||||
var height = Math.max(0, Number(e.detail.height) || 0);
|
||||
if (this.data.showCommentInput) this.setData({ commentKeyboardHeight: height });
|
||||
},
|
||||
onCommentLineChange: function(e) {
|
||||
this.setData({ commentEditorHeight: Math.min(160, Math.max(56, Number(e.detail.height) || 56)) });
|
||||
},
|
||||
onCommentBlur: function() {
|
||||
this.setData({ commentFocus: false });
|
||||
},
|
||||
cancelComment: function() {
|
||||
if (this.data.commentSending) return;
|
||||
this.setData({ showCommentInput: false, commentFocus: false, commentKeyboardHeight: 0 });
|
||||
wx.hideKeyboard();
|
||||
},
|
||||
onHide: function() {
|
||||
this.setData({ showCommentInput: false, commentFocus: false, commentKeyboardHeight: 0 });
|
||||
},
|
||||
|
||||
submitComment: async function() {
|
||||
if (this.data.commentSending) return;
|
||||
var text = this.data.commentText.trim();
|
||||
if (!text) { wx.showToast({ title: '请输入评论内容', icon: 'none' }); return; }
|
||||
this.setData({ commentSending: true });
|
||||
try {
|
||||
var params = { diary_id: this.data.diaryId, content: text };
|
||||
if (this.data.replyTo) {
|
||||
params.parent_id = this.data.replyTo.id;
|
||||
params.reply_to_user_id = this.data.replyTo.user_id;
|
||||
params.reply_to_username = this.data.replyTo.nickname;
|
||||
}
|
||||
var res = await api.diaryCommentAdd(params);
|
||||
if (res.success) {
|
||||
this._commentsGeneration = (this._commentsGeneration || 0) + 1;
|
||||
this._commentsFirst = false;
|
||||
this.setData({commentsLoadingMore:false});
|
||||
var newComment = res.comment || {};
|
||||
if (newComment.created_at) {
|
||||
newComment._time = newComment.created_at.substring(0, 16).replace('T', ' ');
|
||||
} else if (newComment.create_time) {
|
||||
newComment._time = newComment.create_time.substring(0, 16).replace('T', ' ');
|
||||
} else {
|
||||
var now = new Date();
|
||||
newComment._time = now.getFullYear() + '-' + String(now.getMonth()+1).padStart(2,'0') + '-' + String(now.getDate()).padStart(2,'0') + ' ' + String(now.getHours()).padStart(2,'0') + ':' + String(now.getMinutes()).padStart(2,'0');
|
||||
}
|
||||
var newComments = this.data.comments.slice();
|
||||
newComments.unshift(newComment);
|
||||
this.setData({
|
||||
comments: newComments,
|
||||
commentsTotal: this.data.commentsTotal + 1,
|
||||
showCommentInput: false,
|
||||
replyTo: null,
|
||||
commentText: '',
|
||||
commentInitialText: '',
|
||||
commentLength: 0,
|
||||
commentFocus: false,
|
||||
commentKeyboardHeight: 0,
|
||||
'diary.comment_count': (this.data.diary.comment_count || 0) + 1
|
||||
});
|
||||
wx.hideKeyboard();
|
||||
wx.showToast({ title: '评论成功', icon: 'success' });
|
||||
}
|
||||
} catch (e) {
|
||||
wx.showToast({ title: e.error || '评论失败', icon: 'none' });
|
||||
} finally {
|
||||
this.setData({ commentSending: false });
|
||||
}
|
||||
},
|
||||
|
||||
onCommentLongPress: function(e) {
|
||||
var item = e.currentTarget.dataset.item;
|
||||
if (item.user_id != this.data.myUid) return;
|
||||
var self = this;
|
||||
wx.showModal({
|
||||
title: '删除评论',
|
||||
content: '确定要删除这条评论吗?',
|
||||
success: async function(res) {
|
||||
if (res.confirm) {
|
||||
try {
|
||||
await api.diaryCommentDelete({ id: item.id });
|
||||
var list = self.data.comments.filter(function(c) { return c.id != item.id; });
|
||||
self.setData({
|
||||
comments: list,
|
||||
'diary.comment_count': Math.max(0, (self.data.diary.comment_count || 0) - 1)
|
||||
});
|
||||
wx.showToast({ title: '已删除', icon: 'success' });
|
||||
} catch (e) { wx.showToast({ title: '删除失败', icon: 'none' }); }
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onMoreTap: function() {
|
||||
var self = this;
|
||||
wx.showActionSheet({
|
||||
itemList: ['编辑', '删除'],
|
||||
success: function(res) {
|
||||
if (res.tapIndex === 0) {
|
||||
wx.navigateTo({ url: '/pages/diary_edit/diary_edit?id=' + self.data.diaryId });
|
||||
} else if (res.tapIndex === 1) {
|
||||
self._deleteDiary();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_deleteDiary: function() {
|
||||
var self = this;
|
||||
wx.showModal({
|
||||
title: '删除日记',
|
||||
content: '确定要删除这篇日记吗?',
|
||||
success: async function(res) {
|
||||
if (res.confirm) {
|
||||
try {
|
||||
await api.diaryDelete({ id: self.data.diaryId });
|
||||
wx.showToast({ title: '已删除', icon: 'success' });
|
||||
setTimeout(function() { wx.navigateBack(); }, 1500);
|
||||
} catch (e) {
|
||||
wx.showToast({ title: e.error || '删除失败', icon: 'none' });
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
goBack: function() { wx.navigateBack(); },
|
||||
goHome: function() { wx.switchTab({ url: '/pages/index/index' }); }
|
||||
}, {"loadDiary": ["diaryDetail"], "loadComments": ["diaryCommentList"]}));
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"navigationStyle": "custom",
|
||||
"enablePullDownRefresh": false,
|
||||
"usingComponents": {
|
||||
"app-nav": "/components/app-nav/app-nav",
|
||||
"page-state": "/components/page-state/page-state"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<view class="app-shell app-shell--secondary" style="{{layoutStyle}}">
|
||||
<launch-transition />
|
||||
<app-nav title="日记详情" back="{{true}}" /><view class="page-bg">
|
||||
|
||||
<view class="read-state" wx:if="{{loading || loadError}}"><page-state wx:if="{{loading}}" kind="loading" title="正在加载日记" /><page-state wx:else kind="error" title="日记加载失败" action="重试" bind:action="loadDiary" /></view>
|
||||
<scroll-view scroll-y bindscrolltolower="loadMoreComments" lower-threshold="120" class="read-scroll" wx:if="{{!loading && !loadError && diary}}" show-scrollbar="{{false}}" enhanced>
|
||||
<view class="read-page">
|
||||
<view class="read-author"><image class="read-avatar" src="{{diary.creator_avatar || '/images/default-avatar.svg'}}" mode="aspectFill" /><view class="read-author-info"><text class="read-name">{{diary.creator_name || 'TA'}}</text><text class="read-date">{{diary.created_time}}</text><text class="read-location" wx:if="{{diary.location_text}}">{{diary.location_text}}</text></view><view class="read-menu" catchtap="onMoreTap" aria-label="日记操作"><image src="/images/more.svg" mode="aspectFit" /></view></view>
|
||||
<view class="read-paper">
|
||||
<!-- ===== 图片区:有图轮播,无图用背景替代 ===== -->
|
||||
<view wx:if="{{diary.imageUrls && diary.imageUrls.length > 0}}">
|
||||
<view class="img-box">
|
||||
<swiper class="img-swiper" circular="{{false}}" indicator-dots="{{false}}" bindchange="onCoverSwiperChange" current="{{coverSwiperIndex}}">
|
||||
<swiper-item wx:for="{{diary.imageUrls}}" wx:key="*this" class="img-slide">
|
||||
<image src="{{item}}" mode="aspectFill" class="img-item" catchtap="onImageTap" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view class="img-count" wx:if="{{diary.imageUrls.length > 1}}">
|
||||
<text>{{coverSwiperIndex + 1}}/{{diary.imageUrls.length}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- ===== 内容区:白色卡片 ===== -->
|
||||
<view class="content-card">
|
||||
|
||||
<!-- 标题 -->
|
||||
<text class="title-text" wx:if="{{diary.title}}">{{diary.title}}</text>
|
||||
|
||||
<!-- 正文 -->
|
||||
<text class="content-text" wx:if="{{diary.content}}">{{diary.content}}</text>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<!-- ===== 评论区 ===== -->
|
||||
<view class="comment-box">
|
||||
<view class="comment-head">
|
||||
<text class="comment-head-text">留言 {{diary.comment_count || 0}}</text>
|
||||
</view>
|
||||
|
||||
<view class="comment-empty" wx:if="{{comments.length === 0}}">
|
||||
<text>还没有留言,写下你读到这里的心情吧</text>
|
||||
</view>
|
||||
|
||||
<view class="comment-item" wx:for="{{comments}}" wx:key="id" wx:for-item="c"
|
||||
data-item="{{c}}" catchlongpress="onCommentLongPress" catchtap="onReplyTap">
|
||||
<image class="comment-avatar" src="{{c.avatar_url || '/images/default-avatar.svg'}}" mode="aspectFill" />
|
||||
<view class="comment-body">
|
||||
<view class="comment-top">
|
||||
<text class="comment-name">{{c.nickname || '匿名'}}</text>
|
||||
<text class="comment-date">{{c._time || ''}}</text>
|
||||
</view>
|
||||
<text class="comment-content" wx:if="{{!c.reply_to_username}}">{{c.content}}</text>
|
||||
<text class="comment-content" wx:else>
|
||||
<text>回复 </text>
|
||||
<text class="comment-at">@{{c.reply_to_username}}</text>
|
||||
<text>:{{c.content}}</text>
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="j-pagination" wx:if="{{commentsError}}" bindtap="loadComments">留言加载失败,点击重试</view>
|
||||
<view class="j-pagination" wx:elif="{{comments.length}}"><text wx:if="{{commentsLoadingMore}}">正在加载…</text><text wx:elif="{{commentsMoreError}}" bindtap="loadMoreComments">加载失败,点击重试</text><text wx:elif="{{hasMoreComments}}" bindtap="loadMoreComments">加载更多留言</text><text wx:else>已加载全部留言</text></view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 底部输入栏 -->
|
||||
<view class="bottom-bar" wx:if="{{!loading && !loadError && diary}}">
|
||||
<view class="bottom-input" catchtap="onCommentTap">
|
||||
<image class="bottom-input-icon" src="/images/comment.svg" mode="aspectFit" />
|
||||
<text class="bottom-input-text">说点什么...</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 评论面板自行跟随键盘,禁用原生页面上推,避免双重位移。 -->
|
||||
<view class="comment-compose-mask" wx:if="{{showCommentInput}}" catchtap="cancelComment" catchtouchmove="noop">
|
||||
<view class="comment-compose {{commentKeyboardHeight > 0 ? 'comment-compose--keyboard' : ''}}" style="bottom:{{commentKeyboardHeight}}px;" catchtap="noop">
|
||||
<view class="comment-compose-heading"><text>{{replyTo ? '回复 @' + replyTo.nickname : '写下你的留言'}}</text><text class="comment-compose-close" catchtap="cancelComment">收起</text></view>
|
||||
<view class="comment-compose-field">
|
||||
<textarea placeholder-class="handwritten-placeholder" class="comment-compose-input" style="height:{{commentEditorHeight}}px;" placeholder="说点什么,让 TA 知道你的心情…" value="{{commentInitialText}}" bindinput="onCommentInput" bindlinechange="onCommentLineChange" bindkeyboardheightchange="onCommentKeyboardHeight" bindblur="onCommentBlur" focus="{{commentFocus}}" fixed="{{true}}" adjust-position="{{false}}" hold-keyboard="{{true}}" show-confirm-bar="{{false}}" cursor-spacing="0" maxlength="500" disabled="{{commentSending}}" />
|
||||
</view>
|
||||
<view class="comment-compose-toolbar"><text class="comment-compose-count">{{commentLength}}/500</text><button class="comment-compose-send" catchtap="submitComment" disabled="{{commentLength === 0 || commentSending}}" loading="{{commentSending}}" hover-class="none">发送</button></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 图片预览 -->
|
||||
<view class="preview-mask" wx:if="{{showPreview}}" catchtap="closePreview">
|
||||
<swiper class="preview-swiper" current="{{previewIndex}}" bindchange="onPreviewSwiperChange" circular>
|
||||
<swiper-item wx:for="{{previewImages}}" wx:key="*this" class="preview-slide">
|
||||
<image src="{{item}}" mode="widthFix" class="preview-img" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view class="preview-num">{{previewIndex + 1}} / {{previewImages.length}}</view>
|
||||
<view class="preview-close" catchtap="closePreview">
|
||||
<image class="preview-close-icon" src="/images/close.svg" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
@@ -0,0 +1,33 @@
|
||||
@import '../../styles/common.wxss';
|
||||
@import '../../styles/design.wxss';
|
||||
@import '../../styles/journal.wxss';
|
||||
.read-scroll { position:fixed; top:var(--nav-height,64px); left:0; right:0; height:calc(100vh - var(--nav-height,64px) - 100rpx - env(safe-area-inset-bottom)); }
|
||||
.read-state { padding:28rpx 44rpx; }.read-page { padding:32rpx 44rpx 40rpx; }
|
||||
.read-author { display:flex; align-items:center; gap:16rpx; margin-bottom:28rpx; }.read-avatar { width:64rpx; height:64rpx; border-radius:50%; flex-shrink:0; }.read-author-info { flex:1; min-width:0; }.read-name { display:block; font-size:26rpx; font-weight:500; color:#352E2A; }.read-date { display:block; margin-top:6rpx; font-size:21rpx; color:#85776D; }.read-location { display:block; font-size:21rpx; color:#85776D; margin-top:6rpx; line-height:1.5; }
|
||||
.read-menu { width:64rpx; height:64rpx; display:flex; align-items:center; justify-content:center; flex-shrink:0; margin-right:-12rpx; }.read-menu image { width:36rpx; height:36rpx; }
|
||||
.read-paper { padding:12rpx; border:1rpx solid #E9DDD0; border-radius:6rpx 28rpx 6rpx 6rpx; background:#FFFDF8; }
|
||||
.img-box { width:100%; height:500rpx; position:relative; background:#F1EBE2; overflow:hidden; border-radius:3rpx 16rpx 3rpx 3rpx; }.img-swiper { width:100%; height:100%; }.img-slide { display:flex; align-items:center; justify-content:center; }.img-item { width:100%; height:100%; display:block; }
|
||||
.img-count { position:absolute; right:16rpx; bottom:16rpx; background:rgba(53,46,42,.6); color:#FFFDF8; padding:6rpx 14rpx; border-radius:10rpx; font-size:21rpx; }
|
||||
.content-card { padding:32rpx 24rpx 28rpx; }.title-text { display:block; font-size:34rpx; line-height:1.5; font-weight:600; color:#352E2A; margin-bottom:20rpx; }.content-text { display:block; font-size:29rpx; line-height:1.9; color:#4D423A; white-space:pre-wrap; overflow-wrap:break-word; }
|
||||
.comment-box { margin-top:38rpx; }.comment-head { padding-bottom:20rpx; border-bottom:1rpx solid #E9DDD0; }.comment-head-text { color:#352E2A; font-size:28rpx; font-weight:600; }.comment-empty { padding:44rpx 8rpx; text-align:center; font-size:24rpx; line-height:1.7; color:#85776D; }
|
||||
.comment-item { display:flex; align-items:flex-start; gap:14rpx; padding:24rpx 0; border-bottom:1rpx solid #E9DDD0; }.comment-item:last-child { border:0; }.comment-avatar { width:48rpx; height:48rpx; border-radius:50%; flex-shrink:0; }.comment-body { flex:1; min-width:0; }.comment-top { display:flex; justify-content:space-between; gap:12rpx; flex-wrap:wrap; margin-bottom:12rpx; }.comment-name { font-size:24rpx; color:#352E2A; font-weight:500; }.comment-date { font-size:20rpx; color:#A39386; }.comment-content { display:block; font-size:26rpx; line-height:1.65; color:#65594F; overflow-wrap:break-word; }.comment-at { color:#B74768; }
|
||||
.bottom-bar { position:fixed; left:0; right:0; bottom:0; z-index:20; background:#FFFDF8; border-top:1rpx solid #E9DDD0; padding:16rpx 44rpx calc(16rpx + env(safe-area-inset-bottom)); height:calc(100rpx + env(safe-area-inset-bottom)); box-sizing:border-box; }.bottom-input { display:flex; align-items:center; gap:14rpx; height:66rpx; border:1rpx solid #E9DDD0; background:#FAF5EE; padding:0 20rpx; border-radius:16rpx; }.bottom-input-icon { width:30rpx; height:30rpx; }.bottom-input-text { color:#85776D; font-size:25rpx; }
|
||||
.comment-compose-mask { position:fixed; inset:0; z-index:1200; background:rgba(53,46,42,.24); }
|
||||
.comment-compose { position:fixed; left:0; right:0; padding:22rpx 28rpx calc(20rpx + env(safe-area-inset-bottom)); box-sizing:border-box; border-radius:28rpx 28rpx 0 0; background:#FFFDF8; }
|
||||
.comment-compose--keyboard { padding-bottom:16rpx; }
|
||||
.comment-compose-heading { display:flex; align-items:center; justify-content:space-between; gap:20rpx; margin-bottom:16rpx; font-size:23rpx; line-height:1.5; color:#85776D; }
|
||||
.comment-compose-heading > text:first-child { flex:1; min-width:0; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }
|
||||
.comment-compose-close { flex-shrink:0; padding:8rpx 4rpx; color:#B74768; }
|
||||
.comment-compose-field { background:#FFF0F5; border-radius:22rpx; padding:20rpx 24rpx; }
|
||||
.comment-compose-input { display:block; width:100%; font-size:28rpx; line-height:1.6; color:#352E2A; }
|
||||
.comment-compose-toolbar { display:flex; align-items:center; justify-content:space-between; margin-top:14rpx; }
|
||||
.comment-compose-count { font-size:21rpx; color:#A39386; }
|
||||
.comment-compose-send { margin:0; min-width:124rpx; height:64rpx; padding:0 28rpx; border-radius:32rpx; background:#F47FA5; color:#FFF; font-size:25rpx; line-height:64rpx; }
|
||||
.comment-compose-send::after { border:0; }
|
||||
.comment-compose-send[disabled] { background:#F4E6EB; color:#A39386; }
|
||||
.preview-mask { position:fixed; top:0; left:0; right:0; bottom:0; z-index:9999; background:rgba(0,0,0,.95); }.preview-swiper { width:100%; height:100%; }.preview-slide { position:relative; }.preview-img { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:100%; display:block; }.preview-num { position:fixed; bottom:calc(44rpx + env(safe-area-inset-bottom)); left:0; right:0; text-align:center; color:#FFFDF8; font-size:25rpx; }.preview-close { position:fixed; top:var(--nav-height,64px); right:24rpx; width:72rpx; height:72rpx; display:flex; align-items:center; justify-content:center; }.preview-close-icon { width:34rpx; height:34rpx; filter:brightness(0) invert(1); }
|
||||
@media (max-width:350px) { .read-page { padding-left:32rpx; padding-right:32rpx; }.bottom-bar { padding-left:32rpx; padding-right:32rpx; } }
|
||||
|
||||
@import '../../styles/button-theme.wxss';
|
||||
|
||||
@import '../../styles/typography.wxss';
|
||||
Reference in New Issue
Block a user