(v4.2.0) Added sub-panels
This commit is contained in:
+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}
|
||||
])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user