mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-29 12:16:55 +00:00
update
This commit is contained in:
parent
afd569ba96
commit
0ec549042c
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 13 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 13 KiB |
|
@ -1,3 +1,46 @@
|
|||
{
|
||||
"test": "en-test"
|
||||
"test": "en-test",
|
||||
"basis": {
|
||||
"_comment": "базовые элементы интерфейса",
|
||||
"providers": "Провайдеры",
|
||||
"services": "Сервисы",
|
||||
"users": "Пользователи",
|
||||
"more": "Еще",
|
||||
"next": "Далее",
|
||||
"got_it": "Понял"
|
||||
},
|
||||
"more": {
|
||||
"_comment": "Элементы на странице еще",
|
||||
"configuration_wizard": "Мастер Подключения",
|
||||
"settings": "Настройки приложения",
|
||||
"about_project": "О проекте SelfPrivacy",
|
||||
"about_app": "О приложении",
|
||||
"onboarding": "Onboarding",
|
||||
"console": "Console"
|
||||
},
|
||||
"onboarding": {
|
||||
"_comment": "страницы онбординга",
|
||||
"page1_title": "Digital independence, available to all of us.",
|
||||
"page1_text": "Mail, VPN, Messenger, social network and much more on your private server, under your control.",
|
||||
"page2_title": "SelfPrivacy is not a cloud, but your personal datacenter.",
|
||||
"page2_text": "SelfPrivacy works only with your provider accounts: Hetzner, Cloudflare, Backblaze. If you do not own those, we'll help you to create them."
|
||||
},
|
||||
"providers": {
|
||||
"_comment": "вкладка провайдеры",
|
||||
"page_title": "Your Data Center",
|
||||
"server": {
|
||||
"card_title": "Сервер"
|
||||
},
|
||||
"domain": {
|
||||
"card_title": "Домен"
|
||||
},
|
||||
"backup": {
|
||||
"card_title": "Резервное копирование"
|
||||
}
|
||||
},
|
||||
"not_ready_card": {
|
||||
"1": "Завершите настройку приложения используя ",
|
||||
"2": "@:more.configuration_wizard",
|
||||
"3": " для продолжения работы"
|
||||
}
|
||||
}
|
|
@ -1,7 +1,47 @@
|
|||
{
|
||||
"test": "en-test",
|
||||
"basis:": {
|
||||
"_comment": "Повторяющиеся названия",
|
||||
"next": "Далее"
|
||||
"test": "ru-test",
|
||||
"basis": {
|
||||
"_comment": "базовые элементы интерфейса",
|
||||
"providers": "Провайдеры",
|
||||
"services": "Сервисы",
|
||||
"users": "Пользователи",
|
||||
"more": "Еще",
|
||||
"next": "Далее",
|
||||
"got_it": "Понял"
|
||||
},
|
||||
"more": {
|
||||
"_comment": "Элементы на странице еще",
|
||||
"configuration_wizard": "Мастер Подключения",
|
||||
"settings": "Настройки приложения",
|
||||
"about_project": "О проекте SelfPrivacy",
|
||||
"about_app": "О приложении",
|
||||
"onboarding": "Onboarding",
|
||||
"console": "Console"
|
||||
},
|
||||
"onboarding": {
|
||||
"_comment": "страницы онбординга",
|
||||
"page1_title": "Цифровая независимость доступна каждому",
|
||||
"page1_text": "Почта, VPN, Мессенджер, социальная сеть и многое другое на вашем личном сервере, под вашим полным контролем.",
|
||||
"page2_title": "SelfPrivacy — это не облако, а ваш личный дата-центр",
|
||||
"page2_text": "У SelfPrivacy работает только с вашими сервис-провадерами: Hetzner, Cloudflare, Backblaze. Если у вас нет учетных записей, мы поможем их создать."
|
||||
},
|
||||
"providers": {
|
||||
"_comment": "вкладка провайдеры",
|
||||
"page_title": "Ваш Дата-центр",
|
||||
"server": {
|
||||
"card_title": "Сервер"
|
||||
},
|
||||
"domain": {
|
||||
"card_title": "Домен"
|
||||
},
|
||||
"backup": {
|
||||
"card_title": "Резервное копирование"
|
||||
}
|
||||
},
|
||||
"not_ready_card": {
|
||||
"_comment": "Карточка показывающая когда человек скипнул настройку, на карте текст из 3 блоков, средний содержит ссыку на мастер подключения",
|
||||
"1": "Завершите настройку приложения используя ",
|
||||
"2": "@:more.configuration_wizard",
|
||||
"3": " для продолжения работы"
|
||||
}
|
||||
}
|
|
@ -45,7 +45,7 @@ SPEC CHECKSUMS:
|
|||
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
|
||||
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
|
||||
wakelock: bfc7955c418d0db797614075aabbc58a39ab5107
|
||||
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
|
||||
|
||||
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
|
|||
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
|
||||
|
||||
class BlocAndProviderConfig extends StatelessWidget {
|
||||
const BlocAndProviderConfig({Key key, this.child}) : super(key: key);
|
||||
const BlocAndProviderConfig({Key? key, this.child}) : super(key: key);
|
||||
|
||||
final Widget child;
|
||||
final Widget? child;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -2,14 +2,14 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||
import 'package:selfprivacy/ui/components/error/error.dart';
|
||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||
|
||||
import 'get_it_config.dart';
|
||||
import './get_it_config.dart';
|
||||
|
||||
class SimpleBlocObserver extends BlocObserver {
|
||||
SimpleBlocObserver();
|
||||
|
||||
@override
|
||||
void onError(Cubit cubit, Object error, StackTrace stackTrace) {
|
||||
final navigator = getIt.get<NavigationService>().navigator;
|
||||
void onError(Bloc cubit, Object error, StackTrace stackTrace) {
|
||||
final navigator = getIt.get<NavigationService>().navigator!;
|
||||
|
||||
navigator.push(
|
||||
materialRoute(
|
||||
|
|
|
@ -32,7 +32,8 @@ class HiveConfig {
|
|||
await secureStorage.write(key: BNames.key, value: base64UrlEncode(key));
|
||||
}
|
||||
|
||||
return base64Url.decode(await secureStorage.read(key: BNames.key));
|
||||
String? string = await secureStorage.read(key: BNames.key);
|
||||
return base64Url.decode(string!);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,20 +3,20 @@ import 'package:flutter/material.dart';
|
|||
|
||||
class Localization extends StatelessWidget {
|
||||
const Localization({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.child,
|
||||
}) : super(key: key);
|
||||
|
||||
final Widget child;
|
||||
final Widget? child;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return EasyLocalization(
|
||||
preloaderColor: Colors.black,
|
||||
supportedLocales: [Locale('ru'), Locale('en')],
|
||||
path: 'assets/translations',
|
||||
fallbackLocale: Locale('en'),
|
||||
fallbackLocale: Locale('ru'),
|
||||
saveLocale: false,
|
||||
useOnlyLangCode: true,
|
||||
child: child,
|
||||
child: child!,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ abstract class ApiMap {
|
|||
};
|
||||
loggedClient = client;
|
||||
}
|
||||
String rootAddress;
|
||||
String? rootAddress;
|
||||
|
||||
Dio loggedClient;
|
||||
late Dio loggedClient;
|
||||
|
||||
void close() {
|
||||
loggedClient.close();
|
||||
|
@ -61,7 +61,7 @@ class ConsoleInterceptor extends InterceptorsWrapper {
|
|||
addMessage(
|
||||
Message.warn(
|
||||
text:
|
||||
'response-uri: ${response?.request?.uri}\ncode: ${response?.statusCode}\ndata: ${response?.toString()}\n',
|
||||
'response-uri: ${response?.request.uri}\ncode: ${response?.statusCode}\ndata: ${response?.toString()}\n',
|
||||
),
|
||||
);
|
||||
return super.onError(err);
|
||||
|
|
|
@ -3,17 +3,17 @@ import 'package:dio/dio.dart';
|
|||
import 'package:selfprivacy/logic/api_maps/api_map.dart';
|
||||
|
||||
class BackblazeApi extends ApiMap {
|
||||
BackblazeApi([String token]) {
|
||||
BackblazeApi([String? token]) {
|
||||
if (token != null) {
|
||||
loggedClient.options = BaseOptions(
|
||||
headers: {'Authorization': 'Basic $token'},
|
||||
baseUrl: rootAddress,
|
||||
baseUrl: rootAddress!,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String rootAddress =
|
||||
String? rootAddress =
|
||||
'https://api.backblazeb2.com/b2api/v2/b2_authorize_account';
|
||||
|
||||
Future<bool> isValid(String token) async {
|
||||
|
@ -24,7 +24,7 @@ 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) {
|
||||
return true;
|
||||
|
|
|
@ -5,7 +5,7 @@ import 'package:selfprivacy/logic/models/cloudflare_domain.dart';
|
|||
import 'package:selfprivacy/logic/models/dns_records.dart';
|
||||
|
||||
class CloudflareApi extends ApiMap {
|
||||
CloudflareApi([String token]) {
|
||||
CloudflareApi([String? token]) {
|
||||
if (token != null) {
|
||||
loggedClient.options =
|
||||
BaseOptions(headers: {'Authorization': 'Bearer $token'});
|
||||
|
@ -13,7 +13,7 @@ class CloudflareApi extends ApiMap {
|
|||
}
|
||||
|
||||
@override
|
||||
String rootAddress = 'https://api.cloudflare.com/client/v4';
|
||||
String? rootAddress = 'https://api.cloudflare.com/client/v4';
|
||||
|
||||
Future<bool> isValid(String token) async {
|
||||
var url = '$rootAddress/user/tokens/verify';
|
||||
|
@ -35,7 +35,7 @@ class CloudflareApi extends ApiMap {
|
|||
}
|
||||
}
|
||||
|
||||
Future<String> getZoneId(String token, String domain) async {
|
||||
Future<String?> getZoneId(String? token, String domain) async {
|
||||
var url = '$rootAddress/zones';
|
||||
|
||||
var options = Options(
|
||||
|
@ -59,8 +59,8 @@ class CloudflareApi extends ApiMap {
|
|||
}
|
||||
|
||||
Future<void> removeSimilarRecords({
|
||||
String ip4,
|
||||
CloudFlareDomain cloudFlareDomain,
|
||||
String? ip4,
|
||||
required CloudFlareDomain cloudFlareDomain,
|
||||
}) async {
|
||||
var domainName = cloudFlareDomain.domainName;
|
||||
var domainZoneId = cloudFlareDomain.zoneId;
|
||||
|
@ -82,8 +82,8 @@ class CloudflareApi extends ApiMap {
|
|||
}
|
||||
|
||||
Future<void> createMultipleDnsRecords({
|
||||
String ip4,
|
||||
CloudFlareDomain cloudFlareDomain,
|
||||
String? ip4,
|
||||
required CloudFlareDomain cloudFlareDomain,
|
||||
}) async {
|
||||
var domainName = cloudFlareDomain.domainName;
|
||||
var domainZoneId = cloudFlareDomain.zoneId;
|
||||
|
@ -120,7 +120,7 @@ class CloudflareApi extends ApiMap {
|
|||
// );
|
||||
// }
|
||||
|
||||
List<DnsRecords> projectDnsRecords(String domainName, String ip4) {
|
||||
List<DnsRecords> projectDnsRecords(String? domainName, String? ip4) {
|
||||
var domainA = DnsRecords(type: 'A', name: domainName, content: ip4);
|
||||
|
||||
var mx = DnsRecords(type: 'MX', name: '@', content: domainName);
|
||||
|
@ -161,7 +161,7 @@ class CloudflareApi extends ApiMap {
|
|||
];
|
||||
}
|
||||
|
||||
Future<List<String>> domainList() async {
|
||||
Future<List<String>?> domainList() async {
|
||||
var url = '$rootAddress/zones?per_page=50';
|
||||
var response = await loggedClient.get(
|
||||
url,
|
||||
|
@ -169,7 +169,7 @@ class CloudflareApi extends ApiMap {
|
|||
);
|
||||
|
||||
return response.data['result']
|
||||
.map<String>((el) => el['name'] as String)
|
||||
.map<String>((el) => el['name'] as String?)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,24 +2,23 @@ import 'dart:convert';
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:selfprivacy/logic/api_maps/api_map.dart';
|
||||
import 'package:selfprivacy/logic/models/server_details.dart';
|
||||
import 'package:selfprivacy/logic/models/user.dart';
|
||||
import 'package:selfprivacy/utils/password_generator2.dart';
|
||||
|
||||
class HetznerApi extends ApiMap {
|
||||
HetznerApi([String token]) {
|
||||
HetznerApi([String? token]) {
|
||||
if (token != null) {
|
||||
loggedClient.options = BaseOptions(
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
baseUrl: rootAddress,
|
||||
baseUrl: rootAddress!,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String rootAddress = 'https://api.hetzner.cloud/v1/servers';
|
||||
String? rootAddress = 'https://api.hetzner.cloud/v1/servers';
|
||||
|
||||
Future<bool> isValid(String token) async {
|
||||
var options = Options(
|
||||
|
@ -29,7 +28,7 @@ class HetznerApi extends ApiMap {
|
|||
},
|
||||
);
|
||||
|
||||
Response response = await loggedClient.get(rootAddress, options: options);
|
||||
Response response = await loggedClient.get(rootAddress!, options: options);
|
||||
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
return true;
|
||||
|
@ -41,9 +40,9 @@ class HetznerApi extends ApiMap {
|
|||
}
|
||||
|
||||
Future<HetznerServerDetails> createServer({
|
||||
@required String cloudFlareKey,
|
||||
@required User rootUser,
|
||||
@required String domainName,
|
||||
required String? cloudFlareKey,
|
||||
required User rootUser,
|
||||
required String? domainName,
|
||||
}) async {
|
||||
var dbPassword = getRandomString(40);
|
||||
|
||||
|
@ -52,7 +51,7 @@ class HetznerApi extends ApiMap {
|
|||
);
|
||||
|
||||
Response response = await loggedClient.post(
|
||||
rootAddress,
|
||||
rootAddress!,
|
||||
data: data,
|
||||
);
|
||||
|
||||
|
@ -64,17 +63,17 @@ class HetznerApi extends ApiMap {
|
|||
}
|
||||
|
||||
Future<void> deleteSelfprivacyServer({
|
||||
@required String cloudFlareKey,
|
||||
required String? cloudFlareKey,
|
||||
}) async {
|
||||
Response response = await loggedClient.get(rootAddress);
|
||||
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']}');
|
||||
await loggedClient.delete('$rootAddress/${server['id']}');
|
||||
}
|
||||
|
||||
Future<HetznerServerDetails> startServer({
|
||||
HetznerServerDetails server,
|
||||
required HetznerServerDetails server,
|
||||
}) async {
|
||||
await loggedClient.post('/${server.id}/actions/poweron');
|
||||
|
||||
|
@ -84,7 +83,7 @@ class HetznerApi extends ApiMap {
|
|||
}
|
||||
|
||||
Future<HetznerServerDetails> restart({
|
||||
HetznerServerDetails server,
|
||||
required HetznerServerDetails server,
|
||||
}) async {
|
||||
await loggedClient.post('/${server.id}/actions/poweron');
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import 'package:dio/dio.dart';
|
|||
import 'api_map.dart';
|
||||
|
||||
class ServerApi extends ApiMap {
|
||||
ServerApi(String domainName) {
|
||||
ServerApi(String? domainName) {
|
||||
loggedClient.options = BaseOptions(
|
||||
baseUrl: 'https://api.$domainName',
|
||||
);
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:async';
|
|||
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:selfprivacy/logic/models/backblaze_credential.dart';
|
||||
import 'package:selfprivacy/logic/models/cloudflare_domain.dart';
|
||||
|
||||
|
@ -64,23 +63,23 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
|||
}
|
||||
|
||||
void startServerIfDnsIsOkay({
|
||||
AppConfigState state,
|
||||
AppConfigState? state,
|
||||
bool isImmediate = false,
|
||||
}) async {
|
||||
state = state ?? this.state;
|
||||
|
||||
final work = () async {
|
||||
emit(TimerState(dataState: state, isLoading: true));
|
||||
emit(TimerState(dataState: state!, isLoading: true));
|
||||
|
||||
var ip4 = state.hetznerServer.ip4;
|
||||
var domainName = state.cloudFlareDomain.domainName;
|
||||
var ip4 = state.hetznerServer!.ip4;
|
||||
var domainName = state.cloudFlareDomain!.domainName;
|
||||
|
||||
var isMatch = await repository.isDnsAddressesMatch(domainName, ip4);
|
||||
|
||||
if (isMatch) {
|
||||
var server = await repository.startServer(
|
||||
state.hetznerKey,
|
||||
state.hetznerServer,
|
||||
state.hetznerServer!,
|
||||
);
|
||||
repository.saveServerDetails(server);
|
||||
emit(
|
||||
|
@ -111,16 +110,16 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
|||
}
|
||||
|
||||
void resetServerIfServerIsOkay({
|
||||
AppConfigState state,
|
||||
AppConfigState? state,
|
||||
bool isImmediate = false,
|
||||
}) async {
|
||||
state = state ?? this.state;
|
||||
|
||||
var work = () async {
|
||||
emit(TimerState(dataState: state, isLoading: true));
|
||||
emit(TimerState(dataState: state!, isLoading: true));
|
||||
|
||||
var isServerWorking = await repository.isHttpServerWorking(
|
||||
state.cloudFlareDomain.domainName,
|
||||
state.cloudFlareDomain!.domainName,
|
||||
);
|
||||
|
||||
if (isServerWorking) {
|
||||
|
@ -133,8 +132,8 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
|||
));
|
||||
timer = Timer(pauseDuration, () async {
|
||||
var hetznerServerDetails = await repository.restart(
|
||||
state.hetznerKey,
|
||||
state.hetznerServer,
|
||||
state!.hetznerKey,
|
||||
state.hetznerServer!,
|
||||
);
|
||||
emit(
|
||||
state.copyWith(
|
||||
|
@ -165,19 +164,19 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
|||
}
|
||||
}
|
||||
|
||||
Timer timer;
|
||||
Timer? timer;
|
||||
|
||||
void finishCheckIfServerIsOkay({
|
||||
AppConfigState state,
|
||||
AppConfigState? state,
|
||||
bool isImmediate = false,
|
||||
}) async {
|
||||
state = state ?? this.state;
|
||||
|
||||
var work = () async {
|
||||
emit(TimerState(dataState: state, isLoading: true));
|
||||
emit(TimerState(dataState: state!, isLoading: true));
|
||||
|
||||
var isServerWorking = await repository.isHttpServerWorking(
|
||||
state.cloudFlareDomain.domainName,
|
||||
state.cloudFlareDomain!.domainName,
|
||||
);
|
||||
|
||||
if (isServerWorking) {
|
||||
|
@ -238,12 +237,12 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
|||
}
|
||||
|
||||
void createServerAndSetDnsRecords() async {
|
||||
var _stateCopy = state;
|
||||
AppConfigState _stateCopy = state;
|
||||
var onSuccess = (serverDetails) async {
|
||||
await repository.createDnsRecords(
|
||||
state.cloudFlareKey,
|
||||
serverDetails.ip4,
|
||||
state.cloudFlareDomain,
|
||||
state.cloudFlareDomain!,
|
||||
);
|
||||
|
||||
emit(state.copyWith(
|
||||
|
@ -259,8 +258,8 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
|||
emit(state.copyWith(isLoading: true));
|
||||
await repository.createServer(
|
||||
state.hetznerKey,
|
||||
state.rootUser,
|
||||
state.cloudFlareDomain.domainName,
|
||||
state.rootUser!,
|
||||
state.cloudFlareDomain!.domainName,
|
||||
state.cloudFlareKey,
|
||||
onCancel: onCancel,
|
||||
onSuccess: onSuccess,
|
||||
|
@ -277,8 +276,8 @@ class AppConfigCubit extends Cubit<AppConfigState> {
|
|||
}
|
||||
|
||||
void _closeTimer() {
|
||||
if (timer != null && timer.isActive) {
|
||||
timer.cancel();
|
||||
if (timer != null && timer!.isActive) {
|
||||
timer!.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ class AppConfigRepository {
|
|||
}
|
||||
|
||||
Future<HetznerServerDetails> startServer(
|
||||
String hetznerKey,
|
||||
String? hetznerKey,
|
||||
HetznerServerDetails hetznerServer,
|
||||
) async {
|
||||
var hetznerApi = HetznerApi(hetznerKey);
|
||||
|
@ -75,7 +75,7 @@ class AppConfigRepository {
|
|||
await box.put(BNames.hetznerServer, serverDetails);
|
||||
}
|
||||
|
||||
Future<bool> isDnsAddressesMatch(String domainName, String ip4) async {
|
||||
Future<bool> isDnsAddressesMatch(String? domainName, String? ip4) async {
|
||||
print(domainName);
|
||||
var addresses = <String>[
|
||||
'$domainName',
|
||||
|
@ -116,12 +116,12 @@ class AppConfigRepository {
|
|||
}
|
||||
|
||||
Future<void> createServer(
|
||||
String hetznerKey,
|
||||
String? hetznerKey,
|
||||
User rootUser,
|
||||
String domainName,
|
||||
String cloudFlareKey, {
|
||||
void Function() onCancel,
|
||||
Future<void> Function(HetznerServerDetails serverDetails) onSuccess,
|
||||
String? domainName,
|
||||
String? cloudFlareKey, {
|
||||
void Function()? onCancel,
|
||||
required Future<void> Function(HetznerServerDetails serverDetails) onSuccess,
|
||||
}) async {
|
||||
var hetznerApi = HetznerApi(hetznerKey);
|
||||
|
||||
|
@ -135,7 +135,7 @@ class AppConfigRepository {
|
|||
hetznerApi.close();
|
||||
onSuccess(serverDetails);
|
||||
} on DioError catch (e) {
|
||||
if (e.response.data['error']['code'] == 'uniqueness_error') {
|
||||
if (e.response!.data['error']['code'] == 'uniqueness_error') {
|
||||
var nav = getIt.get<NavigationService>();
|
||||
nav.showPopUpDialog(
|
||||
BrandAlert(
|
||||
|
@ -165,7 +165,7 @@ class AppConfigRepository {
|
|||
text: 'Отменить',
|
||||
onPressed: () {
|
||||
hetznerApi.close();
|
||||
onCancel();
|
||||
onCancel!();
|
||||
},
|
||||
),
|
||||
],
|
||||
|
@ -176,8 +176,8 @@ class AppConfigRepository {
|
|||
}
|
||||
|
||||
Future<void> createDnsRecords(
|
||||
String cloudFlareKey,
|
||||
String ip4,
|
||||
String? cloudFlareKey,
|
||||
String? ip4,
|
||||
CloudFlareDomain cloudFlareDomain,
|
||||
) async {
|
||||
var cloudflareApi = CloudflareApi(cloudFlareKey);
|
||||
|
@ -195,7 +195,7 @@ class AppConfigRepository {
|
|||
cloudflareApi.close();
|
||||
}
|
||||
|
||||
Future<bool> isHttpServerWorking(String domainName) async {
|
||||
Future<bool> isHttpServerWorking(String? domainName) async {
|
||||
var api = ServerApi(domainName);
|
||||
var isHttpServerWorking = await api.isHttpServerWorking();
|
||||
api.close();
|
||||
|
@ -203,7 +203,7 @@ class AppConfigRepository {
|
|||
}
|
||||
|
||||
Future<HetznerServerDetails> restart(
|
||||
String hetznerKey,
|
||||
String? hetznerKey,
|
||||
HetznerServerDetails server,
|
||||
) async {
|
||||
var hetznerApi = HetznerApi(hetznerKey);
|
||||
|
|
|
@ -2,21 +2,21 @@ part of 'app_config_cubit.dart';
|
|||
|
||||
class AppConfigState extends Equatable {
|
||||
const AppConfigState({
|
||||
@required this.hetznerKey,
|
||||
@required this.cloudFlareKey,
|
||||
@required this.backblazeCredential,
|
||||
@required this.cloudFlareDomain,
|
||||
@required this.rootUser,
|
||||
@required this.hetznerServer,
|
||||
@required this.isServerStarted,
|
||||
@required this.isServerReseted,
|
||||
@required this.hasFinalChecked,
|
||||
@required this.isLoading,
|
||||
@required this.error,
|
||||
required this.hetznerKey,
|
||||
required this.cloudFlareKey,
|
||||
required this.backblazeCredential,
|
||||
required this.cloudFlareDomain,
|
||||
required this.rootUser,
|
||||
required this.hetznerServer,
|
||||
required this.isServerStarted,
|
||||
required this.isServerReseted,
|
||||
required this.hasFinalChecked,
|
||||
required this.isLoading,
|
||||
required this.error,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [
|
||||
List<Object?> get props => [
|
||||
hetznerKey,
|
||||
cloudFlareKey,
|
||||
backblazeCredential,
|
||||
|
@ -30,31 +30,31 @@ class AppConfigState extends Equatable {
|
|||
error,
|
||||
];
|
||||
|
||||
final String hetznerKey;
|
||||
final String cloudFlareKey;
|
||||
final BackblazeCredential backblazeCredential;
|
||||
final CloudFlareDomain cloudFlareDomain;
|
||||
final User rootUser;
|
||||
final HetznerServerDetails hetznerServer;
|
||||
final bool isServerStarted;
|
||||
final bool isServerReseted;
|
||||
final bool hasFinalChecked;
|
||||
final String? hetznerKey;
|
||||
final String? cloudFlareKey;
|
||||
final BackblazeCredential? backblazeCredential;
|
||||
final CloudFlareDomain? cloudFlareDomain;
|
||||
final User? rootUser;
|
||||
final HetznerServerDetails? hetznerServer;
|
||||
final bool? isServerStarted;
|
||||
final bool? isServerReseted;
|
||||
final bool? hasFinalChecked;
|
||||
|
||||
final bool isLoading;
|
||||
final Exception error;
|
||||
final bool? isLoading;
|
||||
final Exception? error;
|
||||
|
||||
AppConfigState copyWith({
|
||||
String hetznerKey,
|
||||
String cloudFlareKey,
|
||||
BackblazeCredential backblazeCredential,
|
||||
CloudFlareDomain cloudFlareDomain,
|
||||
User rootUser,
|
||||
HetznerServerDetails hetznerServer,
|
||||
bool isServerStarted,
|
||||
bool isServerReseted,
|
||||
bool hasFinalChecked,
|
||||
bool isLoading,
|
||||
Exception error,
|
||||
String? hetznerKey,
|
||||
String? cloudFlareKey,
|
||||
BackblazeCredential? backblazeCredential,
|
||||
CloudFlareDomain? cloudFlareDomain,
|
||||
User? rootUser,
|
||||
HetznerServerDetails? hetznerServer,
|
||||
bool? isServerStarted,
|
||||
bool? isServerReseted,
|
||||
bool? hasFinalChecked,
|
||||
bool? isLoading,
|
||||
Exception? error,
|
||||
}) =>
|
||||
AppConfigState(
|
||||
hetznerKey: hetznerKey ?? this.hetznerKey,
|
||||
|
@ -77,10 +77,10 @@ class AppConfigState extends Equatable {
|
|||
bool get isUserFilled => rootUser != null;
|
||||
bool get isServerCreated => hetznerServer != null;
|
||||
|
||||
bool get isFullyInitilized => _fulfilementList.every((el) => el);
|
||||
int get progress => _fulfilementList.where((el) => el).length;
|
||||
bool get isFullyInitilized => _fulfilementList.every((el) => el!);
|
||||
int get progress => _fulfilementList.where((el) => el!).length;
|
||||
|
||||
List<bool> get _fulfilementList => [
|
||||
List<bool?> get _fulfilementList => [
|
||||
isHetznerFilled,
|
||||
isCloudFlareFilled,
|
||||
isBackblazeFilled,
|
||||
|
@ -112,10 +112,10 @@ class InitialAppConfigState extends AppConfigState {
|
|||
|
||||
class TimerState extends AppConfigState {
|
||||
TimerState({
|
||||
@required this.dataState,
|
||||
required this.dataState,
|
||||
this.timerStart,
|
||||
this.duration,
|
||||
@required bool isLoading,
|
||||
required bool isLoading,
|
||||
}) : super(
|
||||
hetznerKey: dataState.hetznerKey,
|
||||
cloudFlareKey: dataState.cloudFlareKey,
|
||||
|
@ -131,11 +131,11 @@ class TimerState extends AppConfigState {
|
|||
);
|
||||
|
||||
final AppConfigState dataState;
|
||||
final DateTime timerStart;
|
||||
final Duration duration;
|
||||
final DateTime? timerStart;
|
||||
final Duration? duration;
|
||||
|
||||
@override
|
||||
List<Object> get props => [
|
||||
List<Object?> get props => [
|
||||
dataState,
|
||||
timerStart,
|
||||
duration,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:selfprivacy/config/hive_config.dart';
|
||||
export 'package:provider/provider.dart';
|
||||
|
@ -9,8 +8,8 @@ part 'app_settings_state.dart';
|
|||
|
||||
class AppSettingsCubit extends Cubit<AppSettingsState> {
|
||||
AppSettingsCubit({
|
||||
@required bool isDarkModeOn,
|
||||
@required bool isOnbordingShowing,
|
||||
required bool isDarkModeOn,
|
||||
required bool isOnbordingShowing,
|
||||
}) : super(
|
||||
AppSettingsState(
|
||||
isDarkModeOn: isDarkModeOn,
|
||||
|
@ -21,15 +20,15 @@ class AppSettingsCubit extends Cubit<AppSettingsState> {
|
|||
Box box = Hive.box(BNames.appSettings);
|
||||
|
||||
void load() {
|
||||
bool isDarkModeOn = box.get(BNames.isDarkModeOn);
|
||||
bool isOnbordingShowing = box.get(BNames.isOnbordingShowing);
|
||||
bool? isDarkModeOn = box.get(BNames.isDarkModeOn);
|
||||
bool? isOnbordingShowing = box.get(BNames.isOnbordingShowing);
|
||||
emit(state.copyWith(
|
||||
isDarkModeOn: isDarkModeOn,
|
||||
isOnbordingShowing: isOnbordingShowing,
|
||||
));
|
||||
}
|
||||
|
||||
void updateDarkMode({@required bool isDarkModeOn}) {
|
||||
void updateDarkMode({required bool isDarkModeOn}) {
|
||||
box.put(BNames.isDarkModeOn, isDarkModeOn);
|
||||
emit(state.copyWith(isDarkModeOn: isDarkModeOn));
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ part of 'app_settings_cubit.dart';
|
|||
|
||||
class AppSettingsState extends Equatable {
|
||||
const AppSettingsState({
|
||||
@required this.isDarkModeOn,
|
||||
@required this.isOnbordingShowing,
|
||||
required this.isDarkModeOn,
|
||||
required this.isOnbordingShowing,
|
||||
});
|
||||
|
||||
final bool isDarkModeOn;
|
||||
|
|
|
@ -42,13 +42,14 @@ class BackblazeFormCubit extends FormCubit {
|
|||
|
||||
final AppConfigCubit initializingCubit;
|
||||
|
||||
FieldCubit<String> keyId;
|
||||
|
||||
FieldCubit<String> applicationKey;
|
||||
// ignore: close_sinks
|
||||
late final FieldCubit<String> keyId;
|
||||
// ignore: close_sinks
|
||||
late final FieldCubit<String> applicationKey;
|
||||
|
||||
@override
|
||||
FutureOr<bool> asyncValidation() async {
|
||||
bool isKeyValid;
|
||||
late bool isKeyValid;
|
||||
try {
|
||||
String encodedApiKey = encodedBackblazeKey(
|
||||
keyId.state.value,
|
||||
|
|
|
@ -30,11 +30,11 @@ class CloudFlareFormCubit extends FormCubit {
|
|||
|
||||
final AppConfigCubit initializingCubit;
|
||||
|
||||
FieldCubit<String> apiKey;
|
||||
late final FieldCubit<String> apiKey;
|
||||
|
||||
@override
|
||||
FutureOr<bool> asyncValidation() async {
|
||||
bool isKeyValid;
|
||||
late bool isKeyValid;
|
||||
|
||||
try {
|
||||
isKeyValid = await apiClient.isValid(apiKey.state.value);
|
||||
|
|
|
@ -5,7 +5,7 @@ import 'package:selfprivacy/logic/models/cloudflare_domain.dart';
|
|||
|
||||
class DomainSetupCubit extends Cubit<DomainSetupState> {
|
||||
DomainSetupCubit(this.initializingCubit) : super(Initial()) {
|
||||
var token = (initializingCubit.state.cloudFlareKey);
|
||||
var token = initializingCubit.state.cloudFlareKey;
|
||||
|
||||
assert(token != null, 'no cloudflare token');
|
||||
|
||||
|
@ -13,11 +13,11 @@ class DomainSetupCubit extends Cubit<DomainSetupState> {
|
|||
}
|
||||
|
||||
AppConfigCubit initializingCubit;
|
||||
CloudflareApi api;
|
||||
late CloudflareApi api;
|
||||
|
||||
Future<void> load() async {
|
||||
emit(Loading(LoadingTypes.loadingDomain));
|
||||
var list = await api.domainList();
|
||||
var list = await (api.domainList() as Future<List<String>>);
|
||||
if (list.isEmpty) {
|
||||
emit(Empty());
|
||||
} else if (list.length == 1) {
|
||||
|
|
|
@ -30,11 +30,12 @@ class HetznerFormCubit extends FormCubit {
|
|||
|
||||
final AppConfigCubit initializingCubit;
|
||||
|
||||
FieldCubit<String> apiKey;
|
||||
// ignore: close_sinks
|
||||
late final FieldCubit<String> apiKey;
|
||||
|
||||
@override
|
||||
FutureOr<bool> asyncValidation() async {
|
||||
bool isKeyValid;
|
||||
late bool isKeyValid;
|
||||
try {
|
||||
isKeyValid = await apiClient.isValid(apiKey.state.value);
|
||||
} catch (e) {
|
||||
|
|
|
@ -46,9 +46,12 @@ class RootUserFormCubit extends FormCubit {
|
|||
|
||||
final AppConfigCubit initializingCubit;
|
||||
|
||||
FieldCubit<String> userName;
|
||||
FieldCubit<String> password;
|
||||
FieldCubit<bool> isVisible;
|
||||
// ignore: close_sinks
|
||||
late final FieldCubit<String> userName;
|
||||
// ignore: close_sinks
|
||||
late final FieldCubit<String> password;
|
||||
// ignore: close_sinks
|
||||
late final FieldCubit<bool> isVisible;
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
|
|
|
@ -7,8 +7,8 @@ import 'package:selfprivacy/utils/password_generator.dart';
|
|||
|
||||
class UserFormCubit extends FormCubit {
|
||||
UserFormCubit({
|
||||
this.usersCubit,
|
||||
User user,
|
||||
required this.usersCubit,
|
||||
User? user,
|
||||
}) {
|
||||
var isEdit = user != null;
|
||||
|
||||
|
@ -16,7 +16,7 @@ class UserFormCubit extends FormCubit {
|
|||
var passwordRegExp = RegExp(r"[\n\r\s]+");
|
||||
|
||||
login = FieldCubit(
|
||||
initalValue: isEdit ? user.login : '',
|
||||
initalValue: isEdit ? user!.login : '',
|
||||
validations: [
|
||||
RequiredStringValidation('required'),
|
||||
ValidationModel<String>(
|
||||
|
@ -25,7 +25,7 @@ class UserFormCubit extends FormCubit {
|
|||
);
|
||||
|
||||
password = FieldCubit(
|
||||
initalValue: isEdit ? user.password : genPass(),
|
||||
initalValue: isEdit ? user!.password : genPass(),
|
||||
validations: [
|
||||
RequiredStringValidation('required'),
|
||||
ValidationModel<String>(
|
||||
|
@ -42,15 +42,16 @@ class UserFormCubit extends FormCubit {
|
|||
login: login.state.value,
|
||||
password: password.state.value,
|
||||
);
|
||||
usersCubit.add(user);
|
||||
usersCubit.addUser(user);
|
||||
}
|
||||
|
||||
FieldCubit<String> login;
|
||||
FieldCubit<String> password;
|
||||
// ignore: close_sinks
|
||||
late FieldCubit<String> login;
|
||||
late FieldCubit<String> password;
|
||||
|
||||
void genNewPassword() {
|
||||
password.externalSetValue(genPass());
|
||||
}
|
||||
|
||||
UsersCubit usersCubit;
|
||||
late UsersCubit usersCubit;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ class LegnthStringValidationWithLenghShowing extends ValidationModel<String> {
|
|||
: super((n) => n.length != length, errorText);
|
||||
|
||||
@override
|
||||
String check(String val) {
|
||||
String? check(String val) {
|
||||
var length = val.length;
|
||||
var errorMassage = this.errorMassage.replaceAll("[]", length.toString());
|
||||
return test(val) ? errorMassage : null;
|
||||
|
|
|
@ -8,14 +8,14 @@ part 'users_state.dart';
|
|||
class UsersCubit extends Cubit<UsersState> {
|
||||
UsersCubit() : super(UsersState([]));
|
||||
|
||||
void add(User user) {
|
||||
void addUser(User user) {
|
||||
var users = [...state.users];
|
||||
users.add(user);
|
||||
|
||||
emit(UsersState(users));
|
||||
}
|
||||
|
||||
void remove(User user) {
|
||||
void remove(User? user) {
|
||||
var users = [...state.users];
|
||||
users.remove(user);
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@ import 'package:flutter/widgets.dart';
|
|||
|
||||
class NavigationService {
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
NavigatorState get navigator => navigatorKey.currentState;
|
||||
NavigatorState? get navigator => navigatorKey.currentState;
|
||||
|
||||
void showPopUpDialog(AlertDialog dialog) {
|
||||
final context = navigatorKey.currentState.overlay.context;
|
||||
final context = navigatorKey.currentState!.overlay!.context;
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
|
|
|
@ -9,10 +9,10 @@ class BackblazeCredential {
|
|||
BackblazeCredential({this.keyId, this.applicationKey});
|
||||
|
||||
@HiveField(0)
|
||||
final String keyId;
|
||||
final String? keyId;
|
||||
|
||||
@HiveField(1)
|
||||
final String applicationKey;
|
||||
final String? applicationKey;
|
||||
|
||||
get encodedApiKey => encodedBackblazeKey(keyId, applicationKey);
|
||||
|
||||
|
@ -22,7 +22,7 @@ class BackblazeCredential {
|
|||
}
|
||||
}
|
||||
|
||||
String encodedBackblazeKey(String keyId, String applicationKey) {
|
||||
String encodedBackblazeKey(String? keyId, String? applicationKey) {
|
||||
String _apiKey = '$keyId:$applicationKey';
|
||||
String encodedApiKey = base64.encode(utf8.encode(_apiKey));
|
||||
return encodedApiKey;
|
||||
|
|
|
@ -17,8 +17,8 @@ class BackblazeCredentialAdapter extends TypeAdapter<BackblazeCredential> {
|
|||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return BackblazeCredential(
|
||||
keyId: fields[0] as String,
|
||||
applicationKey: fields[1] as String,
|
||||
keyId: fields[0] as String?,
|
||||
applicationKey: fields[1] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@ class CloudFlareDomain {
|
|||
CloudFlareDomain({this.domainName, this.zoneId});
|
||||
|
||||
@HiveField(0)
|
||||
final String domainName;
|
||||
final String? domainName;
|
||||
|
||||
@HiveField(1)
|
||||
final String zoneId;
|
||||
final String? zoneId;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
|
|
|
@ -17,8 +17,8 @@ class CloudFlareDomainAdapter extends TypeAdapter<CloudFlareDomain> {
|
|||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return CloudFlareDomain(
|
||||
domainName: fields[0] as String,
|
||||
zoneId: fields[1] as String,
|
||||
domainName: fields[0] as String?,
|
||||
zoneId: fields[1] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'dns_records.g.dart';
|
||||
|
@ -6,17 +5,17 @@ part 'dns_records.g.dart';
|
|||
@JsonSerializable(createToJson: true, createFactory: false)
|
||||
class DnsRecords {
|
||||
DnsRecords({
|
||||
@required this.type,
|
||||
@required this.name,
|
||||
@required this.content,
|
||||
required this.type,
|
||||
required this.name,
|
||||
required this.content,
|
||||
this.ttl = 3600,
|
||||
this.priority = 10,
|
||||
this.proxied = false,
|
||||
});
|
||||
|
||||
final String type;
|
||||
final String name;
|
||||
final String content;
|
||||
final String? name;
|
||||
final String? content;
|
||||
final int ttl;
|
||||
final int priority;
|
||||
final bool proxied;
|
||||
|
|
|
@ -5,12 +5,12 @@ final formater = new DateFormat('hh:mm');
|
|||
class Message {
|
||||
Message({this.text, this.type = MessageType.normal}) : time = DateTime.now();
|
||||
|
||||
final String text;
|
||||
final String? text;
|
||||
final DateTime time;
|
||||
final MessageType type;
|
||||
String get timeString => formater.format(time);
|
||||
|
||||
static Message warn({String text}) => Message(
|
||||
static Message warn({String? text}) => Message(
|
||||
text: text,
|
||||
type: MessageType.warning,
|
||||
);
|
||||
|
|
|
@ -10,7 +10,7 @@ enum ProviderType {
|
|||
}
|
||||
|
||||
class ProviderModel extends Equatable {
|
||||
const ProviderModel({this.state, this.type});
|
||||
const ProviderModel({required this.state, required this.type});
|
||||
|
||||
final StateType state;
|
||||
final ProviderType type;
|
||||
|
@ -21,7 +21,7 @@ class ProviderModel extends Equatable {
|
|||
);
|
||||
|
||||
@override
|
||||
List<Object> get props => [state, type];
|
||||
List<Object?> get props => [state, type];
|
||||
|
||||
IconData get icon {
|
||||
switch (type) {
|
||||
|
@ -31,10 +31,8 @@ class ProviderModel extends Equatable {
|
|||
case ProviderType.domain:
|
||||
return BrandIcons.globe;
|
||||
|
||||
break;
|
||||
case ProviderType.backup:
|
||||
return BrandIcons.save;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:flutter/widgets.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'server_details.g.dart';
|
||||
|
@ -6,25 +5,25 @@ part 'server_details.g.dart';
|
|||
@HiveType(typeId: 2)
|
||||
class HetznerServerDetails {
|
||||
HetznerServerDetails({
|
||||
@required this.ip4,
|
||||
@required this.id,
|
||||
@required this.createTime,
|
||||
required this.ip4,
|
||||
required this.id,
|
||||
required this.createTime,
|
||||
this.startTime,
|
||||
});
|
||||
|
||||
@HiveField(0)
|
||||
final String ip4;
|
||||
final String? ip4;
|
||||
|
||||
@HiveField(1)
|
||||
final int id;
|
||||
final int? id;
|
||||
|
||||
@HiveField(3)
|
||||
final DateTime createTime;
|
||||
final DateTime? createTime;
|
||||
|
||||
@HiveField(2)
|
||||
final DateTime startTime;
|
||||
final DateTime? startTime;
|
||||
|
||||
HetznerServerDetails copyWith({DateTime startTime}) {
|
||||
HetznerServerDetails copyWith({DateTime? startTime}) {
|
||||
return HetznerServerDetails(
|
||||
startTime: startTime ?? this.startTime,
|
||||
createTime: createTime,
|
||||
|
|
|
@ -17,10 +17,10 @@ class HetznerServerDetailsAdapter extends TypeAdapter<HetznerServerDetails> {
|
|||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return HetznerServerDetails(
|
||||
ip4: fields[0] as String,
|
||||
id: fields[1] as int,
|
||||
createTime: fields[3] as DateTime,
|
||||
startTime: fields[2] as DateTime,
|
||||
ip4: fields[0] as String?,
|
||||
id: fields[1] as int?,
|
||||
createTime: fields[3] as DateTime?,
|
||||
startTime: fields[2] as DateTime?,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class ServerStatus {
|
||||
final StatusTypes http;
|
||||
final StatusTypes imap;
|
||||
final StatusTypes smtp;
|
||||
|
||||
ServerStatus({
|
||||
@required this.http,
|
||||
required this.http,
|
||||
this.imap = StatusTypes.nodata,
|
||||
this.smtp = StatusTypes.nodata,
|
||||
});
|
||||
|
@ -20,7 +18,7 @@ class ServerStatus {
|
|||
}
|
||||
}
|
||||
|
||||
StatusTypes statusTypeFromNumber(int number) {
|
||||
StatusTypes statusTypeFromNumber(int? number) {
|
||||
if (number == 0) {
|
||||
return StatusTypes.ok;
|
||||
} else if (number == 1) {
|
||||
|
|
|
@ -10,7 +10,7 @@ enum ServiceTypes {
|
|||
}
|
||||
|
||||
class Service extends Equatable {
|
||||
const Service({this.state, this.type});
|
||||
const Service({required this.state, required this.type});
|
||||
|
||||
final StateType state;
|
||||
final ServiceTypes type;
|
||||
|
@ -21,5 +21,5 @@ class Service extends Equatable {
|
|||
);
|
||||
|
||||
@override
|
||||
List<Object> get props => [state, type];
|
||||
List<Object?> get props => [state, type];
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import 'dart:ui';
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:selfprivacy/utils/color_utils.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:selfprivacy/utils/crypto.dart';
|
||||
|
@ -11,18 +10,18 @@ part 'user.g.dart';
|
|||
@HiveType(typeId: 1)
|
||||
class User extends Equatable {
|
||||
User({
|
||||
@required this.login,
|
||||
@required this.password,
|
||||
required this.login,
|
||||
required this.password,
|
||||
});
|
||||
|
||||
@HiveField(0)
|
||||
final String login;
|
||||
|
||||
|
||||
@HiveField(1)
|
||||
final String password;
|
||||
|
||||
@override
|
||||
List<Object> get props => [login, password];
|
||||
List<Object?> get props => [login, password];
|
||||
|
||||
Color get color => stringToColor(login);
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ void main() async {
|
|||
class MyApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var appSettings = context.watch<AppSettingsCubit>().state;
|
||||
AppSettingsState appSettings = context.watch<AppSettingsCubit>().state;
|
||||
|
||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
value: SystemUiOverlayStyle.light, // Manually changnig appbar color
|
||||
|
@ -51,12 +51,12 @@ class MyApp extends StatelessWidget {
|
|||
home: appSettings.isOnbordingShowing
|
||||
? OnboardingPage(nextPage: InitializingPage())
|
||||
: RootPage(),
|
||||
builder: (BuildContext context, Widget widget) {
|
||||
builder: (BuildContext context, Widget? widget) {
|
||||
Widget error = Text('...rendering error...');
|
||||
if (widget is Scaffold || widget is Navigator)
|
||||
error = Scaffold(body: Center(child: error));
|
||||
ErrorWidget.builder = (FlutterErrorDetails errorDetails) => error;
|
||||
return widget;
|
||||
return widget!;
|
||||
},
|
||||
),
|
||||
);
|
||||
|
|
|
@ -3,14 +3,14 @@ import 'package:selfprivacy/config/brand_colors.dart';
|
|||
|
||||
class ActionButton extends StatelessWidget {
|
||||
const ActionButton({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.text,
|
||||
this.onPressed,
|
||||
this.isRed = false,
|
||||
}) : super(key: key);
|
||||
|
||||
final VoidCallback onPressed;
|
||||
final String text;
|
||||
final VoidCallback? onPressed;
|
||||
final String? text;
|
||||
final bool isRed;
|
||||
|
||||
@override
|
||||
|
@ -19,12 +19,12 @@ class ActionButton extends StatelessWidget {
|
|||
|
||||
return TextButton(
|
||||
child: Text(
|
||||
text,
|
||||
text!,
|
||||
style: isRed ? TextStyle(color: BrandColors.red1) : null,
|
||||
),
|
||||
onPressed: () {
|
||||
navigator.pop();
|
||||
if (onPressed != null) onPressed();
|
||||
if (onPressed != null) onPressed!();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@ import 'package:flutter/material.dart';
|
|||
|
||||
class BrandAlert extends AlertDialog {
|
||||
BrandAlert({
|
||||
Key key,
|
||||
String title,
|
||||
String contentText,
|
||||
List<Widget> acitons,
|
||||
Key? key,
|
||||
String? title,
|
||||
String? contentText,
|
||||
List<Widget>? acitons,
|
||||
}) : super(
|
||||
key: key,
|
||||
title: title != null ? Text(title) : null,
|
||||
content: title != null ? Text(contentText) : null,
|
||||
content: title != null ? Text(contentText!) : null,
|
||||
actions: acitons,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,10 +8,10 @@ enum BrandButtonTypes { rised, text, iconText }
|
|||
|
||||
class BrandButton {
|
||||
static rised({
|
||||
Key key,
|
||||
@required VoidCallback onPressed,
|
||||
String title,
|
||||
Widget child,
|
||||
Key? key,
|
||||
required VoidCallback? onPressed,
|
||||
String? title,
|
||||
Widget? child,
|
||||
}) {
|
||||
assert(title == null || child == null, 'required title or child');
|
||||
assert(title != null || child != null, 'required title or child');
|
||||
|
@ -24,9 +24,9 @@ class BrandButton {
|
|||
}
|
||||
|
||||
static text({
|
||||
Key key,
|
||||
@required VoidCallback onPressed,
|
||||
@required String title,
|
||||
Key? key,
|
||||
required VoidCallback onPressed,
|
||||
required String title,
|
||||
}) =>
|
||||
_TextButton(
|
||||
key: key,
|
||||
|
@ -35,10 +35,10 @@ class BrandButton {
|
|||
);
|
||||
|
||||
static iconText({
|
||||
Key key,
|
||||
@required VoidCallback onPressed,
|
||||
@required String title,
|
||||
@required Icon icon,
|
||||
Key? key,
|
||||
required VoidCallback onPressed,
|
||||
required String title,
|
||||
required Icon icon,
|
||||
}) =>
|
||||
_IconTextButton(
|
||||
key: key,
|
||||
|
@ -50,15 +50,15 @@ class BrandButton {
|
|||
|
||||
class _RisedButton extends StatelessWidget {
|
||||
const _RisedButton({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.onPressed,
|
||||
this.title,
|
||||
this.child,
|
||||
}) : super(key: key);
|
||||
|
||||
final VoidCallback onPressed;
|
||||
final String title;
|
||||
final Widget child;
|
||||
final VoidCallback? onPressed;
|
||||
final String? title;
|
||||
final Widget? child;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -88,13 +88,13 @@ class _RisedButton extends StatelessWidget {
|
|||
|
||||
class _TextButton extends StatelessWidget {
|
||||
const _TextButton({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.onPressed,
|
||||
this.title,
|
||||
}) : super(key: key);
|
||||
|
||||
final VoidCallback onPressed;
|
||||
final String title;
|
||||
final VoidCallback? onPressed;
|
||||
final String? title;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -106,7 +106,7 @@ class _TextButton extends StatelessWidget {
|
|||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Text(
|
||||
title,
|
||||
title!,
|
||||
style: TextStyle(
|
||||
color: BrandColors.blue,
|
||||
fontSize: 16,
|
||||
|
@ -120,12 +120,12 @@ class _TextButton extends StatelessWidget {
|
|||
}
|
||||
|
||||
class _IconTextButton extends StatelessWidget {
|
||||
const _IconTextButton({Key key, this.onPressed, this.title, this.icon})
|
||||
const _IconTextButton({Key? key, this.onPressed, this.title, this.icon})
|
||||
: super(key: key);
|
||||
|
||||
final VoidCallback onPressed;
|
||||
final String title;
|
||||
final Icon icon;
|
||||
final VoidCallback? onPressed;
|
||||
final String? title;
|
||||
final Icon? icon;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -4,11 +4,11 @@ import 'package:selfprivacy/utils/extensions/elevation_extension.dart';
|
|||
|
||||
class BrandCard extends StatelessWidget {
|
||||
const BrandCard({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.child,
|
||||
}) : super(key: key);
|
||||
|
||||
final Widget child;
|
||||
final Widget? child;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:selfprivacy/config/brand_colors.dart';
|
||||
|
||||
class BrandDivider extends StatelessWidget {
|
||||
const BrandDivider({Key key}) : super(key: key);
|
||||
const BrandDivider({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -4,8 +4,8 @@ import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
|||
|
||||
class BrandHeader extends StatelessWidget {
|
||||
const BrandHeader({
|
||||
Key key,
|
||||
@required this.title,
|
||||
Key? key,
|
||||
required this.title,
|
||||
this.hasBackButton = false,
|
||||
}) : super(key: key);
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ class BrandIcons {
|
|||
BrandIcons._();
|
||||
|
||||
static const _kFontFam = 'BrandIcons';
|
||||
static const _kFontPkg = null;
|
||||
static const dynamic _kFontPkg = null;
|
||||
|
||||
static const IconData connection =
|
||||
IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
|
|
|
@ -4,11 +4,11 @@ var navigatorKey = GlobalKey<NavigatorState>();
|
|||
|
||||
class BrandModalSheet extends StatelessWidget {
|
||||
const BrandModalSheet({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.child,
|
||||
}) : super(key: key);
|
||||
|
||||
final Widget child;
|
||||
final Widget? child;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DraggableScrollableSheet(
|
||||
|
|
|
@ -5,21 +5,19 @@ import 'package:url_launcher/url_launcher.dart';
|
|||
|
||||
class BrandSpanButton extends TextSpan {
|
||||
BrandSpanButton({
|
||||
@required String text,
|
||||
@required VoidCallback onTap,
|
||||
TextStyle style,
|
||||
}) : assert(text != null),
|
||||
assert(onTap != null),
|
||||
super(
|
||||
required String text,
|
||||
required VoidCallback onTap,
|
||||
TextStyle? style,
|
||||
}) : super(
|
||||
recognizer: TapGestureRecognizer()..onTap = onTap,
|
||||
text: text,
|
||||
style: (style ?? TextStyle()).copyWith(color: BrandColors.blue),
|
||||
);
|
||||
|
||||
static link({
|
||||
@required String text,
|
||||
String urlString,
|
||||
TextStyle style,
|
||||
required String text,
|
||||
String? urlString,
|
||||
TextStyle? style,
|
||||
}) =>
|
||||
BrandSpanButton(
|
||||
text: text,
|
||||
|
|
|
@ -1,37 +1,38 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/config/brand_colors.dart';
|
||||
import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
final _kBottomTabBarHeight = 51;
|
||||
|
||||
class BrandTabBar extends StatefulWidget {
|
||||
BrandTabBar({Key key, this.controller}) : super(key: key);
|
||||
BrandTabBar({Key? key, this.controller}) : super(key: key);
|
||||
|
||||
final TabController controller;
|
||||
final TabController? controller;
|
||||
@override
|
||||
_BrandTabBarState createState() => _BrandTabBarState();
|
||||
}
|
||||
|
||||
class _BrandTabBarState extends State<BrandTabBar> {
|
||||
int currentIndex;
|
||||
int? currentIndex;
|
||||
@override
|
||||
void initState() {
|
||||
currentIndex = widget.controller.index;
|
||||
widget.controller.addListener(_listener);
|
||||
currentIndex = widget.controller!.index;
|
||||
widget.controller!.addListener(_listener);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
_listener() {
|
||||
if (currentIndex != widget.controller.index) {
|
||||
if (currentIndex != widget.controller!.index) {
|
||||
setState(() {
|
||||
currentIndex = widget.controller.index;
|
||||
currentIndex = widget.controller!.index;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
widget.controller ?? widget.controller.removeListener(_listener);
|
||||
widget.controller ?? widget.controller!.removeListener(_listener);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
@ -50,10 +51,10 @@ class _BrandTabBarState extends State<BrandTabBar> {
|
|||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_getIconButton('Провайдеры', BrandIcons.server, 0),
|
||||
_getIconButton('Сервисы', BrandIcons.box, 1),
|
||||
_getIconButton('Пользователи', BrandIcons.users, 2),
|
||||
_getIconButton('Еще', BrandIcons.menu, 3),
|
||||
_getIconButton('basis.providers'.tr(), BrandIcons.server, 0),
|
||||
_getIconButton('basis.services'.tr(), BrandIcons.box, 1),
|
||||
_getIconButton('basis.users'.tr(), BrandIcons.users, 2),
|
||||
_getIconButton('basis.more'.tr(), BrandIcons.menu, 3),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -68,7 +69,7 @@ class _BrandTabBarState extends State<BrandTabBar> {
|
|||
var isActive = currentIndex == index;
|
||||
var color = isActive ? acitivColor : BrandColors.inactive;
|
||||
return InkWell(
|
||||
onTap: () => widget.controller.animateTo(index),
|
||||
onTap: () => widget.controller!.animateTo(index),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(6),
|
||||
child: ConstrainedBox(
|
||||
|
|
|
@ -17,26 +17,26 @@ enum TextType {
|
|||
class BrandText extends StatelessWidget {
|
||||
const BrandText(
|
||||
this.text, {
|
||||
Key key,
|
||||
Key? key,
|
||||
this.style,
|
||||
@required this.type,
|
||||
required this.type,
|
||||
this.overflow,
|
||||
this.softWrap,
|
||||
this.textAlign,
|
||||
}) : super(key: key);
|
||||
|
||||
final String text;
|
||||
final TextStyle style;
|
||||
final String? text;
|
||||
final TextStyle? style;
|
||||
final TextType type;
|
||||
final TextOverflow overflow;
|
||||
final bool softWrap;
|
||||
final TextAlign textAlign;
|
||||
final TextOverflow? overflow;
|
||||
final bool? softWrap;
|
||||
final TextAlign? textAlign;
|
||||
|
||||
factory BrandText.h1(
|
||||
String text, {
|
||||
TextStyle style,
|
||||
TextOverflow overflow,
|
||||
bool softWrap,
|
||||
String? text, {
|
||||
TextStyle? style,
|
||||
TextOverflow? overflow,
|
||||
bool? softWrap,
|
||||
}) =>
|
||||
BrandText(
|
||||
text,
|
||||
|
@ -44,18 +44,18 @@ class BrandText extends StatelessWidget {
|
|||
style: style,
|
||||
);
|
||||
|
||||
factory BrandText.onboardingTitle(String text, {TextStyle style}) =>
|
||||
factory BrandText.onboardingTitle(String text, {TextStyle? style}) =>
|
||||
BrandText(
|
||||
text,
|
||||
type: TextType.onboardingTitle,
|
||||
style: style,
|
||||
);
|
||||
factory BrandText.h2(String text, {TextStyle style}) => BrandText(
|
||||
factory BrandText.h2(String? text, {TextStyle? style}) => BrandText(
|
||||
text,
|
||||
type: TextType.h2,
|
||||
style: style,
|
||||
);
|
||||
factory BrandText.h3(String text, {TextStyle style, TextAlign textAlign}) =>
|
||||
factory BrandText.h3(String text, {TextStyle? style, TextAlign? textAlign}) =>
|
||||
BrandText(
|
||||
text,
|
||||
type: TextType.h3,
|
||||
|
@ -63,35 +63,35 @@ class BrandText extends StatelessWidget {
|
|||
textAlign: textAlign,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
);
|
||||
factory BrandText.h4(String text, {TextStyle style}) => BrandText(
|
||||
factory BrandText.h4(String? text, {TextStyle? style}) => BrandText(
|
||||
text,
|
||||
type: TextType.h4,
|
||||
style: style,
|
||||
);
|
||||
factory BrandText.body1(String text, {TextStyle style}) => BrandText(
|
||||
factory BrandText.body1(String? text, {TextStyle? style}) => BrandText(
|
||||
text,
|
||||
type: TextType.body1,
|
||||
style: style,
|
||||
);
|
||||
factory BrandText.body2(String text, {TextStyle style}) => BrandText(
|
||||
factory BrandText.body2(String? text, {TextStyle? style}) => BrandText(
|
||||
text,
|
||||
type: TextType.body2,
|
||||
style: style,
|
||||
);
|
||||
factory BrandText.medium(String text,
|
||||
{TextStyle style, TextAlign textAlign}) =>
|
||||
factory BrandText.medium(String? text,
|
||||
{TextStyle? style, TextAlign? textAlign}) =>
|
||||
BrandText(
|
||||
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,
|
||||
type: TextType.small,
|
||||
style: style,
|
||||
);
|
||||
factory BrandText.buttonTitleText(String text, {TextStyle style}) =>
|
||||
factory BrandText.buttonTitleText(String? text, {TextStyle? style}) =>
|
||||
BrandText(
|
||||
text,
|
||||
type: TextType.buttonTitleText,
|
||||
|
@ -99,7 +99,7 @@ class BrandText extends StatelessWidget {
|
|||
);
|
||||
@override
|
||||
Text build(BuildContext context) {
|
||||
TextStyle style;
|
||||
TextStyle? style;
|
||||
var isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
switch (type) {
|
||||
|
@ -153,7 +153,7 @@ class BrandText extends StatelessWidget {
|
|||
style = style.merge(this.style);
|
||||
}
|
||||
return Text(
|
||||
text,
|
||||
text!,
|
||||
style: style,
|
||||
overflow: overflow,
|
||||
softWrap: softWrap,
|
||||
|
|
|
@ -6,21 +6,21 @@ import 'package:selfprivacy/utils/named_font_weight.dart';
|
|||
|
||||
class BrandTimer extends StatefulWidget {
|
||||
const BrandTimer({
|
||||
Key key,
|
||||
@required this.startDateTime,
|
||||
@required this.duration,
|
||||
Key? key,
|
||||
required this.startDateTime,
|
||||
required this.duration,
|
||||
}) : super(key: key);
|
||||
|
||||
final DateTime startDateTime;
|
||||
final Duration duration;
|
||||
final DateTime? startDateTime;
|
||||
final Duration? duration;
|
||||
|
||||
@override
|
||||
_BrandTimerState createState() => _BrandTimerState();
|
||||
}
|
||||
|
||||
class _BrandTimerState extends State<BrandTimer> {
|
||||
String _timeString;
|
||||
Timer timer;
|
||||
String? _timeString;
|
||||
late Timer timer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -31,8 +31,8 @@ class _BrandTimerState extends State<BrandTimer> {
|
|||
_timerStart() {
|
||||
_timeString = diffenceFromStart;
|
||||
timer = Timer.periodic(Duration(seconds: 1), (Timer t) {
|
||||
var timePassed = DateTime.now().difference(widget.startDateTime);
|
||||
if (timePassed > widget.duration) {
|
||||
var timePassed = DateTime.now().difference(widget.startDateTime!);
|
||||
if (timePassed > widget.duration!) {
|
||||
t.cancel();
|
||||
} else {
|
||||
_getTime();
|
||||
|
@ -66,12 +66,12 @@ class _BrandTimerState extends State<BrandTimer> {
|
|||
}
|
||||
|
||||
String get diffenceFromStart =>
|
||||
_durationToString(DateTime.now().difference(widget.startDateTime));
|
||||
_durationToString(DateTime.now().difference(widget.startDateTime!));
|
||||
|
||||
String _durationToString(Duration duration) {
|
||||
String twoDigits(int n) => n.toString().padLeft(2, "0");
|
||||
String twoDigitSeconds =
|
||||
twoDigits(widget.duration.inSeconds - duration.inSeconds.remainder(60));
|
||||
twoDigits(widget.duration!.inSeconds - duration.inSeconds.remainder(60));
|
||||
|
||||
return "$twoDigitSeconds cек";
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ import 'package:selfprivacy/config/brand_colors.dart';
|
|||
|
||||
class DotsIndicator extends StatelessWidget {
|
||||
const DotsIndicator({
|
||||
Key key,
|
||||
@required this.activeIndex,
|
||||
@required this.count,
|
||||
Key? key,
|
||||
required this.activeIndex,
|
||||
required this.count,
|
||||
}) : super(key: key);
|
||||
|
||||
final int activeIndex;
|
||||
|
|
|
@ -2,10 +2,10 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class BrandError extends StatelessWidget {
|
||||
const BrandError({Key key, this.error, this.stackTrace}) : super(key: key);
|
||||
const BrandError({Key? key, this.error, this.stackTrace}) : super(key: key);
|
||||
|
||||
final Object error;
|
||||
final StackTrace stackTrace;
|
||||
final Object? error;
|
||||
final StackTrace? stackTrace;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -3,14 +3,14 @@ import 'package:selfprivacy/config/brand_colors.dart';
|
|||
import 'package:selfprivacy/logic/models/state_types.dart';
|
||||
|
||||
class IconStatusMask extends StatelessWidget {
|
||||
IconStatusMask({this.child, this.status});
|
||||
IconStatusMask({required this.child, required this.status});
|
||||
final Icon child;
|
||||
|
||||
final StateType status;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Color> colors;
|
||||
late List<Color> colors;
|
||||
switch (status) {
|
||||
case StateType.uninitialized:
|
||||
colors = BrandColors.uninitializedGradientColors;
|
||||
|
|
|
@ -2,9 +2,10 @@ import 'package:flutter/material.dart';
|
|||
import 'package:selfprivacy/config/brand_colors.dart';
|
||||
import 'package:selfprivacy/ui/pages/initializing/initializing.dart';
|
||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
class NotReadyCard extends StatelessWidget {
|
||||
const NotReadyCard({Key key}) : super(key: key);
|
||||
const NotReadyCard({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -16,13 +17,13 @@ class NotReadyCard extends StatelessWidget {
|
|||
text: TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: 'Завершите настройку приложения используя ',
|
||||
text: 'not_ready_card.1'.tr(),
|
||||
style: TextStyle(color: BrandColors.white),
|
||||
),
|
||||
WidgetSpan(
|
||||
child: GestureDetector(
|
||||
child: Text(
|
||||
'Мастер подключения',
|
||||
'not_ready_card.2'.tr(),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.blueAccent
|
||||
|
@ -38,7 +39,7 @@ class NotReadyCard extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: ' для продолжения работы',
|
||||
text: 'not_ready_card.3'.tr(),
|
||||
style: TextStyle(color: BrandColors.white),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -7,9 +7,9 @@ import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
|||
|
||||
class ProgressBar extends StatefulWidget {
|
||||
ProgressBar({
|
||||
Key key,
|
||||
@required this.steps,
|
||||
@required this.activeIndex,
|
||||
Key? key,
|
||||
required this.steps,
|
||||
required this.activeIndex,
|
||||
}) : super(key: key);
|
||||
|
||||
final int activeIndex;
|
||||
|
@ -102,14 +102,14 @@ class _ProgressBarState extends State<ProgressBar> {
|
|||
}
|
||||
|
||||
Expanded _stepTitle({
|
||||
int index,
|
||||
TextStyle style,
|
||||
String step,
|
||||
required int index,
|
||||
TextStyle? style,
|
||||
String? step,
|
||||
}) {
|
||||
var isActive = index == widget.activeIndex;
|
||||
var checked = index < widget.activeIndex;
|
||||
|
||||
style = isActive ? style.copyWith(fontWeight: FontWeight.w700) : style;
|
||||
style = isActive ? style!.copyWith(fontWeight: FontWeight.w700) : style;
|
||||
return Expanded(
|
||||
flex: 2,
|
||||
child: RichText(
|
||||
|
|
|
@ -3,10 +3,10 @@ import 'package:selfprivacy/config/brand_colors.dart';
|
|||
|
||||
class SwitcherBlock extends StatelessWidget {
|
||||
const SwitcherBlock({
|
||||
Key key,
|
||||
@required this.child,
|
||||
@required this.isActive,
|
||||
@required this.onChange,
|
||||
Key? key,
|
||||
required this.child,
|
||||
required this.isActive,
|
||||
required this.onChange,
|
||||
}) : super(key: key);
|
||||
|
||||
final Widget child;
|
||||
|
|
|
@ -81,7 +81,7 @@ class InitializingPage extends StatelessWidget {
|
|||
onPressed: () {
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
materialRoute(RootPage()),
|
||||
(predicate) => predicate == null,
|
||||
(predicate) => false,
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 30),
|
||||
|
@ -96,7 +96,7 @@ class InitializingPage extends StatelessWidget {
|
|||
return BlocProvider(
|
||||
create: (context) => HetznerFormCubit(initializingCubit),
|
||||
child: Builder(builder: (context) {
|
||||
var formCubit = context.watch<HetznerFormCubit>();
|
||||
var formCubitState = context.watch<HetznerFormCubit>().state;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
@ -111,7 +111,7 @@ class InitializingPage extends StatelessWidget {
|
|||
'Здесь будут жить наши данные и SelfPrivacy-сервисы'),
|
||||
Spacer(),
|
||||
CubitFormTextField(
|
||||
formFieldCubit: formCubit.apiKey,
|
||||
formFieldCubit: context.read<HetznerFormCubit>().apiKey,
|
||||
textAlign: TextAlign.center,
|
||||
scrollPadding: EdgeInsets.only(bottom: 70),
|
||||
decoration: InputDecoration(
|
||||
|
@ -120,8 +120,9 @@ class InitializingPage extends StatelessWidget {
|
|||
),
|
||||
Spacer(),
|
||||
BrandButton.rised(
|
||||
onPressed:
|
||||
formCubit.state.isSubmitting ? null : formCubit.trySubmit,
|
||||
onPressed: formCubitState.isSubmitting
|
||||
? null
|
||||
: () => context.read<HetznerFormCubit>().trySubmit(),
|
||||
title: 'Подключить',
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
|
@ -150,7 +151,7 @@ class InitializingPage extends StatelessWidget {
|
|||
return BlocProvider(
|
||||
create: (context) => CloudFlareFormCubit(initializingCubit),
|
||||
child: Builder(builder: (context) {
|
||||
var formCubit = context.watch<CloudFlareFormCubit>();
|
||||
var formCubitState = context.watch<CloudFlareFormCubit>().state;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
@ -165,7 +166,7 @@ class InitializingPage extends StatelessWidget {
|
|||
BrandText.body2('Для управления DNS вашего домена'),
|
||||
Spacer(),
|
||||
CubitFormTextField(
|
||||
formFieldCubit: formCubit.apiKey,
|
||||
formFieldCubit: context.read<CloudFlareFormCubit>().apiKey,
|
||||
textAlign: TextAlign.center,
|
||||
scrollPadding: EdgeInsets.only(bottom: 70),
|
||||
decoration: InputDecoration(
|
||||
|
@ -174,8 +175,9 @@ class InitializingPage extends StatelessWidget {
|
|||
),
|
||||
Spacer(),
|
||||
BrandButton.rised(
|
||||
onPressed:
|
||||
formCubit.state.isSubmitting ? null : formCubit.trySubmit,
|
||||
onPressed: formCubitState.isSubmitting
|
||||
? null
|
||||
: () => context.read<CloudFlareFormCubit>().trySubmit(),
|
||||
title: 'Подключить',
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
|
@ -193,7 +195,7 @@ class InitializingPage extends StatelessWidget {
|
|||
return BlocProvider(
|
||||
create: (context) => BackblazeFormCubit(initializingCubit),
|
||||
child: Builder(builder: (context) {
|
||||
var formCubit = context.watch<BackblazeFormCubit>();
|
||||
var formCubitState = context.watch<BackblazeFormCubit>().state;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
@ -206,7 +208,7 @@ class InitializingPage extends StatelessWidget {
|
|||
SizedBox(height: 10),
|
||||
Spacer(),
|
||||
CubitFormTextField(
|
||||
formFieldCubit: formCubit.keyId,
|
||||
formFieldCubit: context.read<BackblazeFormCubit>().keyId,
|
||||
textAlign: TextAlign.center,
|
||||
scrollPadding: EdgeInsets.only(bottom: 70),
|
||||
decoration: InputDecoration(
|
||||
|
@ -215,7 +217,7 @@ class InitializingPage extends StatelessWidget {
|
|||
),
|
||||
Spacer(),
|
||||
CubitFormTextField(
|
||||
formFieldCubit: formCubit.applicationKey,
|
||||
formFieldCubit: context.read<BackblazeFormCubit>().applicationKey,
|
||||
textAlign: TextAlign.center,
|
||||
scrollPadding: EdgeInsets.only(bottom: 70),
|
||||
decoration: InputDecoration(
|
||||
|
@ -224,8 +226,9 @@ class InitializingPage extends StatelessWidget {
|
|||
),
|
||||
Spacer(),
|
||||
BrandButton.rised(
|
||||
onPressed:
|
||||
formCubit.state.isSubmitting ? null : formCubit.trySubmit,
|
||||
onPressed: formCubitState.isSubmitting
|
||||
? null
|
||||
: () => context.read<BackblazeFormCubit>().trySubmit(),
|
||||
title: 'Подключить',
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
|
@ -243,8 +246,7 @@ class InitializingPage extends StatelessWidget {
|
|||
return BlocProvider(
|
||||
create: (context) => DomainSetupCubit(initializingCubit)..load(),
|
||||
child: Builder(builder: (context) {
|
||||
var domainSetup = context.watch<DomainSetupCubit>();
|
||||
var state = domainSetup.state;
|
||||
DomainSetupState state = context.watch<DomainSetupCubit>().state;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
@ -283,7 +285,7 @@ class InitializingPage extends StatelessWidget {
|
|||
Container(
|
||||
width: 50,
|
||||
child: BrandButton.rised(
|
||||
onPressed: () => domainSetup.load(),
|
||||
onPressed: () => context.read<DomainSetupCubit>().load(),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
@ -302,7 +304,7 @@ class InitializingPage extends StatelessWidget {
|
|||
if (state is Empty) ...[
|
||||
SizedBox(height: 30),
|
||||
BrandButton.rised(
|
||||
onPressed: () => domainSetup.load(),
|
||||
onPressed: () => context.read<DomainSetupCubit>().load(),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
|
@ -319,7 +321,7 @@ class InitializingPage extends StatelessWidget {
|
|||
if (state is Loaded) ...[
|
||||
SizedBox(height: 30),
|
||||
BrandButton.rised(
|
||||
onPressed: () => domainSetup.saveDomain(),
|
||||
onPressed: () => context.read<DomainSetupCubit>().saveDomain(),
|
||||
title: 'Сохранить домен',
|
||||
),
|
||||
],
|
||||
|
@ -340,7 +342,7 @@ class InitializingPage extends StatelessWidget {
|
|||
return BlocProvider(
|
||||
create: (context) => RootUserFormCubit(initializingCubit),
|
||||
child: Builder(builder: (context) {
|
||||
var formCubit = context.watch<RootUserFormCubit>();
|
||||
var formCubitState = context.watch<RootUserFormCubit>().state;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
@ -348,7 +350,7 @@ class InitializingPage extends StatelessWidget {
|
|||
Spacer(),
|
||||
SizedBox(height: 10),
|
||||
CubitFormTextField(
|
||||
formFieldCubit: formCubit.userName,
|
||||
formFieldCubit: context.read<RootUserFormCubit>().userName,
|
||||
textAlign: TextAlign.center,
|
||||
scrollPadding: EdgeInsets.only(bottom: 70),
|
||||
decoration: InputDecoration(
|
||||
|
@ -357,12 +359,12 @@ class InitializingPage extends StatelessWidget {
|
|||
),
|
||||
SizedBox(height: 10),
|
||||
BlocBuilder<FieldCubit<bool>, FieldCubitState<bool>>(
|
||||
bloc: formCubit.isVisible,
|
||||
bloc: context.read<RootUserFormCubit>().isVisible,
|
||||
builder: (context, state) {
|
||||
var isVisible = state.value;
|
||||
return CubitFormTextField(
|
||||
obscureText: !isVisible,
|
||||
formFieldCubit: formCubit.password,
|
||||
formFieldCubit: context.read<RootUserFormCubit>().password,
|
||||
textAlign: TextAlign.center,
|
||||
scrollPadding: EdgeInsets.only(bottom: 70),
|
||||
decoration: InputDecoration(
|
||||
|
@ -371,7 +373,10 @@ class InitializingPage extends StatelessWidget {
|
|||
icon: Icon(
|
||||
isVisible ? Icons.visibility : Icons.visibility_off,
|
||||
),
|
||||
onPressed: () => formCubit.isVisible.setValue(!isVisible),
|
||||
onPressed: () => context
|
||||
.read<RootUserFormCubit>()
|
||||
.isVisible
|
||||
.setValue(!isVisible),
|
||||
),
|
||||
suffixIconConstraints: BoxConstraints(minWidth: 60),
|
||||
prefixIconConstraints: BoxConstraints(maxWidth: 85),
|
||||
|
@ -382,8 +387,9 @@ class InitializingPage extends StatelessWidget {
|
|||
),
|
||||
Spacer(),
|
||||
BrandButton.rised(
|
||||
onPressed:
|
||||
formCubit.state.isSubmitting ? null : formCubit.trySubmit,
|
||||
onPressed: formCubitState.isSubmitting
|
||||
? null
|
||||
: () => context.read<RootUserFormCubit>().trySubmit(),
|
||||
title: 'Подключить',
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
|
@ -410,7 +416,7 @@ class InitializingPage extends StatelessWidget {
|
|||
Spacer(),
|
||||
BrandButton.rised(
|
||||
onPressed:
|
||||
isLoading ? null : appConfigCubit.createServerAndSetDnsRecords,
|
||||
isLoading! ? null : appConfigCubit.createServerAndSetDnsRecords,
|
||||
title: isLoading ? 'loading' : 'Создать сервер',
|
||||
),
|
||||
Spacer(flex: 2),
|
||||
|
@ -427,10 +433,10 @@ class InitializingPage extends StatelessWidget {
|
|||
assert(appConfigCubit.state is TimerState, 'wronge state');
|
||||
var state = appConfigCubit.state as TimerState;
|
||||
|
||||
String text;
|
||||
if (state.isServerReseted) {
|
||||
String? text;
|
||||
if (state.isServerReseted!) {
|
||||
text = 'Сервер презагружен, ждем последнюю проверку';
|
||||
} else if (state.isServerStarted) {
|
||||
} else if (state.isServerStarted!) {
|
||||
text = 'Cервер запушен, сейчас он будет проверен и перезагружен';
|
||||
} else if (state.isServerCreated) {
|
||||
text = 'Cервер создан, идет проверка ДНС адресов и запуск сервера';
|
||||
|
@ -443,7 +449,7 @@ class InitializingPage extends StatelessWidget {
|
|||
SizedBox(height: 10),
|
||||
BrandText.body2(text),
|
||||
SizedBox(height: 10),
|
||||
if (!state.isLoading)
|
||||
if (!state.isLoading!)
|
||||
Row(
|
||||
children: [
|
||||
BrandText.body2('До следующей проверки: '),
|
||||
|
@ -453,7 +459,7 @@ class InitializingPage extends StatelessWidget {
|
|||
)
|
||||
],
|
||||
),
|
||||
if (state.isLoading) BrandText.body2('Проверка'),
|
||||
if (state.isLoading!) BrandText.body2('Проверка'),
|
||||
Spacer(
|
||||
flex: 2,
|
||||
),
|
||||
|
@ -477,7 +483,7 @@ class InitializingPage extends StatelessWidget {
|
|||
|
||||
class _HowHetzner extends StatelessWidget {
|
||||
const _HowHetzner({
|
||||
Key key,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
|
|
@ -5,7 +5,7 @@ import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
|
|||
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
||||
|
||||
class AboutPage extends StatelessWidget {
|
||||
const AboutPage({Key key}) : super(key: key);
|
||||
const AboutPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -11,7 +11,7 @@ import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
|||
import 'package:selfprivacy/utils/named_font_weight.dart';
|
||||
|
||||
class AppSettingsPage extends StatefulWidget {
|
||||
const AppSettingsPage({Key key}) : super(key: key);
|
||||
const AppSettingsPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_AppSettingsPageState createState() => _AppSettingsPageState();
|
||||
|
@ -20,9 +20,7 @@ class AppSettingsPage extends StatefulWidget {
|
|||
class _AppSettingsPageState extends State<AppSettingsPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var appSettings = context.watch<AppSettingsCubit>();
|
||||
|
||||
var isDarkModeOn = appSettings.state.isDarkModeOn;
|
||||
var isDarkModeOn = context.watch<AppSettingsCubit>().state.isDarkModeOn;
|
||||
|
||||
return SafeArea(
|
||||
child: Builder(builder: (context) {
|
||||
|
@ -57,8 +55,9 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
|
|||
activeColor: BrandColors.green1,
|
||||
activeTrackColor: BrandColors.green2,
|
||||
value: Theme.of(context).brightness == Brightness.dark,
|
||||
onChanged: (value) => appSettings.updateDarkMode(
|
||||
isDarkModeOn: !isDarkModeOn),
|
||||
onChanged: (value) => context
|
||||
.read<AppSettingsCubit>()
|
||||
.updateDarkMode(isDarkModeOn: !isDarkModeOn),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -130,9 +129,9 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
|
|||
|
||||
class _TextColumn extends StatelessWidget {
|
||||
const _TextColumn({
|
||||
Key key,
|
||||
@required this.title,
|
||||
@required this.value,
|
||||
Key? key,
|
||||
required this.title,
|
||||
required this.value,
|
||||
this.hasWarning = false,
|
||||
}) : super(key: key);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart';
|
|||
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
|
||||
|
||||
class Console extends StatefulWidget {
|
||||
const Console({Key key}) : super(key: key);
|
||||
const Console({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ConsoleState createState() => _ConsoleState();
|
||||
|
|
|
@ -6,7 +6,7 @@ import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
|||
import 'package:package_info/package_info.dart';
|
||||
|
||||
class InfoPage extends StatelessWidget {
|
||||
const InfoPage({Key key}) : super(key: key);
|
||||
const InfoPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'package:selfprivacy/ui/pages/initializing/initializing.dart';
|
|||
import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart';
|
||||
import 'package:selfprivacy/ui/pages/rootRoute.dart';
|
||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
import 'about/about.dart';
|
||||
import 'app_settings/app_setting.dart';
|
||||
|
@ -16,13 +17,13 @@ import 'console/console.dart';
|
|||
import 'info/info.dart';
|
||||
|
||||
class MorePage extends StatelessWidget {
|
||||
const MorePage({Key key}) : super(key: key);
|
||||
const MorePage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: PreferredSize(
|
||||
child: BrandHeader(title: 'Еще'),
|
||||
child: BrandHeader(title: 'basis.more'.tr()),
|
||||
preferredSize: Size.fromHeight(52),
|
||||
),
|
||||
body: ListView(
|
||||
|
@ -33,32 +34,32 @@ class MorePage extends StatelessWidget {
|
|||
children: [
|
||||
BrandDivider(),
|
||||
_NavItem(
|
||||
title: 'Мастер Подключения',
|
||||
title: 'more.configuration_wizard'.tr(),
|
||||
iconData: BrandIcons.settings,
|
||||
goTo: InitializingPage(),
|
||||
),
|
||||
_NavItem(
|
||||
title: 'Настройки приложения',
|
||||
title: 'more.settings'.tr(),
|
||||
iconData: BrandIcons.settings,
|
||||
goTo: AppSettingsPage(),
|
||||
),
|
||||
_NavItem(
|
||||
title: 'О проекте Selfprivacy',
|
||||
title: 'more.about_project'.tr(),
|
||||
iconData: BrandIcons.triangle,
|
||||
goTo: AboutPage(),
|
||||
),
|
||||
_NavItem(
|
||||
title: 'О приложении',
|
||||
title: 'more.about_app'.tr(),
|
||||
iconData: BrandIcons.help,
|
||||
goTo: InfoPage(),
|
||||
),
|
||||
_NavItem(
|
||||
title: 'Onboarding',
|
||||
title: 'more.onboarding'.tr(),
|
||||
iconData: BrandIcons.triangle,
|
||||
goTo: OnboardingPage(nextPage: RootPage()),
|
||||
),
|
||||
_NavItem(
|
||||
title: 'Console',
|
||||
title: 'more.console'.tr(),
|
||||
iconData: BrandIcons.triangle,
|
||||
goTo: Console(),
|
||||
),
|
||||
|
@ -73,10 +74,10 @@ class MorePage extends StatelessWidget {
|
|||
|
||||
class _NavItem extends StatelessWidget {
|
||||
const _NavItem({
|
||||
Key key,
|
||||
@required this.iconData,
|
||||
@required this.goTo,
|
||||
@required this.title,
|
||||
Key? key,
|
||||
required this.iconData,
|
||||
required this.goTo,
|
||||
required this.title,
|
||||
}) : super(key: key);
|
||||
|
||||
final IconData iconData;
|
||||
|
|
|
@ -3,9 +3,10 @@ import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart';
|
|||
import 'package:selfprivacy/ui/components/brand_button/brand_button.dart';
|
||||
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
class OnboardingPage extends StatefulWidget {
|
||||
const OnboardingPage({Key key, @required this.nextPage}) : super(key: key);
|
||||
const OnboardingPage({Key? key, required this.nextPage}) : super(key: key);
|
||||
|
||||
final Widget nextPage;
|
||||
@override
|
||||
|
@ -54,10 +55,10 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
|||
children: [
|
||||
SizedBox(height: 30),
|
||||
BrandText.h2(
|
||||
'Цифровая независимость и приватность, доступная каждому'),
|
||||
'onboarding.page1_title'.tr(),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
BrandText.body2(
|
||||
'Почта и мессенджер с открытым исходным кодом на вашем личном сервере под вашим полным контролем.'),
|
||||
BrandText.body2('onboarding.page1_text'.tr()),
|
||||
Flexible(
|
||||
child: Center(
|
||||
child: Image.asset(
|
||||
|
@ -78,7 +79,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
|||
curve: Curves.easeIn,
|
||||
);
|
||||
},
|
||||
title: 'Далее',
|
||||
title: 'basis.next'.tr(),
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
],
|
||||
|
@ -94,10 +95,9 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
|||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 30),
|
||||
BrandText.h2('Для работы понадобятся ваши аккаунты'),
|
||||
BrandText.h2('onboarding.page2_title'.tr()),
|
||||
SizedBox(height: 20),
|
||||
BrandText.body2(
|
||||
'Для максимальноей приватности и независимости SelfPrivacy не использует свои серверы. \n \n Если у вас нет домена, аккаунтов на Hetzner, AWS и Clouflare, мы поможем их создать и подключить.'),
|
||||
BrandText.body2('onboarding.page2_text'.tr()),
|
||||
SizedBox(height: 20),
|
||||
Center(
|
||||
child: Image.asset(
|
||||
|
@ -127,7 +127,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
|||
Navigator.of(context)
|
||||
.pushReplacement(materialRoute(widget.nextPage));
|
||||
},
|
||||
title: 'Понял',
|
||||
title: 'basis.got_it'.tr(),
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
],
|
||||
|
@ -137,10 +137,10 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
|||
}
|
||||
|
||||
String _fileName({
|
||||
@required BuildContext context,
|
||||
@required String path,
|
||||
@required String fileName,
|
||||
@required String fileExtention,
|
||||
required BuildContext context,
|
||||
required String path,
|
||||
required String fileName,
|
||||
required String fileExtention,
|
||||
}) {
|
||||
var theme = Theme.of(context);
|
||||
var isDark = theme.brightness == Brightness.dark;
|
||||
|
|
|
@ -12,9 +12,10 @@ import 'package:selfprivacy/ui/components/icon_status_mask/icon_status_mask.dart
|
|||
import 'package:selfprivacy/ui/components/not_ready_card/not_ready_card.dart';
|
||||
import 'package:selfprivacy/ui/pages/providers/settings/settings.dart';
|
||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
class ProvidersPage extends StatefulWidget {
|
||||
ProvidersPage({Key key}) : super(key: key);
|
||||
ProvidersPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ProvidersPageState createState() => _ProvidersPageState();
|
||||
|
@ -23,7 +24,8 @@ class ProvidersPage extends StatefulWidget {
|
|||
class _ProvidersPageState extends State<ProvidersPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var isReady = context.watch<AppConfigCubit>().state.isFullyInitilized;
|
||||
// var isReady = context.watch<AppConfigCubit>().state.isFullyInitilized;
|
||||
var isReady = true;
|
||||
|
||||
final cards = ProviderType.values
|
||||
.map((type) => _Card(
|
||||
|
@ -32,7 +34,7 @@ class _ProvidersPageState extends State<ProvidersPage> {
|
|||
.toList();
|
||||
return Scaffold(
|
||||
appBar: PreferredSize(
|
||||
child: BrandHeader(title: 'Провайдеры'),
|
||||
child: BrandHeader(title: 'providers.page_title'.tr()),
|
||||
preferredSize: Size.fromHeight(52),
|
||||
),
|
||||
body: ListView(
|
||||
|
@ -50,32 +52,31 @@ class _ProvidersPageState extends State<ProvidersPage> {
|
|||
}
|
||||
|
||||
class _Card extends StatelessWidget {
|
||||
const _Card({Key key, @required this.provider}) : super(key: key);
|
||||
const _Card({Key? key, required this.provider}) : super(key: key);
|
||||
|
||||
final ProviderModel provider;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String title;
|
||||
String message;
|
||||
String stableText;
|
||||
var appConfig = context.watch<AppConfigCubit>().state;
|
||||
String? title;
|
||||
String? message;
|
||||
String? stableText;
|
||||
AppConfigState appConfig = context.watch<AppConfigCubit>().state;
|
||||
|
||||
var domainName =
|
||||
appConfig.isDomainFilled ? appConfig.cloudFlareDomain.domainName : '';
|
||||
appConfig.isDomainFilled ? appConfig.cloudFlareDomain!.domainName : '';
|
||||
|
||||
switch (provider.type) {
|
||||
case ProviderType.server:
|
||||
title = 'Сервер';
|
||||
title = 'providers.server.card_title'.tr();
|
||||
stableText = 'В норме';
|
||||
break;
|
||||
case ProviderType.domain:
|
||||
title = 'Домен';
|
||||
title = 'providers.domain.card_title'.tr();
|
||||
message = domainName;
|
||||
stableText = 'Домен настроен';
|
||||
break;
|
||||
case ProviderType.backup:
|
||||
// message = '22 янв 2021 14:30';
|
||||
title = 'Резервное копирование';
|
||||
title = 'providers.backup.card_title'.tr();
|
||||
stableText = 'В норме';
|
||||
break;
|
||||
}
|
||||
|
@ -116,28 +117,29 @@ class _Card extends StatelessWidget {
|
|||
|
||||
class _ProviderDetails extends StatelessWidget {
|
||||
const _ProviderDetails({
|
||||
Key key,
|
||||
@required this.provider,
|
||||
@required this.statusText,
|
||||
Key? key,
|
||||
required this.provider,
|
||||
required this.statusText,
|
||||
}) : super(key: key);
|
||||
|
||||
final ProviderModel provider;
|
||||
final String statusText;
|
||||
final String? statusText;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String title;
|
||||
late String title;
|
||||
|
||||
switch (provider.type) {
|
||||
case ProviderType.server:
|
||||
title = 'Сервер';
|
||||
title = 'providers.server.card_title'.tr();
|
||||
break;
|
||||
case ProviderType.domain:
|
||||
title = 'Домен';
|
||||
title = 'providers.domain.card_title'.tr();
|
||||
|
||||
break;
|
||||
case ProviderType.backup:
|
||||
title = 'Резервное копирование';
|
||||
title = 'providers.backup.card_title'.tr();
|
||||
|
||||
break;
|
||||
}
|
||||
return BrandModalSheet(
|
||||
|
@ -163,7 +165,7 @@ class _ProviderDetails extends StatelessWidget {
|
|||
onSelected: (_PopupMenuItemType result) {
|
||||
switch (result) {
|
||||
case _PopupMenuItemType.setting:
|
||||
navigatorKey.currentState
|
||||
navigatorKey.currentState!
|
||||
.push(materialRoute(SettingsPage()));
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
|||
import 'package:selfprivacy/ui/components/switch_block/switch_bloc.dart';
|
||||
|
||||
class SettingsPage extends StatelessWidget {
|
||||
const SettingsPage({Key key}) : super(key: key);
|
||||
const SettingsPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -62,9 +62,9 @@ class SettingsPage extends StatelessWidget {
|
|||
|
||||
class _Button extends StatelessWidget {
|
||||
const _Button({
|
||||
Key key,
|
||||
@required this.onTap,
|
||||
@required this.child,
|
||||
Key? key,
|
||||
required this.onTap,
|
||||
required this.child,
|
||||
}) : super(key: key);
|
||||
|
||||
final Widget child;
|
||||
|
@ -88,9 +88,9 @@ class _Button extends StatelessWidget {
|
|||
|
||||
class _TextColumn extends StatelessWidget {
|
||||
const _TextColumn({
|
||||
Key key,
|
||||
@required this.title,
|
||||
@required this.value,
|
||||
Key? key,
|
||||
required this.title,
|
||||
required this.value,
|
||||
this.hasWarning = false,
|
||||
}) : super(key: key);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import 'package:selfprivacy/ui/pages/services/services.dart';
|
|||
import 'package:selfprivacy/ui/pages/users/users.dart';
|
||||
|
||||
class RootPage extends StatefulWidget {
|
||||
const RootPage({Key key}) : super(key: key);
|
||||
const RootPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_RootPageState createState() => _RootPageState();
|
||||
|
@ -15,7 +15,7 @@ class RootPage extends StatefulWidget {
|
|||
|
||||
class _RootPageState extends State<RootPage>
|
||||
with SingleTickerProviderStateMixin {
|
||||
TabController tabController;
|
||||
TabController? tabController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -26,7 +26,7 @@ class _RootPageState extends State<RootPage>
|
|||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
tabController.dispose();
|
||||
tabController!.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -12,7 +12,7 @@ import 'package:selfprivacy/ui/components/icon_status_mask/icon_status_mask.dart
|
|||
import 'package:selfprivacy/ui/components/not_ready_card/not_ready_card.dart';
|
||||
|
||||
class ServicesPage extends StatefulWidget {
|
||||
ServicesPage({Key key}) : super(key: key);
|
||||
ServicesPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ServicesPageState createState() => _ServicesPageState();
|
||||
|
@ -21,9 +21,10 @@ class ServicesPage extends StatefulWidget {
|
|||
class _ServicesPageState extends State<ServicesPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final serviceCubit = context.watch<ServicesCubit>();
|
||||
final connected = serviceCubit.state.connected;
|
||||
final uninitialized = serviceCubit.state.uninitialized;
|
||||
final serviceCubitState = context.watch<ServicesCubit>().state;
|
||||
|
||||
final connected = serviceCubitState.connected;
|
||||
final uninitialized = serviceCubitState.uninitialized;
|
||||
var isReady = context.watch<AppConfigCubit>().state.isFullyInitilized;
|
||||
|
||||
return Scaffold(
|
||||
|
@ -49,14 +50,14 @@ class _ServicesPageState extends State<ServicesPage> {
|
|||
}
|
||||
|
||||
class _Card extends StatelessWidget {
|
||||
const _Card({Key key, @required this.service}) : super(key: key);
|
||||
const _Card({Key? key, required this.service}) : super(key: key);
|
||||
|
||||
final Service service;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String title;
|
||||
IconData iconData;
|
||||
String description;
|
||||
String? title;
|
||||
IconData? iconData;
|
||||
String? description;
|
||||
|
||||
switch (service.type) {
|
||||
case ServiceTypes.messanger:
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
part of 'users.dart';
|
||||
|
||||
class _NoUsers extends StatelessWidget {
|
||||
const _NoUsers({Key key, @required this.text})
|
||||
: assert(text != null),
|
||||
super(key: key);
|
||||
const _NoUsers({Key? key, required this.text}) : super(key: key);
|
||||
|
||||
final String text;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
part of 'users.dart';
|
||||
|
||||
class _Fab extends StatelessWidget {
|
||||
const _Fab({Key key}) : super(key: key);
|
||||
const _Fab({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -3,13 +3,12 @@ part of 'users.dart';
|
|||
class _NewUser extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final usersCubit = context.watch<UsersCubit>();
|
||||
|
||||
return BrandModalSheet(
|
||||
child: BlocProvider(
|
||||
create: (context) => UserFormCubit(usersCubit: usersCubit),
|
||||
create: (context) =>
|
||||
UserFormCubit(usersCubit: context.watch<UsersCubit>()),
|
||||
child: Builder(builder: (context) {
|
||||
var formCubit = context.watch<UserFormCubit>();
|
||||
var formCubitState = context.watch<UserFormCubit>().state;
|
||||
|
||||
return BlocListener<UserFormCubit, FormCubitState>(
|
||||
listener: (context, state) {
|
||||
|
@ -27,7 +26,7 @@ class _NewUser extends StatelessWidget {
|
|||
child: Column(
|
||||
children: [
|
||||
CubitFormTextField(
|
||||
formFieldCubit: formCubit.login,
|
||||
formFieldCubit: context.read<UserFormCubit>().login,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Логин',
|
||||
suffixText: '@example',
|
||||
|
@ -35,7 +34,7 @@ class _NewUser extends StatelessWidget {
|
|||
),
|
||||
SizedBox(height: 20),
|
||||
CubitFormTextField(
|
||||
formFieldCubit: formCubit.password,
|
||||
formFieldCubit: context.read<UserFormCubit>().password,
|
||||
decoration: InputDecoration(
|
||||
alignLabelWithHint: false,
|
||||
labelText: 'Пароль',
|
||||
|
@ -46,18 +45,17 @@ class _NewUser extends StatelessWidget {
|
|||
BrandIcons.refresh,
|
||||
color: BrandColors.blue,
|
||||
),
|
||||
onPressed: formCubit.genNewPassword,
|
||||
onPressed:
|
||||
context.read<UserFormCubit>().genNewPassword,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
BrandButton.rised(
|
||||
onPressed: formCubit.state.isSubmitting
|
||||
onPressed: formCubitState.isSubmitting
|
||||
? null
|
||||
: () {
|
||||
formCubit.trySubmit();
|
||||
},
|
||||
: () => context.read<UserFormCubit>().trySubmit(),
|
||||
title: 'Создать',
|
||||
),
|
||||
SizedBox(height: 40),
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
part of 'users.dart';
|
||||
|
||||
class _User extends StatelessWidget {
|
||||
const _User({Key key, this.user}) : super(key: key);
|
||||
const _User({Key? key, this.user}) : super(key: key);
|
||||
|
||||
final User user;
|
||||
final User? user;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
|
@ -26,12 +26,12 @@ class _User extends StatelessWidget {
|
|||
width: 17,
|
||||
height: 17,
|
||||
decoration: BoxDecoration(
|
||||
color: user.color,
|
||||
color: user!.color,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 20),
|
||||
BrandText.h4(user.login),
|
||||
BrandText.h4(user!.login),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -2,11 +2,11 @@ part of 'users.dart';
|
|||
|
||||
class _UserDetails extends StatelessWidget {
|
||||
const _UserDetails({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.user,
|
||||
}) : super(key: key);
|
||||
|
||||
final User user;
|
||||
final User? user;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -17,7 +17,7 @@ class _UserDetails extends StatelessWidget {
|
|||
Container(
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
color: user.color,
|
||||
color: user!.color,
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(20),
|
||||
),
|
||||
|
@ -109,7 +109,7 @@ class _UserDetails extends StatelessWidget {
|
|||
horizontal: 15,
|
||||
),
|
||||
child: BrandText.h1(
|
||||
user.login,
|
||||
user!.login,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)),
|
||||
|
@ -126,14 +126,14 @@ class _UserDetails extends StatelessWidget {
|
|||
Container(
|
||||
height: 40,
|
||||
alignment: Alignment.centerLeft,
|
||||
child: BrandText.h4('${user.login}@example.com'),
|
||||
child: BrandText.h4('${user!.login}@example.com'),
|
||||
),
|
||||
SizedBox(height: 14),
|
||||
BrandText.small('Пароль'),
|
||||
Container(
|
||||
height: 40,
|
||||
alignment: Alignment.centerLeft,
|
||||
child: BrandText.h4(user.password),
|
||||
child: BrandText.h4(user!.password),
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
BrandDivider(),
|
||||
|
|
|
@ -21,14 +21,14 @@ part 'user.dart';
|
|||
part 'empty.dart';
|
||||
|
||||
class UsersPage extends StatelessWidget {
|
||||
const UsersPage({Key key}) : super(key: key);
|
||||
const UsersPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final usersCubit = context.watch<UsersCubit>();
|
||||
final usersCubitState = context.watch<UsersCubit>().state;
|
||||
var isReady = context.watch<AppConfigCubit>().state.isFullyInitilized;
|
||||
final users = usersCubit.state.users;
|
||||
final isEmpty = usersCubit.state.isEmpty;
|
||||
final users = usersCubitState.users;
|
||||
final isEmpty = usersCubitState.isEmpty;
|
||||
|
||||
Widget child;
|
||||
|
||||
|
|
|
@ -8,14 +8,14 @@ extension ElevationExtension on BoxDecoration {
|
|||
BoxDecoration get ev8 => copyWith(boxShadow: [shadow8]);
|
||||
|
||||
BoxDecoration copyWith({
|
||||
Color color,
|
||||
DecorationImage image,
|
||||
BoxBorder border,
|
||||
BorderRadiusGeometry borderRadius,
|
||||
List<BoxShadow> boxShadow,
|
||||
Gradient gradient,
|
||||
BlendMode backgroundBlendMode,
|
||||
BoxShape shape,
|
||||
Color? color,
|
||||
DecorationImage? image,
|
||||
BoxBorder? border,
|
||||
BorderRadiusGeometry? borderRadius,
|
||||
List<BoxShadow>? boxShadow,
|
||||
Gradient? gradient,
|
||||
BlendMode? backgroundBlendMode,
|
||||
BoxShape? shape,
|
||||
}) {
|
||||
return BoxDecoration(
|
||||
color: color ?? this.color,
|
||||
|
|
|
@ -12,10 +12,10 @@ String genPass() {
|
|||
///The password [_generatedValue] is of a specified length, including letters [_letterGen] of mixed cases,
|
||||
///numbers [_numGen], and symbols[_symGen] depending on user choice.
|
||||
class PasswordGenerator {
|
||||
bool _letterGen;
|
||||
bool _numGen;
|
||||
bool _symGen;
|
||||
String _generatedValue;
|
||||
late bool _letterGen;
|
||||
late bool _numGen;
|
||||
late bool _symGen;
|
||||
late String _generatedValue;
|
||||
|
||||
///Constructor.
|
||||
///
|
||||
|
@ -43,7 +43,7 @@ class PasswordGenerator {
|
|||
///'Randomly' selectes caracter type to generate and append [toAppend] to [_generatedValue]
|
||||
// ignore: unnecessary_statements
|
||||
for (n; n > 0; n--) {
|
||||
String toAppend;
|
||||
String? toAppend;
|
||||
var random = new Random();
|
||||
|
||||
///loops until a valid character is generated, meaning the user has to check the character value
|
||||
|
@ -67,7 +67,7 @@ class PasswordGenerator {
|
|||
|
||||
///Generates a letter when called.
|
||||
String _generateLetter() {
|
||||
if (!_letterGen) return null;
|
||||
if (!_letterGen) return '';
|
||||
|
||||
///Finds the integer value for the range between a-z and A-Z, with [base] UTF-16 value for lowercase letters and
|
||||
///[baseUpper] UTF-16 value for uppercase letters
|
||||
|
@ -87,7 +87,7 @@ class PasswordGenerator {
|
|||
}
|
||||
|
||||
///Generates a number when called
|
||||
String _generateNumber() {
|
||||
String? _generateNumber() {
|
||||
if (!_numGen) return null;
|
||||
|
||||
///Finds the integer value for the range between 0-9
|
||||
|
@ -101,7 +101,7 @@ class PasswordGenerator {
|
|||
}
|
||||
|
||||
///Generates a symbol when called
|
||||
String _generateSymbol() {
|
||||
String? _generateSymbol() {
|
||||
if (!_symGen) return null;
|
||||
|
||||
///Finds the integer value for the range between symbols !-.
|
||||
|
|
|
@ -37,7 +37,7 @@ class SlideBottomRoute extends PageRouteBuilder {
|
|||
SlideBottomRoute(this.widget)
|
||||
: super(
|
||||
pageBuilder: pageBuilder(widget),
|
||||
transitionsBuilder: transitionsBuilder,
|
||||
transitionsBuilder: transitionsBuilder as Widget Function(BuildContext, Animation<double>, Animation<double>, Widget),
|
||||
);
|
||||
|
||||
final Widget widget;
|
||||
|
|
|
@ -37,7 +37,7 @@ class SlideRightRoute extends PageRouteBuilder {
|
|||
SlideRightRoute(this.widget)
|
||||
: super(
|
||||
pageBuilder: pageBuilder(widget),
|
||||
transitionsBuilder: transitionsBuilder,
|
||||
transitionsBuilder: transitionsBuilder as Widget Function(BuildContext, Animation<double>, Animation<double>, Widget),
|
||||
);
|
||||
|
||||
final Widget widget;
|
||||
|
|
|
@ -4,7 +4,8 @@ publish_to: 'none'
|
|||
version: 0.1.0+1
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
sdk: '>=2.12.0 <3.0.0'
|
||||
flutter: ">=2.0.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
|
Loading…
Reference in a new issue