[polari/wip/bastianilso/status-hiding] WIP
- From: Bastian Ilsø Hougaard <bastianilso src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [polari/wip/bastianilso/status-hiding] WIP
- Date: Wed, 2 Dec 2015 17:31:10 +0000 (UTC)
commit 9503cf17252a6b83905e2ff69bdf32b241c8f729
Author: Bastian Ilsø <hougaard junior gmail com>
Date: Wed Dec 2 18:27:45 2015 +0100
WIP
src/chatView.js | 211 +++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 149 insertions(+), 62 deletions(-)
---
diff --git a/src/chatView.js b/src/chatView.js
index 9d8d879..2c2cc13 100644
--- a/src/chatView.js
+++ b/src/chatView.js
@@ -11,7 +11,7 @@ const Mainloop = imports.mainloop;
const Utils = imports.utils;
const MAX_NICK_CHARS = 8;
-const IGNORE_STATUS_TIME = 5;
+const IGNORE_STATUS_TIME = 1; // ???????? // was 5
const TP_CURRENT_TIME = GLib.MAXUINT32;
const SCROLL_TIMEOUT = 100; // ms
@@ -19,7 +19,7 @@ const SCROLL_TIMEOUT = 100; // ms
const TIMESTAMP_INTERVAL = 300; // seconds of inactivity after which to
// insert a timestamp
-const ACTIVITY_DURATION = 300; // min
+const ACTIVITY_DURATION = 30; // s? // was 300
const STATUS_NOISE_MAXIMUM = 4;
const NUM_INITIAL_LOG_EVENTS = 50; // number of log events to fetch on start
@@ -104,13 +104,11 @@ const ChatView = new Lang.Class({
this._needsIndicator = true;
this._pending = {};
this._pendingLogs = [];
- this._statusCount = [
- { name: 'left',
- count: 0 },
- { name: 'joined',
- count: 0 }
+ this._statusCounts = [
+ { left: 0,
+ joined: 0,
+ total: 0 },
];
- this._statusTexts = [];
let isRoom = room.type == Tp.HandleType.ROOM;
let target = new Tpl.Entity({ type: isRoom ? Tpl.EntityType.ROOM
@@ -174,7 +172,8 @@ const ChatView = new Lang.Class({
{ name: 'status',
left_margin: MARGIN,
indent: 0,
- justification: Gtk.Justification.RIGHT },
+ justification: Gtk.Justification.RIGHT,
+ invisible: false },
{ name: 'timestamp',
left_margin: MARGIN,
indent: 0,
@@ -187,7 +186,7 @@ const ChatView = new Lang.Class({
{ name: 'expandable',
underline: Pango.Underline.SINGLE },
{ name: 'loading',
- justification: Gtk.Justification.CENTER }
+ justification: Gtk.Justification.CENTER },
];
tags.forEach(function(tagProps) {
tagTable.add(new Gtk.TextTag(tagProps));
@@ -485,8 +484,7 @@ const ChatView = new Lang.Class({
let iter = view.get_iter_at_location(x, y);
let tags = iter.get_tags();
for (let i = 0; i < tags.length; i++) {
- let url = tags[i]._url;
- let statusTexts = tags[i]._statusTexts;
+ let url = tags[i]._url
if (url) {
if (url.indexOf(':') == -1)
url = 'http://' + url;
@@ -502,19 +500,12 @@ const ChatView = new Lang.Class({
return Gdk.EVENT_STOP;
}
break;
- } else if (statusTexts) {
- let buffer = this._view.get_buffer();
- let startIter = buffer.get_iter_at_line(iter.get_line());
- let startMark = buffer.create_mark(null, iter, true);
- let endMark = buffer.create_mark(null, iter, false);
- iter.forward_to_line_end();
- buffer.delete(startIter, iter);
- statusTexts.forEach(Lang.bind(this, function(statusText) {
- buffer.insert(buffer.get_iter_at_mark(startMark), statusText + '\n', -1);
- let startIter = buffer.get_iter_at_mark(startMark);
- let endIter = buffer.get_iter_at_mark(endMark);
- buffer.apply_tag(this._lookupTag('status'), startIter, endIter);
- }));
+ } else if (tags[i].name.indexOf('status-compressed') != -1) {
+ if (isPress && button == Gdk.BUTTON_PRIMARY) {
+ let statusTag = this._lookupTag('status' + tags[i].name.slice(-1));
+ statusTag.invisible = !statusTag.invisible;
+ }
+ return Gdk.EVENT_STOP;
}
}
return Gdk.EVENT_PROPAGATE;
@@ -528,7 +519,7 @@ const ChatView = new Lang.Class({
let tags = iter.get_tags();
let hovering = false;
for (let i = 0; i < tags.length && !hovering; i++)
- if (tags[i]._url || tags[i]._statusTexts)
+ if (tags[i]._url || tags[i].name.indexOf('status-compressed' != -1))
hovering = true;
if (this._hoveringLink != hovering) {
@@ -723,8 +714,10 @@ const ChatView = new Lang.Class({
text += ' (%s)'.format(message);
if (this._shouldStatus(member.alias)) {
this._insertStatus(text);
+ log("member was active, inserting status..");
} else if (time - this._state.lastTimestamp > ACTIVITY_DURATION) {
this._insertStatusCompressed(text, 'left');
+ log("channel is idle, inserting status compressed..");
}
this._setNickStatus(member.alias, Tp.ConnectionPresenceType.OFFLINE);
},
@@ -746,15 +739,15 @@ const ChatView = new Lang.Class({
},
_resetStatusCompressed: function() {
- let mark = this._view.buffer.get_mark('idle-status');
- if (!mark)
+ let markStart = this._view.buffer.get_mark('idle-status-start');
+ let markEnd = this._view.buffer.get_mark('idle-status-end');
+ if (!markStart || !markEnd)
return;
- this._view.buffer.delete_mark(mark);
- this._statusTexts = [];
- this._statusCount.forEach(function(statusEntry) {
- statusEntry.count = 0;
- });
+ this._view.buffer.delete_mark(markStart);
+ this._view.buffer.delete_mark(markEnd);
+ let statusCount = { left: 0, joined: 0, total: 0 };
+ this._statusCounts.push(statusCount);
},
_shouldStatus: function(nick) {
@@ -767,51 +760,145 @@ const ChatView = new Lang.Class({
return time - nickTag._active < ACTIVITY_DURATION;
},
+ // InsertStatusCompressed is called whenenver we insert messages in idle channels
+ // Even if we dont insert them compressed (the 4 first messages fx).
_insertStatusCompressed: function(statusText, status) {
let time = GLib.DateTime.new_now_utc().to_unix();
+ let buffer = this._view.buffer;
+
+ // OK so this seems to make sure we dont show status message from the log history i think.
if (time - this._joinTime < IGNORE_STATUS_TIME)
return;
- this._statusTexts.push(statusText);
+ // Create a statusGroupTag which we can use to toggle invisibility
+ let statusGroupNumber = this._statusCounts.length-1;
+ let statusGroupTag = this._lookupTag('status' + statusGroupNumber);
+ if (!statusGroupTag) {
+ statusGroupTag = new Gtk.TextTag({ name: 'status' + statusGroupNumber });
+ buffer.tag_table.add(statusGroupTag);
+ //log('created new tag ' + statusTag.name);
+ }
+
+ // this tag is just cosmetic stuff.
+ let statusTag = this._lookupTag('status');
- let compressedText = '';
- this._statusCount.forEach(function(statusEntry) {
- if (statusEntry.name == status)
- statusEntry.count++;
+ // Regardless of whether we need to compress, we still insert the tagged text.
+ // It might be invisible, though.
+ // Add to the count of the latest group of status texts.
+ let statusCount = this._statusCounts[this._statusCounts.length-1];
- if (statusEntry.count) {
- if (compressedText)
- compressedText = compressedText + ', '
+ // If this is the first status message, then we need to ensureNewLine first.
+ if (statusCount.total == 0) //TODO: Make sure that we refactor "StatusCount" other places
+ this._ensureNewLine();
+
+ if (status == 'left')
+ statusCount.left++;
+ else if (status == 'joined')
+ statusCount.joined++;
+ statusCount.total++;
+
+ // We get the mark of the latest idle-status message, if it doesnt exist, we create it.
+ // we use the mark to get the iter from which we insert text.
+ // We do this after we ensure a new line for the first message
+ let markStart = buffer.get_mark('idle-status-start');
+ if (!markStart) {
+ let iter = buffer.get_iter_at_line(buffer.get_line_count()-1);
+ markStart = buffer.create_mark('idle-status-start', iter, true);
+ }
- compressedText = compressedText + statusEntry.count +
- ' users ' + statusEntry.name;
+ // not sure what this does..
+ this._state.lastNick = null;
+
+ // we get the iter of the buffer at which we need to insert the text.
+ let endIter = buffer.get_end_iter();
+
+ // Insert the text with our statusTags.
+ this._insertWithTags(endIter, statusText + '\n', [statusGroupTag, statusTag]);
+
+ markStartIter = buffer.get_iter_at_mark(markStart);
+ this._insertWithTags(markStartIter, 'ITERISHERE' , [statusTag]);
+
+ // Do we have more than 4 messages in the buffer?
+ // Then its time to compress.
+ if (statusCount.total > STATUS_NOISE_MAXIMUM) {
+
+ let statusCompressedTag = this._lookupTag('status-compressed' + statusGroupNumber);
+ if (!statusCompressedTag) {
+ statusCompressedTag = new Gtk.TextTag({ name: 'status-compressed' + statusGroupNumber });
+ buffer.tag_table.add(statusCompressedTag);
+ //log('created a statusCompressedTag:' + statusCompressedTag.name);
+ statusGroupTag.invisible = true;
}
- });
- let buffer = this._view.buffer;
- let mark = buffer.get_mark('idle-status');
- if (!mark) {
- let iter = buffer.get_end_iter();
- buffer.create_mark('idle-status', iter, true);
+ // create a compressed text message
+ let compressedText = statusCount.joined + " users joined, "
+ + statusCount.left + " users left. ";
+
+ // Insert a compressed text message before the invisible text.
+
+ let markStartIter = buffer.get_iter_at_mark(markStart);
+ let markEnd = buffer.create_mark('idle-status-end', markStartIter, true);
+ let markEndIter = buffer.get_iter_at_mark(markEnd);
+ log('text to delete: ' + buffer.get_text(markStartIter, markEndIter, true));
+ buffer.delete(markStartIter, markEndIter);
+ log('Deleted the previous message');
+
+ if (statusCount.total == 6) {
+
+ markEndIter = buffer.get_iter_at_mark(markEnd);
+ this._insertWithTags(markEndIter, 'TEST' , [statusTag, statusCompressedTag]);
+ markStartIter = buffer.get_iter_at_mark(markStart);
+ this._insertWithTags(markStartIter, 'TEST' , [statusTag, statusCompressedTag]);
+ }
+
+ log('that test code is not messing up anything');
+ markStartIter = buffer.get_iter_at_mark(markStart);
+ this._insertWithTags(markStartIter, compressedText + ' ( \u2026 ) \n' , [statusTag,
statusCompressedTag]);
+
+ //log('inserting the new message')
}
+ },
+
+
+/*
+ //buffer.delete(startIter, endIter);
+
+ // Toggle invisibility when we reach noise maximum
+ //let statusGroupTag = this._lookupTag('status-group-tag');
+ //statusGroupTag.invisible = true;
+
- if (this._statusTexts.length > STATUS_NOISE_MAXIMUM) {
- let markIter = buffer.get_iter_at_mark(mark);
- let startIter = buffer.get_iter_at_line(markIter.get_line());
- let endIter = buffer.get_end_iter();
- buffer.delete(startIter, endIter);
- let tags = [this._lookupTag('status')];
this._state.lastNick = null;
- this._ensureNewLine();
- this._insertWithTags(endIter, compressedText + ' ( ', tags);
+ // WE CANT use ensureNewLine because the "/n" wont have the invisible tag...
+ //this._ensureNewLine();
+ // lets assume this is start of all status messages.
+
+ log("Current lines of text to hide:");
+ log(buffer.get_text(startIter, endIter, false));
+
let tag = new Gtk.TextTag();
tag._statusTexts = this._statusTexts;
this._view.get_buffer().tag_table.add(tag);
- this._insertWithTags(endIter, '\u2026', tags.concat(this._lookupTag('expandable'), tag));
- this._insertWithTags(endIter, ' )', tags);
- } else {
- this._insertStatus(statusText);
+
+ } else { // If we dont have more than 4 messages in the buffer, just insert normally.
+ // What we need to do, is to ensure that the inserted statuses at this point
+ // Receives their own tag, so we can hide that specific tag.
+ // We could use a timecode or a simple count to keep track.
+ // Either option implies that we check if there was a status message previously i guess?
+ // and then make sure that we give the same tag as previously.
+ // Well, if our count is higher than 0, then we need to use the same.
+
+ let statusGroupTag = this._lookupTag('status-group-tag');
+ if (!statusGroupTag) {
+ statusGroupTag = new Gtk.TextTag({ name: 'status-group-tag'});
+ this._view.get_buffer().get_tag_table().add(statusGroupTag);
}
- },
+
+ this._ensureNewLine();
+ let iter = buffer.get_end_iter();
+ let tags = [statusGroupTag, this._lookupTag('status')];
+
+ //this._insertStatus(statusText);
+ }*/
_insertStatus: function(text) {
let time = GLib.DateTime.new_now_utc().to_unix();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]