1+ using System ;
2+ using System . Threading . Tasks ;
3+ using System . Collections . Generic ;
4+ using LeanCloud ;
5+ using LeanCloud . Storage ;
6+ using LeanCloud . Realtime ;
7+
8+ namespace ChatStack
9+ {
10+ public class Client
11+ {
12+
13+ public bool Beep = true ;
14+
15+ LCIMClient UserClient ;
16+ LCIMConversation Chatroom ;
17+
18+ Dictionary < string , string > UsernameIndex = new Dictionary < string , string > ( ) ;
19+
20+ // TODO: Detect if the user is typing.
21+ // Queue<LCIMTextMessage> MessageBuffer = new Queue<LCIMTextMessage>();
22+
23+
24+ public static void InitApp ( string appId , string appKey , string url = null )
25+ {
26+ // Initialize the app with the LeanCloud credentials.
27+ LCApplication . Initialize ( appId , appKey , url ) ;
28+ }
29+
30+ public static async Task < LCUser > LoginUserAsync ( string username , string password )
31+ {
32+ // Check if the username is an email address.
33+ if ( new System . ComponentModel . DataAnnotations . EmailAddressAttribute ( ) . IsValid ( username ) )
34+ {
35+ return await LCUser . LoginByEmail ( username , password ) ;
36+ }
37+ return await LCUser . Login ( username , password ) ;
38+ }
39+
40+ public async Task LoginClientAsync ( string username , string password )
41+ {
42+ // Log in to client using LCUser.
43+ UserClient = new LCIMClient ( await LoginUserAsync ( username , password ) ) ;
44+
45+ await InitClientAsync ( ) ;
46+ }
47+
48+ public async Task InitClientAsync ( )
49+ {
50+ // Initiate the client with the server.
51+ await UserClient . Open ( ) ;
52+ }
53+
54+ public async Task GetChatroomAsync ( )
55+ {
56+ // Query the ChatStack chatroom.
57+ var conversationQuery = UserClient . GetQuery ( )
58+ . WhereEqualTo ( "name" , "ChatStack" )
59+ . WhereEqualTo ( "tr" , true ) ;
60+ var queryResult = await conversationQuery . Find ( ) ;
61+
62+ Chatroom = queryResult [ 0 ] ;
63+ }
64+
65+ public async Task StartChatAsync ( )
66+ {
67+
68+ // Join the chat.
69+ await Chatroom . Join ( ) ;
70+
71+ // TODO: Fetch previous messages.
72+
73+ // Print the prompt and the number of online users in the chatroom.
74+ Console . WriteLine ( "You are now in the chat. Type /exit or /quit to exit." ) ;
75+ Console . WriteLine ( await Chatroom . GetMembersCount ( ) + " people online." ) ;
76+
77+ // Listen for messages.
78+ UserClient . OnMessage = async ( _ , message ) =>
79+ {
80+ // If the message received is text, assign it to textMessage.
81+ if ( message is LCIMTextMessage textMessage )
82+ {
83+
84+ if ( ! UsernameIndex . ContainsKey ( textMessage . FromClientId ) )
85+ {
86+ // Query and save the sender's username if it's not in the index.
87+ LCQuery < LCUser > senderQuery = LCUser . GetQuery ( ) ;
88+ UsernameIndex [ textMessage . FromClientId ] = ( await senderQuery . Get ( textMessage . FromClientId ) ) . Username ;
89+ }
90+
91+ // TODO: Detect if the user is typing.
92+ // // Peek the input stream without reading it.
93+ // if ((new StreamReader(Console.OpenStandardInput()).Peek() == -1))
94+ // {
95+ // // If the user hasn't typed anything, print the message.
96+ // PrintMessage(textMessage);
97+
98+ // // Print the prompt again.
99+ // Console.Write("> ");
100+ // }
101+ // else
102+ // {
103+ // // If the user is typing, save the message to the buffer.
104+ // MessageBuffer.Enqueue(textMessage);
105+ // }
106+
107+ PrintMessage ( textMessage ) ;
108+
109+ }
110+ } ;
111+
112+ // Ask for message input constantly.
113+ await AskForMessageInputAsync ( ) ;
114+
115+ }
116+
117+ async Task AskForMessageInputAsync ( )
118+ {
119+ while ( true )
120+ {
121+
122+ // Print prompt and get input.
123+ Console . Write ( "> " ) ;
124+ string input = await Task . Run ( ( ) => Console . ReadLine ( ) . Trim ( ) ) ;
125+
126+ // TODO: Detect if the user is typing.
127+ // Clear message buffer.
128+ // while (MessageBuffer.Count > 0)
129+ // PrintMessage(MessageBuffer.Dequeue());
130+
131+ // Check the input for exit commands.
132+ if ( input == "/exit" || input == "/quit" ) break ;
133+
134+ // Send the message if the input is not empty.
135+ if ( ! string . IsNullOrWhiteSpace ( input ) )
136+ {
137+ _ = await Chatroom . Send ( new LCIMTextMessage ( input ) ) ;
138+ }
139+
140+ }
141+ }
142+
143+ void PrintMessage ( LCIMTextMessage message )
144+ {
145+
146+ // Play a beep sound if beep is enabled.
147+ if ( Beep )
148+ Console . Beep ( ) ;
149+
150+ // TODO: Detect if the user is typing.
151+ // Set cursor position to the beginning of the line.
152+ // Console.SetCursorPosition(0, Console.CursorTop);
153+ Console . WriteLine ( ) ;
154+
155+ // Print the message sender's username and the message content.
156+ Console . WriteLine ( $ "* { UsernameIndex [ message . FromClientId ] } : { message . Text } ") ;
157+
158+ // Print the prompt again.
159+ Console . Write ( "> " ) ;
160+
161+ }
162+
163+ // public static void DebugLogger(LCLogLevel level, string info)
164+ // {
165+ // switch (level)
166+ // {
167+ // case LCLogLevel.Debug:
168+ // Console.WriteLine("[DEBUG] " + info);
169+ // break;
170+ // case LCLogLevel.Warn:
171+ // Console.WriteLine("[WARNING] " + info);
172+ // break;
173+ // case LCLogLevel.Error:
174+ // Console.WriteLine("[ERROR] " + info);
175+ // break;
176+ // default:
177+ // Console.WriteLine(info);
178+ // break;
179+ // }
180+ // }
181+
182+ }
183+ }
0 commit comments