@@ -120,6 +120,90 @@ function setupClipboardInterceptor() {
120120
121121setupClipboardInterceptor ( )
122122
123+ function isReplyActionUrl ( url ) {
124+ if ( ! url )
125+ return false
126+ try {
127+ const parsed = new URL ( url , location . href )
128+ const path = parsed . pathname . replace ( / \/ + $ / , '' )
129+ return parsed . hostname === 'api.bilibili.com'
130+ && path === '/x/v2/reply/action'
131+ }
132+ catch {
133+ return / a p i \. b i l i b i l i \. c o m \/ x \/ v 2 \/ r e p l y \/ a c t i o n (?: \? | $ | \/ ) / . test ( String ( url ) )
134+ }
135+ }
136+
137+ let lastReplyActionToastKey = ''
138+ let lastReplyActionToastAt = 0
139+
140+ function notifyReplyActionError ( data ) {
141+ if ( ! data || typeof data !== 'object' )
142+ return
143+ if ( data . code === 0 || data . code === '0' )
144+ return
145+
146+ const message = data . message || data . msg
147+ if ( ! message || message === '0' )
148+ return
149+
150+ const text = String ( message )
151+ const now = Date . now ( )
152+ if ( text === lastReplyActionToastKey && now - lastReplyActionToastAt < 800 )
153+ return
154+ lastReplyActionToastKey = text
155+ lastReplyActionToastAt = now
156+
157+ window . dispatchEvent ( new CustomEvent ( 'bewlyApiToast' , {
158+ detail : { message : text , type : 'error' } ,
159+ } ) )
160+ }
161+
162+ function setupReplyActionInterceptor ( ) {
163+ if ( typeof window . fetch === 'function' ) {
164+ const originalFetch = window . fetch . bind ( window )
165+ window . fetch = function ( ...args ) {
166+ const input = args [ 0 ]
167+ let url = ''
168+ if ( typeof input === 'string' )
169+ url = input
170+ else if ( input && typeof input . url === 'string' )
171+ url = input . url
172+
173+ return originalFetch ( ...args ) . then ( ( response ) => {
174+ if ( isReplyActionUrl ( url ) ) {
175+ response . clone ( ) . json ( ) . then ( notifyReplyActionError ) . catch ( ( ) => { } )
176+ }
177+ return response
178+ } )
179+ }
180+ }
181+
182+ if ( typeof XMLHttpRequest !== 'undefined' ) {
183+ const originalOpen = XMLHttpRequest . prototype . open
184+ const originalSend = XMLHttpRequest . prototype . send
185+
186+ XMLHttpRequest . prototype . open = function ( method , url , ...rest ) {
187+ this . __bewlyReplyActionUrl = typeof url === 'string' ? url : String ( url ?? '' )
188+ return originalOpen . call ( this , method , url , ...rest )
189+ }
190+
191+ XMLHttpRequest . prototype . send = function ( ...args ) {
192+ this . addEventListener ( 'load' , function onLoad ( ) {
193+ if ( ! isReplyActionUrl ( this . __bewlyReplyActionUrl ) )
194+ return
195+ try {
196+ notifyReplyActionError ( JSON . parse ( this . responseText ) )
197+ }
198+ catch { }
199+ } )
200+ return originalSend . apply ( this , args )
201+ }
202+ }
203+ }
204+
205+ setupReplyActionInterceptor ( )
206+
123207window . ___inject = true
124208
125209// History.prototype.pushState = history.pushState
0 commit comments