From 65d97e81bdcce157acbc3a0df498ba03a48b21e8 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Thu, 16 Aug 2012 17:03:48 -0400 Subject: [PATCH 1/6] added getCenter method to mainloop to retrieve most recent center/zoom --- ga_bigboard/static/ga_bigboard/bigboard_mainloop.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ga_bigboard/static/ga_bigboard/bigboard_mainloop.js b/ga_bigboard/static/ga_bigboard/bigboard_mainloop.js index 310910a..7514c3d 100644 --- a/ga_bigboard/static/ga_bigboard/bigboard_mainloop.js +++ b/ga_bigboard/static/ga_bigboard/bigboard_mainloop.js @@ -554,6 +554,10 @@ function BigBoard(args) { z:zoom }, errorHandler(noop)); } + + function getRoomCenter() { + return $.extend({},room.center,{zoom_level:room.zoom_level}); + } var once = true; function mainLoop() { @@ -622,6 +626,7 @@ function BigBoard(args) { persistAnnotation: persistAnnotation, deleteAnnotation: deleteAnnotation, setRoomCenter: setRoomCenter, + getRoomCenter: getRoomCenter, registerCallback: registerCallback }; From e49ab36b3953e105850a3a9c156f395c957da1d7 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Mon, 20 Aug 2012 14:44:54 -0400 Subject: [PATCH 2/6] Fixed issue #25 --- ga_bigboard/static/ga_bigboard/bigboard_mobile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ga_bigboard/static/ga_bigboard/bigboard_mobile.js b/ga_bigboard/static/ga_bigboard/bigboard_mobile.js index eeb0421..c0ae79e 100644 --- a/ga_bigboard/static/ga_bigboard/bigboard_mobile.js +++ b/ga_bigboard/static/ga_bigboard/bigboard_mobile.js @@ -417,7 +417,7 @@ $(document).ready(function() { }; controls.select_control.onUnselect = function(annotation) { iter(annotations, function(ann) { - ann.selected = ann.selected && ann.attributes.resource_uri !== annotations.attributes.resource_uri; + ann.selected = ann.selected && ann.attributes.resource_uri !== annotation.attributes.resource_uri; }); }; @@ -483,7 +483,7 @@ $(document).ready(function() { info_container.append('
  • '); break; default: - info_container.append('
  • ' + v + '
  • '); + info_container.append('
  • ' + v + '
  • '); break; } } From e644be77d191297b01ceca27566db24677eab3d3 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Tue, 21 Aug 2012 16:53:55 -0400 Subject: [PATCH 3/6] started working on personal views --- ga_bigboard/admin.py | 2 ++ ga_bigboard/api.py | 19 +++++++++++++++++++ ga_bigboard/models.py | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/ga_bigboard/admin.py b/ga_bigboard/admin.py index bcfea75..92832da 100644 --- a/ga_bigboard/admin.py +++ b/ga_bigboard/admin.py @@ -10,3 +10,5 @@ admin.site.register(models.SharedOverlay) admin.site.register(models.Overlay) +admin.site.register(models.PersonalView, admin_class=admin.OSMGeoAdmin) + diff --git a/ga_bigboard/api.py b/ga_bigboard/api.py index a635467..cb952f2 100644 --- a/ga_bigboard/api.py +++ b/ga_bigboard/api.py @@ -202,6 +202,24 @@ def obj_create(self, bundle, request=None, **kwargs): return super(ChatResource, self).obj_create(bundle, request, user=request.user) +class PersonalViewResource(GeoResource): + room = f.ForeignKey(to=RoomResource, attribute='room') + user = f.ForeignKey(to=UserResource, attribute='user') + + class Meta: + authentication = ApiKeyAuthentication() + authorization = Authorization() + queryset = models.PersonalView.objects.all() + resource_name = 'personal_views' + allowed_methods = ('get','post','put','delete') + filtering = { + 'room' : ALL_WITH_RELATIONS, + 'user' : ALL_WITH_RELATIONS, + 'when' : ALL, + 'id' : ALL + } + + api_v4 = Api('v4') api_v4.register(UserResource()) api_v4.register(RoleResource()) @@ -211,3 +229,4 @@ def obj_create(self, bundle, request=None, **kwargs): api_v4.register(RoomResource()) api_v4.register(ParticipantResource()) api_v4.register(ChatResource()) +api_v4.register(PersonalViewResource()) diff --git a/ga_bigboard/models.py b/ga_bigboard/models.py index efbd441..04de447 100644 --- a/ga_bigboard/models.py +++ b/ga_bigboard/models.py @@ -224,3 +224,36 @@ def __unicode__(self): class Meta: ordering = ['when'] + + +class PersonalView(m.Model): + """An entry for list of interesting views stored per user per room. + """ + room = m.ForeignKey(Room, db_index=True) + + #: the user to whom this item belongs + user = m.ForeignKey(User) + + #: name of the location + name = m.CharField(max_length=255, blank=False) + + #: optional description of the location + description = m.TextField(blank=True) + + #: center of map at the desired view + where = m.PointField(srid=4326, null=False); + + #: The zoom level of this view + zoom_level = m.IntegerField(default=5, null=False) + + #: when this view was stored + when = m.DateTimeField(auto_now_add=True, db_index=True) + + def __unicode__(self): + return self.room.name + '.' + self.user.username + ' -> ' + self.name + + objects = m.GeoManager() + + class Meta: + ordering = ['when'] + From 1dfe3bbdaf2dde17d6b74225b88498818cb49dc4 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Wed, 22 Aug 2012 15:19:12 -0400 Subject: [PATCH 4/6] got personal views working and implemented in models, api, & mainloop --- ga_bigboard/api.py | 3 + .../static/ga_bigboard/bigboard_mainloop.js | 62 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/ga_bigboard/api.py b/ga_bigboard/api.py index cb952f2..2018ff2 100644 --- a/ga_bigboard/api.py +++ b/ga_bigboard/api.py @@ -218,6 +218,9 @@ class Meta: 'when' : ALL, 'id' : ALL } + + def obj_create(self, bundle, request=None, **kwargs): + return super(PersonalViewResource, self).obj_create(bundle, request, user=request.user) api_v4 = Api('v4') diff --git a/ga_bigboard/static/ga_bigboard/bigboard_mainloop.js b/ga_bigboard/static/ga_bigboard/bigboard_mainloop.js index 7514c3d..109217f 100644 --- a/ga_bigboard/static/ga_bigboard/bigboard_mainloop.js +++ b/ga_bigboard/static/ga_bigboard/bigboard_mainloop.js @@ -6,6 +6,7 @@ function BigBoard(args) { var chats = []; var roles; var annotations; + var personal_views; var last_chat_update = 0; var started = false; // Whether this bigboard instance has been started @@ -17,6 +18,7 @@ function BigBoard(args) { var received_roles = false; var received_room = false; var received_shared_overlays = false; + var received_personal_views = false; var my_username = args.user_name; // DEPRECATED @@ -41,6 +43,7 @@ function BigBoard(args) { var bb_api_join = either(args, 'bb_api_joins', '../join/'); var bb_api_leave = either(args, 'bb_api_leave', '../leave/'); var bb_api_heartbeat = either(args, 'bb_api_heartbeat', '../heartbeat/'); + var bb_api_personalviews = either(args, 'bb_api_personalviews', '../api/v4/personal_views/'); var location = [0,0]; @@ -209,6 +212,15 @@ function BigBoard(args) { //either(args, 'receivedSharedOverlays', noop)(shared_overlays, textStatus, jqXHR); received_shared_overlays = true; } + + function receivedPersonalViews(data, textStatus, jqXHR) { + personal_views = data.objects; + if(debug) { console.log("latest version of personal views received"); } + + runCallbacks('receivedPersonalViews', personal_views, textStatus, jqXHR); + + received_personal_views = true; + } function refreshAnnotations() { received_annotations = false; @@ -310,6 +322,18 @@ function BigBoard(args) { beforeSend : function(xhr) { xhr.setRequestHeader('Authorization', hash)} }); } + + // Refreshes the personal views list + function refreshPersonalViews() { + received_personal_views = false; + $.ajax({ + url : bb_api_personalviews, + data : { room : room.id, limit : 0, format : 'json', username : user_name, api_key : api_key }, + accepts : 'application/json', + success : receivedPersonalViews, + error : errorHandler(either(args, 'refreshPersonalViewsError', noop)) + }); + } function receivedLoginCredentials(data, textStatus, jqXHR) { my_userid = data.user_id; @@ -571,6 +595,7 @@ function BigBoard(args) { refreshParticipants(); refreshSharedOverlays(); refreshChats(); + refreshPersonalViews(); once = false; } } @@ -582,6 +607,7 @@ function BigBoard(args) { if(received_roles) { refreshRoles(); } if(received_shared_overlays) { refreshSharedOverlays(); } if(received_room) { refreshRoom(); } + if(received_personal_views) { refreshPersonalViews(); } } } @@ -606,6 +632,40 @@ function BigBoard(args) { function isStarted() { return started; } + + function addPersonalView(name, description, lon, lat, zoom) { + // Add a personal view to the server + + var data = { + name: name, + description: description, + user : my_user, + room : room.resource_uri, + zoom_level: zoom, + where : { coordinates: [lon, lat], type:'Point' } + }; + + $.ajax({ + url : bb_api_personalviews + '?username=' + user_name + "&api_key=" + api_key, + type : 'POST', + data: JSON.stringify(data), + cache: false, + contentType: 'application/json', + processData: false, + error: errorHandler(noop), + success: function(data) { console.log('success'); console.log(data); } + }); + } + + function deletePersonalView(view) { + // Remove the personal view from the server + + $.ajax({ + url: view.resource_uri + "?username=" + user_name + "&api_key=" + api_key, + type: 'DELETE', + error : errorHandler(either(args, 'failedDeleteAnnotation', noop)) + }); + } return { room : room_name, @@ -627,6 +687,8 @@ function BigBoard(args) { deleteAnnotation: deleteAnnotation, setRoomCenter: setRoomCenter, getRoomCenter: getRoomCenter, + addPersonalView: addPersonalView, + deletePersonalView: deletePersonalView, registerCallback: registerCallback }; From d6b65e6ab43c50c25702d06815121c9aa453b4d9 Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Wed, 22 Aug 2012 15:43:26 -0400 Subject: [PATCH 5/6] fixed bug where personal views were being shared --- ga_bigboard/static/ga_bigboard/bigboard_mainloop.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ga_bigboard/static/ga_bigboard/bigboard_mainloop.js b/ga_bigboard/static/ga_bigboard/bigboard_mainloop.js index 109217f..8bb1fd6 100644 --- a/ga_bigboard/static/ga_bigboard/bigboard_mainloop.js +++ b/ga_bigboard/static/ga_bigboard/bigboard_mainloop.js @@ -328,7 +328,7 @@ function BigBoard(args) { received_personal_views = false; $.ajax({ url : bb_api_personalviews, - data : { room : room.id, limit : 0, format : 'json', username : user_name, api_key : api_key }, + data : { user__username: user_name, room : room.id, limit : 0, format : 'json', username : user_name, api_key : api_key }, accepts : 'application/json', success : receivedPersonalViews, error : errorHandler(either(args, 'refreshPersonalViewsError', noop)) From a64b5b283084527c20114e39c829e5a11416232b Mon Sep 17 00:00:00 2001 From: Nathan Smith Date: Thu, 23 Aug 2012 09:14:16 -0400 Subject: [PATCH 6/6] added personal views to main bb application --- .../static/ga_bigboard/bigboard_mobile.js | 96 ++++++++++++++++++- .../templates/ga_bigboard/room.template.html | 60 ++++++++++++ 2 files changed, 154 insertions(+), 2 deletions(-) diff --git a/ga_bigboard/static/ga_bigboard/bigboard_mobile.js b/ga_bigboard/static/ga_bigboard/bigboard_mobile.js index c0ae79e..5780628 100644 --- a/ga_bigboard/static/ga_bigboard/bigboard_mobile.js +++ b/ga_bigboard/static/ga_bigboard/bigboard_mobile.js @@ -32,6 +32,7 @@ $(document).ready(function() { var geojson = new OpenLayers.Format.GeoJSON(); var roles = null; var overlays = {}; + var personalViews = {}; function init() { if(!initted) { initted = true; @@ -316,7 +317,80 @@ $(document).ready(function() { map.setLayerIndex(annotationLayer, 9999); map.setLayerIndex(participantsLayer, 10000); } - ] + ], + + // adds the personal views to the list + receivedPersonalViews: [ + function(data) { + iter(data, function(obj) { + + // Check if personal view has already been added + if(!personalViews.hasOwnProperty(obj.resource_uri)) { + personalViews[obj.resource_uri] = obj; + + $('
  • ', { + id: 'views_item_'+obj.id + }).appendTo('#personal_views_list'); + $('
    ', { + id: 'views_item_top_'+obj.id, + html: "\ + \ + Go\ + x\ + \ + "+obj.name+"
    " + }).appendTo('#views_item_'+obj.id); + $('
    ', { + id: 'views_item_extra_'+obj.id, + class: 'views-item-extra' + }).appendTo('#views_item_'+obj.id); + $('', { + id: 'views_item_toggle_description_'+obj.id, + class: 'views-item-toggle-description', + html: 'Show Description' + }).appendTo('#views_item_extra_'+obj.id); + $('
    ', { + id: 'views_item_description_'+obj.id, + style: 'display: none;', + html: obj.description + }).appendTo('#views_item_extra_'+obj.id); + + // view description toggle + $('#views_item_toggle_description_'+obj.id).click(function() { + if( $('#views_item_description_'+obj.id).css('display') == 'none' ) { + $('#views_item_description_'+obj.id).show(150); + $('#views_item_toggle_description_'+obj.id).html('Hide Description'); + } else { + $('#views_item_description_'+obj.id).hide(150); + $('#views_item_toggle_description_'+obj.id).html('Show Description'); + } + }); + + // sets map center to chosen personal view + $('#views_item_go_icon_'+obj.id).click(function(e) { + var uri = $(this).data('view-index'); + var center = personalViews[uri]; + + var newCenter = new OpenLayers.LonLat(center.where.coordinates[0], center.where.coordinates[1]) + newCenter.transform(gm, sm); + map.setCenter(newCenter, center.zoom_level); + }); + + // removes the chosen personal view + $('#views_item_remove_icon_'+obj.id).click(function(e) { + // delete on server and remove from list + var uri = $(this).data('view-index'); + var view = personalViews[uri]; + + $('#views_item_'+view.id).remove(); + + bb.deletePersonalView( view ); + }); + } + }); + + } + ] // end receivedPersonalViews } }); @@ -367,9 +441,13 @@ $(document).ready(function() { }); } - + // chat log var rest_of_height = contentHeight-360; $("#chat_log").height(rest_of_height); + + // personal views + rest_of_height = contentHeight-305; + $("#personal_views_list").height(rest_of_height); // Map zoom $("#plus").click(function() { map.zoomIn(); }); @@ -431,6 +509,20 @@ $(document).ready(function() { // ); // return false; //}); + + // add teh current center/zoom to personal views + $('#bb_map_add_personal_view_form').submit(function(e) { + var name = $('#bb_map_add_personal_view_name').val(); + var description = $('#bb_map_add_personal_view_description').val();; + + var c = map.getCenter(); + c.transform(sm, gm); + bb.addPersonalView(name, description, c.lon, c.lat, map.getZoom()); + + $('#bb_map_add_personal_view_name').val(''); + $('#bb_map_add_personal_view_description').val(''); + return false; + }); $("#center_all_here").submit(function() { var c = map.getCenter(); diff --git a/ga_bigboard/templates/ga_bigboard/room.template.html b/ga_bigboard/templates/ga_bigboard/room.template.html index cd19f72..f68b544 100644 --- a/ga_bigboard/templates/ga_bigboard/room.template.html +++ b/ga_bigboard/templates/ga_bigboard/room.template.html @@ -131,6 +131,49 @@ padding-right: 0.5em; text-align: justify; } + + + #personal_views_list { + height: 80px; + overflow: auto; + margin: 0 0 0 0; + /*padding: 5px 5px 0 5px;*/ + padding: 5px 0 5px 0; + list-style: none; + } + #personal_views_list > li { + margin: 0 0 0 0; + padding: 0 0 15px 5px; + list-style: none; + border-bottom: 1px solid 505050; + } + .views-list-operations { + float: right; + color: darkblue; + } + + .views-item-go-icon { + cursor: hand; + cursor: pointer; + padding: 0 5px 0 0; + } + .views-item-remove-icon { + cursor: hand; + cursor: pointer; + padding: 0 5px 0 0; + } + .views-item-extra { + padding: 5px 0 0 0; + } + + .views-item-toggle-description { + cursor: hand; + cursor: pointer; + } + .views-item-toggle-description:hover { + color: darkblue; + } + @@ -291,6 +334,22 @@
  • + +