1306 lines
64 KiB
JavaScript
1306 lines
64 KiB
JavaScript
/**
|
||
* @name PinDMs
|
||
* @author DevilBro
|
||
* @authorId 278543574059057154
|
||
* @version 1.9.4
|
||
* @description Allows you to pin DMs, making them appear at the top of your DMs/ServerList
|
||
* @invite Jx3TjNS
|
||
* @donate https://www.paypal.me/MircoWittrien
|
||
* @patreon https://www.patreon.com/MircoWittrien
|
||
* @website https://mwittrien.github.io/
|
||
* @source https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/PinDMs/
|
||
* @updateUrl https://mwittrien.github.io/BetterDiscordAddons/Plugins/PinDMs/PinDMs.plugin.js
|
||
*/
|
||
|
||
module.exports = (_ => {
|
||
const changeLog = {
|
||
improved: {
|
||
"Predefined Categories": "You can now overwrite predefined categories, meaning you can add a channel from one of the predefined to a custom one, making not appear in the predefined anymore"
|
||
}
|
||
};
|
||
|
||
return !window.BDFDB_Global || (!window.BDFDB_Global.loaded && !window.BDFDB_Global.started) ? class {
|
||
constructor (meta) {for (let key in meta) this[key] = meta[key];}
|
||
getName () {return this.name;}
|
||
getAuthor () {return this.author;}
|
||
getVersion () {return this.version;}
|
||
getDescription () {return `The Library Plugin needed for ${this.name} is missing. Open the Plugin Settings to download it. \n\n${this.description}`;}
|
||
|
||
downloadLibrary () {
|
||
require("request").get("https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js", (e, r, b) => {
|
||
if (!e && b && r.statusCode == 200) require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0BDFDB.plugin.js"), b, _ => BdApi.showToast("Finished downloading BDFDB Library", {type: "success"}));
|
||
else BdApi.alert("Error", "Could not download BDFDB Library Plugin. Try again later or download it manually from GitHub: https://mwittrien.github.io/downloader/?library");
|
||
});
|
||
}
|
||
|
||
load () {
|
||
if (!window.BDFDB_Global || !Array.isArray(window.BDFDB_Global.pluginQueue)) window.BDFDB_Global = Object.assign({}, window.BDFDB_Global, {pluginQueue: []});
|
||
if (!window.BDFDB_Global.downloadModal) {
|
||
window.BDFDB_Global.downloadModal = true;
|
||
BdApi.showConfirmationModal("Library Missing", `The Library Plugin needed for ${this.name} is missing. Please click "Download Now" to install it.`, {
|
||
confirmText: "Download Now",
|
||
cancelText: "Cancel",
|
||
onCancel: _ => {delete window.BDFDB_Global.downloadModal;},
|
||
onConfirm: _ => {
|
||
delete window.BDFDB_Global.downloadModal;
|
||
this.downloadLibrary();
|
||
}
|
||
});
|
||
}
|
||
if (!window.BDFDB_Global.pluginQueue.includes(this.name)) window.BDFDB_Global.pluginQueue.push(this.name);
|
||
}
|
||
start () {this.load();}
|
||
stop () {}
|
||
getSettingsPanel () {
|
||
let template = document.createElement("template");
|
||
template.innerHTML = `<div style="color: var(--header-primary); font-size: 16px; font-weight: 300; white-space: pre; line-height: 22px;">The Library Plugin needed for ${this.name} is missing.\nPlease click <a style="font-weight: 500;">Download Now</a> to install it.</div>`;
|
||
template.content.firstElementChild.querySelector("a").addEventListener("click", this.downloadLibrary);
|
||
return template.content.firstElementChild;
|
||
}
|
||
} : (([Plugin, BDFDB]) => {
|
||
var hoveredCategory, draggedCategory, releasedCategory;
|
||
var hoveredChannel, draggedChannel, releasedChannel;
|
||
|
||
return class PinDMs extends Plugin {
|
||
onLoad () {
|
||
this.defaults = {
|
||
general: {
|
||
pinIcon: {value: true, description: "Show a little 'Pin' Icon for pinned DMs in the Server List"},
|
||
unreadAmount: {value: true, description: "Shows the Amount of unread Messages in a Category in the Channel List"},
|
||
channelAmount: {value: true, description: "Shows the Amount of pinned DMs in a Category in the Channel List"}
|
||
},
|
||
recentOrder: {
|
||
channelList: {value: false, description: "Channel List"},
|
||
guildList: {value: false, description: "Server List"},
|
||
},
|
||
preCategories: {
|
||
friends: {value: {enabled: false, collapsed: false}, description: "FRIENDS"},
|
||
blocked: {value: {enabled: false, collapsed: false}, description: "BLOCKED"},
|
||
bots: {value: {enabled: false, collapsed: false}, description: "Bots"},
|
||
groups: {value: {enabled: false, collapsed: false}, description: "GROUPS"}
|
||
}
|
||
};
|
||
|
||
this.patchedModules = {
|
||
before: {
|
||
PrivateChannelsList: "render"
|
||
},
|
||
after: {
|
||
PrivateChannelsList: "render",
|
||
PrivateChannel: ["render", "componentDidMount"],
|
||
DirectMessage: ["render", "componentDidMount", "componentWillUnmount"]
|
||
}
|
||
};
|
||
|
||
this.css = `
|
||
${BDFDB.dotCN.dmchannel}:hover ${BDFDB.dotCN._pindmsunpinbutton} {
|
||
display: block;
|
||
}
|
||
${BDFDB.dotCN._pindmspinnedchannelsheadercontainer} {
|
||
display: flex;
|
||
cursor: pointer;
|
||
}
|
||
${BDFDB.dotCNS._pindmspinnedchannelsheadercontainer + BDFDB.dotCN.dmchannelheadertext} {
|
||
margin-right: 6px;
|
||
}
|
||
${BDFDB.dotCN._pindmspinnedchannelsheadercontainer + BDFDB.dotCN._pindmspinnedchannelsheadercolored}:hover ${BDFDB.dotCN.dmchannelheadertext} {
|
||
filter: brightness(150%);
|
||
}
|
||
${BDFDB.dotCNS._pindmspinnedchannelsheadercontainer + BDFDB.dotCN._pindmspinnedchannelsheaderamount} {
|
||
position: relative;
|
||
top: -1px;
|
||
margin-right: 6px;
|
||
background-color: var(--background-accent);
|
||
}
|
||
${BDFDB.dotCN._pindmspinnedchannelsheaderarrow} {
|
||
flex: 0;
|
||
width: 16px;
|
||
height: 16px;
|
||
margin-left: 0;
|
||
margin-right: 2px;
|
||
}
|
||
${BDFDB.dotCNS._pindmspinnedchannelsheadercollapsed + BDFDB.dotCN._pindmspinnedchannelsheaderarrow + BDFDB.dotCN.channelheadericonwrapper} {
|
||
transform: rotate(-90deg);
|
||
}
|
||
${BDFDB.dotCN._pindmsunpinbutton} {
|
||
display: none;
|
||
width: 16px;
|
||
height: 16px;
|
||
opacity: .7;
|
||
margin: 2px;
|
||
}
|
||
${BDFDB.dotCN._pindmsunpinbutton}:hover {
|
||
opacity: 1;
|
||
}
|
||
${BDFDB.dotCN._pindmsunpinicon} {
|
||
display: block;
|
||
width: 16px;
|
||
height: 16px;
|
||
}
|
||
${BDFDB.dotCNS._pindmsdmchannelplaceholder + BDFDB.dotCN.namecontainerlayout} {
|
||
box-sizing: border-box;
|
||
border: 1px dashed currentColor;
|
||
}
|
||
${BDFDB.dotCN._pindmspinnedchannelsheadercontainer + BDFDB.dotCN._pindmsdmchannelplaceholder} {
|
||
margin-left: 8px;
|
||
height: 12px;
|
||
box-sizing: border-box;
|
||
border: 1px dashed currentColor;
|
||
}
|
||
${BDFDB.dotCN._pindmsdragpreview} {
|
||
pointer-events: none !important;
|
||
position: absolute !important;
|
||
opacity: 0.5 !important;
|
||
z-index: 10000 !important;
|
||
}
|
||
`;
|
||
}
|
||
|
||
onStart () {
|
||
BDFDB.PatchUtils.patch(this, BDFDB.LibraryModules.DirectMessageUnreadStore, "getUnreadPrivateChannelIds", {after: e => {
|
||
let sortedRecents = this.sortAndUpdate("guildList");
|
||
if (sortedRecents.length) {
|
||
const dms = [];
|
||
for (let pos in sortedRecents) if (!dms.includes(sortedRecents[pos])) dms.push(sortedRecents[pos]);
|
||
e.returnValue = BDFDB.ArrayUtils.removeCopies(dms.concat(e.returnValue));
|
||
}
|
||
}});
|
||
|
||
this.forceUpdateAll();
|
||
}
|
||
|
||
onStop () {
|
||
this.forceUpdateAll();
|
||
}
|
||
|
||
getSettingsPanel (collapseStates = {}) {
|
||
let settingsPanel;
|
||
return settingsPanel = BDFDB.PluginUtils.createSettingsPanel(this, {
|
||
collapseStates: collapseStates,
|
||
children: _ => {
|
||
let settingsItems = [];
|
||
|
||
settingsItems.push(Object.keys(this.defaults.general).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||
type: "Switch",
|
||
plugin: this,
|
||
keys: ["general", key],
|
||
label: this.defaults.general[key].description,
|
||
value: this.settings.general[key]
|
||
})));
|
||
|
||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormDivider, {
|
||
className: BDFDB.disCN.marginbottom8
|
||
}));
|
||
|
||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsPanelList, {
|
||
title: "Sort pinned DMs in the 'Recent Message' instead of the 'Pinned at' Order in:",
|
||
children: Object.keys(this.defaults.recentOrder).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||
type: "Switch",
|
||
plugin: this,
|
||
keys: ["recentOrder", key],
|
||
label: this.defaults.recentOrder[key].description,
|
||
value: this.settings.recentOrder[key]
|
||
}))
|
||
}));
|
||
|
||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormDivider, {
|
||
className: BDFDB.disCN.marginbottom8
|
||
}));
|
||
|
||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsPanelList, {
|
||
title: "Add predefined Category for:",
|
||
children: Object.keys(this.defaults.preCategories).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
|
||
type: "Switch",
|
||
label: BDFDB.LanguageUtils.LanguageStringsCheck[this.defaults.preCategories[key].description] ? BDFDB.LanguageUtils.LanguageStrings[this.defaults.preCategories[key].description] : this.defaults.preCategories[key].description,
|
||
value: this.settings.preCategories[key].enabled,
|
||
onChange: value => {
|
||
this.settings.preCategories[key].enabled = value;
|
||
BDFDB.DataUtils.save(this.settings.preCategories, this, "preCategories");
|
||
}
|
||
}))
|
||
}));
|
||
|
||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormDivider, {
|
||
className: BDFDB.disCN.marginbottom8
|
||
}));
|
||
|
||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
|
||
type: "Button",
|
||
color: BDFDB.LibraryComponents.Button.Colors.RED,
|
||
label: "Unpin all pinned DMs",
|
||
onClick: _ => {
|
||
BDFDB.ModalUtils.confirm(this, "Are you sure you want to unpin all pinned DMs?", _ => BDFDB.DataUtils.remove(this, "pinned", BDFDB.UserUtils.me.id));
|
||
},
|
||
children: BDFDB.LanguageUtils.LanguageStrings.UNPIN
|
||
}));
|
||
|
||
return settingsItems.flat(10);
|
||
}
|
||
});
|
||
}
|
||
|
||
onSettingsClosed () {
|
||
if (this.SettingsUpdated) {
|
||
delete this.SettingsUpdated;
|
||
this.forceUpdateAll();
|
||
}
|
||
}
|
||
|
||
forceUpdateAll () {
|
||
BDFDB.PatchUtils.forceAllUpdates(this);
|
||
BDFDB.DiscordUtils.rerenderAll();
|
||
}
|
||
|
||
onUserContextMenu (e) {
|
||
if (e.instance.props.channel && !e.instance.props.channel.guild_id && e.subType == "useCloseDMItem") e.returnvalue.unshift(this.createItem(e.instance.props.channel.id));
|
||
}
|
||
|
||
onChannelContextMenu (e) {
|
||
if (e.instance.props.channel && !e.instance.props.channel.guild_id && e.instance.props.channel.isGroupDM() && e.subType == "useChannelMarkAsReadItem") {
|
||
if (e.returnvalue.length > 0) e.returnvalue.push(BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuSeparator, {}));
|
||
e.returnvalue.push(this.createItem(e.instance.props.channel.id));
|
||
}
|
||
}
|
||
|
||
createItem (id) {
|
||
if (!id) return;
|
||
let pinnedInGuild = this.isPinnedInGuilds(id);
|
||
|
||
let categories = this.sortAndUpdateCategories("channelList", true);
|
||
let currentCategory = this.getChannelListCategory(id);
|
||
|
||
return BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||
label: this.labels.context_pindm,
|
||
id: BDFDB.ContextMenuUtils.createItemId(this.name, "submenu-pin"),
|
||
children: [
|
||
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||
label: this.labels.context_pinchannel,
|
||
id: BDFDB.ContextMenuUtils.createItemId(this.name, "submenu-channelist"),
|
||
children: [
|
||
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuGroup, {
|
||
children: currentCategory ? BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||
label: this.labels.context_unpinchannel,
|
||
id: BDFDB.ContextMenuUtils.createItemId(this.name, "unpin-channellist"),
|
||
color: BDFDB.LibraryComponents.MenuItems.Colors.DANGER,
|
||
action: _ => this.removeFromCategory(id, currentCategory, "channelList")
|
||
}) : BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||
label: this.labels.context_addtonewcategory,
|
||
id: BDFDB.ContextMenuUtils.createItemId(this.name, "new-channellist"),
|
||
color: BDFDB.LibraryComponents.MenuItems.Colors.BRAND,
|
||
action: _ => this.openCategorySettingsModal({
|
||
id: this.generateId("channelList"),
|
||
name: `${this.labels.header_pinneddms} #${categories.length + 1}`,
|
||
dms: [id],
|
||
pos: categories.length,
|
||
collapsed: false,
|
||
color: null
|
||
}, "channelList", true)
|
||
})
|
||
}),
|
||
categories.length ? BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuGroup, {
|
||
children: categories.map(category => currentCategory && currentCategory.id == category.id || category.predefined ? null : BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||
label: category.name || this.labels.header_pinneddms,
|
||
id: BDFDB.ContextMenuUtils.createItemId(this.name, "pin-channellist", category.id),
|
||
action: _ => {
|
||
if (currentCategory) this.removeFromCategory(id, currentCategory, "channelList");
|
||
this.addToCategory(id, category, "channelList");
|
||
}
|
||
})).filter(n => n)
|
||
}) : null
|
||
].filter(n => n)
|
||
}),
|
||
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||
label: this.labels[pinnedInGuild ? "context_unpinguild" : "context_pinguild"],
|
||
id: BDFDB.ContextMenuUtils.createItemId(this.name, pinnedInGuild ? "unpin-serverlist" : "pin-serverlist"),
|
||
color: pinnedInGuild ? BDFDB.LibraryComponents.MenuItems.Colors.DANGER : BDFDB.LibraryComponents.MenuItems.Colors.DEFAULT,
|
||
action: _ => {
|
||
if (!pinnedInGuild) this.addPin(id, "guildList");
|
||
else this.removePin(id, "guildList");
|
||
}
|
||
})
|
||
].filter(n => n)
|
||
});
|
||
}
|
||
|
||
processPrivateChannelsList (e) {
|
||
let categories = this.sortAndUpdateCategories("channelList", true);
|
||
if (categories.length) {
|
||
e.instance.props.channels = Object.assign({}, e.instance.props.channels);
|
||
e.instance.props.privateChannelIds = [].concat(e.instance.props.privateChannelIds || []);
|
||
e.instance.props.pinnedChannelIds = Object.assign({}, e.instance.props.pinnedChannelIds);
|
||
if (!e.returnvalue) {
|
||
if (draggedChannel && releasedChannel) {
|
||
let categoryId = releasedChannel.split("header_")[1];
|
||
let category = categories.find(n => categoryId != undefined ? n.id == categoryId : n.dms.includes(releasedChannel));
|
||
if (category) {
|
||
BDFDB.ArrayUtils.remove(category.dms, draggedChannel, true);
|
||
category.dms.splice(categoryId != undefined ? 0 : category.dms.indexOf(releasedChannel) + 1, 0, draggedChannel);
|
||
this.savePinnedChannels(Object.assign({}, this.getPinnedChannels("channelList"), {[category.id]: category}), "channelList");
|
||
}
|
||
draggedChannel = null;
|
||
releasedChannel = null;
|
||
}
|
||
if (draggedCategory && releasedCategory) {
|
||
let maybedDraggedCategory = categories.find(n => n.id == draggedCategory);
|
||
let maybedReleasedCategory = categories.find(n => n.id == releasedCategory);
|
||
if (maybedDraggedCategory && maybedReleasedCategory) {
|
||
BDFDB.ArrayUtils.remove(categories, maybedDraggedCategory, true);
|
||
categories.splice(categories.indexOf(maybedReleasedCategory) + 1, 0, maybedDraggedCategory);
|
||
let newCategories = {}, newPos = 0;
|
||
for (let category of [].concat(categories).reverse()) if (!category.predefined) newCategories[category.id] = Object.assign(category, {pos: newPos++});
|
||
this.savePinnedChannels(newCategories, "channelList");
|
||
}
|
||
draggedCategory = null;
|
||
releasedCategory = null;
|
||
}
|
||
e.instance.props.pinnedChannelIds = {};
|
||
for (let category of [].concat(categories).reverse()) {
|
||
e.instance.props.pinnedChannelIds[category.id] = [];
|
||
for (let id of this.sortDMsByTime(this.filterDMs(category.dms, !category.predefined), "channelList").reverse()) {
|
||
BDFDB.ArrayUtils.remove(e.instance.props.privateChannelIds, id, true);
|
||
if (!category.collapsed || e.instance.props.selectedChannelId == id) {
|
||
e.instance.props.privateChannelIds.unshift(id);
|
||
e.instance.props.pinnedChannelIds[category.id].push(id);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else this.injectCategories(e.instance, e.returnvalue, categories);
|
||
|
||
let pinnedIds = BDFDB.ObjectUtils.toArray(e.instance.props.pinnedChannelIds).reverse();
|
||
BDFDB.PatchUtils.unpatch(this, e.instance, "renderDM");
|
||
BDFDB.PatchUtils.patch(this, e.instance, "renderDM", {before: e2 => {
|
||
if (e2.methodArguments[0] != 0) e2.methodArguments[1] += pinnedIds.slice(0, e2.methodArguments[0] - 1).flat().length;
|
||
}, after: e2 => {
|
||
if (e2.methodArguments[0] != 0) {
|
||
let id = e.instance.props.privateChannelIds[e2.methodArguments[1]];
|
||
e2.returnValue = e.instance.props.channels[id] ? BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.PrivateChannelItems[e.instance.props.channels[id].isMultiUserDM() ? "GroupDM" : "DirectMessage"], Object.assign({
|
||
key: id,
|
||
channel: e.instance.props.channels[id],
|
||
selected: e.instance.props.selectedChannelId == id
|
||
}, (e.instance.props.navigator || e.instance.props.listNavigator || {getItemProps: (_ => {})}).getItemProps({
|
||
index: e2.methodArguments[2]
|
||
}))) : null;
|
||
|
||
let category = categories[e2.methodArguments[0] - 1]; // WRONG
|
||
if (category) {
|
||
if (!id || (category.collapsed && e.instance.props.selectedChannelId != id) || !this.filterDMs(category.dms, !category.predefined).includes(id) || draggedCategory == category.id || draggedChannel == id) e2.returnValue = null;
|
||
else if (hoveredCategory == category.id && [].concat(category.dms).reverse()[0] == id) e2.returnValue = [
|
||
e2.returnValue,
|
||
BDFDB.ReactUtils.createElement("h2", {
|
||
className: BDFDB.disCNS.dmchannelheadercontainer + BDFDB.disCNS._pindmspinnedchannelsheadercontainer + BDFDB.disCNS._pindmsdmchannelplaceholder + BDFDB.disCN.namecontainernamecontainer
|
||
})
|
||
].filter(n => n);
|
||
else if (hoveredChannel == id) e2.returnValue = [
|
||
e2.returnValue,
|
||
BDFDB.ReactUtils.createElement("div", {
|
||
className: BDFDB.disCNS.dmchannel + BDFDB.disCNS._pindmsdmchannelpinned + BDFDB.disCNS._pindmsdmchannelplaceholder + BDFDB.disCN.namecontainernamecontainer,
|
||
children: BDFDB.ReactUtils.createElement("div", {
|
||
className: BDFDB.disCN.namecontainerlayout
|
||
})
|
||
})
|
||
].filter(n => n);
|
||
}
|
||
}
|
||
}}, {force: true, noCache: true});
|
||
}
|
||
}
|
||
|
||
injectCategories (instance, returnvalue, categories) {
|
||
if (!returnvalue) return;
|
||
else if (returnvalue && returnvalue.props && BDFDB.ArrayUtils.is(returnvalue.props.sections)) {
|
||
returnvalue.props.sections = [];
|
||
returnvalue.props.sections.push(instance.state.preRenderedChildren);
|
||
let shownPinnedIds = BDFDB.ObjectUtils.toArray(instance.props.pinnedChannelIds).reverse();
|
||
for (let ids of shownPinnedIds) returnvalue.props.sections.push(ids.length || 1);
|
||
returnvalue.props.sections.push(instance.props.privateChannelIds.length - shownPinnedIds.flat().length);
|
||
|
||
let sectionHeight = returnvalue.props.sectionHeight;
|
||
let sectionHeightFunc = typeof sectionHeight != "function" ? _ => sectionHeight : sectionHeight;
|
||
returnvalue.props.sectionHeight = (...args) => {
|
||
if (args[0] != 0 && args[0] != returnvalue.props.sections.length - 1) {
|
||
let category = categories[args[0] - 1];
|
||
if (category) return 40;
|
||
}
|
||
return sectionHeightFunc(...args);
|
||
};
|
||
|
||
let rowHeight = returnvalue.props.rowHeight;
|
||
let rowHeightFunc = typeof rowHeight != "function" ? _ => rowHeight : rowHeight;
|
||
returnvalue.props.rowHeight = (...args) => {
|
||
if (args[0] != 0 && args[0] != returnvalue.props.sections.length - 1) {
|
||
let category = categories[args[0] - 1];
|
||
if (category && (category.collapsed || category.id == draggedCategory)) return 0;
|
||
}
|
||
return rowHeightFunc(...args);
|
||
};
|
||
|
||
let renderRow = returnvalue.props.renderRow;
|
||
returnvalue.props.renderRow = (...args) => {
|
||
let row = renderRow(...args);
|
||
return row && row.key == "no-private-channels" ? null : row;
|
||
};
|
||
|
||
let renderSection = returnvalue.props.renderSection;
|
||
returnvalue.props.renderSection = (...args) => {
|
||
if (args[0].section != 0 && args[0].section != returnvalue.props.sections.length - 1) {
|
||
let category = categories[args[0].section - 1];
|
||
if (category && draggedCategory != category.id) {
|
||
let color = BDFDB.ColorUtils.convert(category.color, "RGBA");
|
||
let foundDMs = this.filterDMs(category.dms, !category.predefined);
|
||
let unreadAmount = this.settings.general.unreadAmount && BDFDB.ArrayUtils.sum(foundDMs.map(id => BDFDB.LibraryModules.UnreadChannelUtils.getMentionCount(id)));
|
||
return category.predefined && foundDMs.length < 1 ? null : [
|
||
BDFDB.ReactUtils.createElement("h2", {
|
||
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN.dmchannelheadercontainer, BDFDB.disCN._pindmspinnedchannelsheadercontainer, category.collapsed && BDFDB.disCN._pindmspinnedchannelsheadercollapsed, color && BDFDB.disCN._pindmspinnedchannelsheadercolored, BDFDB.disCN.namecontainernamecontainer),
|
||
categoryId: category.id,
|
||
onMouseDown: category.predefined ? null : event => {
|
||
event = event.nativeEvent || event;
|
||
let node = BDFDB.DOMUtils.getParent(BDFDB.dotCN._pindmspinnedchannelsheadercontainer, event.target).cloneNode(true);
|
||
let mouseMove = event2 => {
|
||
if (Math.sqrt((event.pageX - event2.pageX)**2) > 20 || Math.sqrt((event.pageY - event2.pageY)**2) > 20) {
|
||
BDFDB.ListenerUtils.stopEvent(event);
|
||
draggedCategory = category.id;
|
||
this.updateContainer("channelList");
|
||
let dragPreview = this.createDragPreview(node, event2);
|
||
document.removeEventListener("mousemove", mouseMove);
|
||
document.removeEventListener("mouseup", mouseUp);
|
||
let dragging = event3 => {
|
||
this.updateDragPreview(dragPreview, event3);
|
||
let placeholder = BDFDB.DOMUtils.getParent(BDFDB.dotCN._pindmsdmchannelplaceholder, event3.target);
|
||
let categoryNode = BDFDB.DOMUtils.getParent(BDFDB.dotCN._pindmspinnedchannelsheadercontainer, placeholder ? placeholder.previousSibling : event3.target);
|
||
let maybeHoveredCategory = categoryNode && categoryNode.getAttribute("categoryId");
|
||
let update = maybeHoveredCategory != hoveredCategory;
|
||
if (maybeHoveredCategory && !this.defaults.preCategories[maybeHoveredCategory]) hoveredCategory = maybeHoveredCategory;
|
||
else hoveredCategory = null;
|
||
if (update) this.updateContainer("channelList");
|
||
};
|
||
let releasing = event3 => {
|
||
BDFDB.DOMUtils.remove(dragPreview);
|
||
if (hoveredCategory) releasedCategory = hoveredCategory;
|
||
else draggedCategory = null;
|
||
hoveredCategory = null;
|
||
this.updateContainer("channelList");
|
||
document.removeEventListener("mousemove", dragging);
|
||
document.removeEventListener("mouseup", releasing);
|
||
};
|
||
document.addEventListener("mousemove", dragging);
|
||
document.addEventListener("mouseup", releasing);
|
||
}
|
||
};
|
||
let mouseUp = _ => {
|
||
document.removeEventListener("mousemove", mouseMove);
|
||
document.removeEventListener("mouseup", mouseUp);
|
||
};
|
||
document.addEventListener("mousemove", mouseMove);
|
||
document.addEventListener("mouseup", mouseUp);
|
||
},
|
||
onClick: _ => {
|
||
if (foundDMs.length || !category.collapsed) {
|
||
category.collapsed = !category.collapsed;
|
||
if (category.predefined) {
|
||
this.settings.preCategories[category.id].collapsed = category.collapsed;
|
||
BDFDB.DataUtils.save(this.settings.preCategories, this, "preCategories");
|
||
}
|
||
else this.savePinnedChannels(Object.assign({}, this.getPinnedChannels("channelList"), {[category.id]: category}), "channelList");
|
||
this.updateContainer("channelList");
|
||
}
|
||
},
|
||
onContextMenu: event => {
|
||
BDFDB.ContextMenuUtils.open(this, event, BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuGroup, {
|
||
children: category.predefined ? BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||
label: this.labels.context_disablepredefined,
|
||
id: BDFDB.ContextMenuUtils.createItemId(this.name, "disable-predefined"),
|
||
action: _ => {
|
||
if (!this.settings.preCategories[category.id]) return;
|
||
this.settings.preCategories[category.id].enabled = false;
|
||
BDFDB.DataUtils.save(this.settings.preCategories, this, "preCategories");
|
||
this.updateContainer("channelList");
|
||
}
|
||
}) : [
|
||
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||
label: BDFDB.LanguageUtils.LanguageStrings.CATEGORY_SETTINGS,
|
||
id: BDFDB.ContextMenuUtils.createItemId(this.name, "category-settings"),
|
||
action: _ => this.openCategorySettingsModal(category, "channelList")
|
||
}),
|
||
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||
label: BDFDB.LanguageUtils.LanguageStrings.DELETE_CATEGORY,
|
||
id: BDFDB.ContextMenuUtils.createItemId(this.name, "remove-category"),
|
||
color: BDFDB.LibraryComponents.MenuItems.Colors.DANGER,
|
||
action: _ => {
|
||
let newData = this.getPinnedChannels("channelList");
|
||
delete newData[category.id];
|
||
this.savePinnedChannels(newData, "channelList");
|
||
this.updateContainer("channelList");
|
||
}
|
||
})
|
||
]
|
||
}));
|
||
},
|
||
children: [
|
||
BDFDB.ObjectUtils.is(color) ? BDFDB.ReactUtils.createElement("span", {
|
||
className: BDFDB.disCN.dmchannelheadertext,
|
||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextGradientElement, {
|
||
gradient: BDFDB.ColorUtils.createGradient(color),
|
||
children: category.name
|
||
})
|
||
}) : BDFDB.ReactUtils.createElement("span", {
|
||
className: BDFDB.disCN.dmchannelheadertext,
|
||
style: {color: color},
|
||
children: category.name,
|
||
}),
|
||
unreadAmount ? BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Badges.NumberBadge, {
|
||
className: BDFDB.disCN._pindmspinnedchannelsheaderamount,
|
||
count: unreadAmount
|
||
}) : null,
|
||
this.settings.general.channelAmount ? BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Badges.NumberBadge, {
|
||
className: BDFDB.disCN._pindmspinnedchannelsheaderamount,
|
||
count: foundDMs.length,
|
||
disableColor: true
|
||
}) : null,
|
||
BDFDB.ReactUtils.createElement("div", {
|
||
className: BDFDB.disCNS._pindmspinnedchannelsheaderarrow + BDFDB.disCNS.channelheadericonwrapper + BDFDB.disCN.channelheadericonclickable,
|
||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
|
||
className: BDFDB.disCNS._pindmspinnedchannelsheaderarrow + BDFDB.disCN.channelheadericon,
|
||
nativeClass: true,
|
||
iconSVG: `<svg width="24" height="24" viewBox="4 4 16 16"><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M16.59 8.59004L12 13.17L7.41 8.59004L6 10L12 16L18 10L16.59 8.59004Z"></path></svg>`
|
||
})
|
||
})
|
||
].filter(n => n)
|
||
}),
|
||
hoveredChannel == "header_" + category.id && BDFDB.ReactUtils.createElement("div", {
|
||
className: BDFDB.disCNS.dmchannel + BDFDB.disCNS._pindmsdmchannelpinned + BDFDB.disCNS._pindmsdmchannelplaceholder + BDFDB.disCN.namecontainernamecontainer,
|
||
children: BDFDB.ReactUtils.createElement("div", {
|
||
className: BDFDB.disCN.namecontainerlayout
|
||
})
|
||
})
|
||
].filter(n => n);
|
||
}
|
||
else return null;
|
||
}
|
||
else return renderSection(...args);
|
||
};
|
||
}
|
||
else if (typeof returnvalue.props.children == "function") {
|
||
let childrenRender = returnvalue.props.children;
|
||
returnvalue.props.children = BDFDB.TimeUtils.suppress((...args) => {
|
||
let children = childrenRender(...args);
|
||
this.injectCategories(instance, children, categories);
|
||
return children;
|
||
}, "Error in Children Render of PrivateChannelList!", this);
|
||
}
|
||
else if (BDFDB.ArrayUtils.is(returnvalue)) {
|
||
for (let child of returnvalue) this.injectCategories(instance, child, categories);
|
||
}
|
||
else this.injectCategories(instance, returnvalue.props.children, categories);
|
||
}
|
||
|
||
processPrivateChannel (e) {
|
||
if (e.instance.props.channel && !this.getPredefinedCategory(e.instance.props.channel.id)) {
|
||
let category = this.getChannelListCategory(e.instance.props.channel.id);
|
||
if (category) {
|
||
if (e.node) {
|
||
BDFDB.DOMUtils.addClass(e.node, BDFDB.disCN._pindmsdmchannelpinned);
|
||
e.node.removeEventListener("mousedown", e.node.PinDMsMouseDownListener);
|
||
if (!this.settings.recentOrder.channelList) {
|
||
e.node.setAttribute("draggable", false);
|
||
e.node.PinDMsMouseDownListener = event => {
|
||
if (!this.started) e.node.removeEventListener("mousedown", e.node.PinDMsMouseDownListener);
|
||
else {
|
||
event = event.nativeEvent || event;
|
||
let mouseMove = event2 => {
|
||
if (Math.sqrt((event.pageX - event2.pageX)**2) > 20 || Math.sqrt((event.pageY - event2.pageY)**2) > 20) {
|
||
BDFDB.ListenerUtils.stopEvent(event);
|
||
draggedChannel = e.instance.props.channel.id;
|
||
this.updateContainer("channelList");
|
||
let dragPreview = this.createDragPreview(e.node, event2);
|
||
document.removeEventListener("mousemove", mouseMove);
|
||
document.removeEventListener("mouseup", mouseUp);
|
||
let dragging = event3 => {
|
||
this.updateDragPreview(dragPreview, event3);
|
||
let maybeHoveredChannel = null;
|
||
let categoryNode = BDFDB.DOMUtils.getParent(BDFDB.dotCN._pindmspinnedchannelsheadercontainer, event3.target);
|
||
if (categoryNode) {
|
||
let hoveredCategoryId = categoryNode.getAttribute("categoryid");
|
||
if (hoveredCategoryId && hoveredCategoryId == category.id) maybeHoveredChannel = "header_" + category.id;
|
||
}
|
||
else {
|
||
let placeholder = BDFDB.DOMUtils.getParent(BDFDB.dotCN._pindmsdmchannelplaceholder, event3.target);
|
||
maybeHoveredChannel = (BDFDB.ReactUtils.findValue(BDFDB.DOMUtils.getParent(BDFDB.dotCN._pindmsdmchannelpinned, placeholder ? placeholder.previousSibling : event3.target), "channel", {up: true}) || {}).id;
|
||
let maybeHoveredCategory = maybeHoveredChannel && this.getChannelListCategory(maybeHoveredChannel);
|
||
if (!maybeHoveredCategory || maybeHoveredCategory.id != category.id) maybeHoveredChannel = null;
|
||
};
|
||
let update = maybeHoveredChannel != hoveredChannel;
|
||
if (maybeHoveredChannel) hoveredChannel = maybeHoveredChannel;
|
||
else hoveredChannel = null;
|
||
if (update) this.updateContainer("channelList");
|
||
};
|
||
let releasing = event3 => {
|
||
BDFDB.DOMUtils.remove(dragPreview);
|
||
if (hoveredChannel) releasedChannel = hoveredChannel;
|
||
else draggedChannel = null;
|
||
hoveredChannel = null;
|
||
this.updateContainer("channelList");
|
||
document.removeEventListener("mousemove", dragging);
|
||
document.removeEventListener("mouseup", releasing);
|
||
};
|
||
document.addEventListener("mousemove", dragging);
|
||
document.addEventListener("mouseup", releasing);
|
||
}
|
||
};
|
||
let mouseUp = _ => {
|
||
document.removeEventListener("mousemove", mouseMove);
|
||
document.removeEventListener("mouseup", mouseUp);
|
||
};
|
||
document.addEventListener("mousemove", mouseMove);
|
||
document.addEventListener("mouseup", mouseUp);
|
||
}
|
||
};
|
||
e.node.addEventListener("mousedown", e.node.PinDMsMouseDownListener);
|
||
}
|
||
}
|
||
if (e.returnvalue) {
|
||
let wrapper = e.returnvalue && e.returnvalue.props.children && e.returnvalue.props.children.props && typeof e.returnvalue.props.children.props.children == "function" ? e.returnvalue.props.children : e.returnvalue;
|
||
if (typeof wrapper.props.children == "function") {
|
||
let childrenRender = wrapper.props.children;
|
||
wrapper.props.children = BDFDB.TimeUtils.suppress((...args) => {
|
||
let children = childrenRender(...args);
|
||
this._processPrivateChannel(e.instance, children, category);
|
||
return children;
|
||
}, "Error in Children Render of PrivateChannel!", this);
|
||
}
|
||
else this._processPrivateChannel(e.instance, wrapper, category);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
_processPrivateChannel (instance, returnvalue, category) {
|
||
let [children, index] = BDFDB.ReactUtils.findParent(returnvalue, {name: "CloseButton"});
|
||
if (index > -1) children.splice(index, 0, BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
|
||
text: BDFDB.LanguageUtils.LanguageStrings.UNPIN,
|
||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Clickable, {
|
||
className: BDFDB.disCN._pindmsunpinbutton,
|
||
onClick: event => {
|
||
BDFDB.ListenerUtils.stopEvent(event);
|
||
this.removeFromCategory(instance.props.channel.id, category, "channelList");
|
||
},
|
||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
|
||
className: BDFDB.disCN._pindmsunpinicon,
|
||
name: BDFDB.LibraryComponents.SvgIcon.Names.PIN
|
||
})
|
||
})
|
||
}));
|
||
}
|
||
|
||
processDirectMessage (e) {
|
||
if (e.instance.props.channel) {
|
||
if (e.node) {
|
||
if (e.methodname == "componentDidMount") {
|
||
BDFDB.DOMUtils.removeClass(e.node, BDFDB.disCN._pindmsrecentpinned);
|
||
if (this.isPinnedInGuilds(e.instance.props.channel.id)) BDFDB.DOMUtils.addClass(e.node, BDFDB.disCN._pindmsrecentpinned);
|
||
}
|
||
if (e.methodname == "componentWillUnmount") {
|
||
if (this.getChannelListCategory(e.instance.props.channel.id)) this.updateContainer("channelList");
|
||
}
|
||
}
|
||
if (e.returnvalue) {
|
||
if (this.settings.general.pinIcon && this.isPinnedInGuilds(e.instance.props.channel.id)) {
|
||
let [children, index] = BDFDB.ReactUtils.findParent(e.returnvalue, {name: "BlobMask"});
|
||
if (index > -1) children[index].props.upperLeftBadge = BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Badges.IconBadge, {
|
||
className: BDFDB.disCN.guildiconbadge,
|
||
disableColor: true,
|
||
style: {transform: "scale(-1, 1)"},
|
||
icon: BDFDB.LibraryComponents.SvgIcon.Names.NOVA_PIN
|
||
});
|
||
}
|
||
if (this.getChannelListCategory(e.instance.props.channel.id)) this.updateContainer("channelList");
|
||
}
|
||
}
|
||
}
|
||
|
||
getPinnedChannels (type) {
|
||
return ((BDFDB.DataUtils.load(this, "pinned", BDFDB.UserUtils.me.id) || {})[type] || {});
|
||
}
|
||
|
||
savePinnedChannels (channels, type) {
|
||
let pinned = BDFDB.DataUtils.load(this, "pinned", BDFDB.UserUtils.me.id) || {};
|
||
if (BDFDB.ObjectUtils.is(channels) && !BDFDB.ObjectUtils.isEmpty(channels)) pinned[type] = channels;
|
||
else delete pinned[type];
|
||
if (!BDFDB.ObjectUtils.isEmpty(pinned)) BDFDB.DataUtils.save(pinned, this, "pinned", BDFDB.UserUtils.me.id);
|
||
else BDFDB.DataUtils.remove(this, "pinned", BDFDB.UserUtils.me.id);
|
||
}
|
||
|
||
generateId (type) {
|
||
if (!type) return null;
|
||
let categories = this.getPinnedChannels(type);
|
||
let id = Math.round(Math.random() * 10000000000000000);
|
||
return categories[id] ? this.generateId() : id.toString();
|
||
}
|
||
|
||
filterDMs (dms, removePredefined) {
|
||
return dms.filter(id => BDFDB.LibraryModules.ChannelStore.getChannel(id) && !(removePredefined && this.getPredefinedCategory(id)));
|
||
}
|
||
|
||
addToCategory (id, category, type) {
|
||
if (!id || !category || !type) return;
|
||
let wasEmpty = !this.filterDMs(category.dms).length;
|
||
if (!category.dms.includes(id)) category.dms.unshift(id);
|
||
this.savePinnedChannels(Object.assign({}, this.getPinnedChannels(type), {[category.id]: category}), type);
|
||
if (wasEmpty && category.dms.length) category.collapsed = false;
|
||
this.updateContainer(type);
|
||
}
|
||
|
||
removeFromCategory (id, category, type) {
|
||
if (!id || !category || !type) return;
|
||
BDFDB.ArrayUtils.remove(category.dms, id, true);
|
||
if (!this.filterDMs(category.dms).length) category.collapsed = true;
|
||
this.savePinnedChannels(Object.assign({}, this.getPinnedChannels(type), {[category.id]: category}), type);
|
||
this.updateContainer(type);
|
||
}
|
||
|
||
getChannelListCategory (id) {
|
||
if (!id) return null;
|
||
let categories = this.getPinnedChannels("channelList");
|
||
for (let catId in categories) if (categories[catId].dms.includes(id)) return categories[catId];
|
||
return null;
|
||
}
|
||
|
||
getPredefinedCategory (id) {
|
||
if (!id || this.getChannelListCategory(id)) return "";
|
||
let channel = BDFDB.LibraryModules.ChannelStore.getChannel(id);
|
||
if (!channel) return "";
|
||
else if (this.settings.preCategories.friends.enabled && channel.isDM() && BDFDB.LibraryModules.RelationshipStore.isFriend(channel.recipients[0])) return "friends";
|
||
else if (this.settings.preCategories.blocked.enabled && channel.isDM() && BDFDB.LibraryModules.RelationshipStore.isBlocked(channel.recipients[0])) return "blocked";
|
||
else if (this.settings.preCategories.bots.enabled && channel.isDM() && (BDFDB.LibraryModules.UserStore.getUser(channel.recipients[0]) || {}).bot) return "bots";
|
||
else if (this.settings.preCategories.groups.enabled && channel.isGroupDM()) return "groups";
|
||
return "";
|
||
}
|
||
|
||
sortAndUpdateCategories (type, reverse) {
|
||
let data = BDFDB.ObjectUtils.sort(this.getPinnedChannels(type), "pos"), newData = {};
|
||
let sorted = [], pos = 0, sort = id => {
|
||
if (sorted[pos] === undefined) {
|
||
newData[id] = Object.assign({}, data[id], {pos});
|
||
sorted[pos] = newData[id];
|
||
}
|
||
else {
|
||
pos++;
|
||
sort(id);
|
||
}
|
||
};
|
||
for (let id in data) sort(id);
|
||
if (!BDFDB.equals(data, newData)) this.savePinnedChannels(newData, type);
|
||
if (type == "channelList" && Object.keys(this.settings.preCategories).some(type => this.settings.preCategories[type].enabled)) {
|
||
let predefinedDMs = {};
|
||
for (let channelId of BDFDB.LibraryModules.DirectMessageStore.getPrivateChannelIds()) {
|
||
let category = this.getPredefinedCategory(channelId);
|
||
if (category) {
|
||
if (!predefinedDMs[category]) predefinedDMs[category] = [];
|
||
predefinedDMs[category].push(channelId);
|
||
}
|
||
}
|
||
for (let type in predefinedDMs) if (predefinedDMs[type].length) sorted.unshift({
|
||
predefined: true,
|
||
collapsed: this.settings.preCategories[type].collapsed,
|
||
color: null,
|
||
dms: predefinedDMs[type],
|
||
id: type,
|
||
name: BDFDB.LanguageUtils.LanguageStringsCheck[this.defaults.preCategories[type].description] ? BDFDB.LanguageUtils.LanguageStrings[this.defaults.preCategories[type].description] : this.defaults.preCategories[type].description
|
||
});
|
||
}
|
||
return (reverse ? sorted.reverse() : sorted).filter(n => n);
|
||
}
|
||
|
||
sortDMsByTime (dms, type) {
|
||
if (dms.length > 1 && this.settings.recentOrder[type]) {
|
||
let timestamps = BDFDB.LibraryModules.DirectMessageStore.getPrivateChannelIds().reduce((newObj, channelId) => (newObj[channelId] = BDFDB.LibraryModules.UnreadChannelUtils.lastMessageId(channelId), newObj), {});
|
||
return [].concat(dms).sort(function (x, y) {
|
||
const xT = parseFloat(timestamps[x]), yT = parseFloat(timestamps[y]);
|
||
return xT > yT ? -1 : xT < yT ? 1 : 0;
|
||
});
|
||
}
|
||
else return dms;
|
||
}
|
||
|
||
openCategorySettingsModal (data, type, isNew) {
|
||
if (!BDFDB.ObjectUtils.is(data) || !type) return;
|
||
let newData = Object.assign({}, data);
|
||
|
||
BDFDB.ModalUtils.open(this, {
|
||
size: "MEDIUM",
|
||
header: BDFDB.LanguageUtils.LanguageStrings.CATEGORY_SETTINGS,
|
||
subHeader: data.name,
|
||
children: [
|
||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormItem, {
|
||
title: BDFDB.LanguageUtils.LanguageStrings.CATEGORY_NAME,
|
||
className: BDFDB.disCN.marginbottom20 + " input-categoryname",
|
||
children: [
|
||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextInput, {
|
||
value: data.name,
|
||
placeholder: data.name,
|
||
autoFocus: true,
|
||
onChange: value => {newData.name = value;}
|
||
}),
|
||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormDivider, {
|
||
className: BDFDB.disCN.dividerdefault
|
||
})
|
||
]
|
||
}),
|
||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormComponents.FormItem, {
|
||
title: this.labels.modal_colorpicker1,
|
||
className: BDFDB.disCN.marginbottom20,
|
||
children: [
|
||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.ColorSwatches, {
|
||
color: data.color,
|
||
onColorChange: value => {newData.color = value;}
|
||
})
|
||
]
|
||
})
|
||
],
|
||
buttons: [{
|
||
contents: isNew ? BDFDB.LanguageUtils.LanguageStrings.CREATE : BDFDB.LanguageUtils.LanguageStrings.SAVE,
|
||
color: "BRAND",
|
||
close: true,
|
||
onClick: _ => {
|
||
if (newData.color != null && !BDFDB.ObjectUtils.is(newData.color)) {
|
||
if (newData.color[0] < 30 && newData.color[1] < 30 && newData.color[2] < 30) newData.color = BDFDB.ColorUtils.change(newData.color, 30);
|
||
else if (newData.color[0] > 225 && newData.color[1] > 225 && newData.color[2] > 225) newData.color = BDFDB.ColorUtils.change(newData.color, -30);
|
||
}
|
||
|
||
this.savePinnedChannels(Object.assign({}, this.getPinnedChannels(type), {[data.id]: newData}), type);
|
||
|
||
this.updateContainer(type);
|
||
}
|
||
}]
|
||
});
|
||
}
|
||
|
||
addPin (id, type) {
|
||
if (!id) return;
|
||
let channels = this.getPinnedChannels(type);
|
||
for (let i in channels) channels[i] = channels[i] + 1;
|
||
channels[id] = 0;
|
||
this.savePinnedChannels(channels, type);
|
||
this.updateContainer(type);
|
||
}
|
||
|
||
removePin (id, type) {
|
||
if (!id) return;
|
||
let channels = this.getPinnedChannels(type);
|
||
delete channels[id];
|
||
this.savePinnedChannels(channels, type);
|
||
this.updateContainer(type);
|
||
}
|
||
|
||
isPinnedInGuilds (id) {
|
||
return this.getPinnedChannels("guildList")[id] != undefined;
|
||
}
|
||
|
||
updateContainer (type) {
|
||
switch (type) {
|
||
case "channelList":
|
||
BDFDB.PatchUtils.forceAllUpdates(this, "PrivateChannelsList");
|
||
if (!Object.keys(this.settings.preCategories).every(type => this.settings.preCategories[type].enabled) && BDFDB.ObjectUtils.isEmpty(this.getPinnedChannels(type))) this.forceUpdateAll();
|
||
break;
|
||
case "guildList":
|
||
BDFDB.GuildUtils.rerenderAll(true);
|
||
break;
|
||
}
|
||
}
|
||
|
||
sortAndUpdate (type) {
|
||
let data = this.getPinnedChannels(type), newData = {};
|
||
delete data[""];
|
||
delete data["null"];
|
||
let sortedDMs = [], existingDMs = [], sortDM = (id, pos) => {
|
||
if (sortedDMs[pos] === undefined) sortedDMs[pos] = id;
|
||
else sortDM(id, pos + 1);
|
||
};
|
||
for (let id in data) sortDM(id, data[id]);
|
||
sortedDMs = sortedDMs.filter(n => n);
|
||
for (let pos in sortedDMs) {
|
||
newData[sortedDMs[pos]] = parseInt(pos);
|
||
if (BDFDB.LibraryModules.ChannelStore.getChannel(sortedDMs[pos])) existingDMs.push(sortedDMs[pos]);
|
||
}
|
||
if (!BDFDB.equals(data, newData)) this.savePinnedChannels(newData, this);
|
||
return this.sortDMsByTime(existingDMs, type);
|
||
}
|
||
|
||
createDragPreview (div, event) {
|
||
if (!Node.prototype.isPrototypeOf(div)) return;
|
||
let dragPreview = div.cloneNode(true);
|
||
BDFDB.DOMUtils.addClass(dragPreview, BDFDB.disCN._pindmsdragpreview);
|
||
BDFDB.DOMUtils.remove(dragPreview.querySelector(BDFDB.dotCNC.guildlowerbadge + BDFDB.dotCNC.guildupperbadge + BDFDB.dotCN.guildpillwrapper));
|
||
document.querySelector(BDFDB.dotCN.appmount).appendChild(dragPreview);
|
||
let rects = BDFDB.DOMUtils.getRects(dragPreview);
|
||
BDFDB.DOMUtils.hide(dragPreview);
|
||
dragPreview.style.setProperty("pointer-events", "none", "important");
|
||
dragPreview.style.setProperty("left", event.clientX - (rects.width/2) + "px", "important");
|
||
dragPreview.style.setProperty("top", event.clientY - (rects.height/2) + "px", "important");
|
||
return dragPreview;
|
||
}
|
||
|
||
updateDragPreview (dragPreview, event) {
|
||
if (!Node.prototype.isPrototypeOf(dragPreview)) return;
|
||
BDFDB.DOMUtils.show(dragPreview);
|
||
let rects = BDFDB.DOMUtils.getRects(dragPreview);
|
||
dragPreview.style.setProperty("left", event.clientX - (rects.width/2) + "px", "important");
|
||
dragPreview.style.setProperty("top", event.clientY - (rects.height/2) + "px", "important");
|
||
}
|
||
|
||
setLabelsByLanguage () {
|
||
switch (BDFDB.LanguageUtils.getLanguage().id) {
|
||
case "bg": // Bulgarian
|
||
return {
|
||
context_addtonewcategory: "Добавяне към нова категория",
|
||
context_disablepredefined: "Деактивирайте предварително определена категория",
|
||
context_pinchannel: "Фиксиране към списъка с канали",
|
||
context_pindm: "Закачете директно съобщение",
|
||
context_pinguild: "Фиксиране към списъка със сървъри",
|
||
context_unpinchannel: "Отделяне от списъка с канали",
|
||
context_unpinguild: "Отделете от списъка със сървъри",
|
||
header_pinneddms: "Закачени директни съобщения",
|
||
modal_colorpicker1: "Категория цвят"
|
||
};
|
||
case "cs": // Czech
|
||
return {
|
||
context_addtonewcategory: "Přidat do nové kategorie",
|
||
context_disablepredefined: "Deaktivovat předdefinovanou kategorii",
|
||
context_pinchannel: "Připnout do seznamu kanálů",
|
||
context_pindm: "Připnout do PZ",
|
||
context_pinguild: "Připnout do seznamu serverů",
|
||
context_unpinchannel: "Odepnout ze seznamu kanálů",
|
||
context_unpinguild: "Odepnout ze seznamu serverů",
|
||
header_pinneddms: "Připnuté přímé zprávy",
|
||
modal_colorpicker1: "Barva kategorie"
|
||
};
|
||
case "da": // Danish
|
||
return {
|
||
context_addtonewcategory: "Føj til ny kategori",
|
||
context_disablepredefined: "Deaktiver foruddefineret kategori",
|
||
context_pinchannel: "Fastgør til kanallisten",
|
||
context_pindm: "Pin direkte besked",
|
||
context_pinguild: "Fastgør til serverlisten",
|
||
context_unpinchannel: "Fjern fra kanallisten",
|
||
context_unpinguild: "Fjern fra serverlisten",
|
||
header_pinneddms: "Fastgjorte direkte beskeder",
|
||
modal_colorpicker1: "Kategorifarve"
|
||
};
|
||
case "de": // German
|
||
return {
|
||
context_addtonewcategory: "Zur neuen Kategorie hinzufügen",
|
||
context_disablepredefined: "Vordefinierte Kategorie deaktivieren",
|
||
context_pinchannel: "An Kanalliste anheften",
|
||
context_pindm: "Direktnachricht anheften",
|
||
context_pinguild: "An Serverliste anheften",
|
||
context_unpinchannel: "Von Kanalliste loslösen",
|
||
context_unpinguild: "Von Serverliste loslösen",
|
||
header_pinneddms: "Gepinnte Direktnachrichten",
|
||
modal_colorpicker1: "Kategoriefarbe"
|
||
};
|
||
case "el": // Greek
|
||
return {
|
||
context_addtonewcategory: "Προσθήκη σε νέα κατηγορία",
|
||
context_disablepredefined: "Απενεργοποίηση προκαθορισμένης κατηγορίας",
|
||
context_pinchannel: "Καρφίτσωμα στη λίστα καναλιών",
|
||
context_pindm: "Καρφιτσώστε το άμεσο μήνυμα",
|
||
context_pinguild: "Καρφίτσωμα στη λίστα διακομιστών",
|
||
context_unpinchannel: "Αποσύνδεση από τη λίστα καναλιών",
|
||
context_unpinguild: "Αποσύνδεση από τη λίστα διακομιστών",
|
||
header_pinneddms: "Καρφιτσωμένα άμεσα μηνύματα",
|
||
modal_colorpicker1: "Χρώμα κατηγορίας"
|
||
};
|
||
case "es": // Spanish
|
||
return {
|
||
context_addtonewcategory: "Agregar a una nueva categoría",
|
||
context_disablepredefined: "Desactivar categoría predefinida",
|
||
context_pinchannel: "Anclar a la lista de canales",
|
||
context_pindm: "Pin de mensaje directo",
|
||
context_pinguild: "Anclar a la lista de servidores",
|
||
context_unpinchannel: "Separar de la lista de canales",
|
||
context_unpinguild: "Separar de la lista de servidores",
|
||
header_pinneddms: "Mensajes directos fijados",
|
||
modal_colorpicker1: "Color de categoría"
|
||
};
|
||
case "fi": // Finnish
|
||
return {
|
||
context_addtonewcategory: "Lisää uuteen luokkaan",
|
||
context_disablepredefined: "Poista ennalta määritetty luokka käytöstä",
|
||
context_pinchannel: "Kiinnitä kanavaluetteloon",
|
||
context_pindm: "Kiinnitä suora viesti",
|
||
context_pinguild: "Kiinnitä palvelinluetteloon",
|
||
context_unpinchannel: "Irrota kanavaluettelosta",
|
||
context_unpinguild: "Irrota palvelinluettelosta",
|
||
header_pinneddms: "Kiinnitetyt suorat viestit",
|
||
modal_colorpicker1: "Luokan väri"
|
||
};
|
||
case "fr": // French
|
||
return {
|
||
context_addtonewcategory: "Ajouter à une nouvelle catégorie",
|
||
context_disablepredefined: "Désactiver la catégorie prédéfinie",
|
||
context_pinchannel: "Épingler à la liste des salons",
|
||
context_pindm: "Épingler le message privé",
|
||
context_pinguild: "Épingler à la liste des serveurs",
|
||
context_unpinchannel: "Détacher de la liste des salons",
|
||
context_unpinguild: "Détacher de la liste des serveurs",
|
||
header_pinneddms: "Messages privés épinglés",
|
||
modal_colorpicker1: "Couleur de la catégorie"
|
||
};
|
||
case "hi": // Hindi
|
||
return {
|
||
context_addtonewcategory: "नई श्रेणी में जोड़ें",
|
||
context_disablepredefined: "पूर्वनिर्धारित श्रेणी को निष्क्रिय करें",
|
||
context_pinchannel: "चैनल सूची में पिन करें",
|
||
context_pindm: "पिन डीएम",
|
||
context_pinguild: "सर्वर सूची में पिन करें",
|
||
context_unpinchannel: "चैनल सूची से अलग करें",
|
||
context_unpinguild: "सर्वर सूची से अलग करें",
|
||
header_pinneddms: "पिन किए गए सीधे संदेश",
|
||
modal_colorpicker1: "श्रेणी रंग"
|
||
};
|
||
case "hr": // Croatian
|
||
return {
|
||
context_addtonewcategory: "Dodaj u novu kategoriju",
|
||
context_disablepredefined: "Deaktivirajte unaprijed definiranu kategoriju",
|
||
context_pinchannel: "Prikvači na popis kanala",
|
||
context_pindm: "Prikvači izravnu poruku",
|
||
context_pinguild: "Prikvači na popis poslužitelja",
|
||
context_unpinchannel: "Odvojite se od popisa kanala",
|
||
context_unpinguild: "Odvojite se od popisa poslužitelja",
|
||
header_pinneddms: "Prikvačene izravne poruke",
|
||
modal_colorpicker1: "Boja kategorije"
|
||
};
|
||
case "hu": // Hungarian
|
||
return {
|
||
context_addtonewcategory: "Hozzáadás új kategóriához",
|
||
context_disablepredefined: "Deaktiválja az előre definiált kategóriát",
|
||
context_pinchannel: "Rögzítés a csatornalistához",
|
||
context_pindm: "Közvetlen üzenet rögzítése",
|
||
context_pinguild: "Rögzítés a kiszolgáló listához",
|
||
context_unpinchannel: "Leválasztás a csatornalistáról",
|
||
context_unpinguild: "Leválasztás a kiszolgáló listáról",
|
||
header_pinneddms: "Rögzített közvetlen üzenetek",
|
||
modal_colorpicker1: "Kategória színe"
|
||
};
|
||
case "it": // Italian
|
||
return {
|
||
context_addtonewcategory: "Aggiungi a una nuova categoria",
|
||
context_disablepredefined: "Disattiva la categoria predefinita",
|
||
context_pinchannel: "Fissa all'elenco dei canali",
|
||
context_pindm: "Metti il messaggio diretto",
|
||
context_pinguild: "Aggiungi all'elenco dei server",
|
||
context_unpinchannel: "Scollega dall'elenco dei canali",
|
||
context_unpinguild: "Scollega dall'elenco dei server",
|
||
header_pinneddms: "Messaggi diretti appuntati",
|
||
modal_colorpicker1: "Colore della categoria"
|
||
};
|
||
case "ja": // Japanese
|
||
return {
|
||
context_addtonewcategory: "新しいカテゴリに追加",
|
||
context_disablepredefined: "事前定義されたカテゴリを非アクティブ化",
|
||
context_pinchannel: "チャネルリストに固定",
|
||
context_pindm: "ダイレクトメッセージを固定する",
|
||
context_pinguild: "サーバーリストに固定する",
|
||
context_unpinchannel: "チャネルリストから切り離す",
|
||
context_unpinguild: "サーバーリストから切り離す",
|
||
header_pinneddms: "固定されたダイレクトメッセージ",
|
||
modal_colorpicker1: "カテゴリカラー"
|
||
};
|
||
case "ko": // Korean
|
||
return {
|
||
context_addtonewcategory: "새 카테고리에 추가",
|
||
context_disablepredefined: "사전 정의 된 카테고리 비활성화",
|
||
context_pinchannel: "채널 목록에 고정",
|
||
context_pindm: "개인 메시지 고정",
|
||
context_pinguild: "서버 목록에 고정",
|
||
context_unpinchannel: "채널 목록에서 분리",
|
||
context_unpinguild: "서버 목록에서 분리",
|
||
header_pinneddms: "고정 된 개인 메시지",
|
||
modal_colorpicker1: "카테고리 색상"
|
||
};
|
||
case "lt": // Lithuanian
|
||
return {
|
||
context_addtonewcategory: "Pridėti prie naujos kategorijos",
|
||
context_disablepredefined: "Išjunkite iš anksto nustatytą kategoriją",
|
||
context_pinchannel: "Prisegti prie kanalų sąrašo",
|
||
context_pindm: "Prisegti tiesioginį pranešimą",
|
||
context_pinguild: "Prisegti prie serverio sąrašo",
|
||
context_unpinchannel: "Atsijungti nuo kanalų sąrašo",
|
||
context_unpinguild: "Atsijungti nuo serverio sąrašo",
|
||
header_pinneddms: "Prisegti tiesioginiai pranešimai",
|
||
modal_colorpicker1: "Kategorijos spalva"
|
||
};
|
||
case "nl": // Dutch
|
||
return {
|
||
context_addtonewcategory: "Toevoegen aan nieuwe categorie",
|
||
context_disablepredefined: "Schakel de voorgedefinieerde categorie uit",
|
||
context_pinchannel: "Vastzetten op kanalenlijst",
|
||
context_pindm: "Direct bericht vastzetten",
|
||
context_pinguild: "Vastzetten op serverlijst",
|
||
context_unpinchannel: "Maak los van de zenderlijst",
|
||
context_unpinguild: "Maak los van de serverlijst",
|
||
header_pinneddms: "Vastgezette directe berichten",
|
||
modal_colorpicker1: "Categorie kleur"
|
||
};
|
||
case "no": // Norwegian
|
||
return {
|
||
context_addtonewcategory: "Legg til i ny kategori",
|
||
context_disablepredefined: "Deaktiver forhåndsdefinert kategori",
|
||
context_pinchannel: "Fest til kanallisten",
|
||
context_pindm: "Fest direkte melding",
|
||
context_pinguild: "Fest til serverlisten",
|
||
context_unpinchannel: "Koble fra kanallisten",
|
||
context_unpinguild: "Koble fra serverlisten",
|
||
header_pinneddms: "Festede direktemeldinger",
|
||
modal_colorpicker1: "Kategorifarge"
|
||
};
|
||
case "pl": // Polish
|
||
return {
|
||
context_addtonewcategory: "Dodaj do nowej kategorii",
|
||
context_disablepredefined: "Dezaktywuj predefiniowaną kategorię",
|
||
context_pinchannel: "Przypnij do listy kanałów",
|
||
context_pindm: "Przypnij bezpośrednią wiadomość",
|
||
context_pinguild: "Przypnij do listy serwerów",
|
||
context_unpinchannel: "Odłącz od listy kanałów",
|
||
context_unpinguild: "Odłącz od listy serwerów",
|
||
header_pinneddms: "Przypięte czaty",
|
||
modal_colorpicker1: "Kolor kategorii"
|
||
};
|
||
case "pt-BR": // Portuguese (Brazil)
|
||
return {
|
||
context_addtonewcategory: "Adicionar à nova categoria",
|
||
context_disablepredefined: "Desativar categoria predefinida",
|
||
context_pinchannel: "Fixar na lista de canais",
|
||
context_pindm: "Fixar mensagem direta",
|
||
context_pinguild: "Fixar na lista de servidores",
|
||
context_unpinchannel: "Desanexar da lista de canais",
|
||
context_unpinguild: "Desanexar da lista de servidores",
|
||
header_pinneddms: "Mensagens diretas fixadas",
|
||
modal_colorpicker1: "Cor da categoria"
|
||
};
|
||
case "ro": // Romanian
|
||
return {
|
||
context_addtonewcategory: "Adăugați la o nouă categorie",
|
||
context_disablepredefined: "Dezactivați categoria predefinită",
|
||
context_pinchannel: "Fixați în lista de canale",
|
||
context_pindm: "Fixați mesajul direct",
|
||
context_pinguild: "Fixați pe lista serverului",
|
||
context_unpinchannel: "Desprindeți din lista de canale",
|
||
context_unpinguild: "Desprindeți din lista serverelor",
|
||
header_pinneddms: "Mesaje directe fixate",
|
||
modal_colorpicker1: "Culoarea categoriei"
|
||
};
|
||
case "ru": // Russian
|
||
return {
|
||
context_addtonewcategory: "Добавить в новую категорию",
|
||
context_disablepredefined: "Отключить предопределенную категорию",
|
||
context_pinchannel: "Закрепить в списке каналов",
|
||
context_pindm: "Закрепить прямую переписку",
|
||
context_pinguild: "Закрепить в списке серверов",
|
||
context_unpinchannel: "Отключить от списка каналов",
|
||
context_unpinguild: "Отключить от списка серверов",
|
||
header_pinneddms: "Закрепленные личные сообщения",
|
||
modal_colorpicker1: "Цвет категории"
|
||
};
|
||
case "sv": // Swedish
|
||
return {
|
||
context_addtonewcategory: "Lägg till i ny kategori",
|
||
context_disablepredefined: "Inaktivera fördefinierad kategori",
|
||
context_pinchannel: "Fäst i kanallistan",
|
||
context_pindm: "Fäst direktmeddelande",
|
||
context_pinguild: "Fäst i serverlistan",
|
||
context_unpinchannel: "Ta bort från kanallistan",
|
||
context_unpinguild: "Ta bort från serverlistan",
|
||
header_pinneddms: "Fästa direktmeddelanden",
|
||
modal_colorpicker1: "Kategorifärg"
|
||
};
|
||
case "th": // Thai
|
||
return {
|
||
context_addtonewcategory: "เพิ่มในหมวดหมู่ใหม่",
|
||
context_disablepredefined: "ปิดใช้งานหมวดหมู่ที่กำหนดไว้ล่วงหน้า",
|
||
context_pinchannel: "ตรึงในรายการช่อง",
|
||
context_pindm: "ตรึงข้อความโดยตรง",
|
||
context_pinguild: "ปักหมุดรายการเซิร์ฟเวอร์",
|
||
context_unpinchannel: "แยกออกจากรายการช่อง",
|
||
context_unpinguild: "แยกออกจากรายการเซิร์ฟเวอร์",
|
||
header_pinneddms: "ข้อความโดยตรงที่ตรึงไว้",
|
||
modal_colorpicker1: "สีหมวดหมู่"
|
||
};
|
||
case "tr": // Turkish
|
||
return {
|
||
context_addtonewcategory: "Yeni kategoriye ekle",
|
||
context_disablepredefined: "Önceden tanımlanmış kategoriyi devre dışı bırakın",
|
||
context_pinchannel: "Kanal listesine sabitle",
|
||
context_pindm: "Doğrudan mesajı sabitle",
|
||
context_pinguild: "Sunucu listesine sabitle",
|
||
context_unpinchannel: "Kanal listesinden çıkar",
|
||
context_unpinguild: "Sunucu listesinden ayır",
|
||
header_pinneddms: "Sabitlenmiş doğrudan mesajlar",
|
||
modal_colorpicker1: "Kategori rengi"
|
||
};
|
||
case "uk": // Ukrainian
|
||
return {
|
||
context_addtonewcategory: "Додати до нової категорії",
|
||
context_disablepredefined: "Вимкнути заздалегідь визначену категорію",
|
||
context_pinchannel: "Закріпити в списку каналів",
|
||
context_pindm: "Закріпити пряме повідомлення",
|
||
context_pinguild: "Закріпити на списку серверів",
|
||
context_unpinchannel: "Від’єднати від списку каналів",
|
||
context_unpinguild: "Від'єднати від списку серверів",
|
||
header_pinneddms: "Закріплені прямі повідомлення",
|
||
modal_colorpicker1: "Колір категорії"
|
||
};
|
||
case "vi": // Vietnamese
|
||
return {
|
||
context_addtonewcategory: "Thêm vào danh mục mới",
|
||
context_disablepredefined: "Hủy kích hoạt danh mục xác định trước",
|
||
context_pinchannel: "Ghim vào danh sách kênh",
|
||
context_pindm: "Ghim tin nhắn trực tiếp",
|
||
context_pinguild: "Ghim vào danh sách máy chủ",
|
||
context_unpinchannel: "Tách khỏi danh sách kênh",
|
||
context_unpinguild: "Tách khỏi danh sách máy chủ",
|
||
header_pinneddms: "Tin nhắn trực tiếp được ghim",
|
||
modal_colorpicker1: "Màu sắc"
|
||
};
|
||
case "zh-CN": // Chinese (China)
|
||
return {
|
||
context_addtonewcategory: "添加到新类别",
|
||
context_disablepredefined: "停用预定义类别",
|
||
context_pinchannel: "固定到频道列表",
|
||
context_pindm: "固定直接讯息",
|
||
context_pinguild: "固定到服务器列表",
|
||
context_unpinchannel: "从频道列表中分离",
|
||
context_unpinguild: "从服务器列表中分离",
|
||
header_pinneddms: "固定直接讯息",
|
||
modal_colorpicker1: "类别颜色"
|
||
};
|
||
case "zh-TW": // Chinese (Taiwan)
|
||
return {
|
||
context_addtonewcategory: "添加到新類別",
|
||
context_disablepredefined: "停用預定義類別",
|
||
context_pinchannel: "固定到頻道列表",
|
||
context_pindm: "固定直接訊息",
|
||
context_pinguild: "固定到服務器列表",
|
||
context_unpinchannel: "從頻道列表中分離",
|
||
context_unpinguild: "從服務器列表中分離",
|
||
header_pinneddms: "固定直接訊息",
|
||
modal_colorpicker1: "類別顏色"
|
||
};
|
||
default: // English
|
||
return {
|
||
context_addtonewcategory: "Add to new Category",
|
||
context_disablepredefined: "Deactivate predefined Category",
|
||
context_pinchannel: "Pin to Channel List",
|
||
context_pindm: "Pin DM",
|
||
context_pinguild: "Pin to Server List",
|
||
context_unpinchannel: "Detach from Channel List",
|
||
context_unpinguild: "Detach from Server List",
|
||
header_pinneddms: "Pinned Direct Messages",
|
||
modal_colorpicker1: "Category Color"
|
||
};
|
||
}
|
||
}
|
||
};
|
||
})(window.BDFDB_Global.PluginUtils.buildPlugin(changeLog));
|
||
})();
|