Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Chat message precise timestamps are now shown via a tap/click popup, rather than hoverhelp, for mobile compatibility. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | chatroom-dev |
| Files: | files | file ages | folders |
| SHA3-256: |
0101325f9dcc55cbc8eb871cc1d85564 |
| User & Date: | stephan 2020-12-23 06:26:40.872 |
Context
|
2020-12-23
| ||
| 07:09 | Implemented paste image into chat from clipboard. Fixed posted file download link but the files download with the same name as their message ID, which isn't very friendly. Not sure how to resolve that bit. ... (check-in: eb7845f339 user: stephan tags: chatroom-dev) | |
| 06:26 | Chat message precise timestamps are now shown via a tap/click popup, rather than hoverhelp, for mobile compatibility. ... (check-in: 0101325f9d user: stephan tags: chatroom-dev) | |
| 05:44 | Import fossil bootstrapping JS into the chat app, add current login name to window.fossil.user.name, and use that name as the initial 'me' value in chat.js (resolves the FIXME in that latter part). ... (check-in: 4e832e9f40 user: stephan tags: chatroom-dev) | |
Changes
Changes to src/chat.c.
| ︙ | ︙ | |||
85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
@ display: flex;
@ flex-direction: row;
@ align-items: center;
@ }
@ #chat-input-file > input {
@ flex: 1 0 auto;
@ }
@ </style>
@ <form accept-encoding="utf-8" id="chat-form">
@ <div id='chat-input-area'>
@ <div id='chat-input-line'>
@ <input type="text" name="msg" id="sbox"\
@ placeholder="Type message here.">
@ <input type="submit" value="Send">
| > > > > > > > | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
@ display: flex;
@ flex-direction: row;
@ align-items: center;
@ }
@ #chat-input-file > input {
@ flex: 1 0 auto;
@ }
@ .chat-timestamp {
@ font-family: monospace;
@ font-size: 0.8em;
@ white-space: pre;
@ text-align: left;
@ opacity: 0.8;
@ }
@ </style>
@ <form accept-encoding="utf-8" id="chat-form">
@ <div id='chat-input-area'>
@ <div id='chat-input-line'>
@ <input type="text" name="msg" id="sbox"\
@ placeholder="Type message here.">
@ <input type="submit" value="Send">
|
| ︙ | ︙ | |||
107 108 109 110 111 112 113 |
/* New chat messages get inserted immediately after this element */
@ <span id='message-inject-point'></span>
builtin_fossil_js_bundle_or("popupwidget", NULL);
/* Always in-line the javascript for the chat page */
@ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */
| | > > > | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
/* New chat messages get inserted immediately after this element */
@ <span id='message-inject-point'></span>
builtin_fossil_js_bundle_or("popupwidget", NULL);
/* Always in-line the javascript for the chat page */
@ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */
@ window.addEventListener('load', function(){
/* We need an onload handler to ensure that window.fossil is
loaded first. */
cgi_append_content(builtin_text("chat.js"),-1);
@ }, false);
@ </script>
style_finish_page();
}
/* Definition of repository tables used by chat
*/
|
| ︙ | ︙ |
Changes to src/chat.js.
1 2 3 |
(function(){
const form = document.querySelector('#chat-form');
let mxMsg = 0;
| < | > | 1 2 3 4 5 6 7 8 9 10 11 12 |
(function(){
const form = document.querySelector('#chat-form');
let mxMsg = 0;
const F = window.fossil;
const _me = F.user.name;
form.addEventListener('submit',(e)=>{
e.preventDefault();
if( form.msg.value.length>0 || form.file.value.length>0 ){
fetch("chat-send",{
method: 'POST',
body: new FormData(form)
});
|
| ︙ | ︙ | |||
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
return [
d.getFullYear(),'-',ff.pad(d.getMonth()+1/*sigh*/),
'-',ff.pad(d.getDate()),
' ',ff.pad(d.getHours()),':',ff.pad(d.getMinutes()),
':',ff.pad(d.getSeconds())
].join('');
};
function newcontent(jx){
var i;
for(i=0; i<jx.msgs.length; ++i){
let m = jx.msgs[i];
let row = document.createElement("fieldset");
if( m.msgid>mxMsg ) mxMsg = m.msgid;
row.classList.add('message-row');
injectMessage(row);
const eWho = document.createElement('legend');
eWho.setAttribute('align', (m.xfrom===_me ? 'right' : 'left'));
eWho.style.backgroundColor = m.uclr;
row.appendChild(eWho);
eWho.classList.add('message-user');
let whoName;
if( m.xfrom===_me ){
whoName = 'me';
row.classList.add('user-is-me');
}else{
whoName = m.xfrom;
}
var d = new Date(m.mtime + "Z");
if( d.getMinutes().toString()!="NaN" ){
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < < | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
return [
d.getFullYear(),'-',ff.pad(d.getMonth()+1/*sigh*/),
'-',ff.pad(d.getDate()),
' ',ff.pad(d.getHours()),':',ff.pad(d.getMinutes()),
':',ff.pad(d.getSeconds())
].join('');
};
/* Returns an almost-ISO8601 form of Date object d. */
const iso8601ish = function(d){
return d.toISOString()
.replace('T',' ').replace(/\.\d+/,'').replace('Z', ' GMT');
};
/* Timestampt popup widget */
const tsPopup = new F.PopupWidget({
cssClass: ['fossil-tooltip', 'chat-timestamp'],
refresh:function(){
const D = F.dom;
D.clearElement(this.e);
const d = new Date(this._timestamp+"Z");
if(d.getMinutes().toString()!=="NaN"){
// Date works, render informative timestamps
D.append(this.e, localTimeString(d)," client-local", D.br(),
iso8601ish(d));
}else{
// Date doesn't work, so dumb it down...
D.append(this.e, this._timestamp," GMT");
}
}
});
const hidePopup = ()=>tsPopup.hide();
tsPopup.e.addEventListener('click', hidePopup, false);
document.body.addEventListener('click', hidePopup, true);
document.body.addEventListener('keydown', function(ev){
if(tsPopup.isShown() && 27===ev.which) tsPopup.hide();
}, true);
/* Event handler for clicking .message-user elements to show their
timestamps. */
const handleLegendClicked = function(ev){
const rect = ev.target.getBoundingClientRect();
tsPopup._timestamp = ev.target.dataset.timestamp;
let x = rect.left, y = rect.top - 10;
tsPopup.show(ev.target)/*so we can get its computed size*/;
// Shift to the left for right-aligned messages
if('right'===ev.target.getAttribute('align')){
const pRect = tsPopup.e.getBoundingClientRect();
x -= pRect.width/3*2;
}
tsPopup.show(x, y);
};
function newcontent(jx){
var i;
for(i=0; i<jx.msgs.length; ++i){
let m = jx.msgs[i];
let row = document.createElement("fieldset");
if( m.msgid>mxMsg ) mxMsg = m.msgid;
row.classList.add('message-row');
injectMessage(row);
const eWho = document.createElement('legend');
eWho.dataset.timestamp = m.mtime;
eWho.addEventListener('click', handleLegendClicked, false);
eWho.setAttribute('align', (m.xfrom===_me ? 'right' : 'left'));
eWho.style.backgroundColor = m.uclr;
row.appendChild(eWho);
eWho.classList.add('message-user');
let whoName;
if( m.xfrom===_me ){
whoName = 'me';
row.classList.add('user-is-me');
}else{
whoName = m.xfrom;
}
var d = new Date(m.mtime + "Z");
if( d.getMinutes().toString()!="NaN" ){
/* Show local time when we can compute it */
eWho.append(textNode(whoName+' @ '+
d.getHours()+":"+(d.getMinutes()+100).toString().slice(1,3)
))
}else{
/* Show UTC on systems where Date() does not work */
eWho.append(textNode(whoName+' @ '+m.mtime.slice(11,16)))
|
| ︙ | ︙ |
Changes to src/default.css.
| ︙ | ︙ | |||
1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 |
.message-row .message-user {
border-radius: 0.25em 0.25em 0 0;
padding: 0 0.5em;
/*text-align: left; Firefox requires the 'align' attribute */
margin-left: 0.15em;
padding: 0 0.5em 0em 0.5em;
margin-bottom: 0.4em;
}
/* Reposition "my" posts to the right */
.message-row.user-is-me .message-user {
/*text-align: right; Firefox requires the 'align' attribute */
margin-left: 0;
margin-right: 0.25em;
}
| > | 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 |
.message-row .message-user {
border-radius: 0.25em 0.25em 0 0;
padding: 0 0.5em;
/*text-align: left; Firefox requires the 'align' attribute */
margin-left: 0.15em;
padding: 0 0.5em 0em 0.5em;
margin-bottom: 0.4em;
cursor: pointer;
}
/* Reposition "my" posts to the right */
.message-row.user-is-me .message-user {
/*text-align: right; Firefox requires the 'align' attribute */
margin-left: 0;
margin-right: 0.25em;
}
|