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