Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/pro-components/chat/chat-actionbar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ comment | String | - | 评价内容 | N
content | String | - | 被复制的内容 | N
copy-mode | String | markdown | 【实验】复制内容的模式,可选 'markdown'(复制markdown原文)或 'text'(复制纯文本)。可选项:markdown/text | N
disabled | Boolean | false | 【讨论中】操作按钮是否可点击 | N
placement | String | start | 【实验】操作栏位置。可选项:start/end/space-around/space-between | N
long-press-position | Object | - | 【实验】长按触发点的位置信息,用于定位 popover。TS 类型:`{pageX: number; pageY: number; clientX: number; clientY: number; x: number; y: number}` | N
placement | String | start | 【实验】操作栏位置。可选项:start/end/space-around/space-between/longpress | N

### ChatActionbar Events

名称 | 参数 | 描述
-- | -- | --
actions | `(detail: {name: string, active: boolean})` | 点击点赞,点踩,复制,分享,重新生成按钮时触发发
actions | `(detail: {name: string, active: boolean, chatId: string})` | 点击点赞,点踩,复制,分享,重新生成按钮时触发发
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"component": true,
"styleIsolation": "apply-shared",
"usingComponents": {
"t-icon": "tdesign-miniprogram/icon/icon"
"t-icon": "tdesign-miniprogram/icon/icon",
"t-popover": "tdesign-miniprogram/popover/popover"
}
}
}
67 changes: 54 additions & 13 deletions packages/pro-components/chat/chat-actionbar/chat-actionbar.less
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@
@chat-actionbar-item-padding: var(--chat-actionbar-item-padding, 16rpx 28rpx);
@chat-actionbar-item-color: @text-color-primary;
@chat-actionbar-item-active: @brand-color;
@chat-actionbar-item-gap: 4rpx;

// TODO: 长按弹出层样式
@chat-actionbar-popover-background: @mask-active;
@chat-actionbar-popover-radius: 32rpx;
@chat-actionbar-popover-padding: 45rpx;
@chat-actionbar-popover-background: rgba(0, 0, 0, 0.9);
@chat-actionbar-popover-radius: 6rpx;
@chat-actionbar-popover-padding: 8rpx 16rpx;
@chat-actionbar-popover-inner-size: 20rpx;
@chat-actionbar-popover-item-width: 128rpx;
@chat-actionbar-popover-item-height: 156rpx;
@chat-actionbar-popover-item-gap: 8rpx;
@chat-actionbar-popover-item-inner-gap: 8rpx;

.@{chat-actionbar} {
display: flex;
Expand All @@ -25,6 +31,40 @@
justify-content: flex-end;
}

// 弹出层
&--popover {
color: @font-white-1;
border-radius: @chat-actionbar-popover-radius;

.@{chat-actionbar}__inner {
background-color: unset;
border: none;
display: flex;
flex-wrap: wrap;
gap: @chat-actionbar-item-gap;

&--column {
gap: @chat-actionbar-popover-item-gap;
}
}

.@{chat-actionbar}__item--popover {
color: #fff;
background-color: unset;
padding: 0;
margin: 0;
font-size: 28rpx;
line-height: 42rpx;
width: @chat-actionbar-popover-item-width;
height: @chat-actionbar-popover-item-height;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: @chat-actionbar-popover-item-inner-gap;
}
}

// 内部容器
&__inner {
background-color: @bg-color-secondarycontainer;
Expand All @@ -42,14 +82,6 @@
align-items: center;
justify-content: space-between;
}

// 弹出层
&--popover {
padding: @chat-actionbar-popover-padding;
background-color: @chat-actionbar-popover-background;
border-radius: @chat-actionbar-popover-radius;
color: @font-white-1;
}
}

// 左侧内容
Expand All @@ -62,8 +94,7 @@
// 操作项
&__item {
color: @chat-actionbar-item-color;
margin: 12rpx 0;
padding: 4rpx 28rpx;
padding: @chat-actionbar-item-padding;
border-right: 2rpx solid @component-stroke;
background-color: unset;
outline: none;
Expand All @@ -81,4 +112,14 @@
color: @chat-actionbar-item-active;
}
}

&__popover-skeleton {
position: fixed;
--td-popover-padding: @chat-actionbar-popover-padding;

&__inner {
width: @chat-actionbar-popover-inner-size;
height: @chat-actionbar-popover-inner-size;
}
}
}
124 changes: 107 additions & 17 deletions packages/pro-components/chat/chat-actionbar/chat-actionbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const name = `${prefix}-chat-actionbar`;
export default class ChatActionbar extends SuperComponent {
options: ComponentsOptionsType = {
multipleSlots: true,
styleIsolation: 'shared',
};

properties = props;
Expand All @@ -23,22 +24,34 @@ export default class ChatActionbar extends SuperComponent {
replay: 'refresh',
copy: 'copy',
share: 'share-1',
quote: 'enter',
},
iconActiveMap: {
good: 'thumb-up-filled',
bad: 'thumb-down-filled',
},
widthStyle: '',
popoverStyle: 'transition: none;position: fixed;',
popoverPosition: '',
longpressVisible: false,
};

