diff --git a/src/core/api/api.ts b/src/core/api/api.ts index 7f393a0..10e7906 100644 --- a/src/core/api/api.ts +++ b/src/core/api/api.ts @@ -25,6 +25,7 @@ export * from "./modules/code" export * from "./modules/cooldown" export * from "./modules/post" export * from "./modules/verifybar" +export * from "./modules/progressbar" export * from "./modules/startscreen" //OPENTICKET DEFAULT MODULES @@ -48,6 +49,7 @@ export * from "./defaults/worker" export * from "./defaults/code" export * from "./defaults/cooldown" export * from "./defaults/post" +export * from "./defaults/progressbar" export * from "./defaults/startscreen" export * from "./defaults/console" diff --git a/src/core/api/defaults/event.ts b/src/core/api/defaults/event.ts index 3e70d00..edab225 100644 --- a/src/core/api/defaults/event.ts +++ b/src/core/api/defaults/event.ts @@ -32,6 +32,7 @@ import { ODPostManager_Default } from "./post" import { ODVerifyBarManager_Default } from "./verifybar" import { ODStartScreenManager_Default } from "./startscreen" import { ODLiveStatusManager_Default } from "./console" +import { ODProgressBarManager_Default, ODProgressBarRendererManager_Default } from "./progressbar" //OPEN TICKET MODULES import { ODOptionManager, ODTicketOption } from "../openticket/option" @@ -56,11 +57,18 @@ export interface ODEventIds_Default { "onPluginClassLoad": ODEvent_Default<(classes:ODPluginClassManager_Default, plugins:ODPluginManager_Default) => ODPromiseVoid> "afterPluginClassesLoaded": ODEvent_Default<(classes:ODPluginClassManager_Default, plugins:ODPluginManager_Default) => ODPromiseVoid> + //flags "onFlagLoad": ODEvent_Default<(flags:ODFlagManager_Default) => ODPromiseVoid> "afterFlagsLoaded": ODEvent_Default<(flags:ODFlagManager_Default) => ODPromiseVoid> "onFlagInit": ODEvent_Default<(flags:ODFlagManager_Default) => ODPromiseVoid> "afterFlagsInitiated": ODEvent_Default<(flags:ODFlagManager_Default) => ODPromiseVoid> + //progres bars + "onProgressBarRendererLoad": ODEvent_Default<(renderers:ODProgressBarRendererManager_Default) => ODPromiseVoid> + "afterProgressBarRenderersLoaded": ODEvent_Default<(renderers:ODProgressBarRendererManager_Default) => ODPromiseVoid> + "onProgressBarLoad": ODEvent_Default<(progressbars:ODProgressBarManager_Default) => ODPromiseVoid> + "afterProgressBarsLoaded": ODEvent_Default<(progressbars:ODProgressBarManager_Default) => ODPromiseVoid> + //configs "onConfigLoad": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid> "afterConfigsLoaded": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid> diff --git a/src/core/api/defaults/progressbar.ts b/src/core/api/defaults/progressbar.ts new file mode 100644 index 0000000..ff5df36 --- /dev/null +++ b/src/core/api/defaults/progressbar.ts @@ -0,0 +1,82 @@ +/////////////////////////////////////// +//DEFAULT PROGRESS BAR MODULE +/////////////////////////////////////// +import { ODValidId } from "../modules/base" +import { ODProgressBar, ODProgressBarManager, ODProgressBarRenderer, ODProgressBarRendererManager } from "../modules/progressbar" + + +/**## ODProgressBarRendererManagerIds_Default `type` + * This type is an array of ids available in the `ODProgressBarRendererManager_Default` class. + * It's used to generate typescript declarations for this class. + */ +export interface ODProgressBarRendererManagerIds_Default { + "test-progressbar-renderer":ODProgressBarRenderer<{}> +} + +/**## ODProgressBarRendererManager_Default `default_class` + * This is a special class that adds type definitions & typescript to the ODProgressBarRendererManager class. + * It doesn't add any extra features! + * + * This default class is made for the global variable `openticket.progressbars.renderers`! + */ +export class ODProgressBarRendererManager_Default extends ODProgressBarRendererManager { + get(id:ProgressBarId): ODProgressBarRendererManagerIds_Default[ProgressBarId] + get(id:ODValidId): ODProgressBarRenderer<{}>|null + + get(id:ODValidId): ODProgressBarRenderer<{}>|null { + return super.get(id) + } + + remove(id:ProgressBarId): ODProgressBarRendererManagerIds_Default[ProgressBarId] + remove(id:ODValidId): ODProgressBarRenderer<{}>|null + + remove(id:ODValidId): ODProgressBarRenderer<{}>|null { + return super.remove(id) + } + + exists(id:keyof ODProgressBarRendererManagerIds_Default): boolean + exists(id:ODValidId): boolean + + exists(id:ODValidId): boolean { + return super.exists(id) + } +} + +/**## ODProgressBarManagerIds_Default `type` + * This type is an array of ids available in the `ODProgressBarManager_Default` class. + * It's used to generate typescript declarations for this class. + */ +export interface ODProgressBarManagerIds_Default { + "test-progressbar":ODProgressBar +} + +/**## ODProgressBarManager_Default `default_class` + * This is a special class that adds type definitions & typescript to the ODProgressBarManager class. + * It doesn't add any extra features! + * + * This default class is made for the global variable `openticket.progressbars`! + */ +export class ODProgressBarManager_Default extends ODProgressBarManager { + declare renderers: ODProgressBarRendererManager_Default + + get(id:ProgressBarId): ODProgressBarManagerIds_Default[ProgressBarId] + get(id:ODValidId): ODProgressBar|null + + get(id:ODValidId): ODProgressBar|null { + return super.get(id) + } + + remove(id:ProgressBarId): ODProgressBarManagerIds_Default[ProgressBarId] + remove(id:ODValidId): ODProgressBar|null + + remove(id:ODValidId): ODProgressBar|null { + return super.remove(id) + } + + exists(id:keyof ODProgressBarManagerIds_Default): boolean + exists(id:ODValidId): boolean + + exists(id:ODValidId): boolean { + return super.exists(id) + } +} \ No newline at end of file diff --git a/src/core/api/defaults/session.ts b/src/core/api/defaults/session.ts index cce95ec..b7153cd 100644 --- a/src/core/api/defaults/session.ts +++ b/src/core/api/defaults/session.ts @@ -9,7 +9,7 @@ import { ODSession, ODSessionManager } from "../modules/session" * It's used to generate typescript declarations for this class. */ export interface ODSessionManagerIds_Default { - "test-session":ODSession + //"test-session":ODSession } /**## ODSessionManager_Default `default_class` diff --git a/src/core/api/main.ts b/src/core/api/main.ts index 5860bd9..498c0da 100644 --- a/src/core/api/main.ts +++ b/src/core/api/main.ts @@ -25,6 +25,7 @@ import { ODCodeManager_Default } from "./defaults/code" import { ODCooldownManager_Default } from "./defaults/cooldown" import { ODPostManager_Default } from "./defaults/post" import { ODVerifyBarManager_Default } from "./defaults/verifybar" +import { ODProgressBarManager_Default } from "./defaults/progressbar" import { ODStartScreenManager_Default } from "./defaults/startscreen" import { ODLiveStatusManager_Default } from "./defaults/console" @@ -65,6 +66,8 @@ export class ODMain { plugins: ODPluginManager_Default /**The manager that manages & checks all the console flags of the bot. (like `--debug`) */ flags: ODFlagManager_Default + /**The manager responsible for progress bars in the console. */ + progressbars: ODProgressBarManager_Default /**The manager that manages & contains all the config files of the bot. (like `config/general.json`) */ configs: ODConfigManager_Default /**The manager that manages & contains all the databases of the bot. (like `database/global.json`) */ @@ -136,9 +139,10 @@ export class ODMain { this.console = new ODConsoleManager(100,this.debugfile) this.debug = new ODDebugger(this.console) this.events = new ODEventManager_Default(this.debug) - + this.plugins = new ODPluginManager_Default(this.debug) this.flags = new ODFlagManager_Default(this.debug) + this.progressbars = new ODProgressBarManager_Default(this.debug) this.configs = new ODConfigManager_Default(this.debug) this.databases = new ODDatabaseManager_Default(this.debug) this.sessions = new ODSessionManager_Default(this.debug) diff --git a/src/core/api/modules/defaults.ts b/src/core/api/modules/defaults.ts index ea334fb..4aaa295 100644 --- a/src/core/api/modules/defaults.ts +++ b/src/core/api/modules/defaults.ts @@ -27,6 +27,10 @@ export interface ODDefaults { flagLoading:boolean, /**Enable the default initializer for open ticket flags. */ flagInitiating:boolean, + /**Load the default open ticket progress bar renderers. */ + progressBarRendererLoading:boolean, + /**Load the default open ticket progress bars. */ + progressBarLoading:boolean, /**Load the default open ticket configs. */ configLoading:boolean, /**Enable the default initializer for open ticket config. */ @@ -237,6 +241,8 @@ export class ODDefaultsManager { flagLoading:true, flagInitiating:true, + progressBarRendererLoading:true, + progressBarLoading:true, configLoading:true, configInitiating:true, databaseLoading:true, diff --git a/src/core/api/modules/progressbar.ts b/src/core/api/modules/progressbar.ts new file mode 100644 index 0000000..2a4209b --- /dev/null +++ b/src/core/api/modules/progressbar.ts @@ -0,0 +1,217 @@ +/////////////////////////////////////// +//PROGRESS BAR MODULE +/////////////////////////////////////// +import { ODSystemError, ODManager, ODManagerData, ODValidId } from "./base" +import { ODDebugger } from "./console" +import readline from "readline" + +/**## ODProgressBarRendererManager `class` + * This is an open ticket progress bar renderer manager. + * + * It is responsible for managing all console progress bar renderers in Open Ticket. + * + * A renderer is a function which will try to visualize the progress bar in the console. + */ +export class ODProgressBarRendererManager extends ODManager> { + constructor(debug:ODDebugger){ + super(debug,"progress bar renderer") + } +} + +/**## ODProgressBarManager `class` + * This is an open ticket progress bar manager. + * + * It is responsible for managing all console progress bars in Open Ticket. An example of this is the slash command registration progress bar. + * + * There are many types of progress bars available, but you can also create your own! + */ +export class ODProgressBarManager extends ODManager { + renderers: ODProgressBarRendererManager + + constructor(debug:ODDebugger){ + super(debug,"progress bar") + this.renderers = new ODProgressBarRendererManager(debug) + } +} + +/**## ODProgressBarRenderFunc `type` + * This is the render function for an Open Ticket console progress bar. + */ +export type ODProgressBarRenderFunc = (settings:Settings,min:number,max:number,value:number) => string + +/**## ODProgressBarRenderer `class` + * This is an open ticket console progress bar renderer. + * + * It is used to render a progress bar in the console of the bot. + * + * There are already a lot of default options available if you just want an easy progress bar! + */ +export class ODProgressBarRenderer extends ODManagerData { + settings: Settings + #render: ODProgressBarRenderFunc + + constructor(id:ODValidId,render:ODProgressBarRenderFunc,settings:Settings){ + super(id) + this.#render = render + this.settings = settings + } + + /**Render a progress bar using this renderer. */ + render(min:number,max:number,value:number){ + try { + return this.#render(this.settings,min,max,value) + }catch(err){ + process.emit("uncaughtException",err) + return "" + } + } +} + +/**## ODProgressBar `class` + * This is an open ticket console progress bar. + * + * It is used to create a simple or advanced progress bar in the console of the bot. + * These progress bars are not visible in the `otdebug.txt` file and should only be used as extra visuals. + * + * Use other classes as existing templates or create your own progress bar from scratch using this class. + */ +export class ODProgressBar extends ODManagerData { + /**The renderer of this progress bar. */ + renderer: ODProgressBarRenderer<{}> + /**Is this progress bar currently active? */ + #active: boolean = false + /**A list of listeners when the progress bar stops. */ + #stopListeners: Function[] = [] + /**The current value of the progress bar. */ + protected value: number + /**The minimum value of the progress bar. */ + min: number + /**The maximum value of the progress bar. */ + max: number + /**The initial value of the progress bar. */ + initialValue: number + + /**Enable automatic stopping when reaching `min` or `max`. */ + autoStop: null|"min"|"max" + + constructor(id:ODValidId,renderer:ODProgressBarRenderer<{}>,min:number,max:number,value:number,autoStop:null|"min"|"max"){ + super(id) + this.renderer = renderer + this.min = min + this.max = max + this.initialValue = this.#parseValue(value) + this.value = this.#parseValue(value) + this.autoStop = autoStop + } + /**Parse a value in such a way that it doesn't go below/above the min/max limits. */ + #parseValue(value:number){ + if (value > this.max) return this.max + else if (value < this.min) return this.min + else return value + } + /**Render progress bar to the console. */ + #renderStdout(){ + if (!this.#active) return + readline.clearLine(process.stdout,0) + readline.cursorTo(process.stdout,0) + process.stdout.write(this.renderer.render(this.min,this.max,this.value)) + } + /**Start showing this progress bar in the console. */ + start(){ + if (this.#active) throw new ODSystemError("ODProgressBar => unable to start when already active!") + this.value = this.#parseValue(this.initialValue) + this.#active = true + this.#renderStdout() + } + /**Update this progress bar while active. (will automatically update the progress bar in the console) */ + protected update(value:number,stop?:boolean){ + if (!this.#active) throw new ODSystemError("ODProgressBar => unable to update when not active yet!") + this.value = this.#parseValue(value) + this.#renderStdout() + if (stop || (this.autoStop == "max" && this.value == this.max) || (this.autoStop == "min" && this.value == this.min)){ + process.stdout.write("\n") + this.#active = false + this.#stopListeners.forEach((cb) => cb()) + this.#stopListeners = [] + } + } + /**Wait for the progress bar to finish. */ + finished(): Promise { + return new Promise((resolve) => { + this.#stopListeners.push(resolve) + }) + } +} + +/**## ODTimedProgressBar `class` + * This is an open ticket timed console progress bar. + * + * It is used to create a simple timed progress bar in the console. + * You can set a fixed duration (milliseconds) in the constructor. + */ +export class ODTimedProgressBar extends ODProgressBar { + /**The time in milliseconds. */ + time: number + /**The mode of the timer. */ + mode: "increasing"|"decreasing" + + constructor(id:ODValidId,renderer:ODProgressBarRenderer<{}>,time:number,mode:"increasing"|"decreasing"){ + super(id,renderer,0,time,0,(mode == "increasing") ? "max" : "min") + this.time = time + this.mode = mode + } + + /**The timer which is used. */ + async #timer(ms:number): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve() + },ms) + }) + } + /**Run the timed progress bar. */ + async #execute(){ + let i = 0 + const fragment = this.time/100 + while (i < 100){ + await this.#timer(fragment) + i++ + super.update((this.mode == "increasing") ? (i*fragment) : this.time-(i*fragment)) + } + } + start(){ + super.start() + this.#execute() + } +} + +/**## ODManualProgressBar `class` + * This is an open ticket manual console progress bar. + * + * It is used to create a simple manual progress bar in the console. + * You can update the progress manually using `update()`. + */ +export class ODManualProgressBar extends ODProgressBar { + constructor(id:ODValidId,renderer:ODProgressBarRenderer<{}>,amount:number,autoStop:null|"min"|"max"){ + super(id,renderer,0,amount,0,autoStop) + } + start(){ + super.start() + } + /**Set the value of the progress bar. */ + set(value:number,stop?:boolean){ + super.update(value,stop) + } + /**Get the current value of the progress bar. */ + get(){ + return this.value + } + /**Increase the value of the progress bar. */ + increase(amount:number,stop?:boolean){ + super.update(this.value+amount,stop) + } + /**Decrease the value of the progress bar. */ + decrease(amount:number,stop?:boolean){ + super.update(this.value-amount,stop) + } +} \ No newline at end of file diff --git a/src/data/framework/eventLoader.ts b/src/data/framework/eventLoader.ts index ad5f88d..beae995 100644 --- a/src/data/framework/eventLoader.ts +++ b/src/data/framework/eventLoader.ts @@ -17,6 +17,12 @@ export const loadAllEvents = () => { "onFlagInit", "afterFlagsInitiated", + //progress bars + "onProgressBarRendererLoad", + "afterProgressBarRenderersLoaded", + "onProgressBarLoad", + "afterProgressBarsLoaded", + //configs "onConfigLoad", "afterConfigsLoaded", diff --git a/src/data/framework/progressBarLoader.ts b/src/data/framework/progressBarLoader.ts new file mode 100644 index 0000000..afc94bf --- /dev/null +++ b/src/data/framework/progressBarLoader.ts @@ -0,0 +1,7 @@ +import {openticket, api, utilities} from "../../index" + +export const loadAllProgressBarRenderers = async () => { +} + +export const loadAllProgressBars = async () => { +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index ac48088..24d20a2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -114,6 +114,21 @@ const main = async () => { openticket.debug.visible = (debugFlag) ? debugFlag.value : false } + //load progress bar renderers + openticket.log("Loading progress bars...","system") + if (openticket.defaults.getDefault("progressBarRendererLoading")){ + await (await import("./data/framework/progressBarLoader.js")).loadAllProgressBarRenderers() + } + await openticket.events.get("onProgressBarRendererLoad").emit([openticket.progressbars.renderers]) + await openticket.events.get("afterProgressBarRenderersLoaded").emit([openticket.progressbars.renderers]) + + //load progress bars + if (openticket.defaults.getDefault("progressBarLoading")){ + await (await import("./data/framework/progressBarLoader.js")).loadAllProgressBars() + } + await openticket.events.get("onProgressBarLoad").emit([openticket.progressbars]) + await openticket.events.get("afterProgressBarsLoaded").emit([openticket.progressbars]) + //load config openticket.log("Loading configs...","system") if (openticket.defaults.getDefault("configLoading")){