fdroid
Kherel 2021-01-06 20:25:53 +01:00
parent 9a749cf006
commit 0ed5fbdd2e
8 changed files with 167 additions and 14 deletions

View File

@ -47,7 +47,7 @@ class BNames {
static String hetznerKey = 'hetznerKey';
static String cloudFlareKey = 'cloudFlareKey';
static String rootUser = 'rootUser';
static String server = 'server';
static String hetznerServer = 'server';
static String isDnsCheckedAndDkimSet = 'isDnsCheckedAndDkimSet';
static String serverInitStart = 'serverInitStart';
}

View File

@ -58,7 +58,7 @@ class HetznerApi extends ApiMap {
return HetznerServerDetails(
id: response.data['server']['id'],
ip4: response.data['server']['public_net']['ipv4']['ip'],
serverInitializaionDateTime: DateTime.now(),
startTime: DateTime.now(),
);
}
}

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:hive/hive.dart';
@ -22,7 +24,7 @@ class AppConfigCubit extends Cubit<AppConfigState> {
cloudFlareKey: box.get(BNames.cloudFlareKey),
domain: box.get(BNames.domain),
rootUser: box.get(BNames.rootUser),
hetznerServer: box.get(BNames.server),
hetznerServer: box.get(BNames.hetznerServer),
isDnsCheckedAndDkimSet: box.get(BNames.isDnsCheckedAndDkimSet),
),
);
@ -53,9 +55,27 @@ class AppConfigCubit extends Cubit<AppConfigState> {
emit(state.copyWith(rootUser: rootUser));
}
void setIsDnsCheckedAndDkimSet() {
box.put(BNames.isDnsCheckedAndDkimSet, true);
emit(state.copyWith(isDnsCheckedAndDkimSet: true));
Future<void> checkDns() async {
var ip4 = state.server.ip4;
var domainName = state.cloudFlareDomain.name;
var addresses = <String>[
'$domainName',
'api.$domainName',
'cloud.$domainName',
'meet.$domainName',
'password.$domainName'
];
var hasError = false;
for (var address in addresses) {
var res = await InternetAddress.lookup(address);
if (res.isEmpty || res[0].address != ip4) {
hasError = true;
break;
}
}
if (hasError) {
emit(state.copyWith(error: Exception('dns checking error')));
}
}
void createServer() async {
@ -74,7 +94,7 @@ class AppConfigCubit extends Cubit<AppConfigState> {
cloudFlareDomain: state.cloudFlareDomain,
)
.then((_) => cloudflareApi.close());
await box.put(BNames.server, serverDetails);
await box.put(BNames.hetznerServer, serverDetails);
hetznerApi.close();

View File

@ -9,6 +9,7 @@ class AppConfigState extends Equatable {
this.server,
this.isDnsCheckedAndDkimSet = false,
this.isLoading = false,
this.error,
});
@override
@ -20,6 +21,7 @@ class AppConfigState extends Equatable {
server,
isDnsCheckedAndDkimSet,
isLoading,
error
];
final String hetznerKey;
@ -29,7 +31,8 @@ class AppConfigState extends Equatable {
final HetznerServerDetails server;
final bool isDnsCheckedAndDkimSet;
final isLoading;
final bool isLoading;
final Exception error;
AppConfigState copyWith({
String hetznerKey,
@ -40,6 +43,7 @@ class AppConfigState extends Equatable {
bool isDnsCheckedAndDkimSet,
bool isLoading,
DateTime serverInitStart,
Exception error,
}) =>
AppConfigState(
hetznerKey: hetznerKey ?? this.hetznerKey,
@ -47,8 +51,10 @@ class AppConfigState extends Equatable {
cloudFlareDomain: domain ?? this.cloudFlareDomain,
rootUser: rootUser ?? this.rootUser,
server: hetznerServer ?? this.server,
isDnsCheckedAndDkimSet: isDnsCheckedAndDkimSet ?? this.isDnsCheckedAndDkimSet,
isDnsCheckedAndDkimSet:
isDnsCheckedAndDkimSet ?? this.isDnsCheckedAndDkimSet,
isLoading: isLoading ?? this.isLoading,
error: error ?? this.error,
);
bool get isHetznerFilled => hetznerKey != null;
@ -56,7 +62,7 @@ class AppConfigState extends Equatable {
bool get isDomainFilled => cloudFlareDomain != null;
bool get isUserFilled => rootUser != null;
bool get isServerFilled => server != null;
bool get isFullyInitilized => _fulfilementList.every((el) => el);
int get progress => _fulfilementList.where((el) => el).length;

View File

@ -8,7 +8,7 @@ class HetznerServerDetails {
HetznerServerDetails({
@required this.ip4,
@required this.id,
@required this.serverInitializaionDateTime,
@required this.startTime,
});
@HiveField(0)
@ -18,7 +18,7 @@ class HetznerServerDetails {
final int id;
@HiveField(2)
final DateTime serverInitializaionDateTime;
final DateTime startTime;
String toString() => id.toString();
}

View File

@ -19,7 +19,7 @@ class HetznerServerDetailsAdapter extends TypeAdapter<HetznerServerDetails> {
return HetznerServerDetails(
ip4: fields[0] as String,
id: fields[1] as int,
serverInitializaionDateTime: fields[2] as DateTime,
startTime: fields[2] as DateTime,
);
}
@ -32,7 +32,7 @@ class HetznerServerDetailsAdapter extends TypeAdapter<HetznerServerDetails> {
..writeByte(1)
..write(obj.id)
..writeByte(2)
..write(obj.serverInitializaionDateTime);
..write(obj.startTime);
}
@override

View File

@ -0,0 +1,76 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
import 'package:selfprivacy/utils/named_font_weight.dart';
class BrandTimer extends StatefulWidget {
const BrandTimer({
Key key,
@required this.startDateTime,
@required this.duration,
@required this.callback,
}) : super(key: key);
final DateTime startDateTime;
final Duration duration;
final VoidCallback callback;
@override
_BrandTimerState createState() => _BrandTimerState();
}
class _BrandTimerState extends State<BrandTimer> {
String _timeString;
Timer timer;
@override
void initState() {
_timeString = diffenceFromStart;
timer = Timer.periodic(Duration(seconds: 1), (Timer t) {
var timePassed = DateTime.now().difference(widget.startDateTime);
if (timePassed > widget.duration) {
t.cancel();
widget.callback();
} else {
_getTime();
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
return BrandText.medium(
_timeString,
style: TextStyle(
fontWeight: NamedFontWeight.demiBold,
),
);
}
void _getTime() {
setState(() {
_timeString = diffenceFromStart;
});
}
String get diffenceFromStart =>
_durationToString(DateTime.now().difference(widget.startDateTime));
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));
return "$twoDigitMinutes:$twoDigitSeconds";
}
@override
void dispose() {
if (timer.isActive) {
timer.cancel();
}
super.dispose();
}
}

View File

@ -1,6 +1,9 @@
import 'dart:io';
import 'package:cubit_form/cubit_form.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:selfprivacy/config/brand_colors.dart';
import 'package:selfprivacy/config/brand_theme.dart';
import 'package:selfprivacy/config/text_themes.dart';
import 'package:selfprivacy/logic/cubit/forms/initializing/cloudflare_form_cubit.dart';
@ -14,6 +17,7 @@ import 'package:selfprivacy/ui/components/brand_card/brand_card.dart';
import 'package:selfprivacy/ui/components/brand_modal_sheet/brand_modal_sheet.dart';
import 'package:selfprivacy/ui/components/brand_span_button/brand_span_button.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
import 'package:selfprivacy/ui/components/brand_timer/brand_timer.dart';
import 'package:selfprivacy/ui/components/progress_bar/progress_bar.dart';
import 'package:selfprivacy/ui/pages/rootRoute.dart';
import 'package:selfprivacy/utils/route_transitions/basic.dart';
@ -22,12 +26,14 @@ class InitializingPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
var cubit = context.watch<AppConfigCubit>();
print(cubit.state.error);
var actualPage = [
_stepHetzner(cubit),
_stepCloudflare(cubit),
_stepDomain(cubit),
_stepUser(cubit),
_stepServer(cubit),
_stepCheck(cubit),
Container(child: Text('Everythigng is initialized'))
][cubit.state.progress];
return BlocListener<AppConfigCubit, AppConfigState>(
@ -286,6 +292,51 @@ class InitializingPage extends StatelessWidget {
});
}
Widget _stepCheck(AppConfigCubit appConfigCubit) {
var state = appConfigCubit.state;
var error = state.error;
print(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),
),
SizedBox(height: 10),
Row(
children: [
BrandText.body2('Времени прошло: '),
BrandTimer(
startDateTime: state.server.startTime,
duration: Duration(minutes: 10),
callback: () {
appConfigCubit.checkDns();
// print(state.server.ip4);
},
),
],
),
Spacer(
flex: 2,
),
BrandButton.text(
onPressed: () => _showModal(context, _HowHetzner()),
title: 'Что это значит?',
),
],
);
});
}
Widget _addCard(Widget child) {
return Container(
height: 500,