Commit 0bce307eabd7924858e0e39293a5fb180ad14885

Fix UI issues

  - Fix the HTML part to fix some UI issues
  - Better handling of error/edge cases
  - Refactor some code
  
3939#helpview {
4040 font-weight: bold;
4141 font-size: 1.3em;
42 min-height: 60px;
42 min-height: 50px;
4343 text-align: center;
4444}
4545#app-overlay {
4646 position: absolute;
47 top: 0px;
47 top: 60px;
48 left: 0;
4849 display: none;
4950 width: 100%;
50 height: 100%;
51 height: 800px;
5152 z-index: 10000;
5253 background-color: rgba(255, 255, 255, 0.7);
5354}
  
2626 url: swtr.swtstoreURL()+'/api/users/me?access_token='+
2727 swtr.access_token,
2828 success: function(data) {
29 console.log(data.username);
3029 swtr.appView.userLoggedIn(data.username);
3130 },
3231 error: function() {
4444 'how': {}
4545 },
4646 initialize: function() {
47 if(!_.has(this, 'id')) {
48 // bad hack to have dates.. FIXIT
49 this.set('created', new Date().toUTCString().substr(0, 25));
50 }
5147 }
5248 });
5349
6666 throw Error('"where" option must be passed to get sweets of a URI');
6767 return false;
6868 }
69 if(!swtr.access_token) {
69 /*if(!swtr.access_token) {
7070 throw new Error('Access Token required to get query that API');
71 }
71 }*/
7272 // setting up params
7373 var where = options.where,
7474 who = options.who || null;
132132 new_models.push(model);
133133 }
134134 });
135 return new_models;
135 return new_models;
136136 },
137137 // update part of the collection after a save on the server
138138 update: function() {
157157 $('#sweet-list').append(this.template({
158158 who: swt.get('who'),
159159 what: swt.get('what'),
160 where: swt.get('where'),
160 where: swt.get('where'),
161161 how: JSON.stringify(swt.get('how').text)
162162 }));
163163 }, this);
174174 this.collection.remove(notPosted);
175175 },
176176 postSweets: function() {
177 swtr.appView.helpview.step(5);
178 swtr.appView.$overlay.show();
179 this.collection.post({
180 success: function(collection, response) {
181 console.log(collection, response);
182 swtr.sweets.update(collection);
183 //TODO: move this to a annotation view or something
184 anno.removeAll();
185 _.each(swtr.sweets.models, function(swt) {
186 if(!_.has(swt.get('how'), 'editable')) {
187 swt.get('how')['editable'] = false;
188 swt.get('how').text += '\n - by ' + swt.get('who');
189 }
190 console.log(swt.get('how'));
191 anno.addAnnotation(swt.get('how'));
192 });
193 //console.log(swtr.sweets.toJSON());
194 swtr.appView.$overlay.hide();
195 swtr.appView.helpview.step(6);
196 },
197 error: function(jqxhr, error, text) {
198 console.log(jqxhr, error, text);
177 var appView = swtr.appView;
178 appView.helpview.step(5);
179 appView.$overlay.show();
180 try {
181 this.collection.post({
182 success: function(collection, response) {
183 console.log(collection, response);
184 swtr.sweets.update(collection);
185 //TODO: move this to a annotation view or something
186 anno.removeAll();
187 _.each(swtr.sweets.models, function(swt) {
188 if(!_.has(swt.get('how'), 'editable')) {
189 swt.get('how')['editable'] = false;
190 swt.get('how').text += '\n - by ' + swt.get('who');
191 }
192 console.log(swt.get('how'));
193 anno.addAnnotation(swt.get('how'));
194 });
195 //console.log(swtr.sweets.toJSON());
196 appView.overlay.hide();
197 appView.helpview.step(6);
198 },
199 error: function(jqxhr, error, text) {
200 console.log(jqxhr, error, text);
201 }
202 });
203 } catch(e) {
204 if(e.message == 'Access Token is required to sweet') {
205 appView.$overlay.hide();
206 appView.helpview.step(9);
199207 }
200 });
208 }
201209 this.cleanUp();
202210 return false;
203211 },
221221 'click #img-url-load': 'setImage',
222222 'click #img-url-submit': 'setImage',
223223 'click #sweet': 'sweet',
224 'click #signin-credentials': 'getSignInCredentials',
224 'click #sign-in': 'signIn',
225225 'click #setbox': 'showHide',
226226 'change .form-control': 'button_custom',
227227 'mouseup .annotorious-editor-button-save': 'add_new_anno'
228228 },
229229 initialize: function() {
230 //var allElements = $('body *');
230 // initialize components
231231 this.helpview = new HelpView();
232232 this.sweetsview = new SweetsView({collection: swtr.sweets});
233
234 //register handlers for annotorious events
233235 anno.addHandler('onAnnotationCreated', this.showSwtHelp);
234 anno.addHandler('onannotationupdated', this.showswthelp);
236 anno.addHandler('onAnnotationUpdated', this.showSwtHelp);
235237 anno.addHandler('onSelectionStarted', function(annotation) {
236238 anno.hideAnnotations();});
237239 anno.addHandler('onSelectionCompleted', function(annotation) {
238240 anno.showAnnotations();
239241 });
240 anno.addPlugin('CustomFields', this.showSwtHelp);
241 anno.addHandler('onSelectionCompleted', this.setShape);
242 anno.addPlugin('CustomFields', {});
243 anno.addHandler('onSelectionCompleted', this.setShape);
244
245 // cache jquery selected elements which are used frequently
242246 this.$overlay = $('#app-overlay');
243247 this.$img = $('#annotatable-img');
248
249 // attach a load event handler, whenever an image is loaded..
250 this.$img.on('load', this, this.imageLoaded);
251 this.$img.on('error', this, this.onImageLoadError);
252
253 // check if already an image is provided at load time..
244254 this.imgURL = this.$img.attr('src');
245255 if(this.imgURL) {
246256 this.initImageAnno();
260260 this.helpview.step(1);
261261 }
262262
263 // initialize the oauth stuff
263264 this.oauth = new Oauth({
264265 app_id: swtr.app_id,
265266 app_secret: swtr.app_secret,
269269 scopes: 'email,sweet'
270270 });
271271 },
272
273 setImage: function() {
274 anno.reset();
272 setImage: function(event) {
273 event.preventDefault();
275274 this.imgURL = $('#img-url-input').val();
275 if(!this.imgURL) {
276 return false;
277 }
278 anno.reset();
279 var self = this;
276280 this.$overlay.show();
277281 this.helpview.step(7);
278 this.$img.attr('onload', function() {
279 swtr.appView.$overlay.hide();
280 });
281282 this.$img.attr('src', this.imgURL);
282 this.initImageAnno();
283283 return false;
284284 },
285 imageLoaded: function(event) {
286 var self = event.data;
287 console.log('image loaded');
288 self.$overlay.hide();
289 self.initImageAnno();
290 },
291 // when image fails to load - could be because of broken URL or network
292 // issues
293 onImageLoadError: function(event) {
294 var self = event.data;
295 console.log('error while loading image');
296 self.$overlay.hide();
297 self.helpview.step(8);
298 },
285299 initImageAnno: function() {
286300 // img is a jquery object which annotorious doesn't accept; instead it
287301 // takes the native object returned by a browser API; fortunately, jqeury
304304 this.getExistingAnnotations();
305305 },
306306 getExistingAnnotations: function() {
307 var self = this;
307308 this.helpview.step(0);
308309 this.$overlay.show();
309310 //console.log('getting existing annotations of ', this.imgURL);
321321 anno.addAnnotation(swt.how);
322322 console.log('swt.how = ', swt.how);
323323 });
324 swtr.appView.$overlay.hide();
325 swtr.appView.helpview.step(2);
324 self.$overlay.hide();
325 self.helpview.step(2);
326326 }
327327 },
328328 error: function(jqxhr, error, statusText) {
329329 if(jqxhr.status === 404) { //annotations don't exist for this image
330330 console.log('annotations don\'t exist for this image. Create one!');
331331 }
332 swtr.appView.$overlay.hide();
333 swtr.appView.helpview.step(2);
332 self.$overlay.hide();
333 self.helpview.step(2);
334334 }
335335 });
336336 },
369369 //$("p").toggle();
370370 $('.annotorious-item-unfocus').css("opacity", "0");
371371 }
372
373372 },
374//annotorious editor widget - custom with options
375//to obtain shapes object, declaring annotation in global scope - TODO refactor
376//code to find better way to do this.
377
378 setShape: function(annotation) {
373 //annotorious editor widget - custom with options
374 //to obtain shapes object, declaring annotation in global scope - TODO refactor
375 //code to find better way to do this.
376 setShape: function(annotation) {
379377 $('.annotorious-editor-text').hide();
380378 $('.annotorious-editor').css("width", "100%");
381 window.annotation=annotation;
382 annotation.text = [];
383 },
384//to create new annotation object
379 window.annotation=annotation;
380 annotation.text = [];
381 },
382 //to create new annotation object
385383 inputStore: function(opt) {
386384 var temp = opt;
387385 var src = $('#img-url-input').val();
387387
388388 },
389389
390//to add the final annotation
390 //to add the final annotation
391391
392//save button - event bind
393 add_new_anno: function(event){
394 var $selected = $('select option:selected');
395 var tempinput = $selected.text()+': '+$('.annotorious-editor textarea').val();
396 this.newanno.text.push(tempinput);
397 var newinput = this.newanno.text.toString();
398 this.newanno.text = newinput;
399 console.log('this.newanno = ', this.newanno);
400 //this.to_Add(this.newanno);
401 var newanno = this.newanno;
402 window.newanno = newanno;
403 },
404//dropdown event
392 //save button - event bind
393 add_new_anno: function(event) {
394 var $selected = $('select option:selected');
395 var tempinput = $selected.text()+': '+$('.annotorious-editor textarea').val();
396 this.newanno.text.push(tempinput);
397 var newinput = this.newanno.text.toString();
398 this.newanno.text = newinput;
399 console.log('this.newanno = ', this.newanno);
400 //this.to_Add(this.newanno);
401 var newanno = this.newanno;
402 window.newanno = newanno;
403 },
404 //dropdown event
405405 button_custom: function(event) {
406406 $('.annotorious-editor-text').show();
407407 var $selected = $('select option:selected');
416416 $('.annotorious-editor-text:first').val("");
417417 $('.annotorious-editor-text:first').attr('placeholder', 'Add a '+$selected.text());
418418 },
419
420
421
422 getSignInCredentials: function(event) {
419 // to sign in the user to swtstore..just make a call to the oauth endpoint
420 signIn: function(event) {
423421 event.preventDefault();
424422 this.oauth.authorize();
425423 return false;
426424 },
427 signIn: function(username, password) {
428 this.$overlay.show();
429 $.ajax({
430 url: swtr.swtstoreURL() + swtr.endpoints.auth,
431 type: 'POST',
432 data: {user: username, hash: password},
433 success: function(data) {
434 swtr.appView.$overlay.hide();
435 swtr.who = username;
436 var text = 'You are signed in as <b>' + swtr.who+ '</b>';
437 $('#signinview').html(text);
438 },
439 error: function(jqxhr, status, error) {
440 swtr.appView.$overlay.hide();
441 if(error === 'FORBIDDEN') {
442 $('#signin-msg').html('Error signing in. Please check your username and password. ');
443 }
444 else {
445 }
446 }
447 });
448 },
449 userLoggedIn: function(token) {
450 swtr.who = token;
425 userLoggedIn: function(username) {
426 swtr.who = username;
451427 var text = 'You are signed in as <b>' + swtr.who + '</b>';
452428 $('#signinview').html(text);
453429 },
462462 break;
463463 case 7: text = 'Fetching your image..';
464464 break;
465 case 8: text = 'Oops! Seems like the image URL is wrong! Or we couldn\'t fetch the image.';
466 break;
467 case 9: text = 'You have to be <i>signed in</i> to sweet store to post sweets';
468 break;
465469 }
466470 $(this.el).html(text);
467471 $(window).scrollTop(0, 0);
476476 swtr.utils = {};
477477
478478 //swtr.AppView = AppView;
479
480 // Persona callbacks
481 /*navigator.id.watch({
482 //when an user logs in
483 onlogin: function(assertion) {
484 //verify assertion and login the user
485 $.ajax({
486 type: 'POST',
487 url: swtr.swtstoreURL() + swtr.endpoints.login,
488 data: {assertion: assertion},
489 success: function(data) {
490 console.log('user logged in', data);
491 swtr.appView.userLoggedIn(data);
492 },
493 error: function() {
494 navigator.id.logout();
495 }
496 });
497 },
498 //when an user logs out
499 onlogout: function() {
500 $.ajax({
501 type: 'POST',
502 //data: {email: swtr.who},
503 url: swtr.swtstoreURL() + swtr.endpoints.logout,
504 success: function() {
505 console.log('user logged out');
506 //swtr.appView.userLoggedOut();
507 },
508 error: function() {
509 }
510 });
511 }
512 });*/
513479
514480})(swtr);
  
