@azurioh/discord-kernel 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +77 -0
- package/dist/authz/authorizer.d.ts +45 -0
- package/dist/authz/authorizer.d.ts.map +1 -0
- package/dist/authz/authorizer.js +31 -0
- package/dist/authz/authorizer.js.map +1 -0
- package/dist/authz/require-level-guard.d.ts +23 -0
- package/dist/authz/require-level-guard.d.ts.map +1 -0
- package/dist/authz/require-level-guard.js +37 -0
- package/dist/authz/require-level-guard.js.map +1 -0
- package/dist/clock.d.ts +13 -0
- package/dist/clock.d.ts.map +1 -0
- package/dist/clock.js +13 -0
- package/dist/clock.js.map +1 -0
- package/dist/concurrency/keyed-queue.d.ts +18 -0
- package/dist/concurrency/keyed-queue.d.ts.map +1 -0
- package/dist/concurrency/keyed-queue.js +37 -0
- package/dist/concurrency/keyed-queue.js.map +1 -0
- package/dist/concurrency/run-with-concurrency.d.ts +15 -0
- package/dist/concurrency/run-with-concurrency.d.ts.map +1 -0
- package/dist/concurrency/run-with-concurrency.js +40 -0
- package/dist/concurrency/run-with-concurrency.js.map +1 -0
- package/dist/config/env.d.ts +17 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +49 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/errors.d.ts +14 -0
- package/dist/config/errors.d.ts.map +1 -0
- package/dist/config/errors.js +25 -0
- package/dist/config/errors.js.map +1 -0
- package/dist/datetime.d.ts +34 -0
- package/dist/datetime.d.ts.map +1 -0
- package/dist/datetime.js +188 -0
- package/dist/datetime.js.map +1 -0
- package/dist/discord/api-errors.d.ts +20 -0
- package/dist/discord/api-errors.d.ts.map +1 -0
- package/dist/discord/api-errors.js +90 -0
- package/dist/discord/api-errors.js.map +1 -0
- package/dist/discord/channel-exporter.d.ts +42 -0
- package/dist/discord/channel-exporter.d.ts.map +1 -0
- package/dist/discord/channel-exporter.js +3 -0
- package/dist/discord/channel-exporter.js.map +1 -0
- package/dist/discord/command/autocomplete-dispatcher.d.ts +26 -0
- package/dist/discord/command/autocomplete-dispatcher.d.ts.map +1 -0
- package/dist/discord/command/autocomplete-dispatcher.js +41 -0
- package/dist/discord/command/autocomplete-dispatcher.js.map +1 -0
- package/dist/discord/command/autocomplete.d.ts +18 -0
- package/dist/discord/command/autocomplete.d.ts.map +1 -0
- package/dist/discord/command/autocomplete.js +65 -0
- package/dist/discord/command/autocomplete.js.map +1 -0
- package/dist/discord/command/context.d.ts +33 -0
- package/dist/discord/command/context.d.ts.map +1 -0
- package/dist/discord/command/context.js +48 -0
- package/dist/discord/command/context.js.map +1 -0
- package/dist/discord/command/cooldown-guard.d.ts +25 -0
- package/dist/discord/command/cooldown-guard.d.ts.map +1 -0
- package/dist/discord/command/cooldown-guard.js +60 -0
- package/dist/discord/command/cooldown-guard.js.map +1 -0
- package/dist/discord/command/create-command.d.ts +100 -0
- package/dist/discord/command/create-command.d.ts.map +1 -0
- package/dist/discord/command/create-command.js +245 -0
- package/dist/discord/command/create-command.js.map +1 -0
- package/dist/discord/command/create-context-menu-command.d.ts +51 -0
- package/dist/discord/command/create-context-menu-command.d.ts.map +1 -0
- package/dist/discord/command/create-context-menu-command.js +128 -0
- package/dist/discord/command/create-context-menu-command.js.map +1 -0
- package/dist/discord/command/errors.d.ts +19 -0
- package/dist/discord/command/errors.d.ts.map +1 -0
- package/dist/discord/command/errors.js +27 -0
- package/dist/discord/command/errors.js.map +1 -0
- package/dist/discord/command/guard.d.ts +30 -0
- package/dist/discord/command/guard.d.ts.map +1 -0
- package/dist/discord/command/guard.js +34 -0
- package/dist/discord/command/guard.js.map +1 -0
- package/dist/discord/command/localization.d.ts +9 -0
- package/dist/discord/command/localization.d.ts.map +1 -0
- package/dist/discord/command/localization.js +13 -0
- package/dist/discord/command/localization.js.map +1 -0
- package/dist/discord/command/options.d.ts +113 -0
- package/dist/discord/command/options.d.ts.map +1 -0
- package/dist/discord/command/options.js +509 -0
- package/dist/discord/command/options.js.map +1 -0
- package/dist/discord/command/permission-guard.d.ts +21 -0
- package/dist/discord/command/permission-guard.d.ts.map +1 -0
- package/dist/discord/command/permission-guard.js +69 -0
- package/dist/discord/command/permission-guard.js.map +1 -0
- package/dist/discord/command/router.d.ts +48 -0
- package/dist/discord/command/router.d.ts.map +1 -0
- package/dist/discord/command/router.js +118 -0
- package/dist/discord/command/router.js.map +1 -0
- package/dist/discord/command/types.d.ts +51 -0
- package/dist/discord/command/types.d.ts.map +1 -0
- package/dist/discord/command/types.js +3 -0
- package/dist/discord/command/types.js.map +1 -0
- package/dist/discord/components/component-router.d.ts +116 -0
- package/dist/discord/components/component-router.d.ts.map +1 -0
- package/dist/discord/components/component-router.js +123 -0
- package/dist/discord/components/component-router.js.map +1 -0
- package/dist/discord/components/interactive-message/index.d.ts +3 -0
- package/dist/discord/components/interactive-message/index.d.ts.map +1 -0
- package/dist/discord/components/interactive-message/index.js +11 -0
- package/dist/discord/components/interactive-message/index.js.map +1 -0
- package/dist/discord/components/interactive-message/interactive-message-collector.d.ts +195 -0
- package/dist/discord/components/interactive-message/interactive-message-collector.d.ts.map +1 -0
- package/dist/discord/components/interactive-message/interactive-message-collector.js +151 -0
- package/dist/discord/components/interactive-message/interactive-message-collector.js.map +1 -0
- package/dist/discord/components/interactive-message/mount-interactive-message.d.ts +30 -0
- package/dist/discord/components/interactive-message/mount-interactive-message.d.ts.map +1 -0
- package/dist/discord/components/interactive-message/mount-interactive-message.js +44 -0
- package/dist/discord/components/interactive-message/mount-interactive-message.js.map +1 -0
- package/dist/discord/components/paginator/index.d.ts +5 -0
- package/dist/discord/components/paginator/index.d.ts.map +1 -0
- package/dist/discord/components/paginator/index.js +15 -0
- package/dist/discord/components/paginator/index.js.map +1 -0
- package/dist/discord/components/paginator/mount-paginator.d.ts +25 -0
- package/dist/discord/components/paginator/mount-paginator.d.ts.map +1 -0
- package/dist/discord/components/paginator/mount-paginator.js +41 -0
- package/dist/discord/components/paginator/mount-paginator.js.map +1 -0
- package/dist/discord/components/paginator/page-state.d.ts +21 -0
- package/dist/discord/components/paginator/page-state.d.ts.map +1 -0
- package/dist/discord/components/paginator/page-state.js +44 -0
- package/dist/discord/components/paginator/page-state.js.map +1 -0
- package/dist/discord/components/paginator/paginator-buttons.d.ts +17 -0
- package/dist/discord/components/paginator/paginator-buttons.d.ts.map +1 -0
- package/dist/discord/components/paginator/paginator-buttons.js +45 -0
- package/dist/discord/components/paginator/paginator-buttons.js.map +1 -0
- package/dist/discord/components/paginator/paginator-view.d.ts +26 -0
- package/dist/discord/components/paginator/paginator-view.d.ts.map +1 -0
- package/dist/discord/components/paginator/paginator-view.js +28 -0
- package/dist/discord/components/paginator/paginator-view.js.map +1 -0
- package/dist/discord/components/persistent-paginator.d.ts +47 -0
- package/dist/discord/components/persistent-paginator.d.ts.map +1 -0
- package/dist/discord/components/persistent-paginator.js +137 -0
- package/dist/discord/components/persistent-paginator.js.map +1 -0
- package/dist/discord/components/settings-editor/index.d.ts +7 -0
- package/dist/discord/components/settings-editor/index.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/index.js +22 -0
- package/dist/discord/components/settings-editor/index.js.map +1 -0
- package/dist/discord/components/settings-editor/mount-settings-editor.d.ts +140 -0
- package/dist/discord/components/settings-editor/mount-settings-editor.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/mount-settings-editor.js +344 -0
- package/dist/discord/components/settings-editor/mount-settings-editor.js.map +1 -0
- package/dist/discord/components/settings-editor/navigation.d.ts +49 -0
- package/dist/discord/components/settings-editor/navigation.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/navigation.js +39 -0
- package/dist/discord/components/settings-editor/navigation.js.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor-card.view.d.ts +56 -0
- package/dist/discord/components/settings-editor/settings-editor-card.view.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor-card.view.js +284 -0
- package/dist/discord/components/settings-editor/settings-editor-card.view.js.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor-field-modal.d.ts +69 -0
- package/dist/discord/components/settings-editor/settings-editor-field-modal.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor-field-modal.js +353 -0
- package/dist/discord/components/settings-editor/settings-editor-field-modal.js.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor-fields.d.ts +216 -0
- package/dist/discord/components/settings-editor/settings-editor-fields.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor-fields.js +66 -0
- package/dist/discord/components/settings-editor/settings-editor-fields.js.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor.view.d.ts +303 -0
- package/dist/discord/components/settings-editor/settings-editor.view.d.ts.map +1 -0
- package/dist/discord/components/settings-editor/settings-editor.view.js +316 -0
- package/dist/discord/components/settings-editor/settings-editor.view.js.map +1 -0
- package/dist/discord/events/create-event.d.ts +5 -0
- package/dist/discord/events/create-event.d.ts.map +1 -0
- package/dist/discord/events/create-event.js +8 -0
- package/dist/discord/events/create-event.js.map +1 -0
- package/dist/discord/events/event-router.d.ts +16 -0
- package/dist/discord/events/event-router.d.ts.map +1 -0
- package/dist/discord/events/event-router.js +51 -0
- package/dist/discord/events/event-router.js.map +1 -0
- package/dist/discord/events/types.d.ts +16 -0
- package/dist/discord/events/types.d.ts.map +1 -0
- package/dist/discord/events/types.js +3 -0
- package/dist/discord/events/types.js.map +1 -0
- package/dist/discord/i18n.d.ts +58 -0
- package/dist/discord/i18n.d.ts.map +1 -0
- package/dist/discord/i18n.js +173 -0
- package/dist/discord/i18n.js.map +1 -0
- package/dist/discord/interaction/button.d.ts +39 -0
- package/dist/discord/interaction/button.d.ts.map +1 -0
- package/dist/discord/interaction/button.js +36 -0
- package/dist/discord/interaction/button.js.map +1 -0
- package/dist/discord/interaction/interaction-router.d.ts +21 -0
- package/dist/discord/interaction/interaction-router.d.ts.map +1 -0
- package/dist/discord/interaction/interaction-router.js +24 -0
- package/dist/discord/interaction/interaction-router.js.map +1 -0
- package/dist/discord/interaction/modal.d.ts +171 -0
- package/dist/discord/interaction/modal.d.ts.map +1 -0
- package/dist/discord/interaction/modal.js +264 -0
- package/dist/discord/interaction/modal.js.map +1 -0
- package/dist/discord/interaction/select-menu.d.ts +104 -0
- package/dist/discord/interaction/select-menu.d.ts.map +1 -0
- package/dist/discord/interaction/select-menu.js +126 -0
- package/dist/discord/interaction/select-menu.js.map +1 -0
- package/dist/discord/permissions.d.ts +32 -0
- package/dist/discord/permissions.d.ts.map +1 -0
- package/dist/discord/permissions.js +40 -0
- package/dist/discord/permissions.js.map +1 -0
- package/dist/discord/placeholder-registry-errors.d.ts +10 -0
- package/dist/discord/placeholder-registry-errors.d.ts.map +1 -0
- package/dist/discord/placeholder-registry-errors.js +18 -0
- package/dist/discord/placeholder-registry-errors.js.map +1 -0
- package/dist/discord/placeholder-registry.d.ts +53 -0
- package/dist/discord/placeholder-registry.d.ts.map +1 -0
- package/dist/discord/placeholder-registry.js +52 -0
- package/dist/discord/placeholder-registry.js.map +1 -0
- package/dist/discord/presenter.d.ts +26 -0
- package/dist/discord/presenter.d.ts.map +1 -0
- package/dist/discord/presenter.js +3 -0
- package/dist/discord/presenter.js.map +1 -0
- package/dist/discord/ui/card.d.ts +114 -0
- package/dist/discord/ui/card.d.ts.map +1 -0
- package/dist/discord/ui/card.js +162 -0
- package/dist/discord/ui/card.js.map +1 -0
- package/dist/discord/ui/color-input-errors.d.ts +12 -0
- package/dist/discord/ui/color-input-errors.d.ts.map +1 -0
- package/dist/discord/ui/color-input-errors.js +21 -0
- package/dist/discord/ui/color-input-errors.js.map +1 -0
- package/dist/discord/ui/color-input.d.ts +37 -0
- package/dist/discord/ui/color-input.d.ts.map +1 -0
- package/dist/discord/ui/color-input.js +166 -0
- package/dist/discord/ui/color-input.js.map +1 -0
- package/dist/discord/ui/colors.d.ts +44 -0
- package/dist/discord/ui/colors.d.ts.map +1 -0
- package/dist/discord/ui/colors.js +45 -0
- package/dist/discord/ui/colors.js.map +1 -0
- package/dist/discord/ui/embed.d.ts +16 -0
- package/dist/discord/ui/embed.d.ts.map +1 -0
- package/dist/discord/ui/embed.js +53 -0
- package/dist/discord/ui/embed.js.map +1 -0
- package/dist/discord/ui/message-attachments.d.ts +40 -0
- package/dist/discord/ui/message-attachments.d.ts.map +1 -0
- package/dist/discord/ui/message-attachments.js +27 -0
- package/dist/discord/ui/message-attachments.js.map +1 -0
- package/dist/errors/business-error.d.ts +41 -0
- package/dist/errors/business-error.d.ts.map +1 -0
- package/dist/errors/business-error.js +39 -0
- package/dist/errors/business-error.js.map +1 -0
- package/dist/errors/describe-error.d.ts +29 -0
- package/dist/errors/describe-error.d.ts.map +1 -0
- package/dist/errors/describe-error.js +49 -0
- package/dist/errors/describe-error.js.map +1 -0
- package/dist/errors/incident-ref.d.ts +7 -0
- package/dist/errors/incident-ref.d.ts.map +1 -0
- package/dist/errors/incident-ref.js +13 -0
- package/dist/errors/incident-ref.js.map +1 -0
- package/dist/errors/index.d.ts +4 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +15 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/i18n/business-message.d.ts +14 -0
- package/dist/i18n/business-message.d.ts.map +1 -0
- package/dist/i18n/business-message.js +19 -0
- package/dist/i18n/business-message.js.map +1 -0
- package/dist/i18n/catalog.d.ts +27 -0
- package/dist/i18n/catalog.d.ts.map +1 -0
- package/dist/i18n/catalog.js +25 -0
- package/dist/i18n/catalog.js.map +1 -0
- package/dist/i18n/errors.d.ts +10 -0
- package/dist/i18n/errors.d.ts.map +1 -0
- package/dist/i18n/errors.js +18 -0
- package/dist/i18n/errors.js.map +1 -0
- package/dist/i18n/index.d.ts +6 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +16 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/locale.d.ts +22 -0
- package/dist/i18n/locale.d.ts.map +1 -0
- package/dist/i18n/locale.js +40 -0
- package/dist/i18n/locale.js.map +1 -0
- package/dist/i18n/translator.d.ts +35 -0
- package/dist/i18n/translator.d.ts.map +1 -0
- package/dist/i18n/translator.js +40 -0
- package/dist/i18n/translator.js.map +1 -0
- package/dist/logger.d.ts +28 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +3 -0
- package/dist/logger.js.map +1 -0
- package/dist/module/module.d.ts +42 -0
- package/dist/module/module.d.ts.map +1 -0
- package/dist/module/module.js +3 -0
- package/dist/module/module.js.map +1 -0
- package/dist/persistence/database.d.ts +24 -0
- package/dist/persistence/database.d.ts.map +1 -0
- package/dist/persistence/database.js +3 -0
- package/dist/persistence/database.js.map +1 -0
- package/dist/resilience/retry.d.ts +36 -0
- package/dist/resilience/retry.d.ts.map +1 -0
- package/dist/resilience/retry.js +78 -0
- package/dist/resilience/retry.js.map +1 -0
- package/dist/scheduler/errors.d.ts +25 -0
- package/dist/scheduler/errors.d.ts.map +1 -0
- package/dist/scheduler/errors.js +45 -0
- package/dist/scheduler/errors.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +68 -0
- package/dist/scheduler/scheduler.d.ts.map +1 -0
- package/dist/scheduler/scheduler.js +162 -0
- package/dist/scheduler/scheduler.js.map +1 -0
- package/package.json +89 -0
- package/src/authz/authorizer.ts +76 -0
- package/src/authz/require-level-guard.ts +42 -0
- package/src/clock.ts +18 -0
- package/src/concurrency/keyed-queue.ts +50 -0
- package/src/concurrency/run-with-concurrency.ts +44 -0
- package/src/config/env.ts +58 -0
- package/src/config/errors.ts +21 -0
- package/src/datetime.ts +221 -0
- package/src/discord/api-errors.ts +91 -0
- package/src/discord/channel-exporter.ts +48 -0
- package/src/discord/command/autocomplete-dispatcher.ts +54 -0
- package/src/discord/command/autocomplete.ts +76 -0
- package/src/discord/command/context.ts +85 -0
- package/src/discord/command/cooldown-guard.ts +81 -0
- package/src/discord/command/create-command.ts +431 -0
- package/src/discord/command/create-context-menu-command.ts +227 -0
- package/src/discord/command/errors.ts +22 -0
- package/src/discord/command/guard.ts +54 -0
- package/src/discord/command/localization.ts +11 -0
- package/src/discord/command/options.ts +847 -0
- package/src/discord/command/permission-guard.ts +74 -0
- package/src/discord/command/router.ts +142 -0
- package/src/discord/command/types.ts +52 -0
- package/src/discord/components/component-router.ts +213 -0
- package/src/discord/components/interactive-message/index.ts +18 -0
- package/src/discord/components/interactive-message/interactive-message-collector.ts +374 -0
- package/src/discord/components/interactive-message/mount-interactive-message.ts +71 -0
- package/src/discord/components/paginator/index.ts +17 -0
- package/src/discord/components/paginator/mount-paginator.ts +69 -0
- package/src/discord/components/paginator/page-state.ts +45 -0
- package/src/discord/components/paginator/paginator-buttons.ts +60 -0
- package/src/discord/components/paginator/paginator-view.ts +61 -0
- package/src/discord/components/persistent-paginator.ts +197 -0
- package/src/discord/components/settings-editor/index.ts +41 -0
- package/src/discord/components/settings-editor/mount-settings-editor.ts +646 -0
- package/src/discord/components/settings-editor/navigation.ts +67 -0
- package/src/discord/components/settings-editor/settings-editor-card.view.ts +344 -0
- package/src/discord/components/settings-editor/settings-editor-field-modal.ts +538 -0
- package/src/discord/components/settings-editor/settings-editor-fields.ts +290 -0
- package/src/discord/components/settings-editor/settings-editor.view.ts +654 -0
- package/src/discord/events/create-event.ts +7 -0
- package/src/discord/events/event-router.ts +53 -0
- package/src/discord/events/types.ts +17 -0
- package/src/discord/i18n.ts +173 -0
- package/src/discord/interaction/button.ts +75 -0
- package/src/discord/interaction/interaction-router.ts +28 -0
- package/src/discord/interaction/modal.ts +505 -0
- package/src/discord/interaction/select-menu.ts +246 -0
- package/src/discord/permissions.ts +57 -0
- package/src/discord/placeholder-registry-errors.ts +11 -0
- package/src/discord/placeholder-registry.ts +77 -0
- package/src/discord/presenter.ts +26 -0
- package/src/discord/ui/card.ts +303 -0
- package/src/discord/ui/color-input-errors.ts +17 -0
- package/src/discord/ui/color-input.ts +179 -0
- package/src/discord/ui/colors.ts +58 -0
- package/src/discord/ui/embed.ts +64 -0
- package/src/discord/ui/message-attachments.ts +57 -0
- package/src/errors/business-error.ts +49 -0
- package/src/errors/describe-error.ts +73 -0
- package/src/errors/incident-ref.ts +10 -0
- package/src/errors/index.ts +12 -0
- package/src/i18n/business-message.ts +23 -0
- package/src/i18n/catalog.ts +41 -0
- package/src/i18n/errors.ts +11 -0
- package/src/i18n/index.ts +11 -0
- package/src/i18n/locale.ts +41 -0
- package/src/i18n/translator.ts +78 -0
- package/src/logger.ts +28 -0
- package/src/module/module.ts +42 -0
- package/src/persistence/database.ts +23 -0
- package/src/resilience/retry.ts +102 -0
- package/src/scheduler/errors.ts +40 -0
- package/src/scheduler/scheduler.ts +248 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type PageState } from "../../../discord/components/paginator/page-state";
|
|
2
|
+
import { type Button } from "../../../discord/interaction/button";
|
|
3
|
+
export interface PaginatorLabels {
|
|
4
|
+
previous: string;
|
|
5
|
+
next: string;
|
|
6
|
+
previousEmoji?: string;
|
|
7
|
+
nextEmoji?: string;
|
|
8
|
+
}
|
|
9
|
+
/** Complete a caller's partial labels with the defaults. */
|
|
10
|
+
export declare function resolveLabels(labels?: Partial<PaginatorLabels>): PaginatorLabels;
|
|
11
|
+
/**
|
|
12
|
+
* The navigation buttons, bound to a fixed page count. Each button carries its
|
|
13
|
+
* own disabled predicate and transition, so the collector only has to hand a
|
|
14
|
+
* click to the matching button instead of knowing what the click means.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createPaginatorButtons(count: number, labels: PaginatorLabels): Button<PageState>[];
|
|
17
|
+
//# sourceMappingURL=paginator-buttons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginator-buttons.d.ts","sourceRoot":"","sources":["../../../../src/discord/components/paginator/paginator-buttons.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,SAAS,EAEd,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,8BAA8B,CAAC;AAMzE,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AASD,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAEhF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,eAAe,GACrB,MAAM,CAAC,SAAS,CAAC,EAAE,CAmBrB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveLabels = resolveLabels;
|
|
4
|
+
exports.createPaginatorButtons = createPaginatorButtons;
|
|
5
|
+
const page_state_1 = require("../../../discord/components/paginator/page-state");
|
|
6
|
+
const button_1 = require("../../../discord/interaction/button");
|
|
7
|
+
/** Custom IDs of the two navigation buttons; also what the collector routes on. */
|
|
8
|
+
const PREV_ID = "paginator:prev";
|
|
9
|
+
const NEXT_ID = "paginator:next";
|
|
10
|
+
const DEFAULT_LABELS = {
|
|
11
|
+
previous: "Previous",
|
|
12
|
+
next: "Next",
|
|
13
|
+
previousEmoji: "◀️",
|
|
14
|
+
nextEmoji: "▶️",
|
|
15
|
+
};
|
|
16
|
+
/** Complete a caller's partial labels with the defaults. */
|
|
17
|
+
function resolveLabels(labels) {
|
|
18
|
+
return { ...DEFAULT_LABELS, ...labels };
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The navigation buttons, bound to a fixed page count. Each button carries its
|
|
22
|
+
* own disabled predicate and transition, so the collector only has to hand a
|
|
23
|
+
* click to the matching button instead of knowing what the click means.
|
|
24
|
+
*/
|
|
25
|
+
function createPaginatorButtons(count, labels) {
|
|
26
|
+
return [
|
|
27
|
+
(0, button_1.createButton)({
|
|
28
|
+
id: PREV_ID,
|
|
29
|
+
label: labels.previous,
|
|
30
|
+
emoji: labels.previousEmoji,
|
|
31
|
+
style: "secondary",
|
|
32
|
+
disabled: (current) => (0, page_state_1.isFirstPage)(current),
|
|
33
|
+
onClick: (ctx) => ctx.update((0, page_state_1.previousPage)(ctx.state, count)),
|
|
34
|
+
}),
|
|
35
|
+
(0, button_1.createButton)({
|
|
36
|
+
id: NEXT_ID,
|
|
37
|
+
label: labels.next,
|
|
38
|
+
emoji: labels.nextEmoji,
|
|
39
|
+
style: "secondary",
|
|
40
|
+
disabled: (current) => (0, page_state_1.isLastPage)(current, count),
|
|
41
|
+
onClick: (ctx) => ctx.update((0, page_state_1.nextPage)(ctx.state, count)),
|
|
42
|
+
}),
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=paginator-buttons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginator-buttons.js","sourceRoot":"","sources":["../../../../src/discord/components/paginator/paginator-buttons.ts"],"names":[],"mappings":";;AA4BA,sCAEC;AAOD,wDAsBC;AA3DD,0EAMmD;AACnD,yDAAyE;AAEzE,mFAAmF;AACnF,MAAM,OAAO,GAAG,gBAAgB,CAAC;AACjC,MAAM,OAAO,GAAG,gBAAgB,CAAC;AASjC,MAAM,cAAc,GAAoB;IACvC,QAAQ,EAAE,UAAU;IACpB,IAAI,EAAE,MAAM;IACZ,aAAa,EAAE,IAAI;IACnB,SAAS,EAAE,IAAI;CACf,CAAC;AAEF,4DAA4D;AAC5D,SAAgB,aAAa,CAAC,MAAiC;IAC9D,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,SAAgB,sBAAsB,CACrC,KAAa,EACb,MAAuB;IAEvB,OAAO;QACN,IAAA,qBAAY,EAAY;YACvB,EAAE,EAAE,OAAO;YACX,KAAK,EAAE,MAAM,CAAC,QAAQ;YACtB,KAAK,EAAE,MAAM,CAAC,aAAa;YAC3B,KAAK,EAAE,WAAW;YAClB,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAA,wBAAW,EAAC,OAAO,CAAC;YAC3C,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAA,yBAAY,EAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;SAC5D,CAAC;QACF,IAAA,qBAAY,EAAY;YACvB,EAAE,EAAE,OAAO;YACX,KAAK,EAAE,MAAM,CAAC,IAAI;YAClB,KAAK,EAAE,MAAM,CAAC,SAAS;YACvB,KAAK,EAAE,WAAW;YAClB,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAA,uBAAU,EAAC,OAAO,EAAE,KAAK,CAAC;YACjD,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAA,qBAAQ,EAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;SACxD,CAAC;KACF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { EmbedBuilder } from "discord.js";
|
|
2
|
+
import type { InteractiveMessagePayload, InteractiveView } from "../../../discord/components/interactive-message";
|
|
3
|
+
import { type PageState } from "../../../discord/components/paginator/page-state";
|
|
4
|
+
import { type Button } from "../../../discord/interaction/button";
|
|
5
|
+
/** Builds the embed shown for one page; supplied by the caller. */
|
|
6
|
+
export type PaginatorRender<T> = (pageItems: T[], page: number, count: number, total: number) => EmbedBuilder;
|
|
7
|
+
/**
|
|
8
|
+
* The message payload shape shared by the initial reply and every update — the
|
|
9
|
+
* generic interactive-message payload, named here for the paginator's callers.
|
|
10
|
+
*/
|
|
11
|
+
export type PaginatorPayload = InteractiveMessagePayload<PageState>;
|
|
12
|
+
export interface PaginatorViewDeps<T> {
|
|
13
|
+
items: T[];
|
|
14
|
+
pageSize: number;
|
|
15
|
+
count: number;
|
|
16
|
+
render: PaginatorRender<T>;
|
|
17
|
+
buttons: Button<PageState>[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Turns a {@link PageState} into a message payload. Everything the paginator
|
|
21
|
+
* sends to Discord goes through here, so the collector never builds a payload of
|
|
22
|
+
* its own and the two renders can never drift apart.
|
|
23
|
+
*/
|
|
24
|
+
export type PaginatorView = InteractiveView<PageState>;
|
|
25
|
+
export declare function createPaginatorView<T>(deps: PaginatorViewDeps<T>): PaginatorView;
|
|
26
|
+
//# sourceMappingURL=paginator-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginator-view.d.ts","sourceRoot":"","sources":["../../../../src/discord/components/paginator/paginator-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,YAAY,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,KAAK,EACX,yBAAyB,EACzB,eAAe,EACf,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,2CAA2C,CAAC;AAC5F,OAAO,EAAE,KAAK,MAAM,EAAmB,MAAM,8BAA8B,CAAC;AAE5E,mEAAmE;AACnE,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,CAChC,SAAS,EAAE,CAAC,EAAE,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,KACT,YAAY,CAAC;AAElB;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAC;AAEpE,MAAM,WAAW,iBAAiB,CAAC,CAAC;IACnC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;AAEvD,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,aAAa,CAuBhF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createPaginatorView = createPaginatorView;
|
|
4
|
+
const page_state_1 = require("../../../discord/components/paginator/page-state");
|
|
5
|
+
const button_1 = require("../../../discord/interaction/button");
|
|
6
|
+
function createPaginatorView(deps) {
|
|
7
|
+
const { items, pageSize, count, render, buttons } = deps;
|
|
8
|
+
function controls(state, disableAll) {
|
|
9
|
+
// A single page has nothing to navigate to, so it carries no action row at all.
|
|
10
|
+
if (count <= 1) {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
return [(0, button_1.createActionRow)(buttons, state, { disableAll })];
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
render(state) {
|
|
17
|
+
const pageItems = (0, page_state_1.selectPageItems)(items, state, pageSize);
|
|
18
|
+
return {
|
|
19
|
+
embeds: [render(pageItems, state.page, count, items.length)],
|
|
20
|
+
components: controls(state, false),
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
disabledControls(state) {
|
|
24
|
+
return { components: controls(state, true) };
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=paginator-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginator-view.js","sourceRoot":"","sources":["../../../../src/discord/components/paginator/paginator-view.ts"],"names":[],"mappings":";;AAqCA,kDAuBC;AAvDD,0EAA4F;AAC5F,yDAA4E;AA+B5E,SAAgB,mBAAmB,CAAI,IAA0B;IAChE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAEzD,SAAS,QAAQ,CAAC,KAAgB,EAAE,UAAmB;QACtD,gFAAgF;QAChF,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YAChB,OAAO,EAAE,CAAC;QACX,CAAC;QACD,OAAO,CAAC,IAAA,wBAAe,EAAC,OAAO,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO;QACN,MAAM,CAAC,KAAK;YACX,MAAM,SAAS,GAAG,IAAA,4BAAe,EAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC1D,OAAO;gBACN,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC5D,UAAU,EAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;aAClC,CAAC;QACH,CAAC;QACD,gBAAgB,CAAC,KAAK;YACrB,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;QAC9C,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { EmbedBuilder } from "discord.js";
|
|
2
|
+
import { type ComponentHandler } from "../../discord/components/component-router";
|
|
3
|
+
import { type PaginatorLabels } from "../../discord/components/paginator/paginator-buttons";
|
|
4
|
+
import type { PaginatorPayload } from "../../discord/components/paginator/paginator-view";
|
|
5
|
+
/** One rendered page: what the caller's data source produces for a page index. */
|
|
6
|
+
export interface PersistentPage {
|
|
7
|
+
embed: EmbedBuilder;
|
|
8
|
+
/** Total number of pages, re-evaluated on every fetch since the data may have changed. */
|
|
9
|
+
pageCount: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Produces the page at `page` (1-based). Asynchronous and injected because a
|
|
13
|
+
* persistent paginator cannot keep the dataset in memory: after a restart the
|
|
14
|
+
* only surviving state is the customId, so every click re-reads the source.
|
|
15
|
+
*/
|
|
16
|
+
export type PersistentPageFetcher = (page: number) => Promise<PersistentPage>;
|
|
17
|
+
export interface PersistentPaginatorOptions {
|
|
18
|
+
/** Handler prefix; navigation buttons extend it with the target page. */
|
|
19
|
+
customId: string;
|
|
20
|
+
fetchPage: PersistentPageFetcher;
|
|
21
|
+
labels?: Partial<PaginatorLabels>;
|
|
22
|
+
}
|
|
23
|
+
export interface PersistentPaginator {
|
|
24
|
+
readonly customId: string;
|
|
25
|
+
/** Payload for the first message; the caller sends it however it replies. */
|
|
26
|
+
render(page?: number): Promise<PaginatorPayload>;
|
|
27
|
+
/** Register this on the module's `components` so clicks keep working after a restart. */
|
|
28
|
+
readonly handler: ComponentHandler;
|
|
29
|
+
}
|
|
30
|
+
/** Build the customId a navigation button carries: `<prefix>:page:<n>`. */
|
|
31
|
+
export declare function encodePaginatorPage(customId: string, page: number): string;
|
|
32
|
+
/**
|
|
33
|
+
* Read the page back out of a clicked customId. Returns `null` for anything that
|
|
34
|
+
* is not a well-formed page reference — a message from an older deploy may carry
|
|
35
|
+
* a shape this build no longer writes, and that must not throw.
|
|
36
|
+
*/
|
|
37
|
+
export declare function decodePaginatorPage(customId: string, clickedId: string): number | null;
|
|
38
|
+
/**
|
|
39
|
+
* A paginator whose whole state lives in the component customId, routed by the
|
|
40
|
+
* {@link ComponentRouter}. Unlike `mountPaginator` — a collector holding items
|
|
41
|
+
* and page in a closure, owner-scoped and dead after an idle timeout — this one
|
|
42
|
+
* has no memory: it survives restarts and never expires, at the cost of refetching
|
|
43
|
+
* the page on every click. Use it for long-lived, shared messages; use the
|
|
44
|
+
* collector for transient, single-user flows.
|
|
45
|
+
*/
|
|
46
|
+
export declare function createPersistentPaginator(options: PersistentPaginatorOptions): PersistentPaginator;
|
|
47
|
+
//# sourceMappingURL=persistent-paginator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistent-paginator.d.ts","sourceRoot":"","sources":["../../../src/discord/components/persistent-paginator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,YAAY,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,EACN,KAAK,gBAAgB,EAKrB,MAAM,uCAAuC,CAAC;AAU/C,OAAO,EACN,KAAK,eAAe,EAEpB,MAAM,kDAAkD,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAC;AAsBtF,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,YAAY,CAAC;IACpB,0FAA0F;IAC1F,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;AAE9E,MAAM,WAAW,0BAA0B;IAC1C,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,qBAAqB,CAAC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACjD,yFAAyF;IACzF,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;CACnC;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAetF;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACxC,OAAO,EAAE,0BAA0B,GACjC,mBAAmB,CAuFrB"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.encodePaginatorPage = encodePaginatorPage;
|
|
4
|
+
exports.decodePaginatorPage = decodePaginatorPage;
|
|
5
|
+
exports.createPersistentPaginator = createPersistentPaginator;
|
|
6
|
+
const component_router_1 = require("../../discord/components/component-router");
|
|
7
|
+
const interactive_message_1 = require("../../discord/components/interactive-message");
|
|
8
|
+
const page_state_1 = require("../../discord/components/paginator/page-state");
|
|
9
|
+
const paginator_buttons_1 = require("../../discord/components/paginator/paginator-buttons");
|
|
10
|
+
const button_1 = require("../../discord/interaction/button");
|
|
11
|
+
/** Separator the {@link ComponentRouter} already matches a handler prefix on. */
|
|
12
|
+
const ID_SEPARATOR = ":";
|
|
13
|
+
/** Marks the segment holding the encoded page, so other state can be added later. */
|
|
14
|
+
const PAGE_SEGMENT = "page";
|
|
15
|
+
/** Pages are 1-based, mirroring {@link PageState}. */
|
|
16
|
+
const FIRST_PAGE = 1;
|
|
17
|
+
/**
|
|
18
|
+
* A page total is whatever the source reports, which may be 0 for an emptied
|
|
19
|
+
* dataset or non-finite from a miscounted query. Both would push the 1-based
|
|
20
|
+
* page index out of range, so treat them as a single empty page.
|
|
21
|
+
*/
|
|
22
|
+
function normalisePageCount(pageCount) {
|
|
23
|
+
if (!Number.isFinite(pageCount)) {
|
|
24
|
+
return FIRST_PAGE;
|
|
25
|
+
}
|
|
26
|
+
return Math.max(FIRST_PAGE, Math.floor(pageCount));
|
|
27
|
+
}
|
|
28
|
+
/** Build the customId a navigation button carries: `<prefix>:page:<n>`. */
|
|
29
|
+
function encodePaginatorPage(customId, page) {
|
|
30
|
+
return [customId, PAGE_SEGMENT, String(page)].join(ID_SEPARATOR);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Read the page back out of a clicked customId. Returns `null` for anything that
|
|
34
|
+
* is not a well-formed page reference — a message from an older deploy may carry
|
|
35
|
+
* a shape this build no longer writes, and that must not throw.
|
|
36
|
+
*/
|
|
37
|
+
function decodePaginatorPage(customId, clickedId) {
|
|
38
|
+
const prefix = `${customId}${ID_SEPARATOR}${PAGE_SEGMENT}${ID_SEPARATOR}`;
|
|
39
|
+
if (!clickedId.startsWith(prefix)) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const raw = clickedId.slice(prefix.length);
|
|
43
|
+
// `Number` alone accepts "", " " and "1e3"; only plain digits are ours.
|
|
44
|
+
if (!/^\d+$/.test(raw)) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const page = Number(raw);
|
|
48
|
+
if (page < FIRST_PAGE) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
return page;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A paginator whose whole state lives in the component customId, routed by the
|
|
55
|
+
* {@link ComponentRouter}. Unlike `mountPaginator` — a collector holding items
|
|
56
|
+
* and page in a closure, owner-scoped and dead after an idle timeout — this one
|
|
57
|
+
* has no memory: it survives restarts and never expires, at the cost of refetching
|
|
58
|
+
* the page on every click. Use it for long-lived, shared messages; use the
|
|
59
|
+
* collector for transient, single-user flows.
|
|
60
|
+
*/
|
|
61
|
+
function createPersistentPaginator(options) {
|
|
62
|
+
const { customId, fetchPage } = options;
|
|
63
|
+
const labels = (0, paginator_buttons_1.resolveLabels)(options.labels);
|
|
64
|
+
function controls(state, count) {
|
|
65
|
+
// A single page has nothing to navigate to, so it carries no action row at all.
|
|
66
|
+
if (count <= 1) {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
// No `onClick`: behaviour is carried by the encoded customId and resolved by
|
|
70
|
+
// the router, which is what lets these buttons outlive the process.
|
|
71
|
+
const buttons = [
|
|
72
|
+
(0, button_1.createButton)({
|
|
73
|
+
id: encodePaginatorPage(customId, (0, page_state_1.previousPage)(state, count).page),
|
|
74
|
+
label: labels.previous,
|
|
75
|
+
emoji: labels.previousEmoji,
|
|
76
|
+
style: "secondary",
|
|
77
|
+
disabled: (current) => (0, page_state_1.isFirstPage)(current),
|
|
78
|
+
}),
|
|
79
|
+
(0, button_1.createButton)({
|
|
80
|
+
id: encodePaginatorPage(customId, (0, page_state_1.nextPage)(state, count).page),
|
|
81
|
+
label: labels.next,
|
|
82
|
+
emoji: labels.nextEmoji,
|
|
83
|
+
style: "secondary",
|
|
84
|
+
disabled: (current) => (0, page_state_1.isLastPage)(current, count),
|
|
85
|
+
}),
|
|
86
|
+
];
|
|
87
|
+
return [(0, button_1.createActionRow)(buttons, state)];
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Fetch a page, then clamp it against the freshly returned total. The total is
|
|
91
|
+
* only known after a fetch, so an out-of-range request (a stale button, a
|
|
92
|
+
* shrunken dataset) costs one extra read rather than an empty page.
|
|
93
|
+
*/
|
|
94
|
+
async function loadPage(requested) {
|
|
95
|
+
const asked = Math.max(requested, FIRST_PAGE);
|
|
96
|
+
const fetched = await fetchPage(asked);
|
|
97
|
+
// A source that reports no page (emptied dataset) or a nonsensical total
|
|
98
|
+
// must not clamp the index to 0: the contract is 1-based, and refetching an
|
|
99
|
+
// index the caller was never told it could receive is worse than rendering
|
|
100
|
+
// the empty first page it already returned.
|
|
101
|
+
const pageCount = normalisePageCount(fetched.pageCount);
|
|
102
|
+
const page = (0, page_state_1.clampPage)(asked, pageCount);
|
|
103
|
+
const resolved = page === asked ? fetched : await fetchPage(page);
|
|
104
|
+
return {
|
|
105
|
+
embeds: [resolved.embed],
|
|
106
|
+
components: controls({ page }, normalisePageCount(resolved.pageCount)),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async function handleClick(interaction, runtime) {
|
|
110
|
+
if (!interaction.isButton()) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const decoded = decodePaginatorPage(customId, interaction.customId);
|
|
114
|
+
if (decoded === null) {
|
|
115
|
+
runtime.logger.warn({ customId: interaction.customId }, "Unreadable paginator page, falling back to the first page");
|
|
116
|
+
}
|
|
117
|
+
// Acknowledge before fetching: a persistent paginator reads its source on
|
|
118
|
+
// every click by design, and Discord invalidates an interaction left
|
|
119
|
+
// unanswered for 3s — the click would be lost with the user still looking
|
|
120
|
+
// at the stale page. `deferUpdate` buys the full edit window instead.
|
|
121
|
+
await interaction.deferUpdate();
|
|
122
|
+
const payload = await loadPage(decoded ?? FIRST_PAGE);
|
|
123
|
+
await interaction.editReply((0, interactive_message_1.toMessageEditOptions)(payload, [...interaction.message.attachments.values()]));
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
customId,
|
|
127
|
+
render: (page = FIRST_PAGE) => loadPage(page),
|
|
128
|
+
handler: (0, component_router_1.createComponentHandler)({
|
|
129
|
+
customId,
|
|
130
|
+
// Navigation only re-renders what the message already showed to
|
|
131
|
+
// whoever can see the channel; it grants no access of its own.
|
|
132
|
+
authorize: (0, component_router_1.openToAnyone)("paging a message reveals nothing its reader could not already see"),
|
|
133
|
+
handle: handleClick,
|
|
134
|
+
}),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=persistent-paginator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistent-paginator.js","sourceRoot":"","sources":["../../../src/discord/components/persistent-paginator.ts"],"names":[],"mappings":";;AAyEA,kDAEC;AAOD,kDAeC;AAUD,8DAyFC;AAnMD,4EAM+C;AAC/C,kFAAgF;AAChF,0EAOmD;AACnD,wFAG0D;AAE1D,yDAA6E;AAE7E,iFAAiF;AACjF,MAAM,YAAY,GAAG,GAAG,CAAC;AACzB,qFAAqF;AACrF,MAAM,YAAY,GAAG,MAAM,CAAC;AAC5B,sDAAsD;AACtD,MAAM,UAAU,GAAG,CAAC,CAAC;AAErB;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,SAAiB;IAC5C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,OAAO,UAAU,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;AACpD,CAAC;AA+BD,2EAA2E;AAC3E,SAAgB,mBAAmB,CAAC,QAAgB,EAAE,IAAY;IACjE,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAClE,CAAC;AAED;;;;GAIG;AACH,SAAgB,mBAAmB,CAAC,QAAgB,EAAE,SAAiB;IACtE,MAAM,MAAM,GAAG,GAAG,QAAQ,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,EAAE,CAAC;IAC1E,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3C,wEAAwE;IACxE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACzB,IAAI,IAAI,GAAG,UAAU,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,yBAAyB,CACxC,OAAmC;IAEnC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACxC,MAAM,MAAM,GAAG,IAAA,iCAAa,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAE7C,SAAS,QAAQ,CAAC,KAAgB,EAAE,KAAa;QAChD,gFAAgF;QAChF,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YAChB,OAAO,EAAE,CAAC;QACX,CAAC;QACD,6EAA6E;QAC7E,oEAAoE;QACpE,MAAM,OAAO,GAAG;YACf,IAAA,qBAAY,EAAY;gBACvB,EAAE,EAAE,mBAAmB,CAAC,QAAQ,EAAE,IAAA,yBAAY,EAAC,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC;gBAClE,KAAK,EAAE,MAAM,CAAC,QAAQ;gBACtB,KAAK,EAAE,MAAM,CAAC,aAAa;gBAC3B,KAAK,EAAE,WAAW;gBAClB,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAA,wBAAW,EAAC,OAAO,CAAC;aAC3C,CAAC;YACF,IAAA,qBAAY,EAAY;gBACvB,EAAE,EAAE,mBAAmB,CAAC,QAAQ,EAAE,IAAA,qBAAQ,EAAC,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC;gBAC9D,KAAK,EAAE,MAAM,CAAC,IAAI;gBAClB,KAAK,EAAE,MAAM,CAAC,SAAS;gBACvB,KAAK,EAAE,WAAW;gBAClB,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAA,uBAAU,EAAC,OAAO,EAAE,KAAK,CAAC;aACjD,CAAC;SACF,CAAC;QACF,OAAO,CAAC,IAAA,wBAAe,EAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACH,KAAK,UAAU,QAAQ,CAAC,SAAiB;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;QACvC,yEAAyE;QACzE,4EAA4E;QAC5E,2EAA2E;QAC3E,4CAA4C;QAC5C,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,IAAA,sBAAS,EAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;QAClE,OAAO;YACN,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;YACxB,UAAU,EAAE,QAAQ,CAAC,EAAE,IAAI,EAAE,EAAE,kBAAkB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;SACtE,CAAC;IACH,CAAC;IAED,KAAK,UAAU,WAAW,CACzB,WAAgC,EAChC,OAAyB;QAEzB,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC7B,OAAO;QACR,CAAC;QACD,MAAM,OAAO,GAAG,mBAAmB,CAAC,QAAQ,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;QACpE,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,IAAI,CAClB,EAAE,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,EAClC,2DAA2D,CAC3D,CAAC;QACH,CAAC;QACD,0EAA0E;QAC1E,qEAAqE;QACrE,0EAA0E;QAC1E,sEAAsE;QACtE,MAAM,WAAW,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,IAAI,UAAU,CAAC,CAAC;QACtD,MAAM,WAAW,CAAC,SAAS,CAC1B,IAAA,0CAAoB,EAAC,OAAO,EAAE,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAC5E,CAAC;IACH,CAAC;IAED,OAAO;QACN,QAAQ;QACR,MAAM,EAAE,CAAC,IAAI,GAAG,UAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC7C,OAAO,EAAE,IAAA,yCAAsB,EAAC;YAC/B,QAAQ;YACR,gEAAgE;YAChE,+DAA+D;YAC/D,SAAS,EAAE,IAAA,+BAAY,EAAC,mEAAmE,CAAC;YAC5F,MAAM,EAAE,WAAW;SACnB,CAAC;KACF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { mountSettingsEditor, type SettingsEditorOptions, type SettingsEditorWrite, } from "../../../discord/components/settings-editor/mount-settings-editor";
|
|
2
|
+
export { currentLevelKey, type SettingsEditorLevel, } from "../../../discord/components/settings-editor/navigation";
|
|
3
|
+
export { editorComponentIds, MAX_SELECT_OPTION_TEXT, MAX_SELECT_OPTIONS, SETTINGS_EDITOR_RESET_CONFIRMING, type SettingsEditorCardChrome, type SettingsEditorChrome, type SettingsEditorEmbedsChrome, type SettingsEditorIds, type SettingsEditorState, } from "../../../discord/components/settings-editor/settings-editor.view";
|
|
4
|
+
export { fieldButtonId, MAX_CARD_BUTTON_LEVEL_ENTRIES, MAX_CARD_LEVEL_ENTRIES, } from "../../../discord/components/settings-editor/settings-editor-card.view";
|
|
5
|
+
export type { SettingsEditorGroupSubmission, SettingsEditorSubmission, } from "../../../discord/components/settings-editor/settings-editor-field-modal";
|
|
6
|
+
export { MAX_MODAL_COMPONENTS, MAX_MODAL_INPUT_LENGTH, pickedFieldValue, type SettingsEditorChoice, type SettingsEditorField, type SettingsEditorFieldValue, type SettingsEditorGroupField, type SettingsEditorPickerField, type SettingsEditorValueField, textFieldValue, } from "../../../discord/components/settings-editor/settings-editor-fields";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/discord/components/settings-editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,mBAAmB,EACnB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,GACxB,MAAM,4DAA4D,CAAC;AACpE,OAAO,EACN,eAAe,EACf,KAAK,mBAAmB,GACxB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EACN,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,gCAAgC,EAChC,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,GACxB,MAAM,2DAA2D,CAAC;AACnE,OAAO,EACN,aAAa,EACb,6BAA6B,EAC7B,sBAAsB,GACtB,MAAM,gEAAgE,CAAC;AACxE,YAAY,EACX,6BAA6B,EAC7B,wBAAwB,GACxB,MAAM,kEAAkE,CAAC;AAC1E,OAAO,EACN,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,cAAc,GACd,MAAM,6DAA6D,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.textFieldValue = exports.pickedFieldValue = exports.MAX_MODAL_INPUT_LENGTH = exports.MAX_MODAL_COMPONENTS = exports.MAX_CARD_LEVEL_ENTRIES = exports.MAX_CARD_BUTTON_LEVEL_ENTRIES = exports.fieldButtonId = exports.SETTINGS_EDITOR_RESET_CONFIRMING = exports.MAX_SELECT_OPTIONS = exports.MAX_SELECT_OPTION_TEXT = exports.editorComponentIds = exports.currentLevelKey = exports.mountSettingsEditor = void 0;
|
|
4
|
+
var mount_settings_editor_1 = require("../../../discord/components/settings-editor/mount-settings-editor");
|
|
5
|
+
Object.defineProperty(exports, "mountSettingsEditor", { enumerable: true, get: function () { return mount_settings_editor_1.mountSettingsEditor; } });
|
|
6
|
+
var navigation_1 = require("../../../discord/components/settings-editor/navigation");
|
|
7
|
+
Object.defineProperty(exports, "currentLevelKey", { enumerable: true, get: function () { return navigation_1.currentLevelKey; } });
|
|
8
|
+
var settings_editor_view_1 = require("../../../discord/components/settings-editor/settings-editor.view");
|
|
9
|
+
Object.defineProperty(exports, "editorComponentIds", { enumerable: true, get: function () { return settings_editor_view_1.editorComponentIds; } });
|
|
10
|
+
Object.defineProperty(exports, "MAX_SELECT_OPTION_TEXT", { enumerable: true, get: function () { return settings_editor_view_1.MAX_SELECT_OPTION_TEXT; } });
|
|
11
|
+
Object.defineProperty(exports, "MAX_SELECT_OPTIONS", { enumerable: true, get: function () { return settings_editor_view_1.MAX_SELECT_OPTIONS; } });
|
|
12
|
+
Object.defineProperty(exports, "SETTINGS_EDITOR_RESET_CONFIRMING", { enumerable: true, get: function () { return settings_editor_view_1.SETTINGS_EDITOR_RESET_CONFIRMING; } });
|
|
13
|
+
var settings_editor_card_view_1 = require("../../../discord/components/settings-editor/settings-editor-card.view");
|
|
14
|
+
Object.defineProperty(exports, "fieldButtonId", { enumerable: true, get: function () { return settings_editor_card_view_1.fieldButtonId; } });
|
|
15
|
+
Object.defineProperty(exports, "MAX_CARD_BUTTON_LEVEL_ENTRIES", { enumerable: true, get: function () { return settings_editor_card_view_1.MAX_CARD_BUTTON_LEVEL_ENTRIES; } });
|
|
16
|
+
Object.defineProperty(exports, "MAX_CARD_LEVEL_ENTRIES", { enumerable: true, get: function () { return settings_editor_card_view_1.MAX_CARD_LEVEL_ENTRIES; } });
|
|
17
|
+
var settings_editor_fields_1 = require("../../../discord/components/settings-editor/settings-editor-fields");
|
|
18
|
+
Object.defineProperty(exports, "MAX_MODAL_COMPONENTS", { enumerable: true, get: function () { return settings_editor_fields_1.MAX_MODAL_COMPONENTS; } });
|
|
19
|
+
Object.defineProperty(exports, "MAX_MODAL_INPUT_LENGTH", { enumerable: true, get: function () { return settings_editor_fields_1.MAX_MODAL_INPUT_LENGTH; } });
|
|
20
|
+
Object.defineProperty(exports, "pickedFieldValue", { enumerable: true, get: function () { return settings_editor_fields_1.pickedFieldValue; } });
|
|
21
|
+
Object.defineProperty(exports, "textFieldValue", { enumerable: true, get: function () { return settings_editor_fields_1.textFieldValue; } });
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/discord/components/settings-editor/index.ts"],"names":[],"mappings":";;;AAAA,oGAIoE;AAHnE,4HAAA,mBAAmB,OAAA;AAIpB,8EAGyD;AAFxD,6GAAA,eAAe,OAAA;AAGhB,kGAUmE;AATlE,0HAAA,kBAAkB,OAAA;AAClB,8HAAA,sBAAsB,OAAA;AACtB,0HAAA,kBAAkB,OAAA;AAClB,wIAAA,gCAAgC,OAAA;AAOjC,4GAIwE;AAHvE,0HAAA,aAAa,OAAA;AACb,0IAAA,6BAA6B,OAAA;AAC7B,mIAAA,sBAAsB,OAAA;AAMvB,sGAWqE;AAVpE,8HAAA,oBAAoB,OAAA;AACpB,gIAAA,sBAAsB,OAAA;AACtB,0HAAA,gBAAgB,OAAA;AAOhB,wHAAA,cAAc,OAAA"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { ChatInputCommandInteraction, ModalMessageModalSubmitInteraction } from "discord.js";
|
|
2
|
+
import type { Clock } from "../../../clock";
|
|
3
|
+
import { type InteractiveMessageHandle, type InteractiveSelect, type StateStore } from "../../../discord/components/interactive-message";
|
|
4
|
+
import { type SettingsEditorLevel } from "../../../discord/components/settings-editor/navigation";
|
|
5
|
+
import { type SettingsEditorChrome, type SettingsEditorIds, type SettingsEditorState } from "../../../discord/components/settings-editor/settings-editor.view";
|
|
6
|
+
import type { SettingsEditorGroupSubmission, SettingsEditorSubmission } from "../../../discord/components/settings-editor/settings-editor-field-modal";
|
|
7
|
+
import { type SettingsEditorField, type SettingsEditorFieldValue } from "../../../discord/components/settings-editor/settings-editor-fields";
|
|
8
|
+
import { type Button } from "../../../discord/interaction/button";
|
|
9
|
+
import { type Locale, type Translator } from "../../../i18n";
|
|
10
|
+
import type { Logger } from "../../../logger";
|
|
11
|
+
/**
|
|
12
|
+
* What one write leaves behind: the new subject, and the files the message must
|
|
13
|
+
* now carry.
|
|
14
|
+
*
|
|
15
|
+
* Files, not the caller's own notion of an asset: the editor attaches them and
|
|
16
|
+
* never looks further, so a caller with no uploads at all is not made to carry
|
|
17
|
+
* the concept.
|
|
18
|
+
*/
|
|
19
|
+
export interface SettingsEditorWrite<S, A> {
|
|
20
|
+
readonly subject: S;
|
|
21
|
+
readonly assets: readonly A[];
|
|
22
|
+
}
|
|
23
|
+
export interface SettingsEditorOptions<S, A, F extends string> {
|
|
24
|
+
/**
|
|
25
|
+
* The screen's own custom ids, from `editorComponentIds`. Declared by the
|
|
26
|
+
* screen rather than derived here, so a test — and a log — names the very
|
|
27
|
+
* control an administrator clicked.
|
|
28
|
+
*/
|
|
29
|
+
readonly ids: SettingsEditorIds;
|
|
30
|
+
readonly fields: readonly SettingsEditorField<F>[];
|
|
31
|
+
/**
|
|
32
|
+
* The levels below the root, if the screen has any. Omitted by a flat screen,
|
|
33
|
+
* which then never renders a return control.
|
|
34
|
+
*/
|
|
35
|
+
readonly levels?: readonly SettingsEditorLevel<F>[];
|
|
36
|
+
readonly initial: SettingsEditorWrite<S, A>;
|
|
37
|
+
/** What the modal for `field` opens on. */
|
|
38
|
+
currentValue(subject: S, field: F): SettingsEditorFieldValue;
|
|
39
|
+
/**
|
|
40
|
+
* Persist one field — its typed value, its upload, or what a picker's select
|
|
41
|
+
* came back with, whichever `submission` carries.
|
|
42
|
+
*
|
|
43
|
+
* A `BusinessError` — an unsupported placeholder, a colour that is not one, an
|
|
44
|
+
* oversized upload — is caught here and shown as a notice: nothing is written,
|
|
45
|
+
* the previous value stands, and the screen stays open saying why in the
|
|
46
|
+
* administrator's language.
|
|
47
|
+
*
|
|
48
|
+
* `submission.interaction` is the modal's own submit interaction, handed over
|
|
49
|
+
* because a screen lives for minutes: a caller whose write is restricted must
|
|
50
|
+
* be able to re-read who is asking *now*, not who opened the screen.
|
|
51
|
+
*/
|
|
52
|
+
save(subject: S, field: F, submission: SettingsEditorSubmission): Promise<SettingsEditorWrite<S, A>>;
|
|
53
|
+
/**
|
|
54
|
+
* Persist a group's whole modal at once — one write, whatever business
|
|
55
|
+
* refusal any of its members can raise refusing before any of it lands.
|
|
56
|
+
* Split across several calls, a refusal partway through would leave the
|
|
57
|
+
* fields before it written while the administrator is told the group
|
|
58
|
+
* failed; the module deciding what "one write" means for its own group is
|
|
59
|
+
* what keeps that from happening (a service already taking a partial patch,
|
|
60
|
+
* most often, the very shape a group's submission already is).
|
|
61
|
+
*
|
|
62
|
+
* Required only of a screen that declares a `group`-kind field — never
|
|
63
|
+
* called otherwise, so a screen with none may leave it out.
|
|
64
|
+
*/
|
|
65
|
+
saveGroup?(subject: S, group: F, submissions: SettingsEditorGroupSubmission<F>, interaction: ModalMessageModalSubmitInteraction): Promise<SettingsEditorWrite<S, A>>;
|
|
66
|
+
/**
|
|
67
|
+
* Extra text shown inside a group's modal, above its member fields — a
|
|
68
|
+
* token legend whose content depends on the subject (a guild's own declared
|
|
69
|
+
* request lines) and so cannot be declared statically alongside the group
|
|
70
|
+
* the way its label and hint are. `null`, or the hook left out entirely, is
|
|
71
|
+
* a group with nothing to say there.
|
|
72
|
+
*/
|
|
73
|
+
groupLegend?(subject: S, group: F): string | null;
|
|
74
|
+
/** Clear every override of the shown subject, uploads included. */
|
|
75
|
+
reset(subject: S): Promise<SettingsEditorWrite<S, A>>;
|
|
76
|
+
readonly chrome: SettingsEditorChrome<S, A>;
|
|
77
|
+
/**
|
|
78
|
+
* Behaviour for whatever the chrome renders above the field menu — the
|
|
79
|
+
* welcome editor's type picker.
|
|
80
|
+
*/
|
|
81
|
+
readonly selects?: InteractiveSelect<SettingsEditorState<S, A>>[];
|
|
82
|
+
/**
|
|
83
|
+
* Behaviour for the buttons the chrome renders beside the editor's own.
|
|
84
|
+
*
|
|
85
|
+
* The counterpart of {@link selects}, and needed for the same reason: a screen
|
|
86
|
+
* whose subject is a list needs controls that add to it and remove from it, and
|
|
87
|
+
* those are buttons. Without this the chrome could draw them and nothing would
|
|
88
|
+
* route the click — which is why the welcome preview's look-alikes are declared
|
|
89
|
+
* permanently disabled rather than merely left unhandled.
|
|
90
|
+
*
|
|
91
|
+
* The editor renders none of them itself: what appears on screen is whatever
|
|
92
|
+
* `chrome.extraRows`/`chrome.extraBlocks` puts there, level by level.
|
|
93
|
+
* Registering a button that no row or block carries is harmless, and is how
|
|
94
|
+
* a control confined to one level works.
|
|
95
|
+
*/
|
|
96
|
+
readonly buttons?: Button<SettingsEditorState<S, A>>[];
|
|
97
|
+
/**
|
|
98
|
+
* What one write changes outside the screen — a published panel that names
|
|
99
|
+
* a ticket type, say. Called after every write that actually lands, never
|
|
100
|
+
* after a refusal, since nothing changed for it to report then.
|
|
101
|
+
*
|
|
102
|
+
* This screen has no "done" control any more, and so no reliable moment
|
|
103
|
+
* that says "the administrator has finished" — only the message being
|
|
104
|
+
* dismissed, which nothing here is told about. Republishing used to wait
|
|
105
|
+
* for that moment on purpose, so a member watching the public result never
|
|
106
|
+
* saw the half-finished states an administrator passes through on the way
|
|
107
|
+
* to the setting they meant. That trade is deliberately given up: a public
|
|
108
|
+
* page that is current beats one that is merely correct but stale for
|
|
109
|
+
* however long this administrator takes, or forever if the process
|
|
110
|
+
* restarts before they are done.
|
|
111
|
+
*
|
|
112
|
+
* A throw here never reaches the administrator as a refusal — see
|
|
113
|
+
* `applyChange`'s own doc: by the time this runs, the write it reports on
|
|
114
|
+
* has already succeeded, and telling them otherwise would be a lie. It is
|
|
115
|
+
* logged instead and the screen still confirms.
|
|
116
|
+
*/
|
|
117
|
+
onWritten?: () => Promise<void>;
|
|
118
|
+
readonly translator: Translator;
|
|
119
|
+
readonly locale: Locale;
|
|
120
|
+
/** Stamps the screen's own embeds, so a render says when it was last refreshed. */
|
|
121
|
+
readonly clock: Clock;
|
|
122
|
+
readonly logger: Logger;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Mount the editor every customisable ticket embed is edited through: a preview
|
|
126
|
+
* of what members see, a menu of fields, a modal per field, and a confirmed
|
|
127
|
+
* reset.
|
|
128
|
+
*
|
|
129
|
+
* Everything specific to *what* is being edited — where the values are read,
|
|
130
|
+
* where they are written, how the preview is rendered — is supplied by the
|
|
131
|
+
* caller. What lives here is the part both screens would otherwise have written
|
|
132
|
+
* twice: the modal round trip, the read-at-submit-time rule, refusals turned
|
|
133
|
+
* into notices, and re-rendering through the interaction that is still usable.
|
|
134
|
+
*
|
|
135
|
+
* Call it on an already-deferred interaction.
|
|
136
|
+
*/
|
|
137
|
+
export declare function mountSettingsEditor<S, A, F extends string>(interaction: ChatInputCommandInteraction, options: SettingsEditorOptions<S, A, F>): Promise<InteractiveMessageHandle & {
|
|
138
|
+
readonly store: StateStore<SettingsEditorState<S, A>>;
|
|
139
|
+
}>;
|
|
140
|
+
//# sourceMappingURL=mount-settings-editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mount-settings-editor.d.ts","sourceRoot":"","sources":["../../../../src/discord/components/settings-editor/mount-settings-editor.ts"],"names":[],"mappings":"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"}
|