//META{"name":"FriendNotifications"}*// class FriendNotifications { initConstructor () { this.friendsOnlineList = {}; this.timeLog = []; this.timeLogModalMarkup = `

Friends LogIn/-Out Timelog

`; this.logEntryMarkup = `

`; this.dividerMarkup = `
`; this.css = ` ${BDFDB.dotCN.guilds} > ${BDFDB.dotCN.friendsonline} { cursor: pointer; } .FriendNotifications-modal .log-time { width: 110px; } .FriendNotifications-modal .log-avatar { width: 35px; height: 35px; background-size: cover; background-position: center; border-radius: 50%; } .FriendNotifications-settings .avatar-list { display: flex; align-items: center; flex-wrap: wrap; } .FriendNotifications-settings .type-toast, .FriendNotifications-settings .type-desktop { border-radius: 3px; padding: 0 3px; } .FriendNotifications-settings .type-toast { background-color: #7289DA; } .FriendNotifications-settings .type-desktop { background-color: #43B581; } .FriendNotifications-settings .settings-avatar.desktop { border-color: #43B581; } .FriendNotifications-settings .settings-avatar { margin: 5px; width: 50px; height: 50px; background-size: cover; background-position: center; border: 5px solid #7289DA; border-radius: 50%; box-sizing: border-box; cursor: pointer; } .FriendNotifications-settings .settings-avatar.desktop { border-color: #43B581; } .FriendNotifications-settings .settings-avatar.disabled { border-color: #36393F; filter: grayscale(100%) brightness(50%); } .FriendNotifications-settings .disable-all { color: white; background-color: #36393F; } `; this.defaults = { settings: { muteOnDND: {value:false, description:"Do not notify me when I am DnD:"}, onlyOnOnline: {value:false, description:"Only notify me when a User logs in:"}, openOnClick: {value:false, description:"Open the DM when you click a Notification:"} } }; } getName () {return "FriendNotifications";} getDescription () {return "Notifies you when a friend either logs in or out. Click the Online Friend-Counter to display a timelog of the current session.";} getVersion () {return "1.1.1";} getAuthor () {return "DevilBro";} getSettingsPanel () { if (!this.started || typeof BDFDB !== "object") return; var settings = BDFDB.getAllData(this, "settings"); var notificationsound = BDFDB.loadAllData(this, "notificationsound"); var desktop = BDFDB.loadAllData(this, "desktop"); var disabled = BDFDB.loadAllData(this, "disabled"); var settingshtml = `
${this.getName()}
`; for (let key in settings) { settingshtml += `

${this.defaults.settings[key].description}

`; } if ("Notification" in window) settingshtml += `
Desktop Notification Sound:
Mute:
`; settingshtml += `

Click on a Icon to toggle Notifications for that User:

`; if ("Notification" in window) settingshtml += `

Rightclick on a Icon to toggle Notifications for that User:

`; settingshtml += `
`; for (let id of this.FriendUtils.getFriendIDs()) { let user = this.UserUtils.getUser(id); if (user) { let data = BDFDB.loadData(user.id, "EditUsers", "users") || {}; settingshtml += `
`; } } settingshtml += `
`; settingshtml += `

Batch set Users:

${"Notification" in window ? `` : ``}
`; settingshtml += `
`; var settingspanel = $(settingshtml)[0]; BDFDB.initElements(settingspanel); $(settingspanel) .on("click", ".settings-checkbox", () => {this.updateSettings(settingspanel);}) .on("click", ".btn-savesong", () => {this.saveAudio(settingspanel);}) .on("click", ".mute-checkbox", (e) => { var notificationsound = BDFDB.loadAllData(this, "notificationsound"); notificationsound.mute = e.currentTarget.checked; BDFDB.saveAllData(notificationsound, this, "notificationsound"); }) .on("mouseenter", ".settings-avatar", (e) => { let user = this.UserUtils.getUser(e.currentTarget.getAttribute("user-id")); let data = BDFDB.loadData(user.id, "EditUsers", "users") || {}; BDFDB.createTooltip(data.name ? data.name : user.username, e.currentTarget, {type:"top"}); }) .on("contextmenu", ".settings-avatar", (e) => { if (!("Notification" in window)) return; let desktopoff = !e.currentTarget.classList.contains("desktop"); let id = e.currentTarget.getAttribute("user-id"); e.currentTarget.classList.remove("disabled"); e.currentTarget.classList.toggle("desktop", desktopoff); BDFDB.saveData(id, desktopoff, this, "desktop"); BDFDB.removeData(id, this, "disabled"); }) .on("click", ".settings-avatar", (e) => { let disableoff = !e.currentTarget.classList.contains("disabled"); let id = e.currentTarget.getAttribute("user-id"); e.currentTarget.classList.remove("desktop"); e.currentTarget.classList.toggle("disabled", disableoff); BDFDB.saveData(id, disableoff, this, "disabled"); BDFDB.removeData(id, this, "desktop"); }) .on("click", ".disable-all, .toast-all, .desktop-all", (e) => { let button = e.currentTarget; let disableon = button.getAttribute("do-disable"); let desktopon = button.getAttribute("do-desktop"); let disabledata = BDFDB.loadAllData(this, "disabled"); let desktopdata = BDFDB.loadAllData(this, "desktop"); settingspanel.querySelectorAll(".settings-avatar").forEach(avatar => { let id = avatar.getAttribute("user-id"); avatar.classList.toggle("disabled", disableon); avatar.classList.toggle("desktop", desktopon); disableon ? disabledata[id] = true : delete disabledata[id]; desktopon ? desktopdata[id] = true : delete desktopdata[id]; }); BDFDB.saveAllData(disabledata, this, "disabled"); BDFDB.saveAllData(desktopdata, this, "desktop"); }); return settingspanel; } //legacy load () {} start () { var libraryScript = null; if (typeof BDFDB !== "object" || typeof BDFDB.isLibraryOutdated !== "function" || BDFDB.isLibraryOutdated()) { libraryScript = document.querySelector('head script[src="https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js"]'); if (libraryScript) libraryScript.remove(); libraryScript = document.createElement("script"); libraryScript.setAttribute("type", "text/javascript"); libraryScript.setAttribute("src", "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js"); document.head.appendChild(libraryScript); } this.startTimeout = setTimeout(() => {this.initialize();}, 30000); if (typeof BDFDB === "object" && typeof BDFDB.isLibraryOutdated === "function") this.initialize(); else libraryScript.addEventListener("load", () => {this.initialize();}); } initialize () { if (typeof BDFDB === "object") { BDFDB.loadMessage(this); this.FriendUtils = BDFDB.WebModules.findByProperties(["getFriendIDs", "getRelationships"]); this.ChannelUtils = BDFDB.WebModules.findByProperties(["getDMFromUserId"]); this.ChannelSwitchUtils = BDFDB.WebModules.findByProperties(["selectPrivateChannel"]); this.UserMetaStore = BDFDB.WebModules.findByProperties(["getStatus", "getOnlineFriendCount"]); this.UserUtils = BDFDB.WebModules.findByProperties(["getUsers"]); var observer = null; observer = new MutationObserver((changes, _) => { changes.forEach( (change, i) => { let settings = BDFDB.getAllData(this, "settings"); let notificationsound = BDFDB.loadAllData(this, "notificationsound"); for (let id of this.FriendUtils.getFriendIDs()) { let online = this.UserMetaStore.getStatus(id) != "offline"; let user = this.UserUtils.getUser(id); if (user && this.friendsOnlineList[id] != online && !BDFDB.loadData(id, this, "disabled")) { this.timeLog.push({user, online, time: new Date()}); if (!(settings.onlyOnOnline && !online) && !(settings.muteOnDND && BDFDB.getUserStatus() == "dnd")) { let data = BDFDB.loadData(user.id, "EditUsers", "users") || {}; let string = `${BDFDB.encodeToHTML(data.name ? data.name : user.username)} is ${online ? "online" : "offline"}.`; let avatar = data.removeIcon ? "" : (data.url ? data.url : BDFDB.getUserAvatar(user.id)); let openChannel = () => { if (settings.openOnClick){ let DMid = this.ChannelUtils.getDMFromUserId(user.id); if (DMid) { require("electron").remote.getCurrentWindow().maximize(); this.ChannelSwitchUtils.selectPrivateChannel(DMid); } } }; if (!BDFDB.loadData(id, this, "desktop")) { let toast = BDFDB.showToast(`
${string}
`, {html:true, timeout:5000, type:(online ? "success" : null), icon:false}); $(toast).on("click." + this.getName(), openChannel); } else { BDFDB.showDesktopNotification(string, {icon:avatar, timeout:5000, click:openChannel, silent:notificationsound.mute, sound:notificationsound.song}); } } } this.friendsOnlineList[id] = online; } } ); }); BDFDB.addObserver(this, `${BDFDB.dotCN.guilds} > ${BDFDB.dotCN.friendsonline}`, {name:"friendCountObserver",instance:observer}, {childList:true, subtree:true, characterData:true}); for (let id of this.FriendUtils.getFriendIDs()) { this.friendsOnlineList[id] = this.UserMetaStore.getStatus(id) != "offline"; } $(`${BDFDB.dotCN.guilds} > ${BDFDB.dotCN.friendsonline}`).first() .on("mouseenter." + this.getName(), (e) => { BDFDB.createTooltip("Timelog", e.currentTarget, {type:"right"}); }) .on("click." + this.getName(), (e) => { this.showTimeLog(); }); } else { console.error(this.getName() + ": Fatal Error: Could not load BD functions!"); } } stop () { if (typeof BDFDB === "object") { BDFDB.unloadMessage(this); } } // begin of own functions updateSettings (settingspanel) { var settings = {}; for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { settings[input.value] = input.checked; } BDFDB.saveAllData(settings, this, "settings"); } saveAudio (settingspanel) { var successSavedAudio = (parsedurl, parseddata) => { if (parsedurl && parseddata) BDFDB.showToast(`Sound was saved successfully.`, {type:"success"}); let notificationsound = BDFDB.loadAllData(this, "notificationsound"); notificationsound.url = parsedurl; notificationsound.song = parseddata; BDFDB.saveAllData(notificationsound, this, "notificationsound"); }; var url = settingspanel.querySelector(".songInput").value; if (url.length == 0) { BDFDB.showToast(`Sound was set to the default sound.`, {type:"warn"}); successSavedAudio(url, url); } else if (url.indexOf("http") == 0) { require("request")(url, (error, response, result) => { if (response) { var type = response.headers["content-type"]; if (type && (type.indexOf("octet-stream") > -1 || type.indexOf("audio") > -1 || type.indexOf("video") > -1)) { successSavedAudio(url, url); return; } } BDFDB.showToast("Use a valid direct link to a video or audio source. They usually end on something like .mp3, .mp4 or .wav.", {type:"danger"}); }); } else { require("fs").readFile(url, (error, response) => { if (error) { BDFDB.showToast("Could not fetch file. Please make sure the file exists.", {type:"danger"}); } else { successSavedAudio(url, `data:audio/mpeg;base64,${response.toString("base64")}`); } }); } } showTimeLog () { var timeLogModal = $(this.timeLogModalMarkup); let logs = this.timeLog.slice(0).reverse(); for (let log of logs) { let entry = $(this.logEntryMarkup); let divider = $(this.dividerMarkup); let data = BDFDB.loadData(log.user.id, "EditUsers", "users") || {}; entry.find(".log-time").text(`[${log.time.toLocaleTimeString()}]`); entry.find(".log-avatar").css("background-image", `url(${data.removeIcon ? "" : (data.url ? data.url : BDFDB.getUserAvatar(log.user.id))})`); entry.find(".log-description").text(`${data.name ? data.name : log.user.username} is ${log.online ? "online" : "offline"}.`); timeLogModal.find(".entries").append(entry).append(divider); } timeLogModal.find(BDFDB.dotCN.modaldivider + ":last-of-type").remove(); BDFDB.appendModal(timeLogModal); } }