feat(fe): 评论改成小红书那套交互——点评论直接唤起输入
上一版做成了居中弹窗,参考图给的是另一种范式:输入栏常驻底部,点任意 一条评论就把它激活并填上「回复 @xxx」。按参考图重做,居中那套一并删掉, 不留死代码。 结构从「一个滚动容器装所有东西」改成三段式: 固定头(共 N 条评论)+ 滚动列表 + 常驻输入栏 输入栏必须在滚动区外——放进去的话列表一滚它就跟着走,点完评论还得再 把输入框找回来,正是这次要解决的问题。 交互: - 点评论或回复的任意位置 → 输入框获得焦点,placeholder 变「回复 @xxx」, 上方出现可取消的橙色提示条。不用再单独点一个「回复」按钮 - 删除从长按改成显式的「删除」文字,只在自己的评论上出现——长按是 隐藏交互,没人会发现 - 回复带首字头像并缩进一层,「甲 回复 乙」的指向关系显示在昵称行 键盘处理用 adjust-position=false + bindfocus 拿键盘高度自己顶:弹层是 fixed 定位,交给系统调整会把整块推出屏幕。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -117,9 +117,11 @@ Component({
|
||||
proInfo: null,
|
||||
saving: false,
|
||||
posterSaving: false,
|
||||
centered: false,
|
||||
commentImages: [],
|
||||
replyTo: {},
|
||||
cmFocus: false,
|
||||
kbHeight: 0,
|
||||
total: 0,
|
||||
},
|
||||
observers: {
|
||||
show: function (show) {
|
||||
@@ -139,8 +141,7 @@ Component({
|
||||
methods: {
|
||||
setType(type, fresh) {
|
||||
const pet = store.getPet();
|
||||
// 评论以输入为主,贴底弹层会被键盘顶掉大半屏,改成居中
|
||||
const patch = { innerType: type, pet, centered: type === 'comments' };
|
||||
const patch = { innerType: type, pet };
|
||||
if (fresh) {
|
||||
patch.segSel = {};
|
||||
patch.optSel = {};
|
||||
@@ -167,6 +168,8 @@ Component({
|
||||
patch.commentText = '';
|
||||
patch.commentImages = [];
|
||||
patch.replyTo = {};
|
||||
patch.cmFocus = false;
|
||||
patch.kbHeight = 0;
|
||||
patch.riskData = null;
|
||||
patch.saving = false;
|
||||
}
|
||||
@@ -413,13 +416,18 @@ Component({
|
||||
api.listComments(this.data.postId)
|
||||
.then((page) =>
|
||||
this.setData({
|
||||
total: page.total || 0,
|
||||
comments: (page.list || []).map((c) => ({
|
||||
...c,
|
||||
timeText: fmtAgo(c.created_at),
|
||||
// 没有头像字段,用昵称首字做个色块,比一律显示同一个 emoji 强
|
||||
initial: (c.author_name || '?').slice(0, 1),
|
||||
imgs: Array.isArray(c.images) ? c.images : [],
|
||||
replies: (c.replies || []).map((r) => ({ ...r, timeText: fmtAgo(r.created_at) })),
|
||||
replies: (c.replies || []).map((r) => ({
|
||||
...r,
|
||||
timeText: fmtAgo(r.created_at),
|
||||
initial: (r.author_name || '?').slice(0, 1),
|
||||
})),
|
||||
})),
|
||||
}),
|
||||
)
|
||||
@@ -965,9 +973,20 @@ Component({
|
||||
});
|
||||
},
|
||||
// 回复某条评论:输入区顶部显示「回复 xxx」,发送时带上 parent_id
|
||||
// 小红书那套:点任意一条评论/回复,直接把输入框激活并填上「回复 @xxx」,
|
||||
// 不用再去底部找输入框、也不用单独点一个「回复」按钮
|
||||
onReplyTo(e) {
|
||||
const { id, name } = e.currentTarget.dataset;
|
||||
this.setData({ replyTo: { id, name } });
|
||||
if (!id) return;
|
||||
this.setData({ replyTo: { id, name }, cmFocus: true });
|
||||
},
|
||||
onCommentFocus(e) {
|
||||
// adjust-position=false,键盘高度自己接管:弹层是 fixed 定位,
|
||||
// 交给系统顶会把整块推出屏幕
|
||||
this.setData({ kbHeight: (e.detail && e.detail.height) || 0 });
|
||||
},
|
||||
onCommentBlur() {
|
||||
this.setData({ kbHeight: 0, cmFocus: false });
|
||||
},
|
||||
onCancelReply() {
|
||||
this.setData({ replyTo: {} });
|
||||
@@ -979,7 +998,11 @@ Component({
|
||||
.listReplies(id)
|
||||
.then((list) =>
|
||||
this.setData({
|
||||
[`comments[${index}].replies`]: (list || []).map((r) => ({ ...r, timeText: fmtAgo(r.created_at) })),
|
||||
[`comments[${index}].replies`]: (list || []).map((r) => ({
|
||||
...r,
|
||||
timeText: fmtAgo(r.created_at),
|
||||
initial: (r.author_name || '?').slice(0, 1),
|
||||
})),
|
||||
}),
|
||||
)
|
||||
.catch((err) => wx.showToast({ title: (err && err.message) || '加载失败', icon: 'none' }));
|
||||
|
||||
Reference in New Issue
Block a user