diff --git a/repertory/repertory/include/ui/handlers.hpp b/repertory/repertory/include/ui/handlers.hpp index 2cf091b5..4073140b 100644 --- a/repertory/repertory/include/ui/handlers.hpp +++ b/repertory/repertory/include/ui/handlers.hpp @@ -71,6 +71,8 @@ private: void handle_put_set_value_by_name(auto &&req, auto &&res) const; + void handle_put_settings(auto &&req, auto &&res) const; + auto launch_process(provider_type prov, std::string_view name, std::string_view args, bool background = false) const -> std::vector; diff --git a/repertory/repertory/include/ui/mgmt_app_config.hpp b/repertory/repertory/include/ui/mgmt_app_config.hpp index 48e8886a..1b1f5f77 100644 --- a/repertory/repertory/include/ui/mgmt_app_config.hpp +++ b/repertory/repertory/include/ui/mgmt_app_config.hpp @@ -56,8 +56,12 @@ public: std::string_view name) const -> std::string; + void set_api_password(std::string_view api_password); + void set_api_port(std::uint16_t api_port); + void set_api_user(std::string_view api_user); + void set_mount_location(provider_type prov, std::string_view name, std::string_view location); }; diff --git a/repertory/repertory/src/ui/handlers.cpp b/repertory/repertory/src/ui/handlers.cpp index a4d7a593..ad85a510 100644 --- a/repertory/repertory/src/ui/handlers.cpp +++ b/repertory/repertory/src/ui/handlers.cpp @@ -118,6 +118,10 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server) handle_put_set_value_by_name(req, res); }); + server->Put("/api/v1/settings", [this](auto &&req, auto &&res) { + handle_put_settings(req, res); + }); + static std::atomic this_server{server_}; static const auto quit_handler = [](int /* sig */) { auto *ptr = this_server.load(); @@ -385,6 +389,25 @@ void handlers::handle_put_set_value_by_name(auto &&req, auto &&res) const { res.status = http_error_codes::ok; } +void handlers::handle_put_settings(auto &&req, auto &&res) const { + nlohmann::json data = nlohmann::json::parse(req.get_param_value("data")); + + if (data.contains(JSON_API_PASSWORD)) { + config_->set_api_password(data.at(JSON_API_PASSWORD).get()); + } + + if (data.contains(JSON_API_PORT)) { + config_->set_api_port( + utils::string::to_uint16(data.at(JSON_API_PORT).get())); + } + + if (data.contains(JSON_API_USER)) { + config_->set_api_user(data.at(JSON_API_USER).get()); + } + + res.status = http_error_codes::ok; +} + auto handlers::launch_process(provider_type prov, std::string_view name, std::string_view args, bool background) const -> std::vector { diff --git a/repertory/repertory/src/ui/mgmt_app_config.cpp b/repertory/repertory/src/ui/mgmt_app_config.cpp index 21bc842a..3a493ec6 100644 --- a/repertory/repertory/src/ui/mgmt_app_config.cpp +++ b/repertory/repertory/src/ui/mgmt_app_config.cpp @@ -147,6 +147,15 @@ void mgmt_app_config::save() const { } } +void mgmt_app_config::set_api_password(std::string_view api_password) { + if (api_password_ == std::string{api_password}) { + return; + } + + api_password_ = std::string{api_password}; + save(); +} + void mgmt_app_config::set_api_port(std::uint16_t api_port) { if (api_port_ == api_port) { return; @@ -156,6 +165,15 @@ void mgmt_app_config::set_api_port(std::uint16_t api_port) { save(); } +void mgmt_app_config::set_api_user(std::string_view api_user) { + if (api_user_ == std::string{api_user}) { + return; + } + + api_user_ = std::string{api_user}; + save(); +} + void mgmt_app_config::set_mount_location(provider_type prov, std::string_view name, std::string_view location) { diff --git a/web/repertory/lib/constants.dart b/web/repertory/lib/constants.dart index 9d6547fa..a65521a9 100644 --- a/web/repertory/lib/constants.dart +++ b/web/repertory/lib/constants.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' show GlobalKey, NavigatorState; const addMountTitle = 'Add New Mount'; +const appSettingsTitle = 'Portal Settings'; const appTitle = 'Repertory Management Portal'; const databaseTypeList = ['rocksdb', 'sqlite']; const downloadTypeList = ['default', 'direct', 'ring_buffer']; diff --git a/web/repertory/lib/main.dart b/web/repertory/lib/main.dart index 0ac99633..4e2067ec 100644 --- a/web/repertory/lib/main.dart +++ b/web/repertory/lib/main.dart @@ -52,7 +52,8 @@ class _MyAppState extends State { '/add': (context) => const AddMountScreen(title: constants.addMountTitle), '/settings': - (context) => const EditSettingsScreen(title: constants.appTitle), + (context) => + const EditSettingsScreen(title: constants.appSettingsTitle), }, onGenerateRoute: (settings) { if (settings.name != '/edit') { diff --git a/web/repertory/lib/widgets/ui_settings.dart b/web/repertory/lib/widgets/ui_settings.dart index 194fcaec..137ee661 100644 --- a/web/repertory/lib/widgets/ui_settings.dart +++ b/web/repertory/lib/widgets/ui_settings.dart @@ -1,21 +1,23 @@ +import 'dart:convert' show jsonDecode, jsonEncode; + import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:repertory/constants.dart' as constants; +import 'package:http/http.dart' as http; import 'package:repertory/helpers.dart' - show getSettingDescription, getSettingValidators, trimNotEmptyValidator; -import 'package:repertory/models/mount.dart'; -import 'package:repertory/models/mount_list.dart'; + show + convertAllToString, + getBaseUri, + getSettingDescription, + getSettingValidators, + trimNotEmptyValidator; import 'package:repertory/settings.dart'; import 'package:settings_ui/settings_ui.dart'; class UISettingsWidget extends StatefulWidget { final bool showAdvanced; - final Function? onChanged; final Map settings; const UISettingsWidget({ super.key, - this.onChanged, required this.settings, required this.showAdvanced, }); @@ -25,6 +27,8 @@ class UISettingsWidget extends StatefulWidget { } class _UISettingsWidgetState extends State { + late Map _origSettings; + @override Widget build(BuildContext context) { List commonSettings = []; @@ -94,6 +98,32 @@ class _UISettingsWidgetState extends State { ); } + @override + void dispose() { + if (!DeepCollectionEquality().equals(widget.settings, _origSettings)) { + http + .put( + Uri.parse( + Uri.encodeFull( + '${getBaseUri()}/api/v1/settings?data=${convertAllToString(widget.settings)})', + ), + ), + ) + .then((_) {}) + .catchError((e) { + debugPrint('$e'); + }); + } + + super.dispose(); + } + + @override + void initState() { + _origSettings = jsonDecode(jsonEncode(widget.settings)); + super.initState(); + } + @override void setState(VoidCallback fn) { if (!mounted) {