Skip to content

Commit 0e8626c

Browse files
committed
Merge pull request siddii#171 from polomarcus/progressBar
Feature Progress bar
2 parents e4bbbec + ec7f0ee commit 0e8626c

30 files changed

+11960
-545
lines changed

Gruntfile.js

Lines changed: 151 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,29 @@ module.exports = function (grunt) {
3030
' */\n'
3131
},
3232

33+
/**
34+
* The directories to delete when `grunt clean` is executed.
35+
*/
36+
clean: [
37+
'<%= dist_dir %>'
38+
],
39+
40+
/* Copy all example into dist/examples */
41+
copy: {
42+
examples: {
43+
src: 'examples/*',
44+
dest: 'dist/'
45+
},
46+
nav: {
47+
src: 'navbar.html',
48+
dest: 'dist/'
49+
},
50+
example: {
51+
src: 'examples.html',
52+
dest: 'dist/'
53+
}
54+
},
55+
3356
concat: {
3457
compile_js: {
3558
options: {
@@ -39,6 +62,34 @@ module.exports = function (grunt) {
3962
'app/**/*.js'
4063
],
4164
dest: '<%= dist_dir %>/<%= pkg.name %>.js'
65+
},
66+
compile_all_js: {
67+
src: [
68+
'<%= dist_dir %>/<%= pkg.name %>.min.js',
69+
'bower_components/momentjs/min/moment-with-locales.min.js',
70+
'bower_components/humanize-duration/humanize-duration.js'
71+
],
72+
dest: '<%= dist_dir %>/assets/js/<%= pkg.name %>-all.min.js'
73+
},
74+
compile_bower_js: {
75+
src: [
76+
'bower_components/angular/angular.min.js',
77+
'bower_components/jquery/jquery.min.js',
78+
'bower_components/bootstrap/docs/assets/js/bootstrap.min.js',
79+
'docs/docs.js',
80+
'docs/prettify.js',
81+
'docs/application.js'
82+
],
83+
dest: '<%= dist_dir %>/assets/js/<%= pkg.name %>-bower.js'
84+
},
85+
compile_bower_css: {
86+
src: [
87+
'bower_components/bootstrap/docs/assets/css/bootstrap.css',
88+
'bower_components/bootstrap/docs/assets/css/bootstrap-responsive.css',
89+
'docs/css/docs.css',
90+
'docs/css/prettify.css'
91+
],
92+
dest: '<%= dist_dir %>/assets/css/<%= pkg.name %>-bower.css'
4293
}
4394
},
4495

@@ -70,6 +121,59 @@ module.exports = function (grunt) {
70121
}
71122
},
72123

