Start moving away from Discord components
This commit is contained in:
parent
be4f788a03
commit
4cb8964aa8
|
@ -1,9 +1,9 @@
|
|||
import {DiscordModules, Utilities} from "modules";
|
||||
|
||||
export default class SimpleMarkdownExt {
|
||||
static parseToReact(str) {
|
||||
static parseToReact(str, inline = true) {
|
||||
if (!this._parser) this._initialize();
|
||||
return this._renderer(this._parse(str, {inline: true}));
|
||||
return this._renderer(this._parse(str, {inline}));
|
||||
}
|
||||
|
||||
static _initialize() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.bd-button {
|
||||
/* .bd-button {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
@ -59,4 +59,539 @@
|
|||
|
||||
.bd-button-disabled:hover {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
} */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Generic Button Styles */
|
||||
.bd-button {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 16px;
|
||||
padding: 2px 16px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.bd-button:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.bd-button .bd-button-content {
|
||||
--button--underline-color: transparent;
|
||||
background-image: linear-gradient(0deg, transparent, transparent 1px, var(--button--underline-color) 0, var(--button--underline-color) 2px, transparent 0);
|
||||
}
|
||||
|
||||
.bd-button:disabled .bd-button-content {
|
||||
background-image: none !important;
|
||||
}
|
||||
|
||||
.bd-button-outlined:disabled {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Button Sizes */
|
||||
.bd-button-tiny {
|
||||
width: 52px;
|
||||
height: 24px;
|
||||
min-width: 52px;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
.bd-button-small {
|
||||
width: 60px;
|
||||
height: 32px;
|
||||
min-width: 60px;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.bd-button-medium {
|
||||
width: 96px;
|
||||
height: 38px;
|
||||
min-width: 96px;
|
||||
min-height: 38px;
|
||||
}
|
||||
|
||||
.bd-button-large {
|
||||
width: 130px;
|
||||
height: 44px;
|
||||
min-width: 130px;
|
||||
min-height: 44px;
|
||||
}
|
||||
|
||||
.bd-button-xlarge {
|
||||
width: 148px;
|
||||
height: 50px;
|
||||
min-width: 148px;
|
||||
min-height: 50px;
|
||||
font-size: 16px;
|
||||
line-height: normal;
|
||||
padding: 2px 20px;
|
||||
}
|
||||
|
||||
.bd-button-icon {
|
||||
height: auto;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.bd-button-grow,
|
||||
.bd-button-icon {
|
||||
width: auto
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Button Looks */
|
||||
.bd-button-filled {
|
||||
-webkit-transition: background-color .17s ease, color .17s ease;
|
||||
transition: background-color .17s ease, color .17s ease
|
||||
}
|
||||
|
||||
.bd-button-outlined {
|
||||
-webkit-transition: color .17s ease, background-color .17s ease, border-color .17s ease;
|
||||
transition: color .17s ease, background-color .17s ease, border-color .17s ease;
|
||||
border-width: 1px;
|
||||
border-style: solid
|
||||
}
|
||||
|
||||
.bd-button-blank {
|
||||
background: transparent;
|
||||
color: currentColor;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.bd-button-filled .bd-button-content,
|
||||
.bd-button-link .bd-button-content,
|
||||
.bd-button-outlined .bd-button-content {
|
||||
margin: 0 auto;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* COLORS */
|
||||
|
||||
/* Color BD Brand */
|
||||
.bd-button-filled.bd-button-color-brand {
|
||||
color: var(--white-500);
|
||||
background-color: #3E82E5; /* BD Blue */
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-brand:hover {
|
||||
background-color: #3875CE;
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-brand:active {
|
||||
background-color: #3268B7;
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-brand:disabled {
|
||||
background-color: #3E82E5; /* BD Blue */
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-brand {
|
||||
color: var(--button-outline-brand-text);
|
||||
border-color: var(--button-outline-brand-border);
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-brand:hover {
|
||||
background-color: var(--button-outline-brand-background-hover);
|
||||
border-color: var(--button-outline-brand-border-hover);
|
||||
color: var(--button-outline-brand-text-hover);
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-brand:active {
|
||||
background-color: var(--button-outline-brand-background-active);
|
||||
border-color: var(--button-outline-brand-border-active);
|
||||
color: var(--button-outline-brand-text-active);
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-brand {
|
||||
color: #3E82E5; /* BD Blue */
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-brand:hover .bd-button-content {
|
||||
--button--underline-color: #3E82E5; /* BD Blue */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Color Blurple */
|
||||
.bd-button-filled.bd-button-color-blurple {
|
||||
color: var(--white-500);
|
||||
background-color: var(--brand-experiment)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-blurple:hover {
|
||||
background-color: var(--brand-experiment-560)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-blurple:active {
|
||||
background-color: var(--brand-experiment-600)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-blurple:disabled {
|
||||
background-color: var(--brand-experiment)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-blurple {
|
||||
color: var(--button-outline-brand-text);
|
||||
border-color: var(--button-outline-brand-border)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-blurple:hover {
|
||||
background-color: var(--button-outline-brand-background-hover);
|
||||
border-color: var(--button-outline-brand-border-hover);
|
||||
color: var(--button-outline-brand-text-hover)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-blurple:active {
|
||||
background-color: var(--button-outline-brand-background-active);
|
||||
border-color: var(--button-outline-brand-border-active);
|
||||
color: var(--button-outline-brand-text-active)
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-blurple {
|
||||
color: var(--brand-experiment)
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-blurple:hover .bd-button-content {
|
||||
--button--underline-color: var(--brand-experiment)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Color Yellow/Warn */
|
||||
.bd-button-filled.bd-button-color-yellow {
|
||||
color: var(--white-500);
|
||||
background-color: var(--status-warning)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-yellow:active,
|
||||
.bd-button-filled.bd-button-color-yellow:hover {
|
||||
background-color: null;
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-yellow:disabled {
|
||||
background-color: var(--status-warning)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-yellow {
|
||||
color: var(--status-warning);
|
||||
border-color: var(--status-warning)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-yellow:active {
|
||||
background-color: hsl(var(--yellow-300-hsl)/.1)
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-yellow {
|
||||
color: var(--status-warning)
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-yellow:hover .bd-button-content {
|
||||
--button--underline-color: var(--status-warning)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Color Link */
|
||||
.bd-button-filled.bd-button-color-link {
|
||||
color: var(--white-500);
|
||||
background-color: var(--text-link)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-link:active,
|
||||
.bd-button-filled.bd-button-color-link:hover {
|
||||
background-color: null
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-link:disabled {
|
||||
background-color: var(--text-link)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-link {
|
||||
color: var(--text-link);
|
||||
border-color: var(--text-link)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-link:active {
|
||||
background-color: hsl(var(--text-link-hsl)/.1)
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-link {
|
||||
color: var(--text-link)
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-link:hover .bd-button-content {
|
||||
--button--underline-color: var(--text-link)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Color White */
|
||||
.bd-button-filled.bd-button-color-white {
|
||||
color: var(--primary-500);
|
||||
background-color: var(--white-500)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-white:active,
|
||||
.bd-button-filled.bd-button-color-white:hover {
|
||||
background-color: null
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-white:disabled {
|
||||
background-color: var(--white-500)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-white {
|
||||
color: var(--white-500);
|
||||
border-color: var(--white-500)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-white:active {
|
||||
background-color: hsl(var(--white-500-hsl)/.1)
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-white {
|
||||
color: var(--white-500)
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-white:hover .bd-button-content {
|
||||
--button--underline-color: var(--white-500)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Color Red/Danger/Error */
|
||||
.bd-button-filled.bd-button-color-red {
|
||||
color: var(--white-500);
|
||||
background-color: var(--button-danger-background)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-red:hover {
|
||||
background-color: var(--button-danger-background-hover)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-red:active {
|
||||
background-color: var(--button-danger-background-active)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-red:disabled {
|
||||
background-color: var(--button-danger-background-disabled)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-red {
|
||||
color: var(--button-outline-danger-text);
|
||||
border-color: var(--button-outline-danger-border)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-red:hover {
|
||||
background-color: var(--button-outline-danger-background-hover);
|
||||
border-color: var(--button-outline-danger-border-hover);
|
||||
color: var(--button-outline-danger-text-hover)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-red:active {
|
||||
background-color: var(--button-outline-danger-background-active);
|
||||
border-color: var(--button-outline-danger-border-active);
|
||||
color: var(--button-outline-danger-text-active)
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-red {
|
||||
color: var(--text-danger)
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-red:hover .bd-button-content {
|
||||
--button--underline-color: var(--text-danger)
|
||||
}
|
||||
|
||||
|
||||
/* Color Green Success */
|
||||
.bd-button-filled.bd-button-color-green {
|
||||
color: var(--white-500);
|
||||
background-color: var(--button-positive-background)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-green:hover {
|
||||
background-color: var(--button-positive-background-hover)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-green:active {
|
||||
background-color: var(--button-positive-background-active)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-green:disabled {
|
||||
background-color: var(--button-positive-background-disabled)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-green {
|
||||
color: var(--button-outline-positive-text);
|
||||
border-color: var(--button-outline-positive-border)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-green:hover {
|
||||
background-color: var(--button-outline-positive-background-hover);
|
||||
border-color: var(--button-outline-positive-border-hover);
|
||||
color: var(--button-outline-positive-text-hover)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-green:active {
|
||||
background-color: var(--button-outline-positive-background-active);
|
||||
border-color: var(--button-outline-positive-border-active);
|
||||
color: var(--button-outline-positive-text-active)
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-green {
|
||||
color: var(--green-360)
|
||||
}
|
||||
|
||||
.bd-button-link.bd-button-color-green:hover .bd-button-content {
|
||||
--button--underline-color: var(--green-360)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Color Primary/Grey */
|
||||
.bd-button-outlined.bd-button-color-primary {
|
||||
color: var(--button-outline-primary-text);
|
||||
border-color: var(--button-outline-primary-border)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-primary:hover {
|
||||
background-color: var(--button-outline-primary-background-hover);
|
||||
border-color: var(--button-outline-primary-border-hover);
|
||||
color: var(--button-outline-primary-text-hover)
|
||||
}
|
||||
|
||||
.bd-button-outlined.bd-button-color-primary:active {
|
||||
background-color: var(--button-outline-primary-background-active);
|
||||
border-color: var(--button-outline-primary-border-active);
|
||||
color: var(--button-outline-primary-text-active)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-primary {
|
||||
color: var(--white-500);
|
||||
background-color: var(--button-secondary-background)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-primary:hover {
|
||||
background-color: var(--button-secondary-background-hover)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-primary:active {
|
||||
background-color: var(--button-secondary-background-active)
|
||||
}
|
||||
|
||||
.bd-button-filled.bd-button-color-primary:disabled {
|
||||
background-color: var(--button-secondary-background-disabled)
|
||||
}
|
||||
|
||||
.theme-dark .bd-button-link.bd-button-color-primary {
|
||||
color: var(--white-500)
|
||||
}
|
||||
|
||||
.theme-dark .bd-button-link.bd-button-color-primary:hover .bd-button-content {
|
||||
--button--underline-color: var(--white-500)
|
||||
}
|
||||
|
||||
.theme-light .bd-button-link.bd-button-color-primary {
|
||||
color: var(--primary-400)
|
||||
}
|
||||
|
||||
.theme-light .bd-button-link.bd-button-color-primary:hover .bd-button-content {
|
||||
--button--underline-color: var(--primary-400)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Color Transparent */
|
||||
.theme-dark .bd-button-filled.bd-button-color-transparent {
|
||||
color: var(--primary-100);
|
||||
background-color: hsl(var(--white-500-hsl)/.1)
|
||||
}
|
||||
|
||||
.theme-dark .bd-button-filled.bd-button-color-transparent:hover {
|
||||
background-color: hsl(var(--white-500-hsl)/.05)
|
||||
}
|
||||
|
||||
.theme-dark .bd-button-filled.bd-button-color-transparent:active {
|
||||
background-color: hsl(var(--white-500-hsl)/.01)
|
||||
}
|
||||
|
||||
.theme-dark .bd-button-filled.bd-button-color-transparent:disabled {
|
||||
background-color: hsl(var(--white-500-hsl)/.1)
|
||||
}
|
||||
|
||||
.theme-dark .bd-button-outlined.bd-button-color-transparent {
|
||||
color: var(--primary-200);
|
||||
border-color: var(--primary-200)
|
||||
}
|
||||
|
||||
.theme-dark .bd-button-outlined.bd-button-color-transparent:active {
|
||||
background-color: hsl(var(--primary-200-hsl)/.1)
|
||||
}
|
||||
|
||||
.theme-dark .bd-button-link.bd-button-color-transparent {
|
||||
color: var(--primary-200)
|
||||
}
|
||||
|
||||
.theme-dark .bd-button-link.bd-button-color-transparent:hover .bd-button-content {
|
||||
--button--underline-color: var(--primary-200)
|
||||
}
|
||||
|
||||
.theme-light .bd-button-filled.bd-button-color-transparent {
|
||||
color: var(--primary-400);
|
||||
background-color: hsl(var(--primary-400-hsl)/.01)
|
||||
}
|
||||
|
||||
.theme-light .bd-button-filled.bd-button-color-transparent:hover {
|
||||
background-color: hsl(var(--primary-400-hsl)/.2)
|
||||
}
|
||||
|
||||
.theme-light .bd-button-filled.bd-button-color-transparent:active {
|
||||
background-color: hsl(var(--primary-400-hsl)/.25)
|
||||
}
|
||||
|
||||
.theme-light .bd-button-filled.bd-button-color-transparent:disabled {
|
||||
background-color: hsl(var(--primary-400-hsl)/.01)
|
||||
}
|
||||
|
||||
.theme-light .bd-button-outlined.bd-button-color-transparent {
|
||||
color: var(--primary-400);
|
||||
border-color: var(--primary-400)
|
||||
}
|
||||
|
||||
.theme-light .bd-button-outlined.bd-button-color-transparent:active {
|
||||
background-color: hsl(var(--primary-400-hsl)/.1)
|
||||
}
|
||||
|
||||
.theme-light .bd-button-link.bd-button-color-transparent {
|
||||
color: var(--primary-400)
|
||||
}
|
||||
|
||||
.theme-light .bd-button-link.bd-button-color-transparent:hover .bd-button-content {
|
||||
--button--underline-color: var(--primary-400)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
@import "./buttons.css";
|
||||
@import "./spinner.css";
|
||||
@import "./search.css";
|
||||
@import "./text.css";
|
||||
|
||||
.bd-chat-badge {
|
||||
vertical-align: bottom;
|
||||
|
@ -19,23 +20,6 @@
|
|||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.bd-changelog-modal video,
|
||||
.bd-changelog-modal img {
|
||||
width: 100%;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.bd-changelog-modal code.inline {
|
||||
padding: 0.2em;
|
||||
margin: -0.2em 0;
|
||||
border-radius: 3px;
|
||||
font-size: 85%;
|
||||
line-height: 1.125rem;
|
||||
white-space: pre-wrap;
|
||||
background: var(--background-secondary);
|
||||
}
|
||||
|
||||
.bd-link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
.bd-text-normal {
|
||||
color: var(--text-normal);
|
||||
}
|
||||
|
||||
.bd-text-muted {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.bd-text-error {
|
||||
color: var(--red-400);
|
||||
}
|
||||
|
||||
.bd-text-brand {
|
||||
color: var(--text-brand);
|
||||
}
|
||||
|
||||
.bd-text-link {
|
||||
color: var(--text-link);
|
||||
}
|
||||
|
||||
.bd-header-primary {
|
||||
color: var(--header-primary);
|
||||
}
|
||||
|
||||
.bd-header-secondary {
|
||||
color: var(--header-secondary);
|
||||
}
|
||||
|
||||
.bd-text-yellow {
|
||||
color: var(--text-warning);
|
||||
}
|
||||
|
||||
.bd-text-green {
|
||||
color: var(--text-positive);
|
||||
}
|
||||
|
||||
.bd-text-red {
|
||||
color: var(--status-danger);
|
||||
}
|
||||
|
||||
.bd-text-white {
|
||||
color: var(--white-500);
|
||||
}
|
||||
|
||||
.bd-text-10 {
|
||||
font-size: 10px;
|
||||
line-height: 12px;
|
||||
}
|
||||
|
||||
.bd-text-12 {
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.bd-text-14 {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.bd-text-16 {
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.bd-text-20 {
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.bd-text-24 {
|
||||
font-size: 24px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.bd-text-32 {
|
||||
font-size: 32px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.bd-text-strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.bd-selectable {
|
||||
user-select: text;
|
||||
}
|
|
@ -166,6 +166,7 @@
|
|||
|
||||
.bd-settings-title {
|
||||
color: var(--header-primary, #FFFFFF);
|
||||
display: flex;
|
||||
font-weight: 600;
|
||||
cursor: default;
|
||||
flex: 1;
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
.bd-changelog-modal video,
|
||||
.bd-changelog-modal img {
|
||||
width: 100%;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.bd-changelog-modal code.inline {
|
||||
padding: 0.2em;
|
||||
margin: -0.2em 0;
|
||||
border-radius: 3px;
|
||||
font-size: 85%;
|
||||
line-height: 1.125rem;
|
||||
white-space: pre-wrap;
|
||||
background: var(--background-secondary);
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content {
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content .emoji {
|
||||
object-fit: contain;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content h1 {
|
||||
line-height: 20px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content h1,
|
||||
.bd-changelog-modal .bd-modal-content h2,
|
||||
.bd-changelog-modal .bd-modal-content strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content em,
|
||||
.bd-changelog-modal .bd-modal-content i {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content p + p {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content ol {
|
||||
margin: 16px 0 16px 16px;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content ol li {
|
||||
list-style-type: decimal;
|
||||
margin-bottom: 8px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content ul {
|
||||
margin: 20px 0 8px 20px;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content ul ul {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content ul li {
|
||||
position: relative;
|
||||
list-style: none;
|
||||
margin-bottom: 8px;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content ul li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content ul li::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: -15px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
margin-top: -4px;
|
||||
margin-left: -3px;
|
||||
border-radius: 50%;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content ul li li::before {
|
||||
top: 12px;
|
||||
height: 2px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content a {
|
||||
color: hsl(200, calc(var(--saturation-factor, 1) * 100%), 49.4%);
|
||||
transition: 0.05s;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.bd-changelog-modal .bd-modal-content a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.theme-dark .bd-changelog-modal .bd-modal-content ol,
|
||||
.theme-dark .bd-changelog-modal .bd-modal-content p,
|
||||
.theme-dark .bd-changelog-modal .bd-modal-content ul li {
|
||||
color: hsl(210, calc(var(--saturation-factor, 1) * 9.3%), 78.8%);
|
||||
}
|
||||
|
||||
.theme-dark .bd-changelog-modal .bd-modal-content ul li::before {
|
||||
background-color: hsl(216, calc(var(--saturation-factor, 1) * 9.8%), 90%);
|
||||
}
|
||||
|
||||
.theme-light .bd-changelog-modal .bd-modal-content ol,
|
||||
.theme-light .bd-changelog-modal .bd-modal-content p,
|
||||
.theme-light .bd-changelog-modal .bd-modal-content ul li {
|
||||
color: hsl(223, calc(var(--saturation-factor, 1) * 5.8%), 52.9%);
|
||||
}
|
||||
|
||||
.theme-light .bd-changelog-modal .bd-modal-content ul li::before {
|
||||
background-color: hsl(223, calc(var(--saturation-factor, 1) * 5.8%), 52.9%);
|
||||
}
|
||||
|
||||
.bd-changelog-title {
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.bd-changelog-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.bd-changelog-title.bd-changelog-first {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.bd-changelog-title::after {
|
||||
content: "";
|
||||
height: 1px;
|
||||
flex: 1 1 auto;
|
||||
margin-left: 4px;
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.bd-changelog-added {
|
||||
color: var(--text-positive);
|
||||
}
|
||||
|
||||
.bd-changelog-added::after {
|
||||
background-color: var(--info-positive-foreground);
|
||||
}
|
||||
|
||||
.bd-changelog-fixed {
|
||||
color: hsl(359, calc(var(--saturation-factor, 1)*87.3%), 59.8%);
|
||||
}
|
||||
|
||||
.bd-changelog-fixed::after {
|
||||
background-color: hsl(359, calc(var(--saturation-factor, 1)*87.3%), 59.8%);
|
||||
}
|
||||
|
||||
.bd-changelog-progress {
|
||||
color: var(--text-warning);
|
||||
}
|
||||
|
||||
.bd-changelog-progress::after {
|
||||
background-color: var(--info-warning-foreground);
|
||||
}
|
||||
|
||||
.bd-changelog-improved {
|
||||
color: hsl(235, calc(var(--saturation-factor, 1)*85.6%), 64.7%);
|
||||
}
|
||||
|
||||
.bd-changelog-improved::after {
|
||||
background-color: hsl(235, calc(var(--saturation-factor, 1)*85.6%), 64.7%);
|
||||
}
|
||||
|
||||
.theme-dark .bd-changelog-improved {
|
||||
color: hsl(235, calc(var(--saturation-factor, 1)*86.1%), 77.5%);
|
||||
}
|
||||
|
||||
.theme-dark .bd-changelog-improved::after {
|
||||
background-color: hsl(235, calc(var(--saturation-factor, 1)*86.1%), 77.5%);
|
||||
}
|
||||
|
||||
.theme-dark .bd-changelog-modal video,
|
||||
.theme-dark .bd-changelog-modal img {
|
||||
box-shadow: 0 2px 10px 0 hsl(var(0, calc(var(--saturation-factor, 1)*0%), 0%-hsl)/.2);
|
||||
}
|
||||
|
||||
.theme-light .bd-changelog-modal video,
|
||||
.theme-light .bd-changelog-modal img {
|
||||
box-shadow: 0 2px 10px 0 hsl(var(0, calc(var(--saturation-factor, 1)*0%), 0%-hsl)/.1);
|
||||
}
|
||||
|
||||
/* .socialLink-1qjJIk {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.theme-light .socialLink-1qjJIk {
|
||||
color: hsl(228, calc(var(--saturation-factor, 1)*6%), 32.5%);
|
||||
}
|
||||
|
||||
.theme-dark .socialLink-1qjJIk {
|
||||
color: hsl(210, calc(var(--saturation-factor, 1)*9.3%), 78.8%);
|
||||
} */
|
|
@ -0,0 +1,124 @@
|
|||
.bd-flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.bd-flex-align-start {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.bd-flex-align-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.bd-flex-align-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bd-flex-align-stretch {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.bd-flex-align-baseline {
|
||||
align-items: baseline
|
||||
}
|
||||
|
||||
.bd-flex-justify-start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.bd-flex-justify-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.bd-flex-justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.bd-flex-justify-around {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.bd-flex-justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.bd-flex-no-wrap {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.bd-flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.bd-flex-wrap-reverse {
|
||||
flex-wrap: wrap-reverse;
|
||||
}
|
||||
|
||||
.bd-flex-horizontal {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.bd-flex-reverse {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.bd-flex-vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.spacer-2upayl {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.bd-flex-vertical {}
|
||||
|
||||
.bd-flex-horizontal {}
|
||||
|
||||
.bd-flex-reverse {}
|
||||
|
||||
.bd-flex-horizontal > .spacer-2upayl,
|
||||
.bd-flex-reverse > .spacer-2upayl,
|
||||
.bd-flex-vertical > .spacer-2upayl {
|
||||
min-height: 1px;
|
||||
}
|
||||
|
||||
.flexCenter-1Mwsxg {}
|
||||
|
||||
.bd-flex {}
|
||||
|
||||
.bd-flex-horizontal {}
|
||||
|
||||
.bd-flex-reverse {}
|
||||
|
||||
.bd-flex-horizontal > .bd-flex,
|
||||
.bd-flex-horizontal > .bd-flex-child {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.bd-flex-horizontal > .bd-flex:first-child,
|
||||
.bd-flex-horizontal > .bd-flex-child:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.bd-flex-horizontal > .bd-flex:last-child,
|
||||
.bd-flex-horizontal > .bd-flex-child:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.bd-flex-reverse > .bd-flex,
|
||||
.bd-flex-reverse > .bd-flex-child {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.bd-flex-reverse > .bd-flex:first-child,
|
||||
.bd-flex-reverse > .bd-flex-child:first-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.bd-flex-reverse > .bd-flex:last-child,
|
||||
.bd-flex-reverse > .bd-flex-child:last-child {
|
||||
margin-left: 0;
|
||||
}
|
|
@ -71,3 +71,94 @@
|
|||
@keyframes bd-modal-open {
|
||||
from {transform: scale(0.7);}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.bd-modal-root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--modal-background);
|
||||
border-radius: 4px;
|
||||
margin: 0 auto;
|
||||
pointer-events: all;
|
||||
position: relative;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.bd-close-button {
|
||||
height: 26px;
|
||||
padding: 4px;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
opacity: 0.5;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
color: var(--interactive-normal);
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.bd-close-button:hover {
|
||||
opacity: 1;
|
||||
color: var(--interactive-hover);
|
||||
}
|
||||
|
||||
.bd-modal-small {
|
||||
width: 440px;
|
||||
max-height: 720px;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.bd-modal-standard {
|
||||
font-size: 13px;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
width: 490px;
|
||||
max-height: 800px;
|
||||
}
|
||||
|
||||
.bd-modal-medium {
|
||||
width: 600px;
|
||||
max-height: 800px;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.bd-modal-large {
|
||||
width: 800px;
|
||||
max-height: 960px;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.bd-modal-header,
|
||||
.bd-modal-footer {
|
||||
position: relative;
|
||||
flex: 0 0 auto;
|
||||
padding: 16px;
|
||||
z-index: 1;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.bd-modal-header {
|
||||
border-radius: 4px 4px 0 0;
|
||||
transition: box-shadow 0.1s ease-out;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.bd-modal-footer {
|
||||
border-radius: 0 0 5px 5px;
|
||||
background-color: var(--modal-footer-background);
|
||||
overflow: hidden;
|
||||
box-shadow: inset 0 1px 0 hsl(var(--primary-630-hsl)/0.6);
|
||||
}
|
||||
|
||||
.bd-modal-content {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
border-radius: 5px 5px 0 0;
|
||||
padding-left: 16px;
|
||||
/* padding-right: 16px; */
|
||||
overflow-x: hidden;
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
padding-bottom: 20px;
|
||||
overflow: hidden scroll;
|
||||
padding-right: 8px;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
.bd-scroller-base {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
min-height: 0;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.bd-scroller-thin {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--scrollbar-thin-thumb) var(--scrollbar-thin-track);
|
||||
}
|
||||
|
||||
.bd-scroller-thin::-webkit-scrollbar-track {
|
||||
border-color: var(--scrollbar-thin-track);
|
||||
background-color: var(--scrollbar-thin-track);
|
||||
border: 2px solid var(--scrollbar-thin-track);
|
||||
}
|
||||
|
||||
.bd-scroller-thin::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.bd-scroller-thin::-webkit-scrollbar-corner {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.bd-scroller-thin::-webkit-scrollbar-thumb {
|
||||
background-clip: padding-box;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 4px;
|
||||
background-color: var(--scrollbar-thin-thumb);
|
||||
min-height: 40px;
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
import {React, Utilities} from "modules";
|
||||
|
||||
// S.Looks = y;
|
||||
// S.Colors = I;
|
||||
// S.BorderColors = O;
|
||||
// S.Hovers = T;
|
||||
// S.Sizes = v;
|
||||
|
||||
const {useCallback} = React;
|
||||
|
||||
export const Looks = Object.freeze({
|
||||
FILLED: "bd-button-filled",
|
||||
OUTLINED: "bd-button-outlined",
|
||||
LINK: "bd-button-link",
|
||||
BLANK: "bd-button-blank"
|
||||
});
|
||||
|
||||
export const Colors = Object.freeze({
|
||||
BRAND: "bd-button-color-brand",
|
||||
BLURPLE: "bd-button-color-blurple",
|
||||
RED: "bd-button-color-red",
|
||||
GREEN: "bd-button-color-green",
|
||||
YELLOW: "bd-button-color-yellow",
|
||||
PRIMARY: "bd-button-color-primary",
|
||||
LINK: "bd-button-color-link",
|
||||
WHITE: "bd-button-color-white",
|
||||
TRANSPARENT: "bd-button-color-transparent",
|
||||
CUSTOM: ""
|
||||
});
|
||||
|
||||
|
||||
export const Sizes = Object.freeze({
|
||||
NONE: "",
|
||||
TINY: "bd-button-tiny",
|
||||
SMALL: "bd-button-small",
|
||||
MEDIUM: "bd-button-medium",
|
||||
LARGE: "bd-button-large",
|
||||
ICON: "bd-button-icon"
|
||||
});
|
||||
|
||||
|
||||
export default function Button({
|
||||
className,
|
||||
children,
|
||||
onClick,
|
||||
onKeyDown,
|
||||
buttonRef,
|
||||
disabled = false,
|
||||
type = "button",
|
||||
look = Looks.FILLED,
|
||||
color = Colors.BRAND,
|
||||
size = Sizes.MEDIUM,
|
||||
grow = true
|
||||
}) {
|
||||
|
||||
const handleClick = useCallback(event => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
onClick?.(event);
|
||||
}, [onClick]);
|
||||
|
||||
return <button className={
|
||||
Utilities.className(
|
||||
"bd-button",
|
||||
className,
|
||||
look,
|
||||
color,
|
||||
size,
|
||||
grow ? "bd-button-grow" : ""
|
||||
)}
|
||||
ref={buttonRef}
|
||||
type={type === "button" ? null : type}
|
||||
onClick={disabled ? () => {} : handleClick}
|
||||
onKeyDown={disabled ? () => {} : onKeyDown}
|
||||
>
|
||||
<div className="bd-button-content">{children}</div>
|
||||
</button>;
|
||||
}
|
||||
|
||||
Button.Looks = Looks;
|
||||
Button.Colors = Colors;
|
||||
Button.Sizes = Sizes;
|
||||
// window.BDButton = Button;
|
||||
// (() => {
|
||||
// const buttons = [];
|
||||
// for (const look in window.BDButton.Looks) {
|
||||
// if (!window.BDButton.Looks[look] || look === "BLANK") continue;
|
||||
// for (const color in window.BDButton.Colors) {
|
||||
// if (!window.BDButton.Colors[color]) continue;
|
||||
// for (const size in window.BDButton.Sizes) {
|
||||
// if (!window.BDButton.Sizes[size]) continue;
|
||||
// buttons.push(window.BdApi.React.createElement(window.BDButton, {
|
||||
// look: window.BDButton.Looks[look],
|
||||
// color: window.BDButton.Colors[color],
|
||||
// size: window.BDButton.Sizes[size]
|
||||
// }, "Hello World!"));
|
||||
// buttons.push(window.BdApi.React.createElement("br"));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// window.BdApi.showConfirmationModal("Buttons", buttons);
|
||||
// })();
|
|
@ -0,0 +1,75 @@
|
|||
import {React, Utilities} from "modules";
|
||||
|
||||
|
||||
export const Direction = Object.freeze({
|
||||
VERTICAL: "bd-flex-vertical",
|
||||
HORIZONTAL: "bd-flex-horizontal",
|
||||
HORIZONTAL_REVERSE: "bd-flex-reverse"
|
||||
});
|
||||
|
||||
export const Justify = Object.freeze({
|
||||
START: "bd-flex-justify-start",
|
||||
END: "bd-flex-justify-end",
|
||||
CENTER: "bd-flex-justify-center",
|
||||
BETWEEN: "bd-flex-justify-between",
|
||||
AROUND: "bd-flex-justify-around"
|
||||
});
|
||||
|
||||
export const Align = Object.freeze({
|
||||
START: "bd-flex-align-start",
|
||||
END: "bd-flex-align-end",
|
||||
CENTER: "bd-flex-align-center",
|
||||
STRETCH: "bd-flex-align-stretch",
|
||||
BASELINE: "bd-flex-align-baseline"
|
||||
});
|
||||
|
||||
export const Wrap = Object.freeze({
|
||||
NO_WRAP: "bd-flex-no-wrap",
|
||||
WRAP: "bd-flex-wrap",
|
||||
WRAP_REVERSE: "bd-flex-wrap-reverse"
|
||||
});
|
||||
|
||||
|
||||
export function Child(props) {
|
||||
if (!props.className) props.className = "";
|
||||
props.className = Utilities.className(props.className, "bd-flex-child");
|
||||
return <Flex {...props} />;
|
||||
}
|
||||
|
||||
|
||||
export default function Flex({
|
||||
children,
|
||||
className,
|
||||
style,
|
||||
shrink = 1,
|
||||
grow = 1,
|
||||
basis = "auto",
|
||||
direction = Direction.HORIZONTAL,
|
||||
align = Align.STRETCH,
|
||||
justify = Justify.START,
|
||||
wrap = Wrap.NO_WRAP
|
||||
}) {
|
||||
return <div
|
||||
className={Utilities.className(
|
||||
"bd-flex",
|
||||
direction,
|
||||
justify,
|
||||
align,
|
||||
wrap,
|
||||
className
|
||||
)}
|
||||
style={Object.assign({
|
||||
flexShrink: shrink,
|
||||
flexGrow: grow,
|
||||
flexBasis: basis
|
||||
}, style)}
|
||||
>
|
||||
{children}
|
||||
</div>;
|
||||
}
|
||||
|
||||
Flex.Child = Child;
|
||||
Flex.Direction = Direction;
|
||||
Flex.Align = Align;
|
||||
Flex.Justify = Justify;
|
||||
Flex.Wrap = Wrap;
|
|
@ -0,0 +1,33 @@
|
|||
import {React, WebpackModules, DiscordModules} from "modules";
|
||||
|
||||
|
||||
const DiscordMarkdown = WebpackModules.find(m => m?.prototype?.render && m.rules);
|
||||
let rules = {};
|
||||
if (DiscordMarkdown) {
|
||||
rules = {
|
||||
...DiscordMarkdown.rules,
|
||||
link: DiscordModules.SimpleMarkdown.defaultRules.link
|
||||
};
|
||||
|
||||
const originalLink = rules.link.react;
|
||||
rules.link.react = function() {
|
||||
const original = Reflect.apply(originalLink, undefined, arguments);
|
||||
original.props.className = "bd-link";
|
||||
original.props.target = "_blank";
|
||||
original.props.rel = "noopener noreferrer";
|
||||
return original;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export default function Markdown({className, children}) {
|
||||
if (!DiscordMarkdown) return <div className="bd-markdown-fallback">{children}</div>;
|
||||
|
||||
return <DiscordMarkdown
|
||||
className={className}
|
||||
parser={DiscordModules.SimpleMarkdown.parserFor(rules)}
|
||||
output={DiscordModules.SimpleMarkdown.reactFor(DiscordModules.SimpleMarkdown.ruleOutput(rules, "react"))}
|
||||
>
|
||||
{children}
|
||||
</DiscordMarkdown>;
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
import {React, Utilities} from "modules";
|
||||
|
||||
|
||||
export const Colors = Object.freeze({
|
||||
STANDARD: "bd-text-normal",
|
||||
MUTED: "bd-text-muted",
|
||||
ERROR: "bd-text-error",
|
||||
BRAND: "bd-text-brand",
|
||||
LINK: "bd-text-link",
|
||||
HEADER_PRIMARY: "bd-header-primary",
|
||||
HEADER_SECONDARY: "bd-header-secondary",
|
||||
STATUS_YELLOW: "bd-text-yellow",
|
||||
STATUS_GREEN: "bd-text-green",
|
||||
STATUS_RED: "bd-text-red",
|
||||
ALWAYS_WHITE: "bd-text-white",
|
||||
CUSTOM: null
|
||||
});
|
||||
|
||||
|
||||
export const Sizes = Object.freeze({
|
||||
SIZE_10: "bd-text-10",
|
||||
SIZE_12: "bd-text-12",
|
||||
SIZE_14: "bd-text-14",
|
||||
SIZE_16: "bd-text-16",
|
||||
SIZE_20: "bd-text-20",
|
||||
SIZE_24: "bd-text-24",
|
||||
SIZE_32: "bd-text-32"
|
||||
});
|
||||
|
||||
|
||||
export default function Text({tag: Tag = "div", className, children, color = Colors.STANDARD, size = Sizes.SIZE_14, selectable, strong, style}) {
|
||||
return <Tag
|
||||
className={
|
||||
Utilities.className(
|
||||
color, size, className,
|
||||
{
|
||||
"bd-selectable": selectable,
|
||||
"bd-text-strong": strong
|
||||
}
|
||||
)}
|
||||
style={style}
|
||||
>
|
||||
{children}
|
||||
</Tag>;
|
||||
}
|
||||
|
||||
Text.Colors = Colors;
|
||||
Text.Sizes = Sizes;
|
||||
|
||||
// te = WebpackModules.getModule(m => m?.Sizes?.SIZE_32 && m.Colors)
|
||||
// foo = []
|
||||
// for (const color in te.Colors) foo.push(BdApi.React.createElement(te, {color: te.Colors[color]}, color))
|
||||
// for (const size in te.Sizes) foo.push(BdApi.React.createElement(te, {size: te.Sizes[size]}, size))
|
||||
// BdApi.showConfirmationModal("Text Elements", foo)
|
|
@ -1,14 +1,27 @@
|
|||
import {Config} from "data";
|
||||
import Logger from "common/logger";
|
||||
import {WebpackModules, React, ReactDOM, Settings, Strings, DOMManager, DiscordModules, DiscordClasses} from "modules";
|
||||
import {WebpackModules, React, ReactDOM, Settings, Strings, DOMManager, DiscordModules} from "modules";
|
||||
import FormattableString from "../structs/string";
|
||||
import AddonErrorModal from "./addonerrormodal";
|
||||
import ErrorBoundary from "./errorboundary";
|
||||
import TextElement from "./base/text";
|
||||
import ModalRoot from "./modals/root";
|
||||
import Flex from "./base/flex";
|
||||
import ModalHeader from "./modals/header";
|
||||
import ModalContent from "./modals/content";
|
||||
import ModalFooter from "./modals/footer";
|
||||
import CloseButton from "./modals/close";
|
||||
|
||||
import ConfirmationModal from "./modals/confirmation";
|
||||
import Button from "./base/button";
|
||||
import CustomMarkdown from "./base/markdown";
|
||||
import SimpleMarkdownExt from "../structs/markdown";
|
||||
|
||||
|
||||
export default class Modals {
|
||||
|
||||
static get shouldShowAddonErrors() {return Settings.get("settings", "addons", "addonErrors");}
|
||||
static get hasModalOpen() {return !!document.getElementsByClassName("bd-modal").length;}
|
||||
|
||||
static get ModalActions() {
|
||||
return this._ModalActions ??= {
|
||||
|
@ -16,21 +29,11 @@ export default class Modals {
|
|||
closeModal: WebpackModules.getModule(m => typeof m === "function" && m?.toString().includes("onCloseCallback()"), {searchExports: true})
|
||||
};
|
||||
}
|
||||
static get ModalStack() {return this._ModalStack ??= WebpackModules.getByProps("push", "update", "pop", "popWithKey");}
|
||||
static get ModalComponents() {return this._ModalComponents ??= WebpackModules.getByProps("Header", "Footer");}
|
||||
static get ModalRoot() {return this._ModalRoot ??= WebpackModules.getModule(m => m?.toString?.()?.includes("ENTERING") && m?.toString?.()?.includes("headerId"), {searchExports: true});}
|
||||
static get ModalClasses() {return this._ModalClasses ??= WebpackModules.getByProps("modal", "content");}
|
||||
static get FlexElements() {return this._FlexElements ??= WebpackModules.getByProps("Child", "Align");}
|
||||
static get TextElement() {return this._TextElement ??= WebpackModules.getModule(m => m?.Sizes?.SIZE_32 && m.Colors);}
|
||||
static get ConfirmationModal() {return this._ConfirmationModal ??= WebpackModules.getModule(m => m?.toString?.()?.includes(".confirmButtonColor"), {searchExports: true});}
|
||||
static get Markdown() {return this._Markdown ??= WebpackModules.find(m => m?.prototype?.render && m.rules);}
|
||||
static get Buttons() {return this._Buttons ??= WebpackModules.getModule(m => m.BorderColors, {searchExports: true});}
|
||||
|
||||
static get ModalQueue() {return this._ModalQueue ??= [];}
|
||||
|
||||
static get hasModalOpen() {return !!document.getElementsByClassName("bd-modal").length;}
|
||||
|
||||
static async initialize() {
|
||||
const names = ["ConfirmationModal", "ModalActions", "Markdown", "ModalRoot", "ModalComponents", "Buttons", "TextElement", "FlexElements"];
|
||||
const names = ["ModalActions"];
|
||||
|
||||
for (const name of names) {
|
||||
let value = this[name];
|
||||
|
@ -154,8 +157,6 @@ export default class Modals {
|
|||
* @returns {string} - the key used for this modal
|
||||
*/
|
||||
static showConfirmationModal(title, content, options = {}) {
|
||||
const Markdown = this.Markdown;
|
||||
const ConfirmationModal = this.ConfirmationModal;
|
||||
const ModalActions = this.ModalActions;
|
||||
|
||||
if (content instanceof FormattableString) content = content.toString();
|
||||
|
@ -163,7 +164,7 @@ export default class Modals {
|
|||
const emptyFunction = () => {};
|
||||
const {onConfirm = emptyFunction, onCancel = emptyFunction, confirmText = Strings.Modals.okay, cancelText = Strings.Modals.cancel, danger = false, key = undefined} = options;
|
||||
|
||||
if (!this.ModalActions || !this.ConfirmationModal || !this.Markdown) {
|
||||
if (!this.ModalActions) {
|
||||
return this.default(title, content, [
|
||||
confirmText && {label: confirmText, action: onConfirm},
|
||||
cancelText && {label: cancelText, action: onCancel, danger}
|
||||
|
@ -171,7 +172,7 @@ export default class Modals {
|
|||
}
|
||||
|
||||
if (!Array.isArray(content)) content = [content];
|
||||
content = content.map(c => typeof(c) === "string" ? React.createElement(Markdown, null, c) : c);
|
||||
content = content.map(c => typeof(c) === "string" ? React.createElement(CustomMarkdown, null, c) : c);
|
||||
|
||||
const modalKey = ModalActions.openModal(props => {
|
||||
return React.createElement(ErrorBoundary, {
|
||||
|
@ -186,7 +187,7 @@ export default class Modals {
|
|||
}
|
||||
}, React.createElement(ConfirmationModal, Object.assign({
|
||||
header: title,
|
||||
confirmButtonColor: danger ? this.Buttons.Colors.RED : this.Buttons.Colors.BRAND,
|
||||
danger: danger,
|
||||
confirmText: confirmText,
|
||||
cancelText: cancelText,
|
||||
onConfirm: onConfirm,
|
||||
|
@ -205,8 +206,8 @@ export default class Modals {
|
|||
}
|
||||
|
||||
this.addonErrorsRef = React.createRef();
|
||||
this.ModalActions.openModal(props => React.createElement(ErrorBoundary, null, React.createElement(this.ModalRoot, Object.assign(props, {
|
||||
size: "medium",
|
||||
this.ModalActions.openModal(props => React.createElement(ErrorBoundary, null, React.createElement(ModalRoot, Object.assign(props, {
|
||||
size: ModalRoot.Sizes.MEDIUM,
|
||||
className: "bd-error-modal",
|
||||
children: [
|
||||
React.createElement(AddonErrorModal, {
|
||||
|
@ -215,43 +216,36 @@ export default class Modals {
|
|||
themeErrors: Array.isArray(themeErrors) ? themeErrors : [],
|
||||
onClose: props.onClose
|
||||
}),
|
||||
React.createElement(this.ModalComponents.Footer, {
|
||||
React.createElement(ModalFooter, {
|
||||
className: "bd-error-modal-footer",
|
||||
}, React.createElement(this.Buttons, {
|
||||
onClick: props.onClose,
|
||||
className: "bd-button"
|
||||
}, React.createElement(Button, {
|
||||
onClick: props.onClose
|
||||
}, Strings.Modals.okay))
|
||||
]
|
||||
}))));
|
||||
}
|
||||
|
||||
static showChangelogModal(options = {}) {
|
||||
const OriginalModalClasses = WebpackModules.getByProps("hideOnFullscreen", "root");
|
||||
const ChangelogModalClasses = WebpackModules.getModule(m => m.modal && m.maxModalWidth);
|
||||
const ChangelogClasses = WebpackModules.getByProps("fixed", "improved") ?? {maxModalWidth: "490px",video: "video-8B-TdZ",container: "container-3PVapX",image: "image-ZPv20Y",title: "title-2ftWWc",lead: "lead-2VtcIe",added: "added-mQcv9V title-2ftWWc",fixed: "fixed-cTX7Hp title-2ftWWc",improved: "improved-2SJXHz title-2ftWWc",progress: "progress-1DcfFh title-2ftWWc",marginTop: "marginTop-VGmU1T",footer: "footer-1gMODG",socialLink: "socialLink-1qjJIk",premiumBanner: "premiumBanner-FU1Urp",premiumIcon: "premiumIcon-rhwgnW",date: "date-2tmzZM"};
|
||||
const TextElement = this.TextElement;
|
||||
const FlexChild = this.FlexElements;
|
||||
const MarkdownParser = WebpackModules.getByProps("defaultRules", "parse");
|
||||
|
||||
if (!OriginalModalClasses || !ChangelogModalClasses || !ChangelogClasses || !TextElement || !FlexChild || !MarkdownParser) return Logger.warn("Modals", "showChangelogModal missing modules");
|
||||
|
||||
const {image = "https://i.imgur.com/wuh5yMK.png", description = "", changes = [], title = "BetterDiscord", subtitle = `v${Config.version}`, footer} = options;
|
||||
const ce = React.createElement;
|
||||
const changelogItems = [options.video ? ce("video", {src: options.video, poster: options.poster, controls: true, className: ChangelogClasses.video}) : ce("img", {src: image})];
|
||||
if (description) changelogItems.push(ce("p", null, MarkdownParser.parse(description)));
|
||||
const changelogItems = [options.video ? ce("video", {src: options.video, poster: options.poster, controls: true, className: "bd-changelog-poster"}) : ce("img", {src: image, className: "bd-changelog-poster"})];
|
||||
if (description) changelogItems.push(ce("p", null, SimpleMarkdownExt.parseToReact(description)));
|
||||
for (let c = 0; c < changes.length; c++) {
|
||||
const entry = changes[c];
|
||||
const type = ChangelogClasses[entry.type] ? ChangelogClasses[entry.type] : ChangelogClasses.added;
|
||||
const margin = c == 0 ? ChangelogClasses.marginTop : "";
|
||||
changelogItems.push(ce("h1", {className: `${type} ${margin}`,}, entry.title));
|
||||
if (entry.description) changelogItems.push(ce("p", null, MarkdownParser.parse(entry.description)));
|
||||
const list = ce("ul", null, entry.items.map(i => ce("li", null, MarkdownParser.parse(i))));
|
||||
const type = "bd-changelog-" + entry.type;
|
||||
const margin = c == 0 ? " bd-changelog-first" : "";
|
||||
changelogItems.push(ce("h1", {className: `bd-changelog-title ${type}${margin}`,}, entry.title));
|
||||
if (entry.description) changelogItems.push(ce("p", null, SimpleMarkdownExt.parseToReact(entry.description)));
|
||||
const list = ce("ul", null, entry.items.map(i => ce("li", null, SimpleMarkdownExt.parseToReact(i))));
|
||||
changelogItems.push(list);
|
||||
}
|
||||
const renderHeader = function() {
|
||||
return ce(FlexChild, {className: OriginalModalClasses.header, grow: 0, shrink: 0, direction: FlexChild.Direction.VERTICAL},
|
||||
ce(TextElement, {tag: "h1", size: TextElement.Sizes.SIZE_20, strong: true}, title),
|
||||
ce(TextElement, {size: TextElement.Sizes.SIZE_12, color: TextElement.Colors.STANDARD, className: ChangelogClasses.date}, subtitle)
|
||||
const renderHeader = function(props) {
|
||||
return ce(ModalHeader, {justify: Flex.Justify.BETWEEN},
|
||||
ce(Flex, {direction: Flex.Direction.VERTICAL},
|
||||
ce(TextElement, {tag: "h1", size: TextElement.Sizes.SIZE_20, strong: true}, title),
|
||||
ce(TextElement, {size: TextElement.Sizes.SIZE_12, color: TextElement.Colors.HEADER_SECONDARY}, subtitle)
|
||||
),
|
||||
ce(CloseButton, {onClick: props.onClose})
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -264,22 +258,17 @@ export default class Modals {
|
|||
};
|
||||
const supportLink = ce("a", {className: `${AnchorClasses.anchor} ${AnchorClasses.anchorUnderlineOnHover}`, onClick: joinSupportServer}, "Join our Discord Server.");
|
||||
const defaultFooter = ce(TextElement, {size: TextElement.Sizes.SIZE_12, color: TextElement.Colors.STANDARD}, "Need support? ", supportLink);
|
||||
return ce(FlexChild, {className: OriginalModalClasses.footer + " " + OriginalModalClasses.footerSeparator},
|
||||
ce(FlexChild.Child, {grow: 1, shrink: 1}, footer ? footer : defaultFooter)
|
||||
);
|
||||
return ce(ModalFooter, null, ce(Flex.Child, {grow: 1, shrink: 1}, footer ? footer : defaultFooter));
|
||||
};
|
||||
|
||||
const body = ce("div", {
|
||||
className: `${OriginalModalClasses.content} ${ChangelogClasses.container} ${ChangelogModalClasses.content} ${DiscordClasses.Scrollers.thin}`
|
||||
}, changelogItems);
|
||||
const body = ce(ModalContent, null, changelogItems);
|
||||
|
||||
const key = this.ModalActions.openModal(props => {
|
||||
return React.createElement(ErrorBoundary, null, React.createElement(this.ModalRoot, Object.assign({
|
||||
className: `bd-changelog-modal ${OriginalModalClasses.root} ${OriginalModalClasses.small} ${ChangelogModalClasses.modal}`,
|
||||
selectable: true,
|
||||
onScroll: _ => _,
|
||||
onClose: _ => _,
|
||||
}, props), renderHeader(), body, renderFooter()));
|
||||
return React.createElement(ErrorBoundary, null, React.createElement(ModalRoot, Object.assign({
|
||||
className: `bd-changelog-modal`,
|
||||
size: ModalRoot.Sizes.SMALL,
|
||||
style: ModalRoot.Styles.STANDARD
|
||||
}, props), renderHeader(props), body, renderFooter()));
|
||||
});
|
||||
return key;
|
||||
}
|
||||
|
@ -317,17 +306,16 @@ export default class Modals {
|
|||
}
|
||||
if (typeof(child) === "function") child = React.createElement(child);
|
||||
|
||||
const mc = this.ModalComponents;
|
||||
const modal = props => {
|
||||
return React.createElement(ErrorBoundary, {}, React.createElement(this.ModalRoot, Object.assign({size: mc.Sizes.MEDIUM, className: "bd-addon-modal" + " " + mc.Sizes.MEDIUM}, props),
|
||||
React.createElement(mc.Header, {separator: false, className: "bd-addon-modal-header"},
|
||||
React.createElement(this.TextElement, {tag: "h1", size: this.TextElement.Sizes.SIZE_20, strong: true}, `${name} Settings`)
|
||||
return React.createElement(ErrorBoundary, {}, React.createElement(ModalRoot, Object.assign({size: ModalRoot.Sizes.MEDIUM, className: "bd-addon-modal" + " " + ModalRoot.Sizes.MEDIUM}, props),
|
||||
React.createElement(ModalHeader, null,
|
||||
React.createElement(TextElement, {tag: "h1", size: TextElement.Sizes.SIZE_20, strong: true}, `${name} Settings`)
|
||||
),
|
||||
React.createElement(mc.Content, {className: "bd-addon-modal-settings"},
|
||||
React.createElement(ModalContent, null,
|
||||
React.createElement(ErrorBoundary, {}, child)
|
||||
),
|
||||
React.createElement(mc.Footer, {className: "bd-addon-modal-footer"},
|
||||
React.createElement(this.Buttons, {onClick: props.onClose, className: "bd-button"}, Strings.Modals.done)
|
||||
React.createElement(ModalFooter, null,
|
||||
React.createElement(Button, {onClick: props.onClose}, Strings.Modals.done)
|
||||
)
|
||||
));
|
||||
};
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import {React} from "modules";
|
||||
import Button from "../base/button";
|
||||
import Close from "../icons/close";
|
||||
|
||||
|
||||
export default function CloseButton({onClick}) {
|
||||
return <Button
|
||||
className="bd-close-button"
|
||||
size={Button.Sizes.ICON}
|
||||
look={Button.Looks.BLANK}
|
||||
color={Button.Colors.TRANSPARENT}
|
||||
onClick={onClick}
|
||||
>
|
||||
<Close size="24px" />
|
||||
</Button>;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import {React} from "modules";
|
||||
import Root from "./root";
|
||||
import Header from "./header";
|
||||
import Footer from "./footer";
|
||||
import Content from "./content";
|
||||
|
||||
import Text from "../base/text";
|
||||
import Button from "../base/button";
|
||||
import CloseButton from "./close";
|
||||
|
||||
const {useRef, useEffect} = React;
|
||||
|
||||
|
||||
export default function ConfirmationModal({transitionState, onClose, header, children, danger = false, onCancel = () => {}, onConfirm = () => {}, cancelText = "Cancel", confirmText = "Okay"}) {
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => buttonRef?.current?.focus?.(), 0);
|
||||
}, []);
|
||||
|
||||
const buttonRef = useRef(null);
|
||||
|
||||
|
||||
return <Root transitionState={transitionState} size={Root.Sizes.SMALL}>
|
||||
<Header><Text tag="h1" size={Text.Sizes.SIZE_20} color={Text.Colors.HEADER_PRIMARY} strong={true}>{header}</Text><CloseButton onClose={onClose} /></Header>
|
||||
<Content>{children}</Content>
|
||||
<Footer>
|
||||
{confirmText && <Button
|
||||
type="submit"
|
||||
buttonRef={buttonRef}
|
||||
color={danger ? Button.Colors.RED : Button.Colors.BRAND}
|
||||
onClick={() => {
|
||||
onConfirm?.();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
{confirmText}
|
||||
</Button>}
|
||||
{cancelText && <Button
|
||||
type="button"
|
||||
look={Button.Looks.LINK}
|
||||
color={Button.Colors.PRIMARY}
|
||||
onClick={() => {
|
||||
onCancel?.();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
{cancelText}
|
||||
</Button>}
|
||||
</Footer>
|
||||
</Root>;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import {React, Utilities} from "modules";
|
||||
|
||||
|
||||
export default function Content({id, className, children, scroller = true}) {
|
||||
return <div id={id} className={Utilities.className("bd-modal-content", {"bd-scroller-base bd-scroller-thin": scroller}, className)}>
|
||||
{children}
|
||||
</div>;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import {React, Utilities} from "modules";
|
||||
import Flex from "../base/flex";
|
||||
|
||||
|
||||
export default function Header({id, className, children}) {
|
||||
return <Flex
|
||||
id={id}
|
||||
className={Utilities.className("bd-modal-footer", className)}
|
||||
grow={0}
|
||||
shrink={0}
|
||||
direction={Flex.Direction.HORIZONTAL_REVERSE}
|
||||
justify={Flex.Justify.START}
|
||||
align={Flex.Align.STRETCH}
|
||||
wrap={Flex.Wrap.NO_WRAP}
|
||||
>
|
||||
{children}
|
||||
</Flex>;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import {React, Utilities} from "modules";
|
||||
import Flex from "../base/flex";
|
||||
|
||||
|
||||
export default function Header({id, className, children}) {
|
||||
return <Flex
|
||||
id={id}
|
||||
className={Utilities.className("bd-modal-header", className)}
|
||||
grow={0}
|
||||
shrink={0}
|
||||
direction={Flex.Direction.HORIZONTAL}
|
||||
justify={Flex.Justify.START}
|
||||
align={Flex.Align.CENTER}
|
||||
wrap={Flex.Wrap.NO_WRAP}
|
||||
>
|
||||
{children}
|
||||
</Flex>;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import {React, Utilities, WebpackModules} from "modules";
|
||||
|
||||
const Spring = WebpackModules.getByProps("useSpring", "animated");
|
||||
const Anims = WebpackModules.getByProps("Easing");
|
||||
|
||||
|
||||
export const Sizes = Object.freeze({
|
||||
SMALL: "bd-modal-small",
|
||||
MEDIUM: "bd-modal-medium",
|
||||
LARGE: "bd-modal-large",
|
||||
DYNAMIC: ""
|
||||
});
|
||||
|
||||
export const Styles = Object.freeze({
|
||||
STANDARD: "bd-modal-standard",
|
||||
CUSTOM: ""
|
||||
});
|
||||
|
||||
|
||||
export default function ModalRoot({className, transitionState, children, size = Sizes.DYNAMIC, style = Styles.CUSTOM}) {
|
||||
const visible = transitionState == 0 || transitionState == 1;
|
||||
const springStyles = Spring.useSpring({
|
||||
opacity: visible ? 1 : 0,
|
||||
transform: visible ? "scale(1)" : "scale(0.7)",
|
||||
config: {
|
||||
duration: visible ? 300 : 100,
|
||||
easing: visible ? Anims.Easing.inOut(Anims.Easing.back()) : Anims.Easing.quad,
|
||||
clamp: true
|
||||
}
|
||||
});
|
||||
return <Spring.animated.div
|
||||
className={Utilities.className("bd-modal-root", size, className, style)}
|
||||
style={springStyles}
|
||||
>
|
||||
{children}
|
||||
</Spring.animated.div>;
|
||||
}
|
||||
|
||||
ModalRoot.Sizes = Sizes;
|
||||
ModalRoot.Styles = Styles;
|
|
@ -57,7 +57,7 @@ function makeButton(title, children, action, {isControl = false, danger = false,
|
|||
const ButtonType = isControl ? "button" : "div";
|
||||
return <DiscordModules.Tooltip color="primary" position="top" text={title}>
|
||||
{(props) => {
|
||||
return <ButtonType {...props} className={(isControl ? "bd-button bd-addon-button" : "bd-addon-button") + (danger ? " bd-button-danger" : "") + (disabled ? " bd-button-disabled" : "")} onClick={action}>{children}</ButtonType>;
|
||||
return <ButtonType {...props} className={(isControl ? "bd-button bd-button-filled bd-addon-button" : "bd-addon-button") + (danger ? " bd-button-color-red" : isControl ? " bd-button-color-brand" : "") + (disabled ? " bd-button-disabled" : "")} onClick={action} disabled={disabled}>{children}</ButtonType>;
|
||||
}}
|
||||
</DiscordModules.Tooltip>;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import {React} from "modules";
|
||||
|
||||
import Button from "../base/button";
|
||||
|
||||
const {useCallback} = React;
|
||||
|
||||
|
||||
|
@ -18,7 +20,7 @@ export default function SettingsTitle({isGroup, className, button, onClick, text
|
|||
const titleClass = className ? `${baseClass} ${className}` : baseClass;
|
||||
return <h2 className={titleClass} onClick={() => {onClick?.();}}>
|
||||
{text}
|
||||
{button && <button className="bd-button bd-button-title" onClick={click}>{button.title}</button>}
|
||||
{button && <Button className="bd-button-title" onClick={click} size={Button.Sizes.NONE}>{button.title}</Button>}
|
||||
{otherChildren}
|
||||
</h2>;
|
||||
|
||||
|
|
Loading…
Reference in New Issue