88 <meta name="description" content="Sweet Maker, Social, Semantic, Web, Decentralized, Makes Sweet">
99 <link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
1010 <link href="{{ url_for('static', filename='css/bootstrap-theme.min.css') }}" rel="stylesheet">
11 <link href="{{ url_for('static', filename='css/swtmaker.css') }}" rel="stylesheet">
1211 <link href="{{ url_for('static', filename='css/annotorious.css') }}" rel="stylesheet">
1312 <link href="{{ url_for('static', filename='css/swtmaker.css') }}" rel="stylesheet">
1413 </head>
15 <body>
1614
15 <body>
1716 <div id="swt-maker" class="container">
18 <div id="helpview" class="alert alert-info col-md-8"></div>
19 <div class="row" id="signinview">
20 <form class="form-inline" role="form">
21 <span id="signin-msg">You are not signed in. </span>
22 <button class="btn btn-sm btn-primary" id="signin-credentials">
23 Sign In
24 </button>
25 </form>
26 </div>
27 <div id="img-input" class="row">
28 <div class="form-group col-md-8">
29 <input type="text" placeholder="Enter URL of the image"
30 id="img-url-input" class="form-control">
17 <!-- first row: helpview and sign in button -->
18 <div class="row">
19 <!-- helpview column of width md-8 -->
20 <div class="col-md-8">
21 <div id="helpview" class="alert alert-info"></div>
3122 </div>
32 <div class="col-md-2">
33 <button class="btn btn-default" id="img-url-submit">Load</button>
23 <!-- signin view column of width md-4 -->
24 <div class="col-md-4">
25 <div id="signinview">
26 <span id="signin-msg">You are not signed in.</span>
27 <button class="btn btn-sm btn-primary" id="sign-in">
28 Sign In
29 </button>
30 </div>
3431 </div>
32 </div> <!-- end first row -->
33 <!-- second row: image URL input box and Load button -->
34 <div class="row">
3535 <div class="col-md-8">
36 <button class="btn btn-default" id="img-url-load">Annotate</button>
37 <button class="btn btn-default" id="sweet">Sweet</button>
38 <input id="setbox" type="checkbox"/ > <label
39 id="setcontrol"><p>Show annotated areas</p><p style="display: none">Hide
40 annotated areas</p></label>
36 <form class="form-inline" role="form">
37 <div class="form-group col-md-11">
38 <label class="sr-only" for="img-url-input">Enter URL of the image</label>
39 <input class="form-control" type="text"
40 placeholder="Enter URL of the image" id="img-url-input">
41 </div>
42 <button type="submit" class="btn btn-primary" id="img-url-load">Load</button>
43 </form>
4144 </div>
42 </div>
43 <div id="img-annotation-wrapper" class="col-md-12 col-xs-12 col-lg-12 col-sm-12 well">
45 <div class="col-md-4">
46 </div>
47 </div> <!-- end second row -->
48 <!-- third row - control panel? -->
49 <div class="row">
50 <div class="col-md-3">
51 <input id="setbox" type="checkbox"/>
52 <label id="setcontrol" for="setbox">Show annotated areas</label>
53 </div>
54 <div class="col-md-1">
55 <button class="btn btn-default" id="sweet">Sweet</button>
56 </div>
57 </div> <!-- end third row -- >
58 <!-- fourth row: the image annotation window -->
59 <div class="row">
60 <div id="img-annotation-wrapper" class="col-md-12 col-xs-12 col-lg-12 col-sm-12 well">
4461 {% if url %}
45 <img src="{{ url }}" id="annotatable-img">
62 <img src="{{ url }}" id="annotatable-img" class="img-responsive">
4663 {% else %}
47 <img src="" id="annotatable-img">
64 <img src="" id="annotatable-img" class="img-responsive">
4865 {% endif %}
49 </div>
66 </div>
67 </div> <!-- end fourth row -->
68
5069 <div id="sweet-list-wrapper">
5170 <ul id="sweet-list"></ul>
5271 <div class="btn-grp">
102102 <script src="{{ url_for('static', filename='js/lib/annotorious.debug.js') }}"></script>
103103 <script src="{{ url_for('static', filename='js/lib/custom-fields-plugin.js') }}"></script>
104104 <script src="{{ url_for('static', filename='js/lib/label.js') }}"></script>
105 <!--script src="https://login.persona.org/include.js"></script-->
106 <!--script src="{{ url_for('static',
107 filename='js/lib/mozilla.persona.include.js') }}"></script-->
108105 <script src="{{ url_for('static', filename='js/oauth.js') }}"></script>
109106 <script src="{{ url_for('static', filename='js/swtmaker.js') }}"></script>
110107
112112 <%= how %>
113113 </li>
114114 </script>
115 <script type="text/template" id="signin-credentials-template">
116 <div class="form-inline col-md-3">
117 <label class="sr-only" for="username">Username</label>
118 <input type="text" class="form-control" id="username" placeholder="Enter username">
119 </div>
120 <div class="form-inline col-md-3">
121 <label class="sr-only" for="password">Password</label>
122 <input type="password" class="form-control" id="password" placeholder="Password">
123 </div>
124 </script>
125 <script type="text/template" id="button-template">
126 <select class="form-control">
127 <option id="">Choose an Option</option>
128 <option id="comment" >Comment</option>
129 <option id="label" >Label</option>
130 <option id="tags">Tags</option>
131 <option id="links">Links</option>
132 </select>
133 </script>
134 <script type="text/template" id="popup-template">
135 <span class="annotorious-popup-text"> </span>
136 </script>
115 <script type="text/template" id="button-template">
116 <select class="form-control">
117 <option id="">Choose an Option</option>
118 <option id="comment" >Comment</option>
119 <option id="label" >Label</option>
120 <option id="tags">Tags</option>
121 <option id="links">Links</option>
122 </select>
123 </script>
124 <script type="text/template" id="popup-template">
125 <span class="annotorious-popup-text"> </span>
126 </script>
137127 </body>
138128</html>