/** * Sidebar main script file * * @author Pierre HUBERT */ const SidebarMain = { show: function() { if(byId("main-sidebar")) return; var sideBar = createElem2({ appendTo: byId("wrapper"), type: "aside", class: "main-sidebar", id: "main-sidebar", }); var section = createElem2({ appendTo: sideBar, type: "section", class: "sidebar" }); // User panel var userPanel = createElem2({ appendTo: section, type: "div", class: "user-panel hidden-xs" }); getUserInfo(userID(), function(info){ if(info.error) return userPanel.innerHTML = "Error!"; // User account image createElem2({ appendTo: userPanel, type: "div", class: "pull-left image cursor-pointer", onclick: () => openUserPage(info), children: [ createElem2({ type: "img", class: "img-circle", src: info.accountImage }) ], }); // User name createElem2({ appendTo: userPanel, type: "div", class: "pull-left info", children: [ createElem2({ type: "p", class: "cursor-pointer", innerHTML: userFullName(info), onclick: () => openUserPage(info), }), createElem2({ type: "a", innerHTML: "Settings", internalHref: "settings", }), ] }); }); // Search form this.addSearchForm(section); // User memberships /*createElem2({ appendTo: section, type: "div", class: "intermediate-label hide-on-collapse", innerHTML: "FRIENDS & GROUPS" });*/ let userMemberships = createElem2({ appendTo: section, type: "div", class: "memberships-list" }); this.refreshMemberships(userMemberships); let interval = setInterval(() => { if(userMemberships.isConnected) this.refreshMemberships(userMemberships); else clearInterval(interval); }, 15000); /*// Recent conversations createElem2({ appendTo: section, type: "div", class: "intermediate-label hide-on-collapse", innerHTML: "CONVERSATIONS" }); let conversationsList = createElem2({ appendTo: section, type: "ul", class: "sidebar-menu recents-conversations-list hide-on-collapse", innerHTML: "
  • TO COME
  • " });*/ }, // ************************************** // Search // ************************************** /** * Add search form to sidebar * * @param {HTMLElement} target The target for the search form */ addSearchForm: function(target) { // Search input /** * @type {HTMLInputElement} */ let searchInput = createElem2({ type: "input", class: "form-control", elemType: "text", id: "sidebarSearchInput", placeholder: "Search...", }); let searchForm = createElem2({ appendTo: target, type: "form", class: "sidebar-form", children: [ createElem2({ type: "div", class: "input-group", children: [ searchInput, createElem2({ type: "span", class: "input-group-btn", innerHTML: '', }), ] }) ] }); // Search results target let searchResults = createElem2({ appendTo: searchForm, type: "div", class: "sidebar-search-results" }); searchResults.style.display = "none"; searchInput.addEventListener("keyup", e => { //Update UI searchResults.style.display = searchInput.value.length < 2 ? "none" : "unset"; if(searchInput.value.length < 2) return; // Perform the search on the server ComunicWeb.components.search.interface.global(searchInput.value, results => { if(results.error) return; //Get information about related groups and users getMultipleUsersInfo(ComunicWeb.components.search.utils.getUsersId(results), usersInfo => { if(usersInfo.error) return; getInfoMultipleGroups(ComunicWeb.components.search.utils.getGroupsId(results), groupsInfo => { if(groupsInfo.error) return; this.applySearchResults(searchResults, results, usersInfo, groupsInfo); }); }); }); }) searchForm.addEventListener("submit", e => { e.preventDefault(); openPage("search?q=" + searchForm.getElementsByTagName("input")[0].value); }); }, /** * Put search form back to its initial state */ resetSearchFrom: function(){ byId("sidebarSearchInput").value = ""; document.querySelector(".sidebar-search-results").style.display = "none"; }, /** * Apply search results * * @param {HTMLElement} target * @param {Array} results * @param {*} users * @param {*} groups */ applySearchResults: function(target, results, users, groups) { emptyElem(target); let resultsTarget = createElem2({ appendTo: target, type: "div", class: "results-container" }); results.forEach(el => { if(el.kind == "user") this.applyUserResult(resultsTarget, users["user-" + el.id]); else this.applyGroupResult(resultsTarget, groups[el.id]); }); $(resultsTarget).slimScroll({ height: '100%' }); }, applyUserResult: function(target, user) { createElem2({ appendTo: target, type: "div", children: [ createElem2({ type: "img", class: "img-circle", src: user.accountImage }), createElem2({ type: "span", innerHTML: userFullName(user) }), ], onclick: () => { openUserPage(user); this.resetSearchFrom(); } }); }, applyGroupResult: function(target, group) { createElem2({ appendTo: target, type: "div", children: [ createElem2({ type: "img", src: group.icon_url }), createElem2({ type: "span", innerHTML: group.name }), ], onclick: () => { openGroupPage(group); this.resetSearchFrom(); } }); }, // ************************************** // Memberships // ************************************** /** * Refresh user memberships * * @param {HTMLElement} target */ refreshMemberships: function(target){ WebAppInterface.getMemberships( () => notify("Could not refresh your memberships!", "error"), (m, u, g, c) => this.applyMemberships(target, m, u, g, c) ); }, /** * Apply memberships * * @param {HTMLElement} target * @param {UserMembership[]} memberships * @param {UsersList} users * @param {*} groups * @param {Map} convs */ applyMemberships: function(target, memberships, users, groups, convs) { // Empty list target.innerHTML = ""; let friendsTarget = createElem2({ appendTo: target, type: "ul", class: "sidebar-menu" }); memberships.forEach(e => { if(e.type == "friend") this.applyFriend(friendsTarget, e.friend, users.get(e.friend.ID_friend)); if(e.type == "group") this.applyGroup(friendsTarget, groups.get(e.id), e.last_activity); if(e.type == "conversation") this.applyConversation(friendsTarget, e.conv, convs.get(e.conv.id)); }); createElem2({ appendTo: friendsTarget, type: "li", innerHTML: "
    ", }); $(friendsTarget).slimscroll({ flex: 2, height: "100%" }); // Highlight active element SidebarMain.refreshActiveElement() }, /** * Apply a friend object * * @param {HTMLElement} target * @param {*} friend * @param {User} user */ applyFriend: function(target, friend, user) { let li = createElem2({ appendTo: target, type: "li" }); li.setAttribute("data-membership-user-id", user.id) if(user.hasVirtualDirectory) li.setAttribute("data-membership-dir", user.virtualDirectory) let a = createElem2({ appendTo: li, onclick: () => openUserPage(user), type: "a" }); // User icon createElem2({ appendTo: a, type: "img", class: "img-circle", src: user.image }); // User name createElem2({ appendTo: a, type: "span", innerHTML: userFullName(user) }); // Private conversation createElem2({ appendTo: a, type: "span", class: "pull-right-container", innerHTML: "", onclick: (e) => { e.stopImmediatePropagation(); ComunicWeb.components.conversations.manager.openPrivate(user.id); } }); // Supplementary information let subInfoEl = createElem2({ appendTo: a, type: "div", class: "subinfo", onclick: friend.accepted != 1 ? (e) => e.stopImmediatePropagation() : undefined }); // Check if friendship request has been accepted or not if(friend.accepted == 1) { if(ComunicWeb.common.date.time() - friend.time_last_activity < 30) subInfoEl.innerHTML = "Online"; else subInfoEl.innerHTML = timeDiffToStr(friend.time_last_activity); } else { const respondRequest = function(accept) { // Update UI subInfoEl.innerHTML = accept ? lang("friends_bar_accepted") : lang("friends_bar_rejected"); if(!accept) li.remove(); // Perform the request the server ComunicWeb.components.friends.list.respondRequest(friend.ID_friend, accept); } // Offer the user to accept or reject the invitation createElem2({ appendTo: subInfoEl, type: "span", class: "btn btn-success btn-xs", innerHTML: "", onclick: (e) => respondRequest(true) }); add_space(subInfoEl); createElem2({ appendTo: subInfoEl, type: "span", class: "btn btn-danger btn-xs", innerHTML: "", onclick: (e) => respondRequest(false) }); } }, /** * Apply group information * * @param {HTMLElement} target * @param {Group} group * @param {*} lastactive */ applyGroup: function(target, group, lastactive) { let li = createElem2({ appendTo: target, type: "li" }); li.setAttribute("data-membership-group-id", group.id) if(group.hasVirtualDirectory) li.setAttribute("data-membership-dir", group.virtual_directory) let a = createElem2({ appendTo: li, type: "a", onclick: () => openGroupPage(group) }); // Group icon createElem2({ appendTo: a, type: "img", src: group.icon_url }); // Group name createElem2({ appendTo: a, type: "span", innerHTML: group.name }); let subInfoEl = createElem2({ appendTo: a, type: "div", class: "subinfo", //onclick: (e) => e.stopImmediatePropagation() }); if(group.membership == "pending") { // Show requested state subInfoEl.innerHTML = "Requested"; } else if(group.membership == "invited") { // Show invited state subInfoEl.innerHTML = " Invited "; const respondRequest = (accept) => { GroupsInterface.respondInvitation(group.id, accept); subInfoEl.innerHTML = accept ? tr("Accepted") : tr("Rejected"); }; // Offer the user to accept or reject the invitation createElem2({ appendTo: subInfoEl, type: "span", class: "btn btn-success btn-xs", innerHTML: "", onclick: (e) => respondRequest(true) }); add_space(subInfoEl); createElem2({ appendTo: subInfoEl, type: "span", class: "btn btn-danger btn-xs", innerHTML: "", onclick: (e) => respondRequest(false) }); } else // Group last activity subInfoEl.innerHTML = timeDiffToStr(lastactive); }, /** * Apply a conversation * * @param {HTMLElement} target * @param {Conversation} conv * @param {String} name */ applyConversation: function(target, conv, name) { let li = createElem2({ appendTo: target, type: "li", class: "conversation_memberhsip" }); li.setAttribute("data-membership-conv-id", conv.id) // Check for unread messages if(conv.last_activity > conv.members.find(m => m.user_id == userID()).last_access) { li.classList.add("has-unread-msg"); } let a = createElem2({ appendTo: li, type: "a", onclick: () => openConversation(conv.id, true) }); // Icon if (conv.logo == null) createElem2({ appendTo: a, type: "i", class: "fa fa-comments" }); else createElem2({ appendTo: a, type: "img", src: conv.logo }); // Conversation name createElem2({ appendTo: a, type: "span", innerHTML: name }); let subInfoEl = createElem2({ appendTo: a, type: "div", class: "subinfo", innerHTML: timeDiffToStr(conv.last_activity) }); // Check if there is an ongoing call on the conversation if(conv.has_call_now) { li.classList.add("with-call"); let callLi = createElem2({ appendTo: target, type: "li", class: "call_notice" }); let a = createElem2({ appendTo: callLi, type: "a", onclick: () => CallsController.Open(conv), innerHTML: " Ongoing call" }); } }, /** * Refresh currently active element in the sidebar */ refreshActiveElement: function() { // Search for target const list = document.querySelector(".memberships-list"); if(!list) return; // Remove previously active element (if any) const activeElem = list.querySelector("li.active"); if(activeElem) activeElem.classList.remove("active") // Check for target element const currPage = ComunicWeb.common.url.getCurrentWebsiteURL(); let query = false; // Friends if(currPage.startsWith("user/")) query = "[data-membership-user-id=\""+currPage.split("/")[1].split("#")[0]+"\"]" // Groups else if(currPage.startsWith("groups/")) query = "[data-membership-group-id=\""+currPage.split("/")[1].split("#")[0]+"\"]" // Conversations else if(currPage.startsWith("conversations/")) query = "[data-membership-conv-id=\""+currPage.split("/")[1].split("#")[0]+"\"]" // Search by virtual directory else { query = "[data-membership-dir=\""+currPage.split("/")[0].split("?")[0].split("#")[0]+"\"]"; } // Query element const target = list.querySelector(query); if(target) target.classList.add("active"); }, } ComunicWeb.components.sideBar.main = SidebarMain // Register to page change events (to refresh active element) document.addEventListener("openPage", (e) => { SidebarMain.refreshActiveElement() })