Skip to content

Commit 9259411

Browse files
committed
Track time interval
1 parent e981a9c commit 9259411

File tree

11 files changed

+186
-75
lines changed

11 files changed

+186
-75
lines changed

src/icons/heat-map-16.png

477 Bytes
Loading

src/icons/pie-chart.png

617 Bytes
Loading

src/index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
<a id="btnByDays">By days</a>
2525
<a id="settings">Settings</a>
2626
</div>
27+
<div id="blockForChartBtn">
28+
<a class="button active chart-btn chart-btn-donut" id="donutChartBtn">Common chart</a>
29+
<a class="button chart-btn chart-btn-heatmap" id="heatMapChartBtn">Time chart</a>
30+
</div>
2731
<div id="chart"></div>
2832
<div id="timeChart"></div>
2933
<div id="resultTable" class="list-of-site"></div>

src/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
"name": "Web Activity Time Tracker",
55
"short_name": "Web Time Tracker",
6-
"version": "1.1.3",
6+
"version": "1.2.0",
77
"minimum_chrome_version": "26",
88

99
"description": "Track and limit time your activity in the browser.",

src/scripts/activity.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Activity {
1010
if (currentTab !== tab.url) {
1111
isDifferentUrl = true;
1212
}
13-
this.setCurrentActiveTab(domain);
13+
1414
if (this.isNewUrl(domain) && !this.isInBlackList(domain)) {
1515
var favicon = tab.favIconUrl;
1616
if (favicon === undefined) {
@@ -20,7 +20,8 @@ class Activity {
2020
tabs.push(newTab);
2121
}
2222

23-
if (isDifferentUrl) {
23+
if (isDifferentUrl && !this.isInBlackList(domain)) {
24+
this.setCurrentActiveTab(domain);
2425
var tabUrl = this.getTab(domain);
2526
if (tabUrl !== undefined)
2627
tabUrl.incCounter();
@@ -108,9 +109,12 @@ class Activity {
108109
currentTab = '';
109110
}
110111

111-
closeIntervalForCurrentTab(){
112-
var tabUrl = this.getTab(currentTab);
113-
if (tabUrl !== undefined)
114-
tabUrl.closeInterval();
112+
closeIntervalForCurrentTab() {
113+
if (currentTab !== '') {
114+
var tabUrl = this.getTab(currentTab);
115+
if (tabUrl !== undefined)
116+
tabUrl.closeInterval();
117+
currentTab = '';
118+
}
115119
}
116120
};

src/scripts/background.js

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,23 @@ function backgroundCheck() {
3030
activity.addTab(activeTab);
3131
}
3232

33-
if (tab !== undefined) {
34-
activity.setCurrentActiveTab(tab.url);
35-
chrome.idle.queryState(parseInt(setting_interval_inactivity), function (state) {
36-
if (state === 'active') {
37-
mainTRacker(activeUrl, tab, activeTab);
38-
}
39-
else checkDOM(state, activeUrl, tab, activeTab);
33+
if (activity.isInBlackList(activeUrl)) {
34+
chrome.browserAction.setBadgeBackgroundColor({ color: '#FF0000' })
35+
chrome.browserAction.setBadgeText({
36+
tabId: activeTab.id,
37+
text: 'n/a'
4038
});
4139
} else {
42-
if (activity.isInBlackList(activeUrl)) {
43-
chrome.browserAction.setBadgeBackgroundColor({ color: '#FF0000' })
44-
chrome.browserAction.setBadgeText({
45-
tabId: activeTab.id,
46-
text: 'n/a'
40+
if (tab !== undefined) {
41+
if (currentTab !== tab.url) {
42+
tab.incCounter();
43+
activity.setCurrentActiveTab(tab.url);
44+
}
45+
chrome.idle.queryState(parseInt(setting_interval_inactivity), function (state) {
46+
if (state === 'active') {
47+
mainTRacker(activeUrl, tab, activeTab);
48+
}
49+
else checkDOM(state, activeUrl, tab, activeTab);
4750
});
4851
}
4952
}
@@ -62,21 +65,13 @@ function mainTRacker(activeUrl, tab, activeTab) {
6265
tab.incSummaryTime();
6366
}
6467
if (setting_view_in_badge === true) {
65-
if (activity.isInBlackList(activeUrl)) {
66-
chrome.browserAction.setBadgeBackgroundColor({ color: '#FF0000' })
67-
chrome.browserAction.setBadgeText({
68-
tabId: activeTab.id,
69-
text: 'n/a'
70-
});
71-
} else {
72-
chrome.browserAction.setBadgeBackgroundColor({ color: [0, 0, 0, 0] })
73-
var today = new Date().toLocaleDateString("en-US");
74-
var summary = tab.days.find(s => s.date === today).summary;
75-
chrome.browserAction.setBadgeText({
76-
tabId: activeTab.id,
77-
text: String(convertSummaryTimeToBadgeString(summary))
78-
});
79-
}
68+
chrome.browserAction.setBadgeBackgroundColor({ color: [0, 0, 0, 0] })
69+
var today = new Date().toLocaleDateString("en-US");
70+
var summary = tab.days.find(s => s.date === today).summary;
71+
chrome.browserAction.setBadgeText({
72+
tabId: activeTab.id,
73+
text: String(convertSummaryTimeToBadgeString(summary))
74+
});
8075
} else {
8176
chrome.browserAction.setBadgeBackgroundColor({ color: [0, 0, 0, 0] })
8277
chrome.browserAction.setBadgeText({
@@ -102,9 +97,10 @@ function isVideoPlayedOnPage() {
10297
}
10398

10499
function checkDOM(state, activeUrl, tab, activeTab) {
105-
if (state === 'idle') {
100+
if (state === 'idle' && isDomainEquals(activeUrl, "youtube.com")) {
106101
checkPermissions(mainTRacker, activeUrl, tab, activeTab);
107102
}
103+
else activity.closeIntervalForCurrentTab();
108104
}
109105

110106
function checkPermissions(callback, activeUrl, tab, activeTab) {
@@ -116,6 +112,7 @@ function checkPermissions(callback, activeUrl, tab, activeTab) {
116112
chrome.tabs.executeScript({ code: "var videoElement = document.getElementsByTagName('video')[0]; (videoElement !== undefined && videoElement.currentTime > 0 && !videoElement.paused && !videoElement.ended && videoElement.readyState > 2);" }, (results) => {
117113
if (results !== undefined && results[0] !== undefined && results[0] === true)
118114
callback(activeUrl, tab, activeTab);
115+
else activity.closeIntervalForCurrentTab();
119116
});
120117
}
121118
});
@@ -161,22 +158,22 @@ function addListener() {
161158
checkSettingsImEmpty();
162159
}
163160
});
164-
chrome.storage.onChanged.addListener(function(changes, namespace) {
161+
chrome.storage.onChanged.addListener(function (changes, namespace) {
165162
for (var key in changes) {
166-
if (key === STORAGE_BLACK_LIST){
163+
if (key === STORAGE_BLACK_LIST) {
167164
loadBlackList();
168165
}
169-
if (key === STORAGE_RESTRICTION_LIST){
166+
if (key === STORAGE_RESTRICTION_LIST) {
170167
loadRestrictionList();
171168
}
172-
if (key === SETTINGS_INTERVAL_INACTIVITY){
169+
if (key === SETTINGS_INTERVAL_INACTIVITY) {
173170
storage.getSettings(SETTINGS_INTERVAL_INACTIVITY, function (item) { setting_interval_inactivity = item; });
174171
}
175-
if (key === SETTINGS_VIEW_TIME_IN_BADGE){
172+
if (key === SETTINGS_VIEW_TIME_IN_BADGE) {
176173
storage.getSettings(SETTINGS_VIEW_TIME_IN_BADGE, function (item) { setting_view_in_badge = item; });
177174
}
178175
}
179-
});
176+
});
180177

181178
chrome.runtime.setUninstallURL("https://docs.google.com/forms/d/e/1FAIpQLSdImHtvey6sg5mzsQwWfAQscgZOOV52blSf9HkywSXJhuQQHg/viewform");
182179
}
@@ -202,7 +199,7 @@ function loadRestrictionList() {
202199
})
203200
}
204201

205-
function loadSettings(){
202+
function loadSettings() {
206203
storage.getSettings(SETTINGS_INTERVAL_INACTIVITY, function (item) { setting_interval_inactivity = item; });
207204
storage.getSettings(SETTINGS_VIEW_TIME_IN_BADGE, function (item) { setting_view_in_badge = item; });
208205
}

src/scripts/chart/chart-core.js

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -285,16 +285,16 @@ function barChart(data) {
285285
}
286286

287287
function drawIntervalChart(data) {
288-
data.forEach(function (item){
288+
data.forEach(function (item) {
289289
var hFrom = getHourFrom(item.interval);
290290
var hTo = getHourTo(item.interval);
291-
if (hFrom != hTo){
291+
if (hFrom != hTo) {
292292
var sourceTimeFrom = item.interval.split('-')[0].split(':');
293293
var sourceTimeTo = item.interval.split('-')[1].split(':');
294294
var timeTo = sourceTimeFrom[0] + ":" + 59 + ":" + 59;
295295
var timeFrom = sourceTimeTo[0] + ":" + 00 + ":" + 00;
296-
data.push({"domain":item.domain, "interval":item.interval.split('-')[0] + "-" + timeTo});
297-
data.push({"domain":item.domain, "interval":timeFrom + "-" + item.interval.split('-')[1]});
296+
data.push({ "domain": item.domain, "interval": item.interval.split('-')[0] + "-" + timeTo });
297+
data.push({ "domain": item.domain, "interval": timeFrom + "-" + item.interval.split('-')[1] });
298298
}
299299
});
300300

@@ -326,6 +326,7 @@ function drawIntervalChart(data) {
326326
var tooltip = d3.select("#timeChart")
327327
.append("div")
328328
.style("opacity", 0)
329+
.style("display", "none")
329330
.style("position", "absolute")
330331
.attr("class", "tooltip")
331332
.style("background-color", "white")
@@ -338,6 +339,7 @@ function drawIntervalChart(data) {
338339
var mouseover = function (d) {
339340
tooltip
340341
.style("opacity", 1)
342+
.style("display", "block")
341343
d3.select(this)
342344
.style("stroke", "black")
343345
.style("stroke-width", "0.5px")
@@ -347,11 +349,12 @@ function drawIntervalChart(data) {
347349
tooltip
348350
.html(d.domain + "<br>" + d.interval)
349351
.style("left", (d3.mouse(this)[0]) + 10 + "px")
350-
.style("top", (d3.mouse(this)[1]) + 275 + "px")
352+
.style("top", (d3.mouse(this)[1]) + 30 + "px")
351353
}
352354
var mouseleave = function (d) {
353355
tooltip
354356
.style("opacity", 0)
357+
.style("display", "none")
355358
d3.select(this)
356359
.style("stroke", "none")
357360
.style("opacity", 0.8)
@@ -385,50 +388,74 @@ function drawIntervalChart(data) {
385388
.attr("transform", "rotate(-90)")
386389
.text("Value");
387390

391+
svg.append("g")
392+
.attr("class", "grid")
393+
.attr("transform", "translate(0," + height + ")")
394+
.call(make_x_axis()
395+
.tickSize(-height, 0, 0)
396+
)
397+
398+
svg.append("g")
399+
.attr("class", "grid")
400+
.call(make_y_axis()
401+
.tickSize(-width, 0, 0)
402+
)
403+
388404
//draw the bars, offset y and bar height based on data
389405
svg.selectAll(".bar")
390406
.data(data)
391407
.enter()
392408
.append("rect")
393-
.style("fill", "lightgreen")
409+
.style("fill", "orangered")
394410
.style("stroke", "#f1f1f1")
395411
.style("stroke-width", "1")
396412
.attr("class", "bar")
397413
.attr("x", function (d) {
398-
return x(getHourFrom(d.interval));
414+
return x(getHourFrom(d.interval)) + 2;
399415
})
400-
.attr("width", 19)
416+
.attr("width", 20)
401417
.attr("y", function (d) {
402-
return y(getMinutesTo(d.interval));
418+
return y(getMinutesTo(d.interval)) - 1;
403419
})
404420
.attr("height", function (d) {
405421
var offset = getMinutesTo(d.interval) - getMinutesFrom(d.interval);
406-
// if (offset == 0)
407-
// return 2;
408-
// else
409-
return offset * tickDistance;
422+
if (offset == 0)
423+
return 1;
424+
else return offset * tickDistance;
410425
})
411426
.on("mouseover", mouseover)
412427
.on("mousemove", mousemove)
413428
.on("mouseleave", mouseleave);
414-
}
415429

416-
function getHourFrom(interval) {
417-
var time = interval.split('-')[0];
418-
return time.split(':')[0];
419-
}
430+
function make_x_axis() {
431+
return d3.axisBottom()
432+
.scale(x)
433+
.ticks(24)
434+
}
420435

421-
function getHourTo(interval) {
422-
var time = interval.split('-')[1];
423-
return time.split(':')[0];
424-
}
436+
function make_y_axis() {
437+
return d3.axisLeft()
438+
.scale(y)
439+
.ticks(10)
440+
}
425441

426-
function getMinutesFrom(interval) {
427-
var time = interval.split('-')[0];
428-
return time.split(':')[1];
429-
}
442+
function getHourFrom(interval) {
443+
var time = interval.split('-')[0];
444+
return time.split(':')[0];
445+
}
446+
447+
function getHourTo(interval) {
448+
var time = interval.split('-')[1];
449+
return time.split(':')[0];
450+
}
451+
452+
function getMinutesFrom(interval) {
453+
var time = interval.split('-')[0];
454+
return time.split(':')[1];
455+
}
430456

431-
function getMinutesTo(interval) {
432-
var time = interval.split('-')[1];
433-
return time.split(':')[1];
457+
function getMinutesTo(interval) {
458+
var time = interval.split('-')[1];
459+
return time.split(':')[1];
460+
}
434461
}

src/scripts/ui.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ class UI {
99
document.getElementById('btnToday').classList.add('active');
1010
document.getElementById('btnAll').classList.remove('active');
1111
document.getElementById('btnByDays').classList.remove('active');
12+
document.getElementById('blockForChartBtn').classList.remove('hide');
13+
this.setUIForDonutChart();
1214

1315
this.clearUI();
1416
}
@@ -17,6 +19,7 @@ class UI {
1719
document.getElementById('btnAll').classList.add('active');
1820
document.getElementById('btnToday').classList.remove('active');
1921
document.getElementById('btnByDays').classList.remove('active');
22+
document.getElementById('blockForChartBtn').classList.add('hide');
2023

2124
this.clearUI();
2225
}
@@ -25,6 +28,7 @@ class UI {
2528
document.getElementById('btnByDays').classList.add('active');
2629
document.getElementById('btnAll').classList.remove('active');
2730
document.getElementById('btnToday').classList.remove('active');
31+
document.getElementById('blockForChartBtn').classList.add('hide');
2832

2933
this.clearUI();
3034
this.addBlockForCalendar(range);
@@ -38,6 +42,18 @@ class UI {
3842
document.getElementById('byDays').innerHTML = null;
3943
}
4044

45+
setUIForDonutChart(){
46+
document.getElementById('donutChartBtn').classList.add('active');
47+
document.getElementById('heatMapChartBtn').classList.remove('active');
48+
document.getElementById('timeChart').innerHTML = null;
49+
}
50+
51+
setUIForTimeChart(){
52+
document.getElementById('donutChartBtn').classList.remove('active');
53+
document.getElementById('heatMapChartBtn').classList.add('active');
54+
document.getElementById('chart').innerHTML = null;
55+
}
56+
4157
createTotalBlock(totalTime) {
4258
var totalElement = document.getElementById('total');
4359

@@ -94,7 +110,7 @@ class UI {
94110
}
95111

96112
drawTimeChart(tabs) {
97-
//drawIntervalChart(tabs);
113+
drawIntervalChart(tabs);
98114
}
99115

100116
drawBarChart(days) {

0 commit comments

Comments
 (0)