fdroid
Kherel 2 years ago
parent afd569ba96
commit 0ec549042c

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 13 KiB

@ -1,3 +1,46 @@
{
"test": "en-test"
"test": "en-test",
"basis": {
"_comment": "базовые элементы интерфейса",
"providers": "Провайдеры",
"services": "Сервисы",
"users": "Пользователи",
"more": "Еще",
"next": "Далее",
"got_it": "Понял"
},
"more": {
"_comment": "Элементы на странице еще",
"configuration_wizard": "Мастер Подключения",
"settings": "Настройки приложения",
"about_project": "О проекте SelfPrivacy",
"about_app": "О приложении",
"onboarding": "Onboarding",
"console": "Console"
},
"onboarding": {
"_comment": "страницы онбординга",
"page1_title": "Digital independence, available to all of us.",
"page1_text": "Mail, VPN, Messenger, social network and much more on your private server, under your control.",
"page2_title": "SelfPrivacy is not a cloud, but your personal datacenter.",
"page2_text": "SelfPrivacy works only with your provider accounts: Hetzner, Cloudflare, Backblaze. If you do not own those, we'll help you to create them."
},
"providers": {
"_comment": "вкладка провайдеры",
"page_title": "Your Data Center",
"server": {
"card_title": "Сервер"
},
"domain": {
"card_title": "Домен"
},
"backup": {
"card_title": "Резервное копирование"
}
},
"not_ready_card": {
"1": "Завершите настройку приложения используя ",
"2": "@:more.configuration_wizard",
"3": " для продолжения работы"
}
}