observers = {
comment(newVal) {
this.setData({
pComment: newVal || '',
});
this.setPComment(newVal);
},
'actionBar, pComment'() {
'actionBar, pComment, placement'() {
this.setActions();
},
longPressPosition(newVal) {
if (this.properties.placement === 'longpress') {
if (newVal) {
this.showPopover(newVal);
} else {
this.hidePopover();
}
}
},
};

methods = {
Expand Down Expand Up @@ -95,6 +108,7 @@ export default class ChatActionbar extends SuperComponent {
this.triggerEvent('actions', {
name,
active: !isActive,
chatId: this.properties.chatId,
});
} else if (name === 'bad') {
const isActive = this.data.pComment === 'bad';
Expand All @@ -104,12 +118,15 @@ export default class ChatActionbar extends SuperComponent {
this.triggerEvent('actions', {
name,
active: !isActive,
chatId: this.properties.chatId,
});
} else {
this.triggerEvent('actions', {
name,
chatId: this.properties.chatId,
});
}
this.onVisibleChange({ detail: { visible: false } });
},

handleCopy() {
Expand All @@ -123,25 +140,95 @@ export default class ChatActionbar extends SuperComponent {
},

setActions() {
const text = {
replay: '刷新',
copy: '复制',
good: '点赞',
bad: '点踩',
share: '分享',
quote: '引用',
};

const baseActions = [];
if (Array.isArray(this.properties.actionBar)) {
this.properties.actionBar.forEach((item) => {
if (item === 'good' || item === 'bad') {
baseActions.push({
name: item,
isActive: this.data.pComment === item,
});
} else {
baseActions.push({
name: item,
isActive: false,
let dataActions = [];
if (this.properties.placement === 'longpress') {
dataActions = ['quote', 'copy', 'share'];
} else if (Array.isArray(this.properties.actionBar)) {
dataActions = this.properties.actionBar;
}
dataActions.forEach((item) => {
if (item === 'good' || item === 'bad') {
baseActions.push({
name: item,
isActive: this.data.pComment === item,
text: text[item] || item,
});
} else {
baseActions.push({
name: item,
isActive: false,
text: text[item] || item,
});
}
});
this.setData({
actions: baseActions,
});
},

setPComment(newVal) {
this.setData({
pComment: newVal || '',
});
},

showPopover(pos) {
this.setData({
widthStyle: `width: ${this.data.actions.length * 128 + (this.data.actions.length - 1) * 8}rpx`,
popoverPosition: `top:${pos.y}px;left:${pos.x}px`,
longpressVisible: true,
});

setTimeout(() => {
const child = this.selectComponent('.popover');
const query = this.createSelectorQuery().in(child);

query.select('.t-popover').boundingClientRect();
query.exec((res) => {
const [rect] = res;

// 新增:检查元素是否超出屏幕宽度
const { screenWidth } = wx.getWindowInfo();
const elementRightEdge = rect.left + rect.width;

if (elementRightEdge > screenWidth) {
this.setData({
popoverStyle: `transition: none;position:fixed; left: unset !important; right: 16rpx !important;`,
});
} else if (rect.left <= 0) {
this.setData({ popoverStyle: `transition: none;position:fixed; left: 16rpx !important;` });
}
});
}
}, 200);
},

hidePopover() {
this.onVisibleChange({ detail: { visible: false } });
},

onVisibleChange(e) {
const { visible } = e.detail;
this.setData({
actions: baseActions,
longpressVisible: visible,
});
if (!visible) {
setTimeout(() => {
this.setData({
popoverPosition: '',
popoverStyle: 'transition: none;position: fixed;',
});
}, 200);
}
},
};

Expand All @@ -150,6 +237,9 @@ export default class ChatActionbar extends SuperComponent {
this.data.filterSpecialChars = this.filterSpecialChars.bind(this);
this.data.handleActionClick = this.handleActionClick.bind(this);
this.data.handleCopy = this.handleCopy.bind(this);
this.data.showPopover = this.showPopover.bind(this);
this.data.hidePopover = this.hidePopover.bind(this);
this.data.setPComment = this.setPComment.bind(this);
},

attached() {
Expand Down
Loading
Loading