4nm
Version:
TypeScript reimplementation of Telegram's official library for communicating with Telegram Web Apps.
233 lines (232 loc) • 5.85 kB
JavaScript
import { MAIN_BUTTON_PRESSED_EVENT } from '../WebView';
/**
* This object controls the main button, which is displayed at the bottom
* of the Web App in the Telegram interface.
* @see https://core.telegram.org/bots/webapps#mainbutton
*/
export class MainButton {
webView;
_color;
_textColor;
_isActive;
_isVisible;
_isProgressVisible;
_text;
constructor(webView, options = {}) {
this.webView = webView;
const { isActive = true, isProgressVisible = false, isVisible = false, text = 'CONTINUE', color = '#2481cc', textColor = '#ffffff', } = options;
this._color = color;
this._isActive = isActive;
this._isProgressVisible = isProgressVisible;
this._isVisible = isVisible;
this._text = text;
this._textColor = textColor;
}
/**
* Syncs current button state with native application.
*
* @private
*/
sync() {
this.webView.postEvent('web_app_setup_main_button', {
is_visible: this.isVisible,
is_active: this.isActive,
is_progress_visible: this.isProgressVisible,
text: this.text,
color: this.color,
text_color: this.textColor,
});
}
/**
* Updates current button visibility state.
*
* @param visible - should button be visible.
* @private
*/
setVisibility(visible) {
if (this.isVisible !== visible) {
this._isVisible = visible;
this.sync();
}
return this;
}
/**
* Updates current progress visibility.
*
* @param visible - should progress be visible.
* @private
*/
setProgressVisibility(visible) {
if (this.isProgressVisible !== visible) {
this._isProgressVisible = visible;
this.sync();
}
return this;
}
/**
* Updates current button active state.
*
* @private
* @param active - should button be active.
* @see sync
*/
setActive(active) {
if (this.isActive !== active) {
this._isActive = active;
this.sync();
}
return this;
}
/**
* Current button color.
*/
get color() {
return this._color;
}
/**
* A method to disable the button.
*
* @see setActive
*/
disable() {
this.setActive(false);
return this;
}
/**
* A method to enable the button.
*
* @see setActive
*/
enable() {
this.setActive(true);
return this;
}
/**
* A method to hide the button.
*
* @see setVisibility
*/
hide() {
this.setVisibility(false);
return this;
}
/**
* A method to hide the loading indicator.
*
* @see setProgressVisibility
*/
hideProgress() {
this.setProgressVisibility(false);
return this;
}
/**
* Shows whether the button is active.
*/
get isActive() {
return this._isActive;
}
/**
* Shows whether the button is displaying a loading indicator.
*/
get isProgressVisible() {
return this._isProgressVisible;
}
/**
* Shows whether the button is visible.
*/
get isVisible() {
return this._isVisible;
}
/**
* Adds onclick listener.
* @param listener - listener to call.
*/
onClick(listener) {
this.webView.on(MAIN_BUTTON_PRESSED_EVENT, listener);
}
/**
* Remove onclick event listener.
* @param listener - listener to call.
*/
offClick(listener) {
this.webView.off(MAIN_BUTTON_PRESSED_EVENT, listener);
}
/**
* A method to set the button text.
*
* @param text - text to set.
* @throws {Error} Text has incorrect length.
* @see sync
*/
setText(text) {
const trimmed = text.trim();
if (trimmed.length === 0 || trimmed.length > 64) {
throw new Error(`Text has incorrect length: ${trimmed.length}`);
}
if (trimmed !== this.text) {
this._text = trimmed;
this.sync();
}
return this;
}
/**
* Updates current button color.
*
* @see sync
* @param color - target color.
*/
setColor(color) {
if (this.color !== color) {
this._color = color;
this.sync();
}
return this;
}
/**
* Updates current button text color.
*
* @see sync
* @param color - target color.
*/
setTextColor(color) {
if (this.textColor !== color) {
this._textColor = color;
this.sync();
}
return this;
}
/**
* A method to make the button visible.
* Note that opening the Web App from the attachment menu hides the main
* button until the user interacts with the Web App interface.
*
* @see setVisibility
*/
show() {
this.setVisibility(true);
return this;
}
/**
* A method to show a loading indicator on the button.
* It is recommended to display loading progress if the action tied to the
* button may take a long time.
*
* @see setProgressVisibility
*/
showProgress() {
this.setProgressVisibility(true);
return this;
}
/**
* Current button text.
*/
get text() {
return this._text;
}
/**
* Current button text color.
*/
get textColor() {
return this._textColor;
}
}