mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-13 01:10:31 -07:00
feature: Added update notification and download links per platform (#362)
Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
parent
5ef7936c33
commit
2c71dde228
16 changed files with 712 additions and 8 deletions
|
|
@ -7,6 +7,7 @@ import 'package:iconsax_plus/iconsax_plus.dart';
|
|||
|
||||
import 'package:fladder/screens/crash_screen/crash_screen.dart';
|
||||
import 'package:fladder/screens/settings/settings_scaffold.dart';
|
||||
import 'package:fladder/screens/settings/widgets/settings_update_information.dart';
|
||||
import 'package:fladder/screens/shared/fladder_icon.dart';
|
||||
import 'package:fladder/screens/shared/fladder_logo.dart';
|
||||
import 'package:fladder/screens/shared/media/external_urls.dart';
|
||||
|
|
@ -42,6 +43,7 @@ class AboutSettingsPage extends ConsumerWidget {
|
|||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final applicationInfo = ref.watch(applicationInfoProvider);
|
||||
|
||||
return SettingsScaffold(
|
||||
label: "",
|
||||
items: [
|
||||
|
|
@ -114,6 +116,7 @@ class AboutSettingsPage extends ConsumerWidget {
|
|||
)
|
||||
],
|
||||
),
|
||||
const SettingsUpdateInformation(),
|
||||
].addInBetween(const SizedBox(height: 16)),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import 'package:window_manager/window_manager.dart';
|
|||
|
||||
import 'package:fladder/providers/arguments_provider.dart';
|
||||
import 'package:fladder/providers/auth_provider.dart';
|
||||
import 'package:fladder/providers/update_provider.dart';
|
||||
import 'package:fladder/providers/user_provider.dart';
|
||||
import 'package:fladder/routes/auto_router.gr.dart';
|
||||
import 'package:fladder/screens/settings/quick_connect_window.dart';
|
||||
|
|
@ -99,6 +100,10 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
|||
final quickConnectAvailable =
|
||||
ref.watch(userProvider.select((value) => value?.serverConfiguration?.quickConnectAvailable ?? false));
|
||||
|
||||
final newRelease = ref.watch(updateProvider.select((value) => value.latestRelease));
|
||||
|
||||
final hasNewUpdate = ref.watch(hasNewUpdateProvider);
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(left: AdaptiveLayout.of(context).sideBarWidth),
|
||||
child: Container(
|
||||
|
|
@ -109,6 +114,18 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
|||
showBackButtonNested: true,
|
||||
showUserIcon: true,
|
||||
items: [
|
||||
if (hasNewUpdate && newRelease != null) ...[
|
||||
Card(
|
||||
color: context.colors.secondaryContainer,
|
||||
child: SettingsListTile(
|
||||
label: Text(context.localized.newReleaseFoundTitle(newRelease.version)),
|
||||
subLabel: Text(context.localized.newUpdateFoundOnGithub),
|
||||
icon: IconsaxPlusLinear.information,
|
||||
onTap: () => navigateTo(const AboutSettingsRoute()),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
SettingsListTile(
|
||||
label: Text(context.localized.settingsClientTitle),
|
||||
subLabel: Text(context.localized.settingsClientDesc),
|
||||
|
|
@ -138,7 +155,7 @@ class _SettingsScreenState extends ConsumerState<SettingsScreen> {
|
|||
),
|
||||
SettingsListTile(
|
||||
label: Text(context.localized.about),
|
||||
subLabel: const Text("Fladder"),
|
||||
subLabel: Text("Fladder, ${context.localized.latestReleases}"),
|
||||
selected: containsRoute(const AboutSettingsRoute()),
|
||||
leading: Opacity(
|
||||
opacity: 1,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:iconsax_plus/iconsax_plus.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:iconsax_plus/iconsax_plus.dart';
|
||||
|
||||
import 'package:fladder/util/list_padding.dart';
|
||||
|
||||
|
|
|
|||
134
lib/screens/settings/widgets/settings_update_information.dart
Normal file
134
lib/screens/settings/widgets/settings_update_information.dart
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:markdown_widget/widget/markdown.dart';
|
||||
|
||||
import 'package:fladder/providers/settings/client_settings_provider.dart';
|
||||
import 'package:fladder/providers/update_provider.dart';
|
||||
import 'package:fladder/screens/settings/settings_list_tile.dart';
|
||||
import 'package:fladder/screens/shared/media/external_urls.dart';
|
||||
import 'package:fladder/util/list_padding.dart';
|
||||
import 'package:fladder/util/localization_helper.dart';
|
||||
import 'package:fladder/util/theme_extensions.dart';
|
||||
import 'package:fladder/util/update_checker.dart';
|
||||
|
||||
class SettingsUpdateInformation extends ConsumerStatefulWidget {
|
||||
const SettingsUpdateInformation({super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<ConsumerStatefulWidget> createState() => _SettingsUpdateInformationState();
|
||||
}
|
||||
|
||||
class _SettingsUpdateInformationState extends ConsumerState<SettingsUpdateInformation> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((value) {
|
||||
final latestRelease = ref.read(updateProvider.select((value) => value.latestRelease));
|
||||
if (latestRelease == null) return;
|
||||
final lastViewedUpdate = ref.read(clientSettingsProvider.select((value) => value.lastViewedUpdate));
|
||||
if (lastViewedUpdate != latestRelease.version) {
|
||||
ref
|
||||
.read(clientSettingsProvider.notifier)
|
||||
.update((value) => value.copyWith(lastViewedUpdate: latestRelease.version));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final updates = ref.watch(updateProvider);
|
||||
final latestRelease = updates.latestRelease;
|
||||
final otherReleases = updates.lastRelease;
|
||||
final checkForUpdate = ref.watch(clientSettingsProvider.select((value) => value.checkForUpdates));
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
const Divider(),
|
||||
SettingsListTile(
|
||||
label: Text(context.localized.latestReleases),
|
||||
subLabel: Text(context.localized.autoCheckForUpdates),
|
||||
onTap: () => ref
|
||||
.read(clientSettingsProvider.notifier)
|
||||
.update((value) => value.copyWith(checkForUpdates: !checkForUpdate)),
|
||||
trailing: Switch(
|
||||
value: checkForUpdate,
|
||||
onChanged: (value) => ref
|
||||
.read(clientSettingsProvider.notifier)
|
||||
.update((value) => value.copyWith(checkForUpdates: !checkForUpdate)),
|
||||
),
|
||||
),
|
||||
if (checkForUpdate) ...[
|
||||
if (latestRelease != null)
|
||||
UpdateInformation(
|
||||
releaseInfo: latestRelease,
|
||||
expanded: true,
|
||||
),
|
||||
...otherReleases.where((element) => element != latestRelease).map(
|
||||
(value) => UpdateInformation(releaseInfo: value),
|
||||
),
|
||||
]
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class UpdateInformation extends StatelessWidget {
|
||||
final ReleaseInfo releaseInfo;
|
||||
final bool expanded;
|
||||
const UpdateInformation({
|
||||
required this.releaseInfo,
|
||||
this.expanded = false,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ExpansionTile(
|
||||
backgroundColor:
|
||||
releaseInfo.isNewerThanCurrent ? context.colors.primaryContainer : context.colors.surfaceContainer,
|
||||
collapsedBackgroundColor: releaseInfo.isNewerThanCurrent ? context.colors.primaryContainer : null,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
collapsedShape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
title: Text(releaseInfo.version),
|
||||
initiallyExpanded: expanded,
|
||||
childrenPadding: const EdgeInsets.all(16),
|
||||
expandedCrossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||
child: MarkdownWidget(
|
||||
data: releaseInfo.changelog,
|
||||
shrinkWrap: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
...releaseInfo.preferredDownloads.entries.map(
|
||||
(entry) {
|
||||
return FilledButton(
|
||||
onPressed: () => launchUrl(context, entry.value),
|
||||
child: Text(
|
||||
entry.key.prettifyKey(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
...releaseInfo.otherDownloads.entries.map(
|
||||
(entry) {
|
||||
return ElevatedButton(
|
||||
onPressed: () => launchUrl(context, entry.value),
|
||||
child: Text(
|
||||
entry.key.prettifyKey(),
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
].addInBetween(const SizedBox(height: 12)),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue