Merge branch 'translation' into l10n_translation
This commit is contained in:
commit
c3d84f5dea
730 changed files with 25032 additions and 8526 deletions
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
|
@ -78,7 +78,7 @@ jobs:
|
|||
git clone https://$USERNAME:$GITHUB_TOKEN@github.com/$REPO.git plugins
|
||||
cd plugins
|
||||
|
||||
cp ../dist/release/*plugins.json .
|
||||
cp ../dist/release/*.json .
|
||||
git add -A
|
||||
|
||||
git commit -m "Plugins for https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA"
|
||||
|
|
|
|||
23
.github/workflows/publish.yml
vendored
23
.github/workflows/publish.yml
vendored
|
|
@ -77,13 +77,22 @@ jobs:
|
|||
if: steps.check.outputs.release == 'true'
|
||||
run: pnpm buildWebStandalone
|
||||
|
||||
- name: Create sources zip
|
||||
if: steps.check.outputs.release == 'true'
|
||||
run: zip -r dist/extension-sources.zip . -x "node_modules/*" -x "dist/*" -x ".git/*"
|
||||
|
||||
- name: Publish extension
|
||||
if: steps.check.outputs.release == 'true'
|
||||
run: |
|
||||
cd dist/browser/chromium-unpacked
|
||||
pnpx chrome-webstore-upload-cli@2.1.0 upload --auto-publish
|
||||
run: pnpx publish-browser-extension@latest --chrome-zip dist/extension-chrome.zip --firefox-zip dist/extension-firefox.zip --firefox-sources-zip dist/extension-sources.zip --edge-zip dist/extension-chrome.zip
|
||||
|
||||
env:
|
||||
EXTENSION_ID: ${{ secrets.CHROME_EXTENSION_ID }}
|
||||
CLIENT_ID: ${{ secrets.CHROME_CLIENT_ID }}
|
||||
CLIENT_SECRET: ${{ secrets.CHROME_CLIENT_SECRET }}
|
||||
REFRESH_TOKEN: ${{ secrets.CHROME_REFRESH_TOKEN }}
|
||||
CHROME_EXTENSION_ID: ${{ secrets.CHROME_EXTENSION_ID }}
|
||||
CHROME_CLIENT_ID: ${{ secrets.CHROME_CLIENT_ID }}
|
||||
CHROME_CLIENT_SECRET: ${{ secrets.CHROME_CLIENT_SECRET }}
|
||||
CHROME_REFRESH_TOKEN: ${{ secrets.CHROME_REFRESH_TOKEN }}
|
||||
FIREFOX_EXTENSION_ID: ${{ secrets.FIREFOX_EXTENSION_ID }}
|
||||
FIREFOX_JWT_ISSUER: ${{ secrets.FIREFOX_JWT_ISSUER }}
|
||||
FIREFOX_JWT_SECRET: ${{ secrets.FIREFOX_JWT_SECRET }}
|
||||
EDGE_PRODUCT_ID: ${{ secrets.EDGE_PRODUCT_ID }}
|
||||
EDGE_CLIENT_ID: ${{ secrets.EDGE_CLIENT_ID }}
|
||||
EDGE_API_KEY: ${{ secrets.EDGE_API_KEY }}
|
||||
|
|
|
|||
12
README.md
12
README.md
|
|
@ -68,17 +68,21 @@ Build Equicord:
|
|||
pnpm build
|
||||
```
|
||||
|
||||
Inject Equicord into your desktop client:
|
||||
|
||||
```shell
|
||||
pnpm inject
|
||||
```
|
||||
|
||||
Build Equicord for web:
|
||||
|
||||
```shell
|
||||
pnpm buildWeb
|
||||
```
|
||||
|
||||
Inject Equicord into your client:
|
||||
After building Equicord's web extension, locate the appropriate ZIP file in the `dist` directory and follow your browser’s guide for installing custom extensions, if supported.
|
||||
|
||||
```shell
|
||||
pnpm inject
|
||||
```
|
||||
Note: Firefox extension zip requires Firefox for developers
|
||||
|
||||
## Credits
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import type { Settings } from "@api/Settings";
|
|||
import { debounce } from "@shared/debounce";
|
||||
import { localStorage } from "@utils/localStorage";
|
||||
import { getStylusWebStoreUrl } from "@utils/web";
|
||||
import { EXTENSION_BASE_URL } from "@utils/web-metadata";
|
||||
import { EXTENSION_BASE_URL, metaReady, RENDERER_CSS_URL } from "@utils/web-metadata";
|
||||
|
||||
// listeners for ipc.on
|
||||
const cssListeners = new Set<(css: string) => void>();
|
||||
|
|
@ -55,7 +55,18 @@ window.VencordNative = {
|
|||
|
||||
native: {
|
||||
getVersions: () => ({}),
|
||||
openExternal: async (url) => void open(url, "_blank")
|
||||
openExternal: async (url) => void open(url, "_blank"),
|
||||
getRendererCss: async () => {
|
||||
if (IS_USERSCRIPT)
|
||||
// need to wait for next tick for _vcUserScriptRendererCss to be set
|
||||
return Promise.resolve().then(() => window._vcUserScriptRendererCss);
|
||||
|
||||
await metaReady;
|
||||
|
||||
return fetch(RENDERER_CSS_URL)
|
||||
.then(res => res.text());
|
||||
},
|
||||
onRendererCssUpdate: NOOP,
|
||||
},
|
||||
|
||||
updater: {
|
||||
|
|
@ -92,18 +103,20 @@ window.VencordNative = {
|
|||
return;
|
||||
}
|
||||
|
||||
const { getTheme, Theme } = require("@utils/discord");
|
||||
|
||||
win.baseUrl = EXTENSION_BASE_URL;
|
||||
win.setCss = setCssDebounced;
|
||||
win.getCurrentCss = () => VencordNative.quickCss.get();
|
||||
win.getTheme = () =>
|
||||
getTheme() === Theme.Light
|
||||
? "vs-light"
|
||||
: "vs-dark";
|
||||
win.getTheme = this.getEditorTheme;
|
||||
|
||||
win.document.write(monacoHtmlLocal);
|
||||
},
|
||||
getEditorTheme: () => {
|
||||
const { getTheme, Theme } = require("@utils/discord");
|
||||
|
||||
return getTheme() === Theme.Light
|
||||
? "vs-light"
|
||||
: "vs-dark";
|
||||
}
|
||||
},
|
||||
|
||||
settings: {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ chrome.webRequest.onHeadersReceived.addListener(
|
|||
({ responseHeaders, type, url }) => {
|
||||
if (!responseHeaders) return;
|
||||
|
||||
if (type === "main_frame") {
|
||||
if (type === "main_frame" && url.includes("discord.com")) {
|
||||
// In main frame requests, the CSP needs to be removed to enable fetching of custom css
|
||||
// as desired by the user
|
||||
removeFirst(responseHeaders, h => h.name.toLowerCase() === "content-security-policy");
|
||||
|
|
|
|||
|
|
@ -2,20 +2,15 @@ if (typeof browser === "undefined") {
|
|||
var browser = chrome;
|
||||
}
|
||||
|
||||
const style = document.createElement("link");
|
||||
style.type = "text/css";
|
||||
style.rel = "stylesheet";
|
||||
style.href = browser.runtime.getURL("dist/Equicord.css");
|
||||
|
||||
document.addEventListener(
|
||||
"DOMContentLoaded",
|
||||
() => {
|
||||
document.body.insertAdjacentElement("afterend", style);
|
||||
window.postMessage({
|
||||
type: "vencord:meta",
|
||||
meta: {
|
||||
EXTENSION_VERSION: browser.runtime.getManifest().version,
|
||||
EXTENSION_BASE_URL: browser.runtime.getURL(""),
|
||||
RENDERER_CSS_URL: browser.runtime.getURL("dist/Equicord.css"),
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@
|
|||
]
|
||||
},
|
||||
"condition": {
|
||||
"resourceTypes": ["main_frame", "sub_frame"]
|
||||
"resourceTypes": ["main_frame", "sub_frame"],
|
||||
"urlFilter": "||discord.com^"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -32,7 +33,7 @@
|
|||
},
|
||||
"condition": {
|
||||
"resourceTypes": ["stylesheet"],
|
||||
"urlFilter": "https://raw.githubusercontent.com/*"
|
||||
"urlFilter": "||raw.githubusercontent.com^"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -5,13 +5,14 @@
|
|||
*/
|
||||
|
||||
import stylistic from "@stylistic/eslint-plugin";
|
||||
import { defineConfig } from "eslint/config";
|
||||
import react from "eslint-plugin-react";
|
||||
import header from "eslint-plugin-simple-header";
|
||||
import simpleImportSort from "eslint-plugin-simple-import-sort";
|
||||
import unusedImports from "eslint-plugin-unused-imports";
|
||||
import tseslint from "typescript-eslint";
|
||||
|
||||
export default tseslint.config(
|
||||
export default defineConfig(
|
||||
{ ignores: ["dist", "browser", "packages/vencord-types"] },
|
||||
{
|
||||
files: ["src/**/*.{tsx,ts,mts,mjs,js,jsx}", "eslint.config.mjs"],
|
||||
|
|
@ -86,6 +87,7 @@ export default tseslint.config(
|
|||
"@stylistic/object-curly-spacing": ["error", "always"],
|
||||
"@stylistic/spaced-comment": ["error", "always", { "markers": ["!"] }],
|
||||
"@stylistic/no-extra-semi": "error",
|
||||
"no-multiple-empty-lines": ["error", { "max": 1, "maxBOF": 0, "maxEOF": 0 }],
|
||||
|
||||
// TS Rules
|
||||
"@stylistic/function-call-spacing": ["error", "never"],
|
||||
|
|
|
|||
|
|
@ -84,13 +84,16 @@
|
|||
},
|
||||
"settings": {
|
||||
"disableMinSize": {
|
||||
"title": "Disable minimum window size"
|
||||
"title": "Disable minimum window size",
|
||||
"description": "Allow the Discord window to be resized smaller than its default minimum size. Useful for tiling window managers or small screens."
|
||||
},
|
||||
"enableReactDevtools": {
|
||||
"title": "Enable React Developer Tools"
|
||||
"title": "Enable React Developer Tools",
|
||||
"description": "Enable the React Developer Tools extension for debugging Discord's React components. Useful for plugin development."
|
||||
},
|
||||
"frameless": {
|
||||
"title": "Disable the window frame"
|
||||
"title": "Disable the window frame",
|
||||
"description": "Remove the native window frame for a cleaner look. You can still move the window by dragging the title bar area."
|
||||
},
|
||||
"hint": "Hint: You can change the position of this settings section in the <0>settings of the Settings plugin</0>!",
|
||||
"macosVibrancyStyle": {
|
||||
|
|
@ -153,7 +156,8 @@
|
|||
"checkYourConnection": "Failed to connect to repository. Check your internet connection",
|
||||
"failedtoFetchCommits": "Could not fetch commits from repository",
|
||||
"repository": "Repository",
|
||||
"viewRecentChanges": "View the most recent changes to Equicord. This fetches commits directly from the repository to show you what's new",
|
||||
"whereUpdatesFetch": "This is the GitHub repository where Equicord fetches updates from",
|
||||
"viewRecentChanges": "These are the new commits and plugin updates since your last version. You can see what features were added, bugs were fixed, and which plugins received updates",
|
||||
"failedToRetrieve": "Failed to retrieve - check console",
|
||||
"upToDate": "Repository Up To Date",
|
||||
"fetchRepo": "Fetch from Repository",
|
||||
|
|
@ -167,7 +171,8 @@
|
|||
"updateLogs_zero": "No Update Logs",
|
||||
"updateLogs_one": "Update Logs ({count} log)",
|
||||
"updateLogs_other": "Update Logs ({count} logs)",
|
||||
"previousSessions": "Previous update sessions with their commit history and plugin changes",
|
||||
"previousSessions": "A history of your previous update sessions with their commit history and plugin changes. Click on a log to expand it and see the details",
|
||||
"info": "Check the repository for new commits, plugin updates, and code changes. This will compare your current version with the latest available and show you what's new",
|
||||
"title": "Changelog"
|
||||
},
|
||||
"restartRequired": {
|
||||
|
|
@ -179,18 +184,22 @@
|
|||
},
|
||||
"title": "Settings",
|
||||
"transparent": {
|
||||
"description": "You need a theme that supports transparency or this will do nothing. WILL STOP THE WINDOW FROM BEING RESIZABLE!! Requires a full restart",
|
||||
"title": "Enable window transparency"
|
||||
"description": "Make the Discord window transparent. A theme that supports transparency is required or this will do nothing.",
|
||||
"title": "Enable window transparency",
|
||||
"noteWindows": "This will stop the window from being resizable and prevents you from snapping the window to screen edges",
|
||||
"note": "This will stop the window from being resizable."
|
||||
},
|
||||
"useQuickCss": {
|
||||
"description": "Loads your Custom CSS",
|
||||
"description": "Load custom CSS from the QuickCSS editor. This allows you to customize Discord's appearance with your own styles.",
|
||||
"title": "Enable Custom CSS"
|
||||
},
|
||||
"winCtrlQ": {
|
||||
"title": "Register Ctrl+Q as shortcut to close Discord (alternative to Alt+F4)"
|
||||
"title": "Register Ctrl+Q as shortcut to close Discord",
|
||||
"description": "Add Ctrl+Q as a keyboard shortcut to close Discord. This provides an alternative to Alt+F4 for quickly closing the application."
|
||||
},
|
||||
"winNativeTitleBar": {
|
||||
"title": "Use Windows' native title bar instead of Discord's custom one"
|
||||
"title": "Use Windows' native title bar instead of Discord's custom one",
|
||||
"description": "Replace Discord's custom title bar with the standard Windows title bar. This may improve compatibility with some window management tools."
|
||||
}
|
||||
},
|
||||
"tabs": {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "equicord",
|
||||
"private": "true",
|
||||
"version": "1.13.6.2",
|
||||
"version": "1.13.11",
|
||||
"description": "The other cutest Discord client mod",
|
||||
"homepage": "https://github.com/Equicord/Equicord#readme",
|
||||
"bugs": {
|
||||
|
|
@ -69,7 +69,6 @@
|
|||
"@types/react-dom": "^19.0.4",
|
||||
"@types/yazl": "^3.3.0",
|
||||
"@vencord/discord-types": "link:packages/discord-types",
|
||||
"adm-zip": "^0.5.16",
|
||||
"diff": "^8.0.2",
|
||||
"esbuild": "^0.27.0",
|
||||
"eslint": "9.39.1",
|
||||
|
|
@ -94,7 +93,7 @@
|
|||
"typescript-transform-paths": "^3.5.5",
|
||||
"zip-local": "^0.3.5"
|
||||
},
|
||||
"packageManager": "pnpm@10.23.0",
|
||||
"packageManager": "pnpm@10.26.2",
|
||||
"pnpm": {
|
||||
"patchedDependencies": {
|
||||
"@types/less@3.0.8": "patches/@types__less@3.0.8.patch"
|
||||
|
|
|
|||
|
|
@ -1 +1,3 @@
|
|||
Hint: https://docs.discord.food is an incredible resource and allows you to copy paste complete enums and interfaces
|
||||
# Contributing to @equicord/discord-types
|
||||
|
||||
<https://docs.discord.food> is an incredible resource and allows you to copy paste complete enums and interfaces
|
||||
|
|
|
|||
|
|
@ -2,20 +2,20 @@
|
|||
|
||||
This package provides TypeScript types for the Webpack modules of Discord's web app.
|
||||
|
||||
While it was primarily created for Vencord, other client mods could also benefit from this, so it is published as a standalone package!
|
||||
While it was primarily created for Equicord based on Vencord and its respective packages, other client mods could also benefit from this, so it is published as a standalone package!
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install -D @vencord/discord-types
|
||||
yarn add -D @vencord/discord-types
|
||||
pnpm add -D @vencord/discord-types
|
||||
npm install -D @equicord/discord-types
|
||||
yarn add -D @equicord/discord-types
|
||||
pnpm add -D @equicord/discord-types
|
||||
```
|
||||
|
||||
## Example Usage
|
||||
|
||||
```ts
|
||||
import type { UserStore } from "@vencord/discord-types";
|
||||
import type { UserStore } from "@equicord/discord-types";
|
||||
|
||||
const userStore: UserStore = findStore("UserStore"); // findStore is up to you to implement, this library only provides types and no runtime code
|
||||
```
|
||||
|
|
@ -23,8 +23,9 @@ const userStore: UserStore = findStore("UserStore"); // findStore is up to you t
|
|||
## Enums
|
||||
|
||||
This library also exports some const enums that you can use from Typescript code:
|
||||
|
||||
```ts
|
||||
import { ApplicationCommandType } from "@vencord/discord-types/enums";
|
||||
import { ApplicationCommandType } from "@equicord/discord-types/enums";
|
||||
|
||||
console.log(ApplicationCommandType.CHAT_INPUT); // 1
|
||||
```
|
||||
|
|
|
|||
|
|
@ -9,18 +9,15 @@ export const enum ActivityType {
|
|||
}
|
||||
|
||||
export const enum ActivityFlags {
|
||||
INSTANCE = 1 << 0,
|
||||
JOIN = 1 << 1,
|
||||
/** @deprecated */
|
||||
SPECTATE = 1 << 2,
|
||||
/** @deprecated */
|
||||
JOIN_REQUEST = 1 << 3,
|
||||
SYNC = 1 << 4,
|
||||
PLAY = 1 << 5,
|
||||
PARTY_PRIVACY_FRIENDS = 1 << 6,
|
||||
PARTY_PRIVACY_VOICE_CHANNEL = 1 << 7,
|
||||
EMBEDDED = 1 << 8,
|
||||
CONTEXTLESS = 1 << 9
|
||||
INSTANCE = 1,
|
||||
JOIN = 2,
|
||||
SYNC = 16,
|
||||
PLAY = 32,
|
||||
PARTY_PRIVACY_FRIENDS = 64,
|
||||
PARTY_PRIVACY_VOICE_CHANNEL = 128,
|
||||
EMBEDDED = 256,
|
||||
CONTEXTLESS = 512,
|
||||
SUPPORTS_GATEWAY_ACTIVITY_ACTION_JOIN = 1024,
|
||||
}
|
||||
|
||||
export const enum ActivityStatusDisplayType {
|
||||
|
|
@ -28,3 +25,26 @@ export const enum ActivityStatusDisplayType {
|
|||
STATE = 1,
|
||||
DETAILS = 2
|
||||
}
|
||||
|
||||
export const enum OrientationLockState {
|
||||
UNLOCKED = 1,
|
||||
PORTRAIT = 2,
|
||||
LANDSCAPE = 3,
|
||||
}
|
||||
|
||||
export const enum ActivityGameMode {
|
||||
PLAY = 0,
|
||||
SPECTATE = 1,
|
||||
}
|
||||
|
||||
export const enum ActivityLayout {
|
||||
FOCUSED = 0,
|
||||
PIP = 1,
|
||||
GRID = 2,
|
||||
}
|
||||
|
||||
export const enum ActivityLabelType {
|
||||
NONE = 0,
|
||||
NEW = 1,
|
||||
UPDATED = 2,
|
||||
}
|
||||
|
|
|
|||
43
packages/discord-types/enums/application.ts
Normal file
43
packages/discord-types/enums/application.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
export const enum ApplicationType {
|
||||
DEPRECATED_GAME = 1,
|
||||
TICKETED_EVENTS = 3,
|
||||
GUILD_ROLE_SUBSCRIPTIONS = 4,
|
||||
GAME = 5,
|
||||
NON_GAME_DETECTABLE = 6,
|
||||
}
|
||||
|
||||
export const enum LinkedGameType {
|
||||
LINKED = 1,
|
||||
OFFICIAL = 2,
|
||||
NVIDIA = 3,
|
||||
}
|
||||
|
||||
export const enum CarouselItemType {
|
||||
IMG = 1,
|
||||
YOUTUBE_VIDEO = 2,
|
||||
VIDEO = 3,
|
||||
}
|
||||
|
||||
export const enum ApplicationFlags {
|
||||
EMBEDDED_RELEASED = 2,
|
||||
EMBEDDED_IAP = 8,
|
||||
APPLICATION_AUTO_MODERATION_RULE_CREATE_BADGE = 64,
|
||||
GAME_PROFILE_DISABLED = 128,
|
||||
CONTEXTLESS_ACTIVITY = 512,
|
||||
SOCIAL_LAYER_INTEGRATION_LIMITED = 1024,
|
||||
CLOUD_GAMING_DEMO = 2048,
|
||||
GATEWAY_PRESENCE = 4096,
|
||||
GATEWAY_PRESENCE_LIMITED = 8192,
|
||||
GATEWAY_GUILD_MEMBERS = 16384,
|
||||
GATEWAY_GUILD_MEMBERS_LIMITED = 32768,
|
||||
EMBEDDED = 131072,
|
||||
GATEWAY_MESSAGE_CONTENT = 262144,
|
||||
GATEWAY_MESSAGE_CONTENT_LIMITED = 524288,
|
||||
EMBEDDED_FIRST_PARTY = 1048576,
|
||||
APPLICATION_COMMAND_BADGE = 8388608,
|
||||
SOCIAL_LAYER_INTEGRATION = 134217728,
|
||||
PROMOTED = 536870912,
|
||||
PARTNER = 1073741824,
|
||||
PARENT = 8589934592,
|
||||
DISABLE_RELATIONSHIPS_ACCESS = 17179869184,
|
||||
}
|
||||
|
|
@ -1,3 +1,58 @@
|
|||
export const enum PermissionOverwriteType {
|
||||
ROLE = 0,
|
||||
MEMBER = 1,
|
||||
OWNER = 2
|
||||
}
|
||||
|
||||
export const enum PermissionOverwriteRowType {
|
||||
EMPTY_STATE = 0,
|
||||
ADMINISTRATOR = 1,
|
||||
ROLE = 2,
|
||||
OWNER = 3,
|
||||
MEMBER = 4,
|
||||
USER = 5,
|
||||
GUILD = 6,
|
||||
}
|
||||
|
||||
export const enum PermissionOverwriteSectionType {
|
||||
ROLES = 0,
|
||||
MEMBERS = 1,
|
||||
USERS = 2,
|
||||
GUILDS = 3,
|
||||
}
|
||||
|
||||
export const enum ForumLayout {
|
||||
DEFAULT = 0,
|
||||
LIST = 1,
|
||||
GRID = 2,
|
||||
}
|
||||
|
||||
export const enum SafetyWarningType {
|
||||
STRANGER_DANGER = 1,
|
||||
INAPPROPRIATE_CONVERSATION_TIER_1 = 2,
|
||||
INAPPROPRIATE_CONVERSATION_TIER_2 = 3,
|
||||
LIKELY_ATO = 4,
|
||||
}
|
||||
|
||||
export const enum ChannelFlags {
|
||||
GUILD_FEED_REMOVED = 1,
|
||||
PINNED = 2,
|
||||
ACTIVE_CHANNELS_REMOVED = 4,
|
||||
REQUIRE_TAG = 16,
|
||||
IS_SPAM = 32,
|
||||
IS_GUILD_RESOURCE_CHANNEL = 128,
|
||||
CLYDE_AI = 256,
|
||||
IS_SCHEDULED_FOR_DELETION = 512,
|
||||
IS_MEDIA_CHANNEL = 1024,
|
||||
SUMMARIES_DISABLED = 2048,
|
||||
IS_ROLE_SUBSCRIPTION_TEMPLATE_PREVIEW_CHANNEL = 8192,
|
||||
IS_BROADCASTING = 16384,
|
||||
HIDE_MEDIA_DOWNLOAD_OPTIONS = 32768,
|
||||
IS_JOIN_REQUEST_INTERVIEW_CHANNEL = 65536,
|
||||
OBFUSCATED = 131072,
|
||||
IS_MODERATOR_REPORT_CHANNEL = 524288,
|
||||
}
|
||||
|
||||
export const enum ChannelType {
|
||||
GUILD_TEXT = 0,
|
||||
DM = 1,
|
||||
|
|
@ -5,11 +60,100 @@ export const enum ChannelType {
|
|||
GROUP_DM = 3,
|
||||
GUILD_CATEGORY = 4,
|
||||
GUILD_ANNOUNCEMENT = 5,
|
||||
GUILD_STORE = 6,
|
||||
ANNOUNCEMENT_THREAD = 10,
|
||||
PUBLIC_THREAD = 11,
|
||||
PRIVATE_THREAD = 12,
|
||||
GUILD_STAGE_VOICE = 13,
|
||||
GUILD_DIRECTORY = 14,
|
||||
GUILD_FORUM = 15,
|
||||
GUILD_MEDIA = 16
|
||||
}
|
||||
GUILD_MEDIA = 16,
|
||||
LOBBY = 17,
|
||||
DM_SDK = 18,
|
||||
UNKNOWN = 10000,
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-defined Sets of channel types for grouping related channels.
|
||||
* Each property is a Set<ChannelType> containing channel type numbers.
|
||||
*/
|
||||
export interface ChannelTypesSets {
|
||||
/** DM and GROUP_DM, channels that support calling. */
|
||||
CALLABLE: Set<ChannelType>;
|
||||
/** Channels that support text messages. */
|
||||
TEXTUAL: Set<ChannelType>;
|
||||
/** Forum and media channels, threads only, no direct messages. */
|
||||
GUILD_THREADS_ONLY: Set<ChannelType>;
|
||||
/** Channels that support stickers. */
|
||||
STICKERS: Set<ChannelType>;
|
||||
/** Channels that can be read/viewed. */
|
||||
READABLE: Set<ChannelType>;
|
||||
/** All guild channel types including threads. */
|
||||
GUILD: Set<ChannelType>;
|
||||
/** Guild channels excluding threads. */
|
||||
GUILD_CHANNEL: Set<ChannelType>;
|
||||
/** All thread types (announcement, public, private). */
|
||||
THREADS: Set<ChannelType>;
|
||||
/** DM and GROUP_DM, private/non-guild channels. */
|
||||
PRIVATE_CHANNEL: Set<ChannelType>;
|
||||
/** Announcement and public threads only. */
|
||||
PUBLIC_THREADS: Set<ChannelType>;
|
||||
/** Guild channels that can have threads. */
|
||||
GUILD_THREADED: Set<ChannelType>;
|
||||
/** Guild channels that are persisted/stored. */
|
||||
GUILD_STORED: Set<ChannelType>;
|
||||
/** Guild channels with text capability. */
|
||||
GUILD_TEXTUAL: Set<ChannelType>;
|
||||
/** Guild voice and stage channels. */
|
||||
GUILD_VOCAL: Set<ChannelType>;
|
||||
/** Thread types that support voice. */
|
||||
VOCAL_THREAD: Set<ChannelType>;
|
||||
/** All channels with voice capability. */
|
||||
VOCAL: Set<ChannelType>;
|
||||
/** Channels that support voice effects. */
|
||||
VOICE_EFFECTS: Set<ChannelType>;
|
||||
/** Guild text-only channels (no voice). */
|
||||
GUILD_TEXT_ONLY: Set<ChannelType>;
|
||||
/** Channels with character-limited names. */
|
||||
LIMITED_CHANNEL_NAME: Set<ChannelType>;
|
||||
/** Channels that support message search. */
|
||||
SEARCHABLE: Set<ChannelType>;
|
||||
/** Guild channels with user-generated content. */
|
||||
GUILD_USER_CONTENT: Set<ChannelType>;
|
||||
/** Guild channels that can have topics. */
|
||||
GUILD_TOPICAL: Set<ChannelType>;
|
||||
/** Guild channels that support webhooks. */
|
||||
GUILD_WEBHOOKS: Set<ChannelType>;
|
||||
/** Guild channels usable as system message channel. */
|
||||
GUILD_SYSTEM_CHANNEL: Set<ChannelType>;
|
||||
/** Guild channels that can have a parent category. */
|
||||
GUILD_PARENTABLE: Set<ChannelType>;
|
||||
/** Guild channels subject to auto-moderation. */
|
||||
GUILD_AUTO_MODERATED: Set<ChannelType>;
|
||||
/** Basic guild channel types for creation. */
|
||||
GUILD_BASIC: Set<ChannelType>;
|
||||
/** Guild channel types that can be created. */
|
||||
CREATEABLE_GUILD_CHANNELS: Set<ChannelType>;
|
||||
/** GROUP_DM only, multi-user DMs. */
|
||||
MULTI_USER_DMS: Set<ChannelType>;
|
||||
/** DM and GROUP_DM. */
|
||||
ALL_DMS: Set<ChannelType>;
|
||||
/** Channels that support invites. */
|
||||
INVITABLE: Set<ChannelType>;
|
||||
/** Guild channels supporting feed-featurable messages. */
|
||||
GUILD_FEED_FEATURABLE_MESSAGES: Set<ChannelType>;
|
||||
/** Channels supporting role subscriptions. */
|
||||
ROLE_SUBSCRIPTIONS: Set<ChannelType>;
|
||||
/** Channels supporting icon emojis. */
|
||||
ICON_EMOJIS: Set<ChannelType>;
|
||||
/** Channels that can be summarized. */
|
||||
SUMMARIZEABLE: Set<ChannelType>;
|
||||
/** Channels supporting content entry embeds. */
|
||||
CONTENT_ENTRY_EMBEDS: Set<ChannelType>;
|
||||
/** Channels that support polls. */
|
||||
POLLS: Set<ChannelType>;
|
||||
/** Channels that can launch activities. */
|
||||
ACTIVITY_LAUNCHABLE: Set<ChannelType>;
|
||||
/** All known channel types. */
|
||||
ALL: Set<ChannelType>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,12 +21,23 @@ export const enum ApplicationCommandInputType {
|
|||
}
|
||||
|
||||
export const enum ApplicationCommandType {
|
||||
/**
|
||||
* @remarks Discord API calls this just CHAT
|
||||
*/
|
||||
CHAT_INPUT = 1,
|
||||
USER = 2,
|
||||
MESSAGE = 3,
|
||||
PRIMARY_ENTRY_POINT = 4,
|
||||
}
|
||||
|
||||
export const enum ApplicationIntegrationType {
|
||||
GUILD_INSTALL = 0,
|
||||
USER_INSTALL = 1
|
||||
USER_INSTALL = 1,
|
||||
}
|
||||
|
||||
export const enum InteractionType {
|
||||
APPLICATION_COMMAND = 2,
|
||||
MESSAGE_COMPONENT = 3,
|
||||
APPLICATION_COMMAND_AUTOCOMPLETE = 4,
|
||||
MODAL_SUBMIT = 5,
|
||||
}
|
||||
|
|
|
|||
103
packages/discord-types/enums/guild.ts
Normal file
103
packages/discord-types/enums/guild.ts
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
export const enum GuildScheduledEventStatus {
|
||||
SCHEDULED = 1,
|
||||
ACTIVE = 2,
|
||||
COMPLETED = 3,
|
||||
CANCELED = 4,
|
||||
}
|
||||
|
||||
export const enum GuildScheduledEventEntityType {
|
||||
NONE = 0,
|
||||
STAGE_INSTANCE = 1,
|
||||
VOICE = 2,
|
||||
EXTERNAL = 3,
|
||||
PRIME_TIME = 4,
|
||||
}
|
||||
|
||||
export const enum GuildScheduledEventPrivacyLevel {
|
||||
PUBLIC = 1,
|
||||
GUILD_ONLY = 2,
|
||||
}
|
||||
|
||||
export const enum GuildNSFWLevel {
|
||||
DEFAULT = 0,
|
||||
EXPLICIT = 1,
|
||||
SAFE = 2,
|
||||
AGE_RESTRICTED = 3,
|
||||
}
|
||||
|
||||
export const enum GuildVerificationLevel {
|
||||
NONE = 0,
|
||||
LOW = 1,
|
||||
MEDIUM = 2,
|
||||
HIGH = 3,
|
||||
VERY_HIGH = 4,
|
||||
}
|
||||
|
||||
export const enum GuildExplicitContentFilter {
|
||||
DISABLED = 0,
|
||||
MEMBERS_WITHOUT_ROLES = 1,
|
||||
ALL_MEMBERS = 2,
|
||||
}
|
||||
|
||||
export const enum GuildMFALevel {
|
||||
NONE = 0,
|
||||
ELEVATED = 1,
|
||||
}
|
||||
|
||||
export const enum GuildDefaultMessageNotifications {
|
||||
ALL_MESSAGES = 0,
|
||||
ONLY_MENTIONS = 1,
|
||||
}
|
||||
|
||||
export const enum GuildPremiumTier {
|
||||
NONE = 0,
|
||||
TIER_1 = 1,
|
||||
TIER_2 = 2,
|
||||
TIER_3 = 3,
|
||||
}
|
||||
|
||||
export const enum GuildSettingsFlags {
|
||||
UNREADS_ALL_MESSAGES = 2048,
|
||||
UNREADS_ONLY_MENTIONS = 4096,
|
||||
OPT_IN_CHANNELS_OFF = 8192,
|
||||
OPT_IN_CHANNELS_ON = 16384,
|
||||
}
|
||||
|
||||
export const enum SystemChannelFlags {
|
||||
SUPPRESS_JOIN_NOTIFICATIONS = 1,
|
||||
SUPPRESS_PREMIUM_SUBSCRIPTIONS = 2,
|
||||
SUPPRESS_GUILD_REMINDER_NOTIFICATIONS = 4,
|
||||
SUPPRESS_JOIN_NOTIFICATION_REPLIES = 8,
|
||||
SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATIONS = 16,
|
||||
SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATION_REPLIES = 32,
|
||||
SUPPRESS_CHANNEL_PROMPT_DEADCHAT = 128,
|
||||
SUPPRESS_UGC_ADDED_NOTIFICATIONS = 256,
|
||||
}
|
||||
|
||||
export const enum GuildMemberFlags {
|
||||
DID_REJOIN = 1,
|
||||
COMPLETED_ONBOARDING = 2,
|
||||
BYPASSES_VERIFICATION = 4,
|
||||
STARTED_ONBOARDING = 8,
|
||||
IS_GUEST = 16,
|
||||
STARTED_HOME_ACTIONS = 32,
|
||||
COMPLETED_HOME_ACTIONS = 64,
|
||||
AUTOMOD_QUARANTINED_USERNAME_OR_GUILD_NICKNAME = 128,
|
||||
AUTOMOD_QUARANTINED_BIO = 256,
|
||||
DM_SETTINGS_UPSELL_ACKNOWLEDGED = 512,
|
||||
AUTOMOD_QUARANTINED_SERVER_TAG = 1024,
|
||||
}
|
||||
|
||||
export const enum RoleFlags {
|
||||
IN_PROMPT = 1,
|
||||
}
|
||||
|
||||
export const enum RecurrenceRuleFrequency {
|
||||
YEARLY = 0,
|
||||
MONTHLY = 1,
|
||||
WEEKLY = 2,
|
||||
DAILY = 3,
|
||||
HOURLY = 4,
|
||||
MINUTELY = 5,
|
||||
SECONDLY = 6,
|
||||
}
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
export * from "./activity";
|
||||
export * from "./application";
|
||||
export * from "./channel";
|
||||
export * from "./commands";
|
||||
export * from "./guild";
|
||||
export * from "./messages";
|
||||
export * from "./misc";
|
||||
export * from "./settings";
|
||||
export * from "./user";
|
||||
export * from "./voice";
|
||||
|
|
|
|||
|
|
@ -1,3 +1,54 @@
|
|||
export const enum ComponentType {
|
||||
UNKNOWN = -1,
|
||||
ACTION_ROW = 1,
|
||||
BUTTON = 2,
|
||||
STRING_SELECT = 3,
|
||||
TEXT_INPUT = 4,
|
||||
USER_SELECT = 5,
|
||||
ROLE_SELECT = 6,
|
||||
MENTIONABLE_SELECT = 7,
|
||||
CHANNEL_SELECT = 8,
|
||||
SECTION = 9,
|
||||
TEXT_DISPLAY = 10,
|
||||
THUMBNAIL = 11,
|
||||
MEDIA_GALLERY = 12,
|
||||
FILE = 13,
|
||||
SEPARATOR = 14,
|
||||
CONTENT_INVENTORY_ENTRY = 16,
|
||||
CONTAINER = 17,
|
||||
LABEL = 18,
|
||||
FILE_UPLOAD = 19,
|
||||
CHECKPOINT_CARD = 20,
|
||||
}
|
||||
|
||||
export const enum ButtonStyle {
|
||||
PRIMARY = 1,
|
||||
SECONDARY = 2,
|
||||
SUCCESS = 3,
|
||||
DESTRUCTIVE = 4,
|
||||
LINK = 5,
|
||||
PREMIUM = 6,
|
||||
}
|
||||
|
||||
export const enum MessageReferenceType {
|
||||
DEFAULT = 0,
|
||||
FORWARD = 1,
|
||||
}
|
||||
|
||||
export const enum PollLayoutType {
|
||||
UNKNOWN = 0,
|
||||
DEFAULT = 1,
|
||||
IMAGE_ONLY_ANSWERS = 2
|
||||
}
|
||||
|
||||
export const enum MessageActivityType {
|
||||
JOIN = 1,
|
||||
LISTEN = 3,
|
||||
WATCH = 4,
|
||||
JOIN_REQUEST = 5,
|
||||
STREAM_REQUEST = 6,
|
||||
}
|
||||
|
||||
export const enum StickerType {
|
||||
/** an official sticker in a pack */
|
||||
STANDARD = 1,
|
||||
|
|
@ -92,6 +143,8 @@ export const enum MessageType {
|
|||
* Name: PREMIUM_GUILD_SUBSCRIPTION
|
||||
* Rendered Content: "{author} just boosted the server{content ? " {content} times"}!"
|
||||
* Deletable: true
|
||||
*
|
||||
* @remarks Discord API calls this GUILD_BOOST
|
||||
*/
|
||||
PREMIUM_GUILD_SUBSCRIPTION = 8,
|
||||
/**
|
||||
|
|
@ -101,6 +154,8 @@ export const enum MessageType {
|
|||
* Name: PREMIUM_GUILD_SUBSCRIPTION_TIER_1
|
||||
* Rendered Content: "{author} just boosted the server{content ? " {content} times"}! {guild} has achieved Level 1! "
|
||||
* Deletable: true
|
||||
*
|
||||
* @remarks Discord API calls this GUILD_BOOST_TIER_1
|
||||
*/
|
||||
PREMIUM_GUILD_SUBSCRIPTION_TIER_1 = 9,
|
||||
/**
|
||||
|
|
@ -110,6 +165,8 @@ export const enum MessageType {
|
|||
* Name: PREMIUM_GUILD_SUBSCRIPTION_TIER_2
|
||||
* Rendered Content: "{author} just boosted the server{content ? " {content} times"}! {guild} has achieved Level 2! "
|
||||
* Deletable: true
|
||||
*
|
||||
* @remarks Discord API calls this GUILD_BOOST_TIER_2
|
||||
*/
|
||||
PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 10,
|
||||
/**
|
||||
|
|
@ -119,6 +176,8 @@ export const enum MessageType {
|
|||
* Name: PREMIUM_GUILD_SUBSCRIPTION_TIER_3
|
||||
* Rendered Content: "{author} just boosted the server{content ? " {content} times"}! {guild} has achieved Level 3! "
|
||||
* Deletable: true
|
||||
*
|
||||
* @remarks Discord API calls this GUILD_BOOST_TIER_3
|
||||
*/
|
||||
PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 11,
|
||||
/**
|
||||
|
|
@ -130,6 +189,14 @@ export const enum MessageType {
|
|||
* Deletable: true
|
||||
*/
|
||||
CHANNEL_FOLLOW_ADD = 12,
|
||||
/**
|
||||
* A message sent when a user starts a stream in a guild.
|
||||
*
|
||||
* Value: 13
|
||||
* Name: GUILD_STREAM
|
||||
* Deletable: true
|
||||
*/
|
||||
GUILD_STREAM = 13,
|
||||
/**
|
||||
* A message sent when a guild is disqualified from discovery
|
||||
*
|
||||
|
|
@ -301,6 +368,22 @@ export const enum MessageType {
|
|||
* Deletable: true
|
||||
*/
|
||||
GUILD_APPLICATION_PREMIUM_SUBSCRIPTION = 32,
|
||||
/**
|
||||
* A message sent when an integration is added to a private channel
|
||||
*
|
||||
* Value: 33
|
||||
* Name: PRIVATE_CHANNEL_INTEGRATION_ADDED
|
||||
* Deletable: true
|
||||
*/
|
||||
PRIVATE_CHANNEL_INTEGRATION_ADDED = 33,
|
||||
/**
|
||||
* A message sent when an integration is removed from a private channel
|
||||
*
|
||||
* Value: 34
|
||||
* Name: PRIVATE_CHANNEL_INTEGRATION_REMOVED
|
||||
* Deletable: true
|
||||
*/
|
||||
PRIVATE_CHANNEL_INTEGRATION_REMOVED = 34,
|
||||
/**
|
||||
* A message sent when a user gifts a premium (Nitro) referral
|
||||
*
|
||||
|
|
@ -380,6 +463,14 @@ export const enum MessageType {
|
|||
* Deletable: true
|
||||
*/
|
||||
PURCHASE_NOTIFICATION = 44,
|
||||
/**
|
||||
* A message sent as a voice hangout invite
|
||||
*
|
||||
* Value: 45
|
||||
* Name: VOICE_HANGOUT_INVITE
|
||||
* Deletable: true
|
||||
*/
|
||||
VOICE_HANGOUT_INVITE = 45,
|
||||
/**
|
||||
* A message sent when a poll is finalized
|
||||
*
|
||||
|
|
@ -470,6 +561,22 @@ export const enum MessageType {
|
|||
* Deletable: true
|
||||
*/
|
||||
HD_STREAMING_UPGRADED = 55,
|
||||
/**
|
||||
* A message sent when a chat wallpaper is set
|
||||
*
|
||||
* Value: 56
|
||||
* Name: CHAT_WALLPAPER_SET
|
||||
* Deletable: true
|
||||
*/
|
||||
CHAT_WALLPAPER_SET = 56,
|
||||
/**
|
||||
* A message sent when a chat wallpaper is removed
|
||||
*
|
||||
* Value: 57
|
||||
* Name: CHAT_WALLPAPER_REMOVED
|
||||
* Deletable: true
|
||||
*/
|
||||
CHAT_WALLPAPER_REMOVED = 57,
|
||||
/**
|
||||
* A message sent when a user resolves a moderation report by deleting the offending message
|
||||
*
|
||||
|
|
@ -524,6 +631,14 @@ export const enum MessageType {
|
|||
* Deletable: true
|
||||
*/
|
||||
EMOJI_ADDED = 63,
|
||||
/**
|
||||
* A message sent as a premium group invite
|
||||
*
|
||||
* Value: 64
|
||||
* Name: PREMIUM_GROUP_INVITE
|
||||
* Deletable: true
|
||||
*/
|
||||
PREMIUM_GROUP_INVITE = 64,
|
||||
}
|
||||
|
||||
export const enum MessageFlags {
|
||||
|
|
|
|||
|
|
@ -2,3 +2,53 @@ export const enum CloudUploadPlatform {
|
|||
REACT_NATIVE = 0,
|
||||
WEB = 1,
|
||||
}
|
||||
|
||||
export const enum DraftType {
|
||||
ChannelMessage = 0,
|
||||
ThreadSettings = 1,
|
||||
FirstThreadMessage = 2,
|
||||
ApplicationLauncherCommand = 3,
|
||||
Poll = 4,
|
||||
SlashCommand = 5,
|
||||
ForwardContextMessage = 6,
|
||||
InteractionModal = 7,
|
||||
}
|
||||
|
||||
export const enum EmojiIntention {
|
||||
REACTION = 0,
|
||||
STATUS = 1,
|
||||
COMMUNITY_CONTENT = 2,
|
||||
CHAT = 3,
|
||||
GUILD_STICKER_RELATED_EMOJI = 4,
|
||||
GUILD_ROLE_BENEFIT_EMOJI = 5,
|
||||
SOUNDBOARD = 6,
|
||||
VOICE_CHANNEL_TOPIC = 7,
|
||||
GIFT = 8,
|
||||
AUTO_SUGGESTION = 9,
|
||||
POLLS = 10,
|
||||
PROFILE = 11,
|
||||
MESSAGE_CONFETTI = 12,
|
||||
GUILD_PROFILE = 13,
|
||||
CHANNEL_NAME = 14,
|
||||
DEFAULT_REACT_EMOJI = 15,
|
||||
}
|
||||
|
||||
export const enum LoadState {
|
||||
NOT_LOADED = 0,
|
||||
LOADING = 1,
|
||||
LOADED = 2,
|
||||
ERROR = 3,
|
||||
}
|
||||
|
||||
export const enum InviteTargetType {
|
||||
STREAM = 1,
|
||||
EMBEDDED_APPLICATION = 2,
|
||||
ROLE_SUBSCRIPTIONS_PURCHASE = 3,
|
||||
}
|
||||
|
||||
export const enum PremiumType {
|
||||
NONE = 0,
|
||||
TIER_1 = 1,
|
||||
TIER_2 = 2,
|
||||
TIER_0 = 3,
|
||||
}
|
||||
|
|
|
|||
42
packages/discord-types/enums/settings.ts
Normal file
42
packages/discord-types/enums/settings.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
export const enum Theme {
|
||||
UNSET = 0,
|
||||
DARK = 1,
|
||||
LIGHT = 2,
|
||||
DARKER = 3,
|
||||
MIDNIGHT = 4,
|
||||
}
|
||||
|
||||
export const enum UIDensity {
|
||||
UNSET = 0,
|
||||
COMPACT = 1,
|
||||
COZY = 2,
|
||||
RESPONSIVE = 3,
|
||||
DEFAULT = 4,
|
||||
}
|
||||
|
||||
export const enum StickerAnimationSetting {
|
||||
ALWAYS = 0,
|
||||
ON_INTERACTION = 1,
|
||||
NEVER = 2,
|
||||
}
|
||||
|
||||
export const enum UserNotificationSetting {
|
||||
ALL_MESSAGES = 0,
|
||||
ONLY_MENTIONS = 1,
|
||||
NO_MESSAGES = 2,
|
||||
}
|
||||
|
||||
export const enum ChannelOverrideFlags {
|
||||
UNREADS_ONLY_MENTIONS = 512,
|
||||
UNREADS_ALL_MESSAGES = 1024,
|
||||
FAVORITED = 2048,
|
||||
OPT_IN_ENABLED = 4096,
|
||||
NEW_FORUM_THREADS_OFF = 8192,
|
||||
NEW_FORUM_THREADS_ON = 16384,
|
||||
}
|
||||
|
||||
export const enum NotifyHighlights {
|
||||
NULL = 0,
|
||||
DISABLED = 1,
|
||||
ENABLED = 2,
|
||||
}
|
||||
53
packages/discord-types/enums/user.ts
Normal file
53
packages/discord-types/enums/user.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
export const enum RelationshipType {
|
||||
NONE = 0,
|
||||
FRIEND = 1,
|
||||
BLOCKED = 2,
|
||||
/**
|
||||
* @remarks Discord API calls this PENDING_INCOMING
|
||||
*/
|
||||
INCOMING_REQUEST = 3,
|
||||
/**
|
||||
* @remarks Discord API calls this PENDING_OUTGOING
|
||||
*/
|
||||
OUTGOING_REQUEST = 4,
|
||||
IMPLICIT = 5,
|
||||
SUGGESTION = 6,
|
||||
}
|
||||
|
||||
export enum GiftIntentType {
|
||||
FRIEND_ANNIVERSARY = 0
|
||||
}
|
||||
|
||||
export const enum ReadStateType {
|
||||
CHANNEL = 0,
|
||||
GUILD_EVENT = 1,
|
||||
NOTIFICATION_CENTER = 2,
|
||||
GUILD_HOME = 3,
|
||||
GUILD_ONBOARDING_QUESTION = 4,
|
||||
MESSAGE_REQUESTS = 5,
|
||||
}
|
||||
|
||||
export const enum UserFlags {
|
||||
STAFF = 1,
|
||||
PARTNER = 2,
|
||||
HYPESQUAD = 4,
|
||||
BUG_HUNTER_LEVEL_1 = 8,
|
||||
MFA_SMS = 16,
|
||||
PREMIUM_PROMO_DISMISSED = 32,
|
||||
HYPESQUAD_ONLINE_HOUSE_1 = 64,
|
||||
HYPESQUAD_ONLINE_HOUSE_2 = 128,
|
||||
HYPESQUAD_ONLINE_HOUSE_3 = 256,
|
||||
PREMIUM_EARLY_SUPPORTER = 512,
|
||||
HAS_UNREAD_URGENT_MESSAGES = 8192,
|
||||
BUG_HUNTER_LEVEL_2 = 16384,
|
||||
VERIFIED_BOT = 65536,
|
||||
VERIFIED_DEVELOPER = 131072,
|
||||
CERTIFIED_MODERATOR = 262144,
|
||||
BOT_HTTP_INTERACTIONS = 524288,
|
||||
SPAMMER = 1048576,
|
||||
DISABLE_PREMIUM = 2097152,
|
||||
PROVISIONAL_ACCOUNT = 8388608,
|
||||
QUARANTINED = 17592186044416,
|
||||
COLLABORATOR = 1125899906842624,
|
||||
RESTRICTED_COLLABORATOR = 2251799813685248,
|
||||
}
|
||||
50
packages/discord-types/enums/voice.ts
Normal file
50
packages/discord-types/enums/voice.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
export const enum ParticipantType {
|
||||
STREAM = 0,
|
||||
HIDDEN_STREAM = 1,
|
||||
USER = 2,
|
||||
ACTIVITY = 3,
|
||||
}
|
||||
|
||||
export const enum RTCPlatform {
|
||||
DESKTOP = 0,
|
||||
MOBILE = 1,
|
||||
XBOX = 2,
|
||||
PLAYSTATION = 3,
|
||||
}
|
||||
|
||||
export const enum VideoSourceType {
|
||||
VIDEO = 0,
|
||||
CAMERA_PREVIEW = 1,
|
||||
}
|
||||
|
||||
export const enum ConnectionStatsFlags {
|
||||
TRANSPORT = 1,
|
||||
OUTBOUND = 2,
|
||||
INBOUND = 4,
|
||||
ALL = 7,
|
||||
}
|
||||
|
||||
export const enum SpeakingFlags {
|
||||
NONE = 0,
|
||||
VOICE = 1,
|
||||
SOUNDSHARE = 2,
|
||||
PRIORITY = 4,
|
||||
HIDDEN = 8,
|
||||
}
|
||||
|
||||
export const enum GoLiveQualityMode {
|
||||
AUTO = 1,
|
||||
FULL = 2,
|
||||
}
|
||||
|
||||
export const enum VoiceProcessingStateReason {
|
||||
CPU_OVERUSE = 1,
|
||||
FAILED = 2,
|
||||
VAD_CPU_OVERUSE = 3,
|
||||
INITIALIZED = 4,
|
||||
}
|
||||
|
||||
export const enum VideoQualityMode {
|
||||
AUTO = 1,
|
||||
FULL = 2,
|
||||
}
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
{
|
||||
"name": "@vencord/discord-types",
|
||||
"author": "Vencord Contributors",
|
||||
"name": "@equicord/discord-types",
|
||||
"author": "Equicord & Vencord Contributors",
|
||||
"private": false,
|
||||
"description": "Typescript definitions for the webpack modules of the Discord Web app",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.2",
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"types": "src/index.d.ts",
|
||||
"type": "module",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Vendicated/Vencord.git",
|
||||
"url": "git+https://github.com/Equicord/Equicord.git",
|
||||
"directory": "packages/discord-types"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -19,4 +19,4 @@
|
|||
"peerDependencies": {
|
||||
"@types/react": "^19.0.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
import { ActivityFlags, ActivityStatusDisplayType, ActivityType } from "../../enums";
|
||||
|
||||
export type ActivityPlatform = "desktop" | "mobile" | "web" | "embedded" | "xbox" | "playstation" | "samsung" | "ios" | "android";
|
||||
|
||||
export interface ActivityAssets {
|
||||
large_image?: string;
|
||||
large_text?: string;
|
||||
|
|
@ -18,8 +20,10 @@ export interface Activity {
|
|||
created_at?: number;
|
||||
id?: string;
|
||||
name: string;
|
||||
application_id: string;
|
||||
application_id?: string;
|
||||
type: ActivityType;
|
||||
session_id?: string;
|
||||
sync_id?: string;
|
||||
emoji?: {
|
||||
animated: boolean;
|
||||
id: string;
|
||||
|
|
@ -41,7 +45,7 @@ export interface Activity {
|
|||
metadata?: {
|
||||
button_urls?: Array<string>;
|
||||
};
|
||||
platform?: string;
|
||||
platform?: ActivityPlatform;
|
||||
party?: {
|
||||
id?: string;
|
||||
size?: [number, number];
|
||||
|
|
|
|||
139
packages/discord-types/src/common/Application.d.ts
vendored
139
packages/discord-types/src/common/Application.d.ts
vendored
|
|
@ -1,23 +1,136 @@
|
|||
import { ActivityLabelType, ApplicationFlags, ApplicationType, CarouselItemType, LinkedGameType, OrientationLockState } from "../../enums";
|
||||
import { Guild } from "./Guild";
|
||||
import { User } from "./User";
|
||||
|
||||
export interface Application {
|
||||
export type EmbeddedActivityPlatform = "ios" | "android" | "web";
|
||||
|
||||
export interface EmbeddedActivityPlatformConfig {
|
||||
label_type: ActivityLabelType;
|
||||
label_from: string | null;
|
||||
label_until: string | null;
|
||||
release_phase: string;
|
||||
omit_badge_from_surfaces: string[];
|
||||
}
|
||||
|
||||
export interface EmbeddedActivityConfig {
|
||||
application_id: string;
|
||||
activity_preview_video_asset_id: string | null;
|
||||
supported_platforms: EmbeddedActivityPlatform[];
|
||||
default_orientation_lock_state: OrientationLockState;
|
||||
tablet_default_orientation_lock_state: OrientationLockState;
|
||||
requires_age_gate: boolean;
|
||||
legacy_responsive_aspect_ratio: boolean;
|
||||
premium_tier_requirement: number | null;
|
||||
free_period_starts_at: string | null;
|
||||
free_period_ends_at: string | null;
|
||||
client_platform_config: Partial<Record<EmbeddedActivityPlatform, EmbeddedActivityPlatformConfig>>;
|
||||
shelf_rank: number;
|
||||
has_csp_exception: boolean;
|
||||
displays_advertisements: boolean;
|
||||
blocked_locales: string[];
|
||||
supported_locales: string[];
|
||||
}
|
||||
|
||||
export interface ApplicationExecutable {
|
||||
os: "win32" | "darwin" | "linux";
|
||||
name: string;
|
||||
isLauncher: boolean;
|
||||
}
|
||||
|
||||
export interface ApplicationThirdPartySku {
|
||||
id: string;
|
||||
sku: string;
|
||||
distributor: string;
|
||||
}
|
||||
|
||||
export interface ApplicationDeveloper {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string | null;
|
||||
type: number | null;
|
||||
icon: string | null | undefined;
|
||||
is_discoverable: boolean;
|
||||
is_monetized: boolean;
|
||||
is_verified: boolean;
|
||||
bot?: User;
|
||||
deeplink_uri?: string;
|
||||
flags?: number;
|
||||
privacy_policy_url?: string;
|
||||
terms_of_service_url?: string;
|
||||
install_params?: ApplicationInstallParams;
|
||||
}
|
||||
|
||||
export interface ApplicationInstallParams {
|
||||
permissions: string | null;
|
||||
scopes: string[];
|
||||
}
|
||||
|
||||
export interface ApplicationIntegrationTypeConfig {
|
||||
oauth2InstallParams: ApplicationInstallParams;
|
||||
}
|
||||
|
||||
export interface ApplicationDirectoryEntry {
|
||||
guild_count?: number;
|
||||
detailed_description?: string;
|
||||
supported_locales?: string[];
|
||||
carousel_items?: { asset_id: string; type: CarouselItemType; }[];
|
||||
}
|
||||
|
||||
export interface Application {
|
||||
id: string;
|
||||
name: string;
|
||||
icon: string | null;
|
||||
description: string;
|
||||
type: ApplicationType | null;
|
||||
coverImage: string | null;
|
||||
primarySkuId: string | undefined;
|
||||
bot: User | null;
|
||||
splash: string | undefined;
|
||||
thirdPartySkus: ApplicationThirdPartySku[];
|
||||
isMonetized: boolean;
|
||||
isVerified: boolean;
|
||||
roleConnectionsVerificationUrl: string | undefined;
|
||||
parentId: string | undefined;
|
||||
connectionEntrypointUrl: string | undefined;
|
||||
overlay: boolean;
|
||||
overlayWarn: boolean;
|
||||
overlayCompatibilityHook: boolean;
|
||||
overlayMethods: number;
|
||||
hook: boolean;
|
||||
aliases: string[];
|
||||
publishers: ApplicationDeveloper[];
|
||||
developers: ApplicationDeveloper[];
|
||||
storeListingSkuId: string | undefined;
|
||||
guildId: string | null;
|
||||
guild: Guild | undefined;
|
||||
executables: ApplicationExecutable[];
|
||||
hashes: string[];
|
||||
eulaId: string | undefined;
|
||||
slug: string | undefined;
|
||||
flags: ApplicationFlags;
|
||||
maxParticipants: number | null;
|
||||
tags: string[];
|
||||
embeddedActivityConfig: EmbeddedActivityConfig | undefined;
|
||||
team: ApplicationTeam | undefined;
|
||||
integrationTypesConfig: Record<string, ApplicationIntegrationTypeConfig>;
|
||||
storefront_available: boolean;
|
||||
termsOfServiceUrl: string | undefined;
|
||||
privacyPolicyUrl: string | undefined;
|
||||
isDiscoverable: boolean;
|
||||
customInstallUrl: string | undefined;
|
||||
installParams: ApplicationInstallParams | undefined;
|
||||
directoryEntry: ApplicationDirectoryEntry | undefined;
|
||||
categories: string[] | undefined;
|
||||
linkedGames: ApplicationLinkedGame[] | undefined;
|
||||
deepLinkUri: string | undefined;
|
||||
}
|
||||
|
||||
export interface ApplicationLinkedGame {
|
||||
id: string;
|
||||
type: LinkedGameType;
|
||||
application?: Application;
|
||||
}
|
||||
|
||||
export interface ApplicationTeam {
|
||||
id: string;
|
||||
name: string;
|
||||
icon: string | null;
|
||||
members: ApplicationTeamMember[];
|
||||
ownerUserId: string;
|
||||
}
|
||||
|
||||
export interface ApplicationTeamMember {
|
||||
user: User;
|
||||
teamId: string;
|
||||
membershipState: number;
|
||||
permissions: string[];
|
||||
role: string;
|
||||
}
|
||||
|
|
|
|||
378
packages/discord-types/src/common/Channel.d.ts
vendored
378
packages/discord-types/src/common/Channel.d.ts
vendored
|
|
@ -1,84 +1,368 @@
|
|||
import { ChannelFlags, ChannelType, ForumLayout, PermissionOverwriteType, SafetyWarningType, UserFlags, VideoQualityMode } from "../../enums";
|
||||
import { DiscordRecord } from "./Record";
|
||||
|
||||
/** Permission overwrite for a role or member. */
|
||||
export interface PermissionOverwrite {
|
||||
id: string;
|
||||
/** 0 = role, 1 = member. */
|
||||
type: PermissionOverwriteType;
|
||||
deny: bigint;
|
||||
allow: bigint;
|
||||
}
|
||||
|
||||
/** Avatar decoration data for user profiles. */
|
||||
export interface AvatarDecorationData {
|
||||
asset: string;
|
||||
expires_at: string | null;
|
||||
sku_id: string;
|
||||
}
|
||||
|
||||
/** Clan identity information. */
|
||||
export interface ClanData {
|
||||
badge: string;
|
||||
identity_enabled: boolean;
|
||||
identity_guild_id: string;
|
||||
tag: string;
|
||||
}
|
||||
|
||||
/** Display name style configuration. */
|
||||
export interface DisplayNameStyles {
|
||||
colors: number[];
|
||||
effect_id: number;
|
||||
font_id: number;
|
||||
}
|
||||
|
||||
/** Collectible item data. */
|
||||
export interface CollectibleItem {
|
||||
asset: string;
|
||||
expires_at: string | null;
|
||||
label: string;
|
||||
palette: string;
|
||||
sku_id: string;
|
||||
}
|
||||
|
||||
/** User collectibles configuration. */
|
||||
export interface Collectibles {
|
||||
nameplate?: CollectibleItem;
|
||||
}
|
||||
|
||||
/** Raw recipient data from API. */
|
||||
export interface RawRecipient {
|
||||
id: string;
|
||||
avatar: string | null;
|
||||
avatar_decoration_data: AvatarDecorationData | null;
|
||||
bot: boolean;
|
||||
clan: ClanData | null;
|
||||
collectibles: Collectibles | null;
|
||||
discriminator: string;
|
||||
display_name: string | null;
|
||||
display_name_styles: DisplayNameStyles | null;
|
||||
global_name: string | null;
|
||||
primary_guild: ClanData | null;
|
||||
public_flags: UserFlags;
|
||||
username: string;
|
||||
}
|
||||
|
||||
/** Thread metadata for thread channels. */
|
||||
export interface ThreadMetadata {
|
||||
archived: boolean;
|
||||
autoArchiveDuration: number;
|
||||
archiveTimestamp: string | undefined;
|
||||
createTimestamp: string | undefined;
|
||||
locked: boolean;
|
||||
invitable: boolean;
|
||||
}
|
||||
|
||||
/** Icon emoji for channels that support it. */
|
||||
export interface ChannelIconEmoji {
|
||||
id: string | null;
|
||||
name: string;
|
||||
}
|
||||
|
||||
/** Thread member info, present when user has joined a thread. */
|
||||
export interface ThreadMember {
|
||||
flags: number;
|
||||
joinTimestamp: string;
|
||||
muted: boolean;
|
||||
muteConfig: {
|
||||
end_time: string | null;
|
||||
selected_time_window: number;
|
||||
} | null;
|
||||
}
|
||||
|
||||
/** Available tag for forum/media channels. */
|
||||
export interface ForumTag {
|
||||
id: string;
|
||||
name: string;
|
||||
emojiId: string | null;
|
||||
emojiName: string | null;
|
||||
moderated: boolean;
|
||||
color: number | null;
|
||||
}
|
||||
|
||||
/** Default reaction emoji for forum/media channels. */
|
||||
export interface DefaultReactionEmoji {
|
||||
emojiId: string | null;
|
||||
emojiName: string;
|
||||
}
|
||||
|
||||
/** Linked lobby for voice channels. */
|
||||
export interface LinkedLobby {
|
||||
application_id: string;
|
||||
lobby_id: string;
|
||||
linked_by: string;
|
||||
linked_at: string;
|
||||
require_application_authorization: boolean;
|
||||
}
|
||||
|
||||
/** Safety warning for DM spam detection. */
|
||||
export interface SafetyWarning {
|
||||
id: string;
|
||||
type: SafetyWarningType;
|
||||
expiry: string;
|
||||
dismiss_timestamp: string | null;
|
||||
}
|
||||
|
||||
/** Sort order for forum/media channels. */
|
||||
export type ForumSortOrder = 0 | 1;
|
||||
|
||||
/** Tag setting for forum/media channels. */
|
||||
export type ForumTagSetting = "match_all" | "match_some";
|
||||
|
||||
/** Discord channel object. */
|
||||
export class Channel extends DiscordRecord {
|
||||
constructor(channel: object);
|
||||
application_id: number | undefined;
|
||||
bitrate: number;
|
||||
|
||||
/** Application ID for bot-created channels. */
|
||||
application_id: string | undefined;
|
||||
/** Applied tag IDs. Threads in forum/media channels only. */
|
||||
appliedTags: string[] | undefined;
|
||||
/** Available tags for forum/media channels. */
|
||||
availableTags: ForumTag[] | undefined;
|
||||
/** Internal, use bitrate getter. Voice channels only. */
|
||||
bitrate_: number | undefined;
|
||||
/** Whether blocked user warning was dismissed. */
|
||||
blockedUserWarningDismissed: boolean | undefined;
|
||||
/** Default auto-archive duration for threads in minutes. Guild text channels only. */
|
||||
defaultAutoArchiveDuration: number | undefined;
|
||||
flags: number;
|
||||
/** Default layout for forum/media channels. */
|
||||
defaultForumLayout: ForumLayout | undefined;
|
||||
/** Default reaction emoji for forum/media channels. */
|
||||
defaultReactionEmoji: DefaultReactionEmoji | undefined;
|
||||
/** Default sort order for forum/media channels. */
|
||||
defaultSortOrder: ForumSortOrder | undefined;
|
||||
/** Default tag setting for forum/media channels. */
|
||||
defaultTagSetting: ForumTagSetting | undefined;
|
||||
/** Default slowmode for new threads. Guild text channels only. */
|
||||
defaultThreadRateLimitPerUser: number | undefined;
|
||||
/** Internal, use flags getter. */
|
||||
flags_: ChannelFlags;
|
||||
/** Guild ID. */
|
||||
guild_id: string;
|
||||
icon: string;
|
||||
/** User ID who purchased HD streaming. */
|
||||
hdStreamingBuyerId: string | undefined;
|
||||
/** HD streaming end timestamp. */
|
||||
hdStreamingUntil: string | undefined;
|
||||
/** Icon hash for group DMs. */
|
||||
icon: string | undefined;
|
||||
/** Icon emoji for channels that support it. */
|
||||
iconEmoji: ChannelIconEmoji | undefined;
|
||||
/** Channel snowflake ID. */
|
||||
id: string;
|
||||
lastMessageId: string;
|
||||
/** For DMs, whether this is a message request. */
|
||||
isMessageRequest: boolean;
|
||||
/** Timestamp when message request was created. */
|
||||
isMessageRequestTimestamp: string | null;
|
||||
/** Whether the DM is flagged as spam. */
|
||||
isSpam: boolean;
|
||||
/** ID of the last message in the channel. */
|
||||
lastMessageId: string | null;
|
||||
/** ISO timestamp of the last pinned message. */
|
||||
lastPinTimestamp: string | undefined;
|
||||
member: unknown;
|
||||
/** Linked lobby for voice channels. */
|
||||
linkedLobby: LinkedLobby | null;
|
||||
/** Thread member info if user joined thread. Threads only. */
|
||||
member: ThreadMember | undefined;
|
||||
/** Approximate member count. Threads only. */
|
||||
memberCount: number | undefined;
|
||||
/** Preview of member IDs in the thread. Threads only. */
|
||||
memberIdsPreview: string[] | undefined;
|
||||
memberListId: unknown;
|
||||
/** Member list ID for guild channels. */
|
||||
memberListId: string | undefined;
|
||||
/** Approximate message count. Threads only. */
|
||||
messageCount: number | undefined;
|
||||
/** Channel name. */
|
||||
name: string;
|
||||
nicks: Record<string, unknown>;
|
||||
nsfw: boolean;
|
||||
originChannelId: unknown;
|
||||
ownerId: string;
|
||||
/** Custom nicknames in group DMs, keyed by user ID. */
|
||||
nicks: Record<string, string>;
|
||||
/** Internal, use nsfw getter. Guild channels only. */
|
||||
nsfw_: boolean;
|
||||
/** Origin channel ID for crossposted messages. */
|
||||
originChannelId: string | undefined;
|
||||
/** Owner ID for group DMs and threads. */
|
||||
ownerId: string | undefined;
|
||||
/** Parent category or channel ID. */
|
||||
parent_id: string;
|
||||
permissionOverwrites: {
|
||||
[role: string]: {
|
||||
id: string;
|
||||
type: number;
|
||||
deny: bigint;
|
||||
allow: bigint;
|
||||
};
|
||||
};
|
||||
position: number;
|
||||
rateLimitPerUser: number;
|
||||
rawRecipients: {
|
||||
id: string;
|
||||
avatar: string;
|
||||
username: string;
|
||||
public_flags: number;
|
||||
discriminator: string;
|
||||
}[];
|
||||
/** Parent channel type for threads. */
|
||||
parentChannelThreadType: ChannelType | undefined;
|
||||
/** Internal, use permissionOverwrites getter. Guild channels only. */
|
||||
permissionOverwrites_: Record<string, PermissionOverwrite>;
|
||||
/** Internal, use position getter. Guild channels only. */
|
||||
position_: number;
|
||||
/** Internal, use rateLimitPerUser getter. */
|
||||
rateLimitPerUser_: number;
|
||||
/** Raw recipient data from API. DMs and group DMs. */
|
||||
rawRecipients: RawRecipient[];
|
||||
/** Recipient flags for DMs. */
|
||||
recipientFlags: number;
|
||||
/** Recipient user IDs. DMs and group DMs. */
|
||||
recipients: string[];
|
||||
rtcRegion: string;
|
||||
threadMetadata: {
|
||||
locked: boolean;
|
||||
archived: boolean;
|
||||
invitable: boolean;
|
||||
createTimestamp: string | undefined;
|
||||
autoArchiveDuration: number;
|
||||
archiveTimestamp: string | undefined;
|
||||
};
|
||||
topic: string;
|
||||
type: number;
|
||||
userLimit: number;
|
||||
videoQualityMode: undefined;
|
||||
/** RTC region for voice channels, null for automatic. Voice channels only. */
|
||||
rtcRegion: string | null;
|
||||
/** Safety warnings for DM spam detection. */
|
||||
safetyWarnings: SafetyWarning[];
|
||||
/** Template string. */
|
||||
template: string | undefined;
|
||||
/** Theme color for group DMs. */
|
||||
themeColor: number | undefined;
|
||||
/** Thread metadata. Threads only. */
|
||||
threadMetadata: ThreadMetadata | undefined;
|
||||
/** Internal, use topic getter. */
|
||||
topic_: string | null;
|
||||
/** Total messages sent in thread. Threads only. */
|
||||
totalMessageSent: number | undefined;
|
||||
/** Channel type from ChannelType enum. */
|
||||
type: ChannelType;
|
||||
/** Internal, use userLimit getter. Voice channels only. */
|
||||
userLimit_: number | undefined;
|
||||
/** Channel version number. */
|
||||
version: number | undefined;
|
||||
/** Video quality mode for voice channels. Voice channels only. */
|
||||
videoQualityMode: VideoQualityMode | undefined;
|
||||
|
||||
/** Computed access permissions for the current user. */
|
||||
get accessPermissions(): bigint;
|
||||
get lastActiveTimestamp(): number;
|
||||
/** Bitrate in bits per second. Voice channels only. */
|
||||
get bitrate(): number;
|
||||
/** Channel flags bitmask. */
|
||||
get flags(): ChannelFlags;
|
||||
/** Whether HD streaming splash is active. */
|
||||
get isHDStreamSplashed(): boolean;
|
||||
/** Whether the channel is marked as NSFW. */
|
||||
get nsfw(): boolean;
|
||||
/** Permission overwrites keyed by role or user ID. */
|
||||
get permissionOverwrites(): Record<string, PermissionOverwrite>;
|
||||
/** Channel position in the channel list. */
|
||||
get position(): number;
|
||||
/** Slowmode delay in seconds. */
|
||||
get rateLimitPerUser(): number;
|
||||
/** Channel topic or description. */
|
||||
get topic(): string;
|
||||
/** Maximum users allowed in voice channel. 0 = unlimited. */
|
||||
get userLimit(): number;
|
||||
|
||||
computeLurkerPermissionsAllowList(): unknown;
|
||||
getApplicationId(): unknown;
|
||||
/** Computes allowed permissions for lurkers. */
|
||||
computeLurkerPermissionsAllowList(): bigint | undefined;
|
||||
/** Gets the application ID for bot-created channels. */
|
||||
getApplicationId(): string | undefined;
|
||||
/** Gets the default layout for forum channels. */
|
||||
getDefaultLayout(): ForumLayout;
|
||||
/** Gets the default sort order for forum channels. */
|
||||
getDefaultSortOrder(): ForumSortOrder;
|
||||
/** Gets the default tag setting for forum channels. */
|
||||
getDefaultTagSetting(): ForumTagSetting;
|
||||
/** Gets the guild ID this channel belongs to. */
|
||||
getGuildId(): string;
|
||||
getRecipientId(): unknown;
|
||||
/** Gets the recipient user ID for DMs. */
|
||||
getRecipientId(): string | undefined;
|
||||
/** Checks if the channel has a specific flag. */
|
||||
hasFlag(flag: number): boolean;
|
||||
/** Returns a new Channel with the given properties merged. */
|
||||
merge(props: Record<string, unknown>): this;
|
||||
/** Returns a new Channel with the given property set. */
|
||||
set(key: string, value: unknown): this;
|
||||
/** Converts the channel to a plain JavaScript object. */
|
||||
toJS(): Record<string, unknown>;
|
||||
/** Whether this is an active (non-archived) thread. */
|
||||
isActiveThread(): boolean;
|
||||
/** Whether this is an announcement thread. */
|
||||
isAnnouncementThread(): boolean;
|
||||
/** Whether this is an archived and locked thread. */
|
||||
isArchivedLockedThread(): boolean;
|
||||
/** Whether this is an archived thread. */
|
||||
isArchivedThread(): boolean;
|
||||
/** Whether this is a category channel. */
|
||||
isCategory(): boolean;
|
||||
/** Whether this is a DM channel. */
|
||||
isDM(): boolean;
|
||||
/** Whether this is a directory channel. */
|
||||
isDirectory(): boolean;
|
||||
/** Whether this is a forum channel. */
|
||||
isForumChannel(): boolean;
|
||||
/** Whether this is a forum-like channel (forum or media). */
|
||||
isForumLikeChannel(): boolean;
|
||||
/** Whether this is a forum post thread. */
|
||||
isForumPost(): boolean;
|
||||
/** Whether this is a group DM. */
|
||||
isGroupDM(): boolean;
|
||||
/** Whether this is a stage voice channel. */
|
||||
isGuildStageVoice(): boolean;
|
||||
isGuildVoice(): boolean;
|
||||
/** Whether this is a guild voice or stage channel. */
|
||||
isGuildVocal(): boolean;
|
||||
/** Whether this is a guild vocal channel or vocal thread. */
|
||||
isGuildVocalOrThread(): boolean;
|
||||
/** Whether this is a guild voice channel. */
|
||||
isGuildVoice(): boolean;
|
||||
/** Whether this is a guild voice channel or voice thread. */
|
||||
isGuildVoiceOrThread(): boolean;
|
||||
/** Whether this channel supports listen mode. */
|
||||
isListenModeCapable(): boolean;
|
||||
/** Whether this is a locked thread. */
|
||||
isLockedThread(): boolean;
|
||||
/** Whether this channel is managed by an integration. */
|
||||
isManaged(): boolean;
|
||||
/** Whether this is a media channel. */
|
||||
isMediaChannel(): boolean;
|
||||
/** Whether this is a media post thread. */
|
||||
isMediaPost(): boolean;
|
||||
/** Whether this is a moderator report channel. */
|
||||
isModeratorReportChannel(): boolean;
|
||||
/** Whether this is a multi-user DM (group DM). */
|
||||
isMultiUserDM(): boolean;
|
||||
/** Whether the channel is marked as NSFW. */
|
||||
isNSFW(): boolean;
|
||||
isOwner(): boolean;
|
||||
/**
|
||||
* Checks if the given user is the channel owner.
|
||||
* @param userId User ID to check.
|
||||
*/
|
||||
isOwner(userId: string): boolean;
|
||||
/** Whether this is a private channel (DM or group DM). */
|
||||
isPrivate(): boolean;
|
||||
/** Whether this channel supports ringing. */
|
||||
isRingable(): boolean;
|
||||
/** Whether this is a role subscription template preview channel. */
|
||||
isRoleSubscriptionTemplatePreviewChannel(): boolean;
|
||||
/** Whether this channel is scheduled for deletion. */
|
||||
isScheduledForDeletion(): boolean;
|
||||
/** Whether this is a system DM (from Discord). */
|
||||
isSystemDM(): boolean;
|
||||
/** Whether this is any type of thread. */
|
||||
isThread(): boolean;
|
||||
/** Whether this channel supports voice. */
|
||||
isVocal(): boolean;
|
||||
/** Whether this is a vocal thread. */
|
||||
isVocalThread(): boolean;
|
||||
|
||||
/**
|
||||
* Adds a recipient to a group DM.
|
||||
* @param userId User ID to add.
|
||||
* @param nick Optional nickname for the user.
|
||||
* @param currentUserId Current user's ID.
|
||||
*/
|
||||
addRecipient(userId: string, nick?: string | null, currentUserId?: string): this;
|
||||
/**
|
||||
* Removes a recipient from a group DM.
|
||||
* @param userId User ID to remove.
|
||||
*/
|
||||
removeRecipient(userId: string): this;
|
||||
}
|
||||
|
|
|
|||
50
packages/discord-types/src/common/Guild.d.ts
vendored
50
packages/discord-types/src/common/Guild.d.ts
vendored
|
|
@ -1,9 +1,18 @@
|
|||
import { Role } from './Role';
|
||||
import { DiscordRecord } from './Record';
|
||||
import {
|
||||
GuildDefaultMessageNotifications,
|
||||
GuildExplicitContentFilter,
|
||||
GuildMFALevel,
|
||||
GuildNSFWLevel,
|
||||
GuildPremiumTier,
|
||||
GuildVerificationLevel,
|
||||
PermissionOverwriteType,
|
||||
SystemChannelFlags,
|
||||
} from "../../enums";
|
||||
|
||||
// copy(Object.keys(findByProps("CREATOR_MONETIZABLE")).map(JSON.stringify).join("|"))
|
||||
export type GuildFeatures =
|
||||
"INVITE_SPLASH" | "VIP_REGIONS" | "VANITY_URL" | "MORE_EMOJI" | "MORE_STICKERS" | "MORE_SOUNDBOARD" | "VERIFIED" | "COMMERCE" | "DISCOVERABLE" | "COMMUNITY" | "FEATURABLE" | "NEWS" | "HUB" | "PARTNERED" | "ANIMATED_ICON" | "BANNER" | "ENABLED_DISCOVERABLE_BEFORE" | "WELCOME_SCREEN_ENABLED" | "MEMBER_VERIFICATION_GATE_ENABLED" | "PREVIEW_ENABLED" | "ROLE_SUBSCRIPTIONS_ENABLED" | "ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE" | "CREATOR_MONETIZABLE" | "CREATOR_MONETIZABLE_PROVISIONAL" | "CREATOR_MONETIZABLE_WHITEGLOVE" | "CREATOR_MONETIZABLE_DISABLED" | "CREATOR_MONETIZABLE_RESTRICTED" | "CREATOR_STORE_PAGE" | "CREATOR_MONETIZABLE_PENDING_NEW_OWNER_ONBOARDING" | "PRODUCTS_AVAILABLE_FOR_PURCHASE" | "GUILD_WEB_PAGE_VANITY_URL" | "THREADS_ENABLED" | "THREADS_ENABLED_TESTING" | "NEW_THREAD_PERMISSIONS" | "ROLE_ICONS" | "TEXT_IN_STAGE_ENABLED" | "TEXT_IN_VOICE_ENABLED" | "HAS_DIRECTORY_ENTRY" | "ANIMATED_BANNER" | "LINKED_TO_HUB" | "EXPOSED_TO_ACTIVITIES_WTP_EXPERIMENT" | "GUILD_HOME_DEPRECATION_OVERRIDE" | "GUILD_HOME_TEST" | "GUILD_HOME_OVERRIDE" | "GUILD_ONBOARDING" | "GUILD_ONBOARDING_EVER_ENABLED" | "GUILD_ONBOARDING_HAS_PROMPTS" | "GUILD_SERVER_GUIDE" | "INTERNAL_EMPLOYEE_ONLY" | "AUTO_MODERATION" | "INVITES_DISABLED" | "BURST_REACTIONS" | "SOUNDBOARD" | "SHARD" | "ACTIVITY_FEED_ENABLED_BY_USER" | "ACTIVITY_FEED_DISABLED_BY_USER" | "SUMMARIES_ENABLED_GA" | "LEADERBOARD_ENABLED" | "SUMMARIES_ENABLED_BY_USER" | "SUMMARIES_OPT_OUT_EXPERIENCE" | "CHANNEL_ICON_EMOJIS_GENERATED" | "NON_COMMUNITY_RAID_ALERTS" | "RAID_ALERTS_DISABLED" | "AUTOMOD_TRIGGER_USER_PROFILE" | "ENABLED_MODERATION_EXPERIENCE_FOR_NON_COMMUNITY" | "GUILD_PRODUCTS_ALLOW_ARCHIVED_FILE" | "CLAN" | "MEMBER_VERIFICATION_MANUAL_APPROVAL" | "FORWARDING_DISABLED" | "MEMBER_VERIFICATION_ROLLOUT_TEST" | "AUDIO_BITRATE_128_KBPS" | "AUDIO_BITRATE_256_KBPS" | "AUDIO_BITRATE_384_KBPS" | "VIDEO_BITRATE_ENHANCED" | "MAX_FILE_SIZE_50_MB" | "MAX_FILE_SIZE_100_MB" | "GUILD_TAGS" | "ENHANCED_ROLE_COLORS" | "PREMIUM_TIER_3_OVERRIDE" | "REPORT_TO_MOD_PILOT" | "TIERLESS_BOOSTING_SYSTEM_MESSAGE";
|
||||
"ACTIVITY_FEED_DISABLED_BY_USER" | "ACTIVITY_FEED_ENABLED_BY_USER" | "AGE_VERIFICATION_LARGE_GUILD" | "ANIMATED_BANNER" | "ANIMATED_ICON" | "AUDIO_BITRATE_128_KBPS" | "AUDIO_BITRATE_256_KBPS" | "AUDIO_BITRATE_384_KBPS" | "AUTOMOD_TRIGGER_USER_PROFILE" | "AUTO_MODERATION" | "BANNER" | "BURST_REACTIONS" | "BYPASS_SLOWMODE_PERMISSION_MIGRATION_COMPLETE" | "CHANNEL_ICON_EMOJIS_GENERATED" | "CLAN" | "COMMERCE" | "COMMUNITY" | "CREATOR_MONETIZABLE" | "CREATOR_MONETIZABLE_DISABLED" | "CREATOR_MONETIZABLE_PENDING_NEW_OWNER_ONBOARDING" | "CREATOR_MONETIZABLE_PROVISIONAL" | "CREATOR_MONETIZABLE_RESTRICTED" | "CREATOR_MONETIZABLE_WHITEGLOVE" | "CREATOR_STORE_PAGE" | "DISCOVERABLE" | "ENABLED_DISCOVERABLE_BEFORE" | "ENABLED_MODERATION_EXPERIENCE_FOR_NON_COMMUNITY" | "ENHANCED_ROLE_COLORS" | "EXPOSED_TO_ACTIVITIES_WTP_EXPERIMENT" | "FEATURABLE" | "FORWARDING_DISABLED" | "GAME_SERVERS" | "GUILD_HOME_DEPRECATION_OVERRIDE" | "GUILD_HOME_OVERRIDE" | "GUILD_HOME_TEST" | "GUILD_ONBOARDING" | "GUILD_ONBOARDING_EVER_ENABLED" | "GUILD_ONBOARDING_HAS_PROMPTS" | "GUILD_PRODUCTS_ALLOW_ARCHIVED_FILE" | "GUILD_SERVER_GUIDE" | "GUILD_TAGS" | "GUILD_TAGS_BADGE_PACK_FLEX" | "GUILD_TAGS_BADGE_PACK_PETS" | "GUILD_WEB_PAGE_VANITY_URL" | "HAS_DIRECTORY_ENTRY" | "HUB" | "INTERNAL_EMPLOYEE_ONLY" | "INVITES_DISABLED" | "INVITE_SPLASH" | "LINKED_TO_HUB" | "MAX_FILE_SIZE_100_MB" | "MAX_FILE_SIZE_50_MB" | "MEMBER_VERIFICATION_GATE_ENABLED" | "MEMBER_VERIFICATION_MANUAL_APPROVAL" | "MEMBER_VERIFICATION_ROLLOUT_TEST" | "MORE_EMOJI" | "MORE_SOUNDBOARD" | "MORE_STICKERS" | "NEWS" | "NEW_THREAD_PERMISSIONS" | "NON_COMMUNITY_RAID_ALERTS" | "PARTNERED" | "PIN_PERMISSION_MIGRATION_COMPLETE" | "PREMIUM_TIER_3_OVERRIDE" | "PREVIEW_ENABLED" | "PRODUCTS_AVAILABLE_FOR_PURCHASE" | "RAID_ALERTS_DISABLED" | "RELAY_ENABLED" | "REPORT_TO_MOD_PILOT" | "REPORT_TO_MOD_SURVEY" | "ROLE_ICONS" | "ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE" | "ROLE_SUBSCRIPTIONS_ENABLED" | "SOCIAL_LAYER_STOREFRONT" | "SOUNDBOARD" | "SUMMARIES_ENABLED_BY_USER" | "SUMMARIES_ENABLED_GA" | "SUMMARIES_OPT_OUT_EXPERIENCE" | "TEXT_IN_STAGE_ENABLED" | "TEXT_IN_VOICE_ENABLED" | "THREADS_ENABLED" | "THREADS_ENABLED_TESTING" | "TIERLESS_BOOSTING_SYSTEM_MESSAGE" | "VANITY_URL" | "VERIFIED" | "VIDEO_BITRATE_ENHANCED" | "VIP_REGIONS" | "WELCOME_SCREEN_ENABLED";
|
||||
export type GuildPremiumFeatures =
|
||||
"ANIMATED_ICON" | "STAGE_CHANNEL_VIEWERS_150" | "ROLE_ICONS" | "GUILD_TAGS" | "BANNER" | "MAX_FILE_SIZE_50_MB" | "VIDEO_QUALITY_720_60FPS" | "STAGE_CHANNEL_VIEWERS_50" | "VIDEO_QUALITY_1080_60FPS" | "MAX_FILE_SIZE_100_MB" | "VANITY_URL" | "VIDEO_BITRATE_ENHANCED" | "STAGE_CHANNEL_VIEWERS_300" | "AUDIO_BITRATE_128_KBPS" | "ANIMATED_BANNER" | "TIERLESS_BOOSTING" | "ENHANCED_ROLE_COLORS" | "INVITE_SPLASH" | "AUDIO_BITRATE_256_KBPS" | "AUDIO_BITRATE_384_KBPS";
|
||||
|
||||
|
|
@ -11,20 +20,15 @@ export class Guild extends DiscordRecord {
|
|||
constructor(guild: object);
|
||||
afkChannelId: string | undefined;
|
||||
afkTimeout: number;
|
||||
applicationCommandCounts: {
|
||||
0: number;
|
||||
1: number;
|
||||
2: number;
|
||||
};
|
||||
application_id: unknown;
|
||||
application_id: string | null;
|
||||
banner: string | undefined;
|
||||
defaultMessageNotifications: number;
|
||||
defaultMessageNotifications: GuildDefaultMessageNotifications;
|
||||
description: string | undefined;
|
||||
discoverySplash: string | undefined;
|
||||
explicitContentFilter: number;
|
||||
explicitContentFilter: GuildExplicitContentFilter;
|
||||
features: Set<GuildFeatures>;
|
||||
homeHeader: string | undefined;
|
||||
hubType: unknown;
|
||||
hubType: number | null;
|
||||
icon: string | undefined;
|
||||
id: string;
|
||||
joinedAt: Date;
|
||||
|
|
@ -32,10 +36,13 @@ export class Guild extends DiscordRecord {
|
|||
maxMembers: number;
|
||||
maxStageVideoChannelUsers: number;
|
||||
maxVideoChannelUsers: number;
|
||||
mfaLevel: number;
|
||||
moderatorReporting: unknown;
|
||||
mfaLevel: GuildMFALevel;
|
||||
moderatorReporting: {
|
||||
moderatorReportingEnabled: boolean;
|
||||
moderatorReportChannelId: string;
|
||||
} | null;
|
||||
name: string;
|
||||
nsfwLevel: number;
|
||||
nsfwLevel: GuildNSFWLevel;
|
||||
ownerConfiguredContentLevel: number;
|
||||
ownerId: string;
|
||||
preferredLocale: string;
|
||||
|
|
@ -47,18 +54,25 @@ export class Guild extends DiscordRecord {
|
|||
};
|
||||
premiumProgressBarEnabled: boolean;
|
||||
premiumSubscriberCount: number;
|
||||
premiumTier: 0 | 1 | 2 | 3;
|
||||
premiumTier: GuildPremiumTier;
|
||||
profile: {
|
||||
badge: string | undefined;
|
||||
tag: string | undefined;
|
||||
} | undefined;
|
||||
publicUpdatesChannelId: string | undefined;
|
||||
roles: Record<string, Role>;
|
||||
rulesChannelId: string | undefined;
|
||||
safetyAlertsChannelId: string | undefined;
|
||||
splash: string | undefined;
|
||||
systemChannelFlags: number;
|
||||
systemChannelFlags: SystemChannelFlags;
|
||||
systemChannelId: string | undefined;
|
||||
vanityURLCode: string | undefined;
|
||||
verificationLevel: number;
|
||||
verificationLevel: GuildVerificationLevel;
|
||||
}
|
||||
|
||||
export interface RoleOrUserPermission {
|
||||
type: PermissionOverwriteType;
|
||||
id?: string;
|
||||
permissions?: bigint;
|
||||
overwriteAllow?: bigint;
|
||||
overwriteDeny?: bigint;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,30 @@
|
|||
import { GuildMemberFlags } from "../../enums";
|
||||
import { Collectibles, DisplayNameStyles } from "./Channel";
|
||||
|
||||
export interface GuildMember {
|
||||
avatar: string | undefined;
|
||||
avatarDecoration: string | undefined;
|
||||
banner: string | undefined;
|
||||
bio: string;
|
||||
avatar: string | null | undefined;
|
||||
avatarDecoration: string | null | undefined;
|
||||
collectibles: Collectibles | null;
|
||||
colorRoleId: string | undefined;
|
||||
colorString: string;
|
||||
colorString: string | undefined;
|
||||
colorStrings: {
|
||||
primaryColor: string | undefined;
|
||||
secondaryColor: string | undefined;
|
||||
tertiaryColor: string | undefined;
|
||||
};
|
||||
communicationDisabledUntil: string | undefined;
|
||||
flags: number;
|
||||
fullProfileLoadedTimestamp: number;
|
||||
} | null;
|
||||
communicationDisabledUntil: string | null | undefined;
|
||||
displayNameStyles: DisplayNameStyles | null;
|
||||
flags: GuildMemberFlags;
|
||||
fullProfileLoadedTimestamp: number | undefined;
|
||||
guildId: string;
|
||||
highestRoleId: string;
|
||||
hoistRoleId: string;
|
||||
iconRoleId: string;
|
||||
highestRoleId: string | undefined;
|
||||
hoistRoleId: string | undefined;
|
||||
iconRoleId: string | undefined;
|
||||
isPending: boolean | undefined;
|
||||
joinedAt: string | undefined;
|
||||
nick: string | undefined;
|
||||
premiumSince: string | undefined;
|
||||
nick: string | null | undefined;
|
||||
premiumSince: string | null | undefined;
|
||||
roles: string[];
|
||||
unusualDMActivityUntil: string | undefined;
|
||||
userId: string;
|
||||
}
|
||||
|
|
|
|||
24
packages/discord-types/src/common/Role.d.ts
vendored
24
packages/discord-types/src/common/Role.d.ts
vendored
|
|
@ -1,3 +1,5 @@
|
|||
import { RoleFlags } from "../../enums";
|
||||
|
||||
export interface Role {
|
||||
color: number;
|
||||
colorString: string | undefined;
|
||||
|
|
@ -11,23 +13,25 @@ export interface Role {
|
|||
secondary_color: number | undefined;
|
||||
tertiary_color: number | undefined;
|
||||
};
|
||||
flags: number;
|
||||
description: string | null;
|
||||
flags: RoleFlags;
|
||||
guildId: string;
|
||||
hoist: boolean;
|
||||
icon: string | undefined;
|
||||
icon: string | null;
|
||||
id: string;
|
||||
managed: boolean;
|
||||
mentionable: boolean;
|
||||
name: string;
|
||||
originalPosition: number;
|
||||
permissions: bigint;
|
||||
position: number;
|
||||
/**
|
||||
* probably incomplete
|
||||
*/
|
||||
tags: {
|
||||
bot_id: string;
|
||||
integration_id: string;
|
||||
premium_subscriber: unknown;
|
||||
bot_id?: string;
|
||||
integration_id?: string;
|
||||
premium_subscriber?: null;
|
||||
subscription_listing_id?: string;
|
||||
available_for_purchase?: null;
|
||||
guild_connections?: null;
|
||||
} | undefined;
|
||||
unicodeEmoji: string | undefined;
|
||||
unicodeEmoji: string | null;
|
||||
version: number | undefined;
|
||||
}
|
||||
|
|
|
|||
53
packages/discord-types/src/common/User.d.ts
vendored
53
packages/discord-types/src/common/User.d.ts
vendored
|
|
@ -1,66 +1,85 @@
|
|||
// TODO: a lot of optional params can also be null, not just undef
|
||||
|
||||
import { DiscordRecord } from "./Record";
|
||||
import { AvatarDecorationData, ClanData, Collectibles, DisplayNameStyles } from "./Channel";
|
||||
import { PremiumType, UserFlags } from "../../enums";
|
||||
|
||||
export class User extends DiscordRecord {
|
||||
constructor(user: object);
|
||||
accentColor: number;
|
||||
ageVerificationStatus: number;
|
||||
avatar: string;
|
||||
avatarDecorationData: AvatarDecorationData | null;
|
||||
banner: string | null | undefined;
|
||||
bio: string;
|
||||
bot: boolean;
|
||||
collectibles: Collectibles | null;
|
||||
desktop: boolean;
|
||||
discriminator: string;
|
||||
displayNameStyles: DisplayNameStyles | null;
|
||||
email: string | undefined;
|
||||
flags: number;
|
||||
flags: UserFlags;
|
||||
globalName: string | undefined;
|
||||
guildMemberAvatars: Record<string, string>;
|
||||
hasBouncedEmail: boolean;
|
||||
id: string;
|
||||
mfaEnabled: boolean;
|
||||
mobile: boolean;
|
||||
nsfwAllowed: boolean | undefined;
|
||||
personalConnectionId: string | null;
|
||||
phone: string | undefined;
|
||||
premiumType: number | undefined;
|
||||
premiumState: { subscriptionId: string; } | null;
|
||||
premiumType: PremiumType | undefined;
|
||||
premiumUsageFlags: number;
|
||||
publicFlags: number;
|
||||
primaryGuild: ClanData | null;
|
||||
publicFlags: UserFlags;
|
||||
purchasedFlags: number;
|
||||
system: boolean;
|
||||
username: string;
|
||||
verified: boolean;
|
||||
|
||||
get avatarDecoration(): AvatarDecorationData | null;
|
||||
get createdAt(): Date;
|
||||
get hasPremiumPerks(): boolean;
|
||||
get isProvisional(): boolean;
|
||||
get nameplate(): { asset: string; sku_id: string; } | null;
|
||||
get premiumGroupRole(): { id: string; name: string; color: number; } | null;
|
||||
get tag(): string;
|
||||
get usernameNormalized(): string;
|
||||
|
||||
addGuildAvatarHash(guildId: string, avatarHash: string): User;
|
||||
getAvatarSource(guildId: string, canAnimate?: boolean): { uri: string; };
|
||||
getAvatarURL(guildId?: string | null, t?: unknown, canAnimate?: boolean): string;
|
||||
addGuildAvatarHash(guildId: string, avatarHash: string): this;
|
||||
getAvatarSource(guildId: string): { uri: string; };
|
||||
getAvatarURL(guildId?: string | null, size?: number, canAnimate?: boolean, format?: string): string;
|
||||
hadPremiumSubscription(): boolean;
|
||||
hasAvatarForGuild(guildId: string): boolean;
|
||||
hasDisabledPremium(): boolean;
|
||||
hasFlag(flag: number): boolean;
|
||||
hasFlag(flag: UserFlags): boolean;
|
||||
hasFreePremium(): boolean;
|
||||
hasHadSKU(e: unknown): boolean;
|
||||
hasHadPremium(): boolean;
|
||||
hasHadSKU(sku: string): boolean;
|
||||
hasPremiumUsageFlag(flag: number): boolean;
|
||||
hasPurchasedFlag(flag: number): boolean;
|
||||
hasUniqueUsername(): boolean;
|
||||
hasUrgentMessages(): boolean;
|
||||
hasVerifiedEmailOrPhone(): boolean;
|
||||
isClaimed(): boolean;
|
||||
isFractionalPremiumWithNoSubscription(): boolean;
|
||||
isLocalBot(): boolean;
|
||||
isNonUserBot(): boolean;
|
||||
isPhoneVerified(): boolean;
|
||||
isStaff(): boolean;
|
||||
isPremiumGroupMember(): boolean;
|
||||
isPremiumGroupPrimary(): boolean;
|
||||
isPremiumWithFractionalPremiumOnly(): boolean;
|
||||
isPremiumWithPremiumGroup(): boolean;
|
||||
isSystemUser(): boolean;
|
||||
isVerifiedBot(): boolean;
|
||||
removeGuildAvatarHash(guildId: string): User;
|
||||
removeGuildAvatarHash(guildId: string): this;
|
||||
toJS(): object;
|
||||
toString(): string;
|
||||
update(props: Partial<User>): this;
|
||||
}
|
||||
|
||||
export interface UserJSON {
|
||||
avatar: string;
|
||||
avatarDecoration: unknown | undefined;
|
||||
avatarDecoration: AvatarDecorationData | null;
|
||||
discriminator: string;
|
||||
id: string;
|
||||
publicFlags: number;
|
||||
publicFlags: UserFlags;
|
||||
username: string;
|
||||
globalName: string | undefined;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,41 +1,74 @@
|
|||
export type EmbedType =
|
||||
| "image"
|
||||
| "video"
|
||||
| "link"
|
||||
| "article"
|
||||
| "tweet"
|
||||
| "rich"
|
||||
| "gifv"
|
||||
| "application_news"
|
||||
| "auto_moderation_message"
|
||||
| "auto_moderation_notification"
|
||||
| "text"
|
||||
| "post_preview"
|
||||
| "gift"
|
||||
| "safety_policy_notice"
|
||||
| "safety_system_notification"
|
||||
| "age_verification_system_notification"
|
||||
| "voice_channel"
|
||||
| "gaming_profile"
|
||||
| "poll_result";
|
||||
|
||||
export interface EmbedMedia {
|
||||
height: number;
|
||||
width: number;
|
||||
url: string;
|
||||
proxyURL: string;
|
||||
placeholder: string;
|
||||
placeholderVersion: number;
|
||||
description: string;
|
||||
srcIsAnimated: boolean;
|
||||
flags: number;
|
||||
contentType: string;
|
||||
}
|
||||
|
||||
export interface EmbedField {
|
||||
rawName: string;
|
||||
rawValue: string;
|
||||
inline: boolean;
|
||||
}
|
||||
|
||||
export interface Embed {
|
||||
id: string;
|
||||
url: string;
|
||||
type: EmbedType;
|
||||
rawTitle: string;
|
||||
rawDescription: string;
|
||||
referenceId: string | undefined;
|
||||
flags: number | undefined;
|
||||
contentScanVersion: number;
|
||||
author?: {
|
||||
name: string;
|
||||
url: string;
|
||||
iconURL: string | undefined;
|
||||
iconProxyURL: string | undefined;
|
||||
};
|
||||
color: string;
|
||||
fields: [];
|
||||
id: string;
|
||||
image?: {
|
||||
height: number;
|
||||
width: number;
|
||||
url: string;
|
||||
proxyURL: string;
|
||||
footer?: {
|
||||
text: string;
|
||||
iconURL: string | undefined;
|
||||
iconProxyURL: string | undefined;
|
||||
};
|
||||
provider?: {
|
||||
name: string;
|
||||
url: string | undefined;
|
||||
};
|
||||
rawDescription: string;
|
||||
rawTitle: string;
|
||||
referenceId: unknown;
|
||||
timestamp: string;
|
||||
thumbnail?: {
|
||||
height: number;
|
||||
proxyURL: string | undefined;
|
||||
url: string;
|
||||
width: number;
|
||||
};
|
||||
type: string;
|
||||
url: string | undefined;
|
||||
video?: {
|
||||
height: number;
|
||||
width: number;
|
||||
url: string;
|
||||
proxyURL: string | undefined;
|
||||
};
|
||||
timestamp?: Date;
|
||||
color: string;
|
||||
thumbnail?: EmbedMedia;
|
||||
image?: EmbedMedia;
|
||||
images?: EmbedMedia[];
|
||||
video?: EmbedMedia;
|
||||
fields: EmbedField[];
|
||||
}
|
||||
|
||||
export interface EmbedJSON {
|
||||
|
|
@ -48,7 +81,7 @@ export interface EmbedJSON {
|
|||
title: string;
|
||||
color: string;
|
||||
description: string;
|
||||
type: string;
|
||||
type: EmbedType;
|
||||
url: string | undefined;
|
||||
provider?: {
|
||||
name: string;
|
||||
|
|
|
|||
|
|
@ -1,42 +1,114 @@
|
|||
/** Union type for both custom (guild) emojis and unicode emojis. */
|
||||
export type Emoji = CustomEmoji | UnicodeEmoji;
|
||||
|
||||
/**
|
||||
* Custom emoji uploaded to a guild.
|
||||
*/
|
||||
export interface CustomEmoji {
|
||||
/** Discriminator for custom emojis. */
|
||||
type: 1;
|
||||
allNamesString: string;
|
||||
/** Whether the emoji is animated (GIF). */
|
||||
animated: boolean;
|
||||
/** Whether the emoji is available for use. */
|
||||
available: boolean;
|
||||
/** Guild id this emoji belongs to. */
|
||||
guildId: string;
|
||||
/** Unique emoji id (snowflake). */
|
||||
id: string;
|
||||
/** Whether the emoji is managed by an integration (e.g. Twitch). */
|
||||
managed: boolean;
|
||||
/** Emoji name without colons. */
|
||||
name: string;
|
||||
/** Original name before any modifications. */
|
||||
originalName?: string;
|
||||
/** Whether the emoji requires colons to use. */
|
||||
require_colons: boolean;
|
||||
/** Role ids that can use this emoji (empty array means everyone). */
|
||||
roles: string[];
|
||||
/** Version number, incremented when emoji is updated. */
|
||||
version?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Built-in unicode emoji.
|
||||
*/
|
||||
export interface UnicodeEmoji {
|
||||
/** Discriminator for unicode emojis. */
|
||||
type: 0;
|
||||
diversityChildren: Record<any, any>;
|
||||
emojiObject: {
|
||||
names: string[];
|
||||
surrogates: string;
|
||||
unicodeVersion: number;
|
||||
};
|
||||
/** Skin tone variant emojis keyed by diversity surrogate code (e.g. "1f3fb" for light skin). */
|
||||
diversityChildren: Record<string, UnicodeEmoji>;
|
||||
/** Raw emoji data from Discord's emoji dataset. */
|
||||
emojiObject: EmojiObject;
|
||||
/** Index position in the emoji list. */
|
||||
index: number;
|
||||
/** Unicode surrogate pair(s) for this emoji. */
|
||||
surrogates: string;
|
||||
/** Unique name identifier for this emoji. */
|
||||
uniqueName: string;
|
||||
/** Whether to render using sprite sheet. */
|
||||
useSpriteSheet: boolean;
|
||||
/** Original name if renamed in context. */
|
||||
originalName?: string;
|
||||
/** Emoji id when used in custom emoji context. */
|
||||
id?: string;
|
||||
/** Guild id when used in guild context. */
|
||||
guildId?: string;
|
||||
/** Formatted string of all emoji names. */
|
||||
get allNamesString(): string;
|
||||
get animated(): boolean;
|
||||
get defaultDiversityChild(): any;
|
||||
/** Always false for unicode emojis. */
|
||||
get animated(): false;
|
||||
/** Default skin tone variant or undefined if no diversity. */
|
||||
get defaultDiversityChild(): UnicodeEmoji | undefined;
|
||||
/** Whether this emoji supports skin tone modifiers. */
|
||||
get hasDiversity(): boolean | undefined;
|
||||
/** Whether this emoji is a skin tone variant of another. */
|
||||
get hasDiversityParent(): boolean | undefined;
|
||||
/** Whether this emoji supports multiple diversity modifiers (e.g. handshake with two skin tones). */
|
||||
get hasMultiDiversity(): boolean | undefined;
|
||||
/** Whether this emoji is a multi-diversity variant of another. */
|
||||
get hasMultiDiversityParent(): boolean | undefined;
|
||||
get managed(): boolean;
|
||||
/** Always true for unicode emojis. */
|
||||
get managed(): true;
|
||||
/** Primary emoji name. */
|
||||
get name(): string;
|
||||
/** All names/aliases for this emoji. */
|
||||
get names(): string[];
|
||||
/** Surrogate sequence with optional diversity modifier. */
|
||||
get optionallyDiverseSequence(): string | undefined;
|
||||
/** Unicode version when this emoji was added. */
|
||||
get unicodeVersion(): number;
|
||||
/** CDN url for emoji image. */
|
||||
get url(): string;
|
||||
/**
|
||||
* Iterates over all diversity variants of this emoji.
|
||||
* @param callback Function called for each diversity variant.
|
||||
*/
|
||||
forEachDiversity(callback: (emoji: UnicodeEmoji) => void): void;
|
||||
/**
|
||||
* Iterates over all names/aliases of this emoji.
|
||||
* @param callback Function called for each name.
|
||||
*/
|
||||
forEachName(callback: (name: string) => void): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw emoji data from Discord's emoji dataset.
|
||||
*/
|
||||
export interface EmojiObject {
|
||||
/** All names/aliases for this emoji. */
|
||||
names: string[];
|
||||
/** Unicode surrogate pair(s). */
|
||||
surrogates: string;
|
||||
/** Unicode version when this emoji was added. */
|
||||
unicodeVersion: number;
|
||||
/** Index in the sprite sheet for rendering. */
|
||||
spriteIndex?: number;
|
||||
/** Whether this emoji supports multiple skin tone modifiers. */
|
||||
hasMultiDiversity?: boolean;
|
||||
/** Whether this emoji is a diversity variant with a multi-diversity parent. */
|
||||
hasMultiDiversityParent?: boolean;
|
||||
/** Skin tone modifier codes for this variant (e.g. ["1f3fb"] or ["1f3fb", "1f3fc"]). */
|
||||
diversity?: string[];
|
||||
/** Sprite indices of diversity children for parent emojis. */
|
||||
diversityChildren?: number[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,60 +2,135 @@ import { CommandOption } from './Commands';
|
|||
import { User, UserJSON } from '../User';
|
||||
import { Embed, EmbedJSON } from './Embed';
|
||||
import { DiscordRecord } from "../Record";
|
||||
import { MessageFlags, MessageType, StickerFormatType } from "../../../enums";
|
||||
import { ApplicationCommandOptionType, ApplicationCommandType, ApplicationIntegrationType, ButtonStyle, ComponentType, InteractionType, MessageActivityType, MessageFlags, MessageReferenceType, MessageType, PollLayoutType, StickerFormatType } from "../../../enums";
|
||||
|
||||
export type MessageState = "SENT" | "SENDING" | "SEND_FAILED";
|
||||
|
||||
export type CodedLinkType =
|
||||
| "INVITE"
|
||||
| "TEMPLATE"
|
||||
| "BUILD_OVERRIDE"
|
||||
| "MANUAL_BUILD_OVERRIDE"
|
||||
| "EXPERIMENT"
|
||||
| "EVENT"
|
||||
| "CHANNEL_LINK"
|
||||
| "APP_DIRECTORY_PROFILE"
|
||||
| "APP_DIRECTORY_STOREFRONT"
|
||||
| "APP_DIRECTORY_STOREFRONT_SKU"
|
||||
| "APP_OAUTH2_LINK"
|
||||
| "ACTIVITY_BOOKMARK"
|
||||
| "EMBEDDED_ACTIVITY_INVITE"
|
||||
| "GUILD_PRODUCT"
|
||||
| "SERVER_SHOP"
|
||||
| "SOCIAL_LAYER_STOREFRONT"
|
||||
| "QUESTS_EMBED"
|
||||
| "COLLECTIBLES_SHOP";
|
||||
|
||||
export interface MessageActivity {
|
||||
type: MessageActivityType;
|
||||
party_id?: string;
|
||||
}
|
||||
|
||||
export interface PollMedia {
|
||||
text?: string;
|
||||
emoji?: ReactionEmoji;
|
||||
}
|
||||
|
||||
export interface PollAnswer {
|
||||
answer_id: number;
|
||||
poll_media: PollMedia;
|
||||
}
|
||||
|
||||
export interface Poll {
|
||||
question: PollMedia;
|
||||
answers: PollAnswer[];
|
||||
expiry: string;
|
||||
allow_multiselect: boolean;
|
||||
layout_type: PollLayoutType;
|
||||
}
|
||||
|
||||
export interface RoleSubscriptionData {
|
||||
role_subscription_listing_id: string;
|
||||
tier_name: string;
|
||||
total_months_subscribed: number;
|
||||
is_renewal: boolean;
|
||||
}
|
||||
|
||||
export interface MessageComponent {
|
||||
type: ComponentType;
|
||||
id?: string;
|
||||
custom_id?: string;
|
||||
disabled?: boolean;
|
||||
style?: ButtonStyle;
|
||||
label?: string;
|
||||
emoji?: ReactionEmoji;
|
||||
url?: string;
|
||||
options?: { label: string; value: string; description?: string; emoji?: ReactionEmoji; default?: boolean; }[];
|
||||
placeholder?: string;
|
||||
min_values?: number;
|
||||
max_values?: number;
|
||||
components?: MessageComponent[];
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: looks like discord has moved over to Date instead of Moment;
|
||||
*/
|
||||
export class Message extends DiscordRecord {
|
||||
constructor(message: object);
|
||||
activity: unknown;
|
||||
application: unknown;
|
||||
applicationId: string | unknown;
|
||||
activity: MessageActivity | null;
|
||||
activityInstance: { applicationId: string; instanceId: string; } | null;
|
||||
application: { id: string; name: string; icon: string | null; } | null;
|
||||
applicationId: string | null;
|
||||
attachments: MessageAttachment[];
|
||||
author: User;
|
||||
blocked: boolean;
|
||||
bot: boolean;
|
||||
call: {
|
||||
duration: moment.Duration;
|
||||
endedTimestamp: moment.Moment;
|
||||
duration: number | null;
|
||||
endedTimestamp: Date | null;
|
||||
participants: string[];
|
||||
};
|
||||
} | null;
|
||||
changelogId: string | null;
|
||||
channel_id: string;
|
||||
/**
|
||||
* NOTE: not fully typed
|
||||
*/
|
||||
codedLinks: {
|
||||
code?: string;
|
||||
type: string;
|
||||
type: CodedLinkType;
|
||||
}[];
|
||||
colorString: unknown;
|
||||
components: unknown[];
|
||||
colorString: string | null;
|
||||
components: MessageComponent[];
|
||||
content: string;
|
||||
customRenderedContent: unknown;
|
||||
editedTimestamp: Date;
|
||||
customRenderedContent: {
|
||||
content: React.ReactNode;
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
editedTimestamp: Date | null;
|
||||
embeds: Embed[];
|
||||
flags: MessageFlags;
|
||||
giftCodes: string[];
|
||||
giftInfo: { sku_id: string; slug: string; } | null;
|
||||
giftingPrompt: { recipientUserId: string; } | null;
|
||||
id: string;
|
||||
interaction: {
|
||||
id: string;
|
||||
name: string;
|
||||
type: number;
|
||||
type: InteractionType;
|
||||
user: User;
|
||||
}[] | undefined;
|
||||
}[] | null;
|
||||
interactionData: {
|
||||
application_command: {
|
||||
application_id: string;
|
||||
default_member_permissions: unknown;
|
||||
default_member_permissions: string | null;
|
||||
default_permission: boolean;
|
||||
description: string;
|
||||
dm_permission: unknown;
|
||||
dm_permission: boolean | null;
|
||||
id: string;
|
||||
name: string;
|
||||
options: CommandOption[];
|
||||
permissions: unknown[];
|
||||
type: number;
|
||||
permissions: string[];
|
||||
type: ApplicationCommandType;
|
||||
version: string;
|
||||
};
|
||||
attachments: MessageAttachment[];
|
||||
|
|
@ -63,23 +138,40 @@ export class Message extends DiscordRecord {
|
|||
id: string;
|
||||
name: string;
|
||||
options: {
|
||||
focused: unknown;
|
||||
focused: boolean | undefined;
|
||||
name: string;
|
||||
type: number;
|
||||
type: ApplicationCommandOptionType;
|
||||
value: string;
|
||||
}[];
|
||||
type: number;
|
||||
type: InteractionType;
|
||||
version: string;
|
||||
}[];
|
||||
interactionError: unknown[];
|
||||
}[] | null;
|
||||
interactionMetadata: {
|
||||
id: string;
|
||||
type: InteractionType;
|
||||
name?: string;
|
||||
command_type?: ApplicationCommandType;
|
||||
ephemerality_reason?: number;
|
||||
user: User;
|
||||
authorizing_integration_owners: Record<ApplicationIntegrationType, string>;
|
||||
original_response_message_id?: string;
|
||||
interacted_message_id?: string;
|
||||
target_user?: User;
|
||||
target_message_id?: string;
|
||||
} | null;
|
||||
interactionError: string[] | null;
|
||||
ignored: boolean;
|
||||
isSearchHit: boolean;
|
||||
loggingName: unknown;
|
||||
isUnsupported: boolean;
|
||||
loggingName: string | null;
|
||||
mentionChannels: string[];
|
||||
mentionEveryone: boolean;
|
||||
mentionGames: { id: string; name: string; }[];
|
||||
mentionRoles: string[];
|
||||
mentioned: boolean;
|
||||
mentions: string[];
|
||||
messageReference: {
|
||||
type?: MessageReferenceType;
|
||||
guild_id?: string;
|
||||
channel_id: string;
|
||||
message_id: string;
|
||||
|
|
@ -87,18 +179,26 @@ export class Message extends DiscordRecord {
|
|||
messageSnapshots: {
|
||||
message: Message;
|
||||
}[];
|
||||
nick: unknown; // probably a string
|
||||
nick: string | null;
|
||||
nonce: string | undefined;
|
||||
pinned: boolean;
|
||||
poll: Poll | null;
|
||||
potions: { id: string; expiresAt: string; }[];
|
||||
premiumGroupInviteId: string | null;
|
||||
purchaseNotification: { type: number; guild_product_purchase?: { product_name: string; }; } | null;
|
||||
reactions: MessageReaction[];
|
||||
state: string;
|
||||
referralTrialOfferId: string | null;
|
||||
roleSubscriptionData: RoleSubscriptionData | null;
|
||||
sharedClientTheme: { primary_color: number; secondary_color: number; } | null;
|
||||
soundboardSounds: { sound_id: string; volume: number; emoji_id?: string; emoji_name?: string; }[];
|
||||
state: MessageState;
|
||||
stickerItems: {
|
||||
format_type: StickerFormatType;
|
||||
id: string;
|
||||
name: string;
|
||||
}[];
|
||||
stickers: unknown[];
|
||||
timestamp: moment.Moment;
|
||||
stickers: { id: string; name: string; format_type: StickerFormatType; }[];
|
||||
timestamp: Date;
|
||||
tts: boolean;
|
||||
type: MessageType;
|
||||
webhookId: string | undefined;
|
||||
|
|
@ -121,10 +221,18 @@ export class Message extends DiscordRecord {
|
|||
removeReaction(emoji: ReactionEmoji, fromCurrentUser: boolean): Message;
|
||||
|
||||
getChannelId(): string;
|
||||
getContentMessage(): Message;
|
||||
hasFlag(flag: MessageFlags): boolean;
|
||||
hasPotions(): boolean;
|
||||
isCommandType(): boolean;
|
||||
isEdited(): boolean;
|
||||
isFirstMessageInForumPost(channel: unknown): boolean;
|
||||
isInteractionPlaceholder(): boolean;
|
||||
isPoll(): boolean;
|
||||
isSystemDM(): boolean;
|
||||
canDeleteOwnMessage(userId: string): boolean;
|
||||
userHasReactedWithEmoji(emoji: ReactionEmoji, burst?: boolean): boolean;
|
||||
addReactionBatch(reactions: { emoji: ReactionEmoji; users: string[]; }[], burstReactions: { emoji: ReactionEmoji; users: string[]; }[]): Message;
|
||||
|
||||
/** Vencord added */
|
||||
deleted?: boolean;
|
||||
|
|
@ -135,14 +243,14 @@ export interface MessageJSON {
|
|||
attachments: MessageAttachment[];
|
||||
author: UserJSON;
|
||||
channel_id: string;
|
||||
components: unknown[];
|
||||
components: MessageComponent[];
|
||||
content: string;
|
||||
edited_timestamp: string;
|
||||
embeds: EmbedJSON[];
|
||||
flags: number;
|
||||
flags: MessageFlags;
|
||||
guild_id: string | undefined;
|
||||
id: string;
|
||||
loggingName: unknown;
|
||||
loggingName: string | null;
|
||||
member: {
|
||||
avatar: string | undefined;
|
||||
communication_disabled_until: string | undefined;
|
||||
|
|
@ -167,10 +275,10 @@ export interface MessageJSON {
|
|||
nonce: string | undefined;
|
||||
pinned: boolean;
|
||||
referenced_message: MessageJSON | undefined;
|
||||
state: string;
|
||||
state: MessageState;
|
||||
timestamp: string;
|
||||
tts: boolean;
|
||||
type: number;
|
||||
type: MessageType;
|
||||
}
|
||||
|
||||
export interface MessageAttachment {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { StickerFormatType, StickerType } from "../../../enums";
|
||||
|
||||
interface BaseSticker {
|
||||
asset: string;
|
||||
asset?: string;
|
||||
available: boolean;
|
||||
description: string;
|
||||
format_type: StickerFormatType;
|
||||
|
|
|
|||
34
packages/discord-types/src/components.d.ts
vendored
34
packages/discord-types/src/components.d.ts
vendored
|
|
@ -36,17 +36,19 @@ export type Button = ComponentType<ButtonProps> & {
|
|||
|
||||
// #endregion
|
||||
|
||||
export type Tooltip = ComponentType<{
|
||||
export interface TooltipChildrenProps {
|
||||
onClick(): void;
|
||||
onMouseEnter(): void;
|
||||
onMouseLeave(): void;
|
||||
onContextMenu(): void;
|
||||
onFocus(): void;
|
||||
onBlur(): void;
|
||||
"aria-label"?: string;
|
||||
}
|
||||
|
||||
export interface TooltipProps {
|
||||
text: ReactNode | ComponentType;
|
||||
children: FunctionComponent<{
|
||||
onClick(): void;
|
||||
onMouseEnter(): void;
|
||||
onMouseLeave(): void;
|
||||
onContextMenu(): void;
|
||||
onFocus(): void;
|
||||
onBlur(): void;
|
||||
"aria-label"?: string;
|
||||
}>;
|
||||
children: FunctionComponent<TooltipChildrenProps>;
|
||||
"aria-label"?: string;
|
||||
|
||||
allowOverflow?: boolean;
|
||||
|
|
@ -63,7 +65,9 @@ export type Tooltip = ComponentType<{
|
|||
|
||||
tooltipClassName?: string;
|
||||
tooltipContentClassName?: string;
|
||||
}> & {
|
||||
}
|
||||
|
||||
export type Tooltip = ComponentType<TooltipProps> & {
|
||||
Colors: Record<"BLACK" | "BRAND" | "CUSTOM" | "GREEN" | "GREY" | "PRIMARY" | "RED" | "YELLOW", string>;
|
||||
};
|
||||
|
||||
|
|
@ -318,14 +322,6 @@ export type Slider = ComponentClass<PropsWithChildren<{
|
|||
"aria-describedby"?: string;
|
||||
}>>;
|
||||
|
||||
// TODO - type maybe idk probably not that useful other than the constants
|
||||
export type Flex = ComponentType<PropsWithChildren<any>> & {
|
||||
Align: Record<"START" | "END" | "CENTER" | "STRETCH" | "BASELINE", string>;
|
||||
Direction: Record<"VERTICAL" | "HORIZONTAL" | "HORIZONTAL_REVERSE", string>;
|
||||
Justify: Record<"START" | "END" | "CENTER" | "BETWEEN" | "AROUND", string>;
|
||||
Wrap: Record<"NO_WRAP" | "WRAP" | "WRAP_REVERSE", string>;
|
||||
};
|
||||
|
||||
declare enum PopoutAnimation {
|
||||
NONE = "1",
|
||||
TRANSLATE = "2",
|
||||
|
|
|
|||
|
|
@ -4,17 +4,20 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { GuildMemberFlags } from "../enums";
|
||||
import { VoiceState } from "./stores";
|
||||
|
||||
export type PassiveUpdateType = "PASSIVE_UPDATE_V2";
|
||||
|
||||
export interface PassiveUpdateState {
|
||||
type: string;
|
||||
type: PassiveUpdateType;
|
||||
guildId: string;
|
||||
members?: ({
|
||||
user: {
|
||||
avatar: null | string;
|
||||
communication_disabled_until: null | string;
|
||||
deaf: boolean;
|
||||
flags: number;
|
||||
flags: GuildMemberFlags;
|
||||
joined_at: string;
|
||||
mute: boolean;
|
||||
nick: string;
|
||||
|
|
@ -27,7 +30,7 @@ export interface PassiveUpdateState {
|
|||
nick: string | null;
|
||||
mute: boolean;
|
||||
joined_at: string;
|
||||
flags: number;
|
||||
flags: GuildMemberFlags;
|
||||
deaf: boolean;
|
||||
communication_disabled_until: null | string;
|
||||
avatar: null | string;
|
||||
|
|
|
|||
74
packages/discord-types/src/stores/AccessibilityStore.d.ts
vendored
Normal file
74
packages/discord-types/src/stores/AccessibilityStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import { FluxStore } from "..";
|
||||
|
||||
export type ReducedMotionPreference = "auto" | "reduce" | "no-preference";
|
||||
export type ForcedColorsPreference = "none" | "active";
|
||||
export type ContrastPreference = "no-preference" | "more" | "less" | "custom";
|
||||
export type RoleStyle = "username" | "dot" | "hidden";
|
||||
export type ContrastMode = "default" | "high";
|
||||
|
||||
export interface AccessibilityState {
|
||||
fontSize: number;
|
||||
zoom: number;
|
||||
keyboardModeEnabled: boolean;
|
||||
contrastMode: ContrastMode;
|
||||
colorblindMode: boolean;
|
||||
lowContrastMode: boolean;
|
||||
saturation: number;
|
||||
contrast: number;
|
||||
desaturateUserColors: boolean;
|
||||
forcedColorsModalSeen: boolean;
|
||||
keyboardNavigationExplainerModalSeen: boolean;
|
||||
messageGroupSpacing: number | null;
|
||||
systemPrefersReducedMotion: ReducedMotionPreference;
|
||||
systemPrefersCrossfades: boolean;
|
||||
prefersReducedMotion: ReducedMotionPreference;
|
||||
systemForcedColors: ForcedColorsPreference;
|
||||
syncForcedColors: boolean;
|
||||
systemPrefersContrast: ContrastPreference;
|
||||
alwaysShowLinkDecorations: boolean;
|
||||
roleStyle: RoleStyle;
|
||||
displayNameStylesEnabled: boolean;
|
||||
submitButtonEnabled: boolean;
|
||||
syncProfileThemeWithUserTheme: boolean;
|
||||
enableCustomCursor: boolean;
|
||||
switchIconsEnabled: boolean;
|
||||
}
|
||||
|
||||
export class AccessibilityStore extends FluxStore {
|
||||
get fontScale(): number;
|
||||
get fontSize(): number;
|
||||
get isFontScaledUp(): boolean;
|
||||
get isFontScaledDown(): boolean;
|
||||
get fontScaleClass(): string;
|
||||
get zoom(): number;
|
||||
get isZoomedIn(): boolean;
|
||||
get isZoomedOut(): boolean;
|
||||
get keyboardModeEnabled(): boolean;
|
||||
get colorblindMode(): boolean;
|
||||
get lowContrastMode(): boolean;
|
||||
get saturation(): number;
|
||||
get contrast(): number;
|
||||
get desaturateUserColors(): boolean;
|
||||
get forcedColorsModalSeen(): boolean;
|
||||
get keyboardNavigationExplainerModalSeen(): boolean;
|
||||
get messageGroupSpacing(): number;
|
||||
get isMessageGroupSpacingIncreased(): boolean;
|
||||
get isMessageGroupSpacingDecreased(): boolean;
|
||||
get isSubmitButtonEnabled(): boolean;
|
||||
get syncProfileThemeWithUserTheme(): boolean;
|
||||
get systemPrefersReducedMotion(): ReducedMotionPreference;
|
||||
get rawPrefersReducedMotion(): ReducedMotionPreference;
|
||||
get useReducedMotion(): boolean;
|
||||
get systemForcedColors(): ForcedColorsPreference;
|
||||
get syncForcedColors(): boolean;
|
||||
get useForcedColors(): boolean;
|
||||
get systemPrefersContrast(): ContrastPreference;
|
||||
get systemPrefersCrossfades(): boolean;
|
||||
get alwaysShowLinkDecorations(): boolean;
|
||||
get enableCustomCursor(): boolean;
|
||||
get roleStyle(): RoleStyle;
|
||||
get displayNameStylesEnabled(): boolean;
|
||||
get isHighContrastModeEnabled(): boolean;
|
||||
get isSwitchIconsEnabled(): boolean;
|
||||
getUserAgnosticState(): AccessibilityState;
|
||||
}
|
||||
33
packages/discord-types/src/stores/ActiveJoinedThreadsStore.d.ts
vendored
Normal file
33
packages/discord-types/src/stores/ActiveJoinedThreadsStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import { Channel, FluxStore } from "..";
|
||||
|
||||
export interface ThreadJoined {
|
||||
channel: Channel;
|
||||
joinTimestamp: number;
|
||||
}
|
||||
|
||||
export type ThreadsForParent = Record<string, ThreadJoined>;
|
||||
export type ThreadsForGuild = Record<string, ThreadsForParent>;
|
||||
export type AllActiveJoinedThreads = Record<string, ThreadsForGuild>;
|
||||
|
||||
export interface NewThreadCounts {
|
||||
[parentChannelId: string]: number;
|
||||
}
|
||||
|
||||
export class ActiveJoinedThreadsStore extends FluxStore {
|
||||
computeAllActiveJoinedThreads(guildId?: string | null): Channel[];
|
||||
getActiveJoinedRelevantThreadsForGuild(guildId: string): ThreadsForGuild;
|
||||
getActiveJoinedRelevantThreadsForParent(guildId: string, parentChannelId: string): ThreadsForParent;
|
||||
getActiveJoinedThreadsForGuild(guildId: string): ThreadsForGuild;
|
||||
getActiveJoinedThreadsForParent(guildId: string, parentChannelId: string): ThreadsForParent;
|
||||
getActiveJoinedUnreadThreadsForGuild(guildId: string): ThreadsForGuild;
|
||||
getActiveJoinedUnreadThreadsForParent(guildId: string, parentChannelId: string): ThreadsForParent;
|
||||
getActiveThreadCount(guildId: string, parentChannelId: string): number;
|
||||
getActiveUnjoinedThreadsForGuild(guildId: string): ThreadsForGuild;
|
||||
getActiveUnjoinedThreadsForParent(guildId: string, parentChannelId: string): ThreadsForParent;
|
||||
getActiveUnjoinedUnreadThreadsForGuild(guildId: string): ThreadsForGuild;
|
||||
getActiveUnjoinedUnreadThreadsForParent(guildId: string, parentChannelId: string): ThreadsForParent;
|
||||
getAllActiveJoinedThreads(): AllActiveJoinedThreads;
|
||||
getNewThreadCount(guildId: string, parentChannelId: string): number;
|
||||
getNewThreadCountsForGuild(guildId: string): NewThreadCounts;
|
||||
hasActiveJoinedUnreadThreads(guildId: string, parentChannelId: string): boolean;
|
||||
}
|
||||
25
packages/discord-types/src/stores/ApplicationStore.d.ts
vendored
Normal file
25
packages/discord-types/src/stores/ApplicationStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { Application, FluxStore } from "..";
|
||||
import { ApplicationType } from "../../enums";
|
||||
|
||||
export interface ApplicationStoreState {
|
||||
botUserIdToAppUsage: Record<string, ApplicationUsage>;
|
||||
}
|
||||
|
||||
export interface ApplicationUsage {
|
||||
applicationId: string;
|
||||
lastUsedMs: number;
|
||||
}
|
||||
|
||||
export class ApplicationStore extends FluxStore {
|
||||
_getAllApplications(): Application[];
|
||||
getState(): ApplicationStoreState;
|
||||
getApplication(applicationId: string): Application;
|
||||
getApplicationByName(name: string): Application | undefined;
|
||||
getApplicationLastUpdated(applicationId: string): number | undefined;
|
||||
getGuildApplication(guildId: string, type: ApplicationType): Application | undefined;
|
||||
getGuildApplicationIds(guildId: string): string[];
|
||||
getAppIdForBotUserId(botUserId: string): string | undefined;
|
||||
getFetchingOrFailedFetchingIds(): string[];
|
||||
isFetchingApplication(applicationId: string): boolean;
|
||||
didFetchingApplicationFail(applicationId: string): boolean;
|
||||
}
|
||||
24
packages/discord-types/src/stores/CallStore.d.ts
vendored
Normal file
24
packages/discord-types/src/stores/CallStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { FluxStore } from "..";
|
||||
|
||||
export interface Call {
|
||||
channelId: string;
|
||||
messageId: string | null;
|
||||
region: string | null;
|
||||
ringing: string[];
|
||||
unavailable: boolean;
|
||||
regionUpdated: boolean;
|
||||
}
|
||||
|
||||
export interface CallStoreState {
|
||||
calls: Record<string, Call>;
|
||||
enqueuedRings: Record<string, string[]>;
|
||||
}
|
||||
|
||||
export class CallStore extends FluxStore {
|
||||
getCall(channelId: string): Call;
|
||||
getCalls(): Call[];
|
||||
getMessageId(channelId: string): string | null;
|
||||
isCallActive(channelId: string, messageId?: string): boolean;
|
||||
isCallUnavailable(channelId: string): boolean;
|
||||
getInternalState(): CallStoreState;
|
||||
}
|
||||
105
packages/discord-types/src/stores/ChannelRTCStore.d.ts
vendored
Normal file
105
packages/discord-types/src/stores/ChannelRTCStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
import { AvatarDecorationData, FluxStore, User, VoiceState } from "..";
|
||||
import { ActivityType, ParticipantType, RTCPlatform } from "../../enums";
|
||||
import { StreamType } from "./FriendsStore";
|
||||
|
||||
export type RTCLayout = "normal" | "minimum" | "no-chat" | "full-screen" | "haven";
|
||||
export type RTCMode = "video" | "voice";
|
||||
export type RTCLayoutContext = "OVERLAY" | "APP" | "POPOUT" | "CALL_TILE_POPOUT";
|
||||
export type ParticipantFilterType = "VIDEO" | "STREAM" | "FILTERED" | "SPEAKING" | "ACTIVITY" | "NOT_POPPED_OUT";
|
||||
|
||||
export interface StreamResolution {
|
||||
height: number;
|
||||
width: number;
|
||||
}
|
||||
|
||||
export interface Stream {
|
||||
channelId: string;
|
||||
guildId: string | null;
|
||||
ownerId: string;
|
||||
streamType: StreamType;
|
||||
}
|
||||
|
||||
export interface BaseParticipant {
|
||||
id: string;
|
||||
type: ParticipantType;
|
||||
isPoppedOut?: boolean;
|
||||
}
|
||||
|
||||
export interface UserParticipant extends BaseParticipant {
|
||||
type: ParticipantType.USER;
|
||||
user: User;
|
||||
voiceState: VoiceState | null;
|
||||
voicePlatform: RTCPlatform | null;
|
||||
speaking: boolean;
|
||||
voiceDb: number;
|
||||
latched: boolean;
|
||||
lastSpoke: number;
|
||||
soundsharing: boolean;
|
||||
ringing: boolean;
|
||||
userNick: string;
|
||||
userAvatarDecoration: AvatarDecorationData | null;
|
||||
localVideoDisabled: boolean;
|
||||
userVideo?: boolean;
|
||||
streamId?: string;
|
||||
}
|
||||
|
||||
export interface StreamParticipant extends BaseParticipant {
|
||||
type: ParticipantType.STREAM | ParticipantType.HIDDEN_STREAM;
|
||||
user: User;
|
||||
userNick: string;
|
||||
userVideo: boolean;
|
||||
stream: Stream;
|
||||
maxResolution?: StreamResolution;
|
||||
maxFrameRate?: number;
|
||||
streamId?: string;
|
||||
}
|
||||
|
||||
export interface ActivityParticipant extends BaseParticipant {
|
||||
type: ParticipantType.ACTIVITY;
|
||||
applicationId: string;
|
||||
activityType: ActivityType;
|
||||
activityUrl: string;
|
||||
participants: string[];
|
||||
guildId: string | null;
|
||||
sortKey: string;
|
||||
}
|
||||
|
||||
export type Participant = UserParticipant | StreamParticipant | ActivityParticipant;
|
||||
|
||||
export interface SelectedParticipantStats {
|
||||
view_mode_grid_duration_ms?: number;
|
||||
view_mode_focus_duration_ms?: number;
|
||||
view_mode_toggle_count?: number;
|
||||
}
|
||||
|
||||
export interface ChannelRTCState {
|
||||
voiceParticipantsHidden: Record<string, boolean>;
|
||||
}
|
||||
|
||||
export class ChannelRTCStore extends FluxStore {
|
||||
getActivityParticipants(channelId: string): ActivityParticipant[];
|
||||
getAllChatOpen(): Record<string, boolean>;
|
||||
getChatOpen(channelId: string): boolean;
|
||||
getFilteredParticipants(channelId: string): Participant[];
|
||||
getGuildRingingUsers(channelId: string): Set<string>;
|
||||
getLayout(channelId: string, context?: RTCLayoutContext): RTCLayout;
|
||||
getMode(channelId: string): RTCMode;
|
||||
getParticipant(channelId: string, participantId: string): Participant | null;
|
||||
getParticipants(channelId: string): Participant[];
|
||||
getParticipantsListOpen(channelId: string): boolean;
|
||||
getParticipantsOpen(channelId: string): boolean;
|
||||
getParticipantsVersion(channelId: string): number;
|
||||
getSelectedParticipant(channelId: string): Participant | null;
|
||||
getSelectedParticipantId(channelId: string): string | null;
|
||||
getSelectedParticipantStats(channelId: string): SelectedParticipantStats;
|
||||
getSpeakingParticipants(channelId: string): UserParticipant[];
|
||||
getStageStreamSize(channelId: string): StreamResolution | undefined;
|
||||
getStageVideoLimitBoostUpsellDismissed(channelId: string): boolean | undefined;
|
||||
getState(): ChannelRTCState;
|
||||
getStreamParticipants(channelId: string): StreamParticipant[];
|
||||
getUserParticipantCount(channelId: string): number;
|
||||
getVideoParticipants(channelId: string): UserParticipant[];
|
||||
getVoiceParticipantsHidden(channelId: string): boolean;
|
||||
isFullscreenInContext(): boolean;
|
||||
isParticipantPoppedOut(channelId: string, participantId: string): boolean;
|
||||
}
|
||||
|
|
@ -1,24 +1,111 @@
|
|||
import { Channel, FluxStore } from "..";
|
||||
|
||||
/** Debug info for channel store state. */
|
||||
export interface ChannelStoreDebugInfo {
|
||||
/** Guild IDs that have been loaded. */
|
||||
loadedGuildIds: string[];
|
||||
/** Guild IDs currently being loaded. */
|
||||
pendingGuildLoads: string[];
|
||||
/** String descriptions of guild channel counts. */
|
||||
guildSizes: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Flux store managing all channel data including guild channels,
|
||||
* threads, DMs, and group DMs.
|
||||
*/
|
||||
export class ChannelStore extends FluxStore {
|
||||
/**
|
||||
* Gets a channel by ID.
|
||||
* @param channelId Channel ID to look up.
|
||||
*/
|
||||
getChannel(channelId: string): Channel;
|
||||
/**
|
||||
* Gets basic channel info by ID, returns undefined if not found.
|
||||
* @param channelId Channel ID to look up.
|
||||
*/
|
||||
getBasicChannel(channelId: string): Channel | undefined;
|
||||
/**
|
||||
* Checks if a channel exists in the store.
|
||||
* @param channelId Channel ID to check.
|
||||
*/
|
||||
hasChannel(channelId: string): boolean;
|
||||
|
||||
/**
|
||||
* Gets all channel IDs, optionally filtered by guild.
|
||||
* @param guildId Guild ID to filter by, or null/undefined for all channels.
|
||||
*/
|
||||
getChannelIds(guildId?: string | null): string[];
|
||||
/**
|
||||
* Gets basic guild channels as a mutable record.
|
||||
* @param guildId Guild ID to get channels for.
|
||||
* @returns Record keyed by channel ID.
|
||||
*/
|
||||
getMutableBasicGuildChannelsForGuild(guildId: string): Record<string, Channel>;
|
||||
/**
|
||||
* Gets all guild channels as a mutable record.
|
||||
* @param guildId Guild ID to get channels for.
|
||||
* @returns Record keyed by channel ID.
|
||||
*/
|
||||
getMutableGuildChannelsForGuild(guildId: string): Record<string, Channel>;
|
||||
/**
|
||||
* Gets all threads for a guild.
|
||||
* @param guildId Guild ID to get threads for.
|
||||
*/
|
||||
getAllThreadsForGuild(guildId: string): Channel[];
|
||||
getAllThreadsForParent(channelId: string): Channel[];
|
||||
/**
|
||||
* Gets all threads under a parent channel.
|
||||
* @param parentChannelId Parent channel ID.
|
||||
*/
|
||||
getAllThreadsForParent(parentChannelId: string): Channel[];
|
||||
/**
|
||||
* Gets sorted linked channels for a guild, such as stage instances and events.
|
||||
* @param guildId Guild ID.
|
||||
*/
|
||||
getSortedLinkedChannelsForGuild(guildId: string): Channel[];
|
||||
|
||||
getDMFromUserId(userId: string): string;
|
||||
/**
|
||||
* Gets DM channel ID for a user.
|
||||
* @param userId User ID to get DM for.
|
||||
* @returns Channel ID, not the channel object.
|
||||
*/
|
||||
getDMFromUserId(userId: string): string | undefined;
|
||||
/**
|
||||
* Gets DM channel object for a user.
|
||||
* @param userId User ID to get DM for.
|
||||
*/
|
||||
getDMChannelFromUserId(userId: string): Channel | undefined;
|
||||
/** Gets all user IDs that have DM channels. */
|
||||
getDMUserIds(): string[];
|
||||
/**
|
||||
* Gets mutable map of user ID to DM channel ID.
|
||||
* @returns Record keyed by user ID.
|
||||
*/
|
||||
getMutableDMsByUserIds(): Record<string, string>;
|
||||
/**
|
||||
* Gets mutable map of all private channels.
|
||||
* @returns Record keyed by channel ID.
|
||||
*/
|
||||
getMutablePrivateChannels(): Record<string, Channel>;
|
||||
/** Gets private channels sorted by last message. */
|
||||
getSortedPrivateChannels(): Channel[];
|
||||
|
||||
/**
|
||||
* Gets version number for guild channels, incremented on changes.
|
||||
* @param guildId Guild ID.
|
||||
*/
|
||||
getGuildChannelsVersion(guildId: string): number;
|
||||
/** Gets version number for private channels, incremented on changes. */
|
||||
getPrivateChannelsVersion(): number;
|
||||
/**
|
||||
* Gets initial channel state for overlay rendering.
|
||||
* @returns Record keyed by channel ID.
|
||||
*/
|
||||
getInitialOverlayState(): Record<string, Channel>;
|
||||
|
||||
/** Gets debug info about store state. */
|
||||
getDebugInfo(): ChannelStoreDebugInfo;
|
||||
|
||||
/** Loads all guild and private channels from disk cache. */
|
||||
loadAllGuildAndPrivateChannelsFromDisk(): Promise<void>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,5 @@
|
|||
import { FluxStore } from "..";
|
||||
|
||||
export enum DraftType {
|
||||
ChannelMessage = 0,
|
||||
ThreadSettings = 1,
|
||||
FirstThreadMessage = 2,
|
||||
ApplicationLauncherCommand = 3,
|
||||
Poll = 4,
|
||||
SlashCommand = 5,
|
||||
ForwardContextMessage = 6
|
||||
}
|
||||
import { DraftType } from "../../enums";
|
||||
|
||||
export interface Draft {
|
||||
timestamp: number;
|
||||
|
|
|
|||
516
packages/discord-types/src/stores/EmojiStore.d.ts
vendored
516
packages/discord-types/src/stores/EmojiStore.d.ts
vendored
|
|
@ -1,57 +1,467 @@
|
|||
import { Channel, CustomEmoji, Emoji, FluxStore } from "..";
|
||||
import { EmojiIntention, LoadState } from "../../enums";
|
||||
|
||||
export class EmojiStore extends FluxStore {
|
||||
getCustomEmojiById(id?: string | null): CustomEmoji | undefined;
|
||||
getUsableCustomEmojiById(id?: string | null): CustomEmoji | undefined;
|
||||
getGuilds(): Record<string, {
|
||||
id: string;
|
||||
get emojis(): CustomEmoji[];
|
||||
get rawEmojis(): CustomEmoji[];
|
||||
get usableEmojis(): CustomEmoji[];
|
||||
get emoticons(): any[];
|
||||
getEmoji(id: string): CustomEmoji | undefined;
|
||||
isUsable(emoji: CustomEmoji): boolean;
|
||||
}>;
|
||||
getGuildEmoji(guildId?: string | null): CustomEmoji[];
|
||||
getNewlyAddedEmoji(guildId?: string | null): CustomEmoji[];
|
||||
getTopEmoji(guildId?: string | null): CustomEmoji[];
|
||||
getTopEmojisMetadata(guildId?: string | null): {
|
||||
emojiIds: string[];
|
||||
topEmojisTTL: number;
|
||||
};
|
||||
hasPendingUsage(): boolean;
|
||||
hasUsableEmojiInAnyGuild(): boolean;
|
||||
searchWithoutFetchingLatest(data: any): any;
|
||||
getSearchResultsOrder(...args: any[]): any;
|
||||
getState(): {
|
||||
pendingUsages: { key: string, timestamp: number; }[];
|
||||
};
|
||||
searchWithoutFetchingLatest(data: {
|
||||
channel: Channel;
|
||||
query: string;
|
||||
count?: number;
|
||||
intention: number;
|
||||
includeExternalGuilds?: boolean;
|
||||
matchComparator?(name: string): boolean;
|
||||
}): Record<"locked" | "unlocked", Emoji[]>;
|
||||
/** Emoji picker category names. */
|
||||
export type EmojiCategory =
|
||||
| "top guild emoji"
|
||||
| "favorites"
|
||||
| "recent"
|
||||
| "custom"
|
||||
| "people"
|
||||
| "nature"
|
||||
| "food"
|
||||
| "activity"
|
||||
| "travel"
|
||||
| "objects"
|
||||
| "symbols"
|
||||
| "flags";
|
||||
|
||||
getDisambiguatedEmojiContext(): {
|
||||
backfillTopEmojis: Record<any, any>;
|
||||
customEmojis: Record<string, CustomEmoji>;
|
||||
emojisById: Record<string, CustomEmoji>;
|
||||
emojisByName: Record<string, CustomEmoji>;
|
||||
emoticonRegex: RegExp | null;
|
||||
emoticonsByName: Record<string, any>;
|
||||
escapedEmoticonNames: string;
|
||||
favoriteNamesAndIds?: any;
|
||||
favorites?: any;
|
||||
frequentlyUsed?: any;
|
||||
groupedCustomEmojis: Record<string, CustomEmoji[]>;
|
||||
guildId?: string;
|
||||
isFavoriteEmojiWithoutFetchingLatest(e: Emoji): boolean;
|
||||
newlyAddedEmoji: Record<string, CustomEmoji[]>;
|
||||
topEmojis?: any;
|
||||
unicodeAliases: Record<string, string>;
|
||||
get favoriteEmojisWithoutFetchingLatest(): Emoji[];
|
||||
};
|
||||
/**
|
||||
* Tracks usage statistics for a single emoji to compute frecency scores.
|
||||
*/
|
||||
export interface EmojiUsageRecord {
|
||||
/** Total number of times this emoji has been used. */
|
||||
totalUses: number;
|
||||
/** Array of recent usage timestamps in milliseconds. */
|
||||
recentUses: number[];
|
||||
/** Computed frecency score combining frequency and recency, -1 when dirty. */
|
||||
frecency: number;
|
||||
/** Raw score before frecency computation. */
|
||||
score: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for tracking emoji usage.
|
||||
*/
|
||||
export interface TrackOptions {
|
||||
/** Timestamp of the usage in milliseconds. */
|
||||
timestamp?: number;
|
||||
/** Number of uses since last track call. */
|
||||
usesSinceLastTrack?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frecency tracker for emoji usage, combines frequency and recency to rank emojis.
|
||||
* Used by both regular emoji picker and reaction emoji picker.
|
||||
*/
|
||||
export interface EmojiFrecency {
|
||||
/** True when data has been modified and needs recomputation. */
|
||||
dirty: boolean;
|
||||
/** Cached array of frequently used emojis after computation. */
|
||||
_frequently: Emoji[];
|
||||
/** Maximum number of frequently used items to track (default 42). */
|
||||
numFrequentlyItems: number;
|
||||
/** Maximum number of recent usage samples to keep per emoji (default 10). */
|
||||
maxSamples: number;
|
||||
/** Computes bonus score for frecency calculation (returns 100). */
|
||||
computeBonus: () => number;
|
||||
/**
|
||||
* Computes weight multiplier based on recency index.
|
||||
* Returns 100 for index <= 3, 70 for <= 15, 50 for <= 30, 30 for <= 45, 10 for <= 80.
|
||||
*/
|
||||
computeWeight: (index: number) => number;
|
||||
/**
|
||||
* Computes frecency score for an emoji.
|
||||
* @param totalUses Total number of times emoji was used.
|
||||
* @param score Raw score value.
|
||||
* @param config Configuration for frecency calculation.
|
||||
*/
|
||||
computeFrecency: (totalUses: number, score: number, config: {
|
||||
/** Number of recent uses to consider. */
|
||||
numOfRecentUses?: number;
|
||||
/** Maximum total uses to cap at. */
|
||||
maxTotalUse?: number;
|
||||
}) => number;
|
||||
/** Whether to calculate max total use dynamically. */
|
||||
calculateMaxTotalUse: boolean;
|
||||
/**
|
||||
* Looks up an emoji by name or id.
|
||||
* @param name Emoji name or id to look up.
|
||||
* @returns The emoji if found.
|
||||
*/
|
||||
lookupKey: (name: string) => Emoji | undefined;
|
||||
/** Usage history keyed by emoji name (for unicode) or id (for custom). */
|
||||
usageHistory: Record<string, EmojiUsageRecord>;
|
||||
/** Callback invoked after frecency computation completes. */
|
||||
afterCompute: () => void;
|
||||
|
||||
/**
|
||||
* Overwrites the usage history with new data.
|
||||
* @param history New usage history to set.
|
||||
* @param pendingUsages Pending usages to track after overwriting.
|
||||
*/
|
||||
overwriteHistory(history: Record<string, EmojiUsageRecord> | null, pendingUsages?: PendingUsage[]): void;
|
||||
/** Marks the frecency data as dirty, requiring recomputation. */
|
||||
markDirty(): void;
|
||||
/** Returns whether the frecency data needs recomputation. */
|
||||
isDirty(): boolean;
|
||||
/**
|
||||
* Tracks usage of an emoji.
|
||||
* @param key Emoji name or id.
|
||||
* @param options Track options including timestamp.
|
||||
*/
|
||||
track(key: string, options?: TrackOptions): void;
|
||||
/**
|
||||
* Gets the usage record for an emoji, computing if dirty.
|
||||
* @param key Emoji name or id.
|
||||
* @returns The usage record or null if not found.
|
||||
*/
|
||||
getEntry(key: string): EmojiUsageRecord | null;
|
||||
/**
|
||||
* Gets the score for an emoji.
|
||||
* @param key Emoji name or id.
|
||||
* @returns The score or null if not found.
|
||||
*/
|
||||
getScore(key: string): number | null;
|
||||
/**
|
||||
* Gets the frecency for an emoji.
|
||||
* @param key Emoji name or id.
|
||||
* @returns The frecency or null if not found.
|
||||
*/
|
||||
getFrecency(key: string): number | null;
|
||||
/** Recomputes frecency scores for all emojis. */
|
||||
compute(): void;
|
||||
/** Gets the frequently used emojis, computing if necessary. */
|
||||
get frequently(): Emoji[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Container for a guild's emoji collection with usability checks.
|
||||
*/
|
||||
export interface GuildEmojis {
|
||||
/** Guild id this emoji collection belongs to. */
|
||||
id: string;
|
||||
/** User id for permission checks. */
|
||||
_userId: string;
|
||||
/** Internal emoji array. */
|
||||
_emojis: CustomEmoji[];
|
||||
/** Fast lookup map of emoji id to emoji. */
|
||||
_emojiMap: Record<string, CustomEmoji>;
|
||||
/** Internal emoticons array. */
|
||||
_emoticons: Emoticon[];
|
||||
/** Internal usable emojis cache. */
|
||||
_usableEmojis: CustomEmoji[];
|
||||
/** Whether user can see server subscription IAP. */
|
||||
_canSeeServerSubIAP: boolean;
|
||||
/** All custom emojis in this guild. */
|
||||
get emojis(): CustomEmoji[];
|
||||
/** Custom emojis the current user can use in this guild. */
|
||||
get usableEmojis(): CustomEmoji[];
|
||||
/** Text emoticons configured for this guild. */
|
||||
get emoticons(): Emoticon[];
|
||||
/**
|
||||
* Gets an emoji by id from this guild.
|
||||
* @param id Emoji id to look up.
|
||||
*/
|
||||
getEmoji(id: string): CustomEmoji | undefined;
|
||||
/**
|
||||
* Gets a usable emoji by id from this guild.
|
||||
* @param id Emoji id to look up.
|
||||
*/
|
||||
getUsableEmoji(id: string): CustomEmoji | undefined;
|
||||
/**
|
||||
* Checks if an emoji is usable by the current user.
|
||||
* @param emoji Emoji to check.
|
||||
*/
|
||||
isUsable(emoji: CustomEmoji): boolean;
|
||||
/** Returns array of all emoji ids in this guild. */
|
||||
emojiIds(): string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Text emoticon that can be converted to emoji.
|
||||
*/
|
||||
export interface Emoticon {
|
||||
/** Names/aliases for this emoticon. */
|
||||
names: string[];
|
||||
/** The text representation (e.g. ":)" or ":D"). */
|
||||
surrogates: string;
|
||||
/** Whether this emoticon should use sprite sheet rendering. */
|
||||
useSpriteSheet: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pending emoji usage waiting to be recorded.
|
||||
*/
|
||||
export interface PendingUsage {
|
||||
/** Emoji key (name for unicode, id for custom). */
|
||||
key: string;
|
||||
/** Timestamp in milliseconds when usage occurred. */
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializable state for EmojiStore persistence.
|
||||
*/
|
||||
export interface EmojiStoreState {
|
||||
/** Pending emoji usages not yet committed. */
|
||||
pendingUsages: PendingUsage[];
|
||||
/** Pending reaction emoji usages not yet committed. */
|
||||
emojiReactionPendingUsages: PendingUsage[];
|
||||
/** Guild ids with expanded emoji sections in picker. */
|
||||
expandedSectionsByGuildIds: Set<string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Context for emoji disambiguation, caching resolved emoji data for a guild context.
|
||||
* Provides fast lookup of emojis without triggering data fetches.
|
||||
*/
|
||||
export interface DisambiguatedEmojiContext {
|
||||
/** User's favorite emojis or null if not loaded. */
|
||||
favorites: Emoji[] | null;
|
||||
/** Set of favorite emoji names and ids for fast lookup, or null if not loaded. */
|
||||
favoriteNamesAndIds: Set<string> | null;
|
||||
/** Top emojis for the current guild or null if not loaded. */
|
||||
topEmojis: Emoji[] | null;
|
||||
/** Current guild id context or null for DMs. */
|
||||
guildId: string | null;
|
||||
/** Regex-escaped emoticon names for matching. */
|
||||
escapedEmoticonNames: string;
|
||||
/** All emojis with disambiguation applied (unique names). */
|
||||
disambiguatedEmoji: Emoji[];
|
||||
/** Compiled regex for matching emoticons or null if none. */
|
||||
emoticonRegex: RegExp | null;
|
||||
/** Frequently used emojis or null if not loaded. */
|
||||
frequentlyUsed: Emoji[] | null;
|
||||
/** Frequently used reaction emojis or null if not loaded. */
|
||||
frequentlyUsedReactionEmojis: Emoji[] | null;
|
||||
/** Set of frequently used reaction emoji names and ids, or null if not loaded. */
|
||||
frequentlyUsedReactionNamesAndIds: Set<string> | null;
|
||||
/** Unicode emoji aliases keyed by alias name, maps to primary name. */
|
||||
unicodeAliases: Record<string, string>;
|
||||
/** Custom emojis keyed by emoji id. */
|
||||
customEmojis: Record<string, CustomEmoji>;
|
||||
/** Custom emojis grouped by guild id. */
|
||||
groupedCustomEmojis: Record<string, CustomEmoji[]>;
|
||||
/** Emoticons keyed by name for fast lookup. */
|
||||
emoticonsByName: Record<string, Emoticon>;
|
||||
/** All emojis keyed by name for fast lookup. */
|
||||
emojisByName: Record<string, Emoji>;
|
||||
/** Custom emojis keyed by id for fast lookup. */
|
||||
emojisById: Record<string, CustomEmoji>;
|
||||
/** Newly added emojis grouped by guild id. */
|
||||
newlyAddedEmoji: Record<string, CustomEmoji[]>;
|
||||
/**
|
||||
* Checks if an emoji is a favorite without triggering a fetch.
|
||||
* @param emoji Emoji to check.
|
||||
*/
|
||||
isFavoriteEmojiWithoutFetchingLatest(emoji: Emoji): boolean;
|
||||
|
||||
/** Gets favorite emojis without triggering a fetch. */
|
||||
get favoriteEmojisWithoutFetchingLatest(): Emoji[];
|
||||
/** Gets all disambiguated emojis. */
|
||||
getDisambiguatedEmoji(): Emoji[];
|
||||
/** Gets all custom emojis keyed by name. */
|
||||
getCustomEmoji(): Record<string, CustomEmoji>;
|
||||
/** Gets custom emojis grouped by guild id. */
|
||||
getGroupedCustomEmoji(): Record<string, CustomEmoji[]>;
|
||||
/**
|
||||
* Gets an emoji by name.
|
||||
* @param name Emoji name to look up.
|
||||
*/
|
||||
getByName(name: string): Emoji | undefined;
|
||||
/**
|
||||
* Gets an emoticon by name.
|
||||
* @param name Emoticon name to look up.
|
||||
*/
|
||||
getEmoticonByName(name: string): Emoticon | undefined;
|
||||
/**
|
||||
* Gets an emoji by id.
|
||||
* @param id Emoji id to look up.
|
||||
*/
|
||||
getById(id: string): Emoji | undefined;
|
||||
/**
|
||||
* Gets the regex for matching custom emoticons.
|
||||
* @returns RegExp or null if no emoticons.
|
||||
*/
|
||||
getCustomEmoticonRegex(): RegExp | null;
|
||||
/** Gets frequently used emojis without triggering a fetch. */
|
||||
getFrequentlyUsedEmojisWithoutFetchingLatest(): Emoji[];
|
||||
/** Rebuilds the frequently used reaction emojis cache and returns it. */
|
||||
rebuildFrequentlyUsedReactionsEmojisWithoutFetchingLatest(): {
|
||||
frequentlyUsedReactionEmojis: Emoji[];
|
||||
frequentlyUsedReactionNamesAndIds: Set<string>;
|
||||
};
|
||||
/** Gets frequently used reaction emojis without triggering a fetch. */
|
||||
getFrequentlyUsedReactionEmojisWithoutFetchingLatest(): Emoji[];
|
||||
/**
|
||||
* Checks if an emoji is frequently used for reactions.
|
||||
* @param emoji Emoji to check.
|
||||
*/
|
||||
isFrequentlyUsedReactionEmojiWithoutFetchingLatest(emoji: Emoji): boolean;
|
||||
/** Rebuilds the favorite emojis cache and returns it. */
|
||||
rebuildFavoriteEmojisWithoutFetchingLatest(): {
|
||||
favorites: Emoji[];
|
||||
favoriteNamesAndIds: Set<string>;
|
||||
};
|
||||
/**
|
||||
* Gets emojis in priority order (favorites, frequent, top) without fetching.
|
||||
* @returns Array of emojis in priority order.
|
||||
*/
|
||||
getEmojiInPriorityOrderWithoutFetchingLatest(): Emoji[];
|
||||
/**
|
||||
* Gets top emojis for a guild without triggering a fetch.
|
||||
* @param guildId Guild id to get top emojis for.
|
||||
*/
|
||||
getTopEmojiWithoutFetchingLatest(guildId: string): Emoji[];
|
||||
/**
|
||||
* Gets newly added emojis for a specific guild.
|
||||
* @param guildId Guild id.
|
||||
*/
|
||||
getNewlyAddedEmojiForGuild(guildId: string): CustomEmoji[];
|
||||
/** Gets escaped custom emoticon names for regex matching. */
|
||||
getEscapedCustomEmoticonNames(): string;
|
||||
/**
|
||||
* Checks if a name matches an emoji name chain.
|
||||
* @param name Name to match.
|
||||
*/
|
||||
nameMatchesChain(name: string): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search options for emoji search.
|
||||
*/
|
||||
export interface EmojiSearchOptions {
|
||||
/** Channel context for permission checks. */
|
||||
channel: Channel;
|
||||
/** Search query string. */
|
||||
query: string;
|
||||
/** Maximum number of results to return. */
|
||||
count?: number;
|
||||
/** Intention for using the emoji, affects availability filtering. */
|
||||
intention: EmojiIntention;
|
||||
/** Whether to include emojis from guilds the user is not in. */
|
||||
includeExternalGuilds?: boolean;
|
||||
/** Whether to only show unicode emojis in results. */
|
||||
showOnlyUnicode?: boolean;
|
||||
/**
|
||||
* Custom comparator for matching emoji names.
|
||||
* @param name Emoji name to compare.
|
||||
* @returns True if the name matches.
|
||||
*/
|
||||
matchComparator?(name: string): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search results split by availability.
|
||||
*/
|
||||
export interface EmojiSearchResults {
|
||||
/** Emojis that are locked (require Nitro or permissions). */
|
||||
locked: Emoji[];
|
||||
/** Emojis that are available for use. */
|
||||
unlocked: Emoji[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata about top emojis for a guild.
|
||||
*/
|
||||
export interface TopEmojisMetadata {
|
||||
/** Array of top emoji ids. */
|
||||
emojiIds: string[];
|
||||
/** Time-to-live for this data in milliseconds. */
|
||||
topEmojisTTL: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flux store managing all emoji data including custom guild emojis,
|
||||
* unicode emojis, favorites, frecency, and search functionality.
|
||||
*/
|
||||
export class EmojiStore extends FluxStore {
|
||||
/** Array of emoji category names for the picker. */
|
||||
get categories(): EmojiCategory[];
|
||||
/**
|
||||
* Current skin tone modifier surrogate for emoji diversity.
|
||||
* Empty string for default yellow, or skin tone modifier (🏻🏼🏽🏾🏿).
|
||||
*/
|
||||
get diversitySurrogate(): string;
|
||||
/** Frecency tracker for emoji picker usage. */
|
||||
get emojiFrecencyWithoutFetchingLatest(): EmojiFrecency;
|
||||
/** Frecency tracker for reaction emoji usage. */
|
||||
get emojiReactionFrecencyWithoutFetchingLatest(): EmojiFrecency;
|
||||
/** Guild ids with expanded emoji sections in picker. */
|
||||
get expandedSectionsByGuildIds(): Set<string>;
|
||||
/** Current load state of the emoji store. */
|
||||
get loadState(): LoadState;
|
||||
|
||||
/**
|
||||
* Gets a custom emoji by its id.
|
||||
* @param id Emoji id to look up.
|
||||
* @returns The custom emoji if found.
|
||||
*/
|
||||
getCustomEmojiById(id?: string | null): CustomEmoji | undefined;
|
||||
/**
|
||||
* Gets a usable custom emoji by its id.
|
||||
* @param id Emoji id to look up.
|
||||
* @returns The custom emoji if found and usable by current user.
|
||||
*/
|
||||
getUsableCustomEmojiById(id?: string | null): CustomEmoji | undefined;
|
||||
/**
|
||||
* Gets all guild emoji collections keyed by guild id.
|
||||
* @returns Record of guild id to GuildEmojis.
|
||||
*/
|
||||
getGuilds(): Record<string, GuildEmojis>;
|
||||
/**
|
||||
* Gets all custom emojis for a guild.
|
||||
* @param guildId Guild id to get emojis for, or null for all guilds.
|
||||
* @returns Array of custom emojis.
|
||||
*/
|
||||
getGuildEmoji(guildId?: string | null): CustomEmoji[];
|
||||
/**
|
||||
* Gets usable custom emojis for a guild.
|
||||
* @param guildId Guild id to get emojis for.
|
||||
* @returns Array of usable custom emojis.
|
||||
*/
|
||||
getUsableGuildEmoji(guildId?: string | null): CustomEmoji[];
|
||||
/**
|
||||
* Gets newly added emojis for a guild.
|
||||
* @param guildId Guild id to get emojis for.
|
||||
* @returns Array of newly added custom emojis.
|
||||
*/
|
||||
getNewlyAddedEmoji(guildId?: string | null): CustomEmoji[];
|
||||
/**
|
||||
* Gets top emojis for a guild based on usage.
|
||||
* @param guildId Guild id to get emojis for.
|
||||
* @returns Array of top custom emojis.
|
||||
*/
|
||||
getTopEmoji(guildId?: string | null): CustomEmoji[];
|
||||
/**
|
||||
* Gets metadata about top emojis for a guild.
|
||||
* @param guildId Guild id to get metadata for.
|
||||
* @returns Metadata including emoji ids and TTL, or undefined if not cached.
|
||||
*/
|
||||
getTopEmojisMetadata(guildId?: string | null): TopEmojisMetadata | undefined;
|
||||
/**
|
||||
* Checks if user has any favorite emojis in a guild context.
|
||||
* @param guildId Guild id to check.
|
||||
* @returns True if user has favorites.
|
||||
*/
|
||||
hasFavoriteEmojis(guildId?: string | null): boolean;
|
||||
/**
|
||||
* Checks if there are pending emoji usages to be recorded.
|
||||
* @returns True if there are pending usages.
|
||||
*/
|
||||
hasPendingUsage(): boolean;
|
||||
/**
|
||||
* Checks if user has any usable custom emojis in any guild.
|
||||
* @returns True if user has usable emojis.
|
||||
*/
|
||||
hasUsableEmojiInAnyGuild(): boolean;
|
||||
/** Internal method for ordering search results. */
|
||||
getSearchResultsOrder(...args: any[]): any;
|
||||
/**
|
||||
* Gets the serializable state for persistence.
|
||||
* @returns Current store state.
|
||||
*/
|
||||
getState(): EmojiStoreState;
|
||||
/**
|
||||
* Searches for emojis without triggering data fetches.
|
||||
* @param options Search options including query and filters.
|
||||
* @returns Search results split by locked/unlocked.
|
||||
*/
|
||||
searchWithoutFetchingLatest(options: EmojiSearchOptions): EmojiSearchResults;
|
||||
/**
|
||||
* Gets the disambiguated emoji context for a guild.
|
||||
* @param guildId Guild id to get context for, or null/undefined for global context.
|
||||
*/
|
||||
getDisambiguatedEmojiContext(guildId?: string | null): DisambiguatedEmojiContext;
|
||||
}
|
||||
|
|
|
|||
57
packages/discord-types/src/stores/FluxStore.d.ts
vendored
57
packages/discord-types/src/stores/FluxStore.d.ts
vendored
|
|
@ -1,6 +1,7 @@
|
|||
import { FluxDispatcher, FluxEvents } from "..";
|
||||
|
||||
type Callback = () => void;
|
||||
type SyncCallback = () => boolean | void;
|
||||
|
||||
/*
|
||||
For some reason, this causes type errors when you try to destructure it:
|
||||
|
|
@ -14,31 +15,75 @@ type Callback = () => void;
|
|||
export type FluxEvent = any;
|
||||
|
||||
export type ActionHandler = (event: FluxEvent) => void;
|
||||
/** keyed by FluxEvents action type */
|
||||
export type ActionHandlers = Partial<Record<FluxEvents, ActionHandler>>;
|
||||
|
||||
/**
|
||||
* Base class for all Discord Flux stores.
|
||||
* Provides change notification, action handling, and store synchronization.
|
||||
*/
|
||||
export class FluxStore {
|
||||
constructor(dispatcher: FluxDispatcher, actionHandlers?: ActionHandlers);
|
||||
/**
|
||||
* @param dispatcher the FluxDispatcher instance to register with
|
||||
* @param actionHandlers handlers for Flux actions, keyed by action type
|
||||
* @param band priority band for action handling (default 2), lower runs first
|
||||
*/
|
||||
constructor(dispatcher: FluxDispatcher, actionHandlers?: ActionHandlers, band?: number);
|
||||
|
||||
/** returns displayName if set, otherwise constructor.name */
|
||||
getName(): string;
|
||||
|
||||
/** adds listener to _changeCallbacks, invoked before react listeners and triggers syncWith processing */
|
||||
addChangeListener(callback: Callback): void;
|
||||
/** Listener will be removed once the callback returns false. */
|
||||
/**
|
||||
* adds a listener that auto-removes when callback returns false.
|
||||
* @param callback returning false removes the listener
|
||||
* @param preemptive if true (default), calls callback immediately and skips adding if it returns false
|
||||
*/
|
||||
addConditionalChangeListener(callback: () => boolean, preemptive?: boolean): void;
|
||||
/** adds listener to _reactChangeCallbacks, invoked after all regular change listeners complete */
|
||||
addReactChangeListener(callback: Callback): void;
|
||||
removeChangeListener(callback: Callback): void;
|
||||
removeReactChangeListener(callback: Callback): void;
|
||||
|
||||
/** called by dispatcher after action handlers run, marks changed if listeners exist and may resume paused dispatch */
|
||||
doEmitChanges(event: FluxEvent): void;
|
||||
/** marks store as changed for batched listener notification */
|
||||
emitChange(): void;
|
||||
|
||||
/** unique token identifying this store in the dispatcher */
|
||||
getDispatchToken(): string;
|
||||
/** override to set up initial state, called once by initializeIfNeeded */
|
||||
initialize(): void;
|
||||
/** calls initialize() if not already initialized, adds performance mark if init takes >5ms */
|
||||
initializeIfNeeded(): void;
|
||||
/** this is a setter */
|
||||
mustEmitChanges(actionHandler: ActionHandler | undefined): void;
|
||||
registerActionHandlers(actionHandlers: ActionHandlers): void;
|
||||
syncWith(stores: FluxStore[], callback: Callback, timeout?: number): void;
|
||||
/**
|
||||
* sets callback to determine if changes must emit during paused dispatch.
|
||||
* @param callback if omitted, defaults to () => true (always emit)
|
||||
*/
|
||||
mustEmitChanges(callback?: ActionHandler): void;
|
||||
/**
|
||||
* registers additional action handlers after construction.
|
||||
* @param actionHandlers handlers keyed by action type
|
||||
* @param band priority band, lower runs first
|
||||
*/
|
||||
registerActionHandlers(actionHandlers: ActionHandlers, band?: number): void;
|
||||
/**
|
||||
* syncs this store with other stores, re-emitting when they change.
|
||||
* without timeout: synchronous, callback runs during emitNonReactOnce.
|
||||
* with timeout: debounced, adds regular change listener to each source store.
|
||||
* @param stores stores to sync with
|
||||
* @param callback returning false skips emitChange on this store
|
||||
* @param timeout if provided, debounces the sync callback
|
||||
*/
|
||||
syncWith(stores: FluxStore[], callback: SyncCallback, timeout?: number): void;
|
||||
/** adds dispatcher dependencies so this store's handlers run after the specified stores */
|
||||
waitFor(...stores: FluxStore[]): void;
|
||||
|
||||
/** initializes all registered stores, called once at app startup */
|
||||
static initialize(): void;
|
||||
/** clears all registered stores and destroys the change listener system */
|
||||
static destroy(): void;
|
||||
/** returns all registered FluxStore instances */
|
||||
static getAll(): FluxStore[];
|
||||
}
|
||||
|
|
|
|||
69
packages/discord-types/src/stores/FriendsStore.d.ts
vendored
Normal file
69
packages/discord-types/src/stores/FriendsStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import { Activity, FluxStore, Guild, User } from "..";
|
||||
import { GiftIntentType, RelationshipType } from "../../enums";
|
||||
|
||||
export type FriendsSection = "ADD_FRIEND" | "ALL" | "ONLINE" | "PENDING" | "PENDING_IGNORED" | "SPAM" | "SUGGESTIONS";
|
||||
|
||||
export type StatusType = "online" | "offline" | "idle" | "dnd" | "invisible" | "streaming" | "unknown";
|
||||
|
||||
export type StreamType = "call" | "guild";
|
||||
|
||||
export interface ApplicationStream {
|
||||
channelId: string;
|
||||
guildId: string | null;
|
||||
ownerId: string;
|
||||
streamType: StreamType;
|
||||
}
|
||||
|
||||
export interface FriendsRow {
|
||||
key: string;
|
||||
userId: string;
|
||||
/**
|
||||
* 99 means contact based friend suggestions from FriendSuggestionStore,
|
||||
* shown in SUGGESTIONS tab. different from RelationshipType.SUGGESTION
|
||||
* which is for implicit suggestions in RelationshipStore
|
||||
*/
|
||||
type: RelationshipType | 99;
|
||||
status: StatusType;
|
||||
isMobile: boolean;
|
||||
activities: Activity[];
|
||||
applicationStream: ApplicationStream | null;
|
||||
user: User | null;
|
||||
usernameLower: string | null;
|
||||
mutualGuildsLength: number;
|
||||
mutualGuilds: Guild[];
|
||||
nickname: string | null;
|
||||
spam: boolean;
|
||||
giftIntentType: GiftIntentType | undefined;
|
||||
ignoredUser: boolean;
|
||||
applicationId: string | undefined;
|
||||
isGameRelationship: boolean;
|
||||
comparator: [RelationshipType | 99, string | null];
|
||||
}
|
||||
|
||||
export interface RelationshipCounts {
|
||||
[RelationshipType.FRIEND]: number;
|
||||
[RelationshipType.INCOMING_REQUEST]: number;
|
||||
[RelationshipType.OUTGOING_REQUEST]: number;
|
||||
[RelationshipType.BLOCKED]: number;
|
||||
/** contact based friend suggestions from FriendSuggestionStore */
|
||||
99: number;
|
||||
}
|
||||
|
||||
export interface FriendsRows {
|
||||
_rows: FriendsRow[];
|
||||
reset(): FriendsRows;
|
||||
clone(): FriendsRows;
|
||||
update(updater: (userId: string) => Partial<FriendsRow>): boolean;
|
||||
filter(section: FriendsSection, searchQuery?: string | null): FriendsRow[];
|
||||
getRelationshipCounts(): RelationshipCounts;
|
||||
}
|
||||
|
||||
export interface FriendsState {
|
||||
fetching: boolean;
|
||||
section: FriendsSection;
|
||||
rows: FriendsRows;
|
||||
}
|
||||
|
||||
export class FriendsStore extends FluxStore {
|
||||
getState(): FriendsState;
|
||||
}
|
||||
46
packages/discord-types/src/stores/GuildChannelStore.d.ts
vendored
Normal file
46
packages/discord-types/src/stores/GuildChannelStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import { Channel, FluxStore, ThreadJoined } from "..";
|
||||
import { ChannelType } from "../../enums";
|
||||
|
||||
export interface ChannelWithComparator {
|
||||
channel: Channel;
|
||||
comparator: number;
|
||||
}
|
||||
|
||||
export interface GuildChannels {
|
||||
[ChannelType.GUILD_CATEGORY]: ChannelWithComparator[];
|
||||
id: string;
|
||||
SELECTABLE: ChannelWithComparator[] | ThreadJoined[];
|
||||
VOCAL: ChannelWithComparator[];
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface ChannelNameDisambiguation {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export class GuildChannelStore extends FluxStore {
|
||||
getAllGuilds(): Record<string, GuildChannels>;
|
||||
getChannels(guildId: string): GuildChannels;
|
||||
getDefaultChannel(guildId: string): Channel | null;
|
||||
getDirectoryChannelIds(guildId: string): string[];
|
||||
getFirstChannel(
|
||||
guildId: string,
|
||||
predicate: (item: ChannelWithComparator) => boolean,
|
||||
includeVocal?: boolean
|
||||
): Channel | null;
|
||||
getFirstChannelOfType(
|
||||
guildId: string,
|
||||
predicate: (item: ChannelWithComparator) => boolean,
|
||||
type: "SELECTABLE" | "VOCAL" | ChannelType.GUILD_CATEGORY
|
||||
): Channel | null;
|
||||
getSFWDefaultChannel(guildId: string): Channel | null;
|
||||
getSelectableChannelIds(guildId: string): string[];
|
||||
getSelectableChannels(guildId: string): ChannelWithComparator[];
|
||||
getTextChannelNameDisambiguations(guildId: string): Record<string, ChannelNameDisambiguation>;
|
||||
getVocalChannelIds(guildId: string): string[];
|
||||
hasCategories(guildId: string): boolean;
|
||||
hasChannels(guildId: string): boolean;
|
||||
hasElevatedPermissions(guildId: string): boolean;
|
||||
hasSelectableChannel(guildId: string, channelId: string): boolean;
|
||||
}
|
||||
7
packages/discord-types/src/stores/GuildMemberCountStore.d.ts
vendored
Normal file
7
packages/discord-types/src/stores/GuildMemberCountStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { FluxStore } from "..";
|
||||
|
||||
export class GuildMemberCountStore extends FluxStore {
|
||||
getMemberCounts(): Record<string, number>;
|
||||
getMemberCount(guildId: string): number;
|
||||
getOnlineCount(guildId: string): number;
|
||||
}
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
import { FluxStore, GuildMember } from "..";
|
||||
|
||||
export interface PendingRoleUpdates {
|
||||
added: string[];
|
||||
removed: string[];
|
||||
}
|
||||
|
||||
export class GuildMemberStore extends FluxStore {
|
||||
/** @returns Format: [guildId-userId: Timestamp (string)] */
|
||||
getCommunicationDisabledUserMap(): Record<string, string>;
|
||||
|
|
@ -11,6 +16,10 @@ export class GuildMemberStore extends FluxStore {
|
|||
getTrueMember(guildId: string, userId: string): GuildMember | null;
|
||||
getMemberIds(guildId: string): string[];
|
||||
getMembers(guildId: string): GuildMember[];
|
||||
getMemberVersion(): number;
|
||||
getMemberRoleWithPendingUpdates(guildId: string, userId: string): string[];
|
||||
getPendingRoleUpdates(guildId: string): PendingRoleUpdates;
|
||||
memberOf(userId: string): string[];
|
||||
|
||||
getCachedSelfMember(guildId: string): GuildMember | null;
|
||||
getSelfMember(guildId: string): GuildMember | null;
|
||||
|
|
@ -20,7 +29,6 @@ export class GuildMemberStore extends FluxStore {
|
|||
getNicknameGuildsMapping(userId: string): Record<string, string[]>;
|
||||
getNicknames(userId: string): string[];
|
||||
|
||||
isMember(guildId: string, userId: string): boolean;
|
||||
isMember(guildId: string, userId: string): boolean;
|
||||
isGuestOrLurker(guildId: string, userId: string): boolean;
|
||||
isCurrentUserGuest(guildId: string): boolean;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { FluxStore, Guild, Role } from "..";
|
||||
|
||||
// TODO: add the rest of the methods for GuildRoleStore
|
||||
export class GuildRoleStore extends FluxStore {
|
||||
serializeAllGuildRoles(): Array<{ partitionKey: string; values: Record<string, Role>; }>;
|
||||
getUnsafeMutableRoles(guildId: string): Record<string, Role>;
|
||||
getManyRoles(guildId: string, roleIds: string[]): Role[];
|
||||
getRole(guildId: string, roleId: string): Role;
|
||||
getNumRoles(guildId: string): number;
|
||||
getEveryoneRole(guild: Guild): Role;
|
||||
getRolesSnapshot(guildId: string): Record<string, Role>;
|
||||
getSortedRoles(guildId: string): Role[];
|
||||
|
||||
getEveryoneRole(guild: Guild): Role;
|
||||
getManyRoles(guildId: string, roleIds: string[]): Role[];
|
||||
getNumRoles(guildId: string): number;
|
||||
getRole(guildId: string, roleId: string): Role;
|
||||
getUnsafeMutableRoles(guildId: string): Record<string, Role>;
|
||||
serializeAllGuildRoles(): Array<{ partitionKey: string; values: Record<string, Role>; }>;
|
||||
}
|
||||
|
|
|
|||
67
packages/discord-types/src/stores/GuildScheduledEventStore.d.ts
vendored
Normal file
67
packages/discord-types/src/stores/GuildScheduledEventStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import { FluxStore } from "..";
|
||||
import { GuildScheduledEventEntityType, GuildScheduledEventPrivacyLevel, GuildScheduledEventStatus, RecurrenceRuleFrequency } from "../../enums";
|
||||
|
||||
export interface GuildScheduledEventEntityMetadata {
|
||||
location?: string;
|
||||
}
|
||||
|
||||
export interface GuildScheduledEventRecurrenceRule {
|
||||
start: string;
|
||||
end: string | null;
|
||||
frequency: RecurrenceRuleFrequency;
|
||||
interval: number;
|
||||
byWeekday: number[] | null;
|
||||
byNWeekday: { n: number; day: number; }[] | null;
|
||||
byMonth: number[] | null;
|
||||
byMonthDay: number[] | null;
|
||||
byYearDay: number[] | null;
|
||||
count: number | null;
|
||||
}
|
||||
|
||||
export interface GuildScheduledEvent {
|
||||
id: string;
|
||||
guild_id: string;
|
||||
channel_id: string | null;
|
||||
creator_id: string | null;
|
||||
name: string;
|
||||
description: string | null;
|
||||
image: string | null;
|
||||
scheduled_start_time: string;
|
||||
scheduled_end_time: string | null;
|
||||
privacy_level: GuildScheduledEventPrivacyLevel;
|
||||
status: GuildScheduledEventStatus;
|
||||
entity_type: GuildScheduledEventEntityType;
|
||||
entity_id: string | null;
|
||||
entity_metadata: GuildScheduledEventEntityMetadata | null;
|
||||
sku_ids: string[];
|
||||
recurrence_rule: GuildScheduledEventRecurrenceRule | null;
|
||||
// TODO: type
|
||||
guild_scheduled_event_exceptions: any[];
|
||||
auto_start: boolean;
|
||||
}
|
||||
|
||||
export interface GuildScheduledEventRsvp {
|
||||
guildScheduledEventId: string;
|
||||
userId: string;
|
||||
interested: boolean;
|
||||
}
|
||||
|
||||
export interface GuildScheduledEventUsers {
|
||||
// TODO: finish typing
|
||||
[userId: string]: any;
|
||||
}
|
||||
|
||||
export class GuildScheduledEventStore extends FluxStore {
|
||||
getGuildScheduledEvent(eventId: string): GuildScheduledEvent | null;
|
||||
getGuildScheduledEventsForGuild(guildId: string): GuildScheduledEvent[];
|
||||
getGuildScheduledEventsByIndex(status: GuildScheduledEventStatus): GuildScheduledEvent[];
|
||||
getGuildEventCountByIndex(status: GuildScheduledEventStatus): number;
|
||||
getRsvpVersion(): number;
|
||||
getRsvp(eventId: string, recurrenceId: string | null, userId: string | null): GuildScheduledEventRsvp | null;
|
||||
isInterestedInEventRecurrence(eventId: string, recurrenceId: string | null): boolean;
|
||||
getUserCount(eventId: string, recurrenceId: string | null): number;
|
||||
hasUserCount(eventId: string, recurrenceId: string | null): boolean;
|
||||
isActive(eventId: string): boolean;
|
||||
getActiveEventByChannel(channelId: string): GuildScheduledEvent | null;
|
||||
getUsersForGuildEvent(eventId: string, recurrenceId: string | null): GuildScheduledEventUsers;
|
||||
}
|
||||
|
|
@ -4,5 +4,6 @@ export class GuildStore extends FluxStore {
|
|||
getGuild(guildId: string): Guild;
|
||||
getGuildCount(): number;
|
||||
getGuilds(): Record<string, Guild>;
|
||||
getGuildsArray(): Guild[];
|
||||
getGuildIds(): string[];
|
||||
}
|
||||
|
|
|
|||
17
packages/discord-types/src/stores/InstantInviteStore.d.ts
vendored
Normal file
17
packages/discord-types/src/stores/InstantInviteStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { FluxStore } from "..";
|
||||
import { Invite } from "./InviteStore";
|
||||
|
||||
export interface FriendInvite extends Invite {
|
||||
max_age: number;
|
||||
max_uses: number;
|
||||
uses: number;
|
||||
created_at: string;
|
||||
revoked?: boolean;
|
||||
}
|
||||
|
||||
export class InstantInviteStore extends FluxStore {
|
||||
getInvite(channelId: string): Invite;
|
||||
getFriendInvite(): FriendInvite | null;
|
||||
getFriendInvitesFetching(): boolean;
|
||||
canRevokeFriendInvite(): boolean;
|
||||
}
|
||||
39
packages/discord-types/src/stores/InviteStore.d.ts
vendored
Normal file
39
packages/discord-types/src/stores/InviteStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { Channel, FluxStore, Guild, User } from "..";
|
||||
import { Application } from "../common/Application";
|
||||
import { GuildScheduledEvent } from "./GuildScheduledEventStore";
|
||||
import { GuildScheduledEventPrivacyLevel, InviteTargetType } from "../../enums";
|
||||
|
||||
export interface StageInstance {
|
||||
id: string;
|
||||
guild_id: string;
|
||||
channel_id: string;
|
||||
topic: string;
|
||||
privacy_level: GuildScheduledEventPrivacyLevel;
|
||||
discoverable_disabled: boolean;
|
||||
guild_scheduled_event_id: string | null;
|
||||
}
|
||||
|
||||
export interface Invite {
|
||||
code: string;
|
||||
guild: Guild | null;
|
||||
channel: Channel | null;
|
||||
inviter: User | null;
|
||||
approximate_member_count?: number;
|
||||
approximate_presence_count?: number;
|
||||
expires_at?: string | null;
|
||||
flags?: number;
|
||||
target_type?: InviteTargetType;
|
||||
target_user?: User;
|
||||
target_application?: Application;
|
||||
stage_instance?: StageInstance;
|
||||
guild_scheduled_event?: GuildScheduledEvent;
|
||||
}
|
||||
|
||||
export class InviteStore extends FluxStore {
|
||||
getInvite(code: string): Invite;
|
||||
// TODO: finish typing
|
||||
getInviteError(code: string): any | undefined;
|
||||
getInvites(): Record<string, Invite>;
|
||||
getInviteKeyForGuildId(guildId: string): string | undefined;
|
||||
getFriendMemberIds(code: string): string[] | undefined;
|
||||
}
|
||||
6
packages/discord-types/src/stores/LocaleStore.d.ts
vendored
Normal file
6
packages/discord-types/src/stores/LocaleStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import { FluxStore } from "..";
|
||||
|
||||
export class LocaleStore extends FluxStore {
|
||||
get locale(): string;
|
||||
get systemLocale(): string;
|
||||
}
|
||||
2738
packages/discord-types/src/stores/MediaEngineStore.d.ts
vendored
2738
packages/discord-types/src/stores/MediaEngineStore.d.ts
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -1,13 +1,55 @@
|
|||
import { MessageJSON, FluxStore, Message } from "..";
|
||||
import { FluxStore, Message } from "..";
|
||||
|
||||
export type JumpType = "ANIMATED" | "INSTANT";
|
||||
|
||||
export interface MessageCache {
|
||||
_messages: Message[];
|
||||
_map: Record<string, Message>;
|
||||
_wasAtEdge: boolean;
|
||||
_isCacheBefore: boolean;
|
||||
}
|
||||
|
||||
export interface ChannelMessages {
|
||||
channelId: string;
|
||||
ready: boolean;
|
||||
cached: boolean;
|
||||
jumpType: JumpType;
|
||||
jumpTargetId: string | null;
|
||||
jumpTargetOffset: number;
|
||||
jumpSequenceId: number;
|
||||
jumped: boolean;
|
||||
jumpedToPresent: boolean;
|
||||
jumpFlash: boolean;
|
||||
jumpReturnTargetId: string | null;
|
||||
focusTargetId: string | null;
|
||||
focusSequenceId: number;
|
||||
initialScrollSequenceId: number;
|
||||
hasMoreBefore: boolean;
|
||||
hasMoreAfter: boolean;
|
||||
loadingMore: boolean;
|
||||
revealedMessageId: string | null;
|
||||
hasFetched: boolean;
|
||||
error: boolean;
|
||||
_array: Message[];
|
||||
_before: MessageCache;
|
||||
_after: MessageCache;
|
||||
_map: Record<string, Message>;
|
||||
}
|
||||
|
||||
export class MessageStore extends FluxStore {
|
||||
focusedMessageId(channelId: string): string | undefined;
|
||||
getLastChatCommandMessage(channelId: string): Message | undefined;
|
||||
getLastEditableMessage(channelId: string): Message | undefined;
|
||||
getLastMessage(channelId: string): Message | undefined;
|
||||
getLastNonCurrentUserMessage(channelId: string): Message | undefined;
|
||||
getMessage(channelId: string, messageId: string): Message;
|
||||
/** @returns This return object is fucking huge; I'll type it later. */
|
||||
getMessages(channelId: string): unknown;
|
||||
getRawMessages(channelId: string): Record<string | number, MessageJSON>;
|
||||
/** @see {@link ChannelMessages} */
|
||||
getMessages(channelId: string): ChannelMessages;
|
||||
hasCurrentUserSentMessage(channelId: string): boolean;
|
||||
hasCurrentUserSentMessageSinceAppStart(channelId: string): boolean;
|
||||
hasPresent(channelId: string): boolean;
|
||||
isLoadingMessages(channelId: string): boolean;
|
||||
isReady(channelId: string): boolean;
|
||||
jumpedMessageId(channelId: string): string | undefined;
|
||||
whenReady(channelId: string, callback: () => void): void;
|
||||
}
|
||||
|
|
|
|||
26
packages/discord-types/src/stores/NotificationSettingsStore.d.ts
vendored
Normal file
26
packages/discord-types/src/stores/NotificationSettingsStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { FluxStore } from "..";
|
||||
|
||||
export type DesktopNotificationType = "ALL" | "ONLY_MENTIONS" | "NEVER";
|
||||
export type TTSNotificationType = "ALL" | "ONLY_MENTIONS" | "NEVER";
|
||||
|
||||
export interface NotificationSettingsState {
|
||||
desktopType: DesktopNotificationType;
|
||||
disableAllSounds: boolean;
|
||||
disabledSounds: string[];
|
||||
ttsType: TTSNotificationType;
|
||||
disableUnreadBadge: boolean;
|
||||
taskbarFlash: boolean;
|
||||
notifyMessagesInSelectedChannel: boolean;
|
||||
}
|
||||
|
||||
export class NotificationSettingsStore extends FluxStore {
|
||||
get taskbarFlash(): boolean;
|
||||
getUserAgnosticState(): NotificationSettingsState;
|
||||
getDesktopType(): DesktopNotificationType;
|
||||
getTTSType(): TTSNotificationType;
|
||||
getDisabledSounds(): string[];
|
||||
getDisableAllSounds(): boolean;
|
||||
getDisableUnreadBadge(): boolean;
|
||||
getNotifyMessagesInSelectedChannel(): boolean;
|
||||
isSoundDisabled(sound: string): boolean;
|
||||
}
|
||||
16
packages/discord-types/src/stores/OverridePremiumTypeStore.d.ts
vendored
Normal file
16
packages/discord-types/src/stores/OverridePremiumTypeStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { FluxStore } from "..";
|
||||
import { PremiumType } from "../../enums";
|
||||
|
||||
export interface OverridePremiumTypeState {
|
||||
createdAtOverride: Date | undefined;
|
||||
premiumTypeActual: PremiumType | null;
|
||||
premiumTypeOverride: PremiumType | undefined;
|
||||
}
|
||||
|
||||
export class OverridePremiumTypeStore extends FluxStore {
|
||||
getState(): OverridePremiumTypeState;
|
||||
getCreatedAtOverride(): Date | undefined;
|
||||
getPremiumTypeActual(): PremiumType | null;
|
||||
getPremiumTypeOverride(): PremiumType | undefined;
|
||||
get premiumType(): PremiumType | undefined;
|
||||
}
|
||||
57
packages/discord-types/src/stores/PermissionStore.d.ts
vendored
Normal file
57
packages/discord-types/src/stores/PermissionStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import { Channel, Guild, Role, FluxStore } from "..";
|
||||
|
||||
export interface GuildPermissionProps {
|
||||
canManageGuild: boolean;
|
||||
canManageChannels: boolean;
|
||||
canManageRoles: boolean;
|
||||
canManageBans: boolean;
|
||||
canManageNicknames: boolean;
|
||||
canManageGuildExpressions: boolean;
|
||||
canViewAuditLog: boolean;
|
||||
canViewAuditLogV2: boolean;
|
||||
canManageWebhooks: boolean;
|
||||
canViewGuildAnalytics: boolean;
|
||||
canAccessMembersPage: boolean;
|
||||
isGuildAdmin: boolean;
|
||||
isOwner: boolean;
|
||||
isOwnerWithRequiredMfaLevel: boolean;
|
||||
guild: Guild;
|
||||
}
|
||||
|
||||
export interface PartialChannelContext {
|
||||
channelId: string;
|
||||
}
|
||||
|
||||
export interface PartialGuildContext {
|
||||
guildId: string;
|
||||
}
|
||||
|
||||
export type PartialContext = PartialChannelContext | PartialGuildContext;
|
||||
|
||||
type PartialChannel = Channel | { id: string; };
|
||||
type PartialGuild = Guild | { id: string; };
|
||||
|
||||
export class PermissionStore extends FluxStore {
|
||||
// TODO: finish typing these
|
||||
can(permission: bigint, channelOrGuild: PartialChannel | PartialGuild, guildId?: string, overwrites?: Record<string, any>, userId?: string): boolean;
|
||||
canBasicChannel(permission: bigint, channel: PartialChannel, guildId?: string, overwrites?: Record<string, any>, userId?: string): boolean;
|
||||
canWithPartialContext(permission: bigint, context: PartialContext): boolean;
|
||||
canManageUser(permission: bigint, userOrUserId: string, guild: PartialGuild): boolean;
|
||||
canAccessGuildSettings(guild: PartialGuild): boolean;
|
||||
canAccessMemberSafetyPage(guild: PartialGuild): boolean;
|
||||
canImpersonateRole(guild: PartialGuild, role: Role): boolean;
|
||||
|
||||
// TODO: finish typing
|
||||
computePermissions(channel: PartialChannel, guildId?: string, overwrites?: Record<string, any>, userId?: string): bigint;
|
||||
computeBasicPermissions(channel: PartialChannel): number;
|
||||
|
||||
getChannelPermissions(channel: PartialChannel): bigint;
|
||||
getGuildPermissions(guild: PartialGuild): bigint;
|
||||
getGuildPermissionProps(guild: PartialGuild): GuildPermissionProps;
|
||||
|
||||
getHighestRole(guild: PartialGuild): Role | null;
|
||||
isRoleHigher(guild: PartialGuild, firstRole: Role | null, secondRole: Role | null): boolean;
|
||||
|
||||
getGuildVersion(guildId: string): number;
|
||||
getChannelsVersion(): number;
|
||||
}
|
||||
|
|
@ -8,17 +8,29 @@ export interface UserAndActivity {
|
|||
|
||||
export type DiscordPlatform = "desktop" | "mobile" | "web" | "embedded";
|
||||
|
||||
export interface PresenceStoreState {
|
||||
presencesForGuilds: Record<string, Record<string, { status: OnlineStatus; activities: Activity[]; clientStatus: Partial<Record<DiscordPlatform, OnlineStatus>>; }>>;
|
||||
statuses: Record<string, OnlineStatus>;
|
||||
activities: Record<string, Activity[]>;
|
||||
filteredActivities: Record<string, Activity[]>;
|
||||
hiddenActivities: Record<string, Activity[]>;
|
||||
// TODO: finish typing
|
||||
activityMetadata: Record<string, any>;
|
||||
clientStatuses: Record<string, Partial<Record<DiscordPlatform, OnlineStatus>>>;
|
||||
}
|
||||
|
||||
export class PresenceStore extends FluxStore {
|
||||
findActivity(userId: string, predicate: (activity: Activity) => boolean, guildId?: string): Activity | undefined;
|
||||
getActivities(userId: string, guildId?: string): Activity[];
|
||||
// TODO: finish typing
|
||||
getActivityMetadata(userId: string): any;
|
||||
getAllApplicationActivities(applicationId: string): UserAndActivity[];
|
||||
getApplicationActivity(userId: string, applicationId: string, guildId?: string): Activity | null;
|
||||
getClientStatus(userId: string): Record<DiscordPlatform, OnlineStatus>;
|
||||
getHiddenActivities(): any;
|
||||
getHiddenActivities(): Activity[];
|
||||
/** literally just getActivities(...)[0] */
|
||||
getPrimaryActivity(userId: string, guildId?: string): Activity | null;
|
||||
getState(): any;
|
||||
getState(): PresenceStoreState;
|
||||
getStatus(userId: string, guildId?: string | null, defaultStatus?: OnlineStatus): OnlineStatus;
|
||||
getUnfilteredActivities(userId: string, guildId?: string): Activity[];
|
||||
getUserIds(): string[];
|
||||
|
|
|
|||
83
packages/discord-types/src/stores/RTCConnectionStore.d.ts
vendored
Normal file
83
packages/discord-types/src/stores/RTCConnectionStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
import { FluxStore } from "..";
|
||||
|
||||
export type RTCConnectionState =
|
||||
| "DISCONNECTED"
|
||||
| "AWAITING_ENDPOINT"
|
||||
| "AUTHENTICATING"
|
||||
| "CONNECTING"
|
||||
| "RTC_DISCONNECTED"
|
||||
| "RTC_CONNECTING"
|
||||
| "RTC_CONNECTED"
|
||||
| "NO_ROUTE"
|
||||
| "ICE_CHECKING"
|
||||
| "DTLS_CONNECTING";
|
||||
|
||||
export type RTCConnectionQuality = "unknown" | "bad" | "average" | "fine";
|
||||
|
||||
export interface LastRTCConnectionState {
|
||||
duration: number | null;
|
||||
mediaSessionId: string | null;
|
||||
rtcConnectionId: string | null;
|
||||
wasEverMultiParticipant: boolean;
|
||||
wasEverRtcConnected: boolean;
|
||||
// TODO: type
|
||||
voiceStateAnalytics: any;
|
||||
channelId: string;
|
||||
}
|
||||
|
||||
export interface RTCConnectionPacketStats {
|
||||
inbound: number;
|
||||
outbound: number;
|
||||
lost: number;
|
||||
}
|
||||
|
||||
export interface VoiceStateStats {
|
||||
max_voice_state_count: number;
|
||||
}
|
||||
|
||||
export interface SecureFramesState {
|
||||
version: number;
|
||||
epochAuthenticator: string;
|
||||
}
|
||||
|
||||
export interface SecureFramesRosterMapEntry {
|
||||
pendingVerifyState: number;
|
||||
verifiedState: number;
|
||||
}
|
||||
|
||||
export class RTCConnectionStore extends FluxStore {
|
||||
// TODO: type
|
||||
getRTCConnection(): any | null;
|
||||
getState(): RTCConnectionState;
|
||||
isConnected(): boolean;
|
||||
isDisconnected(): boolean;
|
||||
getRemoteDisconnectVoiceChannelId(): string | null;
|
||||
getLastSessionVoiceChannelId(): string | null;
|
||||
setLastSessionVoiceChannelId(channelId: string | null): void;
|
||||
getGuildId(): string | undefined;
|
||||
getChannelId(): string | undefined;
|
||||
getHostname(): string;
|
||||
getQuality(): RTCConnectionQuality;
|
||||
getPings(): number[];
|
||||
getAveragePing(): number;
|
||||
getLastPing(): number | undefined;
|
||||
getOutboundLossRate(): number | undefined;
|
||||
getMediaSessionId(): string | undefined;
|
||||
getRTCConnectionId(): string | undefined;
|
||||
getDuration(): number | undefined;
|
||||
getLastRTCConnectionState(): LastRTCConnectionState | null;
|
||||
getVoiceFilterSpeakingDurationMs(): number | undefined;
|
||||
getPacketStats(): RTCConnectionPacketStats | undefined;
|
||||
getVoiceStateStats(): VoiceStateStats | undefined;
|
||||
// TODO: finish typing
|
||||
getUserVoiceSettingsStats(userId: string): any | undefined;
|
||||
getWasEverMultiParticipant(): boolean;
|
||||
getWasEverRtcConnected(): boolean;
|
||||
getUserIds(): string[] | undefined;
|
||||
getJoinVoiceId(): string | null;
|
||||
isUserConnected(userId: string): boolean | undefined;
|
||||
getSecureFramesState(): SecureFramesState | undefined;
|
||||
getSecureFramesRosterMapEntry(oderId: string): SecureFramesRosterMapEntry | undefined;
|
||||
getLastNonZeroRemoteVideoSinkWantsTime(): number | null;
|
||||
getWasMoved(): boolean;
|
||||
}
|
||||
70
packages/discord-types/src/stores/ReadStateStore.d.ts
vendored
Normal file
70
packages/discord-types/src/stores/ReadStateStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import { Channel, FluxStore } from "..";
|
||||
import { ReadStateType } from "../../enums";
|
||||
|
||||
export interface GuildChannelUnreadState {
|
||||
mentionCount: number;
|
||||
unread: boolean;
|
||||
isMentionLowImportance: boolean;
|
||||
}
|
||||
|
||||
export interface ReadStateSnapshot {
|
||||
unread: boolean;
|
||||
mentionCount: number;
|
||||
guildUnread: boolean | null;
|
||||
guildMentionCount: number | null;
|
||||
takenAt: number;
|
||||
}
|
||||
|
||||
export interface SerializedReadState {
|
||||
channelId: string;
|
||||
type: ReadStateType;
|
||||
_guildId: string;
|
||||
_persisted: boolean;
|
||||
_lastMessageId: string;
|
||||
_lastMessageTimestamp: number;
|
||||
_ackMessageId: string;
|
||||
_ackMessageTimestamp: number;
|
||||
ackPinTimestamp: number;
|
||||
lastPinTimestamp: number;
|
||||
_mentionCount: number;
|
||||
flags: number;
|
||||
lastViewed: number;
|
||||
}
|
||||
|
||||
export class ReadStateStore extends FluxStore {
|
||||
ackMessageId(channelId: string, type?: ReadStateType): string | null;
|
||||
getAllReadStates(includePrivate?: boolean): SerializedReadState[];
|
||||
getChannelIdsForWindowId(windowId: string): string[];
|
||||
getForDebugging(channelId: string): object | undefined;
|
||||
getGuildChannelUnreadState(
|
||||
channel: Channel,
|
||||
isOptInEnabled: boolean,
|
||||
guildHasActiveThreads: boolean,
|
||||
isChannelMuted: boolean,
|
||||
isGuildHome: boolean
|
||||
): GuildChannelUnreadState;
|
||||
getGuildUnreadsSentinel(guildId: string): number;
|
||||
getIsMentionLowImportance(channelId: string, type?: ReadStateType): boolean;
|
||||
getMentionChannelIds(): string[];
|
||||
getMentionCount(channelId: string, type?: ReadStateType): number;
|
||||
getNonChannelAckId(type: ReadStateType): string | null;
|
||||
getNotifCenterReadState(channelId: string): object | undefined;
|
||||
getOldestUnreadMessageId(channelId: string, type?: ReadStateType): string | null;
|
||||
getOldestUnreadTimestamp(channelId: string, type?: ReadStateType): number;
|
||||
getReadStatesByChannel(): Record<string, object>;
|
||||
getSnapshot(channelId: string, maxAge: number): ReadStateSnapshot;
|
||||
getTrackedAckMessageId(channelId: string, type?: ReadStateType): string | null;
|
||||
getUnreadCount(channelId: string, type?: ReadStateType): number;
|
||||
hasOpenedThread(channelId: string): boolean;
|
||||
hasRecentlyVisitedAndRead(channelId: string): boolean;
|
||||
hasTrackedUnread(channelId: string): boolean;
|
||||
hasUnread(channelId: string, type?: ReadStateType): boolean;
|
||||
hasUnreadOrMentions(channelId: string, type?: ReadStateType): boolean;
|
||||
hasUnreadPins(channelId: string): boolean;
|
||||
isEstimated(channelId: string, type?: ReadStateType): boolean;
|
||||
isForumPostUnread(channelId: string): boolean;
|
||||
isNewForumThread(threadId: string, parentChannelId: string, guildId: string): boolean;
|
||||
lastMessageId(channelId: string, type?: ReadStateType): string | null;
|
||||
lastMessageTimestamp(channelId: string, type?: ReadStateType): number;
|
||||
lastPinTimestamp(channelId: string): number;
|
||||
}
|
||||
|
|
@ -1,38 +1,43 @@
|
|||
import { FluxStore } from "..";
|
||||
import { Message, MessageJSON } from "../common/messages";
|
||||
import { RelationshipType } from "../../enums";
|
||||
|
||||
export class RelationshipStore extends FluxStore {
|
||||
getFriendIDs(): string[];
|
||||
getIgnoredIDs(): string[];
|
||||
getBlockedIDs(): string[];
|
||||
getBlockedOrIgnoredIDs(): string[];
|
||||
|
||||
getPendingCount(): number;
|
||||
getRelationshipCount(): number;
|
||||
|
||||
/** Related to friend nicknames. */
|
||||
getNickname(userId: string): string;
|
||||
|
||||
/** @returns Enum value from constants.RelationshipTypes */
|
||||
getRelationshipType(userId: string): number;
|
||||
isBlockedOrIgnored(userId: string): boolean;
|
||||
isBlockedOrIgnoredForMessage(userId: string): boolean;
|
||||
isBlocked(userId: string): boolean;
|
||||
isBlockedForMessage(userId: string): boolean;
|
||||
isFriend(userId: string): boolean;
|
||||
isIgnored(userId: string): boolean;
|
||||
isIgnoredForMessage(userId: string): boolean;
|
||||
isUnfilteredPendingIncoming(userId: string): boolean;
|
||||
isSpam(userId): boolean;
|
||||
getSince(userId: string): string;
|
||||
getSinces(): Record<number, string>;
|
||||
|
||||
getFriendCount(): number;
|
||||
getRelationshipCount(): number;
|
||||
getFriendIDs(): string[];
|
||||
getIgnoredIDs(): string[];
|
||||
|
||||
getMutableRelationships(): Map<string, RelationshipType>;
|
||||
getNickname(userId: string): string;
|
||||
getOriginApplicationId(userId: string): string | undefined;
|
||||
getOutgoingCount(): number;
|
||||
getPendingCount(): number;
|
||||
getPendingIgnoredCount(): number;
|
||||
getSpamCount(): number;
|
||||
getRelationshipCount(): number;
|
||||
|
||||
getMutableRelationships(): Map<string, number>;
|
||||
/** @returns Enum value from constants.RelationshipTypes */
|
||||
getRelationshipType(userId: string): RelationshipType;
|
||||
getSince(userId: string): string;
|
||||
getSinces(): Record<string, string>;
|
||||
getSpamCount(): number;
|
||||
getVersion(): number;
|
||||
|
||||
isBlocked(userId: string): boolean;
|
||||
isBlockedForMessage(message: Message | MessageJSON): boolean;
|
||||
|
||||
/**
|
||||
* @see {@link isBlocked}
|
||||
* @see {@link isIgnored}
|
||||
*/
|
||||
isBlockedOrIgnored(userId: string): boolean;
|
||||
isBlockedOrIgnoredForMessage(message: Message | MessageJSON): boolean;
|
||||
|
||||
isFriend(userId: string): boolean;
|
||||
isIgnored(userId: string): boolean;
|
||||
isIgnoredForMessage(message: Message | MessageJSON): boolean;
|
||||
isSpam(userId: string): boolean;
|
||||
isStranger(userId: string): boolean;
|
||||
isUnfilteredPendingIncoming(userId: string): boolean;
|
||||
}
|
||||
|
|
|
|||
62
packages/discord-types/src/stores/RunningGameStore.d.ts
vendored
Normal file
62
packages/discord-types/src/stores/RunningGameStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import { FluxStore } from "..";
|
||||
|
||||
export interface RunningGame {
|
||||
id?: string;
|
||||
name: string;
|
||||
exePath: string;
|
||||
cmdLine: string;
|
||||
distributor: string;
|
||||
lastFocused: number;
|
||||
lastLaunched: number;
|
||||
nativeProcessObserverId: number;
|
||||
pid?: number;
|
||||
hidden?: boolean;
|
||||
isLauncher?: boolean;
|
||||
elevated?: boolean;
|
||||
sandboxed?: boolean;
|
||||
}
|
||||
|
||||
export interface GameOverlayStatus {
|
||||
enabledLegacy: boolean;
|
||||
enabledOOP: boolean;
|
||||
}
|
||||
|
||||
export type SystemServiceState = "unknown" | "running" | "stopped" | "error";
|
||||
|
||||
export interface SystemServiceStatus {
|
||||
state: SystemServiceState;
|
||||
}
|
||||
|
||||
export class RunningGameStore extends FluxStore {
|
||||
canShowAdminWarning: boolean;
|
||||
|
||||
addExecutableTrackedByAnalytics(exe: string): void;
|
||||
getCandidateGames(): RunningGame[];
|
||||
getCurrentGameForAnalytics(): RunningGame | null;
|
||||
getCurrentNonGameForAnalytics(): RunningGame | null;
|
||||
getGameForName(name: string): RunningGame | null;
|
||||
getGameForPID(pid: number): RunningGame | null;
|
||||
getGameOrTransformedSubgameForPID(pid: number): RunningGame | null;
|
||||
getGameOverlayStatus(game: RunningGame): GameOverlayStatus | null;
|
||||
getGamesSeen(includeHidden?: boolean): RunningGame[];
|
||||
getLauncherForPID(pid: number): RunningGame | null;
|
||||
getObservedAppNameForWindow(windowHandle: number): string | null;
|
||||
getOverlayEnabledForGame(game: RunningGame): boolean;
|
||||
getOverlayOptionsForPID(pid: number): object | null;
|
||||
getOverrideForGame(game: RunningGame): object | null;
|
||||
getOverrides(): object[];
|
||||
getRunningDiscordApplicationIds(): string[];
|
||||
getRunningGames(): RunningGame[];
|
||||
getRunningNonGames(): RunningGame[];
|
||||
getRunningVerifiedApplicationIds(): string[];
|
||||
getSeenGameByName(name: string): RunningGame | null;
|
||||
getSystemServiceStatus(service: string): SystemServiceStatus;
|
||||
getVisibleGame(): RunningGame | null;
|
||||
getVisibleRunningGames(): RunningGame[];
|
||||
isDetectionEnabled(type?: string): boolean;
|
||||
isGamesSeenLoaded(): boolean;
|
||||
isObservedAppRunning(app: string): boolean;
|
||||
isSystemServiceInitialized(service: string): boolean;
|
||||
shouldContinueWithoutElevatedProcessForPID(pid: number): boolean;
|
||||
shouldElevateProcessForPID(pid: number): boolean;
|
||||
}
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
import { FluxStore } from "..";
|
||||
|
||||
export interface ChannelFollowingDestination {
|
||||
guildId?: string;
|
||||
channelId?: string;
|
||||
}
|
||||
|
||||
export class SelectedChannelStore extends FluxStore {
|
||||
getChannelId(guildId?: string | null): string;
|
||||
getVoiceChannelId(): string | undefined;
|
||||
getCurrentlySelectedChannelId(guildId?: string): string | undefined;
|
||||
getMostRecentSelectedTextChannelId(guildId: string): string | undefined;
|
||||
getLastSelectedChannelId(guildId?: string): string;
|
||||
// yes this returns a string
|
||||
getLastSelectedChannels(guildId?: string): string;
|
||||
|
||||
/** If you follow an announcement channel, this will return whichever channel you chose as destination */
|
||||
getLastChannelFollowingDestination(): { guildId?: string; channelId?: string; } | undefined;
|
||||
getLastChannelFollowingDestination(): ChannelFollowingDestination | undefined;
|
||||
}
|
||||
|
|
|
|||
47
packages/discord-types/src/stores/SoundboardStore.d.ts
vendored
Normal file
47
packages/discord-types/src/stores/SoundboardStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { FluxStore } from "..";
|
||||
|
||||
export interface SoundboardSound {
|
||||
soundId: string;
|
||||
name: string;
|
||||
volume: number;
|
||||
emojiId: string | null;
|
||||
emojiName: string | null;
|
||||
available: boolean;
|
||||
guildId: string;
|
||||
userId?: string;
|
||||
}
|
||||
|
||||
export interface TopSoundForGuild {
|
||||
soundId: string;
|
||||
rank: number;
|
||||
}
|
||||
|
||||
export interface SoundboardOverlayState {
|
||||
soundboardSounds: Record<string, SoundboardSound[]>;
|
||||
favoritedSoundIds: string[];
|
||||
localSoundboardMutes: string[];
|
||||
}
|
||||
|
||||
export class SoundboardStore extends FluxStore {
|
||||
getOverlaySerializedState(): SoundboardOverlayState;
|
||||
getSounds(): Map<string, SoundboardSound[]>;
|
||||
getSoundsForGuild(guildId: string): SoundboardSound[] | null;
|
||||
getSound(guildId: string, soundId: string): SoundboardSound;
|
||||
getSoundById(soundId: string): SoundboardSound;
|
||||
isFetchingSounds(): boolean;
|
||||
isFetchingDefaultSounds(): boolean;
|
||||
isFetching(): boolean;
|
||||
shouldFetchDefaultSounds(): boolean;
|
||||
hasFetchedDefaultSounds(): boolean;
|
||||
isUserPlayingSounds(userId: string): boolean;
|
||||
isPlayingSound(soundId: string): boolean;
|
||||
isFavoriteSound(soundId: string): boolean;
|
||||
getFavorites(): Set<string>;
|
||||
getAllTopSoundsForGuilds(): Map<string, TopSoundForGuild[]>;
|
||||
isLocalSoundboardMuted(userId: string): boolean;
|
||||
hasHadOtherUserPlaySoundInSession(): boolean;
|
||||
shouldFetchTopSoundsForGuilds(): boolean;
|
||||
hasFetchedTopSoundsForGuilds(): boolean;
|
||||
hasFetchedAllSounds(): boolean;
|
||||
isFetchingAnySounds(): boolean;
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import { FluxStore } from "..";
|
||||
|
||||
export class SpellCheckStore extends FluxStore {
|
||||
hasLearnedWord(word: string): boolean;
|
||||
isEnabled(): boolean;
|
||||
}
|
||||
|
|
|
|||
111
packages/discord-types/src/stores/SpotifyStore.d.ts
vendored
Normal file
111
packages/discord-types/src/stores/SpotifyStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
import { FluxStore } from "..";
|
||||
import { ActivityFlags } from "../../enums";
|
||||
|
||||
export type SpotifyDeviceType = "computer" | "smartphone" | "speaker" | "tv" | "game_console" | "automobile" | "unknown";
|
||||
export type SpotifyMediaType = "track" | "episode";
|
||||
export type SpotifyAlbumType = "album" | "single" | "compilation";
|
||||
|
||||
export interface SpotifyDevice {
|
||||
id: string;
|
||||
is_active: boolean;
|
||||
is_private_session: boolean;
|
||||
is_restricted: boolean;
|
||||
name: string;
|
||||
supports_volume: boolean;
|
||||
type: SpotifyDeviceType;
|
||||
volume_percent: number;
|
||||
}
|
||||
|
||||
export interface SpotifySocket {
|
||||
accessToken: string;
|
||||
accountId: string;
|
||||
connectionId: string;
|
||||
isPremium: boolean;
|
||||
socket: WebSocket;
|
||||
}
|
||||
|
||||
export interface SpotifySocketAndDevice {
|
||||
socket: SpotifySocket;
|
||||
device: SpotifyDevice;
|
||||
}
|
||||
|
||||
export interface SpotifyArtist {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface SpotifyImage {
|
||||
url: string;
|
||||
height: number;
|
||||
width: number;
|
||||
}
|
||||
|
||||
export interface SpotifyAlbum {
|
||||
id: string;
|
||||
name: string;
|
||||
type: SpotifyAlbumType;
|
||||
image: SpotifyImage | null;
|
||||
}
|
||||
|
||||
export interface SpotifyTrack {
|
||||
id: string;
|
||||
name: string;
|
||||
duration: number;
|
||||
isLocal: boolean;
|
||||
type: SpotifyMediaType;
|
||||
album: SpotifyAlbum;
|
||||
artists: SpotifyArtist[];
|
||||
}
|
||||
|
||||
export interface SpotifyPlayerState {
|
||||
track: SpotifyTrack;
|
||||
startTime: number;
|
||||
context: { uri: string } | null;
|
||||
}
|
||||
|
||||
export interface SpotifyActivity {
|
||||
name: string;
|
||||
assets: {
|
||||
large_image?: string;
|
||||
large_text?: string;
|
||||
};
|
||||
details: string;
|
||||
state: string | undefined;
|
||||
timestamps: {
|
||||
start: number;
|
||||
end: number;
|
||||
};
|
||||
party: {
|
||||
id: string;
|
||||
};
|
||||
sync_id?: string;
|
||||
flags?: ActivityFlags;
|
||||
metadata?: {
|
||||
context_uri: string | undefined;
|
||||
album_id: string;
|
||||
artist_ids: string[];
|
||||
type: SpotifyMediaType;
|
||||
button_urls: string[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface SpotifySyncingWith {
|
||||
oderId: string;
|
||||
partyId: string;
|
||||
sessionId: string;
|
||||
userId: string;
|
||||
}
|
||||
|
||||
export class SpotifyStore extends FluxStore {
|
||||
hasConnectedAccount(): boolean;
|
||||
getActiveSocketAndDevice(): SpotifySocketAndDevice | null;
|
||||
getPlayableComputerDevices(): SpotifySocketAndDevice[];
|
||||
canPlay(deviceId: string): boolean;
|
||||
getSyncingWith(): SpotifySyncingWith | undefined;
|
||||
wasAutoPaused(): boolean;
|
||||
getLastPlayedTrackId(): string | undefined;
|
||||
getTrack(): SpotifyTrack | null;
|
||||
getPlayerState(accountId: string): SpotifyPlayerState | null;
|
||||
shouldShowActivity(): boolean;
|
||||
getActivity(): SpotifyActivity | null;
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import { FluxStore, GuildSticker, PremiumStickerPack, Sticker } from "..";
|
||||
import { LoadState } from "../../enums";
|
||||
|
||||
export type StickerGuildMap = Map<string, GuildSticker[]>;
|
||||
export type StickerPackMap = Map<string, Sticker[]>;
|
||||
|
||||
export interface StickerPackMeta {
|
||||
id: string;
|
||||
|
|
@ -33,15 +35,24 @@ export interface StickerCategoryType {
|
|||
iconUrl?: string;
|
||||
}
|
||||
|
||||
export class StickersStore extends FluxStore {
|
||||
getAllGuildStickers(): StickerGuildMap;
|
||||
getRawStickersByGuild(): StickerGuildMap;
|
||||
getPremiumPacks(): PremiumStickerPack[];
|
||||
getAllStickersIterator(): IterableIterator<Sticker>;
|
||||
export interface StickerMetadataEntry {
|
||||
type: number;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export class StickersStore extends FluxStore {
|
||||
hasLoadedStickerPacks: boolean;
|
||||
isFetchingStickerPacks: boolean;
|
||||
isLoaded: boolean;
|
||||
loadState: LoadState;
|
||||
|
||||
getAllGuildStickers(): StickerGuildMap;
|
||||
getAllPackStickers(): StickerPackMap;
|
||||
getPremiumPacks(): PremiumStickerPack[];
|
||||
getRawStickersByGuild(): StickerGuildMap;
|
||||
getStickerById(id: string): Sticker | undefined;
|
||||
getStickerMetadataArrays(): [Record<string, StickerMetadataEntry[]>, Record<string, StickerMetadataEntry[]>];
|
||||
getStickerPack(id: string): PremiumStickerPack | undefined;
|
||||
getStickersByGuildId(guildId: string): Sticker[] | undefined;
|
||||
|
||||
isPremiumPack(id: string): boolean;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,14 @@
|
|||
import { FluxStore } from "@vencord/discord-types";
|
||||
import { FluxStore } from "..";
|
||||
|
||||
export interface StreamerModeSettings {
|
||||
enabled: boolean;
|
||||
autoToggle: boolean;
|
||||
hideInstantInvites: boolean;
|
||||
hidePersonalInformation: boolean;
|
||||
disableSounds: boolean;
|
||||
disableNotifications: boolean;
|
||||
enableContentProtection: boolean;
|
||||
}
|
||||
|
||||
export class StreamerModeStore extends FluxStore {
|
||||
get autoToggle(): boolean;
|
||||
|
|
@ -8,4 +18,7 @@ export class StreamerModeStore extends FluxStore {
|
|||
get enabled(): boolean;
|
||||
get hideInstantInvites(): boolean;
|
||||
get hidePersonalInformation(): boolean;
|
||||
|
||||
getSettings(): StreamerModeSettings;
|
||||
getState(): Record<string, StreamerModeSettings>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@ export type Theme = "light" | "dark" | "darker" | "midnight";
|
|||
|
||||
export interface ThemeState {
|
||||
theme: Theme;
|
||||
/** 0 = not loaded, 1 = loaded */
|
||||
status: 0 | 1;
|
||||
preferences: Record<ThemePreference, Theme>;
|
||||
}
|
||||
export class ThemeStore extends FluxStore {
|
||||
get theme(): Theme;
|
||||
get darkSidebar(): boolean;
|
||||
get systemTheme(): SystemTheme;
|
||||
themePreferenceForSystemTheme(preference: ThemePreference): Theme;
|
||||
get theme(): Theme;
|
||||
|
||||
getState(): ThemeState;
|
||||
themePreferenceForSystemTheme(preference: ThemePreference): Theme;
|
||||
}
|
||||
|
|
|
|||
11
packages/discord-types/src/stores/UploadAttachmentStore.d.ts
vendored
Normal file
11
packages/discord-types/src/stores/UploadAttachmentStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { CloudUpload, FluxStore } from "..";
|
||||
import { DraftType } from "../../enums";
|
||||
|
||||
export class UploadAttachmentStore extends FluxStore {
|
||||
getFirstUpload(channelId: string, draftType: DraftType): CloudUpload | null;
|
||||
hasAdditionalUploads(channelId: string, draftType: DraftType): boolean;
|
||||
getUploads(channelId: string, draftType: DraftType): CloudUpload[];
|
||||
getUploadCount(channelId: string, draftType: DraftType): number;
|
||||
getUpload(channelId: string, uploadId: string, draftType: DraftType): CloudUpload;
|
||||
findUpload(channelId: string, draftType: DraftType, predicate: (upload: CloudUpload) => boolean): CloudUpload | undefined;
|
||||
}
|
||||
92
packages/discord-types/src/stores/UserGuildSettingsStore.d.ts
vendored
Normal file
92
packages/discord-types/src/stores/UserGuildSettingsStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import { Channel, FluxStore, Guild } from "..";
|
||||
import { ChannelOverrideFlags, GuildSettingsFlags, NotifyHighlights, UserNotificationSetting } from "../../enums";
|
||||
|
||||
export interface MuteConfig {
|
||||
selected_time_window: number;
|
||||
end_time: string | null;
|
||||
}
|
||||
|
||||
export interface ChannelOverride {
|
||||
muted: boolean;
|
||||
mute_config: MuteConfig | null;
|
||||
message_notifications: UserNotificationSetting;
|
||||
flags: ChannelOverrideFlags;
|
||||
collapsed: boolean;
|
||||
channel_id: string;
|
||||
}
|
||||
|
||||
export interface GuildSettings {
|
||||
suppress_everyone: boolean;
|
||||
suppress_roles: boolean;
|
||||
mute_scheduled_events: boolean;
|
||||
mobile_push: boolean;
|
||||
muted: boolean;
|
||||
message_notifications: UserNotificationSetting;
|
||||
flags: GuildSettingsFlags;
|
||||
channel_overrides: Record<string, ChannelOverride>;
|
||||
notify_highlights: NotifyHighlights;
|
||||
hide_muted_channels: boolean;
|
||||
version: number;
|
||||
mute_config: MuteConfig | null;
|
||||
guild_id: string;
|
||||
}
|
||||
|
||||
export interface AccountNotificationSettings {
|
||||
flags: number;
|
||||
}
|
||||
|
||||
export interface UserGuildSettingsState {
|
||||
useNewNotifications: boolean;
|
||||
}
|
||||
|
||||
export class UserGuildSettingsStore extends FluxStore {
|
||||
get accountNotificationSettings(): AccountNotificationSettings;
|
||||
get mentionOnAllMessages(): boolean;
|
||||
get useNewNotifications(): boolean;
|
||||
|
||||
allowAllMessages(channel: Channel): boolean;
|
||||
allowNoMessages(channel: Channel): boolean;
|
||||
getAddedToMessages(): string[];
|
||||
// TODO: finish typing
|
||||
getAllSettings(): { userGuildSettings: Record<string, GuildSettings>; };
|
||||
getChannelFlags(channel: Channel): ChannelOverrideFlags;
|
||||
getChannelIdFlags(guildId: string, channelId: string): ChannelOverrideFlags;
|
||||
getChannelMessageNotifications(guildId: string, channelId: string): UserNotificationSetting | null;
|
||||
getChannelMuteConfig(guildId: string, channelId: string): MuteConfig | null;
|
||||
getChannelOverrides(guildId: string): Record<string, ChannelOverride>;
|
||||
getChannelRecordUnreadSetting(channel: Channel): number;
|
||||
getChannelUnreadSetting(guildId: string, channelId: string): number;
|
||||
getGuildFavorites(guildId: string): string[];
|
||||
getGuildFlags(guildId: string): GuildSettingsFlags;
|
||||
getGuildUnreadSetting(guildId: string): number;
|
||||
getMessageNotifications(guildId: string): UserNotificationSetting;
|
||||
getMuteConfig(guildId: string): MuteConfig | null;
|
||||
getMutedChannels(guildId: string): string[];
|
||||
getNewForumThreadsCreated(channel: Channel): boolean;
|
||||
getNotifyHighlights(guildId: string): NotifyHighlights;
|
||||
getOptedInChannels(guildId: string): string[];
|
||||
// TODO: finish typing these
|
||||
getOptedInChannelsWithPendingUpdates(guildId: string): Record<string, any>;
|
||||
getPendingChannelUpdates(guildId: string): Record<string, any>;
|
||||
getState(): UserGuildSettingsState;
|
||||
isAddedToMessages(channelId: string): boolean;
|
||||
isCategoryMuted(guildId: string, channelId: string): boolean;
|
||||
isChannelMuted(guildId: string, channelId: string): boolean;
|
||||
isChannelOptedIn(guildId: string, channelId: string, usePending?: boolean): boolean;
|
||||
isChannelOrParentOptedIn(guildId: string, channelId: string, usePending?: boolean): boolean;
|
||||
isChannelRecordOrParentOptedIn(channel: Channel, usePending?: boolean): boolean;
|
||||
isFavorite(guildId: string, channelId: string): boolean;
|
||||
isGuildCollapsed(guildId: string): boolean;
|
||||
isGuildOrCategoryOrChannelMuted(guildId: string, channelId: string): boolean;
|
||||
isMessagesFavorite(guildId: string): boolean;
|
||||
isMobilePushEnabled(guildId: string): boolean;
|
||||
isMuteScheduledEventsEnabled(guildId: string): boolean;
|
||||
isMuted(guildId: string): boolean;
|
||||
isOptInEnabled(guildId: string): boolean;
|
||||
isSuppressEveryoneEnabled(guildId: string): boolean;
|
||||
isSuppressRolesEnabled(guildId: string): boolean;
|
||||
isTemporarilyMuted(guildId: string): boolean;
|
||||
resolveGuildUnreadSetting(guild: Guild): number;
|
||||
resolveUnreadSetting(channel: Channel): number;
|
||||
resolvedMessageNotifications(channel: Channel): UserNotificationSetting;
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { FluxStore, Guild, User, Application, ApplicationInstallParams } from "..";
|
||||
import { ApplicationIntegrationType } from "../../enums";
|
||||
import { ApplicationFlags, ApplicationIntegrationType } from "../../enums";
|
||||
|
||||
export interface MutualFriend {
|
||||
/**
|
||||
|
|
@ -54,7 +54,7 @@ export interface ProfileApplication {
|
|||
id: string;
|
||||
customInstallUrl: string | undefined;
|
||||
installParams: ApplicationInstallParams | undefined;
|
||||
flags: number;
|
||||
flags: ApplicationFlags;
|
||||
popularApplicationCommandIds?: string[];
|
||||
integrationTypesConfig: Record<ApplicationIntegrationType, Partial<{
|
||||
oauth2_install_params: ApplicationInstallParams;
|
||||
|
|
@ -101,28 +101,21 @@ export interface UserProfile extends UserProfileBase, Pick<User, "premiumType">
|
|||
premiumSince: Date | null;
|
||||
}
|
||||
|
||||
export class UserProfileStore extends FluxStore {
|
||||
/**
|
||||
* @param userId the user ID of the profile being fetched.
|
||||
* @param guildId the guild ID to of the profile being fetched.
|
||||
* defaults to the internal symbol `NO GUILD ID` if nullish
|
||||
*
|
||||
* @returns true if the profile is being fetched, false otherwise.
|
||||
*/
|
||||
isFetchingProfile(userId: string, guildId?: string): boolean;
|
||||
/**
|
||||
* Check if mutual friends for {@link userId} are currently being fetched.
|
||||
*
|
||||
* @param userId the user ID of the mutual friends being fetched.
|
||||
*
|
||||
* @returns true if mutual friends are being fetched, false otherwise.
|
||||
*/
|
||||
isFetchingFriends(userId: string): boolean;
|
||||
export interface ApplicationWidgetConfig {
|
||||
applicationId: string;
|
||||
widgetType: number;
|
||||
}
|
||||
|
||||
export interface WishlistSettings {
|
||||
privacy: number;
|
||||
}
|
||||
|
||||
export class UserProfileStore extends FluxStore {
|
||||
get applicationWidgetApplicationConfigs(): Record<string, ApplicationWidgetConfig>;
|
||||
get isSubmitting(): boolean;
|
||||
|
||||
getUserProfile(userId: string): UserProfile | undefined;
|
||||
|
||||
getApplicationWidgetApplicationConfig(applicationId: string): ApplicationWidgetConfig | undefined;
|
||||
getFirstWishlistId(userId: string): string | null;
|
||||
getGuildMemberProfile(userId: string, guildId: string | undefined): UserProfileBase | null;
|
||||
/**
|
||||
* Get the mutual friends of a user.
|
||||
|
|
@ -148,4 +141,26 @@ export class UserProfileStore extends FluxStore {
|
|||
* @returns an array of mutual guilds, or undefined if the user has no mutual guilds
|
||||
*/
|
||||
getMutualGuilds(userId: string): MutualGuild[] | undefined;
|
||||
getUserProfile(userId: string): UserProfile | undefined;
|
||||
// TODO: finish typing
|
||||
getWidgets(userId: string): any[] | undefined;
|
||||
getWishlistIds(userId: string): string[];
|
||||
getWishlistSettings(userId: string): WishlistSettings | null;
|
||||
/**
|
||||
* Check if mutual friends for {@link userId} are currently being fetched.
|
||||
*
|
||||
* @param userId the user ID of the mutual friends being fetched.
|
||||
*
|
||||
* @returns true if mutual friends are being fetched, false otherwise.
|
||||
*/
|
||||
isFetchingFriends(userId: string): boolean;
|
||||
/**
|
||||
* @param userId the user ID of the profile being fetched.
|
||||
* @param guildId the guild ID to of the profile being fetched.
|
||||
* defaults to the internal symbol `NO GUILD ID` if nullish
|
||||
*
|
||||
* @returns true if the profile is being fetched, false otherwise.
|
||||
*/
|
||||
isFetchingProfile(userId: string, guildId?: string): boolean;
|
||||
takeSnapshot(): Record<string, UserProfile>;
|
||||
}
|
||||
|
|
|
|||
226
packages/discord-types/src/stores/UserSettingsProtoStore.d.ts
vendored
Normal file
226
packages/discord-types/src/stores/UserSettingsProtoStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
import { FluxStore } from "..";
|
||||
import { StickerAnimationSetting, Theme, UIDensity } from "../../enums";
|
||||
|
||||
export type UserStatus = "online" | "idle" | "dnd" | "invisible";
|
||||
|
||||
export interface GuildFolder {
|
||||
guildIds: string[];
|
||||
folderId?: number;
|
||||
folderName?: string;
|
||||
folderColor?: number;
|
||||
}
|
||||
|
||||
export interface GuildProto {
|
||||
// TODO: finish typing
|
||||
channels: Record<string, any>;
|
||||
hubProgress: number;
|
||||
guildOnboardingProgress: number;
|
||||
dismissedGuildContent: Record<string, number>;
|
||||
disableRaidAlertPush: boolean;
|
||||
disableRaidAlertNag: boolean;
|
||||
leaderboardsDisabled: boolean;
|
||||
// TODO: finish typing
|
||||
guildDismissibleContentStates: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface UserSettingsVersions {
|
||||
clientVersion: number;
|
||||
serverVersion: number;
|
||||
dataVersion: number;
|
||||
}
|
||||
|
||||
export interface InboxSettings {
|
||||
currentTab: number;
|
||||
viewedTutorial: boolean;
|
||||
}
|
||||
|
||||
export interface GuildsSettings {
|
||||
guilds: Record<string, GuildProto>;
|
||||
}
|
||||
|
||||
export interface UserContentSettings {
|
||||
dismissedContents: string;
|
||||
lastReceivedChangelogId: string;
|
||||
// TODO: finish typing
|
||||
recurringDismissibleContentStates: Record<string, any>;
|
||||
// TODO: type
|
||||
lastDismissedOutboundPromotionStartDate: any;
|
||||
premiumTier0ModalDismissedAt: any;
|
||||
}
|
||||
|
||||
export interface VoiceAndVideoSettings {
|
||||
// TODO: type
|
||||
videoBackgroundFilterDesktop: any;
|
||||
alwaysPreviewVideo: boolean;
|
||||
afkTimeout: number;
|
||||
streamNotificationsEnabled: boolean;
|
||||
nativePhoneIntegrationEnabled: boolean;
|
||||
disableStreamPreviews: boolean;
|
||||
soundmojiVolume: number;
|
||||
}
|
||||
|
||||
export interface TextAndImagesSettings {
|
||||
emojiPickerCollapsedSections: string[];
|
||||
stickerPickerCollapsedSections: string[];
|
||||
soundboardPickerCollapsedSections: string[];
|
||||
dmSpamFilterV2: number;
|
||||
viewImageDescriptions: boolean;
|
||||
inlineAttachmentMedia: boolean;
|
||||
inlineEmbedMedia: boolean;
|
||||
gifAutoPlay: boolean;
|
||||
renderEmbeds: boolean;
|
||||
renderReactions: boolean;
|
||||
animateEmoji: boolean;
|
||||
animateStickers: StickerAnimationSetting;
|
||||
enableTtsCommand: boolean;
|
||||
messageDisplayCompact: boolean;
|
||||
explicitContentFilter: number;
|
||||
viewNsfwGuilds: boolean;
|
||||
convertEmoticons: boolean;
|
||||
viewNsfwCommands: boolean;
|
||||
includeStickersInAutocomplete: boolean;
|
||||
// TODO: type these
|
||||
explicitContentSettings: any;
|
||||
goreContentSettings: any;
|
||||
showMentionSuggestions: boolean;
|
||||
}
|
||||
|
||||
export interface NotificationsSettings {
|
||||
notificationCenterAckedBeforeId: string;
|
||||
focusModeExpiresAtMs: string;
|
||||
reactionNotifications: number;
|
||||
gameActivityNotifications: boolean;
|
||||
customStatusPushNotifications: boolean;
|
||||
showInAppNotifications: boolean;
|
||||
notifyFriendsOnGoLive: boolean;
|
||||
enableVoiceActivityNotifications: boolean;
|
||||
enableUserResurrectionNotifications: boolean;
|
||||
}
|
||||
|
||||
export interface PrivacySettings {
|
||||
restrictedGuildIds: string[];
|
||||
defaultGuildsRestricted: boolean;
|
||||
allowAccessibilityDetection: boolean;
|
||||
activityRestrictedGuildIds: string[];
|
||||
defaultGuildsActivityRestricted: boolean;
|
||||
activityJoiningRestrictedGuildIds: string[];
|
||||
messageRequestRestrictedGuildIds: string[];
|
||||
guildsLeaderboardOptOutDefault: boolean;
|
||||
slayerSdkReceiveDmsInGame: boolean;
|
||||
defaultGuildsActivityRestrictedV2: boolean;
|
||||
detectPlatformAccounts: boolean;
|
||||
passwordless: boolean;
|
||||
contactSyncEnabled: boolean;
|
||||
friendSourceFlags: number;
|
||||
friendDiscoveryFlags: number;
|
||||
dropsOptedOut: boolean;
|
||||
hideLegacyUsername: boolean;
|
||||
defaultGuildsRestrictedV2: boolean;
|
||||
quests3PDataOptedOut: boolean;
|
||||
}
|
||||
|
||||
export interface GameLibrarySettings {
|
||||
disableGamesTab: boolean;
|
||||
}
|
||||
|
||||
export interface StatusSettings {
|
||||
statusExpiresAtMs: string;
|
||||
status: { value: UserStatus; } | null;
|
||||
showCurrentGame: boolean;
|
||||
statusCreatedAtMs: string;
|
||||
}
|
||||
|
||||
export interface LocalizationSettings {
|
||||
locale: { localeCode: string; } | null;
|
||||
timezoneOffset: { offset: number; } | null;
|
||||
}
|
||||
|
||||
export interface AppearanceSettings {
|
||||
theme: Theme;
|
||||
developerMode: boolean;
|
||||
mobileRedesignDisabled: boolean;
|
||||
timestampHourCycle: number;
|
||||
launchPadMode: number;
|
||||
uiDensity: UIDensity;
|
||||
swipeRightToLeftMode: number;
|
||||
// TODO: type
|
||||
clientThemeSettings: any;
|
||||
}
|
||||
|
||||
export interface GuildFoldersSettings {
|
||||
folders: GuildFolder[];
|
||||
guildPositions: string[];
|
||||
}
|
||||
|
||||
export interface AudioContextSettings {
|
||||
// TODO: finish these
|
||||
user: Record<string, any>;
|
||||
stream: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface ClipsSettings {
|
||||
allowVoiceRecording: boolean;
|
||||
}
|
||||
|
||||
export interface InAppFeedbackSettings {
|
||||
// TODO: finish typing
|
||||
inAppFeedbackStates: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface UserSettings {
|
||||
versions: UserSettingsVersions;
|
||||
inbox: InboxSettings;
|
||||
guilds: GuildsSettings;
|
||||
userContent: UserContentSettings;
|
||||
voiceAndVideo: VoiceAndVideoSettings;
|
||||
textAndImages: TextAndImagesSettings;
|
||||
notifications: NotificationsSettings;
|
||||
privacy: PrivacySettings;
|
||||
// TODO: finish typing
|
||||
debug: Record<string, any>;
|
||||
gameLibrary: GameLibrarySettings;
|
||||
status: StatusSettings;
|
||||
localization: LocalizationSettings;
|
||||
appearance: AppearanceSettings;
|
||||
guildFolders: GuildFoldersSettings;
|
||||
audioContextSettings: AudioContextSettings;
|
||||
clips: ClipsSettings;
|
||||
inAppFeedbackSettings: InAppFeedbackSettings;
|
||||
}
|
||||
|
||||
export interface FrecencySettings {
|
||||
// TODO: type all of these
|
||||
versions: any;
|
||||
favoriteGifs: any;
|
||||
favoriteStickers: any;
|
||||
stickerFrecency: any;
|
||||
favoriteEmojis: any;
|
||||
emojiFrecency: any;
|
||||
applicationCommandFrecency: any;
|
||||
favoriteSoundboardSounds: any;
|
||||
applicationFrecency: any;
|
||||
playedSoundFrecency: any;
|
||||
guildAndChannelFrecency: any;
|
||||
emojiReactionFrecency: any;
|
||||
}
|
||||
|
||||
export interface ProtoState {
|
||||
// TODO: type
|
||||
proto: any;
|
||||
}
|
||||
|
||||
export class UserSettingsProtoStore extends FluxStore {
|
||||
settings: UserSettings;
|
||||
frecencyWithoutFetchingLatest: FrecencySettings;
|
||||
wasMostRecentUpdateFromServer: boolean;
|
||||
getState(): Record<string, ProtoState>;
|
||||
computeState(): Record<string, ProtoState>;
|
||||
getFullState(): Record<string, ProtoState>;
|
||||
hasLoaded(settingsType: number): boolean;
|
||||
getGuildFolders(): GuildFolder[];
|
||||
getGuildRecentsDismissedAt(guildId: string): number;
|
||||
getDismissedGuildContent(guildId: string): Record<string, number> | null;
|
||||
// TODO: finish typing
|
||||
getGuildDismissedContentState(guildId: string): any;
|
||||
getGuildsProto(): Record<string, GuildProto>;
|
||||
}
|
||||
30
packages/discord-types/src/stores/UserStore.d.ts
vendored
30
packages/discord-types/src/stores/UserStore.d.ts
vendored
|
|
@ -1,10 +1,34 @@
|
|||
import { FluxStore, User } from "..";
|
||||
|
||||
/** returned by takeSnapshot for persistence */
|
||||
export interface UserStoreSnapshot {
|
||||
/** snapshot format version, currently 1 */
|
||||
version: number;
|
||||
data: {
|
||||
/** contains only the current user */
|
||||
users: User[];
|
||||
};
|
||||
}
|
||||
|
||||
export class UserStore extends FluxStore {
|
||||
filter(filter: (user: User) => boolean, sort?: boolean): Record<string, User>;
|
||||
findByTag(username: string, discriminator: string): User;
|
||||
forEach(action: (user: User) => void): void;
|
||||
/**
|
||||
* filters users and optionally sorts results.
|
||||
* @param sort if true (default false), sorts alphabetically by username
|
||||
*/
|
||||
filter(filter: (user: User) => boolean, sort?: boolean): User[];
|
||||
/**
|
||||
* finds user by username and discriminator.
|
||||
* for new username system (unique usernames), pass null/undefined as discriminator.
|
||||
*/
|
||||
findByTag(username: string, discriminator?: string | null): User | undefined;
|
||||
/** @param action return false to break iteration early */
|
||||
forEach(action: (user: User) => boolean | void): void;
|
||||
getCurrentUser(): User;
|
||||
getUser(userId: string): User;
|
||||
/** keyed by user ID */
|
||||
getUsers(): Record<string, User>;
|
||||
/** increments when users are added/updated/removed */
|
||||
getUserStoreVersion(): number;
|
||||
/** only includes current user, used for persistence */
|
||||
takeSnapshot(): UserStoreSnapshot;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,19 +28,28 @@ export interface VoiceState extends DiscordRecord {
|
|||
|
||||
export class VoiceStateStore extends FluxStore {
|
||||
getAllVoiceStates(): VoiceStates;
|
||||
getVoiceStateVersion(): number;
|
||||
|
||||
getVoiceStates(guildId?: string | null): UserVoiceStateRecords;
|
||||
getVoiceStatesForChannel(channelId: string): UserVoiceStateRecords;
|
||||
getVideoVoiceStatesForChannel(channelId: string): UserVoiceStateRecords;
|
||||
|
||||
getVoiceState(guildId: string | null, userId: string): VoiceState | undefined;
|
||||
getUserVoiceChannelId(guildId: string | null, userId: string): string | undefined;
|
||||
getDiscoverableVoiceState(guildId: string | null, userId: string): VoiceState | null;
|
||||
getVoiceStateForChannel(channelId: string, userId?: string): VoiceState | undefined;
|
||||
getVoiceStateForUser(userId: string): VoiceState | undefined;
|
||||
getDiscoverableVoiceStateForUser(userId: string): VoiceState | undefined;
|
||||
getVoiceStateForSession(userId: string, sessionId?: string | null): VoiceState | null | undefined;
|
||||
|
||||
getUserVoiceChannelId(guildId: string | null, userId: string): string | undefined;
|
||||
getCurrentClientVoiceChannelId(guildId: string | null): string | undefined;
|
||||
isCurrentClientInVoiceChannel(): boolean;
|
||||
|
||||
getUsersWithVideo(channelId: string): Set<string>;
|
||||
getVoicePlatformForChannel(channelId: string, guildId: string): string | undefined;
|
||||
|
||||
isCurrentClientInVoiceChannel(): boolean;
|
||||
isInChannel(channelId: string, userId?: string): boolean;
|
||||
hasVideo(channelId: string): boolean;
|
||||
|
||||
get userHasBeenMovedVersion(): number;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,22 @@
|
|||
import { FluxStore } from "..";
|
||||
|
||||
export class WindowStore extends FluxStore {
|
||||
isElementFullScreen(): boolean;
|
||||
isFocused(): boolean;
|
||||
windowSize(): Record<"width" | "height", number>;
|
||||
export interface WindowSize {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export class WindowStore extends FluxStore {
|
||||
/** returns focused window ID, or null if no window is focused */
|
||||
getFocusedWindowId(): string | null;
|
||||
getLastFocusedWindowId(): string;
|
||||
/** true if any window is focused (getFocusedWindowId() !== null) */
|
||||
isAppFocused(): boolean;
|
||||
/** @param windowId defaults to current window */
|
||||
isElementFullScreen(windowId?: string): boolean;
|
||||
/** @param windowId defaults to current window */
|
||||
isFocused(windowId?: string): boolean;
|
||||
/** @param windowId defaults to current window */
|
||||
isVisible(windowId?: string): boolean;
|
||||
/** @param windowId defaults to current window, returns {width: 0, height: 0} for invalid ID */
|
||||
windowSize(windowId?: string): WindowSize;
|
||||
}
|
||||
|
|
|
|||
32
packages/discord-types/src/stores/index.d.ts
vendored
32
packages/discord-types/src/stores/index.d.ts
vendored
|
|
@ -1,25 +1,47 @@
|
|||
// please keep in alphabetical order
|
||||
export * from "./AccessibilityStore";
|
||||
export * from "./ActiveJoinedThreadsStore";
|
||||
export * from "./ApplicationStore";
|
||||
export * from "./AuthenticationStore";
|
||||
export * from "./CallStore";
|
||||
export * from "./ChannelRTCStore";
|
||||
export * from "./ChannelStore";
|
||||
export * from "./DraftStore";
|
||||
export * from "./EmojiStore";
|
||||
export * from "./FluxStore";
|
||||
export * from "./FriendsStore";
|
||||
export * from "./GuildChannelStore";
|
||||
export * from "./GuildMemberCountStore";
|
||||
export * from "./GuildMemberStore";
|
||||
export * from "./GuildRoleStore";
|
||||
export * from "./GuildScheduledEventStore";
|
||||
export * from "./GuildStore";
|
||||
export * from "./MessageStore";
|
||||
export * from "./PresenceStore";
|
||||
export * from "./RelationshipStore";
|
||||
export * from "./InstantInviteStore";
|
||||
export * from "./InviteStore";
|
||||
export * from "./LocaleStore";
|
||||
export * from "./MediaEngineStore";
|
||||
export * from "./StreamerModeStore";
|
||||
export * from "./SpellCheckStore";
|
||||
export * from "./MessageStore";
|
||||
export * from "./NotificationSettingsStore";
|
||||
export * from "./OverridePremiumTypeStore";
|
||||
export * from "./PermissionStore";
|
||||
export * from "./PresenceStore";
|
||||
export * from "./ReadStateStore";
|
||||
export * from "./RelationshipStore";
|
||||
export * from "./RTCConnectionStore";
|
||||
export * from "./RunningGameStore";
|
||||
export * from "./SelectedChannelStore";
|
||||
export * from "./SelectedGuildStore";
|
||||
export * from "./SoundboardStore";
|
||||
export * from "./SpellCheckStore";
|
||||
export * from "./SpotifyStore";
|
||||
export * from "./StickersStore";
|
||||
export * from "./StreamerModeStore";
|
||||
export * from "./ThemeStore";
|
||||
export * from "./TypingStore";
|
||||
export * from "./UploadAttachmentStore";
|
||||
export * from "./UserGuildSettingsStore";
|
||||
export * from "./UserProfileStore";
|
||||
export * from "./UserSettingsProtoStore";
|
||||
export * from "./UserStore";
|
||||
export * from "./VoiceStateStore";
|
||||
export * from "./WindowStore";
|
||||
|
|
|
|||
15
packages/discord-types/src/utils.d.ts
vendored
15
packages/discord-types/src/utils.d.ts
vendored
|
|
@ -3,6 +3,7 @@ import type { ReactNode } from "react";
|
|||
import { LiteralUnion } from "type-fest";
|
||||
|
||||
import type { FluxEvents } from "./fluxEvents";
|
||||
import { ApplicationCommandOptionType, ChannelType, PremiumType } from "../enums";
|
||||
|
||||
export { FluxEvents };
|
||||
|
||||
|
|
@ -86,6 +87,8 @@ export type Permissions = "CREATE_INSTANT_INVITE"
|
|||
| "VIEW_GUILD_ANALYTICS"
|
||||
| "VIEW_CREATOR_MONETIZATION_ANALYTICS"
|
||||
| "MODERATE_MEMBERS"
|
||||
| "USE_EMBEDDED_ACTIVITIES"
|
||||
| "USE_EXTERNAL_APPS"
|
||||
| "SEND_MESSAGES"
|
||||
| "SEND_TTS_MESSAGES"
|
||||
| "MANAGE_MESSAGES"
|
||||
|
|
@ -102,6 +105,9 @@ export type Permissions = "CREATE_INSTANT_INVITE"
|
|||
| "USE_EXTERNAL_STICKERS"
|
||||
| "SEND_MESSAGES_IN_THREADS"
|
||||
| "SEND_VOICE_MESSAGES"
|
||||
| "SEND_POLLS"
|
||||
| "PIN_MESSAGES"
|
||||
| "BYPASS_SLOWMODE"
|
||||
| "CONNECT"
|
||||
| "SPEAK"
|
||||
| "MUTE_MEMBERS"
|
||||
|
|
@ -110,9 +116,9 @@ export type Permissions = "CREATE_INSTANT_INVITE"
|
|||
| "USE_VAD"
|
||||
| "PRIORITY_SPEAKER"
|
||||
| "STREAM"
|
||||
| "USE_EMBEDDED_ACTIVITIES"
|
||||
| "USE_SOUNDBOARD"
|
||||
| "USE_EXTERNAL_SOUNDS"
|
||||
| "SET_VOICE_CHANNEL_STATUS"
|
||||
| "REQUEST_TO_SPEAK"
|
||||
| "MANAGE_EVENTS"
|
||||
| "CREATE_EVENTS";
|
||||
|
|
@ -276,6 +282,7 @@ export interface UsernameUtils {
|
|||
humanizeStatus: any;
|
||||
}
|
||||
|
||||
// TODO: fix type
|
||||
export class DisplayProfile {
|
||||
userId: string;
|
||||
banner?: string;
|
||||
|
|
@ -291,7 +298,7 @@ export class DisplayProfile {
|
|||
canEditThemes: boolean;
|
||||
premiumGuildSince: Date | null;
|
||||
premiumSince: Date | null;
|
||||
premiumType?: number;
|
||||
premiumType?: PremiumType;
|
||||
primaryColor?: number;
|
||||
|
||||
getBadges(): Array<{
|
||||
|
|
@ -323,7 +330,7 @@ export interface DateUtils {
|
|||
}
|
||||
|
||||
export interface CommandOptions {
|
||||
type: number;
|
||||
type: ApplicationCommandOptionType;
|
||||
name: string;
|
||||
description: string;
|
||||
required?: boolean;
|
||||
|
|
@ -332,7 +339,7 @@ export interface CommandOptions {
|
|||
values: string | number;
|
||||
}[];
|
||||
options?: CommandOptions[];
|
||||
channel_types?: number[];
|
||||
channel_types?: ChannelType[];
|
||||
min_value?: number;
|
||||
max_value?: number;
|
||||
autocomplete?: boolean;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@equicord/types",
|
||||
"private": false,
|
||||
"version": "1.13.4",
|
||||
"version": "1.13.9",
|
||||
"description": "",
|
||||
"types": "index.d.ts",
|
||||
"scripts": {
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Vencord",
|
||||
"author": "Equicord & Vencord Contributors",
|
||||
"license": "GPL-3.0",
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
|
|
|
|||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
|
|
@ -101,9 +101,6 @@ importers:
|
|||
'@vencord/discord-types':
|
||||
specifier: link:packages/discord-types
|
||||
version: link:packages/discord-types
|
||||
adm-zip:
|
||||
specifier: ^0.5.16
|
||||
version: 0.5.16
|
||||
diff:
|
||||
specifier: ^8.0.2
|
||||
version: 8.0.2
|
||||
|
|
@ -893,10 +890,6 @@ packages:
|
|||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
adm-zip@0.5.16:
|
||||
resolution: {integrity: sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==}
|
||||
engines: {node: '>=12.0'}
|
||||
|
||||
agent-base@7.1.3:
|
||||
resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==}
|
||||
engines: {node: '>= 14'}
|
||||
|
|
@ -2157,7 +2150,6 @@ packages:
|
|||
engines: {node: '>=0.6.0', teleport: '>=0.2.0'}
|
||||
deprecated: |-
|
||||
You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.
|
||||
|
||||
(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)
|
||||
|
||||
qified@0.5.2:
|
||||
|
|
@ -3196,8 +3188,6 @@ snapshots:
|
|||
|
||||
acorn@8.15.0: {}
|
||||
|
||||
adm-zip@0.5.16: {}
|
||||
|
||||
agent-base@7.1.3: {}
|
||||
|
||||
ajv@6.12.6:
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@
|
|||
import { readFileSync } from "fs";
|
||||
import { appendFile, mkdir, readdir, readFile, rm, writeFile } from "fs/promises";
|
||||
import path, { join } from "path";
|
||||
import Zip from "zip-local";
|
||||
|
||||
import { BUILD_TIMESTAMP, commonOpts, globPlugins, IS_DEV, IS_REPORTER, IS_COMPANION_TEST, VERSION, commonRendererPlugins, buildOrWatchAll, stringifyValues, IS_ANTI_CRASH_TEST } from "./common.mjs";
|
||||
import AdmZip from "adm-zip";
|
||||
|
||||
/**
|
||||
* @type {import("esbuild").BuildOptions}
|
||||
|
|
@ -185,14 +185,7 @@ async function buildExtension(target, files) {
|
|||
}
|
||||
|
||||
const appendCssRuntime = readFile("dist/Equicord.user.css", "utf-8").then(content => {
|
||||
const cssRuntime = `
|
||||
;document.addEventListener("DOMContentLoaded", () => document.body.insertAdjacentElement("afterend",
|
||||
Object.assign(document.createElement("style"), {
|
||||
textContent: \`${content.replaceAll("`", "\\`")}\`,
|
||||
id: "vencord-css-core"
|
||||
})
|
||||
), { once: true });
|
||||
`;
|
||||
const cssRuntime = `unsafeWindow._vcUserScriptRendererCss=\`${content.replaceAll("`", "\\`")}\``;
|
||||
|
||||
return appendFile("dist/Equicord.user.js", cssRuntime);
|
||||
});
|
||||
|
|
@ -204,15 +197,14 @@ if (!process.argv.includes("--skip-extension")) {
|
|||
buildExtension("firefox-unpacked", ["background.js", "content.js", "manifestv2.json", "icon.png"]),
|
||||
]);
|
||||
|
||||
const chromiumZip = new AdmZip();
|
||||
chromiumZip.addLocalFolder("dist/browser/chromium-unpacked");
|
||||
chromiumZip.writeZip(path.resolve("dist/extension-chrome.zip"));
|
||||
console.info("Packed Chromium Extension written to dist/extension-chrome.zip");
|
||||
|
||||
const firefoxZip = new AdmZip();
|
||||
firefoxZip.addLocalFolder("dist/browser/firefox-unpacked");
|
||||
firefoxZip.writeZip(path.resolve("dist/extension-firefox.zip"));
|
||||
console.info("Packed Firefox Extension written to dist/extension-firefox.zip");
|
||||
Zip.zip("dist/browser/chromium-unpacked", (_err, zip) => {
|
||||
zip.compress().save("dist/extension-chrome.zip");
|
||||
console.info("Packed Chromium Extension written to dist/extension-chrome.zip");
|
||||
});
|
||||
Zip.zip("dist/browser/firefox-unpacked", (_err, zip) => {
|
||||
zip.compress().save("dist/extension-firefox.zip");
|
||||
console.info("Packed Firefox Extension written to dist/extension-firefox.zip");
|
||||
});
|
||||
} else {
|
||||
await appendCssRuntime;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import { fileURLToPath } from "url";
|
|||
import { promisify } from "util";
|
||||
|
||||
import { getPluginTarget } from "../utils.mjs";
|
||||
import { builtinModules } from "module";
|
||||
|
||||
const PackageJSON = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), "../../package.json"), "utf-8"));
|
||||
|
||||
|
|
@ -261,7 +260,7 @@ export const fileUrlPlugin = {
|
|||
build.onLoad({ filter, namespace: "file-uri" }, async ({ pluginData: { path, uri } }) => {
|
||||
const { searchParams } = new URL(uri);
|
||||
const base64 = searchParams.has("base64");
|
||||
const minify = IS_STANDALONE === true && searchParams.has("minify");
|
||||
const minify = searchParams.has("minify");
|
||||
const noTrim = searchParams.get("trim") === "false";
|
||||
|
||||
const encoding = base64 ? "base64" : "utf-8";
|
||||
|
|
@ -294,7 +293,7 @@ export const fileUrlPlugin = {
|
|||
throw new Error(`Don't know how to minify file type: ${path}`);
|
||||
}
|
||||
|
||||
if (base64)
|
||||
if (base64 && !content.startsWith("data:"))
|
||||
content = Buffer.from(content).toString("base64");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -87,8 +87,14 @@ const IGNORED_DISCORD_ERRORS = [
|
|||
function toCodeBlock(s: string, indentation = 0, isDiscord = false) {
|
||||
s = s.replace(/```/g, "`\u200B`\u200B`");
|
||||
|
||||
const indentationStr = Array(!isDiscord ? indentation : 0).fill(" ").join("");
|
||||
return `\`\`\`\n${s.split("\n").map(s => indentationStr + s).join("\n")}\n${indentationStr}\`\`\``;
|
||||
s = s.replace(/\\x([0-9A-Fa-f]{2})/g, (_, hex) =>
|
||||
String.fromCharCode(parseInt(hex, 16))
|
||||
);
|
||||
|
||||
const indentationStr = " ".repeat(!isDiscord ? indentation : 0);
|
||||
const content = s.split("\n").map(s => indentationStr + s).join("\n");
|
||||
|
||||
return `\`\`\`\n${content}\n${indentationStr}\`\`\``;
|
||||
}
|
||||
|
||||
async function printReport() {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export * as Webpack from "./webpack";
|
|||
export * as WebpackPatcher from "./webpack/patchWebpack";
|
||||
export { PlainSettings, Settings };
|
||||
|
||||
import { addVencordUiStyles } from "@components/css";
|
||||
import { coreStyleRootNode, initStyles } from "@api/Styles";
|
||||
import { openSettingsTabModal, UpdaterTab } from "@components/settings";
|
||||
import { debounce } from "@shared/debounce";
|
||||
import { IS_WINDOWS } from "@utils/constants";
|
||||
|
|
@ -40,12 +40,12 @@ import { get as dsGet } from "./api/DataStore";
|
|||
import { NotificationData, showNotification } from "./api/Notifications";
|
||||
import { initPluginManager, PMLogger, startAllPlugins } from "./api/PluginManager";
|
||||
import { PlainSettings, Settings, SettingsStore } from "./api/Settings";
|
||||
import { getCloudSettings, putCloudSettings } from "./api/SettingsSync/cloudSync";
|
||||
import { getCloudSettings, putCloudSettings, shouldCloudSync } from "./api/SettingsSync/cloudSync";
|
||||
import { localStorage } from "./utils/localStorage";
|
||||
import { relaunch } from "./utils/native";
|
||||
import { checkForUpdates, update, UpdateLogger } from "./utils/updater";
|
||||
import { onceReady } from "./webpack";
|
||||
import { SettingsRouter } from "./webpack/common";
|
||||
import { openUserSettingsPanel } from "./webpack/common";
|
||||
import { patches } from "./webpack/patchWebpack";
|
||||
|
||||
if (IS_REPORTER) {
|
||||
|
|
@ -54,6 +54,10 @@ if (IS_REPORTER) {
|
|||
|
||||
async function syncSettings() {
|
||||
// Check if cloud auth exists for current user before attempting sync
|
||||
if (localStorage.Vencord_cloudSyncDirection === undefined) {
|
||||
// by default, sync bi-directionally
|
||||
localStorage.Vencord_cloudSyncDirection = "both";
|
||||
}
|
||||
const hasCloudAuth = await dsGet("Vencord_cloudSecret");
|
||||
if (!hasCloudAuth) {
|
||||
if (Settings.cloud.authenticated) {
|
||||
|
|
@ -62,7 +66,7 @@ async function syncSettings() {
|
|||
title: t("vencord.cloud.settings.header"),
|
||||
body: "Cloud sync was disabled because this account isn't connected to the cloud App. You can enable it again by connecting this account in Cloud Settings. (note: it will store your preferences separately)",
|
||||
color: "var(--yellow-360)",
|
||||
onClick: () => SettingsRouter.open("VencordCloud")
|
||||
onClick: () => openUserSettingsPanel("equicord_cloud")
|
||||
});
|
||||
// Disable cloud sync globally
|
||||
Settings.cloud.authenticated = false;
|
||||
|
|
@ -80,20 +84,19 @@ async function syncSettings() {
|
|||
title: t("vencord.cloud.integrations.header"),
|
||||
body: t("vencord.cloud.integrations.reauthenticateOtherClient"),
|
||||
color: "var(--yellow-360)",
|
||||
onClick: () => SettingsRouter.open("EquicordCloud")
|
||||
onClick: () => openUserSettingsPanel("equicord_cloud")
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
Settings.cloud.settingsSync && // if it's enabled
|
||||
Settings.cloud.authenticated // if cloud integrations are enabled
|
||||
Settings.cloud.authenticated && // if cloud integrations are enabled
|
||||
localStorage.Vencord_cloudSyncDirection !== "manual" // if we're not in manual mode
|
||||
) {
|
||||
if (localStorage.Vencord_settingsDirty) {
|
||||
if (localStorage.Vencord_settingsDirty && shouldCloudSync("push")) {
|
||||
await putCloudSettings();
|
||||
delete localStorage.Vencord_settingsDirty;
|
||||
} else if (await getCloudSettings(false)) {
|
||||
// if we synchronized something (false means no sync)
|
||||
} else if (shouldCloudSync("pull") && await getCloudSettings(false)) { // if we synchronized something (false means no sync)
|
||||
// we show a notification here instead of allowing getCloudSettings() to show one to declutter the amount of
|
||||
// potential notifications that might occur. getCloudSettings() will always send a notification regardless if
|
||||
// there was an error to notify the user, but besides that we only want to show one notification instead of all
|
||||
|
|
@ -108,9 +111,8 @@ async function syncSettings() {
|
|||
}
|
||||
|
||||
const saveSettingsOnFrequentAction = debounce(async () => {
|
||||
if (Settings.cloud.settingsSync && Settings.cloud.authenticated) {
|
||||
if (Settings.cloud.settingsSync && Settings.cloud.authenticated && shouldCloudSync("push")) {
|
||||
await putCloudSettings();
|
||||
delete localStorage.Vencord_settingsDirty;
|
||||
}
|
||||
}, 60_000);
|
||||
|
||||
|
|
@ -192,16 +194,15 @@ async function init() {
|
|||
}
|
||||
|
||||
initPluginManager();
|
||||
initStyles();
|
||||
startAllPlugins(StartAt.Init);
|
||||
init();
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
addVencordUiStyles();
|
||||
|
||||
startAllPlugins(StartAt.DOMContentLoaded);
|
||||
|
||||
// FIXME
|
||||
if (IS_DISCORD_DESKTOP && Settings.winNativeTitleBar && IS_WINDOWS) {
|
||||
createAndAppendStyle("vencord-native-titlebar-style").textContent = "[class*=titleBar]{display: none!important}";
|
||||
createAndAppendStyle("vencord-native-titlebar-style", coreStyleRootNode).textContent = "[class*=titleBar]{display: none!important}";
|
||||
}
|
||||
}, { once: true });
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@
|
|||
*/
|
||||
|
||||
import type { Settings } from "@api/Settings";
|
||||
import { CspRequestResult } from "@main/csp/manager";
|
||||
import { PluginIpcMappings } from "@main/ipcPlugins";
|
||||
import type { CspRequestResult } from "@main/csp/manager";
|
||||
import type { PluginIpcMappings } from "@main/ipcPlugins";
|
||||
import { IpcEvents } from "@shared/IpcEvents";
|
||||
import { IpcRes } from "@utils/types";
|
||||
import { ipcRenderer } from "electron";
|
||||
import type { IpcRes } from "@utils/types";
|
||||
import { ipcRenderer } from "electron/renderer";
|
||||
|
||||
function invoke<T = any>(event: IpcEvents, ...args: any[]) {
|
||||
export function invoke<T = any>(event: IpcEvents, ...args: any[]) {
|
||||
return ipcRenderer.invoke(event, ...args) as Promise<T>;
|
||||
}
|
||||
|
||||
|
|
@ -31,8 +31,12 @@ for (const [plugin, methods] of Object.entries(pluginIpcMap)) {
|
|||
|
||||
export default {
|
||||
themes: {
|
||||
uploadTheme: (fileName: string, fileData: string) => invoke<void>(IpcEvents.UPLOAD_THEME, fileName, fileData),
|
||||
deleteTheme: (fileName: string) => invoke<void>(IpcEvents.DELETE_THEME, fileName),
|
||||
uploadTheme: async (fileName: string, fileData: string): Promise<void> => {
|
||||
throw new Error("uploadTheme is WEB only");
|
||||
},
|
||||
deleteTheme: async (fileName: string): Promise<void> => {
|
||||
throw new Error("deleteTheme is WEB only");
|
||||
},
|
||||
getThemesDir: () => invoke<string>(IpcEvents.GET_THEMES_DIR),
|
||||
getThemesList: () => invoke<Array<{ fileName: string; content: string; }>>(IpcEvents.GET_THEMES_LIST),
|
||||
getThemeData: (fileName: string) => invoke<string | undefined>(IpcEvents.GET_THEME_DATA, fileName),
|
||||
|
|
@ -70,11 +74,18 @@ export default {
|
|||
|
||||
openFile: () => invoke<void>(IpcEvents.OPEN_QUICKCSS),
|
||||
openEditor: () => invoke<void>(IpcEvents.OPEN_MONACO_EDITOR),
|
||||
getEditorTheme: () => sendSync<string>(IpcEvents.GET_MONACO_THEME),
|
||||
},
|
||||
|
||||
native: {
|
||||
getVersions: () => process.versions as Partial<NodeJS.ProcessVersions>,
|
||||
openExternal: (url: string) => invoke<void>(IpcEvents.OPEN_EXTERNAL, url)
|
||||
openExternal: (url: string) => invoke<void>(IpcEvents.OPEN_EXTERNAL, url),
|
||||
getRendererCss: () => invoke<string>(IpcEvents.GET_RENDERER_CSS),
|
||||
onRendererCssUpdate: (cb: (newCss: string) => void) => {
|
||||
if (!IS_DEV) return;
|
||||
|
||||
ipcRenderer.on(IpcEvents.RENDERER_CSS_UPDATE, (_e, newCss: string) => cb(newCss));
|
||||
}
|
||||
},
|
||||
|
||||
csp: {
|
||||
|
|
|
|||
|
|
@ -17,9 +17,12 @@
|
|||
*/
|
||||
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import globalBadges from "@equicordplugins/globalBadges";
|
||||
import BadgeAPIPlugin from "@plugins/_api/badges";
|
||||
import { ComponentType, HTMLProps } from "react";
|
||||
|
||||
import { isPluginEnabled } from "./PluginManager";
|
||||
|
||||
export const enum BadgePosition {
|
||||
START,
|
||||
END
|
||||
|
|
@ -47,7 +50,8 @@ export interface ProfileBadge {
|
|||
key?: string;
|
||||
|
||||
/**
|
||||
* Allows dynamically returning multiple badges
|
||||
* Allows dynamically returning multiple badges.
|
||||
* May call hooks but then you must not use shouldShow
|
||||
*/
|
||||
getBadges?(userInfo: BadgeUserArgs): ProfileBadge[];
|
||||
}
|
||||
|
|
@ -99,6 +103,18 @@ export function _getBadges(args: BadgeUserArgs) {
|
|||
|
||||
const donorBadges = BadgeAPIPlugin.getDonorBadges(args.userId);
|
||||
const equicordDonorBadges = BadgeAPIPlugin.getEquicordDonorBadges(args.userId);
|
||||
const GlobalBadges = isPluginEnabled(globalBadges.name) ? globalBadges.getGlobalBadges(args.userId) : false;
|
||||
|
||||
// do globalbadges first so it shows before the contrib badges but after donor badges
|
||||
if (GlobalBadges) {
|
||||
badges.unshift(
|
||||
...GlobalBadges.map(badge => ({
|
||||
...args,
|
||||
...badge,
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
if (donorBadges) {
|
||||
badges.unshift(
|
||||
...donorBadges.map(badge => ({
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ export interface ChatBarProps {
|
|||
};
|
||||
}
|
||||
|
||||
export type ChatBarButtonFactory = (props: ChatBarProps & { isMainChat: boolean; }) => JSX.Element | null;
|
||||
export type ChatBarButtonFactory = (props: ChatBarProps & { isMainChat: boolean; isAnyChat: boolean; }) => JSX.Element | null;
|
||||
export type ChatBarButtonData = {
|
||||
render: ChatBarButtonFactory;
|
||||
/**
|
||||
|
|
@ -98,13 +98,14 @@ const logger = new Logger("ChatButtons");
|
|||
function VencordChatBarButtons(props: ChatBarProps) {
|
||||
const { chatBarButtons } = useSettings(["uiElements.chatBarButtons.*"]).uiElements;
|
||||
|
||||
const { analyticsName } = props.type;
|
||||
return (
|
||||
<>
|
||||
{Array.from(ChatBarButtonMap)
|
||||
.filter(([key]) => chatBarButtons[key]?.enabled !== false)
|
||||
.map(([key, { render: Button }]) => (
|
||||
<ErrorBoundary noop key={key} onError={e => logger.error(`Failed to render ${key}`, e.error)}>
|
||||
<Button {...props} isMainChat={props.type.analyticsName === "normal"} />
|
||||
<Button {...props} isMainChat={analyticsName === "normal"} isAnyChat={["normal", "sidebar"].includes(analyticsName)} />
|
||||
</ErrorBoundary>
|
||||
))}
|
||||
</>
|
||||
|
|
@ -173,7 +174,7 @@ addContextMenuPatch("textarea-context", (children, args) => {
|
|||
if (idx === -1) return;
|
||||
|
||||
group.splice(idx, 0,
|
||||
<Menu.MenuItem id="vc-chat-buttons" key="vencord-chat-buttons" label="Vencord Buttons">
|
||||
<Menu.MenuItem id="vc-chat-buttons" key="vencord-chat-buttons" label="Equicord Buttons">
|
||||
{buttons.map(([id]) => (
|
||||
<Menu.MenuCheckboxItem
|
||||
label={id}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,6 @@ export const _handleCommand = function (cmd: VencordCommand, args: CommandArgume
|
|||
}
|
||||
} as never;
|
||||
|
||||
|
||||
/**
|
||||
* Prepare a Command Option for Discord by filling missing fields
|
||||
* @param opt
|
||||
|
|
|
|||
204
src/api/HeaderBar.tsx
Normal file
204
src/api/HeaderBar.tsx
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2025 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { findComponentByCodeLazy } from "@webpack";
|
||||
import { useEffect, useState } from "@webpack/common";
|
||||
import type { ComponentType, JSX, MouseEventHandler, ReactNode } from "react";
|
||||
|
||||
const logger = new Logger("HeaderBarAPI");
|
||||
|
||||
const HeaderBarIcon = findComponentByCodeLazy(".HEADER_BAR_BADGE_TOP:", '.iconBadge,"top"') as ComponentType<HeaderBarButtonProps>;
|
||||
|
||||
export interface HeaderBarButtonProps {
|
||||
/** The icon component to render inside the button */
|
||||
icon: ComponentType<any>;
|
||||
/** Tooltip text shown on hover. Pass null to disable tooltip */
|
||||
tooltip: ReactNode;
|
||||
/** Called when the button is clicked */
|
||||
onClick?: MouseEventHandler<HTMLDivElement>;
|
||||
/** Called when the button is right-clicked */
|
||||
onContextMenu?: MouseEventHandler<HTMLDivElement>;
|
||||
/** Additional CSS class names */
|
||||
className?: string;
|
||||
/** CSS class name for the icon element */
|
||||
iconClassName?: string;
|
||||
/** Tooltip position relative to the button */
|
||||
position?: "top" | "bottom" | "left" | "right";
|
||||
/** Whether the button appears in a selected/active state */
|
||||
selected?: boolean;
|
||||
/** Whether the button is disabled */
|
||||
disabled?: boolean;
|
||||
/** Whether to show a notification badge */
|
||||
showBadge?: boolean;
|
||||
/** Position of the notification badge */
|
||||
badgePosition?: "top" | "bottom";
|
||||
/** Size of the icon in pixels */
|
||||
iconSize?: number;
|
||||
/** Ref to the button element */
|
||||
ref?: React.RefObject<any>;
|
||||
}
|
||||
|
||||
export type HeaderBarButtonFactory = () => JSX.Element | null;
|
||||
|
||||
export interface HeaderBarButtonData {
|
||||
/** Function that renders the button component */
|
||||
render: HeaderBarButtonFactory;
|
||||
/** Icon component used for settings UI display */
|
||||
icon: ComponentType<any>;
|
||||
/** Higher priority buttons appear further right. Default: 0 */
|
||||
priority?: number;
|
||||
/** Where to render the button. Default: "headerbar" */
|
||||
location?: "headerbar" | "channeltoolbar";
|
||||
}
|
||||
|
||||
interface ButtonEntry {
|
||||
render: HeaderBarButtonFactory;
|
||||
priority: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Button component for the top header bar (title bar area).
|
||||
*
|
||||
* @example
|
||||
* <HeaderBarButton
|
||||
* icon={MyIcon}
|
||||
* tooltip="My Button"
|
||||
* onClick={() => console.log("clicked")}
|
||||
* />
|
||||
*/
|
||||
export const HeaderBarButton = HeaderBarIcon;
|
||||
|
||||
/**
|
||||
* Button component for the channel toolbar (below the search bar).
|
||||
* Automatically handles selected state styling.
|
||||
*
|
||||
* @example
|
||||
* <ChannelToolbarButton
|
||||
* icon={MyIcon}
|
||||
* tooltip={isOpen ? null : "My Button"}
|
||||
* onClick={() => setOpen(v => !v)}
|
||||
* selected={isOpen}
|
||||
* />
|
||||
*/
|
||||
export function ChannelToolbarButton(props: HeaderBarButtonProps) {
|
||||
return <HeaderBarIcon {...props} />;
|
||||
}
|
||||
|
||||
const headerBarButtons = new Map<string, ButtonEntry>();
|
||||
const channelToolbarButtons = new Map<string, ButtonEntry>();
|
||||
|
||||
const headerBarListeners = new Set<() => void>();
|
||||
const channelToolbarListeners = new Set<() => void>();
|
||||
|
||||
/**
|
||||
* Adds a button to the header bar (title bar area).
|
||||
*
|
||||
* @param id - Unique identifier for the button (e.g., "my-plugin-button")
|
||||
* @param render - Function that returns the button JSX
|
||||
* @param priority - Higher values appear further right. Default: 0
|
||||
*
|
||||
* @example
|
||||
* addHeaderBarButton("my-button", () => (
|
||||
* <HeaderBarButton
|
||||
* icon={MyIcon}
|
||||
* tooltip="My Button"
|
||||
* onClick={handleClick}
|
||||
* />
|
||||
* ));
|
||||
*/
|
||||
export function addHeaderBarButton(id: string, render: HeaderBarButtonFactory, priority = 0) {
|
||||
headerBarButtons.set(id, { render, priority });
|
||||
headerBarListeners.forEach(listener => listener());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a button from the header bar.
|
||||
*
|
||||
* @param id - The identifier used when adding the button
|
||||
*/
|
||||
export function removeHeaderBarButton(id: string) {
|
||||
headerBarButtons.delete(id);
|
||||
headerBarListeners.forEach(listener => listener());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a button to the channel toolbar (below the search bar, next to pins/members).
|
||||
*
|
||||
* @param id - Unique identifier for the button (e.g., "my-plugin-toolbar")
|
||||
* @param render - Function that returns the button JSX
|
||||
* @param priority - Higher values appear further right. Default: 0
|
||||
*
|
||||
* @example
|
||||
* addChannelToolbarButton("my-toolbar", () => (
|
||||
* <ChannelToolbarButton
|
||||
* icon={MyIcon}
|
||||
* tooltip="My Button"
|
||||
* onClick={handleClick}
|
||||
* />
|
||||
* ));
|
||||
*/
|
||||
export function addChannelToolbarButton(id: string, render: HeaderBarButtonFactory, priority = 0) {
|
||||
channelToolbarButtons.set(id, { render, priority });
|
||||
channelToolbarListeners.forEach(listener => listener());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a button from the channel toolbar.
|
||||
*
|
||||
* @param id - The identifier used when adding the button
|
||||
*/
|
||||
export function removeChannelToolbarButton(id: string) {
|
||||
channelToolbarButtons.delete(id);
|
||||
channelToolbarListeners.forEach(listener => listener());
|
||||
}
|
||||
|
||||
function HeaderBarButtons() {
|
||||
const [, forceUpdate] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = () => forceUpdate(n => n + 1);
|
||||
headerBarListeners.add(listener);
|
||||
return () => { headerBarListeners.delete(listener); };
|
||||
}, []);
|
||||
|
||||
return Array.from(headerBarButtons)
|
||||
.sort(([, a], [, b]) => a.priority - b.priority)
|
||||
.map(([id, { render: Button }]) => (
|
||||
<ErrorBoundary noop key={id} onError={e => logger.error(`Failed to render header bar button: ${id}`, e.error)}>
|
||||
<Button />
|
||||
</ErrorBoundary>
|
||||
));
|
||||
}
|
||||
|
||||
function ChannelToolbarButtons() {
|
||||
const [, forceUpdate] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = () => forceUpdate(n => n + 1);
|
||||
channelToolbarListeners.add(listener);
|
||||
return () => { channelToolbarListeners.delete(listener); };
|
||||
}, []);
|
||||
|
||||
return Array.from(channelToolbarButtons)
|
||||
.sort(([, a], [, b]) => a.priority - b.priority)
|
||||
.map(([id, { render: Button }]) => (
|
||||
<ErrorBoundary noop key={id} onError={e => logger.error(`Failed to render channel toolbar button: ${id}`, e.error)}>
|
||||
<Button />
|
||||
</ErrorBoundary>
|
||||
));
|
||||
}
|
||||
|
||||
/** @internal Injected by HeaderBarAPI patch (do NOT call directly) */
|
||||
export function _addHeaderBarButtons() {
|
||||
return [<HeaderBarButtons key="vc-header-bar-buttons" />];
|
||||
}
|
||||
|
||||
/** @internal Injected by HeaderBarAPI patch (do NOT call directly) */
|
||||
export function _addChannelToolbarButtons(toolbar: ReactNode[]) {
|
||||
toolbar.push(<ChannelToolbarButtons key="vc-channel-toolbar-buttons" />);
|
||||
}
|
||||
|
|
@ -106,7 +106,6 @@ export function removeMessagePreEditListener(listener: MessageEditListener) {
|
|||
return editListeners.delete(listener);
|
||||
}
|
||||
|
||||
|
||||
// Message clicks
|
||||
export type MessageClickListener = (message: Message, channel: Channel, event: MouseEvent) => void;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@
|
|||
|
||||
import * as DataStore from "@api/DataStore";
|
||||
import { Settings } from "@api/Settings";
|
||||
import { classNameFactory } from "@api/Styles";
|
||||
import { BaseText } from "@components/BaseText";
|
||||
import { Flex } from "@components/Flex";
|
||||
import { Paragraph } from "@components/Paragraph";
|
||||
import { openNotificationSettingsModal } from "@components/settings/tabs/vencord/NotificationSettings";
|
||||
import { classNameFactory } from "@utils/css";
|
||||
import { closeModal, ModalCloseButton, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
||||
import { useAwaiter } from "@utils/react";
|
||||
import { t } from "@utils/translation";
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
}
|
||||
|
||||
.vc-notification-title {
|
||||
color: var(--header-primary);
|
||||
color: var(--text-strong);
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.25rem;
|
||||
|
|
@ -47,13 +47,13 @@
|
|||
.vc-notification-close-btn {
|
||||
all: unset;
|
||||
cursor: pointer;
|
||||
color: var(--interactive-normal);
|
||||
color: var(--interactive-icon-default);
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.2s ease-in-out, color 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.vc-notification-close-btn:hover {
|
||||
color: var(--interactive-hover);
|
||||
color: var(--interactive-icon-hover);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
|
@ -137,5 +137,5 @@
|
|||
|
||||
.vc-notification-log-danger-btn {
|
||||
color: var(--white-500);
|
||||
background-color: var(--button-danger-background);
|
||||
background-color: var(--redesign-button-danger-background);
|
||||
}
|
||||
|
|
@ -40,6 +40,9 @@ import Plugins from "~plugins";
|
|||
export { Plugins as plugins };
|
||||
|
||||
import { traceFunction } from "../debug/Tracer";
|
||||
import { addAudioProcessor, removeAudioProcessor } from "./AudioPlayer";
|
||||
import { addChannelToolbarButton, addHeaderBarButton, removeChannelToolbarButton, removeHeaderBarButton } from "./HeaderBar";
|
||||
import { addUserAreaButton, removeUserAreaButton } from "./UserArea";
|
||||
|
||||
const logger = new Logger("PluginManager", "#a6d189");
|
||||
|
||||
|
|
@ -98,6 +101,10 @@ function isReporterTestable(p: Plugin, part: ReporterTestable) {
|
|||
: (p.reporterTestable & part) === part;
|
||||
}
|
||||
|
||||
export function pluginRequiresRestart(p: Plugin) {
|
||||
return p.requiresRestart !== false && (p.requiresRestart || !!p.patches?.length);
|
||||
}
|
||||
|
||||
export const startAllPlugins = traceFunction("startAllPlugins", function startAllPlugins(target: StartAt) {
|
||||
logger.info(`Starting plugins (stage ${target})`);
|
||||
for (const name in Plugins) {
|
||||
|
|
@ -126,7 +133,7 @@ export function startDependenciesRecursive(p: Plugin) {
|
|||
settings[d].enabled = true;
|
||||
dep.isDependency = true;
|
||||
|
||||
if (dep.patches) {
|
||||
if (pluginRequiresRestart(dep)) {
|
||||
logger.warn(`Enabling dependency ${d} requires restart.`);
|
||||
restartNeeded = true;
|
||||
return;
|
||||
|
|
@ -186,7 +193,9 @@ export const startPlugin = traceFunction("startPlugin", function startPlugin(p:
|
|||
const {
|
||||
name, commands, contextMenus, managedStyle, userProfileBadges,
|
||||
onBeforeMessageEdit, onBeforeMessageSend, onMessageClick,
|
||||
renderChatBarButton, chatBarButton, renderMemberListDecorator, renderMessageAccessory, renderMessageDecoration, renderMessagePopoverButton, messagePopoverButton, renderNicknameIcon
|
||||
renderChatBarButton, chatBarButton, renderMemberListDecorator, renderMessageAccessory, renderMessageDecoration, renderMessagePopoverButton, messagePopoverButton,
|
||||
// Custom
|
||||
renderNicknameIcon, headerBarButton, audioProcessor, userAreaButton
|
||||
} = p;
|
||||
|
||||
if (p.start) {
|
||||
|
|
@ -240,13 +249,24 @@ export const startPlugin = traceFunction("startPlugin", function startPlugin(p:
|
|||
// @ts-expect-error: legacy code doesn't have icon
|
||||
else if (renderChatBarButton) addChatBarButton(name, renderChatBarButton);
|
||||
if (renderMemberListDecorator) addMemberListDecorator(name, renderMemberListDecorator);
|
||||
if (renderNicknameIcon) addNicknameIcon(name, renderNicknameIcon);
|
||||
if (renderMessageDecoration) addMessageDecoration(name, renderMessageDecoration);
|
||||
if (renderMessageAccessory) addMessageAccessory(name, renderMessageAccessory);
|
||||
if (messagePopoverButton) addMessagePopoverButton(name, messagePopoverButton.render, messagePopoverButton.icon);
|
||||
// @ts-expect-error: legacy code doesn't have icon
|
||||
else if (renderMessagePopoverButton) addMessagePopoverButton(name, renderMessagePopoverButton);
|
||||
|
||||
// Custom
|
||||
if (renderNicknameIcon) addNicknameIcon(name, renderNicknameIcon);
|
||||
if (headerBarButton) {
|
||||
if (headerBarButton.location === "channeltoolbar") {
|
||||
addChannelToolbarButton(name, headerBarButton.render, headerBarButton.priority);
|
||||
} else {
|
||||
addHeaderBarButton(name, headerBarButton.render, headerBarButton.priority);
|
||||
}
|
||||
}
|
||||
if (audioProcessor) addAudioProcessor(name, audioProcessor);
|
||||
if (userAreaButton) addUserAreaButton(name, userAreaButton.render, userAreaButton.priority);
|
||||
|
||||
return true;
|
||||
}, p => `startPlugin ${p.name}`);
|
||||
|
||||
|
|
@ -254,7 +274,9 @@ export const stopPlugin = traceFunction("stopPlugin", function stopPlugin(p: Plu
|
|||
const {
|
||||
name, commands, contextMenus, managedStyle, userProfileBadges,
|
||||
onBeforeMessageEdit, onBeforeMessageSend, onMessageClick,
|
||||
renderChatBarButton, chatBarButton, renderMemberListDecorator, renderMessageAccessory, renderMessageDecoration, renderMessagePopoverButton, messagePopoverButton, renderNicknameIcon
|
||||
renderChatBarButton, chatBarButton, renderMemberListDecorator, renderMessageAccessory, renderMessageDecoration, renderMessagePopoverButton, messagePopoverButton,
|
||||
// Custom
|
||||
renderNicknameIcon, headerBarButton, audioProcessor, userAreaButton
|
||||
} = p;
|
||||
|
||||
if (p.stop) {
|
||||
|
|
@ -304,11 +326,22 @@ export const stopPlugin = traceFunction("stopPlugin", function stopPlugin(p: Plu
|
|||
|
||||
if (chatBarButton || renderChatBarButton) removeChatBarButton(name);
|
||||
if (renderMemberListDecorator) removeMemberListDecorator(name);
|
||||
if (renderNicknameIcon) removeNicknameIcon(name);
|
||||
if (renderMessageDecoration) removeMessageDecoration(name);
|
||||
if (renderMessageAccessory) removeMessageAccessory(name);
|
||||
if (messagePopoverButton || renderMessagePopoverButton) removeMessagePopoverButton(name);
|
||||
|
||||
// Custom
|
||||
if (renderNicknameIcon) removeNicknameIcon(name);
|
||||
if (headerBarButton) {
|
||||
if (headerBarButton.location === "channeltoolbar") {
|
||||
removeChannelToolbarButton(name);
|
||||
} else {
|
||||
removeHeaderBarButton(name);
|
||||
}
|
||||
}
|
||||
if (audioProcessor) removeAudioProcessor(name);
|
||||
if (userAreaButton) removeUserAreaButton(name);
|
||||
|
||||
return true;
|
||||
}, p => `stopPlugin ${p.name}`);
|
||||
|
||||
|
|
@ -318,7 +351,9 @@ export const initPluginManager = onlyOnce(function init() {
|
|||
|
||||
const pluginKeysToBind: Array<keyof PluginDef & `${"on" | "render"}${string}`> = [
|
||||
"onBeforeMessageEdit", "onBeforeMessageSend", "onMessageClick",
|
||||
"renderChatBarButton", "renderMemberListDecorator", "renderMessageAccessory", "renderMessageDecoration", "renderMessagePopoverButton", "renderNicknameIcon"
|
||||
"renderChatBarButton", "renderMemberListDecorator", "renderMessageAccessory", "renderMessageDecoration", "renderMessagePopoverButton",
|
||||
// Custom
|
||||
"renderNicknameIcon"
|
||||
];
|
||||
|
||||
const neededApiPlugins = new Set<string>();
|
||||
|
|
@ -353,9 +388,14 @@ export const initPluginManager = onlyOnce(function init() {
|
|||
if (p.renderMessageAccessory) neededApiPlugins.add("MessageAccessoriesAPI");
|
||||
if (p.renderMessageDecoration) neededApiPlugins.add("MessageDecorationsAPI");
|
||||
if (p.messagePopoverButton || p.renderMessagePopoverButton) neededApiPlugins.add("MessagePopoverAPI");
|
||||
if (p.renderNicknameIcon) neededApiPlugins.add("NicknameIconsAPI");
|
||||
if (p.userProfileBadge) neededApiPlugins.add("BadgeAPI");
|
||||
|
||||
// Custom
|
||||
if (p.renderNicknameIcon) neededApiPlugins.add("NicknameIconsAPI");
|
||||
if (p.headerBarButton) neededApiPlugins.add("HeaderBarAPI");
|
||||
if (p.audioProcessor) neededApiPlugins.add("AudioPlayerAPI");
|
||||
if (p.userAreaButton) neededApiPlugins.add("UserAreaAPI");
|
||||
|
||||
for (const key of pluginKeysToBind) {
|
||||
p[key] &&= p[key].bind(p) as any;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ export interface Settings {
|
|||
eagerPatches: boolean;
|
||||
enabledThemes: string[];
|
||||
enabledThemeLinks: string[];
|
||||
enableOnlineThemes: boolean;
|
||||
pinnedThemes: string[];
|
||||
themeNames: Record<string, string>;
|
||||
enableReactDevtools: boolean;
|
||||
themeLinks: string[];
|
||||
|
|
@ -110,6 +112,8 @@ const DefaultSettings: Settings = {
|
|||
eagerPatches: IS_REPORTER,
|
||||
enabledThemes: [],
|
||||
enabledThemeLinks: [],
|
||||
enableOnlineThemes: true,
|
||||
pinnedThemes: [],
|
||||
themeNames: {},
|
||||
enableReactDevtools: false,
|
||||
frameless: false,
|
||||
|
|
@ -247,21 +251,6 @@ export function useSettings(paths?: UseSettings<Settings>[]) {
|
|||
return SettingsStore.store;
|
||||
}
|
||||
|
||||
export function migratePluginToSetting(newName: string, oldName: string, settingName: string) {
|
||||
const { plugins } = SettingsStore.plain;
|
||||
const newPlugin = plugins[newName];
|
||||
const oldPlugin = plugins[oldName];
|
||||
|
||||
if (!newPlugin || !oldPlugin) return;
|
||||
|
||||
if (oldPlugin?.enabled) {
|
||||
newPlugin[settingName] = true;
|
||||
oldPlugin.enabled = false;
|
||||
if (!newPlugin?.enabled) newPlugin.enabled = true;
|
||||
SettingsStore.markAsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
export function migratePluginSettings(name: string, ...oldNames: string[]) {
|
||||
const { plugins } = SettingsStore.plain;
|
||||
if (name in plugins) return;
|
||||
|
|
@ -283,21 +272,46 @@ export function migratePluginSetting(pluginName: string, newSetting: string, old
|
|||
|
||||
if (!Object.hasOwn(settings, oldSetting) || Object.hasOwn(settings, newSetting)) return;
|
||||
|
||||
logger.info(`Migrating plugin setting from ${oldSetting} to ${newSetting} on ${pluginName}`);
|
||||
settings[newSetting] = settings[oldSetting];
|
||||
delete settings[oldSetting];
|
||||
SettingsStore.markAsChanged();
|
||||
}
|
||||
|
||||
export function migrateSettingFromPlugin(newPlugin: string, newSetting: string, oldPlugin: string, oldSetting: string) {
|
||||
const newSettings = SettingsStore.plain.plugins[newPlugin];
|
||||
const oldSettings = SettingsStore.plain.plugins[oldPlugin];
|
||||
if (!oldSettings || !Object.hasOwn(oldSettings, oldSetting)) return;
|
||||
if (!newSettings || (Object.hasOwn(newSettings, newSetting))) return;
|
||||
export function migratePluginToSettings(deleteOldSettings: boolean, newName: string, oldName: string, ...settingNames: string[]) {
|
||||
const { plugins } = SettingsStore.plain;
|
||||
const newPlugin = plugins[newName];
|
||||
const oldPlugin = plugins[oldName];
|
||||
|
||||
if (Object.hasOwn(newSettings, newSetting)) return;
|
||||
if (newPlugin && oldPlugin?.enabled) {
|
||||
for (const settingName of settingNames) {
|
||||
logger.info(`Migrating plugin to setting from old name ${oldName} to ${newName} as ${settingName}`);
|
||||
newPlugin[settingName] = true;
|
||||
}
|
||||
|
||||
newPlugin.enabled = true;
|
||||
if (deleteOldSettings) delete plugins[oldName];
|
||||
SettingsStore.markAsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
export function migrateSettingsFromPlugin(newPlugin: string, oldPlugin: string, ...settings: string[]) {
|
||||
const { plugins } = SettingsStore.plain;
|
||||
|
||||
const oldSettings = plugins[oldPlugin];
|
||||
const newSettings = plugins[newPlugin];
|
||||
if (!oldSettings || !newSettings) return;
|
||||
|
||||
for (const setting of settings) {
|
||||
if (!Object.hasOwn(oldSettings, setting)) continue;
|
||||
if (Object.hasOwn(newSettings, setting)) continue;
|
||||
|
||||
logger.info(`Migrating plugin setting "${setting}" from ${oldPlugin} to ${newPlugin}`);
|
||||
|
||||
newSettings[setting] = oldSettings[setting];
|
||||
delete oldSettings[setting];
|
||||
}
|
||||
|
||||
newSettings[newSetting] = oldSettings[oldSetting];
|
||||
delete oldSettings[oldSetting];
|
||||
SettingsStore.markAsChanged();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@
|
|||
|
||||
import { showNotification } from "@api/Notifications";
|
||||
import { PlainSettings, Settings } from "@api/Settings";
|
||||
import { localStorage } from "@utils/localStorage";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { relaunch } from "@utils/native";
|
||||
import { t } from "@utils/translation";
|
||||
import { SettingsRouter } from "@webpack/common";
|
||||
import { openUserSettingsPanel } from "@webpack/common";
|
||||
import { deflateSync, inflateSync } from "fflate";
|
||||
|
||||
import { deauthorizeCloud, getCloudAuth, getCloudUrl } from "./cloudSetup";
|
||||
|
|
@ -17,8 +18,14 @@ import { exportSettings, importSettings } from "./offline";
|
|||
|
||||
const logger = new Logger("SettingsSync:Cloud", "#39b7e0");
|
||||
|
||||
export function shouldCloudSync(direction: "push" | "pull") {
|
||||
const localDirection = localStorage.Vencord_cloudSyncDirection;
|
||||
|
||||
return localDirection === direction || localDirection === "both";
|
||||
}
|
||||
|
||||
export async function putCloudSettings(manual?: boolean) {
|
||||
const settings = await exportSettings({ minify: true });
|
||||
const settings = await exportSettings({ syncDataStore: false, minify: true });
|
||||
|
||||
try {
|
||||
const res = await fetch(new URL("/v1/settings", getCloudUrl()), {
|
||||
|
|
@ -53,6 +60,8 @@ export async function putCloudSettings(manual?: boolean) {
|
|||
noPersist: true,
|
||||
});
|
||||
}
|
||||
|
||||
delete localStorage.Vencord_settingsDirty;
|
||||
} catch (e: any) {
|
||||
logger.error("Failed to sync up", e);
|
||||
showNotification({
|
||||
|
|
@ -80,7 +89,7 @@ export async function getCloudSettings(shouldNotify = true, force = false) {
|
|||
title: t("vencord.cloud.settings.header"),
|
||||
body: t("vencord.cloud.settings.accountChanged"),
|
||||
color: "var(--yellow-360)",
|
||||
onClick: () => SettingsRouter.open("VencordCloud")
|
||||
onClick: () => openUserSettingsPanel("equicord_cloud")
|
||||
});
|
||||
// Disable cloud sync globally
|
||||
Settings.cloud.authenticated = false;
|
||||
|
|
@ -136,7 +145,7 @@ export async function getCloudSettings(shouldNotify = true, force = false) {
|
|||
const data = await res.arrayBuffer();
|
||||
|
||||
const settings = new TextDecoder().decode(inflateSync(new Uint8Array(data)));
|
||||
await importSettings(settings);
|
||||
await importSettings(settings, "all", true);
|
||||
|
||||
// sync with server timestamp instead of local one
|
||||
PlainSettings.cloud.settingsSyncVersion = written;
|
||||
|
|
@ -152,6 +161,8 @@ export async function getCloudSettings(shouldNotify = true, force = false) {
|
|||
noPersist: true
|
||||
});
|
||||
|
||||
delete localStorage.Vencord_settingsDirty;
|
||||
|
||||
return true;
|
||||
} catch (e: any) {
|
||||
logger.error("Failed to sync down", e);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ import { moment, Toasts } from "@webpack/common";
|
|||
|
||||
import { DataStore } from "..";
|
||||
|
||||
type BackupType = "all" | "plugins" | "css" | "datastore";
|
||||
|
||||
const toast = (type: string, message: string) =>
|
||||
Toasts.show({
|
||||
type,
|
||||
|
|
@ -27,7 +29,22 @@ const toastFailure = (err: any) =>
|
|||
|
||||
const logger = new Logger("SettingsSync:Offline", "#39b7e0");
|
||||
|
||||
export async function importSettings(data: string) {
|
||||
function isSafeObject(obj: any) {
|
||||
if (obj == null || typeof obj !== "object") return true;
|
||||
|
||||
for (const key in obj) {
|
||||
if (["__proto__", "constructor", "prototype"].includes(key)) {
|
||||
return false;
|
||||
}
|
||||
if (!isSafeObject(obj[key])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function importSettings(data: string, type: BackupType = "all", cloud = false) {
|
||||
try {
|
||||
var parsed = JSON.parse(data);
|
||||
} catch (err) {
|
||||
|
|
@ -35,58 +52,67 @@ export async function importSettings(data: string) {
|
|||
throw new Error("Failed to parse JSON: " + String(err));
|
||||
}
|
||||
|
||||
if ("settings" in parsed && "quickCss" in parsed) {
|
||||
Object.assign(PlainSettings, parsed.settings);
|
||||
await VencordNative.settings.set(parsed.settings);
|
||||
await VencordNative.quickCss.set(parsed.quickCss);
|
||||
} else
|
||||
throw new Error("Invalid Settings. Is this even a Vencord Settings file?");
|
||||
}
|
||||
|
||||
export async function exportSettings({ minify }: { minify?: boolean; } = {}) {
|
||||
const settings = VencordNative.settings.get();
|
||||
const quickCss = await VencordNative.quickCss.get();
|
||||
const dataStore = await DataStore.entries();
|
||||
return JSON.stringify({ settings, quickCss, dataStore }, null, minify ? undefined : 4);
|
||||
}
|
||||
|
||||
export async function exportPlugins({ minify }: { minify?: boolean; } = {}) {
|
||||
const { plugins } = VencordNative.settings.get();
|
||||
return JSON.stringify({ settings: { plugins } }, null, minify ? undefined : 4);
|
||||
}
|
||||
|
||||
export async function exportCSS({ minify }: { minify?: boolean; } = {}) {
|
||||
const quickCss = await VencordNative.quickCss.get();
|
||||
return JSON.stringify({ quickCss }, null, minify ? undefined : 4);
|
||||
}
|
||||
|
||||
export async function exportDataStores({ minify }: { minify?: boolean; } = {}) {
|
||||
const dataStore = await DataStore.entries();
|
||||
return JSON.stringify({ dataStore }, null, minify ? undefined : 4);
|
||||
}
|
||||
|
||||
type BackupType = "settings" | "plugins" | "css" | "datastore";
|
||||
|
||||
export async function downloadSettingsBackup(type: BackupType, { minify }: { minify?: boolean; } = {}) {
|
||||
let backup: string;
|
||||
if (!isSafeObject(parsed))
|
||||
throw new Error("Unsafe Settings");
|
||||
|
||||
switch (type) {
|
||||
case "settings":
|
||||
backup = await exportSettings({ minify });
|
||||
break;
|
||||
case "plugins":
|
||||
backup = await exportPlugins({ minify });
|
||||
break;
|
||||
case "css":
|
||||
backup = await exportCSS({ minify });
|
||||
break;
|
||||
case "datastore":
|
||||
backup = await exportDataStores({ minify });
|
||||
break;
|
||||
default:
|
||||
throw new Error("Invalid backup type");
|
||||
}
|
||||
case "all": {
|
||||
if (!cloud && (!("settings" in parsed)))
|
||||
throw new Error("Invalid Settings. Plugin settings is required for this import try a different one.");
|
||||
|
||||
if (parsed.settings) {
|
||||
Object.assign(PlainSettings, parsed.settings);
|
||||
await VencordNative.settings.set(parsed.settings);
|
||||
}
|
||||
if (parsed.quickCss) await VencordNative.quickCss.set(parsed.quickCss);
|
||||
if (parsed.dataStore) await DataStore.setMany(parsed.dataStore);
|
||||
break;
|
||||
}
|
||||
case "plugins": {
|
||||
if (!parsed.settings) throw new Error("Plugin settings missing");
|
||||
|
||||
Object.assign(PlainSettings, parsed.settings);
|
||||
await VencordNative.settings.set(parsed.settings);
|
||||
break;
|
||||
}
|
||||
case "css": {
|
||||
if (!parsed.quickCss) throw new Error("CSS missing");
|
||||
|
||||
await VencordNative.quickCss.set(parsed.quickCss);
|
||||
break;
|
||||
}
|
||||
case "datastore": {
|
||||
if (!parsed.dataStore) throw new Error("DataStore data missing");
|
||||
|
||||
await DataStore.setMany(parsed.dataStore);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function exportSettings({ syncDataStore = true, type = "all", minify }: { syncDataStore?: boolean; type?: BackupType; minify?: boolean; }) {
|
||||
const settings = VencordNative.settings.get();
|
||||
const quickCss = await VencordNative.quickCss.get();
|
||||
const dataStore = syncDataStore ? await DataStore.entries() : undefined;
|
||||
|
||||
switch (type) {
|
||||
case "all": {
|
||||
return JSON.stringify({ settings, quickCss, ...(syncDataStore && { dataStore }) }, null, minify ? undefined : 4);
|
||||
}
|
||||
case "plugins": {
|
||||
return JSON.stringify({ settings }, null, minify ? undefined : 4);
|
||||
}
|
||||
case "css": {
|
||||
return JSON.stringify({ quickCss }, null, minify ? undefined : 4);
|
||||
}
|
||||
case "datastore": {
|
||||
return JSON.stringify({ dataStore }, null, minify ? undefined : 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function downloadSettingsBackup(type: BackupType = "all", { minify }: { minify?: boolean; } = {}) {
|
||||
const backup = await exportSettings({ minify, type });
|
||||
const filename = `equicord-${type}-backup-${moment().format("YYYY-MM-DD")}.json`;
|
||||
const data = new TextEncoder().encode(backup);
|
||||
|
||||
|
|
@ -97,18 +123,18 @@ export async function downloadSettingsBackup(type: BackupType, { minify }: { min
|
|||
}
|
||||
}
|
||||
|
||||
export async function uploadSettingsBackup(showToast = true): Promise<void> {
|
||||
export async function uploadSettingsBackup(type: BackupType = "all", showToast = true): Promise<void> {
|
||||
if (IS_DISCORD_DESKTOP) {
|
||||
const [file] = await DiscordNative.fileManager.openFiles({
|
||||
filters: [
|
||||
{ name: "Vencord Settings Backup", extensions: ["json"] },
|
||||
{ name: "Equicord Settings Backup", extensions: ["json"] },
|
||||
{ name: "all", extensions: ["*"] }
|
||||
]
|
||||
});
|
||||
|
||||
if (file) {
|
||||
try {
|
||||
await importSettings(new TextDecoder().decode(file.data));
|
||||
await importSettings(new TextDecoder().decode(file.data), type);
|
||||
if (showToast) toastSuccess();
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
|
|
@ -122,7 +148,7 @@ export async function uploadSettingsBackup(showToast = true): Promise<void> {
|
|||
const reader = new FileReader();
|
||||
reader.onload = async () => {
|
||||
try {
|
||||
await importSettings(reader.result as string);
|
||||
await importSettings(reader.result as string, type);
|
||||
if (showToast) toastSuccess();
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue