Merge pull request #2931 from FinnStutzenstein/Issue2669
Reorganize the current list of speakers. Fixes #2669 and find()-calls
This commit is contained in:
commit
160333beea
@ -12,6 +12,8 @@ Agenda:
|
|||||||
- Added button to remove all speakers from a list of speakers.
|
- Added button to remove all speakers from a list of speakers.
|
||||||
- Added option to create or edit agenda items as subitems of others.
|
- Added option to create or edit agenda items as subitems of others.
|
||||||
- Fixed security issue: Comments were shown for unprivileged users.
|
- Fixed security issue: Comments were shown for unprivileged users.
|
||||||
|
- Added option to choose whether to show the current list of speakers slide
|
||||||
|
as a slide or an overlay.
|
||||||
|
|
||||||
Core:
|
Core:
|
||||||
- Added support for multiple projectors.
|
- Added support for multiple projectors.
|
||||||
|
@ -73,13 +73,19 @@ class ListOfSpeakersSlide(ProjectorElement):
|
|||||||
return {'agenda_item_id': self.config_entry.get('id')}
|
return {'agenda_item_id': self.config_entry.get('id')}
|
||||||
|
|
||||||
|
|
||||||
class CurrentListOfSpeakersMetaClass(ProjectorElement):
|
class CurrentListOfSpeakersSlide(ProjectorElement):
|
||||||
"""
|
"""
|
||||||
Main class for the list of speaker slides.
|
Slide for the current list of speakers.
|
||||||
|
"""
|
||||||
|
name = 'agenda/current-list-of-speakers'
|
||||||
|
|
||||||
"""
|
|
||||||
def get_requirements(self, config_entry):
|
def get_requirements(self, config_entry):
|
||||||
items = self.get_agenda_items(config['projector_currentListOfSpeakers_reference'])
|
# The query mechanism on client needs the referenced projector.
|
||||||
|
reference_projector = Projector.objects.get(
|
||||||
|
pk=config['projector_currentListOfSpeakers_reference'])
|
||||||
|
yield reference_projector
|
||||||
|
|
||||||
|
items = self.get_agenda_items(reference_projector)
|
||||||
for item in items:
|
for item in items:
|
||||||
yield item
|
yield item
|
||||||
for speaker in item.speakers.filter(end_time=None):
|
for speaker in item.speakers.filter(end_time=None):
|
||||||
@ -90,8 +96,7 @@ class CurrentListOfSpeakersMetaClass(ProjectorElement):
|
|||||||
# Yield last speakers
|
# Yield last speakers
|
||||||
yield speaker.user
|
yield speaker.user
|
||||||
|
|
||||||
def get_agenda_items(self, projector_id):
|
def get_agenda_items(self, projector):
|
||||||
projector = Projector.objects.get(pk=projector_id)
|
|
||||||
for element in projector.elements.values():
|
for element in projector.elements.values():
|
||||||
agenda_item_id = element.get('agenda_item_id')
|
agenda_item_id = element.get('agenda_item_id')
|
||||||
if agenda_item_id is not None:
|
if agenda_item_id is not None:
|
||||||
@ -99,26 +104,23 @@ class CurrentListOfSpeakersMetaClass(ProjectorElement):
|
|||||||
|
|
||||||
def get_collection_elements_required_for_this(self, collection_element, config_entry):
|
def get_collection_elements_required_for_this(self, collection_element, config_entry):
|
||||||
output = super().get_collection_elements_required_for_this(collection_element, config_entry)
|
output = super().get_collection_elements_required_for_this(collection_element, config_entry)
|
||||||
# Full update if agenda_item changes because then we may have new
|
# Full update if agenda_item or referenced projector changes because
|
||||||
# candidates and therefor need new users.
|
# then we may have new candidates and therefor need new users.
|
||||||
items = self.get_agenda_items(config['projector_currentListOfSpeakers_reference'])
|
reference_projector = Projector.objects.get(
|
||||||
|
pk=config['projector_currentListOfSpeakers_reference'])
|
||||||
|
is_reference_projector = collection_element == CollectionElement.from_values(
|
||||||
|
reference_projector.get_collection_string(),
|
||||||
|
reference_projector.pk)
|
||||||
|
is_config = (
|
||||||
|
collection_element.collection_string == 'core/config' and
|
||||||
|
collection_element.information.get('changed_config') == 'projector_currentListOfSpeakers_reference')
|
||||||
|
|
||||||
|
if is_reference_projector or is_config:
|
||||||
|
output.extend(self.get_requirements_as_collection_elements(config_entry))
|
||||||
|
else:
|
||||||
|
items = self.get_agenda_items(reference_projector)
|
||||||
for item in items:
|
for item in items:
|
||||||
if collection_element == CollectionElement.from_values(item.get_collection_string(), item.pk):
|
if collection_element == CollectionElement.from_values(item.get_collection_string(), item.pk):
|
||||||
output.extend(self.get_requirements_as_collection_elements(config_entry))
|
output.extend(self.get_requirements_as_collection_elements(config_entry))
|
||||||
break
|
break
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
class CurrentListOfSpeakersSlide(CurrentListOfSpeakersMetaClass):
|
|
||||||
"""
|
|
||||||
Slide for the current list of speakers.
|
|
||||||
"""
|
|
||||||
name = 'agenda/current-list-of-speakers'
|
|
||||||
|
|
||||||
|
|
||||||
class CurrentListOfSpeakersOverlaySlide(CurrentListOfSpeakersMetaClass):
|
|
||||||
"""
|
|
||||||
List of speakers overlay.
|
|
||||||
Subclass of ListOfSpeakers
|
|
||||||
"""
|
|
||||||
name = 'agenda/current-list-of-speakers-overlay'
|
|
||||||
|
@ -289,101 +289,73 @@ angular.module('OpenSlidesApp.agenda', ['OpenSlidesApp.users'])
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
// TODO: Remove all find() calls from the projector logic. It is also used on the site so this has to be
|
|
||||||
// changed with the refactoring of the site autoupdate.
|
|
||||||
.factory('CurrentListOfSpeakersItem', [
|
.factory('CurrentListOfSpeakersItem', [
|
||||||
'Projector',
|
'Projector',
|
||||||
'Assignment', // TODO: Remove this after refactoring of data loading on start.
|
|
||||||
'Topic', // TODO: Remove this after refactoring of data loading on start.
|
|
||||||
'Motion', // TODO: Remove this after refactoring of data loading on start.
|
|
||||||
'MotionBlock', // TODO: Remove this after refactoring of data loading on start.
|
|
||||||
'Agenda',
|
'Agenda',
|
||||||
function (Projector, Assignment, Topic, Motion, MotionBlock, Agenda) {
|
function (Projector, Agenda) {
|
||||||
return {
|
return {
|
||||||
getItem: function (projectorId) {
|
getItem: function (projectorId) {
|
||||||
var elementPromise;
|
var projector = Projector.get(projectorId), item;
|
||||||
return Projector.find(projectorId).then(function (projector) {
|
if (projector) {
|
||||||
// scan all elements
|
|
||||||
_.forEach(projector.elements, function(element) {
|
_.forEach(projector.elements, function(element) {
|
||||||
switch(element.name) {
|
if (element.agenda_item_id) {
|
||||||
case 'motions/motion':
|
item = Agenda.get(element.agenda_item_id);
|
||||||
elementPromise = Motion.find(element.id).then(function(motion) {
|
|
||||||
return Motion.loadRelations(motion, 'agenda_item').then(function() {
|
|
||||||
return motion.agenda_item;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'motions/motion-block':
|
|
||||||
elementPromise = MotionBlock.find(element.id).then(function(motionBlock) {
|
|
||||||
return MotionBlock.loadRelations(motionBlock, 'agenda_item').then(function() {
|
|
||||||
return motionBlock.agenda_item;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'topics/topic':
|
|
||||||
elementPromise = Topic.find(element.id).then(function(topic) {
|
|
||||||
return Topic.loadRelations(topic, 'agenda_item').then(function() {
|
|
||||||
return topic.agenda_item;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'assignments/assignment':
|
|
||||||
elementPromise = Assignment.find(element.id).then(function(assignment) {
|
|
||||||
return Assignment.loadRelations(assignment, 'agenda_item').then(function() {
|
|
||||||
return assignment.agenda_item;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'agenda/list-of-speakers':
|
|
||||||
elementPromise = Agenda.find(element.id).then(function(item) {
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return elementPromise;
|
}
|
||||||
});
|
return item;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
.factory('ListOfSpeakersOverlay', [
|
.factory('CurrentListOfSpeakersSlide', [
|
||||||
'$http',
|
'$http',
|
||||||
'Projector',
|
'Projector',
|
||||||
'gettextCatalog',
|
function($http, Projector) {
|
||||||
'gettext',
|
var name = 'agenda/current-list-of-speakers';
|
||||||
function($http, Projector, gettextCatalog, gettext) {
|
|
||||||
var name = 'agenda/current-list-of-speakers-overlay';
|
|
||||||
return {
|
return {
|
||||||
name: name,
|
|
||||||
verboseName: gettext('List of speakers overlay'),
|
|
||||||
project: function (projectorId, overlay) {
|
project: function (projectorId, overlay) {
|
||||||
var isProjectedId = this.isProjected(overlay);
|
var isProjected = this.isProjectedWithOverlayStatus();
|
||||||
if (isProjectedId.length > 0) {
|
_.forEach(isProjected, function (mapping) {
|
||||||
// Deactivate
|
$http.post('/rest/core/projector/' + mapping.projectorId + '/deactivate_elements/',
|
||||||
var projector = Projector.get(isProjectedId[0]);
|
[mapping.uuid]
|
||||||
var uuid;
|
);
|
||||||
_.forEach(projector.elements, function (element) {
|
|
||||||
if (element.name == 'agenda/current-list-of-speakers-overlay') {
|
|
||||||
uuid = element.uuid;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
$http.post('/rest/core/projector/' + isProjectedId + '/deactivate_elements/',
|
|
||||||
[uuid]);
|
// The slide was projected, if the id matches. If the overlay is given, also
|
||||||
|
// the overlay is checked
|
||||||
|
var wasProjectedBefore = _.some(isProjected, function (mapping) {
|
||||||
|
var value = (mapping.projectorId === projectorId);
|
||||||
|
if (overlay !== undefined) {
|
||||||
|
value = value && (mapping.overlay === overlay);
|
||||||
}
|
}
|
||||||
// Activate, if the projector_id is a new projector.
|
return value;
|
||||||
if (isProjectedId != projectorId) {
|
});
|
||||||
|
overlay = overlay || false; // set overlay if it wasn't defined
|
||||||
|
|
||||||
|
if (!wasProjectedBefore) {
|
||||||
|
var activate = function () {
|
||||||
return $http.post(
|
return $http.post(
|
||||||
'/rest/core/projector/' + projectorId + '/activate_elements/',
|
'/rest/core/projector/' + projectorId + '/activate_elements/',
|
||||||
[{name: 'agenda/current-list-of-speakers-overlay',stable: true}]);
|
[{name: name,
|
||||||
|
stable: overlay, // if this is an overlay, it should not be
|
||||||
|
// removed by changing the main content
|
||||||
|
overlay: overlay}]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
if (!overlay) {
|
||||||
|
// clear all elements on this projector, because we are _not_ using the overlay.
|
||||||
|
$http.post('/rest/core/projector/' + projectorId + '/clear_elements/').then(activate);
|
||||||
|
} else {
|
||||||
|
activate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isProjected: function () {
|
isProjected: function () {
|
||||||
// Returns the ids of all projectors with an agenda-item element. Else return an empty list.
|
// Returns the ids of all projectors with an agenda-item element. Else return an empty list.
|
||||||
var predicate = function (element) {
|
var predicate = function (element) {
|
||||||
var value;
|
return element.name === name;
|
||||||
value = element.name == 'agenda/current-list-of-speakers-overlay';
|
|
||||||
return value;
|
|
||||||
};
|
};
|
||||||
var isProjectedIds = [];
|
var isProjectedIds = [];
|
||||||
Projector.getAll().forEach(function (projector) {
|
Projector.getAll().forEach(function (projector) {
|
||||||
@ -392,7 +364,23 @@ angular.module('OpenSlidesApp.agenda', ['OpenSlidesApp.users'])
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
return isProjectedIds;
|
return isProjectedIds;
|
||||||
|
},
|
||||||
|
// Returns a list of mappings between pojector id, overlay and uuid.
|
||||||
|
isProjectedWithOverlayStatus: function () {
|
||||||
|
var mapping = [];
|
||||||
|
_.forEach(Projector.getAll(), function (projector) {
|
||||||
|
_.forEach(projector.elements, function (element, uuid) {
|
||||||
|
if (element.name === name) {
|
||||||
|
mapping.push({
|
||||||
|
projectorId: projector.id,
|
||||||
|
uuid: uuid,
|
||||||
|
overlay: element.overlay || false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return mapping;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
@ -16,9 +16,6 @@ angular.module('OpenSlidesApp.agenda.projector', ['OpenSlidesApp.agenda'])
|
|||||||
slidesProvider.registerSlide('agenda/current-list-of-speakers', {
|
slidesProvider.registerSlide('agenda/current-list-of-speakers', {
|
||||||
template: 'static/templates/agenda/slide-current-list-of-speakers.html',
|
template: 'static/templates/agenda/slide-current-list-of-speakers.html',
|
||||||
});
|
});
|
||||||
slidesProvider.registerSlide('agenda/current-list-of-speakers-overlay', {
|
|
||||||
template: 'static/templates/agenda/slide-current-list-of-speakers-overlay.html',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
@ -27,7 +24,9 @@ angular.module('OpenSlidesApp.agenda.projector', ['OpenSlidesApp.agenda'])
|
|||||||
'Agenda',
|
'Agenda',
|
||||||
'CurrentListOfSpeakersItem',
|
'CurrentListOfSpeakersItem',
|
||||||
'Config',
|
'Config',
|
||||||
function ($scope, Agenda, CurrentListOfSpeakersItem, Config) {
|
'Projector',
|
||||||
|
function ($scope, Agenda, CurrentListOfSpeakersItem, Config, Projector) {
|
||||||
|
$scope.overlay = $scope.element.overlay;
|
||||||
// Watch for changes in the current list of speakers reference
|
// Watch for changes in the current list of speakers reference
|
||||||
$scope.$watch(function () {
|
$scope.$watch(function () {
|
||||||
return Config.lastModified('projector_currentListOfSpeakers_reference');
|
return Config.lastModified('projector_currentListOfSpeakers_reference');
|
||||||
@ -35,6 +34,12 @@ angular.module('OpenSlidesApp.agenda.projector', ['OpenSlidesApp.agenda'])
|
|||||||
$scope.currentListOfSpeakersReference = $scope.config('projector_currentListOfSpeakers_reference');
|
$scope.currentListOfSpeakersReference = $scope.config('projector_currentListOfSpeakers_reference');
|
||||||
$scope.updateCurrentListOfSpeakers();
|
$scope.updateCurrentListOfSpeakers();
|
||||||
});
|
});
|
||||||
|
// Watch for changes in the referenced projector
|
||||||
|
$scope.$watch(function () {
|
||||||
|
return Projector.lastModified($scope.currentListOfSpeakersReference);
|
||||||
|
}, function () {
|
||||||
|
$scope.updateCurrentListOfSpeakers();
|
||||||
|
});
|
||||||
// Watch for changes in the current item.
|
// Watch for changes in the current item.
|
||||||
$scope.$watch(function () {
|
$scope.$watch(function () {
|
||||||
return Agenda.lastModified();
|
return Agenda.lastModified();
|
||||||
@ -42,12 +47,7 @@ angular.module('OpenSlidesApp.agenda.projector', ['OpenSlidesApp.agenda'])
|
|||||||
$scope.updateCurrentListOfSpeakers();
|
$scope.updateCurrentListOfSpeakers();
|
||||||
});
|
});
|
||||||
$scope.updateCurrentListOfSpeakers = function () {
|
$scope.updateCurrentListOfSpeakers = function () {
|
||||||
var itemPromise = CurrentListOfSpeakersItem.getItem($scope.currentListOfSpeakersReference);
|
$scope.agendaItem = CurrentListOfSpeakersItem.getItem($scope.currentListOfSpeakersReference);
|
||||||
if (itemPromise) {
|
|
||||||
itemPromise.then(function(item) {
|
|
||||||
$scope.agendaItem = item;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
@ -55,7 +55,7 @@ angular.module('OpenSlidesApp.agenda.site', [
|
|||||||
})
|
})
|
||||||
.state('agenda.current-list-of-speakers', {
|
.state('agenda.current-list-of-speakers', {
|
||||||
url: '/speakers',
|
url: '/speakers',
|
||||||
controller: 'ListOfSpeakersViewCtrl',
|
controller: 'CurrentListOfSpeakersViewCtrl',
|
||||||
data: {
|
data: {
|
||||||
title: gettext('Current list of speakers'),
|
title: gettext('Current list of speakers'),
|
||||||
},
|
},
|
||||||
@ -588,7 +588,7 @@ angular.module('OpenSlidesApp.agenda.site', [
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
.controller('ListOfSpeakersViewCtrl', [
|
.controller('CurrentListOfSpeakersViewCtrl', [
|
||||||
'$scope',
|
'$scope',
|
||||||
'$state',
|
'$state',
|
||||||
'$http',
|
'$http',
|
||||||
@ -596,7 +596,9 @@ angular.module('OpenSlidesApp.agenda.site', [
|
|||||||
'ProjectionDefault',
|
'ProjectionDefault',
|
||||||
'Config',
|
'Config',
|
||||||
'CurrentListOfSpeakersItem',
|
'CurrentListOfSpeakersItem',
|
||||||
function($scope, $state, $http, Projector, ProjectionDefault, Config, CurrentListOfSpeakersItem) {
|
'CurrentListOfSpeakersSlide',
|
||||||
|
function($scope, $state, $http, Projector, ProjectionDefault, Config, CurrentListOfSpeakersItem,
|
||||||
|
CurrentListOfSpeakersSlide) {
|
||||||
// Watch for changes in the current list of speakers reference
|
// Watch for changes in the current list of speakers reference
|
||||||
$scope.$watch(function () {
|
$scope.$watch(function () {
|
||||||
return Config.lastModified('projector_currentListOfSpeakers_reference');
|
return Config.lastModified('projector_currentListOfSpeakers_reference');
|
||||||
@ -608,52 +610,44 @@ angular.module('OpenSlidesApp.agenda.site', [
|
|||||||
return Projector.lastModified();
|
return Projector.lastModified();
|
||||||
}, function() {
|
}, function() {
|
||||||
$scope.projectors = Projector.getAll();
|
$scope.projectors = Projector.getAll();
|
||||||
$scope.updateCurrentListOfSpeakers();
|
if ($scope.projectors.length === 1) {
|
||||||
var projectiondefault = ProjectionDefault.filter({name: 'agenda_current_list_of_speakers'})[0];
|
$scope.currentListOfSpeakersAsOverlay = true;
|
||||||
if (projectiondefault) {
|
|
||||||
$scope.defaultProjectorId = projectiondefault.projector_id;
|
|
||||||
}
|
}
|
||||||
|
$scope.updateCurrentListOfSpeakers();
|
||||||
|
$scope.listOfSpeakersDefaultProjectorId = ProjectionDefault.filter({name: 'agenda_current_list_of_speakers'})[0].projector_id;
|
||||||
});
|
});
|
||||||
$scope.updateCurrentListOfSpeakers = function () {
|
$scope.updateCurrentListOfSpeakers = function () {
|
||||||
var itemPromise = CurrentListOfSpeakersItem.getItem($scope.currentListOfSpeakersReference);
|
$scope.agendaItem = CurrentListOfSpeakersItem.getItem($scope.currentListOfSpeakersReference);
|
||||||
if (itemPromise) {
|
|
||||||
itemPromise.then(function(item) {
|
|
||||||
$scope.AgendaItem = item;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Project current list of speakers
|
|
||||||
// same logic as in core/base.js
|
|
||||||
$scope.projectCurrentLoS = function (projectorId) {
|
|
||||||
var isCurrentLoSProjectedIds = $scope.isCurrentLoSProjected($scope.mainListTree);
|
|
||||||
_.forEach(isCurrentLoSProjectedIds, function (id) {
|
|
||||||
$http.post('/rest/core/projector/' + id + '/clear_elements/');
|
|
||||||
});
|
|
||||||
if (_.indexOf(isCurrentLoSProjectedIds, projectorId) == -1) {
|
|
||||||
$http.post('/rest/core/projector/' + projectorId + '/prune_elements/',
|
|
||||||
[{name: 'agenda/current-list-of-speakers'}]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// same logic as in core/base.js
|
|
||||||
$scope.isCurrentLoSProjected = function () {
|
|
||||||
// Returns the ids of all projectors with an element with the name
|
|
||||||
// 'agenda/current-list-of-speakers'. Elsewise returns an empty list.
|
|
||||||
var projectorIds = [];
|
|
||||||
$scope.projectors.forEach(function (projector) {
|
|
||||||
var key = _.findKey(projector.elements, function (element) {
|
|
||||||
return element.name == 'agenda/current-list-of-speakers';
|
|
||||||
});
|
|
||||||
if (typeof key === 'string') {
|
|
||||||
projectorIds.push(projector.id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return projectorIds;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// go to the list of speakers (management) of the currently
|
// go to the list of speakers (management) of the currently
|
||||||
// displayed projector slide
|
// displayed projector slide
|
||||||
$scope.goToListOfSpeakers = function() {
|
$scope.goToListOfSpeakers = function() {
|
||||||
$state.go('agenda.item.detail', {id: $scope.AgendaItem.id});
|
if ($scope.agendaItem) {
|
||||||
|
$state.go('agenda.item.detail', {id: $scope.agendaItem.id});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$scope.currentListOfSpeakers = CurrentListOfSpeakersSlide;
|
||||||
|
// Set the current overlay status
|
||||||
|
if ($scope.currentListOfSpeakers.isProjected().length) {
|
||||||
|
var isProjected = $scope.currentListOfSpeakers.isProjectedWithOverlayStatus();
|
||||||
|
$scope.currentListOfSpeakersAsOverlay = isProjected[0].overlay;
|
||||||
|
} else {
|
||||||
|
$scope.currentListOfSpeakersAsOverlay = true;
|
||||||
|
}
|
||||||
|
$scope.currentListOfSpeakersItem = function () {
|
||||||
|
return CurrentListOfSpeakersItem.getItem($scope.currentListOfSpeakersReference);
|
||||||
|
};
|
||||||
|
$scope.setOverlay = function (overlay) {
|
||||||
|
$scope.currentListOfSpeakersAsOverlay = overlay;
|
||||||
|
var isProjected = $scope.currentListOfSpeakers.isProjectedWithOverlayStatus();
|
||||||
|
if (isProjected.length) {
|
||||||
|
_.forEach(isProjected, function (mapping) {
|
||||||
|
if (mapping.overlay != overlay) { // change the overlay if it is different
|
||||||
|
$scope.currentListOfSpeakers.project(mapping.projectorId, overlay);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
@ -7,41 +7,59 @@
|
|||||||
</a>
|
</a>
|
||||||
<!-- manage list of speakers -->
|
<!-- manage list of speakers -->
|
||||||
<button os-perms="agenda.can_manage"
|
<button os-perms="agenda.can_manage"
|
||||||
|
ng-disabled="!currentListOfSpeakersItem()"
|
||||||
ng-click="goToListOfSpeakers()"
|
ng-click="goToListOfSpeakers()"
|
||||||
class="btn btn-sm btn-default">
|
class="btn btn-sm btn-default">
|
||||||
<i class="fa fa-microphone"></i>
|
<i class="fa fa-microphone"></i>
|
||||||
<translate>Manage list</translate>
|
<translate>Manage list</translate>
|
||||||
</button>
|
</button>
|
||||||
<!-- project -->
|
|
||||||
<div os-perms="core.can_manage_projector" class="btn-group" uib-dropdown
|
<!-- Current list of speakers projector button -->
|
||||||
uib-tooltip="{{ 'Projector' | translate }} {{ isCurrentLoSProjected()[0] || '' }}"
|
<div class="btn-group button" uib-dropdown
|
||||||
tooltip-enable="isCurrentLoSProjected().length">
|
uib-tooltip="{{ 'Project the current list of speakers' | translate }}"
|
||||||
|
os-perms="core.can_manage_projector">
|
||||||
<button type="button" class="btn btn-default btn-sm"
|
<button type="button" class="btn btn-default btn-sm"
|
||||||
title="{{ 'Project current list of speakers' | translate }}"
|
title="{{ 'Project current list of speakers' | translate }}"
|
||||||
ng-click="projectCurrentLoS(defaultProjectorId)"
|
ng-click="currentListOfSpeakers.project(listOfSpeakersDefaultProjectorId, currentListOfSpeakersAsOverlay)"
|
||||||
ng-class="{ 'btn-primary': isCurrentLoSProjected().length && inArray(isCurrentLoSProjected(), defaultProjectorId) }">
|
ng-class="{ 'btn-primary': currentListOfSpeakers.isProjected().length && inArray(currentListOfSpeakers.isProjected(), listOfSpeakersDefaultProjectorId)}">
|
||||||
<i class="fa fa-video-camera"></i>
|
<i class="fa fa-video-camera"></i>
|
||||||
<translate>Current list of speakers</translate>
|
<translate>Current list of speakers</translate>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-default btn-sm" uib-dropdown-toggle
|
<button type="button" class="btn btn-default btn-sm"
|
||||||
ng-class="{ 'btn-primary': isCurrentLoSProjected().length && !inArray(isCurrentLoSProjected(), defaultProjectorId) }">
|
ng-if="projectors.length > 1"
|
||||||
|
uib-dropdown-toggle
|
||||||
|
ng-class="{ 'btn-primary': currentListOfSpeakers.isProjected().length && !inArray(currentListOfSpeakers.isProjected(), listOfSpeakersDefaultProjectorId)}">
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" role="menu" aria-labelledby="split-button">
|
<ul class="dropdown-menu" role="menu" aria-labelledby="split-button" ng-if="projectors.length > 1">
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="" ng-click="setOverlay(false); $event.stopPropagation();">
|
||||||
|
<i class="fa" ng-class="currentListOfSpeakersAsOverlay ? 'fa-circle-o' : 'fa-check-circle-o'"></i>
|
||||||
|
<translate>Project as slide</translate>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="" ng-click="setOverlay(true); $event.stopPropagation();">
|
||||||
|
<i class="fa" ng-class="currentListOfSpeakersAsOverlay ? 'fa-check-circle-o' : 'fa-circle-o'"></i>
|
||||||
|
<translate>Project as overlay</translate>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="divider"></li>
|
||||||
<li role="menuitem" ng-repeat="projector in projectors | orderBy:'id'">
|
<li role="menuitem" ng-repeat="projector in projectors | orderBy:'id'">
|
||||||
<a href="" ng-click="projectCurrentLoS(projector.id)"
|
<a href="" ng-click="currentListOfSpeakers.project(projector.id, currentListOfSpeakersAsOverlay)"
|
||||||
ng-class="{ 'projected': inArray(isCurrentLoSProjected(), projector.id) }">
|
ng-class="{ 'projected': inArray(currentListOfSpeakers.isProjected(), projector.id) }">
|
||||||
<i class="fa fa-video-camera" ng-show="inArray(isCurrentLoSProjected(), projector.id) "></i>
|
<i class="fa fa-video-camera" ng-show="inArray(currentListOfSpeakers.isProjected(), projector.id)"></i>
|
||||||
{{ projector.name | translate }}
|
{{ projector.name | translate }}
|
||||||
<span ng-if="projector.id == defaultProjectorId">(<translate>Default</translate>)</span>
|
<span ng-if="projector.id == listOfSpeakersDefaultProjectorId">(<translate>Default</translate>)</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 translate>Current list of speakers</h1>
|
<h1 translate>Current list of speakers</h1>
|
||||||
<h2> {{ AgendaItem.getTitle() }}
|
<h2> {{ agendaItem.getTitle() }}
|
||||||
<span class="slimlabel label label-danger ng-scope" style="" ng-if="AgendaItem.speaker_list_closed" translate>
|
<span class="slimlabel label label-danger ng-scope" style="" ng-if="agendaItem.speaker_list_closed" translate>
|
||||||
Closed
|
Closed
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
@ -50,16 +68,16 @@
|
|||||||
|
|
||||||
<div class="details">
|
<div class="details">
|
||||||
<!-- Last speakers -->
|
<!-- Last speakers -->
|
||||||
<p ng-repeat="speaker in lastSpeakers = (AgendaItem.speakers | filter: {end_time: '!!', begin_time: '!!'}) |
|
<p ng-repeat="speaker in lastSpeakers = (agendaItem.speakers | filter: {end_time: '!!', begin_time: '!!'}) |
|
||||||
limitTo: config('agenda_show_last_speakers') : (lastSpeakers.length - config('agenda_show_last_speakers'))" class="lastSpeakers">
|
limitTo: config('agenda_show_last_speakers') : (lastSpeakers.length - config('agenda_show_last_speakers'))" class="lastSpeakers">
|
||||||
{{ speaker.user.get_full_name() }}
|
{{ speaker.user.get_full_name() }}
|
||||||
<!-- Current speaker -->
|
<!-- Current speaker -->
|
||||||
<p ng-repeat="speaker in currentspeakers = (AgendaItem.speakers| filter: {end_time: null, begin_time: '!!'})"
|
<p ng-repeat="speaker in currentspeakers = (agendaItem.speakers| filter: {end_time: null, begin_time: '!!'})"
|
||||||
class="currentSpeaker">
|
class="currentSpeaker">
|
||||||
<i class="fa fa-microphone fa-lg"></i> {{ speaker.user.get_full_name() }}
|
<i class="fa fa-microphone fa-lg"></i> {{ speaker.user.get_full_name() }}
|
||||||
<!-- Next speakers -->
|
<!-- Next speakers -->
|
||||||
<ol class="nextSpeakers">
|
<ol class="nextSpeakers">
|
||||||
<li ng-repeat="speaker in AgendaItem.speakers | filter: {begin_time: null} | orderBy:'weight'">
|
<li ng-repeat="speaker in agendaItem.speakers | filter: {begin_time: null} | orderBy:'weight'">
|
||||||
{{ speaker.user.get_full_name() }}
|
{{ speaker.user.get_full_name() }}
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
<div id="speakerbox">
|
||||||
|
<h3 translate>List of speakers</h3>
|
||||||
|
|
||||||
|
<!-- Last speakers -->
|
||||||
|
<p ng-repeat="speaker in lastSpeakers = (agendaItem.speakers
|
||||||
|
| filter: {end_time: '!!', begin_time: '!!'})
|
||||||
|
| limitTo: config('agenda_show_last_speakers') : (lastSpeakers.length - config('agenda_show_last_speakers'))"
|
||||||
|
class="lastSpeakers">
|
||||||
|
{{ speaker.user.get_full_name() }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- Current speaker -->
|
||||||
|
<p ng-repeat="speaker in agendaItem.speakers | filter: {end_time: null, begin_time: '!!'} "
|
||||||
|
class="currentSpeaker">
|
||||||
|
<i class="fa fa-microphone fa-lg"></i> {{ speaker.user.get_full_name() }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- Next speakers -->
|
||||||
|
<ol class="nextSpeakers">
|
||||||
|
<li ng-repeat="speaker in nextSpeakers = (agendaItem.speakers
|
||||||
|
| filter: {begin_time: null})
|
||||||
|
| orderBy:'weight'
|
||||||
|
| limitTo: 3">
|
||||||
|
{{ speaker.user.get_full_name() }}
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<p ng-if="nextSpeakers.length > 3" class="lastSpeakers">
|
||||||
|
<i>+ {{ nextSpeakers.length - 3 }}</i>
|
||||||
|
</p>
|
||||||
|
</div>
|
@ -0,0 +1,33 @@
|
|||||||
|
<div class="content scrollcontent">
|
||||||
|
<div class="title">
|
||||||
|
<h1 translate>Current list of speakers</h1>
|
||||||
|
<h2> {{ agendaItem.getTitle() }}
|
||||||
|
<span class="slimlabel label label-danger ng-scope"
|
||||||
|
ng-if="agendaItem.speaker_list_closed" translate>Closed</span>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Last speakers -->
|
||||||
|
<p ng-repeat="speaker in lastSpeakers = (agendaItem.speakers
|
||||||
|
| filter: {end_time: '!!', begin_time: '!!'})
|
||||||
|
| limitTo: config('agenda_show_last_speakers') : (lastSpeakers.length - config('agenda_show_last_speakers'))"
|
||||||
|
class="lastSpeakers">
|
||||||
|
{{ speaker.user.get_full_name() }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- Current speaker -->
|
||||||
|
<p ng-repeat="speaker in currentspeakers = (agendaItem.speakers
|
||||||
|
| filter: {end_time: null, begin_time: '!!'})"
|
||||||
|
class="currentSpeaker">
|
||||||
|
<i class="fa fa-microphone fa-lg"></i> {{ speaker.user.get_full_name() }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- Next speakers -->
|
||||||
|
<ol class="nextSpeakers">
|
||||||
|
<li ng-repeat="speaker in agendaItem.speakers
|
||||||
|
| filter: {begin_time: null}
|
||||||
|
| orderBy:'weight'">
|
||||||
|
{{ speaker.user.get_full_name() }}
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
@ -1,19 +0,0 @@
|
|||||||
<div ng-controller="SlideCurrentListOfSpeakersCtrl">
|
|
||||||
<div ng-if="agendaItem.speakers && agendaItem.speakers.length">
|
|
||||||
<div id="speakerbox">
|
|
||||||
<h3 translate>List of speakers</h3>
|
|
||||||
<p ng-repeat="speaker in lastSpeakers = (agendaItem.speakers | filter: {end_time: '!!', begin_time: '!!'}) |
|
|
||||||
limitTo: config('agenda_show_last_speakers') : (lastSpeakers.length - config('agenda_show_last_speakers'))"
|
|
||||||
class="lastSpeakers">
|
|
||||||
{{ speaker.user.get_full_name() }}
|
|
||||||
<p ng-repeat="speaker in agendaItem.speakers | filter: {end_time: null, begin_time: '!!'} "
|
|
||||||
class="currentSpeaker">
|
|
||||||
<i class="fa fa-microphone fa-lg"></i> {{ speaker.user.get_full_name() }}
|
|
||||||
<ol class="nextSpeakers">
|
|
||||||
<li ng-repeat="speaker in nextSpeakers = (agendaItem.speakers | filter: {begin_time: null}) | orderBy:'weight' | limitTo: 3">
|
|
||||||
{{ speaker.user.get_full_name() }}
|
|
||||||
</ol>
|
|
||||||
<p ng-if="nextSpeakers.length > 3" class="lastSpeakers">
|
|
||||||
<i>+ {{ nextSpeakers.length - 3 }}</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,23 +1,8 @@
|
|||||||
<div ng-controller="SlideCurrentListOfSpeakersCtrl" class="content scrollcontent">
|
<div ng-controller="SlideCurrentListOfSpeakersCtrl">
|
||||||
<div class="title">
|
|
||||||
<h1 translate>Current list of speakers</h1>
|
<ng-include src="'static/templates/agenda/partial-slide-current-list-of-speakers.html'"
|
||||||
<h2> {{ agendaItem.getTitle() }}
|
ng-if="!overlay"></ng-include>
|
||||||
<span class="slimlabel label label-danger ng-scope" style=""
|
<ng-include src="'static/templates/agenda/partial-slide-current-list-of-speakers-overlay.html'"
|
||||||
ng-if="agendaItem.speaker_list_closed" translate>Closed</span>
|
ng-if="overlay"></ng-include>
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Last speakers -->
|
|
||||||
<p ng-repeat="speaker in lastSpeakers = (agendaItem.speakers | filter: {end_time: '!!', begin_time: '!!'}) |
|
|
||||||
limitTo: config('agenda_show_last_speakers') : (lastSpeakers.length - config('agenda_show_last_speakers'))" class="lastSpeakers">
|
|
||||||
{{ speaker.user.get_full_name() }}
|
|
||||||
<!-- Current speaker -->
|
|
||||||
<p ng-repeat="speaker in currentspeakers = (agendaItem.speakers| filter: {end_time: null, begin_time: '!!'})"
|
|
||||||
class="currentSpeaker">
|
|
||||||
<i class="fa fa-microphone fa-lg"></i> {{ speaker.user.get_full_name() }}
|
|
||||||
<!-- Next speakers -->
|
|
||||||
<ol class="nextSpeakers">
|
|
||||||
<li ng-repeat="speaker in agendaItem.speakers | filter: {begin_time: null} | orderBy:'weight'">
|
|
||||||
{{ speaker.user.get_full_name() }}
|
|
||||||
</ol>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -230,9 +230,10 @@ h3 {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
background: #d3d3d3;
|
background: #d3d3d3;
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
border: 1px solid;
|
border: 1px solid #999;
|
||||||
padding: 3px 7px 10px 19px;
|
padding: 0px 7px 10px 19px;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
|
box-shadow: 3px 3px 10px 1px rgba(0,0,0,0.5);
|
||||||
}
|
}
|
||||||
ul, ol {
|
ul, ol {
|
||||||
margin: 0 0 10px 2em;
|
margin: 0 0 10px 2em;
|
||||||
|
@ -712,7 +712,8 @@ angular.module('OpenSlidesApp.core', [
|
|||||||
value.name != 'agenda/item-list' &&
|
value.name != 'agenda/item-list' &&
|
||||||
value.name != 'core/clock' &&
|
value.name != 'core/clock' &&
|
||||||
value.name != 'core/countdown' &&
|
value.name != 'core/countdown' &&
|
||||||
value.name != 'core/message' ) {
|
value.name != 'core/message' &&
|
||||||
|
value.name != 'agenda/current-list-of-speakers' ) {
|
||||||
return_dict = {
|
return_dict = {
|
||||||
'state': value.name.replace('/', '.')+'.detail.update',
|
'state': value.name.replace('/', '.')+'.detail.update',
|
||||||
'param': {id: value.id}
|
'param': {id: value.id}
|
||||||
|
@ -1036,7 +1036,7 @@ angular.module('OpenSlidesApp.core.site', [
|
|||||||
'Config',
|
'Config',
|
||||||
'Projector',
|
'Projector',
|
||||||
'CurrentListOfSpeakersItem',
|
'CurrentListOfSpeakersItem',
|
||||||
'ListOfSpeakersOverlay',
|
'CurrentListOfSpeakersSlide',
|
||||||
'ProjectionDefault',
|
'ProjectionDefault',
|
||||||
'ProjectorMessage',
|
'ProjectorMessage',
|
||||||
'Countdown',
|
'Countdown',
|
||||||
@ -1044,7 +1044,7 @@ angular.module('OpenSlidesApp.core.site', [
|
|||||||
'ngDialog',
|
'ngDialog',
|
||||||
'ProjectorMessageForm',
|
'ProjectorMessageForm',
|
||||||
function($scope, $http, $interval, $state, $q, $filter, Config, Projector, CurrentListOfSpeakersItem,
|
function($scope, $http, $interval, $state, $q, $filter, Config, Projector, CurrentListOfSpeakersItem,
|
||||||
ListOfSpeakersOverlay, ProjectionDefault, ProjectorMessage, Countdown, gettextCatalog,
|
CurrentListOfSpeakersSlide, ProjectionDefault, ProjectorMessage, Countdown, gettextCatalog,
|
||||||
ngDialog, ProjectorMessageForm) {
|
ngDialog, ProjectorMessageForm) {
|
||||||
ProjectorMessage.bindAll({}, $scope, 'messages');
|
ProjectorMessage.bindAll({}, $scope, 'messages');
|
||||||
|
|
||||||
@ -1078,7 +1078,6 @@ angular.module('OpenSlidesApp.core.site', [
|
|||||||
cancelIntervalTimers();
|
cancelIntervalTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.listofspeakers = ListOfSpeakersOverlay;
|
|
||||||
$scope.$watch(function () {
|
$scope.$watch(function () {
|
||||||
return Projector.lastModified();
|
return Projector.lastModified();
|
||||||
}, function () {
|
}, function () {
|
||||||
@ -1086,20 +1085,14 @@ angular.module('OpenSlidesApp.core.site', [
|
|||||||
if (!$scope.active_projector) {
|
if (!$scope.active_projector) {
|
||||||
$scope.changeProjector($filter('orderBy')($scope.projectors, 'id')[0]);
|
$scope.changeProjector($filter('orderBy')($scope.projectors, 'id')[0]);
|
||||||
}
|
}
|
||||||
|
if ($scope.projectors.length === 1) {
|
||||||
|
$scope.currentListOfSpeakersAsOverlay = true;
|
||||||
|
}
|
||||||
|
|
||||||
$scope.messageDefaultProjectorId = ProjectionDefault.filter({name: 'messages'})[0].projector_id;
|
$scope.messageDefaultProjectorId = ProjectionDefault.filter({name: 'messages'})[0].projector_id;
|
||||||
$scope.countdownDefaultProjectorId = ProjectionDefault.filter({name: 'countdowns'})[0].projector_id;
|
$scope.countdownDefaultProjectorId = ProjectionDefault.filter({name: 'countdowns'})[0].projector_id;
|
||||||
$scope.getDefaultOverlayProjector();
|
$scope.listOfSpeakersDefaultProjectorId = ProjectionDefault.filter({name: 'agenda_current_list_of_speakers'})[0].projector_id;
|
||||||
});
|
});
|
||||||
// gets the default projector where the current list of speakers overlay will be displayed
|
|
||||||
$scope.getDefaultOverlayProjector = function () {
|
|
||||||
var projectiondefault = ProjectionDefault.filter({name: 'agenda_current_list_of_speakers'})[0];
|
|
||||||
if (projectiondefault) {
|
|
||||||
$scope.listofSpeakersDefaultProjectorId = projectiondefault.projector_id;
|
|
||||||
} else {
|
|
||||||
$scope.listOfSpeakersDefaultProjectorId = 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// watch for changes in projector_broadcast and currentListOfSpeakersReference
|
// watch for changes in projector_broadcast and currentListOfSpeakersReference
|
||||||
var last_broadcast;
|
var last_broadcast;
|
||||||
$scope.$watch(function () {
|
$scope.$watch(function () {
|
||||||
@ -1172,11 +1165,35 @@ angular.module('OpenSlidesApp.core.site', [
|
|||||||
ProjectorMessage.destroy(message.id);
|
ProjectorMessage.destroy(message.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Current list of speakers */
|
||||||
|
$scope.currentListOfSpeakers = CurrentListOfSpeakersSlide;
|
||||||
|
// Set the current overlay status
|
||||||
|
if ($scope.currentListOfSpeakers.isProjected().length) {
|
||||||
|
var isProjected = $scope.currentListOfSpeakers.isProjectedWithOverlayStatus();
|
||||||
|
$scope.currentListOfSpeakersAsOverlay = isProjected[0].overlay;
|
||||||
|
} else {
|
||||||
|
$scope.currentListOfSpeakersAsOverlay = true;
|
||||||
|
}
|
||||||
// go to the list of speakers(management) of the currently displayed list of speakers reference slide
|
// go to the list of speakers(management) of the currently displayed list of speakers reference slide
|
||||||
$scope.goToListOfSpeakers = function() {
|
$scope.goToListOfSpeakers = function() {
|
||||||
CurrentListOfSpeakersItem.getItem($scope.currentListOfSpeakersReference).then(function (success) {
|
var item = $scope.currentListOfSpeakersItem();
|
||||||
$state.go('agenda.item.detail', {id: success.id});
|
if (item) {
|
||||||
|
$state.go('agenda.item.detail', {id: item.id});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$scope.currentListOfSpeakersItem = function () {
|
||||||
|
return CurrentListOfSpeakersItem.getItem($scope.currentListOfSpeakersReference);
|
||||||
|
};
|
||||||
|
$scope.setOverlay = function (overlay) {
|
||||||
|
$scope.currentListOfSpeakersAsOverlay = overlay;
|
||||||
|
var isProjected = $scope.currentListOfSpeakers.isProjectedWithOverlayStatus();
|
||||||
|
if (isProjected.length) {
|
||||||
|
_.forEach(isProjected, function (mapping) {
|
||||||
|
if (mapping.overlay != overlay) { // change the overlay if it is different
|
||||||
|
$scope.currentListOfSpeakers.project(mapping.projectorId, overlay);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
@ -268,14 +268,55 @@
|
|||||||
<h4 translate>List of speakers</h4>
|
<h4 translate>List of speakers</h4>
|
||||||
</a>
|
</a>
|
||||||
<div uib-collapse="!isSpeakerList" ng-cloak>
|
<div uib-collapse="!isSpeakerList" ng-cloak>
|
||||||
<projector-button model="listofspeakers" default-projector-id="listOfSpeakersDefaultProjectorId">
|
|
||||||
</projector-button>
|
<!-- Current list of speakers projector button -->
|
||||||
<div class="btn-group" os-perms="agenda.can_manage">
|
<div class="btn-group button" uib-dropdown
|
||||||
<a ng-click="goToListOfSpeakers()" class="btn btn-default btn-sm"
|
uib-tooltip="{{ 'Project the current list of speakers' | translate }}"
|
||||||
title="{{ 'Manage current list of speakers' | translate}}">
|
os-perms="core.can_manage_projector">
|
||||||
<i class="fa fa-microphone"></i>
|
<button type="button" class="btn btn-default btn-sm"
|
||||||
|
title="{{ 'Project current list of speakers' | translate }}"
|
||||||
|
ng-click="currentListOfSpeakers.project(listOfSpeakersDefaultProjectorId, currentListOfSpeakersAsOverlay)"
|
||||||
|
ng-class="{ 'btn-primary': currentListOfSpeakers.isProjected().length && inArray(currentListOfSpeakers.isProjected(), listOfSpeakersDefaultProjectorId)}">
|
||||||
|
<i class="fa fa-video-camera"></i>
|
||||||
|
<translate>Current list of speakers</translate>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-default btn-sm slimDropDown"
|
||||||
|
ng-if="projectors.length > 1"
|
||||||
|
uib-dropdown-toggle
|
||||||
|
ng-class="{ 'btn-primary': currentListOfSpeakers.isProjected().length && !inArray(currentListOfSpeakers.isProjected(), listOfSpeakersDefaultProjectorId)}">
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" role="menu" aria-labelledby="split-button" ng-if="projectors.length > 1">
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="" ng-click="setOverlay(false); $event.stopPropagation();">
|
||||||
|
<i class="fa" ng-class="currentListOfSpeakersAsOverlay ? 'fa-circle-o' : 'fa-check-circle-o'"></i>
|
||||||
|
<translate>Project as slide</translate>
|
||||||
</a>
|
</a>
|
||||||
|
</li>
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="" ng-click="setOverlay(true); $event.stopPropagation();">
|
||||||
|
<i class="fa" ng-class="currentListOfSpeakersAsOverlay ? 'fa-check-circle-o' : 'fa-circle-o'"></i>
|
||||||
|
<translate>Project as overlay</translate>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
<li role="menuitem" ng-repeat="projector in projectors | orderBy:'id'">
|
||||||
|
<a href="" ng-click="currentListOfSpeakers.project(projector.id, currentListOfSpeakersAsOverlay)"
|
||||||
|
ng-class="{ 'projected': inArray(currentListOfSpeakers.isProjected(), projector.id) }">
|
||||||
|
<i class="fa fa-video-camera" ng-show="inArray(currentListOfSpeakers.isProjected(), projector.id)"></i>
|
||||||
|
{{ projector.name | translate }}
|
||||||
|
<span ng-if="projector.id == listOfSpeakersDefaultProjectorId">(<translate>Default</translate>)</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<button os-perms="agenda.can_manage"
|
||||||
|
ng-disabled="!currentListOfSpeakersItem()"
|
||||||
|
ng-click="goToListOfSpeakers()" class="btn btn-default btn-sm"
|
||||||
|
uib-tooltip="{{ 'Manage the current list of speakers' | translate}}">
|
||||||
|
<i class="fa fa-microphone"></i>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div><!-- end div ProjectorControlCtrl -->
|
</div><!-- end div ProjectorControlCtrl -->
|
||||||
|
Loading…
Reference in New Issue
Block a user