mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-11 18:39:45 +00:00
Minor bug fixing
Co-authored-by: Inex Code <inex.code@selfprivacy.org>
This commit is contained in:
parent
2ac8e4366b
commit
80e0488700
|
@ -52,7 +52,6 @@ linter:
|
||||||
sized_box_shrink_expand: true
|
sized_box_shrink_expand: true
|
||||||
sort_constructors_first: true
|
sort_constructors_first: true
|
||||||
unnecessary_await_in_return: true
|
unnecessary_await_in_return: true
|
||||||
unnecessary_lambdas: true
|
|
||||||
unnecessary_null_checks: true
|
unnecessary_null_checks: true
|
||||||
unnecessary_parenthesis: true
|
unnecessary_parenthesis: true
|
||||||
use_enums: true
|
use_enums: true
|
||||||
|
|
|
@ -73,20 +73,25 @@ class BackblazeApi extends ApiMap {
|
||||||
|
|
||||||
Future<bool> isValid(final String encodedApiKey) async {
|
Future<bool> isValid(final String encodedApiKey) async {
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
final Response response = await client.get(
|
try {
|
||||||
'b2_authorize_account',
|
final Response response = await client.get(
|
||||||
options: Options(headers: {'Authorization': 'Basic $encodedApiKey'}),
|
'b2_authorize_account',
|
||||||
);
|
options: Options(headers: {'Authorization': 'Basic $encodedApiKey'}),
|
||||||
close(client);
|
);
|
||||||
if (response.statusCode == HttpStatus.ok) {
|
if (response.statusCode == HttpStatus.ok) {
|
||||||
if (response.data['allowed']['capabilities'].contains('listBuckets')) {
|
if (response.data['allowed']['capabilities'].contains('listBuckets')) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
throw Exception('code: ${response.statusCode}');
|
||||||
}
|
}
|
||||||
|
} on DioError {
|
||||||
return false;
|
return false;
|
||||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
} finally {
|
||||||
return false;
|
close(client);
|
||||||
} else {
|
|
||||||
throw Exception('code: ${response.statusCode}');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -447,7 +447,8 @@ class ServerApi extends ApiMap {
|
||||||
final Dio client = await getClient();
|
final Dio client = await getClient();
|
||||||
try {
|
try {
|
||||||
response = await client.get('/services/restic/backup/list');
|
response = await client.get('/services/restic/backup/list');
|
||||||
backups = response.data.map<Backup>(Backup.fromJson).toList();
|
backups =
|
||||||
|
response.data.map<Backup>((final e) => Backup.fromJson(e)).toList();
|
||||||
} on DioError catch (e) {
|
} on DioError catch (e) {
|
||||||
print(e.message);
|
print(e.message);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -846,7 +847,9 @@ class ServerApi extends ApiMap {
|
||||||
return ApiResponse(
|
return ApiResponse(
|
||||||
statusCode: code,
|
statusCode: code,
|
||||||
data: (response.data != null)
|
data: (response.data != null)
|
||||||
? response.data.map<ApiToken>(ApiToken.fromJson).toList()
|
? response.data
|
||||||
|
.map<ApiToken>((final e) => ApiToken.fromJson(e))
|
||||||
|
.toList()
|
||||||
: [],
|
: [],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ class ApiDevicesCubit
|
||||||
@override
|
@override
|
||||||
void load() async {
|
void load() async {
|
||||||
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
if (serverInstallationCubit.state is ServerInstallationFinished) {
|
||||||
emit(const ApiDevicesState([], LoadingStatus.refreshing));
|
|
||||||
final List<ApiToken>? devices = await _getApiTokens();
|
final List<ApiToken>? devices = await _getApiTokens();
|
||||||
if (devices != null) {
|
if (devices != null) {
|
||||||
emit(ApiDevicesState(devices, LoadingStatus.success));
|
emit(ApiDevicesState(devices, LoadingStatus.success));
|
||||||
|
|
|
@ -17,6 +17,14 @@ class RecoveryKeyState extends ServerInstallationDependendState {
|
||||||
DateTime? get generatedAt => _status.date;
|
DateTime? get generatedAt => _status.date;
|
||||||
DateTime? get expiresAt => _status.expiration;
|
DateTime? get expiresAt => _status.expiration;
|
||||||
int? get usesLeft => _status.usesLeft;
|
int? get usesLeft => _status.usesLeft;
|
||||||
|
|
||||||
|
bool get isInvalidBecauseExpired =>
|
||||||
|
_status.expiration != null &&
|
||||||
|
_status.expiration!.isBefore(DateTime.now());
|
||||||
|
|
||||||
|
bool get isInvalidBecauseUsed =>
|
||||||
|
_status.usesLeft != null && _status.usesLeft == 0;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [_status, loadingStatus];
|
List<Object> get props => [_status, loadingStatus];
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ class ServerAuthorizationException implements Exception {
|
||||||
|
|
||||||
class ServerInstallationRepository {
|
class ServerInstallationRepository {
|
||||||
Box box = Hive.box(BNames.serverInstallationBox);
|
Box box = Hive.box(BNames.serverInstallationBox);
|
||||||
|
Box<User> usersBox = Hive.box(BNames.usersBox);
|
||||||
|
|
||||||
Future<ServerInstallationState> load() async {
|
Future<ServerInstallationState> load() async {
|
||||||
final String? hetznerToken = getIt<ApiConfigModel>().hetznerKey;
|
final String? hetznerToken = getIt<ApiConfigModel>().hetznerKey;
|
||||||
|
@ -123,6 +124,7 @@ class ServerInstallationRepository {
|
||||||
|
|
||||||
void clearAppConfig() {
|
void clearAppConfig() {
|
||||||
box.clear();
|
box.clear();
|
||||||
|
usersBox.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ServerHostingDetails> startServer(
|
Future<ServerHostingDetails> startServer(
|
||||||
|
@ -526,7 +528,7 @@ class ServerInstallationRepository {
|
||||||
),
|
),
|
||||||
provider: ServerProvider.unknown,
|
provider: ServerProvider.unknown,
|
||||||
id: 0,
|
id: 0,
|
||||||
ip4: '',
|
ip4: serverIp,
|
||||||
startTime: null,
|
startTime: null,
|
||||||
createTime: null,
|
createTime: null,
|
||||||
);
|
);
|
||||||
|
@ -668,7 +670,6 @@ class ServerInstallationRepository {
|
||||||
BNames.isServerResetedSecondTime,
|
BNames.isServerResetedSecondTime,
|
||||||
BNames.hasFinalChecked,
|
BNames.hasFinalChecked,
|
||||||
BNames.isLoading,
|
BNames.isLoading,
|
||||||
BNames.isRecoveringServer,
|
|
||||||
]);
|
]);
|
||||||
getIt<ApiConfigModel>().init();
|
getIt<ApiConfigModel>().init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:cubit_form/cubit_form.dart';
|
import 'package:cubit_form/cubit_form.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/devices/devices_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/devices/devices_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/api_token.dart';
|
import 'package:selfprivacy/logic/models/json/api_token.dart';
|
||||||
|
@ -30,6 +31,58 @@ class _DevicesScreenState extends State<DevicesScreen> {
|
||||||
heroSubtitle: 'devices.main_screen.description'.tr(),
|
heroSubtitle: 'devices.main_screen.description'.tr(),
|
||||||
hasBackButton: true,
|
hasBackButton: true,
|
||||||
hasFlashButton: false,
|
hasFlashButton: false,
|
||||||
|
children: [
|
||||||
|
if (devicesStatus.status == LoadingStatus.uninitialized) ...[
|
||||||
|
const Center(
|
||||||
|
heightFactor: 8,
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
if (devicesStatus.status != LoadingStatus.uninitialized) ...[
|
||||||
|
_DevicesInfo(
|
||||||
|
devicesStatus: devicesStatus,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
OutlinedButton(
|
||||||
|
onPressed: () => Navigator.of(context)
|
||||||
|
.push(materialRoute(const NewDeviceScreen())),
|
||||||
|
child: Text('devices.main_screen.authorize_new_device'.tr()),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
const Divider(height: 1),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.info_outline,
|
||||||
|
color: Theme.of(context).colorScheme.onBackground,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
'devices.main_screen.tip'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DevicesInfo extends StatelessWidget {
|
||||||
|
const _DevicesInfo({
|
||||||
|
required this.devicesStatus,
|
||||||
|
});
|
||||||
|
|
||||||
|
final ApiDevicesState devicesStatus;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) => Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'devices.main_screen.this_device'.tr(),
|
'devices.main_screen.this_device'.tr(),
|
||||||
|
@ -49,34 +102,8 @@ class _DevicesScreenState extends State<DevicesScreen> {
|
||||||
...devicesStatus.otherDevices
|
...devicesStatus.otherDevices
|
||||||
.map((final device) => _DeviceTile(device: device))
|
.map((final device) => _DeviceTile(device: device))
|
||||||
.toList(),
|
.toList(),
|
||||||
const SizedBox(height: 16),
|
|
||||||
OutlinedButton(
|
|
||||||
onPressed: () => Navigator.of(context)
|
|
||||||
.push(materialRoute(const NewDeviceScreen())),
|
|
||||||
child: Text('devices.main_screen.authorize_new_device'.tr()),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
const Divider(height: 1),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.info_outline,
|
|
||||||
color: Theme.of(context).colorScheme.onBackground,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Text(
|
|
||||||
'devices.main_screen.tip'.tr(),
|
|
||||||
style: Theme.of(context).textTheme.bodyMedium!,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
],
|
],
|
||||||
),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DeviceTile extends StatelessWidget {
|
class _DeviceTile extends StatelessWidget {
|
||||||
|
|
|
@ -151,7 +151,7 @@ class RecoveryKeyInformation extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(final BuildContext context) {
|
Widget build(final BuildContext context) {
|
||||||
const EdgeInsets padding =
|
const EdgeInsets padding =
|
||||||
EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0);
|
EdgeInsets.symmetric(vertical: 8.0, horizontal: 8.0);
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: Column(
|
child: Column(
|
||||||
|
@ -164,6 +164,11 @@ class RecoveryKeyInformation extends StatelessWidget {
|
||||||
'recovery_key.key_valid_until'.tr(
|
'recovery_key.key_valid_until'.tr(
|
||||||
args: [DateFormat.yMMMMd().format(state.expiresAt!)],
|
args: [DateFormat.yMMMMd().format(state.expiresAt!)],
|
||||||
),
|
),
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||||
|
color: state.isInvalidBecauseExpired
|
||||||
|
? Theme.of(context).colorScheme.error
|
||||||
|
: Theme.of(context).colorScheme.onBackground,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (state.usesLeft != null)
|
if (state.usesLeft != null)
|
||||||
|
@ -173,6 +178,11 @@ class RecoveryKeyInformation extends StatelessWidget {
|
||||||
'recovery_key.key_valid_for'.tr(
|
'recovery_key.key_valid_for'.tr(
|
||||||
args: [state.usesLeft!.toString()],
|
args: [state.usesLeft!.toString()],
|
||||||
),
|
),
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||||
|
color: state.isInvalidBecauseUsed
|
||||||
|
? Theme.of(context).colorScheme.error
|
||||||
|
: Theme.of(context).colorScheme.onBackground,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (state.generatedAt != null)
|
if (state.generatedAt != null)
|
||||||
|
@ -182,7 +192,6 @@ class RecoveryKeyInformation extends StatelessWidget {
|
||||||
'recovery_key.key_creation_date'.tr(
|
'recovery_key.key_creation_date'.tr(
|
||||||
args: [DateFormat.yMMMMd().format(state.generatedAt!)],
|
args: [DateFormat.yMMMMd().format(state.generatedAt!)],
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.start,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in a new issue