| | @@ -397,10 +397,12 @@ |
| 397 | 397 | this.playNewMessageSound.uri = uri; |
| 398 | 398 | this.settings.set('audible-alert', !!uri); |
| 399 | 399 | return this; |
| 400 | 400 | } |
| 401 | 401 | }; |
| 402 | + F.fetch.beforesend = ()=>cs.ajaxStart(); |
| 403 | + F.fetch.aftersend = ()=>cs.ajaxEnd(); |
| 402 | 404 | cs.e.inputCurrent = cs.e.inputSingle; |
| 403 | 405 | /* Install default settings... */ |
| 404 | 406 | Object.keys(cs.settings.defaults).forEach(function(k){ |
| 405 | 407 | const v = cs.settings.get(k,cs); |
| 406 | 408 | if(cs===v) cs.settings.set(k,cs.settings.defaults[k]); |
| | @@ -538,18 +540,15 @@ |
| 538 | 540 | e = this.getMessageElemById(id); |
| 539 | 541 | } |
| 540 | 542 | if(!(e instanceof HTMLElement)) return; |
| 541 | 543 | if(this.userMayDelete(e)){ |
| 542 | 544 | this.ajaxStart(); |
| 543 | | - fetch("chat-delete/" + id) |
| 544 | | - .then(function(response){ |
| 545 | | - if(!response.ok) throw cs._newResponseError(response); |
| 546 | | - return response; |
| 547 | | - }) |
| 548 | | - .then(()=>this.deleteMessageElem(e)) |
| 549 | | - .catch(err=>this.reportErrorAsMessage(err)) |
| 550 | | - .finally(()=>this.ajaxEnd()); |
| 545 | + F.fetch("chat-delete/" + id, { |
| 546 | + responseType: 'json', |
| 547 | + onload:(r)=>this.deleteMessageElem(r), |
| 548 | + onerror:(err)=>this.reportErrorAsMessage(err) |
| 549 | + }); |
| 551 | 550 | }else{ |
| 552 | 551 | this.deleteMessageElem(id); |
| 553 | 552 | } |
| 554 | 553 | }; |
| 555 | 554 | document.addEventListener('visibilitychange', function(ev){ |
| | @@ -878,27 +877,25 @@ |
| 878 | 877 | const file = BlobXferState.blob || this.e.inputFile.files[0]; |
| 879 | 878 | if(file) fd.set("file", file); |
| 880 | 879 | if( !msg && !file ) return; |
| 881 | 880 | const self = this; |
| 882 | 881 | fd.set("lmtime", localTime8601(new Date())); |
| 883 | | - fetch("chat-send",{ |
| 884 | | - method: 'POST', |
| 885 | | - body: fd |
| 886 | | - }).then((x)=>{ |
| 887 | | - if(x.ok) return x.text(); |
| 888 | | - else throw Chat._newResponseError(x); |
| 889 | | - }).then(function(txt){ |
| 882 | + F.fetch("chat-send",{ |
| 883 | + payload: fd, |
| 884 | + responseType: 'text', |
| 885 | + onerror:(err)=>this.reportErrorAsMessage(err), |
| 886 | + onload:function(txt){ |
| 890 | 887 | if(!txt) return/*success response*/; |
| 891 | 888 | try{ |
| 892 | 889 | const json = JSON.parse(txt); |
| 893 | 890 | self.newContent({msgs:[json]}); |
| 894 | 891 | }catch(e){ |
| 895 | 892 | self.reportError(e); |
| 896 | 893 | return; |
| 897 | 894 | } |
| 898 | | - }) |
| 899 | | - .catch((e)=>this.reportErrorAsMessage(e)); |
| 895 | + } |
| 896 | + }); |
| 900 | 897 | BlobXferState.clear(); |
| 901 | 898 | Chat.inputValue("").inputFocus(); |
| 902 | 899 | }; |
| 903 | 900 | |
| 904 | 901 | Chat.e.inputSingle.addEventListener('keydown',function(ev){ |
| | @@ -1155,35 +1152,36 @@ |
| 1155 | 1152 | D.fieldset(loadLegend), "id", "load-msg-toolbar" |
| 1156 | 1153 | ); |
| 1157 | 1154 | Chat.disableDuringAjax.push(toolbar); |
| 1158 | 1155 | /* Loads the next n oldest messages, or all previous history if n is negative. */ |
| 1159 | 1156 | const loadOldMessages = function(n){ |
| 1160 | | - Chat.ajaxStart(); |
| 1161 | 1157 | Chat.e.messagesWrapper.classList.add('loading'); |
| 1162 | 1158 | Chat._isBatchLoading = true; |
| 1163 | | - var gotMessages = false; |
| 1164 | 1159 | const scrollHt = Chat.e.messagesWrapper.scrollHeight, |
| 1165 | 1160 | scrollTop = Chat.e.messagesWrapper.scrollTop; |
| 1166 | | - fetch("chat-poll?before="+Chat.mnMsg+"&n="+n) |
| 1167 | | - .then(Chat._fetchJsonOrError) |
| 1168 | | - .then(function(x){ |
| 1169 | | - gotMessages = x.msgs.length; |
| 1161 | + F.fetch("chat-poll",{ |
| 1162 | + urlParams:{ |
| 1163 | + before: Chat.mnMsg, |
| 1164 | + n: n |
| 1165 | + }, |
| 1166 | + responseType: 'json', |
| 1167 | + onerror:function(err){ |
| 1168 | + Chat.reportErrorAsMessage(err); |
| 1169 | + Chat._isBatchLoading = false; |
| 1170 | + }, |
| 1171 | + onload:function(x){ |
| 1172 | + let gotMessages = x.msgs.length; |
| 1170 | 1173 | newcontent(x,true); |
| 1171 | | - }) |
| 1172 | | - .catch(e=>Chat.reportErrorAsMessage(e)) |
| 1173 | | - .finally(function(){ |
| 1174 | 1174 | Chat._isBatchLoading = false; |
| 1175 | | - Chat.e.messagesWrapper.classList.remove('loading'); |
| 1176 | | - Chat.ajaxEnd(); |
| 1177 | 1175 | if(Chat._gotServerError){ |
| 1178 | | - F.toast.error("Got an error response from the server. ", |
| 1179 | | - "See message for details."); |
| 1176 | + Chat._gotServerError = false; |
| 1180 | 1177 | return; |
| 1181 | | - }else if(n<0/*we asked for all history*/ |
| 1178 | + } |
| 1179 | + if(n<0/*we asked for all history*/ |
| 1182 | 1180 | || 0===gotMessages/*we found no history*/ |
| 1183 | 1181 | || (n>0 && gotMessages<n /*we got fewer history entries than requested*/) |
| 1184 | | - || (false!==gotMessages && n===0 && gotMessages<Chat.loadMessageCount |
| 1182 | + || (n===0 && gotMessages<Chat.loadMessageCount |
| 1185 | 1183 | /*we asked for default amount and got fewer than that.*/)){ |
| 1186 | 1184 | /* We've loaded all history. Permanently disable the |
| 1187 | 1185 | history-load toolbar and keep it from being re-enabled |
| 1188 | 1186 | via the ajaxStart()/ajaxEnd() mechanism... */ |
| 1189 | 1187 | const div = Chat.e.loadOlderToolbar.querySelector('div'); |
| | @@ -1199,11 +1197,16 @@ |
| 1199 | 1197 | was requested, per user request */ |
| 1200 | 1198 | Chat.e.messagesWrapper.scrollTo( |
| 1201 | 1199 | 0, Chat.e.messagesWrapper.scrollHeight - scrollHt + scrollTop |
| 1202 | 1200 | ); |
| 1203 | 1201 | } |
| 1204 | | - }); |
| 1202 | + }, |
| 1203 | + aftersend:function(){ |
| 1204 | + Chat.e.messagesWrapper.classList.remove('loading'); |
| 1205 | + Chat.ajaxEnd(); |
| 1206 | + } |
| 1207 | + }); |
| 1205 | 1208 | }; |
| 1206 | 1209 | const wrapper = D.div(); /* browsers don't all properly handle >1 child in a fieldset */; |
| 1207 | 1210 | D.append(toolbar, wrapper); |
| 1208 | 1211 | var btn = D.button("Previous "+Chat.loadMessageCount+" messages"); |
| 1209 | 1212 | D.append(wrapper, btn); |
| | @@ -1213,47 +1216,65 @@ |
| 1213 | 1216 | btn.addEventListener('click',()=>loadOldMessages(-1)); |
| 1214 | 1217 | D.append(Chat.e.messagesWrapper, toolbar); |
| 1215 | 1218 | toolbar.disabled = true /*will be enabled when msg load finishes */; |
| 1216 | 1219 | })()/*end history loading widget setup*/; |
| 1217 | 1220 | |
| 1218 | | - async function poll(isFirstCall){ |
| 1219 | | - if(poll.running) return; |
| 1220 | | - poll.running = true; |
| 1221 | | - if(isFirstCall){ |
| 1221 | + const afterFetch = function f(){ |
| 1222 | + if(true===f.isFirstCall){ |
| 1223 | + f.isFirstCall = false; |
| 1224 | + Chat.ajaxEnd(); |
| 1225 | + Chat.e.messagesWrapper.classList.remove('loading'); |
| 1226 | + setTimeout(function(){ |
| 1227 | + Chat.scrollMessagesTo(1); |
| 1228 | + }, 250); |
| 1229 | + } |
| 1230 | + if(Chat._gotServerError && Chat.intervalTimer){ |
| 1231 | + clearInterval(Chat.intervalTimer); |
| 1232 | + Chat.reportErrorAsMessage( |
| 1233 | + "Shutting down chat poller due to server-side error. ", |
| 1234 | + "Reload this page to reactivate it."); |
| 1235 | + delete Chat.intervalTimer; |
| 1236 | + } |
| 1237 | + poll.running = false; |
| 1238 | + }; |
| 1239 | + afterFetch.isFirstCall = true; |
| 1240 | + const poll = async function f(){ |
| 1241 | + if(f.running) return; |
| 1242 | + f.running = true; |
| 1243 | + Chat._isBatchLoading = f.isFirstCall; |
| 1244 | + if(true===f.isFirstCall){ |
| 1245 | + f.isFirstCall = false; |
| 1222 | 1246 | Chat.ajaxStart(); |
| 1223 | 1247 | Chat.e.messagesWrapper.classList.add('loading'); |
| 1224 | 1248 | } |
| 1225 | | - Chat._isBatchLoading = isFirstCall; |
| 1226 | | - var p = fetch("chat-poll?name=" + Chat.mxMsg); |
| 1227 | | - p.then(Chat._fetchJsonOrError) |
| 1228 | | - .then(y=>newcontent(y)) |
| 1229 | | - .catch(e=>console.error(e)) |
| 1230 | | - /* ^^^ we don't use Chat.reportError(e) here b/c the polling |
| 1231 | | - fails exepectedly when it times out, but is then immediately |
| 1232 | | - resumed, and reportError() produces a loud error message. */ |
| 1233 | | - .finally(function(){ |
| 1234 | | - if(isFirstCall){ |
| 1235 | | - Chat._isBatchLoading = false; |
| 1236 | | - Chat.ajaxEnd(); |
| 1237 | | - Chat.e.messagesWrapper.classList.remove('loading'); |
| 1238 | | - setTimeout(function(){ |
| 1239 | | - Chat.scrollMessagesTo(1); |
| 1240 | | - }, 250); |
| 1241 | | - } |
| 1242 | | - if(Chat._gotServerError && Chat.intervalTimer){ |
| 1243 | | - clearInterval(Chat.intervalTimer); |
| 1244 | | - delete Chat.intervalTimer; |
| 1245 | | - } |
| 1246 | | - poll.running=false; |
| 1247 | | - }); |
| 1248 | | - } |
| 1249 | + F.fetch("chat-poll",{ |
| 1250 | + timeout: 420 * 1000/*FIXME: get the value from the server*/, |
| 1251 | + urlParams:{ |
| 1252 | + name: Chat.mxMsg |
| 1253 | + }, |
| 1254 | + responseType: "json", |
| 1255 | + // Disable the ajax start/end handling for this long-polling op: |
| 1256 | + beforesend: function(){}, |
| 1257 | + aftersend: function(){}, |
| 1258 | + onerror:function(err){ |
| 1259 | + Chat._isBatchLoading = false; |
| 1260 | + console.error(err); |
| 1261 | + /* ^^^ we don't use Chat.reportError() here b/c the polling |
| 1262 | + fails exepectedly when it times out, but is then immediately |
| 1263 | + resumed, and reportError() produces a loud error message. */ |
| 1264 | + afterFetch(); |
| 1265 | + }, |
| 1266 | + onload:function(y){ |
| 1267 | + newcontent(y); |
| 1268 | + Chat._isBatchLoading = false; |
| 1269 | + afterFetch(); |
| 1270 | + } |
| 1271 | + }); |
| 1272 | + }; |
| 1273 | + poll.isFirstCall = true; |
| 1249 | 1274 | Chat._gotServerError = poll.running = false; |
| 1250 | | - poll(true); |
| 1251 | | - if(!Chat._gotServerError){ |
| 1252 | | - Chat.intervalTimer = setInterval(poll, 1000); |
| 1253 | | - } |
| 1254 | 1275 | if( window.fossil.config.chat.fromcli ){ |
| 1255 | 1276 | Chat.chatOnlyMode(true); |
| 1256 | 1277 | } |
| 1257 | | - |
| 1278 | + Chat.intervalTimer = setInterval(poll, 1000); |
| 1258 | 1279 | F.page.chat = Chat/* enables testing the APIs via the dev tools */; |
| 1259 | 1280 | })(); |
| 1260 | 1281 | |