Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 151 additions & 2 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,29 @@ module.exports = function (grunt) {
' */\n'
},

/**
* The directories to delete when `grunt clean` is executed.
*/
clean: [
'<%= dist_dir %>'
],

/* Copy all example into dist/examples */
copy: {
examples: {
src: 'examples/*',
dest: 'dist/'
},
nav: {
src: 'navbar.html',
dest: 'dist/'
},
example: {
src: 'examples.html',
dest: 'dist/'
}
},

concat: {
compile_js: {
options: {
Expand All @@ -39,6 +62,34 @@ module.exports = function (grunt) {
'app/**/*.js'
],
dest: '<%= dist_dir %>/<%= pkg.name %>.js'
},
compile_all_js: {
src: [
'<%= dist_dir %>/<%= pkg.name %>.min.js',
'bower_components/momentjs/min/moment-with-locales.min.js',
'bower_components/humanize-duration/humanize-duration.js'
],
dest: '<%= dist_dir %>/assets/js/<%= pkg.name %>-all.min.js'
},
compile_bower_js: {
src: [
'bower_components/angular/angular.min.js',
'bower_components/jquery/jquery.min.js',
'bower_components/bootstrap/docs/assets/js/bootstrap.min.js',
'docs/docs.js',
'docs/prettify.js',
'docs/application.js'
],
dest: '<%= dist_dir %>/assets/js/<%= pkg.name %>-bower.js'
},
compile_bower_css: {
src: [
'bower_components/bootstrap/docs/assets/css/bootstrap.css',
'bower_components/bootstrap/docs/assets/css/bootstrap-responsive.css',
'docs/css/docs.css',
'docs/css/prettify.css'
],
dest: '<%= dist_dir %>/assets/css/<%= pkg.name %>-bower.css'
}
},

Expand Down Expand Up @@ -70,6 +121,59 @@ module.exports = function (grunt) {
}
},

/**
* The `index` task compiles the `index.html` file as a Grunt template. CSS
* and JS files co-exist here but they get split apart later.
*/
index: {
/**
* During development, we don't want to have wait for compilation,
* concatenation, minification, etc. So to avoid these steps, we simply
* add all script files directly to the `<head>` of `index.html`. The
* `src` property contains the list of included files.
*/
build: {
dir: '',
src: [
'bower_components/angular/angular.min.js',
'app/**/*.js',
'bower_components/momentjs/min/moment-with-locales.min.js',
'bower_components/humanize-duration/humanize-duration.js',
'docs/docs.js',
'bower_components/jquery/jquery.min.js',
'bower_components/bootstrap/docs/assets/js/bootstrap.min.js',
'docs/prettify.js',
'docs/application.js',
'bower_components/bootstrap/docs/assets/css/bootstrap.css',
'bower_components/bootstrap/docs/assets/css/bootstrap-responsive.css',
'docs/css/docs.css',
'docs/css/prettify.css'
]
},

/**
* When it is time to have a completely compiled application, we can
* alter the above to include only a single JavaScript and a single CSS
* file. Now we're back!
*/
compile: {
dir: '<%= dist_dir %>/',
src: [
'<%= dist_dir %>/assets/js/<%= pkg.name %>-bower.js',
'<%= dist_dir %>/assets/js/<%= pkg.name %>-all.min.js',
'<%= dist_dir %>/assets/css/<%= pkg.name %>-bower.css'
]
}
},

'gh-pages': {
options: {
base: 'dist',
message: 'Update gh-pages'
},
src: ['**']
},

