BetterDiscordAddons/Plugins/PinDMs/PinDMs.plugin.js

1306 lines
64 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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));
})();