From 35cf6ebaf9b26a9dc316f5d8f6859f2d1319c7c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Wo=C5=BAniak?= Date: Mon, 3 Apr 2023 16:08:53 +0200 Subject: [PATCH] Add cloud storage, fix upload and move to trunk --- .dockerignore | 10 +- .env | 2 +- .gitignore | 35 +- Cargo.lock | 417 +++- Cargo.toml | 2 +- Dockerfile.build | 15 - crates/bitque-config/Cargo.toml | 4 +- .../src/{amazon.rs => cloud_storage.rs} | 0 crates/bitque-config/src/lib.rs | 4 +- crates/bitque-data/Cargo.toml | 3 +- crates/bitque-data/src/lib.rs | 96 +- crates/bitque-server/Cargo.toml | 2 +- crates/bitque-server/src/main.rs | 26 +- crates/cloud-storage-actor/src/lib.rs | 14 +- crates/database-actor/src/issues.rs | 4 +- crates/derive_enum_primitive/src/lib.rs | 192 +- crates/derive_enum_sql/src/lib.rs | 2 +- crates/filesystem-actor/src/lib.rs | 10 +- .../assets/InspiredGitHub.tmTheme | 1725 +++++++++++++++++ crates/highlight-actor/src/lib.rs | 2 +- crates/highlight-actor/src/load.rs | 20 +- crates/web-actor/Cargo.toml | 2 +- crates/web-actor/src/avatar.rs | 44 +- crates/web-actor/src/errors.rs | 4 +- .../src/handlers/upload_avatar_image.rs | 56 +- crates/web/Cargo.toml | 15 +- crates/web/Trunk.toml | 20 + .../fonts/CircularStd-Black.eot | Bin .../fonts/CircularStd-Black.otf | Bin .../fonts/CircularStd-Black.svg | 0 .../fonts/CircularStd-Black.ttf | Bin .../fonts/CircularStd-Black.woff | Bin .../fonts/CircularStd-Black.woff2 | Bin .../fonts/CircularStd-Bold.eot | Bin .../fonts/CircularStd-Bold.otf | Bin .../fonts/CircularStd-Bold.svg | 0 .../fonts/CircularStd-Bold.ttf | Bin .../fonts/CircularStd-Bold.woff | Bin .../fonts/CircularStd-Bold.woff2 | Bin .../fonts/CircularStd-Book.eot | Bin .../fonts/CircularStd-Book.otf | Bin .../fonts/CircularStd-Book.svg | 0 .../fonts/CircularStd-Book.ttf | Bin .../fonts/CircularStd-Book.woff | Bin .../fonts/CircularStd-Book.woff2 | Bin .../fonts/CircularStd-Medium.eot | Bin .../fonts/CircularStd-Medium.otf | Bin .../fonts/CircularStd-Medium.svg | 0 .../fonts/CircularStd-Medium.ttf | Bin .../fonts/CircularStd-Medium.woff | Bin .../fonts/CircularStd-Medium.woff2 | Bin .../web/{static => assets}/fonts/icofont.eot | Bin .../web/{static => assets}/fonts/icofont.svg | 0 .../web/{static => assets}/fonts/icofont.ttf | Bin .../web/{static => assets}/fonts/icofont.woff | Bin .../{static => assets}/fonts/icofont.woff2 | Bin crates/web/{static => assets}/fonts/jira.svg | 0 crates/web/{static => assets}/fonts/jira.ttf | Bin crates/web/{static => assets}/fonts/jira.woff | Bin .../web/{static => assets/images}/favicon.png | Bin .../{static => assets/images}/feedback.png | Bin crates/web/{static => assets/images}/logo.svg | 0 .../web/{static => assets/images}/logo2.svg | 0 .../images}/project-avatar.svg | 0 .../images}/project-icon.svg | 0 crates/web/{js => assets/styles}/css/app.scss | 0 .../web/{js => assets/styles}/css/aside.scss | 0 .../styles}/css/deleteIssueStatus.scss | 0 .../{js => assets/styles}/css/epicsPage.scss | 0 .../web/{js => assets/styles}/css/fonts.scss | 0 .../web/{js => assets/styles}/css/global.scss | 0 .../{js => assets/styles}/css/iconfonts.scss | 0 .../web/{js => assets/styles}/css/invite.scss | 0 .../web/{js => assets/styles}/css/issue.scss | 0 .../styles}/css/issuesAndFilters.scss | 0 .../web/{js => assets/styles}/css/login.scss | 0 .../{js => assets/styles}/css/normalize.scss | 0 .../{js => assets/styles}/css/profile.scss | 0 .../{js => assets/styles}/css/project.scss | 0 .../styles}/css/projectSettings.scss | 0 .../{js => assets/styles}/css/register.scss | 0 .../{js => assets/styles}/css/reports.scss | 0 .../web/{js => assets/styles}/css/shared.scss | 0 .../{js => assets/styles}/css/sidebar.scss | 0 .../styles}/css/styledAvatar.scss | 0 .../styles}/css/styledButton.scss | 0 .../styles}/css/styledCheckbox.scss | 0 .../styles}/css/styledComment.scss | 0 .../styles}/css/styledDateTimeInput.scss | 0 .../styles}/css/styledEditor.scss | 0 .../{js => assets/styles}/css/styledForm.scss | 0 .../{js => assets/styles}/css/styledIcon.scss | 0 .../styles}/css/styledImageInput.scss | 0 .../styles}/css/styledInput.scss | 0 .../{js => assets/styles}/css/styledLink.scss | 0 .../styles}/css/styledModal.scss | 0 .../{js => assets/styles}/css/styledPage.scss | 0 .../{js => assets/styles}/css/styledRte.scss | 0 .../styles}/css/styledSelect.scss | 0 .../styles}/css/styledSelectChild.scss | 0 .../styles}/css/styledTextArea.scss | 0 .../styles}/css/styledTooltip.scss | 0 .../styles}/css/timeTracking.scss | 0 .../web/{js => assets/styles}/css/users.scss | 0 .../{js => assets/styles}/css/variables.scss | 0 .../styles.css => assets/styles/styles.scss} | 0 crates/web/index.html | 16 + crates/web/js/nginx-selfsigned.crt | 21 - crates/web/js/nginx-selfsigned.key | 28 - crates/web/js/template.ejs | 40 - crates/web/js/template.html | 74 - crates/web/scripts/compile-css.sh | 1 + crates/web/scripts/dev.sh | 23 +- crates/web/src/changes.rs | 1 + crates/web/src/components/events.rs | 2 +- crates/web/src/components/styled_editor.rs | 2 +- crates/web/src/components/styled_rte.rs | 2 +- crates/web/src/images/logo.rs | 4 +- crates/web/src/{lib.rs => main.rs} | 25 +- crates/web/src/modals/epics_edit/view.rs | 9 +- crates/web/src/modals/issues_create/model.rs | 4 +- crates/web/src/modals/issues_create/view.rs | 9 +- crates/web/src/modals/issues_edit/view.rs | 19 +- crates/web/src/modals/update.rs | 3 +- crates/web/src/model.rs | 2 +- .../pages/issues_and_filters/view/filters.rs | 53 +- crates/web/src/pages/profile_page/view.rs | 2 +- .../web/src/pages/project_page/view/board.rs | 8 +- .../src/pages/project_settings_page/update.rs | 4 +- .../src/pages/project_settings_page/view.rs | 15 +- crates/web/src/pages/reports_page/model.rs | 2 +- crates/web/src/pages/reports_page/view.rs | 2 +- crates/web/src/pages/users_page/view.rs | 7 +- crates/web/src/ws/mod.rs | 20 +- crates/web/static/index.js | 8 - crates/web/tailwind.config.js | 8 + crates/websocket-actor/src/lib.rs | 27 +- docker-compose.yml | 19 +- docker/Dockerfile.build | 22 + docker/boot-server.sh | 5 + docker/config/db.toml | 2 + docker/config/fs.toml | 5 + docker/config/highlight.toml | 2 + docker/config/mail.toml | 5 + docker/config/web.toml | 4 + .../up.sql | 4 - 146 files changed, 2692 insertions(+), 543 deletions(-) delete mode 100644 Dockerfile.build rename crates/bitque-config/src/{amazon.rs => cloud_storage.rs} (100%) create mode 100644 crates/highlight-actor/assets/InspiredGitHub.tmTheme create mode 100644 crates/web/Trunk.toml rename crates/web/{static => assets}/fonts/CircularStd-Black.eot (100%) rename crates/web/{static => assets}/fonts/CircularStd-Black.otf (100%) rename crates/web/{static => assets}/fonts/CircularStd-Black.svg (100%) rename crates/web/{static => assets}/fonts/CircularStd-Black.ttf (100%) rename crates/web/{static => assets}/fonts/CircularStd-Black.woff (100%) rename crates/web/{static => assets}/fonts/CircularStd-Black.woff2 (100%) rename crates/web/{static => assets}/fonts/CircularStd-Bold.eot (100%) rename crates/web/{static => assets}/fonts/CircularStd-Bold.otf (100%) rename crates/web/{static => assets}/fonts/CircularStd-Bold.svg (100%) rename crates/web/{static => assets}/fonts/CircularStd-Bold.ttf (100%) rename crates/web/{static => assets}/fonts/CircularStd-Bold.woff (100%) rename crates/web/{static => assets}/fonts/CircularStd-Bold.woff2 (100%) rename crates/web/{static => assets}/fonts/CircularStd-Book.eot (100%) rename crates/web/{static => assets}/fonts/CircularStd-Book.otf (100%) rename crates/web/{static => assets}/fonts/CircularStd-Book.svg (100%) rename crates/web/{static => assets}/fonts/CircularStd-Book.ttf (100%) rename crates/web/{static => assets}/fonts/CircularStd-Book.woff (100%) rename crates/web/{static => assets}/fonts/CircularStd-Book.woff2 (100%) rename crates/web/{static => assets}/fonts/CircularStd-Medium.eot (100%) rename crates/web/{static => assets}/fonts/CircularStd-Medium.otf (100%) rename crates/web/{static => assets}/fonts/CircularStd-Medium.svg (100%) rename crates/web/{static => assets}/fonts/CircularStd-Medium.ttf (100%) rename crates/web/{static => assets}/fonts/CircularStd-Medium.woff (100%) rename crates/web/{static => assets}/fonts/CircularStd-Medium.woff2 (100%) rename crates/web/{static => assets}/fonts/icofont.eot (100%) rename crates/web/{static => assets}/fonts/icofont.svg (100%) rename crates/web/{static => assets}/fonts/icofont.ttf (100%) rename crates/web/{static => assets}/fonts/icofont.woff (100%) rename crates/web/{static => assets}/fonts/icofont.woff2 (100%) rename crates/web/{static => assets}/fonts/jira.svg (100%) rename crates/web/{static => assets}/fonts/jira.ttf (100%) rename crates/web/{static => assets}/fonts/jira.woff (100%) rename crates/web/{static => assets/images}/favicon.png (100%) rename crates/web/{static => assets/images}/feedback.png (100%) rename crates/web/{static => assets/images}/logo.svg (100%) rename crates/web/{static => assets/images}/logo2.svg (100%) rename crates/web/{static => assets/images}/project-avatar.svg (100%) rename crates/web/{static => assets/images}/project-icon.svg (100%) rename crates/web/{js => assets/styles}/css/app.scss (100%) rename crates/web/{js => assets/styles}/css/aside.scss (100%) rename crates/web/{js => assets/styles}/css/deleteIssueStatus.scss (100%) rename crates/web/{js => assets/styles}/css/epicsPage.scss (100%) rename crates/web/{js => assets/styles}/css/fonts.scss (100%) rename crates/web/{js => assets/styles}/css/global.scss (100%) rename crates/web/{js => assets/styles}/css/iconfonts.scss (100%) rename crates/web/{js => assets/styles}/css/invite.scss (100%) rename crates/web/{js => assets/styles}/css/issue.scss (100%) rename crates/web/{js => assets/styles}/css/issuesAndFilters.scss (100%) rename crates/web/{js => assets/styles}/css/login.scss (100%) rename crates/web/{js => assets/styles}/css/normalize.scss (100%) rename crates/web/{js => assets/styles}/css/profile.scss (100%) rename crates/web/{js => assets/styles}/css/project.scss (100%) rename crates/web/{js => assets/styles}/css/projectSettings.scss (100%) rename crates/web/{js => assets/styles}/css/register.scss (100%) rename crates/web/{js => assets/styles}/css/reports.scss (100%) rename crates/web/{js => assets/styles}/css/shared.scss (100%) rename crates/web/{js => assets/styles}/css/sidebar.scss (100%) rename crates/web/{js => assets/styles}/css/styledAvatar.scss (100%) rename crates/web/{js => assets/styles}/css/styledButton.scss (100%) rename crates/web/{js => assets/styles}/css/styledCheckbox.scss (100%) rename crates/web/{js => assets/styles}/css/styledComment.scss (100%) rename crates/web/{js => assets/styles}/css/styledDateTimeInput.scss (100%) rename crates/web/{js => assets/styles}/css/styledEditor.scss (100%) rename crates/web/{js => assets/styles}/css/styledForm.scss (100%) rename crates/web/{js => assets/styles}/css/styledIcon.scss (100%) rename crates/web/{js => assets/styles}/css/styledImageInput.scss (100%) rename crates/web/{js => assets/styles}/css/styledInput.scss (100%) rename crates/web/{js => assets/styles}/css/styledLink.scss (100%) rename crates/web/{js => assets/styles}/css/styledModal.scss (100%) rename crates/web/{js => assets/styles}/css/styledPage.scss (100%) rename crates/web/{js => assets/styles}/css/styledRte.scss (100%) rename crates/web/{js => assets/styles}/css/styledSelect.scss (100%) rename crates/web/{js => assets/styles}/css/styledSelectChild.scss (100%) rename crates/web/{js => assets/styles}/css/styledTextArea.scss (100%) rename crates/web/{js => assets/styles}/css/styledTooltip.scss (100%) rename crates/web/{js => assets/styles}/css/timeTracking.scss (100%) rename crates/web/{js => assets/styles}/css/users.scss (100%) rename crates/web/{js => assets/styles}/css/variables.scss (100%) rename crates/web/{js/styles.css => assets/styles/styles.scss} (100%) create mode 100644 crates/web/index.html delete mode 100644 crates/web/js/nginx-selfsigned.crt delete mode 100644 crates/web/js/nginx-selfsigned.key delete mode 100644 crates/web/js/template.ejs delete mode 100644 crates/web/js/template.html create mode 100755 crates/web/scripts/compile-css.sh rename crates/web/src/{lib.rs => main.rs} (96%) delete mode 100644 crates/web/static/index.js create mode 100644 crates/web/tailwind.config.js create mode 100644 docker/Dockerfile.build create mode 100755 docker/boot-server.sh create mode 100644 docker/config/db.toml create mode 100644 docker/config/fs.toml create mode 100644 docker/config/highlight.toml create mode 100644 docker/config/mail.toml create mode 100644 docker/config/web.toml diff --git a/.dockerignore b/.dockerignore index fbf04ccb..fa50b7a3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -82,9 +82,9 @@ fabric.properties /tmp/ -/web/target/ -/web/tmp/ -/web/build/ +crates/web/target/ +crates/web/tmp/ +crates/web/build/ -/bitque-server/target/ -/bitque-server/tmp/ +crates/bitque-server/target/ +crates/bitque-server/tmp/ diff --git a/.env b/.env index 52f374cc..c76ca86a 100644 --- a/.env +++ b/.env @@ -1,5 +1,5 @@ DEBUG=true -RUST_LOG=debug +RUST_LOG=info JIRS_CLIENT_PORT=80 JIRS_CLIENT_BIND=bitque.lvh.me DATABASE_URL=postgres://postgres@localhost:5432/bitque diff --git a/.gitignore b/.gitignore index 58e0716b..e9ac444a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,27 +1,12 @@ /target - -mail.toml -mail.test.toml -web.toml -web.test.toml -db.toml -db.test.toml -fs.toml -fs.test.toml -highlight.toml -highlight.test.toml - -pkg -bitque-client/pkg -bitque-client/tmp -bitque-client/build +/crates/bitque-client/pkg +/crates/bitque-client/tmp +/crates/bitque-client/build +/crates/bitque-server/target +/crates/bitque-cli/target +/crates/bitque-bat/bat +/crates/highlight/bitque-highlight/build +/crates/bitque-client/src/location.rs +/uploads +/config tmp -bitque-server/target -bitque-cli/target -bitque-bat/bat - -highlight/bitque-highlight/build -uploads -config -shared/bitque-config/target -bitque-client/src/location.rs diff --git a/Cargo.lock b/Cargo.lock index f9865a2b..098209e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -234,7 +234,7 @@ dependencies = [ "ahash 0.7.6", "bytes", "bytestring", - "cfg-if", + "cfg-if 1.0.0", "cookie", "derive_more", "encoding_rs", @@ -321,7 +321,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "getrandom", "once_cell", "version_check 0.9.4", @@ -400,6 +400,12 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "anymap2" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" + [[package]] name = "ascii_utils" version = "0.9.3" @@ -601,6 +607,7 @@ version = "0.1.0" dependencies = [ "actix", "chrono", + "derive_enum_primitive", "diesel 2.0.3", "diesel-derive-enum 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "diesel-derive-more", @@ -611,6 +618,35 @@ dependencies = [ "uuid 1.3.0", ] +[[package]] +name = "bitque_client" +version = "0.1.0" +dependencies = [ + "bincode", + "bitque-data", + "chrono", + "console_error_panic_hook", + "derive_enum_iter", + "derive_enum_primitive", + "dotenv", + "futures", + "js-sys", + "seed", + "serde", + "serde_json", + "strum", + "tracing", + "tracing-subscriber", + "tracing-subscriber-wasm", + "uuid 1.3.0", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "wasm-sockets", + "web-sys", + "wee_alloc", +] + [[package]] name = "bitquec" version = "0.1.0" @@ -693,6 +729,12 @@ dependencies = [ "jobserver", ] +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" @@ -825,6 +867,16 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -873,7 +925,7 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -882,7 +934,7 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-utils", ] @@ -892,7 +944,7 @@ version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -1042,6 +1094,15 @@ dependencies = [ "uuid 1.3.0", ] +[[package]] +name = "dbg" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4677188513e0e9d7adced5997cf9a1e7a3c996c994f90093325c5332c1a8b221" +dependencies = [ + "version_check 0.1.5", +] + [[package]] name = "derive_db_execute" version = "0.1.0" @@ -1250,6 +1311,12 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112" +[[package]] +name = "enclose" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1056f553da426e9c025a662efa48b52e62e0a3a7648aa2d15aeaaf7f0d329357" + [[package]] name = "encoding" version = "0.2.33" @@ -1320,7 +1387,7 @@ version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -1552,9 +1619,179 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", + "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "gloo" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a4bef6b277b3ab073253d4bca60761240cf8d6998f4bd142211957b69a61b20" +dependencies = [ + "gloo-console", + "gloo-dialogs", + "gloo-events", + "gloo-file", + "gloo-history", + "gloo-net", + "gloo-render", + "gloo-storage", + "gloo-timers", + "gloo-utils", + "gloo-worker", +] + +[[package]] +name = "gloo-console" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b7ce3c05debe147233596904981848862b068862e9ec3e34be446077190d3f" +dependencies = [ + "gloo-utils", + "js-sys", + "serde", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-dialogs" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67062364ac72d27f08445a46cab428188e2e224ec9e37efdba48ae8c289002e6" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-events" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b107f8abed8105e4182de63845afcc7b69c098b7852a813ea7462a320992fc" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-file" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d5564e570a38b43d78bdc063374a0c3098c4f0d64005b12f9bbe87e869b6d7" +dependencies = [ + "futures-channel", + "gloo-events", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-history" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd451019e0b7a2b8a7a7b23e74916601abf1135c54664e57ff71dcc26dfcdeb7" +dependencies = [ + "gloo-events", + "gloo-utils", + "serde", + "serde-wasm-bindgen", + "serde_urlencoded", + "thiserror", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-net" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9902a044653b26b99f7e3693a42f171312d9be8b26b5697bd1e43ad1f8a35e10" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-render" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd9306aef67cfd4449823aadcd14e3958e0800aa2183955a309112a84ec7764" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-storage" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6ab60bf5dbfd6f0ed1f7843da31b41010515c745735c970e821945ca91e480" +dependencies = [ + "gloo-utils", + "js-sys", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-utils" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8e8fc851e9c7b9852508bc6e3f690f452f474417e8545ec9857b7f7377036b5" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-worker" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13471584da78061a28306d1359dd0178d8d6fc1c7c80e5e35d27260346e0516a" +dependencies = [ + "anymap2", + "bincode", + "gloo-console", + "gloo-utils", + "js-sys", + "serde", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", ] [[package]] @@ -1781,7 +2018,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -1981,7 +2218,7 @@ version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -2040,6 +2277,12 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + [[package]] name = "mime" version = "0.3.17" @@ -2211,7 +2454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2" dependencies = [ "bitflags 1.3.2", - "cfg-if", + "cfg-if 1.0.0", "foreign-types", "libc", "once_cell", @@ -2291,7 +2534,7 @@ version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "redox_syscall 0.2.16", "smallvec", @@ -2316,6 +2559,26 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2 1.0.54", + "quote 1.0.26", + "syn 1.0.109", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -2734,7 +2997,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "ordered-multimap", ] @@ -2748,7 +3011,7 @@ dependencies = [ "aws-creds", "aws-region", "base64 0.13.1", - "cfg-if", + "cfg-if 1.0.0", "hex", "hmac", "http", @@ -2870,6 +3133,12 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.1.0" @@ -2905,6 +3174,34 @@ dependencies = [ "libc", ] +[[package]] +name = "seed" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9352d75dd253803ce05722fe3acaafffc461d4faeaf0ebe0d8bf831059482e21" +dependencies = [ + "console_error_panic_hook", + "cookie", + "dbg", + "enclose", + "futures", + "getrandom", + "gloo-file", + "gloo-timers", + "gloo-utils", + "indexmap", + "js-sys", + "rand 0.8.5", + "serde", + "serde-wasm-bindgen", + "serde_json", + "uuid 1.3.0", + "version_check 0.9.4", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "semver" version = "1.0.17" @@ -2920,6 +3217,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde-xml-rs" version = "0.5.1" @@ -2990,7 +3298,7 @@ version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "digest", ] @@ -3007,7 +3315,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "digest", ] @@ -3110,6 +3418,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "static_assertions" version = "1.1.0" @@ -3224,7 +3538,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "fastrand", "redox_syscall 0.3.5", "rustix 0.37.5", @@ -3300,7 +3614,7 @@ version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "once_cell", ] @@ -3468,7 +3782,7 @@ version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "log", "pin-project-lite", "tracing-attributes", @@ -3526,6 +3840,17 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "tracing-subscriber-wasm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79804e80980173c6c8e53d98508eb24a2dbc4ee17a3e8d2ca8e5bad6bf13a898" +dependencies = [ + "gloo", + "tracing", + "tracing-subscriber", +] + [[package]] name = "triple_accel" version = "0.3.4" @@ -3717,7 +4042,9 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", + "serde", + "serde_json", "wasm-bindgen-macro", ] @@ -3742,7 +4069,7 @@ version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "js-sys", "wasm-bindgen", "web-sys", @@ -3777,6 +4104,43 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +[[package]] +name = "wasm-bindgen-test" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db36fc0f9fb209e88fb3642590ae0205bb5a56216dabd963ba15879fe53a30b" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0734759ae6b3b1717d661fe4f016efcfb9828f5edb4520c18eaee05af3b43be9" +dependencies = [ + "proc-macro2 1.0.54", + "quote 1.0.26", +] + +[[package]] +name = "wasm-sockets" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d14bbe65995269301ab677e5d69b3b69195447c01137ef44f72b10eecea55c77" +dependencies = [ + "js-sys", + "log", + "thiserror", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-streams" version = "0.2.3" @@ -3854,6 +4218,19 @@ dependencies = [ "uuid 1.3.0", ] +[[package]] +name = "wee_alloc" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "memory_units", + "spin", + "winapi", +] + [[package]] name = "wildmatch" version = "2.1.1" diff --git a/Cargo.toml b/Cargo.toml index 5a4414ca..61582504 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ members = [ "./crates/cloud-storage-actor", "./crates/filesystem-actor", # Client -# "./crates/web" + "./crates/web" ] exclude = [ "crates/bitque-cli", diff --git a/Dockerfile.build b/Dockerfile.build deleted file mode 100644 index 8e3cc6c3..00000000 --- a/Dockerfile.build +++ /dev/null @@ -1,15 +0,0 @@ -FROM ubuntu:18.04 - -WORKDIR /app/ - -RUN apt-get update && apt-get install -y curl git openssl libpq-dev gcc openssl1.0 make cmake -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain nightly -y -RUN . $HOME/.cargo/env && \ - rustup toolchain install nightly && rustup default nightly - -RUN ls -al /app -CMD . $HOME/.cargo/env && \ - cd ./bitque-server && \ - rm -Rf ./target/debug/bitque_server && \ - cargo build --bin bitque_server --release --no-default-features --features local-storage && \ - cp /app/target/release/bitque_server /app/build/ diff --git a/crates/bitque-config/Cargo.toml b/crates/bitque-config/Cargo.toml index c676d284..514a6f86 100644 --- a/crates/bitque-config/Cargo.toml +++ b/crates/bitque-config/Cargo.toml @@ -13,12 +13,12 @@ name = "bitque_config" path = "./src/lib.rs" [features] -aws-s3 = ["rust-s3"] +cloud-storage = ["rust-s3"] local-storage = [] database = [] hi = [] mail = [] -web = ["aws-s3", "local-storage"] +web = ["cloud-storage", "local-storage"] websocket = [] default = ["local-storage", "database", "hi", "mail", "web", "websocket"] diff --git a/crates/bitque-config/src/amazon.rs b/crates/bitque-config/src/cloud_storage.rs similarity index 100% rename from crates/bitque-config/src/amazon.rs rename to crates/bitque-config/src/cloud_storage.rs diff --git a/crates/bitque-config/src/lib.rs b/crates/bitque-config/src/lib.rs index e2af2d56..d0790e03 100644 --- a/crates/bitque-config/src/lib.rs +++ b/crates/bitque-config/src/lib.rs @@ -1,5 +1,5 @@ -#[cfg(feature = "aws-s3")] -pub mod amazon; +#[cfg(feature = "cloud-storage")] +pub mod cloud_storage; #[cfg(feature = "database")] pub mod database; diff --git a/crates/bitque-data/Cargo.toml b/crates/bitque-data/Cargo.toml index ffe9c934..031c7a84 100644 --- a/crates/bitque-data/Cargo.toml +++ b/crates/bitque-data/Cargo.toml @@ -14,13 +14,14 @@ path = "./src/lib.rs" [features] backend = ["diesel", "actix", "diesel-derive-newtype"] -frontend = [] +frontend = ['derive_enum_primitive'] [dependencies] actix = { version = "0.13.0", optional = true } chrono = { version = "*", features = ["serde"] } diesel = { version = "2.0.3", features = ["postgres", "numeric", "uuid", "r2d2"], optional = true } diesel-derive-enum = { version = "2.0.1", features = ["postgres"] } +derive_enum_primitive = { workspace = true, optional = true } #diesel-derive-enum = { path = "../derive_enum_sql", features = ["postgres"] } diesel-derive-more = { version = "1.1.3" } diesel-derive-newtype = { version = "2.0.0-rc.0", optional = true } diff --git a/crates/bitque-data/src/lib.rs b/crates/bitque-data/src/lib.rs index b974f9a4..46ac7e60 100644 --- a/crates/bitque-data/src/lib.rs +++ b/crates/bitque-data/src/lib.rs @@ -1,6 +1,7 @@ use std::cmp::Ordering; use chrono::NaiveDateTime; +use derive_enum_primitive::*; #[cfg(feature = "backend")] use diesel::*; #[cfg(feature = "backend")] @@ -55,10 +56,14 @@ pub type EndsAt = NaiveDateTime; Clone, Copy, Debug, + Default, Deserialize, Display, + EnumAsStr, EnumIter, + EnumLabel, EnumString, + EnumU32, Hash, IntoStaticStr, PartialEq, @@ -66,27 +71,27 @@ pub type EndsAt = NaiveDateTime; Serialize, )] #[strum(serialize_all = "snake_case")] +#[cfg_attr(feature = "backend", PgType = "IssueTypeMapping")] pub enum IssueType { + #[default] Task, Bug, Story, } -impl Default for IssueType { - fn default() -> Self { - IssueType::Task - } -} - #[cfg_attr(feature = "backend", derive(DbEnum))] #[derive( Clone, Copy, Debug, + Default, Deserialize, Display, + EnumAsStr, EnumIter, + EnumLabel, EnumString, + EnumU32, Hash, IntoStaticStr, PartialEq, @@ -94,36 +99,38 @@ impl Default for IssueType { Serialize, )] #[strum(serialize_all = "snake_case")] +#[cfg_attr(feature = "backend", PgType = "IssuePriorityMapping")] pub enum IssuePriority { Highest, High, + #[default] Medium, Low, Lowest, } -impl Default for IssuePriority { - fn default() -> Self { - IssuePriority::Medium - } -} - #[cfg_attr(feature = "backend", derive(DbEnum))] #[derive( Clone, Copy, Debug, + Default, Deserialize, Display, + EnumAsStr, EnumIter, + EnumLabel, EnumString, + EnumU32, Hash, IntoStaticStr, PartialEq, Serialize, )] #[strum(serialize_all = "snake_case")] +#[cfg_attr(feature = "backend", PgType = "UserRoleMapping")] pub enum UserRole { + #[default] User, Manager, Owner, @@ -144,22 +151,20 @@ impl PartialOrd for UserRole { } } -impl Default for UserRole { - fn default() -> Self { - UserRole::User - } -} - #[cfg_attr(feature = "backend", derive(DbEnum))] #[cfg_attr(feature = "backend", PgType = "ProjectCategoryMapping")] #[derive( Clone, Copy, Debug, + Default, Deserialize, Display, + EnumAsStr, EnumIter, + EnumLabel, EnumString, + EnumU32, Hash, IntoStaticStr, PartialEq, @@ -167,28 +172,27 @@ impl Default for UserRole { Serialize, )] #[strum(serialize_all = "snake_case")] +#[cfg_attr(feature = "backend", PgType = "ProjectCategoryMapping")] pub enum ProjectCategory { + #[default] Software, Marketing, Business, } -impl Default for ProjectCategory { - fn default() -> Self { - ProjectCategory::Software - } -} - #[cfg_attr(feature = "backend", derive(DbEnum))] #[cfg_attr(feature = "backend", PgType = "InvitationStateMapping")] #[derive( Clone, Copy, Debug, + Default, Deserialize, Display, + EnumAsStr, EnumIter, EnumString, + EnumU32, Hash, IntoStaticStr, PartialEq, @@ -196,28 +200,28 @@ impl Default for ProjectCategory { Serialize, )] #[strum(serialize_all = "snake_case")] +#[cfg_attr(feature = "backend", PgType = "InvitationStateMapping")] pub enum InvitationState { + #[default] Sent, Accepted, Revoked, } -impl Default for InvitationState { - fn default() -> Self { - InvitationState::Sent - } -} - #[cfg_attr(feature = "backend", derive(DbEnum))] #[cfg_attr(feature = "backend", PgType = "TimeTrackingMapping")] #[derive( Clone, Copy, Debug, + Default, Deserialize, Display, + EnumAsStr, EnumIter, + EnumLabel, EnumString, + EnumU32, Hash, IntoStaticStr, PartialEq, @@ -225,18 +229,14 @@ impl Default for InvitationState { Serialize, )] #[strum(serialize_all = "snake_case")] +#[cfg_attr(feature = "backend", PgType = "TimeTrackingMapping")] pub enum TimeTracking { + #[default] Untracked, Fibonacci, Hourly, } -impl Default for TimeTracking { - fn default() -> Self { - Self::Untracked - } -} - #[derive(Clone, Debug, PartialEq, Serialize)] pub struct ErrorResponse { pub errors: Vec, @@ -386,9 +386,13 @@ pub struct IssueAssignee { Clone, Copy, Debug, + Default, Deserialize, Display, + EnumAsStr, + EnumLabel, EnumString, + EnumU32, Hash, IntoStaticStr, PartialEq, @@ -396,18 +400,14 @@ pub struct IssueAssignee { Serialize, )] #[strum(serialize_all = "snake_case")] +#[cfg_attr(feature = "backend", PgType = "MessageTypeMapping")] pub enum MessageType { ReceivedInvitation, AssignedToIssue, + #[default] Mention, } -impl Default for MessageType { - fn default() -> Self { - Self::Mention - } -} - #[cfg_attr(feature = "backend", derive(Queryable))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Message { @@ -475,10 +475,14 @@ pub struct HighlightedCode { Clone, Copy, Debug, + Default, Deserialize, Display, + EnumAsStr, EnumIter, + EnumLabel, EnumString, + EnumU32, Hash, IntoStaticStr, PartialEq, @@ -488,18 +492,14 @@ pub struct HighlightedCode { #[strum(serialize_all = "snake_case")] #[cfg_attr(feature = "backend", PgType = "TextEditorModeMapping")] #[repr(C)] +#[cfg_attr(feature = "backend", PgType = "TextEditorModeMapping")] pub enum TextEditorMode { + #[default] MdOnly, RteOnly, Mixed, } -impl Default for TextEditorMode { - fn default() -> Self { - TextEditorMode::MdOnly - } -} - #[cfg_attr(feature = "backend", derive(Queryable))] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct UserSetting { diff --git a/crates/bitque-server/Cargo.toml b/crates/bitque-server/Cargo.toml index 3de9ac01..6a422aba 100644 --- a/crates/bitque-server/Cargo.toml +++ b/crates/bitque-server/Cargo.toml @@ -9,7 +9,7 @@ license = "MPL-2.0" #license-file = "../LICENSE" [features] -aws-s3 = ["cloud-storage-actor"] +cloud-storage = ["cloud-storage-actor"] local-storage = ["filesystem-actor"] default = ["local-storage"] diff --git a/crates/bitque-server/src/main.rs b/crates/bitque-server/src/main.rs index 7659d958..da80b9e3 100644 --- a/crates/bitque-server/src/main.rs +++ b/crates/bitque-server/src/main.rs @@ -2,7 +2,9 @@ #![recursion_limit = "256"] use actix::Actor; +use actix_web::web::Data; use actix_web::{App, HttpServer}; +use tracing::info; use tracing_subscriber::util::SubscriberInitExt; pub mod errors; @@ -39,28 +41,30 @@ async fn main() -> Result<(), String> { #[cfg(feature = "local-storage")] let fs_addr = actix::SyncArbiter::start( bitque_config::fs::Configuration::read().concurrency, - filesystem_actor::FileSystemExecutor::default, + filesystem_actor::LocalStorageExecutor::default, ); - #[cfg(feature = "aws-s3")] - let amazon_addr = actix::SyncArbiter::start( + #[cfg(feature = "cloud-storage")] + let cloud_storage_addr = actix::SyncArbiter::start( bitque_config::web::Configuration::read().concurrency, - amazon_actor::AmazonExecutor::default, + cloud_storage_actor::CloudStorageExecutor::default, ); let ws_server = websocket_actor::server::WsServer::start_default(); + info!("Listen at {}", web_config.bind_addr()); + HttpServer::new(move || { let app = App::new().wrap(actix_web::middleware::Logger::default()); // data step let app = app - .app_data(ws_server.clone()) - .app_data(db_addr.clone()) - .app_data(mail_addr.clone()) - .app_data(hi_addr.clone()) - .app_data(database_actor::build_pool()); - featured! { app, "local-storage", app.app_data(fs_addr.clone()) }; - featured! { app, "aws-s3", app.data(amazon_addr.clone()) }; + .app_data(Data::new(ws_server.clone())) + .app_data(Data::new(db_addr.clone())) + .app_data(Data::new(mail_addr.clone())) + .app_data(Data::new(hi_addr.clone())) + .app_data(Data::new(database_actor::build_pool())); + featured! { app, "local-storage", app.app_data(Data::new(fs_addr.clone())) }; + featured! { app, "cloud-storage", app.app_data(Data::new(cloud_storage_addr.clone())) }; // services step let app = app diff --git a/crates/cloud-storage-actor/src/lib.rs b/crates/cloud-storage-actor/src/lib.rs index 09264dde..94a25d5c 100644 --- a/crates/cloud-storage-actor/src/lib.rs +++ b/crates/cloud-storage-actor/src/lib.rs @@ -14,15 +14,15 @@ pub enum AmazonError { Credentials, } -pub struct AmazonExecutor; +pub struct CloudStorageExecutor; -impl Default for AmazonExecutor { +impl Default for CloudStorageExecutor { fn default() -> Self { Self {} } } -impl actix::Actor for AmazonExecutor { +impl actix::Actor for CloudStorageExecutor { type Context = actix::SyncContext; } @@ -33,7 +33,7 @@ pub struct S3PutObject { pub file_name: String, } -impl actix::Handler for AmazonExecutor { +impl actix::Handler for CloudStorageExecutor { type Result = Result; fn handle(&mut self, msg: S3PutObject, _ctx: &mut Self::Context) -> Self::Result { @@ -42,12 +42,12 @@ impl actix::Handler for AmazonExecutor { mut source, file_name, } = msg; - bitque_config::amazon::config().set_variables(); + bitque_config::cloud_storage::config().set_variables(); tokio::runtime::Runtime::new() .expect("Failed to start amazon agent") .block_on(async { - let s3 = bitque_config::amazon::config(); + let s3 = bitque_config::cloud_storage::config(); tracing::debug!("{:?}", s3); let mut v: Vec = Vec::with_capacity(1024 * 1024 * 16); @@ -55,7 +55,7 @@ impl actix::Handler for AmazonExecutor { v.extend_from_slice(&b) } - let config = bitque_config::amazon::config(); + let config = bitque_config::cloud_storage::config(); let bucket = s3::Bucket::new( config.bucket.as_str(), Region::from_str(config.region_name.as_str()).unwrap(), diff --git a/crates/database-actor/src/issues.rs b/crates/database-actor/src/issues.rs index f1cc4c1e..560a7c6f 100644 --- a/crates/database-actor/src/issues.rs +++ b/crates/database-actor/src/issues.rs @@ -4,7 +4,7 @@ use diesel::prelude::*; use crate::models::Issue; -#[derive(derive_db_execute::Execute, Default)] +#[derive(Default, derive_db_execute::Execute)] #[db_exec( result = "Issue", schema = "issues", @@ -24,7 +24,7 @@ pub struct LoadProjectIssues { pub project_id: ProjectId, } -#[derive(derive_db_execute::Execute, Default)] +#[derive(Default, derive_db_execute::Execute)] #[db_exec(result = "Issue", schema = "issues")] pub struct UpdateIssue { pub issue_id: bitque_data::IssueId, diff --git a/crates/derive_enum_primitive/src/lib.rs b/crates/derive_enum_primitive/src/lib.rs index 1fc7fdf8..d7b342b1 100644 --- a/crates/derive_enum_primitive/src/lib.rs +++ b/crates/derive_enum_primitive/src/lib.rs @@ -2,12 +2,11 @@ extern crate proc_macro; use proc_macro::{TokenStream, TokenTree}; -fn into_str(name: &str, variants: &[String]) -> String { +fn as_str(name: &str, variants: &[String]) -> String { let mut code = format!( r#" -#[cfg(feature = "frontend")] impl {name} {{ - pub fn to_str(&self) -> &'static str {{ + pub fn as_str(&self) -> &'static str {{ match self {{ "#, name = name, @@ -32,8 +31,7 @@ impl {name} {{ fn from_str(name: &str, variants: &[String]) -> String { let mut code = format!( r#" -#[cfg(feature = "frontend")] -impl FromStr for {name} {{ +impl std::str::FromStr for {name} {{ type Err = String; fn from_str(s: &str) -> Result {{ match s {{ @@ -68,7 +66,6 @@ impl FromStr for {name} {{ fn into_label(name: &str, variants: &[String]) -> String { let mut code = format!( r#" -#[cfg(feature = "frontend")] impl {name} {{ pub fn to_label(&self) -> &'static str {{ match self {{ @@ -139,16 +136,128 @@ impl Into<{name}> for u32 {{ code } -#[proc_macro_derive(EnumPrimitive)] -pub fn derive_enum_primitive(item: TokenStream) -> TokenStream { +#[proc_macro_derive(EnumU32)] +pub fn derive_enum_u32(item: TokenStream) -> TokenStream { let mut it = item.into_iter().peekable(); + while let Some(token) = it.peek() { - if let TokenTree::Ident(_) = token { - break; - } else { - it.next(); + match token { + TokenTree::Ident(_) => { + break; + } + _ => { + it.next(); + } } } + + if let Some(TokenTree::Ident(ident)) = it.next() { + if ident.to_string().as_str() != "pub" { + panic!("Expect to find keyword pub but was found {:?}", ident) + } + } else { + panic!("Expect to find keyword pub but nothing was found") + } + if let Some(TokenTree::Ident(ident)) = it.next() { + if ident.to_string().as_str() != "enum" { + panic!("Expect to find keyword struct but was found {:?}", ident) + } + } else { + panic!("Expect to find keyword struct but nothing was found") + } + let name = it + .next() + .expect("Expect to struct name but nothing was found") + .to_string(); + + let mut variants = vec![]; + if let Some(TokenTree::Group(group)) = it.next() { + for token in group.stream() { + if let TokenTree::Ident(ident) = token { + variants.push(ident.to_string()) + } + } + } else { + panic!("Enum variants group expected"); + } + if variants.is_empty() { + panic!("Enum cannot be empty") + } + + let mut code = String::new(); + code.push_str(into_u32(&name, &variants).as_str()); + code.push_str(from_u32(&name, &variants).as_str()); + code.parse().unwrap() +} + +#[proc_macro_derive(EnumLabel)] +pub fn derive_enum_label(item: TokenStream) -> TokenStream { + let mut it = item.into_iter().peekable(); + + while let Some(token) = it.peek() { + match token { + TokenTree::Ident(_) => { + break; + } + _ => { + it.next(); + } + } + } + + if let Some(TokenTree::Ident(ident)) = it.next() { + if ident.to_string().as_str() != "pub" { + panic!("Expect to find keyword pub but was found {:?}", ident) + } + } else { + panic!("Expect to find keyword pub but nothing was found") + } + if let Some(TokenTree::Ident(ident)) = it.next() { + if ident.to_string().as_str() != "enum" { + panic!("Expect to find keyword struct but was found {:?}", ident) + } + } else { + panic!("Expect to find keyword struct but nothing was found") + } + let name = it + .next() + .expect("Expect to struct name but nothing was found") + .to_string(); + + let mut variants = vec![]; + if let Some(TokenTree::Group(group)) = it.next() { + for token in group.stream() { + if let TokenTree::Ident(ident) = token { + variants.push(ident.to_string()) + } + } + } else { + panic!("Enum variants group expected"); + } + if variants.is_empty() { + panic!("Enum cannot be empty") + } + + let mut code = String::new(); + code.push_str(into_label(&name, &variants).as_str()); + code.parse().unwrap() +} + +#[proc_macro_derive(EnumStr)] +pub fn derive_enum_str(item: TokenStream) -> TokenStream { + let mut it = item.into_iter().peekable(); + + while let Some(token) = it.peek() { + match token { + TokenTree::Ident(_) => { + break; + } + _ => { + it.next(); + } + } + } + if let Some(TokenTree::Ident(ident)) = it.next() { if ident.to_string().as_str() != "pub" { panic!("Expect to find keyword pub but was found {:?}", ident) @@ -185,10 +294,61 @@ pub fn derive_enum_primitive(item: TokenStream) -> TokenStream { let mut code = String::new(); code.push_str(from_str(&name, &variants).as_str()); - code.push_str(into_str(&name, &variants).as_str()); - code.push_str(into_label(&name, &variants).as_str()); - code.push_str(into_u32(&name, &variants).as_str()); - code.push_str(from_u32(&name, &variants).as_str()); + + code.parse().unwrap() +} + +#[proc_macro_derive(EnumAsStr)] +pub fn derive_enum_as_str(item: TokenStream) -> TokenStream { + let mut it = item.into_iter().peekable(); + + while let Some(token) = it.peek() { + match token { + TokenTree::Ident(_) => { + break; + } + _ => { + it.next(); + } + } + } + + if let Some(TokenTree::Ident(ident)) = it.next() { + if ident.to_string().as_str() != "pub" { + panic!("Expect to find keyword pub but was found {:?}", ident) + } + } else { + panic!("Expect to find keyword pub but nothing was found") + } + if let Some(TokenTree::Ident(ident)) = it.next() { + if ident.to_string().as_str() != "enum" { + panic!("Expect to find keyword struct but was found {:?}", ident) + } + } else { + panic!("Expect to find keyword struct but nothing was found") + } + let name = it + .next() + .expect("Expect to struct name but nothing was found") + .to_string(); + + let mut variants = vec![]; + if let Some(TokenTree::Group(group)) = it.next() { + for token in group.stream() { + if let TokenTree::Ident(ident) = token { + variants.push(ident.to_string()) + } + } + } else { + panic!("Enum variants group expected"); + } + if variants.is_empty() { + panic!("Enum cannot be empty") + } + + let mut code = String::new(); + + code.push_str(as_str(&name, &variants).as_str()); code.parse().unwrap() } diff --git a/crates/derive_enum_sql/src/lib.rs b/crates/derive_enum_sql/src/lib.rs index b305ed4b..ae06ba8d 100644 --- a/crates/derive_enum_sql/src/lib.rs +++ b/crates/derive_enum_sql/src/lib.rs @@ -113,7 +113,7 @@ fn val_from_attrs(attrs: &[Attribute], attr_name: &str) -> Option { /// Defines the casing for the database representation. Follows serde naming /// convention. -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] enum CaseStyle { Camel, Kebab, diff --git a/crates/filesystem-actor/src/lib.rs b/crates/filesystem-actor/src/lib.rs index cff62ea1..e47237d4 100644 --- a/crates/filesystem-actor/src/lib.rs +++ b/crates/filesystem-actor/src/lib.rs @@ -13,11 +13,11 @@ pub enum FsError { WriteFile, } -pub struct FileSystemExecutor { +pub struct LocalStorageExecutor { config: Configuration, } -impl FileSystemExecutor { +impl LocalStorageExecutor { pub fn client_path(&self) -> &str { self.config.client_path.as_str() } @@ -27,7 +27,7 @@ impl FileSystemExecutor { } } -impl Default for FileSystemExecutor { +impl Default for LocalStorageExecutor { fn default() -> Self { Self { config: Configuration::read(), @@ -35,7 +35,7 @@ impl Default for FileSystemExecutor { } } -impl actix::Actor for FileSystemExecutor { +impl actix::Actor for LocalStorageExecutor { type Context = SyncContext; } @@ -46,7 +46,7 @@ pub struct CreateFile { pub file_name: String, } -impl actix::Handler for FileSystemExecutor { +impl actix::Handler for LocalStorageExecutor { type Result = Result; fn handle(&mut self, msg: CreateFile, _ctx: &mut Self::Context) -> Self::Result { diff --git a/crates/highlight-actor/assets/InspiredGitHub.tmTheme b/crates/highlight-actor/assets/InspiredGitHub.tmTheme new file mode 100644 index 00000000..f88e8665 --- /dev/null +++ b/crates/highlight-actor/assets/InspiredGitHub.tmTheme @@ -0,0 +1,1725 @@ + + + + + + name + GitHub + settings + + + + + settings + + + background + #ffffff + foreground + #323232 + invisibles + #000000 + caret + #323232 + + + gutter + #ffffff + gutterForeground + #b3b3b3 + + + guide + #e8e8e8 + stackGuide + #e8e8e8 + activeGuide + #b3b3b3 + + + lineHighlight + #f5f5f5 + findHighlight + #f8eec7 + findHighlightForeground + #323232 + selection + #f8eec7 + selectionBorder + #ffffff + + + bracketsForeground + #63a35c + bracketsOptions + underline + bracketContentsForeground + #63a35c + bracketContentsOptions + underline + + + tagsForeground + #63a35c + tagsOptions + underline + + + + + + name + Comment + scope + comment + settings + + foreground + #969896 + fontStyle + italic + + + + + + name + String + scope + string + settings + + foreground + #183691 + + + + + + name + RegExp Operator + scope + regexp-operator + settings + + foreground + #a71d5d + + + + + + name + RegExp Character Class + scope + string.regexp.characterclass punctuation.definition.string.begin, string.regexp.characterclass punctuation.definition.string.end + settings + + foreground + #a71d5d + + + + + + name + Number + scope + constant.numeric + settings + + foreground + #0086b3 + + + + + + name + Built-in Constant + scope + constant.language + settings + + foreground + #0086b3 + + + + + + name + User-defined Constant + scope + constant.character, constant.other, variable.other.constant + settings + + foreground + #0086b3 + + + + + + name + Variable + scope + variable + settings + + foreground + #323232 + + + + + + name + Keyword + scope + keyword + settings + + foreground + #a71d5d + fontStyle + bold + + + + + + name + Bitwise + scope + bitwise-operator + settings + + foreground + #a71d5d + fontStyle + bold + + + + + + name + Storage + scope + storage + settings + + foreground + #a71d5d + fontStyle + bold + + + + + + name + Storage Type + scope + storage.type + settings + + foreground + #a71d5d + fontStyle + bold + + + + + + name + Class Name + scope + entity.name.class + settings + + foreground + #0086b3 + + + + + + name + Inherited Class + scope + entity.other.inherited-class + settings + + foreground + #0086b3 + + + + + + name + Function Name + scope + entity.name.function + settings + + foreground + #795da3 + fontStyle + bold + + + + + + name + Function Argument + scope + variable.parameter + settings + + foreground + #323232 + + + + + + name + Tag Name + scope + entity.name.tag + settings + + foreground + #63a35c + + + + + + name + Tag Attribute + scope + entity.other.attribute-name + settings + + foreground + #795da3 + + + + + + name + Library Function + scope + support.function + settings + + foreground + #62a35c + + + + + + name + Library Constant + scope + support.constant + settings + + foreground + #0086b3 + + + + + + name + Library Class + scope + support.type, support.class + settings + + foreground + #0086b3 + + + + + + name + Library Variable + scope + support.other.variable + settings + + foreground + #323232 + + + + + + name + Invalid + scope + invalid, invalid.illegal, invalid.deprecated + settings + + background + #f5f5f5 + foreground + #b52a1d + fontStyle + bold + + + + + + + + + name + Find-in-files Filename + scope + entity.name.filename.find-in-files + settings + + foreground + #323232 + fontStyle + bold + + + + name + Find-in-files Line Numbers + scope + constant.numeric.line-number.find-in-files, constant.numeric.line-number.match.find-in-files + settings + + foreground + #b3b3b3 + + + + + + + + + + name + Diff Header + scope + meta.diff.header + settings + + foreground + #969896 + background + #ffffff + fontStyle + italic + + + + + name + Diff Header + scope + meta.diff.header punctuation.definition.from-file.diff + settings + + foreground + #bd2c00 + background + #ffecec + fontStyle + italic bold + + + + + name + Diff Header + scope + meta.diff.header punctuation.definition.to-file.diff + settings + + foreground + #55a532 + background + #eaffea + fontStyle + italic bold + + + + + name + Diff Range + scope + meta.diff.range + settings + + foreground + #969896 + fontStyle + italic bold + + + + + name + Diff Deleted + scope + markup.deleted + settings + + background + #ffecec + + + + + name + Diff Deleted Punctuation + scope + markup.deleted punctuation.definition.inserted + settings + + foreground + #bd2c00 + fontStyle + bold + + + + + name + Diff Inserted + scope + markup.inserted + settings + + background + #eaffea + + + + + name + Diff Inserted Punctuation + scope + markup.inserted punctuation.definition.inserted + settings + + foreground + #55a532 + fontStyle + bold + + + + + + + + + + name + GitGutter Deleted + scope + markup.deleted.git_gutter + settings + + foreground + #bd2c00 + + + + + name + GitGutter Inserted + scope + markup.inserted.git_gutter + settings + + foreground + #55a532 + + + + + name + GitGutter Modified + scope + markup.changed.git_gutter + settings + + foreground + #0086B3 + + + + + name + GitGutter Ignored + scope + markup.ignored.git_gutter + settings + + foreground + #b3b3b3 + + + + + name + GitGutter Untracked + scope + markup.untracked.git_gutter + settings + + foreground + #b3b3b3 + + + + + + + + + + name + Entity Punctuation + scope + source.css punctuation.definition.entity + settings + + foreground + #323232 + + + + + name + Pseudo Selector + scope + source.css entity.other.attribute-name.pseudo-class, source.css entity.other.attribute-name.pseudo-element + settings + + foreground + #a71d5d + + + + + name + Property Value + scope + source.css meta.value, source.css support.constant, source.css support.function + settings + + foreground + #323232 + + + + + name + Color + scope + source.css constant.other.color + settings + + foreground + #ed6a43 + + + + + + + + + + name + Entity Punctuation + scope + source.scss punctuation.definition.entity + settings + + foreground + #323232 + + + + + name + Pseudo Selector + scope + source.scss entity.other.attribute-name.pseudo-class, source.scss entity.other.attribute-name.pseudo-element + settings + + foreground + #a71d5d + + + + + name + Color + scope + source.scss support.constant.property-value, source.scss support.function + settings + + foreground + #323232 + + + + + name + Variable + scope + source.scss variable + settings + + foreground + #a71d5d + + + + + + + + + + name + this + scope + variable.language.this.js + settings + + foreground + #ed6a43 + + + + + name + Function + scope + source.js entity.name.function + settings + + foreground + #323232 + fontStyle + regular + + + + + name + Function Definition + scope + source.js meta.function entity.name.function, source.js entity.name.function meta.function + settings + + foreground + #795da3 + fontStyle + bold + + + + + name + New Function + scope + entity.name.type.new.js + settings + + foreground + #795da3 + + + + + name + Function Prototype + scope + variable.language.prototype.js + settings + + foreground + #0086b3 + + + + + name + Support Function + scope + source.js support.function + settings + + foreground + #0086b3 + + + + + name + Function Prototype + scope + support.type.object.console.js + settings + + foreground + #795da3 + + + + + + + + + + name + JSON Property - 20 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 20 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 19 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 19 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 18 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 18 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 17 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 17 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 16 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 16 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 15 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 15 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 14 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 14 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 13 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 13 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 12 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 12 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 11 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 11 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 10 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 10 Deep + scope + meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 9 Deep + scope + meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 9 Deep + scope + meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 8 Deep + scope + meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 8 Deep + scope + meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 7 Deep + scope + meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 7 Deep + scope + meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 6 Deep + scope + meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 6 Deep + scope + meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 5 Deep + scope + meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 5 Deep + scope + meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 4 Deep + scope + meta meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 4 Deep + scope + meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 3 Deep + scope + meta meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 3 Deep + scope + meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 2 Deep + scope + meta meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 2 Deep + scope + meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property - 1 Deep + scope + meta meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value - 1 Deep + scope + meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + name + JSON Property + scope + meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #183691 + fontStyle + bold + + + + name + JSON Value + scope + meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json + settings + + foreground + #323232 + fontStyle + regular + + + + + + + + + + name + Keyword + scope + source.python keyword + settings + + fontStyle + bold + + + + + name + Storage + scope + source.python storage + settings + + fontStyle + bold + + + + + name + Storage Type + scope + source.python storage.type + settings + + fontStyle + bold + + + + + name + Function + scope + source.python entity.name.function + settings + + foreground + #323232 + fontStyle + bold + + + + + + + + + + name + Class + scope + source.php entity.name.type.class + settings + + foreground + #323232 + fontStyle + bold + + + + + + + + + + name + Language Variable + scope + variable.language.ruby + settings + + foreground + #ed6a43 + + + + + name + Module Name + scope + entity.name.type.module.ruby + settings + + foreground + #795da3 + fontStyle + bold + + + + + name + Class Name + scope + entity.name.type.class.ruby + settings + + foreground + #795da3 + fontStyle + bold + + + + + name + Inherited Class + scope + entity.other.inherited-class.ruby + settings + + foreground + #795da3 + fontStyle + bold + + + + + + + + + + name + Punctuation + scope + text.html.markdown punctuation.definition + settings + + foreground + #a71d5d + + + + + name + Separator + scope + text.html.markdown meta.separator + settings + + foreground + #b3b3b3 + + + + + name + Heading + scope + text.html.markdown markup.heading + settings + + fontStyle + bold + + + + + name + Code Block + scope + text.html.markdown markup.raw.block + settings + + foreground + #323232 + + + + + name + Inline Code + scope + text.html.markdown markup.raw.inline + settings + + foreground + #323232 + + + + + name + Link and Image + scope + text.html.markdown meta.link, text.html.markdown meta.image + settings + + foreground + #4183c4 + + + + name + Link URL + scope + text.html.markdown markup.underline.link, text.html.markdown constant.other.reference + settings + + fontStyle + italic + + + + + name + List + scope + text.html.markdown markup.list + settings + + foreground + #ed6a43 + + + + + name + Bold + scope + text.html.markdown markup.bold + settings + + fontStyle + bold + + + + + name + Italic + scope + text.html.markdown markup.italic + settings + + fontStyle + italic + + + + + name + Bold Italic + scope + text.html.markdown markup.bold markup.italic + settings + + fontStyle + bold italic + + + + + name + Italic Bold + scope + text.html.markdown markup.italic markup.bold + settings + + fontStyle + italic bold + + + + + diff --git a/crates/highlight-actor/src/lib.rs b/crates/highlight-actor/src/lib.rs index 19aa96a6..51de9ffa 100644 --- a/crates/highlight-actor/src/lib.rs +++ b/crates/highlight-actor/src/lib.rs @@ -75,7 +75,7 @@ impl HighlightActor { .theme_set .as_ref() .themes - .get("GitHub") + .get("InspiredGitHub") .ok_or(HighlightError::UnknownTheme)?; let mut hi = HighlightLines::new(set, theme); diff --git a/crates/highlight-actor/src/load.rs b/crates/highlight-actor/src/load.rs index dfdb0b28..07a95252 100644 --- a/crates/highlight-actor/src/load.rs +++ b/crates/highlight-actor/src/load.rs @@ -1,24 +1,12 @@ -use std::io::BufRead; - -use bincode::{deserialize_from, Result}; -use flate2::bufread::ZlibDecoder; -use serde::de::DeserializeOwned; - -fn from_reader(input: R) -> Result { - let mut decoder = ZlibDecoder::new(input); - deserialize_from(&mut decoder) -} - -fn from_binary(v: &[u8]) -> T { - from_reader(v).unwrap() -} +use syntect::highlighting::ThemeSet; +use syntect::parsing::SyntaxSet; #[inline(always)] pub fn integrated_syntaxset() -> syntect::parsing::SyntaxSet { - from_binary(include_bytes!("./syntaxes.bin")) + SyntaxSet::load_defaults_newlines() } #[inline(always)] pub fn integrated_themeset() -> syntect::highlighting::ThemeSet { - from_binary(include_bytes!("./themes.bin")) + ThemeSet::load_defaults() } diff --git a/crates/web-actor/Cargo.toml b/crates/web-actor/Cargo.toml index e9f1791d..c604bf41 100644 --- a/crates/web-actor/Cargo.toml +++ b/crates/web-actor/Cargo.toml @@ -14,7 +14,7 @@ path = "./src/lib.rs" [features] local-storage = ["filesystem-actor"] -aws-s3 = ["cloud-storage-actor"] +cloud-storage = ["cloud-storage-actor"] default = ["local-storage"] [dependencies] diff --git a/crates/web-actor/src/avatar.rs b/crates/web-actor/src/avatar.rs index d053a3cf..07eaf6a2 100644 --- a/crates/web-actor/src/avatar.rs +++ b/crates/web-actor/src/avatar.rs @@ -4,29 +4,28 @@ use actix::Addr; use actix_multipart::{Field, Multipart}; use actix_web::web::Data; use actix_web::{post, web, Error, HttpResponse}; -use bitque_data::msg::{WsMsg, WsMsgUser}; +use bitque_data::msg::WsMsgUser; use bitque_data::{User, UserId}; use database_actor::authorize_user::AuthorizeUser; use database_actor::user_projects::CurrentUserProject; use database_actor::users::UpdateAvatarUrl; use database_actor::DbExecutor; -#[cfg(feature = "local-storage")] use futures::executor::block_on; use futures::{StreamExt, TryStreamExt}; -use tracing::error; +use tracing::{error, warn}; use websocket_actor::server::InnerMsg::BroadcastToChannel; use websocket_actor::server::WsServer; use crate::ServiceError; -#[cfg(feature = "aws-s3")] +#[cfg(feature = "cloud-storage")] #[post("/")] pub async fn upload( mut payload: Multipart, db: Data>, ws: Data>, - fs: Data>, - amazon: Data>, + fs: Data>, + cloud_storage: Data>, ) -> Result { let mut user_id: Option = None; let mut avatar_url: Option = None; @@ -41,14 +40,16 @@ pub async fn upload( user_id = Some(handle_token(field, db.clone()).await?); } Some("avatar") => { - let id = user_id.ok_or_else(|| HttpResponse::Unauthorized().finish())?; + let Some(id) = user_id else { + warn!("user id not found. Not authorized"); + return Ok(ServiceError::Unauthorized.into()); + }; avatar_url = Some( crate::handlers::upload_avatar_image::handle_image( id, field, - disposition.clone(), fs.clone(), - amazon.clone(), + cloud_storage.clone(), ) .await?, ); @@ -56,6 +57,10 @@ pub async fn upload( _ => continue, }; } + + tracing::info!("user_id {user_id:?}"); + tracing::info!("token {avatar_url:?}"); + let user_id = match user_id { Some(id) => id, _ => return Ok(HttpResponse::Unauthorized().finish()), @@ -69,25 +74,26 @@ pub async fn upload( match (user_id, avatar_url) { (user_id, Some(avatar_url)) => { let user = update_user_avatar(user_id, avatar_url.clone(), db).await?; - ws.send(BroadcastToChannel( + let Ok(_) = ws.send(BroadcastToChannel( project_id, WsMsgUser::AvatarUrlChanged(user.id, avatar_url).into(), )) - .await - .map_err(|_| HttpResponse::UnprocessableEntity().finish())?; + .await else { + return Ok(HttpResponse::UnprocessableEntity().finish()); + }; Ok(HttpResponse::NoContent().finish()) } _ => Ok(HttpResponse::UnprocessableEntity().finish()), } } -#[cfg(not(feature = "aws-s3"))] +#[cfg(not(feature = "cloud-storage"))] #[post("/")] pub async fn upload( mut payload: Multipart, db: Data>, ws: Data>, - fs: Data>, + fs: Data>, ) -> Result { let mut user_id: Option = None; let mut avatar_url: Option = None; @@ -144,7 +150,7 @@ async fn update_user_avatar( user_id: UserId, new_url: String, db: Data>, -) -> Result { +) -> Result { match db .send(UpdateAvatarUrl { user_id, @@ -155,11 +161,11 @@ async fn update_user_avatar( Ok(Ok(user)) => Ok(user), Ok(Err(e)) => { - ::tracing::error!("{:?}", e); + error!("{:?}", e); Err(ServiceError::Unauthorized.into()) } Err(e) => { - ::tracing::error!("{:?}", e); + error!("{:?}", e); Err(ServiceError::Unauthorized.into()) } } @@ -185,11 +191,11 @@ async fn handle_token(mut field: Field, db: Data>) -> Result Ok(user.id), Ok(Err(e)) => { - ::tracing::error!("{:?}", e); + error!("{:?}", e); Err(ServiceError::Unauthorized.into()) } Err(e) => { - ::tracing::error!("{:?}", e); + error!("{:?}", e); Err(ServiceError::Unauthorized.into()) } } diff --git a/crates/web-actor/src/errors.rs b/crates/web-actor/src/errors.rs index 62400f6b..b6735f7d 100644 --- a/crates/web-actor/src/errors.rs +++ b/crates/web-actor/src/errors.rs @@ -8,14 +8,14 @@ use bitque_data::ErrorResponse; const TOKEN_NOT_FOUND: &str = "Token not found"; const DATABASE_CONNECTION_FAILED: &str = "Database connection failed"; -#[derive(Debug, Copy, Clone)] +#[derive(Clone, Copy, Debug)] pub enum HighlightError { UnknownLanguage, UnknownTheme, ResultUnserializable, } -#[derive(Debug, Clone)] +#[derive(Clone, Debug)] pub enum ServiceError { Unauthorized, DatabaseConnectionLost, diff --git a/crates/web-actor/src/handlers/upload_avatar_image.rs b/crates/web-actor/src/handlers/upload_avatar_image.rs index 65792bb7..7ae2dcf5 100644 --- a/crates/web-actor/src/handlers/upload_avatar_image.rs +++ b/crates/web-actor/src/handlers/upload_avatar_image.rs @@ -1,18 +1,19 @@ -use actix::Addr; +use actix::{spawn, Addr}; use actix_multipart::Field; use actix_web::web::Data; -use actix_web::Error; +use actix_web::{Error, HttpResponse}; use bitque_data::UserId; +use futures::future::join_all; use futures::StreamExt; use tokio::sync::broadcast::{Receiver, Sender}; use tracing::error; -#[cfg(all(feature = "local-storage", feature = "aws-s3"))] +#[cfg(all(feature = "local-storage", feature = "cloud-storage"))] pub(crate) async fn handle_image( user_id: UserId, mut field: Field, - fs: Data>, - amazon: Data>, + fs: Data>, + cloud_storage: Data>, ) -> Result { let filename = field.content_disposition().get_filename().unwrap(); let system_file_name = format!("{}-{}", user_id, filename); @@ -20,38 +21,35 @@ pub(crate) async fn handle_image( let (sender, receiver) = tokio::sync::broadcast::channel(64); let fs_fut = local_storage_write(system_file_name.clone(), fs, user_id, sender.subscribe()); - let aws_fut = aws_s3(system_file_name, amazon, receiver); + let aws_fut = cloud_storage_write(system_file_name, cloud_storage, receiver); let read_fut = read_form_data(&mut field, sender); - let fs_join = tokio::task::spawn(fs_fut); - let aws_join = tokio::task::spawn(aws_fut); read_fut.await; - let mut new_link = None; + let results = join_all([spawn(fs_fut), spawn(aws_fut)]).await; - if let Ok(url) = fs_join.await { - new_link = url; + for res in results { + return if let Ok(Some(link)) = res { + Ok(link) + } else { + Err(HttpResponse::UnprocessableEntity().finish().into()) + }; } - - if let Ok(url) = aws_join.await { - new_link = url; - } - - Ok(new_link.unwrap_or_default()) + Err(HttpResponse::UnprocessableEntity().finish().into()) } -#[cfg(all(not(feature = "local-storage"), feature = "aws-s3"))] +#[cfg(all(not(feature = "local-storage"), feature = "cloud-storage"))] pub(crate) async fn handle_image( user_id: UserId, mut field: Field, - amazon: Data>, + cloud_storage: Data>, ) -> Result { let filename = field.content_disposition().get_filename().unwrap(); let system_file_name = format!("{}-{}", user_id, filename); let (sender, receiver) = tokio::sync::broadcast::channel(64); - let aws_fut = aws_s3(system_file_name, amazon, receiver); + let aws_fut = cloud - storage_write(system_file_name, cloud_storage, receiver); let read_fut = read_form_data(&mut field, sender); let aws_join = tokio::task::spawn(aws_fut); @@ -66,11 +64,11 @@ pub(crate) async fn handle_image( Ok(new_link.unwrap_or_default()) } -#[cfg(all(feature = "local-storage", not(feature = "aws-s3")))] +#[cfg(all(feature = "local-storage", not(feature = "cloud-storage")))] pub(crate) async fn handle_image( user_id: UserId, mut field: Field, - fs: Data>, + fs: Data>, ) -> Result { let filename = field.content_disposition().get_filename().unwrap(); let system_file_name = format!("{}-{}", user_id, filename); @@ -103,19 +101,19 @@ async fn read_form_data(field: &mut Field, sender: Sender) { } /// Stream bytes directly to AWS S3 Service -#[cfg(feature = "aws-s3")] -async fn aws_s3( +#[cfg(feature = "cloud-storage")] +async fn cloud_storage_write( system_file_name: String, - amazon: Data>, + cloud_storage: Data>, receiver: Receiver, ) -> Option { - let s3 = bitque_config::amazon::config(); + let s3 = bitque_config::cloud_storage::config(); if !s3.active { return None; } - match amazon - .send(amazon_actor::S3PutObject { + match cloud_storage + .send(cloud_storage_actor::S3PutObject { source: receiver, file_name: system_file_name.to_string(), }) @@ -129,7 +127,7 @@ async fn aws_s3( #[cfg(feature = "local-storage")] async fn local_storage_write( system_file_name: String, - fs: Data>, + fs: Data>, _user_id: bitque_data::UserId, receiver: Receiver, ) -> Option { diff --git a/crates/web/Cargo.toml b/crates/web/Cargo.toml index 8db38dcf..90a5e3d4 100644 --- a/crates/web/Cargo.toml +++ b/crates/web/Cargo.toml @@ -8,11 +8,6 @@ repository = "https://gitlab.com/adrian.wozniak/bitque" license = "MPL-2.0" #license-file = "../LICENSE" -[lib] -crate-type = ["cdylib", "rlib"] -name = "bitque_client" -path = "src/lib.rs" - [features] print-model = [] default = [] @@ -25,16 +20,20 @@ console_error_panic_hook = { version = "*" } derive_enum_iter = { workspace = true } derive_enum_primitive = { workspace = true } dotenv = { version = "*" } -futures = "0.3.6" +futures = { version = "0.3.6" } js-sys = { version = "*", default-features = false } -seed = { version = "0" } -serde = { version = "1", features = [] } +seed = { version = "0", features = ['serde-wasm-bindgen'] } +serde = { version = "1", features = ['derive'] } serde_json = { version = "*" } tracing = { version = "0.1.37" } +tracing-subscriber = { version = "0.3.16" } +tracing-subscriber-wasm = { version = "0.1.0" } uuid = { version = "1.3.0", features = ["serde"] } wasm-bindgen = { version = "*", features = ["enable-interning"] } wasm-bindgen-futures = { version = "*" } wee_alloc = { version = "*", features = ["static_array_backend"] } +wasm-sockets = { version = "1", features = [] } +strum = { version = "*" } [dependencies.web-sys] version = "*" diff --git a/crates/web/Trunk.toml b/crates/web/Trunk.toml new file mode 100644 index 00000000..0a0aa1a7 --- /dev/null +++ b/crates/web/Trunk.toml @@ -0,0 +1,20 @@ +[build] +target = "./index.html" + +[watch] +ignore = [ + "tmp", +] + +[[hooks]] +stage = "build" +command = "zsh" +command_arguments = ['./scripts/compile-css.sh'] + +[[proxy]] +rewrite = "/ws" +backend = "http://0.0.0.0:5000" + +[[proxy]] +rewrite = "/avatar" +backend = "http://0.0.0.0:5000/avatar" diff --git a/crates/web/static/fonts/CircularStd-Black.eot b/crates/web/assets/fonts/CircularStd-Black.eot similarity index 100% rename from crates/web/static/fonts/CircularStd-Black.eot rename to crates/web/assets/fonts/CircularStd-Black.eot diff --git a/crates/web/static/fonts/CircularStd-Black.otf b/crates/web/assets/fonts/CircularStd-Black.otf similarity index 100% rename from crates/web/static/fonts/CircularStd-Black.otf rename to crates/web/assets/fonts/CircularStd-Black.otf diff --git a/crates/web/static/fonts/CircularStd-Black.svg b/crates/web/assets/fonts/CircularStd-Black.svg similarity index 100% rename from crates/web/static/fonts/CircularStd-Black.svg rename to crates/web/assets/fonts/CircularStd-Black.svg diff --git a/crates/web/static/fonts/CircularStd-Black.ttf b/crates/web/assets/fonts/CircularStd-Black.ttf similarity index 100% rename from crates/web/static/fonts/CircularStd-Black.ttf rename to crates/web/assets/fonts/CircularStd-Black.ttf diff --git a/crates/web/static/fonts/CircularStd-Black.woff b/crates/web/assets/fonts/CircularStd-Black.woff similarity index 100% rename from crates/web/static/fonts/CircularStd-Black.woff rename to crates/web/assets/fonts/CircularStd-Black.woff diff --git a/crates/web/static/fonts/CircularStd-Black.woff2 b/crates/web/assets/fonts/CircularStd-Black.woff2 similarity index 100% rename from crates/web/static/fonts/CircularStd-Black.woff2 rename to crates/web/assets/fonts/CircularStd-Black.woff2 diff --git a/crates/web/static/fonts/CircularStd-Bold.eot b/crates/web/assets/fonts/CircularStd-Bold.eot similarity index 100% rename from crates/web/static/fonts/CircularStd-Bold.eot rename to crates/web/assets/fonts/CircularStd-Bold.eot diff --git a/crates/web/static/fonts/CircularStd-Bold.otf b/crates/web/assets/fonts/CircularStd-Bold.otf similarity index 100% rename from crates/web/static/fonts/CircularStd-Bold.otf rename to crates/web/assets/fonts/CircularStd-Bold.otf diff --git a/crates/web/static/fonts/CircularStd-Bold.svg b/crates/web/assets/fonts/CircularStd-Bold.svg similarity index 100% rename from crates/web/static/fonts/CircularStd-Bold.svg rename to crates/web/assets/fonts/CircularStd-Bold.svg diff --git a/crates/web/static/fonts/CircularStd-Bold.ttf b/crates/web/assets/fonts/CircularStd-Bold.ttf similarity index 100% rename from crates/web/static/fonts/CircularStd-Bold.ttf rename to crates/web/assets/fonts/CircularStd-Bold.ttf diff --git a/crates/web/static/fonts/CircularStd-Bold.woff b/crates/web/assets/fonts/CircularStd-Bold.woff similarity index 100% rename from crates/web/static/fonts/CircularStd-Bold.woff rename to crates/web/assets/fonts/CircularStd-Bold.woff diff --git a/crates/web/static/fonts/CircularStd-Bold.woff2 b/crates/web/assets/fonts/CircularStd-Bold.woff2 similarity index 100% rename from crates/web/static/fonts/CircularStd-Bold.woff2 rename to crates/web/assets/fonts/CircularStd-Bold.woff2 diff --git a/crates/web/static/fonts/CircularStd-Book.eot b/crates/web/assets/fonts/CircularStd-Book.eot similarity index 100% rename from crates/web/static/fonts/CircularStd-Book.eot rename to crates/web/assets/fonts/CircularStd-Book.eot diff --git a/crates/web/static/fonts/CircularStd-Book.otf b/crates/web/assets/fonts/CircularStd-Book.otf similarity index 100% rename from crates/web/static/fonts/CircularStd-Book.otf rename to crates/web/assets/fonts/CircularStd-Book.otf diff --git a/crates/web/static/fonts/CircularStd-Book.svg b/crates/web/assets/fonts/CircularStd-Book.svg similarity index 100% rename from crates/web/static/fonts/CircularStd-Book.svg rename to crates/web/assets/fonts/CircularStd-Book.svg diff --git a/crates/web/static/fonts/CircularStd-Book.ttf b/crates/web/assets/fonts/CircularStd-Book.ttf similarity index 100% rename from crates/web/static/fonts/CircularStd-Book.ttf rename to crates/web/assets/fonts/CircularStd-Book.ttf diff --git a/crates/web/static/fonts/CircularStd-Book.woff b/crates/web/assets/fonts/CircularStd-Book.woff similarity index 100% rename from crates/web/static/fonts/CircularStd-Book.woff rename to crates/web/assets/fonts/CircularStd-Book.woff diff --git a/crates/web/static/fonts/CircularStd-Book.woff2 b/crates/web/assets/fonts/CircularStd-Book.woff2 similarity index 100% rename from crates/web/static/fonts/CircularStd-Book.woff2 rename to crates/web/assets/fonts/CircularStd-Book.woff2 diff --git a/crates/web/static/fonts/CircularStd-Medium.eot b/crates/web/assets/fonts/CircularStd-Medium.eot similarity index 100% rename from crates/web/static/fonts/CircularStd-Medium.eot rename to crates/web/assets/fonts/CircularStd-Medium.eot diff --git a/crates/web/static/fonts/CircularStd-Medium.otf b/crates/web/assets/fonts/CircularStd-Medium.otf similarity index 100% rename from crates/web/static/fonts/CircularStd-Medium.otf rename to crates/web/assets/fonts/CircularStd-Medium.otf diff --git a/crates/web/static/fonts/CircularStd-Medium.svg b/crates/web/assets/fonts/CircularStd-Medium.svg similarity index 100% rename from crates/web/static/fonts/CircularStd-Medium.svg rename to crates/web/assets/fonts/CircularStd-Medium.svg diff --git a/crates/web/static/fonts/CircularStd-Medium.ttf b/crates/web/assets/fonts/CircularStd-Medium.ttf similarity index 100% rename from crates/web/static/fonts/CircularStd-Medium.ttf rename to crates/web/assets/fonts/CircularStd-Medium.ttf diff --git a/crates/web/static/fonts/CircularStd-Medium.woff b/crates/web/assets/fonts/CircularStd-Medium.woff similarity index 100% rename from crates/web/static/fonts/CircularStd-Medium.woff rename to crates/web/assets/fonts/CircularStd-Medium.woff diff --git a/crates/web/static/fonts/CircularStd-Medium.woff2 b/crates/web/assets/fonts/CircularStd-Medium.woff2 similarity index 100% rename from crates/web/static/fonts/CircularStd-Medium.woff2 rename to crates/web/assets/fonts/CircularStd-Medium.woff2 diff --git a/crates/web/static/fonts/icofont.eot b/crates/web/assets/fonts/icofont.eot similarity index 100% rename from crates/web/static/fonts/icofont.eot rename to crates/web/assets/fonts/icofont.eot diff --git a/crates/web/static/fonts/icofont.svg b/crates/web/assets/fonts/icofont.svg similarity index 100% rename from crates/web/static/fonts/icofont.svg rename to crates/web/assets/fonts/icofont.svg diff --git a/crates/web/static/fonts/icofont.ttf b/crates/web/assets/fonts/icofont.ttf similarity index 100% rename from crates/web/static/fonts/icofont.ttf rename to crates/web/assets/fonts/icofont.ttf diff --git a/crates/web/static/fonts/icofont.woff b/crates/web/assets/fonts/icofont.woff similarity index 100% rename from crates/web/static/fonts/icofont.woff rename to crates/web/assets/fonts/icofont.woff diff --git a/crates/web/static/fonts/icofont.woff2 b/crates/web/assets/fonts/icofont.woff2 similarity index 100% rename from crates/web/static/fonts/icofont.woff2 rename to crates/web/assets/fonts/icofont.woff2 diff --git a/crates/web/static/fonts/jira.svg b/crates/web/assets/fonts/jira.svg similarity index 100% rename from crates/web/static/fonts/jira.svg rename to crates/web/assets/fonts/jira.svg diff --git a/crates/web/static/fonts/jira.ttf b/crates/web/assets/fonts/jira.ttf similarity index 100% rename from crates/web/static/fonts/jira.ttf rename to crates/web/assets/fonts/jira.ttf diff --git a/crates/web/static/fonts/jira.woff b/crates/web/assets/fonts/jira.woff similarity index 100% rename from crates/web/static/fonts/jira.woff rename to crates/web/assets/fonts/jira.woff diff --git a/crates/web/static/favicon.png b/crates/web/assets/images/favicon.png similarity index 100% rename from crates/web/static/favicon.png rename to crates/web/assets/images/favicon.png diff --git a/crates/web/static/feedback.png b/crates/web/assets/images/feedback.png similarity index 100% rename from crates/web/static/feedback.png rename to crates/web/assets/images/feedback.png diff --git a/crates/web/static/logo.svg b/crates/web/assets/images/logo.svg similarity index 100% rename from crates/web/static/logo.svg rename to crates/web/assets/images/logo.svg diff --git a/crates/web/static/logo2.svg b/crates/web/assets/images/logo2.svg similarity index 100% rename from crates/web/static/logo2.svg rename to crates/web/assets/images/logo2.svg diff --git a/crates/web/static/project-avatar.svg b/crates/web/assets/images/project-avatar.svg similarity index 100% rename from crates/web/static/project-avatar.svg rename to crates/web/assets/images/project-avatar.svg diff --git a/crates/web/static/project-icon.svg b/crates/web/assets/images/project-icon.svg similarity index 100% rename from crates/web/static/project-icon.svg rename to crates/web/assets/images/project-icon.svg diff --git a/crates/web/js/css/app.scss b/crates/web/assets/styles/css/app.scss similarity index 100% rename from crates/web/js/css/app.scss rename to crates/web/assets/styles/css/app.scss diff --git a/crates/web/js/css/aside.scss b/crates/web/assets/styles/css/aside.scss similarity index 100% rename from crates/web/js/css/aside.scss rename to crates/web/assets/styles/css/aside.scss diff --git a/crates/web/js/css/deleteIssueStatus.scss b/crates/web/assets/styles/css/deleteIssueStatus.scss similarity index 100% rename from crates/web/js/css/deleteIssueStatus.scss rename to crates/web/assets/styles/css/deleteIssueStatus.scss diff --git a/crates/web/js/css/epicsPage.scss b/crates/web/assets/styles/css/epicsPage.scss similarity index 100% rename from crates/web/js/css/epicsPage.scss rename to crates/web/assets/styles/css/epicsPage.scss diff --git a/crates/web/js/css/fonts.scss b/crates/web/assets/styles/css/fonts.scss similarity index 100% rename from crates/web/js/css/fonts.scss rename to crates/web/assets/styles/css/fonts.scss diff --git a/crates/web/js/css/global.scss b/crates/web/assets/styles/css/global.scss similarity index 100% rename from crates/web/js/css/global.scss rename to crates/web/assets/styles/css/global.scss diff --git a/crates/web/js/css/iconfonts.scss b/crates/web/assets/styles/css/iconfonts.scss similarity index 100% rename from crates/web/js/css/iconfonts.scss rename to crates/web/assets/styles/css/iconfonts.scss diff --git a/crates/web/js/css/invite.scss b/crates/web/assets/styles/css/invite.scss similarity index 100% rename from crates/web/js/css/invite.scss rename to crates/web/assets/styles/css/invite.scss diff --git a/crates/web/js/css/issue.scss b/crates/web/assets/styles/css/issue.scss similarity index 100% rename from crates/web/js/css/issue.scss rename to crates/web/assets/styles/css/issue.scss diff --git a/crates/web/js/css/issuesAndFilters.scss b/crates/web/assets/styles/css/issuesAndFilters.scss similarity index 100% rename from crates/web/js/css/issuesAndFilters.scss rename to crates/web/assets/styles/css/issuesAndFilters.scss diff --git a/crates/web/js/css/login.scss b/crates/web/assets/styles/css/login.scss similarity index 100% rename from crates/web/js/css/login.scss rename to crates/web/assets/styles/css/login.scss diff --git a/crates/web/js/css/normalize.scss b/crates/web/assets/styles/css/normalize.scss similarity index 100% rename from crates/web/js/css/normalize.scss rename to crates/web/assets/styles/css/normalize.scss diff --git a/crates/web/js/css/profile.scss b/crates/web/assets/styles/css/profile.scss similarity index 100% rename from crates/web/js/css/profile.scss rename to crates/web/assets/styles/css/profile.scss diff --git a/crates/web/js/css/project.scss b/crates/web/assets/styles/css/project.scss similarity index 100% rename from crates/web/js/css/project.scss rename to crates/web/assets/styles/css/project.scss diff --git a/crates/web/js/css/projectSettings.scss b/crates/web/assets/styles/css/projectSettings.scss similarity index 100% rename from crates/web/js/css/projectSettings.scss rename to crates/web/assets/styles/css/projectSettings.scss diff --git a/crates/web/js/css/register.scss b/crates/web/assets/styles/css/register.scss similarity index 100% rename from crates/web/js/css/register.scss rename to crates/web/assets/styles/css/register.scss diff --git a/crates/web/js/css/reports.scss b/crates/web/assets/styles/css/reports.scss similarity index 100% rename from crates/web/js/css/reports.scss rename to crates/web/assets/styles/css/reports.scss diff --git a/crates/web/js/css/shared.scss b/crates/web/assets/styles/css/shared.scss similarity index 100% rename from crates/web/js/css/shared.scss rename to crates/web/assets/styles/css/shared.scss diff --git a/crates/web/js/css/sidebar.scss b/crates/web/assets/styles/css/sidebar.scss similarity index 100% rename from crates/web/js/css/sidebar.scss rename to crates/web/assets/styles/css/sidebar.scss diff --git a/crates/web/js/css/styledAvatar.scss b/crates/web/assets/styles/css/styledAvatar.scss similarity index 100% rename from crates/web/js/css/styledAvatar.scss rename to crates/web/assets/styles/css/styledAvatar.scss diff --git a/crates/web/js/css/styledButton.scss b/crates/web/assets/styles/css/styledButton.scss similarity index 100% rename from crates/web/js/css/styledButton.scss rename to crates/web/assets/styles/css/styledButton.scss diff --git a/crates/web/js/css/styledCheckbox.scss b/crates/web/assets/styles/css/styledCheckbox.scss similarity index 100% rename from crates/web/js/css/styledCheckbox.scss rename to crates/web/assets/styles/css/styledCheckbox.scss diff --git a/crates/web/js/css/styledComment.scss b/crates/web/assets/styles/css/styledComment.scss similarity index 100% rename from crates/web/js/css/styledComment.scss rename to crates/web/assets/styles/css/styledComment.scss diff --git a/crates/web/js/css/styledDateTimeInput.scss b/crates/web/assets/styles/css/styledDateTimeInput.scss similarity index 100% rename from crates/web/js/css/styledDateTimeInput.scss rename to crates/web/assets/styles/css/styledDateTimeInput.scss diff --git a/crates/web/js/css/styledEditor.scss b/crates/web/assets/styles/css/styledEditor.scss similarity index 100% rename from crates/web/js/css/styledEditor.scss rename to crates/web/assets/styles/css/styledEditor.scss diff --git a/crates/web/js/css/styledForm.scss b/crates/web/assets/styles/css/styledForm.scss similarity index 100% rename from crates/web/js/css/styledForm.scss rename to crates/web/assets/styles/css/styledForm.scss diff --git a/crates/web/js/css/styledIcon.scss b/crates/web/assets/styles/css/styledIcon.scss similarity index 100% rename from crates/web/js/css/styledIcon.scss rename to crates/web/assets/styles/css/styledIcon.scss diff --git a/crates/web/js/css/styledImageInput.scss b/crates/web/assets/styles/css/styledImageInput.scss similarity index 100% rename from crates/web/js/css/styledImageInput.scss rename to crates/web/assets/styles/css/styledImageInput.scss diff --git a/crates/web/js/css/styledInput.scss b/crates/web/assets/styles/css/styledInput.scss similarity index 100% rename from crates/web/js/css/styledInput.scss rename to crates/web/assets/styles/css/styledInput.scss diff --git a/crates/web/js/css/styledLink.scss b/crates/web/assets/styles/css/styledLink.scss similarity index 100% rename from crates/web/js/css/styledLink.scss rename to crates/web/assets/styles/css/styledLink.scss diff --git a/crates/web/js/css/styledModal.scss b/crates/web/assets/styles/css/styledModal.scss similarity index 100% rename from crates/web/js/css/styledModal.scss rename to crates/web/assets/styles/css/styledModal.scss diff --git a/crates/web/js/css/styledPage.scss b/crates/web/assets/styles/css/styledPage.scss similarity index 100% rename from crates/web/js/css/styledPage.scss rename to crates/web/assets/styles/css/styledPage.scss diff --git a/crates/web/js/css/styledRte.scss b/crates/web/assets/styles/css/styledRte.scss similarity index 100% rename from crates/web/js/css/styledRte.scss rename to crates/web/assets/styles/css/styledRte.scss diff --git a/crates/web/js/css/styledSelect.scss b/crates/web/assets/styles/css/styledSelect.scss similarity index 100% rename from crates/web/js/css/styledSelect.scss rename to crates/web/assets/styles/css/styledSelect.scss diff --git a/crates/web/js/css/styledSelectChild.scss b/crates/web/assets/styles/css/styledSelectChild.scss similarity index 100% rename from crates/web/js/css/styledSelectChild.scss rename to crates/web/assets/styles/css/styledSelectChild.scss diff --git a/crates/web/js/css/styledTextArea.scss b/crates/web/assets/styles/css/styledTextArea.scss similarity index 100% rename from crates/web/js/css/styledTextArea.scss rename to crates/web/assets/styles/css/styledTextArea.scss diff --git a/crates/web/js/css/styledTooltip.scss b/crates/web/assets/styles/css/styledTooltip.scss similarity index 100% rename from crates/web/js/css/styledTooltip.scss rename to crates/web/assets/styles/css/styledTooltip.scss diff --git a/crates/web/js/css/timeTracking.scss b/crates/web/assets/styles/css/timeTracking.scss similarity index 100% rename from crates/web/js/css/timeTracking.scss rename to crates/web/assets/styles/css/timeTracking.scss diff --git a/crates/web/js/css/users.scss b/crates/web/assets/styles/css/users.scss similarity index 100% rename from crates/web/js/css/users.scss rename to crates/web/assets/styles/css/users.scss diff --git a/crates/web/js/css/variables.scss b/crates/web/assets/styles/css/variables.scss similarity index 100% rename from crates/web/js/css/variables.scss rename to crates/web/assets/styles/css/variables.scss diff --git a/crates/web/js/styles.css b/crates/web/assets/styles/styles.scss similarity index 100% rename from crates/web/js/styles.css rename to crates/web/assets/styles/styles.scss diff --git a/crates/web/index.html b/crates/web/index.html new file mode 100644 index 00000000..e4160c55 --- /dev/null +++ b/crates/web/index.html @@ -0,0 +1,16 @@ + + + + + BitQ + + + + + + + + +
+ + diff --git a/crates/web/js/nginx-selfsigned.crt b/crates/web/js/nginx-selfsigned.crt deleted file mode 100644 index 671f06a0..00000000 --- a/crates/web/js/nginx-selfsigned.crt +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDazCCAlOgAwIBAgIUDjHRR+doFMtPDDYS5nI8q7lcgwQwDQYJKoZIhvcNAQEL -BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM -GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA2MTAwNzM2MTFaFw0yMTA2 -MTAwNzM2MTFaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw -HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQC+8ugcWfHcH77/CF9ey0/qlwy6zQ0Vl/p9QC70NCFd -BiMnmh9jyglirSaSGuZOZedNhhg7n8JPJBk9435L0L2Ceuwa0RlzC3HUicSF61pZ -qQ3gnWu5S5deqGlP++QBWeRj6so3e6fIzc8jiarAKvB7iO5t6PvhAjvpDfWBhMUk -tnkHUnQx1dCZnYQxhbGPUNGgIy+8SkjE8JkURhQQviBONaCR6yjbh81ZF6mMjhUe -tdWJ0AIZ9FjPE+4jG/URGgXv78+gAFBav63wKOyrAVwn2S3m2xLZ76ErhUibQ5ie -M0r9hflpEjETc0xkwCBDKFLVfDOk9bzEeOwqMJf1qun/AgMBAAGjUzBRMB0GA1Ud -DgQWBBRoVikqYGbNf+avLLMUtih8z27PhDAfBgNVHSMEGDAWgBRoVikqYGbNf+av -LLMUtih8z27PhDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAY -V4CQ3Xd7EIjHfZGVGoWMX7bhIBn6vzPNpUDV3NiCQfpgk/1BLRqiISx/4+40X4C0 -xk6QHe+Fl6IRYd/4UT1ik43Vu2Q0ED7JlITHkPFdGsH1V8BiImx+b3+EGEBCGahm -UdMOhuyt3gkQRtz9Vvn4o+xLrP8YNLJ0qUchQNIsC7MTMZUpFJ+NJ3nHXOgdn2+s -3bNGDcHh+VVjF38DxHH66egdDUYZvL2DPJ5sCgz+q2D8tY7UUTviw4feGeOpU5ls -R9zVMhiQ38y/ERJvHn61XnyUP32kd+rRkn+iQRy4pDjX1FQte9vlSAlOfedhEwaY -g7qI9zFDYyGPX4g0A4j8 ------END CERTIFICATE----- diff --git a/crates/web/js/nginx-selfsigned.key b/crates/web/js/nginx-selfsigned.key deleted file mode 100644 index 2a85c780..00000000 --- a/crates/web/js/nginx-selfsigned.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC+8ugcWfHcH77/ -CF9ey0/qlwy6zQ0Vl/p9QC70NCFdBiMnmh9jyglirSaSGuZOZedNhhg7n8JPJBk9 -435L0L2Ceuwa0RlzC3HUicSF61pZqQ3gnWu5S5deqGlP++QBWeRj6so3e6fIzc8j -iarAKvB7iO5t6PvhAjvpDfWBhMUktnkHUnQx1dCZnYQxhbGPUNGgIy+8SkjE8JkU -RhQQviBONaCR6yjbh81ZF6mMjhUetdWJ0AIZ9FjPE+4jG/URGgXv78+gAFBav63w -KOyrAVwn2S3m2xLZ76ErhUibQ5ieM0r9hflpEjETc0xkwCBDKFLVfDOk9bzEeOwq -MJf1qun/AgMBAAECggEAXRhwseHoWTnhFNYwKTdWrzkVq71tM6n1Jju0qLsBySjE -2vn5c9181e81buZOgsqMCu/lwKwTQCKJa/MOEEilHIhxtGFd1wktZkIE3oXwduZF -Lc2SR7TjB/Nz5NsaPs5k25INJR/UncI5y0nDRg2pUZFhLZT5uKouK2Hy4EKrG0pB -8bYYlTq9Ra+CDBHlXQEGzzfFFGjAaHXc2uYcSn3bhBuUAzPW735CZZ0uCh/0d5Om -xp1vJpMIhr5YDymVHXS1WV1rqvfDeNQNZYOKv2NHbxa+dUbkGkVrgW4KD0mYucw0 -JjyFWKLhetZM8f8k/9bC1dbss59CsHBfNRJ4Abv/gQKBgQD91jnKkk+PC1WDD6Oh -haa2ZSlixc9dUQVG/ve3dsGTll839qvqNCTdIMIXIJI/FYG2e0M3ITcW7Kc8MKJZ -MynlgUW7027vYW5m89JY/Ev+ymnh1/xHeoLVMHlr/ZPUxoBA22KiowsZTONMFPZT -7sJS7WxbiU5kMGE5og7sqC8JvQKBgQDAk3vNCqqkhE7dZvJ1s/sX5Tn9lAu9CZj6 -hZQrPh6ZxynsyE7Nj8Hp6Fh9uW2NzahG16Zil0uvqrvtcshI3sGy1+NWxsWQyO3A -DP7kKerEJ/5AS9jSis5OCnsrOCEF1ZvabSAKlgSTf93AZ8qjs2xCdyyqxYpzwfX8 -U6/8aiq4awKBgF31pXDBleeKN34LFPPeKCbN7XLda/PL4Ns11/Y2ZFNAT0DE8z// -S0H7NT0gVmI5kMk+eVP33I+EzCawjffcw35ryqdLDX5Yn2hGiq9bvLm0rVrm+0Bu -Le3CQr/hno4daC4ZxzoShjI4Ts7D16ab85yEvB5qBfV6HxMZVNLvMnI1AoGAF5S3 -rybkOFr/MTs+60zLrWRjUnrDaTV4pwyeVSE5LAloR9dLVv6IdzT9SP/gu2F4fpw/ -gokWOn+EnZHVlp64R0cKToDuhkkkW8T7nULIvZZMGuFuvnFCy+mapXMtEALVH80H -BGTUUJ9yrvHGrX71/bmMHaksx/nzPh+dSCJT8tsCgYEA7CvaE0Lsw8/ImkVNjKBj -+AprNB1s93/nrgO6Ql/O3Dv0/OUj6PscKYpgID29RpygoMqs4oZzNRQ72oRM5ijc -tOPrvfFINJ9JDAVrUMH5raadX8KJXtvoDzy6MSr8jvBbj6HeNDbyz/OnUd03fF72 -z9B6af93B6IpwbRK7q6JFlc= ------END PRIVATE KEY----- diff --git a/crates/web/js/template.ejs b/crates/web/js/template.ejs deleted file mode 100644 index 9a8415d2..00000000 --- a/crates/web/js/template.ejs +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - JIRS - - - -
- -
-
- - diff --git a/crates/web/js/template.html b/crates/web/js/template.html deleted file mode 100644 index c06eb8c0..00000000 --- a/crates/web/js/template.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - JIRS - - - - - -
-
-
-
Loading....
-
Please wait
-
-
- - - diff --git a/crates/web/scripts/compile-css.sh b/crates/web/scripts/compile-css.sh new file mode 100755 index 00000000..d99588c7 --- /dev/null +++ b/crates/web/scripts/compile-css.sh @@ -0,0 +1 @@ +rsass -I ./assets/styles -t expanded ./assets/styles/styles.scss > tmp/styles.css diff --git a/crates/web/scripts/dev.sh b/crates/web/scripts/dev.sh index c12356a3..c27afeee 100755 --- a/crates/web/scripts/dev.sh +++ b/crates/web/scripts/dev.sh @@ -1,18 +1,33 @@ #!/usr/bin/env bash +ROOT=$(git rev-parse --show-toplevel) + RSASS_PATH=$(command -v rsass) if [[ "${RSASS_PATH}" == "" ]]; then - cargo install rsass --features=commandline + cargo install rsass-cli + RSASS_PATH=$(command -v rsass) fi WASM_PACK_PATH=$(command -v wasm-pack) if [[ "${WASM_PACK_PATH}" == "" ]]; then cargo install wasm-pack + WASM_PACK_PATH=$(command -v wasm-pack) +fi + +TRUNK_PATH=$(command -v trunk) +if [[ "${TRUNK_PATH}" == "" ]]; then + cargo install --locked trunk + TRUNK_PATH=$(command -v trunk) +fi + +CARGO_WATCH=$(command -v cargo-watch) +if [[ "${CARGO_WATCH}" == "" ]]; then + cargo install cargo-watch fi export PROJECT_ROOT=$(git rev-parse --show-toplevel) -export CLIENT_ROOT=${PROJECT_ROOT}/web -export HI_ROOT=${PROJECT_ROOT}/highlight/bitque-highlight +export CLIENT_ROOT=${PROJECT_ROOT}/crates/web +export HI_ROOT=${PROJECT_ROOT}/crates/highlight/bitque-highlight export MODE=force export BUILD_TYPE=--dev export COPY_TO=${CLIENT_ROOT}/tmp @@ -22,7 +37,7 @@ echo $CLIENT_ROOT cd ${CLIENT_ROOT} -. .env +. ${ROOT}/.env cargo watch \ -i ${CLIENT_ROOT}/src/location.rs \ diff --git a/crates/web/src/changes.rs b/crates/web/src/changes.rs index e7833a2d..f5b0afba 100644 --- a/crates/web/src/changes.rs +++ b/crates/web/src/changes.rs @@ -1,4 +1,5 @@ use bitque_data::{EpicId, IssueStatusId, WsMsg}; +use seed::prelude::WebSocketMessage; use crate::components::styled_md_editor::MdEditorMode as TabMode; use crate::FieldId; diff --git a/crates/web/src/components/events.rs b/crates/web/src/components/events.rs index 8ba8f5ff..3a7b3df9 100644 --- a/crates/web/src/components/events.rs +++ b/crates/web/src/components/events.rs @@ -40,7 +40,7 @@ pub fn on_click_change_day(field_id: crate::FieldId, date: chrono::NaiveDateTime ev.stop_propagation(); ev.prevent_default(); - // log::info!("{:?}", date); + // info!("{:?}", date); crate::Msg::StyledDateTimeInputChanged( field_id, StyledDateTimeChanged::DayChanged(Some(date)), diff --git a/crates/web/src/components/styled_editor.rs b/crates/web/src/components/styled_editor.rs index a62aa403..9fb110cf 100644 --- a/crates/web/src/components/styled_editor.rs +++ b/crates/web/src/components/styled_editor.rs @@ -118,7 +118,7 @@ fn editor_mode_checkbox_option<'l>( TextEditorMode::RteOnly => "Rich Text Editor", TextEditorMode::Mixed => "Editor with possibility to switch between modes", }, - class_list: tem.to_str(), + class_list: tem.as_str(), value, icon: match tem { TextEditorMode::MdOnly => StyledIcon::from(Icon::MdEditor).render(), diff --git a/crates/web/src/components/styled_rte.rs b/crates/web/src/components/styled_rte.rs index 24bed1b4..f009d589 100644 --- a/crates/web/src/components/styled_rte.rs +++ b/crates/web/src/components/styled_rte.rs @@ -368,7 +368,7 @@ impl StyledRteState { } self.schedule_focus(orders); } - _ => log::error!("unknown rte command {:?}", m), + _ => error!("unknown rte command {:?}", m), }, }; // orders.skip().send_msg(Msg::StrInputChanged( diff --git a/crates/web/src/images/logo.rs b/crates/web/src/images/logo.rs index aff5f50b..5271d8ef 100644 --- a/crates/web/src/images/logo.rs +++ b/crates/web/src/images/logo.rs @@ -2,9 +2,9 @@ use seed::prelude::*; use crate::Msg; -static LOGO: &str = include_str!("../../static/logo2.svg"); +static LOGO: &str = include_str!("../../assets/images/logo2.svg"); #[inline(always)] pub fn render() -> Vec> { - Node::from_html(LOGO) + Node::from_html(None, LOGO) } diff --git a/crates/web/src/lib.rs b/crates/web/src/main.rs similarity index 96% rename from crates/web/src/lib.rs rename to crates/web/src/main.rs index 60928744..2077cd14 100644 --- a/crates/web/src/lib.rs +++ b/crates/web/src/main.rs @@ -192,7 +192,7 @@ fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders) { })); } Ok(m) => { - log::info!("INCOMING {:?}", m); + tracing::info!("INCOMING {:?}", m); orders .skip() .send_msg(Msg::WebSocketChange(WebSocketChanged::WsMsg(m))); @@ -215,7 +215,7 @@ fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders) { }; if cfg!(debug_assertions) { - log::info!("msg {:?}", msg); + tracing::info!("msg {:?}", msg); } match &msg { @@ -326,17 +326,18 @@ fn resolve_page(url: Url) -> Option { Some(page) } -#[wasm_bindgen] -pub fn render() { +// #[wasm_bindgen(start)] +pub fn main() { let app = seed::App::start("app", init, update, view); - wasm_logger::init(if cfg!(debug_assertions) { - console_error_panic_hook::set_once(); - wasm_logger::Config::default() - } else { - wasm_logger::Config::new(log::Level::Error) - .message_on_new_line() - .module_prefix("bitque") - }); + console_error_panic_hook::set_once(); + { + use tracing_subscriber_wasm::MakeConsoleWriter; + tracing_subscriber::fmt::fmt() + .with_ansi(false) + .with_writer(MakeConsoleWriter::default().map_trace_level_to(tracing::Level::DEBUG)) + .without_time() + .init() + }; #[cfg(debug_assertions)] crate::shared::on_event::keydown(move |ev| { diff --git a/crates/web/src/modals/epics_edit/view.rs b/crates/web/src/modals/epics_edit/view.rs index 0bcee322..4ba2ac3a 100644 --- a/crates/web/src/modals/epics_edit/view.rs +++ b/crates/web/src/modals/epics_edit/view.rs @@ -1,6 +1,7 @@ use bitque_data::{EpicFieldId, IssueType}; use seed::prelude::*; use seed::*; +use strum::IntoEnumIterator; use crate::components::styled_button::*; use crate::components::styled_checkbox::*; @@ -80,9 +81,7 @@ pub fn view(_model: &model::Model, modal: &Model) -> Node { fn transform_into_available(modal: &super::Model) -> Node { let types = StyledCheckbox { options: Some( - IssueType::default() - .into_iter() - .map(|it| issue_type_select_option(it, &modal.transform_into)), + IssueType::iter().map(|it| issue_type_select_option(it, &modal.transform_into)), ), ..Default::default() } @@ -105,10 +104,10 @@ fn issue_type_select_option<'l>(ty: IssueType, state: &StyledCheckboxState) -> C let value: u32 = ty.into(); ChildBuilder { field_id: state.field_id.clone(), - name: ty.to_str(), + name: ty.as_str(), label: ty.to_label(), value: ty.into(), - class_list: ty.to_str(), + class_list: ty.as_str(), selected: value == state.value, ..Default::default() } diff --git a/crates/web/src/modals/issues_create/model.rs b/crates/web/src/modals/issues_create/model.rs index fb8ad0c6..c7b177cd 100644 --- a/crates/web/src/modals/issues_create/model.rs +++ b/crates/web/src/modals/issues_create/model.rs @@ -1,6 +1,6 @@ use bitque_data::{IssueFieldId, IssuePriority}; use derive_enum_iter::EnumIter; -use derive_enum_primitive::EnumPrimitive; +use derive_enum_primitive::*; use seed::prelude::*; use crate::components::styled_date_time_input::*; @@ -10,7 +10,7 @@ use crate::model::IssueModal; use crate::shared::validate::*; use crate::{FieldId, Msg}; -#[derive(Clone, Copy, EnumIter, EnumPrimitive)] +#[derive(Clone, Copy, EnumIter, EnumU32)] pub enum Type { Task, Bug, diff --git a/crates/web/src/modals/issues_create/view.rs b/crates/web/src/modals/issues_create/view.rs index 0b9994ba..e49b9da0 100644 --- a/crates/web/src/modals/issues_create/view.rs +++ b/crates/web/src/modals/issues_create/view.rs @@ -1,6 +1,7 @@ use bitque_data::{IssueFieldId, IssuePriority, User}; use seed::prelude::*; use seed::*; +use strum::IntoEnumIterator; use crate::components::styled_avatar::StyledAvatar; use crate::components::styled_button::{ButtonVariant, StyledButton}; @@ -327,7 +328,7 @@ fn assignee_select_option(user: &User) -> StyledSelectOption { } fn issue_priority_field(modal: &AddIssueModal) -> Node { - let priorities = IssuePriority::default().into_iter(); + let priorities = IssuePriority::iter(); let select_priority = StyledSelect { id: FieldId::AddIssueModal(IssueFieldId::Priority), name: "priority", @@ -354,13 +355,13 @@ fn priority_select_option<'l>(priority: IssuePriority) -> StyledSelectOption<'l> icon: Some( StyledIcon { icon: priority.into(), - class_list: priority.to_str(), + class_list: priority.as_str(), ..Default::default() } .render(), ), - text: Some(priority.to_str()), - class_list: priority.to_str(), + text: Some(priority.as_str()), + class_list: priority.as_str(), value: priority.into(), name: Some("priority"), ..Default::default() diff --git a/crates/web/src/modals/issues_edit/view.rs b/crates/web/src/modals/issues_edit/view.rs index 0519fa83..cb956f48 100644 --- a/crates/web/src/modals/issues_edit/view.rs +++ b/crates/web/src/modals/issues_edit/view.rs @@ -5,6 +5,7 @@ use bitque_data::{ use comments::*; use seed::prelude::*; use seed::*; +use strum::IntoEnumIterator; use crate::components::styled_avatar::StyledAvatar; use crate::components::styled_button::{ButtonVariant, StyledButton}; @@ -151,11 +152,7 @@ fn modal_header(_model: &Model, modal: &EditIssueModal) -> Node { dropdown_width: Some(150), valid: true, opened: top_type_state.opened, - options: Some( - IssueType::default() - .into_iter() - .map(|t| type_select_option(t, &text)), - ), + options: Some(IssueType::iter().map(|t| type_select_option(t, &text))), selected: vec![type_select_option(payload.issue_type, &text)], ..Default::default() } @@ -359,11 +356,7 @@ fn priorities_select( variant: SelectVariant::Empty, opened: priority_state.opened, text_filter: priority_state.text_filter.as_str(), - options: Some( - IssuePriority::default() - .into_iter() - .map(priority_select_option), - ), + options: Some(IssuePriority::iter().map(priority_select_option)), selected: vec![priority_select_option(payload.priority)], ..Default::default() } @@ -382,13 +375,13 @@ fn priority_select_option<'l>(ip: IssuePriority) -> StyledSelectOption<'l> { icon: Some( StyledIcon { icon: ip.into(), - class_list: ip.to_str(), + class_list: ip.as_str(), ..Default::default() } .render(), ), - text: Some(ip.to_str()), - class_list: ip.to_str(), + text: Some(ip.as_str()), + class_list: ip.as_str(), value: ip.into(), name: Some("priority"), ..Default::default() diff --git a/crates/web/src/modals/update.rs b/crates/web/src/modals/update.rs index 0d0cb12f..cafba1b4 100644 --- a/crates/web/src/modals/update.rs +++ b/crates/web/src/modals/update.rs @@ -1,6 +1,7 @@ use bitque_data::msg::WsMsgComment; use bitque_data::{CommentId, EpicId, IssueId, IssueStatusId, TimeTracking, WsMsg}; use seed::prelude::*; +use tracing::debug; use crate::model::{ModalType, Model, Page}; use crate::shared::go_to_board; @@ -51,7 +52,7 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders) { #[cfg(debug_assertions)] Msg::Debug(DebugMsg::Console) => { orders.skip(); - log::debug!("{:?}", model); + debug!("{:?}", model); } _ => (), diff --git a/crates/web/src/model.rs b/crates/web/src/model.rs index fbbc8b82..163cf961 100644 --- a/crates/web/src/model.rs +++ b/crates/web/src/model.rs @@ -2,7 +2,7 @@ use std::collections::hash_map::HashMap; use bitque_data::*; use seed::app::Orders; -use seed::browser::web_socket::WebSocket; +use seed::prelude::WebSocket; use serde::{Deserialize, Serialize}; use uuid::Uuid; diff --git a/crates/web/src/pages/issues_and_filters/view/filters.rs b/crates/web/src/pages/issues_and_filters/view/filters.rs index a4fc4c62..1d440d79 100644 --- a/crates/web/src/pages/issues_and_filters/view/filters.rs +++ b/crates/web/src/pages/issues_and_filters/view/filters.rs @@ -1,5 +1,6 @@ use seed::prelude::*; use seed::*; +use strum::IntoEnumIterator; use super::super::IssuesAndFiltersMsg; use crate::components::styled_button::ButtonVariant; @@ -86,40 +87,28 @@ fn options<'l, 'm: 'l>(model: &'m Model, jql: &Jql) -> Vec { - vec![ - bitque_data::IssuePriority::Lowest, - bitque_data::IssuePriority::Low, - bitque_data::IssuePriority::Medium, - bitque_data::IssuePriority::High, - bitque_data::IssuePriority::Highest, - ] - .into_iter() - .map(|u| StyledSelectOption { - name: Some("priority"), - icon: None, - text: Some(u.to_label()), - value: u.into(), - class_list: "", - variant: SelectVariant::Empty, - }) - .collect() + bitque_data::IssuePriority::iter() + .map(|u| StyledSelectOption { + name: Some("priority"), + icon: None, + text: Some(u.to_label()), + value: u.into(), + class_list: "", + variant: SelectVariant::Empty, + }) + .collect() } Some(JqlPartType::Op) if matches!(jql.field(), Some(JqlPart::Field(FieldOption::Type))) => { - vec![ - bitque_data::IssueType::Task, - bitque_data::IssueType::Bug, - bitque_data::IssueType::Story, - ] - .into_iter() - .map(|u| StyledSelectOption { - name: Some("type"), - icon: None, - text: Some(u.to_label()), - value: u.into(), - class_list: "", - variant: SelectVariant::Empty, - }) - .collect() + bitque_data::IssueType::iter() + .map(|u| StyledSelectOption { + name: Some("type"), + icon: None, + text: Some(u.to_label()), + value: u.into(), + class_list: "", + variant: SelectVariant::Empty, + }) + .collect() } Some(JqlPartType::Op) => { vec![field_select_option(model, 1, jql)] diff --git a/crates/web/src/pages/profile_page/view.rs b/crates/web/src/pages/profile_page/view.rs index 07901225..f68af253 100644 --- a/crates/web/src/pages/profile_page/view.rs +++ b/crates/web/src/pages/profile_page/view.rs @@ -185,7 +185,7 @@ fn editor_mode_checkbox_option<'l>( TextEditorMode::RteOnly => "Advanced Rich Text Editor", TextEditorMode::Mixed => "Editor with possibility to switch between modes", }, - class_list: tem.to_str(), + class_list: tem.as_str(), value, ..Default::default() } diff --git a/crates/web/src/pages/project_page/view/board.rs b/crates/web/src/pages/project_page/view/board.rs index 612dbef0..4b4cbc0d 100644 --- a/crates/web/src/pages/project_page/view/board.rs +++ b/crates/web/src/pages/project_page/view/board.rs @@ -123,16 +123,16 @@ impl<'l> ProjectIssue<'l> { let issue_type_icon = StyledIcon { icon: self.issue.issue_type.into(), - class_list: self.issue.issue_type.to_str(), - color: Some(self.issue.issue_type.to_str()), + class_list: self.issue.issue_type.as_str(), + color: Some(self.issue.issue_type.as_str()), ..Default::default() } .render(); let priority_icon = StyledIcon { icon: self.issue.priority.into(), - class_list: self.issue.priority.to_str(), - color: Some(self.issue.priority.to_str()), + class_list: self.issue.priority.as_str(), + color: Some(self.issue.priority.as_str()), ..Default::default() } .render(); diff --git a/crates/web/src/pages/project_settings_page/update.rs b/crates/web/src/pages/project_settings_page/update.rs index 3c1294de..bc19bcab 100644 --- a/crates/web/src/pages/project_settings_page/update.rs +++ b/crates/web/src/pages/project_settings_page/update.rs @@ -167,7 +167,7 @@ fn swap_position(bellow_id: IssueStatusId, model: &mut Model) { } let dragged_id = match page.column_drag.dragged_id.as_ref().cloned() { Some(id) => id, - _ => return log::error!("Nothing is dragged"), + _ => return tracing::error!("Nothing is dragged"), }; let bellow = model @@ -202,7 +202,7 @@ fn sync(model: &mut Model, orders: &mut impl Orders) { std::mem::swap(&mut old, &mut page.column_drag.dirty); old } - _ => return log::error!("bad content type"), + _ => return tracing::error!("bad content type"), }; for id in dirty { let IssueStatus { name, position, .. } = match model.issue_statuses_by_id.get(&id) { diff --git a/crates/web/src/pages/project_settings_page/view.rs b/crates/web/src/pages/project_settings_page/view.rs index 08fd73b3..ad735d4c 100644 --- a/crates/web/src/pages/project_settings_page/view.rs +++ b/crates/web/src/pages/project_settings_page/view.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use bitque_data::{IssueStatus, ProjectCategory, TimeTracking}; use seed::prelude::*; use seed::*; +use strum::IntoEnumIterator; use crate::components::styled_button::{ButtonVariant, StyledButton}; use crate::components::styled_checkbox::{ChildBuilder, StyledCheckbox, StyledCheckboxState}; @@ -71,9 +72,7 @@ pub fn view(model: &model::Model) -> Node { fn time_tracking_select(page: &ProjectSettingsPage) -> Node { let time_tracking = StyledCheckbox { options: Some( - TimeTracking::default() - .into_iter() - .map(|tt| time_tracking_checkbox_option(tt, &page.time_tracking)), + TimeTracking::iter().map(|tt| time_tracking_checkbox_option(tt, &page.time_tracking)), ), class_list: "timeTracking", } @@ -171,11 +170,7 @@ fn category_field(page: &ProjectSettingsPage) -> Node { text_filter: page.project_category_state.text_filter.as_str(), valid: true, variant: SelectVariant::Normal, - options: Some( - ProjectCategory::default() - .into_iter() - .map(category_select_option), - ), + options: Some(ProjectCategory::iter().map(category_select_option)), selected: vec![category_select_option( page.payload.category.as_ref().cloned().unwrap_or_default(), )], @@ -193,8 +188,8 @@ fn category_field(page: &ProjectSettingsPage) -> Node { #[inline(always)] fn category_select_option<'l>(pc: ProjectCategory) -> StyledSelectOption<'l> { StyledSelectOption { - class_list: pc.to_str(), - text: Some(pc.to_str()), + class_list: pc.as_str(), + text: Some(pc.as_str()), value: pc.into(), ..Default::default() } diff --git a/crates/web/src/pages/reports_page/model.rs b/crates/web/src/pages/reports_page/model.rs index 0c8a06c8..a1b368a7 100644 --- a/crates/web/src/pages/reports_page/model.rs +++ b/crates/web/src/pages/reports_page/model.rs @@ -11,7 +11,7 @@ pub struct ReportsPage { impl Default for ReportsPage { fn default() -> Self { - let first_day = chrono::Utc::today().with_day(1).unwrap().naive_local(); + let first_day = chrono::Utc::now().date_naive().with_day(1).unwrap(); let last_day = (first_day + chrono::Duration::days(32)) .with_day(1) .unwrap() diff --git a/crates/web/src/pages/reports_page/view.rs b/crates/web/src/pages/reports_page/view.rs index 74d21bf9..ff9849bc 100644 --- a/crates/web/src/pages/reports_page/view.rs +++ b/crates/web/src/pages/reports_page/view.rs @@ -205,7 +205,7 @@ fn issue_list(page: &ReportsPage, project_name: &str, this_month_updated: &[&Iss .render(); let priority_icon = StyledIcon::from(Icon::from(*priority)) .render(); - let desc = Node::from_html( + let desc = Node::from_html(None, description .as_deref() .unwrap_or_default(), diff --git a/crates/web/src/pages/users_page/view.rs b/crates/web/src/pages/users_page/view.rs index 4036117f..7cb5ca31 100644 --- a/crates/web/src/pages/users_page/view.rs +++ b/crates/web/src/pages/users_page/view.rs @@ -1,6 +1,7 @@ use bitque_data::{InvitationState, UserRole, UsersFieldId}; use seed::prelude::*; use seed::*; +use strum::IntoEnumIterator; use crate::components::styled_button::{ButtonVariant, StyledButton}; use crate::components::styled_field::StyledField; @@ -147,7 +148,7 @@ pub fn view(model: &Model) -> Node { // .build() // .render(); li![ - C!["invitation", invitation.state.to_str()], + C!["invitation", invitation.state.as_str()], span![invitation.name.as_str()], span![invitation.email.as_str()], span![format!("{}", invitation.state)], @@ -175,7 +176,7 @@ fn user_role_select(page: &UsersPage) -> Node { text_filter: page.user_role_state.text_filter.as_str(), opened: page.user_role_state.opened, selected: vec![user_role_select_option(page.user_role)], - options: Some(UserRole::default().into_iter().map(user_role_select_option)), + options: Some(UserRole::iter().map(user_role_select_option)), ..Default::default() } .render(); @@ -188,7 +189,7 @@ fn user_role_select(page: &UsersPage) -> Node { } fn user_role_select_option<'l>(ur: UserRole) -> StyledSelectOption<'l> { - let name = ur.to_str(); + let name = ur.into(); StyledSelectOption { text: Some(name), diff --git a/crates/web/src/ws/mod.rs b/crates/web/src/ws/mod.rs index 3d8a9e4b..1663c5bd 100644 --- a/crates/web/src/ws/mod.rs +++ b/crates/web/src/ws/mod.rs @@ -6,6 +6,7 @@ use bitque_data::msg::{ }; use bitque_data::*; pub use init_load_sets::*; +use seed::browser::web_socket::State; use seed::prelude::*; use crate::model::*; @@ -18,7 +19,6 @@ mod init_load_sets; pub mod issue; pub fn flush_queue(model: &mut Model, orders: &mut impl Orders) { - use seed::browser::web_socket::State; match model.ws.as_ref() { Some(ws) if ws.state() != State::Open => return, None => return, @@ -38,7 +38,6 @@ pub fn enqueue_ws_msg(v: Vec, ws: Option<&WebSocket>, orders: &mut impl O } pub fn send_ws_msg(msg: WsMsg, ws: Option<&WebSocket>, orders: &mut impl Orders) { - use seed::browser::web_socket::State; let ws = match ws { Some(ws) if ws.state() == State::Open => ws, _ => { @@ -50,15 +49,14 @@ pub fn send_ws_msg(msg: WsMsg, ws: Option<&WebSocket>, orders: &mut impl Orders< }; let binary = bincode::serialize(&msg).unwrap_or_default(); if let Err(e) = ws.send_bytes(binary.as_slice()) { - log::error!("Failed to send ws msg. {:?}", e); + tracing::error!("Failed to send ws msg. {:?}", e); } } pub fn open_socket(model: &mut Model, orders: &mut impl Orders) { - use seed::browser::web_socket::State; use seed::prelude::*; - use seed::*; - log::warn!("{:?}", model.ws.as_ref().map(|ws| ws.state())); + + tracing::warn!("{:?}", model.ws.as_ref().map(|ws| ws.state())); match model.ws.as_ref() { Some(ws) if ws.state() != State::Closed => { @@ -78,12 +76,12 @@ pub fn open_socket(model: &mut Model, orders: &mut impl Orders) { ))) }) .on_open(|| { - log::info!("open_socket opened"); + tracing::info!("open_socket opened"); Some(Msg::WebSocketChange(WebSocketChanged::WebSocketOpened)) }) .on_close(|_| Some(Msg::WebSocketChange(WebSocketChanged::WebSocketClosed))) .on_error(|| { - error!("Failed to open WebSocket"); + tracing::error!("Failed to open WebSocket"); None as Option }) // .protocols(&["bitque"]) @@ -127,7 +125,7 @@ pub fn update(msg: &mut WsMsg, model: &mut Model, orders: &mut impl Orders) )); } WsMsg::Session(WsMsgSession::AuthorizeExpired) => { - log::warn!("Received token expired"); + tracing::warn!("Received token expired"); if let Ok(msg) = write_auth_token(None) { orders.skip().send_msg(msg).send_msg(Msg::ResourceChanged( ResourceKind::Auth, @@ -475,7 +473,7 @@ pub fn update(msg: &mut WsMsg, model: &mut Model, orders: &mut impl Orders) orders.skip().send_msg(msg); } Err(e) => { - log::error!("{}", e); + tracing::error!("{}", e); } } } @@ -483,7 +481,7 @@ pub fn update(msg: &mut WsMsg, model: &mut Model, orders: &mut impl Orders) orders.send_msg(Msg::InvalidPair); } _ => { - log::info!( + tracing::info!( "got web socket message but don't know what to do with it {:?}", msg ); diff --git a/crates/web/static/index.js b/crates/web/static/index.js deleted file mode 100644 index 67160a41..00000000 --- a/crates/web/static/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import("/bitque.js").then(async module => { - // window.module = module; - await module.default(); - module.render(); - document.querySelector('main').className = ''; - const spinner = document.querySelector('.spinner'); - spinner && spinner.remove(); -}); diff --git a/crates/web/tailwind.config.js b/crates/web/tailwind.config.js new file mode 100644 index 00000000..eac1012a --- /dev/null +++ b/crates/web/tailwind.config.js @@ -0,0 +1,8 @@ +module.exports = { + mode: 'jit', + purge: [ + "src/**/*.rs" + ], + darkMode: 'media', // or 'media' or 'class' + plugins: [], +} diff --git a/crates/websocket-actor/src/lib.rs b/crates/websocket-actor/src/lib.rs index e7005ee1..654d05f5 100644 --- a/crates/websocket-actor/src/lib.rs +++ b/crates/websocket-actor/src/lib.rs @@ -18,10 +18,10 @@ pub mod handlers; pub mod prelude; pub mod server; -pub type WsResult = std::result::Result, WsMsg>; +pub type WsResult = Result, WsMsg>; trait WsMessageSender { - fn send_msg(&mut self, msg: &bitque_data::WsMsg); + fn send_msg(&mut self, msg: &WsMsg); } pub struct WebSocketActor { @@ -29,14 +29,14 @@ pub struct WebSocketActor { mail: Data>, addr: Addr, hi: Data>, - current_user: Option, - current_user_project: Option, - current_project: Option, + current_user: Option, + current_user_project: Option, + current_project: Option, } pub type WsCtx = ws::WebsocketContext; -impl actix::Actor for WebSocketActor { +impl Actor for WebSocketActor { type Context = WsCtx; } @@ -44,7 +44,7 @@ impl WsMessageSender for ws::WebsocketContext { fn send_msg(&mut self, msg: &WsMsg) { match bincode::serialize(msg) { Err(err) => { - ::tracing::error!("{}", err); + error!("{}", err); } Ok(v) => self.binary(v), } @@ -111,7 +111,7 @@ impl WebSocketActor { WsMsg::Session(m) => self.exec(m), // hi - WsMsg::HighlightCode(lang, code) => self.exec(hi::HighlightCode(lang, code)), + WsMsg::HighlightCode(lang, code) => self.exec(HighlightCode(lang, code)), // else fail _ => { @@ -144,8 +144,8 @@ impl WebSocketActor { .send(InnerMsg::Join(project_id, user.id, addr)) .await { - Err(e) => ::tracing::error!("{:?}", e), - _ => ::tracing::info!(" joined channel"), + Err(e) => error!("{:?}", e), + _ => info!(" joined channel"), }; } @@ -203,8 +203,7 @@ impl StreamHandler> for WebSocketActor { Ok(ws::Message::Text(text)) => ctx.text(text), Ok(ws::Message::Binary(bin)) => { - let ws_msg: bincode::Result = - bincode::deserialize(bin.to_vec().as_slice()); + let ws_msg: bincode::Result = bincode::deserialize(bin.to_vec().as_slice()); let msg = match ws_msg { Ok(m) => m, _ => return, @@ -237,7 +236,7 @@ impl StreamHandler> for WebSocketActor { pub trait WsHandler where - Self: actix::Actor, + Self: Actor, { fn handle_msg(&mut self, msg: Message, _ctx: &mut ::Context) -> WsResult; } @@ -245,7 +244,7 @@ where #[async_trait::async_trait] pub trait AsyncHandler where - Self: actix::Actor, + Self: Actor, { async fn exec(&mut self, msg: Message) -> WsResult; } diff --git a/docker-compose.yml b/docker-compose.yml index f03b3d21..c68402da 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,14 +1,27 @@ version: '3.0' +volumes: + uploads: services: app: build: dockerfile: Dockerfile.build + context: . + volumes: + - ./docker/boot-server.sh:/usr/bin/boot-bitque + - ./docker/config:/app/config + - ./migrations:/app/migrations + - uploads:/app/uploads + depends_on: + - postgresql + - minio + postgresql: + image: postgres:latest + environment: + POSTGRES_DB: bitque + POSTGRES_HOST_AUTH_METHOD: trust minio: image: docker.io/bitnami/minio:2023 - ports: - - '9000:9000' - - '9001:9001' environment: - MINIO_ROOT_USER=minio - MINIO_ROOT_PASSWORD=miniosecret diff --git a/docker/Dockerfile.build b/docker/Dockerfile.build new file mode 100644 index 00000000..18644040 --- /dev/null +++ b/docker/Dockerfile.build @@ -0,0 +1,22 @@ +FROM archlinux:latest as diesel +WORKDIR /app/ +RUN pacman -Syu --noconfirm curl git openssl postgresql gcc openssl make cmake rustup +RUN rustup default nightly +RUN cargo install diesel_cli --no-default-features --features postgres +RUN cp ~/.cargo/bin/diesel /usr/bin/diesel + +FROM archlinux:latest as build-app +WORKDIR /app/ +RUN pacman -Syu --noconfirm curl git openssl postgresql gcc openssl make cmake rustup +RUN rustup default nightly +COPY . . +RUN cargo install --no-default-features --features local-storage --path ./crates/bitque-server +RUN cp ~/.cargo/bin/bitque /usr/bin/bitque + +FROM archlinux:latest +WORKDIR /app/ +RUN pacman -Syu --noconfirm curl git openssl postgresql gcc openssl make cmake rustup + +COPY --from=diesel /usr/bin/diesel /usr/bin/diesel +COPY --from=build-app /usr/bin/bitque /usr/bin/bitque +CMD boot-bitque diff --git a/docker/boot-server.sh b/docker/boot-server.sh new file mode 100755 index 00000000..9a7613a6 --- /dev/null +++ b/docker/boot-server.sh @@ -0,0 +1,5 @@ +cd /app + +psql postgres -U postgres -h postgresql -c 'CREATE DATABASE bitque' || echo "DB OK" +diesel migration run --database-url postgres://postgres@postgresql/bitque +bitque diff --git a/docker/config/db.toml b/docker/config/db.toml new file mode 100644 index 00000000..1468b147 --- /dev/null +++ b/docker/config/db.toml @@ -0,0 +1,2 @@ +concurrency = 2 +database_url = "postgres://postgres@postgresql/bitque" diff --git a/docker/config/fs.toml b/docker/config/fs.toml new file mode 100644 index 00000000..dacdf61b --- /dev/null +++ b/docker/config/fs.toml @@ -0,0 +1,5 @@ +store_path = "./uploads" +client_path = "/uploads" +tmp_path = "/tmp" +concurrency = 2 +active = true diff --git a/docker/config/highlight.toml b/docker/config/highlight.toml new file mode 100644 index 00000000..f4e8d8f1 --- /dev/null +++ b/docker/config/highlight.toml @@ -0,0 +1,2 @@ +concurrency = 2 +theme = "Github" diff --git a/docker/config/mail.toml b/docker/config/mail.toml new file mode 100644 index 00000000..28a3762d --- /dev/null +++ b/docker/config/mail.toml @@ -0,0 +1,5 @@ +concurrency = 2 +user = "apikey" +pass = "YOUR-TOKEN" +host = "smtp.sendgrid.net" +from = "contact@bitque.pl" diff --git a/docker/config/web.toml b/docker/config/web.toml new file mode 100644 index 00000000..9ba2961a --- /dev/null +++ b/docker/config/web.toml @@ -0,0 +1,4 @@ +concurrency = 2 +port = "5000" +bind = "0.0.0.0" +ssl = false diff --git a/migrations/2020-05-21-051229_multi_project_users/up.sql b/migrations/2020-05-21-051229_multi_project_users/up.sql index 39657662..9a963a0c 100644 --- a/migrations/2020-05-21-051229_multi_project_users/up.sql +++ b/migrations/2020-05-21-051229_multi_project_users/up.sql @@ -1,5 +1,3 @@ -BEGIN; - DROP TABLE IF EXISTS user_projects CASCADE; CREATE TABLE user_projects ( id serial primary key not null, @@ -18,5 +16,3 @@ FROM users; ALTER TABLE users DROP COLUMN role; ALTER TABLE users DROP COLUMN project_id; - -COMMIT;