-
Notifications
You must be signed in to change notification settings - Fork 63
Updated color-me module #206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: closed-source-sync-july
Are you sure you want to change the base?
Changes from all commits
416e14e
aed8314
71d25b4
457c1b0
e0324c0
ab0fe07
d731fef
53bda0e
a199239
7c4a2de
7d169c5
e08d187
9772e66
7eb74cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,6 +1,7 @@ | ||||||
| const {localize} = require('../../../src/functions/localize'); | ||||||
| const {client} = require('../../../main'); | ||||||
| const {embedType, dateToDiscordTimestamp} = require('../../../src/functions/helpers'); | ||||||
| const { Constants } = require('discord.js'); | ||||||
|
|
||||||
| module.exports.beforeSubcommand = async function (interaction) { | ||||||
| await interaction.deferReply({ephemeral: true}); | ||||||
|
|
@@ -10,6 +11,7 @@ module.exports.subcommands = { | |||||
| 'manage': async function (interaction) { | ||||||
| let roleIcon; | ||||||
| let iconW = true; | ||||||
| let colorfulW = true; | ||||||
| if (interaction.options.getAttachment('icon') !== null) { | ||||||
| if (client.guild.features.includes('ROLE_ICONS')) { | ||||||
| roleIcon = interaction.options.getAttachment('icon').url; | ||||||
|
|
@@ -22,6 +24,11 @@ module.exports.subcommands = { | |||||
| const moduleStrings = interaction.client.configurations['color-me']['strings']; | ||||||
| const moduleModel = interaction.client.models['color-me']['Role']; | ||||||
|
|
||||||
| const multiColor = client.guild.features.includes('ENHANCED_ROLE_COLORS') && moduleConf['allowEnhancedRoleColors']; | ||||||
| if (!multiColor && (interaction.options.getString('secondary-color') !== null || interaction.options.getBoolean('holographic'))) { | ||||||
| colorfulW = false; | ||||||
| } | ||||||
|
|
||||||
| const pos = moduleConf.rolePosition | ||||||
| ? interaction.guild.roles.resolve(moduleConf.rolePosition).position | ||||||
| : 0; | ||||||
|
|
@@ -44,29 +51,62 @@ module.exports.subcommands = { | |||||
| userID: interaction.user.id | ||||||
| } | ||||||
| }); | ||||||
| const { | ||||||
| roleColor: primaryColor, | ||||||
| cancel | ||||||
| } = await color(interaction.options.getString('primary-color'), interaction, moduleStrings); | ||||||
|
|
||||||
| let secondaryColor, cancelSec; | ||||||
| if (multiColor) { | ||||||
| let { | ||||||
| roleColor: secondaryColorTemp, | ||||||
| cancel: cancelSecTemp | ||||||
| } = await color(interaction.options.getString('secondary-color'), interaction, moduleStrings); | ||||||
| secondaryColor = secondaryColorTemp; | ||||||
| cancelSec = cancelSecTemp; | ||||||
| } else { | ||||||
| secondaryColor = null; | ||||||
| } | ||||||
| if (cancel || cancelSec) return; | ||||||
| const isHolographic = interaction.options.getBoolean('holographic') && multiColor; | ||||||
| if (role) { | ||||||
| role = role.roleID; | ||||||
| const { | ||||||
| roleColor, | ||||||
| cancel | ||||||
| } = await color(interaction, moduleStrings); | ||||||
| if (cancel) return; | ||||||
| if (interaction.guild.roles.cache.find(r => r.id === role)) { | ||||||
| role = interaction.guild.roles.resolve(role); | ||||||
| role.edit( | ||||||
| await role.edit( | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Blocking -
const clone = role._clone();
clone._patch(d);
return clone;and That means at line 96-99 Assigning the return value fixes it:
Suggested change
|
||||||
| { | ||||||
| name: interaction.options.getString('name'), | ||||||
| color: roleColor, | ||||||
| colors: isHolographic ? { | ||||||
| primaryColor: Constants.HolographicStyle.Primary, | ||||||
| secondaryColor: Constants.HolographicStyle.Secondary, | ||||||
| tertiaryColor: Constants.HolographicStyle.Tertiary | ||||||
| } : { | ||||||
| primaryColor: primaryColor, | ||||||
| secondaryColor: secondaryColor | ||||||
| }, | ||||||
| icon: roleIcon, | ||||||
| reason: localize('color-me', 'edit-log-reason', { | ||||||
| user: interaction.user.username | ||||||
| }) | ||||||
| } | ||||||
| ); | ||||||
|
hfgd123 marked this conversation as resolved.
|
||||||
| if (iconW) { | ||||||
| await moduleModel.update({ | ||||||
| userID: interaction.user.id, | ||||||
| roleID: role.id, | ||||||
| name: role.name, | ||||||
| primaryColor: role.colors.primaryColor, | ||||||
| secondaryColor: role.colors.secondaryColor, | ||||||
| holo: !!role.colors.tertiaryColor, | ||||||
|
Comment on lines
+97
to
+99
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Blocking - these write raw integers into a
It also splits the column into two formats: rows migrated from the old Storing hex keeps the column single-format and needs no value migration. There's only a const toHex = (c) => (c === null || c === undefined ? null : '#' + c.toString(16).padStart(6, '0'));then |
||||||
| timestamp: new Date() | ||||||
| }, { | ||||||
| where: { | ||||||
| userID: interaction.user.id | ||||||
| } | ||||||
| }); | ||||||
| if (iconW && colorfulW) { | ||||||
| await interaction.editReply(embedType(moduleStrings['updated'], {})); | ||||||
| } else { | ||||||
| await interaction.editReply(embedType(moduleStrings['updatedNoIcon'], {})); | ||||||
| await interaction.editReply(embedType(moduleStrings['updatedLimited'], {})); | ||||||
| } | ||||||
| } else { | ||||||
| if (interaction.guild.roles.cache.size >= 250) { | ||||||
|
|
@@ -76,7 +116,14 @@ module.exports.subcommands = { | |||||
| role = await interaction.guild.roles.create( | ||||||
| { | ||||||
| name: interaction.options.getString('name'), | ||||||
| color: roleColor, | ||||||
| colors: isHolographic ? { | ||||||
| primaryColor: Constants.HolographicStyle.Primary, | ||||||
| secondaryColor: Constants.HolographicStyle.Secondary, | ||||||
| tertiaryColor: Constants.HolographicStyle.Tertiary | ||||||
| } : { | ||||||
| primaryColor: primaryColor, | ||||||
| secondaryColor: secondaryColor | ||||||
| }, | ||||||
| icon: roleIcon, | ||||||
| hoist: moduleConf.listRoles, | ||||||
| permissions: '', | ||||||
|
|
@@ -85,13 +132,14 @@ module.exports.subcommands = { | |||||
| reason: localize('color-me', 'create-log-reason', { | ||||||
| user: interaction.user.username | ||||||
| }) | ||||||
| } | ||||||
| ); | ||||||
| }); | ||||||
| await moduleModel.update({ | ||||||
| userID: interaction.user.id, | ||||||
| roleID: role.id, | ||||||
| name: role.name, | ||||||
| color: role.hexColor, | ||||||
| primaryColor: role.colors.primaryColor, | ||||||
| secondaryColor: role.colors.secondaryColor, | ||||||
| holo: !!role.colors.tertiaryColor, | ||||||
|
Comment on lines
+140
to
+142
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same integer-vs-hex problem as line 97 - this is the create-after-record-exists path. |
||||||
| timestamp: new Date() | ||||||
| }, { | ||||||
| where: { | ||||||
|
|
@@ -101,23 +149,25 @@ module.exports.subcommands = { | |||||
| if (!interaction.member.roles.cache.has(role)) { | ||||||
| await interaction.member.roles.add(role); | ||||||
| } | ||||||
| if (iconW) { | ||||||
| if (iconW && colorfulW) { | ||||||
| await interaction.editReply(embedType(moduleStrings['updated'], {})); | ||||||
| } else { | ||||||
| await interaction.editReply(embedType(moduleStrings['updatedNoIcon'], {})); | ||||||
| await interaction.editReply(embedType(moduleStrings['updatedLimited'], {})); | ||||||
| } | ||||||
| } | ||||||
| } else { | ||||||
| const { | ||||||
| roleColor, | ||||||
| cancel | ||||||
| } = await color(interaction, moduleStrings); | ||||||
| if (cancel) return; | ||||||
| try { | ||||||
| role = await interaction.guild.roles.create( | ||||||
| { | ||||||
| name: interaction.options.getString('name'), | ||||||
| color: roleColor, | ||||||
| colors: isHolographic ? { | ||||||
| primaryColor: Constants.HolographicStyle.Primary, | ||||||
| secondaryColor: Constants.HolographicStyle.Secondary, | ||||||
| tertiaryColor: Constants.HolographicStyle.Tertiary | ||||||
| } : { | ||||||
| primaryColor: primaryColor, | ||||||
| secondaryColor: secondaryColor | ||||||
| }, | ||||||
| icon: roleIcon, | ||||||
| hoist: moduleConf.listRoles, | ||||||
| permissions: '', | ||||||
|
|
@@ -132,11 +182,13 @@ module.exports.subcommands = { | |||||
| userID: interaction.user.id, | ||||||
| roleID: role.id, | ||||||
| name: role.name, | ||||||
| color: role.hexColor, | ||||||
| primaryColor: role.colors.primaryColor, | ||||||
| secondaryColor: role.colors.secondaryColor, | ||||||
| holo: !!role.colors.tertiaryColor, | ||||||
|
Comment on lines
+185
to
+187
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same integer-vs-hex problem again - the first-time create path. |
||||||
| timestamp: new Date() | ||||||
| }); | ||||||
| await interaction.member.roles.add(role); | ||||||
| if (iconW) { | ||||||
| if (iconW && colorfulW) { | ||||||
| await interaction.editReply(embedType(moduleStrings['created'], {})); | ||||||
| } else { | ||||||
| await interaction.editReply(embedType(moduleStrings['createdNoIcon'], {})); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
So a user who asks for holographic on a non-enhanced guild is told their icon was dropped. |
||||||
|
|
@@ -168,7 +220,7 @@ module.exports.subcommands = { | |||||
| role = role.roleID; | ||||||
| if (interaction.guild.roles.cache.find(r => r.id === role)) { | ||||||
| role = interaction.guild.roles.resolve(role); | ||||||
| role.delete(localize('color-me', 'delete-manual-log-reason', { | ||||||
| await role.delete(localize('color-me', 'delete-manual-log-reason', { | ||||||
| user: interaction.member.user.username | ||||||
| })); | ||||||
| await interaction.editReply(await embedType(moduleStrings['removed'], {})); | ||||||
|
|
@@ -196,8 +248,20 @@ module.exports.config = { | |||||
| { | ||||||
| type: 'STRING', | ||||||
| required: false, | ||||||
| name: 'color', | ||||||
| description: localize('color-me', 'color-option-description') | ||||||
| name: 'primary-color', | ||||||
| description: localize('color-me', 'primary-color-option-description') | ||||||
| }, | ||||||
| { | ||||||
| type: 'STRING', | ||||||
| required: false, | ||||||
| name: 'secondary-color', | ||||||
| description: localize('color-me', 'secondary-color-option-description') | ||||||
| }, | ||||||
| { | ||||||
| type: 'BOOLEAN', | ||||||
| required: false, | ||||||
| name: 'holographic', | ||||||
| description: localize('color-me', 'holographic-option-description') | ||||||
| }, | ||||||
| { | ||||||
| type: 'ATTACHMENT', | ||||||
|
|
@@ -227,9 +291,9 @@ module.exports.config = { | |||||
| * Gets a color from the String of a command option | ||||||
| * @returns {Promise<{roleColor: string|number, cancel: boolean}>} | ||||||
| */ | ||||||
| async function color(interaction, moduleStrings) { | ||||||
| if (interaction.options.getString('color')) { | ||||||
| let roleColor = interaction.options.getString('color'); | ||||||
| async function color(colorString, interaction, moduleStrings) { | ||||||
| if (colorString) { | ||||||
| let roleColor = colorString; | ||||||
| if (!roleColor.startsWith('#')) { | ||||||
| roleColor = '#' + roleColor; | ||||||
| } | ||||||
|
|
@@ -246,12 +310,12 @@ async function color(interaction, moduleStrings) { | |||||
| }; | ||||||
| } | ||||||
| return { | ||||||
| roleColor: 0xF1C40F, | ||||||
| roleColor: 0x000000, | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This flips the default from gold to colorless for every role created or edited without It's arguably the better default (Discord renders |
||||||
| cancel: false | ||||||
| }; | ||||||
| } | ||||||
|
|
||||||
| // Exported for unit testing of the colour-validation logic. | ||||||
| // Exported for unit testing of the color-validation logic. | ||||||
| module.exports.color = color; | ||||||
|
|
||||||
| /** | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,13 @@ | |
| "default": "", | ||
| "description": "The role, beneath which the custom-roles should be created", | ||
| "type": "roleID" | ||
| }, | ||
| { | ||
| "name": "allowEnhancedRoleColors", | ||
| "humanName": "Allow \"Enhanced Role Colors\"", | ||
| "default": true, | ||
| "description": "Should the module allow users to use the \"Enhanced Role Colors\" feature? (If your server doesn't have this feature unlocked, this setting will have no effect)", | ||
| "type": "boolean" | ||
| } | ||
|
Comment on lines
+41
to
47
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Nothing crashes ( |
||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,10 +28,10 @@ | |
| "allowEmbed": true | ||
| }, | ||
| { | ||
| "name": "updatedNoIcon", | ||
| "humanName": "Role updated without icon", | ||
| "default": "Your role was updated successfully, but your role icon was not used, as this requires the guild to be boost level 2 or higher.", | ||
| "description": "This messages gets send when a booster sucessfully updates their custom role, but the guild has not enough boosts to use role icons", | ||
| "name": "updatedLimited", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Heads-up rather than a change request: renaming the key means any server that customised |
||
| "humanName": "Role updated with limited features", | ||
| "default": "Your role was updated successfully, but either your role icon or enhanced role colors were not used, as these features either need to be unlocked by boosting the server or were disabled by the server admin.", | ||
| "description": "This message is sent when a booster successfully updates their custom role, but the guild does not have enough boosts to use role icons or enhanced role colors, or the feature was disabled in the module configuration", | ||
| "type": "string", | ||
| "allowEmbed": true | ||
| }, | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,5 @@ | ||||||||
| const {localize} = require('../../../src/functions/localize'); | ||||||||
| const {Constants} = require('discord.js'); | ||||||||
| let pos; | ||||||||
|
|
||||||||
| module.exports.run = async function (client, oldGuildMember, newGuildMember) { | ||||||||
|
|
@@ -36,7 +37,7 @@ module.exports.run = async function (client, oldGuildMember, newGuildMember) { | |||||||
| if (moduleConf.recreateRole) { | ||||||||
| if (!oldGuildMember.premiumSince && newGuildMember.premiumSince) { | ||||||||
| const data = await client.models['color-me']['Role'].findOne({ | ||||||||
| attributes: ['roleID', 'name', 'color'], | ||||||||
| attributes: ['roleID', 'name', 'primaryColor', 'secondaryColor', 'holo'], | ||||||||
| raw: true, | ||||||||
| where: { | ||||||||
| userID: newGuildMember.id | ||||||||
|
|
@@ -45,12 +46,21 @@ module.exports.run = async function (client, oldGuildMember, newGuildMember) { | |||||||
| if (data) { | ||||||||
| let role = data.roleID; | ||||||||
| const name = data.name; | ||||||||
| const color = data.color; | ||||||||
| const primaryColor = data.primaryColor; | ||||||||
| const secondaryColor = data.secondaryColor; | ||||||||
| const isHolographic = data.holo && client.guild.features.includes('ENHANCED_ROLE_COLORS'); | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
| if (!newGuildMember.guild.roles.cache.find(r => r.id === role)) { | ||||||||
| role = await client.guild.roles.create( | ||||||||
| { | ||||||||
| name: name, | ||||||||
| color: color, | ||||||||
| colors: isHolographic ? { | ||||||||
| primaryColor: Constants.HolographicStyle.Primary, | ||||||||
| secondaryColor: Constants.HolographicStyle.Secondary, | ||||||||
| tertiaryColor: Constants.HolographicStyle.Tertiary | ||||||||
| } : { | ||||||||
| primaryColor: primaryColor, | ||||||||
| secondaryColor: client.guild.features.includes('ENHANCED_ROLE_COLORS') ? secondaryColor : null | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Follow-on from line 51 - this one also needs to respect
Suggested change
|
||||||||
| }, | ||||||||
| hoist: moduleConf.listRoles, | ||||||||
| position: pos, | ||||||||
| permissions: '', | ||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| const {DataTypes} = require('sequelize'); | ||
|
|
||
| const TABLE = 'colorme_Role'; | ||
|
|
||
| module.exports = { | ||
| // Tables to snapshot before this migration runs (see Backups). Optional but recommended. | ||
| tables: [TABLE], | ||
|
|
||
| up: async ({context: {queryInterface, sequelize}}) => { | ||
| await sequelize.transaction(async (transaction) => { | ||
| const description = await queryInterface.describeTable(TABLE).catch(() => ({})); | ||
|
|
||
| if (!description.primaryColor && description.color) { | ||
| await queryInterface.renameColumn(TABLE, 'color', 'primaryColor', {transaction}); | ||
| } | ||
| if (!description.secondaryColor) { | ||
| await queryInterface.addColumn(TABLE, 'secondaryColor', { | ||
| type: DataTypes.STRING | ||
| }, {transaction}); | ||
| } | ||
| if (!description.holo) { | ||
| await queryInterface.addColumn(TABLE, 'holo', { | ||
|
hfgd123 marked this conversation as resolved.
|
||
| defaultValue: false, | ||
| type: DataTypes.BOOLEAN | ||
| }, {transaction}); | ||
| } | ||
| }); | ||
| }, | ||
|
|
||
| down: async ({context: {queryInterface, sequelize}}) => { | ||
| await sequelize.transaction(async (transaction) => { | ||
| const description = await queryInterface.describeTable(TABLE).catch(() => ({})); | ||
| if (description.primaryColor && !description.color) await queryInterface.renameColumn(TABLE, 'primaryColor', 'color', {transaction}); | ||
| if (description.secondaryColor) await queryInterface.removeColumn(TABLE, 'secondaryColor', {transaction}); | ||
| if (description.holo) await queryInterface.removeColumn(TABLE, 'holo', {transaction}); | ||
| }); | ||
| } | ||
| }; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: no trailing newline. ( |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit:
const { Constants }here vsconst {Constants}inguildMemberUpdate.js:2and the rest of the codebase.@stylistic/object-curly-spacingis off so lint won't catch it.