124+
/**
125+
* The `index` task compiles the `index.html` file as a Grunt template. CSS
126+
* and JS files co-exist here but they get split apart later.
127+
*/
128+
index: {
129+
/**
130+
* During development, we don't want to have wait for compilation,
131+
* concatenation, minification, etc. So to avoid these steps, we simply
132+
* add all script files directly to the `<head>` of `index.html`. The
133+
* `src` property contains the list of included files.
134+
*/
135+
build: {
136+
dir: '',
137+
src: [
138+
'bower_components/angular/angular.min.js',
139+
'app/**/*.js',
140+
'bower_components/momentjs/min/moment-with-locales.min.js',
141+
'bower_components/humanize-duration/humanize-duration.js',
142+
'docs/docs.js',
143+
'bower_components/jquery/jquery.min.js',
144+
'bower_components/bootstrap/docs/assets/js/bootstrap.min.js',
145+
'docs/prettify.js',
146+
'docs/application.js',
147+
'bower_components/bootstrap/docs/assets/css/bootstrap.css',
148+
'bower_components/bootstrap/docs/assets/css/bootstrap-responsive.css',
149+
'docs/css/docs.css',
150+
'docs/css/prettify.css'
151+
]
152+
},
153+
154+
/**
155+
* When it is time to have a completely compiled application, we can
156+
* alter the above to include only a single JavaScript and a single CSS
157+
* file. Now we're back!
158+
*/
159+
compile: {
160+
dir: '<%= dist_dir %>/',
161+
src: [
162+
'<%= dist_dir %>/assets/js/<%= pkg.name %>-bower.js',
163+
'<%= dist_dir %>/assets/js/<%= pkg.name %>-all.min.js',
164+
'<%= dist_dir %>/assets/css/<%= pkg.name %>-bower.css'
165+
]
166+
}
167+
},
168+
169+
'gh-pages': {
170+
options: {
171+
base: 'dist',
172+
message: 'Update gh-pages'
173+
},
174+
src: ['**']
175+
},
176+
73177
connect: {
74178
server: {
75179
options: {
@@ -83,7 +187,7 @@ module.exports = function (grunt) {
83187
testserver: {
84188
options: {
85189
port: 3030,
86-
base: '.'
190+
base: 'dist'
87191
}
88192
}
89193
},
@@ -119,7 +223,52 @@ module.exports = function (grunt) {
119223
grunt.registerTask('tests', [ 'connect:testserver', 'build', 'karma:unit', 'karma:e2e']);
120224

121225
grunt.registerTask('build', [
122-
'jshint', 'concat', 'uglify'
226+
'clean', 'jshint', 'concat:compile_js', 'uglify', 'concat:compile_all_js', 'concat:compile_bower_js', 'concat:compile_bower_css','copy:examples','copy:nav','copy:example', 'index:compile', 'index:build'
123227
]);
124228

229+
/**
230+
* A utility function to get all app JavaScript sources.
231+
*/
232+
function filterForJS ( files ) {
233+
return files.filter( function ( file ) {
234+
return file.match( /\.js$/ );
235+
});
236+
}
237+
238+
/**
239+
* A utility function to get all app CSS sources.
240+
*/
241+
function filterForCSS ( files ) {
242+
return files.filter( function ( file ) {
243+
return file.match( /\.css$/ );
244+
});
245+
}
246+
247+
/**
248+
* The index.html template includes the stylesheet and javascript sources
249+
* based on dynamic names calculated in this Gruntfile. This task assembles
250+
* the list into variables for the template to use and then runs the
251+
* compilation.
252+
*/
253+
grunt.registerMultiTask( 'index', 'Process index.html template', function () {
254+
var dirRE = new RegExp( '^('+grunt.config('build_dir')+'|'+grunt.config('dist_dir')+')\/', 'g' );
255+
var jsFiles = filterForJS( this.filesSrc ).map( function ( file ) {
256+
return file.replace( dirRE, '' );
257+
});
258+
var cssFiles = filterForCSS( this.filesSrc ).map( function ( file ) {
259+
return file.replace( dirRE, '' );
260+
});
261+
262+
grunt.file.copy('index.tpl.html', this.data.dir + 'index.html', {
263+
process: function ( contents, path ) {
264+
return grunt.template.process( contents, {
265+
data: {
266+
scripts: jsFiles,
267+
styles: cssFiles,
268+
version: grunt.config( 'pkg.version' )
269+
}
270+
});
271+
}
272+
});
273+
});
125274
};

app/js/_timer.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ var timerModule = angular.module('timer', [])
1313
language: '@?',
1414
maxTimeUnit: '='
1515
},
16-
controller: ['$scope', '$element', '$attrs', '$timeout', 'I18nService', '$interpolate', function ($scope, $element, $attrs, $timeout, I18nService, $interpolate) {
16+
controller: ['$scope', '$element', '$attrs', '$timeout', 'I18nService', '$interpolate', 'progressBarService', function ($scope, $element, $attrs, $timeout, I18nService, $interpolate, progressBarService) {
1717

1818
// Checking for trim function since IE8 doesn't have it
1919
// If not a function, create tirm with RegEx to mimic native trim
@@ -40,6 +40,10 @@ var timerModule = angular.module('timer', [])
4040
var i18nService = new I18nService();
4141
i18nService.init($scope.language);
4242

43+
//progress bar
44+
$scope.displayProgressBar = 0;
45+
$scope.displayProgressActive = 'active'; //Bootstrap active effect for progress bar
46+
4347
if ($element.html().trim().length === 0) {
4448
$element.append($compile('<span>' + $interpolate.startSymbol() + 'millis' + $interpolate.endSymbol() + '</span>')($scope));
4549
} else {
@@ -252,16 +256,18 @@ var timerModule = angular.module('timer', [])
252256
calculateTimeUnits();
253257

254258
var tick = function tick() {
255-
259+
var typeTimer = null; // countdown or endTimeAttr
256260
$scope.millis = moment().diff($scope.startTime);
257261
var adjustment = $scope.millis % 1000;
258262

259263
if ($scope.endTimeAttr) {
264+
typeTimer = $scope.endTimeAttr;
260265
$scope.millis = moment($scope.endTime).diff(moment());
261266
adjustment = $scope.interval - $scope.millis % 1000;
262267
}
263268

264269
if ($scope.countdownattr) {
270+
typeTimer = $scope.countdownattr;
265271
$scope.millis = $scope.countdown * 1000;
266272
}
267273

@@ -293,6 +299,15 @@ var timerModule = angular.module('timer', [])
293299
$scope.$eval($scope.finishCallback);
294300
}
295301
}
302+
303+
if(typeTimer !== null){
304+
//calculate progress bar
305+
$scope.progressBar = progressBarService.calculateProgressBar($scope.startTime, $scope.millis, $scope.endTime, $scope.countdownattr);
306+
307+
if($scope.progressBar === 100){
308+
$scope.displayProgressActive = ''; //No more Bootstrap active effect
309+
}
310+
}
296311
};
297312

298313
if ($scope.autoStart === undefined || $scope.autoStart === true) {

app/js/progressBarService.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
var app = angular.module('timer');
2+
3+
app.factory('progressBarService', function() {
4+
5+
var ProgressBarService = function() {};
6+
7+
/**
8+
* calculate the remaining time in a progress bar in percentage
9+
* @param {momentjs} startValue in seconds
10+
* @param {integer} currentCountdown, where are we in the countdown
11+
* @param {integer} remainingTime, remaining milliseconds
12+
* @param {integer} endTime, end time, can be undefined
13+
* @param {integer} coutdown, original coutdown value, can be undefined
14+
*
15+
* joke : https://www.youtube.com/watch?v=gENVB6tjq_M
16+
* @return {float} 0 --> 100
17+
*/
18+
ProgressBarService.prototype.calculateProgressBar = function calculateProgressBar(startValue, remainingTime, endTimeAttr, coutdown) {
19+
var displayProgressBar = 0,
20+
endTimeValue,
21+
initialCountdown;
22+
23+
remainingTime = remainingTime / 1000; //seconds
24+
25+
26+
if(endTimeAttr !== null){
27+
endTimeValue = moment(endTimeAttr);
28+
initialCountdown = endTimeValue.diff(startValue, 'seconds');
29+
displayProgressBar = remainingTime * 100 / initialCountdown;
30+
}
31+
else {
32+
displayProgressBar = remainingTime * 100 / coutdown;
33+
}
34+
35+
displayProgressBar = 100 - displayProgressBar; //To have 0 to 100 and not 100 to 0
36+
displayProgressBar = Math.round(displayProgressBar * 10) / 10; //learn more why : http://stackoverflow.com/questions/588004/is-floating-point-math-broken
37+
38+
if(displayProgressBar > 100){ //security
39+
displayProgressBar = 100;
40+
}
41+
42+
return displayProgressBar;
43+
};
44+
45+
return new ProgressBarService();
46+
});

0 commit comments

Comments
 (0)