connect: {
server: {
options: {
Expand All @@ -83,7 +187,7 @@ module.exports = function (grunt) {
testserver: {
options: {
port: 3030,
base: '.'
base: 'dist'
}
}
},
Expand Down Expand Up @@ -119,7 +223,52 @@ module.exports = function (grunt) {
grunt.registerTask('tests', [ 'connect:testserver', 'build', 'karma:unit', 'karma:e2e']);

grunt.registerTask('build', [
'jshint', 'concat', 'uglify'
'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'
]);

/**
* A utility function to get all app JavaScript sources.
*/
function filterForJS ( files ) {
return files.filter( function ( file ) {
return file.match( /\.js$/ );
});
}

/**
* A utility function to get all app CSS sources.
*/
function filterForCSS ( files ) {
return files.filter( function ( file ) {
return file.match( /\.css$/ );
});
}

/**
* The index.html template includes the stylesheet and javascript sources
* based on dynamic names calculated in this Gruntfile. This task assembles
* the list into variables for the template to use and then runs the
* compilation.
*/
grunt.registerMultiTask( 'index', 'Process index.html template', function () {
var dirRE = new RegExp( '^('+grunt.config('build_dir')+'|'+grunt.config('dist_dir')+')\/', 'g' );
var jsFiles = filterForJS( this.filesSrc ).map( function ( file ) {
return file.replace( dirRE, '' );
});
var cssFiles = filterForCSS( this.filesSrc ).map( function ( file ) {
return file.replace( dirRE, '' );
});

grunt.file.copy('index.tpl.html', this.data.dir + 'index.html', {
process: function ( contents, path ) {
return grunt.template.process( contents, {
data: {
scripts: jsFiles,
styles: cssFiles,
version: grunt.config( 'pkg.version' )
}
});
}
});
});
};
19 changes: 17 additions & 2 deletions app/js/_timer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var timerModule = angular.module('timer', [])
language: '@?',
maxTimeUnit: '='
},
controller: ['$scope', '$element', '$attrs', '$timeout', 'I18nService', '$interpolate', function ($scope, $element, $attrs, $timeout, I18nService, $interpolate) {
controller: ['$scope', '$element', '$attrs', '$timeout', 'I18nService', '$interpolate', 'progressBarService', function ($scope, $element, $attrs, $timeout, I18nService, $interpolate, progressBarService) {

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

//progress bar
$scope.displayProgressBar = 0;
$scope.displayProgressActive = 'active'; //Bootstrap active effect for progress bar

if ($element.html().trim().length === 0) {
$element.append($compile('<span>' + $interpolate.startSymbol() + 'millis' + $interpolate.endSymbol() + '</span>')($scope));
} else {
Expand Down Expand Up @@ -252,16 +256,18 @@ var timerModule = angular.module('timer', [])
calculateTimeUnits();

var tick = function tick() {

var typeTimer = null; // countdown or endTimeAttr
$scope.millis = moment().diff($scope.startTime);
var adjustment = $scope.millis % 1000;

if ($scope.endTimeAttr) {
typeTimer = $scope.endTimeAttr;
$scope.millis = moment($scope.endTime).diff(moment());
adjustment = $scope.interval - $scope.millis % 1000;
}

if ($scope.countdownattr) {
typeTimer = $scope.countdownattr;
$scope.millis = $scope.countdown * 1000;
}

Expand Down Expand Up @@ -293,6 +299,15 @@ var timerModule = angular.module('timer', [])
$scope.$eval($scope.finishCallback);
}
}

if(typeTimer !== null){
//calculate progress bar
$scope.progressBar = progressBarService.calculateProgressBar($scope.startTime, $scope.millis, $scope.endTime, $scope.countdownattr);

if($scope.progressBar === 100){
$scope.displayProgressActive = ''; //No more Bootstrap active effect
}
}
};

if ($scope.autoStart === undefined || $scope.autoStart === true) {
Expand Down
46 changes: 46 additions & 0 deletions app/js/progressBarService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
var app = angular.module('timer');

app.factory('progressBarService', function() {

var ProgressBarService = function() {};

/**
* calculate the remaining time in a progress bar in percentage
* @param {momentjs} startValue in seconds
* @param {integer} currentCountdown, where are we in the countdown
* @param {integer} remainingTime, remaining milliseconds
* @param {integer} endTime, end time, can be undefined
* @param {integer} coutdown, original coutdown value, can be undefined
*
* joke : https://www.youtube.com/watch?v=gENVB6tjq_M
* @return {float} 0 --> 100
*/
ProgressBarService.prototype.calculateProgressBar = function calculateProgressBar(startValue, remainingTime, endTimeAttr, coutdown) {
var displayProgressBar = 0,
endTimeValue,
initialCountdown;

remainingTime = remainingTime / 1000; //seconds


if(endTimeAttr !== null){
endTimeValue = moment(endTimeAttr);
initialCountdown = endTimeValue.diff(startValue, 'seconds');
displayProgressBar = remainingTime * 100 / initialCountdown;
}
else {
displayProgressBar = remainingTime * 100 / coutdown;
}

displayProgressBar = 100 - displayProgressBar; //To have 0 to 100 and not 100 to 0
displayProgressBar = Math.round(displayProgressBar * 10) / 10; //learn more why : http://stackoverflow.com/questions/588004/is-floating-point-math-broken

if(displayProgressBar > 100){ //security
displayProgressBar = 100;
}

return displayProgressBar;
};

return new ProgressBarService();
});
Loading