Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature(editor) Downloading additional metadata. #58

Merged
merged 12 commits into from
Jan 24, 2014
Merged
6 changes: 3 additions & 3 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-uglify');
//grunt.loadNpmTasks('grunt-conventional-changelog');
grunt.loadNpmTasks('grunt-conventional-changelog');
grunt.loadNpmTasks('grunt-changelog');
grunt.loadNpmTasks('grunt-bump');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-karma');
Expand Down Expand Up @@ -112,8 +112,8 @@ module.exports = function (grunt) {
*/
changelog: {
options: {
after: "2013-09-05T10:18:39.4492679+10:00",
before: "today",
//after: "2013-09-05T10:18:39.4492679+10:00",
//before: "now",
dest: 'CHANGELOG.md',
template: 'changelog.tpl'
}
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ng-boilerplate",
"version": "0.0.8",
"version": "0.0.9",
"devDependencies": {
"angular": "1.2.2",
"angular-mocks": "~1.2.0",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"author": "QUT Bioacoustics",
"name": "baw-client",
"version": "0.0.8",
"version": "0.0.9",
"description": "The AngularJS client for the QUT Bioacoustics server",
"licenses": {
"type": "Apache",
Expand Down
5 changes: 5 additions & 0 deletions src/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ var app = angular.module('baw',

// http default configuration
$httpProvider.defaults.withCredentials = true;

// the default accept type is ` "application/json, text/plain, */*" `
// for angular. This causes rails to do stupid shit for things like 403s... with old header it gives a 302
// and redirects to HTML page. WTF.
$httpProvider.defaults.headers['common']['Accept'] = 'application/json';
}])


Expand Down
29 changes: 29 additions & 0 deletions src/app/listen/_listen.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@

.noPermissions {
@extend .alert;
@extend .alert-warning;
}

.project-names>span:not(:last-child) {
word-spacing : -0.3em;

& * {
word-spacing: normal;
}
}

#chunkInfo>span:nth-child(2) {
text-align: right;

input[type="range"] {
width: 300px;


}

&>span {
Expand All @@ -11,6 +27,19 @@
}
}

.hide-thumb {

&::-ms-thumb {
opacity: 0;
}
&::-moz-range-thumb {
opacity: 0;
}
&::-webkit-slider-thumb {
opacity: 0;
}

}

.position {
& span {
Expand Down
158 changes: 129 additions & 29 deletions src/app/listen/listen.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ angular.module('bawApp.listen', ['decipher.tags', 'ui.bootstrap.typeahead'])
'$location',
'$routeParams',
'$route',
'$q',
'conf.paths',
'conf.constants',
'$url',
Expand All @@ -13,6 +14,8 @@ angular.module('bawApp.listen', ['decipher.tags', 'ui.bootstrap.typeahead'])
'AudioEvent',
'Tag',
'Taggings',
'Site',
'Project',
/**
* The listen controller.
* @param $scope
Expand All @@ -28,10 +31,14 @@ angular.module('bawApp.listen', ['decipher.tags', 'ui.bootstrap.typeahead'])
* @param $url
* @param AudioRecording
* @param Taggings
* @param $q
* @param Site
* @param Project
*/
function ListenCtrl(
$scope, $resource, $location, $routeParams, $route, paths, constants, $url,
AudioRecording, Media, AudioEvent, Tag, Taggings) {
$scope, $resource, $location, $routeParams, $route, $q, paths, constants, $url,
AudioRecording, Media, AudioEvent, Tag, Taggings, Site, Project) {

var CHUNK_DURATION_SECONDS = constants.listen.chunkDurationSeconds;

function getMediaParameters(format) {
Expand Down Expand Up @@ -72,11 +79,15 @@ angular.module('bawApp.listen', ['decipher.tags', 'ui.bootstrap.typeahead'])


// set up some dummy objects for use later
$scope.jumpToHide = true;
$scope.model = {
audioElement: {},
audioEvents: [],
media: null,
selectedAudioEvent: null
selectedAudioEvent: null,
audioRecording: null,
projects: [],
site: null
};

var formatPaths = function () {
Expand Down Expand Up @@ -144,20 +155,102 @@ angular.module('bawApp.listen', ['decipher.tags', 'ui.bootstrap.typeahead'])
console.error("retrieval of media json failed");
});

$scope.model.audioRecording = AudioRecording.get({recordingId: recordingId}, {},
function audioRecordingGetSuccess() {
// no-op
// if an audioRecording 'model' is ever created, this is where we would transform the returned data

// set up jumpto vars
var maxMinutes = Math.floor(parseFloat($scope.model.audioRecording.durationSeconds) / 60);
$scope.jumpToMax = maxMinutes;
$scope.jumpToMinute = Math.floor( parseFloat($routeParams.start) / 60);
},
function audioRecordingGetFailure() {
console.error("retrieval of audioRecording json failed");
var getAudioRecording = function getAudioRecording(recordingId) {
var deferred = $q.defer();

AudioRecording.get({recordingId: recordingId}, {},
function audioRecordingGetSuccess(value) {
// if an audioRecording 'model' is ever created, this is where we would transform the returned data
$scope.model.audioRecording = value;

var result = {audioRecording: value};

// set up jumpto vars
var maxMinutes = Math.floor(parseFloat($scope.model.audioRecording.durationSeconds) / 60);
$scope.jumpToMax = maxMinutes;
$scope.jumpToMinute = Math.floor( parseFloat($routeParams.start) / 60);
$scope.jumpToHide = false;

deferred.resolve(result);
},
function audioRecordingGetFailure() {
deferred.reject("retrieval of audioRecording json failed");
});

return deferred.promise;
};

var getSite = function getSite(result) {
var siteDeferred = $q.defer();
// get site
Site.get({siteId: result.audioRecording.siteId}, {}, function getSiteSuccess(value) {

value.link = paths.api.routes.siteAbsolute.format({"siteId": value.id});

$scope.model.site = value;
result.site = value;
siteDeferred.resolve(result);
}, function getSiteError() {
siteDeferred.reject("retrieval of site json failed");
});

return siteDeferred.promise;
};

var getProjects = function getProjects(result) {
var projectPromises = [];

$scope.model.projects = $scope.model.projects || [];
result.projects = result.projects || [];

result.site.projectIds.forEach(function (id, index) {
var projectDeferred = $q.defer();
// get project
Project.get({projectId: id}, {}, function getProjectSuccess(value) {

value.link = paths.api.routes.projectAbsolute.format({"projectId": value.id});

$scope.model.projects[index] = value;
result.projects[index] = value;
projectDeferred.resolve(result);
}, function getProjectError(error) {
if (error.status === 403) {
console.warn("The project %s does not give permissions to current user to access it's content. There are %s projects.", id, result.site.projectIds.length);
// populate field anyway, not really sure what to do here, temp value added
var denied = {
id: id,
permissions: "access denied"
};

denied.link = paths.api.routes.projectAbsolute.format({"projectId": denied.id});

$scope.model.projects[index] = denied;
result.projects[index] = denied;

// we don't mind that this "error" has occurred - there should be at least one project
// that did resolve. Resolve promise anyway
projectDeferred.resolve(result);
}
else {
projectDeferred.reject("retrieval of project json failed");
}
});

projectPromises[index] = projectDeferred.promise;
});

return $q.all(projectPromises);
};
getAudioRecording(recordingId).then(getSite).then(getProjects).then(function success(result) {
console.info("Metadata Promise chain success", result);
}, function error(err) {
console.error("An error occurred downloading metadata for this chunk:" + err, err);
}, function notify() {
// TODO: remove dodgy scope closure from promise functions, and update values here incrementally!
console.debug("All promises notify", arguments);
});


AudioEvent.query(
{
Expand Down Expand Up @@ -185,7 +278,7 @@ angular.module('bawApp.listen', ['decipher.tags', 'ui.bootstrap.typeahead'])
$scope.tags.push(baw.Tag.make(value));
});

$scope.model.audioEvents.forEach(function(value){
$scope.model.audioEvents.forEach(function (value) {
Tag.resolveAll(value.tags, $scope.tags);
});
},
Expand Down Expand Up @@ -255,11 +348,16 @@ angular.module('bawApp.listen', ['decipher.tags', 'ui.bootstrap.typeahead'])
var offset = base.add({seconds: $scope.model.media.startOffset});
return offset;
};



$scope.previousEnabled = false;
$scope.nextEnabled = false;

$scope.createNavigationHref = function (linkType, stepBy) {
// skip if resources not available
if (!$scope.model.audioRecording) {
return "#";
}

if (!angular.isNumber(stepBy)) {
stepBy = CHUNK_DURATION_SECONDS;
}
Expand All @@ -268,13 +366,13 @@ angular.module('bawApp.listen', ['decipher.tags', 'ui.bootstrap.typeahead'])

if (linkType === "previous") {
var lowerBound = ($routeParams.start - stepBy);

if ($routeParams.start > 0) {
$scope.previousEnabled = true;
} else {
$scope.previousEnabled = false;
$scope.previousEnabled = false;
}

if (lowerBound === 0) {
baseLink.end = lowerBound + stepBy;
}
Expand All @@ -292,24 +390,24 @@ angular.module('bawApp.listen', ['decipher.tags', 'ui.bootstrap.typeahead'])
return uriPrev;

}
else if (linkType === "next") {
else if (linkType === "next") {

var maxEnd = Math.floor($scope.model.audioRecording.durationSeconds);

var uriNext = $url.formatUri(
paths.site.ngRoutes.listen,
{
recordingId: recordingId,
start: ($routeParams.start + stepBy),
end: (($routeParams.end + stepBy < maxEnd) ? $routeParams.end + stepBy : maxEnd)
end: (($routeParams.end + stepBy < maxEnd) ? $routeParams.end + stepBy : maxEnd)
});

if ($routeParams.end < $scope.model.audioRecording.durationSeconds - constants.listen.minAudioDurationSeconds) {
$scope.nextEnabled = true;
} else {
$scope.nextEnabled = false;
$scope.nextEnabled = false;
}

return uriNext;
}

Expand Down Expand Up @@ -341,8 +439,11 @@ angular.module('bawApp.listen', ['decipher.tags', 'ui.bootstrap.typeahead'])
$scope.model.audioEvents.forEach(function (value, key) {
value.selected = false;
});

$scope.model.selectedAudioEvent = null;
};


$scope.singleEditDisabled = function () {
return ($scope.model.selectedAudioEvent === null || $scope.model.selectedAudioEvent.id === undefined);
};
Expand All @@ -366,7 +467,6 @@ angular.module('bawApp.listen', ['decipher.tags', 'ui.bootstrap.typeahead'])
tagTemplateUrl: "/templates/tags.html"
};


$scope.$on('decipher.tags.initialized', function (event) {
event.stopPropagation();
console.debug('decipher.tags.initialized', arguments);
Expand Down Expand Up @@ -436,7 +536,7 @@ angular.module('bawApp.listen', ['decipher.tags', 'ui.bootstrap.typeahead'])
// assumes tags array is kept in sync
//delete $scope.model.selectedAudioEvent.tags[index];

console.debug("Tag removal success", removedTag.tag.text );
console.debug("Tag removal success", removedTag.tag.text);
},
function error(response) {
console.error("Tagging creation failed", response);
Expand Down
Loading