diff --git a/assets/icons/payconic.svg b/assets/icons/payconic.svg
new file mode 100644
index 0000000..b7c1d2f
--- /dev/null
+++ b/assets/icons/payconic.svg
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/lib/app/app.dart b/lib/app/app.dart
index 2254103..b82167e 100644
--- a/lib/app/app.dart
+++ b/lib/app/app.dart
@@ -1,7 +1,10 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
-import 'package:kooltab2/theme.dart';
-import 'package:kooltab2/utils/app_update_util.dart';
+import 'package:provider/provider.dart';
+
+import '../models/settings.dart';
+import '../viewmodels/settings_view_model.dart';
+import '../theme.dart';
class KoolTabApp extends StatefulWidget {
const KoolTabApp({super.key, required this.router});
@@ -13,13 +16,37 @@ class KoolTabApp extends StatefulWidget {
}
class _KoolTabAppState extends State {
+ @override
+ void initState() {
+ super.initState();
+
+ WidgetsBinding.instance.addPostFrameCallback((_) {
+ context.read().ensureLoaded();
+ });
+ }
+
@override
Widget build(BuildContext context) {
+ final settings = context.watch().settings;
+
return MaterialApp.router(
title: 'KoolTab',
debugShowCheckedModeBanner: false,
routerConfig: widget.router,
- theme: darkTheme,
+ theme: lightTheme,
+ darkTheme: darkTheme,
+ themeMode: _mapThemeMode(settings.themeMode, context),
);
}
-}
+
+ ThemeMode _mapThemeMode(AppThemeMode mode, BuildContext context) {
+ final hasLoaded = context.read().hasLoaded;
+
+ return switch (mode) {
+ AppThemeMode.dark => ThemeMode.dark,
+ AppThemeMode.light => ThemeMode.light,
+ AppThemeMode.system =>
+ hasLoaded ? ThemeMode.system : ThemeMode.dark,
+ };
+ }
+}
\ No newline at end of file
diff --git a/lib/theme.dart b/lib/theme.dart
index ec430dd..40cd273 100644
--- a/lib/theme.dart
+++ b/lib/theme.dart
@@ -462,11 +462,10 @@ final ThemeData neoBrutalDarkTheme = ThemeData(
);
const _violetL = Color(0xFF7C3AED);
-const _violetSoftL = Color(0xFF6D28D9);
-const _bgL = Color(0xFFFAFAFC);
+const _bgL = Color(0xFFF6F5F3);
const _surfaceL = Color(0xFFFFFFFF);
-const _surfaceRaisedL = Color(0xFFF3F1F8);
-const _outlineL = Color(0x14000000); // ~8% black
+const _surfaceRaisedL = Color(0xFFF0EDE7);
+const _outlineL = Color(0x1A000000); // ~10% black
final ThemeData lightTheme = ThemeData(
useMaterial3: true,
@@ -477,7 +476,7 @@ final ThemeData lightTheme = ThemeData(
seedColor: _violetL,
brightness: Brightness.light,
surface: _surfaceL,
- error: const Color(0xFFE5484D),
+ error: const Color(0xFFDC2626),
),
scaffoldBackgroundColor: _bgL,
@@ -487,22 +486,28 @@ final ThemeData lightTheme = ThemeData(
elevation: 0,
centerTitle: false,
backgroundColor: _bgL,
- foregroundColor: Colors.black87,
+ foregroundColor: const Color(0xFF1A1A1A),
surfaceTintColor: Colors.transparent,
titleTextStyle: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.w800,
letterSpacing: -0.3,
- color: Colors.black87,
+ color: Color(0xFF1A1A1A),
+ ),
+ iconTheme: const IconThemeData(
+ color: Color(0xFF5C5C5C),
+ size: 22,
+ ),
+ actionsIconTheme: const IconThemeData(
+ color: Color(0xFF5C5C5C),
+ size: 22,
),
- iconTheme: const IconThemeData(color: Colors.black54, size: 22),
- actionsIconTheme: const IconThemeData(color: Colors.black54, size: 22),
),
iconButtonTheme: IconButtonThemeData(
style: IconButton.styleFrom(
- backgroundColor: Colors.black.withValues(alpha: 0.04),
- foregroundColor: Colors.black54,
+ backgroundColor: const Color(0x08000000),
+ foregroundColor: const Color(0xFF5C5C5C),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadii.md),
),
@@ -512,7 +517,8 @@ final ThemeData lightTheme = ThemeData(
cardTheme: CardThemeData(
color: _surfaceL,
- elevation: 0,
+ elevation: 1,
+ shadowColor: const Color(0x0C000000),
margin: const EdgeInsets.symmetric(
horizontal: AppSpacing.md,
vertical: AppSpacing.sm,
@@ -528,8 +534,8 @@ final ThemeData lightTheme = ThemeData(
elevation: 0,
backgroundColor: _violetL,
foregroundColor: Colors.white,
- disabledBackgroundColor: Colors.black.withValues(alpha: 0.06),
- disabledForegroundColor: Colors.black26,
+ disabledBackgroundColor: const Color(0x0F000000),
+ disabledForegroundColor: const Color(0x42000000),
padding: const EdgeInsets.symmetric(
horizontal: AppSpacing.xl,
vertical: AppSpacing.lg,
@@ -563,7 +569,7 @@ final ThemeData lightTheme = ThemeData(
outlinedButtonTheme: OutlinedButtonThemeData(
style: OutlinedButton.styleFrom(
- foregroundColor: Colors.black87,
+ foregroundColor: const Color(0xFF1A1A1A),
side: const BorderSide(color: _outlineL, width: 1.4),
padding: const EdgeInsets.symmetric(
horizontal: AppSpacing.xl,
@@ -577,7 +583,7 @@ final ThemeData lightTheme = ThemeData(
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
- foregroundColor: Colors.black54,
+ foregroundColor: const Color(0xFF5C5C5C),
padding: const EdgeInsets.symmetric(
horizontal: AppSpacing.lg,
vertical: AppSpacing.md,
@@ -590,8 +596,8 @@ final ThemeData lightTheme = ThemeData(
inputDecorationTheme: InputDecorationTheme(
filled: true,
- fillColor: _surfaceRaisedL,
- hintStyle: const TextStyle(color: Colors.black38),
+ fillColor: _surfaceL,
+ hintStyle: const TextStyle(color: Color(0xFF9E9E9E)),
contentPadding: const EdgeInsets.symmetric(
horizontal: AppSpacing.lg,
vertical: AppSpacing.lg,
@@ -613,27 +619,31 @@ final ThemeData lightTheme = ThemeData(
dialogTheme: DialogThemeData(
backgroundColor: _surfaceL,
surfaceTintColor: Colors.transparent,
- elevation: 8,
+ elevation: 12,
+ shadowColor: const Color(0x18000000),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadii.lg),
),
titleTextStyle: const TextStyle(
- color: Colors.black87,
+ color: Color(0xFF1A1A1A),
fontSize: 19,
fontWeight: FontWeight.w800,
),
- contentTextStyle: const TextStyle(color: Colors.black54, height: 1.4),
+ contentTextStyle: const TextStyle(
+ color: Color(0xFF5C5C5C),
+ height: 1.4,
+ ),
),
floatingActionButtonTheme: const FloatingActionButtonThemeData(
backgroundColor: _violetL,
foregroundColor: Colors.white,
- elevation: 2,
+ elevation: 3,
),
navigationBarTheme: NavigationBarThemeData(
backgroundColor: _surfaceL,
- indicatorColor: _violetL.withValues(alpha: 0.15),
+ indicatorColor: _violetL.withValues(alpha: 0.12),
labelTextStyle: const WidgetStatePropertyAll(
TextStyle(fontWeight: FontWeight.w600),
),
@@ -644,8 +654,8 @@ final ThemeData lightTheme = ThemeData(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadii.md),
),
- iconColor: _violetSoftL,
- textColor: Colors.black87,
+ iconColor: _violetL,
+ textColor: const Color(0xFF1A1A1A),
contentPadding: const EdgeInsets.symmetric(
horizontal: AppSpacing.md,
vertical: AppSpacing.xs,
@@ -653,9 +663,9 @@ final ThemeData lightTheme = ThemeData(
),
snackBarTheme: SnackBarThemeData(
- backgroundColor: Colors.black87,
+ backgroundColor: const Color(0xFF1E1E24),
behavior: SnackBarBehavior.floating,
- elevation: 4,
+ elevation: 6,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadii.md),
),
@@ -671,11 +681,11 @@ final ThemeData lightTheme = ThemeData(
chipTheme: ChipThemeData(
backgroundColor: _surfaceRaisedL,
labelStyle: const TextStyle(
- color: Colors.black87,
+ color: Color(0xFF1A1A1A),
fontWeight: FontWeight.w600,
fontSize: 12,
),
- padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
+ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadii.sm),
side: const BorderSide(color: _outlineL),
@@ -683,21 +693,37 @@ final ThemeData lightTheme = ThemeData(
),
textTheme: const TextTheme(
- displayLarge: TextStyle(color: Colors.black87, fontWeight: FontWeight.w800),
+ displayLarge: TextStyle(
+ color: Color(0xFF1A1A1A),
+ fontWeight: FontWeight.w800,
+ ),
headlineMedium: TextStyle(
- color: Colors.black87,
+ color: Color(0xFF1A1A1A),
fontWeight: FontWeight.w800,
letterSpacing: -0.3,
),
titleLarge: TextStyle(
- color: Colors.black87,
+ color: Color(0xFF1A1A1A),
fontWeight: FontWeight.w800,
letterSpacing: -0.2,
),
- titleMedium: TextStyle(color: Colors.black87, fontWeight: FontWeight.w700),
- bodyLarge: TextStyle(color: Colors.black54, fontSize: 16, height: 1.5),
- bodyMedium: TextStyle(color: Colors.black45, height: 1.4),
- bodySmall: TextStyle(color: Colors.black38, height: 1.3),
- labelLarge: TextStyle(color: Colors.black87, fontWeight: FontWeight.w700),
+ titleMedium: TextStyle(
+ color: Color(0xFF1A1A1A),
+ fontWeight: FontWeight.w700,
+ ),
+ bodyLarge: TextStyle(
+ color: Color(0xFF5C5C5C),
+ fontSize: 16,
+ height: 1.5,
+ ),
+ bodyMedium: TextStyle(color: Color(0xFF757575), height: 1.4),
+ bodySmall: TextStyle(
+ color: Color(0xFF9E9E9E),
+ height: 1.3,
+ ),
+ labelLarge: TextStyle(
+ color: Color(0xFF1A1A1A),
+ fontWeight: FontWeight.w700,
+ ),
),
);
diff --git a/lib/utils/app_update_util.dart b/lib/utils/app_update_util.dart
index ba2fe16..9af9913 100644
--- a/lib/utils/app_update_util.dart
+++ b/lib/utils/app_update_util.dart
@@ -1,13 +1,9 @@
import 'dart:convert';
-import 'dart:io';
-import 'package:crypto/crypto.dart';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
-import 'package:open_filex/open_filex.dart';
import 'package:package_info_plus/package_info_plus.dart';
-import 'package:path_provider/path_provider.dart';
class UpdateInfo {
final bool update;
diff --git a/lib/viewmodels/settings_view_model.dart b/lib/viewmodels/settings_view_model.dart
index 4b9bfdc..e3a7c3c 100644
--- a/lib/viewmodels/settings_view_model.dart
+++ b/lib/viewmodels/settings_view_model.dart
@@ -75,7 +75,7 @@ class SettingsViewModel extends ChangeNotifier {
? update.download
: "$kUpdateServerUrl${update.download}";
- debugPrint("Download Url: ${url}");
+ debugPrint("Download Url: $url");
final stream = OtaUpdate().execute(
url,
diff --git a/lib/views/widgets/closed_tab_card.dart b/lib/views/widgets/closed_tab_card.dart
index ec09841..d9a31f8 100644
--- a/lib/views/widgets/closed_tab_card.dart
+++ b/lib/views/widgets/closed_tab_card.dart
@@ -6,7 +6,7 @@ import 'package:kooltab2/models/closed_tab_item.dart';
class ClosedTabCard extends StatefulWidget {
final ClosedTab closedTab;
- const ClosedTabCard({required this.closedTab});
+ const ClosedTabCard({super.key, required this.closedTab});
@override
State createState() => _ClosedTabCardState();
diff --git a/lib/views/widgets/product_tile.dart b/lib/views/widgets/product_tile.dart
index 0d03cc6..77c03c2 100644
--- a/lib/views/widgets/product_tile.dart
+++ b/lib/views/widgets/product_tile.dart
@@ -10,6 +10,7 @@ class ProductTile extends StatelessWidget {
static const _tileImageSize = 280.0;
const ProductTile({
+ super.key,
required this.product,
required this.enabled,
required this.onTap,
@@ -25,8 +26,7 @@ class ProductTile extends StatelessWidget {
product.stockQuantity > 0 &&
product.stockQuantity <= product.lowStockThreshold;
- final hasImage = product.imagePath != null &&
- product.imagePath!.isNotEmpty;
+ final hasImage = product.imagePath != null && product.imagePath!.isNotEmpty;
final borderColor = outOfStock
? scheme.error.withValues(alpha: 0.7)
@@ -58,8 +58,8 @@ class ProductTile extends StatelessWidget {
File(product.imagePath!),
fit: BoxFit.scaleDown,
cacheWidth: _tileImageSize.toInt(),
- errorBuilder:
- (context, error, stackTrace) => _noImage(scheme),
+ errorBuilder: (context, error, stackTrace) =>
+ _noImage(scheme),
)
: _noImage(scheme),
),
diff --git a/lib/views/widgets/slide_confirm.dart b/lib/views/widgets/slide_confirm.dart
index 1175a96..081b1f3 100644
--- a/lib/views/widgets/slide_confirm.dart
+++ b/lib/views/widgets/slide_confirm.dart
@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
class SlideConfirm extends StatefulWidget {
final VoidCallback onConfirmed;
- const SlideConfirm({required this.onConfirmed});
+ const SlideConfirm({super.key, required this.onConfirmed});
@override
State createState() => _SlideConfirmState();