mirror of
https://github.com/JGeek00/adguard-home-manager.git
synced 2025-06-08 15:47:47 +00:00
Optimizations dns rewrites, encryption and updater
This commit is contained in:
parent
129a77d979
commit
fb9fbbd35e
7 changed files with 253 additions and 319 deletions
|
@ -1,6 +1,9 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_split_view/flutter_split_view.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
@ -15,6 +18,8 @@ class AdvancedSettings extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||||
|
|
||||||
|
final width = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
Future updateSslCheck(bool newStatus) async {
|
Future updateSslCheck(bool newStatus) async {
|
||||||
final result = await appConfigProvider.setOverrideSslCheck(newStatus);
|
final result = await appConfigProvider.setOverrideSslCheck(newStatus);
|
||||||
|
@ -64,11 +69,16 @@ class AdvancedSettings extends StatelessWidget {
|
||||||
title: AppLocalizations.of(context)!.logs,
|
title: AppLocalizations.of(context)!.logs,
|
||||||
subtitle: AppLocalizations.of(context)!.checkAppLogs,
|
subtitle: AppLocalizations.of(context)!.checkAppLogs,
|
||||||
onTap: () => {
|
onTap: () => {
|
||||||
Navigator.of(context).push(
|
if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) {
|
||||||
MaterialPageRoute(
|
SplitView.of(context).push(const AppLogs())
|
||||||
builder: (context) => const AppLogs()
|
}
|
||||||
|
else {
|
||||||
|
Navigator.of(context).push(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const AppLogs()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
},
|
},
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
top: 10,
|
top: 10,
|
||||||
|
|
|
@ -7,10 +7,12 @@ import 'package:adguard_home_manager/models/rewrite_rules.dart';
|
||||||
|
|
||||||
class AddDnsRewriteModal extends StatefulWidget {
|
class AddDnsRewriteModal extends StatefulWidget {
|
||||||
final void Function(RewriteRulesData) onConfirm;
|
final void Function(RewriteRulesData) onConfirm;
|
||||||
|
final bool dialog;
|
||||||
|
|
||||||
const AddDnsRewriteModal({
|
const AddDnsRewriteModal({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.onConfirm
|
required this.onConfirm,
|
||||||
|
required this.dialog
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -50,118 +52,143 @@ class _AddDnsRewriteModalState extends State<AddDnsRewriteModal> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
Widget content() {
|
||||||
padding: MediaQuery.of(context).viewInsets,
|
return Column(
|
||||||
child: Container(
|
mainAxisSize: MainAxisSize.min,
|
||||||
height: Platform.isIOS ? 416 : 400,
|
children: [
|
||||||
decoration: BoxDecoration(
|
SingleChildScrollView(
|
||||||
borderRadius: const BorderRadius.only(
|
child: Wrap(
|
||||||
topLeft: Radius.circular(28),
|
children: [
|
||||||
topRight: Radius.circular(28)
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 24),
|
||||||
|
child: Icon(
|
||||||
|
Icons.add,
|
||||||
|
size: 24,
|
||||||
|
color: Theme.of(context).listTileTheme.iconColor
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
AppLocalizations.of(context)!.addDnsRewrite,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 24, right: 24, bottom: 12
|
||||||
|
),
|
||||||
|
child: TextFormField(
|
||||||
|
controller: domainController,
|
||||||
|
onChanged: validateDomain,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
prefixIcon: const Icon(Icons.link_rounded),
|
||||||
|
border: const OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(10)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
errorText: domainError,
|
||||||
|
labelText: AppLocalizations.of(context)!.domain,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 24, right: 24, top: 12
|
||||||
|
),
|
||||||
|
child: TextFormField(
|
||||||
|
controller: answerController,
|
||||||
|
onChanged: (_) => checkValidValues(),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
prefixIcon: const Icon(Icons.system_update_alt_rounded),
|
||||||
|
border: const OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(10)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
labelText: AppLocalizations.of(context)!.answer,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
color: Theme.of(context).dialogBackgroundColor,
|
Padding(
|
||||||
),
|
padding: const EdgeInsets.all(24),
|
||||||
child: Column(
|
child: Row(
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
Expanded(
|
children: [
|
||||||
child: ListView(
|
TextButton(
|
||||||
physics: (Platform.isIOS ? 426 : 410) < MediaQuery.of(context).size.height
|
onPressed: () => Navigator.pop(context),
|
||||||
? const NeverScrollableScrollPhysics()
|
child: Text(AppLocalizations.of(context)!.cancel),
|
||||||
: null,
|
),
|
||||||
children: [
|
const SizedBox(width: 20),
|
||||||
Padding(
|
TextButton(
|
||||||
padding: const EdgeInsets.only(top: 24),
|
onPressed: validData == true
|
||||||
child: Icon(
|
? () {
|
||||||
Icons.add,
|
Navigator.pop(context);
|
||||||
size: 24,
|
widget.onConfirm(
|
||||||
color: Theme.of(context).listTileTheme.iconColor
|
RewriteRulesData(
|
||||||
),
|
domain: domainController.text,
|
||||||
),
|
answer: answerController.text
|
||||||
const SizedBox(height: 16),
|
)
|
||||||
Text(
|
);
|
||||||
AppLocalizations.of(context)!.addDnsRewrite,
|
}
|
||||||
textAlign: TextAlign.center,
|
: null,
|
||||||
|
child: Text(
|
||||||
|
AppLocalizations.of(context)!.confirm,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 24,
|
color: validData == true
|
||||||
color: Theme.of(context).colorScheme.onSurface
|
? Theme.of(context).colorScheme.primary
|
||||||
|
: Theme.of(context).colorScheme.onSurface.withOpacity(0.38)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
),
|
||||||
Padding(
|
],
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
child: TextFormField(
|
|
||||||
controller: domainController,
|
|
||||||
onChanged: validateDomain,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
prefixIcon: const Icon(Icons.link_rounded),
|
|
||||||
border: const OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.all(
|
|
||||||
Radius.circular(10)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
errorText: domainError,
|
|
||||||
labelText: AppLocalizations.of(context)!.domain,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
child: TextFormField(
|
|
||||||
controller: answerController,
|
|
||||||
onChanged: (_) => checkValidValues(),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
prefixIcon: const Icon(Icons.system_update_alt_rounded),
|
|
||||||
border: const OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.all(
|
|
||||||
Radius.circular(10)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
labelText: AppLocalizations.of(context)!.answer,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Padding(
|
),
|
||||||
padding: const EdgeInsets.all(24),
|
if (Platform.isIOS) const SizedBox(height: 16)
|
||||||
child: Row(
|
],
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
);
|
||||||
children: [
|
}
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.pop(context),
|
if (widget.dialog == true) {
|
||||||
child: Text(AppLocalizations.of(context)!.cancel),
|
return Dialog(
|
||||||
),
|
child: ConstrainedBox(
|
||||||
const SizedBox(width: 20),
|
constraints: const BoxConstraints(
|
||||||
TextButton(
|
maxWidth: 400
|
||||||
onPressed: validData == true
|
),
|
||||||
? () {
|
child: content()
|
||||||
Navigator.pop(context);
|
|
||||||
widget.onConfirm(
|
|
||||||
RewriteRulesData(
|
|
||||||
domain: domainController.text,
|
|
||||||
answer: answerController.text
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
child: Text(
|
|
||||||
AppLocalizations.of(context)!.confirm,
|
|
||||||
style: TextStyle(
|
|
||||||
color: validData == true
|
|
||||||
? Theme.of(context).colorScheme.primary
|
|
||||||
: Theme.of(context).colorScheme.onSurface.withOpacity(0.38)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (Platform.isIOS) const SizedBox(height: 16)
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
}
|
||||||
|
else {
|
||||||
|
return Padding(
|
||||||
|
padding: MediaQuery.of(context).viewInsets,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(28),
|
||||||
|
topRight: Radius.circular(28)
|
||||||
|
),
|
||||||
|
color: Theme.of(context).dialogBackgroundColor,
|
||||||
|
),
|
||||||
|
child: content()
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
@ -70,6 +72,8 @@ class _DnsRewritesWidgetState extends State<DnsRewritesWidget> {
|
||||||
final serversProvider = Provider.of<ServersProvider>(context);
|
final serversProvider = Provider.of<ServersProvider>(context);
|
||||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||||
|
|
||||||
|
final width = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
void deleteDnsRewrite(RewriteRulesData rule) async {
|
void deleteDnsRewrite(RewriteRulesData rule) async {
|
||||||
ProcessModal processModal = ProcessModal(context: context);
|
ProcessModal processModal = ProcessModal(context: context);
|
||||||
processModal.open(AppLocalizations.of(context)!.deleting);
|
processModal.open(AppLocalizations.of(context)!.deleting);
|
||||||
|
@ -288,14 +292,26 @@ class _DnsRewritesWidgetState extends State<DnsRewritesWidget> {
|
||||||
body: generateBody(),
|
body: generateBody(),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: () => {
|
onPressed: () => {
|
||||||
showModalBottomSheet(
|
if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) {
|
||||||
context: context,
|
showDialog(
|
||||||
builder: (context) => AddDnsRewriteModal(
|
context: context,
|
||||||
onConfirm: addDnsRewrite,
|
builder: (context) => AddDnsRewriteModal(
|
||||||
),
|
onConfirm: addDnsRewrite,
|
||||||
backgroundColor: Colors.transparent,
|
dialog: true,
|
||||||
isScrollControlled: true
|
),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AddDnsRewriteModal(
|
||||||
|
onConfirm: addDnsRewrite,
|
||||||
|
dialog: false,
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
isScrollControlled: true
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: const Icon(Icons.add),
|
child: const Icon(Icons.add),
|
||||||
),
|
),
|
||||||
|
|
|
@ -26,8 +26,12 @@ class EncryptionTextField extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final width = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: width > 900
|
||||||
|
? const EdgeInsets.symmetric(horizontal: 8)
|
||||||
|
: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: const BoxConstraints(
|
constraints: const BoxConstraints(
|
||||||
maxHeight: 200
|
maxHeight: 200
|
||||||
|
|
|
@ -234,6 +234,8 @@ class _EncryptionSettingsWidgetState extends State<EncryptionSettingsWidget> {
|
||||||
final serversProvider = Provider.of<ServersProvider>(context);
|
final serversProvider = Provider.of<ServersProvider>(context);
|
||||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||||
|
|
||||||
|
final width = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
void saveData() async {
|
void saveData() async {
|
||||||
ProcessModal processModal = ProcessModal(context: context);
|
ProcessModal processModal = ProcessModal(context: context);
|
||||||
processModal.open(AppLocalizations.of(context)!.savingConfig);
|
processModal.open(AppLocalizations.of(context)!.savingConfig);
|
||||||
|
@ -343,43 +345,59 @@ class _EncryptionSettingsWidgetState extends State<EncryptionSettingsWidget> {
|
||||||
disabled: !enabled,
|
disabled: !enabled,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
EncryptionTextField(
|
Wrap(
|
||||||
enabled: enabled,
|
children: [
|
||||||
controller: httpsPortController,
|
FractionallySizedBox(
|
||||||
icon: Icons.numbers_rounded,
|
widthFactor: width > 900 ? 0.33 : 1,
|
||||||
onChanged: (value) {
|
child: EncryptionTextField(
|
||||||
setState(() => httpsPortError = validatePort(context, value));
|
enabled: enabled,
|
||||||
onEditValidate();
|
controller: httpsPortController,
|
||||||
},
|
icon: Icons.numbers_rounded,
|
||||||
errorText: httpsPortError,
|
onChanged: (value) {
|
||||||
label: AppLocalizations.of(context)!.httpsPort,
|
setState(() => httpsPortError = validatePort(context, value));
|
||||||
keyboardType: TextInputType.number,
|
onEditValidate();
|
||||||
),
|
},
|
||||||
const SizedBox(height: 30),
|
errorText: httpsPortError,
|
||||||
EncryptionTextField(
|
label: AppLocalizations.of(context)!.httpsPort,
|
||||||
enabled: enabled,
|
keyboardType: TextInputType.number,
|
||||||
controller: tlsPortController,
|
),
|
||||||
icon: Icons.numbers_rounded,
|
),
|
||||||
onChanged: (value) {
|
Padding(
|
||||||
setState(() => tlsPortError = validatePort(context, value));
|
padding: width <= 900
|
||||||
onEditValidate();
|
? const EdgeInsets.symmetric(vertical: 24)
|
||||||
},
|
: const EdgeInsets.all(0),
|
||||||
errorText: tlsPortError,
|
child: FractionallySizedBox(
|
||||||
label: AppLocalizations.of(context)!.tlsPort,
|
widthFactor: width > 900 ? 0.33 : 1,
|
||||||
keyboardType: TextInputType.number,
|
child: EncryptionTextField(
|
||||||
),
|
enabled: enabled,
|
||||||
const SizedBox(height: 30),
|
controller: tlsPortController,
|
||||||
EncryptionTextField(
|
icon: Icons.numbers_rounded,
|
||||||
enabled: enabled,
|
onChanged: (value) {
|
||||||
controller: dnsOverQuicPortController,
|
setState(() => tlsPortError = validatePort(context, value));
|
||||||
icon: Icons.numbers_rounded,
|
onEditValidate();
|
||||||
onChanged: (value) {
|
},
|
||||||
setState(() => dnsOverQuicPortError = validatePort(context, value));
|
errorText: tlsPortError,
|
||||||
onEditValidate();
|
label: AppLocalizations.of(context)!.tlsPort,
|
||||||
},
|
keyboardType: TextInputType.number,
|
||||||
errorText: dnsOverQuicPortError,
|
),
|
||||||
label: AppLocalizations.of(context)!.dnsOverQuicPort,
|
),
|
||||||
keyboardType: TextInputType.number,
|
),
|
||||||
|
FractionallySizedBox(
|
||||||
|
widthFactor: width > 900 ? 0.33 : 1,
|
||||||
|
child: EncryptionTextField(
|
||||||
|
enabled: enabled,
|
||||||
|
controller: dnsOverQuicPortController,
|
||||||
|
icon: Icons.numbers_rounded,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() => dnsOverQuicPortError = validatePort(context, value));
|
||||||
|
onEditValidate();
|
||||||
|
},
|
||||||
|
errorText: dnsOverQuicPortError,
|
||||||
|
label: AppLocalizations.of(context)!.dnsOverQuicPort,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
SectionLabel(
|
SectionLabel(
|
||||||
label: AppLocalizations.of(context)!.certificates,
|
label: AppLocalizations.of(context)!.certificates,
|
||||||
|
|
|
@ -34,7 +34,9 @@ class Settings extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (!(Platform.isAndroid || Platform.isIOS)) {
|
final width = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) {
|
||||||
return const SplitView.material(
|
return const SplitView.material(
|
||||||
breakpoint: 900,
|
breakpoint: 900,
|
||||||
child: SettingsWidget(),
|
child: SettingsWidget(),
|
||||||
|
|
|
@ -65,16 +65,18 @@ class UpdateScreen extends StatelessWidget {
|
||||||
Widget headerPortrait() {
|
Widget headerPortrait() {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
|
const SizedBox(height: 8),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
if (Navigator.canPop(context)) IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.arrow_back,
|
Icons.arrow_back,
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
),
|
),
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
),
|
),
|
||||||
|
if (!Navigator.canPop(context)) const SizedBox(),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.refresh_rounded,
|
Icons.refresh_rounded,
|
||||||
|
@ -170,120 +172,6 @@ class UpdateScreen extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget headerLandscape() {
|
|
||||||
return Column(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
IconButton(
|
|
||||||
icon: Icon(
|
|
||||||
Icons.arrow_back,
|
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
icon: Icon(
|
|
||||||
Icons.refresh_rounded,
|
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
tooltip: AppLocalizations.of(context)!.checkUpdates,
|
|
||||||
onPressed: () => serversProvider.checkServerUpdatesAvailable(serversProvider.selectedServer!)
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
top: 8, bottom: 16, left: 16, right: 16
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
serversProvider.updateAvailable.loadStatus == LoadStatus.loading
|
|
||||||
? Column(
|
|
||||||
children: const [
|
|
||||||
CircularProgressIndicator(),
|
|
||||||
SizedBox(height: 4)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: Icon(
|
|
||||||
serversProvider.updateAvailable.data!.updateAvailable != null
|
|
||||||
? serversProvider.updateAvailable.data!.updateAvailable == true
|
|
||||||
? Icons.system_update_rounded
|
|
||||||
: Icons.system_security_update_good_rounded
|
|
||||||
: Icons.system_security_update_warning_rounded,
|
|
||||||
size: 40,
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Text(
|
|
||||||
serversProvider.updateAvailable.loadStatus == LoadStatus.loading
|
|
||||||
? AppLocalizations.of(context)!.checkingUpdates
|
|
||||||
: serversProvider.updateAvailable.data!.updateAvailable != null
|
|
||||||
? serversProvider.updateAvailable.data!.updateAvailable == true
|
|
||||||
? AppLocalizations.of(context)!.updateAvailable
|
|
||||||
: AppLocalizations.of(context)!.serverUpdated
|
|
||||||
: AppLocalizations.of(context)!.unknownStatus,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 24,
|
|
||||||
fontWeight: FontWeight.w400
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 40),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
if (serversProvider.updateAvailable.loadStatus == LoadStatus.loaded) Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
serversProvider.updateAvailable.data!.updateAvailable != null && serversProvider.updateAvailable.data!.updateAvailable == true
|
|
||||||
? AppLocalizations.of(context)!.newVersion
|
|
||||||
: AppLocalizations.of(context)!.currentVersion,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 4),
|
|
||||||
Text(
|
|
||||||
serversProvider.updateAvailable.data!.updateAvailable != null
|
|
||||||
? serversProvider.updateAvailable.data!.updateAvailable == true
|
|
||||||
? serversProvider.updateAvailable.data!.newVersion ?? 'N/A'
|
|
||||||
: serversProvider.updateAvailable.data!.currentVersion
|
|
||||||
: "N/A",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (serversProvider.updateAvailable.loadStatus != LoadStatus.loaded) const SizedBox(),
|
|
||||||
FilledButton.icon(
|
|
||||||
icon: const Icon(Icons.download_rounded),
|
|
||||||
label: Text(AppLocalizations.of(context)!.updateNow),
|
|
||||||
onPressed: serversProvider.updateAvailable.data!.updateAvailable != null && serversProvider.updateAvailable.data!.updateAvailable == true
|
|
||||||
? serversProvider.updateAvailable.data!.canAutoupdate == true
|
|
||||||
? () => update()
|
|
||||||
: () => showAutoUpdateUnavailableModal()
|
|
||||||
: null
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
final changelog = serversProvider.updateAvailable.loadStatus == LoadStatus.loaded && serversProvider.updateAvailable.data!.changelog != null
|
final changelog = serversProvider.updateAvailable.loadStatus == LoadStatus.loaded && serversProvider.updateAvailable.data!.changelog != null
|
||||||
? ListView(
|
? ListView(
|
||||||
children: [
|
children: [
|
||||||
|
@ -313,51 +201,20 @@ class UpdateScreen extends StatelessWidget {
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: MediaQuery.of(context).size.width > 700
|
body: Column(
|
||||||
? Row(
|
children: [
|
||||||
children: [
|
Container(
|
||||||
Expanded(
|
color: Theme.of(context).colorScheme.surfaceVariant,
|
||||||
flex: 2,
|
child: SafeArea(
|
||||||
child: Container(
|
child: headerPortrait()
|
||||||
color: Theme.of(context).colorScheme.surfaceVariant,
|
)
|
||||||
child: Column(
|
),
|
||||||
mainAxisSize: MainAxisSize.max,
|
const SizedBox(height: 16),
|
||||||
children: [
|
changelog != null
|
||||||
Container(
|
? Expanded(child: changelog)
|
||||||
height: MediaQuery.of(context).size.height,
|
: const SizedBox(),
|
||||||
padding: EdgeInsets.only(
|
]
|
||||||
top: MediaQuery.of(context).viewPadding.top
|
)
|
||||||
),
|
|
||||||
child: headerLandscape(),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
flex: 3,
|
|
||||||
child: SafeArea(
|
|
||||||
child: SizedBox(
|
|
||||||
width: MediaQuery.of(context).size.width*0.6,
|
|
||||||
child: changelog ?? const SizedBox(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
color: Theme.of(context).colorScheme.surfaceVariant,
|
|
||||||
child: SafeArea(
|
|
||||||
child: headerPortrait()
|
|
||||||
)
|
|
||||||
),
|
|
||||||
changelog != null
|
|
||||||
? Expanded(child: changelog)
|
|
||||||
: const SizedBox(),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue