Diff
Not logged in

Differences From Artifact [77da11f25b]:

To Artifact [67a5ae8bad]:


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);
})();