Merge pull request #79 from DarkView/k30_pingableRoles

[K30] Migrated PingableRoles
This commit is contained in:
Miikka 2020-07-22 20:27:22 +03:00 committed by GitHub
commit 5107a5f5c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 233 additions and 1 deletions

View file

@ -0,0 +1,46 @@
import { PluginOptions } from "knub";
import { PingableRolesPluginType, ConfigSchema } from "./types";
import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
import { GuildPingableRoles } from "src/data/GuildPingableRoles";
import { PingableRoleEnableCmd } from "./commands/PingableRoleEnableCmd";
import { PingableRoleDisableCmd } from "./commands/PingableRoleDisableCmd";
import { TypingEnablePingableEvt, MessageCreateDisablePingableEvt } from "./events/ChangePingableEvts";
const defaultOptions: PluginOptions<PingableRolesPluginType> = {
config: {
can_manage: false,
},
overrides: [
{
level: ">=100",
config: {
can_manage: true,
},
},
],
};
export const PingableRolesPlugin = zeppelinPlugin<PingableRolesPluginType>()("pingable_roles", {
configSchema: ConfigSchema,
defaultOptions,
// prettier-ignore
commands: [
PingableRoleEnableCmd,
PingableRoleDisableCmd,
],
// prettier-ignore
events: [
TypingEnablePingableEvt,
MessageCreateDisablePingableEvt,
],
onLoad(pluginData) {
const { state, guild } = pluginData;
state.pingableRoles = GuildPingableRoles.getGuildInstance(guild.id);
state.cache = new Map();
state.timeouts = new Map();
},
});

View file

@ -0,0 +1,30 @@
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { pingableRolesCmd } from "../types";
import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
export const PingableRoleDisableCmd = pingableRolesCmd({
trigger: ["pingable_role disable", "pingable_role d"],
permission: "can_manage",
signature: {
channelId: ct.channelId(),
role: ct.role(),
},
async run({ message: msg, args, pluginData }) {
const pingableRole = await pluginData.state.pingableRoles.getByChannelAndRoleId(args.channelId, args.role.id);
if (!pingableRole) {
sendErrorMessage(pluginData, msg.channel, `**${args.role.name}** is not set as pingable in <#${args.channelId}>`);
return;
}
await pluginData.state.pingableRoles.delete(args.channelId, args.role.id);
pluginData.state.cache.delete(args.channelId);
sendSuccessMessage(
pluginData,
msg.channel,
`**${args.role.name}** is no longer set as pingable in <#${args.channelId}>`,
);
},
});

View file

@ -0,0 +1,37 @@
import { commandTypeHelpers as ct } from "../../../commandTypes";
import { pingableRolesCmd } from "../types";
import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils";
export const PingableRoleEnableCmd = pingableRolesCmd({
trigger: "pingable_role",
permission: "can_manage",
signature: {
channelId: ct.channelId(),
role: ct.role(),
},
async run({ message: msg, args, pluginData }) {
const existingPingableRole = await pluginData.state.pingableRoles.getByChannelAndRoleId(
args.channelId,
args.role.id,
);
if (existingPingableRole) {
sendErrorMessage(
pluginData,
msg.channel,
`**${args.role.name}** is already set as pingable in <#${args.channelId}>`,
);
return;
}
await pluginData.state.pingableRoles.add(args.channelId, args.role.id);
pluginData.state.cache.delete(args.channelId);
sendSuccessMessage(
pluginData,
msg.channel,
`**${args.role.name}** has been set as pingable in <#${args.channelId}>`,
);
},
});

View file

