mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-11 18:39:45 +00:00
update
This commit is contained in:
parent
a07a7247f5
commit
20166647ea
Binary file not shown.
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 34 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 23 KiB |
|
@ -49,4 +49,4 @@ SPEC CHECKSUMS:
|
||||||
|
|
||||||
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
||||||
|
|
||||||
COCOAPODS: 1.10.0
|
COCOAPODS: 1.10.1
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:selfprivacy/ui/components/error/error.dart';
|
import 'package:selfprivacy/ui/components/error/error.dart';
|
||||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||||
|
|
||||||
class SimpleBlocObserver extends BlocObserver {
|
import 'get_it_config.dart';
|
||||||
final GlobalKey<NavigatorState> navigatorKey;
|
|
||||||
|
|
||||||
SimpleBlocObserver({this.navigatorKey});
|
class SimpleBlocObserver extends BlocObserver {
|
||||||
|
SimpleBlocObserver();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onError(Cubit cubit, Object error, StackTrace stackTrace) {
|
void onError(Cubit cubit, Object error, StackTrace stackTrace) {
|
||||||
navigatorKey.currentState.push(
|
final navigator = getIt.get<NavigationService>().navigator;
|
||||||
|
|
||||||
|
navigator.push(
|
||||||
materialRoute(
|
materialRoute(
|
||||||
BrandError(
|
BrandError(
|
||||||
error: error,
|
error: error,
|
||||||
|
|
|
@ -56,6 +56,7 @@ var darkTheme = ligtTheme.copyWith(
|
||||||
scaffoldBackgroundColor: Color(0xFF202120),
|
scaffoldBackgroundColor: Color(0xFF202120),
|
||||||
iconTheme: IconThemeData(color: BrandColors.gray3),
|
iconTheme: IconThemeData(color: BrandColors.gray3),
|
||||||
cardColor: BrandColors.gray1,
|
cardColor: BrandColors.gray1,
|
||||||
|
dialogBackgroundColor: Color(0xFF202120),
|
||||||
textTheme: GoogleFonts.interTextTheme(
|
textTheme: GoogleFonts.interTextTheme(
|
||||||
TextTheme(
|
TextTheme(
|
||||||
headline1: headline1Style.copyWith(color: BrandColors.white),
|
headline1: headline1Style.copyWith(color: BrandColors.white),
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
import 'package:selfprivacy/logic/get_it/console.dart';
|
import 'package:selfprivacy/logic/get_it/console.dart';
|
||||||
|
import 'package:selfprivacy/logic/get_it/navigation.dart';
|
||||||
import 'package:selfprivacy/logic/get_it/timer.dart';
|
import 'package:selfprivacy/logic/get_it/timer.dart';
|
||||||
|
|
||||||
|
export 'package:selfprivacy/logic/get_it/console.dart';
|
||||||
|
export 'package:selfprivacy/logic/get_it/navigation.dart';
|
||||||
|
export 'package:selfprivacy/logic/get_it/timer.dart';
|
||||||
|
|
||||||
final getIt = GetIt.instance;
|
final getIt = GetIt.instance;
|
||||||
|
|
||||||
void getItSetup() {
|
void getItSetup() {
|
||||||
|
getIt.registerSingleton<NavigationService>(NavigationService());
|
||||||
|
|
||||||
getIt.registerSingleton<ConsoleModel>(ConsoleModel());
|
getIt.registerSingleton<ConsoleModel>(ConsoleModel());
|
||||||
getIt.registerSingleton<TimerModel>(TimerModel());
|
getIt.registerSingleton<TimerModel>(TimerModel());
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ class BNames {
|
||||||
static String cloudFlareKey = 'cloudFlareKey';
|
static String cloudFlareKey = 'cloudFlareKey';
|
||||||
static String rootUser = 'rootUser';
|
static String rootUser = 'rootUser';
|
||||||
static String hetznerServer = 'hetznerServer';
|
static String hetznerServer = 'hetznerServer';
|
||||||
static String isDkimSetted = 'isDkimSetted';
|
// static String isDkimSetted = 'isDkimSetted';
|
||||||
static String isDnsChecked = 'isDnsChecked';
|
static String isDnsChecked = 'isDnsChecked';
|
||||||
static String isServerStarted = 'isServerStarted';
|
static String isServerStarted = 'isServerStarted';
|
||||||
static String backblazeKey = 'backblazeKey';
|
static String backblazeKey = 'backblazeKey';
|
||||||
|
|
|
@ -46,6 +46,13 @@ final body2Style = defaultTextStyle.copyWith(
|
||||||
color: BrandColors.textColor2,
|
color: BrandColors.textColor2,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final buttonTitleText = defaultTextStyle.copyWith(
|
||||||
|
color: BrandColors.white,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
height: 1,
|
||||||
|
);
|
||||||
|
|
||||||
final mediumStyle = defaultTextStyle.copyWith(fontSize: 13, height: 1.53);
|
final mediumStyle = defaultTextStyle.copyWith(fontSize: 13, height: 1.53);
|
||||||
|
|
||||||
final smallStyle = defaultTextStyle.copyWith(fontSize: 11, height: 1.45);
|
final smallStyle = defaultTextStyle.copyWith(fontSize: 11, height: 1.45);
|
||||||
|
|
|
@ -27,7 +27,6 @@ class BackblazeApi extends ApiMap {
|
||||||
Response response = await loggedClient.get(rootAddress, options: options);
|
Response response = await loggedClient.get(rootAddress, options: options);
|
||||||
|
|
||||||
if (response.statusCode == HttpStatus.ok) {
|
if (response.statusCode == HttpStatus.ok) {
|
||||||
print(response);
|
|
||||||
return true;
|
return true;
|
||||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -105,20 +105,20 @@ class CloudflareApi extends ApiMap {
|
||||||
await Future.wait(allCreateFutures);
|
await Future.wait(allCreateFutures);
|
||||||
}
|
}
|
||||||
|
|
||||||
setDkim(String dkimRecordString, String domainZoneId) {
|
// setDkim(String dkimRecordString, String domainZoneId) {
|
||||||
var txt3 = DnsRecords(
|
// var txt3 = DnsRecords(
|
||||||
type: 'TXT',
|
// type: 'TXT',
|
||||||
name: 'selector._domainkey',
|
// name: 'selector._domainkey',
|
||||||
content: dkimRecordString,
|
// content: dkimRecordString,
|
||||||
ttl: 18000,
|
// ttl: 18000,
|
||||||
);
|
// );
|
||||||
|
|
||||||
var url = '$rootAddress/zones/$domainZoneId/dns_records';
|
// var url = '$rootAddress/zones/$domainZoneId/dns_records';
|
||||||
loggedClient.post(
|
// loggedClient.post(
|
||||||
url,
|
// url,
|
||||||
data: txt3.toJson(),
|
// data: txt3.toJson(),
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
List<DnsRecords> projectDnsRecords(String domainName, String ip4) {
|
List<DnsRecords> projectDnsRecords(String domainName, String ip4) {
|
||||||
var domainA = DnsRecords(type: 'A', name: domainName, content: ip4);
|
var domainA = DnsRecords(type: 'A', name: domainName, content: ip4);
|
||||||
|
@ -160,4 +160,16 @@ class CloudflareApi extends ApiMap {
|
||||||
vpn
|
vpn
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<String>> domainList() async {
|
||||||
|
var url = '$rootAddress/zones?per_page=50';
|
||||||
|
var response = await loggedClient.get(
|
||||||
|
url,
|
||||||
|
queryParameters: {'per_page': 50},
|
||||||
|
);
|
||||||
|
|
||||||
|
return response.data['result']
|
||||||
|
.map<String>((el) => el['name'] as String)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,16 @@ class HetznerApi extends ApiMap {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> deleteSelfprivacyServer({
|
||||||
|
@required String cloudFlareKey,
|
||||||
|
}) async {
|
||||||
|
Response response = await loggedClient.get(rootAddress);
|
||||||
|
|
||||||
|
List list = response.data['servers'];
|
||||||
|
var server = list.firstWhere((el) => el['name'] == 'selfprivacy-server');
|
||||||
|
return await loggedClient.delete('$rootAddress/${server['id']}');
|
||||||
|
}
|
||||||
|
|
||||||
Future<HetznerServerDetails> startServer({
|
Future<HetznerServerDetails> startServer({
|
||||||
HetznerServerDetails server,
|
HetznerServerDetails server,
|
||||||
}) async {
|
}) async {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
@ -26,22 +25,22 @@ class ServerApi extends ApiMap {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getDkim(String domainName) async {
|
// Future<String> getDkim(String domainName) async {
|
||||||
var response = await loggedClient.get(
|
// var response = await loggedClient.get(
|
||||||
'/getDKIM',
|
// '/getDKIM',
|
||||||
options: Options(responseType: ResponseType.plain),
|
// options: Options(responseType: ResponseType.plain),
|
||||||
);
|
// );
|
||||||
return _decodeAndCutData(response.data, domainName);
|
// return _decodeAndCutData(response.data, domainName);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
String _decodeAndCutData(String text, String domainName) {
|
// String _decodeAndCutData(String text, String domainName) {
|
||||||
var decodedTextString = text.substring(1, text.length - 1);
|
// var decodedTextString = text.substring(1, text.length - 1);
|
||||||
var stringToBase64 = utf8.fuse(base64);
|
// var stringToBase64 = utf8.fuse(base64);
|
||||||
|
|
||||||
return stringToBase64
|
// return stringToBase64
|
||||||
.decode(decodedTextString)
|
// .decode(decodedTextString)
|
||||||
.replaceAll("selector._domainkey IN TXT ( ", "")
|
// .replaceAll("selector._domainkey IN TXT ( ", "")
|
||||||
.replaceAll("\"\n \"", "")
|
// .replaceAll("\"\n \"", "")
|
||||||
.replaceAll(' ) ; ----- DKIM key selector for $domainName\n', '');
|
// .replaceAll(' ) ; ----- DKIM key selector for $domainName\n', '');
|
||||||
}
|
// }
|
||||||
|
|
|
@ -14,22 +14,30 @@ import 'app_config_repository.dart';
|
||||||
part 'app_config_state.dart';
|
part 'app_config_state.dart';
|
||||||
|
|
||||||
/// Initializing steps:
|
/// Initializing steps:
|
||||||
/// 1. Hetzner key |setHetznerKey
|
///
|
||||||
/// 2. Cloudflare key |setCloudflareKey
|
/// The set phase.
|
||||||
/// 3. Backblaze Id + Key |setBackblazeKey
|
/// 1.1. Hetzner key |setHetznerKey
|
||||||
|
/// 1.2. Cloudflare key |setCloudflareKey
|
||||||
/// 4. Set Domain address |setDomain
|
/// 1.3. Backblaze Id + Key |setBackblazeKey
|
||||||
/// 5. Set Root user name password |setRootUser
|
/// 1.4. Set Domain address |setDomain
|
||||||
/// 6. Set Create server ans set DNS-Records |createServerAndSetDnsRecords
|
/// 1.5. Set Root user name password |setRootUser
|
||||||
|
/// 1.6. Set Create server ans set DNS-Records |createServerAndSetDnsRecords
|
||||||
/// (without start)
|
/// (without start)
|
||||||
/// 7. ChecksAndSets:
|
///
|
||||||
/// 7.1 checkDnsAndStartServer |checkDnsAndStartServer
|
/// The check phase.
|
||||||
/// 7.2 setDkim |setDkim
|
///
|
||||||
/// a. checkServer
|
/// 2.1. a. wait 60sec checkDnsAndStartServer |startServerIfDnsIsOkay
|
||||||
/// b. getDkim
|
/// b. checkDns
|
||||||
/// c. Set DKIM
|
/// c. if dns is okay start server
|
||||||
/// d. server restart
|
///
|
||||||
|
/// 2.2. a. wait 60sec |resetServerIfServerIsOkay
|
||||||
|
/// b. checkServer
|
||||||
|
/// c. if server is ok wait 30 sec
|
||||||
|
/// d. reset server
|
||||||
|
///
|
||||||
|
/// 2.3. a. wait 60sec |finishCheckIfServerIsOkay
|
||||||
|
/// b. checkServer
|
||||||
|
/// c. if server is okay set that fully checked
|
||||||
|
|
||||||
class AppConfigCubit extends Cubit<AppConfigState> {
|
class AppConfigCubit extends Cubit<AppConfigState> {
|
||||||
AppConfigCubit() : super(InitialAppConfigState());
|
AppConfigCubit() : super(InitialAppConfigState());
|
||||||
|
@ -66,34 +74,22 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
||||||
emit(state.copyWith(rootUser: rootUser));
|
emit(state.copyWith(rootUser: rootUser));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDkim() async {
|
void serverReset() async {
|
||||||
var callBack = () async {
|
var callBack = () async {
|
||||||
var isServerWorking = await repository.isHttpServerWorking(
|
var isServerWorking = await repository.isHttpServerWorking(
|
||||||
state.cloudFlareDomain.domainName,
|
state.cloudFlareDomain.domainName,
|
||||||
);
|
);
|
||||||
if (!isServerWorking) {
|
if (!isServerWorking) {
|
||||||
var last = DateTime.now();
|
var last = DateTime.now();
|
||||||
print(last);
|
|
||||||
emit(state.copyWith(lastServerStatusCheckTime: last));
|
emit(state.copyWith(lastServerStatusCheckTime: last));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await repository.setDkim(
|
|
||||||
state.cloudFlareDomain.domainName,
|
|
||||||
state.cloudFlareKey,
|
|
||||||
state.cloudFlareDomain.zoneId,
|
|
||||||
);
|
|
||||||
|
|
||||||
var hetznerServerDetails = await repository.restart(
|
var hetznerServerDetails = await repository.restart(
|
||||||
state.hetznerKey,
|
state.hetznerKey,
|
||||||
state.hetznerServer,
|
state.hetznerServer,
|
||||||
);
|
);
|
||||||
emit(
|
emit(state.copyWith(hetznerServer: hetznerServerDetails));
|
||||||
state.copyWith(
|
|
||||||
isDkimSetted: true,
|
|
||||||
hetznerServer: hetznerServerDetails,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_tryOrAddError(state, callBack);
|
_tryOrAddError(state, callBack);
|
||||||
|
@ -125,14 +121,7 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void createServerAndSetDnsRecords() async {
|
void createServerAndSetDnsRecords() async {
|
||||||
var callback = () async {
|
var onSuccess = (serverDetails) async {
|
||||||
var serverDetails = await repository.createServer(
|
|
||||||
state.hetznerKey,
|
|
||||||
state.rootUser,
|
|
||||||
state.cloudFlareDomain.domainName,
|
|
||||||
state.cloudFlareKey,
|
|
||||||
);
|
|
||||||
|
|
||||||
await repository.createDnsRecords(
|
await repository.createDnsRecords(
|
||||||
state.cloudFlareKey,
|
state.cloudFlareKey,
|
||||||
serverDetails.ip4,
|
serverDetails.ip4,
|
||||||
|
@ -144,6 +133,19 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
||||||
hetznerServer: serverDetails,
|
hetznerServer: serverDetails,
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var onCancel = () => emit(state.copyWith(isLoading: false));
|
||||||
|
|
||||||
|
var callback = () async {
|
||||||
|
await repository.createServer(
|
||||||
|
state.hetznerKey,
|
||||||
|
state.rootUser,
|
||||||
|
state.cloudFlareDomain.domainName,
|
||||||
|
state.cloudFlareKey,
|
||||||
|
onCancel: onCancel,
|
||||||
|
onSuccess: onSuccess,
|
||||||
|
);
|
||||||
|
};
|
||||||
_tryOrAddError(state, callback);
|
_tryOrAddError(state, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:selfprivacy/config/hive_config.dart';
|
import 'package:selfprivacy/config/hive_config.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/cloudflare.dart';
|
import 'package:selfprivacy/logic/api_maps/cloudflare.dart';
|
||||||
|
@ -11,6 +12,8 @@ import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
import 'package:selfprivacy/logic/get_it/console.dart';
|
import 'package:selfprivacy/logic/get_it/console.dart';
|
||||||
import 'package:selfprivacy/logic/models/message.dart';
|
import 'package:selfprivacy/logic/models/message.dart';
|
||||||
import 'package:basic_utils/basic_utils.dart';
|
import 'package:basic_utils/basic_utils.dart';
|
||||||
|
import 'package:selfprivacy/ui/components/action_button/action_button.dart';
|
||||||
|
import 'package:selfprivacy/ui/components/brand_alert/brand_alert.dart';
|
||||||
import 'app_config_cubit.dart';
|
import 'app_config_cubit.dart';
|
||||||
|
|
||||||
class AppConfigRepository {
|
class AppConfigRepository {
|
||||||
|
@ -26,7 +29,6 @@ class AppConfigRepository {
|
||||||
hetznerServer: box.get(BNames.hetznerServer),
|
hetznerServer: box.get(BNames.hetznerServer),
|
||||||
isServerStarted: box.get(BNames.isServerStarted, defaultValue: false),
|
isServerStarted: box.get(BNames.isServerStarted, defaultValue: false),
|
||||||
isDnsChecked: box.get(BNames.isDnsChecked, defaultValue: false),
|
isDnsChecked: box.get(BNames.isDnsChecked, defaultValue: false),
|
||||||
isDkimSetted: box.get(BNames.isDkimSetted, defaultValue: false),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,19 +112,64 @@ class AppConfigRepository {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<HetznerServerDetails> createServer(String hetznerKey, User rootUser,
|
Future<void> createServer(
|
||||||
String domainName, String cloudFlareKey) async {
|
String hetznerKey,
|
||||||
|
User rootUser,
|
||||||
|
String domainName,
|
||||||
|
String cloudFlareKey, {
|
||||||
|
void Function() onCancel,
|
||||||
|
Future<void> Function(HetznerServerDetails serverDetails) onSuccess,
|
||||||
|
}) async {
|
||||||
var hetznerApi = HetznerApi(hetznerKey);
|
var hetznerApi = HetznerApi(hetznerKey);
|
||||||
var serverDetails = await hetznerApi.createServer(
|
|
||||||
cloudFlareKey: cloudFlareKey,
|
|
||||||
rootUser: rootUser,
|
|
||||||
domainName: domainName,
|
|
||||||
);
|
|
||||||
await box.put(BNames.hetznerServer, serverDetails);
|
|
||||||
|
|
||||||
hetznerApi.close();
|
try {
|
||||||
|
var serverDetails = await hetznerApi.createServer(
|
||||||
|
cloudFlareKey: cloudFlareKey,
|
||||||
|
rootUser: rootUser,
|
||||||
|
domainName: domainName,
|
||||||
|
);
|
||||||
|
await box.put(BNames.hetznerServer, serverDetails);
|
||||||
|
hetznerApi.close();
|
||||||
|
onSuccess(serverDetails);
|
||||||
|
} on DioError catch (e) {
|
||||||
|
if (e.response.data['error']['code'] == 'uniqueness_error') {
|
||||||
|
var nav = getIt.get<NavigationService>();
|
||||||
|
nav.showPopUpDialog(
|
||||||
|
BrandAlert(
|
||||||
|
title: 'Сервер с таким именем уже существует',
|
||||||
|
contentText: 'Уничтожить сервер и создать новый?',
|
||||||
|
acitons: [
|
||||||
|
ActionButton(
|
||||||
|
text: 'Удалить',
|
||||||
|
isRed: true,
|
||||||
|
onPressed: () async {
|
||||||
|
await hetznerApi.deleteSelfprivacyServer(
|
||||||
|
cloudFlareKey: cloudFlareKey,
|
||||||
|
);
|
||||||
|
|
||||||
return serverDetails;
|
var serverDetails = await hetznerApi.createServer(
|
||||||
|
cloudFlareKey: cloudFlareKey,
|
||||||
|
rootUser: rootUser,
|
||||||
|
domainName: domainName,
|
||||||
|
);
|
||||||
|
hetznerApi.close();
|
||||||
|
|
||||||
|
await box.put(BNames.hetznerServer, serverDetails);
|
||||||
|
onSuccess(serverDetails);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ActionButton(
|
||||||
|
text: 'Отменить',
|
||||||
|
onPressed: () {
|
||||||
|
hetznerApi.close();
|
||||||
|
onCancel();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> createDnsRecords(
|
Future<void> createDnsRecords(
|
||||||
|
@ -152,21 +199,6 @@ class AppConfigRepository {
|
||||||
return isHttpServerWorking;
|
return isHttpServerWorking;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setDkim(
|
|
||||||
String domainName,
|
|
||||||
String cloudFlareKey,
|
|
||||||
String zoneId,
|
|
||||||
) async {
|
|
||||||
var api = ServerApi(domainName);
|
|
||||||
var dkimRecordString = await api.getDkim(domainName);
|
|
||||||
var cloudflareApi = CloudflareApi(cloudFlareKey);
|
|
||||||
|
|
||||||
await cloudflareApi.setDkim(dkimRecordString, zoneId);
|
|
||||||
box.put(BNames.isDkimSetted, true);
|
|
||||||
|
|
||||||
cloudflareApi.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<HetznerServerDetails> restart(
|
Future<HetznerServerDetails> restart(
|
||||||
String hetznerKey,
|
String hetznerKey,
|
||||||
HetznerServerDetails server,
|
HetznerServerDetails server,
|
||||||
|
|
|
@ -10,11 +10,10 @@ class AppConfigState extends Equatable {
|
||||||
this.hetznerServer,
|
this.hetznerServer,
|
||||||
this.isLoading = false,
|
this.isLoading = false,
|
||||||
this.error,
|
this.error,
|
||||||
this.lastDnsCheckTime,
|
// this.lastDnsCheckTime,
|
||||||
this.lastServerStatusCheckTime,
|
// this.lastServerStatusCheckTime,
|
||||||
this.isDnsChecked = false,
|
this.isDnsChecked = false,
|
||||||
this.isServerStarted = false,
|
this.isServerStarted = false,
|
||||||
this.isDkimSetted = false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -28,9 +27,8 @@ class AppConfigState extends Equatable {
|
||||||
isDnsCheckedAndServerStarted,
|
isDnsCheckedAndServerStarted,
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
lastDnsCheckTime,
|
// lastDnsCheckTime,
|
||||||
lastServerStatusCheckTime,
|
// lastServerStatusCheckTime,
|
||||||
isDkimSetted,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
final String hetznerKey;
|
final String hetznerKey;
|
||||||
|
@ -39,11 +37,10 @@ class AppConfigState extends Equatable {
|
||||||
final CloudFlareDomain cloudFlareDomain;
|
final CloudFlareDomain cloudFlareDomain;
|
||||||
final User rootUser;
|
final User rootUser;
|
||||||
final HetznerServerDetails hetznerServer;
|
final HetznerServerDetails hetznerServer;
|
||||||
final bool isDkimSetted;
|
|
||||||
final bool isServerStarted;
|
final bool isServerStarted;
|
||||||
final bool isDnsChecked;
|
final bool isDnsChecked;
|
||||||
final DateTime lastDnsCheckTime;
|
// final DateTime lastDnsCheckTime;
|
||||||
final DateTime lastServerStatusCheckTime;
|
// final DateTime lastServerStatusCheckTime;
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
final Exception error;
|
final Exception error;
|
||||||
|
|
||||||
|
@ -58,7 +55,6 @@ class AppConfigState extends Equatable {
|
||||||
Exception error,
|
Exception error,
|
||||||
DateTime lastDnsCheckTime,
|
DateTime lastDnsCheckTime,
|
||||||
DateTime lastServerStatusCheckTime,
|
DateTime lastServerStatusCheckTime,
|
||||||
bool isDkimSetted,
|
|
||||||
bool isServerStarted,
|
bool isServerStarted,
|
||||||
bool isDnsChecked,
|
bool isDnsChecked,
|
||||||
}) =>
|
}) =>
|
||||||
|
@ -73,10 +69,9 @@ class AppConfigState extends Equatable {
|
||||||
isDnsChecked: isDnsChecked ?? this.isDnsChecked,
|
isDnsChecked: isDnsChecked ?? this.isDnsChecked,
|
||||||
isLoading: isLoading ?? this.isLoading,
|
isLoading: isLoading ?? this.isLoading,
|
||||||
error: error ?? this.error,
|
error: error ?? this.error,
|
||||||
lastDnsCheckTime: lastDnsCheckTime ?? this.lastDnsCheckTime,
|
// lastDnsCheckTime: lastDnsCheckTime ?? this.lastDnsCheckTime,
|
||||||
lastServerStatusCheckTime:
|
// lastServerStatusCheckTime:
|
||||||
lastServerStatusCheckTime ?? this.lastServerStatusCheckTime,
|
// lastServerStatusCheckTime ?? this.lastServerStatusCheckTime,
|
||||||
isDkimSetted: isDkimSetted ?? this.isDkimSetted,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
bool get isHetznerFilled => hetznerKey != null;
|
bool get isHetznerFilled => hetznerKey != null;
|
||||||
|
@ -85,7 +80,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 => hetznerServer != null;
|
bool get isServerFilled => hetznerServer != null;
|
||||||
bool get hasFinalChecked => isDnsCheckedAndServerStarted && isDkimSetted;
|
bool get hasFinalChecked => isDnsCheckedAndServerStarted;
|
||||||
|
|
||||||
bool get isDnsCheckedAndServerStarted => isDnsChecked && isServerStarted;
|
bool get isDnsCheckedAndServerStarted => isDnsChecked && isServerStarted;
|
||||||
|
|
||||||
|
@ -107,3 +102,22 @@ class AppConfigState extends Equatable {
|
||||||
class InitialAppConfigState extends AppConfigState {
|
class InitialAppConfigState extends AppConfigState {
|
||||||
InitialAppConfigState() : super();
|
InitialAppConfigState() : super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TimerState extends AppConfigState {
|
||||||
|
TimerState({
|
||||||
|
this.dataState,
|
||||||
|
this.timerStart,
|
||||||
|
this.duration,
|
||||||
|
}) : super();
|
||||||
|
|
||||||
|
final AppConfigState dataState;
|
||||||
|
final DateTime timerStart;
|
||||||
|
final Duration duration;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [
|
||||||
|
dataState,
|
||||||
|
timerStart,
|
||||||
|
duration,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
78
lib/logic/cubit/forms/initializing/domain_cloudflare.dart
Normal file
78
lib/logic/cubit/forms/initializing/domain_cloudflare.dart
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/cloudflare.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/cloudflare_domain.dart';
|
||||||
|
|
||||||
|
class DomainSetupCubit extends Cubit<DomainSetupState> {
|
||||||
|
DomainSetupCubit(this.initializingCubit) : super(Initial()) {
|
||||||
|
var token = (initializingCubit.state.cloudFlareKey);
|
||||||
|
|
||||||
|
assert(token != null, 'no cloudflare token');
|
||||||
|
|
||||||
|
api = CloudflareApi(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
AppConfigCubit initializingCubit;
|
||||||
|
CloudflareApi api;
|
||||||
|
|
||||||
|
Future<void> load() async {
|
||||||
|
emit(Loading(LoadingTypes.loadingDomain));
|
||||||
|
var list = await api.domainList();
|
||||||
|
if (list.isEmpty) {
|
||||||
|
emit(Empty());
|
||||||
|
} else if (list.length == 1) {
|
||||||
|
emit(Loaded(list.first));
|
||||||
|
} else {
|
||||||
|
emit(MoreThenOne());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() {
|
||||||
|
api.close();
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> saveDomain() async {
|
||||||
|
assert(state is Loaded, 'wrong state');
|
||||||
|
var domainName = (state as Loaded).domain;
|
||||||
|
|
||||||
|
emit(Loading(LoadingTypes.saving));
|
||||||
|
|
||||||
|
var zoneId = await api.getZoneId(
|
||||||
|
initializingCubit.state.cloudFlareKey,
|
||||||
|
domainName,
|
||||||
|
);
|
||||||
|
|
||||||
|
var domain = CloudFlareDomain(
|
||||||
|
domainName: domainName,
|
||||||
|
zoneId: zoneId,
|
||||||
|
);
|
||||||
|
|
||||||
|
initializingCubit.setDomain(domain);
|
||||||
|
emit(DomainSetted());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class DomainSetupState {}
|
||||||
|
|
||||||
|
class Initial extends DomainSetupState {}
|
||||||
|
|
||||||
|
class Empty extends DomainSetupState {}
|
||||||
|
|
||||||
|
class MoreThenOne extends DomainSetupState {}
|
||||||
|
|
||||||
|
class Loading extends DomainSetupState {
|
||||||
|
Loading(this.type);
|
||||||
|
final LoadingTypes type;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum LoadingTypes { loadingDomain, saving }
|
||||||
|
|
||||||
|
class Loaded extends DomainSetupState {
|
||||||
|
final String domain;
|
||||||
|
|
||||||
|
Loaded(this.domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
class DomainSetted extends DomainSetupState {}
|
|
@ -1,68 +1,68 @@
|
||||||
import 'dart:async';
|
// import 'dart:async';
|
||||||
|
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
// import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/cloudflare.dart';
|
// import 'package:selfprivacy/logic/api_maps/cloudflare.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
// import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/cloudflare_domain.dart';
|
// import 'package:selfprivacy/logic/models/cloudflare_domain.dart';
|
||||||
|
|
||||||
class DomainFormCubit extends FormCubit {
|
// class DomainFormCubit extends FormCubit {
|
||||||
CloudflareApi apiClient = CloudflareApi();
|
// CloudflareApi apiClient = CloudflareApi();
|
||||||
|
|
||||||
DomainFormCubit(this.initializingCubit) {
|
// DomainFormCubit(this.initializingCubit) {
|
||||||
var regExp =
|
// var regExp =
|
||||||
RegExp(r"^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}");
|
// RegExp(r"^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}");
|
||||||
domainName = FieldCubit(
|
// domainName = FieldCubit(
|
||||||
initalValue: '',
|
// initalValue: '',
|
||||||
validations: [
|
// validations: [
|
||||||
RequiredStringValidation('required'),
|
// RequiredStringValidation('required'),
|
||||||
ValidationModel<String>(
|
// ValidationModel<String>(
|
||||||
(s) => !regExp.hasMatch(s),
|
// (s) => !regExp.hasMatch(s),
|
||||||
'invalid domain format',
|
// 'invalid domain format',
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
);
|
// );
|
||||||
|
|
||||||
super.setFields([domainName]);
|
// super.setFields([domainName]);
|
||||||
}
|
// }
|
||||||
|
|
||||||
@override
|
// @override
|
||||||
FutureOr<void> onSubmit() async {
|
// FutureOr<void> onSubmit() async {
|
||||||
var domain = CloudFlareDomain(
|
// var domain = CloudFlareDomain(
|
||||||
domainName: domainName.state.value,
|
// domainName: domainName.state.value,
|
||||||
zoneId: zoneId,
|
// zoneId: zoneId,
|
||||||
);
|
// );
|
||||||
initializingCubit.setDomain(domain);
|
// initializingCubit.setDomain(domain);
|
||||||
}
|
// }
|
||||||
|
|
||||||
final AppConfigCubit initializingCubit;
|
// final AppConfigCubit initializingCubit;
|
||||||
|
|
||||||
FieldCubit<String> domainName;
|
// FieldCubit<String> domainName;
|
||||||
String zoneId;
|
// String zoneId;
|
||||||
|
|
||||||
@override
|
// @override
|
||||||
FutureOr<bool> asyncValidation() async {
|
// FutureOr<bool> asyncValidation() async {
|
||||||
var key = initializingCubit.state.cloudFlareKey;
|
// var key = initializingCubit.state.cloudFlareKey;
|
||||||
|
|
||||||
String zoneId;
|
// String zoneId;
|
||||||
|
|
||||||
try {
|
// try {
|
||||||
zoneId = await apiClient.getZoneId(key, domainName.state.value);
|
// zoneId = await apiClient.getZoneId(key, domainName.state.value);
|
||||||
} catch (e) {
|
// } catch (e) {
|
||||||
addError(e);
|
// addError(e);
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (zoneId == null) {
|
// if (zoneId == null) {
|
||||||
domainName.setError('Domain not in the list');
|
// domainName.setError('Domain not in the list');
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
this.zoneId = zoneId;
|
// this.zoneId = zoneId;
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@override
|
// @override
|
||||||
Future<void> close() async {
|
// Future<void> close() async {
|
||||||
apiClient.close();
|
// apiClient.close();
|
||||||
|
|
||||||
return super.close();
|
// return super.close();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
|
@ -30,7 +30,9 @@ class RootUserFormCubit extends FormCubit {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
super.setFields([userName, password]);
|
isVisible = FieldCubit(initalValue: false);
|
||||||
|
|
||||||
|
super.setFields([userName, password, isVisible]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -46,6 +48,7 @@ class RootUserFormCubit extends FormCubit {
|
||||||
|
|
||||||
FieldCubit<String> userName;
|
FieldCubit<String> userName;
|
||||||
FieldCubit<String> password;
|
FieldCubit<String> password;
|
||||||
|
FieldCubit<bool> isVisible;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
|
|
16
lib/logic/get_it/navigation.dart
Normal file
16
lib/logic/get_it/navigation.dart
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
class NavigationService {
|
||||||
|
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
NavigatorState get navigator => navigatorKey.currentState;
|
||||||
|
|
||||||
|
void showPopUpDialog(AlertDialog dialog) {
|
||||||
|
final context = navigatorKey.currentState.overlay.context;
|
||||||
|
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (_) => dialog,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,11 +15,10 @@ import 'config/get_it_config.dart';
|
||||||
import 'config/localization.dart';
|
import 'config/localization.dart';
|
||||||
import 'logic/cubit/app_settings/app_settings_cubit.dart';
|
import 'logic/cubit/app_settings/app_settings_cubit.dart';
|
||||||
|
|
||||||
final navigatorKey = GlobalKey<NavigatorState>();
|
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
await HiveConfig.init();
|
await HiveConfig.init();
|
||||||
Bloc.observer = SimpleBlocObserver(navigatorKey: navigatorKey);
|
Bloc.observer = SimpleBlocObserver();
|
||||||
Wakelock.enable();
|
Wakelock.enable();
|
||||||
getItSetup();
|
getItSetup();
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
@ -41,7 +40,7 @@ class MyApp extends StatelessWidget {
|
||||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||||
value: SystemUiOverlayStyle.light, // Manually changnig appbar color
|
value: SystemUiOverlayStyle.light, // Manually changnig appbar color
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
navigatorKey: navigatorKey,
|
navigatorKey: getIt.get<NavigationService>().navigatorKey,
|
||||||
localizationsDelegates: context.localizationDelegates,
|
localizationsDelegates: context.localizationDelegates,
|
||||||
supportedLocales: context.supportedLocales,
|
supportedLocales: context.supportedLocales,
|
||||||
locale: context.locale,
|
locale: context.locale,
|
||||||
|
|
31
lib/ui/components/action_button/action_button.dart
Normal file
31
lib/ui/components/action_button/action_button.dart
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:selfprivacy/config/brand_colors.dart';
|
||||||
|
|
||||||
|
class ActionButton extends StatelessWidget {
|
||||||
|
const ActionButton({
|
||||||
|
Key key,
|
||||||
|
this.text,
|
||||||
|
this.onPressed,
|
||||||
|
this.isRed = false,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final VoidCallback onPressed;
|
||||||
|
final String text;
|
||||||
|
final bool isRed;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var navigator = Navigator.of(context);
|
||||||
|
|
||||||
|
return TextButton(
|
||||||
|
child: Text(
|
||||||
|
text,
|
||||||
|
style: isRed ? TextStyle(color: BrandColors.red1) : null,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
navigator.pop();
|
||||||
|
if (onPressed != null) onPressed();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
15
lib/ui/components/brand_alert/brand_alert.dart
Normal file
15
lib/ui/components/brand_alert/brand_alert.dart
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class BrandAlert extends AlertDialog {
|
||||||
|
BrandAlert({
|
||||||
|
Key key,
|
||||||
|
String title,
|
||||||
|
String contentText,
|
||||||
|
List<Widget> acitons,
|
||||||
|
}) : super(
|
||||||
|
key: key,
|
||||||
|
title: title != null ? Text(title) : null,
|
||||||
|
content: title != null ? Text(contentText) : null,
|
||||||
|
actions: acitons,
|
||||||
|
);
|
||||||
|
}
|
|
@ -6,42 +6,32 @@ import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
||||||
|
|
||||||
enum BrandButtonTypes { rised, text, iconText }
|
enum BrandButtonTypes { rised, text, iconText }
|
||||||
|
|
||||||
class BrandButton extends StatelessWidget {
|
class BrandButton {
|
||||||
const BrandButton({
|
|
||||||
Key key,
|
|
||||||
this.onPressed,
|
|
||||||
this.type,
|
|
||||||
this.title,
|
|
||||||
this.icon,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
final VoidCallback onPressed;
|
|
||||||
final BrandButtonTypes type;
|
|
||||||
final String title;
|
|
||||||
final Icon icon;
|
|
||||||
|
|
||||||
static rised({
|
static rised({
|
||||||
Key key,
|
Key key,
|
||||||
@required VoidCallback onPressed,
|
@required VoidCallback onPressed,
|
||||||
@required String title,
|
String title,
|
||||||
}) =>
|
Widget child,
|
||||||
BrandButton(
|
}) {
|
||||||
key: key,
|
assert(title == null || child == null, 'required title or child');
|
||||||
onPressed: onPressed,
|
assert(title != null || child != null, 'required title or child');
|
||||||
title: title,
|
return _RisedButton(
|
||||||
type: BrandButtonTypes.rised,
|
key: key,
|
||||||
);
|
title: title,
|
||||||
|
onPressed: onPressed,
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static text({
|
static text({
|
||||||
Key key,
|
Key key,
|
||||||
@required VoidCallback onPressed,
|
@required VoidCallback onPressed,
|
||||||
@required String title,
|
@required String title,
|
||||||
}) =>
|
}) =>
|
||||||
BrandButton(
|
_TextButton(
|
||||||
key: key,
|
key: key,
|
||||||
onPressed: onPressed,
|
|
||||||
title: title,
|
title: title,
|
||||||
type: BrandButtonTypes.text,
|
onPressed: onPressed,
|
||||||
);
|
);
|
||||||
|
|
||||||
static iconText({
|
static iconText({
|
||||||
|
@ -50,38 +40,12 @@ class BrandButton extends StatelessWidget {
|
||||||
@required String title,
|
@required String title,
|
||||||
@required Icon icon,
|
@required Icon icon,
|
||||||
}) =>
|
}) =>
|
||||||
BrandButton(
|
_IconTextButton(
|
||||||
key: key,
|
key: key,
|
||||||
onPressed: onPressed,
|
|
||||||
title: title,
|
title: title,
|
||||||
type: BrandButtonTypes.iconText,
|
onPressed: onPressed,
|
||||||
icon: icon,
|
icon: icon,
|
||||||
);
|
);
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
switch (type) {
|
|
||||||
case BrandButtonTypes.rised:
|
|
||||||
return _RisedButton(
|
|
||||||
title: title,
|
|
||||||
onPressed: onPressed,
|
|
||||||
);
|
|
||||||
case BrandButtonTypes.text:
|
|
||||||
return _TextButton(
|
|
||||||
title: title,
|
|
||||||
onPressed: onPressed,
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case BrandButtonTypes.iconText:
|
|
||||||
return _IconTextButton(
|
|
||||||
title: title,
|
|
||||||
onPressed: onPressed,
|
|
||||||
icon: icon,
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _RisedButton extends StatelessWidget {
|
class _RisedButton extends StatelessWidget {
|
||||||
|
@ -89,10 +53,12 @@ class _RisedButton extends StatelessWidget {
|
||||||
Key key,
|
Key key,
|
||||||
this.onPressed,
|
this.onPressed,
|
||||||
this.title,
|
this.title,
|
||||||
|
this.child,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final VoidCallback onPressed;
|
final VoidCallback onPressed;
|
||||||
final String title;
|
final String title;
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -111,15 +77,7 @@ class _RisedButton extends StatelessWidget {
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
padding: EdgeInsets.all(12),
|
padding: EdgeInsets.all(12),
|
||||||
child: Text(
|
child: child ?? BrandText.buttonTitleText(title),
|
||||||
title,
|
|
||||||
style: TextStyle(
|
|
||||||
color: BrandColors.white,
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
height: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -10,18 +10,20 @@ enum TextType {
|
||||||
body2, // with opacity
|
body2, // with opacity
|
||||||
medium,
|
medium,
|
||||||
small,
|
small,
|
||||||
onboardingTitle
|
onboardingTitle,
|
||||||
|
buttonTitleText // risen button title text,
|
||||||
}
|
}
|
||||||
|
|
||||||
class BrandText extends StatelessWidget {
|
class BrandText extends StatelessWidget {
|
||||||
const BrandText(this.text,
|
const BrandText(
|
||||||
{Key key,
|
this.text, {
|
||||||
this.style,
|
Key key,
|
||||||
@required this.type,
|
this.style,
|
||||||
this.overflow,
|
@required this.type,
|
||||||
this.softWrap,
|
this.overflow,
|
||||||
this.textAlign})
|
this.softWrap,
|
||||||
: super(key: key);
|
this.textAlign,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
final String text;
|
final String text;
|
||||||
final TextStyle style;
|
final TextStyle style;
|
||||||
|
@ -53,10 +55,13 @@ class BrandText extends StatelessWidget {
|
||||||
type: TextType.h2,
|
type: TextType.h2,
|
||||||
style: style,
|
style: style,
|
||||||
);
|
);
|
||||||
factory BrandText.h3(String text, {TextStyle style}) => BrandText(
|
factory BrandText.h3(String text, {TextStyle style, TextAlign textAlign}) =>
|
||||||
|
BrandText(
|
||||||
text,
|
text,
|
||||||
type: TextType.h3,
|
type: TextType.h3,
|
||||||
style: style,
|
style: style,
|
||||||
|
textAlign: textAlign,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
);
|
);
|
||||||
factory BrandText.h4(String text, {TextStyle style}) => BrandText(
|
factory BrandText.h4(String text, {TextStyle style}) => BrandText(
|
||||||
text,
|
text,
|
||||||
|
@ -75,13 +80,23 @@ class BrandText extends StatelessWidget {
|
||||||
);
|
);
|
||||||
factory BrandText.medium(String text,
|
factory BrandText.medium(String text,
|
||||||
{TextStyle style, TextAlign textAlign}) =>
|
{TextStyle style, TextAlign textAlign}) =>
|
||||||
BrandText(text,
|
BrandText(
|
||||||
type: TextType.medium, style: style, textAlign: textAlign);
|
text,
|
||||||
|
type: TextType.medium,
|
||||||
|
style: style,
|
||||||
|
textAlign: textAlign,
|
||||||
|
);
|
||||||
factory BrandText.small(String text, {TextStyle style}) => BrandText(
|
factory BrandText.small(String text, {TextStyle style}) => BrandText(
|
||||||
text,
|
text,
|
||||||
type: TextType.small,
|
type: TextType.small,
|
||||||
style: style,
|
style: style,
|
||||||
);
|
);
|
||||||
|
factory BrandText.buttonTitleText(String text, {TextStyle style}) =>
|
||||||
|
BrandText(
|
||||||
|
text,
|
||||||
|
type: TextType.buttonTitleText,
|
||||||
|
style: style,
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
Text build(BuildContext context) {
|
Text build(BuildContext context) {
|
||||||
TextStyle style;
|
TextStyle style;
|
||||||
|
@ -128,6 +143,11 @@ class BrandText extends StatelessWidget {
|
||||||
style =
|
style =
|
||||||
isDark ? mediumStyle.copyWith(color: Colors.white) : mediumStyle;
|
isDark ? mediumStyle.copyWith(color: Colors.white) : mediumStyle;
|
||||||
break;
|
break;
|
||||||
|
case TextType.buttonTitleText:
|
||||||
|
style = !isDark
|
||||||
|
? buttonTitleText.copyWith(color: Colors.white)
|
||||||
|
: buttonTitleText;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (this.style != null) {
|
if (this.style != null) {
|
||||||
style = style.merge(this.style);
|
style = style.merge(this.style);
|
||||||
|
|
|
@ -9,12 +9,10 @@ class BrandTimer extends StatefulWidget {
|
||||||
Key key,
|
Key key,
|
||||||
@required this.startDateTime,
|
@required this.startDateTime,
|
||||||
@required this.duration,
|
@required this.duration,
|
||||||
@required this.callback,
|
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final DateTime startDateTime;
|
final DateTime startDateTime;
|
||||||
final Duration duration;
|
final Duration duration;
|
||||||
final VoidCallback callback;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_BrandTimerState createState() => _BrandTimerState();
|
_BrandTimerState createState() => _BrandTimerState();
|
||||||
|
@ -36,7 +34,6 @@ class _BrandTimerState extends State<BrandTimer> {
|
||||||
var timePassed = DateTime.now().difference(widget.startDateTime);
|
var timePassed = DateTime.now().difference(widget.startDateTime);
|
||||||
if (timePassed > widget.duration) {
|
if (timePassed > widget.duration) {
|
||||||
t.cancel();
|
t.cancel();
|
||||||
widget.callback();
|
|
||||||
} else {
|
} else {
|
||||||
_getTime();
|
_getTime();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ 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/backblaze_form_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/forms/initializing/backblaze_form_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/initializing/cloudflare_form_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/forms/initializing/cloudflare_form_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/initializing/domain_form_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/forms/initializing/domain_cloudflare.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/initializing/hetzner_form_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/forms/initializing/hetzner_form_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/forms/initializing/root_user_form_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/forms/initializing/root_user_form_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
||||||
|
@ -16,7 +16,6 @@ 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';
|
||||||
|
@ -34,7 +33,8 @@ class InitializingPage extends StatelessWidget {
|
||||||
_stepServer(cubit),
|
_stepServer(cubit),
|
||||||
_stepCheck(cubit),
|
_stepCheck(cubit),
|
||||||
Container(child: Text('Everythigng is initialized'))
|
Container(child: Text('Everythigng is initialized'))
|
||||||
][2];
|
][cubit.state.progress];
|
||||||
|
|
||||||
return BlocListener<AppConfigCubit, AppConfigState>(
|
return BlocListener<AppConfigCubit, AppConfigState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state.isFullyInitilized) {
|
if (state.isFullyInitilized) {
|
||||||
|
@ -96,8 +96,10 @@ class InitializingPage extends StatelessWidget {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Spacer(),
|
Image.asset(
|
||||||
Image.asset('assets/images/logos/hetzner.png'),
|
'assets/images/logos/hetzner.png',
|
||||||
|
width: 150,
|
||||||
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
BrandText.h2('Подключите сервер Hetzner'),
|
BrandText.h2('Подключите сервер Hetzner'),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
|
@ -149,8 +151,11 @@ class InitializingPage extends StatelessWidget {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Spacer(),
|
Image.asset(
|
||||||
Image.asset('assets/images/logos/cloudflare.png'),
|
'assets/images/logos/cloudflare.png',
|
||||||
|
width: 150,
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
BrandText.h2('Подключите CloudFlare'),
|
BrandText.h2('Подключите CloudFlare'),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
BrandText.body2('Для управления DNS вашего домена'),
|
BrandText.body2('Для управления DNS вашего домена'),
|
||||||
|
@ -188,12 +193,13 @@ class InitializingPage extends StatelessWidget {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Spacer(),
|
Image.asset(
|
||||||
Image.asset('assets/images/logos/backblaze.png'),
|
'assets/images/logos/backblaze.png',
|
||||||
|
height: 50,
|
||||||
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
BrandText.h2('Подключите облачное хранилище Backblaze'),
|
BrandText.h2('Подключите облачное хранилище Backblaze'),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
BrandText.body2('Здесь будут храниться данные'),
|
|
||||||
Spacer(),
|
Spacer(),
|
||||||
CubitFormTextField(
|
CubitFormTextField(
|
||||||
formFieldCubit: formCubit.keyId,
|
formFieldCubit: formCubit.keyId,
|
||||||
|
@ -231,30 +237,90 @@ class InitializingPage extends StatelessWidget {
|
||||||
|
|
||||||
Widget _stepDomain(AppConfigCubit initializingCubit) {
|
Widget _stepDomain(AppConfigCubit initializingCubit) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => DomainFormCubit(initializingCubit),
|
create: (context) => DomainSetupCubit(initializingCubit)..load(),
|
||||||
child: Builder(builder: (context) {
|
child: Builder(builder: (context) {
|
||||||
var formCubit = context.watch<DomainFormCubit>();
|
var domainSetup = context.watch<DomainSetupCubit>();
|
||||||
|
var state = domainSetup.state;
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Spacer(),
|
Image.asset(
|
||||||
BrandText.h2('Введите домен:'),
|
'assets/images/logos/cloudflare.png',
|
||||||
|
width: 150,
|
||||||
|
),
|
||||||
|
SizedBox(height: 30),
|
||||||
|
BrandText.h2('Домен'),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
CubitFormTextField(
|
if (state is Empty)
|
||||||
keyboardType: TextInputType.emailAddress,
|
BrandText.body2('На данный момент подлюченных доменов нет'),
|
||||||
formFieldCubit: formCubit.domainName,
|
if (state is Loading)
|
||||||
textAlign: TextAlign.center,
|
BrandText.body2(
|
||||||
scrollPadding: EdgeInsets.only(bottom: 70),
|
state.type == LoadingTypes.loadingDomain
|
||||||
decoration: InputDecoration(
|
? 'Загружаем список доменов'
|
||||||
hintText: 'Домен',
|
: 'Сохранение..',
|
||||||
),
|
),
|
||||||
),
|
if (state is MoreThenOne)
|
||||||
|
BrandText.body2(
|
||||||
|
'Найдено больше одного домена, для вашей безопастности, просим вам удалить не нужные домены',
|
||||||
|
),
|
||||||
|
if (state is Loaded) ...[
|
||||||
|
SizedBox(height: 10),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: BrandText.h3(
|
||||||
|
'${state.domain}',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 50,
|
||||||
|
child: BrandButton.rised(
|
||||||
|
onPressed: () => domainSetup.load(),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.refresh,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
if (state is Empty) ...[
|
||||||
|
SizedBox(height: 30),
|
||||||
|
BrandButton.rised(
|
||||||
|
onPressed: () => domainSetup.load(),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.refresh,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
SizedBox(width: 10),
|
||||||
|
BrandText.buttonTitleText('Обновить cписок'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
if (state is Loaded) ...[
|
||||||
|
SizedBox(height: 30),
|
||||||
|
BrandButton.rised(
|
||||||
|
onPressed: () => domainSetup.saveDomain(),
|
||||||
|
title: 'Сохранить домен',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
SizedBox(height: 10),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
BrandButton.rised(
|
|
||||||
onPressed:
|
|
||||||
formCubit.state.isSubmitting ? null : formCubit.trySubmit,
|
|
||||||
title: 'Подключить',
|
|
||||||
),
|
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
BrandButton.text(
|
BrandButton.text(
|
||||||
onPressed: () => _showModal(context, _HowHetzner()),
|
onPressed: () => _showModal(context, _HowHetzner()),
|
||||||
|
@ -286,13 +352,29 @@ class InitializingPage extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
CubitFormTextField(
|
BlocBuilder<FieldCubit<bool>, FieldCubitState<bool>>(
|
||||||
formFieldCubit: formCubit.password,
|
cubit: formCubit.isVisible,
|
||||||
textAlign: TextAlign.center,
|
builder: (context, state) {
|
||||||
scrollPadding: EdgeInsets.only(bottom: 70),
|
var isVisible = state.value;
|
||||||
decoration: InputDecoration(
|
return CubitFormTextField(
|
||||||
hintText: 'Пароль',
|
obscureText: !isVisible,
|
||||||
),
|
formFieldCubit: formCubit.password,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
scrollPadding: EdgeInsets.only(bottom: 70),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Пароль',
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
isVisible ? Icons.visibility : Icons.visibility_off,
|
||||||
|
),
|
||||||
|
onPressed: () => formCubit.isVisible.setValue(!isVisible),
|
||||||
|
),
|
||||||
|
suffixIconConstraints: BoxConstraints(minWidth: 60),
|
||||||
|
prefixIconConstraints: BoxConstraints(maxWidth: 85),
|
||||||
|
prefixIcon: Container(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
BrandButton.rised(
|
BrandButton.rised(
|
||||||
|
@ -338,52 +420,40 @@ class InitializingPage extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _stepCheck(AppConfigCubit appConfigCubit) {
|
Widget _stepCheck(AppConfigCubit appConfigCubit) {
|
||||||
var state = appConfigCubit.state;
|
return Text('step check');
|
||||||
var isDnsChecked = state.isDnsCheckedAndServerStarted;
|
// var state = appConfigCubit.state as TimerState;
|
||||||
return Builder(builder: (context) {
|
// var isDnsChecked = state.dataState.isDnsChecked;
|
||||||
return Column(
|
// return Builder(builder: (context) {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
// return Column(
|
||||||
children: [
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
Spacer(flex: 2),
|
// children: [
|
||||||
SizedBox(height: 10),
|
// Spacer(flex: 2),
|
||||||
BrandText.body2(
|
// SizedBox(height: 10),
|
||||||
isDnsChecked
|
// BrandText.body2(
|
||||||
? 'Dns сервера вступили в силу, мы стартанули сервер, как только он поднимется, мы закончим инициализацию.'
|
// isDnsChecked
|
||||||
: 'Мы начали процесс инциализации сервера, раз в минуту мы будем проверять наличие DNS записей, как только они вступят в силу мы продолжим инциализацию',
|
// ? 'Dns сервера вступили в силу, мы стартанули сервер, как только он поднимется, мы закончим инициализацию.'
|
||||||
),
|
// : 'Мы начали процесс инциализации сервера, раз в минуту мы будем проверять наличие DNS записей, как только они вступят в силу мы продолжим инциализацию',
|
||||||
SizedBox(height: 10),
|
// ),
|
||||||
Row(
|
// SizedBox(height: 10),
|
||||||
children: [
|
// Row(
|
||||||
BrandText.body2('До следующей проверки: '),
|
// children: [
|
||||||
isDnsChecked
|
// BrandText.body2('До следующей проверки: '),
|
||||||
? BrandTimer(
|
// BrandTimer(
|
||||||
startDateTime: state.lastServerStatusCheckTime ??
|
// startDateTime: state.timerStart,
|
||||||
state.hetznerServer.startTime,
|
// duration: state.duration,
|
||||||
duration: Duration(minutes: 1),
|
// )
|
||||||
callback: () {
|
// ],
|
||||||
appConfigCubit.setDkim();
|
// ),
|
||||||
},
|
// Spacer(
|
||||||
)
|
// flex: 2,
|
||||||
: BrandTimer(
|
// ),
|
||||||
startDateTime: state.lastDnsCheckTime ??
|
// BrandButton.text(
|
||||||
state.hetznerServer.createTime,
|
// onPressed: () => _showModal(context, _HowHetzner()),
|
||||||
duration: Duration(minutes: 1),
|
// title: 'Что это значит?',
|
||||||
callback: () {
|
// ),
|
||||||
appConfigCubit.checkDnsAndStartServer();
|
// ],
|
||||||
},
|
// );
|
||||||
)
|
// });
|
||||||
],
|
|
||||||
),
|
|
||||||
Spacer(
|
|
||||||
flex: 2,
|
|
||||||
),
|
|
||||||
BrandButton.text(
|
|
||||||
onPressed: () => _showModal(context, _HowHetzner()),
|
|
||||||
title: 'Что это значит?',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _addCard(Widget child) {
|
Widget _addCard(Widget child) {
|
||||||
|
|
|
@ -3,6 +3,8 @@ import 'package:selfprivacy/config/brand_colors.dart';
|
||||||
import 'package:selfprivacy/config/brand_theme.dart';
|
import 'package:selfprivacy/config/brand_theme.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
|
||||||
|
import 'package:selfprivacy/ui/components/action_button/action_button.dart';
|
||||||
|
import 'package:selfprivacy/ui/components/brand_alert/brand_alert.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart';
|
import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
|
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
|
||||||
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
||||||
|
@ -89,37 +91,26 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
child: AlertDialog(
|
child: BrandAlert(
|
||||||
title: Text('Are you sure?'),
|
title: 'Вы уверенны',
|
||||||
content: SingleChildScrollView(
|
contentText: 'Сбросить все ключи?',
|
||||||
child: ListBody(
|
acitons: [
|
||||||
children: <Widget>[
|
ActionButton(
|
||||||
Text('Reset all keys?'),
|
text: 'Да, сбросить',
|
||||||
],
|
isRed: true,
|
||||||
),
|
onPressed: () {
|
||||||
|
context
|
||||||
|
.read<AppConfigCubit>()
|
||||||
|
.clearAppConfig();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}),
|
||||||
|
ActionButton(
|
||||||
|
text: 'Отмена',
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
],
|
||||||
TextButton(
|
),
|
||||||
child: Text(
|
);
|
||||||
'Reset',
|
|
||||||
style: TextStyle(
|
|
||||||
color: BrandColors.red1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
context.read<AppConfigCubit>().clearAppConfig();
|
|
||||||
Navigator.of(context)..pop()..pop();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
child: Text('Cancel'),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.of(context)..pop();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
));
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
87
pubspec.lock
87
pubspec.lock
|
@ -7,14 +7,14 @@ packages:
|
||||||
name: _fe_analyzer_shared
|
name: _fe_analyzer_shared
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.0.0"
|
version: "12.0.0"
|
||||||
analyzer:
|
analyzer:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: analyzer
|
name: analyzer
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.41.1"
|
version: "0.40.6"
|
||||||
archive:
|
archive:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -169,6 +169,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.1"
|
||||||
|
coverage:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: coverage
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.14.2"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -225,6 +232,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.3"
|
version: "2.3.3"
|
||||||
|
either_option:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: either_option
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.6"
|
||||||
email_validator:
|
email_validator:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -419,7 +433,7 @@ packages:
|
||||||
name: js
|
name: js
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.2"
|
version: "0.6.3-nullsafety.2"
|
||||||
json_annotation:
|
json_annotation:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -490,6 +504,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
|
node_preamble:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: node_preamble
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.13"
|
||||||
package_config:
|
package_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -552,7 +573,7 @@ packages:
|
||||||
name: pedantic
|
name: pedantic
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.2"
|
version: "1.10.0-nullsafety.2"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -587,7 +608,7 @@ packages:
|
||||||
name: pool
|
name: pool
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.5.0-nullsafety.2"
|
||||||
process:
|
process:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -672,6 +693,20 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.9"
|
version: "0.7.9"
|
||||||
|
shelf_packages_handler:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shelf_packages_handler
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.1"
|
||||||
|
shelf_static:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shelf_static
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.9+2"
|
||||||
shelf_web_socket:
|
shelf_web_socket:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -698,6 +733,20 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.10+1"
|
version: "0.9.10+1"
|
||||||
|
source_map_stack_trace:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_map_stack_trace
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0-nullsafety.3"
|
||||||
|
source_maps:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_maps
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.10-nullsafety.2"
|
||||||
source_span:
|
source_span:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -740,6 +789,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0-nullsafety.1"
|
version: "1.2.0-nullsafety.1"
|
||||||
|
test:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: test
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.16.0-nullsafety.5"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -747,6 +803,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.19-nullsafety.2"
|
version: "0.2.19-nullsafety.2"
|
||||||
|
test_core:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: test_core
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.12-nullsafety.5"
|
||||||
time:
|
time:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -824,6 +887,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0-nullsafety.3"
|
version: "2.1.0-nullsafety.3"
|
||||||
|
vm_service:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vm_service
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "5.5.0"
|
||||||
wakelock:
|
wakelock:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -859,6 +929,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
webkit_inspection_protocol:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: webkit_inspection_protocol
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.5"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -14,6 +14,7 @@ dependencies:
|
||||||
cupertino_icons: ^1.0.0
|
cupertino_icons: ^1.0.0
|
||||||
dio: ^3.0.10
|
dio: ^3.0.10
|
||||||
easy_localization: ^2.3.3
|
easy_localization: ^2.3.3
|
||||||
|
either_option: ^1.0.6
|
||||||
equatable: ^1.2.5
|
equatable: ^1.2.5
|
||||||
flutter_bloc: ^6.1.1
|
flutter_bloc: ^6.1.1
|
||||||
flutter_secure_storage: ^3.3.5
|
flutter_secure_storage: ^3.3.5
|
||||||
|
|
Loading…
Reference in a new issue