mirror of
https://github.com/Auties00/Reboot-Launcher.git
synced 2026-01-13 19:22:22 +01:00
9.1.3
This commit is contained in:
@@ -2,20 +2,26 @@ import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:app_links/app_links.dart';
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart' show MaterialPage;
|
||||
import 'package:get/get.dart';
|
||||
import 'package:reboot_common/common.dart';
|
||||
import 'package:reboot_launcher/src/controller/backend_controller.dart';
|
||||
import 'package:reboot_launcher/src/controller/hosting_controller.dart';
|
||||
import 'package:reboot_launcher/src/controller/settings_controller.dart';
|
||||
import 'package:reboot_launcher/src/controller/update_controller.dart';
|
||||
import 'package:reboot_launcher/src/dialog/abstract/dialog.dart';
|
||||
import 'package:reboot_launcher/src/dialog/abstract/info_bar.dart';
|
||||
import 'package:reboot_launcher/src/dialog/implementation/dll.dart';
|
||||
import 'package:reboot_launcher/src/dialog/implementation/server.dart';
|
||||
import 'package:reboot_launcher/src/page/abstract/page.dart';
|
||||
import 'package:reboot_launcher/src/page/abstract/page_suggestion.dart';
|
||||
import 'package:reboot_launcher/src/page/pages.dart';
|
||||
import 'package:reboot_launcher/src/util/dll.dart';
|
||||
import 'package:reboot_launcher/src/util/matchmaker.dart';
|
||||
import 'package:reboot_launcher/src/util/os.dart';
|
||||
import 'package:reboot_launcher/src/util/translations.dart';
|
||||
import 'package:reboot_launcher/src/widget/info_bar_area.dart';
|
||||
@@ -33,6 +39,8 @@ class HomePage extends StatefulWidget {
|
||||
class _HomePageState extends State<HomePage> with WindowListener, AutomaticKeepAliveClientMixin {
|
||||
static const double _kDefaultPadding = 12.0;
|
||||
|
||||
final BackendController _backendController = Get.find<BackendController>();
|
||||
final HostingController _hostingController = Get.find<HostingController>();
|
||||
final SettingsController _settingsController = Get.find<SettingsController>();
|
||||
final UpdateController _updateController = Get.find<UpdateController>();
|
||||
final GlobalKey _searchKey = GlobalKey();
|
||||
@@ -45,9 +53,62 @@ class _HomePageState extends State<HomePage> with WindowListener, AutomaticKeepA
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
windowManager.addListener(this);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _checkUpdates());
|
||||
super.initState();
|
||||
windowManager.addListener(this);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_checkUpdates();
|
||||
_initAppLink();
|
||||
_checkGameServer();
|
||||
});
|
||||
}
|
||||
|
||||
void _initAppLink() async {
|
||||
final appLinks = AppLinks();
|
||||
final initialUrl = await appLinks.getInitialLink();
|
||||
if(initialUrl != null) {
|
||||
_joinServer(initialUrl);
|
||||
}
|
||||
|
||||
appLinks.uriLinkStream.listen(_joinServer);
|
||||
}
|
||||
|
||||
void _joinServer(Uri uri) {
|
||||
final uuid = uri.host;
|
||||
final server = _hostingController.findServerById(uuid);
|
||||
if(server != null) {
|
||||
_backendController.joinServer(_hostingController.uuid, server);
|
||||
}else {
|
||||
showInfoBar(
|
||||
translations.noServerFound,
|
||||
duration: infoBarLongDuration,
|
||||
severity: InfoBarSeverity.error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _checkGameServer() async {
|
||||
try {
|
||||
final address = _backendController.gameServerAddress.text;
|
||||
if(isLocalHost(address)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var result = await pingGameServer(address);
|
||||
if(result) {
|
||||
return;
|
||||
}
|
||||
|
||||
var oldOwner = _backendController.gameServerOwner.value;
|
||||
_backendController.joinLocalHost();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => showInfoBar(
|
||||
oldOwner == null ? translations.serverNoLongerAvailableUnnamed : translations.serverNoLongerAvailable(oldOwner),
|
||||
severity: InfoBarSeverity.warning,
|
||||
duration: infoBarLongDuration
|
||||
));
|
||||
}catch(_) {
|
||||
// Intended behaviour
|
||||
// Just ignore the error
|
||||
}
|
||||
}
|
||||
|
||||
void _checkUpdates() {
|
||||
@@ -58,7 +119,10 @@ class _HomePageState extends State<HomePage> with WindowListener, AutomaticKeepA
|
||||
}
|
||||
|
||||
for(final injectable in InjectableDll.values) {
|
||||
downloadCriticalDllInteractive("${injectable.name}.dll");
|
||||
downloadCriticalDllInteractive(
|
||||
injectable.path,
|
||||
silent: true
|
||||
);
|
||||
}
|
||||
|
||||
watchDlls().listen((filePath) => showDllDeletedDialog(() {
|
||||
@@ -157,54 +221,55 @@ class _HomePageState extends State<HomePage> with WindowListener, AutomaticKeepA
|
||||
super.build(context);
|
||||
_settingsController.language.value;
|
||||
loadTranslations(context);
|
||||
return Obx(() => NavigationPaneTheme(
|
||||
data: NavigationPaneThemeData(
|
||||
backgroundColor: FluentTheme.of(context).micaBackgroundColor.withOpacity(0.93),
|
||||
),
|
||||
child: NavigationView(
|
||||
paneBodyBuilder: (pane, body) => _PaneBody(
|
||||
padding: _kDefaultPadding,
|
||||
controller: pagesController,
|
||||
body: body
|
||||
),
|
||||
appBar: NavigationAppBar(
|
||||
height: 32,
|
||||
title: _draggableArea,
|
||||
actions: WindowTitleBar(focused: _focused()),
|
||||
leading: _backButton,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
pane: NavigationPane(
|
||||
selected: pageIndex.value,
|
||||
onChanged: (index) {
|
||||
final lastPageIndex = pageIndex.value;
|
||||
if(lastPageIndex != index) {
|
||||
pageIndex.value = index;
|
||||
}else if(pageStack.isNotEmpty) {
|
||||
Navigator.of(pageKey.currentContext!).pop();
|
||||
final element = pageStack.removeLast();
|
||||
appStack.remove(element);
|
||||
pagesController.add(null);
|
||||
}
|
||||
},
|
||||
menuButton: const SizedBox(),
|
||||
displayMode: PaneDisplayMode.open,
|
||||
items: _items,
|
||||
customPane: _CustomPane(_settingsController),
|
||||
header: const ProfileWidget(),
|
||||
autoSuggestBox: _autoSuggestBox,
|
||||
indicator: const StickyNavigationIndicator(
|
||||
duration: Duration(milliseconds: 500),
|
||||
curve: Curves.easeOut,
|
||||
indicatorSize: 3.25
|
||||
)
|
||||
),
|
||||
contentShape: const RoundedRectangleBorder(),
|
||||
onOpenSearch: () => _searchFocusNode.requestFocus(),
|
||||
transitionBuilder: (child, animation) => child
|
||||
)
|
||||
),
|
||||
);
|
||||
return Obx(() {
|
||||
return NavigationPaneTheme(
|
||||
data: NavigationPaneThemeData(
|
||||
backgroundColor: FluentTheme.of(context).micaBackgroundColor.withOpacity(0.93),
|
||||
),
|
||||
child: NavigationView(
|
||||
paneBodyBuilder: (pane, body) => _PaneBody(
|
||||
padding: _kDefaultPadding,
|
||||
controller: pagesController,
|
||||
body: body
|
||||
),
|
||||
appBar: NavigationAppBar(
|
||||
height: 32,
|
||||
title: _draggableArea,
|
||||
actions: WindowTitleBar(focused: _focused()),
|
||||
leading: _backButton,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
pane: NavigationPane(
|
||||
selected: pageIndex.value,
|
||||
onChanged: (index) {
|
||||
final lastPageIndex = pageIndex.value;
|
||||
if(lastPageIndex != index) {
|
||||
pageIndex.value = index;
|
||||
}else if(pageStack.isNotEmpty) {
|
||||
Navigator.of(pageKey.currentContext!).pop();
|
||||
final element = pageStack.removeLast();
|
||||
appStack.remove(element);
|
||||
pagesController.add(null);
|
||||
}
|
||||
},
|
||||
menuButton: const SizedBox(),
|
||||
displayMode: PaneDisplayMode.open,
|
||||
items: _items,
|
||||
customPane: _CustomPane(_settingsController),
|
||||
header: const ProfileWidget(),
|
||||
autoSuggestBox: _autoSuggestBox,
|
||||
indicator: const StickyNavigationIndicator(
|
||||
duration: Duration(milliseconds: 500),
|
||||
curve: Curves.easeOut,
|
||||
indicatorSize: 3.25
|
||||
)
|
||||
),
|
||||
contentShape: const RoundedRectangleBorder(),
|
||||
onOpenSearch: () => _searchFocusNode.requestFocus(),
|
||||
transitionBuilder: (child, animation) => child
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget get _backButton => StreamBuilder(
|
||||
|
||||
@@ -69,9 +69,11 @@ class InfoPage extends RebootPage {
|
||||
class _InfoPageState extends RebootPageState<InfoPage> {
|
||||
final SettingsController _settingsController = Get.find<SettingsController>();
|
||||
RxInt _counter = RxInt(kDebugMode ? 0 : 180);
|
||||
late bool _showButton;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_showButton = _settingsController.firstRun.value;
|
||||
if(_settingsController.firstRun.value) {
|
||||
Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||
if (_counter.value <= 0) {
|
||||
@@ -89,24 +91,29 @@ class _InfoPageState extends RebootPageState<InfoPage> {
|
||||
List<Widget> get settings => InfoPage._infoTiles;
|
||||
|
||||
@override
|
||||
Widget? get button => Obx(() {
|
||||
if(!_settingsController.firstRun.value) {
|
||||
Widget? get button {
|
||||
if(!_showButton) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
final totalSecondsLeft = _counter.value;
|
||||
final minutesLeft = totalSecondsLeft ~/ 60;
|
||||
final secondsLeft = totalSecondsLeft % 60;
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
height: 48,
|
||||
child: Button(
|
||||
onPressed: totalSecondsLeft <= 0 ? () => pageIndex.value = RebootPageType.play.index : null,
|
||||
child: Text(
|
||||
totalSecondsLeft <= 0 ? "I have read the instructions"
|
||||
: "Read the instructions for at least ${secondsLeft == 0 ? '$minutesLeft minute${minutesLeft > 1 ? 's' : ''}' : minutesLeft == 0 ? '$secondsLeft second${secondsLeft > 1 ? 's' : ''}' : '$minutesLeft minute${minutesLeft > 1 ? 's' : ''} and $secondsLeft second${secondsLeft > 1 ? 's' : ''}'}"
|
||||
),
|
||||
)
|
||||
);
|
||||
});
|
||||
return Obx(() {
|
||||
final totalSecondsLeft = _counter.value;
|
||||
final minutesLeft = totalSecondsLeft ~/ 60;
|
||||
final secondsLeft = totalSecondsLeft % 60;
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
height: 48,
|
||||
child: Button(
|
||||
onPressed: totalSecondsLeft <= 0 ? () {
|
||||
_showButton = false;
|
||||
pageIndex.value = RebootPageType.play.index;
|
||||
} : null,
|
||||
child: Text(
|
||||
totalSecondsLeft <= 0 ? "I have read the instructions"
|
||||
: "Read the instructions for at least ${secondsLeft == 0 ? '$minutesLeft minute${minutesLeft > 1 ? 's' : ''}' : minutesLeft == 0 ? '$secondsLeft second${secondsLeft > 1 ? 's' : ''}' : '$minutesLeft minute${minutesLeft > 1 ? 's' : ''} and $secondsLeft second${secondsLeft > 1 ? 's' : ''}'}"
|
||||
),
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import 'package:reboot_launcher/src/controller/game_controller.dart';
|
||||
import 'package:reboot_launcher/src/controller/hosting_controller.dart';
|
||||
import 'package:reboot_launcher/src/controller/settings_controller.dart';
|
||||
import 'package:reboot_launcher/src/controller/update_controller.dart';
|
||||
import 'package:reboot_launcher/src/dialog/abstract/dialog.dart';
|
||||
import 'package:reboot_launcher/src/dialog/abstract/info_bar.dart';
|
||||
import 'package:reboot_launcher/src/dialog/implementation/data.dart';
|
||||
import 'package:reboot_launcher/src/dialog/implementation/server.dart';
|
||||
@@ -65,8 +66,10 @@ class _HostingPageState extends RebootPageState<HostPage> {
|
||||
}
|
||||
|
||||
@override
|
||||
Widget get button => const LaunchButton(
|
||||
host: true
|
||||
Widget get button => LaunchButton(
|
||||
host: true,
|
||||
startLabel: translations.startHosting,
|
||||
stopLabel: translations.stopHosting
|
||||
);
|
||||
|
||||
@override
|
||||
@@ -194,6 +197,8 @@ class _HostingPageState extends RebootPageState<HostPage> {
|
||||
title: Text(translations.settingsServerTypeName),
|
||||
subtitle: Text(translations.settingsServerTypeDescription),
|
||||
content: Obx(() => DropDownButton(
|
||||
onOpen: () => inDialog = true,
|
||||
onClose: () => inDialog = false,
|
||||
leading: Text(_updateController.customGameServer.value ? translations.settingsServerTypeCustomName : translations.settingsServerTypeEmbeddedName),
|
||||
items: {
|
||||
false: translations.settingsServerTypeEmbeddedName,
|
||||
@@ -209,7 +214,9 @@ class _HostingPageState extends RebootPageState<HostPage> {
|
||||
_updateController.customGameServer.value = entry.key;
|
||||
_updateController.infoBarEntry?.close();
|
||||
if(!entry.key) {
|
||||
_updateController.updateReboot(true);
|
||||
_updateController.updateReboot(
|
||||
force: true
|
||||
);
|
||||
}
|
||||
}
|
||||
)).toList()
|
||||
@@ -256,13 +263,17 @@ class _HostingPageState extends RebootPageState<HostPage> {
|
||||
title: Text(translations.settingsServerTimerName),
|
||||
subtitle: Text(translations.settingsServerTimerSubtitle),
|
||||
content: Obx(() => DropDownButton(
|
||||
onOpen: () => inDialog = true,
|
||||
onClose: () => inDialog = false,
|
||||
leading: Text(_updateController.timer.value.text),
|
||||
items: UpdateTimer.values.map((entry) => MenuFlyoutItem(
|
||||
text: Text(entry.text),
|
||||
onPressed: () {
|
||||
_updateController.timer.value = entry;
|
||||
_updateController.infoBarEntry?.close();
|
||||
_updateController.updateReboot(true);
|
||||
_updateController.updateReboot(
|
||||
force: true
|
||||
);
|
||||
}
|
||||
)).toList()
|
||||
))
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:flutter_localized_locales/flutter_localized_locales.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:reboot_common/common.dart';
|
||||
import 'package:reboot_launcher/src/controller/settings_controller.dart';
|
||||
import 'package:reboot_launcher/src/dialog/abstract/dialog.dart';
|
||||
import 'package:reboot_launcher/src/dialog/implementation/data.dart';
|
||||
import 'package:reboot_launcher/src/page/abstract/page.dart';
|
||||
import 'package:reboot_launcher/src/page/abstract/page_type.dart';
|
||||
@@ -46,6 +47,8 @@ class _SettingsPageState extends RebootPageState<SettingsPage> {
|
||||
title: Text(translations.settingsUtilsLanguageName),
|
||||
subtitle: Text(translations.settingsUtilsLanguageDescription),
|
||||
content: Obx(() => DropDownButton(
|
||||
onOpen: () => inDialog = true,
|
||||
onClose: () => inDialog = false,
|
||||
leading: Text(_getLocaleName(_settingsController.language.value)),
|
||||
items: AppLocalizations.supportedLocales.map((locale) => MenuFlyoutItem(
|
||||
text: Text(_getLocaleName(locale.languageCode)),
|
||||
@@ -60,6 +63,8 @@ class _SettingsPageState extends RebootPageState<SettingsPage> {
|
||||
title: Text(translations.settingsUtilsThemeName),
|
||||
subtitle: Text(translations.settingsUtilsThemeDescription),
|
||||
content: Obx(() => DropDownButton(
|
||||
onOpen: () => inDialog = true,
|
||||
onClose: () => inDialog = false,
|
||||
leading: Text(_settingsController.themeMode.value.title),
|
||||
items: ThemeMode.values.map((themeMode) => MenuFlyoutItem(
|
||||
text: Text(themeMode.title),
|
||||
|
||||
Reference in New Issue
Block a user