Started with CLI "Quick Setup" feature.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import {opendiscord, api, utilities} from "../../index"
|
||||
import {Terminal, terminal} from "terminal-kit"
|
||||
import ansis from "ansis"
|
||||
|
||||
const logo = [
|
||||
" ██████╗ ██████╗ ███████╗███╗ ██╗ ████████╗██╗ ██████╗██╗ ██╗███████╗████████╗ ",
|
||||
" ██╔═══██╗██╔══██╗██╔════╝████╗ ██║ ╚══██╔══╝██║██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝ ",
|
||||
" ██║ ██║██████╔╝█████╗ ██╔██╗ ██║ ██║ ██║██║ █████╔╝ █████╗ ██║ ",
|
||||
" ██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║ ██║ ██║██║ ██╔═██╗ ██╔══╝ ██║ ",
|
||||
" ╚██████╔╝██║ ███████╗██║ ╚████║ ██║ ██║╚██████╗██║ ██╗███████╗ ██║ ",
|
||||
" ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝ "
|
||||
]
|
||||
|
||||
/**A utility function to center text to a certain width. */
|
||||
export function centerText(text:string,width:number){
|
||||
if (width < text.length) return text
|
||||
let newWidth = width-ansis.strip(text).length+1
|
||||
let final = " ".repeat(newWidth/2)+text
|
||||
return final
|
||||
}
|
||||
|
||||
/**A utility function to terminate the interactive CLI. */
|
||||
export async function terminate(){
|
||||
terminal.grabInput(false)
|
||||
terminal.clear()
|
||||
terminal.green("👋 Exited the Open Ticket Interactive Setup CLI.\n")
|
||||
process.exit(0)
|
||||
}
|
||||
terminal.on("key",(name,matches,data) => {
|
||||
if (name == "CTRL_C") terminate()
|
||||
})
|
||||
|
||||
/**Render the header of the interactive CLI. */
|
||||
export function renderHeader(path:(string|number)[]|string){
|
||||
terminal.grabInput(true)
|
||||
terminal.clear().moveTo(1,1)
|
||||
terminal(ansis.hex("#f8ba00")(logo.join("\n")+"\n"))
|
||||
terminal.bold(centerText("Interactive Setup CLI - Version: "+opendiscord.versions.get("opendiscord:version").toString()+" - Support: https://discord.dj-dj.be\n",88))
|
||||
if (typeof path == "string") terminal.cyan(centerText(path+"\n\n",88))
|
||||
else if (path.length < 1) terminal.cyan(centerText("👋 Hi! Welcome to the Open Ticket Interactive Setup CLI! 👋\n\n",88))
|
||||
else terminal.cyan(centerText("🌐 Current Location: "+path.map((v,i) => {
|
||||
if (i == 0) return v.toString()
|
||||
else if (typeof v == "string") return ".\""+v+"\""
|
||||
else if (typeof v == "number") return "."+v
|
||||
}).join("")+"\n\n",88))
|
||||
}
|
||||
|
||||
async function renderCliModeSelector(backFn:(() => api.ODPromiseVoid)){
|
||||
renderHeader([])
|
||||
terminal(ansis.bold.green("Please select what CLI module you want to use.\n")+ansis.italic.gray("(use arrow keys to navigate, exit using escape)\n"))
|
||||
|
||||
const answer = await terminal.singleColumnMenu([
|
||||
"✏️ Edit Config "+ansis.gray("=> Edit the current config, add/remove new tickets/questions/panels & more!"),
|
||||
"⏱️ Quick Setup "+ansis.gray("=> A quick and easy way of setting up the bot in your Discord server."),
|
||||
],{
|
||||
leftPadding:"> ",
|
||||
style:terminal.cyan,
|
||||
selectedStyle:terminal.bgDefaultColor.bold,
|
||||
submittedStyle:terminal.bgBlue,
|
||||
extraLines:2,
|
||||
cancelable:true
|
||||
}).promise
|
||||
|
||||
if (answer.canceled) return await backFn()
|
||||
else if (answer.selectedIndex == 0) await (await import("./editConfig.js")).renderEditConfig(async () => {await renderCliModeSelector(backFn)})
|
||||
else if (answer.selectedIndex == 1) await (await import("./quickSetup.js")).renderQuickSetup(async () => {await renderCliModeSelector(backFn)})
|
||||
}
|
||||
|
||||
export async function execute(){
|
||||
if (terminal.width < 100 || terminal.height < 35){
|
||||
terminal(ansis.red.bold("\n\nMake sure your console or cmd window has a "+ansis.cyan("minimum width & height")+" of "+ansis.cyan("100x35")+" characters."))
|
||||
terminal(ansis.red.bold("\nOtherwise the Open Ticket Interactive Setup CLI will be rendered incorrectly."))
|
||||
terminal(ansis.red.bold("\nThe current terminal dimensions are: "+ansis.cyan(terminal.width+"x"+terminal.height)+"."))
|
||||
}else await renderCliModeSelector(terminate)
|
||||
}
|
||||
@@ -1,50 +1,9 @@
|
||||
import {opendiscord, api, utilities} from "../../index"
|
||||
import {Terminal, terminal} from "terminal-kit"
|
||||
import ansis from "ansis"
|
||||
import {renderHeader} from "./cli"
|
||||
|
||||
const logo = [
|
||||
" ██████╗ ██████╗ ███████╗███╗ ██╗ ████████╗██╗ ██████╗██╗ ██╗███████╗████████╗ ",
|
||||
" ██╔═══██╗██╔══██╗██╔════╝████╗ ██║ ╚══██╔══╝██║██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝ ",
|
||||
" ██║ ██║██████╔╝█████╗ ██╔██╗ ██║ ██║ ██║██║ █████╔╝ █████╗ ██║ ",
|
||||
" ██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║ ██║ ██║██║ ██╔═██╗ ██╔══╝ ██║ ",
|
||||
" ╚██████╔╝██║ ███████╗██║ ╚████║ ██║ ██║╚██████╗██║ ██╗███████╗ ██║ ",
|
||||
" ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝ "
|
||||
]
|
||||
|
||||
/**A utility function to center text to a certain width. */
|
||||
function centerText(text:string,width:number){
|
||||
if (width < text.length) return text
|
||||
let newWidth = width-ansis.strip(text).length+1
|
||||
let final = " ".repeat(newWidth/2)+text
|
||||
return final
|
||||
}
|
||||
|
||||
/**A utility function to terminate the interactive CLI. */
|
||||
async function terminate(){
|
||||
terminal.grabInput(false)
|
||||
terminal.clear()
|
||||
terminal.green("👋 Exited the Open Ticket Interactive Setup CLI.\n")
|
||||
process.exit(0)
|
||||
}
|
||||
terminal.on("key",(name,matches,data) => {
|
||||
if (name == "CTRL_C") terminate()
|
||||
})
|
||||
|
||||
/**Render the header of the interactive CLI. */
|
||||
function renderHeader(path:(string|number)[]){
|
||||
terminal.grabInput(true)
|
||||
terminal.clear().moveTo(1,1)
|
||||
terminal(ansis.hex("#f8ba00")(logo.join("\n")+"\n"))
|
||||
terminal.bold(centerText("Interactive Setup CLI - Version: "+opendiscord.versions.get("opendiscord:version").toString()+" - Support: https://discord.dj-dj.be\n",88))
|
||||
if (path.length < 1) terminal.cyan(centerText("👋 Hi! Welcome to the Open Ticket Interactive Setup CLI! 👋\n\n",88))
|
||||
else terminal.cyan(centerText("🌐 Current Location: "+path.map((v,i) => {
|
||||
if (i == 0) return v.toString()
|
||||
else if (typeof v == "string") return ".\""+v+"\""
|
||||
else if (typeof v == "number") return "."+v
|
||||
}).join("")+"\n\n",88))
|
||||
}
|
||||
|
||||
async function renderConfigSelector(backFn:(() => api.ODPromiseVoid)){
|
||||
export async function renderEditConfig(backFn:(() => api.ODPromiseVoid)){
|
||||
renderHeader([])
|
||||
terminal(ansis.bold.green("Please select which config you would like to edit.\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
|
||||
|
||||
@@ -65,7 +24,7 @@ async function renderConfigSelector(backFn:(() => api.ODPromiseVoid)){
|
||||
if (answer.canceled) return await backFn()
|
||||
const checker = checkerList[answer.selectedIndex]
|
||||
const configData = checker.config.data as api.ODValidJsonType
|
||||
await chooseConfigStructure(checker,async () => {await renderConfigSelector(backFn)},checker.structure,configData,{},NaN,["("+checker.config.path+")"])
|
||||
await chooseConfigStructure(checker,async () => {await renderEditConfig(backFn)},checker.structure,configData,{},NaN,["("+checker.config.path+")"])
|
||||
}
|
||||
|
||||
async function chooseConfigStructure(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),structure:api.ODCheckerStructure,data:api.ODValidJsonType,parent:object|any[],parentIndex:string|number,path:(string|number)[]){
|
||||
@@ -938,7 +897,6 @@ async function renderAdditionConfigArrayStructureSelector(checker:api.ODChecker,
|
||||
else if (answer.selectedIndex == 5) await renderConfigArrayStructureDuplicateSelector(checker,backFnFunc,structure,structure.options.propertyChecker,localData,parent,parentIndex,path)
|
||||
}
|
||||
|
||||
|
||||
async function renderAdditionConfigTypeSwitchStructure(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),nextFn:((data:any) => api.ODPromiseVoid),structure:api.ODCheckerTypeSwitchStructure,parent:object|any[],parentIndex:string|number,path:(string|number)[],localPath:(string|number)[]){
|
||||
renderHeader(path)
|
||||
terminal(ansis.bold.green("You are now creating "+(typeof parentIndex == "string" ? "the property "+ansis.blue("\""+parentIndex+"\"") : "property "+ansis.blue("#"+(parentIndex+1)))+".\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
|
||||
@@ -973,11 +931,3 @@ async function renderAdditionConfigTypeSwitchStructure(checker:api.ODChecker,bac
|
||||
else if (answer.selectedText.startsWith("Create as array/list") && structure.options.array) await renderAdditionConfigArrayStructureSelector(checker,async () => {await renderAdditionConfigTypeSwitchStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)},nextFn,structure.options.array,parent,parentIndex,path,localPath)
|
||||
else if (answer.selectedText.startsWith("Create as null") && structure.options.null) await renderAdditionConfigNullStructure(checker,async () => {await renderAdditionConfigTypeSwitchStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)},nextFn,structure.options.null,parent,parentIndex,path,localPath)
|
||||
}
|
||||
|
||||
export async function execute(){
|
||||
if (terminal.width < 100 || terminal.height < 35){
|
||||
terminal(ansis.red.bold("\n\nMake sure your console or cmd window has a "+ansis.cyan("minimum width & height")+" of "+ansis.cyan("100x35")+" characters."))
|
||||
terminal(ansis.red.bold("\nOtherwise the Open Ticket Interactive Setup CLI will be rendered incorrectly."))
|
||||
terminal(ansis.red.bold("\nThe current terminal dimensions are: "+ansis.cyan(terminal.width+"x"+terminal.height)+"."))
|
||||
}else await renderConfigSelector(terminate)
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
import {opendiscord, api, utilities} from "../../index"
|
||||
import {Terminal, terminal} from "terminal-kit"
|
||||
import ansis from "ansis"
|
||||
import {renderHeader} from "./cli"
|
||||
|
||||
export async function renderQuickSetup(backFn:() => api.ODPromiseVoid){
|
||||
if (quickSetupRequiresReset()) await renderQuickSetupWarning(backFn)
|
||||
else await renderQuickSetupWelcome(backFn)
|
||||
}
|
||||
|
||||
function quickSetupRequiresReset(): boolean {
|
||||
const generalConfig = opendiscord.configs.get("opendiscord:general")
|
||||
if (generalConfig.data.token != "your bot token here! (or leave empty when using 'tokenFromENV')") return true
|
||||
if (generalConfig.data.mainColor != "#f8ba00") return true
|
||||
if (generalConfig.data.language != "english") return true
|
||||
if (generalConfig.data.prefix != "!ticket ") return true
|
||||
if (generalConfig.data.serverId != "discord server id") return true
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
async function renderQuickSetupWarning(backFn:() => api.ODPromiseVoid) {
|
||||
renderHeader("⏱️ Open Ticket Quick Setup: Warning")
|
||||
|
||||
terminal.bold(ansis.yellow("WARNING! ")+ansis.red("By using the 'Quick Setup' feature, your current config will be completely resetted!"))
|
||||
terminal.gray("\n\nAre you sure you want to continue?")
|
||||
|
||||
const answer = await terminal.singleColumnMenu([
|
||||
ansis.green("✅ No, take me back."),
|
||||
ansis.red("🚨 Yes, continue and reset the config.")
|
||||
],{
|
||||
leftPadding:"> ",
|
||||
style:terminal.cyan,
|
||||
selectedStyle:terminal.bgDefaultColor.bold,
|
||||
submittedStyle:terminal.bgBlue,
|
||||
extraLines:2,
|
||||
cancelable:true
|
||||
}).promise
|
||||
|
||||
if (answer.canceled || answer.selectedIndex == 0) return await backFn()
|
||||
if (answer.selectedIndex == 1) await renderQuickSetupWelcome(async () => {await renderQuickSetupWarning(backFn)})
|
||||
}
|
||||
|
||||
async function renderQuickSetupWelcome(backFn:() => api.ODPromiseVoid){
|
||||
renderHeader("⏱️ Open Ticket Quick Setup: Introduction")
|
||||
|
||||
terminal.bold.underline.blue("Open Ticket: Quick Setup\n")
|
||||
terminal.gray([
|
||||
"Hi there! Thank you for downloading and installing Open Ticket.",
|
||||
"You have chosen to configure the bot using the 'Quick Setup CLI'.",
|
||||
"",
|
||||
"This program will help you with configuring Open Ticket using a step-by-step method.",
|
||||
"If you've ever used Google Forms, then this will probably be very easy for you 😉.",
|
||||
"",
|
||||
ansis.magenta("The configuration should normally only take around 5 minutes."),
|
||||
ansis.magenta("Once you've completed the form, the bot is technically ready for usage!")
|
||||
].join("\n")+"\n\n")
|
||||
|
||||
const answer = await terminal.singleColumnMenu([
|
||||
ansis.green("Press 'Enter' to start!")
|
||||
],{
|
||||
leftPadding:"> ",
|
||||
style:terminal.cyan,
|
||||
selectedStyle:terminal.bgDefaultColor.bold,
|
||||
submittedStyle:terminal.bgBlue,
|
||||
extraLines:2,
|
||||
cancelable:true
|
||||
}).promise
|
||||
|
||||
if (answer.canceled) return await backFn()
|
||||
else if (answer.selectedIndex == 0) await renderQuickSetupDevPortalInfo(async () => {await renderQuickSetupWelcome(backFn)})
|
||||
}
|
||||
|
||||
async function renderQuickSetupDevPortalInfo(backFn:() => api.ODPromiseVoid){
|
||||
renderHeader("⏱️ Open Ticket Quick Setup: Dev Portal & Experience")
|
||||
|
||||
terminal.bold.blue("(Step 1) Have you already created a Discord bot to use for Open Ticket?\n")
|
||||
|
||||
const answer = await terminal.singleColumnMenu([
|
||||
"✅ Yes I have, and it has been invited to the server.",
|
||||
"❓ No not yet, I don't know how to create one.",
|
||||
"👶 I've never seen a Discord bot before.",
|
||||
],{
|
||||
leftPadding:"> ",
|
||||
style:terminal.gray,
|
||||
selectedStyle:terminal.bgDefaultColor.bold,
|
||||
submittedStyle:terminal.bgBlue,
|
||||
extraLines:2,
|
||||
cancelable:true
|
||||
}).promise
|
||||
|
||||
if (answer.canceled) return await backFn()
|
||||
else if (answer.selectedIndex == 0) await backFn() //TODO NEXT QUESTION
|
||||
else if (answer.selectedIndex == 1) await renderQuickSetupDevPortalGuide(0,async () => {await renderQuickSetupDevPortalInfo(backFn)})
|
||||
else if (answer.selectedIndex == 2) await renderQuickSetupDevPortalGuide(1,async () => {await renderQuickSetupDevPortalInfo(backFn)})
|
||||
}
|
||||
|
||||
async function renderQuickSetupDevPortalGuide(variation:0|1,backFn:() => api.ODPromiseVoid){
|
||||
renderHeader("⏱️ Open Ticket Quick Setup: Dev Portal & Experience")
|
||||
|
||||
if (variation == 0){
|
||||
terminal.bold.blue("(Step 1.1) You've mentioned that you don't know how to create a Discord bot.\n\n")
|
||||
terminal.gray("Please visit the following URL for a step-by-step guide on how to create a Discord bot.\nIf it still doesn't work, join our Discord server and we will help you further!\n"+ansis.magenta("=> https://otdocs.dj-dj.be/docs/guides/get-started#bot\n\n"))
|
||||
}else{
|
||||
terminal.bold.blue("(Step 1.2) You've mentioned that you've never seen Discord bot before.\n\n")
|
||||
terminal.gray("How did you even download Open Ticket 🤪? But still, we have a step-by-step guide on how to create a Discord bot.\nIf it still doesn't work, join our Discord server and we will help you further!\n"+ansis.magenta("=> https://otdocs.dj-dj.be/docs/guides/get-started#bot\n\n"))
|
||||
}
|
||||
|
||||
const answer = await terminal.singleColumnMenu([
|
||||
ansis.green("✅ Alright, I've made the bot. Take me back please!")
|
||||
],{
|
||||
leftPadding:"> ",
|
||||
style:terminal.cyan,
|
||||
selectedStyle:terminal.bgDefaultColor.bold,
|
||||
submittedStyle:terminal.bgBlue,
|
||||
extraLines:2,
|
||||
cancelable:true
|
||||
}).promise
|
||||
|
||||
return await backFn()
|
||||
}
|
||||
+1
-1
@@ -301,7 +301,7 @@ const main = async () => {
|
||||
|
||||
//switch to CLI context instead of running the bot
|
||||
if (useCliFlag && useCliFlag.value){
|
||||
await (await (import("./core/startup/cli.js"))).execute()
|
||||
await (await (import("./core/cli/cli.js"))).execute()
|
||||
await utilities.timer(1000)
|
||||
console.log("\n\n"+ansis.red("❌ Something went wrong in the Interactive Setup CLI. Please try again or report a bug in our discord server."))
|
||||
process.exit(0)
|
||||
|
||||
Reference in New Issue
Block a user