@ -1,7 +1,47 @@
{
"test": "en-test",
"basis:": {
"_comment": "Повторяющиеся названия",
"next": "Далее"
"test": "ru-test",
"basis": {
"_comment": "базовые элементы интерфейса",
"providers": "Провайдеры",
"services": "Сервисы",
"users": "Пользователи",
"more": "Еще",
"next": "Далее",
"got_it": "Понял"
},
"more": {
"_comment": "Элементы на странице еще",
"configuration_wizard": "Мастер Подключения",
"settings": "Настройки приложения",
"about_project": "О проекте SelfPrivacy",
"about_app": "О приложении",
"onboarding": "Onboarding",
"console": "Console"
},
"onboarding": {
"_comment": "страницы онбординга",
"page1_title": "Цифровая независимость доступна каждому",
"page1_text": "Почта, VPN, Мессенджер, социальная сеть и многое другое на вашем личном сервере, под вашим полным контролем.",
"page2_title": "SelfPrivacy — это не облако, а ваш личный дата-центр",
"page2_text": "У SelfPrivacy работает только с вашими сервис-провадерами: Hetzner, Cloudflare, Backblaze. Если у вас нет учетных записей, мы поможем их создать."
},
"providers": {
"_comment": "вкладка провайдеры",
"page_title": "Ваш Дата-центр",
"server": {
"card_title": "Сервер"
},
"domain": {
"card_title": "Домен"
},
"backup": {
"card_title": "Резервное копирование"
}
},
"not_ready_card": {
"_comment": "Карточка показывающая когда человек скипнул настройку, на карте текст из 3 блоков, средний содержит ссыку на мастер подключения",
"1": "Завершите настройку приложения используя ",
"2": "@:more.configuration_wizard",
"3": " для продолжения работы"
}
}

@ -45,7 +45,7 @@ SPEC CHECKSUMS:
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
wakelock: bfc7955c418d0db797614075aabbc58a39ab5107
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c

@ -7,9 +7,9 @@ import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
class BlocAndProviderConfig extends StatelessWidget {
const BlocAndProviderConfig({Key key, this.child}) : super(key: key);
const BlocAndProviderConfig({Key? key, this.child}) : super(key: key);
final Widget child;
final Widget? child;
@override
Widget build(BuildContext context) {

@ -2,14 +2,14 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:selfprivacy/ui/components/error/error.dart';
import 'package:selfprivacy/utils/route_transitions/basic.dart';
import 'get_it_config.dart';
import './get_it_config.dart';
class SimpleBlocObserver extends BlocObserver {
SimpleBlocObserver();
@override
void onError(Cubit cubit, Object error, StackTrace stackTrace) {
final navigator = getIt.get<NavigationService>().navigator;
void onError(Bloc cubit, Object error, StackTrace stackTrace) {
final navigator = getIt.get<NavigationService>().navigator!;
navigator.push(
materialRoute(

@ -32,7 +32,8 @@ class HiveConfig {
await secureStorage.write(key: BNames.key, value: base64UrlEncode(key));
}
return base64Url.decode(await secureStorage.read(key: BNames.key));
String? string = await secureStorage.read(key: BNames.key);
return base64Url.decode(string!);
}
}

@ -3,20 +3,20 @@ import 'package:flutter/material.dart';
class Localization extends StatelessWidget {
const Localization({
Key key,
Key? key,
this.child,
}) : super(key: key);
final Widget child;
final Widget? child;
@override
Widget build(BuildContext context) {
return EasyLocalization(
preloaderColor: Colors.black,
supportedLocales: [Locale('ru'), Locale('en')],
path: 'assets/translations',
fallbackLocale: Locale('en'),
fallbackLocale: Locale('ru'),
saveLocale: false,
useOnlyLangCode: true,
child: child,
child: child!,
);
}
}

@ -18,9 +18,9 @@ abstract class ApiMap {
};
loggedClient = client;
}
String rootAddress;
String? rootAddress;
Dio loggedClient;
late Dio loggedClient;
void close() {
loggedClient.close();
@ -61,7 +61,7 @@ class ConsoleInterceptor extends InterceptorsWrapper {
addMessage(
Message.warn(
text:
'response-uri: ${response?.request?.uri}\ncode: ${response?.statusCode}\ndata: ${response?.toString()}\n',
'response-uri: ${response?.request.uri}\ncode: ${response?.statusCode}\ndata: ${response?.toString()}\n',
),
);
return super.onError(err);

@ -3,17 +3,17 @@ import 'package:dio/dio.dart';
import 'package:selfprivacy/logic/api_maps/api_map.dart';
class BackblazeApi extends ApiMap {
BackblazeApi([String token]) {
BackblazeApi([String? token]) {
if (token != null) {
loggedClient.options = BaseOptions(
headers: {'Authorization': 'Basic $token'},
baseUrl: rootAddress,
baseUrl: rootAddress!,
);
}
}
@override
String rootAddress =
String? rootAddress =
'https://api.backblazeb2.com/b2api/v2/b2_authorize_account';
Future<bool> isValid(String token) async {
@ -24,7 +24,7 @@ class BackblazeApi extends ApiMap {
},
);
Response response = await loggedClient.get(rootAddress, options: options);
Response response = await loggedClient.get(rootAddress!, options: options);
if (response.statusCode == HttpStatus.ok) {
return true;

@ -5,7 +5,7 @@ import 'package:selfprivacy/logic/models/cloudflare_domain.dart';
import 'package:selfprivacy/logic/models/dns_records.dart';
class CloudflareApi extends ApiMap {
CloudflareApi([String token]) {
CloudflareApi([String? token]) {
if (token != null) {
loggedClient.options =
BaseOptions(headers: {'Authorization': 'Bearer $token'});
@ -13,7 +13,7 @@ class CloudflareApi extends ApiMap {
}
@override
String rootAddress = 'https://api.cloudflare.com/client/v4';
String? rootAddress = 'https://api.cloudflare.com/client/v4';
Future<bool> isValid(String token) async {
var url = '$rootAddress/user/tokens/verify';
@ -35,7 +35,7 @@ class CloudflareApi extends ApiMap {
}
}
Future<String> getZoneId(String token, String domain) async {
Future<String?> getZoneId(String? token, String domain) async {
var url = '$rootAddress/zones';
var options = Options(
@ -59,8 +59,8 @@ class CloudflareApi extends ApiMap {
}
Future<void> removeSimilarRecords({
String ip4,
CloudFlareDomain cloudFlareDomain,
String? ip4,
required CloudFlareDomain cloudFlareDomain,
}) async {
var domainName = cloudFlareDomain.domainName;
var domainZoneId = cloudFlareDomain.zoneId;
@ -82,8 +82,8 @@ class CloudflareApi extends ApiMap {
}
Future<void> createMultipleDnsRecords({
String ip4,
CloudFlareDomain cloudFlareDomain,
String? ip4,
required CloudFlareDomain cloudFlareDomain,
}) async {
var domainName = cloudFlareDomain.domainName;
var domainZoneId = cloudFlareDomain.zoneId;
@ -120,7 +120,7 @@ class CloudflareApi extends ApiMap {
// );
// }
List<DnsRecords> projectDnsRecords(String domainName, String ip4) {
List<DnsRecords> projectDnsRecords(String? domainName, String? ip4) {
var domainA = DnsRecords(type: 'A', name: domainName, content: ip4);
var mx = DnsRecords(type: 'MX', name: '@', content: domainName);
@ -161,7 +161,7 @@ class CloudflareApi extends ApiMap {
];
}
Future<List<String>> domainList() async {
Future<List<String>?> domainList() async {
var url = '$rootAddress/zones?per_page=50';
var response = await loggedClient.get(
url,
@ -169,7 +169,7 @@ class CloudflareApi extends ApiMap {
);
return response.data['result']
.map<String>((el) => el['name'] as String)
.map<String>((el) => el['name'] as String?)
.toList();
}
}

@ -2,24 +2,23 @@ import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:selfprivacy/logic/api_maps/api_map.dart';
import 'package:selfprivacy/logic/models/server_details.dart';
import 'package:selfprivacy/logic/models/user.dart';
import 'package:selfprivacy/utils/password_generator2.dart';
class HetznerApi extends ApiMap {
HetznerApi([String token]) {
HetznerApi([String? token]) {
if (token != null) {
loggedClient.options = BaseOptions(
headers: {'Authorization': 'Bearer $token'},
baseUrl: rootAddress,
baseUrl: rootAddress!,
);
}
}
@override
String rootAddress = 'https://api.hetzner.cloud/v1/servers';
String? rootAddress = 'https://api.hetzner.cloud/v1/servers';
Future<bool> isValid(String token) async {
var options = Options(
@ -29,7 +28,7 @@ class HetznerApi extends ApiMap {
},
);
Response response = await loggedClient.get(rootAddress, options: options);
Response response = await loggedClient.get(rootAddress!, options: options);
if (response.statusCode == HttpStatus.ok) {
return true;
@ -41,9 +40,9 @@ class HetznerApi extends ApiMap {
}
Future<HetznerServerDetails> createServer({
@required String cloudFlareKey,
@required User rootUser,
@required String domainName,
required String? cloudFlareKey,
required User rootUser,
required String? domainName,
}) async {
var dbPassword = getRandomString(40);
@ -52,7 +51,7 @@ class HetznerApi extends ApiMap {
);
Response response = await loggedClient.post(
rootAddress,
rootAddress!,
data: data,
);
@ -64,17 +63,17 @@ class HetznerApi extends ApiMap {
}
Future<void> deleteSelfprivacyServer({
@required String cloudFlareKey,
required String? cloudFlareKey,
}) async {
Response response = await loggedClient.get(rootAddress);
Response response = await loggedClient.get(rootAddress!);
List list = response.data['servers'];
var server = list.firstWhere((el) => el['name'] == 'selfprivacy-server');
return await loggedClient.delete('$rootAddress/${server['id']}');
await loggedClient.delete('$rootAddress/${server['id']}');
}
Future<HetznerServerDetails> startServer({
HetznerServerDetails server,
required HetznerServerDetails server,
}) async {
await loggedClient.post('/${server.id}/actions/poweron');
@ -84,7 +83,7 @@ class HetznerApi extends ApiMap {
}
Future<HetznerServerDetails> restart({
HetznerServerDetails server,
required HetznerServerDetails server,
}) async {
await loggedClient.post('/${server.id}/actions/poweron');

@ -5,7 +5,7 @@ import 'package:dio/dio.dart';
import 'api_map.dart';
class ServerApi extends ApiMap {
ServerApi(String domainName) {
ServerApi(String? domainName) {
loggedClient.options = BaseOptions(
baseUrl: 'https://api.$domainName',
);

@ -2,7 +2,6 @@ import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:selfprivacy/logic/models/backblaze_credential.dart';
import 'package:selfprivacy/logic/models/cloudflare_domain.dart';
@ -64,23 +63,23 @@ class AppConfigCubit extends Cubit<AppConfigState> {
}
void startServerIfDnsIsOkay({
AppConfigState state,
AppConfigState? state,
bool isImmediate = false,
}) async {
state = state ?? this.state;
final work = () async {
emit(TimerState(dataState: state, isLoading: true));
emit(TimerState(dataState: state!, isLoading: true));
var ip4 = state.hetznerServer.ip4;
var domainName = state.cloudFlareDomain.domainName;
var ip4 = state.hetznerServer!.ip4;
var domainName = state.cloudFlareDomain!.domainName;
var isMatch = await repository.isDnsAddressesMatch(domainName, ip4);
if (isMatch) {
var server = await repository.startServer(
state.hetznerKey,
state.hetznerServer,
state.hetznerServer!,
);
repository.saveServerDetails(server);
emit(
@ -111,16 +110,16 @@ class AppConfigCubit extends Cubit<AppConfigState> {
}
void resetServerIfServerIsOkay({
AppConfigState state,
AppConfigState? state,
bool isImmediate = false,
}) async {
state = state ?? this.state;
var work = () async {
emit(TimerState(dataState: state, isLoading: true));
emit(TimerState(dataState: state!, isLoading: true));
var isServerWorking = await repository.isHttpServerWorking(
state.cloudFlareDomain.domainName,
state.cloudFlareDomain!.domainName,
);
if (isServerWorking) {
@ -133,8 +132,8 @@ class AppConfigCubit extends Cubit<AppConfigState> {
));
timer = Timer(pauseDuration, () async {
var hetznerServerDetails = await repository.restart(
state.hetznerKey,
state.hetznerServer,
state!.hetznerKey,
state.hetznerServer!,
);
emit(
state.copyWith(
@ -165,19 +164,19 @@ class AppConfigCubit extends Cubit<AppConfigState> {
}
}
Timer timer;
Timer? timer;
void finishCheckIfServerIsOkay({
AppConfigState state,
AppConfigState? state,
bool isImmediate = false,
}) async {
state = state ?? this.state;
var work = () async {
emit(TimerState(dataState: state, isLoading: true));
emit(TimerState(dataState: state!, isLoading: true));
var isServerWorking = await repository.isHttpServerWorking(
state.cloudFlareDomain.domainName,
state.cloudFlareDomain!.domainName,
);
if (isServerWorking) {
@ -238,12 +237,12 @@ class AppConfigCubit extends Cubit<AppConfigState> {
}
void createServerAndSetDnsRecords() async {
var _stateCopy = state;
AppConfigState _stateCopy = state;
var onSuccess = (serverDetails) async {
await repository.createDnsRecords(
state.cloudFlareKey,
serverDetails.ip4,
state.cloudFlareDomain,
state.cloudFlareDomain!,
);
emit(state.copyWith(
@ -259,8 +258,8 @@ class AppConfigCubit extends Cubit<AppConfigState> {
emit(state.copyWith(isLoading: true));
await repository.createServer(
state.hetznerKey,
state.rootUser,
state.cloudFlareDomain.domainName,
state.rootUser!,
state.cloudFlareDomain!.domainName,
state.cloudFlareKey,
onCancel: onCancel,
onSuccess: onSuccess,
@ -277,8 +276,8 @@ class AppConfigCubit extends Cubit<AppConfigState> {
}
void _closeTimer() {
if (timer != null && timer.isActive) {
timer.cancel();
if (timer != null && timer!.isActive) {
timer!.cancel();
}
}
}

@ -60,7 +60,7 @@ class AppConfigRepository {
}
Future<HetznerServerDetails> startServer(
String hetznerKey,
String? hetznerKey,
HetznerServerDetails hetznerServer,
) async {
var hetznerApi = HetznerApi(hetznerKey);
@ -75,7 +75,7 @@ class AppConfigRepository {
await box.put(BNames.hetznerServer, serverDetails);
}
Future<bool> isDnsAddressesMatch(String domainName, String ip4) async {
Future<bool> isDnsAddressesMatch(String? domainName, String? ip4) async {
print(domainName);
var addresses = <String>[
'$domainName',
@ -116,12 +116,12 @@ class AppConfigRepository {
}
Future<void> createServer(
String hetznerKey,
String? hetznerKey,
User rootUser,
String domainName,
String cloudFlareKey, {
void Function() onCancel,
Future<void> Function(HetznerServerDetails serverDetails) onSuccess,
String? domainName,
String? cloudFlareKey, {
void Function()? onCancel,
required Future<void> Function(HetznerServerDetails serverDetails) onSuccess,
}) async {
var hetznerApi = HetznerApi(hetznerKey);
@ -135,7 +135,7 @@ class AppConfigRepository {
hetznerApi.close();
onSuccess(serverDetails);
} on DioError catch (e) {
if (e.response.data['error']['code'] == 'uniqueness_error') {
if (e.response!.data['error']['code'] == 'uniqueness_error') {
var nav = getIt.get<NavigationService>();
nav.showPopUpDialog(
BrandAlert(
@ -165,7 +165,7 @@ class AppConfigRepository {
text: 'Отменить',
onPressed: () {
hetznerApi.close();
onCancel();
onCancel!();
},
),
],
@ -176,8 +176,8 @@ class AppConfigRepository {
}
Future<void> createDnsRecords(
String cloudFlareKey,
String ip4,
String? cloudFlareKey,
String? ip4,
CloudFlareDomain cloudFlareDomain,
) async {
var cloudflareApi = CloudflareApi(cloudFlareKey);
@ -195,7 +195,7 @@ class AppConfigRepository {
cloudflareApi.close();
}
Future<bool> isHttpServerWorking(String domainName) async {
Future<bool> isHttpServerWorking(String? domainName) async {
var api = ServerApi(domainName);
var isHttpServerWorking = await api.isHttpServerWorking();
api.close();
@ -203,7 +203,7 @@ class AppConfigRepository {
}
Future<HetznerServerDetails> restart(
String hetznerKey,
String? hetznerKey,
HetznerServerDetails server,
) async {
var hetznerApi = HetznerApi(hetznerKey);

@ -2,21 +2,21 @@ part of 'app_config_cubit.dart';
class AppConfigState extends Equatable {
const AppConfigState({
@required this.hetznerKey,
@required this.cloudFlareKey,
@required this.backblazeCredential,
@required this.cloudFlareDomain,
@required this.rootUser,
@required this.hetznerServer,
@required this.isServerStarted,
@required this.isServerReseted,
@required this.hasFinalChecked,
@required this.isLoading,
@required this.error,
required this.hetznerKey,
required this.cloudFlareKey,
required this.backblazeCredential,
required this.cloudFlareDomain,
required this.rootUser,
required this.hetznerServer,
required this.isServerStarted,
required this.isServerReseted,
required this.hasFinalChecked,
required this.isLoading,
required this.error,
});
@override
List<Object> get props => [
List<Object?> get props => [
hetznerKey,
cloudFlareKey,
backblazeCredential,
@ -30,31 +30,31 @@ class AppConfigState extends Equatable {
error,
];
final String hetznerKey;
final String cloudFlareKey;
final BackblazeCredential backblazeCredential;
final CloudFlareDomain cloudFlareDomain;
final User rootUser;
final HetznerServerDetails hetznerServer;
final bool isServerStarted;
final bool isServerReseted;
final bool hasFinalChecked;
final String? hetznerKey;
final String? cloudFlareKey;
final BackblazeCredential? backblazeCredential;
final CloudFlareDomain? cloudFlareDomain;
final User? rootUser;
final HetznerServerDetails? hetznerServer;
final bool? isServerStarted;
final bool? isServerReseted;
final bool? hasFinalChecked;
final bool isLoading;
final Exception error;
final bool? isLoading;
final Exception? error;
AppConfigState copyWith({
String hetznerKey,
String cloudFlareKey,
BackblazeCredential backblazeCredential,
CloudFlareDomain cloudFlareDomain,
User rootUser,
HetznerServerDetails hetznerServer,
bool isServerStarted,
bool isServerReseted,
bool hasFinalChecked,
bool isLoading,
Exception error,
String? hetznerKey,
String? cloudFlareKey,
BackblazeCredential? backblazeCredential,
CloudFlareDomain? cloudFlareDomain,
User? rootUser,
HetznerServerDetails? hetznerServer,
bool? isServerStarted,
bool? isServerReseted,
bool? hasFinalChecked,
bool? isLoading,
Exception? error,
}) =>
AppConfigState(
hetznerKey: hetznerKey ?? this.hetznerKey,
@ -77,10 +77,10 @@ class AppConfigState extends Equatable {
bool get isUserFilled => rootUser != null;
bool get isServerCreated => hetznerServer != null;
bool get isFullyInitilized => _fulfilementList.every((el) => el);
int get progress => _fulfilementList.where((el) => el).length;
bool get isFullyInitilized => _fulfilementList.every((el) => el!);
int get progress => _fulfilementList.where((el) => el!).length;
List<bool> get _fulfilementList => [
List<bool?> get _fulfilementList => [
isHetznerFilled,
isCloudFlareFilled,
isBackblazeFilled,
@ -112,10 +112,10 @@ class InitialAppConfigState extends AppConfigState {
class TimerState extends AppConfigState {
TimerState({
@required this.dataState,
required this.dataState,
this.timerStart,
this.duration,
@required bool isLoading,
required bool isLoading,
}) : super(
hetznerKey: dataState.hetznerKey,
cloudFlareKey: dataState.cloudFlareKey,
@ -131,11 +131,11 @@ class TimerState extends AppConfigState {
);
final AppConfigState dataState;
final DateTime timerStart;
final Duration duration;
final DateTime? timerStart;
final Duration? duration;
@override
List<Object> get props => [
List<Object?> get props => [
dataState,
timerStart,
duration,

@ -1,6 +1,5 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/widgets.dart';
import 'package:hive/hive.dart';
import 'package:selfprivacy/config/hive_config.dart';
export 'package:provider/provider.dart';
@ -9,8 +8,8 @@ part 'app_settings_state.dart';
class AppSettingsCubit extends Cubit<AppSettingsState> {
AppSettingsCubit({
@required bool isDarkModeOn,
@required bool isOnbordingShowing,
required bool isDarkModeOn,
required bool isOnbordingShowing,
}) : super(
AppSettingsState(
isDarkModeOn: isDarkModeOn,
@ -21,15 +20,15 @@ class AppSettingsCubit extends Cubit<AppSettingsState> {
Box box = Hive.box(BNames.appSettings);
void load() {
bool isDarkModeOn = box.get(BNames.isDarkModeOn);
bool isOnbordingShowing = box.get(BNames.isOnbordingShowing);
bool? isDarkModeOn = box.get(BNames.isDarkModeOn);
bool? isOnbordingShowing = box.get(BNames.isOnbordingShowing);
emit(state.copyWith(
isDarkModeOn: isDarkModeOn,
isOnbordingShowing: isOnbordingShowing,
));
}
void updateDarkMode({@required bool isDarkModeOn}) {
void updateDarkMode({required bool isDarkModeOn}) {
box.put(BNames.isDarkModeOn, isDarkModeOn);
emit(state.copyWith(isDarkModeOn: isDarkModeOn));
}

@ -2,8 +2,8 @@ part of 'app_settings_cubit.dart';
class AppSettingsState extends Equatable {
const AppSettingsState({
@required this.isDarkModeOn,
@required this.isOnbordingShowing,
required this.isDarkModeOn,
required this.isOnbordingShowing,
});
final bool isDarkModeOn;

@ -42,13 +42,14 @@ class BackblazeFormCubit extends FormCubit {
final AppConfigCubit initializingCubit;
FieldCubit<String> keyId;
FieldCubit<String> applicationKey;
// ignore: close_sinks
late final FieldCubit<String> keyId;
// ignore: close_sinks
late final FieldCubit<String> applicationKey;
@override
FutureOr<bool> asyncValidation() async {
bool isKeyValid;
late bool isKeyValid;
try {
String encodedApiKey = encodedBackblazeKey(
keyId.state.value,

@ -30,11 +30,11 @@ class CloudFlareFormCubit extends FormCubit {
final AppConfigCubit initializingCubit;
FieldCubit<String> apiKey;
late final FieldCubit<String> apiKey;
@override
FutureOr<bool> asyncValidation() async {
bool isKeyValid;
late bool isKeyValid;
try {
isKeyValid = await apiClient.isValid(apiKey.state.value);

@ -5,7 +5,7 @@ import 'package:selfprivacy/logic/models/cloudflare_domain.dart';
class DomainSetupCubit extends Cubit<DomainSetupState> {
DomainSetupCubit(this.initializingCubit) : super(Initial()) {
var token = (initializingCubit.state.cloudFlareKey);
var token = initializingCubit.state.cloudFlareKey;
assert(token != null, 'no cloudflare token');
@ -13,11 +13,11 @@ class DomainSetupCubit extends Cubit<DomainSetupState> {
}
AppConfigCubit initializingCubit;
CloudflareApi api;
late CloudflareApi api;
Future<void> load() async {
emit(Loading(LoadingTypes.loadingDomain));
var list = await api.domainList();
var list = await (api.domainList() as Future<List<String>>);
if (list.isEmpty) {
emit(Empty());
} else if (list.length == 1) {

@ -30,11 +30,12 @@ class HetznerFormCubit extends FormCubit {
final AppConfigCubit initializingCubit;
FieldCubit<String> apiKey;
// ignore: close_sinks
late final FieldCubit<String> apiKey;
@override
FutureOr<bool> asyncValidation() async {
bool isKeyValid;
late bool isKeyValid;
try {
isKeyValid = await apiClient.isValid(apiKey.state.value);
} catch (e) {

@ -46,9 +46,12 @@ class RootUserFormCubit extends FormCubit {
final AppConfigCubit initializingCubit;
FieldCubit<String> userName;
FieldCubit<String> password;
FieldCubit<bool> isVisible;
// ignore: close_sinks
late final FieldCubit<String> userName;
// ignore: close_sinks
late final FieldCubit<String> password;
// ignore: close_sinks
late final FieldCubit<bool> isVisible;
@override
Future<void> close() async {

@ -7,8 +7,8 @@ import 'package:selfprivacy/utils/password_generator.dart';
class UserFormCubit extends FormCubit {
UserFormCubit({
this.usersCubit,
User user,
required this.usersCubit,
User? user,
}) {
var isEdit = user != null;
@ -16,7 +16,7 @@ class UserFormCubit extends FormCubit {
var passwordRegExp = RegExp(r"[\n\r\s]+");
login = FieldCubit(
initalValue: isEdit ? user.login : '',
initalValue: isEdit ? user!.login : '',
validations: [
RequiredStringValidation('required'),
ValidationModel<String>(
@ -25,7 +25,7 @@ class UserFormCubit extends FormCubit {
);
password = FieldCubit(
initalValue: isEdit ? user.password : genPass(),
initalValue: isEdit ? user!.password : genPass(),
validations: [
RequiredStringValidation('required'),
ValidationModel<String>(
@ -42,15 +42,16 @@ class UserFormCubit extends FormCubit {
login: login.state.value,
password: password.state.value,
);
usersCubit.add(user);
usersCubit.addUser(user);
}
FieldCubit<String> login;
FieldCubit<String> password;
// ignore: close_sinks
late FieldCubit<String> login;
late FieldCubit<String> password;
void genNewPassword() {
password.externalSetValue(genPass());
}
UsersCubit usersCubit;
late UsersCubit usersCubit;
}

@ -5,7 +5,7 @@ class LegnthStringValidationWithLenghShowing extends ValidationModel<String> {
: super((n) => n.length != length, errorText);
@override
String check(String val) {
String? check(String val) {
var length = val.length;
var errorMassage = this.errorMassage.replaceAll("[]", length.toString());
return test(val) ? errorMassage : null;

@ -8,14 +8,14 @@ part 'users_state.dart';
class UsersCubit extends Cubit<UsersState> {
UsersCubit() : super(UsersState([]));
void add(User user) {
void addUser(User user) {
var users = [...state.users];
users.add(user);
emit(UsersState(users));
}
void remove(User user) {
void remove(User? user) {
var users = [...state.users];
users.remove(user);

@ -3,10 +3,10 @@ import 'package:flutter/widgets.dart';
class NavigationService {
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
NavigatorState get navigator => navigatorKey.currentState;
NavigatorState? get navigator => navigatorKey.currentState;
void showPopUpDialog(AlertDialog dialog) {
final context = navigatorKey.currentState.overlay.context;
final context = navigatorKey.currentState!.overlay!.context;
showDialog(
context: context,

@ -9,10 +9,10 @@ class BackblazeCredential {
BackblazeCredential({this.keyId, this.applicationKey});
@HiveField(0)
final String keyId;
final String? keyId;
@HiveField(1)
final String applicationKey;
final String? applicationKey;
get encodedApiKey => encodedBackblazeKey(keyId, applicationKey);
@ -22,7 +22,7 @@ class BackblazeCredential {
}
}
String encodedBackblazeKey(String keyId, String applicationKey) {
String encodedBackblazeKey(String? keyId, String? applicationKey) {
String _apiKey = '$keyId:$applicationKey';
String encodedApiKey = base64.encode(utf8.encode(_apiKey));
return encodedApiKey;

@ -17,8 +17,8 @@ class BackblazeCredentialAdapter extends TypeAdapter<BackblazeCredential> {
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return BackblazeCredential(
keyId: fields[0] as String,
applicationKey: fields[1] as String,
keyId: fields[0] as String?,
applicationKey: fields[1] as String?,
);
}

@ -7,10 +7,10 @@ class CloudFlareDomain {
CloudFlareDomain({this.domainName, this.zoneId});
@HiveField(0)
final String domainName;
final String? domainName;
@HiveField(1)
final String zoneId;
final String? zoneId;
@override
String toString() {

@ -17,8 +17,8 @@ class CloudFlareDomainAdapter extends TypeAdapter<CloudFlareDomain> {
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return CloudFlareDomain(
domainName: fields[0] as String,
zoneId: fields[1] as String,
domainName: fields[0] as String?,
zoneId: fields[1] as String?,
);
}

@ -1,4 +1,3 @@
import 'package:flutter/foundation.dart';
import 'package:json_annotation/json_annotation.dart';
part 'dns_records.g.dart';
@ -6,17 +5,17 @@ part 'dns_records.g.dart';
@JsonSerializable(createToJson: true, createFactory: false)
class DnsRecords {
DnsRecords({
@required this.type,
@required this.name,
@required this.content,
required this.type,
required this.name,
required this.content,
this.ttl = 3600,
this.priority = 10,
this.proxied = false,
});
final String type;
final String name;
final String content;
final String? name;
final String? content;
final int ttl;
final int priority;
final bool proxied;

@ -5,12 +5,12 @@ final formater = new DateFormat('hh:mm');
class Message {
Message({this.text, this.type = MessageType.normal}) : time = DateTime.now();
final String text;
final String? text;
final DateTime time;
final MessageType type;
String get timeString => formater.format(time);
static Message warn({String text}) => Message(
static Message warn({String? text}) => Message(
text: text,
type: MessageType.warning,
);

@ -10,7 +10,7 @@ enum ProviderType {
}
class ProviderModel extends Equatable {
const ProviderModel({this.state, this.type});
const ProviderModel({required this.state, required this.type});
final StateType state;
final ProviderType type;
@ -21,7 +21,7 @@ class ProviderModel extends Equatable {
);
@override
List<Object> get props => [state, type];
List<Object?> get props => [state, type];
IconData get icon {
switch (type) {
@ -31,10 +31,8 @@ class ProviderModel extends Equatable {
case ProviderType.domain:
return BrandIcons.globe;
break;
case ProviderType.backup:
return BrandIcons.save;
}
return null;
}
}

@ -1,4 +1,3 @@
import 'package:flutter/widgets.dart';
import 'package:hive/hive.dart';
part 'server_details.g.dart';
@ -6,25 +5,25 @@ part 'server_details.g.dart';
@HiveType(typeId: 2)
class HetznerServerDetails {
HetznerServerDetails({
@required this.ip4,
@required this.id,
@required this.createTime,
required this.ip4,
required this.id,
required this.createTime,
this.startTime,
});
@HiveField(0)
final String ip4;
final String? ip4;
@HiveField(1)
final int id;
final int? id;
@HiveField(3)
final DateTime createTime;
final DateTime? createTime;
@HiveField(2)
final DateTime startTime;
final DateTime? startTime;
HetznerServerDetails copyWith({DateTime startTime}) {
HetznerServerDetails copyWith({DateTime? startTime}) {
return HetznerServerDetails(
startTime: startTime ?? this.startTime,
createTime: createTime,

@ -17,10 +17,10 @@ class HetznerServerDetailsAdapter extends TypeAdapter<HetznerServerDetails> {
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return HetznerServerDetails(
ip4: fields[0] as String,
id: fields[1] as int,
createTime: fields[3] as DateTime,
startTime: fields[2] as DateTime,
ip4: fields[0] as String?,
id: fields[1] as int?,
createTime: fields[3] as DateTime?,
startTime: fields[2] as DateTime?,
);
}

@ -1,12 +1,10 @@
import 'package:flutter/foundation.dart';
class ServerStatus {
final StatusTypes http;
final StatusTypes imap;
final StatusTypes smtp;
ServerStatus({
@required this.http,
required this.http,
this.imap = StatusTypes.nodata,
this.smtp = StatusTypes.nodata,
});
@ -20,7 +18,7 @@ class ServerStatus {
}
}
StatusTypes statusTypeFromNumber(int number) {
StatusTypes statusTypeFromNumber(int? number) {
if (number == 0) {
return StatusTypes.ok;