Fossil SCM
The ping=TCPPORT query parameter to /chat causes a call to /chat-ping on localhost and the given port whenever new chat content arrives. Can be used for notifications.
Commit
ebdd91b92fbff770d9457bcedd990453283763e5b70156eef2c5731ed90d7ca8
Parent
822653c26952d70…
2 files changed
+24
-1
+3
+24
-1
| --- src/chat.c | ||
| +++ src/chat.c | ||
| @@ -72,17 +72,27 @@ | ||
| 72 | 72 | |
| 73 | 73 | /* |
| 74 | 74 | ** WEBPAGE: chat |
| 75 | 75 | ** |
| 76 | 76 | ** Start up a browser-based chat session. |
| 77 | +** | |
| 78 | +** This is the main page that humans use to access the chatroom. Simply | |
| 79 | +** point a web-browser at /chat and the screen fills with the latest | |
| 80 | +** chat messages, and waits for new one. | |
| 81 | +** | |
| 82 | +** Other /chat-OP pages are used by XHR requests from this page to | |
| 83 | +** send new chat message, delete older messages, or poll for changes. | |
| 77 | 84 | */ |
| 78 | 85 | void chat_webpage(void){ |
| 86 | + int iPingTcp; | |
| 79 | 87 | login_check_credentials(); |
| 80 | 88 | if( !g.perm.Chat ){ |
| 81 | 89 | login_needed(g.anon.Chat); |
| 82 | 90 | return; |
| 83 | 91 | } |
| 92 | + iPingTcp = atoi(PD("ping","0")); | |
| 93 | + if( iPingTcp<1000 || iPingTcp>65535 ) iPingTcp = 0; | |
| 84 | 94 | style_set_current_feature("chat"); |
| 85 | 95 | style_header("Chat"); |
| 86 | 96 | @ <style> |
| 87 | 97 | @ #dialog { |
| 88 | 98 | @ width: 97%%; |
| @@ -169,12 +179,13 @@ | ||
| 169 | 179 | /* Always in-line the javascript for the chat page */ |
| 170 | 180 | @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */ |
| 171 | 181 | /* We need an onload handler to ensure that window.fossil is |
| 172 | 182 | initialized before the chat init code runs. */ |
| 173 | 183 | @ window.addEventListener('load', function(){ |
| 174 | - @ window.fossil.config.chatInitSize = | |
| 184 | + @ window.fossil.config.chatInitSize =\ | |
| 175 | 185 | @ %d(db_get_int("chat-initial-history",50)); |
| 186 | + @ window.fossil.config.pingTcp = %d(iPingTcp); | |
| 176 | 187 | cgi_append_content(builtin_text("chat.js"),-1); |
| 177 | 188 | @ }, false); |
| 178 | 189 | @ </script> |
| 179 | 190 | |
| 180 | 191 | style_finish_page(); |
| @@ -532,5 +543,17 @@ | ||
| 532 | 543 | " VALUES(julianday('now'), %Q, %d);\n" |
| 533 | 544 | "COMMIT;", |
| 534 | 545 | mdel, g.zLogin, mdel |
| 535 | 546 | ); |
| 536 | 547 | } |
| 548 | + | |
| 549 | +/* | |
| 550 | +** WEBPAGE: chat-ping | |
| 551 | +** | |
| 552 | +** HTTP requests coming to this page from a loopback IP address cause | |
| 553 | +** a single \007 (bel) character to be written on the controlling TTY. | |
| 554 | +** This is used to implement an audiable alert by local web clients. | |
| 555 | +*/ | |
| 556 | +void chat_ping_webpage(void){ | |
| 557 | + const char *zIpAddr = PD("REMOTE_ADDR","nil"); | |
| 558 | + if( cgi_is_loopback(zIpAddr) ) fputc(7, stderr); | |
| 559 | +} | |
| 537 | 560 |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -72,17 +72,27 @@ | |
| 72 | |
| 73 | /* |
| 74 | ** WEBPAGE: chat |
| 75 | ** |
| 76 | ** Start up a browser-based chat session. |
| 77 | */ |
| 78 | void chat_webpage(void){ |
| 79 | login_check_credentials(); |
| 80 | if( !g.perm.Chat ){ |
| 81 | login_needed(g.anon.Chat); |
| 82 | return; |
| 83 | } |
| 84 | style_set_current_feature("chat"); |
| 85 | style_header("Chat"); |
| 86 | @ <style> |
| 87 | @ #dialog { |
| 88 | @ width: 97%%; |
| @@ -169,12 +179,13 @@ | |
| 169 | /* Always in-line the javascript for the chat page */ |
| 170 | @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */ |
| 171 | /* We need an onload handler to ensure that window.fossil is |
| 172 | initialized before the chat init code runs. */ |
| 173 | @ window.addEventListener('load', function(){ |
| 174 | @ window.fossil.config.chatInitSize = |
| 175 | @ %d(db_get_int("chat-initial-history",50)); |
| 176 | cgi_append_content(builtin_text("chat.js"),-1); |
| 177 | @ }, false); |
| 178 | @ </script> |
| 179 | |
| 180 | style_finish_page(); |
| @@ -532,5 +543,17 @@ | |
| 532 | " VALUES(julianday('now'), %Q, %d);\n" |
| 533 | "COMMIT;", |
| 534 | mdel, g.zLogin, mdel |
| 535 | ); |
| 536 | } |
| 537 |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -72,17 +72,27 @@ | |
| 72 | |
| 73 | /* |
| 74 | ** WEBPAGE: chat |
| 75 | ** |
| 76 | ** Start up a browser-based chat session. |
| 77 | ** |
| 78 | ** This is the main page that humans use to access the chatroom. Simply |
| 79 | ** point a web-browser at /chat and the screen fills with the latest |
| 80 | ** chat messages, and waits for new one. |
| 81 | ** |
| 82 | ** Other /chat-OP pages are used by XHR requests from this page to |
| 83 | ** send new chat message, delete older messages, or poll for changes. |
| 84 | */ |
| 85 | void chat_webpage(void){ |
| 86 | int iPingTcp; |
| 87 | login_check_credentials(); |
| 88 | if( !g.perm.Chat ){ |
| 89 | login_needed(g.anon.Chat); |
| 90 | return; |
| 91 | } |
| 92 | iPingTcp = atoi(PD("ping","0")); |
| 93 | if( iPingTcp<1000 || iPingTcp>65535 ) iPingTcp = 0; |
| 94 | style_set_current_feature("chat"); |
| 95 | style_header("Chat"); |
| 96 | @ <style> |
| 97 | @ #dialog { |
| 98 | @ width: 97%%; |
| @@ -169,12 +179,13 @@ | |
| 179 | /* Always in-line the javascript for the chat page */ |
| 180 | @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */ |
| 181 | /* We need an onload handler to ensure that window.fossil is |
| 182 | initialized before the chat init code runs. */ |
| 183 | @ window.addEventListener('load', function(){ |
| 184 | @ window.fossil.config.chatInitSize =\ |
| 185 | @ %d(db_get_int("chat-initial-history",50)); |
| 186 | @ window.fossil.config.pingTcp = %d(iPingTcp); |
| 187 | cgi_append_content(builtin_text("chat.js"),-1); |
| 188 | @ }, false); |
| 189 | @ </script> |
| 190 | |
| 191 | style_finish_page(); |
| @@ -532,5 +543,17 @@ | |
| 543 | " VALUES(julianday('now'), %Q, %d);\n" |
| 544 | "COMMIT;", |
| 545 | mdel, g.zLogin, mdel |
| 546 | ); |
| 547 | } |
| 548 | |
| 549 | /* |
| 550 | ** WEBPAGE: chat-ping |
| 551 | ** |
| 552 | ** HTTP requests coming to this page from a loopback IP address cause |
| 553 | ** a single \007 (bel) character to be written on the controlling TTY. |
| 554 | ** This is used to implement an audiable alert by local web clients. |
| 555 | */ |
| 556 | void chat_ping_webpage(void){ |
| 557 | const char *zIpAddr = PD("REMOTE_ADDR","nil"); |
| 558 | if( cgi_is_loopback(zIpAddr) ) fputc(7, stderr); |
| 559 | } |
| 560 |
+3
| --- src/chat.js | ||
| +++ src/chat.js | ||
| @@ -360,10 +360,13 @@ | ||
| 360 | 360 | // perfectly safe to use in this context. |
| 361 | 361 | eContent.innerHTML += m.xmsg |
| 362 | 362 | } |
| 363 | 363 | eContent.classList.add('chat-message'); |
| 364 | 364 | } |
| 365 | + if(i && window.fossil.config.pingTcp){ | |
| 366 | + fetch("http:/"+"/localhost:"+window.fossil.config.pingTcp+"/chat-ping"); | |
| 367 | + } | |
| 365 | 368 | } |
| 366 | 369 | async function poll(){ |
| 367 | 370 | if(poll.running) return; |
| 368 | 371 | poll.running = true; |
| 369 | 372 | fetch("chat-poll?name=" + Chat.mxMsg) |
| 370 | 373 |
| --- src/chat.js | |
| +++ src/chat.js | |
| @@ -360,10 +360,13 @@ | |
| 360 | // perfectly safe to use in this context. |
| 361 | eContent.innerHTML += m.xmsg |
| 362 | } |
| 363 | eContent.classList.add('chat-message'); |
| 364 | } |
| 365 | } |
| 366 | async function poll(){ |
| 367 | if(poll.running) return; |
| 368 | poll.running = true; |
| 369 | fetch("chat-poll?name=" + Chat.mxMsg) |
| 370 |
| --- src/chat.js | |
| +++ src/chat.js | |
| @@ -360,10 +360,13 @@ | |
| 360 | // perfectly safe to use in this context. |
| 361 | eContent.innerHTML += m.xmsg |
| 362 | } |
| 363 | eContent.classList.add('chat-message'); |
| 364 | } |
| 365 | if(i && window.fossil.config.pingTcp){ |
| 366 | fetch("http:/"+"/localhost:"+window.fossil.config.pingTcp+"/chat-ping"); |
| 367 | } |
| 368 | } |
| 369 | async function poll(){ |
| 370 | if(poll.running) return; |
| 371 | poll.running = true; |
| 372 | fetch("chat-poll?name=" + Chat.mxMsg) |
| 373 |