diaspora/app/assets/javascripts/app/views/aspect_membership_view.js
2017-08-16 23:23:34 +02:00

168 lines
5.5 KiB
JavaScript

// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
/**
* this view lets the user (de-)select aspect memberships in the context
* of another users profile or the contact page.
*
* updates to the list of aspects are immediately propagated to the server, and
* the results are dislpayed as flash messages.
*/
app.views.AspectMembership = app.views.Base.extend({
templateName: "aspect_membership_dropdown",
className: "btn-group aspect_dropdown aspect_membership_dropdown",
subviews: {
".newAspectContainer": "aspectCreateView"
},
events: {
"click ul.aspect_membership.dropdown-menu > li.aspect_selector"
: "_clickHandler",
"keypress ul.aspect_membership.dropdown-menu > li.aspect_selector"
: "_clickHandler"
},
initialize: function(opts) {
_.extend(this, opts);
this.list_item = null;
this.dropdown = null;
},
presenter: function() {
var aspectMembershipsLength = this.person.contact ? this.person.contact.aspectMemberships.length : 0;
return _.extend(this.defaultPresenter(), {
aspects: this.aspectsPresenter(),
dropdownMayCreateNewAspect: this.dropdownMayCreateNewAspect
}, aspectMembershipsLength === 0 ? {
extraButtonClass: "btn-default",
noAspectIsSelected: true
} : { // this.contact.aspectMemberships.length > 0
aspectMembershipsLength: aspectMembershipsLength,
allAspectsAreSelected: aspectMembershipsLength === app.aspects.length,
onlyOneAspectIsSelected: aspectMembershipsLength === 1,
firstMembershipName: this.person.contact.aspectMemberships.at(0).get("aspect").name,
extraButtonClass: "btn-success"
});
},
aspectsPresenter: function() {
return _.map(app.aspects.models, function(aspect) {
return _.extend(
this.person.contact ?
{membership: this.person.contact.aspectMemberships.findByAspectId(aspect.attributes.id)} : {},
aspect.attributes // id, name
);
}, this);
},
aspectCreateView: function() {
return new app.views.AspectCreate({
person: this.person
});
},
// decide what to do when clicked
// -> addMembership
// -> removeMembership
_clickHandler: function(evt) {
this.list_item = $(evt.target).closest('li.aspect_selector');
this.dropdown = this.list_item.parent();
this.list_item.addClass('loading');
if (this.list_item.is(".selected")) {
this.removeMembership(this.list_item.data("membership_id"));
} else {
this.addMembership(this.list_item.data("aspect_id"));
}
return false; // stop the event
},
// return the (short) name of the person associated with the current dropdown
_name: function() {
return this.person.name || this.person.get("name");
},
_personId: function() {
return this.person.id;
},
// create a membership for the given person in the given aspect
addMembership: function(aspectId) {
if (!this.person.contact) {
this.person.contact = new app.models.Contact();
}
this.listenToOnce(this.person.contact.aspectMemberships, "sync", this._successSaveCb);
this.listenToOnce(this.person.contact.aspectMemberships, "error", this._displayError);
return this.person.contact.aspectMemberships.create({"aspect_id": aspectId, "person_id": this._personId()});
},
_successSaveCb: function(aspectMembership) {
var aspectId = aspectMembership.get("aspect_id"),
startSharing = false;
// the user didn't have this person in any aspects before, congratulate them
// on their newly found friendship ;)
if( this.dropdown.find("li.selected").length === 0 ) {
var msg = Diaspora.I18n.t("aspect_dropdown.started_sharing_with", { "name": this._name() });
startSharing = true;
app.flashMessages.success(msg);
}
app.events.trigger("aspect_membership:create", {
membership: {aspectId: aspectId, personId: this._personId()},
startSharing: startSharing
});
this.render();
app.events.trigger("aspect_membership:update");
},
// show an error flash msg
_displayError: function(model, resp) {
this._done();
this.dropdown.closest(".aspect_membership_dropdown").removeClass("open"); // close the dropdown
app.flashMessages.handleAjaxError(resp);
},
// remove the membership with the given id
removeMembership: function(membershipId) {
var membership = this.person.contact.aspectMemberships.get(membershipId);
this.listenToOnce(membership, "sync", this._successDestroyCb);
this.listenToOnce(membership, "error", this._displayError);
return membership.destroy({wait: true});
},
_successDestroyCb: function(aspectMembership) {
var membershipId = aspectMembership.get("id"),
aspectId = aspectMembership.get("aspect").id,
stopSharing = false;
this.render();
// we just removed the last aspect, inform the user with a flash message
// that they are no longer sharing with that person
if (this.$el.find("li.selected").length === 0) {
var msg = Diaspora.I18n.t("aspect_dropdown.stopped_sharing_with", { "name": this._name() });
stopSharing = true;
app.flashMessages.success(msg);
}
app.events.trigger("aspect_membership:destroy", {
membership: {aspectId: aspectId, personId: this._personId()},
stopSharing: stopSharing
});
app.events.trigger("aspect_membership:update");
},
// cleanup tasks after aspect selection
_done: function() {
if( this.list_item ) {
this.list_item.removeClass('loading');
}
},
});
// @license-end