mirror of
https://github.com/inventree/inventree-app.git
synced 2026-08-18 17:26:28 +00:00
Add Android intent wedge scanner support with auto configuration for supported Zebra and Datalogic devices. Intent wedge scans can be done without pressing the scan button first. Adds the ability for an MDM server to push settings on Android.
235 lines
7.0 KiB
Dart
235 lines
7.0 KiB
Dart
import "dart:async";
|
|
import "dart:io";
|
|
|
|
import "package:flutter/foundation.dart";
|
|
import "package:flutter/material.dart";
|
|
import "package:flutter/services.dart";
|
|
|
|
import "package:adaptive_theme/adaptive_theme.dart";
|
|
import "package:flutter_localizations/flutter_localizations.dart";
|
|
import "package:flutter_localized_locales/flutter_localized_locales.dart";
|
|
import "package:inventree/barcode/barcode.dart";
|
|
import "package:inventree/barcode/wedge_detect.dart";
|
|
import "package:one_context/one_context.dart";
|
|
import "package:package_info_plus/package_info_plus.dart";
|
|
import "package:sentry_flutter/sentry_flutter.dart";
|
|
import "package:inventree/dsn.dart";
|
|
|
|
import "package:inventree/managed_config.dart";
|
|
import "package:inventree/preferences.dart";
|
|
import "package:inventree/inventree/sentry.dart";
|
|
import "package:inventree/l10n/supported_locales.dart";
|
|
import "package:inventree/l10n/collected/app_localizations.dart";
|
|
import "package:inventree/settings/release.dart";
|
|
import "package:inventree/user_profile.dart";
|
|
import "package:inventree/widget/home.dart";
|
|
|
|
Future<void> main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
AdaptiveThemeMode? savedThemeMode = await AdaptiveTheme.getThemeMode();
|
|
|
|
await runZonedGuarded<Future<void>>(
|
|
() async {
|
|
PackageInfo info = await PackageInfo.fromPlatform();
|
|
String pkg = info.packageName;
|
|
String version = info.version;
|
|
String build = info.buildNumber;
|
|
|
|
String release = "${pkg}@${version}:${build}";
|
|
|
|
if (SENTRY_DSN_KEY.isNotEmpty) {
|
|
await Sentry.init((options) {
|
|
options.dsn = SENTRY_DSN_KEY;
|
|
options.release = release;
|
|
options.environment = isInDebugMode() ? "debug" : "release";
|
|
options.diagnosticLevel = SentryLevel.debug;
|
|
options.attachStacktrace = true;
|
|
});
|
|
}
|
|
|
|
// Pass any flutter errors off to the Sentry reporting context!
|
|
FlutterError.onError = (FlutterErrorDetails details) async {
|
|
// Ensure that the error gets reported to sentry!
|
|
await sentryReportError(
|
|
"FlutterError.onError",
|
|
details.exception,
|
|
details.stack,
|
|
context: {
|
|
"context": details.context.toString(),
|
|
"summary": details.summary.toString(),
|
|
"library": details.library ?? "null",
|
|
},
|
|
);
|
|
};
|
|
|
|
// Get any config provided by the MDM server
|
|
await initManagedConfiguration();
|
|
|
|
final AdaptiveThemeMode? managedThemeMode =
|
|
await getPendingManagedThemeMode();
|
|
|
|
if (managedThemeMode != null) savedThemeMode = managedThemeMode;
|
|
|
|
final int orientation =
|
|
await InvenTreeSettingsManager().getValue(
|
|
INV_SCREEN_ORIENTATION,
|
|
SCREEN_ORIENTATION_SYSTEM,
|
|
)
|
|
as int;
|
|
|
|
List<DeviceOrientation> orientations = [];
|
|
|
|
switch (orientation) {
|
|
case SCREEN_ORIENTATION_PORTRAIT:
|
|
orientations.add(DeviceOrientation.portraitUp);
|
|
case SCREEN_ORIENTATION_LANDSCAPE:
|
|
orientations.add(DeviceOrientation.landscapeLeft);
|
|
default:
|
|
orientations.add(DeviceOrientation.portraitUp);
|
|
orientations.add(DeviceOrientation.landscapeLeft);
|
|
orientations.add(DeviceOrientation.landscapeRight);
|
|
}
|
|
|
|
SystemChrome.setPreferredOrientations(orientations).then((_) {
|
|
runApp(InvenTreeApp(savedThemeMode));
|
|
});
|
|
},
|
|
(Object error, StackTrace stackTrace) async {
|
|
sentryReportError("main.runZonedGuarded", error, stackTrace);
|
|
},
|
|
);
|
|
}
|
|
|
|
class InvenTreeApp extends StatefulWidget {
|
|
// This widget is the root of your application.
|
|
|
|
const InvenTreeApp(this.savedThemeMode);
|
|
|
|
final AdaptiveThemeMode? savedThemeMode;
|
|
|
|
@override
|
|
InvenTreeAppState createState() => InvenTreeAppState(savedThemeMode);
|
|
|
|
static InvenTreeAppState? of(BuildContext context) =>
|
|
context.findAncestorStateOfType<InvenTreeAppState>();
|
|
}
|
|
|
|
class InvenTreeAppState extends State<StatefulWidget> {
|
|
InvenTreeAppState(this.savedThemeMode) : super();
|
|
|
|
// Custom _locale (default = null; use system default)
|
|
Locale? _locale;
|
|
|
|
final AdaptiveThemeMode? savedThemeMode;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
// Run some async init tasks
|
|
runInitTasks();
|
|
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
applyPendingThemeMode();
|
|
});
|
|
}
|
|
|
|
Future<void> applyPendingThemeMode() async {
|
|
final AdaptiveThemeMode? mode = await getPendingManagedThemeMode();
|
|
|
|
if (mode == null) return;
|
|
|
|
final BuildContext? ctx = OneContext().context;
|
|
|
|
if (ctx == null) return;
|
|
|
|
final manager = AdaptiveTheme.maybeOf(ctx);
|
|
|
|
if (manager == null) return;
|
|
|
|
manager.setThemeMode(mode);
|
|
await clearPendingManagedThemeMode();
|
|
}
|
|
|
|
// Run app init routines in the background
|
|
Future<void> runInitTasks() async {
|
|
// Set the app locale (language)
|
|
Locale? locale = await InvenTreeSettingsManager().getSelectedLocale();
|
|
setLocale(locale);
|
|
|
|
await initWedgeScannerDefault();
|
|
|
|
if (!kIsWeb && Platform.isAndroid) {
|
|
initGlobalIntentListener();
|
|
}
|
|
|
|
// First-run only: seed a demo server profile if none are configured
|
|
await UserProfileDBManager().seedDemoProfileIfNeeded();
|
|
|
|
// Display release notes if this is a new version
|
|
final String version =
|
|
await InvenTreeSettingsManager().getValue("recentVersion", "")
|
|
as String;
|
|
|
|
final PackageInfo info = await PackageInfo.fromPlatform();
|
|
|
|
if (version != info.version) {
|
|
// Save latest version to the settings database
|
|
await InvenTreeSettingsManager().setValue("recentVersion", info.version);
|
|
|
|
// Load release notes from external file
|
|
String notes = await rootBundle.loadString("assets/release_notes.md");
|
|
|
|
// Show the release notes
|
|
OneContext().push(
|
|
MaterialPageRoute(builder: (context) => ReleaseNotesWidget(notes)),
|
|
);
|
|
}
|
|
}
|
|
|
|
// Update the app locale
|
|
void setLocale(Locale? locale) {
|
|
setState(() {
|
|
_locale = locale;
|
|
});
|
|
}
|
|
|
|
Locale? get locale => _locale;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AdaptiveTheme(
|
|
light: ThemeData(
|
|
brightness: Brightness.light,
|
|
colorSchemeSeed: Colors.lightBlueAccent,
|
|
useMaterial3: true,
|
|
),
|
|
dark: ThemeData(
|
|
brightness: Brightness.dark,
|
|
colorSchemeSeed: Colors.blue,
|
|
useMaterial3: true,
|
|
),
|
|
initial: savedThemeMode ?? AdaptiveThemeMode.system,
|
|
builder: (light, dark) => MaterialApp(
|
|
theme: light,
|
|
darkTheme: dark,
|
|
debugShowCheckedModeBanner: false,
|
|
builder: OneContext().builder,
|
|
navigatorKey: OneContext().key,
|
|
onGenerateTitle: (BuildContext context) => "InvenTree",
|
|
home: InvenTreeHomePage(),
|
|
localizationsDelegates: [
|
|
I18N.delegate,
|
|
LocaleNamesLocalizationsDelegate(),
|
|
GlobalMaterialLocalizations.delegate,
|
|
GlobalCupertinoLocalizations.delegate,
|
|
GlobalWidgetsLocalizations.delegate,
|
|
],
|
|
supportedLocales: supported_locales,
|
|
locale: _locale,
|
|
),
|
|
);
|
|
}
|
|
}
|