Fossil SCM
Add context-loading buttons to /chat search.
Commit
884214d0e3d6e0c54ba3f0127a67496fcc693919427b67db21a0e1658c957029
Parent
7561498cf78d164…
2 files changed
+1
-2
+169
-7
+1
-2
| --- src/chat.c | ||
| +++ src/chat.c | ||
| @@ -244,12 +244,11 @@ | ||
| 244 | 244 | @ <div id='chat-config-options'></div> |
| 245 | 245 | /* ^^^populated client-side */ |
| 246 | 246 | @ <div class='button-bar'><button class='action-close'>Close Settings</button></div> |
| 247 | 247 | @ </div> |
| 248 | 248 | @ <div id='chat-search' class='hidden chat-view'> |
| 249 | - @ <header>Chat history search...</header> | |
| 250 | - @ <div id='chat-search-body' class='message-widget-content'></div> | |
| 249 | + @ <div class='message-widget-content'></div> | |
| 251 | 250 | /* ^^^populated client-side */ |
| 252 | 251 | @ <div class='button-bar'><button class='action-close'>Close Search</button></div> |
| 253 | 252 | @ </div> |
| 254 | 253 | @ <div id='chat-messages-wrapper' class='chat-view'> |
| 255 | 254 | /* New chat messages get inserted immediately after this element */ |
| 256 | 255 |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -244,12 +244,11 @@ | |
| 244 | @ <div id='chat-config-options'></div> |
| 245 | /* ^^^populated client-side */ |
| 246 | @ <div class='button-bar'><button class='action-close'>Close Settings</button></div> |
| 247 | @ </div> |
| 248 | @ <div id='chat-search' class='hidden chat-view'> |
| 249 | @ <header>Chat history search...</header> |
| 250 | @ <div id='chat-search-body' class='message-widget-content'></div> |
| 251 | /* ^^^populated client-side */ |
| 252 | @ <div class='button-bar'><button class='action-close'>Close Search</button></div> |
| 253 | @ </div> |
| 254 | @ <div id='chat-messages-wrapper' class='chat-view'> |
| 255 | /* New chat messages get inserted immediately after this element */ |
| 256 |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -244,12 +244,11 @@ | |
| 244 | @ <div id='chat-config-options'></div> |
| 245 | /* ^^^populated client-side */ |
| 246 | @ <div class='button-bar'><button class='action-close'>Close Settings</button></div> |
| 247 | @ </div> |
| 248 | @ <div id='chat-search' class='hidden chat-view'> |
| 249 | @ <div class='message-widget-content'></div> |
| 250 | /* ^^^populated client-side */ |
| 251 | @ <div class='button-bar'><button class='action-close'>Close Search</button></div> |
| 252 | @ </div> |
| 253 | @ <div id='chat-messages-wrapper' class='chat-view'> |
| 254 | /* New chat messages get inserted immediately after this element */ |
| 255 |
+169
-7
| --- src/fossil.page.chat.js | ||
| +++ src/fossil.page.chat.js | ||
| @@ -1011,11 +1011,11 @@ | ||
| 1011 | 1011 | iframe.style.maxHeight = iframe.style.height |
| 1012 | 1012 | = iframe.contentWindow.document.documentElement.scrollHeight + 'px'; |
| 1013 | 1013 | if(isHidden) D.addClass(iframe, 'hidden'); |
| 1014 | 1014 | } |
| 1015 | 1015 | }; |
| 1016 | - | |
| 1016 | + | |
| 1017 | 1017 | cf.prototype = { |
| 1018 | 1018 | scrollIntoView: function(){ |
| 1019 | 1019 | this.e.content.scrollIntoView(); |
| 1020 | 1020 | }, |
| 1021 | 1021 | setMessage: function(m){ |
| @@ -1292,10 +1292,160 @@ | ||
| 1292 | 1292 | }/*_handleLegendClicked()*/ |
| 1293 | 1293 | }; |
| 1294 | 1294 | return cf; |
| 1295 | 1295 | })()/*MessageWidget*/; |
| 1296 | 1296 | |
| 1297 | + /** | |
| 1298 | + A widget for loading more messages (context) around a /chat-query | |
| 1299 | + result message. | |
| 1300 | + */ | |
| 1301 | + Chat.SearchCtxLoader = (function(){ | |
| 1302 | + const nMsgContext = 5; | |
| 1303 | + const zUpArrow = '\u25B2'; | |
| 1304 | + const zDownArrow = '\u25BC'; | |
| 1305 | + const cf = function(o){ | |
| 1306 | + | |
| 1307 | + /* iFirstInTable: | |
| 1308 | + ** msgid of first row in chatfts table. | |
| 1309 | + ** | |
| 1310 | + ** iLastInTable: | |
| 1311 | + ** msgid of last row in chatfts table. | |
| 1312 | + ** | |
| 1313 | + ** iPrevId: | |
| 1314 | + ** msgid of message immediately above this spacer. Or 0 if this | |
| 1315 | + ** spacer is above all results. | |
| 1316 | + ** | |
| 1317 | + ** iNextId: | |
| 1318 | + ** msgid of message immediately below this spacer. Or 0 if this | |
| 1319 | + ** spacer is below all results. | |
| 1320 | + ** | |
| 1321 | + ** bIgnoreClick: | |
| 1322 | + ** ignore any clicks if this is true. This is used to ensure there | |
| 1323 | + ** is only ever one request belonging to this widget outstanding | |
| 1324 | + ** at any time. | |
| 1325 | + */ | |
| 1326 | + this.o = { | |
| 1327 | + iFirstInTable: o.first, | |
| 1328 | + iLastInTable: o.last, | |
| 1329 | + iPrevId: o.previd, | |
| 1330 | + iNextId: o.nextid, | |
| 1331 | + bIgnoreClick: false, | |
| 1332 | + }; | |
| 1333 | + | |
| 1334 | + this.e = { | |
| 1335 | + body: D.addClass(D.div(), 'spacer-widget'), | |
| 1336 | + | |
| 1337 | + above: D.addClass(D.div(), 'spacer-widget-above'), | |
| 1338 | + buttons: D.addClass(D.div(), 'spacer-widget-buttons'), | |
| 1339 | + below: D.addClass(D.div(), 'spacer-widget-below'), | |
| 1340 | + | |
| 1341 | + up: D.addClass( | |
| 1342 | + D.button(zDownArrow+' Load '+nMsgContext+' more '+zDownArrow), | |
| 1343 | + 'up' | |
| 1344 | + ), | |
| 1345 | + down: D.addClass( | |
| 1346 | + D.button(zUpArrow+' Load '+nMsgContext+' more '+zUpArrow), | |
| 1347 | + 'down' | |
| 1348 | + ), | |
| 1349 | + all: D.addClass(D.button('Load More'), 'all') | |
| 1350 | + }; | |
| 1351 | + | |
| 1352 | + D.append(this.e.buttons, this.e.up, this.e.down, this.e.all); | |
| 1353 | + D.append(this.e.body, this.e.above, this.e.buttons, this.e.below); | |
| 1354 | + | |
| 1355 | + const ms = this; | |
| 1356 | + this.e.up.addEventListener('click', ()=>ms.load_messages(false)); | |
| 1357 | + this.e.down.addEventListener('click', ()=>ms.load_messages(true)); | |
| 1358 | + this.e.all.addEventListener('click', ()=>ms.load_messages( (ms.o.iPrevId==0) )); | |
| 1359 | + this.set_button_visibility(); | |
| 1360 | + }; | |
| 1361 | + | |
| 1362 | + cf.prototype = { | |
| 1363 | + set_button_visibility: function() { | |
| 1364 | + const o = this.o; | |
| 1365 | + | |
| 1366 | + const iPrevId = (o.iPrevId!=0) ? o.iPrevId : o.iFirstInTable-1; | |
| 1367 | + const iNextId = (o.iNextId!=0) ? o.iNextId : o.iLastInTable+1; | |
| 1368 | + var nDiff = (iNextId - iPrevId) - 1; | |
| 1369 | + | |
| 1370 | + D.addClass([this.e.up, this.e.down, this.e.all], 'hidden'); | |
| 1371 | + | |
| 1372 | + if( nDiff>0 ){ | |
| 1373 | + | |
| 1374 | + if( nDiff>nMsgContext && (o.iPrevId==0 || o.iNextId==0) ){ | |
| 1375 | + nDiff = nMsgContext; | |
| 1376 | + } | |
| 1377 | + | |
| 1378 | + if( nDiff<=nMsgContext && o.iPrevId!=0 && o.iNextId!=0 ){ | |
| 1379 | + D.removeClass(this.e.all, 'hidden'); | |
| 1380 | + this.e.all.innerText = ( | |
| 1381 | + zUpArrow + " Load " + nDiff + " more " + zDownArrow | |
| 1382 | + ); | |
| 1383 | + }else{ | |
| 1384 | + if( o.iPrevId!=0 ) D.removeClass(this.e.up, 'hidden'); | |
| 1385 | + if( o.iNextId!=0 ) D.removeClass(this.e.down, 'hidden'); | |
| 1386 | + } | |
| 1387 | + } | |
| 1388 | + }, | |
| 1389 | + | |
| 1390 | + load_messages: function(bDown) { | |
| 1391 | + if( this.bIgnoreClick ) return; | |
| 1392 | + | |
| 1393 | + var iFirst = 0; /* msgid of first message to fetch */ | |
| 1394 | + var nFetch = 0; /* Number of messages to fetch */ | |
| 1395 | + var iEof = 0; /* last msgid in spacers range, plus 1 */ | |
| 1396 | + | |
| 1397 | + const e = this.e, o = this.o; | |
| 1398 | + this.bIgnoreClick = true; | |
| 1399 | + | |
| 1400 | + /* Figure out the required range of messages. */ | |
| 1401 | + if( bDown ){ | |
| 1402 | + iFirst = this.o.iNextId - nMsgContext; | |
| 1403 | + if( iFirst<this.o.iFirstInTable ){ | |
| 1404 | + iFirst = this.o.iFirstInTable; | |
| 1405 | + } | |
| 1406 | + }else{ | |
| 1407 | + iFirst = this.o.iPrevId+1; | |
| 1408 | + } | |
| 1409 | + nFetch = nMsgContext; | |
| 1410 | + iEof = (this.o.iNextId > 0) ? this.o.iNextId : this.o.iLastInTable+1; | |
| 1411 | + if( iFirst+nFetch>iEof ){ | |
| 1412 | + nFetch = iEof - iFirst; | |
| 1413 | + } | |
| 1414 | + const ms = this; | |
| 1415 | + F.fetch("chat-query",{ | |
| 1416 | + urlParams:{ | |
| 1417 | + q: '', | |
| 1418 | + n: nFetch, | |
| 1419 | + i: iFirst | |
| 1420 | + }, | |
| 1421 | + responseType: "json", | |
| 1422 | + onload:function(jx){ | |
| 1423 | + const firstChildOfBelow = e.below.firstChild; | |
| 1424 | + jx.msgs.forEach((m) => { | |
| 1425 | + var mw = new Chat.MessageWidget(m); | |
| 1426 | + if( bDown ){ | |
| 1427 | + e.below.insertBefore(mw.e.body, firstChildOfBelow); | |
| 1428 | + }else{ | |
| 1429 | + D.append(e.above, mw.e.body); | |
| 1430 | + } | |
| 1431 | + }); | |
| 1432 | + if( bDown ){ | |
| 1433 | + o.iNextId -= jx.msgs.length; | |
| 1434 | + }else{ | |
| 1435 | + o.iPrevId += jx.msgs.length; | |
| 1436 | + } | |
| 1437 | + ms.set_button_visibility(); | |
| 1438 | + ms.bIgnoreClick = false; | |
| 1439 | + } | |
| 1440 | + }); | |
| 1441 | + } | |
| 1442 | + }; | |
| 1443 | + | |
| 1444 | + return cf; | |
| 1445 | + })() /*SearchCtxLoader*/; | |
| 1446 | + | |
| 1297 | 1447 | const BlobXferState = (function(){ |
| 1298 | 1448 | /* State for paste and drag/drop */ |
| 1299 | 1449 | const bxs = { |
| 1300 | 1450 | dropDetails: document.querySelector('#chat-drop-details'), |
| 1301 | 1451 | blob: undefined, |
| @@ -2173,28 +2323,40 @@ | ||
| 2173 | 2323 | */ |
| 2174 | 2324 | Chat.submitSearch = function(){ |
| 2175 | 2325 | const term = this.inputValue(true); |
| 2176 | 2326 | const eMsgTgt = D.clearElement( |
| 2177 | 2327 | this.e.viewSearch.querySelector('.message-widget-content') |
| 2178 | - ); | |
| 2328 | + ) | |
| 2179 | 2329 | if( !term ) return; |
| 2180 | - D.append(eMsgTgt, "TODO: search term = ", term); | |
| 2330 | + D.append( eMsgTgt, "Searching for ",term," ..."); | |
| 2181 | 2331 | F.fetch( |
| 2182 | 2332 | "chat-query", { |
| 2183 | 2333 | urlParams: {q: term}, |
| 2184 | 2334 | responseType: 'json', |
| 2185 | 2335 | onload:function(jx){ |
| 2186 | - let prevId = 0; | |
| 2336 | + let previd = 0; | |
| 2187 | 2337 | console.log("jx =",jx); |
| 2188 | 2338 | D.clearElement(eMsgTgt); |
| 2189 | 2339 | jx.msgs.forEach((m)=>{ |
| 2190 | 2340 | const mw = new Chat.MessageWidget(m); |
| 2191 | - D.append( eMsgTgt, mw.e.body ); | |
| 2192 | - prevId = m.msgid; | |
| 2341 | + const spacer = new Chat.SearchCtxLoader({ | |
| 2342 | + first: jx.first, | |
| 2343 | + last: jx.last, | |
| 2344 | + previd: previd, | |
| 2345 | + nextid: m.msgid | |
| 2346 | + }); | |
| 2347 | + D.append( eMsgTgt, spacer.e.body, mw.e.body ); | |
| 2348 | + previd = m.msgid; | |
| 2193 | 2349 | }); |
| 2194 | 2350 | if( jx.msgs.length ){ |
| 2195 | - // TODO: MessageSpacer | |
| 2351 | + const spacer = new Chat.SearchCtxLoader({ | |
| 2352 | + first: jx.first, | |
| 2353 | + last: jx.last, | |
| 2354 | + previd: previd, | |
| 2355 | + nextid: 0 | |
| 2356 | + }); | |
| 2357 | + D.append( eMsgTgt, spacer.e.body ); | |
| 2196 | 2358 | }else{ |
| 2197 | 2359 | D.append( D.clearElement(eMsgTgt), |
| 2198 | 2360 | 'No results matching the search term: ', |
| 2199 | 2361 | term ); |
| 2200 | 2362 | } |
| 2201 | 2363 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -1011,11 +1011,11 @@ | |
| 1011 | iframe.style.maxHeight = iframe.style.height |
| 1012 | = iframe.contentWindow.document.documentElement.scrollHeight + 'px'; |
| 1013 | if(isHidden) D.addClass(iframe, 'hidden'); |
| 1014 | } |
| 1015 | }; |
| 1016 | |
| 1017 | cf.prototype = { |
| 1018 | scrollIntoView: function(){ |
| 1019 | this.e.content.scrollIntoView(); |
| 1020 | }, |
| 1021 | setMessage: function(m){ |
| @@ -1292,10 +1292,160 @@ | |
| 1292 | }/*_handleLegendClicked()*/ |
| 1293 | }; |
| 1294 | return cf; |
| 1295 | })()/*MessageWidget*/; |
| 1296 | |
| 1297 | const BlobXferState = (function(){ |
| 1298 | /* State for paste and drag/drop */ |
| 1299 | const bxs = { |
| 1300 | dropDetails: document.querySelector('#chat-drop-details'), |
| 1301 | blob: undefined, |
| @@ -2173,28 +2323,40 @@ | |
| 2173 | */ |
| 2174 | Chat.submitSearch = function(){ |
| 2175 | const term = this.inputValue(true); |
| 2176 | const eMsgTgt = D.clearElement( |
| 2177 | this.e.viewSearch.querySelector('.message-widget-content') |
| 2178 | ); |
| 2179 | if( !term ) return; |
| 2180 | D.append(eMsgTgt, "TODO: search term = ", term); |
| 2181 | F.fetch( |
| 2182 | "chat-query", { |
| 2183 | urlParams: {q: term}, |
| 2184 | responseType: 'json', |
| 2185 | onload:function(jx){ |
| 2186 | let prevId = 0; |
| 2187 | console.log("jx =",jx); |
| 2188 | D.clearElement(eMsgTgt); |
| 2189 | jx.msgs.forEach((m)=>{ |
| 2190 | const mw = new Chat.MessageWidget(m); |
| 2191 | D.append( eMsgTgt, mw.e.body ); |
| 2192 | prevId = m.msgid; |
| 2193 | }); |
| 2194 | if( jx.msgs.length ){ |
| 2195 | // TODO: MessageSpacer |
| 2196 | }else{ |
| 2197 | D.append( D.clearElement(eMsgTgt), |
| 2198 | 'No results matching the search term: ', |
| 2199 | term ); |
| 2200 | } |
| 2201 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -1011,11 +1011,11 @@ | |
| 1011 | iframe.style.maxHeight = iframe.style.height |
| 1012 | = iframe.contentWindow.document.documentElement.scrollHeight + 'px'; |
| 1013 | if(isHidden) D.addClass(iframe, 'hidden'); |
| 1014 | } |
| 1015 | }; |
| 1016 | |
| 1017 | cf.prototype = { |
| 1018 | scrollIntoView: function(){ |
| 1019 | this.e.content.scrollIntoView(); |
| 1020 | }, |
| 1021 | setMessage: function(m){ |
| @@ -1292,10 +1292,160 @@ | |
| 1292 | }/*_handleLegendClicked()*/ |
| 1293 | }; |
| 1294 | return cf; |
| 1295 | })()/*MessageWidget*/; |
| 1296 | |
| 1297 | /** |
| 1298 | A widget for loading more messages (context) around a /chat-query |
| 1299 | result message. |
| 1300 | */ |
| 1301 | Chat.SearchCtxLoader = (function(){ |
| 1302 | const nMsgContext = 5; |
| 1303 | const zUpArrow = '\u25B2'; |
| 1304 | const zDownArrow = '\u25BC'; |
| 1305 | const cf = function(o){ |
| 1306 | |
| 1307 | /* iFirstInTable: |
| 1308 | ** msgid of first row in chatfts table. |
| 1309 | ** |
| 1310 | ** iLastInTable: |
| 1311 | ** msgid of last row in chatfts table. |
| 1312 | ** |
| 1313 | ** iPrevId: |
| 1314 | ** msgid of message immediately above this spacer. Or 0 if this |
| 1315 | ** spacer is above all results. |
| 1316 | ** |
| 1317 | ** iNextId: |
| 1318 | ** msgid of message immediately below this spacer. Or 0 if this |
| 1319 | ** spacer is below all results. |
| 1320 | ** |
| 1321 | ** bIgnoreClick: |
| 1322 | ** ignore any clicks if this is true. This is used to ensure there |
| 1323 | ** is only ever one request belonging to this widget outstanding |
| 1324 | ** at any time. |
| 1325 | */ |
| 1326 | this.o = { |
| 1327 | iFirstInTable: o.first, |
| 1328 | iLastInTable: o.last, |
| 1329 | iPrevId: o.previd, |
| 1330 | iNextId: o.nextid, |
| 1331 | bIgnoreClick: false, |
| 1332 | }; |
| 1333 | |
| 1334 | this.e = { |
| 1335 | body: D.addClass(D.div(), 'spacer-widget'), |
| 1336 | |
| 1337 | above: D.addClass(D.div(), 'spacer-widget-above'), |
| 1338 | buttons: D.addClass(D.div(), 'spacer-widget-buttons'), |
| 1339 | below: D.addClass(D.div(), 'spacer-widget-below'), |
| 1340 | |
| 1341 | up: D.addClass( |
| 1342 | D.button(zDownArrow+' Load '+nMsgContext+' more '+zDownArrow), |
| 1343 | 'up' |
| 1344 | ), |
| 1345 | down: D.addClass( |
| 1346 | D.button(zUpArrow+' Load '+nMsgContext+' more '+zUpArrow), |
| 1347 | 'down' |
| 1348 | ), |
| 1349 | all: D.addClass(D.button('Load More'), 'all') |
| 1350 | }; |
| 1351 | |
| 1352 | D.append(this.e.buttons, this.e.up, this.e.down, this.e.all); |
| 1353 | D.append(this.e.body, this.e.above, this.e.buttons, this.e.below); |
| 1354 | |
| 1355 | const ms = this; |
| 1356 | this.e.up.addEventListener('click', ()=>ms.load_messages(false)); |
| 1357 | this.e.down.addEventListener('click', ()=>ms.load_messages(true)); |
| 1358 | this.e.all.addEventListener('click', ()=>ms.load_messages( (ms.o.iPrevId==0) )); |
| 1359 | this.set_button_visibility(); |
| 1360 | }; |
| 1361 | |
| 1362 | cf.prototype = { |
| 1363 | set_button_visibility: function() { |
| 1364 | const o = this.o; |
| 1365 | |
| 1366 | const iPrevId = (o.iPrevId!=0) ? o.iPrevId : o.iFirstInTable-1; |
| 1367 | const iNextId = (o.iNextId!=0) ? o.iNextId : o.iLastInTable+1; |
| 1368 | var nDiff = (iNextId - iPrevId) - 1; |
| 1369 | |
| 1370 | D.addClass([this.e.up, this.e.down, this.e.all], 'hidden'); |
| 1371 | |
| 1372 | if( nDiff>0 ){ |
| 1373 | |
| 1374 | if( nDiff>nMsgContext && (o.iPrevId==0 || o.iNextId==0) ){ |
| 1375 | nDiff = nMsgContext; |
| 1376 | } |
| 1377 | |
| 1378 | if( nDiff<=nMsgContext && o.iPrevId!=0 && o.iNextId!=0 ){ |
| 1379 | D.removeClass(this.e.all, 'hidden'); |
| 1380 | this.e.all.innerText = ( |
| 1381 | zUpArrow + " Load " + nDiff + " more " + zDownArrow |
| 1382 | ); |
| 1383 | }else{ |
| 1384 | if( o.iPrevId!=0 ) D.removeClass(this.e.up, 'hidden'); |
| 1385 | if( o.iNextId!=0 ) D.removeClass(this.e.down, 'hidden'); |
| 1386 | } |
| 1387 | } |
| 1388 | }, |
| 1389 | |
| 1390 | load_messages: function(bDown) { |
| 1391 | if( this.bIgnoreClick ) return; |
| 1392 | |
| 1393 | var iFirst = 0; /* msgid of first message to fetch */ |
| 1394 | var nFetch = 0; /* Number of messages to fetch */ |
| 1395 | var iEof = 0; /* last msgid in spacers range, plus 1 */ |
| 1396 | |
| 1397 | const e = this.e, o = this.o; |
| 1398 | this.bIgnoreClick = true; |
| 1399 | |
| 1400 | /* Figure out the required range of messages. */ |
| 1401 | if( bDown ){ |
| 1402 | iFirst = this.o.iNextId - nMsgContext; |
| 1403 | if( iFirst<this.o.iFirstInTable ){ |
| 1404 | iFirst = this.o.iFirstInTable; |
| 1405 | } |
| 1406 | }else{ |
| 1407 | iFirst = this.o.iPrevId+1; |
| 1408 | } |
| 1409 | nFetch = nMsgContext; |
| 1410 | iEof = (this.o.iNextId > 0) ? this.o.iNextId : this.o.iLastInTable+1; |
| 1411 | if( iFirst+nFetch>iEof ){ |
| 1412 | nFetch = iEof - iFirst; |
| 1413 | } |
| 1414 | const ms = this; |
| 1415 | F.fetch("chat-query",{ |
| 1416 | urlParams:{ |
| 1417 | q: '', |
| 1418 | n: nFetch, |
| 1419 | i: iFirst |
| 1420 | }, |
| 1421 | responseType: "json", |
| 1422 | onload:function(jx){ |
| 1423 | const firstChildOfBelow = e.below.firstChild; |
| 1424 | jx.msgs.forEach((m) => { |
| 1425 | var mw = new Chat.MessageWidget(m); |
| 1426 | if( bDown ){ |
| 1427 | e.below.insertBefore(mw.e.body, firstChildOfBelow); |
| 1428 | }else{ |
| 1429 | D.append(e.above, mw.e.body); |
| 1430 | } |
| 1431 | }); |
| 1432 | if( bDown ){ |
| 1433 | o.iNextId -= jx.msgs.length; |
| 1434 | }else{ |
| 1435 | o.iPrevId += jx.msgs.length; |
| 1436 | } |
| 1437 | ms.set_button_visibility(); |
| 1438 | ms.bIgnoreClick = false; |
| 1439 | } |
| 1440 | }); |
| 1441 | } |
| 1442 | }; |
| 1443 | |
| 1444 | return cf; |
| 1445 | })() /*SearchCtxLoader*/; |
| 1446 | |
| 1447 | const BlobXferState = (function(){ |
| 1448 | /* State for paste and drag/drop */ |
| 1449 | const bxs = { |
| 1450 | dropDetails: document.querySelector('#chat-drop-details'), |
| 1451 | blob: undefined, |
| @@ -2173,28 +2323,40 @@ | |
| 2323 | */ |
| 2324 | Chat.submitSearch = function(){ |
| 2325 | const term = this.inputValue(true); |
| 2326 | const eMsgTgt = D.clearElement( |
| 2327 | this.e.viewSearch.querySelector('.message-widget-content') |
| 2328 | ) |
| 2329 | if( !term ) return; |
| 2330 | D.append( eMsgTgt, "Searching for ",term," ..."); |
| 2331 | F.fetch( |
| 2332 | "chat-query", { |
| 2333 | urlParams: {q: term}, |
| 2334 | responseType: 'json', |
| 2335 | onload:function(jx){ |
| 2336 | let previd = 0; |
| 2337 | console.log("jx =",jx); |
| 2338 | D.clearElement(eMsgTgt); |
| 2339 | jx.msgs.forEach((m)=>{ |
| 2340 | const mw = new Chat.MessageWidget(m); |
| 2341 | const spacer = new Chat.SearchCtxLoader({ |
| 2342 | first: jx.first, |
| 2343 | last: jx.last, |
| 2344 | previd: previd, |
| 2345 | nextid: m.msgid |
| 2346 | }); |
| 2347 | D.append( eMsgTgt, spacer.e.body, mw.e.body ); |
| 2348 | previd = m.msgid; |
| 2349 | }); |
| 2350 | if( jx.msgs.length ){ |
| 2351 | const spacer = new Chat.SearchCtxLoader({ |
| 2352 | first: jx.first, |
| 2353 | last: jx.last, |
| 2354 | previd: previd, |
| 2355 | nextid: 0 |
| 2356 | }); |
| 2357 | D.append( eMsgTgt, spacer.e.body ); |
| 2358 | }else{ |
| 2359 | D.append( D.clearElement(eMsgTgt), |
| 2360 | 'No results matching the search term: ', |
| 2361 | term ); |
| 2362 | } |
| 2363 |