mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-25 09:35:37 -05:00
Small strict null checking pass on a few files (#4293)
* fix some null checking * fix various null strict checks * move location fo sql files in json * fix compile and more unused properties * formatting * small formatting changes * readd types * add comments for angular components * formatting * remove any decl
This commit is contained in:
@@ -30,7 +30,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
`
|
||||
})
|
||||
export class BreadcrumbComponent implements OnInit, OnDestroy {
|
||||
private menuItems: MenuItem[] = [];
|
||||
protected menuItems: MenuItem[] = []; // used by angular template
|
||||
private disposables: Array<IDisposable> = new Array();
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -13,11 +13,10 @@ export interface IButtonStyles extends vsIButtonStyles {
|
||||
}
|
||||
|
||||
export class Button extends vsButton {
|
||||
private buttonFocusOutline: Color;
|
||||
private buttonFocusOutline?: Color;
|
||||
|
||||
constructor(container: HTMLElement, options?: IButtonOptions) {
|
||||
super(container, options);
|
||||
this.buttonFocusOutline = null;
|
||||
|
||||
this._register(DOM.addDisposableListener(this.element, DOM.EventType.FOCUS, () => {
|
||||
this.element.style.outlineColor = this.buttonFocusOutline ? this.buttonFocusOutline.toString() : null;
|
||||
|
||||
@@ -23,7 +23,7 @@ export interface ICheckboxStyles {
|
||||
export class Checkbox extends Widget {
|
||||
private _el: HTMLInputElement;
|
||||
private _label: HTMLSpanElement;
|
||||
private disabledCheckboxForeground: Color;
|
||||
private disabledCheckboxForeground?: Color;
|
||||
|
||||
private _onChange = new Emitter<boolean>();
|
||||
public readonly onChange: Event<boolean> = this._onChange.event;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
import 'vs/css!./media/dropdownList';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { Dropdown, IDropdownOptions } from 'vs/base/browser/ui/dropdown/dropdown';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
@@ -15,10 +14,8 @@ import { EventType as GestureEventType } from 'vs/base/browser/touch';
|
||||
import { List } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Builder } from 'sql/base/browser/builder';
|
||||
|
||||
import { Button } from 'sql/base/browser/ui/button/button';
|
||||
import { attachButtonStyler } from 'sql/platform/theme/common/styler';
|
||||
import { Button, IButtonStyles } from 'sql/base/browser/ui/button/button';
|
||||
|
||||
export interface IDropdownStyles {
|
||||
backgroundColor?: Color;
|
||||
@@ -28,51 +25,49 @@ export interface IDropdownStyles {
|
||||
|
||||
export class DropdownList extends Dropdown {
|
||||
|
||||
protected backgroundColor: Color;
|
||||
protected foregroundColor: Color;
|
||||
protected borderColor: Color;
|
||||
protected backgroundColor?: Color;
|
||||
protected foregroundColor?: Color;
|
||||
protected borderColor?: Color;
|
||||
|
||||
private button?: Button;
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
private _options: IDropdownOptions,
|
||||
private _contentContainer: HTMLElement,
|
||||
private _list: List<any>,
|
||||
private _themeService: IThemeService,
|
||||
private _action?: IAction,
|
||||
action?: IAction,
|
||||
) {
|
||||
super(container, _options);
|
||||
if (_action) {
|
||||
let button = new Button(_contentContainer);
|
||||
button.label = _action.label;
|
||||
this.toDispose.push(DOM.addDisposableListener(button.element, DOM.EventType.CLICK, () => {
|
||||
this._action.run();
|
||||
if (action) {
|
||||
this.button = new Button(_contentContainer);
|
||||
this.button.label = action.label;
|
||||
this.toDispose.push(DOM.addDisposableListener(this.button.element, DOM.EventType.CLICK, () => {
|
||||
action.run();
|
||||
this.hide();
|
||||
}));
|
||||
this.toDispose.push(DOM.addDisposableListener(button.element, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
|
||||
this.toDispose.push(DOM.addDisposableListener(this.button.element, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
|
||||
let event = new StandardKeyboardEvent(e);
|
||||
if (event.equals(KeyCode.Enter)) {
|
||||
e.stopPropagation();
|
||||
this._action.run();
|
||||
action.run();
|
||||
this.hide();
|
||||
}
|
||||
}));
|
||||
attachButtonStyler(button, this._themeService);
|
||||
}
|
||||
|
||||
DOM.append(this.element, DOM.$('div.dropdown-icon'));
|
||||
|
||||
this.toDispose.push(new Builder(this.element).on([DOM.EventType.CLICK, DOM.EventType.MOUSE_DOWN, GestureEventType.Tap], (e: Event) => {
|
||||
DOM.EventHelper.stop(e, true); // prevent default click behaviour to trigger
|
||||
}).on([DOM.EventType.MOUSE_DOWN, GestureEventType.Tap], (e: Event) => {
|
||||
// We want to show the context menu on dropdown so that as a user you can press and hold the
|
||||
// mouse button, make a choice of action in the menu and release the mouse to trigger that
|
||||
// action.
|
||||
// Due to some weird bugs though, we delay showing the menu to unwind event stack
|
||||
// (see https://github.com/Microsoft/vscode/issues/27648)
|
||||
setTimeout(() => this.show(), 100);
|
||||
}).on([DOM.EventType.KEY_DOWN], (e: KeyboardEvent) => {
|
||||
let event = new StandardKeyboardEvent(e);
|
||||
if (event.equals(KeyCode.Enter)) {
|
||||
[DOM.EventType.CLICK, DOM.EventType.MOUSE_DOWN, GestureEventType.Tap].forEach(event => {
|
||||
this._register(DOM.addDisposableListener(this.element, event, e => DOM.EventHelper.stop(e, true))); // prevent default click behaviour to trigger
|
||||
});
|
||||
|
||||
[DOM.EventType.MOUSE_DOWN, GestureEventType.Tap].forEach(event => {
|
||||
this._register(DOM.addDisposableListener(this.element, event, e => setTimeout(() => this.show(), 100)));
|
||||
});
|
||||
|
||||
this._register(DOM.addStandardDisposableListener(this.element, DOM.EventType.KEY_DOWN, (e: StandardKeyboardEvent) => {
|
||||
if (e.equals(KeyCode.Enter)) {
|
||||
e.stopPropagation();
|
||||
setTimeout(() => {
|
||||
this.show();
|
||||
@@ -96,7 +91,7 @@ export class DropdownList extends Dropdown {
|
||||
protected renderContents(container: HTMLElement): IDisposable {
|
||||
let div = DOM.append(container, this._contentContainer);
|
||||
div.style.width = DOM.getTotalWidth(this.element) + 'px';
|
||||
return null;
|
||||
return { dispose: () => { } };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,11 +121,14 @@ export class DropdownList extends Dropdown {
|
||||
}
|
||||
}
|
||||
|
||||
public style(styles: IDropdownStyles): void {
|
||||
public style(styles: IDropdownStyles & IButtonStyles): void {
|
||||
this.backgroundColor = styles.backgroundColor;
|
||||
this.foregroundColor = styles.foregroundColor;
|
||||
this.borderColor = styles.borderColor;
|
||||
this.applyStyles();
|
||||
if (this.button) {
|
||||
this.button.style(styles);
|
||||
}
|
||||
}
|
||||
|
||||
protected applyStyles(): void {
|
||||
@@ -143,7 +141,7 @@ export class DropdownList extends Dropdown {
|
||||
}
|
||||
}
|
||||
|
||||
private applyStylesOnElement(element: HTMLElement, background: string, foreground: string, border: string): void {
|
||||
private applyStylesOnElement(element: HTMLElement, background: string | null, foreground: string | null, border: string | null): void {
|
||||
if (element) {
|
||||
element.style.backgroundColor = background;
|
||||
element.style.color = foreground;
|
||||
@@ -153,4 +151,4 @@ export class DropdownList extends Dropdown {
|
||||
element.style.borderColor = border;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as nls from 'vs/nls';
|
||||
|
||||
export class ToggleDropdownAction extends Action {
|
||||
private static readonly ID = 'dropdownAction.toggle';
|
||||
|
||||
@@ -15,7 +15,6 @@ import { InputBox, IInputBoxStyles } from 'sql/base/browser/ui/inputBox/inputBox
|
||||
import { IMessage, MessageType } from 'vs/base/browser/ui/inputbox/inputBox';
|
||||
import { IListStyles } from 'vs/base/browser/ui/list/listWidget';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import * as nls from 'vs/nls';
|
||||
@@ -74,14 +73,6 @@ const defaults: IDropdownOptions = {
|
||||
actionLabel: nls.localize('dropdownAction.toggle', "Toggle dropdown")
|
||||
};
|
||||
|
||||
interface ListResource {
|
||||
label: string;
|
||||
}
|
||||
|
||||
interface TableTemplate {
|
||||
label: HTMLElement;
|
||||
}
|
||||
|
||||
export class Dropdown extends Disposable {
|
||||
private $el: Builder;
|
||||
private $input: Builder;
|
||||
@@ -110,12 +101,12 @@ export class Dropdown extends Disposable {
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
contextViewService: IContextViewProvider,
|
||||
private _themeService: IThemeService,
|
||||
opt?: IDropdownOptions
|
||||
) {
|
||||
super();
|
||||
this._contextView = new ContextView(document.body);
|
||||
this._options = mixin(opt, defaults, false) as IDropdownOptions;
|
||||
this._options = opt || Object.create(null);
|
||||
mixin(this._options, defaults, false) as IDropdownOptions;
|
||||
this.$el = $('.monaco-dropdown').style('width', '100%').appendTo(container);
|
||||
|
||||
this.$input = $('.dropdown-input').style('width', '100%').appendTo(this.$el);
|
||||
@@ -125,7 +116,7 @@ export class Dropdown extends Disposable {
|
||||
this._showList();
|
||||
this._tree.domFocus();
|
||||
this._tree.focusFirst();
|
||||
}, opt.actionLabel);
|
||||
}, this._options.actionLabel);
|
||||
|
||||
this._input = new InputBox(this.$input.getHTMLElement(), contextViewService, {
|
||||
validationOptions: {
|
||||
@@ -258,18 +249,18 @@ export class Dropdown extends Disposable {
|
||||
return p;
|
||||
}
|
||||
}, 0);
|
||||
let height = filteredLength * this._renderer.getHeight(undefined, undefined) > this._options.maxHeight ? this._options.maxHeight : filteredLength * this._renderer.getHeight(undefined, undefined);
|
||||
let height = filteredLength * this._renderer.getHeight() > this._options.maxHeight! ? this._options.maxHeight! : filteredLength * this._renderer.getHeight();
|
||||
this.$treeContainer.style('height', height + 'px').style('width', DOM.getContentWidth(this.$input.getHTMLElement()) - 2 + 'px');
|
||||
this._tree.layout(parseInt(this.$treeContainer.style('height')));
|
||||
this._tree.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public set values(vals: string[]) {
|
||||
public set values(vals: string[] | undefined) {
|
||||
if (vals) {
|
||||
this._filter.filterString = '';
|
||||
this._dataSource.options = vals.map(i => { return { value: i }; });
|
||||
let height = this._dataSource.options.length * 22 > this._options.maxHeight ? this._options.maxHeight : this._dataSource.options.length * 22;
|
||||
let height = this._dataSource.options.length * 22 > this._options.maxHeight! ? this._options.maxHeight! : this._dataSource.options.length * 22;
|
||||
this.$treeContainer.style('height', height + 'px').style('width', DOM.getContentWidth(this.$input.getHTMLElement()) - 2 + 'px');
|
||||
this._tree.layout(parseInt(this.$treeContainer.style('height')));
|
||||
this._tree.setInput(new DropdownModel());
|
||||
@@ -297,13 +288,15 @@ export class Dropdown extends Disposable {
|
||||
style(style: IListStyles & IInputBoxStyles & IDropdownStyles) {
|
||||
this._tree.style(style);
|
||||
this._input.style(style);
|
||||
this.$treeContainer.style('background-color', style.contextBackground.toString());
|
||||
if (style.contextBackground) {
|
||||
this.$treeContainer.style('background-color', style.contextBackground.toString());
|
||||
}
|
||||
this.$treeContainer.style('outline', `1px solid ${style.contextBorder || this._options.contextBorder}`);
|
||||
}
|
||||
|
||||
private _inputValidator(value: string): IMessage {
|
||||
if (this._dataSource.options && !this._dataSource.options.find(i => i.value === value)) {
|
||||
if (this._options.strictSelection) {
|
||||
if (this._options.strictSelection && this._options.errorMessage) {
|
||||
return {
|
||||
content: this._options.errorMessage,
|
||||
type: MessageType.ERROR
|
||||
|
||||
@@ -26,11 +26,11 @@ export class DropdownModel {
|
||||
}
|
||||
|
||||
export class DropdownRenderer implements tree.IRenderer {
|
||||
public getHeight(tree: tree.ITree, element: Resource): number {
|
||||
public getHeight(): number {
|
||||
return 22;
|
||||
}
|
||||
|
||||
public getTemplateId(tree: tree.ITree, element: Resource): string {
|
||||
public getTemplateId(): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ export class EditableDropDown extends AngularDisposable implements OnInit, OnCha
|
||||
ariaLabel: '',
|
||||
actionLabel: ''
|
||||
};
|
||||
this._selectbox = new Dropdown(this._el.nativeElement, this.contextViewService, this.themeService, dropdownOptions);
|
||||
this._selectbox = new Dropdown(this._el.nativeElement, this.contextViewService, dropdownOptions);
|
||||
this._selectbox.values = this.options;
|
||||
this._selectbox.value = this.selectedOption;
|
||||
|
||||
|
||||
@@ -20,12 +20,12 @@ export interface IInputBoxStyles extends vsIInputBoxStyles {
|
||||
}
|
||||
|
||||
export class InputBox extends vsInputBox {
|
||||
private enabledInputBackground: Color;
|
||||
private enabledInputForeground: Color;
|
||||
private enabledInputBorder: Color;
|
||||
private disabledInputBackground: Color;
|
||||
private disabledInputForeground: Color;
|
||||
private disabledInputBorder: Color;
|
||||
private enabledInputBackground?: Color;
|
||||
private enabledInputForeground?: Color;
|
||||
private enabledInputBorder?: Color;
|
||||
private disabledInputBackground?: Color;
|
||||
private disabledInputForeground?: Color;
|
||||
private disabledInputBorder?: Color;
|
||||
|
||||
private _lastLoseFocusValue: string;
|
||||
|
||||
@@ -41,8 +41,6 @@ export class InputBox extends vsInputBox {
|
||||
this.enabledInputForeground = this.inputForeground;
|
||||
this.enabledInputBorder = this.inputBorder;
|
||||
this.disabledInputBackground = Color.transparent;
|
||||
this.disabledInputForeground = null;
|
||||
this.disabledInputBorder = null;
|
||||
|
||||
this._lastLoseFocusValue = this.value;
|
||||
let self = this;
|
||||
@@ -126,4 +124,4 @@ export class InputBox extends vsInputBox {
|
||||
this.inputForeground = enabled ? this.enabledInputForeground : this.disabledInputForeground;
|
||||
this.inputBorder = enabled ? this.enabledInputBorder : this.disabledInputBorder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { IContextViewProvider, AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { RenderOptions, renderFormattedText, renderText } from 'vs/base/browser/htmlContentRenderer';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
@@ -33,27 +32,26 @@ export interface IListBoxStyles {
|
||||
* Extends SelectBox to allow multiple selection and adding/remove items dynamically
|
||||
*/
|
||||
export class ListBox extends SelectBox {
|
||||
private enabledSelectBackground: Color;
|
||||
private enabledSelectForeground: Color;
|
||||
private enabledSelectBorder: Color;
|
||||
private disabledSelectBackground: Color;
|
||||
private disabledSelectForeground: Color;
|
||||
private disabledSelectBorder: Color;
|
||||
private enabledSelectBackground?: Color;
|
||||
private enabledSelectForeground?: Color;
|
||||
private enabledSelectBorder?: Color;
|
||||
private disabledSelectBackground?: Color;
|
||||
private disabledSelectForeground?: Color;
|
||||
private disabledSelectBorder?: Color;
|
||||
|
||||
private inputValidationInfoBorder: Color;
|
||||
private inputValidationInfoBackground: Color;
|
||||
private inputValidationWarningBorder: Color;
|
||||
private inputValidationWarningBackground: Color;
|
||||
private inputValidationErrorBorder: Color;
|
||||
private inputValidationErrorBackground: Color;
|
||||
private inputValidationInfoBorder?: Color;
|
||||
private inputValidationInfoBackground?: Color;
|
||||
private inputValidationWarningBorder?: Color;
|
||||
private inputValidationWarningBackground?: Color;
|
||||
private inputValidationErrorBorder?: Color;
|
||||
private inputValidationErrorBackground?: Color;
|
||||
|
||||
private message: IMessage;
|
||||
private message?: IMessage;
|
||||
private contextViewProvider: IContextViewProvider;
|
||||
private isValid: boolean;
|
||||
|
||||
constructor(
|
||||
options: string[],
|
||||
selectedOption: string,
|
||||
contextViewProvider: IContextViewProvider,
|
||||
private _clipboardService: IClipboardService) {
|
||||
|
||||
@@ -73,8 +71,6 @@ export class ListBox extends SelectBox {
|
||||
this.enabledSelectForeground = this.selectForeground;
|
||||
this.enabledSelectBorder = this.selectBorder;
|
||||
this.disabledSelectBackground = Color.transparent;
|
||||
this.disabledSelectForeground = null;
|
||||
this.disabledSelectBorder = null;
|
||||
|
||||
this.inputValidationInfoBorder = defaultOpts.inputValidationInfoBorder;
|
||||
this.inputValidationInfoBackground = defaultOpts.inputValidationInfoBackground;
|
||||
@@ -112,7 +108,7 @@ export class ListBox extends SelectBox {
|
||||
|
||||
if (this.isValid) {
|
||||
this.selectElement.style.border = `1px solid ${this.selectBorder}`;
|
||||
} else {
|
||||
} else if (this.message) {
|
||||
const styles = this.stylesForType(this.message.type);
|
||||
this.selectElement.style.border = styles.border ? `1px solid ${styles.border}` : null;
|
||||
}
|
||||
@@ -123,7 +119,7 @@ export class ListBox extends SelectBox {
|
||||
}
|
||||
|
||||
public get selectedOptions(): string[] {
|
||||
let selected = [];
|
||||
let selected: string[] = [];
|
||||
for (let i = 0; i < this.selectElement.selectedOptions.length; i++) {
|
||||
selected.push(this.selectElement.selectedOptions[i].innerHTML);
|
||||
}
|
||||
@@ -136,7 +132,7 @@ export class ListBox extends SelectBox {
|
||||
|
||||
// Remove selected options
|
||||
public remove(): void {
|
||||
let indexes = [];
|
||||
let indexes: number[] = [];
|
||||
for (let i = 0; i < this.selectElement.selectedOptions.length; i++) {
|
||||
indexes.push(this.selectElement.selectedOptions[i].index);
|
||||
}
|
||||
@@ -219,24 +215,26 @@ export class ListBox extends SelectBox {
|
||||
className: 'monaco-inputbox-message'
|
||||
};
|
||||
|
||||
let spanElement: HTMLElement = (this.message.formatContent
|
||||
? renderFormattedText(this.message.content, renderOptions)
|
||||
: renderText(this.message.content, renderOptions)) as any;
|
||||
dom.addClass(spanElement, this.classForType(this.message.type));
|
||||
if (this.message) {
|
||||
let spanElement: HTMLElement = (this.message.formatContent
|
||||
? renderFormattedText(this.message.content, renderOptions)
|
||||
: renderText(this.message.content, renderOptions)) as any;
|
||||
dom.addClass(spanElement, this.classForType(this.message.type));
|
||||
|
||||
const styles = this.stylesForType(this.message.type);
|
||||
spanElement.style.backgroundColor = styles.background ? styles.background.toString() : null;
|
||||
spanElement.style.border = styles.border ? `1px solid ${styles.border}` : null;
|
||||
const styles = this.stylesForType(this.message.type);
|
||||
spanElement.style.backgroundColor = styles.background ? styles.background.toString() : null;
|
||||
spanElement.style.border = styles.border ? `1px solid ${styles.border}` : null;
|
||||
|
||||
dom.append(div, spanElement);
|
||||
dom.append(div, spanElement);
|
||||
}
|
||||
|
||||
return null;
|
||||
return { dispose: () => { } };
|
||||
},
|
||||
layout: layout
|
||||
});
|
||||
}
|
||||
|
||||
private classForType(type: MessageType): string {
|
||||
private classForType(type?: MessageType): string {
|
||||
switch (type) {
|
||||
case MessageType.INFO: return 'info';
|
||||
case MessageType.WARNING: return 'warning';
|
||||
@@ -244,11 +242,11 @@ export class ListBox extends SelectBox {
|
||||
}
|
||||
}
|
||||
|
||||
private stylesForType(type: MessageType): { border: Color; background: Color } {
|
||||
private stylesForType(type?: MessageType): { border?: Color; background?: Color } {
|
||||
switch (type) {
|
||||
case MessageType.INFO: return { border: this.inputValidationInfoBorder, background: this.inputValidationInfoBackground };
|
||||
case MessageType.WARNING: return { border: this.inputValidationWarningBorder, background: this.inputValidationWarningBackground };
|
||||
default: return { border: this.inputValidationErrorBorder, background: this.inputValidationErrorBackground };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,11 +81,11 @@ export class PanelComponent extends Disposable {
|
||||
private _actionbar: ActionBar;
|
||||
private _mru: TabComponent[];
|
||||
|
||||
protected ScrollbarVisibility = ScrollbarVisibility;
|
||||
protected NavigationBarLayout = NavigationBarLayout;
|
||||
protected ScrollbarVisibility = ScrollbarVisibility; // used by angular template
|
||||
protected NavigationBarLayout = NavigationBarLayout; // used by angular template
|
||||
|
||||
@ViewChild('panelActionbar', { read: ElementRef }) private _actionbarRef: ElementRef;
|
||||
constructor( @Inject(forwardRef(() => NgZone)) private _zone: NgZone) {
|
||||
constructor(@Inject(forwardRef(() => NgZone)) private _zone: NgZone) {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user