@@ -138,11 +138,12 @@
138 138 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
viewPreview: E1('#chat-preview'),
139 139 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
previewContent: E1('#chat-preview-content'),
140 140 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
btnPreview: E1('#chat-preview-button'),
141 141 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
views: document.querySelectorAll('.chat-view'),
142 142 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
activeUserListWrapper: E1('#chat-user-list-wrapper'),
143 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- activeUserList: E1('#chat-user-list')
143 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ activeUserList: E1('#chat-user-list'),
144 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ btnClearFilter: E1('#chat-clear-filter')
144 145 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
},
145 146 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
me: F.user.name,
146 147 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
mxMsg: F.config.chat.initSize ? -F.config.chat.initSize : -50,
147 148 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
mnMsg: undefined/*lowest message ID we've seen so far (for history loading)*/,
148 149 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
pageIsActive: 'visible'===document.visibilityState,
@@ -157,15 +158,31 @@
157 158 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
(JS Date object). Only messages received by the chat client
158 159 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
are considered. */
159 160 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/* Reminder: to convert a Julian time J to JS:
160 161 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
new Date((J - 2440587.5) * 86400000) */
161 162 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
},
162 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- filterState:{
163 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- activeUser: undefined,
164 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- match: function(uname){
165 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- return this.activeUser===uname || !this.activeUser;
166 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
163 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ filter: {
164 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ user:{
165 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ activeTag: undefined,
166 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ match: function(uname){
167 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return !this.activeTag || this.activeTag===uname;
168 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ },
169 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ matchElem: function(e){
170 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return !this.activeTag || this.activeTag===e.dataset.xfrom;
171 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
172 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ },
173 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ hashtag:{
174 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ activeTag: undefined,
175 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ match: function(tag){
176 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return !this.activeTag || tag===this.activeTag;
177 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ },
178 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ matchElem: function(e){
179 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return !this.activeTag
180 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ || !!e.querySelector('[data-hashtag='+this.activeTag+']');
181 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
182 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ },
183 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ current: undefined/*gets set to current active filter*/
167 184 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
},
168 185 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/** Gets (no args) or sets (1 arg) the current input text field value,
169 186 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
taking into account single- vs multi-line input. The getter returns
170 187 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
a string and the setter returns this object. */
171 188 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
inputValue: function(){
@@ -280,11 +297,12 @@
280 297 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
the list. */
281 298 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
injectMessageElem: function f(e, atEnd){
282 299 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
const mip = atEnd ? this.e.loadOlderToolbar : this.e.messageInjectPoint,
283 300 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
holder = this.e.viewMessages,
284 301 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
prevMessage = this.e.newestMessage;
285 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if(!this.filterState.match(e.dataset.xfrom)){
302 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(this.filter.current
303 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ && !this.filter.current.matchElem(e)){
286 304 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
e.classList.add('hidden');
287 305 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
288 306 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if(atEnd){
289 307 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
const fe = mip.nextElementSibling;
290 308 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if(fe) mip.parentNode.insertBefore(e, fe);
@@ -478,11 +496,11 @@
478 496 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
else return 0;
479 497 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
};
480 498 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
callee.addUserElem = function(u){
481 499 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
const uSpan = D.addClass(D.span(), 'chat-user');
482 500 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
const uDate = self.usersLastSeen[u];
483 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if(self.filterState.activeUser===u){
501 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(self.filter.user.activeTag===u){
484 502 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
uSpan.classList.add('selected');
485 503 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
486 504 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
uSpan.dataset.uname = u;
487 505 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
D.append(uSpan, u, "\n",
488 506 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
D.append(
@@ -500,37 +518,111 @@
500 518 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Object.keys(this.usersLastSeen).sort(
501 519 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
callee.sortUsersSeen
502 520 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
).forEach(callee.addUserElem);
503 521 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return this;
504 522 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
},
523 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /**
524 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ For each Chat.MessageWidget element (X.message-widget) for
525 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ which predicate(elem) returns true, the 'hidden' class is
526 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ removed from that message. For all others, 'hidden' is
527 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ added. If predicate is falsy, 'hidden' is removed from all
528 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ elements. After filtering, it will try to scroll the last
529 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ not-filtered-out message into view, but exactly where it
530 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ scrolls into view (top, middle, button) is
531 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ unpredictable. Returns this object.
532 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
533 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ The argument may optionally be an object from this.filter,
534 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ in which case its matchElem() method becomes the predicate.
535 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
536 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Note that this does not encapsulate certain filter-specific
537 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ logic which applies changes to elements other than the
538 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ main message list or this.e.btnClearFilter.
539 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
540 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ applyMessageFilter: function(predicate){
541 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const self = this;
542 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ let eLast;
543 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ console.debug("applyMessageFilter(",predicate,")");
544 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(!predicate){
545 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ D.removeClass(this.e.viewMessages.querySelectorAll('.message-widget.hidden'),
546 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ 'hidden');
547 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ D.addClass(this.e.btnClearFilter, 'hidden');
548 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }else if('function'!==typeof predicate
549 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ && predicate.matchElem){
550 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* assume Chat.filter object */
551 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const p = predicate;
552 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ predicate = (e)=>p.matchElem(e);
553 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
554 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(predicate){
555 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this.e.viewMessages.querySelectorAll('.message-widget').forEach(function(e){
556 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(predicate(e)){
557 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ e.classList.remove('hidden');
558 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ eLast = e;
559 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }else{
560 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ e.classList.add('hidden');
561 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
562 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ });
563 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ D.removeClass(this.e.btnClearFilter, 'hidden');
564 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
565 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(eLast) eLast.scrollIntoView(false);
566 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ else this.scrollMessagesTo(1);
567 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return this;
568 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ },
569 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /**
570 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Clears the current message filter, if any, and clears the
571 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ activeTag property of all members of this.filter. Returns
572 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this object. This also unfortunately performs some
573 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ filter-type-specific logic which we have not yet managed to
574 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ encapsulate more cleanly.
575 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
576 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ clearFilters: function(){
577 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(!this.filter.current) return this;
578 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this.filter.current = undefined;
579 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this.applyMessageFilter(false);
580 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const self = this;
581 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Object.keys(this.filter).forEach(function(k){
582 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const f = self.filter[k];
583 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(f) f.activeTag = undefined;
584 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ });
585 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this.e.activeUserList.querySelectorAll('.chat-user').forEach(
586 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /*Unfortante filter-specific logic*/
587 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ (e)=>e.classList.remove('selected')
588 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ );
589 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return this;
590 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ },
505 591 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/**
506 592 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Applies user name filter to all current messages, or clears
507 593 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
the filter if uname is falsy.
508 594 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
509 595 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
setUserFilter: function(uname){
510 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- this.filterState.activeUser = uname;
511 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- const mw = this.e.viewMessages.querySelectorAll('.message-widget');
596 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(!uname || (this.filter.current
597 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ && this.filter.current!==this.filter.user)){
598 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this.clearFilters();
599 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
600 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this.filter.user.activeTag = uname;
601 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(uname) this.applyMessageFilter(this.filter.user);
602 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this.filter.current = uname ? this.filter.user : undefined;
512 603 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
const self = this;
513 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- let eLast;
514 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if(!uname){
515 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- D.removeClass(Chat.e.viewMessages.querySelectorAll('.message-widget.hidden'),
516 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- 'hidden');
517 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }else{
518 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- mw.forEach(function(w){
519 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if(self.filterState.match(w.dataset.xfrom)){
520 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- w.classList.remove('hidden');
521 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- eLast = w;
522 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }else{
523 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- w.classList.add('hidden');
524 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
525 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- });
526 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
527 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if(eLast) eLast.scrollIntoView(false);
528 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- else this.scrollMessagesTo(1);
529 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- cs.e.activeUserList.querySelectorAll('.chat-user').forEach(function(e){
530 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- e.classList[uname===e.dataset.uname ? 'add' : 'remove']('selected');
531 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- });
604 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this.e.activeUserList.querySelectorAll('.chat-user').forEach(function(e){
605 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ e.classList[
606 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ self.filter.user.activeTag===e.dataset.uname
607 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ? 'add' : 'remove'
608 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ]('selected');
609 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ });
610 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return this;
611 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ },
612 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /**
613 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Applies a hashtag filter to all current messages, or clears
614 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ the filter if tag is falsy.
615 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
616 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ setHashtagFilter: function(tag){
617 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(!tag || (this.filter.current
618 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ && this.filter.current!==this.filter.hashtag)){
619 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this.clearFilters();
620 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
621 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this.filter.hashtag.activeTag = tag;
622 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(tag) this.applyMessageFilter(this.filter.hashtag);
623 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ this.filter.current = tag ? this.filter.hashtag : undefined;
532 624 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return this;
533 625 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
},
534 626 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
535 627 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/**
536 628 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
If animations are enabled, passes its arguments
@@ -782,21 +874,45 @@
782 874 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
cs.setCurrentView(cs.e.viewMessages);
783 875 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if(eUser.classList.contains('selected')){
784 876 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/* If curently selected, toggle filter off */
785 877 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
eUser.classList.remove('selected');
786 878 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
cs.setUserFilter(false);
787 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- delete f.$eSelected;
788 879 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}else{
789 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if(f.$eSelected) f.$eSelected.classList.remove('selected');
790 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- f.$eSelected = eUser;
791 880 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
eUser.classList.add('selected');
792 881 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
cs.setUserFilter(uname);
793 882 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
794 883 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return false;
795 884 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}, false);
885 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
886 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ cs.e.btnClearFilter.addEventListener('click',function(){
887 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ D.addClass(this,'hidden');
888 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ cs.clearFilters();
889 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }, false);
796 890 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return cs;
797 891 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
})()/*Chat initialization*/;
892 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
893 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /** To be passed each MessageWidget's top-level DOM element
894 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ after initial processing of the message, to set up
895 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ hashtag references. */
896 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const setupHashtags = function f(elem){
897 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(!f.$click){
898 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ f.$click = function(ev){
899 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const tag = ev.target.dataset.hashtag;
900 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(tag){
901 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ console.debug("hashtag = ",tag);
902 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Chat.setHashtagFilter(
903 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ tag===Chat.filter.hashtag.activeTag
904 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ? false : tag
905 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ );
906 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
907 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ };
908 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
909 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ elem.querySelectorAll('[data-hashtag]').forEach(function(e){
910 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ e.dataset.hashtag = e.dataset.hashtag.toLowerCase();
911 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ e.addEventListener('click', f.$click, false);
912 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ })
913 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ };
798 914 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
799 915 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/**
800 916 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Custom widget type for rendering messages (one message per
801 917 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
instance). These are modelled after FIELDSET elements but we
802 918 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
don't use FIELDSET because of cross-browser inconsistencies in
@@ -915,10 +1031,11 @@
915 1031 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
// Used by Chat.reportErrorAsMessage()
916 1032 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
D.append(contentTarget, m.xmsg);
917 1033 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}else{
918 1034 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
contentTarget.innerHTML = m.xmsg;
919 1035 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
contentTarget.querySelectorAll('a').forEach(addAnchorTargetBlank);
1036 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ setupHashtags(contentTarget);
920 1037 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if(F.pikchr){
921 1038 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
F.pikchr.addSrcView(contentTarget.querySelectorAll('svg.pikchr'));
922 1039 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
923 1040 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
924 1041 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
@@ -999,31 +1116,24 @@
999 1116 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
y: 'a'
1000 1117 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}), "User's Timeline"),
1001 1118 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
'target', '_blank'
1002 1119 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
);
1003 1120 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
D.append(toolbar2, timelineLink);
1004 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if(Chat.filterState.activeUser &&
1005 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Chat.filterState.match(eMsg.dataset.xfrom)){
1006 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- /* Add a button to clear user filter and jump to
1121 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(Chat.filter.current){
1122 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* Add a button to clear filter and jump to
1007 1123 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
this message in its original context. */
1008 1124 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
D.append(
1009 1125 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
this.e,
1010 1126 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
D.append(
1011 1127 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
D.addClass(D.div(), 'toolbar'),
1012 1128 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
D.button(
1013 1129 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
"Message in context",
1014 1130 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
function(){
1015 1131 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
self.hide();
1016 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Chat.setUserFilter(false);
1132 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Chat.clearFilters();
1017 1133 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
eMsg.scrollIntoView(false);
1018 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Chat.animate(
1019 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- eMsg.firstElementChild, 'anim-flip-h'
1020 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- //eMsg.firstElementChild, 'anim-flip-v'
1021 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- //eMsg.childNodes, 'anim-rotate-360'
1022 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- //eMsg.childNodes, 'anim-flip-v'
1023 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- //eMsg, 'anim-flip-v'
1024 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- );
1134 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Chat.animate(eMsg.firstElementChild, 'anim-flip-h');
1025 1135 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
})
1026 1136 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
)
1027 1137 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
);
1028 1138 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}/*jump-to button*/
1029 1139 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
@@ -1241,12 +1351,14 @@
1241 1351 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
persistentSetting: 'active-user-list',
1242 1352 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
callback: function(){
1243 1353 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
D.toggleClass(Chat.e.activeUserListWrapper,'hidden');
1244 1354 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
D.removeClass(Chat.e.activeUserListWrapper, 'collapsed');
1245 1355 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if(Chat.e.activeUserListWrapper.classList.contains('hidden')){
1246 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- /* When hiding this element, undo all filtering */
1247 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Chat.setUserFilter(false);
1356 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* When hiding this element, undo user filtering */
1357 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if(Chat.filter.current === Chat.filter.user){
1358 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Chat.setUserFilter(false);
1359 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
1248 1360 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/*Ideally we'd scroll the final message into view
1249 1361 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
now, but because viewMessages is currently hidden behind
1250 1362 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
viewConfig, scrolling is a no-op. */
1251 1363 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Chat.scrollMessagesTo(1);
1252 1364 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}else{
1253 1365 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!