1+ /// <reference types="@react-telegram/core" />
2+ import React , { useState } from "react" ;
3+ import { MtcuteAdapter } from "@react-telegram/mtcute-adapter" ;
4+
5+
6+ interface CalculatorState {
7+ display : string ;
8+ previousValue : string ;
9+ operator : string | null ;
10+ waitingForOperand : boolean ;
11+ }
12+
13+ const initialState : CalculatorState = {
14+ display : "0" ,
15+ previousValue : "0" ,
16+ operator : null ,
17+ waitingForOperand : false ,
18+ } ;
19+
20+ const Calculator = ( ) => {
21+ const [ state , setState ] = useState < CalculatorState > ( initialState ) ;
22+
23+ const inputNumber = ( num : string ) => {
24+ if ( state . waitingForOperand ) {
25+ setState ( {
26+ ...state ,
27+ display : num ,
28+ waitingForOperand : false ,
29+ } ) ;
30+ } else {
31+ setState ( {
32+ ...state ,
33+ display : state . display === "0" ? num : state . display + num ,
34+ } ) ;
35+ }
36+ } ;
37+
38+ const inputDecimal = ( ) => {
39+ if ( state . waitingForOperand ) {
40+ setState ( {
41+ ...state ,
42+ display : "0." ,
43+ waitingForOperand : false ,
44+ } ) ;
45+ } else if ( state . display . indexOf ( "." ) === - 1 ) {
46+ setState ( {
47+ ...state ,
48+ display : state . display + "." ,
49+ } ) ;
50+ }
51+ } ;
52+
53+ const clear = ( ) => {
54+ setState ( initialState ) ;
55+ } ;
56+
57+ const performOperation = ( nextOperator : string | null ) => {
58+ const inputValue = parseFloat ( state . display ) ;
59+
60+ if ( state . previousValue === "0" ) {
61+ setState ( {
62+ ...state ,
63+ previousValue : String ( inputValue ) ,
64+ operator : nextOperator ,
65+ waitingForOperand : true ,
66+ } ) ;
67+ } else if ( state . operator ) {
68+ const previousValue = parseFloat ( state . previousValue ) ;
69+ let newValue = previousValue ;
70+
71+ if ( state . operator === "+" ) {
72+ newValue = previousValue + inputValue ;
73+ } else if ( state . operator === "-" ) {
74+ newValue = previousValue - inputValue ;
75+ } else if ( state . operator === "*" ) {
76+ newValue = previousValue * inputValue ;
77+ } else if ( state . operator === "/" ) {
78+ newValue = inputValue !== 0 ? previousValue / inputValue : 0 ;
79+ }
80+
81+ const display = String ( newValue ) ;
82+
83+ setState ( {
84+ display,
85+ previousValue : nextOperator ? display : "0" ,
86+ operator : nextOperator ,
87+ waitingForOperand : true ,
88+ } ) ;
89+ }
90+ } ;
91+
92+ const calculate = ( ) => {
93+ performOperation ( null ) ;
94+ } ;
95+
96+ const renderButton = ( label : string , onClick : ( ) => void , wide : boolean = false ) => (
97+ < button onClick = { onClick } >
98+ { label }
99+ </ button >
100+ ) ;
101+
102+ return (
103+ < >
104+ < b > 🧮 Calculator</ b >
105+ < br />
106+ < br />
107+ < code > { state . display } </ code >
108+ < br />
109+ < br />
110+ < row >
111+ { renderButton ( "C" , clear ) }
112+ { renderButton ( "±" , ( ) => setState ( { ...state , display : String ( - parseFloat ( state . display ) ) } ) ) }
113+ { renderButton ( "%" , ( ) => setState ( { ...state , display : String ( parseFloat ( state . display ) / 100 ) } ) ) }
114+ { renderButton ( "÷" , ( ) => performOperation ( "/" ) ) }
115+ </ row >
116+ < row >
117+ { renderButton ( "7" , ( ) => inputNumber ( "7" ) ) }
118+ { renderButton ( "8" , ( ) => inputNumber ( "8" ) ) }
119+ { renderButton ( "9" , ( ) => inputNumber ( "9" ) ) }
120+ { renderButton ( "×" , ( ) => performOperation ( "*" ) ) }
121+ </ row >
122+ < row >
123+ { renderButton ( "4" , ( ) => inputNumber ( "4" ) ) }
124+ { renderButton ( "5" , ( ) => inputNumber ( "5" ) ) }
125+ { renderButton ( "6" , ( ) => inputNumber ( "6" ) ) }
126+ { renderButton ( "−" , ( ) => performOperation ( "-" ) ) }
127+ </ row >
128+ < row >
129+ { renderButton ( "1" , ( ) => inputNumber ( "1" ) ) }
130+ { renderButton ( "2" , ( ) => inputNumber ( "2" ) ) }
131+ { renderButton ( "3" , ( ) => inputNumber ( "3" ) ) }
132+ { renderButton ( "+" , ( ) => performOperation ( "+" ) ) }
133+ </ row >
134+ < row >
135+ { renderButton ( "0" , ( ) => inputNumber ( "0" ) , true ) }
136+ { renderButton ( "." , inputDecimal ) }
137+ { renderButton ( "=" , calculate ) }
138+ </ row >
139+ </ >
140+ ) ;
141+ } ;
142+
143+ // Main bot setup
144+ async function main ( ) {
145+ // You'll need to set these environment variables
146+ const config = {
147+ apiId : parseInt ( process . env . API_ID || '0' ) ,
148+ apiHash : process . env . API_HASH || '' ,
149+ botToken : process . env . BOT_TOKEN || '' ,
150+ storage : process . env . STORAGE_PATH || '.mtcute'
151+ } ;
152+
153+ if ( ! config . apiId || ! config . apiHash || ! config . botToken ) {
154+ console . error ( 'Please set API_ID, API_HASH, and BOT_TOKEN environment variables' ) ;
155+ process . exit ( 1 ) ;
156+ }
157+
158+ const adapter = new MtcuteAdapter ( config ) ;
159+
160+ // Set up command handlers
161+ adapter . onCommand ( 'start' , ( ) => < Calculator /> ) ;
162+ adapter . onCommand ( 'calculator' , ( ) => < Calculator /> ) ;
163+ adapter . onCommand ( 'calc' , ( ) => < Calculator /> ) ;
164+
165+ // Start the bot
166+ await adapter . start ( config . botToken ) ;
167+
168+ console . log ( 'Calculator bot is running! Send /calculator to begin.' ) ;
169+ }
170+
171+ // Run the bot
172+ main ( ) . catch ( console . error ) ;
0 commit comments