1
2
3
4
5
6
7
8
9
10
11
12
13
|
(function(){
const form = document.querySelector('#chat-form');
let mxMsg = -50;
if( window.fossilChatInitSize ) mxMsg = -window.fossilChatInitSize;
const F = window.fossil, D = F.dom;
const _me = F.user.name;
/* State for paste and drag/drop */
const BlobXferState = {
dropDetails: document.querySelector('#chat-drop-details'),
blob: undefined
};
/** Updates the paste/drop zone with details of the pasted/dropped
data. The argument must be a Blob or Blob-like object (File) or
|
<
<
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
(function(){
const form = document.querySelector('#chat-form');
const F = window.fossil, D = F.dom;
const Chat = (function(){
const cs = {
me: F.user.name,
mxMsg: F.config.chatInitSize ? -F.config.chatInitSize : -50,
pageIsActive: !document.hidden,
onPageActive: function(){console.debug("Page active.")}, //override below
onPageInactive: function(){console.debug("Page inactive.")} //override below
};
document.addEventListener('visibilitychange', function(ev){
cs.pageIsActive = !document.hidden;
if(cs.pageIsActive) cs.onPageActive();
else cs.onPageInactive();
}, true);
return cs;
})();
/* State for paste and drag/drop */
const BlobXferState = {
dropDetails: document.querySelector('#chat-drop-details'),
blob: undefined
};
/** Updates the paste/drop zone with details of the pasted/dropped
data. The argument must be a Blob or Blob-like object (File) or
|
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
if(f.injectPoint.nextSibling){
f.injectPoint.parentNode.insertBefore(e, f.injectPoint.nextSibling);
}else{
f.injectPoint.parentNode.appendChild(e);
}
};
/* Returns a new TEXT node with the given text content. */
const textNode = (T)=>document.createTextNode(T);
/** Returns the local time string of Date object d, defaulting
to the current time. */
const localTimeString = function ff(d){
if(!ff.pad){
ff.pad = (x)=>(''+x).length>1 ? x : '0'+x;
}
d || (d = new Date());
|
<
|
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
if(f.injectPoint.nextSibling){
f.injectPoint.parentNode.insertBefore(e, f.injectPoint.nextSibling);
}else{
f.injectPoint.parentNode.appendChild(e);
}
};
/* Returns a new TEXT node with the given text content. */
/** Returns the local time string of Date object d, defaulting
to the current time. */
const localTimeString = function ff(d){
if(!ff.pad){
ff.pad = (x)=>(''+x).length>1 ? x : '0'+x;
}
d || (d = new Date());
|
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
|
}
f.popup.show(x, y);
};
/** Callback for poll() to inject new content into the page. */
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);
if( m.xfrom==_me && window.outerWidth<1000 ){
eWho.setAttribute('align', 'right');
row.style.justifyContent = "flex-end";
}else{
eWho.setAttribute('align', 'left');
}
eWho.style.backgroundColor = m.uclr;
row.appendChild(eWho);
eWho.classList.add('message-user');
let 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)))
}
let span = document.createElement("div");
span.classList.add('message-content');
span.style.backgroundColor = m.uclr;
row.appendChild(span);
if( m.fsize>0 ){
if( m.fmime && m.fmime.startsWith("image/") ){
let img = document.createElement("img");
img.src = "chat-download/" + m.msgid;
span.appendChild(img);
}else{
let a = document.createElement("a");
let txt = "(" + m.fname + " " + m.fsize + " bytes)";
a.href = window.fossil.rootPath+
'chat-download/' + m.msgid+'/'+encodeURIComponent(m.fname);
// ^^^ add m.fname to URL to cause downloaded file to have that name.
a.appendChild(textNode(txt));
span.appendChild(a);
}
let br = document.createElement("br");
br.style.clear = "both";
span.appendChild(br);
}
if(m.xmsg){
span.innerHTML += m.xmsg;
}
span.classList.add('chat-message');
}
}
async function poll(){
if(poll.running) return;
poll.running = true;
fetch("chat-poll?name=" + mxMsg)
.then(x=>x.json())
.then(y=>newcontent(y))
.catch(e=>console.error(e))
.finally(()=>poll.running=false)
}
poll();
setInterval(poll, 1000);
})();
|
|
<
|
>
|
<
|
<
|
|
<
|
|
|
<
|
<
|
<
|
|
|
>
|
<
|
|
|
>
|
|
|
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
}
f.popup.show(x, y);
};
/** Callback for poll() to inject new content into the page. */
function newcontent(jx){
var i;
for(i=0; i<jx.msgs.length; ++i){
const m = jx.msgs[i];
if( m.msgid>Chat.mxMsg ) Chat.mxMsg = m.msgid;
const eWho = D.create('legend'),
row = D.addClass(D.fieldset(eWho), 'message-row');
injectMessage(row);
eWho.dataset.timestamp = m.mtime;
eWho.addEventListener('click', handleLegendClicked, false);
if( m.xfrom==Chat.me && window.outerWidth<1000 ){
eWho.setAttribute('align', 'right');
row.style.justifyContent = "flex-end";
}else{
eWho.setAttribute('align', 'left');
}
eWho.style.backgroundColor = m.uclr;
eWho.classList.add('message-user');
let 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(D.text(whoName+' @ '+
d.getHours()+":"+(d.getMinutes()+100).toString().slice(1,3)
))
}else{
/* Show UTC on systems where Date() does not work */
eWho.append(D.text(whoName+' @ '+m.mtime.slice(11,16)))
}
let eContent = D.addClass(D.div(),'message-content','chat-message');
eContent.style.backgroundColor = m.uclr;
row.appendChild(eContent);
if( m.fsize>0 ){
if( m.fmime && m.fmime.startsWith("image/") ){
eContent.appendChild(D.img("chat-download/" + m.msgid));
}else{
eContent.appendChild(D.a(
window.fossil.rootPath+
'chat-download/' + m.msgid+'/'+encodeURIComponent(m.fname),
// ^^^ add m.fname to URL to cause downloaded file to have that name.
"(" + m.fname + " " + m.fsize + " bytes)"
));
}
const br = D.br();
br.style.clear = "both";
eContent.appendChild(br);
}
if(m.xmsg){
try{D.moveChildrenTo(eContent, D.parseHtml(m.xmsg))}
catch(e){console.error(e)}
}
eContent.classList.add('chat-message');
}
}
async function poll(){
if(poll.running) return;
poll.running = true;
fetch("chat-poll?name=" + Chat.mxMsg)
.then(x=>x.json())
.then(y=>newcontent(y))
.catch(e=>console.error(e))
.finally(()=>poll.running=false)
}
poll();
setInterval(poll, 1000);
})();
|