commit 8caa12b4ceeac2ef00a1f499a8312d131e64a1f7 Author: Selim Mustafaev Date: Wed Jan 5 22:36:47 2022 +0300 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b8a35d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea/ +cmake-build-* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..23bfdea --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.0) +project(autocat_gnome) + +set(CMAKE_CXX_STANDARD 20) + +#if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") +# add_compile_options(-stdlib=libc++) +#endif() + +find_package(PkgConfig) + +pkg_check_modules(GTKMM REQUIRED gtkmm-4.0) +pkg_check_modules(GLIBMM REQUIRED glibmm-2.68) +pkg_check_modules(LIBSOUP REQUIRED libsoup-2.4) + +include_directories(${GTKMM_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS} ${LIBSOUP_INCLUDE_DIRS}) +link_directories(${GTKMM_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} ${LIBSOUP_LIBRARY_DIRS}) + +add_executable(autocat_gnome main.cpp gui/MainWindow.cpp gui/MainWindow.h gui/LoginWindow.cpp gui/LoginWindow.h services/Api.cpp services/Api.h coro/Task.h models/User.cpp models/User.h) +target_link_libraries(autocat_gnome ${GTKMM_LIBRARIES} ${GLIBMM_LIBRARIES} ${LIBSOUP_LIBRARIES}) diff --git a/coro/Task.h b/coro/Task.h new file mode 100644 index 0000000..799a09a --- /dev/null +++ b/coro/Task.h @@ -0,0 +1,101 @@ +// +// Created by selim on 03.01.2022. +// + +#ifndef AUTOCAT_GNOME_TASK_H +#define AUTOCAT_GNOME_TASK_H + +#include +#include +#include + +template +class Task { +public: + struct promise_type { + auto initial_suspend() const noexcept { + std::cout << "initial_suspend" << std::endl; + return std::suspend_never(); + } + + auto final_suspend() const noexcept { + std::cout << "final_suspend" << std::endl; + return std::suspend_never(); + } + + Task get_return_object() { + std::cout << "get_return_object" << std::endl; + return Task{ std::coroutine_handle::from_promise(*this) }; + } + + void return_value(const T& value) noexcept(std::is_nothrow_copy_constructible_v) { + std::cout << "return_value: " << value << std::endl; + _value = value; + } + +// void return_void() { +// std::cout << "return_void" << std::endl; +// } + + void unhandled_exception() { + std::cout << "unhandled_exception" << std::endl; + throw; + } + }; + +private: + std::optional _value = std::nullopt; + std::coroutine_handle _handle; + +//public: +// bool await_ready() const noexcept { +// std::cout << "Awaiter::await_ready" << std::endl; +// return false; +// } +// +// void await_suspend(std::coroutine_handle handle) const { +// std::cout << "Awaiter::await_suspend" << std::endl; +// _handle = handle; +// } +// +// T await_resume() { +// std::cout << "Awaiter::await_resume" << std::endl; +// return _value.value(); +// } + +public: + void set_result(T result) { + _value = result; + _handle(); + } +}; + +template struct Awaiter { +public: + bool await_ready() const noexcept { + std::cout << "Awaiter::await_ready" << std::endl; + return false; + } + + void await_suspend(std::coroutine_handle::promise_type> cont) const { + std::cout << "Awaiter::await_suspend" << std::endl; + } + + U await_resume() { + std::cout << "Awaiter::await_resume" << std::endl; + return _task.value(); + } + +private: + Task _task; + +public: + explicit Awaiter(Task task): _task(task) {} +}; + +template +auto operator co_await(Task task) noexcept /*requires(!std::is_reference_v)*/ { + return Awaiter(task); +} + +#endif //AUTOCAT_GNOME_TASK_H diff --git a/gui/LoginWindow.cpp b/gui/LoginWindow.cpp new file mode 100644 index 0000000..6d20787 --- /dev/null +++ b/gui/LoginWindow.cpp @@ -0,0 +1,69 @@ +// +// Created by selim on 03.01.2022. +// + +#include "LoginWindow.h" +#include "../services/Api.h" + +#include +#include + +LoginWindow::LoginWindow() { + set_title("Login"); + set_default_size(640, 480); + + _emailField.set_placeholder_text("Email"); + _passwordField.set_placeholder_text("Password"); + _passwordField.set_input_purpose(Gtk::InputPurpose::PASSWORD); + _passwordField.set_visibility(false); + + _emailField.signal_changed().connect(sigc::mem_fun(*this, &LoginWindow::ValidateFields)); + _passwordField.signal_changed().connect(sigc::mem_fun(*this, &LoginWindow::ValidateFields)); + + _loginButton.set_margin_top(8); + _loginButton.set_margin_bottom(8); + _loginButton.set_label("Log in"); + _loginButton.signal_clicked().connect(sigc::mem_fun(*this, &LoginWindow::LoginClicked)); + _loginButton.set_sensitive(false); + + Gtk::Box box(Gtk::Orientation::VERTICAL, 8); + box.set_margin(48); + box.set_valign(Gtk::Align::CENTER); + + box.append(_emailField); + box.append(_passwordField); + box.append(_loginButton); + box.append(_spinner); + + set_child(box); +} + +//Task foo() { +// co_return 42; +//} +// +//Task bar() { +// auto xxx = co_await foo(); +// std::cout << "xxx: " << xxx << std::endl; +//} + +void LoginWindow::LoginClicked() { + auto email = _emailField.get_text(); + auto password = _passwordField.get_text(); + + _loginButton.set_sensitive(false); + _emailField.set_sensitive(false); + _passwordField.set_sensitive(false); + _spinner.start(); + + std::cout << "Login clicked" << std::endl; + std::cout << "Login: " << email << std::endl; + std::cout << "Password: " << password << std::endl; + + User user = co_await Api::login(email, password); +} + +void LoginWindow::ValidateFields() { + bool buttonEnabled = _emailField.get_text_length() > 0 && _passwordField.get_text_length() > 0; + _loginButton.set_sensitive(buttonEnabled); +} diff --git a/gui/LoginWindow.h b/gui/LoginWindow.h new file mode 100644 index 0000000..e2b8fd5 --- /dev/null +++ b/gui/LoginWindow.h @@ -0,0 +1,29 @@ +// +// Created by selim on 03.01.2022. +// + +#ifndef AUTOCAT_GNOME_LOGINWINDOW_H +#define AUTOCAT_GNOME_LOGINWINDOW_H + +#include +#include +#include +#include + +class LoginWindow: public Gtk::Window { +private: + Gtk::Entry _emailField; + Gtk::Entry _passwordField; + Gtk::Button _loginButton; + Gtk::Spinner _spinner; + +public: + LoginWindow(); + ~LoginWindow() override = default; + + void LoginClicked(); + void ValidateFields(); +}; + + +#endif //AUTOCAT_GNOME_LOGINWINDOW_H diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp new file mode 100644 index 0000000..40ce501 --- /dev/null +++ b/gui/MainWindow.cpp @@ -0,0 +1,10 @@ +// +// Created by selim on 03.01.2022. +// + +#include "MainWindow.h" + +MainWindow::MainWindow() { + set_title("Main window"); + set_default_size(640, 480); +} diff --git a/gui/MainWindow.h b/gui/MainWindow.h new file mode 100644 index 0000000..183db06 --- /dev/null +++ b/gui/MainWindow.h @@ -0,0 +1,16 @@ +// +// Created by selim on 03.01.2022. +// + +#ifndef AUTOCAT_GNOME_MAINWINDOW_H +#define AUTOCAT_GNOME_MAINWINDOW_H + +#include + +class MainWindow: public Gtk::Window { +public: + MainWindow(); +}; + + +#endif //AUTOCAT_GNOME_MAINWINDOW_H diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..fad08aa --- /dev/null +++ b/main.cpp @@ -0,0 +1,8 @@ +#include "gui/MainWindow.h" +#include "gui/LoginWindow.h" +#include + +int main(int argc, char* argv[]) { + auto app = Gtk::Application::create("pro.aliencat.aliencat"); + return app->make_window_and_run(argc, argv); +} diff --git a/models/User.cpp b/models/User.cpp new file mode 100644 index 0000000..3fb4b85 --- /dev/null +++ b/models/User.cpp @@ -0,0 +1,9 @@ +// +// Created by selim on 05.01.2022. +// + +#include "User.h" + +User::User(std::string_view login, std::string_view token): login(login), token(token) { + +} diff --git a/models/User.h b/models/User.h new file mode 100644 index 0000000..31245c1 --- /dev/null +++ b/models/User.h @@ -0,0 +1,23 @@ +// +// Created by selim on 05.01.2022. +// + +#ifndef AUTOCAT_GNOME_USER_H +#define AUTOCAT_GNOME_USER_H + +#include +#include + +class User { +public: + std::string login; + std::string token; + std::optional googleIdToken; + std::optional googleRefreshToken; + +public: + User(std::string_view login, std::string_view token); +}; + + +#endif //AUTOCAT_GNOME_USER_H diff --git a/services/Api.cpp b/services/Api.cpp new file mode 100644 index 0000000..2e5cc94 --- /dev/null +++ b/services/Api.cpp @@ -0,0 +1,49 @@ +// +// Created by selim on 03.01.2022. +// + +#include "Api.h" +#include + +template +struct callback { + void(*function)(Args..., void*) = nullptr; + std::unique_ptr state; +}; + +template +callback voidify(Lambda&& l) { + using Func = typename std::decay::type; + std::unique_ptr data( + new Func(std::forward(l)), + +[](void* ptr){ + std::cout << "!!!!!!!!!!!!!!!!! Deleting data" << std::endl; + delete (Func*)ptr; + } + ); + return { + +[](Args... args, void* v)->void { + Func* f = static_cast< Func* >(v); + (*f)(std::forward(args)...); + }, + std::move(data) + }; +} + +const std::string Api::_baseUrl = "https://vps.aliencat.pro:8443/"; +SoupSession* Api::_session = soup_session_new(); + +Task Api::login(std::string email, std::string password) { + std::string url = _baseUrl + "user/login"; + auto msg = soup_message_new(SOUP_METHOD_POST, url.c_str()); + + auto task = Task(); + + auto callback = voidify([&](SoupSession* session, SoupMessage* message) { + std::cout << "Callback called" << std::endl; + task.set_result(User("qwe", "asdf")); + }); + soup_session_queue_message(_session, msg, callback.function, callback.state.get()); + + return task; +} diff --git a/services/Api.h b/services/Api.h new file mode 100644 index 0000000..ec17397 --- /dev/null +++ b/services/Api.h @@ -0,0 +1,23 @@ +// +// Created by selim on 03.01.2022. +// + +#ifndef AUTOCAT_GNOME_API_H +#define AUTOCAT_GNOME_API_H + +#include +#include +#include "../models/User.h" +#include "../coro/Task.h" + +class Api { +private: + static const std::string _baseUrl; + static SoupSession* _session; + +public: + static Task login(std::string email, std::string password); +}; + + +#endif //AUTOCAT_GNOME_API_H