diff --git a/http/js/iznik/router.js b/http/js/iznik/router.js index 46e8c0f04..d8117343d 100644 --- a/http/js/iznik/router.js +++ b/http/js/iznik/router.js @@ -210,7 +210,7 @@ define([ "mypost/:id/:id": "userMyPostAction", "mypost/:id": "userMyPost", "stories/fornewsletter": "userNewsletterReview", - "stories": "userStories", + "stories(/:id)": "userStories", "story/:id": "userStory", "volunteering": "userVolunteerings", "volunteering/group/(/:id)": "userVolunteerings", @@ -385,12 +385,14 @@ define([ } }, - userStories: function() { + userStories: function(groupid) { if (!MODTOOLS) { var self = this; require(["iznik/views/pages/user/stories"], function () { - var page = new Iznik.Views.User.Pages.Stories(); + var page = new Iznik.Views.User.Pages.Stories({ + groupid: groupid + }); self.loadRoute({page: page}); }); } @@ -1083,6 +1085,7 @@ define([ if (ret.ret === 0) { try { Storage.set('draft', id); + Storage.set('draftrepost', id); if (ret.messagetype == 'Offer') { // Make them reconfirm the location diff --git a/http/js/iznik/views/chat/chat.js b/http/js/iznik/views/chat/chat.js index 14bd8ee37..574f186eb 100644 --- a/http/js/iznik/views/chat/chat.js +++ b/http/js/iznik/views/chat/chat.js @@ -163,10 +163,16 @@ define([ updateCounts: function () { var self = this; var unseen = 0; + var titleunseen = 0; // console.log("update Chat counts"); Iznik.Session.chats.each(function (chat) { + var chattype = chat.get('chattype'); unseen += chat.get('unseen'); + + if (chattype === 'User2User' || chattype === 'User2Mod') { + titleunseen += chat.get('unseen'); + } }); /* CC Iznik.Session.chats.each(function (chat) { var chatView = Iznik.activeChats.viewManager.findByModel(chat); @@ -183,7 +189,7 @@ define([ $(this).empty().hide(); } - Iznik.setTitleCounts(unseen, null); + Iznik.setTitleCounts(titleunseen, null); } }); diff --git a/http/js/iznik/views/pages/modtools/settings.js b/http/js/iznik/views/pages/modtools/settings.js index 34a154d4d..e31dddb57 100644 --- a/http/js/iznik/views/pages/modtools/settings.js +++ b/http/js/iznik/views/pages/modtools/settings.js @@ -363,10 +363,10 @@ define([ }, { name: 'mentored', - label: 'Mentored?', + label: 'Mentor Caretakers?', control: 'radio', options: [{label: 'Yes', value: 1}, {label: 'No', value:0 }], - helpMessage: '(Freegle only) If Yes, this group is being run by Mentors until a local owner can be found.', + helpMessage: '(Freegle only) If Yes, this group is being run by Mentor Caretakers.', disabled: !Iznik.Session.isAdminOrSupport() }, { diff --git a/http/js/iznik/views/pages/pages.js b/http/js/iznik/views/pages/pages.js index 47aba9fb0..dc1947e22 100644 --- a/http/js/iznik/views/pages/pages.js +++ b/http/js/iznik/views/pages/pages.js @@ -455,9 +455,18 @@ define([ e.preventDefault(); e.stopPropagation(); - self.notifications.allSeen().then(function() { - $('.js-notifholder .js-notifcount').css('visibility', 'hidden'); - }); + // Make the count go away. + $('.js-notifholder .js-notifcount').css('visibility', 'hidden'); + + // Fake a click on the notifications to close it. This also means that when + // we reopen it we will refetch it, and then the backgrounds on each notification + // will be correct. + if ($('.dropdown').find('.dropdown-menu').is(":hidden")){ + $('.dropdown-toggle').dropdown('toggle'); + } + + // Update the server in the background. + self.notifications.allSeen(); }); } @@ -848,6 +857,7 @@ define([ render: function() { var self = this; + var p = Iznik.resolvedPromise(self); if (!self.rendered) { diff --git a/http/js/iznik/views/pages/user/explore.js b/http/js/iznik/views/pages/user/explore.js index 7a468058a..0d868b3e0 100644 --- a/http/js/iznik/views/pages/user/explore.js +++ b/http/js/iznik/views/pages/user/explore.js @@ -456,7 +456,9 @@ define([ events: { 'click .js-join': 'join', - 'click .js-leave': 'leave' + 'click .js-leave': 'leave', + 'click .js-locgive': 'locGive', + 'click .js-locfind': 'locFind' }, join: function() { @@ -493,6 +495,24 @@ define([ }) ; }, + locGive: function() { + // This group has a default location. Set it as our location and skip the "where am I" page. + var self = this; + Storage.set('myhomegroup', self.model.get('id')); + Storage.set('myhomegrouptime', (new Date()).getTime()); + Storage.set('mylocation', JSON.stringify(self.model.get('defaultlocation'))) + Router.navigate('/give/whatisit', true); + }, + + locFind: function() { + // This group has a default location. Set it as our location and skip straight to post a wanted + var self = this; + Storage.set('myhomegroup', self.model.get('id')); + Storage.set('myhomegrouptime', (new Date()).getTime()); + Storage.set('mylocation', JSON.stringify(self.model.get('defaultlocation'))) + Router.navigate('/find/whatisit', true); + }, + filter: function(model) { var thetype = model.get('type'); diff --git a/http/js/iznik/views/pages/user/home.js b/http/js/iznik/views/pages/user/home.js index d6aead7a9..c9cd4501c 100644 --- a/http/js/iznik/views/pages/user/home.js +++ b/http/js/iznik/views/pages/user/home.js @@ -477,7 +477,7 @@ define([ // We don't have the full model, because we only fetched a summary. Get the full // version and re-render. self.expanded = true; - self.model.fetch().then(self.render); + self.model.fetch().then(_.bind(self.render, self)); // Abort the panel toggle - will happen once next render fires. return (false); @@ -545,7 +545,7 @@ define([ // We don't have the full model, because we only fetched a summary. Get the full // version and re-render. self.expanded = true; - self.model.fetch().then(self.render); + self.model.fetch().then(_.bind(self.render, self)); // Abort the panel toggle - will happen once next render fires. return(false); diff --git a/http/js/iznik/views/pages/user/pages.js b/http/js/iznik/views/pages/user/pages.js index 963f3c906..eceb80863 100644 --- a/http/js/iznik/views/pages/user/pages.js +++ b/http/js/iznik/views/pages/user/pages.js @@ -185,7 +185,6 @@ define([ } try { - console.log("Save home group", val); Storage.set('myhomegroup', val); Storage.set('myhomegrouptime', (new Date()).getTime()); } catch (e) {} @@ -263,7 +262,6 @@ define([ self.$('.js-next').hide(); self.$('.js-external').hide(); - console.log("changeGroup", first); if (first) { self.$('.js-closestgroupname').html(first.namedisplay); @@ -324,74 +322,86 @@ define([ if (groups.length > 0) { // We have a group select dropdown on the page. if (self.groupsnear) { - // We have some groups near their chosen location. - var homegroup = null; - var homegrouptime = null; - var homegroupfound = false; - var firstonhere = null; - - try { - homegroup = Storage.get('myhomegroup'); - homegrouptime = Storage.get('myhomegrouptime'); - } catch (e) {}; - - // If the first group has been founded since the home group was set up, then we want to - // use that rather than a previous preference. Otherwise new groups don't get existing - // members from their area. - if (self.groupsnear.length > 0) { - var g = self.groupsnear[0]; - if (g) { - var founded = (new Date(g.founded)).getTime(); - if (!homegrouptime || homegrouptime < founded) { - homegroup = g.id; - try { - Storage.set('myhomegroup', homegroup); - Storage.set('myhomegrouptime', (new Date()).getTime()); - } catch (e) {}; + self.listenToOnce(Iznik.Session, 'isLoggedIn', function (loggedIn) { + // We have some groups near their chosen location. + var mygroups = Iznik.Session.get('groups'); + mygroups.each(function(group) { + if (group.get('type') == 'Freegle' && + group.get('privategroup')) { + // We are a member of a private group. That should appear at the top. + groups.append(''); + groups.find('option:last').text(group.get('namedisplay')); } - } - } + }); - // Show home group if it's present. - var addedGroups = []; - groups.empty(); - _.each(self.groupsnear, function(groupnear) { - if (homegroup == groupnear.id) { - homegroupfound = true; - } + var homegroup = null; + var homegrouptime = null; + var homegroupfound = false; + var firstonhere = null; - if (!firstonhere && groupnear.onhere) { - firstonhere = groupnear.id; + try { + homegroup = Storage.get('myhomegroup'); + homegrouptime = Storage.get('myhomegrouptime'); + } catch (e) {}; + + // If the first group has been founded since the home group was set up, then we want to + // use that rather than a previous preference. Otherwise new groups don't get existing + // members from their area. + if (self.groupsnear.length > 0) { + var g = self.groupsnear[0]; + if (g) { + var founded = (new Date(g.founded)).getTime(); + if (!homegrouptime || homegrouptime < founded) { + homegroup = g.id; + try { + Storage.set('myhomegroup', homegroup); + Storage.set('myhomegrouptime', (new Date()).getTime()); + } catch (e) {}; + } + } } - groups.append(''); - groups.find('option:last').text(groupnear.namedisplay); - addedGroups.push(groupnear.id); - }); - // Add remaining Freegle groups we're a member of - maybe we have a reason to post on them. - self.listenToOnce(Iznik.Session, 'isLoggedIn', function (loggedIn) { + // Show home group if it's present. + var addedGroups = []; + groups.empty(); + _.each(self.groupsnear, function(groupnear) { + if (homegroup == groupnear.id) { + homegroupfound = true; + } + + if (!firstonhere && groupnear.onhere) { + firstonhere = groupnear.id; + } + groups.append(''); + groups.find('option:last').text(groupnear.namedisplay); + addedGroups.push(groupnear.id); + }); + + // Add remaining Freegle groups we're a member of - maybe we have a reason to post on them. if (loggedIn) { var mygroups = Iznik.Session.get('groups'); mygroups.each(function(group) { - if (group.get('type') == 'Freegle' && addedGroups.indexOf(group.get('id'))) { + if (group.get('type') == 'Freegle' && + !group.get('privategroup') && + addedGroups.indexOf(group.get('id'))) { groups.append(''); groups.find('option:last').text(group.get('namedisplay')); } }); } + + if (homegroupfound) { + groups.val(homegroup); + } + + self.changeGroup(); + groups.on('change', _.bind(self.changeGroup, self)); }); Iznik.Session.testLoggedIn([ 'me', 'groups' ]); - - if (homegroupfound) { - groups.val(homegroup); - } - - self.changeGroup(); - groups.on('change', _.bind(self.changeGroup, self)); } } else { // We don't have a groups drop down. Hide that section, but still check for whether we need to diff --git a/http/js/iznik/views/pages/user/post.js b/http/js/iznik/views/pages/user/post.js index 392dbe0a9..8d4237862 100644 --- a/http/js/iznik/views/pages/user/post.js +++ b/http/js/iznik/views/pages/user/post.js @@ -117,6 +117,7 @@ define([ clearDraft: function() { var self = this; Storage.remove('draft'); + Storage.remove('draftrepost'); self.render(); }, @@ -200,7 +201,7 @@ define([ }, save: function () { - // Save the current message as a draft. + // Save the current message as a draft. It may already be one. var self = this; var item = this.getItem(); @@ -224,6 +225,7 @@ define([ }); var data = { + id: Storage.get('draft') ? Storage.get('draft') : null, collection: 'Draft', locationid: locationid, messagetype: self.msgType, @@ -459,7 +461,10 @@ define([ // clear out our local storage but still have submitted the message. In that case // we don't want to use it. if (self.msgType == msg.get('type') && msg.get('isdraft')) { - self.$('.js-olddraft').fadeIn('slow'); + if (id !== Storage.get('draftrepost')) { + // And we're not reposting it. + self.$('.js-olddraft').fadeIn('slow'); + } // Parse out item from subject. var matches = /(.*?)\:([^)].*)\((.*)\)/.exec(msg.get('subject')); @@ -543,6 +548,7 @@ define([ // The draft has now been sent. Storage.set('lastpost', id); Storage.remove('draft'); + Storage.remove('draftrepost'); } catch (e) {} if (ret.newuser) { diff --git a/http/js/iznik/views/pages/user/stories.js b/http/js/iznik/views/pages/user/stories.js index b0ab2c277..60846bbf3 100644 --- a/http/js/iznik/views/pages/user/stories.js +++ b/http/js/iznik/views/pages/user/stories.js @@ -51,7 +51,8 @@ define([ self.collection.fetch({ data: { - reviewnewsletter: self.options.reviewnewsletter + reviewnewsletter: self.options.reviewnewsletter, + groupid: self.options.groupid } }); }); diff --git a/http/js/iznik/views/user/message.js b/http/js/iznik/views/user/message.js index d1345b2ce..fdd06d1d0 100644 --- a/http/js/iznik/views/user/message.js +++ b/http/js/iznik/views/user/message.js @@ -9,6 +9,30 @@ define([ 'iznik/views/infinite', 'iznik/views/user/schedule' ], function($, _, Backbone, Iznik, moment, Clipboard) { + // jQuery equivalent to Prototype's positionedOffset + (function($) { + $.fn.positionedOffset = function() { + // get viewport offset for our main element + var coords = $(this).offset(); + + // get parent and parent viewport offset + var parent = $(this).offsetParent(); + var parentCoords = $(parent).offset(); + + // do some math to calculate relative offset + var diff_left = coords.left - parentCoords.left; + var diff_top = coords.top - parentCoords.top; + + // return values + var offsetCoords = { + left: diff_left, + top: diff_top + } + + return offsetCoords; + }; + })($); + Iznik.Views.User.Message = Iznik.View.extend({ className: "marginbotsm botspace", @@ -145,6 +169,7 @@ define([ }, carettoggle: function() { + var self = this; if (this.expanded) { this.$('.js-snippet').slideDown(); } else { @@ -152,6 +177,24 @@ define([ } this.expanded = !this.expanded; this.caretshow(); + + if (this.expanded) { + if (Iznik.isShort()) { + // On mobile, the expand may happen below the bottom of the screen, in which case we're not + // really aware that anything has happened. Scroll so that the end of this message is + // at the bottom of the screen. + self.$el.one('shown.bs.collapse', function() { + var li = self.$el.closest('li').get(0); + + if (li && li.nextSibling) { + li.scrollIntoView({ + behaviour: 'smooth', + block: 'end' + }); + } + }); + } + } }, fop: function() { diff --git a/http/template/user/explore/single.html b/http/template/user/explore/single.html index 304c86cf1..d3d233c20 100644 --- a/http/template/user/explore/single.html +++ b/http/template/user/explore/single.html @@ -53,7 +53,7 @@
Offer stuff you don't need, or find stuff you want.
+ PayPal are doubling donations today. So if you're able to donate to us, it'll go twice + as far. In any case, thanks for freegling! +
+ ++ PayPal are doubling donations today. So if you're able to donate to us, it'll go twice + as far. In any case, thanks for freegling! +
+ ++ PayPal are doubling donations today. So if you're able to donate to us, it'll go twice + as far. In any case, thanks for freegling! +
+ +Or by cheque to Freegle, 150 Whitecross, Abingdon, Oxon, OX13 6BT.
+Monthly donations really help.
+Or by cheque (to Freegle, 150 Whitecross, Abingdon, Oxon, OX13 6BT) or bank transfer (sort code 60-83-01, account number 20339094). For these please complete a Gift Aid Declaration here. Thanks!
Monthly donations really help.
Or by cheque (to Freegle, 150 Whitecross, Abingdon, Oxon, OX13 6BT) or bank transfer (sort code 60-83-01, account number 20339094). For these please complete a Gift Aid Declaration here. Thanks!
This will contribute to the general fund for the ongoing support of Freegle. If we raise more than the target, we'll use it to support other communities.