/** * Copyright (c) 2008-2012 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.osedu.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sakaiproject.profile2.tool.pages.panels; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.wicket.AttributeModifier; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigator; import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.link.ExternalLink; import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.link.PopupSettings; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.ResourceModel; import org.apache.wicket.model.StringResourceModel; import org.apache.wicket.spring.injection.annot.SpringBean; import org.sakaiproject.profile2.logic.ProfileConnectionsLogic; import org.sakaiproject.profile2.logic.ProfilePrivacyLogic; import org.sakaiproject.profile2.logic.SakaiProxy; import org.sakaiproject.profile2.model.Person; import org.sakaiproject.profile2.model.ProfilePreferences; import org.sakaiproject.profile2.model.ProfilePrivacy; import org.sakaiproject.profile2.tool.components.ProfileImageRenderer; import org.sakaiproject.profile2.tool.components.ProfileStatusRenderer; import org.sakaiproject.profile2.tool.dataproviders.ConfirmedFriendsDataProvider; import org.sakaiproject.profile2.tool.models.FriendAction; import org.sakaiproject.profile2.tool.pages.MySearch; import org.sakaiproject.profile2.tool.pages.ViewFriends; import org.sakaiproject.profile2.tool.pages.ViewProfile; import org.sakaiproject.profile2.tool.pages.windows.RemoveFriend; import org.sakaiproject.profile2.types.PrivacyType; import org.sakaiproject.profile2.util.ProfileConstants; import org.sakaiproject.profile2.util.ProfileUtils; public class ConfirmedFriends extends Panel { private static final long serialVersionUID = 1L; private static final Logger log = Logger.getLogger(ConfirmedFriends.class); @SpringBean(name="org.sakaiproject.profile2.logic.SakaiProxy") private SakaiProxy sakaiProxy; @SpringBean(name="org.sakaiproject.profile2.logic.ProfileConnectionsLogic") protected ProfileConnectionsLogic connectionsLogic; @SpringBean(name="org.sakaiproject.profile2.logic.ProfilePrivacyLogic") protected ProfilePrivacyLogic privacyLogic; private Integer numConfirmedFriends = 0; private boolean ownList = false; public ConfirmedFriends(final String id, final String userUuid) { super(id); log.debug("ConfirmedFriends()"); //setup model to store the actions in the modal windows final FriendAction friendActionModel = new FriendAction(); //get info for user viewing this page (will be the same if user is viewing own list, different if viewing someone else's) final String currentUserUuid = sakaiProxy.getCurrentUserId(); //User currentUser = sakaiProxy.getUserQuietly(currentUserUuid); //final String currentUserType = currentUser.getType(); //to be used for checking if connection between users is allowed, when this is added //if viewing own friends, you can manage them. if(userUuid.equals(currentUserUuid)) { ownList = true; } //get our list of confirmed friends as an IDataProvider ConfirmedFriendsDataProvider provider = new ConfirmedFriendsDataProvider(userUuid); //init number of friends numConfirmedFriends = provider.size(); //model so we can update the number of friends IModel<Integer> numConfirmedFriendsModel = new Model<Integer>() { private static final long serialVersionUID = 1L; public Integer getObject() { return numConfirmedFriends; } }; //heading final WebMarkupContainer confirmedFriendsHeading = new WebMarkupContainer("confirmedFriendsHeading"); Label confirmedFriendsLabel = new Label("confirmedFriendsLabel"); //if viewing own list, "my friends", else, "their name's friends" if(ownList) { confirmedFriendsLabel.setDefaultModel(new ResourceModel("heading.friends.my")); } else { String displayName = sakaiProxy.getUserDisplayName(userUuid); confirmedFriendsLabel.setDefaultModel(new StringResourceModel("heading.friends.view", null, new Object[]{ displayName } )); } confirmedFriendsHeading.add(confirmedFriendsLabel); confirmedFriendsHeading.add(new Label("confirmedFriendsNumber", numConfirmedFriendsModel)); confirmedFriendsHeading.setOutputMarkupId(true); add(confirmedFriendsHeading); // actions Form<Void> confirmedFriendsButtonForm = new Form<Void>("confirmedFriendsButtonForm"); add(confirmedFriendsButtonForm); //create worksite panel final CreateWorksitePanel createWorksitePanel = new CreateWorksitePanel("createWorksitePanel", connectionsLogic.getConnectionsForUser(userUuid)); //create placeholder and set invisible initially createWorksitePanel.setOutputMarkupPlaceholderTag(true); createWorksitePanel.setVisible(false); confirmedFriendsButtonForm.add(createWorksitePanel); final AjaxButton createWorksiteButton = new AjaxButton("createWorksiteButton", confirmedFriendsButtonForm) { private static final long serialVersionUID = 1L; @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { createWorksitePanel.setVisible(true); target.addComponent(createWorksitePanel); target.appendJavascript("fixWindowVertical();"); } }; createWorksiteButton.setModel(new ResourceModel("link.worksite.create")); createWorksiteButton.add(new AttributeModifier("title", true, new ResourceModel("link.title.worksite.create"))); createWorksiteButton.setVisible(sakaiProxy.isUserAllowedAddSite(userUuid)); confirmedFriendsButtonForm.add(createWorksiteButton); //search for connections AjaxButton searchConnectionsButton = new AjaxButton("searchConnectionsButton", confirmedFriendsButtonForm) { private static final long serialVersionUID = 1L; @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { setResponsePage(new MySearch()); } }; searchConnectionsButton.setModel(new ResourceModel("link.my.friends.search")); confirmedFriendsButtonForm.add(searchConnectionsButton); //container which wraps list final WebMarkupContainer confirmedFriendsContainer = new WebMarkupContainer("confirmedFriendsContainer"); confirmedFriendsContainer.setOutputMarkupId(true); //connection window final ModalWindow connectionWindow = new ModalWindow("connectionWindow"); //results DataView<Person> confirmedFriendsDataView = new DataView<Person>("connections", provider) { private static final long serialVersionUID = 1L; protected void populateItem(final Item<Person> item) { Person person = (Person)item.getDefaultModelObject(); final String personUuid = person.getUuid(); //setup values String displayName = person.getDisplayName(); boolean friend; //get friend status if(ownList) { friend = true; //viewing own page of conenctions, must be friend! } else { friend = connectionsLogic.isUserXFriendOfUserY(userUuid, personUuid); //other person viewing, check if they are friends } //get other objects ProfilePrivacy privacy = person.getPrivacy(); ProfilePreferences prefs = person.getPreferences(); //image wrapper, links to profile Link<String> friendItem = new Link<String>("connectionPhotoWrap", new Model<String>(personUuid)) { private static final long serialVersionUID = 1L; public void onClick() { setResponsePage(new ViewProfile(getModelObject())); } }; //image friendItem.add(new ProfileImageRenderer("connectionPhoto", personUuid, prefs, privacy, ProfileConstants.PROFILE_IMAGE_THUMBNAIL, true)); item.add(friendItem); //name and link to profile Link<String> profileLink = new Link<String>("connectionLink", new Model<String>(personUuid)) { private static final long serialVersionUID = 1L; public void onClick() { setResponsePage(new ViewProfile(getModelObject())); } }; profileLink.add(new Label("connectionName", displayName)); item.add(profileLink); //status component ProfileStatusRenderer status = new ProfileStatusRenderer("connectionStatus", person, "connection-status-msg", "connection-status-date"); status.setOutputMarkupId(true); item.add(status); /* ACTIONS */ WebMarkupContainer c1 = new WebMarkupContainer("removeConnectionContainer"); c1.setOutputMarkupId(true); //REMOVE FRIEND LINK AND WINDOW final AjaxLink<String> removeConnectionLink = new AjaxLink<String>("removeConnectionLink", new Model<String>(personUuid)) { private static final long serialVersionUID = 1L; public void onClick(AjaxRequestTarget target) { //get this item, and set content for modalwindow String friendUuid = getModelObject(); connectionWindow.setContent(new RemoveFriend(connectionWindow.getContentId(), connectionWindow, friendActionModel, userUuid, friendUuid)); //modalwindow handler connectionWindow.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() { private static final long serialVersionUID = 1L; public void onClose(AjaxRequestTarget target){ if(friendActionModel.isRemoved()) { //decrement number of friends numConfirmedFriends--; //remove friend item from display target.appendJavascript("$('#" + item.getMarkupId() + "').slideUp();"); //update label target.addComponent(confirmedFriendsHeading); //if none left, hide whole thing if(numConfirmedFriends==0) { target.appendJavascript("$('#" + confirmedFriendsContainer.getMarkupId() + "').fadeOut();"); } } } }); connectionWindow.show(target); target.appendJavascript("fixWindowVertical();"); } }; //ContextImage removeConnectionIcon = new ContextImage("removeConnectionIcon",new Model<String>(ProfileConstants.DELETE_IMG)); removeConnectionLink.add(new AttributeModifier("alt", true, new StringResourceModel("accessibility.connection.remove", null, new Object[]{ displayName } ))); //removeConnectionLink.add(removeConnectionIcon); removeConnectionLink.add(new AttributeModifier("title", true,new ResourceModel("link.title.removefriend"))); removeConnectionLink.add(new Label("removeConnectionLabel", new ResourceModel("button.friend.remove")).setOutputMarkupId(true)); c1.add(removeConnectionLink); item.add(c1); //can only delete if own connections if(!ownList) { removeConnectionLink.setEnabled(false); removeConnectionLink.setVisible(false); } WebMarkupContainer c2 = new WebMarkupContainer("viewFriendsContainer"); c2.setOutputMarkupId(true); final AjaxLink<String> viewFriendsLink = new AjaxLink<String>("viewFriendsLink") { private static final long serialVersionUID = 1L; public void onClick(AjaxRequestTarget target) { // always ViewFriends because a user isn't connected to himself setResponsePage(new ViewFriends(personUuid)); } }; final Label viewFriendsLabel = new Label("viewFriendsLabel", new ResourceModel("link.view.friends")); viewFriendsLink.add(viewFriendsLabel); //hide if not allowed if(!privacyLogic.isActionAllowed(userUuid, currentUserUuid, PrivacyType.PRIVACY_OPTION_MYFRIENDS)) { viewFriendsLink.setEnabled(false); c2.setVisible(false); } viewFriendsLink.setOutputMarkupId(true); c2.add(viewFriendsLink); item.add(c2); WebMarkupContainer c3 = new WebMarkupContainer("emailContainer"); c3.setOutputMarkupId(true); ExternalLink emailLink = new ExternalLink("emailLink", "mailto:" + person.getProfile().getEmail(), new ResourceModel("profile.email").getObject()); c3.add(emailLink); if (StringUtils.isBlank(person.getProfile().getEmail()) || false == privacyLogic.isActionAllowed( person.getUuid(), currentUserUuid, PrivacyType.PRIVACY_OPTION_CONTACTINFO)) { c3.setVisible(false); } item.add(c3); WebMarkupContainer c4 = new WebMarkupContainer("websiteContainer"); c4.setOutputMarkupId(true); // TODO home page, university profile URL or academic/research URL (see PRFL-35) ExternalLink websiteLink = new ExternalLink("websiteLink", person.getProfile() .getHomepage(), new ResourceModel( "profile.homepage").getObject()).setPopupSettings(new PopupSettings()); c4.add(websiteLink); if (StringUtils.isBlank(person.getProfile().getHomepage()) || false == privacyLogic.isActionAllowed( person.getUuid(), currentUserUuid, PrivacyType.PRIVACY_OPTION_CONTACTINFO)) { c4.setVisible(false); } item.add(c4); // basic info can be set to 'only me' so still need to check if (true == privacyLogic.isActionAllowed( person.getUuid(), currentUserUuid, PrivacyType.PRIVACY_OPTION_BASICINFO)) { item.add(new Label("connectionSummary", StringUtils.abbreviate(ProfileUtils.stripHtml( person.getProfile().getPersonalSummary()), 200))); } else { item.add(new Label("connectionSummary", "")); } item.setOutputMarkupId(true); } }; confirmedFriendsDataView.setOutputMarkupId(true); confirmedFriendsDataView.setItemsPerPage(ProfileConstants.MAX_CONNECTIONS_PER_PAGE); confirmedFriendsContainer.add(confirmedFriendsDataView); //add results container add(confirmedFriendsContainer); //add window add(connectionWindow); //add pager AjaxPagingNavigator pager = new AjaxPagingNavigator("navigator", confirmedFriendsDataView); add(pager); //initially, if no friends, hide container and pager if(numConfirmedFriends == 0) { confirmedFriendsContainer.setVisible(false); pager.setVisible(false); } //also, if num less than num required for pager, hide it if(numConfirmedFriends <= ProfileConstants.MAX_CONNECTIONS_PER_PAGE) { pager.setVisible(false); } } }