feat(timezone): Adds timezone as option
This commit is contained in:
parent
0b9089ffae
commit
b852c06f83
11 changed files with 278 additions and 22 deletions
9
package-lock.json
generated
9
package-lock.json
generated
|
|
@ -27,7 +27,8 @@
|
||||||
"node-cron": "^4.0.7",
|
"node-cron": "^4.0.7",
|
||||||
"node-ical": "^0.20.1",
|
"node-ical": "^0.20.1",
|
||||||
"object-path-set": "^1.0.2",
|
"object-path-set": "^1.0.2",
|
||||||
"svg2img": "^1.0.0-beta.2"
|
"svg2img": "^1.0.0-beta.2",
|
||||||
|
"tzdata": "^1.0.44"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.29.0",
|
"@eslint/js": "^9.29.0",
|
||||||
|
|
@ -4518,6 +4519,12 @@
|
||||||
"typescript": ">=4.8.4 <5.9.0"
|
"typescript": ">=4.8.4 <5.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tzdata": {
|
||||||
|
"version": "1.0.44",
|
||||||
|
"resolved": "https://registry.npmjs.org/tzdata/-/tzdata-1.0.44.tgz",
|
||||||
|
"integrity": "sha512-xJ8xcdoFRwFpIQ90QV3WFXJNCO/feNn9vHVsZMJiKmtMYuo7nvF6CTpBc+SgegC1fb/3L+m32ytXT9XrBjrINg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "6.21.1",
|
"version": "6.21.1",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,8 @@
|
||||||
"node-cron": "^4.0.7",
|
"node-cron": "^4.0.7",
|
||||||
"node-ical": "^0.20.1",
|
"node-ical": "^0.20.1",
|
||||||
"object-path-set": "^1.0.2",
|
"object-path-set": "^1.0.2",
|
||||||
"svg2img": "^1.0.0-beta.2"
|
"svg2img": "^1.0.0-beta.2",
|
||||||
|
"tzdata": "^1.0.44"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.29.0",
|
"@eslint/js": "^9.29.0",
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ export enum TransformerType {
|
||||||
PermissionBoolean,
|
PermissionBoolean,
|
||||||
String,
|
String,
|
||||||
Paragraph,
|
Paragraph,
|
||||||
|
Timezone
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConfigurationTransformerItem = {
|
type ConfigurationTransformerItem = {
|
||||||
|
|
@ -35,6 +36,7 @@ export class ConfigurationTransformer {
|
||||||
return <ChannelId>configValue.value;
|
return <ChannelId>configValue.value;
|
||||||
case TransformerType.PermissionBoolean:
|
case TransformerType.PermissionBoolean:
|
||||||
return configValue.value === '1';
|
return configValue.value === '1';
|
||||||
|
case TransformerType.Timezone:
|
||||||
case TransformerType.Paragraph:
|
case TransformerType.Paragraph:
|
||||||
case TransformerType.String:
|
case TransformerType.String:
|
||||||
return configValue.value;
|
return configValue.value;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ import {ConfigurationTransformer, TransformerType} from "../ConfigurationTransfo
|
||||||
export type RuntimeGroupConfiguration = {
|
export type RuntimeGroupConfiguration = {
|
||||||
channels: Nullable<ChannelRuntimeGroupConfiguration>,
|
channels: Nullable<ChannelRuntimeGroupConfiguration>,
|
||||||
permissions: PermissionRuntimeGroupConfiguration,
|
permissions: PermissionRuntimeGroupConfiguration,
|
||||||
calendar: CalendarRuntimeGroupConfiguration
|
calendar: CalendarRuntimeGroupConfiguration,
|
||||||
|
timezone: string|null
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ChannelRuntimeGroupConfiguration = {
|
export type ChannelRuntimeGroupConfiguration = {
|
||||||
|
|
@ -49,7 +50,8 @@ export class GroupConfigurationProvider implements ConfigurationProvider<
|
||||||
title: null,
|
title: null,
|
||||||
description: null,
|
description: null,
|
||||||
location: null
|
location: null
|
||||||
}
|
},
|
||||||
|
timezone: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,6 +99,10 @@ export class GroupConfigurationProvider implements ConfigurationProvider<
|
||||||
{
|
{
|
||||||
path: ['calendar', 'location'],
|
path: ['calendar', 'location'],
|
||||||
type: TransformerType.String
|
type: TransformerType.String
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ['timezone'],
|
||||||
|
type: TransformerType.Timezone
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ import { Nullable } from "../../types/Nullable";
|
||||||
import {ConfigurationTransformer, TransformerType} from "../ConfigurationTransformer";
|
import {ConfigurationTransformer, TransformerType} from "../ConfigurationTransformer";
|
||||||
|
|
||||||
export type RuntimeServerConfiguration = {
|
export type RuntimeServerConfiguration = {
|
||||||
permissions: PermissionRuntimeServerConfiguration
|
permissions: PermissionRuntimeServerConfiguration,
|
||||||
|
timezone: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PermissionRuntimeServerConfiguration = {
|
export type PermissionRuntimeServerConfiguration = {
|
||||||
|
|
@ -35,7 +36,8 @@ export class ServerConfigurationProvider implements ConfigurationProvider<
|
||||||
groupCreation: {
|
groupCreation: {
|
||||||
allowEveryone: false
|
allowEveryone: false
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
timezone: '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
get(path: string): Nullable<ServerConfigurationModel> {
|
get(path: string): Nullable<ServerConfigurationModel> {
|
||||||
|
|
@ -62,6 +64,10 @@ export class ServerConfigurationProvider implements ConfigurationProvider<
|
||||||
{
|
{
|
||||||
path: ['permissions', 'groupCreation', 'allowEveryone'],
|
path: ['permissions', 'groupCreation', 'allowEveryone'],
|
||||||
type: TransformerType.PermissionBoolean
|
type: TransformerType.PermissionBoolean
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ['timezone'],
|
||||||
|
type: TransformerType.Timezone
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
||||||
93
source/Configuration/TimezoneHandler.ts
Normal file
93
source/Configuration/TimezoneHandler.ts
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
import {GroupModel} from "../Database/Models/GroupModel";
|
||||||
|
import {ConfigurationHandler, PathConfigurationFrom} from "./ConfigurationHandler";
|
||||||
|
import {GroupConfigurationProvider} from "./Groups/GroupConfigurationProvider";
|
||||||
|
import {Container} from "../Container/Container";
|
||||||
|
import {GroupConfigurationRepository} from "../Database/Repositories/GroupConfigurationRepository";
|
||||||
|
import {ServerConfigurationProvider} from "./Server/ServerConfigurationProvider";
|
||||||
|
import {Snowflake, time} from "discord.js";
|
||||||
|
import {ServerConfigurationRepository} from "../Database/Repositories/ServerConfigurationRepository";
|
||||||
|
import tzdata from 'tzdata';
|
||||||
|
import {Nullable} from "../types/Nullable";
|
||||||
|
|
||||||
|
export type Timezone = {
|
||||||
|
zone: string,
|
||||||
|
gmt: string,
|
||||||
|
name: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum TimezoneSaveTarget {
|
||||||
|
Server,
|
||||||
|
Group
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TimezoneHandler {
|
||||||
|
public static ALL_TIMEZONES: string[] = Object.keys(tzdata.zones)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly serverid: Snowflake,
|
||||||
|
private readonly group: GroupModel|null = null
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public use<TReturn>(callback: () => TReturn): TReturn {
|
||||||
|
const previousTZ = process.env.TZ;
|
||||||
|
|
||||||
|
process.env.TZ = this.getCurrentTimezone();
|
||||||
|
const result = callback();
|
||||||
|
process.env.TZ = previousTZ;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCurrentTimezone(): string {
|
||||||
|
const configs = [
|
||||||
|
this.getGroupConfiguration(),
|
||||||
|
this.getServerConfiguration()
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const config of configs) {
|
||||||
|
if (!config) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const timezone = config.getConfigurationByPath('timezone');
|
||||||
|
if (timezone.from === PathConfigurationFrom.Default) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <string>timezone.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return process.env.TZ ?? "Europe/London";
|
||||||
|
}
|
||||||
|
|
||||||
|
public save(timezone: string, target: TimezoneSaveTarget) {
|
||||||
|
const config = target === TimezoneSaveTarget.Server ? this.getServerConfiguration() : this.getGroupConfiguration();
|
||||||
|
if (!config) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
config.save('timezone', timezone);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getGroupConfiguration(): Nullable<ConfigurationHandler> {
|
||||||
|
if (!this.group) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ConfigurationHandler(
|
||||||
|
new GroupConfigurationProvider(
|
||||||
|
Container.get<GroupConfigurationRepository>(GroupConfigurationRepository.name),
|
||||||
|
this.group
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
private getServerConfiguration(): ConfigurationHandler {
|
||||||
|
return new ConfigurationHandler(
|
||||||
|
new ServerConfigurationProvider(
|
||||||
|
Container.get<ServerConfigurationRepository>(ServerConfigurationRepository.name),
|
||||||
|
this.serverid
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -36,11 +36,11 @@ export class PlaydateRepository extends Repository<PlaydateModel, DBPlaydate> {
|
||||||
}
|
}
|
||||||
|
|
||||||
findPlaydatesInRange(fromDate: Date, toDate: Date | undefined = undefined, group: GroupModel | undefined = undefined) {
|
findPlaydatesInRange(fromDate: Date, toDate: Date | undefined = undefined, group: GroupModel | undefined = undefined) {
|
||||||
let sql = `SELECT * FROM ${this.schema.name} WHERE time_from > ?`;
|
let sql = `SELECT * FROM ${this.schema.name} WHERE time_from >= ?`;
|
||||||
const params = [fromDate.getTime()];
|
const params = [fromDate.getTime()];
|
||||||
|
|
||||||
if (toDate) {
|
if (toDate) {
|
||||||
sql = `${sql} AND time_from < ?`
|
sql = `${sql} AND time_from <= ?`
|
||||||
params.push(toDate.getTime());
|
params.push(toDate.getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import {
|
import {
|
||||||
AutocompleteInteraction,
|
AutocompleteInteraction,
|
||||||
ChatInputCommandInteraction,
|
ChatInputCommandInteraction,
|
||||||
EmbedBuilder,
|
|
||||||
GuildMember,
|
GuildMember,
|
||||||
GuildMemberRoleManager,
|
GuildMemberRoleManager,
|
||||||
|
hyperlink,
|
||||||
|
inlineCode,
|
||||||
InteractionReplyOptions,
|
InteractionReplyOptions,
|
||||||
MessageFlags,
|
MessageFlags,
|
||||||
PermissionFlagsBits,
|
PermissionFlagsBits,
|
||||||
|
|
@ -35,8 +36,8 @@ import {PermissionError} from "../PermissionError";
|
||||||
import {EmbedLibrary, EmbedType} from "../EmbedLibrary";
|
import {EmbedLibrary, EmbedType} from "../EmbedLibrary";
|
||||||
import {EventHandler} from "../../Events/EventHandler";
|
import {EventHandler} from "../../Events/EventHandler";
|
||||||
import {ElementChangedEvent} from "../../Events/EventClasses/ElementChangedEvent";
|
import {ElementChangedEvent} from "../../Events/EventClasses/ElementChangedEvent";
|
||||||
import GroupConfiguration from "../../Database/tables/GroupConfiguration";
|
|
||||||
import Groups from "../../Database/tables/Groups";
|
import Groups from "../../Database/tables/Groups";
|
||||||
|
import {TimezoneHandler, TimezoneSaveTarget} from "../../Configuration/TimezoneHandler";
|
||||||
|
|
||||||
export class GroupCommand implements Command, ChatInteractionCommand, AutocompleteCommand {
|
export class GroupCommand implements Command, ChatInteractionCommand, AutocompleteCommand {
|
||||||
private static GOODBYE_MESSAGES: string[] = [
|
private static GOODBYE_MESSAGES: string[] = [
|
||||||
|
|
@ -95,6 +96,16 @@ export class GroupCommand implements Command, ChatInteractionCommand, Autocomple
|
||||||
.setDescription("The member, that is the new leader")
|
.setDescription("The member, that is the new leader")
|
||||||
.setRequired(true)
|
.setRequired(true)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
.addSubcommand(command => command
|
||||||
|
.setName("timezone")
|
||||||
|
.setDescription("Sets the timezone for the group, if a value is provided. If not, the current timezone is displayed.")
|
||||||
|
.addIntegerOption(GroupSelection.createOptionSetup())
|
||||||
|
.addStringOption(option => option
|
||||||
|
.setName('timezone')
|
||||||
|
.setDescription("The timezone the group should use.")
|
||||||
|
.setRequired(false)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,6 +126,9 @@ export class GroupCommand implements Command, ChatInteractionCommand, Autocomple
|
||||||
case "transfer":
|
case "transfer":
|
||||||
await this.transferLeadership(interaction);
|
await this.transferLeadership(interaction);
|
||||||
break;
|
break;
|
||||||
|
case "timezone":
|
||||||
|
await this.handleTimezone(interaction);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error("Unsupported command");
|
throw new Error("Unsupported command");
|
||||||
}
|
}
|
||||||
|
|
@ -395,4 +409,51 @@ export class GroupCommand implements Command, ChatInteractionCommand, Autocomple
|
||||||
flags: MessageFlags.Ephemeral,
|
flags: MessageFlags.Ephemeral,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async handleTimezone(interaction: ChatInputCommandInteraction) {
|
||||||
|
const group = GroupSelection.getGroup(interaction);
|
||||||
|
const enteredTimezone = interaction.options.getString('timezone');
|
||||||
|
|
||||||
|
const timezoneHandler = new TimezoneHandler(
|
||||||
|
interaction.guildId ?? '',
|
||||||
|
group
|
||||||
|
);
|
||||||
|
if (!enteredTimezone) {
|
||||||
|
await interaction.reply(
|
||||||
|
{
|
||||||
|
embeds: [
|
||||||
|
EmbedLibrary.withGroup(
|
||||||
|
group,
|
||||||
|
"Timezone",
|
||||||
|
`The group currently uses the timezone ${inlineCode(timezoneHandler.getCurrentTimezone())}.`,
|
||||||
|
EmbedType.Info
|
||||||
|
)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TimezoneHandler.ALL_TIMEZONES.includes(enteredTimezone)) {
|
||||||
|
throw new UserError(
|
||||||
|
`Invalid timezone provided: ${enteredTimezone}`,
|
||||||
|
`Try using timezones found in this list using the 'TZ Identifier'. ${hyperlink("List", 'https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List')}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
timezoneHandler.save(enteredTimezone, TimezoneSaveTarget.Group);
|
||||||
|
await interaction.reply(
|
||||||
|
{
|
||||||
|
embeds: [
|
||||||
|
EmbedLibrary.withGroup(
|
||||||
|
group,
|
||||||
|
"Timezone changed",
|
||||||
|
`The group now uses the timezone ${inlineCode(enteredTimezone)}.`,
|
||||||
|
EmbedType.Info
|
||||||
|
)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -29,6 +29,8 @@ import {PermissionError} from "../PermissionError";
|
||||||
import {EmbedLibrary, EmbedType} from "../EmbedLibrary";
|
import {EmbedLibrary, EmbedType} from "../EmbedLibrary";
|
||||||
import {GroupConfigurationModel} from "../../Database/Models/GroupConfigurationModel";
|
import {GroupConfigurationModel} from "../../Database/Models/GroupConfigurationModel";
|
||||||
import parser from "any-date-parser";
|
import parser from "any-date-parser";
|
||||||
|
import {TimezoneHandler} from "../../Configuration/TimezoneHandler";
|
||||||
|
import _ from "lodash";
|
||||||
|
|
||||||
export class PlaydatesCommand implements Command, AutocompleteCommand, ChatInteractionCommand {
|
export class PlaydatesCommand implements Command, AutocompleteCommand, ChatInteractionCommand {
|
||||||
definition(): SlashCommandBuilder {
|
definition(): SlashCommandBuilder {
|
||||||
|
|
@ -123,8 +125,18 @@ export class PlaydatesCommand implements Command, AutocompleteCommand, ChatInter
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const fromDate = parser.fromString(<string>interaction.options.get("from")?.value ?? '');
|
const timezoneHandler = new TimezoneHandler(
|
||||||
const toDate = parser.fromString(<string>interaction.options.get("to")?.value ?? '');
|
interaction.guildId ?? '',
|
||||||
|
group
|
||||||
|
);
|
||||||
|
|
||||||
|
const [fromDate, toDate] = timezoneHandler.use(() => {
|
||||||
|
return [
|
||||||
|
parser.fromString(<string>interaction.options.get("from")?.value ?? ''),
|
||||||
|
parser.fromString(<string>interaction.options.get("to")?.value ?? '')
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
if (!fromDate.isValid()) {
|
if (!fromDate.isValid()) {
|
||||||
throw new UserError("No date or invalid date format for the from parameter.");
|
throw new UserError("No date or invalid date format for the from parameter.");
|
||||||
|
|
@ -184,13 +196,19 @@ export class PlaydatesCommand implements Command, AutocompleteCommand, ChatInter
|
||||||
|
|
||||||
const group = GroupSelection.getGroup(interaction);
|
const group = GroupSelection.getGroup(interaction);
|
||||||
|
|
||||||
|
const timezone = new TimezoneHandler(
|
||||||
|
interaction.guildId ?? '',
|
||||||
|
group
|
||||||
|
);
|
||||||
const playdates = Container.get<PlaydateRepository>(PlaydateRepository.name).findFromGroup(group);
|
const playdates = Container.get<PlaydateRepository>(PlaydateRepository.name).findFromGroup(group);
|
||||||
await interaction.respond(
|
await interaction.respond(
|
||||||
playdates.map(playdate => {
|
timezone.use(() => {
|
||||||
return {
|
return _.slice(playdates, 0, 25).map(playdate => {
|
||||||
name: `${playdate.from_time.toLocaleString()} - ${playdate.to_time.toLocaleString()}`,
|
return {
|
||||||
value: <number>playdate.id
|
name: `${playdate.from_time.toLocaleString()} - ${playdate.to_time.toLocaleString()}`,
|
||||||
}
|
value: <number>playdate.id
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,24 @@
|
||||||
import {CacheType, ChatInputCommandInteraction, PermissionFlagsBits, SlashCommandBuilder, Snowflake} from "discord.js";
|
import {
|
||||||
|
CacheType,
|
||||||
|
ChatInputCommandInteraction,
|
||||||
|
hyperlink,
|
||||||
|
inlineCode,
|
||||||
|
PermissionFlagsBits,
|
||||||
|
SlashCommandBuilder,
|
||||||
|
Snowflake
|
||||||
|
} from "discord.js";
|
||||||
import {ChatInteractionCommand, Command} from "./Command";
|
import {ChatInteractionCommand, Command} from "./Command";
|
||||||
import {GroupSelection} from "../CommandPartials/GroupSelection";
|
|
||||||
import {MenuHandler} from "../../Configuration/MenuHandler";
|
import {MenuHandler} from "../../Configuration/MenuHandler";
|
||||||
import {ConfigurationHandler} from "../../Configuration/ConfigurationHandler";
|
import {ConfigurationHandler} from "../../Configuration/ConfigurationHandler";
|
||||||
import {GroupConfigurationProvider} from "../../Configuration/Groups/GroupConfigurationProvider";
|
|
||||||
import {Container} from "../../Container/Container";
|
import {Container} from "../../Container/Container";
|
||||||
import {GroupConfigurationRepository} from "../../Database/Repositories/GroupConfigurationRepository";
|
|
||||||
import {MenuRenderer} from "../../Menu/MenuRenderer";
|
import {MenuRenderer} from "../../Menu/MenuRenderer";
|
||||||
import {MenuTraversal} from "../../Menu/MenuTraversal";
|
import {MenuTraversal} from "../../Menu/MenuTraversal";
|
||||||
import {MenuItemType} from "../../Menu/MenuRenderer.types";
|
import {MenuItemType} from "../../Menu/MenuRenderer.types";
|
||||||
import {ServerConfigurationProvider} from "../../Configuration/Server/ServerConfigurationProvider";
|
import {ServerConfigurationProvider} from "../../Configuration/Server/ServerConfigurationProvider";
|
||||||
import {ServerConfigurationRepository} from "../../Database/Repositories/ServerConfigurationRepository";
|
import {ServerConfigurationRepository} from "../../Database/Repositories/ServerConfigurationRepository";
|
||||||
|
import {TimezoneHandler, TimezoneSaveTarget} from "../../Configuration/TimezoneHandler";
|
||||||
|
import {EmbedLibrary, EmbedType} from "../EmbedLibrary";
|
||||||
|
import {UserError} from "../UserError";
|
||||||
|
|
||||||
export class ServerCommand implements Command, ChatInteractionCommand {
|
export class ServerCommand implements Command, ChatInteractionCommand {
|
||||||
definition(): SlashCommandBuilder {
|
definition(): SlashCommandBuilder {
|
||||||
|
|
@ -22,6 +30,15 @@ export class ServerCommand implements Command, ChatInteractionCommand {
|
||||||
.setName("config")
|
.setName("config")
|
||||||
.setDescription("Starts the configurator for the server settings")
|
.setDescription("Starts the configurator for the server settings")
|
||||||
)
|
)
|
||||||
|
.addSubcommand(command => command
|
||||||
|
.setName("timezone")
|
||||||
|
.setDescription("Sets the timezone for the server, if a value is provided. If not, the current timezone is displayed.")
|
||||||
|
.addStringOption(option => option
|
||||||
|
.setName('timezone')
|
||||||
|
.setDescription("The timezone the server should use.")
|
||||||
|
.setRequired(false)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(interaction: ChatInputCommandInteraction<CacheType>): Promise<void> {
|
async execute(interaction: ChatInputCommandInteraction<CacheType>): Promise<void> {
|
||||||
|
|
@ -29,6 +46,9 @@ export class ServerCommand implements Command, ChatInteractionCommand {
|
||||||
case "config":
|
case "config":
|
||||||
await this.startConfiguration(interaction);
|
await this.startConfiguration(interaction);
|
||||||
break
|
break
|
||||||
|
case "timezone":
|
||||||
|
await this.handleTimezone(interaction);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,4 +99,46 @@ export class ServerCommand implements Command, ChatInteractionCommand {
|
||||||
|
|
||||||
menu.display(interaction);
|
menu.display(interaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async handleTimezone(interaction: ChatInputCommandInteraction<CacheType>) {
|
||||||
|
const enteredTimezone = interaction.options.getString('timezone');
|
||||||
|
|
||||||
|
const timezoneHandler = new TimezoneHandler(
|
||||||
|
interaction.guildId ?? ''
|
||||||
|
);
|
||||||
|
if (!enteredTimezone) {
|
||||||
|
await interaction.reply(
|
||||||
|
{
|
||||||
|
embeds: [
|
||||||
|
EmbedLibrary.base(
|
||||||
|
"Timezone",
|
||||||
|
`The group currently uses the timezone ${inlineCode(timezoneHandler.getCurrentTimezone())}.`,
|
||||||
|
EmbedType.Info
|
||||||
|
)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TimezoneHandler.ALL_TIMEZONES.includes(enteredTimezone)) {
|
||||||
|
throw new UserError(
|
||||||
|
`Invalid timezone provided: ${enteredTimezone}`,
|
||||||
|
`Try using timezones found in this list using the 'TZ Identifier'. ${hyperlink("List", 'https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List')}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
timezoneHandler.save(enteredTimezone, TimezoneSaveTarget.Server);
|
||||||
|
await interaction.reply(
|
||||||
|
{
|
||||||
|
embeds: [
|
||||||
|
EmbedLibrary.base(
|
||||||
|
"Timezone changed",
|
||||||
|
`The server now uses the timezone ${inlineCode(enteredTimezone)}.`,
|
||||||
|
EmbedType.Success
|
||||||
|
)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -15,7 +15,7 @@ export class UserError extends Error {
|
||||||
public getEmbed(e: UserError): EmbedBuilder {
|
public getEmbed(e: UserError): EmbedBuilder {
|
||||||
const embed = EmbedLibrary.base(
|
const embed = EmbedLibrary.base(
|
||||||
"Please validate your request!",
|
"Please validate your request!",
|
||||||
inlineCode(e.message),
|
e.message,
|
||||||
EmbedType.Error
|
EmbedType.Error
|
||||||
).setFooter({
|
).setFooter({
|
||||||
text: "Type: Request"
|
text: "Type: Request"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue