Commit d6760a53cfe5cc47528ad7421b3397e01cd0daab

Integrate the PlayAreaView component
  
7272 background: #fff;
7373 height: 60px;
7474 margin-left: -15px;
75 display: none;
7576}
7677.ocd-item .text{
7778 margin-top: 3px;
  
3535 var where = options.where,
3636 who = options.who || null;
3737 url = swtr.swtstoreURL() + swtr.endpoints.get + '?where=' +
38 encodeURIComponent(where) + '&access_token=' + swtr.access_token;
38 encodeURIComponent(where);// '&access_token=' + swtr.access_token;
3939 if(who) {
4040 url += '&who=' + who;
4141 }
100100 update: function() {
101101 }
102102 });
103
103104 swtr.ImgAnnoView = Backbone.View.extend({
104 el: $("#img-annotation-wrapper"),
105 el: $('#img-annotation-wrapper'),
105106 events: {
106 'change #custom-dropdown ': 'getFormValue',
107 'click #setbox': 'showHide'
107 'change #custom-dropdown': 'getFormValue',
108 'click #toggle-anno-areas': 'toggleAnnoAreas'
108109 },
109110 initialize: function(options) {
111 this.$el = $('#img-annotation-wrapper');
110112 this.listenTo(this.collection, 'add', this.render);
111113 // attach event handlers to the anno object
112114 anno.addHandler('onAnnotationCreated', this.showSwtHelp);
127127 this.$img = options.$img;
128128 options.$img.on('load', this, this.imageLoaded);
129129 options.$img.on('error', this, this.onImageLoadError);
130 this.setImage(options.url);
131130 }
131 if(!options.helpview) {
132 //TODO: figure out a better way so that everyone can communicate with
133 //helpview independently
134 throw new Error('Image annotation view must be passed a reference to the helpview');
135 }
136 this.helpview = options.helpview;
137 //console.log('initing img annoview; helpview in opts', options.helpview);
138 this.setImage(options.url);
132139 },
133140 render: function(model) {
134141 var swt = model.toJSON();
149149 },
150150 showSwtHelp: function(annotation) {
151151 var self = swtr.imgAnnoView;//TODO: figure out how we can bind the scope when this func is called as a callback
152 swtr.appView.helpview.step(3);
152 self.helpview.step(3);
153153 $('#sweet').show();
154154 },
155155 updateNewAnno: function(annotation) {
269269 },
270270 setImage: function(url) {
271271 this.imgURL = url;
272 console.log(url);
272 //console.log(url);
273273 if(this.$img.attr('src') === this.imgURL) {
274274 return;
275275 }
276276 anno.reset();
277 var self = this;
278277 swtr.appView.$overlay.show();
279 swtr.appView.helpview.step(7);
278 this.helpview.step(7);
280279 this.$img.attr('src', this.imgURL);
281280 },
282281 imageLoaded: function(event) {
285285 // reset the collection
286286 swtr.sweets.reset();
287287 anno.makeAnnotatable(swtr.imgAnnoView.img);
288 swtr.imgAnnoView.getExistingAnnotations();
288 self.getExistingAnnotations();
289289 },
290290 // when image fails to load - could be because of broken URL or network
291291 // issues
293293 var self = event.data;
294294 console.log('error while loading image');
295295 swtr.appView.$overlay.hide();
296 swtr.appView.helpview.step(8);
296 self.helpview.step(8);
297297 },
298298 initImageAnno: function() {
299299 // img is a jquery object which annotorious doesn't accept; instead it
305305 },
306306 getExistingAnnotations: function() {
307307 var self = this;
308 swtr.appView.helpview.step(0);
308 this.helpview.step(0);
309309 swtr.appView.$overlay.show();
310310 swtr.sweets.getAll({
311311 where: this.imgURL,
313313 if(_.isArray(data)) {
314314 swtr.sweets.add(data);
315315 swtr.appView.$overlay.hide();
316 swtr.appView.helpview.step(2);
316 self.helpview.step(2);
317317 }
318318 },
319319 error: function(jqxhr, error, statusText) {
321321 console.log('annotations don\'t exist for this image. Create one!');
322322 }
323323 swtr.appView.$overlay.hide();
324 swtr.appView.helpview.step(2);
324 self.helpview.step(2);
325325 }
326326 });
327327 },
328 showHide: function() {
329 if($("#setbox:checked").length) {
330 $('.annotorious-item-unfocus').css("opacity", "0.5");
328 toggleAnnoAreas: function() {
329 if($('#toggle-anno-areas').is(':checked')) {
330 $('.annotorious-item-unfocus').css('opacity', '0.5');
331331 }
332332 else {
333 $('.annotorious-item-unfocus').css("opacity", "0");
333 $('.annotorious-item-unfocus').css('opacity', '0');
334334 }
335335 }
336336 });
  
