mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-03-12 01:34:10 +00:00
update
This commit is contained in:
parent
9a749cf006
commit
0ed5fbdd2e
8 changed files with 167 additions and 14 deletions
lib
config
logic
api_maps
cubit/app_config
models
ui
|
@ -47,7 +47,7 @@ class BNames {
|
||||||
static String hetznerKey = 'hetznerKey';
|
static String hetznerKey = 'hetznerKey';
|
||||||
static String cloudFlareKey = 'cloudFlareKey';
|
static String cloudFlareKey = 'cloudFlareKey';
|
||||||
static String rootUser = 'rootUser';
|
static String rootUser = 'rootUser';
|
||||||
static String server = 'server';
|
static String hetznerServer = 'server';
|
||||||
static String isDnsCheckedAndDkimSet = 'isDnsCheckedAndDkimSet';
|
static String isDnsCheckedAndDkimSet = 'isDnsCheckedAndDkimSet';
|
||||||
static String serverInitStart = 'serverInitStart';
|
static String serverInitStart = 'serverInitStart';
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ class HetznerApi extends ApiMap {
|
||||||
return HetznerServerDetails(
|
return HetznerServerDetails(
|
||||||
id: response.data['server']['id'],
|
id: response.data['server']['id'],
|
||||||
ip4: response.data['server']['public_net']['ipv4']['ip'],
|
ip4: response.data['server']['public_net']['ipv4']['ip'],
|
||||||
serverInitializaionDateTime: DateTime.now(),
|
startTime: DateTime.now(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
@ -22,7 +24,7 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
||||||
cloudFlareKey: box.get(BNames.cloudFlareKey),
|
cloudFlareKey: box.get(BNames.cloudFlareKey),
|
||||||
domain: box.get(BNames.domain),
|
domain: box.get(BNames.domain),
|
||||||
rootUser: box.get(BNames.rootUser),
|
rootUser: box.get(BNames.rootUser),
|
||||||
hetznerServer: box.get(BNames.server),
|
hetznerServer: box.get(BNames.hetznerServer),
|
||||||
isDnsCheckedAndDkimSet: box.get(BNames.isDnsCheckedAndDkimSet),
|
isDnsCheckedAndDkimSet: box.get(BNames.isDnsCheckedAndDkimSet),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -53,9 +55,27 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
||||||
emit(state.copyWith(rootUser: rootUser));
|
emit(state.copyWith(rootUser: rootUser));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setIsDnsCheckedAndDkimSet() {
|
Future<void> checkDns() async {
|
||||||
box.put(BNames.isDnsCheckedAndDkimSet, true);
|
var ip4 = state.server.ip4;
|
||||||
emit(state.copyWith(isDnsCheckedAndDkimSet: true));
|
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 {
|
void createServer() async {
|
||||||
|
@ -74,7 +94,7 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
||||||
cloudFlareDomain: state.cloudFlareDomain,
|
cloudFlareDomain: state.cloudFlareDomain,
|
||||||
)
|
)
|
||||||
.then((_) => cloudflareApi.close());
|
.then((_) => cloudflareApi.close());
|
||||||
await box.put(BNames.server, serverDetails);
|
await box.put(BNames.hetznerServer, serverDetails);
|
||||||
|
|
||||||
hetznerApi.close();
|
hetznerApi.close();
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ class AppConfigState extends Equatable {
|
||||||
this.server,
|
this.server,
|
||||||
this.isDnsCheckedAndDkimSet = false,
|
this.isDnsCheckedAndDkimSet = false,
|
||||||
this.isLoading = false,
|
this.isLoading = false,
|
||||||
|
this.error,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -20,6 +21,7 @@ class AppConfigState extends Equatable {
|
||||||
server,
|
server,
|
||||||
isDnsCheckedAndDkimSet,
|
isDnsCheckedAndDkimSet,
|
||||||
isLoading,
|
isLoading,
|
||||||
|
error
|
||||||
];
|
];
|
||||||
|
|
||||||
final String hetznerKey;
|
final String hetznerKey;
|
||||||
|
@ -29,7 +31,8 @@ class AppConfigState extends Equatable {
|
||||||
final HetznerServerDetails server;
|
final HetznerServerDetails server;
|
||||||
final bool isDnsCheckedAndDkimSet;
|
final bool isDnsCheckedAndDkimSet;
|
||||||
|
|
||||||
final isLoading;
|
final bool isLoading;
|
||||||
|
final Exception error;
|
||||||
|
|
||||||
AppConfigState copyWith({
|
AppConfigState copyWith({
|
||||||
String hetznerKey,
|
String hetznerKey,
|
||||||
|
@ -40,6 +43,7 @@ class AppConfigState extends Equatable {
|
||||||
bool isDnsCheckedAndDkimSet,
|
bool isDnsCheckedAndDkimSet,
|
||||||
bool isLoading,
|
bool isLoading,
|
||||||
DateTime serverInitStart,
|
DateTime serverInitStart,
|
||||||
|
Exception error,
|
||||||
}) =>
|
}) =>
|
||||||
AppConfigState(
|
AppConfigState(
|
||||||
hetznerKey: hetznerKey ?? this.hetznerKey,
|
hetznerKey: hetznerKey ?? this.hetznerKey,
|
||||||
|
@ -47,8 +51,10 @@ class AppConfigState extends Equatable {
|
||||||
cloudFlareDomain: domain ?? this.cloudFlareDomain,
|
cloudFlareDomain: domain ?? this.cloudFlareDomain,
|
||||||
rootUser: rootUser ?? this.rootUser,
|
rootUser: rootUser ?? this.rootUser,
|
||||||
server: hetznerServer ?? this.server,
|
server: hetznerServer ?? this.server,
|
||||||
isDnsCheckedAndDkimSet: isDnsCheckedAndDkimSet ?? this.isDnsCheckedAndDkimSet,
|
isDnsCheckedAndDkimSet:
|
||||||
|
isDnsCheckedAndDkimSet ?? this.isDnsCheckedAndDkimSet,
|
||||||
isLoading: isLoading ?? this.isLoading,
|
isLoading: isLoading ?? this.isLoading,
|
||||||
|
error: error ?? this.error,
|
||||||
);
|
);
|
||||||
|
|
||||||
bool get isHetznerFilled => hetznerKey != null;
|
bool get isHetznerFilled => hetznerKey != null;
|
||||||
|
@ -56,7 +62,7 @@ class AppConfigState extends Equatable {
|
||||||
bool get isDomainFilled => cloudFlareDomain != null;
|
bool get isDomainFilled => cloudFlareDomain != null;
|
||||||
bool get isUserFilled => rootUser != null;
|
bool get isUserFilled => rootUser != null;
|
||||||
bool get isServerFilled => server != null;
|
bool get isServerFilled => server != null;
|
||||||
|
|
||||||
bool get isFullyInitilized => _fulfilementList.every((el) => el);
|
bool get isFullyInitilized => _fulfilementList.every((el) => el);
|
||||||
|
|
||||||
int get progress => _fulfilementList.where((el) => el).length;
|
int get progress => _fulfilementList.where((el) => el).length;
|
||||||
|
|
|
@ -8,7 +8,7 @@ class HetznerServerDetails {
|
||||||
HetznerServerDetails({
|
HetznerServerDetails({
|
||||||
@required this.ip4,
|
@required this.ip4,
|
||||||
@required this.id,
|
@required this.id,
|
||||||
@required this.serverInitializaionDateTime,
|
@required this.startTime,
|
||||||
});
|
});
|
||||||
|
|
||||||
@HiveField(0)
|
@HiveField(0)
|
||||||
|
@ -18,7 +18,7 @@ class HetznerServerDetails {
|
||||||
final int id;
|
final int id;
|
||||||
|
|
||||||
@HiveField(2)
|
@HiveField(2)
|
||||||
final DateTime serverInitializaionDateTime;
|
final DateTime startTime;
|
||||||
|
|
||||||
String toString() => id.toString();
|
String toString() => id.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ class HetznerServerDetailsAdapter extends TypeAdapter<HetznerServerDetails> {
|
||||||
return HetznerServerDetails(
|
return HetznerServerDetails(
|
||||||
ip4: fields[0] as String,
|
ip4: fields[0] as String,
|
||||||
id: fields[1] as int,
|
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)
|
..writeByte(1)
|
||||||
..write(obj.id)
|
..write(obj.id)
|
||||||
..writeByte(2)
|
..writeByte(2)
|
||||||
..write(obj.serverInitializaionDateTime);
|
..write(obj.startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
76
lib/ui/components/brand_timer/brand_timer.dart
Normal file
76
lib/ui/components/brand_timer/brand_timer.dart
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,9 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.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/brand_theme.dart';
|
||||||
import 'package:selfprivacy/config/text_themes.dart';
|
import 'package:selfprivacy/config/text_themes.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/initializing/cloudflare_form_cubit.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_modal_sheet/brand_modal_sheet.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_span_button/brand_span_button.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_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/components/progress_bar/progress_bar.dart';
|
||||||
import 'package:selfprivacy/ui/pages/rootRoute.dart';
|
import 'package:selfprivacy/ui/pages/rootRoute.dart';
|
||||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||||
|
@ -22,12 +26,14 @@ class InitializingPage extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var cubit = context.watch<AppConfigCubit>();
|
var cubit = context.watch<AppConfigCubit>();
|
||||||
|
print(cubit.state.error);
|
||||||
var actualPage = [
|
var actualPage = [
|
||||||
_stepHetzner(cubit),
|
_stepHetzner(cubit),
|
||||||
_stepCloudflare(cubit),
|
_stepCloudflare(cubit),
|
||||||
_stepDomain(cubit),
|
_stepDomain(cubit),
|
||||||
_stepUser(cubit),
|
_stepUser(cubit),
|
||||||
_stepServer(cubit),
|
_stepServer(cubit),
|
||||||
|
_stepCheck(cubit),
|
||||||
Container(child: Text('Everythigng is initialized'))
|
Container(child: Text('Everythigng is initialized'))
|
||||||
][cubit.state.progress];
|
][cubit.state.progress];
|
||||||
return BlocListener<AppConfigCubit, AppConfigState>(
|
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) {
|
Widget _addCard(Widget child) {
|
||||||
return Container(
|
return Container(
|
||||||
height: 500,
|
height: 500,
|
||||||
|
|
Loading…
Add table
Reference in a new issue