(v4.2.0) Added sub-panels
This commit is contained in:
+17
-2
@@ -123,7 +123,7 @@ const panelButtons = () => {
|
||||
new api.ODWorker("opendiscord:ticket-option",0,async (instance,params) => {
|
||||
const {panel,option} = params
|
||||
|
||||
instance.setCustomId("od:ticket-option_"+panel.id.value+"_"+option.id.value)
|
||||
instance.setCustomId("od:ticket-option|"+option.id.value)
|
||||
instance.setMode("button")
|
||||
instance.setColor(option.get("opendiscord:button-color").value)
|
||||
if (option.get("opendiscord:button-emoji").value) instance.setEmoji(option.get("opendiscord:button-emoji").value)
|
||||
@@ -152,7 +152,22 @@ const panelButtons = () => {
|
||||
new api.ODWorker("opendiscord:role-option",0,async (instance,params) => {
|
||||
const {panel,option} = params
|
||||
|
||||
instance.setCustomId("od:role-option_"+panel.id.value+"_"+option.id.value)
|
||||
instance.setCustomId("od:role-option|"+option.id.value)
|
||||
instance.setMode("button")
|
||||
instance.setColor(option.get("opendiscord:button-color").value)
|
||||
if (option.get("opendiscord:button-emoji").value) instance.setEmoji(option.get("opendiscord:button-emoji").value)
|
||||
if (option.get("opendiscord:button-label").value) instance.setLabel(option.get("opendiscord:button-label").value)
|
||||
if (!option.get("opendiscord:button-emoji").value && !option.get("opendiscord:button-label").value) instance.setLabel("<"+option.id.value+">")
|
||||
})
|
||||
)
|
||||
|
||||
//SUB-PANEL OPTION
|
||||
buttons.add(new api.ODButton("opendiscord:subpanel-option"))
|
||||
buttons.get("opendiscord:subpanel-option").workers.add(
|
||||
new api.ODWorker("opendiscord:subpanel-option",0,async (instance,params) => {
|
||||
const {panel,option} = params
|
||||
|
||||
instance.setCustomId("od:subpanel-option|"+option.id.value)
|
||||
instance.setMode("button")
|
||||
instance.setColor(option.get("opendiscord:button-color").value)
|
||||
if (option.get("opendiscord:button-emoji").value) instance.setEmoji(option.get("opendiscord:button-emoji").value)
|
||||
|
||||
@@ -24,14 +24,14 @@ const panelDropdowns = () => {
|
||||
|
||||
return {
|
||||
label:(label.length > 0) ? label : "<no-label-provided>",
|
||||
value:"od:ticket-option_"+panel.id.value+"_"+option.id.value,
|
||||
value:"od:ticket-option|"+option.id.value,
|
||||
emoji:(emoji.length > 0) ? emoji : undefined,
|
||||
description:(desc.length > 0) ? desc : undefined,
|
||||
default:false
|
||||
}
|
||||
})
|
||||
|
||||
instance.setCustomId("od:panel-dropdown_"+panel.id.value)
|
||||
instance.setCustomId("od:panel-dropdown")
|
||||
instance.setType("string")
|
||||
instance.setMaxValues(1)
|
||||
instance.setMinValues(0)
|
||||
|
||||
@@ -274,7 +274,10 @@ const panelMessages = () => {
|
||||
messages.add(new api.ODMessage("opendiscord:panel"))
|
||||
messages.get("opendiscord:panel").workers.add([
|
||||
new api.ODWorker("opendiscord:panel-layout",1,async (instance,params,origin) => {
|
||||
const {guild,channel,user,panel} = params
|
||||
const {guild,channel,user,panel,isSubPanel} = params
|
||||
|
||||
//ephemeral if sub-panel
|
||||
if (isSubPanel) instance.setEphemeral(true)
|
||||
|
||||
//add text
|
||||
const text = panel.get("opendiscord:text").value
|
||||
@@ -292,7 +295,7 @@ const panelMessages = () => {
|
||||
|
||||
//add embed
|
||||
const embedOptions = panel.get("opendiscord:embed").value
|
||||
if (embedOptions.enabled) instance.addEmbed(await embeds.getSafe("opendiscord:panel").build(origin,{guild,channel,user,panel}))
|
||||
if (embedOptions.enabled) instance.addEmbed(await embeds.getSafe("opendiscord:panel").build(origin,{guild,channel,user,panel,isSubPanel}))
|
||||
}),
|
||||
new api.ODWorker("opendiscord:panel-components",0,async (instance,params,origin) => {
|
||||
const {guild,channel,user,panel} = params
|
||||
@@ -315,6 +318,7 @@ const panelMessages = () => {
|
||||
if (option instanceof api.ODTicketOption) instance.addComponent(await buttons.getSafe("opendiscord:ticket-option").build(origin,{guild,channel,user,panel,option}))
|
||||
else if (option instanceof api.ODWebsiteOption) instance.addComponent(await buttons.getSafe("opendiscord:website-option").build(origin,{guild,channel,user,panel,option}))
|
||||
else if (option instanceof api.ODRoleOption) instance.addComponent(await buttons.getSafe("opendiscord:role-option").build(origin,{guild,channel,user,panel,option}))
|
||||
else if (option instanceof api.ODSubPanelOption) instance.addComponent(await buttons.getSafe("opendiscord:subpanel-option").build(origin,{guild,channel,user,panel,option}))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
+60
-2
@@ -36,12 +36,13 @@ export async function registerCommandResponders(){
|
||||
}
|
||||
|
||||
await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:panel-ready").build(origin,{guild,channel,user,panel}))
|
||||
const panelMessage = await channel.send((await opendiscord.builders.messages.getSafe("opendiscord:panel").build(origin,{guild,channel,user,panel})).message)
|
||||
const panelMessage = await channel.send((await opendiscord.builders.messages.getSafe("opendiscord:panel").build(origin,{guild,channel,user,panel,isSubPanel:false})).message)
|
||||
if (panelMessage) await panelMsgState.setMsgState({channel,message:panelMessage},{
|
||||
messageOrigin:origin,
|
||||
panelId:panel.id.value,
|
||||
panelOptionIds:panel.get("opendiscord:options").value,
|
||||
panelAutoUpdate:(instance.options.getBoolean("auto-update",false) ?? false)
|
||||
panelAutoUpdate:(instance.options.getBoolean("auto-update",false) ?? false),
|
||||
isSubPanel:false
|
||||
},panelMessage.flags.has("Ephemeral"))
|
||||
}),
|
||||
new api.ODWorker("opendiscord:logs",-1,(instance,params,origin,cancel) => {
|
||||
@@ -54,3 +55,60 @@ export async function registerCommandResponders(){
|
||||
})
|
||||
])
|
||||
}
|
||||
|
||||
export async function registerButtonResponders(){
|
||||
//SUBPANEL OPTION BUTTON RESPONDER
|
||||
opendiscord.responders.buttons.add(new api.ODButtonResponder("opendiscord:subpanel-option",/^od:subpanel-option\|([^|]+)/))
|
||||
opendiscord.responders.buttons.get("opendiscord:subpanel-option").workers.add(
|
||||
new api.ODWorker("opendiscord:subpanel-option",0,async (instance,params,origin,cancel) => {
|
||||
const {guild,channel,user,message} = instance
|
||||
|
||||
const match = /^od:subpanel-option\|([^|]+)/.exec(instance.interaction.customId)
|
||||
if (!match) return cancel()
|
||||
const optionId = match[1]
|
||||
|
||||
//check message state
|
||||
const state = await panelMsgState.getMsgState({channel,message})
|
||||
if (!state){
|
||||
//TODO TRANSLATION!!!
|
||||
await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build(origin,{guild,channel,user,error:"This panel is no longer valid or has expired. Create a new panel using `{0}` to solve the issue. It is normal to receive this error after a major Open Ticket update.".replace("{0}","/panel"),layout:"simple",customTitle:"Message State Expired"}))
|
||||
return cancel()
|
||||
}
|
||||
|
||||
//responder checks
|
||||
const isInGuild = await openticketUtils.replyIsInGuild(instance,origin)
|
||||
if (!isInGuild || !guild || channel.isDMBased()) return cancel()
|
||||
|
||||
//get option data
|
||||
const option = opendiscord.options.get(optionId)
|
||||
if (!option || !(option instanceof api.ODSubPanelOption)){
|
||||
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-option-unknown").build(origin,{guild:instance.guild,channel:instance.channel,user:instance.user}))
|
||||
return cancel()
|
||||
}
|
||||
|
||||
//get panel data
|
||||
const subPanel = opendiscord.panels.get(option.get("opendiscord:panel-id").value)
|
||||
if (!subPanel){
|
||||
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-panel-unknown").build(origin,{guild,channel,user}))
|
||||
return cancel()
|
||||
}
|
||||
|
||||
//send sub-panel message (ephemeral)
|
||||
const panelMessage = await instance.reply((await opendiscord.builders.messages.getSafe("opendiscord:panel").build("sub-panel",{guild,channel,user,panel:subPanel,isSubPanel:true})))
|
||||
if (panelMessage.success) await panelMsgState.setMsgState({channel,message:panelMessage.message},{
|
||||
messageOrigin:"sub-panel",
|
||||
panelId:subPanel.id.value,
|
||||
panelOptionIds:subPanel.get("opendiscord:options").value,
|
||||
panelAutoUpdate:false,
|
||||
isSubPanel:true
|
||||
},panelMessage.ephemeral)
|
||||
|
||||
opendiscord.log(instance.user.displayName+" created a sub-panel!","info",[
|
||||
{key:"user",value:instance.user.username},
|
||||
{key:"userid",value:instance.user.id,hidden:true},
|
||||
{key:"channelid",value:instance.channel.id,hidden:true},
|
||||
{key:"method",value:origin}
|
||||
])
|
||||
})
|
||||
)
|
||||
}
|
||||
@@ -8,17 +8,20 @@ const generalConfig = opendiscord.configs.get("opendiscord:general")
|
||||
|
||||
export async function registerButtonResponders(){
|
||||
//ROLE OPTION BUTTON RESPONDER
|
||||
opendiscord.responders.buttons.add(new api.ODButtonResponder("opendiscord:role-option",/^od:role-option_/))
|
||||
opendiscord.responders.buttons.add(new api.ODButtonResponder("opendiscord:role-option",/^od:role-option\|([^|]+)/))
|
||||
opendiscord.responders.buttons.get("opendiscord:role-option").workers.add(
|
||||
new api.ODWorker("opendiscord:role-option",0,async (instance,params,origin,cancel) => {
|
||||
const {guild,channel,user} = instance
|
||||
|
||||
const match = /^od:role-option\|([^|]+)/.exec(instance.interaction.customId)
|
||||
if (!match) return cancel()
|
||||
const optionId = match[1]
|
||||
|
||||
//responder checks
|
||||
const isInGuild = await openticketUtils.replyIsInGuild(instance,origin)
|
||||
if (!isInGuild || !guild || channel.isDMBased()) return cancel()
|
||||
|
||||
//get option data
|
||||
const optionId = instance.interaction.customId.split("_")[2]
|
||||
const option = opendiscord.options.get(optionId)
|
||||
if (!option || !(option instanceof api.ODRoleOption)){
|
||||
//error
|
||||
|
||||
+12
-6
@@ -80,11 +80,15 @@ export async function registerCommandResponders(){
|
||||
|
||||
export async function registerButtonResponders(){
|
||||
//TICKET OPTION BUTTON RESPONDER
|
||||
opendiscord.responders.buttons.add(new api.ODButtonResponder("opendiscord:ticket-option",/^od:ticket-option_/))
|
||||
opendiscord.responders.buttons.add(new api.ODButtonResponder("opendiscord:ticket-option",/^od:ticket-option\|([^|]+)/))
|
||||
opendiscord.responders.buttons.get("opendiscord:ticket-option").workers.add(
|
||||
new api.ODWorker("opendiscord:ticket-option",0,async (instance,params,origin,cancel) => {
|
||||
const {guild,channel,user,message} = instance
|
||||
|
||||
const match = /^od:ticket-option\|([^|]+)/.exec(instance.interaction.customId)
|
||||
if (!match) return cancel()
|
||||
const optionId = match[1]
|
||||
|
||||
//check message state
|
||||
const state = await panelMsgState.getMsgState({channel,message})
|
||||
if (!state){
|
||||
@@ -98,7 +102,6 @@ export async function registerButtonResponders(){
|
||||
if (!isInGuild || !guild || channel.isDMBased()) return cancel()
|
||||
|
||||
//get option data
|
||||
const optionId = instance.interaction.customId.split("_")[2]
|
||||
const option = opendiscord.options.get(optionId)
|
||||
if (!option || !(option instanceof api.ODTicketOption)){
|
||||
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-option-unknown").build(origin,{guild:instance.guild,channel:instance.channel,user:instance.user}))
|
||||
@@ -130,7 +133,7 @@ export async function registerButtonResponders(){
|
||||
|
||||
export async function registerDropdownResponders(){
|
||||
//PANEL DROPDOWN TICKETS DROPDOWN RESPONDER
|
||||
opendiscord.responders.dropdowns.add(new api.ODDropdownResponder("opendiscord:panel-dropdown-tickets",/^od:panel-dropdown_/))
|
||||
opendiscord.responders.dropdowns.add(new api.ODDropdownResponder("opendiscord:panel-dropdown-tickets",/^od:panel-dropdown/))
|
||||
opendiscord.responders.dropdowns.get("opendiscord:panel-dropdown-tickets").workers.add(
|
||||
new api.ODWorker("opendiscord:panel-dropdown-tickets",0,async (instance,params,origin,cancel) => {
|
||||
const {guild,channel,user,message} = instance
|
||||
@@ -148,7 +151,9 @@ export async function registerDropdownResponders(){
|
||||
if (!isInGuild || !guild || channel.isDMBased()) return cancel()
|
||||
|
||||
//get option data
|
||||
const optionId = instance.values.getStringValues()[0].split("_")[2]
|
||||
const match = /^od:ticket-option\|([^|]+)/.exec(instance.values.getStringValues()[0])
|
||||
if (!match) return cancel()
|
||||
const optionId = match[1]
|
||||
const option = opendiscord.options.get(optionId)
|
||||
if (!option || !(option instanceof api.ODTicketOption)){
|
||||
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-option-unknown").build(origin,{guild:instance.guild,channel:instance.channel,user:instance.user}))
|
||||
@@ -178,12 +183,13 @@ export async function registerDropdownResponders(){
|
||||
//update panel after dropdown usage (reset panel choice)
|
||||
const panel = opendiscord.panels.get(state.data.panelId)
|
||||
if (panel){
|
||||
const panelMessage = await instance.message.edit((await opendiscord.builders.messages.getSafe("opendiscord:panel").build("auto-update",{guild,channel,user,panel})).message)
|
||||
const panelMessage = await instance.message.edit((await opendiscord.builders.messages.getSafe("opendiscord:panel").build("auto-update",{guild,channel,user,panel,isSubPanel:state.data.isSubPanel})).message)
|
||||
if (panelMessage) await panelMsgState.setMsgState({channel,message:panelMessage},{
|
||||
messageOrigin:"auto-update",
|
||||
panelId:panel.id.value,
|
||||
panelOptionIds:panel.get("opendiscord:options").value,
|
||||
panelAutoUpdate:state.data.panelAutoUpdate //same value
|
||||
panelAutoUpdate:state.data.panelAutoUpdate, //same value
|
||||
isSubPanel:state.data.isSubPanel //same value
|
||||
},panelMessage.flags.has("Ephemeral"))
|
||||
}
|
||||
})
|
||||
|
||||
+67
-81
@@ -96,6 +96,21 @@ export interface ODRoleOptionIdMappings extends ODOptionIdConstraint {
|
||||
"opendiscord:add-on-join":ODOptionData<boolean>
|
||||
}
|
||||
|
||||
/**## ODSubPanelOptionIdMappings `interface`
|
||||
* A list of all available IDs in the default `ODSubPanelOption` class in `opendiscord`.
|
||||
* It's used to generate typescript declarations for this class.
|
||||
*/
|
||||
export interface ODSubPanelOptionIdMappings extends ODOptionIdConstraint {
|
||||
"opendiscord:name":ODOptionData<string>,
|
||||
"opendiscord:description":ODOptionData<string>,
|
||||
|
||||
"opendiscord:button-emoji":ODOptionData<string>,
|
||||
"opendiscord:button-label":ODOptionData<string>,
|
||||
"opendiscord:button-color":ODOptionData<api.ODValidButtonColor>,
|
||||
|
||||
"opendiscord:panel-id":ODOptionData<string>
|
||||
}
|
||||
|
||||
/**## ODOptionManager `class`
|
||||
* This is an Open Ticket option manager.
|
||||
*
|
||||
@@ -149,21 +164,41 @@ export interface ODOptionJson {
|
||||
*
|
||||
* It's recommended to use `ODTicketOption`, `ODWebsiteOption` or `ODRoleOption` instead!
|
||||
*/
|
||||
export class ODOption extends api.ODManager<ODOptionData<api.ODValidJsonType>> {
|
||||
export abstract class ODOption<IdList extends ODOptionIdConstraint = ODOptionIdConstraint> extends api.ODManager<ODOptionData<api.ODValidJsonType>> {
|
||||
/**The id of this option. (from the config) */
|
||||
id:api.ODId
|
||||
/**The type of this option. (e.g. `opendiscord:ticket`, `opendiscord:website`, `opendiscord:role`) */
|
||||
type: string
|
||||
abstract readonly type: string
|
||||
|
||||
constructor(id:api.ODValidId, type:string, data:ODOptionData<api.ODValidJsonType>[]){
|
||||
constructor(id:api.ODValidId, data:ODOptionData<api.ODValidJsonType>[]){
|
||||
super()
|
||||
this.id = new api.ODId(id)
|
||||
this.type = type
|
||||
data.forEach((data) => {
|
||||
this.add(data)
|
||||
})
|
||||
}
|
||||
|
||||
get<OptionId extends keyof api.ODNoGeneric<IdList>>(id:OptionId): IdList[OptionId]
|
||||
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
|
||||
|
||||
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
|
||||
return super.get(id)
|
||||
}
|
||||
|
||||
remove<OptionId extends keyof api.ODNoGeneric<IdList>>(id:OptionId): IdList[OptionId]
|
||||
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
|
||||
|
||||
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
|
||||
return super.remove(id)
|
||||
}
|
||||
|
||||
exists(id:keyof api.ODNoGeneric<IdList>): boolean
|
||||
exists(id:api.ODValidId): boolean
|
||||
|
||||
exists(id:api.ODValidId): boolean {
|
||||
return super.exists(id)
|
||||
}
|
||||
|
||||
/**Convert this option to a JSON object for storing this option in the database. */
|
||||
toJson(version:api.ODVersion): ODOptionJson {
|
||||
const data = this.getAll().map((data) => {
|
||||
@@ -180,11 +215,6 @@ export class ODOption extends api.ODManager<ODOptionData<api.ODValidJsonType>> {
|
||||
data
|
||||
}
|
||||
}
|
||||
|
||||
/**Create an option from a JSON object in the database. */
|
||||
static fromJson(json:ODOptionJson): ODOption {
|
||||
return new ODOption(json.id,json.type,json.data.map((data) => new ODOptionData(data.id,data.value)))
|
||||
}
|
||||
}
|
||||
|
||||
/**## ODOptionData `class`
|
||||
@@ -224,32 +254,11 @@ export class ODOptionData<DataType extends api.ODValidJsonType> extends api.ODMa
|
||||
*
|
||||
* Use this option to create a new ticket!
|
||||
*/
|
||||
export class ODTicketOption extends ODOption {
|
||||
type: "opendiscord:ticket" = "opendiscord:ticket"
|
||||
export class ODTicketOption extends ODOption<ODTicketOptionIdMappings> {
|
||||
readonly type: "opendiscord:ticket" = "opendiscord:ticket"
|
||||
|
||||
constructor(id:api.ODValidId, data:ODOptionData<api.ODValidJsonType>[]){
|
||||
super(id,"opendiscord:ticket",data)
|
||||
}
|
||||
|
||||
get<OptionId extends keyof api.ODNoGeneric<ODTicketOptionIdMappings>>(id:OptionId): ODTicketOptionIdMappings[OptionId]
|
||||
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
|
||||
|
||||
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
|
||||
return super.get(id)
|
||||
}
|
||||
|
||||
remove<OptionId extends keyof api.ODNoGeneric<ODTicketOptionIdMappings>>(id:OptionId): ODTicketOptionIdMappings[OptionId]
|
||||
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
|
||||
|
||||
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
|
||||
return super.remove(id)
|
||||
}
|
||||
|
||||
exists(id:keyof api.ODNoGeneric<ODTicketOptionIdMappings>): boolean
|
||||
exists(id:api.ODValidId): boolean
|
||||
|
||||
exists(id:api.ODValidId): boolean {
|
||||
return super.exists(id)
|
||||
super(id,data)
|
||||
}
|
||||
|
||||
static fromJson(json: ODOptionJson): ODTicketOption {
|
||||
@@ -264,32 +273,11 @@ export class ODTicketOption extends ODOption {
|
||||
*
|
||||
* Use this option to create a button which links to a website!
|
||||
*/
|
||||
export class ODWebsiteOption extends ODOption {
|
||||
type: "opendiscord:website" = "opendiscord:website"
|
||||
export class ODWebsiteOption extends ODOption<ODWebsiteOptionIdMappings> {
|
||||
readonly type: "opendiscord:website" = "opendiscord:website"
|
||||
|
||||
constructor(id:api.ODValidId, data:ODOptionData<api.ODValidJsonType>[]){
|
||||
super(id,"opendiscord:website",data)
|
||||
}
|
||||
|
||||
get<OptionId extends keyof api.ODNoGeneric<ODWebsiteOptionIdMappings>>(id:OptionId): ODWebsiteOptionIdMappings[OptionId]
|
||||
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
|
||||
|
||||
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
|
||||
return super.get(id)
|
||||
}
|
||||
|
||||
remove<OptionId extends keyof api.ODNoGeneric<ODWebsiteOptionIdMappings>>(id:OptionId): ODWebsiteOptionIdMappings[OptionId]
|
||||
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
|
||||
|
||||
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
|
||||
return super.remove(id)
|
||||
}
|
||||
|
||||
exists(id:keyof api.ODNoGeneric<ODWebsiteOptionIdMappings>): boolean
|
||||
exists(id:api.ODValidId): boolean
|
||||
|
||||
exists(id:api.ODValidId): boolean {
|
||||
return super.exists(id)
|
||||
super(id,data)
|
||||
}
|
||||
|
||||
static fromJson(json: ODOptionJson): ODWebsiteOption {
|
||||
@@ -304,32 +292,11 @@ export class ODWebsiteOption extends ODOption {
|
||||
*
|
||||
* Use this option to create a button for reaction roles!
|
||||
*/
|
||||
export class ODRoleOption extends ODOption {
|
||||
type: "opendiscord:role" = "opendiscord:role"
|
||||
export class ODRoleOption extends ODOption<ODRoleOptionIdMappings> {
|
||||
readonly type: "opendiscord:role" = "opendiscord:role"
|
||||
|
||||
constructor(id:api.ODValidId, data:ODOptionData<api.ODValidJsonType>[]){
|
||||
super(id,"opendiscord:role",data)
|
||||
}
|
||||
|
||||
get<OptionId extends keyof api.ODNoGeneric<ODRoleOptionIdMappings>>(id:OptionId): ODRoleOptionIdMappings[OptionId]
|
||||
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
|
||||
|
||||
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
|
||||
return super.get(id)
|
||||
}
|
||||
|
||||
remove<OptionId extends keyof api.ODNoGeneric<ODRoleOptionIdMappings>>(id:OptionId): ODRoleOptionIdMappings[OptionId]
|
||||
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
|
||||
|
||||
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
|
||||
return super.remove(id)
|
||||
}
|
||||
|
||||
exists(id:keyof api.ODNoGeneric<ODRoleOptionIdMappings>): boolean
|
||||
exists(id:api.ODValidId): boolean
|
||||
|
||||
exists(id:api.ODValidId): boolean {
|
||||
return super.exists(id)
|
||||
super(id,data)
|
||||
}
|
||||
|
||||
static fromJson(json:ODOptionJson): ODRoleOption {
|
||||
@@ -337,6 +304,25 @@ export class ODRoleOption extends ODOption {
|
||||
}
|
||||
}
|
||||
|
||||
/**## ODSubPanelOption `class`
|
||||
* This is an Open Ticket sub-panel option.
|
||||
*
|
||||
* This class contains all data related to an Open Ticket sub-panel option (parsed from the config).
|
||||
*
|
||||
* Use this option to create a button for sub-panels!
|
||||
*/
|
||||
export class ODSubPanelOption extends ODOption<ODSubPanelOptionIdMappings> {
|
||||
readonly type: "opendiscord:sub-panel" = "opendiscord:sub-panel"
|
||||
|
||||
constructor(id:api.ODValidId, data:ODOptionData<api.ODValidJsonType>[]){
|
||||
super(id,data)
|
||||
}
|
||||
|
||||
static fromJson(json:ODOptionJson): ODSubPanelOption {
|
||||
return new ODSubPanelOption(json.id,json.data.map((data) => new ODOptionData(data.id,data.value)))
|
||||
}
|
||||
}
|
||||
|
||||
/**## ODOptionSuffixManager `class`
|
||||
* This is an Open Ticket option suffix manager.
|
||||
*
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import * as api from "@open-discord-bots/framework/api"
|
||||
import { ODPermissionEmbedType } from "./permission.js"
|
||||
import { ODTranscriptCompiler, ODTranscriptCompilerCompileResult } from "../api/transcript.js"
|
||||
import { ODRoleOption, ODTicketOption, ODWebsiteOption } from "../api/option.js"
|
||||
import { ODRoleOption, ODSubPanelOption, ODTicketOption, ODWebsiteOption } from "../api/option.js"
|
||||
import { ODTicket, ODTicketClearFilter } from "../api/ticket.js"
|
||||
import { ODRole, ODRoleUpdateResult } from "../api/role.js"
|
||||
import { ODPriorityLevel } from "../api/priority.js"
|
||||
@@ -25,9 +25,10 @@ export interface ODButtonManagerIdMappings extends api.ODButtonManagerIdConstrai
|
||||
"opendiscord:help-menu-page":{origin:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu-page"}
|
||||
"opendiscord:help-menu-switch":{origin:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu-switch"},
|
||||
|
||||
"opendiscord:ticket-option":{origin:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODTicketOption},workers:"opendiscord:ticket-option"},
|
||||
"opendiscord:website-option":{origin:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODWebsiteOption},workers:"opendiscord:website-option"},
|
||||
"opendiscord:role-option":{origin:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODRoleOption},workers:"opendiscord:role-option"}
|
||||
"opendiscord:ticket-option":{origin:"slash"|"text"|"sub-panel"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODTicketOption},workers:"opendiscord:ticket-option"},
|
||||
"opendiscord:website-option":{origin:"slash"|"text"|"sub-panel"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODWebsiteOption},workers:"opendiscord:website-option"},
|
||||
"opendiscord:role-option":{origin:"slash"|"text"|"sub-panel"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODRoleOption},workers:"opendiscord:role-option"}
|
||||
"opendiscord:subpanel-option":{origin:"slash"|"text"|"sub-panel"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODSubPanelOption},workers:"opendiscord:subpanel-option"}
|
||||
|
||||
"opendiscord:visit-ticket":{origin:"ticket-created"|"dm"|"logs"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:visit-ticket"},
|
||||
|
||||
@@ -51,7 +52,7 @@ export interface ODButtonManagerIdMappings extends api.ODButtonManagerIdConstrai
|
||||
* It's used to generate typescript declarations for this class.
|
||||
*/
|
||||
export interface ODDropdownManagerIdMappings extends api.ODDropdownManagerIdConstraint {
|
||||
"opendiscord:panel-dropdown-tickets":{origin:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,options:ODTicketOption[]},workers:"opendiscord:panel-dropdown-tickets"}
|
||||
"opendiscord:panel-dropdown-tickets":{origin:"slash"|"text"|"sub-panel"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,options:ODTicketOption[]},workers:"opendiscord:panel-dropdown-tickets"}
|
||||
}
|
||||
|
||||
/**## ODFileManagerIdMappings `interface`
|
||||
@@ -93,7 +94,7 @@ export interface ODEmbedManagerIdMappings extends api.ODEmbedManagerIdConstraint
|
||||
"opendiscord:stats-reset":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,reason:string|null},workers:"opendiscord:stats-reset"},
|
||||
"opendiscord:stats-ticket-unknown":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,id:string},workers:"opendiscord:stats-ticket-unknown"},
|
||||
|
||||
"opendiscord:panel":{origin:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel},workers:"opendiscord:panel"},
|
||||
"opendiscord:panel":{origin:"slash"|"text"|"sub-panel"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,isSubPanel:boolean},workers:"opendiscord:panel"},
|
||||
"opendiscord:ticket-created":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created"},
|
||||
"opendiscord:ticket-created-dm":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created-dm"},
|
||||
"opendiscord:ticket-created-logs":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created-logs"},
|
||||
@@ -176,7 +177,7 @@ export interface ODMessageManagerIdMappings extends api.ODMessageManagerIdConstr
|
||||
"opendiscord:stats-reset":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,reason:string|null},workers:"opendiscord:stats-reset"},
|
||||
"opendiscord:stats-ticket-unknown":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,id:string},workers:"opendiscord:stats-ticket-unknown"},
|
||||
|
||||
"opendiscord:panel":{origin:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel},workers:"opendiscord:panel-layout"|"opendiscord:panel-components"},
|
||||
"opendiscord:panel":{origin:"slash"|"text"|"sub-panel"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,isSubPanel:boolean},workers:"opendiscord:panel-layout"|"opendiscord:panel-components"},
|
||||
"opendiscord:panel-ready":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel},workers:"opendiscord:panel-ready"},
|
||||
|
||||
"opendiscord:ticket-created":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created"},
|
||||
|
||||
@@ -48,6 +48,7 @@ export interface ODButtonResponderManagerIdMappings extends api.ODButtonResponde
|
||||
|
||||
"opendiscord:ticket-option":{origin:"button",params:{},workers:"opendiscord:ticket-option"},
|
||||
"opendiscord:role-option":{origin:"button",params:{},workers:"opendiscord:role-option"},
|
||||
"opendiscord:subpanel-option":{origin:"button",params:{},workers:"opendiscord:subpanel-option"},
|
||||
|
||||
"opendiscord:claim-ticket":{origin:"button",params:{},workers:"opendiscord:claim-ticket"},
|
||||
"opendiscord:unclaim-ticket":{origin:"button",params:{},workers:"opendiscord:unclaim-ticket"},
|
||||
|
||||
@@ -67,13 +67,15 @@ export class ODClearMessageState extends api.ODState<{
|
||||
*/
|
||||
export class ODPanelMessageState extends api.ODState<{
|
||||
/**The method this message was generated with. */
|
||||
messageOrigin:"slash"|"text"|"auto-update"|"other",
|
||||
messageOrigin:"slash"|"text"|"sub-panel"|"auto-update"|"other",
|
||||
/**The Id of the panel associated with this message. */
|
||||
panelId:string,
|
||||
/**A list of options available in this panel. (buttons or dropdown) */
|
||||
panelOptionIds:string[]
|
||||
/**Should this panel be auto-updated on restart? */
|
||||
panelAutoUpdate:boolean
|
||||
panelAutoUpdate:boolean,
|
||||
/**Is this panel a sub-panel? */
|
||||
isSubPanel:boolean
|
||||
},false,false> {
|
||||
constructor(id:api.ODValidId,client:api.ODClientManager,database:api.ODDatabase){
|
||||
super(id,client,database,{})
|
||||
|
||||
@@ -378,15 +378,42 @@ export const migrations = [
|
||||
await globalDatabase.delete("opendiscord:panel-update",panelMessage.key)
|
||||
}
|
||||
})
|
||||
opendiscord.events.get("afterStatesInitiated").listen(async (states) => {
|
||||
const panelMsgState = states.get("opendiscord:panel-message")
|
||||
opendiscord.events.get("beforeReadyForUsage").listen(async () => {
|
||||
const panelMsgState = opendiscord.states.get("opendiscord:panel-message")
|
||||
for (const {channelId,messageId,panelId,autoUpdate} of migratedPanelStates){
|
||||
await panelMsgState.setMsgState({channel:channelId,message:messageId},{
|
||||
messageOrigin:"auto-update",
|
||||
panelId,
|
||||
panelOptionIds:[],
|
||||
panelAutoUpdate:autoUpdate
|
||||
panelAutoUpdate:autoUpdate,
|
||||
isSubPanel:false
|
||||
},false)
|
||||
|
||||
if (!autoUpdate){
|
||||
//auto update ALL non auto-update panels once to update button changes from v4.1 -> v4.2
|
||||
const panel = opendiscord.panels.get(panelId)
|
||||
if (!panel) continue
|
||||
|
||||
//fetch panel message
|
||||
const mainServer = opendiscord.client.mainServer
|
||||
const message = await opendiscord.client.fetchChannelMessage(channelId,messageId)
|
||||
if (!message || !mainServer || !message.editable || message.flags.has("Ephemeral")) continue
|
||||
|
||||
const panelMessage = await message.edit((await opendiscord.builders.messages.getSafe("opendiscord:panel").build("auto-update",{guild:mainServer,channel:message.channel,user:opendiscord.client.client.user,panel,isSubPanel:false})).message)
|
||||
if (panelMessage) await panelMsgState.setMsgState({channel:message.channel,message:panelMessage},{
|
||||
messageOrigin:"auto-update",
|
||||
panelId:panel.id.value,
|
||||
panelOptionIds:panel.get("opendiscord:options").value,
|
||||
panelAutoUpdate:false,
|
||||
isSubPanel:false
|
||||
},panelMessage.flags.has("Ephemeral"))
|
||||
|
||||
opendiscord.log("Panel in server got updated to v4.2!","info",[
|
||||
{key:"channelid",value:channelId},
|
||||
{key:"messageid",value:messageId},
|
||||
{key:"panel",value:panel.id.value}
|
||||
])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -270,12 +270,13 @@ export async function loadPanelAutoUpdateCode(){
|
||||
const message = await opendiscord.client.fetchChannelMessage(channel,panelState.messageId)
|
||||
if (!message || !message.editable || message.flags.has("Ephemeral")) continue
|
||||
|
||||
const panelMessage = await message.edit((await opendiscord.builders.messages.getSafe("opendiscord:panel").build("auto-update",{guild:mainServer,channel,user:opendiscord.client.client.user,panel})).message)
|
||||
const panelMessage = await message.edit((await opendiscord.builders.messages.getSafe("opendiscord:panel").build("auto-update",{guild:mainServer,channel,user:opendiscord.client.client.user,panel,isSubPanel:false})).message)
|
||||
if (panelMessage) await panelMsgState.setMsgState({channel,message:panelMessage},{
|
||||
messageOrigin:"auto-update",
|
||||
panelId:panel.id.value,
|
||||
panelOptionIds:panel.get("opendiscord:options").value,
|
||||
panelAutoUpdate:true
|
||||
panelAutoUpdate:true,
|
||||
isSubPanel:false
|
||||
},panelMessage.flags.has("Ephemeral"))
|
||||
|
||||
opendiscord.log("Panel in server got auto-updated!","info",[
|
||||
|
||||
@@ -9,11 +9,9 @@ export async function loadAllOptions(){
|
||||
const loadedOption = loadTicketOption(option)
|
||||
opendiscord.options.add(loadedOption)
|
||||
opendiscord.options.suffix.add(loadTicketOptionSuffix(loadedOption))
|
||||
}else if (option.type == "website"){
|
||||
opendiscord.options.add(loadWebsiteOption(option))
|
||||
}else if (option.type == "role"){
|
||||
opendiscord.options.add(loadRoleOption(option))
|
||||
}
|
||||
}else if (option.type == "website") opendiscord.options.add(loadWebsiteOption(option))
|
||||
else if (option.type == "role") opendiscord.options.add(loadRoleOption(option))
|
||||
else if (option.type == "sub-panel") opendiscord.options.add(loadSubPanelOption(option))
|
||||
})
|
||||
|
||||
//update options on config reload
|
||||
@@ -23,17 +21,15 @@ export async function loadAllOptions(){
|
||||
await opendiscord.options.suffix.loopAll((data,id) => {opendiscord.options.suffix.remove(id)})
|
||||
|
||||
//add new options
|
||||
optionConfig.data.forEach((option) => {
|
||||
for (const option of optionConfig.data){
|
||||
if (option.type == "ticket"){
|
||||
const loadedOption = loadTicketOption(option)
|
||||
opendiscord.options.add(loadedOption)
|
||||
opendiscord.options.suffix.add(loadTicketOptionSuffix(loadedOption))
|
||||
}else if (option.type == "website"){
|
||||
opendiscord.options.add(loadWebsiteOption(option))
|
||||
}else if (option.type == "role"){
|
||||
opendiscord.options.add(loadRoleOption(option))
|
||||
}
|
||||
})
|
||||
}else if (option.type == "website") opendiscord.options.add(loadWebsiteOption(option))
|
||||
else if (option.type == "role") opendiscord.options.add(loadRoleOption(option))
|
||||
else if (option.type == "sub-panel") opendiscord.options.add(loadSubPanelOption(option))
|
||||
}
|
||||
|
||||
//update options in tickets
|
||||
await opendiscord.tickets.loopAll((ticket) => {
|
||||
@@ -132,6 +128,19 @@ export const loadRoleOption = (opt:api.ODOptionsJsonConfig_RoleOption): api.ODRo
|
||||
])
|
||||
}
|
||||
|
||||
export const loadSubPanelOption = (opt:api.ODOptionsJsonConfig_SubPanelOption): api.ODSubPanelOption => {
|
||||
return new api.ODSubPanelOption(opt.id,[
|
||||
new api.ODOptionData("opendiscord:name",opt.name),
|
||||
new api.ODOptionData("opendiscord:description",opt.description),
|
||||
|
||||
new api.ODOptionData("opendiscord:button-emoji",opt.button.emoji),
|
||||
new api.ODOptionData("opendiscord:button-label",opt.button.label),
|
||||
new api.ODOptionData("opendiscord:button-color",opt.button.color),
|
||||
|
||||
new api.ODOptionData("opendiscord:panel-id",opt.subPanelId)
|
||||
])
|
||||
}
|
||||
|
||||
export const loadTicketOptionSuffix = (option:api.ODTicketOption): api.ODOptionSuffix => {
|
||||
const mode = option.get("opendiscord:channel-suffix").value
|
||||
const globalDatabase = opendiscord.databases.get("opendiscord:global")
|
||||
|
||||
+8
-9
@@ -526,15 +526,13 @@ const main = async () => {
|
||||
await opendiscord.events.get("afterStatesLoaded").emit([opendiscord.states])
|
||||
|
||||
//init states (async to prevent blocking startup)
|
||||
utilities.runAsync(async () => {
|
||||
opendiscord.log("Initiating states...","system")
|
||||
await opendiscord.events.get("onStateInit").emit([opendiscord.states])
|
||||
if (opendiscord.sharedFuses.getFuse("stateInitiating")){
|
||||
await opendiscord.states.init()
|
||||
await opendiscord.events.get("afterStatesInitiated").emit([opendiscord.states])
|
||||
}
|
||||
opendiscord.log("Message states ready!","info")
|
||||
})
|
||||
opendiscord.log("Initiating states... (may take a while for many tickets)","system")
|
||||
await opendiscord.events.get("onStateInit").emit([opendiscord.states])
|
||||
if (opendiscord.sharedFuses.getFuse("stateInitiating")){
|
||||
await opendiscord.states.init()
|
||||
await opendiscord.events.get("afterStatesInitiated").emit([opendiscord.states])
|
||||
}
|
||||
opendiscord.log("Message states ready!","info")
|
||||
|
||||
//plugin loading before managers
|
||||
await opendiscord.events.get("onPluginBeforeManagerLoad").emit([])
|
||||
@@ -727,6 +725,7 @@ const main = async () => {
|
||||
await (await import("./actions/handleVerifyBar.js")).registerButtonResponders()
|
||||
await (await import("./actions/handleTranscriptErrors.js")).registerButtonResponders()
|
||||
await (await import("./commands/help.js")).registerButtonResponders()
|
||||
await (await import("./commands/panel.js")).registerButtonResponders()
|
||||
await (await import("./commands/ticket.js")).registerButtonResponders()
|
||||
await (await import("./commands/close.js")).registerButtonResponders()
|
||||
await (await import("./commands/reopen.js")).registerButtonResponders()
|
||||
|
||||
Reference in New Issue
Block a user