diff --git a/src/main/java/org/olat/course/nodes/members/MembersCourseNodeRunController.java b/src/main/java/org/olat/course/nodes/members/MembersCourseNodeRunController.java index d7a2cf12fc86faef7f3e33427fb42ec89e2a2ca1..301484a25fa1fe8a5767b04f587f127adc7625fd 100644 --- a/src/main/java/org/olat/course/nodes/members/MembersCourseNodeRunController.java +++ b/src/main/java/org/olat/course/nodes/members/MembersCourseNodeRunController.java @@ -29,9 +29,11 @@ import static org.olat.course.nodes.members.MembersCourseNodeEditController.EMAI import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Set; import org.olat.NewControllerFactory; @@ -58,9 +60,15 @@ import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.util.StringHelper; import org.olat.core.util.mail.ContactList; import org.olat.core.util.mail.ContactMessage; +import org.olat.core.util.session.UserSessionManager; import org.olat.course.groupsandrights.CourseGroupManager; import org.olat.course.run.environment.CourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironment; +import org.olat.instantMessaging.InstantMessagingModule; +import org.olat.instantMessaging.InstantMessagingService; +import org.olat.instantMessaging.OpenInstantMessageEvent; +import org.olat.instantMessaging.model.Buddy; +import org.olat.instantMessaging.model.Presence; import org.olat.modules.ModuleConfiguration; import org.olat.modules.co.ContactFormController; import org.olat.repository.RepositoryEntry; @@ -89,27 +97,34 @@ public class MembersCourseNodeRunController extends FormBasicController { private FormLink ownersEmailLink; private FormLink coachesEmailLink; private FormLink participantsEmailLink; - private List<FormLink> memberLinks = new ArrayList<FormLink>(); - private List<FormLink> emailLinks = new ArrayList<FormLink>(); - private List<FormLink> ownerLinks; - private List<FormLink> coachesLinks; - private List<FormLink> participantsLinks; + private List<Member> ownerList; + private List<Member> coachList; + private List<Member> participantList; private final boolean canEmail; private final boolean showOwners; private final boolean showCoaches; private final boolean showParticipants; + private final boolean chatEnabled; private ContactFormController emailController; private CloseableModalController cmc; + private int count = 0; + @Autowired private UserManager userManager; @Autowired private BaseSecurity securityManager; @Autowired private RepositoryService repositoryService; + @Autowired + private InstantMessagingModule imModule; + @Autowired + private InstantMessagingService imService; + @Autowired + private UserSessionManager sessionManager; public MembersCourseNodeRunController(UserRequest ureq, WindowControl wControl, UserCourseEnvironment userCourseEnv, ModuleConfiguration config) { super(ureq, wControl, "members"); @@ -121,6 +136,7 @@ public class MembersCourseNodeRunController extends FormBasicController { showOwners = config.getBooleanSafe(CONFIG_KEY_SHOWOWNER); showCoaches = config.getBooleanSafe(CONFIG_KEY_SHOWCOACHES); showParticipants = config.getBooleanSafe(CONFIG_KEY_SHOWPARTICIPANTS); + chatEnabled = imModule.isEnabled() && imModule.isPrivateEnabled(); String emailFct = config.getStringValue(CONFIG_KEY_EMAIL_FUNCTION, EMAIL_FUNCTION_COACH_ADMIN); canEmail = EMAIL_FUNCTION_ALL.equals(emailFct) || userCourseEnv.isAdmin() || userCourseEnv.isCoach(); @@ -170,18 +186,18 @@ public class MembersCourseNodeRunController extends FormBasicController { } Set<Long> duplicateCatcher = new HashSet<Long>(); - ownerLinks = initFormMemberList("owners", owners, duplicateCatcher, formLayout, canEmail); - coachesLinks = initFormMemberList("coaches", coaches, duplicateCatcher, formLayout, canEmail); - participantsLinks = initFormMemberList("participants", participants, duplicateCatcher, formLayout, canEmail); + ownerList = initFormMemberList("owners", owners, duplicateCatcher, formLayout, canEmail); + coachList = initFormMemberList("coaches", coaches, duplicateCatcher, formLayout, canEmail); + participantList = initFormMemberList("participants", participants, duplicateCatcher, formLayout, canEmail); if(formLayout instanceof FormLayoutContainer) { FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout; layoutCont.contextPut("showOwners", showOwners); - layoutCont.contextPut("hasOwners", new Boolean(!ownerLinks.isEmpty())); + layoutCont.contextPut("hasOwners", new Boolean(!ownerList.isEmpty())); layoutCont.contextPut("showCoaches", showCoaches); - layoutCont.contextPut("hasCoaches", new Boolean(!coachesLinks.isEmpty())); + layoutCont.contextPut("hasCoaches", new Boolean(!coachList.isEmpty())); layoutCont.contextPut("showParticipants", showParticipants); - layoutCont.contextPut("hasParticipants", new Boolean(!participantsLinks.isEmpty())); + layoutCont.contextPut("hasParticipants", new Boolean(!participantList.isEmpty())); } } @@ -190,47 +206,100 @@ public class MembersCourseNodeRunController extends FormBasicController { return repositoryService.getMembers(courseRepositoryEntry, GroupRoles.owner.name()); } - private List<FormLink> initFormMemberList(String name, List<Identity> ids, Set<Long> duplicateCatcher, FormItemContainer formLayout, boolean withEmail) { + private List<Member> initFormMemberList(String name, List<Identity> ids, Set<Long> duplicateCatcher, FormItemContainer formLayout, boolean withEmail) { String page = velocity_root + "/memberList.html"; FormLayoutContainer container = FormLayoutContainer.createCustomFormLayout(name, getTranslator(), page); formLayout.add(name, container); container.setRootForm(mainForm); - List<FormLink> links = createMemberLinks(ids, duplicateCatcher, container, withEmail); - container.contextPut("memberLinks", links); + List<Member> members = createMemberLinks(ids, duplicateCatcher, container, withEmail); + container.contextPut("members", members); container.contextPut("avatarBaseURL", avatarBaseURL); - return links; + return members; } - protected List<FormLink> createMemberLinks(List<Identity> identities, Set<Long> duplicateCatcher, FormLayoutContainer formLayout, boolean withEmail) { - List<FormLink> idLinks = new ArrayList<FormLink>(); + protected List<Member> createMemberLinks(List<Identity> identities, Set<Long> duplicateCatcher, FormLayoutContainer formLayout, boolean withEmail) { + List<Member> members = new ArrayList<>(); for(Identity identity:identities) { if(duplicateCatcher.contains(identity.getKey())) continue; Member member = createMember(identity); + members.add(member); + + String guiId = Integer.toString(++count); String fullname = StringHelper.escapeHtml(member.getFullName()); - FormLink idLink = uifactory.addFormLink("id_" + identity.getKey(), fullname, null, formLayout, Link.NONTRANSLATED); + + FormLink idLink = uifactory.addFormLink("id_".concat(guiId), "id", fullname, null, formLayout, Link.NONTRANSLATED); + idLink.setUserObject(member); - idLinks.add(idLink); formLayout.add(idLink.getComponent().getComponentName(), idLink); - memberLinks.add(idLink); + member.setIdLink(idLink); if(withEmail) { - FormLink emailLink = uifactory.addFormLink("mail_" + identity.getKey(), "", null, formLayout, Link.NONTRANSLATED); + FormLink emailLink = uifactory.addFormLink("mail_".concat(guiId), "mail", "", null, formLayout, Link.NONTRANSLATED); emailLink.setUserObject(member); emailLink.setIconLeftCSS("o_icon o_icon_mail o_icon-lg"); emailLink.setElementCssClass("o_mail"); formLayout.add(emailLink.getComponent().getComponentName(), emailLink); - emailLinks.add(emailLink); member.setEmailLink(emailLink); } + if(chatEnabled) { + FormLink chatLink = uifactory.addFormLink("chat_".concat(guiId), "chat", "", null, formLayout, Link.NONTRANSLATED); + chatLink.setUserObject(member); + chatLink.setElementCssClass("o_chat"); + formLayout.add(chatLink.getComponent().getComponentName(), chatLink); + member.setChatLink(chatLink); + } + duplicateCatcher.add(identity.getKey()); } - return idLinks; + + if(chatEnabled) { + Long me = getIdentity().getKey(); + if(imModule.isOnlineStatusEnabled()) { + Map<Long,Member> loadStatus = new HashMap<>(); + + for(Member member:members) { + if(member.getKey().equals(me)) { + member.getChatLink().setVisible(false); + } else if(sessionManager.isOnline(member.getKey())) { + loadStatus.put(member.getKey(), member); + } else { + member.getChatLink().setIconLeftCSS("o_icon o_icon_status_unavailable"); + } + } + + if(loadStatus.size() > 0) { + List<Long> statusToLoadList = new ArrayList<>(loadStatus.keySet()); + Map<Long,String> statusMap = imService.getBuddyStatus(statusToLoadList); + for(Long toLoad:statusToLoadList) { + String status = statusMap.get(toLoad); + Member member = loadStatus.get(toLoad); + if(status == null || Presence.available.name().equals(status)) { + member.getChatLink().setIconLeftCSS("o_icon o_icon_status_available"); + } else if(Presence.dnd.name().equals(status)) { + member.getChatLink().setIconLeftCSS("o_icon o_icon_status_dnd"); + } else { + member.getChatLink().setIconLeftCSS("o_icon o_icon_status_unavailable"); + } + } + } + } else { + for(Member member:members) { + if(member.getKey().equals(me)) { + member.getChatLink().setVisible(false); + } else { + member.getChatLink().setIconLeftCSS("o_icon o_icon_status_chat"); + } + } + } + } + + return members; } - protected Member createMember(Identity identity) { + private Member createMember(Identity identity) { User user = identity.getUser(); String firstname = user.getProperty(UserConstants.FIRSTNAME, null); String lastname = user.getProperty(UserConstants.LASTNAME, null); @@ -251,7 +320,7 @@ public class MembersCourseNodeRunController extends FormBasicController { @Override protected void doDispose() { - memberLinks = emailLinks = ownerLinks = coachesLinks = participantsLinks = null; + // } @Override @@ -261,44 +330,46 @@ public class MembersCourseNodeRunController extends FormBasicController { @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { - if(memberLinks.contains(source)) { - FormLink memberLink = (FormLink)source; - Member member = (Member)memberLink.getUserObject(); - openHomePage(member, ureq); - } else if (emailLinks.contains(source)) { - FormLink emailLink = (FormLink)source; - Member member = (Member)emailLink.getUserObject(); - ContactList memberList = new ContactList(translate("members.to", new String[]{member.getFullName(), courseEnv.getCourseTitle()})); - Identity identity = securityManager.loadIdentityByKey(member.getKey()); - memberList.add(identity); - sendEmailToMember(memberList, ureq); - } else if (source == ownersEmailLink) { - ContactList ownerList = new ContactList(translate("owners.to", new String[]{ courseEnv.getCourseTitle() })); - ownerList.addAllIdentites(getOwners()); - sendEmailToMember(ownerList, ureq); + if (source == ownersEmailLink) { + ContactList owners = new ContactList(translate("owners.to", new String[]{ courseEnv.getCourseTitle() })); + owners.addAllIdentites(getOwners()); + doSendEmailToMember(owners, ureq); } else if (source == coachesEmailLink) { - ContactList coachList = new ContactList(translate("coaches.to", new String[]{ courseEnv.getCourseTitle() })); + ContactList coaches = new ContactList(translate("coaches.to", new String[]{ courseEnv.getCourseTitle() })); Set<Long> sendToWhatYouSee = new HashSet<>(); - for(FormLink coachLink:coachesLinks) { - Member member = (Member)coachLink.getUserObject(); - sendToWhatYouSee.add(member.getKey()); + for(Member coach:coachList) { + sendToWhatYouSee.add(coach.getKey()); } CourseGroupManager cgm = courseEnv.getCourseGroupManager(); - avoidInvisibleMember(cgm.getCoachesFromBusinessGroups(), coachList, sendToWhatYouSee); - avoidInvisibleMember(cgm.getCoaches(), coachList, sendToWhatYouSee); - sendEmailToMember(coachList, ureq); + avoidInvisibleMember(cgm.getCoachesFromBusinessGroups(), coaches, sendToWhatYouSee); + avoidInvisibleMember(cgm.getCoaches(), coaches, sendToWhatYouSee); + doSendEmailToMember(coaches, ureq); } else if (source == participantsEmailLink) { - ContactList participantList = new ContactList(translate("participants.to", new String[]{ courseEnv.getCourseTitle() })); + ContactList participants = new ContactList(translate("participants.to", new String[]{ courseEnv.getCourseTitle() })); Set<Long> sendToWhatYouSee = new HashSet<>(); - for(FormLink participantLink:participantsLinks) { - Member member = (Member)participantLink.getUserObject(); - sendToWhatYouSee.add(member.getKey()); + for(Member participant:participantList) { + sendToWhatYouSee.add(participant.getKey()); } CourseGroupManager cgm = courseEnv.getCourseGroupManager(); - avoidInvisibleMember(cgm.getParticipantsFromBusinessGroups(), participantList, sendToWhatYouSee); - avoidInvisibleMember(cgm.getParticipants(), participantList, sendToWhatYouSee); - sendEmailToMember(participantList, ureq); + avoidInvisibleMember(cgm.getParticipantsFromBusinessGroups(), participants, sendToWhatYouSee); + avoidInvisibleMember(cgm.getParticipants(), participants, sendToWhatYouSee); + doSendEmailToMember(participants, ureq); + } else if(source instanceof FormLink) { + FormLink link = (FormLink)source; + Object uobject = link.getUserObject(); + if(uobject instanceof Member) { + Member member = (Member)uobject; + String cmd = link.getCmd(); + if("id".equals(cmd)) { + doOpenHomePage(member, ureq); + } else if("mail".equals(cmd)) { + doSendEmailToMember(member, ureq); + } else if("chat".equals(cmd)) { + doOpenChat(member, ureq); + } + } } + super.formInnerEvent(ureq, source, event); } private void avoidInvisibleMember(List<Identity> members, ContactList contactList, Set<Long> sendToWhatYouSee) { @@ -325,8 +396,21 @@ public class MembersCourseNodeRunController extends FormBasicController { } super.event(ureq, source, event); } + + protected void doOpenChat(Member member, UserRequest ureq) { + Buddy buddy = imService.getBuddyById(member.getKey()); + OpenInstantMessageEvent e = new OpenInstantMessageEvent(ureq, buddy); + ureq.getUserSession().getSingleUserEventCenter().fireEventToListenersOf(e, InstantMessagingService.TOWER_EVENT_ORES); + } - protected void sendEmailToMember(ContactList contactList, UserRequest ureq) { + protected void doSendEmailToMember(Member member, UserRequest ureq) { + ContactList memberList = new ContactList(translate("members.to", new String[]{ member.getFullName(), courseEnv.getCourseTitle() })); + Identity identity = securityManager.loadIdentityByKey(member.getKey()); + memberList.add(identity); + doSendEmailToMember(memberList, ureq); + } + + protected void doSendEmailToMember(ContactList contactList, UserRequest ureq) { if (contactList.getEmailsAsStrings().size() > 0) { removeAsListenerAndDispose(emailController); @@ -345,7 +429,7 @@ public class MembersCourseNodeRunController extends FormBasicController { } } - protected void openHomePage(Member member, UserRequest ureq) { + protected void doOpenHomePage(Member member, UserRequest ureq) { String url = "[HomePage:" + member.getKey() + "]"; BusinessControl bc = BusinessControlFactory.getInstance().createFromString(url); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl()); @@ -359,7 +443,10 @@ public class MembersCourseNodeRunController extends FormBasicController { private final Long key; private boolean portrait; private String portraitCssClass; + private FormLink emailLink; + private FormLink chatLink; + private FormLink idLink; public Member(Long key, String firstName, String lastName, String fullName, boolean portrait, String portraitCssClass) { this.firstName = firstName; @@ -381,20 +468,43 @@ public class MembersCourseNodeRunController extends FormBasicController { public String getPortraitCssClass() { return portraitCssClass; } - public boolean isPortraitAvailable() { return portrait; } + public FormLink getIdLink() { + return idLink; + } + + public void setIdLink(FormLink idLink) { + this.idLink = idLink; + } + public FormLink getEmailLink() { return emailLink; } + + public String getEmailComponentName() { + return emailLink == null ? null : emailLink.getComponent().getComponentName(); + } public void setEmailLink(FormLink emailLink) { this.emailLink = emailLink; } + public FormLink getChatLink() { + return chatLink; + } + + public String getChatComponentName() { + return chatLink == null ? null : chatLink.getComponent().getComponentName(); + } + + public void setChatLink(FormLink chatLink) { + this.chatLink = chatLink; + } + public String getFullName() { return fullName; } diff --git a/src/main/java/org/olat/course/nodes/members/_content/memberList.html b/src/main/java/org/olat/course/nodes/members/_content/memberList.html index 36d91c4b36bf062bf1fbf55944b5ae695ec6e202..876fefcae29b3cbf58dd04fa6e47d433549b7516 100644 --- a/src/main/java/org/olat/course/nodes/members/_content/memberList.html +++ b/src/main/java/org/olat/course/nodes/members/_content/memberList.html @@ -1,17 +1,20 @@ -#foreach($memberLink in $memberLinks) +#foreach($member in $members) <div class="o_cmember col-xs-12 col-sm-6 col-md-4 "> <div class="clearfix"> <div class="o_portrait pull-left"> - #if($memberLink.getUserObject().isPortraitAvailable()) - <img src="$r.staticLink("images/transparent.gif")" class="$memberLink.getUserObject().getPortraitCssClass()" style="background-image: url('$avatarBaseURL/$memberLink.getUserObject().getKey()/portrait.jpg')" alt="$r.escapeHtml("$memberLink.getUserObject().getFullName()")" /> + #if($member.isPortraitAvailable()) + <img src="$r.staticLink("images/transparent.gif")" class="$member.getPortraitCssClass()" style="background-image: url('$avatarBaseURL/$member.getKey()/portrait.jpg')" alt="$r.escapeHtml("$member.getFullName()")" /> #else - <img src="$r.staticLink("images/transparent.gif")" class="$memberLink.getUserObject().getPortraitCssClass()" alt="$r.escapeHtml("$memberLink.getUserObject().getFullName()")" /> + <img src="$r.staticLink("images/transparent.gif")" class="$member.getPortraitCssClass()" alt="$r.escapeHtml("$member.getFullName()")" /> #end </div> <div class="o_cmember_info_wrapper"> - $r.render($memberLink.getComponent().getComponentName()) - #if($r.available($memberLink.getUserObject().getEmailLink().getComponent().getComponentName())) - $r.render($memberLink.getUserObject().getEmailLink().getComponent().getComponentName()) + #if($r.available($member.getChatComponentName()) && $r.visible($member.getChatComponentName())) + $r.render($member.getChatComponentName()) + #end + $r.render($member.getIdLink().getComponent().getComponentName()) + #if($r.available($member.getEmailComponentName())) + $r.render($member.getEmailComponentName()) #end </div> </div>