diff --git a/res/app/components/stf/timeline/index.js b/res/app/components/stf/timeline/index.js
new file mode 100644
index 00000000..4c72af19
--- /dev/null
+++ b/res/app/components/stf/timeline/index.js
@@ -0,0 +1,4 @@
+module.exports = angular.module('stf.timeline', [
+
+])
+ .factory('TimelineService', require('./timeline-service'))
diff --git a/res/app/components/stf/timeline/timeline-service.js b/res/app/components/stf/timeline/timeline-service.js
new file mode 100644
index 00000000..b2c108dc
--- /dev/null
+++ b/res/app/components/stf/timeline/timeline-service.js
@@ -0,0 +1,41 @@
+module.exports = function TimelineServiceFactory() {
+ var TimelineService = {}
+
+ TimelineService.lines = []
+
+ function addLine(line, type) {
+ TimelineService.lines.push({
+ type: type,
+ title: line.title,
+ message: line.message,
+ serial: angular.copy(line.serial),
+ time: Date.now()
+ })
+ }
+
+ TimelineService.info = function (line) {
+ addLine(line, 'info')
+ }
+
+ TimelineService.warn = function (line) {
+ addLine(line, 'warn')
+ }
+
+ TimelineService.success = function (line) {
+ addLine(line, 'success')
+ }
+
+ TimelineService.error = function (line) {
+ addLine(line, 'error')
+ }
+
+ TimelineService.fatal = function (line) {
+ addLine(line, 'fatal')
+ }
+
+ TimelineService.clear = function () {
+ TimelineService.lines = []
+ }
+
+ return TimelineService
+}
diff --git a/res/app/components/stf/timeline/timeline-spec.js b/res/app/components/stf/timeline/timeline-spec.js
new file mode 100644
index 00000000..dc2d0fa3
--- /dev/null
+++ b/res/app/components/stf/timeline/timeline-spec.js
@@ -0,0 +1,11 @@
+describe('TimelineService', function() {
+
+ beforeEach(module('stf.timeline'));
+
+ it('should ...', inject(function(TimelineService) {
+
+ //expect(TimelineService.doSomething()).toEqual('something');
+
+ }));
+
+})
\ No newline at end of file
diff --git a/res/app/components/stf/timelines/index.js b/res/app/components/stf/timelines/index.js
new file mode 100644
index 00000000..8b9b1f5a
--- /dev/null
+++ b/res/app/components/stf/timelines/index.js
@@ -0,0 +1,6 @@
+require('./timelines.css')
+
+module.exports = angular.module('stf.timelines', [
+
+])
+ .directive('timelines', require('./timelines-directive'))
diff --git a/res/app/components/stf/timelines/timeline-message/index.js b/res/app/components/stf/timelines/timeline-message/index.js
new file mode 100644
index 00000000..185c6977
--- /dev/null
+++ b/res/app/components/stf/timelines/timeline-message/index.js
@@ -0,0 +1,4 @@
+module.exports = angular.module('stf.timeline-message', [
+
+])
+ .directive('timelineMessage', require('./timeline-message-directive'))
diff --git a/res/app/components/stf/timelines/timeline-message/timeline-message-directive.js b/res/app/components/stf/timelines/timeline-message/timeline-message-directive.js
new file mode 100644
index 00000000..b8821402
--- /dev/null
+++ b/res/app/components/stf/timelines/timeline-message/timeline-message-directive.js
@@ -0,0 +1,41 @@
+module.exports = function timelineMessageDirective(Timelines, $sce, $interpolate) {
+
+ var defaults = {
+ message: '',
+ type: 'info',
+ ttl: 5000
+ }
+
+ return {
+ restrict: 'AE',
+ replace: true,
+ template: '',
+ transclude: true,
+ link: function (scope, iElem, iAttrs, ctrls, transcludeFn) {
+
+ var options = angular.extend({}, defaults, scope.$eval(iAttrs.timelineMessage))
+
+ transcludeFn(function (elem, scope) {
+ var e,
+ html,
+ interpolateFn,
+ safeHtml;
+
+ // Create temporary wrapper element so we can grab the inner html
+ e = angular.element(document.createElement('div'))
+ e.append(elem)
+ html = e.html()
+
+ // Interpolate expressions in current scope
+ interpolateFn = $interpolate(html)
+ html = interpolateFn(scope)
+
+ // Tell Angular the HTML can be trusted so it can be used in ng-bind-html
+ safeHtml = $sce.trustAsHtml(html)
+
+ // Add notification
+ Timelines.add(safeHtml, options.type, options.ttl)
+ })
+ }
+ }
+}
diff --git a/res/app/components/stf/timelines/timeline-message/timeline-message-spec.js b/res/app/components/stf/timelines/timeline-message/timeline-message-spec.js
new file mode 100644
index 00000000..38918ab1
--- /dev/null
+++ b/res/app/components/stf/timelines/timeline-message/timeline-message-spec.js
@@ -0,0 +1,23 @@
+describe('timelineMessage', function () {
+
+ beforeEach(module('stf.timeline-message'));
+
+ var scope, compile;
+
+ beforeEach(inject(function ($rootScope, $compile) {
+ scope = $rootScope.$new();
+ compile = $compile;
+ }));
+
+ it('should ...', function () {
+
+ /*
+ To test your directive, you need to create some html that would use your directive,
+ send that through compile() then compare the results.
+
+ var element = compile('
hi
')(scope);
+ expect(element.text()).toBe('hello, world');
+ */
+
+ });
+});
\ No newline at end of file
diff --git a/res/app/components/stf/timelines/timelines-directive.js b/res/app/components/stf/timelines/timelines-directive.js
new file mode 100644
index 00000000..96cabc33
--- /dev/null
+++ b/res/app/components/stf/timelines/timelines-directive.js
@@ -0,0 +1,12 @@
+module.exports = function timelinesDirective(Timelines) {
+ return {
+ restrict: 'AE',
+ replace: false,
+ scope: {},
+ template: require('./timelines.jade'),
+ link: function (scope) {
+ scope.cssPrefix = Timelines.options.cssPrefix;
+ scope.notifications = Timelines.notifications;
+ }
+ }
+}
diff --git a/res/app/components/stf/timelines/timelines-spec.js b/res/app/components/stf/timelines/timelines-spec.js
new file mode 100644
index 00000000..01f034fb
--- /dev/null
+++ b/res/app/components/stf/timelines/timelines-spec.js
@@ -0,0 +1,23 @@
+describe('timelines', function () {
+
+ beforeEach(module('stf.timelines'));
+
+ var scope, compile;
+
+ beforeEach(inject(function ($rootScope, $compile) {
+ scope = $rootScope.$new();
+ compile = $compile;
+ }));
+
+ it('should ...', function () {
+
+ /*
+ To test your directive, you need to create some html that would use your directive,
+ send that through compile() then compare the results.
+
+ var element = compile('hi
')(scope);
+ expect(element.text()).toBe('hello, world');
+ */
+
+ });
+});
\ No newline at end of file
diff --git a/res/app/components/stf/timelines/timelines.css b/res/app/components/stf/timelines/timelines.css
new file mode 100644
index 00000000..ccbb6c51
--- /dev/null
+++ b/res/app/components/stf/timelines/timelines.css
@@ -0,0 +1,3 @@
+.stf-timelines {
+
+}
\ No newline at end of file
diff --git a/res/app/components/stf/timelines/timelines.jade b/res/app/components/stf/timelines/timelines.jade
new file mode 100644
index 00000000..ea2ce702
--- /dev/null
+++ b/res/app/components/stf/timelines/timelines.jade
@@ -0,0 +1,5 @@
+div.stf-timelines
+ ui.list-unstyled
+ li(ng-repeat='(id, notification) in notifications')
+ div(ng-class='{{cssPrefix}} {{cssPrefix}}-{{notification.type}}')
+ div(ng-bind-html='notification.message')
diff --git a/res/app/control-panes/activity/activity-controller.js b/res/app/control-panes/activity/activity-controller.js
index 0185db8e..b8e49c89 100644
--- a/res/app/control-panes/activity/activity-controller.js
+++ b/res/app/control-panes/activity/activity-controller.js
@@ -1,3 +1,39 @@
-module.exports = function ActivityCtrl($scope) {
-
+module.exports = function ActivityCtrl($scope, gettext, TimelineService) {
+ $scope.timeline = TimelineService
+
+ $scope.$watch('device.state', function (newValue, oldValue) {
+
+ if (newValue !== oldValue) {
+
+ var title = ''
+ var message = ''
+
+ if (oldValue === 'using') {
+
+ title = newValue
+ message = 'Device is now ' + newValue
+
+
+ } else {
+ title = newValue
+ message = '!Device is now ' + newValue
+ }
+
+ $scope.timeline.info({
+ title: title,
+ message: message,
+ serial: $scope.device.serial
+ })
+
+// $scope.timeline.push({
+// title: title,
+// message: message,
+// serial: angular.copy($scope.device.serial),
+// time: Date.now()
+// })
+
+ }
+
+
+ }, true)
}
diff --git a/res/app/control-panes/activity/activity.jade b/res/app/control-panes/activity/activity.jade
index ef877294..19b8007b 100644
--- a/res/app/control-panes/activity/activity.jade
+++ b/res/app/control-panes/activity/activity.jade
@@ -4,41 +4,47 @@
span(translate) Activity
.widget-content.padded
- ul.timeline.activity-list
- li.active
- .timeline-time
- strong Oct 3
- span 4:53 PM
- .timeline-icon
- .bg-primary
- i.fa.fa-exclamation-circle.fa-1x
- .timeline-content
- h2 WebSocket Disconnected
- p Socket connection was lost, try again reloading the page.
- div
- refresh-page
+ ul(ng-repeat='line in timeline.lines')
+ li
+ h3 {{line.title}}
+ p {{line.message}}
- //a(href='/')
- .status.unread
- //i.fa.fa-exclamation-triangle.fa-2x.activity-icon
- h2.activity-title WebSocket Disconnected
- span.activity-date 2014/04/30 18:33:22
-
- p.pull-left Socket connection was lost, try again reloading the page.
- .activity-buttons.pull-right
- refresh-page
- .clearfix
- //li.list-group-item
- .reviewer-info
- i.fa.fa-mobile.fa-2x.activity-icon
- h5.activity-title 'Nexus 5' Disconnected
- em.activity-date.pull-right 2014/04/30 15:33:22
- .review-text
- p.pull-left Device was disconnected because it timed out.
- .activity-buttons.pull-right
- button.btn.btn-sm.btn-primary-outline(ng-click='')
- i.fa.fa-refresh
- span(translate) Reconnect device
+ ul.timeline.activity-list
+ li.active
+ .timeline-time
+ strong Oct 3
+ span 4:53 PM
+ .timeline-icon
+ .bg-primary
+ i.fa.fa-exclamation-circle.fa-1x
+ .timeline-content
+ h2 WebSocket Disconnected
+ p Socket connection was lost, try again reloading the page.
+ div
+ refresh-page
+
+
+ //a(href='/')
+ .status.unread
+ //i.fa.fa-exclamation-triangle.fa-2x.activity-icon
+ h2.activity-title WebSocket Disconnected
+ span.activity-date 2014/04/30 18:33:22
+
+ p.pull-left Socket connection was lost, try again reloading the page.
+ .activity-buttons.pull-right
+ refresh-page
+ .clearfix
+ //li.list-group-item
+ .reviewer-info
+ i.fa.fa-mobile.fa-2x.activity-icon
+ h5.activity-title 'Nexus 5' Disconnected
+ em.activity-date.pull-right 2014/04/30 15:33:22
+ .review-text
+ p.pull-left Device was disconnected because it timed out.
+ .activity-buttons.pull-right
+ button.btn.btn-sm.btn-primary-outline(ng-click='')
+ i.fa.fa-refresh
+ span(translate) Reconnect device
diff --git a/res/app/control-panes/activity/index.js b/res/app/control-panes/activity/index.js
index be1cea09..f980bac5 100644
--- a/res/app/control-panes/activity/index.js
+++ b/res/app/control-panes/activity/index.js
@@ -1,7 +1,8 @@
require('./activity.css')
module.exports = angular.module('stf.activity', [
- require('stf/common-ui').name
+ require('stf/common-ui').name,
+ require('stf/timeline').name
])
.run(["$templateCache", function ($templateCache) {
$templateCache.put('control-panes/activity/activity.jade',