4545 'click #sweet-cancel': 'cancelSweeting',
4646 'click #post-sweet': 'postSweets'
4747 },
48 initialize: function() {
48 initialize: function(opts) {
4949 this.template = _.template($('#sweet-template').html());
50 this.helpview = opts.helpview;
51 //this.setElement(opts.el);
5052 },
5153 render: function() {
5254 $('#sweet-list').html('<h4>These are your sweet annotations!</h4>');
6363 how: JSON.stringify(this.getHumanReadableParts(swt.get('how')))
6464 }));
6565 }, this);
66 $(this.el).fadeIn(300);
66 this.$el.fadeIn(300);
6767 },
6868 getHumanReadableParts: function(how) {
6969 var human_readable_json = {};
9292 this.collection.remove(notPosted);
9393 },
9494 postSweets: function() {
95 console.log("postSWr");
9695 var appView = swtr.appView;
97 appView.helpview.step(5);
96 this.helpview.step(5);
9897 appView.$overlay.show();
9998 try {
10099 this.collection.post({
101100 success: function(collection, response) {
102101 console.log(collection, response);
103102 swtr.sweets.set(collection);
104 //TODO: move this to a annotation view or something
105// anno.removeAll();
106 // _.each(swtr.sweets.models, function(swt) {
107 // if(!_.has(swt.get('how'), 'editable')) {
108 // swt.get('how')['editable'] = false;
109 // //console.log(swt.get('how').text.Comment);
110 // swt.get('how').text = swtr.imgAnnoView.createPopupText(swt.get('how'));
111 // //console.log(swt.get('how'));
112 // swt.get('how').text += '\n - by ' + swt.get('who');
113 // }
114 // //console.log(swt.get('how'));
115 // anno.addAnnotation(swt.get('how'));
116 // });
117 //console.log(swtr.sweets.toJSON());
118 swtr.appView.$overlay.hide();
119 swtr.appView.helpview.step(6);
103 appView.$overlay.hide();
104 this.helpview.step(6);
120105 },
121106 error: function(jqxhr, error, text) {
122107 console.log(jqxhr, error, text);
123 swtr.appView.$overlay.hide();
124 swtr.appView.helpview.step(10);
108 appView.$overlay.hide();
109 this.helpview.step(10);
125110 }
126111 });
127112 } catch(e) {
128113 if(e.message == 'Access Token is required to sweet') {
129114 appView.$overlay.hide();
130 appView.helpview.step(9);
115 this.helpview.step(9);
131116 }
132117 }
133118 this.cleanUp();
120120 },
121121 cleanUp: function() {
122122 //console.log('cleaning up');
123 $(this.el).hide();
123 this.$el.hide();
124124 }
125125 });
126126
149149 // pluck uniq tags of sweets
150150 var tags = _.chain(this.collection.pluck('how')).pluck('tags').flatten().
151151 uniq().value();
152
152153 // render them as filter controls
153154 _.each(tags, function(tag) {
154155 if(tag) {
217217 anno.addAnnotation(swt.get('how'));
218218 });
219219 }
220 },
221 filterSweet: function(event) {
222 /*if(!event.currentTarget.checked) {
223 var results = this.collection.filter(function(model) {
224 if(model.get('who') != event.currentTarget.name)
225 return model;
226 });
227 if(results.length) {
228 _.each(results, function(result) {
229 anno.removeAnnotation(result.get('how'));
230 });
231 }
232 else { // if results is empty then remove all anno.
233 anno.removeAll();
234 }
235 }
236 else {
237 results = this.collection.filter(function(model) {
238 if(model.get('who') == event.currentTarget.name)
239 return model;
240 });
241 _.each(results, function(result) {
242 anno.addAnnotation(result.get('how'));
243 });
244
245 }
246 // if(results) {
247 // anno.removeAll();
248 // }
249 // swtr.annoView.collection = results;
250 // swtr.annoView.renderWith();*/
251220 }
252221 });
253222
254223 var AppView = Backbone.View.extend({
255224 el: $('body'),
256225 events: {
257 'click #user-input-submit': 'submitUserInput',
258 'click #sweet': 'sweet',
259226 'click #sign-in': 'signIn',
260227 //'mouseup .annotorious-editor-button-save': 'addnew_anno'
261228 },
230230 // initialize components
231231 this.source = 'none';
232232 //this.helpview = new HelpView();
233 this.sweetsview = new SweetsView({collection: swtr.sweets});
234233
235234 // cache jquery selected elements which are used frequently
236235 this.$overlay = $('#app-overlay');
237 this.$img = $('#annotatable-img');
238236
239237 //this.helpview.step(1);
240238 // initialize the oauth stuff
243243 scopes: 'email,sweet'
244244 });
245245 },
246 signIn: function(event) {
247 event.preventDefault();
248 if(swtr.who === 'Guest') {
249 this.oauth.authorize();
250 }
251 return false;
252 },
253 userLoggedIn: function(username) {
254 swtr.who = username;
255 var text = 'Signed in as <b><u>' + swtr.who + '</u></b>';
256 $('#signinview').html(text);
257 },
258 userLoggedOut: function() {
259 swtr.who = 'Guest';
260 $('#signinview').html('Logged out');
261 }
262 });
263
264 var PlayAreaView = Backbone.View.extend({
265 id: '#play-page-container',
266 events: {
267 'click #user-input-submit': 'submitUserInput',
268 'click #sweet': 'sweet'
269 },
270 initialize: function() {
271 this.template = _.template($('#play-page-template').html());
272 this.helpview = new HelpView();
273 this.render();
274 this.sweetsview = new SweetsView({
275 el: $('#sweet-list-wrapper'),
276 collection: swtr.sweets,
277 helpview: this.helpview
278 });
279 this.$img = $('#annotatable-img');
280 this.helpview.step(1);
281 },
282 render: function() {
283 this.$el.html(this.template());
284 $('#play-page').html(this.$el);
285 },
246286 submitUserInput: function(event) {
247287 event.preventDefault();
248288 var input = $('#user-input').val();
249 if(this.source === 'ocd') {
250 this.loadOCDSearch(input);
251 }
252 else if (this.source === 'none') {
253 this.loadURL(input);
254 }
289 this.loadURL(input);
255290 },
291 getSweets: function() {
292 console.log('getSweets');
293 var annos = _.filter(anno.getAnnotations(), function(anno) {
294 return (!_.has(anno, 'editable') || anno.editable === true);
295 });
296
297 _.each(annos, function(anno) {
298 swtr.sweets.add({
299 who: swtr.who,
300 where: anno.src,
301 // remove the text field; we don't want to store that in the sweets
302 how: _.omit(anno, 'text')
303 });
304 });
305 },
306 showSweets: function() {
307 console.log('showSweets');
308 this.sweetsview.render();
309 },
310 sweet: function() {
311 console.log('sweeting');
312 this.getSweets();
313 this.showSweets();
314 return false;
315 },
256316 // load a URL for annotation (can be of image or html resource for now)
257317 loadURL: function(url, type) {
258318 //console.log('loadURL()');
259 if(this.source !== 'ocd') {
260 $('#ocd-results').hide();
261 }
262 $('#img-annotation-wrapper').show();
263319 if(!url || !url.match(/http/)) {
264320 this.helpview.step(13);
265321 return false;
266322 }
267323 // if type is given explicitly; we load it as such.
268324 if(type === 'image') {
269 if(swtr.imgAnnoView) {
270 swtr.imgAnnoView.setImage(url);
271 }
272 else {
273 swtr.imgAnnoView = new swtr.ImgAnnoView({
274 collection:swtr.sweets,
275 img: this.$img[0],
276 $img: this.$img,
277 url: url
278 });
279 }
325 this.initImageAnno(url);
280326 return false;
281327 }
282328 // else try to find what resource is the URL..
283329 // if url has an image extension then load the image annotation
284330 if(url.match(/.jpg|.jpeg|.png|.gif|.bmp|.svg/)) {
285 if(swtr.imgAnnoView) {
286 swtr.imgAnnoView.setImage(url);
287 }
288 else {
289 swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets,
290 img: this.$img[0],
291 $img: this.$img,
292 url: url});
293 }
294
331 this.initImageAnno(url);
295332 return false;
296333 }
297334 // else check with our /media-type endpoint to see what type of resource
298335 // it is
299336 else {
300337 this.helpview.step(12);
301 this.$overlay.show();
338 swtr.appView.$overlay.show();
302339 var self = this;
303340 $.get('/media-type', {where: url}, function(response) {
304341 //console.log(response);
305 self.$overlay.hide();
342 self.appView.$overlay.hide();
306343 if(response.type === 'image') {
307 if(swtr.imgAnnoView) {
308 swtr.imgAnnoView.setImage(url);
309 }
310 else {
311 swtr.imgAnnoView = new swtr.ImgAnnoView({collection:swtr.sweets,
312 img: self.$img[0],
313 $img: self.$img,
314 url: url});
315 }
344 this.initImageAnno(url);
316345 }
317346 else {
318347 window.location.href = '/annotate?where=' + url;
349349 });
350350 }
351351 },
352 getSweets: function() {
353 var annos = _.filter(anno.getAnnotations(), function(anno) {
354 return (!_.has(anno, 'editable') || anno.editable === true);
355 });
356
357 _.each(annos, function(anno) {
358 swtr.sweets.add({
359 who: swtr.who,
360 where: anno.src,
361 // remove the text field; we don't want to store that in the sweets
362 how: _.omit(anno, 'text')
352 initImageAnno: function(url) {
353 if(swtr.imgAnnoView) {
354 swtr.imgAnnoView.setImage(url);
355 }
356 else {
357 swtr.imgAnnoView = new swtr.ImgAnnoView({
358 collection: swtr.sweets,
359 img: this.$img[0],
360 $img: this.$img,
361 url: url,
362 helpview: this.helpview
363363 });
364 });
364 }
365365 },
366 showSweets: function() {
367 this.sweetsview.render();
368 },
369 sweet: function() {
370 this.getSweets();
371 this.showSweets();
372 return false;
373 },
374 signIn: function(event) {
375 event.preventDefault();
376 this.oauth.authorize();
377 return false;
378 },
379 userLoggedIn: function(username) {
380 swtr.who = username;
381 var text = 'Signed in as <b><u>' + swtr.who + '</u></b>';
382 $('#signinview').html(text);
383 },
384 userLoggedOut: function() {
385 swtr.who = 'Guest';
386 $('#signinview').html('Logged out');
366 destroy: function() {
367 this.helpview.remove();
368 this.remove();
387369 }
388370 });
389371
390
391 var PlayAreaView = Backbone.View.extend({
392 el: $('#play-page'),
393 events: {
394 },
395 initialize: function() {
396 this.render();
397 },
398 render: function() {
399 }
400 });
401
402372 var SearchView = Backbone.View.extend({
403373 id: 'search-page-container',
404374 events: {
516516 //console.log('onImgClick');
517517 event.preventDefault();
518518 // TODO: init the image anno
519 this.highlightImg(event);
519 this.drawCoverOnImg(event);
520520 //swtr.appView.loadURL(url, 'image');
521521 return false;
522522 },
523 highlightImg: function(event) {
523 drawCoverOnImg: function(event) {
524524 //console.log('highlightImg');
525525 var elem = $(event.currentTarget).parent().parent();
526526 // if .ocd-item-cover exists return
527527 if(elem.find('.ocd-item-cover').length) {
528 $(elem.find('.ocd-item-cover')[0]).slideDown();
528529 return;
529530 }
530531 //console.log(elem);
531532 elem.prepend(this.cover_template());
532 $(elem.find('.ocd-item-cover')[0]).slideDown('slow');
533 $(elem.find('.ocd-item-cover')[0]).slideDown();
533534 },
534535 onCoverCloseClick: function(event) {
535536 var elem = $(event.currentTarget).parent();
536 elem.slideUp('slow');
537 elem.remove();
537 elem.slideUp();
538538 },
539539 onMarkClick: function(event) {
540540 var url = $(event.currentTarget).parent().parent().
541541 find('img').attr('src');
542 //TODO: load the image in the play area/workbench
542543 console.log('load image anno', url);
543544 },
544545 search: function(data, cb) {
671671 initialize: function() {
672672 var self = this;
673673 swtr.LDs = new LDSwts();
674 swtr.LDs.getAll({what: 'img-anno',
675 success: function(data) {
676 swtr.LDs.add(data);
677 if(!swtr.tagCloudView) {
678 swtr.tagCloudView = new TagCloudView({collection: swtr.LDs});
679 }
680 }});
674 swtr.LDs.getAll({
675 what: 'img-anno',
676 success: function(data) {
677 swtr.LDs.add(data);
678 if(!swtr.tagCloudView) {
679 swtr.tagCloudView = new TagCloudView({collection: swtr.LDs});
680 }
681 }
682 });
681683 },
682684 destroy: function() {
683685 this.remove();
684
685686 }
686687 });
687688
696696 this.user_tag_el = $('#user-tag-cloud');
697697 this.tags_tag_el = $('#tags-tag-cloud');
698698 this.render();
699
700699 },
701700 userTagClicked: function(e) {
702701 console.log(e);
719719 .fontSize(function(d) { return d.size; })
720720 .on("end", this.draw)
721721 .start();
722
723722 },
724723 draw: function (words) {
725724 var fill = d3.scale.category20();
735735 .attr("transform", function(d) {
736736 return "translate(" + [d.x, d.y] + ")";})
737737 .text(function(d) { return d.text; });
738
739738 },
740739 renderTagsTagCloud: function() {
741740 var sweetsWithTags = swtr.LDs.filter(function(k) {
756756 .fontSize(function(d) { return d.size; })
757757 .on("end", this.drawTags)
758758 .start();
759
760759 },
761760 drawTags: function(words) {
762761 var fill = d3.scale.category20();
774774 })
775775 .text(function(d) {console.log(d); return d.text; });
776776 }
777
778777 });
779778
780779 var AppRouter = Backbone.Router.extend({
785785 },
786786 components: {
787787 'linked-data': LDView,
788 'play': DummyView,
788 'play': PlayAreaView,
789789 'search': SearchView
790790 },
791791 home: function() {
  
8686 </footer>
8787 </div>
8888
89 <div id="play-page" class="page">
90 <!-- second row: image URL input box and Load button -->
91 <div class="row" id="user-input-row">
92 <div class="col-md-8">
93 <form class="form-inline" role="form">
94 <div class="form-group col-md-11">
95 <label class="sr-only" for="user-input">Enter URL of an image or web page</label>
96 <input class="form-control" type="text"
97 placeholder="Enter URL of an image or web page" id="user-input">
98 </div>
99 <button type="submit" class="btn btn-info" id="user-input-submit">Load</button>
100 </form>
101 </div>
102 <div class="col-md-4">
103 </div>
104 </div> <!-- end second row -->
105 <!-- third row - control panel? -->
106 <div class="row" id="control-panel">
107 <div class="col-md-8">
108 <form class="form-inline" role="form">
109 <div class="form-group">
110 <button class="btn btn-default" id="sweet">Sweet</button>
111 </div>
112 </form>
113 </div>
114 <div class="col-md-4"></div>
115 </div> <!-- end third row -- >
116 <!-- fourth row: the image annotation window -->
117 <div class="row">
118 <div id="img-annotation-wrapper" class="col-md-12 col-xs-12 col-lg-12 col-sm-12 well">
119 <div id="img-anno-controls">
120 <form class="form-inline" role="form">
121 <div class="form-group">
122 <label class="checkbox-inline">
123 <input type="checkbox" id="setbox"> Show annotated areas
124 </label>
125 </div>
126 </form>
127 </div>
128 {% if url %}
129 <img src="{{ url }}" id="annotatable-img" class="img-responsive" alt="Annotation Workbench">
130 {% else %}
131 <img src="" id="annotatable-img" class="img-responsive" alt="Annotation Workbench">
132 {% endif %}
133 </div>
134 </div> <!-- end fourth row -->
89 <div id="play-page" class="page"></div>
13590
136 <div id="sweet-list-wrapper">
137 <ul id="sweet-list"></ul>
138 <div class="btn-grp">
139 <button class="btn btn-default" id="sweet-cancel">Cancel</button>
140 <button class="btn btn-primary" id="post-sweet">Sweet</button>
141 </div>
142 </div>
91 <!-- the search page -->
92 <div id="search-page" class="page"></div>
14393
144 </div>
14594 <div id="linked-data-page" class="page">
14695 <div id="tag-cloud">
14796 <div id="tags-tag-cloud"></div>
14897 <div id="user-tag-cloud"></div>
14998 </div>
15099 </div>
151 <!-- the search page -->
152 <div id="search-page" class="page"></div>
153100
154 <div id="linked-data-page" class="page"></div>
155
156101 </div>
157102 <div id="app-overlay"></div>
158103
170170 <li class="custom-popup-line"><span>Related Links: </span><%= Links %></li>
171171 </ul>
172172 </span>
173 </script>
174 <script type="text/template" id="play-page-template">
175 <!-- second row: image URL input box and Load button -->
176 <div class="row" id="user-input-row">
177 <div class="col-md-8">
178 <form class="form-inline" role="form">
179 <div class="form-group col-md-11">
180 <label class="sr-only" for="user-input">Enter URL of an image or web page</label>
181 <input class="form-control" type="text"
182 placeholder="Enter URL of an image or web page" id="user-input">
183 </div>
184 <button type="submit" class="btn btn-info" id="user-input-submit">Load</button>
185 </form>
186 </div>
187 <div class="col-md-4">
188 </div>
189 </div> <!-- end second row -->
190 <!-- third row - control panel? -->
191 <div class="row" id="control-panel">
192 <div class="col-md-8">
193 <form class="form-inline" role="form">
194 <div class="form-group">
195 <button class="btn btn-default" id="sweet">Sweet</button>
196 </div>
197 </form>
198 </div>
199 <div class="col-md-4"></div>
200 </div> <!-- end third row -- >
201 <!-- fourth row: the image annotation window -->
202 <div class="row">
203 <div id="img-annotation-wrapper" class="col-md-12 col-xs-12 col-lg-12 col-sm-12 well">
204 <div id="img-anno-controls">
205 <form class="form-inline" role="form">
206 <div class="form-group">
207 <label class="checkbox-inline">
208 <input type="checkbox" id="toggle-anno-areas"> Show annotated areas
209 </label>
210 </div>
211 </form>
212 </div>
213 {% if url %}
214 <img src="{{ url }}" id="annotatable-img" class="img-responsive" alt="Annotation Workbench">
215 {% else %}
216 <img src="" id="annotatable-img" class="img-responsive" alt="Annotation Workbench">
217 {% endif %}
218 </div>
219 </div> <!-- end fourth row -->
220
221 <div id="sweet-list-wrapper">
222 <ul id="sweet-list"></ul>
223 <div class="btn-grp">
224 <button class="btn btn-default" id="sweet-cancel">Cancel</button>
225 <button class="btn btn-primary" id="post-sweet">Sweet</button>
226 </div>
227 </div>
173228 </script>
174229 <script type="text/template" id="search-page-template">
175230 <div class="row" id="search-user-input-row">