Diff
Not logged in

Differences From Artifact [77da11f25b]:

To Artifact [67a5ae8bad]:


1
2
3
4
5


6













7
8
9
10
11
12
13
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');
  let mxMsg = -50;
  if( window.fossilChatInitSize ) mxMsg = -window.fossilChatInitSize;
  const F = window.fossil, D = F.dom;
  const Chat = (function(){
    const cs = {
  const _me = F.user.name;
      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
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. */
  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());
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
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){
      let m = jx.msgs[i];
      const m = jx.msgs[i];
      let row = document.createElement("fieldset");
      if( m.msgid>mxMsg ) mxMsg = m.msgid;
      row.classList.add('message-row');
      if( m.msgid>Chat.mxMsg ) Chat.mxMsg = m.msgid;
      const eWho = D.create('legend'),
            row = D.addClass(D.fieldset(eWho), '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 ){
      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;
      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+' @ '+
        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(textNode(whoName+' @ '+m.mtime.slice(11,16)))
        eWho.append(D.text(whoName+' @ '+m.mtime.slice(11,16)))
      }
      let span = document.createElement("div");
      span.classList.add('message-content');
      span.style.backgroundColor = m.uclr;
      row.appendChild(span);
      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/") ){
          let img = document.createElement("img");
          img.src = "chat-download/" + m.msgid;
          eContent.appendChild(D.img("chat-download/" + m.msgid));
          span.appendChild(img);
        }else{
          let a = document.createElement("a");
          eContent.appendChild(D.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));
            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)"
          ));
          span.appendChild(a);
        }
        let br = document.createElement("br");
        const br = D.br();
        br.style.clear = "both";
        span.appendChild(br);
        eContent.appendChild(br);
      }
      if(m.xmsg){
        span.innerHTML += m.xmsg;
        try{D.moveChildrenTo(eContent, D.parseHtml(m.xmsg))}
        catch(e){console.error(e)}
      }
      span.classList.add('chat-message');
      eContent.classList.add('chat-message');
    }
  }
  async function poll(){
    if(poll.running) return;
    poll.running = true;
    fetch("chat-poll?name=" + mxMsg)
    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);
})();