mirror of
				https://github.com/inventree/inventree-app.git
				synced 2025-11-04 07:15:46 +00:00 
			
		
		
		
	Adds "dark mode" support (#317)
* Adds "dark mode" support - Uses adaptive_theme package * CI fixes * More fixes * Update release notes
This commit is contained in:
		@@ -4,10 +4,12 @@
 | 
				
			|||||||
### 0.11.2 - April 2023
 | 
					### 0.11.2 - April 2023
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Adds "dark mode" display option
 | 
				
			||||||
- Add action to issue a purchase order
 | 
					- Add action to issue a purchase order
 | 
				
			||||||
- Add action to cancel a purchase order
 | 
					- Add action to cancel a purchase order
 | 
				
			||||||
- Reimplement periodic checks for notifications
 | 
					- Reimplement periodic checks for notifications
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### 0.11.1 - April 2023
 | 
					### 0.11.1 - April 2023
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -211,6 +211,12 @@
 | 
				
			|||||||
  "damaged": "Damaged",
 | 
					  "damaged": "Damaged",
 | 
				
			||||||
  "@damaged": {},
 | 
					  "@damaged": {},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  "darkMode": "Dark Mode",
 | 
				
			||||||
 | 
					  "@darkMode": {},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  "darkModeEnable": "Enable dark mode",
 | 
				
			||||||
 | 
					  "@darkModeEnable": {},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  "delete": "Delete",
 | 
					  "delete": "Delete",
 | 
				
			||||||
  "@delete": {},
 | 
					  "@delete": {},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ import "dart:async";
 | 
				
			|||||||
import "package:flutter/material.dart";
 | 
					import "package:flutter/material.dart";
 | 
				
			||||||
import "package:flutter/services.dart";
 | 
					import "package:flutter/services.dart";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "package:adaptive_theme/adaptive_theme.dart";
 | 
				
			||||||
import "package:flutter_gen/gen_l10n/app_localizations.dart";
 | 
					import "package:flutter_gen/gen_l10n/app_localizations.dart";
 | 
				
			||||||
import "package:flutter_localizations/flutter_localizations.dart";
 | 
					import "package:flutter_localizations/flutter_localizations.dart";
 | 
				
			||||||
import "package:flutter_localized_locales/flutter_localized_locales.dart";
 | 
					import "package:flutter_localized_locales/flutter_localized_locales.dart";
 | 
				
			||||||
@@ -22,6 +23,8 @@ Future<void> main() async {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  WidgetsFlutterBinding.ensureInitialized();
 | 
					  WidgetsFlutterBinding.ensureInitialized();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final savedThemeMode = await AdaptiveTheme.getThemeMode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await runZonedGuarded<Future<void>>(() async {
 | 
					  await runZonedGuarded<Future<void>>(() async {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PackageInfo info = await PackageInfo.fromPlatform();
 | 
					    PackageInfo info = await PackageInfo.fromPlatform();
 | 
				
			||||||
@@ -53,7 +56,7 @@ Future<void> main() async {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    runApp(
 | 
					    runApp(
 | 
				
			||||||
      InvenTreeApp()
 | 
					      InvenTreeApp(savedThemeMode)
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  }, (Object error, StackTrace stackTrace) async {
 | 
					  }, (Object error, StackTrace stackTrace) async {
 | 
				
			||||||
@@ -65,8 +68,12 @@ Future<void> main() async {
 | 
				
			|||||||
class InvenTreeApp extends StatefulWidget {
 | 
					class InvenTreeApp extends StatefulWidget {
 | 
				
			||||||
  // This widget is the root of your application.
 | 
					  // This widget is the root of your application.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const InvenTreeApp(this.savedThemeMode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final AdaptiveThemeMode? savedThemeMode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  InvenTreeAppState createState() => InvenTreeAppState();
 | 
					  InvenTreeAppState createState() => InvenTreeAppState(savedThemeMode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static InvenTreeAppState? of(BuildContext context) => context.findAncestorStateOfType<InvenTreeAppState>();
 | 
					  static InvenTreeAppState? of(BuildContext context) => context.findAncestorStateOfType<InvenTreeAppState>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -75,9 +82,13 @@ class InvenTreeApp extends StatefulWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class InvenTreeAppState extends State<StatefulWidget> {
 | 
					class InvenTreeAppState extends State<StatefulWidget> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  InvenTreeAppState(this.savedThemeMode) : super();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Custom _locale (default = null; use system default)
 | 
					  // Custom _locale (default = null; use system default)
 | 
				
			||||||
  Locale? _locale;
 | 
					  Locale? _locale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final AdaptiveThemeMode? savedThemeMode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState() {
 | 
					  void initState() {
 | 
				
			||||||
    super.initState();
 | 
					    super.initState();
 | 
				
			||||||
@@ -122,15 +133,25 @@ class InvenTreeAppState extends State<StatefulWidget> {
 | 
				
			|||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return MaterialApp(
 | 
					    return AdaptiveTheme(
 | 
				
			||||||
 | 
					      light: ThemeData(
 | 
				
			||||||
 | 
					        brightness: Brightness.light,
 | 
				
			||||||
 | 
					        primarySwatch: Colors.lightBlue,
 | 
				
			||||||
 | 
					        secondaryHeaderColor: Colors.blueGrey
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					      dark: ThemeData(
 | 
				
			||||||
 | 
					        brightness: Brightness.dark,
 | 
				
			||||||
 | 
					        primarySwatch: Colors.lightBlue,
 | 
				
			||||||
 | 
					        secondaryHeaderColor: Colors.blueGrey,
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					      initial: savedThemeMode ?? AdaptiveThemeMode.light,
 | 
				
			||||||
 | 
					      builder: (light, dark) =>  MaterialApp(
 | 
				
			||||||
 | 
					        theme: light,
 | 
				
			||||||
 | 
					        darkTheme: dark,
 | 
				
			||||||
        debugShowCheckedModeBanner: false,
 | 
					        debugShowCheckedModeBanner: false,
 | 
				
			||||||
        builder: OneContext().builder,
 | 
					        builder: OneContext().builder,
 | 
				
			||||||
        navigatorKey: OneContext().key,
 | 
					        navigatorKey: OneContext().key,
 | 
				
			||||||
        onGenerateTitle: (BuildContext context) => "InvenTree",
 | 
					        onGenerateTitle: (BuildContext context) => "InvenTree",
 | 
				
			||||||
      theme: ThemeData(
 | 
					 | 
				
			||||||
        primarySwatch: Colors.lightBlue,
 | 
					 | 
				
			||||||
        secondaryHeaderColor: Colors.blueGrey,
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
        home: InvenTreeHomePage(),
 | 
					        home: InvenTreeHomePage(),
 | 
				
			||||||
        localizationsDelegates: [
 | 
					        localizationsDelegates: [
 | 
				
			||||||
          I18N.delegate,
 | 
					          I18N.delegate,
 | 
				
			||||||
@@ -141,6 +162,7 @@ class InvenTreeAppState extends State<StatefulWidget> {
 | 
				
			|||||||
        ],
 | 
					        ],
 | 
				
			||||||
        supportedLocales: supported_locales,
 | 
					        supportedLocales: supported_locales,
 | 
				
			||||||
        locale: _locale,
 | 
					        locale: _locale,
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,9 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
import "package:flutter/material.dart";
 | 
					import "package:flutter/material.dart";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "package:adaptive_theme/adaptive_theme.dart";
 | 
				
			||||||
import "package:font_awesome_flutter/font_awesome_flutter.dart";
 | 
					import "package:font_awesome_flutter/font_awesome_flutter.dart";
 | 
				
			||||||
import "package:flutter_localized_locales/flutter_localized_locales.dart";
 | 
					import "package:flutter_localized_locales/flutter_localized_locales.dart";
 | 
				
			||||||
 | 
					import "package:one_context/one_context.dart";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "package:inventree/api_form.dart";
 | 
					import "package:inventree/api_form.dart";
 | 
				
			||||||
import "package:inventree/l10.dart";
 | 
					import "package:inventree/l10.dart";
 | 
				
			||||||
@@ -9,6 +11,8 @@ import "package:inventree/l10n/supported_locales.dart";
 | 
				
			|||||||
import "package:inventree/main.dart";
 | 
					import "package:inventree/main.dart";
 | 
				
			||||||
import "package:inventree/preferences.dart";
 | 
					import "package:inventree/preferences.dart";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "package:inventree/widget/progress.dart";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class InvenTreeAppSettingsWidget extends StatefulWidget {
 | 
					class InvenTreeAppSettingsWidget extends StatefulWidget {
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
@@ -28,23 +32,32 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
 | 
				
			|||||||
  bool reportErrors = true;
 | 
					  bool reportErrors = true;
 | 
				
			||||||
  bool strictHttps = false;
 | 
					  bool strictHttps = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool darkMode = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Locale? locale;
 | 
					  Locale? locale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState() {
 | 
					  void initState() {
 | 
				
			||||||
    super.initState();
 | 
					    super.initState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loadSettings();
 | 
					    loadSettings(OneContext().context!);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future <void> loadSettings() async {
 | 
					  Future <void> loadSettings(BuildContext context) async {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    showLoadingOverlay(context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    barcodeSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool;
 | 
					    barcodeSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool;
 | 
				
			||||||
    serverSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_SERVER, true) as bool;
 | 
					    serverSounds = await InvenTreeSettingsManager().getValue(INV_SOUNDS_SERVER, true) as bool;
 | 
				
			||||||
    reportErrors = await InvenTreeSettingsManager().getValue(INV_REPORT_ERRORS, true) as bool;
 | 
					    reportErrors = await InvenTreeSettingsManager().getValue(INV_REPORT_ERRORS, true) as bool;
 | 
				
			||||||
    strictHttps = await InvenTreeSettingsManager().getValue(INV_STRICT_HTTPS, false) as bool;
 | 
					    strictHttps = await InvenTreeSettingsManager().getValue(INV_STRICT_HTTPS, false) as bool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    darkMode = AdaptiveTheme.of(context).mode.isDark;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    locale = await InvenTreeSettingsManager().getSelectedLocale();
 | 
					    locale = await InvenTreeSettingsManager().getSelectedLocale();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hideLoadingOverlay();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (mounted) {
 | 
					    if (mounted) {
 | 
				
			||||||
      setState(() {});
 | 
					      setState(() {});
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -168,6 +181,24 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
 | 
				
			|||||||
              ),
 | 
					              ),
 | 
				
			||||||
              leading: FaIcon(FontAwesomeIcons.mobile),
 | 
					              leading: FaIcon(FontAwesomeIcons.mobile),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
 | 
					            ListTile(
 | 
				
			||||||
 | 
					              title: Text(L10().darkMode),
 | 
				
			||||||
 | 
					              subtitle: Text(L10().darkModeEnable),
 | 
				
			||||||
 | 
					              leading: FaIcon(FontAwesomeIcons.moon),
 | 
				
			||||||
 | 
					              trailing: Switch(
 | 
				
			||||||
 | 
					                value: darkMode,
 | 
				
			||||||
 | 
					                onChanged: (bool value) {
 | 
				
			||||||
 | 
					                  if (value) {
 | 
				
			||||||
 | 
					                    AdaptiveTheme.of(context).setDark();
 | 
				
			||||||
 | 
					                  } else {
 | 
				
			||||||
 | 
					                    AdaptiveTheme.of(context).setLight();
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                  setState(() {
 | 
				
			||||||
 | 
					                    darkMode = value;
 | 
				
			||||||
 | 
					                  });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              )
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
            ListTile(
 | 
					            ListTile(
 | 
				
			||||||
              title: Text(L10().strictHttps),
 | 
					              title: Text(L10().strictHttps),
 | 
				
			||||||
              subtitle: Text(L10().strictHttpsDetails),
 | 
					              subtitle: Text(L10().strictHttpsDetails),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,14 +52,6 @@ class _InvenTreeSettingsState extends State<InvenTreeSettingsWidget> {
 | 
				
			|||||||
                    Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeLoginSettingsWidget()));
 | 
					                    Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeLoginSettingsWidget()));
 | 
				
			||||||
                  },
 | 
					                  },
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
              ListTile(
 | 
					 | 
				
			||||||
                title: Text(L10().homeScreen),
 | 
					 | 
				
			||||||
                subtitle: Text(L10().homeScreenSettings),
 | 
					 | 
				
			||||||
                leading: FaIcon(FontAwesomeIcons.house, color: COLOR_CLICK),
 | 
					 | 
				
			||||||
                onTap: () {
 | 
					 | 
				
			||||||
                  Navigator.push(context, MaterialPageRoute(builder: (context) => HomeScreenSettingsWidget()));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
              ListTile(
 | 
					              ListTile(
 | 
				
			||||||
                  title: Text(L10().appSettings),
 | 
					                  title: Text(L10().appSettings),
 | 
				
			||||||
                  subtitle: Text(L10().appSettingsDetails),
 | 
					                  subtitle: Text(L10().appSettingsDetails),
 | 
				
			||||||
@@ -68,6 +60,14 @@ class _InvenTreeSettingsState extends State<InvenTreeSettingsWidget> {
 | 
				
			|||||||
                    Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeAppSettingsWidget()));
 | 
					                    Navigator.push(context, MaterialPageRoute(builder: (context) => InvenTreeAppSettingsWidget()));
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
 | 
					              ListTile(
 | 
				
			||||||
 | 
					                title: Text(L10().homeScreen),
 | 
				
			||||||
 | 
					                subtitle: Text(L10().homeScreenSettings),
 | 
				
			||||||
 | 
					                leading: FaIcon(FontAwesomeIcons.house, color: COLOR_CLICK),
 | 
				
			||||||
 | 
					                onTap: () {
 | 
				
			||||||
 | 
					                  Navigator.push(context, MaterialPageRoute(builder: (context) => HomeScreenSettingsWidget()));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
              ListTile(
 | 
					              ListTile(
 | 
				
			||||||
                title: Text(L10().part),
 | 
					                title: Text(L10().part),
 | 
				
			||||||
                subtitle: Text(L10().partSettings),
 | 
					                subtitle: Text(L10().partSettings),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,14 @@ packages:
 | 
				
			|||||||
      url: "https://pub.dev"
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "52.0.0"
 | 
					    version: "52.0.0"
 | 
				
			||||||
 | 
					  adaptive_theme:
 | 
				
			||||||
 | 
					    dependency: "direct main"
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: adaptive_theme
 | 
				
			||||||
 | 
					      sha256: "61bde10390e937d11d05c6cf0d5cf378a73d49f9a442262e43613dae60ed0b3f"
 | 
				
			||||||
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "3.2.0"
 | 
				
			||||||
  analyzer:
 | 
					  analyzer:
 | 
				
			||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@ environment:
 | 
				
			|||||||
  sdk: ">=2.16.0 <3.0.0"
 | 
					  sdk: ">=2.16.0 <3.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dependencies:
 | 
					dependencies:
 | 
				
			||||||
 | 
					  adaptive_theme: ^3.2.0                  # Theme management (e.g. dark mode)
 | 
				
			||||||
  audioplayers: ^3.0.1                    # Play audio files
 | 
					  audioplayers: ^3.0.1                    # Play audio files
 | 
				
			||||||
  cached_network_image: ^3.2.0            # Download and cache remote images
 | 
					  cached_network_image: ^3.2.0            # Download and cache remote images
 | 
				
			||||||
  camera: ^0.10.3                         # Camera
 | 
					  camera: ^0.10.3                         # Camera
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user