Files
im_webapp/umd/965.prod.js
T
Your NameandClaude Sonnet 5 eb4c1cd8da 用登录页现有logo重新生成PWA图标/favicon/OG分享图;顺手发现并重建了严重过期的生产构建产物
图标部分:logo.svg/logo96.png/logo192.png/logo32x32.png/logo32x32a.png原来画的是开源Tinode
项目自己的蓝绿橙"t"speech-bubble标志。用登录页AppMark组件的真实CSS参数(白色圆角方卡 + 旋转
-18deg的蓝色squircle + 加粗白色首字母,色值#1677ff,圆角50% 50% 50% 18%)原样重新画成独立
的SVG/PNG资源,不是另起一套新设计——文字/图标/圆角比例/旋转角度均按登录页实测的computed style
数值1:1还原。favicon(32x32)的"未读"变体(右下角绿点)沿用原有的visual language。

og-logo.jpeg(社交分享预览图,og:image meta标签用)问题比图标本身更明显:原图整个背景是金门大桥
照片,前景写着"Tinode / Open Source Instant Messenger",这两行文字是本次engagement里最直接的
一处Tinode品牌泄漏(没有隐藏在代码里,链接分享出去别人就直接看到)。改成深色渐变背景+同一套
logo mark+"MeetingIM"+"即时通讯",不再引用任何第三方项目的名字或素材。

意外发现:umd/index.prod.js(生产构建产物,index.html的<script>直接引用)从很早之前就没有
重新构建过,仍然包含"TinodeWeb"/"web.tinode.co"/tinode.co的隐私政策与服务条款链接/
support@tinode.co邮箱等一整套本轮及更早各轮已经在源码里修掉的Tinode字样——如果这份产物被
原样部署,之前所有品牌清理都不会真正体现在生产环境。已用`npm run build:prod`重新构建(干净
通过,只有两条跟本次改动无关的资源体积警告),确认重建后的产物里"MeetingIM"正确替换了旧品牌名、
真实域名替换了tinode.co。这次只重新生成了产物文件,没有执行任何部署动作。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 23:30:11 +08:00

2 lines
7.9 KiB
JavaScript

"use strict";(self.webpackChunktinode_webapp=self.webpackChunktinode_webapp||[]).push([[965],{965:function(e,t,i){i.r(t);var s=i(1594),a=i.n(s),n=i(8181),r=i(8492),o=i(3537),d=i.n(o),h=i(7981),l=i(7256),c=(i(3272),i(4848));const u=100,p="audio/webm",m=[p,"audio/mp4",""],f=(0,n.defineMessages)({icon_title_delete:{id:"icon_title_delete",defaultMessage:"Delete recording",description:"Icon tool tip for deleting recorded audio"},icon_title_pause:{id:"icon_title_pause",defaultMessage:"Pause playback",description:"Icon tool tip for pausing audio playback"},icon_title_resume:{id:"icon_title_resume",defaultMessage:"Resume playback",description:"Icon tool tip for resuming audio playback"},icon_title_send:{id:"icon_title_send",defaultMessage:"Send message",description:"Icon tool tip for sending a message"},failed_to_init_audio:{id:"failed_to_init_audio",defaultMessage:"Failed to initialize audio recording",description:"Error message when audio is not available"}});class g extends a().PureComponent{constructor(e){super(e),this.state={enabled:!0,audioRecord:null,recording:!0,paused:!1,duration:"0:00",blobUrl:null,preview:null},this.visualize=this.visualize.bind(this),this.initMediaRecording=this.initMediaRecording.bind(this),this.initCanvas=this.initCanvas.bind(this),this.getRecording=this.getRecording.bind(this),this.cleanUp=this.cleanUp.bind(this),this.handleResume=this.handleResume.bind(this),this.handlePause=this.handlePause.bind(this),this.handleDelete=this.handleDelete.bind(this),this.handleDone=this.handleDone.bind(this),this.durationMillis=0,this.startedOn=null,this.viewBuffer=[],this.canvasRef=a().createRef(),this.recordingTimestamp=0}componentDidMount(){this.stream=null,this.mediaRecorder=null,this.audioContext=null,this.audioInput=null,this.analyser=null,this.audioChunks=[];try{navigator.mediaDevices.getUserMedia({audio:!0,video:!1}).then(this.initMediaRecording,this.props.onError)}catch(e){this.props.onError(e)}}componentWillUnmount(){this._unmounted=!0,this.startedOn=null,this.stream&&this.cleanUp()}visualize(){this.initCanvas();const e=new Uint8Array(this.analyser.frequencyBinCount),t=this.canvasWidth,i=this.canvasHeight,s=t/10|0,a=u*s;this.canvasContext.lineWidth=6,this.canvasContext.strokeStyle="#BBBD";let n=0,r=0,o=0;const d=h=>{if(!this.startedOn)return;window.requestAnimationFrame(d);const c=this.durationMillis+(Date.now()-this.startedOn);this.setState({duration:(0,l.Ye)(c/1e3)}),c>6e5&&(this.startedOn=null,this.mediaRecorder.pause(),this.durationMillis=c,this.setState({enabled:!1,recording:!1,duration:(0,l.Ye)(this.durationMillis/1e3)})),this.analyser.getByteTimeDomainData(e);let p=0;for(const t of e)p+=(t-127)**2;r+=Math.sqrt(p/e.length),o++;let m=c/u|0;const f=a>c?0:(c-u*m)/u*10;n!=m&&(n=m,this.viewBuffer.push(r/o),r=0,o=0,this.viewBuffer.length>s&&this.viewBuffer.shift()),this.canvasContext.clearRect(0,0,t,i),this.canvasContext.beginPath();for(let e=0;e<this.viewBuffer.length;e++){let t=10*e-f,s=Math.max(Math.min(this.viewBuffer[e]/64,.9)*i,1);this.canvasContext.moveTo(t,.5*(i-s)),this.canvasContext.lineTo(t,.5*(i+s))}this.canvasContext.stroke();const g=(new Date).getTime();g-this.recordingTimestamp>3e3&&(this.props.onRecordingProgress(),this.recordingTimestamp=g)};d()}handlePause(e){e.preventDefault(),this.mediaRecorder.pause(),this.mediaRecorder.requestData(),this.durationMillis+=Date.now()-this.startedOn,this.startedOn=null,this.setState({recording:!1})}handleResume(e){e.preventDefault(),this.state.enabled&&(this.startedOn=Date.now(),this.mediaRecorder.resume(),this.setState({recording:!0},this.visualize))}handleDelete(e){e.preventDefault(),this.durationMillis=0,this.startedOn=null,this.mediaRecorder&&this.mediaRecorder.stop(),this.cleanUp(),this.setState({recording:!1}),!this.mediaRecorder&&this.props.onDeleted&&this.props.onDeleted()}handleDone(e){e.preventDefault(),this.setState({recording:!1}),this.startedOn&&(this.durationMillis+=Date.now()-this.startedOn,this.startedOn=null),this.mediaRecorder?this.mediaRecorder.stop():this.props.onDeleted&&this.props.onDeleted()}initCanvas(){this.canvasRef.current.width=2*this.canvasRef.current.offsetWidth,this.canvasRef.current.height=2*this.canvasRef.current.offsetHeight,this.canvasContext=this.canvasRef.current.getContext("2d"),this.canvasContext.lineCap="round",this.canvasContext.translate(.5,.5),this.canvasWidth=this.canvasRef.current.width,this.canvasHeight=this.canvasRef.current.height}initMediaRecording(e){if(this._unmounted)e.getTracks().forEach(e=>e.stop());else{if(this.stream=e,m.some(t=>!!MediaRecorder.isTypeSupported(t)&&(this.mediaRecorder=new MediaRecorder(e,{mimeType:t,audioBitsPerSecond:24e3}),!0)),!this.mediaRecorder)return console.warn("MediaRecorder failed to initialize: no supported audio formats"),void this.props.onError(this.props.intl.formatMessage(f.failed_to_init_audio));if(this.audioContext=new AudioContext,this.audioInput=this.audioContext.createMediaStreamSource(e),!this.audioInput)return console.warn("createMediaStreamSource returned null: audio input unavailable"),void this.props.onError(this.props.intl.formatMessage(f.failed_to_init_audio));this.analyser=this.audioContext.createAnalyser(),this.analyser.fftSize=256,this.audioInput.connect(this.analyser),this.mediaRecorder.onstop=e=>{this.durationMillis>2e3?this.getRecording(this.mediaRecorder.mimeType).then(e=>this.props.onFinished(e.url,e.preview,this.durationMillis)):this.props.onDeleted(),this.cleanUp()},this.mediaRecorder.ondataavailable=e=>{e.data.size>0&&this.audioChunks.push(e.data),"inactive"!=this.mediaRecorder.state&&this.getRecording(this.mediaRecorder.mimeType).then(e=>{this.setState({blobUrl:e.url,preview:e.preview})})},this.durationMillis=0,this.startedOn=Date.now(),this.mediaRecorder.start(),this.visualize(),this.props.onRecordingProgress(),this.recordingTimestamp=this.startedOn}}getRecording(e){e=e||p;let t=new Blob(this.audioChunks,{type:e});return(e==p?d()(t,e):Promise.resolve(t)).then(e=>(t=e,e.arrayBuffer())).then(e=>this.audioContext.decodeAudioData(e)).then(e=>this.createPreview(e)).then(e=>({url:window.URL.createObjectURL(t),preview:(0,h.Pv)(e)}))}createPreview(e){const t=e.getChannelData(0),i=Math.min(t.length,96),s=t.length/i|0,a=Math.max(1,s/10|0);let n=[],r=-1;for(let e=0;e<i;e++){let i=0,o=0;for(let n=0;n<s;n+=a)i+=t[s*e+n]**2,o++;const d=Math.sqrt(i/o);n.push(d),r=Math.max(r,d)}return r>0&&(n=n.map(e=>100*e/r|0)),n}cleanUp(){this.audioInput&&this.audioInput.disconnect(),this.stream&&this.stream.getTracks().forEach(e=>e.stop())}render(){const{formatMessage:e}=this.props.intl,t="material-icons "+(this.state.enabled?"red":"gray");return this.props.holdMode?(0,c.jsxs)("div",{className:"compose-record-overlay"+(this.props.cancelling?" cancel":""),role:"status",children:[(0,c.jsx)("i",{className:"material-icons",children:this.props.cancelling?"delete_outline":"mic"}),this.state.recording?(0,c.jsx)("canvas",{ref:this.canvasRef}):null,(0,c.jsx)("strong",{children:this.props.cancelling?"松开手指,取消发送":"手指上滑,取消发送"}),(0,c.jsx)("small",{children:this.state.duration})]}):(0,c.jsxs)("div",{className:"audio",children:[(0,c.jsx)("a",{href:"#",onClick:this.handleDelete,title:e(f.icon_title_delete),children:(0,c.jsx)("i",{className:"material-icons gray",children:"delete_outline"})}),this.state.recording?(0,c.jsx)("canvas",{ref:this.canvasRef}):(0,c.jsx)(r.A,{src:this.state.blobUrl,preview:this.state.preview,duration:this.durationMillis,short:!0}),(0,c.jsx)("div",{className:"duration",children:this.state.duration}),this.state.recording?(0,c.jsx)("a",{href:"#",onClick:this.handlePause,title:e(f.icon_title_pause),children:(0,c.jsx)("i",{className:"material-icons",children:"pause_circle_outline"})}):(0,c.jsx)("a",{href:"#",onClick:this.handleResume,title:e(f.icon_title_resume),children:(0,c.jsx)("i",{className:t,children:"radio_button_checked"})}),(0,c.jsx)("a",{href:"#",onClick:this.handleDone,title:e(f.icon_title_send),children:(0,c.jsx)("i",{className:"material-icons",children:"send"})})]})}}t.default=(0,n.injectIntl)(g,{forwardRef:!0})}}]);
//# sourceMappingURL=965.prod.js.map