mirror of
https://github.com/TangSengDaoDao/TangSengDaoDaoWeb
synced 2025-06-03 07:43:32 +00:00
feat:图片上传展示进度
This commit is contained in:
parent
13fed127d7
commit
3bf051acc9
25
packages/tsdaodaobase/src/Messages/Image/index.css
Normal file
25
packages/tsdaodaobase/src/Messages/Image/index.css
Normal file
@ -0,0 +1,25 @@
|
||||
@keyframes loading {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.loading-box{
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
position:absolute;
|
||||
top:50%;
|
||||
left:50%;
|
||||
transform:translate(-16px,-16px);
|
||||
}
|
||||
.loading-icon{
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
animation: loading 1s linear infinite;
|
||||
}
|
||||
.loading-text{
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
}
|
@ -1,124 +1,172 @@
|
||||
import { MediaMessageContent } from "wukongimjssdk"
|
||||
import React from "react"
|
||||
import WKApp from "../../App"
|
||||
import { MessageContentTypeConst } from "../../Service/Const"
|
||||
import MessageBase from "../Base"
|
||||
import { MessageCell } from "../MessageCell"
|
||||
import Viewer from 'react-viewer';
|
||||
|
||||
|
||||
import WKSDK, { MediaMessageContent, Task } from "wukongimjssdk";
|
||||
import React from "react";
|
||||
import WKApp from "../../App";
|
||||
import { MessageContentTypeConst } from "../../Service/Const";
|
||||
import MessageBase from "../Base";
|
||||
import { MessageCell } from "../MessageCell";
|
||||
import Viewer from "react-viewer";
|
||||
import "./index.css";
|
||||
export class ImageContent extends MediaMessageContent {
|
||||
width!: number
|
||||
height!: number
|
||||
url!: string
|
||||
imgData?: string
|
||||
constructor(file?: File, imgData?: string, width?: number, height?: number) {
|
||||
super()
|
||||
this.file = file
|
||||
this.imgData = imgData
|
||||
this.width = width || 0
|
||||
this.height = height || 0
|
||||
}
|
||||
decodeJSON(content: any) {
|
||||
this.width = content["width"] || 0
|
||||
this.height = content["height"] || 0
|
||||
this.url = content["url"] || ''
|
||||
this.remoteUrl = this.url
|
||||
}
|
||||
encodeJSON() {
|
||||
return { "width": this.width || 0, "height": this.height || 0, "url": this.remoteUrl || "" }
|
||||
}
|
||||
get contentType() {
|
||||
return MessageContentTypeConst.image
|
||||
}
|
||||
get conversationDigest() {
|
||||
return "[图片]"
|
||||
}
|
||||
width!: number;
|
||||
height!: number;
|
||||
url!: string;
|
||||
imgData?: string;
|
||||
constructor(file?: File, imgData?: string, width?: number, height?: number) {
|
||||
super();
|
||||
this.file = file;
|
||||
this.imgData = imgData;
|
||||
this.width = width || 0;
|
||||
this.height = height || 0;
|
||||
}
|
||||
decodeJSON(content: any) {
|
||||
this.width = content["width"] || 0;
|
||||
this.height = content["height"] || 0;
|
||||
this.url = content["url"] || "";
|
||||
this.remoteUrl = this.url;
|
||||
}
|
||||
encodeJSON() {
|
||||
return { width: this.width || 0, height: this.height || 0, url: this.remoteUrl || "" };
|
||||
}
|
||||
get contentType() {
|
||||
return MessageContentTypeConst.image;
|
||||
}
|
||||
get conversationDigest() {
|
||||
return "[图片]";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface ImageCellState {
|
||||
showPreview: boolean
|
||||
showPreview: boolean;
|
||||
loading: boolean;
|
||||
progress: number;
|
||||
}
|
||||
|
||||
export class ImageCell extends MessageCell<any, ImageCellState> {
|
||||
taskListener!: any;
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.state = {
|
||||
showPreview: false,
|
||||
loading: false,
|
||||
progress: 0,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props: any) {
|
||||
super(props)
|
||||
this.state = {
|
||||
showPreview: false,
|
||||
imageScale(orgWidth: number, orgHeight: number, maxWidth = 250, maxHeight = 250) {
|
||||
let actSize = { width: orgWidth, height: orgHeight };
|
||||
if (orgWidth > orgHeight) {
|
||||
//横图
|
||||
if (orgWidth > maxWidth) {
|
||||
// 横图超过最大宽度
|
||||
let rate = maxWidth / orgWidth; // 缩放比例
|
||||
actSize.width = maxWidth;
|
||||
actSize.height = orgHeight * rate;
|
||||
}
|
||||
} else if (orgWidth < orgHeight) {
|
||||
//竖图
|
||||
if (orgHeight > maxHeight) {
|
||||
let rate = maxHeight / orgHeight; // 缩放比例
|
||||
actSize.width = orgWidth * rate;
|
||||
actSize.height = maxHeight;
|
||||
}
|
||||
} else if (orgWidth === orgHeight) {
|
||||
if (orgWidth > maxWidth) {
|
||||
let rate = maxWidth / orgWidth; // 缩放比例
|
||||
actSize.width = maxWidth;
|
||||
actSize.height = orgHeight * rate;
|
||||
}
|
||||
}
|
||||
return actSize;
|
||||
}
|
||||
|
||||
getImageSrc(content: ImageContent) {
|
||||
if (content.url && content.url !== "") {
|
||||
// 等待发送的消息
|
||||
let downloadURL = WKApp.dataSource.commonDataSource.getImageURL(content.url, {
|
||||
width: content.width,
|
||||
height: content.height,
|
||||
});
|
||||
if (downloadURL.indexOf("?") != -1) {
|
||||
downloadURL += "&filename=image.png";
|
||||
} else {
|
||||
downloadURL += "?filename=image.png";
|
||||
}
|
||||
return downloadURL;
|
||||
}
|
||||
return content.imgData;
|
||||
}
|
||||
|
||||
getImageElement() {
|
||||
const { message } = this.props;
|
||||
const content = message.content as ImageContent;
|
||||
let scaleSize = this.imageScale(content.width, content.height);
|
||||
if (!this.taskListener && !content?.url) {
|
||||
this.taskListener = (task: Task) => {
|
||||
this.setState({
|
||||
loading: true,
|
||||
progress: Math.trunc(task.progress() * 100),
|
||||
});
|
||||
if (task.progress() === 1) {
|
||||
this.setState({
|
||||
loading: false,
|
||||
progress: 100,
|
||||
});
|
||||
WKSDK.shared().taskManager.removeListener(this.taskListener);
|
||||
}
|
||||
};
|
||||
WKSDK.shared().taskManager.addListener(this.taskListener);
|
||||
}
|
||||
return (
|
||||
<div style={{ position: "relative" }}>
|
||||
<img
|
||||
alt=""
|
||||
src={this.getImageSrc(content)}
|
||||
style={{ borderRadius: "5px", width: scaleSize.width, height: scaleSize.height }}
|
||||
/>
|
||||
{this.state.loading && scaleSize.width > 32 && (
|
||||
<i className="loading-box">
|
||||
<img className="loading-icon" src={require("../../assets/loading.png")} alt="" />
|
||||
{scaleSize.height > 46 && <p className="loading-text">{this.state.progress}%</p>}
|
||||
</i>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
imageScale(orgWidth: number, orgHeight: number, maxWidth = 250, maxHeight = 250) {
|
||||
let actSize = { width: orgWidth, height: orgHeight };
|
||||
if (orgWidth > orgHeight) {//横图
|
||||
if (orgWidth > maxWidth) { // 横图超过最大宽度
|
||||
let rate = maxWidth / orgWidth; // 缩放比例
|
||||
actSize.width = maxWidth;
|
||||
actSize.height = orgHeight * rate;
|
||||
}
|
||||
} else if (orgWidth < orgHeight) { //竖图
|
||||
if (orgHeight > maxHeight) {
|
||||
let rate = maxHeight / orgHeight; // 缩放比例
|
||||
actSize.width = orgWidth * rate;
|
||||
actSize.height = maxHeight;
|
||||
}
|
||||
} else if (orgWidth === orgHeight) {
|
||||
if (orgWidth > maxWidth) {
|
||||
let rate = maxWidth / orgWidth; // 缩放比例
|
||||
actSize.width = maxWidth;
|
||||
actSize.height = orgHeight * rate;
|
||||
}
|
||||
}
|
||||
return actSize;
|
||||
}
|
||||
|
||||
getImageSrc(content: ImageContent) {
|
||||
if (content.url && content.url !== "") { // 等待发送的消息
|
||||
let downloadURL = WKApp.dataSource.commonDataSource.getImageURL(content.url, { width: content.width, height: content.height })
|
||||
if (downloadURL.indexOf("?") != -1) {
|
||||
downloadURL += "&filename=image.png"
|
||||
} else {
|
||||
downloadURL += "?filename=image.png"
|
||||
}
|
||||
return downloadURL
|
||||
}
|
||||
return content.imgData
|
||||
}
|
||||
|
||||
getImageElement() {
|
||||
const { message } = this.props
|
||||
const content = message.content as ImageContent
|
||||
let scaleSize = this.imageScale(content.width, content.height);
|
||||
return <img alt="" src={this.getImageSrc(content)} style={{ borderRadius: '5px', width: scaleSize.width, height: scaleSize.height }} />
|
||||
}
|
||||
|
||||
render() {
|
||||
const { message, context } = this.props
|
||||
const { showPreview } = this.state
|
||||
const content = message.content as ImageContent
|
||||
let scaleSize = this.imageScale(content.width, content.height);
|
||||
const imageURL = this.getImageSrc(content) || ""
|
||||
return <MessageBase context={context} message={message}>
|
||||
<div style={{ width: scaleSize.width, height: scaleSize.height, cursor: "pointer" }} onClick={() => {
|
||||
this.setState({
|
||||
showPreview: !this.state.showPreview,
|
||||
})
|
||||
}}>
|
||||
{this.getImageElement()}
|
||||
</div>
|
||||
<Viewer
|
||||
visible={showPreview}
|
||||
noImgDetails={true}
|
||||
downloadable={true}
|
||||
rotatable={false}
|
||||
changeable={false}
|
||||
showTotal={false}
|
||||
onMaskClick={() => { this.setState({ showPreview: false }); }}
|
||||
onClose={() => { this.setState({ showPreview: false }); }}
|
||||
images={[{ src: imageURL, alt: '', downloadUrl: imageURL }]}
|
||||
/>
|
||||
</MessageBase>
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const { message, context } = this.props;
|
||||
const { showPreview } = this.state;
|
||||
const content = message.content as ImageContent;
|
||||
let scaleSize = this.imageScale(content.width, content.height);
|
||||
const imageURL = this.getImageSrc(content) || "";
|
||||
return (
|
||||
<MessageBase context={context} message={message}>
|
||||
<div
|
||||
style={{ width: scaleSize.width, height: scaleSize.height, cursor: "pointer" }}
|
||||
onClick={() => {
|
||||
this.setState({
|
||||
showPreview: !this.state.showPreview,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{this.getImageElement()}
|
||||
</div>
|
||||
<Viewer
|
||||
visible={showPreview}
|
||||
noImgDetails={true}
|
||||
downloadable={true}
|
||||
rotatable={false}
|
||||
changeable={false}
|
||||
showTotal={false}
|
||||
onMaskClick={() => {
|
||||
this.setState({ showPreview: false });
|
||||
}}
|
||||
onClose={() => {
|
||||
this.setState({ showPreview: false });
|
||||
}}
|
||||
images={[{ src: imageURL, alt: "", downloadUrl: imageURL }]}
|
||||
/>
|
||||
</MessageBase>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
BIN
packages/tsdaodaobase/src/assets/loading.png
Normal file
BIN
packages/tsdaodaobase/src/assets/loading.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.1 KiB |
@ -18,10 +18,13 @@ export class MediaMessageUploadTask extends MessageTask {
|
||||
async start(): Promise<void> {
|
||||
const mediaContent = this.message.content as MediaMessageContent
|
||||
if(mediaContent.file) {
|
||||
const fileNameSuffix = mediaContent.file.name.substring(
|
||||
mediaContent.file.name.lastIndexOf(".")
|
||||
);
|
||||
const param = new FormData();
|
||||
param.append("file", mediaContent.file);
|
||||
const fileName = this.getUUID();
|
||||
const path = `/${this.message.channel.channelType}/${this.message.channel.channelID}/${fileName}${mediaContent.extension??""}`
|
||||
const path = `/${this.message.channel.channelType}/${this.message.channel.channelID}/${fileName}${fileNameSuffix ?? ""}`;
|
||||
const uploadURL = await this.getUploadURL(path)
|
||||
if(uploadURL) {
|
||||
this.uploadFile(mediaContent.file,uploadURL)
|
||||
@ -52,7 +55,7 @@ export class MediaMessageUploadTask extends MessageTask {
|
||||
this.canceler = c
|
||||
}),
|
||||
onUploadProgress: e => {
|
||||
var completeProgress = ((e.loaded / e.total) | 0);
|
||||
var completeProgress = ((e.loaded / e.total) || 0);
|
||||
this._progress = completeProgress
|
||||
this.update()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user