@ -0,0 +1,47 @@
import { pingableRolesEvt } from "../types";
import { getPingableRolesForChannel } from "../utils/getPingableRolesForChannel";
import { enablePingableRoles } from "../utils/enablePingableRoles";
import { disablePingableRoles } from "../utils/disablePingableRoles";
const TIMEOUT = 10 * 1000;
export const TypingEnablePingableEvt = pingableRolesEvt({
event: "typingStart",
async listener(meta) {
const pluginData = meta.pluginData;
const channel = meta.args.channel;
const pingableRoles = await getPingableRolesForChannel(pluginData, channel.id);
if (pingableRoles.length === 0) return;
if (pluginData.state.timeouts.has(channel.id)) {
clearTimeout(pluginData.state.timeouts.get(channel.id));
}
enablePingableRoles(pluginData, pingableRoles);
const timeout = setTimeout(() => {
disablePingableRoles(pluginData, pingableRoles);
}, TIMEOUT);
pluginData.state.timeouts.set(channel.id, timeout);
},
});
export const MessageCreateDisablePingableEvt = pingableRolesEvt({
event: "messageCreate",
async listener(meta) {
const pluginData = meta.pluginData;
const msg = meta.args.message;
const pingableRoles = await getPingableRolesForChannel(pluginData, msg.channel.id);
if (pingableRoles.length === 0) return;
if (pluginData.state.timeouts.has(msg.channel.id)) {
clearTimeout(pluginData.state.timeouts.get(msg.channel.id));
}
disablePingableRoles(pluginData, pingableRoles);
},
});

View file

@ -0,0 +1,22 @@
import * as t from "io-ts";
import { BasePluginType, eventListener, command } from "knub";
import { GuildPingableRoles } from "src/data/GuildPingableRoles";
import { PingableRole } from "src/data/entities/PingableRole";
export const ConfigSchema = t.type({
can_manage: t.boolean,
});
export type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
export interface PingableRolesPluginType extends BasePluginType {
config: TConfigSchema;
state: {
pingableRoles: GuildPingableRoles;
cache: Map<string, PingableRole[]>;
timeouts: Map<string, any>;
};
}
export const pingableRolesCmd = command<PingableRolesPluginType>();
export const pingableRolesEvt = eventListener<PingableRolesPluginType>();

View file

@ -0,0 +1,17 @@
import { PingableRole } from "src/data/entities/PingableRole";
import { PluginData } from "knub";
import { PingableRolesPluginType } from "../types";
export function disablePingableRoles(pluginData: PluginData<PingableRolesPluginType>, pingableRoles: PingableRole[]) {
for (const pingableRole of pingableRoles) {
const role = pluginData.guild.roles.get(pingableRole.role_id);
if (!role) continue;
role.edit(
{
mentionable: false,
},
"Disable pingable role",
);
}
}

View file

@ -0,0 +1,17 @@
import { PingableRole } from "src/data/entities/PingableRole";
import { PluginData } from "knub";
import { PingableRolesPluginType } from "../types";
export function enablePingableRoles(pluginData: PluginData<PingableRolesPluginType>, pingableRoles: PingableRole[]) {
for (const pingableRole of pingableRoles) {
const role = pluginData.guild.roles.get(pingableRole.role_id);
if (!role) continue;
role.edit(
{
mentionable: true,
},
"Enable pingable role",
);
}
}

View file

@ -0,0 +1,14 @@
import { PingableRole } from "src/data/entities/PingableRole";
import { PluginData } from "knub";
import { PingableRolesPluginType } from "../types";
export async function getPingableRolesForChannel(
pluginData: PluginData<PingableRolesPluginType>,
channelId: string,
): Promise<PingableRole[]> {
if (!pluginData.state.cache.has(channelId)) {
pluginData.state.cache.set(channelId, await pluginData.state.pingableRoles.getForChannel(channelId));
}
return pluginData.state.cache.get(channelId);
}

View file

@ -8,14 +8,16 @@ import { AutoReactionsPlugin } from "./AutoReactions/AutoReactionsPlugin";
import { RemindersPlugin } from "./Reminders/RemindersPlugin";
import { UsernameSaverPlugin } from "./UsernameSaver/UsernameSaverPlugin";
import { WelcomeMessagePlugin } from "./WelcomeMessage/WelcomeMessagePlugin";
import { PingableRolesPlugin } from "./PingableRoles/PingableRolesPlugin";
// prettier-ignore
export const guildPlugins: Array<ZeppelinPluginBlueprint<any>> = [
AutoReactionsPlugin,
LocateUserPlugin,
PersistPlugin,
PingableRolesPlugin,
MessageSaverPlugin,
NameHistoryPlugin,
PersistPlugin,
RemindersPlugin,
UsernameSaverPlugin,
UtilityPlugin,