Add window manager
This commit is contained in:
parent
dd91864b3b
commit
a8fe9c3dca
|
|
@ -91,6 +91,8 @@ enum AppEnvironment {
|
||||||
const String kSharedPrefs = 'shared_prefs';
|
const String kSharedPrefs = 'shared_prefs';
|
||||||
const String kSharedPrefUrl = 'url';
|
const String kSharedPrefUrl = 'url';
|
||||||
const String kSharedPrefToken = 'checksum';
|
const String kSharedPrefToken = 'checksum';
|
||||||
|
const String kSharedPrefWidth = 'width';
|
||||||
|
const String kSharedPrefHeight = 'height';
|
||||||
|
|
||||||
const String kProductProPlanMonth = 'pro_plan';
|
const String kProductProPlanMonth = 'pro_plan';
|
||||||
const String kProductEnterprisePlanMonth_2 = 'enterprise_plan';
|
const String kProductEnterprisePlanMonth_2 = 'enterprise_plan';
|
||||||
|
|
|
||||||
|
|
@ -58,9 +58,23 @@ import 'package:invoiceninja_flutter/utils/web_stub.dart'
|
||||||
|
|
||||||
// STARTER: import - do not remove comment
|
// STARTER: import - do not remove comment
|
||||||
import 'package:invoiceninja_flutter/redux/purchase_order/purchase_order_middleware.dart';
|
import 'package:invoiceninja_flutter/redux/purchase_order/purchase_order_middleware.dart';
|
||||||
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
void main({bool isTesting = false}) async {
|
void main({bool isTesting = false}) async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
await windowManager.ensureInitialized();
|
||||||
|
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
windowManager.waitUntilReadyToShow(
|
||||||
|
WindowOptions(
|
||||||
|
size: Size(
|
||||||
|
prefs.getDouble(kSharedPrefWidth) ?? 800,
|
||||||
|
prefs.getDouble(kSharedPrefHeight) ?? 600,
|
||||||
|
),
|
||||||
|
), () async {
|
||||||
|
await windowManager.show();
|
||||||
|
await windowManager.focus();
|
||||||
|
});
|
||||||
|
|
||||||
final store = Store<AppState>(appReducer,
|
final store = Store<AppState>(appReducer,
|
||||||
initialState: await _initialState(isTesting),
|
initialState: await _initialState(isTesting),
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,9 @@ class InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
WebUtils.warnChanges(widget.store);
|
if (kIsWeb) {
|
||||||
|
WebUtils.warnChanges(widget.store);
|
||||||
|
}
|
||||||
|
|
||||||
Timer.periodic(Duration(milliseconds: kMillisecondsToTimerRefreshData),
|
Timer.periodic(Duration(milliseconds: kMillisecondsToTimerRefreshData),
|
||||||
(_) {
|
(_) {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||||
// Package imports:
|
// Package imports:
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/app_title_bar.dart';
|
import 'package:invoiceninja_flutter/ui/app/app_title_bar.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/app/window_manager.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/purchase_order/edit/purchase_order_edit_vm.dart';
|
import 'package:invoiceninja_flutter/ui/purchase_order/edit/purchase_order_edit_vm.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/purchase_order/purchase_order_email_vm.dart';
|
import 'package:invoiceninja_flutter/ui/purchase_order/purchase_order_email_vm.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/purchase_order/purchase_order_pdf_vm.dart';
|
import 'package:invoiceninja_flutter/ui/purchase_order/purchase_order_pdf_vm.dart';
|
||||||
|
|
@ -302,29 +303,31 @@ class MainScreen extends StatelessWidget {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
child: DesktopSessionTimeout(
|
child: WindowManager(
|
||||||
child: SafeArea(
|
child: DesktopSessionTimeout(
|
||||||
child: FocusTraversalGroup(
|
child: SafeArea(
|
||||||
policy: ReadingOrderTraversalPolicy(),
|
child: FocusTraversalGroup(
|
||||||
child: Column(
|
policy: ReadingOrderTraversalPolicy(),
|
||||||
children: [
|
child: Column(
|
||||||
if (isWindows()) AppTitleBar(),
|
children: [
|
||||||
Expanded(
|
if (isWindows()) AppTitleBar(),
|
||||||
child: ChangeLayoutBanner(
|
Expanded(
|
||||||
appLayout: prefState.appLayout,
|
child: ChangeLayoutBanner(
|
||||||
suggestedLayout: AppLayout.desktop,
|
appLayout: prefState.appLayout,
|
||||||
child: Row(children: <Widget>[
|
suggestedLayout: AppLayout.desktop,
|
||||||
if (prefState.showMenu) MenuDrawerBuilder(),
|
child: Row(children: <Widget>[
|
||||||
Expanded(
|
if (prefState.showMenu) MenuDrawerBuilder(),
|
||||||
child: AppBorder(
|
Expanded(
|
||||||
child: screen,
|
child: AppBorder(
|
||||||
isLeft: prefState.showMenu &&
|
child: screen,
|
||||||
(!state.isFullScreen || showFilterSidebar),
|
isLeft: prefState.showMenu &&
|
||||||
)),
|
(!state.isFullScreen || showFilterSidebar),
|
||||||
]),
|
)),
|
||||||
|
]),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
import 'package:invoiceninja_flutter/constants.dart';
|
||||||
|
import 'package:invoiceninja_flutter/main_app.dart';
|
||||||
|
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/app/dialogs/alert_dialog.dart';
|
||||||
|
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
|
class WindowManager extends StatefulWidget {
|
||||||
|
const WindowManager({Key key, this.child}) : super(key: key);
|
||||||
|
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<WindowManager> createState() => _WindowManagerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _WindowManagerState extends State<WindowManager> with WindowListener {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
windowManager.addListener(this);
|
||||||
|
_init();
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _init() async {
|
||||||
|
await windowManager.setPreventClose(true);
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onWindowResize() async {
|
||||||
|
final size = await windowManager.getSize();
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
prefs.setDouble(kSharedPrefWidth, size.width);
|
||||||
|
prefs.setDouble(kSharedPrefHeight, size.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onWindowClose() async {
|
||||||
|
final localization = AppLocalization.of(context);
|
||||||
|
final store = StoreProvider.of<AppState>(navigatorKey.currentContext);
|
||||||
|
final state = store.state;
|
||||||
|
|
||||||
|
if (await windowManager.isPreventClose()) {
|
||||||
|
if (state.hasChanges()) {
|
||||||
|
showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => MessageDialog(
|
||||||
|
localization.errorUnsavedChanges,
|
||||||
|
dismissLabel: localization.continueEditing,
|
||||||
|
onDiscard: () async {
|
||||||
|
await windowManager.destroy();
|
||||||
|
},
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
await windowManager.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
windowManager.removeListener(this);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => widget.child;
|
||||||
|
}
|
||||||
|
|
@ -7,17 +7,25 @@
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
#include <printing/printing_plugin.h>
|
#include <printing/printing_plugin.h>
|
||||||
|
#include <screen_retriever/screen_retriever_plugin.h>
|
||||||
#include <sentry_flutter/sentry_flutter_plugin.h>
|
#include <sentry_flutter/sentry_flutter_plugin.h>
|
||||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||||
|
#include <window_manager/window_manager_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
g_autoptr(FlPluginRegistrar) printing_registrar =
|
g_autoptr(FlPluginRegistrar) printing_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "PrintingPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "PrintingPlugin");
|
||||||
printing_plugin_register_with_registrar(printing_registrar);
|
printing_plugin_register_with_registrar(printing_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) screen_retriever_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin");
|
||||||
|
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) sentry_flutter_registrar =
|
g_autoptr(FlPluginRegistrar) sentry_flutter_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "SentryFlutterPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "SentryFlutterPlugin");
|
||||||
sentry_flutter_plugin_register_with_registrar(sentry_flutter_registrar);
|
sentry_flutter_plugin_register_with_registrar(sentry_flutter_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) window_manager_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin");
|
||||||
|
window_manager_plugin_register_with_registrar(window_manager_registrar);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,10 @@
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
printing
|
printing
|
||||||
|
screen_retriever
|
||||||
sentry_flutter
|
sentry_flutter
|
||||||
url_launcher_linux
|
url_launcher_linux
|
||||||
|
window_manager
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,13 @@ import package_info
|
||||||
import package_info_plus_macos
|
import package_info_plus_macos
|
||||||
import path_provider_macos
|
import path_provider_macos
|
||||||
import printing
|
import printing
|
||||||
|
import screen_retriever
|
||||||
import sentry_flutter
|
import sentry_flutter
|
||||||
import shared_preferences_macos
|
import shared_preferences_macos
|
||||||
import sign_in_with_apple
|
import sign_in_with_apple
|
||||||
import sqflite
|
import sqflite
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
|
import window_manager
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin"))
|
InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin"))
|
||||||
|
|
@ -22,9 +24,11 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin"))
|
PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin"))
|
||||||
|
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
|
||||||
SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin"))
|
SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
SignInWithApplePlugin.register(with: registry.registrar(forPlugin: "SignInWithApplePlugin"))
|
SignInWithApplePlugin.register(with: registry.registrar(forPlugin: "SignInWithApplePlugin"))
|
||||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
|
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ dependencies:
|
||||||
image_cropper: ^2.0.2
|
image_cropper: ^2.0.2
|
||||||
msal_js: ^2.14.0
|
msal_js: ^2.14.0
|
||||||
sign_in_with_apple: ^4.0.0
|
sign_in_with_apple: ^4.0.0
|
||||||
|
window_manager: ^0.2.5
|
||||||
# bitsdojo_window: ^0.1.2
|
# bitsdojo_window: ^0.1.2
|
||||||
# quick_actions: ^0.2.1
|
# quick_actions: ^0.2.1
|
||||||
# idb_shim: ^1.11.1+1
|
# idb_shim: ^1.11.1+1
|
||||||
|
|
|
||||||
14
pubspec.lock
14
pubspec.lock
|
|
@ -1015,6 +1015,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.27.3"
|
version: "0.27.3"
|
||||||
|
screen_retriever:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: screen_retriever
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.2"
|
||||||
sentry:
|
sentry:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1463,6 +1470,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.1"
|
version: "2.5.1"
|
||||||
|
window_manager:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: window_manager
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.5"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ dependencies:
|
||||||
image_cropper: ^2.0.2
|
image_cropper: ^2.0.2
|
||||||
msal_js: ^2.14.0
|
msal_js: ^2.14.0
|
||||||
sign_in_with_apple: ^4.0.0
|
sign_in_with_apple: ^4.0.0
|
||||||
|
window_manager: ^0.2.5
|
||||||
# bitsdojo_window: ^0.1.2
|
# bitsdojo_window: ^0.1.2
|
||||||
# quick_actions: ^0.2.1
|
# quick_actions: ^0.2.1
|
||||||
# idb_shim: ^1.11.1+1
|
# idb_shim: ^1.11.1+1
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ dependencies:
|
||||||
image_cropper: ^2.0.2
|
image_cropper: ^2.0.2
|
||||||
msal_js: ^2.14.0
|
msal_js: ^2.14.0
|
||||||
sign_in_with_apple: ^4.0.0
|
sign_in_with_apple: ^4.0.0
|
||||||
|
window_manager: ^0.2.5
|
||||||
# bitsdojo_window: ^0.1.2
|
# bitsdojo_window: ^0.1.2
|
||||||
# quick_actions: ^0.2.1
|
# quick_actions: ^0.2.1
|
||||||
# idb_shim: ^1.11.1+1
|
# idb_shim: ^1.11.1+1
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,20 @@
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
#include <printing/printing_plugin.h>
|
#include <printing/printing_plugin.h>
|
||||||
|
#include <screen_retriever/screen_retriever_plugin.h>
|
||||||
#include <sentry_flutter/sentry_flutter_plugin.h>
|
#include <sentry_flutter/sentry_flutter_plugin.h>
|
||||||
#include <url_launcher_windows/url_launcher_windows.h>
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
|
#include <window_manager/window_manager_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
PrintingPluginRegisterWithRegistrar(
|
PrintingPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("PrintingPlugin"));
|
registry->GetRegistrarForPlugin("PrintingPlugin"));
|
||||||
|
ScreenRetrieverPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
|
||||||
SentryFlutterPluginRegisterWithRegistrar(
|
SentryFlutterPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("SentryFlutterPlugin"));
|
registry->GetRegistrarForPlugin("SentryFlutterPlugin"));
|
||||||
UrlLauncherWindowsRegisterWithRegistrar(
|
UrlLauncherWindowsRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||||
|
WindowManagerPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("WindowManagerPlugin"));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,10 @@
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
printing
|
printing
|
||||||
|
screen_retriever
|
||||||
sentry_flutter
|
sentry_flutter
|
||||||
url_launcher_windows
|
url_launcher_windows
|
||||||
|
window_manager
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue