diff --git a/lib/config/get_it_config.dart b/lib/config/get_it_config.dart index e00ed9be7e..931adfa266 100644 --- a/lib/config/get_it_config.dart +++ b/lib/config/get_it_config.dart @@ -1,8 +1,10 @@ import 'package:get_it/get_it.dart'; import 'package:selfprivacy/logic/get_it/console.dart'; +import 'package:selfprivacy/logic/get_it/timer.dart'; final getIt = GetIt.instance; void getItSetup() { - getIt.registerSingleton(ConsoleModelImplementation()); + getIt.registerSingleton(ConsoleModel()); + getIt.registerSingleton(TimerModel()); } diff --git a/lib/logic/api_maps/hetzner.dart b/lib/logic/api_maps/hetzner.dart index 328c8f2611..432b26c0be 100644 --- a/lib/logic/api_maps/hetzner.dart +++ b/lib/logic/api_maps/hetzner.dart @@ -10,8 +10,10 @@ import 'package:selfprivacy/logic/models/user.dart'; class HetznerApi extends ApiMap { HetznerApi([String token]) { if (token != null) { - loggedClient.options = - BaseOptions(headers: {'Authorization': 'Bearer $token'}); + loggedClient.options = BaseOptions( + headers: {'Authorization': 'Bearer $token'}, + baseUrl: rootAddress, + ); } } @@ -42,7 +44,7 @@ class HetznerApi extends ApiMap { @required String domainName, }) async { var data = jsonDecode( - '''{"name":"selfprivacy-server","server_type":"cx11","start_after_create":true,"image":"ubuntu-20.04", "volumes":[],"networks":[],"user_data":"#cloud-config\\nruncmd:\\n- curl https://git.selfprivacy.org/ilchub/selfprivacy-nixos-infect/raw/branch/master/nixos-infect | PROVIDER=hetzner NIX_CHANNEL=nixos-20.09 DOMAIN=$domainName USER=${rootUser.login} PASSWORD=${rootUser.password} HASHED_PASSWORD=${rootUser.hashPassword} bash 2>&1 | tee /tmp/infect.log","labels":{},"automount":false}'''); + '''{"name":"selfprivacy-server","server_type":"cx11","start_after_create":false,"image":"ubuntu-20.04", "volumes":[],"networks":[],"user_data":"#cloud-config\\nruncmd:\\n- curl https://git.selfprivacy.org/ilchub/selfprivacy-nixos-infect/raw/branch/master/nixos-infect | PROVIDER=hetzner NIX_CHANNEL=nixos-20.09 DOMAIN=$domainName USER=${rootUser.login} PASSWORD=${rootUser.password} HASHED_PASSWORD=${rootUser.hashPassword} bash 2>&1 | tee /tmp/infect.log","labels":{},"automount":false}'''); Response response = await loggedClient.post( rootAddress, @@ -52,6 +54,16 @@ class HetznerApi extends ApiMap { return HetznerServerDetails( id: response.data['server']['id'], ip4: response.data['server']['public_net']['ipv4']['ip'], + createTime: DateTime.now(), + ); + } + + Future startServer({ + HetznerServerDetails server, + }) async { + await loggedClient.post('/${server.id}/actions/poweron'); + + return server.copyWith( startTime: DateTime.now(), ); } diff --git a/lib/logic/cubit/app_config/app_config_cubit.dart b/lib/logic/cubit/app_config/app_config_cubit.dart index 7a99de3e41..390693e4db 100644 --- a/lib/logic/cubit/app_config/app_config_cubit.dart +++ b/lib/logic/cubit/app_config/app_config_cubit.dart @@ -11,6 +11,7 @@ import 'package:selfprivacy/logic/models/message.dart'; import 'package:selfprivacy/logic/models/server_details.dart'; import 'package:selfprivacy/logic/models/user.dart'; import 'package:basic_utils/basic_utils.dart'; +import 'package:selfprivacy/config/get_it_config.dart'; part 'app_config_state.dart'; @@ -27,7 +28,7 @@ class AppConfigCubit extends Cubit { domain: box.get(BNames.domain), rootUser: box.get(BNames.rootUser), hetznerServer: box.get(BNames.hetznerServer), - isDnsCheckedAndDkimSet: box.get(BNames.isDnsCheckedAndDkimSet), + serverStarted: box.get(BNames.isDnsCheckedAndDkimSet), ), ); } @@ -77,13 +78,13 @@ class AppConfigCubit extends Cubit { getIt.get().addMessage( Message( text: - 'DnsLookup: address:$address, $RRecordType, provider: CLOUDFLARE', + 'DnsLookup: address: $address, $RRecordType, provider: CLOUDFLARE, ip4: $ip4', ), ); getIt.get().addMessage( Message( text: - 'DnsLookup: address:$address, $RRecordType, provider: CLOUDFLARE', + 'DnsLookup: ${res.isEmpty ? (res[0].data != ip4 ? 'wrong ip4' : 'right ip4') : 'empty'}', ), ); if (res.isEmpty || res[0].data != ip4) { @@ -92,10 +93,26 @@ class AppConfigCubit extends Cubit { } } if (hasError) { - emit(state.copyWith(error: Exception('dns cloudflare checking error'))); + emit(state.copyWith(lastDnsCheckTime: DateTime.now())); } else { - print('check complete'); + var hetznerApi = HetznerApi(state.hetznerKey); + + var serverDetails = await hetznerApi.startServer(server: state.server); + + await box.put(BNames.hetznerServer, serverDetails); + + hetznerApi.close(); + + emit( + state.copyWith( + serverStarted: true, + isLoading: false, + hetznerServer: serverDetails, + ), + ); } + + print('check complete: $hasError, time:' + DateTime.now().toString()); } void createServer() async { diff --git a/lib/logic/cubit/app_config/app_config_state.dart b/lib/logic/cubit/app_config/app_config_state.dart index 8faab83b1b..80d7e25610 100644 --- a/lib/logic/cubit/app_config/app_config_state.dart +++ b/lib/logic/cubit/app_config/app_config_state.dart @@ -7,9 +7,10 @@ class AppConfigState extends Equatable { this.cloudFlareDomain, this.rootUser, this.server, - this.isDnsCheckedAndDkimSet = false, + this.isDnsChecked = false, this.isLoading = false, this.error, + this.lastDnsCheckTime, }); @override @@ -19,9 +20,10 @@ class AppConfigState extends Equatable { cloudFlareDomain, rootUser, server, - isDnsCheckedAndDkimSet, + isDnsChecked, isLoading, - error + error, + lastDnsCheckTime ]; final String hetznerKey; @@ -29,7 +31,8 @@ class AppConfigState extends Equatable { final CloudFlareDomain cloudFlareDomain; final User rootUser; final HetznerServerDetails server; - final bool isDnsCheckedAndDkimSet; + final bool isDnsChecked; + final DateTime lastDnsCheckTime; final bool isLoading; final Exception error; @@ -40,10 +43,10 @@ class AppConfigState extends Equatable { CloudFlareDomain domain, User rootUser, HetznerServerDetails hetznerServer, - bool isDnsCheckedAndDkimSet, + bool serverStarted, bool isLoading, - DateTime serverInitStart, Exception error, + DateTime lastDnsCheckTime, }) => AppConfigState( hetznerKey: hetznerKey ?? this.hetznerKey, @@ -51,10 +54,10 @@ class AppConfigState extends Equatable { cloudFlareDomain: domain ?? this.cloudFlareDomain, rootUser: rootUser ?? this.rootUser, server: hetznerServer ?? this.server, - isDnsCheckedAndDkimSet: - isDnsCheckedAndDkimSet ?? this.isDnsCheckedAndDkimSet, + isDnsChecked: serverStarted ?? this.isDnsChecked, isLoading: isLoading ?? this.isLoading, error: error ?? this.error, + lastDnsCheckTime: lastDnsCheckTime ?? this.lastDnsCheckTime, ); bool get isHetznerFilled => hetznerKey != null; @@ -73,7 +76,7 @@ class AppConfigState extends Equatable { isDomainFilled, isUserFilled, isServerFilled, - isDnsCheckedAndDkimSet, + isDnsChecked, ]; } diff --git a/lib/logic/get_it/console.dart b/lib/logic/get_it/console.dart index 53a547a165..80dc5a371b 100644 --- a/lib/logic/get_it/console.dart +++ b/lib/logic/get_it/console.dart @@ -1,19 +1,11 @@ import 'package:flutter/material.dart'; import 'package:selfprivacy/logic/models/message.dart'; -abstract class ConsoleModel extends ChangeNotifier { - void addMessage(Message message); - - List get messages; -} - -class ConsoleModelImplementation extends ConsoleModel { +class ConsoleModel extends ChangeNotifier { List _messages = []; - @override List get messages => _messages; - @override void addMessage(Message message) { messages.add(message); notifyListeners(); diff --git a/lib/logic/get_it/timer.dart b/lib/logic/get_it/timer.dart new file mode 100644 index 0000000000..0444b44edb --- /dev/null +++ b/lib/logic/get_it/timer.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +class TimerModel extends ChangeNotifier { + DateTime _time = DateTime.now(); + + DateTime get messages => _time; + + void restart() { + _time = DateTime.now(); + notifyListeners(); + } +} diff --git a/lib/logic/models/server_details.dart b/lib/logic/models/server_details.dart index 0c887ddad3..fd51d30fa0 100644 --- a/lib/logic/models/server_details.dart +++ b/lib/logic/models/server_details.dart @@ -8,7 +8,8 @@ class HetznerServerDetails { HetznerServerDetails({ @required this.ip4, @required this.id, - @required this.startTime, + @required this.createTime, + this.startTime, }); @HiveField(0) @@ -20,5 +21,17 @@ class HetznerServerDetails { @HiveField(2) final DateTime startTime; + @HiveField(3) + final DateTime createTime; + + HetznerServerDetails copyWith({DateTime startTime}) { + return HetznerServerDetails( + startTime: startTime ?? this.startTime, + createTime: createTime, + id: id, + ip4: ip4, + ); + } + String toString() => id.toString(); } diff --git a/lib/logic/models/server_details.g.dart b/lib/logic/models/server_details.g.dart index 4148911f96..8561c135ab 100644 --- a/lib/logic/models/server_details.g.dart +++ b/lib/logic/models/server_details.g.dart @@ -19,6 +19,7 @@ class HetznerServerDetailsAdapter extends TypeAdapter { return HetznerServerDetails( ip4: fields[0] as String, id: fields[1] as int, + createTime: fields[3] as DateTime, startTime: fields[2] as DateTime, ); } @@ -26,13 +27,15 @@ class HetznerServerDetailsAdapter extends TypeAdapter { @override void write(BinaryWriter writer, HetznerServerDetails obj) { writer - ..writeByte(3) + ..writeByte(4) ..writeByte(0) ..write(obj.ip4) ..writeByte(1) ..write(obj.id) ..writeByte(2) - ..write(obj.startTime); + ..write(obj.startTime) + ..writeByte(3) + ..write(obj.createTime); } @override diff --git a/lib/main.dart b/lib/main.dart index 083ccf4a69..eb76d4646b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,6 +6,8 @@ import 'package:selfprivacy/ui/pages/initializing/initializing.dart'; import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:selfprivacy/ui/pages/rootRoute.dart'; +import 'package:wakelock/wakelock.dart'; + import 'config/bloc_config.dart'; import 'config/bloc_observer.dart'; import 'config/brand_theme.dart'; @@ -18,6 +20,7 @@ final navigatorKey = GlobalKey(); void main() async { await HiveConfig.init(); Bloc.observer = SimpleBlocObserver(navigatorKey: navigatorKey); + Wakelock.enable(); getItSetup(); WidgetsFlutterBinding.ensureInitialized(); diff --git a/lib/ui/components/brand_timer/brand_timer.dart b/lib/ui/components/brand_timer/brand_timer.dart index 7dc21c86a6..2dd67cdca7 100644 --- a/lib/ui/components/brand_timer/brand_timer.dart +++ b/lib/ui/components/brand_timer/brand_timer.dart @@ -26,6 +26,11 @@ class _BrandTimerState extends State { @override void initState() { + _timerStart(); + super.initState(); + } + + _timerStart() { _timeString = diffenceFromStart; timer = Timer.periodic(Duration(seconds: 1), (Timer t) { var timePassed = DateTime.now().difference(widget.startDateTime); @@ -36,7 +41,15 @@ class _BrandTimerState extends State { _getTime(); } }); - super.initState(); + } + + @override + void didUpdateWidget(BrandTimer oldWidget) { + if (timer.isActive) { + timer.cancel(); + } + _timerStart(); + super.didUpdateWidget(oldWidget); } @override @@ -60,10 +73,9 @@ class _BrandTimerState extends State { String _durationToString(Duration duration) { String twoDigits(int n) => n.toString().padLeft(2, "0"); - String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60)); - String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60)); + String twoDigitSeconds = twoDigits(60 - duration.inSeconds.remainder(60)); - return "$twoDigitMinutes:$twoDigitSeconds"; + return "$twoDigitSeconds cек"; } @override diff --git a/lib/ui/pages/initializing/initializing.dart b/lib/ui/pages/initializing/initializing.dart index 51fa5fc763..46d8555478 100644 --- a/lib/ui/pages/initializing/initializing.dart +++ b/lib/ui/pages/initializing/initializing.dart @@ -287,33 +287,27 @@ class InitializingPage extends StatelessWidget { Widget _stepCheck(AppConfigCubit appConfigCubit) { var state = appConfigCubit.state; - var error = state.error; return Builder(builder: (context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Spacer(flex: 2), - BrandText.h2(error == null ? 'Создание началось' : 'Error'), SizedBox(height: 10), - error == null - ? BrandText.body2( - 'Мы начали процесс инциализации сервера, через 10 минут, мы проверим правильность DNS записей, и закончим инциализацию', - ) - : BrandText.body2( - error.toString(), - style: TextStyle(color: BrandColors.red1), - ), + BrandText.body2( + 'Мы начали процесс инциализации сервера, раз в минуты мы будем проверять наличие DNS записей, как только они вступят в силу мы закончим инциализацию', + ), SizedBox(height: 10), Row( children: [ - BrandText.body2('Времени прошло: '), + BrandText.body2('До следующей проверки: '), BrandTimer( - startDateTime: state.server.startTime, - duration: Duration(minutes: 10), + startDateTime: + state.lastDnsCheckTime ?? state.server.createTime, + duration: Duration(seconds: 10), callback: () { appConfigCubit.checkDns(); }, - ), + ) ], ), Spacer( diff --git a/pubspec.lock b/pubspec.lock index f3808d26ec..cb1cd60306 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -176,6 +176,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.5" + csslib: + dependency: transitive + description: + name: csslib + url: "https://pub.dartlang.org" + source: hosted + version: "0.16.2" cubit_form: dependency: "direct main" description: @@ -350,6 +357,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.8.2" + html: + dependency: transitive + description: + name: html + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.0+4" http: dependency: transitive description: @@ -378,6 +392,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.19" + import_js_library: + dependency: transitive + description: + name: import_js_library + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" intl: dependency: transitive description: @@ -803,6 +824,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0-nullsafety.3" + wakelock: + dependency: "direct main" + description: + name: wakelock + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.1+1" + wakelock_platform_interface: + dependency: transitive + description: + name: wakelock_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0+1" + wakelock_web: + dependency: transitive + description: + name: wakelock_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0+3" watcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index f320bdc744..19dc788e15 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -25,6 +25,7 @@ dependencies: package_info: ^0.4.3+2 provider: ^4.3.2+2 url_launcher: ^5.7.10 + wakelock: ^0.2.1+1 dev_dependencies: flutter_test: