diff --git a/.gitignore b/.gitignore index 3fa7dad33..0c11a246e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ webpack-assets.json .idea/ iosapp/www/ios/ http/ios/ +.package-lock.json diff --git a/http/css/style.less b/http/css/style.less index 10b5291da..5c3a13dc6 100644 --- a/http/css/style.less +++ b/http/css/style.less @@ -1918,6 +1918,22 @@ blockquote cite:before { content: "\2013"; } +.video-container { + position: relative; + padding-bottom: 56.25%; + padding-top: 30px; height: 0; overflow: hidden; +} + +.video-container iframe, +.video-container object, +.video-container embed { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + /*================================================== = Bootstrap 3 Media Queries = ==================================================*/ diff --git a/http/js/iznik/models/chat/chat.js b/http/js/iznik/models/chat/chat.js index d8ec3a1de..f461d433b 100644 --- a/http/js/iznik/models/chat/chat.js +++ b/http/js/iznik/models/chat/chat.js @@ -33,14 +33,14 @@ define([ } }).then(function() { // We've sent it successfully. - trigger.trigger('sent', msg); - Storage.set('chatqueue', JSON.stringify(sending)); if (sending.length > 0) { // We have another message to send. _.delay(_.bind(sendQueue, self), 100); } + + trigger.trigger('sent', msg); }); } } catch (e) { diff --git a/http/js/iznik/views/chat/chat.js b/http/js/iznik/views/chat/chat.js index 96d24138d..90aac36a6 100644 --- a/http/js/iznik/views/chat/chat.js +++ b/http/js/iznik/views/chat/chat.js @@ -369,7 +369,12 @@ define([ var cb = _.bind(self.fetchedChats, self); - Iznik.Session.chats.fetch().then(cb); + // We only fetch the summary information, for performance. + Iznik.Session.chats.fetch({ + data: { + summary: true + } + }).then(cb); }); $(document).on('hide', function () { @@ -589,7 +594,11 @@ define([ self.model.close().then(function() { // Also refetch the chats, so that our cached copy gets updated. - Iznik.Session.chats.fetch(); + Iznik.Session.chats.fetch({ + data: { + summary: true + } + }); }) } catch (e) { console.error(e.message) @@ -621,7 +630,11 @@ define([ self.model.block().then(function() { // Also refetch the chats, so that our cached copy gets updated. - Iznik.Session.chats.fetch(); + Iznik.Session.chats.fetch({ + data: { + summary: true + } + }); }) } catch (e) { console.error(e.message) diff --git a/http/js/iznik/views/group/communityevents.js b/http/js/iznik/views/group/communityevents.js index 6b1784c41..5b68cbbd9 100644 --- a/http/js/iznik/views/group/communityevents.js +++ b/http/js/iznik/views/group/communityevents.js @@ -222,111 +222,128 @@ define([ save: function() { var self = this; - if (!self.wait && self.dates.length > 0) { - self.promises = []; + // Check all datas are in the future + var datesvalid = true; + var today = new moment(); + self.$('.js-datesinvalid').hide(); + self.datesCV.viewManager.each(function(date) { + var start = new moment(date.getStart()); + var end = new moment(date.getEnd()); + + if (start.diff(today) < 0 || end.diff(today) < 0) { + datesvalid = false; + } + }); - if (self.$('form').valid()) { - self.wait = new Iznik.Views.PleaseWait({ - timeout: 1 - }); - self.wait.render(); + if (!datesvalid) { + self.$('.js-datesinvalid').fadeIn('slow'); + } else { + if (!self.wait && self.dates.length > 0) { + self.promises = []; - self.$('input,textarea').each(function () { - var name = $(this).prop('name'); - if (name.length > 0 && name != 'photo') { - self.model.set(name, $(this).val()); - } - }); + if (self.$('form').valid()) { + self.wait = new Iznik.Views.PleaseWait({ + timeout: 1 + }); + self.wait.render(); - var p = self.model.save({}, { - success: function(model, response, options) { - if (response.id) { - self.model.set('id', response.id); + self.$('input,textarea').each(function () { + var name = $(this).prop('name'); + if (name.length > 0 && name != 'photo') { + self.model.set(name, $(this).val()); } - } - }).then(function() { - // Add the group and dates. - var groups = self.model.get('groups'); - if (_.isUndefined(groups) || self.groupSelect.get() != groups[0]['id']) { - self.promises.push($.ajax({ - url: API + 'communityevent', - type: 'PATCH', - data: { - id: self.model.get('id'), - action: 'AddGroup', - groupid: self.groupSelect.get() - }, - success: function (ret) { - if (!_.isUndefined(groups)) { - self.promises.push($.ajax({ - url: API + 'communityevent', - type: 'PATCH', - data: { - id: self.model.get('id'), - action: 'RemoveGroup', - groupid: groups[0]['id'] - } - })); - } - } - })); - } - - // Delete any old dates. - var olddates = self.model.get('dates'); - _.each(olddates, function(adate) { - self.promises.push($.ajax({ - url: API + 'communityevent', - type: 'PATCH', - data: { - id: self.model.get('id'), - action: 'RemoveDate', - dateid: adate.id - } - })); }); - // Add new dates. - self.datesCV.viewManager.each(function(date) { - var start = date.getStart(); - var end = date.getEnd(); - - self.promises.push($.ajax({ - url: API + 'communityevent', - type: 'PATCH', - data: { - id: self.model.get('id'), - action: 'AddDate', - start: start, - end: end + var p = self.model.save({}, { + success: function(model, response, options) { + if (response.id) { + self.model.set('id', response.id); } - })); - }); + } + }).then(function() { + // Add the group and dates. + var groups = self.model.get('groups'); + if (_.isUndefined(groups) || self.groupSelect.get() != groups[0]['id']) { + self.promises.push($.ajax({ + url: API + 'communityevent', + type: 'PATCH', + data: { + id: self.model.get('id'), + action: 'AddGroup', + groupid: self.groupSelect.get() + }, + success: function (ret) { + if (!_.isUndefined(groups)) { + self.promises.push($.ajax({ + url: API + 'communityevent', + type: 'PATCH', + data: { + id: self.model.get('id'), + action: 'RemoveGroup', + groupid: groups[0]['id'] + } + })); + } + } + })); + } - if (self.model.get('photo')) { - self.promises.push($.ajax({ - url: API + 'communityevent', - type: 'PATCH', - data: { - id: self.model.get('id'), - action: 'SetPhoto', - photoid: self.model.get('photo') - } - })); - } + // Delete any old dates. + var olddates = self.model.get('dates'); + _.each(olddates, function(adate) { + self.promises.push($.ajax({ + url: API + 'communityevent', + type: 'PATCH', + data: { + id: self.model.get('id'), + action: 'RemoveDate', + dateid: adate.id + } + })); + }); + + // Add new dates. + self.datesCV.viewManager.each(function(date) { + var start = date.getStart(); + var end = date.getEnd(); + + self.promises.push($.ajax({ + url: API + 'communityevent', + type: 'PATCH', + data: { + id: self.model.get('id'), + action: 'AddDate', + start: start, + end: end + } + })); + }); + + if (self.model.get('photo')) { + self.promises.push($.ajax({ + url: API + 'communityevent', + type: 'PATCH', + data: { + id: self.model.get('id'), + action: 'SetPhoto', + photoid: self.model.get('photo') + } + })); + } - Promise.all(self.promises).then(function() { - self.wait.close(); - self.wait = null; - self.trigger('saved'); - self.model.trigger('edited'); + Promise.all(self.promises).then(function() { + self.wait.close(); + self.wait = null; + self.trigger('saved'); + self.model.trigger('edited'); - if (self.closeAfterSave) { - self.close(); - (new Iznik.Views.User.CommunityEvent.Confirm()).render(); - } + if (self.closeAfterSave) { + self.close(); + (new Iznik.Views.User.CommunityEvent.Confirm()).render(); + } + }); }); - }); + } } } }, diff --git a/http/js/iznik/views/pages/chat.js b/http/js/iznik/views/pages/chat.js index 6ab5552dc..3274371bf 100644 --- a/http/js/iznik/views/pages/chat.js +++ b/http/js/iznik/views/pages/chat.js @@ -406,7 +406,11 @@ define([ self.model.close().then(function() { // Reload. Bit clunky but it'll do. - Iznik.Session.chats.fetch().then(function() { + Iznik.Session.chats.fetch({ + data: { + summary: true + } + }).then(function() { // CC window.location.reload(); Router.navigate("/chats", true); }); @@ -435,7 +439,11 @@ define([ self.model.block().then(function() { // Reload. Bit clunky but it'll do. - Iznik.Session.chats.fetch().then(function() { + Iznik.Session.chats.fetch({ + data: { + summary: true + } + }).then(function() { window.location.reload(); }); }); diff --git a/http/js/iznik/views/pages/modtools/settings.js b/http/js/iznik/views/pages/modtools/settings.js index d1d5b6853..0a42708bf 100644 --- a/http/js/iznik/views/pages/modtools/settings.js +++ b/http/js/iznik/views/pages/modtools/settings.js @@ -384,7 +384,7 @@ define([ }, { name: 'approvemembers', - label: '(Freegle native groups only) Group approves new members?', + label: '(Freegle native groups only) New member approval required?', control: 'radio', options: [{label: 'Yes', value: 1}, {label: 'No', value:0 }], helpMessage: "Normally members can join immediately, and any posts they make will be moderated. Some groups prefer to approve new members manually, which gives more control over the group but loses postential members." diff --git a/http/js/iznik/views/pages/pages.js b/http/js/iznik/views/pages/pages.js index 4af65c67c..1efe8816a 100644 --- a/http/js/iznik/views/pages/pages.js +++ b/http/js/iznik/views/pages/pages.js @@ -159,6 +159,8 @@ define([ $('.js-unseennews').hide(); } } + + self.notificationChecking = false; } }); } @@ -388,7 +390,7 @@ define([ collection: self.notifications, modelViewOptions: { page: self, - notificationCheck: self.notificationCheck + notificationCheck: _.bind(self.notificationCheck, self) }, processKeyEvents: false, detachedRendering: true @@ -400,7 +402,7 @@ define([ collection: self.notifications, modelViewOptions: { page: self, - notificationCheck: self.notificationCheck + notificationCheck: _.bind(self.notificationCheck, self) }, processKeyEvents: false, detachedRendering: true diff --git a/http/js/iznik/views/pages/user/explore.js b/http/js/iznik/views/pages/user/explore.js index ab5becbac..07378ac9b 100644 --- a/http/js/iznik/views/pages/user/explore.js +++ b/http/js/iznik/views/pages/user/explore.js @@ -676,7 +676,8 @@ define([ self.$('.js-description a').attr('data-realurl', true); // Add the area map. - self.areaMap(); + // TODO MAPS + // self.areaMap(); self.collection = new Iznik.Collections.Message(null, { modtools: false, diff --git a/http/js/iznik/views/pages/user/find.js b/http/js/iznik/views/pages/user/find.js index f11ed08c4..deec769f0 100644 --- a/http/js/iznik/views/pages/user/find.js +++ b/http/js/iznik/views/pages/user/find.js @@ -479,7 +479,11 @@ define([ var p = Iznik.Views.User.Pages.WhatNext.prototype.render.call(this); p.then(function () { - if (!Storage.get('dontaskschedule')) { + var now = (new Date()).getTime(); + var last = Storage.get('lastaskschedule'); + + if (!Storage.get('dontaskschedule') && (!last || (now - last > 24 * 60 * 60 * 1000))) { + Storage.set('lastaskschedule', now); self.listenToOnce(Iznik.Session, 'isLoggedIn', function () { try { var v = new Iznik.Views.User.Schedule.Modal({ diff --git a/http/js/iznik/views/pages/user/give.js b/http/js/iznik/views/pages/user/give.js index 5c7b138c7..3fe17269d 100644 --- a/http/js/iznik/views/pages/user/give.js +++ b/http/js/iznik/views/pages/user/give.js @@ -76,7 +76,11 @@ define([ } catch (e) { } - if (!Storage.get('dontaskschedule')) { + var now = (new Date()).getTime(); + var last = Storage.get('lastaskschedule'); + + if (!Storage.get('dontaskschedule') && (!last || (now - last > 24 * 60 * 60 * 1000))) { + Storage.set('lastaskschedule', now); self.listenToOnce(Iznik.Session, 'isLoggedIn', function () { try { // Now ask them to tell us their schedule. diff --git a/http/js/iznik/views/pages/user/home.js b/http/js/iznik/views/pages/user/home.js index abbe41090..070e33d42 100644 --- a/http/js/iznik/views/pages/user/home.js +++ b/http/js/iznik/views/pages/user/home.js @@ -282,7 +282,8 @@ define([ cached: cb }).then(cb); - // We need the chats, as they are used when displaying messages. + // We need the chats, as they are used when displaying messages. We fetch the full info + // as we need the user profiles. var cb = _.bind(self.fetchedChats, self); Iznik.Session.chats.fetch().then(cb); @@ -412,7 +413,8 @@ define([ $('#js-eventcontainer').append(v.$el); }); - // We need the chats, as they are used when displaying messages. + // We need the chats, as they are used when displaying messages. We fetch the full version + // as we need it for profile. var cb = _.bind(self.fetchedChats, self); Iznik.Session.chats.fetch().then(cb); }); diff --git a/http/js/iznik/views/pages/user/landing.js b/http/js/iznik/views/pages/user/landing.js index f5136b2c0..9a28c7e15 100644 --- a/http/js/iznik/views/pages/user/landing.js +++ b/http/js/iznik/views/pages/user/landing.js @@ -24,9 +24,10 @@ define([ p.then(function(self) { // Add map. - var v = new Iznik.Views.Visualise.Map(); - v.render(); - self.$('.js-visualise').html(v.$el); + // TODO MAPS + // var v = new Iznik.Views.Visualise.Map(); + // v.render(); + // self.$('.js-visualise').html(v.$el); // Add stories require(['iznik/models/membership'], function () { diff --git a/http/js/iznik/views/pages/user/newsfeed.js b/http/js/iznik/views/pages/user/newsfeed.js index b13b7ece8..495b89dca 100644 --- a/http/js/iznik/views/pages/user/newsfeed.js +++ b/http/js/iznik/views/pages/user/newsfeed.js @@ -129,6 +129,8 @@ define([ var checks = { 'find': [ 'wanted', + 'wanting', + 'requesting', 'looking for', 'has anybody got', 'has anyone got', diff --git a/http/js/iznik/views/pages/user/settings.js b/http/js/iznik/views/pages/user/settings.js index 73035080a..006c1bafb 100644 --- a/http/js/iznik/views/pages/user/settings.js +++ b/http/js/iznik/views/pages/user/settings.js @@ -139,20 +139,23 @@ define([ }, onholidaytill: function(e) { + var self = this; var me = Iznik.Session.get('me'); - // Set the hour else midnight and under DST goes back a day. - e.date.hour(5); - var till = e.date.toISOString(); + if (!_.isUndefined(e.data)) { + // Set the hour else midnight and under DST goes back a day. + e.date.hour(5); + var till = e.date.toISOString(); - this.$('.js-onholidaytill').datetimepicker('hide'); + self.$('.js-onholidaytill').datetimepicker('hide'); - Iznik.Session.save({ - id: me.id, - onholidaytill: till - }, { - patch: true - }); + Iznik.Session.save({ + id: me.id, + onholidaytill: till + }, { + patch: true + }); + } }, onholiday: function() { @@ -385,7 +388,8 @@ define([ self.$('.datepicker').datetimepicker({ format: 'ddd, DD MMMM', minDate: new moment(), - maxDate: (new moment()).add(30, 'days') + maxDate: (new moment()).add(30, 'days'), + keyBinds: { 'delete':null } }); self.$('.datepicker').on("dp.change", _.bind(self.onholidaytill, self)); diff --git a/http/js/iznik/views/pages/user/stats.js b/http/js/iznik/views/pages/user/stats.js index e03ef5897..936f944d0 100644 --- a/http/js/iznik/views/pages/user/stats.js +++ b/http/js/iznik/views/pages/user/stats.js @@ -313,7 +313,6 @@ define([ self.map = new google.maps.Map(self.$('.js-usermap').get()[0], mapOptions); - // Searchbox var input = document.getElementById('pac-input'); self.searchBox = new google.maps.places.SearchBox(input); diff --git a/http/js/iznik/views/pages/user/volunteering.js b/http/js/iznik/views/pages/user/volunteering.js index 9c8bfdb06..d12bfeca2 100644 --- a/http/js/iznik/views/pages/user/volunteering.js +++ b/http/js/iznik/views/pages/user/volunteering.js @@ -83,9 +83,7 @@ define([ var self = this; self.model.renew().then(function() { - self.model.fetch().then(function() { - self.render(); - }) + self.$('.js-warn').fadeOut('slow'); }); }, diff --git a/http/js/iznik/views/user/message.js b/http/js/iznik/views/user/message.js index 743efd444..904370f6e 100644 --- a/http/js/iznik/views/user/message.js +++ b/http/js/iznik/views/user/message.js @@ -141,8 +141,8 @@ define([ } else { this.$('.js-snippet').slideUp(); } - this.caretshow(); this.expanded = !this.expanded; + this.caretshow(); }, fop: function() { @@ -1009,19 +1009,21 @@ define([ }, showMap: function() { - var self = this; - var loc = null; - - if (self.model.get('location')) { - loc = self.model.get('location'); - } else if (self.model.get('area')) { - loc = self.model.get('area'); - } - - if (loc) { - self.$('.js-mapzoom .js-map').attr('src', "https://maps.google.com/maps/api/staticmap?size=110x110&zoom=" + self.model.get('mapzoom') + "¢er=" + loc.lat + "," + loc.lng + "&maptype=roadmap&markers=icon:" + self.model.get('mapicon') + "|" + loc.lat + "," + loc.lng + "&sensor=false&key=AIzaSyCdTSJKGWJUOx2pq1Y0f5in5g4kKAO5dgg"); - self.$('.js-mapzoom').show(); - } + // TODO MAPS + return; + // var self = this; + // var loc = null; + // + // if (self.model.get('location')) { + // loc = self.model.get('location'); + // } else if (self.model.get('area')) { + // loc = self.model.get('area'); + // } + // + // if (loc) { + // self.$('.js-mapzoom .js-map').attr('src', "https://maps.google.com/maps/api/staticmap?size=110x110&zoom=" + self.model.get('mapzoom') + "¢er=" + loc.lat + "," + loc.lng + "&maptype=roadmap&markers=icon:" + self.model.get('mapicon') + "|" + loc.lat + "," + loc.lng + "&sensor=false&key=AIzaSyCdTSJKGWJUOx2pq1Y0f5in5g4kKAO5dgg"); + // self.$('.js-mapzoom').show(); + // } }, mapZoom: function(e) { @@ -1076,7 +1078,11 @@ define([ ChatHolder().fetchAndRestore(chatid); // And now prompt them to give us their schedule. - if (!Storage.get('dontaskschedule')) { + var now = (new Date()).getTime(); + var last = Storage.get('lastaskschedule'); + + if (!Storage.get('dontaskschedule') && (!last || (now - last > 24 * 60 * 60 * 1000))) { + Storage.set('lastaskschedule', now); var v = new Iznik.Views.User.Schedule.Modal({ mine: true, help: true, @@ -1319,54 +1325,56 @@ define([ template: 'user_message_mapzoom', render: function() { - var self = this; - - var p = Iznik.Views.Modal.prototype.render.call(self); - p.then(function() { - self.waitDOM(self, function(self) { - // Set map to be square - will have height 0 when we open. - var map = self.$('.js-map'); - var mapWidth = map.width(); - map.height(mapWidth); - - var location = self.model.get('location'); - var area = self.model.get('area'); - var centre = null; - - if (location) { - centre = new google.maps.LatLng(location.lat, location.lng); - } else if (area) { - centre = new google.maps.LatLng(area.lat, area.lng); - self.$('.js-vague').show(); - } - - var mapOptions = { - mapTypeControl : false, - streetViewControl : false, - center : centre, - panControl : mapWidth > 400, - zoomControl : mapWidth > 400, - zoom : self.model.get('zoom') ? self.model.get('zoom') : 16 - }; - - self.map = new google.maps.Map(map.get()[0], mapOptions); - - var icon = { - url: iznikroot + 'images/user_logo.png', // CC - scaledSize: new google.maps.Size(50, 50), - origin: new google.maps.Point(0,0), - anchor: new google.maps.Point(0, 0) - }; - - var marker = new google.maps.Marker({ - position: centre, - icon: icon, - map: self.map - }); - }); - }); - - return(p); + // TODO MAPS + return Iznik.resolvedPromise(this); + // var self = this; + // + // var p = Iznik.Views.Modal.prototype.render.call(self); + // p.then(function() { + // self.waitDOM(self, function(self) { + // // Set map to be square - will have height 0 when we open. + // var map = self.$('.js-map'); + // var mapWidth = map.width(); + // map.height(mapWidth); + // + // var location = self.model.get('location'); + // var area = self.model.get('area'); + // var centre = null; + // + // if (location) { + // centre = new google.maps.LatLng(location.lat, location.lng); + // } else if (area) { + // centre = new google.maps.LatLng(area.lat, area.lng); + // self.$('.js-vague').show(); + // } + // + // var mapOptions = { + // mapTypeControl : false, + // streetViewControl : false, + // center : centre, + // panControl : mapWidth > 400, + // zoomControl : mapWidth > 400, + // zoom : self.model.get('zoom') ? self.model.get('zoom') : 16 + // }; + // + // self.map = new google.maps.Map(map.get()[0], mapOptions); + // + // var icon = { + // url: '/images/user_logo.png', + // scaledSize: new google.maps.Size(50, 50), + // origin: new google.maps.Point(0,0), + // anchor: new google.maps.Point(0, 0) + // }; + // + // var marker = new google.maps.Marker({ + // position: centre, + // icon: icon, + // map: self.map + // }); + // }); + // }); + // + // return(p); } }); }); \ No newline at end of file diff --git a/http/js/iznik/views/user/schedule.js b/http/js/iznik/views/user/schedule.js index 284809a90..fd935cebf 100644 --- a/http/js/iznik/views/user/schedule.js +++ b/http/js/iznik/views/user/schedule.js @@ -239,28 +239,35 @@ define([ render: function () { var self = this; - var p = Iznik.Views.Modal.prototype.render.call(this); + self.wait = new Iznik.Views.PleaseWait(); + self.wait.render(); + + // The schedule involves a server fetch; render it before opening the modal to avoid ugly empty + // modal. + var v = new Iznik.Views.User.Schedule({ + chatuserid: self.options.chatuserid, + schedule: self.options.schedule, + mine: self.options.mine, + help: self.options.help, + otheruser: self.options.otheruser, + cancel: true + }); - p.then(function () { - var v = new Iznik.Views.User.Schedule({ - chatuserid: self.options.chatuserid, - schedule: self.options.schedule, - mine: self.options.mine, - help: self.options.help, - otheruser: self.options.otheruser, - cancel: true - }); + self.listenToOnce(v, 'saved', function () { + self.close(); + }); - self.listenToOnce(v, 'saved', function () { - self.close(); - }); + self.listenToOnce(v, 'cancelled', function () { + self.close(); + }); - self.listenToOnce(v, 'cancelled', function () { - self.close(); - }); + var p = v.render(); - v.render(); - self.$('.js-schedule').append(v.$el); + p.then(function() { + self.wait.close(); + Iznik.Views.Modal.prototype.render.call(self).then(function() { + self.$('.js-schedule').append(v.$el); + }); }); return (p); diff --git a/http/js/iznik/views/user/user.js b/http/js/iznik/views/user/user.js index d440d9c98..7e87f40ae 100644 --- a/http/js/iznik/views/user/user.js +++ b/http/js/iznik/views/user/user.js @@ -1214,6 +1214,8 @@ define([ self.ratings2.render(); self.$('.js-ratings2').html(self.ratings2.$el); + + self.$('.js-abouttext').html(Iznik.twem(self.$('.js-abouttext').html())); }) }); diff --git a/http/template/chat/address.html b/http/template/chat/address.html index 3b00cb628..1c5fcc86a 100644 --- a/http/template/chat/address.html +++ b/http/template/chat/address.html @@ -27,9 +27,10 @@
The affected domains are .
- - + +{{ info.aboutme.text }}+
{{ info.aboutme.text }}<% } %>