@@ -18,49 +18,127 @@ using std::string, std::vector, nlohmann::json;
1818namespace fs = std::filesystem;
1919namespace ch = std::chrono;
2020
21- char drawUI (string title, vector<string> arr) {
22- noecho ();
23- short choice = 0 , ch;
24- bool kurwa = true ;
25- while (kurwa) {
26- printw (" %s\n " , title.c_str ());
27- for (int i = 0 ; i < arr.size (); i++)
28- printw (" %c %s\n " , i == choice ? ' >' : ' ' , arr[i].c_str ());
29- switch (ch = getch ()) {
30- case ' k' :
31- case KEY_UP:
32- if (choice > 0 ) choice--;
33- break ;
34- case ' j' :
35- case KEY_DOWN:
36- if (choice < arr.size () - 1 ) choice++;
37- break ;
38- case ' \n ' :
39- kurwa = false ;
40- break ;
21+ class clsUi {
22+ public:
23+ short maxx, maxy;
24+
25+ short menu (const string& title, const vector<string>& choices) {
26+ noecho ();
27+ curs_set (false );
28+ short choice = 0 , input = 0 , maxWidth = 0 , maxHeight = choices.size (),
29+ minWidth = 15 ;
30+ for (const string& str : choices) {
31+ short len = str.length ();
32+ if (len > maxWidth) maxWidth = len;
4133 }
42- clear ();
34+ short titleLen = title.length ();
35+ if (titleLen > maxWidth) maxWidth = titleLen;
36+ if (minWidth > maxWidth) maxWidth = minWidth;
37+ WINDOW* win =
38+ newwin (maxHeight + 2 , maxWidth + 2 , maxy / 2 - (maxHeight + 2 ) / 2 ,
39+ maxx / 2 - (maxWidth + 2 ) / 2 );
40+ keypad (win, true );
41+ box (win, 0 , 0 );
42+ mvwprintw (win, 0 , 1 , " %s" , title.c_str ());
43+ for (int i = 1 ; i < choices.size (); i++)
44+ mvwprintw (win, i + 1 , 1 , " %s" , choices[i].c_str ());
45+ do {
46+ switch (input) {
47+ case ' k' :
48+ case KEY_UP:
49+ if (choice > 0 ) {
50+ mvwprintw (win, choice + 1 , 1 , " %s%*c" ,
51+ choices[choice].c_str (),
52+ maxWidth - choices[choice].length () + 1 ,
53+ ' \0 ' );
54+ --choice;
55+ }
56+ break ;
57+ case ' j' :
58+ case KEY_DOWN:
59+ if (choice < choices.size () - 1 ) {
60+ mvwprintw (win, choice + 1 , 1 , " %s%*c" ,
61+ choices[choice].c_str (),
62+ maxWidth - choices[choice].length () + 1 ,
63+ ' \0 ' );
64+ ++choice;
65+ }
66+ break ;
67+ default :
68+ break ;
69+ }
70+ wattron (win, A_STANDOUT);
71+ mvwprintw (win, choice + 1 , 1 , " %s%*c" , choices[choice].c_str (),
72+ maxWidth - choices[choice].length () + 1 , ' \0 ' );
73+ wattroff (win, A_STANDOUT);
74+ } while ((input = wgetch (win)) != ' \n ' );
75+ werase (win);
76+ wrefresh (win);
77+ delwin (win);
78+ echo ();
79+ curs_set (true );
80+ return choice;
4381 }
44- echo ();
45- return choice;
46- }
47- void progressBar (const long &prog, const long &total) {
48- int y, x;
49- getyx (stdscr, y, x);
50- const int len = 30 ;
51- int percent = ceil (float (len) / total * prog);
52- wchar_t str[len + 1 ];
53- for (int i = 0 ; i < percent; i++) str[i] = L' \u2588 ' ;
54- for (int i = percent; i < len; i++) str[i] = L' \u2592 ' ;
55- str[len] = L' \0 ' ;
56- mvprintw (y, 0 , " |%ls|" , str);
57- if (prog == total) addch (' \n ' );
58- refresh ();
59- }
82+
83+ void progressBar (const long & prog, const long & total) {
84+ short y, x;
85+ getyx (stdscr, y, x);
86+ const int len = 30 ;
87+ short percent = ceil (float (len) / total * prog);
88+ wchar_t str[len + 1 ];
89+ for (short i = 0 ; i < percent; i++) str[i] = L' \u2588 ' ;
90+ for (short i = percent; i < len; i++) str[i] = L' \u2592 ' ;
91+ str[len] = L' \0 ' ;
92+ mvprintw (y, 0 , " |%ls|" , str);
93+ if (prog == total) move (y + 1 , 0 );
94+ refresh ();
95+ }
96+
97+ void notification (const string& title, const vector<string>& message) {
98+ noecho ();
99+ curs_set (false );
100+ short maxWidth = 0 , maxHeight = message.size (),
101+ titleLen = title.length ();
102+ for (const string& str : message) {
103+ short len = str.length ();
104+ if (len > maxWidth) maxWidth = len;
105+ }
106+ if (titleLen > maxWidth) maxWidth = titleLen;
107+ maxWidth += 4 ;
108+ WINDOW* win =
109+ newwin (maxHeight + 2 , maxWidth, maxy / 2 - (maxHeight + 2 ) / 2 ,
110+ maxx / 2 - maxWidth / 2 );
111+ box (win, 0 , 0 );
112+ mvwprintw (win, 0 , maxWidth / 2 - titleLen / 2 , " %s" , title.c_str ());
113+ for (short i = 0 ; i < maxHeight; i++)
114+ mvwprintw (win, i + 1 , maxWidth / 2 - message[i].length () / 2 , " %s" ,
115+ message[i].c_str ());
116+ wrefresh (win);
117+
118+ wgetch (win);
119+ werase (win);
120+ wrefresh (win);
121+ delwin (win);
122+
123+ echo ();
124+ curs_set (true );
125+ }
126+
127+ clsUi () {
128+ setlocale (LC_ALL, " " );
129+ initscr ();
130+ cbreak ();
131+ scrollok (stdscr, true );
132+ keypad (stdscr, true );
133+ getmaxyx (stdscr, maxy, maxx);
134+ }
135+ ~clsUi () { endwin (); }
136+ };
60137
61138class client {
62139 public:
63140 clsSock sock;
141+ clsUi ui;
64142
65143 void reg () {
66144 char buffer[1024 ];
@@ -88,14 +166,14 @@ class client {
88166 clear ();
89167 } while (sock.recv () != " ok" );
90168 }
91- client (SSL * ssl) : sock(ssl) {}
169+ client (SSL* ssl, clsUi& ui ) : sock(ssl), ui(ui ) {}
92170};
93171
94172class project {
95173 private:
96174 json genJson (string path) {
97175 json res;
98- for (const fs::directory_entry & entry : fs::directory_iterator (path)) {
176+ for (const fs::directory_entry& entry : fs::directory_iterator (path)) {
99177 if (entry.is_directory ())
100178 res[entry.path ().filename ().string ()] =
101179 genJson (entry.path ().string ());
@@ -108,7 +186,7 @@ class project {
108186 return res;
109187 }
110188
111- void compJson (json & oldjs, json & newjs, string path) {
189+ void compJson (json& oldjs, json& newjs, string path) {
112190 for (json::iterator it = oldjs.begin (); it != oldjs.end (); ++it) {
113191 if (newjs.contains (it.key ())) {
114192 if (it.value ().is_number () && newjs[it.key ()].is_object ()) {
@@ -183,12 +261,13 @@ class project {
183261
184262 void set () {
185263 char buffer[1024 ];
186- do {
264+ /* do {
187265 printw("Path to your project: ");
188266 getstr(buffer);
189267 prjPath = buffer;
190- } while (!fs::exists (prjPath) && !fs::is_directory (prjPath));
191- // prjPath = "/home/jomm/Documents/kurwa/client/test/";
268+ } while (!fs::exists(prjPath) && !fs::is_directory(prjPath)); */
269+ prjPath = " /home/jomm/Documents/kurwa/client/test/" ;
270+ // prjPath += '/';
192271 do {
193272 printw (" Name of your project: " );
194273 getstr (buffer);
@@ -229,10 +308,10 @@ class project {
229308 }
230309 }
231310
232- project (client & x) : owner(x) {}
311+ project (client& x) : owner(x) {}
233312};
234313
235- int main (int argc, char * argv[]) {
314+ int main (int argc, char * argv[]) {
236315 string path = fs::canonical (argv[0 ]).parent_path ().string () + ' /' ;
237316
238317 setlocale (LC_ALL, " " );
@@ -241,13 +320,14 @@ int main(int argc, char *argv[]) {
241320 keypad (stdscr, TRUE );
242321
243322 SSL_library_init ();
244- SSL_CTX * ctx = SSL_CTX_new (TLS_client_method ());
323+ SSL_CTX* ctx = SSL_CTX_new (TLS_client_method ());
245324
246325 SSL_CTX_load_verify_locations (ctx, (path + " cert.pem" ).c_str (), NULL );
247326
248- client client (SSL_new (ctx));
327+ clsUi ui;
328+ client client (SSL_new (ctx), ui);
249329
250- switch (drawUI (" Choose one option:" , {" Sign In" , " Sign Up" })) {
330+ switch (ui. menu (" Choose one option:" , {" Sign In" , " Sign Up" })) {
251331 case 0 :
252332 client.sock .send (" signIn" );
253333 client.log ();
@@ -259,9 +339,9 @@ int main(int argc, char *argv[]) {
259339 break ;
260340 }
261341 project project (client);
262- switch (drawUI (" Choose one option:" ,
263- {" Create new project" , " Open existing project" ,
264- " Download project from server" })) {
342+ switch (ui. menu (" Choose one option:" ,
343+ {" Create new project" , " Open existing project" ,
344+ " Download project from server" })) {
265345 case 0 :
266346 client.sock .send (" createPrj" );
267347 project.set ();
0 commit comments