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
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"navigationBarTitleText": "Attachments 聊天附件",
"disableScroll": true,
"usingComponents": {
"base": "./base",
"fileLoading": "./file-loading",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.skyline {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

与全局样式文件内容重复,可移除

display: flex;
flex-direction: column;
height: 100vh;

.scroll-view {
flex: 1;
height: 0;
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
<t-navbar class="demo-navbar" title="Attachments" leftArrow placeholder />
<view class="demo">
<t-demo-header
title="Attachments 文件附件"
desc="用于聊天场景中上传、预览和管理附件的组件。"
notice="渲染框架支持情况:WebView"
/>
<t-demo title="01 组件类型" desc="图片类型">
<base />
</t-demo>
<t-demo desc="文件类型">
<file />
</t-demo>
<t-demo title="02 组件状态" desc="图片类型加载状态">
<imageLoading />
</t-demo>
<t-demo desc="文件类型加载状态">
<fileLoading />
</t-demo>
<view class="skyline">
<t-navbar class="demo-navbar" title="Attachments" leftArrow placeholder />
<scroll-view scroll-y type="list" class="scroll-view">
<view class="demo">
<t-demo-header
title="Attachments 文件附件"
desc="用于聊天场景中上传、预览和管理附件的组件。"
notice="渲染框架支持情况:WebView"
/>
<t-demo title="01 组件类型" desc="图片类型">
<base />
</t-demo>
<t-demo desc="文件类型">
<file />
</t-demo>
<t-demo title="02 组件状态" desc="图片类型加载状态">
<imageLoading />
</t-demo>
<t-demo desc="文件类型加载状态">
<fileLoading />
</t-demo>
</view>
</scroll-view>
</view>
3 changes: 2 additions & 1 deletion packages/pro-components/chat/attachments/attachments.less
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

// 可滚动内容区域
&__scrollable {
height: 100%;
/* 移除固定高度设置,由动态绑定控制高度 */
display: flex;
align-items: center;
justify-content: flex-start;
Expand Down Expand Up @@ -80,6 +80,7 @@
&__files {
box-sizing: border-box;
margin-left: @attachments-file-margin;
display: inline-block;

&:first-of-type {
margin-left: 0;
Expand Down
33 changes: 33 additions & 0 deletions packages/pro-components/chat/attachments/attachments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,17 @@ export default class Attachments extends SuperComponent {
data = {
classPrefix: name,
files: [],
isSkyline: false,
scrollViewHeight: 0, // 新增:scroll-view的高度
};

observers = {
items() {
this.setFiles();
// 新增:文件列表变化时重新计算高度
wx.nextTick(() => {
this.getScrollViewHeight();
});
},
};

Expand All @@ -51,6 +57,13 @@ export default class Attachments extends SuperComponent {
this.handleRemove(item, index);
}
},
// 新增:图片加载完成回调
onImageLoad() {
// 图片加载完成后重新计算高度
wx.nextTick(() => {
this.getScrollViewHeight();
});
},
handleFileClick(item) {
if (this.data.imageViewer && item.fileType === 'image') {
wx.previewImage({
Expand All @@ -62,6 +75,20 @@ export default class Attachments extends SuperComponent {
handleRemove(item, index) {
this.triggerEvent('remove', { item, index });
},
// 修改:获取所有文件元素的最大高度
getScrollViewHeight() {
const query = this.createSelectorQuery();
query.selectAll('.t-attachments__files').boundingClientRect();
query.exec((res) => {
if (res[0] && res[0].length > 0) {
// 获取所有文件元素的最大高度
const maxFileHeight = Math.max(...res[0].map((rect) => rect.height));
this.setData({
scrollViewHeight: maxFileHeight,
});
}
});
},
renderDesc(item) {
const sizeInBytes = item.size || 0;
let formattedSize;
Expand Down Expand Up @@ -187,9 +214,15 @@ export default class Attachments extends SuperComponent {
this.data.renderIcon = this.renderIcon.bind(this);
this.data.renderFileType = this.renderFileType.bind(this);
this.data.renderExtension = this.renderExtension.bind(this);
// 检测 Skyline 模式
this.setData({ isSkyline: this.renderer === 'skyline' });
},
attached() {
this.setFiles();
// 新增:组件挂载时计算高度
wx.nextTick(() => {
this.getScrollViewHeight();
});
},
detached() {},
};
Expand Down
157 changes: 92 additions & 65 deletions packages/pro-components/chat/attachments/attachments.wxml
Original file line number Diff line number Diff line change
@@ -1,75 +1,102 @@
<wxs src="./attachments.wxs" module="_this" />
<wxs src="../../../components/common/utils.wxs" module="_" />

<!-- 图片文件模板 -->
<template name="image-item">
<view class="file-image {{classPrefix}}__file {{removable ? classPrefix + '__file--removable' : ''}}">
<block wx:if="{{item.status==='pending' || item.status==='fail' || item.status==='error'}}">
<view class="{{item.status}} {{classPrefix}}__file--{{item.status}}">
<t-loading theme="{{isSkyline ? 'spinner' : 'circular'}}" size="48rpx" />
</view>
</block>
<block wx:else>
<image
class="image"
src="{{item.url}}"
mode="{{_this.getImageMode(item)}}"
lazy-load="false"
style="{{inChat ? _this.imageStyle(item) : ''}}"
bindload="onImageLoad"
></image>
</block>
<view wx:if="{{removable}}" class="{{classPrefix}}__remove">
<t-icon data-index="{{index}}" name="multiply" size="16px" catchtap="onRemoveTap" />
</view>
</view>
</template>

<!-- 普通文件模板 -->
<template name="file-item">
<view class="file {{classPrefix}}__file {{removable ? classPrefix + '__file--removable' : ''}}">
<view class="image">
<block wx:if="{{item.status==='pending'}}">
<view class="loading {{classPrefix}}__file--pending">
<t-loading theme="{{isSkyline ? 'spinner' : 'circular'}}" size="48rpx" />
</view>
</block>
<block wx:elif="{{item.status==='fail'}}">
<view class="fail {{classPrefix}}__file--fail">
<t-loading theme="{{isSkyline ? 'spinner' : 'circular'}}" size="48rpx" />
</view>
</block>
<block wx:elif="{{item.status==='error'}}">
<view class="error {{classPrefix}}__file--error">
<t-loading theme="{{isSkyline ? 'spinner' : 'circular'}}" size="48rpx" />
</view>
</block>
<block wx:else>
<t-icon name="{{item.fileIcon.name}}" color="{{item.fileIcon.color}}" size="48rpx"></t-icon>
</block>
</view>
<view class="{{classPrefix}}__content">
<view class="{{classPrefix}}__title">{{item.name}}</view>
<view wx:if="{{item.status==='pending'}}" class="{{classPrefix}}__desc">上传中...{{item.progress || 0+"%"}}</view>
<view wx:elif="{{item.status==='fail'}}" class="{{classPrefix}}__desc">上传失败</view>
<view wx:elif="{{item.status==='error'}}" class="{{classPrefix}}__desc">{{item.errorMessage}}</view>
<view wx:else class="{{classPrefix}}__desc">{{item.desc}}</view>
</view>
<view wx:if="{{removable}}" class="{{classPrefix}}__remove">
<t-icon data-index="{{index}}" name="multiply" size="16px" catchtap="onRemoveTap" />
</view>
</view>
</template>

<view
class="{{classPrefix}} {{[inChat ? classPrefix + '--chatting' : '', _this.getFileTypeClass(inChat, files)]}}"
style="{{_._style([style, customStyle])}}"
>
<view class="{{classPrefix}}__left">
<view class="{{classPrefix}}__scrollable scroll-x">
<block wx:for="{{files}}" wx:for-item="item" wx:for-index="index" wx:key="index">
<view class="{{classPrefix}}__files" bindtap="onFileWrapTap" data-index="{{index}}">
<block wx:if="{{item.fileType==='image'}}">
<view class="file-image {{classPrefix}}__file {{removable ? classPrefix + '__file--removable' : ''}}">
<block wx:if="{{item.status==='pending' || item.status==='fail' || item.status==='error'}}">
<view class="{{item.status}} {{classPrefix}}__file--{{item.status}}">
<t-loading theme="circular" size="48rpx" />
</view>
</block>
<block wx:else>
<image
class="image"
src="{{item.url}}"
mode="{{_this.getImageMode(item)}}"
lazy-load="false"
style="{{inChat ? _this.imageStyle(item) : ''}}"
></image>
</block>
<view wx:if="{{removable}}" class="{{classPrefix}}__remove">
<t-icon data-index="{{index}}" name="multiply" size="16px" catchtap="onRemoveTap" />
</view>
</view>
</block>
<block wx:else>
<view class="file {{classPrefix}}__file {{removable ? classPrefix + '__file--removable' : ''}}">
<view class="image">
<block wx:if="{{item.status==='pending'}}">
<view class="loading {{classPrefix}}__file--pending">
<t-loading theme="circular" size="48rpx" />
</view>
</block>
<block wx:elif="{{item.status==='fail'}}">
<view class="fail {{classPrefix}}__file--fail">
<t-loading theme="circular" size="48rpx" />
</view>
</block>
<block wx:elif="{{item.status==='error'}}">
<view class="error {{classPrefix}}__file--error">
<t-loading theme="circular" size="48rpx" />
</view>
</block>
<block wx:else>
<t-icon name="{{item.fileIcon.name}}" color="{{item.fileIcon.color}}" size="48rpx"></t-icon>
</block>
</view>
<view class="{{classPrefix}}__content">
<view class="{{classPrefix}}__title">{{item.name}}</view>
<block>
<view wx:if="{{item.status==='pending'}}" class="{{classPrefix}}__desc"
>上传中...{{item.progress || 0+"%"}}</view
>
<view wx:elif="{{item.status==='fail'}}" class="{{classPrefix}}__desc">上传失败</view>
<view wx:elif="{{item.status==='error'}}" class="{{classPrefix}}__desc">{{item.errorMessage}}</view>
<view wx:else class="{{classPrefix}}__desc">{{item.desc}}</view>
</block>
</view>
<view wx:if="{{removable}}" class="{{classPrefix}}__remove">
<t-icon data-index="{{index}}" name="multiply" size="16px" catchtap="onRemoveTap" />
</view>
</view>
</block>
</view>
</block>
</view>
<!-- 对话模式:图片横向滚动,文件纵向排列 -->
<block wx:if="{{inChat}}">
<!-- 图片横向滚动区域 -->
<scroll-view wx:if="{{_this.hasImageFile(files)}}" class="{{classPrefix}}__scrollable scroll-x" scroll-x style="height: {{scrollViewHeight}}px">
<block wx:for="{{files}}" wx:for-item="item" wx:for-index="index" wx:key="index">
<view wx:if="{{item.fileType==='image'}}" class="{{classPrefix}}__files" bindtap="onFileWrapTap" data-index="{{index}}">
<template is="image-item" data="{{item, index, classPrefix, removable, isSkyline, inChat}}" />
</view>
</block>
</scroll-view>

<!-- 非图片文件纵向排列 -->
<view class="{{classPrefix}}__files-container">
<block wx:for="{{files}}" wx:for-item="item" wx:for-index="index" wx:key="index">
<view wx:if="{{item.fileType!=='image'}}" class="{{classPrefix}}__files" bindtap="onFileWrapTap" data-index="{{index}}">
<template is="file-item" data="{{item, index, classPrefix, removable, isSkyline}}" />
</view>
</block>
</view>
</block>

<!-- 非对话模式:所有文件横向滚动 -->
<block wx:else>
<scroll-view class="{{classPrefix}}__scrollable scroll-x" scroll-x style="height: {{scrollViewHeight}}px">
<block wx:for="{{files}}" wx:for-item="item" wx:for-index="index" wx:key="index">
<view class="{{classPrefix}}__files" bindtap="onFileWrapTap" data-index="{{index}}">
<template wx:if="{{item.fileType==='image'}}" is="image-item" data="{{item, index, classPrefix, removable, isSkyline, inChat}}" />
<template wx:else is="file-item" data="{{item, index, classPrefix, removable, isSkyline}}" />
</view>
</block>
</scroll-view>
</block>
</view>
</view>
17 changes: 17 additions & 0 deletions packages/pro-components/chat/attachments/attachments.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,25 @@ function getFileTypeClass(inChat, files) {
return allImages ? 'all_images' : 'all_files';
}

function hasImageFile(files) {
// 如果 files 为空或不存在,返回 false
if (!files || files.length === 0) {
return false;
}

// 检查是否存在至少一个图片文件
for (var i = 0; i < files.length; i++) {
if (files[i].fileType === 'image') {
return true;
}
}

return false;
}

module.exports = {
imageStyle: imageStyle,
getImageMode: getImageMode,
getFileTypeClass: getFileTypeClass,
hasImageFile: hasImageFile,
};
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@
border-right: 2rpx solid @component-stroke;
background-color: unset;
outline: none;
border: none;
border-radius: 0;
line-height: inherit;

&:after {
display: none;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"navigationBarTitleText": "ChatContent",
"disableScroll": true,
"usingComponents": {
"base": "./base"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.skyline {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上

display: flex;
flex-direction: column;
height: 100vh;

.scroll-view {
flex: 1;
height: 0;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
<t-navbar class="demo-navbar" title="ChatContent" leftArrow placeholder />
<view class="demo">
<t-demo-header title="ChatContent 对话正文" desc="支持 markdown 格式的渲染。" notice="渲染框架支持情况:WebView" />
<t-demo title="01 组件类型">
<base />
</t-demo>
<view class="skyline">
<t-navbar class="demo-navbar" title="ChatContent" leftArrow placeholder />
<scroll-view scroll-y type="list" class="scroll-view">
<view class="demo">
<t-demo-header
title="ChatContent 对话正文"
desc="支持 markdown 格式的渲染。"
notice="渲染框架支持情况:WebView"
/>
<t-demo title="01 组件类型">
<base />
</t-demo>
</view>
</scroll-view>
</view>
Loading
Loading