From 3bf051acc91c896f2a927fec963147ffdfae267f Mon Sep 17 00:00:00 2001 From: lililemon Date: Wed, 29 May 2024 17:09:09 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=9B=BE=E7=89=87=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E8=BF=9B=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tsdaodaobase/src/Messages/Image/index.css | 25 ++ .../tsdaodaobase/src/Messages/Image/index.tsx | 274 ++++++++++-------- packages/tsdaodaobase/src/assets/loading.png | Bin 0 -> 6231 bytes packages/tsdaodaodatasource/src/task.ts | 7 +- 4 files changed, 191 insertions(+), 115 deletions(-) create mode 100644 packages/tsdaodaobase/src/Messages/Image/index.css create mode 100644 packages/tsdaodaobase/src/assets/loading.png diff --git a/packages/tsdaodaobase/src/Messages/Image/index.css b/packages/tsdaodaobase/src/Messages/Image/index.css new file mode 100644 index 0000000..2898e23 --- /dev/null +++ b/packages/tsdaodaobase/src/Messages/Image/index.css @@ -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; +} diff --git a/packages/tsdaodaobase/src/Messages/Image/index.tsx b/packages/tsdaodaobase/src/Messages/Image/index.tsx index 4064973..d8c4a7f 100644 --- a/packages/tsdaodaobase/src/Messages/Image/index.tsx +++ b/packages/tsdaodaobase/src/Messages/Image/index.tsx @@ -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 { + 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 ( +
+ + {this.state.loading && scaleSize.width > 32 && ( + + + {scaleSize.height > 46 &&

{this.state.progress}%

} +
+ )} +
+ ); + } - 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 - } - - 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 -
{ - this.setState({ - showPreview: !this.state.showPreview, - }) - }}> - {this.getImageElement()} -
- { this.setState({ showPreview: false }); }} - onClose={() => { this.setState({ showPreview: false }); }} - images={[{ src: imageURL, alt: '', downloadUrl: imageURL }]} - /> -
- } -} \ No newline at end of file + 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 ( + +
{ + this.setState({ + showPreview: !this.state.showPreview, + }); + }} + > + {this.getImageElement()} +
+ { + this.setState({ showPreview: false }); + }} + onClose={() => { + this.setState({ showPreview: false }); + }} + images={[{ src: imageURL, alt: "", downloadUrl: imageURL }]} + /> +
+ ); + } +} diff --git a/packages/tsdaodaobase/src/assets/loading.png b/packages/tsdaodaobase/src/assets/loading.png new file mode 100644 index 0000000000000000000000000000000000000000..1ae236180cc4ef54f7e19fb6b68550b9f841f387 GIT binary patch literal 6231 zcmbW6cQjmIw8t5P(PBm)b<~mQBua#gk|4_H1f%yF(Yw(*(K{gsV)RZ(2$C>*^b)<- z1PPHh`ThO=cGQa?il!*IAUw$YdfNRNlzT6R^ATIXA zOwm6OF#2kp$CQK}22fEhEmI4@eR|s#YakDbK~PQD-<@Q`hx{)ljK6lXj*d$2cs;X| zV4ofl_o05Bhpq&6FxAb7Oe#>j1gxj)O}hvnU70C)0S@6?Mv;rey@67prMcx_+q4C8 zikuzcL>Sy0Cgu%i?P)Hva6Uyiz9h647J84m7Ku+e%&X7(0y2;lTjpc{xQd{+BXZ-` z&aC`&hU~tIJ#@k?_o)=0W5FP7EKJJ-D~I>YfUf12z=BH|`jC zk0d6l=GHkqr0kt&&cn}#a1EH6*^-mbU$8go>-j`Mgd9W^VSNu>cju9K`LsKVFq2BU zKTEuq`|V^dCtm0Qwyojb8L=oohis8FDpg*9@5Vh?1Qq!%}X{_7# zXtET!Hu40fP=TmPIpi)sj_`Xb{5@A~++<7KR-kqX5#g~kA5d>)Zag4d5pW7I9tuh6 zhNH{u4DdbW-ogn#=*HVN`ta7?aoC;T;yrqNai_N~d4yqlCE93Rl9K1IToj}8?mQ2k zn8KliRkV?4MMt8;t`SA(-nZpy776V^8~s1O@74wf9PX>q*%D=Zpr%>djZ>d=vAJZr zzKxwa?cJblb^FOAfeq$JktE@&ts(kO04Wd-(WUTcn3>Ice3sOgj-r;uALu0UT^PDG z;V$1pw**aFR9B4#u)r}F94Q8bq8C|)&4Cx%9KVfd;ACP;g?BSnHo05$#$*A@GL+6O z#656C+cSaOm5WtsV;!8Eoz`BYEf>wu%||S7N*TxWl+f`Nc`+@Fa(%X_chjLbmvJ48 zuPy*tzZG-$9q#N-$?J%hN#@^%9E|lKxO8XO{~V`r&%$&I ze4ewby_spN#xIjcVDBO(UDWfqzS^SbelnBs#PkC2-vA^Kn?<2Viy{h7;cDQJo z9&uK>4tiJ7DcwGuWnWPTuyZv`SB9T#rE zo9H~FY~`#hK9M)F z%ud(YjT-5Bm8Sq7=09OVT&Unlk%>2Xjz@LJx(RO3@eVg;$Os+Uie0(k`^$tzLwzG+ z3hP|1D+TE5ROupYMM_pGh8%F9aHk5wvalC)N@cN(zERSsN zh-NaXF0Ki!+DU%CZ}EvK*?li^Q7LC`n)5sCr`WiO(8>-ml#hR9mLwwU(sRn`iy8P! zi36U9fO6Ist#0-^)s$9@73G)A3Yvi-%A2CUDsV{#Tjt_CYzYTPCzLt)5Mi*ZZl*Sq9_kc10++!b1>NSFNNP2lDHtra#nX!Its7p!i6pjzdDUTdvsK7 zeZ_PL;4~|E`s~*h!a))x-(*#&7F6j?y6|E- zwoCAxF0{=mU@!6s9OG+lU?^e?g|`5p9rUN&F+X%d>ZBW|s~VG|nOQ;30>j4+b*R%- z(W<-0VY$Cd&)u{>G723?*3%8~1l{IIn@g*@Yn*9bVUuVs)r_^;N5hk|j}**3WPNnw zX50IJHW>B^M>S<=ckycdK~Uu1YJ(aV~$WFPW2Uo3nW! z;sYO)*H<7ubZs>PjT|ArI?bJNFRgPULzAOi3r2f8LB3+45(fn97NHVU;|04VbM%C7 zxCWVjPmK9J+PAH!GLFi;5$P6Q2s-ZbWNeg4ELO9b)dVdt%wj1PQ+JsCR6Iy+T-)+WE z#3CMfD-VZ5>dxjR5LeqUEl}HCm+Zd`Tv5hmkQifaOZset`sf8UZ@K^jgRiVrb~K?z zl?on2c`AbYcG)H&|8t6*?CWJpl@5akUrLvIfS-f_B+oQ&@~Ga@H!anvpfdwbB)q>l%Ih5?eYKC@wd4afND8cV z)a7WOic^Dqn^<)3UsOl5j!cd8`v7hhqD0$HhiH4CS)GvfJ)5uuc_Wqy7Lk(1Da&6K zM+r;DPdLEz0jf=hKkP2;KfR2{pi1xznj#bxFF9V5zInfKEY>oi#VȄ@`>@kkfw zHVV@ticJaC8>?D9(XVt%y;mJo8G+KU2e`Lz+rLS-d&Fa38I^Oo!@1=mUtI1q3VC5) zJ#n~mkp1wmLs}kXC3zoh*m2P|x;tKEKyj{G6UMvV6om*mz7g!SkX|rqJ&3WKPS*r# zk8Wcu*KC4SgeRj#%g%lV|M?^o4BYegW)08(Bw^&8lIXW9dtN9^O#TG+02PoPx=z5= zV)S6Rk>D!cX&BUGfA@7yRY%(HPG#BIq(upcKV|+ooDD(Dw))PBb|WR=73_!Q&b4pw zvRs<|T6~RKja9MLMAPxg>C0>@BD$e1vIY-r78>8f1(Let0!!Tj0m=;qIPhK91s7o)n-^8GZ1uahoq1dcQmP&W~u z5L2@Ef?qna$Mf#y@cs9mBsKN;YBWN!S1EM`=k`9?oBlEi&_Ut2@z^~rbtw`nrS);) zC=Re4UeEb0T&;;R_od6vGVz_}H#=#F9?VD+x;L-#$ma^>8S%UO?C+IYO{K9tU``-4 zP{VG`a#HJ(;Q%lxJ*_?W%M_91u2I~RB0X*Et^b+)5XQ8$``+Hbm0S;|v6)ADzA|R9 zumY50$^kC@{uo~yvXVbtO)Ou^jkZLZ>l{~3>Vy{%L6%vB=Mu@UorMBET(byyq9tP= zHMVWLJ*0g|pqa$}Nj5Gg$#QG3cvZ!b7g-&&`5>5@uIGZM?saRYhvWLH5M)QEkk3LG z^8Vr`e&IFrs|B9Eiu z)CK(Mu3($B?+WC`S0wlKJPSl#%~QHV(7$ zsYYc**y|>PFd(}opLG^wQcupZ?FXusaqF(2i%(uGqHBz5VT{C(4a<_G@t(d{DbxU+G>J6Rl{rakfF+X9(2#}YxL03j|`@~6UNoM{bPRD$=H5moelgivP zbeGL3ke zRce8$iLqB&%q&-O=zqP$2L|2Se8=osA2EysdS^bIylYN<)xc#4`}R}S=4Yh@YPsUf znPBKgQh4EW5i6LED7?enQvlqPyqwD9^f|=Q+@^!=e2J7_$KwR({W z*_(1FJ`!GEY}{$Ok!TPq*N;_|c|Hk&8r_0gHwn7mCOPT~zLYL>LOYK)`h8Mj2bvU$ z4Nz#d zstPO@47Yc!f9OTF{$<623q2anaw%SJ4;E;O&E$BQHOJ_bfTqspZPW}|^~M#i{5p32 z1m)YIB?;SjZ8?Wz6_$&YrjJgcGZP+8c(MXvd$(^Gx4s9j{iYf^`dSls^oXNyG(k#H za(SF0lsM;9vE2IUMOH8J)!L*iaL@0sS`Bnqm=UV((3iiN73zk*V$r;bK#1W=aZ3cW z%+`A(*zTlO^eOk4t3EDQq;Fn|u&+AT^#yppe%Pl3K#HvAs(tPnh(0!Jk3ob{(fq}w zl3IF@CnJ6Z;00X`>#2G90=_BbUKfwm;%$X66*W3SPRp_>BDA?_8<^+7Bcjf8VjY>D z1-;>S_V)&OFK=HQwq;pAftlLJx~%;p8Z$5N&XVDX2ECDGo+K{I^f#N3UdZF1NMz;3b>kq4?`!UsSWX-iG5K0%E`)<3|6dc}9E3OjQBF&my&z;6NEm{5-UluH zeccbq3|q)W>;No6f0NDIbQKk-Lfc-Ut2@ZgF)ighpW#u6w}46k(--_@j7af{!M`Pp z8E*Gmsma)dTY&Pk%BUG};ju#uS79wX?G1z`IJXfR>Pp?wSg*ON6Gjc%`} zyE9BisHOxsaFGh64)a0-KFxKs^nh29A54KP7-NCWCF4By1C9BW0^} z-Mz6H3ZVW>+-jjzpKb9_rFz2&LPK;U^)hg-`XEq*AQR7s_YAL{ynuef}f<{6lQ!zW(%fpg^m4q1xgL`+s)XLspsNXX?}p7C3}N| z5tG6Cacmbw8}+f&hpou=mfzaOJ_@PHEa)pT#nIa&gq!oTq*F+i;yGN zc&@iZ$FCjWJ7@~SewE|#54@i*KFN(LI}2$cKD!v1m}soV>o9*CrdMSl=&<6rXu}$S zmbCdNX@;d#cobu7NWyTcmjZ}t~O5%BGu-n4qKRZF;; zF{mH^*Us}nq~wp)N;b0W~v9G_z zj62#hp%X5jHYo%(cX{W?OMWH#E0q1s`q>u!Jo_i)x{3x>6dQumsL;OcWD@;2o~}}LDu(ig>wmSE77_n zbTrRG*VTUWuK8x8U7GwLL6->X-Qwbx`ZUQ*khLfJ5!q^tmYR_`TV;<=aF&Y%x$wx} zzkzS77&o1%kc;}$`~YaACu+u9SlCaI`e~7o=y{F3zWV5r;;LA5@{@$kU0~O^E8+T| zM0Nnli`Y-A=b{1~{SBUnet6e8*NUxGPyNOX3lQr;CXgXs77VSwe@w;~5YN6|U*O2W z+FK0<)frZRu#aybQ5>|-gmJn}C7BQ4@RI1D{i3ypaG*M*jHHd*CA+qLG4{;5YIlAR z)Mk6dKzes@lo#{on0HX)r86Yv>yg{>bdoFid^Ciu&d-0v1v?V(H5msCVBuN#k|f1m z&I?6ff9M@K`*DykY64S>ZB;9maVNJ+j5-;JquX3>=d`PEf)ac@+|Mb8b2*7)OZr{` zZd;_qPL;v9gB+GCQ05PZ0Zy@MkEj$8|9=xFA!cxxC{;>174A;~p2`yqMU1?8*#7{i Cuz+L$ literal 0 HcmV?d00001 diff --git a/packages/tsdaodaodatasource/src/task.ts b/packages/tsdaodaodatasource/src/task.ts index 3c45906..4322876 100644 --- a/packages/tsdaodaodatasource/src/task.ts +++ b/packages/tsdaodaodatasource/src/task.ts @@ -18,10 +18,13 @@ export class MediaMessageUploadTask extends MessageTask { async start(): Promise { 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() }