feat: use platform_ui widgets in option select page and use platform back button in title bar

This commit is contained in:
Kingkor Roy Tirtho 2022-12-23 14:33:51 +06:00
parent 3ed153fd37
commit 96e4f14e19
10 changed files with 155 additions and 120 deletions

View File

@ -1,14 +1,12 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
import 'package:window_manager/window_manager.dart';
import 'package:window_size/window_size.dart';
import 'src/app.dart';
import 'src/mixins/app_version.dart';
import 'src/model/app_settings.dart';
import 'src/model/operating_system.dart';
import 'src/model/option.dart';
@ -69,15 +67,12 @@ void main() async {
skipTaskbar: false,
titleBarStyle: TitleBarStyle.hidden,
);
windowManager.waitUntilReadyToShow(windowOptions, () async {
await windowManager.waitUntilReadyToShow(windowOptions, () async {
await windowManager.show();
await windowManager.focus();
});
final foundQuickGet = await Process.run('which', ['quickget']);
if (foundQuickGet.exitCode == 0) {
gOperatingSystems = await loadOperatingSystems(false);
AppVersion.packageInfo = await PackageInfo.fromPlatform();
}
runApp(
MultiProvider(
providers: [

View File

@ -1,12 +1,16 @@
import 'dart:io';
import 'package:adwaita/adwaita.dart';
import 'package:fluent_ui/fluent_ui.dart' as fluent;
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:gettext_i18n/gettext_i18n.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:platform_ui/platform_ui.dart';
import 'package:provider/provider.dart';
import 'package:quickgui/main.dart';
import 'package:quickgui/src/mixins/app_version.dart';
import 'package:quickgui/src/model/operating_system.dart';
import 'package:quickgui/src/pages/deget_not_found_page.dart';
import 'package:quickgui/src/supported_locales.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -24,78 +28,128 @@ class App extends StatefulWidget {
State<App> createState() => _AppState();
}
class _AppState extends State<App> with PreferencesMixin, WindowListener {
class _AppState extends State<App> with PreferencesMixin {
bool isCheckingQuickemu = true;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final foundQuickGet = await Process.run('which', ['quickget']);
if (foundQuickGet.exitCode == 0) {
gOperatingSystems = await loadOperatingSystems(false);
AppVersion.packageInfo = await PackageInfo.fromPlatform();
setState(() {
isCheckingQuickemu = false;
});
} else {
setState(() {
isCheckingQuickemu = false;
});
}
final pref = await SharedPreferences.getInstance();
final appSettings = context.read<AppSettings>();
appSettings.setActiveLocaleSilently(
pref.getString(prefCurrentLocale) ?? Platform.localeName,
);
final cacheThemeMode = pref.getString(prefThemeMode);
appSettings.themeModeSilently = ThemeMode.values.firstWhere((element) {
return element.name == cacheThemeMode;
});
});
}
@override
Widget build(BuildContext context) {
return FutureBuilder<SharedPreferences>(
future: SharedPreferences.getInstance(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.data != null) {
var appSettings = context.read<AppSettings>();
appSettings.setActiveLocaleSilently(
snapshot.data?.getString(prefCurrentLocale) ??
Platform.localeName);
var pref = snapshot.data!.getString(prefThemeMode);
if (pref != null) {
appSettings.themeModeSilently =
ThemeMode.values.firstWhere((element) => element.name == pref);
final appSettings = context.watch<AppSettings>();
return PlatformApp(
themeMode: appSettings.themeMode,
home: isCheckingQuickemu
? Column(
children: [
AppBar(
backgroundColor: Colors.transparent,
actions: [
Theme(
data: AdwaitaThemeData.dark(),
child: PlatformWindowButtons(
isMaximized: () => windowManager.isMaximized(),
onClose: windowManager.close,
onMinimize: windowManager.minimize,
onMaximize: windowManager.maximize,
onRestore: windowManager.restore,
),
)
],
),
const Spacer(),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
PlatformText.subheading(
"Checking Quickemu...",
style: const TextStyle(color: Colors.white),
),
const SizedBox(height: 10),
SizedBox(
width: 200,
child: LinearProgressIndicator(
backgroundColor: Colors.grey[800]!,
),
),
],
),
const Spacer(),
],
)
: AppVersion.packageInfo == null
? const DebgetNotFoundPage()
: const MainPage(),
supportedLocales: supportedLocales.map(
(s) => s.contains("_")
? Locale(s.split("_")[0], s.split("_")[1])
: Locale(s),
),
localizationsDelegates: [
GettextLocalizationsDelegate(),
...GlobalMaterialLocalizations.delegates,
GlobalWidgetsLocalizations.delegate,
],
windowButtonConfig: PlatformWindowButtonConfig(
isMaximized: () => windowManager.isMaximized(),
onClose: windowManager.close,
onMinimize: windowManager.minimize,
onMaximize: windowManager.maximize,
onRestore: windowManager.restore,
showMaximizeButton: false,
),
windowsTheme: fluent.ThemeData(
scaffoldBackgroundColor: fluent.Colors.grey[30],
),
windowsDarkTheme: fluent.ThemeData.dark().copyWith(
scaffoldBackgroundColor: fluent.Colors.grey[200],
),
locale: appSettings.languageCode != null
? Locale(appSettings.languageCode!, appSettings.countryCode)
: null,
localeListResolutionCallback: (locales, supportedLocales) {
if (locales != null) {
for (var locale in locales) {
var supportedLocale = supportedLocales.where((element) =>
element.languageCode == locale.languageCode &&
element.countryCode == locale.countryCode);
if (supportedLocale.isNotEmpty) {
return supportedLocale.first;
}
supportedLocale = supportedLocales.where(
(element) => element.languageCode == locale.languageCode);
if (supportedLocale.isNotEmpty) {
return supportedLocale.first;
}
}
return Consumer<AppSettings>(
builder: (context, appSettings, _) {
return PlatformApp(
themeMode: appSettings.themeMode,
home: AppVersion.packageInfo == null
? const DebgetNotFoundPage()
: const MainPage(),
supportedLocales: supportedLocales.map((s) => s.contains("_")
? Locale(s.split("_")[0], s.split("_")[1])
: Locale(s)),
localizationsDelegates: [
GettextLocalizationsDelegate(),
...GlobalMaterialLocalizations.delegates,
GlobalWidgetsLocalizations.delegate,
],
windowButtonConfig: PlatformWindowButtonConfig(
isMaximized: () => windowManager.isMaximized(),
onClose: windowManager.close,
onMinimize: windowManager.minimize,
onMaximize: windowManager.maximize,
onRestore: windowManager.restore,
showMaximizeButton: false,
),
windowsTheme: fluent.ThemeData(
scaffoldBackgroundColor: fluent.Colors.grey[50],
),
windowsDarkTheme: fluent.ThemeData.dark(),
locale:
Locale(appSettings.languageCode!, appSettings.countryCode),
localeListResolutionCallback: (locales, supportedLocales) {
if (locales != null) {
for (var locale in locales) {
var supportedLocale = supportedLocales.where((element) =>
element.languageCode == locale.languageCode &&
element.countryCode == locale.countryCode);
if (supportedLocale.isNotEmpty) {
return supportedLocale.first;
}
supportedLocale = supportedLocales.where((element) =>
element.languageCode == locale.languageCode);
if (supportedLocale.isNotEmpty) {
return supportedLocale.first;
}
}
}
return null;
},
);
},
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
return null;
},
);
}

View File

@ -14,6 +14,7 @@ class DownloaderPage extends StatelessWidget {
return PlatformScaffold(
appBar: TitleBar(
title: PlatformText.subheading(context.t('Downloader')),
leading: const PlatformBackButton(),
),
body: Column(
children: const [

View File

@ -29,7 +29,6 @@ class _MainPageState extends State<MainPage> {
appBar: TitleBar(
automaticallyImplyLeading: false,
title: PlatformText.subheading(context.t('Quickgui')),
centerTitle: true,
actions: [
PlatformIconButton(
icon: const Icon(Icons.settings),

View File

@ -531,6 +531,7 @@ class _ManagerState extends State<Manager> with PreferencesMixin {
Widget build(BuildContext context) {
return PlatformScaffold(
appBar: TitleBar(
leading: const PlatformBackButton(),
title: PlatformText.subheading(context.t('Manager')),
),
body: _buildVmList(),

View File

@ -32,6 +32,7 @@ class _OperatingSystemSelectionState extends State<OperatingSystemSelection> {
return PlatformScaffold(
appBar: TitleBar(
title: PlatformText.subheading(context.t('Select operating system')),
leading: const PlatformBackButton(),
),
body: SingleChildScrollView(
child: Column(

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:gettext_i18n/gettext_i18n.dart';
import 'package:platform_ui/platform_ui.dart';
import 'package:quickgui/src/widgets/title_bar.dart';
import '../model/version.dart';
@ -29,49 +30,28 @@ class _OptionSelectionState extends State<OptionSelection> {
.where((e) => e.option.toLowerCase().contains(term.toLowerCase()))
.toList();
return Scaffold(
appBar: AppBar(
return PlatformScaffold(
appBar: TitleBar(
title: PlatformText(context.t('Select option')),
bottom: widget.version.options.length <= 6
? null
: PreferredSize(
preferredSize: const Size.fromHeight(kToolbarHeight),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).canvasColor,
),
child: Padding(
padding: const EdgeInsets.all(8),
child: Material(
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Icon(Icons.search),
Expanded(
child: TextField(
focusNode: focusNode,
decoration: InputDecoration.collapsed(
hintText: context.t('Search option')),
onChanged: (value) {
setState(() {
term = value;
});
},
),
),
],
),
),
),
),
),
),
leading: const PlatformBackButton(),
),
body: SingleChildScrollView(
child: Column(
children: [
if (widget.version.options.length > 6)
Padding(
padding: const EdgeInsets.all(8.0),
child: PlatformTextField(
focusNode: focusNode,
prefixIcon: Icons.search,
placeholder: context.t('Search option'),
onChanged: (value) {
setState(() {
term = value;
});
},
),
),
ListView.builder(
shrinkWrap: true,
itemCount: list.length,
@ -80,7 +60,7 @@ class _OptionSelectionState extends State<OptionSelection> {
return Card(
color: PlatformTheme.of(context).secondaryBackgroundColor,
elevation: platform == TargetPlatform.macOS ? 0 : null,
child: ListTile(
child: PlatformListTile(
title: PlatformText(item.option),
onTap: () {
Navigator.of(context).pop(item);

View File

@ -42,6 +42,7 @@ class _VersionSelectionState extends State<VersionSelection> {
context
.t('Select version for {0}', args: [widget.operatingSystem.name]),
),
leading: const PlatformBackButton(),
),
body: SingleChildScrollView(
child: Column(

View File

@ -44,6 +44,7 @@ class _SettingsPageState extends State<SettingsPage> with PreferencesMixin {
return PlatformScaffold(
appBar: TitleBar(
title: PlatformText.subheading(context.t('Settings')),
leading: const PlatformBackButton(),
),
body: Consumer<AppSettings>(
builder: (context, appSettings, _) {

View File

@ -18,7 +18,7 @@ class TitleBar extends StatelessWidget with PreferredSizeWidget {
final TextStyle? titleTextStyle;
final double? titleWidth;
const TitleBar({
TitleBar({
this.actions,
this.leading,
this.automaticallyImplyLeading = true,
@ -38,7 +38,7 @@ class TitleBar extends StatelessWidget with PreferredSizeWidget {
@override
Widget build(BuildContext context) {
return PlatformAppBar(
var platformAppBar = PlatformAppBar(
automaticallyImplyLeading: automaticallyImplyLeading,
backgroundColor: backgroundColor,
foregroundColor: foregroundColor,
@ -47,7 +47,7 @@ class TitleBar extends StatelessWidget with PreferredSizeWidget {
leading: leading,
leadingWidth: leadingWidth,
title: title,
titleSpacing: titleSpacing,
titleSpacing: titleSpacing ?? (leading == null ? 16 : null),
toolbarOpacity: toolbarOpacity,
toolbarTextStyle: toolbarTextStyle,
titleTextStyle: titleTextStyle,
@ -58,8 +58,10 @@ class TitleBar extends StatelessWidget with PreferredSizeWidget {
const PlatformWindowButtons(),
],
);
return platformAppBar;
}
@override
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
Size get preferredSize =>
Size.fromHeight(platform == TargetPlatform.windows ? 35 : kToolbarHeight);
}