From 740fef5d7de2e5d3679ffd49e9f7c8efe61dbf40 Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Mon, 21 Apr 2025 21:56:24 +0200 Subject: [PATCH] Clean up shit --- lib/main.dart | 219 +++++++++----------------------------------------- 1 file changed, 38 insertions(+), 181 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 69a2a8c..bdd27d8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,34 +1,27 @@ import 'dart:async'; -import 'dart:io'; // Required for Platform check import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; // Needed for LogicalKeyboardKey +import 'package:flutter/services.dart'; import 'package:system_tray/system_tray.dart'; import 'package:window_manager/window_manager.dart'; import 'package:audioplayers/audioplayers.dart'; -// For path joining -// --- Configuration --- -const Duration popupInterval = Duration(hours: 1); // How often to pop up +const Duration popupInterval = Duration(hours: 1); const String notificationSound = 'MeetTheSniper.mp3'; -// -------------------- void main() async { WidgetsFlutterBinding.ensureInitialized(); - // Must add this line. await windowManager.ensureInitialized(); - // Use it only after calling `hiddenWindowAtLaunch` WindowOptions windowOptions = const WindowOptions( - size: Size(1600, 900), // Increased size to 1600x900 + size: Size(1600, 900), center: true, backgroundColor: Colors.transparent, skipTaskbar: false, titleBarStyle: TitleBarStyle.normal, ); - // Hide window at launch windowManager.waitUntilReadyToShow(windowOptions, () async { - await windowManager.hide(); // Start hidden + await windowManager.hide(); }); runApp(const JournalerApp()); @@ -37,10 +30,8 @@ void main() async { class JournalerApp extends StatelessWidget { const JournalerApp({super.key}); - // --- Base Theme Configuration --- static final TextTheme _baseTextTheme = const TextTheme( bodyMedium: TextStyle(fontSize: 24), - // Define other common styles if needed ); static final TextStyle _baseTitleTextStyle = const TextStyle( @@ -48,15 +39,12 @@ class JournalerApp extends StatelessWidget { fontWeight: FontWeight.w500, ); - static final InputDecorationTheme - _baseInputDecorationTheme = const InputDecorationTheme( - border: OutlineInputBorder(), - labelStyle: TextStyle(fontSize: 20), // Base label size - // contentPadding: EdgeInsets.all(12.0), // Example: Add padding globally - ); - // ------------------------------ + static final InputDecorationTheme _baseInputDecorationTheme = + const InputDecorationTheme( + border: OutlineInputBorder(), + labelStyle: TextStyle(fontSize: 20), + ); - // Define the light theme static final ThemeData lightTheme = ThemeData.light().copyWith( visualDensity: VisualDensity.adaptivePlatformDensity, colorScheme: ColorScheme.fromSeed( @@ -77,12 +65,9 @@ class JournalerApp extends StatelessWidget { color: Colors.grey[700], ), ), - textTheme: _baseTextTheme.copyWith( - // Optionally override specific light theme text styles here - ), + textTheme: _baseTextTheme, ); - // Define the dark theme static final ThemeData darkTheme = ThemeData.dark().copyWith( visualDensity: VisualDensity.adaptivePlatformDensity, colorScheme: ColorScheme.fromSeed( @@ -97,7 +82,7 @@ class JournalerApp extends StatelessWidget { ), inputDecorationTheme: _baseInputDecorationTheme.copyWith( border: const OutlineInputBorder( - borderSide: BorderSide(color: Colors.grey), // Dark theme default border + borderSide: BorderSide(color: Colors.grey), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.blue.shade300, width: 2.0), @@ -107,9 +92,7 @@ class JournalerApp extends StatelessWidget { ), ), textTheme: _baseTextTheme.copyWith( - // Ensure body text is readable on dark background bodyMedium: _baseTextTheme.bodyMedium?.copyWith(color: Colors.white), - // Optionally override other dark theme text styles here ), ); @@ -143,20 +126,16 @@ class _MainPageState extends State with WindowListener { final TextEditingController _todoController = TextEditingController(); Timer? _popupTimer; - Timer? _debounceTimer; // Timer for debouncing Todo saves + Timer? _debounceTimer; @override void initState() { super.initState(); windowManager.addListener(this); _initSystemTray(); - _loadData(); // Placeholder for loading initial data + _loadData(); _startPopupTimer(); - // Prevent window from closing, instead hide it - // Needs `implements WindowListener` and `windowManager.addListener(this);` - // and `windowManager.removeListener(this);` in dispose windowManager.setPreventClose(true); - // Set aspect ratio after ensuring initialized _setWindowConfig(); } @@ -164,7 +143,7 @@ class _MainPageState extends State with WindowListener { void dispose() { windowManager.removeListener(this); _popupTimer?.cancel(); - _debounceTimer?.cancel(); // Cancel debounce timer on dispose + _debounceTimer?.cancel(); _previousEntryController.dispose(); _currentEntryController.dispose(); _todoController.dispose(); @@ -172,67 +151,30 @@ class _MainPageState extends State with WindowListener { super.dispose(); } - // --- Window Listener --- // @override void onWindowClose() { - _saveData(); // Placeholder for saving data - windowManager.hide(); // Hide instead of closing - // Alternatively, to fully close: - // windowManager.destroy(); + _saveData(); + windowManager.hide(); } @override void onWindowFocus() { - // Maybe reload data if needed when window becomes active - setState(() { - // If you need to refresh state - }); + setState(() {}); } - // --- System Tray --- // Future _initSystemTray() async { - // Use simple relative paths for assets declared in pubspec.yaml - // The build process handles packaging these assets correctly. String iconPath = 'assets/app_icon.ico'; - // IMPORTANT: You need to create an icon file named app_icon.ico (for Windows) - // and/or app_icon.png (for Mac/Linux) and place it in the 'assets/' directory. - // Create the 'assets' directory if it doesn't exist at the root of your project. - // Then, ensure your pubspec.yaml lists the 'assets/' directory: - // flutter: - // uses-material-design: true - // assets: - // - assets/ - // - assets/sounds/ # Keep this if you have it + await _systemTray.initSystemTray(iconPath: iconPath, toolTip: "Journaler"); - // Check if the asset file exists before trying to use it (optional but recommended) - // Note: This basic check works during development. Accessing assets might - // require different handling in production builds depending on the platform. - // try { - // await rootBundle.load(iconPath); // Check if asset is loadable - // } catch (_) { - // debugPrint("Error: System tray icon '$iconPath' not found in assets."); - // // Handle the error, maybe use a default icon or skip tray init - // return; - // } - - await _systemTray.initSystemTray( - // title: "Journaler", // Optional: Title shown on hover (might not work on all OS) - iconPath: iconPath, // Use the corrected path - toolTip: "Journaler", - ); - - // Handle system tray menu item clicks _systemTray.registerSystemTrayEventHandler((eventName) { debugPrint("System Tray Event: $eventName"); _showWindow(); }); } - // --- Periodic Popup & Sound --- // void _startPopupTimer() { _popupTimer = Timer.periodic(popupInterval, (timer) { - // Timer now only requests the window to show _showWindow(); }); } @@ -240,28 +182,22 @@ class _MainPageState extends State with WindowListener { Future _showWindow() async { bool wasVisible = await windowManager.isVisible(); if (!wasVisible) { - // Ensure size and position before showing - await windowManager.setSize(const Size(1600, 900)); // Set desired size - await windowManager.center(); // Center the window + await windowManager.setSize(const Size(1600, 900)); + await windowManager.center(); await windowManager.show(); await windowManager.focus(); - // Play sound ONLY when window becomes visible await _playSound(); } else { - // If already visible, just bring to front and focus await windowManager.focus(); } } Future _playSound() async { try { - // Stop any previous playback before starting anew await _audioPlayer.stop(); - // Assumes the sound file is in assets/sounds/ await _audioPlayer.play(AssetSource('sounds/$notificationSound')); debugPrint("Played sound: $notificationSound"); } catch (e, stackTrace) { - // Catch stack trace for more details debugPrint("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); debugPrint("Error playing sound '$notificationSound': $e"); debugPrint("Stack trace: $stackTrace"); @@ -269,157 +205,94 @@ class _MainPageState extends State with WindowListener { "Ensure file exists, is valid audio, and assets/sounds/ is in pubspec.yaml", ); debugPrint("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); - // Handle error, e.g., show a notification or log } } - // --- Data Handling (Placeholders) --- // void _loadData() { - // TODO: Implement logic to load previous entry and todo list - // Example: - // _previousEntryController.text = await loadPreviousEntryFromDatabase(); - // _todoController.text = await loadTodoListFromFile(); _previousEntryController.text = "This is a placeholder for the previous entry."; _todoController.text = "- Placeholder Todo 1\n- Placeholder Todo 2"; - _currentEntryController.text = ""; // Current entry always starts empty + _currentEntryController.text = ""; debugPrint("Data loaded (placeholder)."); } void _saveData() { - // TODO: Implement logic to save the current entry and todo list - // This is called when the window is closed (hidden) or the save button is pressed. String currentEntry = _currentEntryController.text; String todoList = _todoController.text; print( "Saving data (placeholder)... Current Entry: [${currentEntry.length} chars], Todo: [${todoList.length} chars]", ); - - // --- Your persistence logic goes here --- - // Example: - // await saveEntryToDatabase(currentEntry); - // await saveTodoListToFile(todoList); - // --------------------------------------- - - // You might want to update the previous entry for the *next* session here, - // or handle this logic when loading data next time. - // Example (simplistic, assumes immediate update for next view): - // setState(() { - // _previousEntryController.text = currentEntry; - // _currentEntryController.clear(); // Clear current entry after saving - // }); - - // Potentially clear current entry after saving, or handle it on next load - // _currentEntryController.clear(); // Decide if you want to clear it immediately } - // --- Add a specific save function for Todo List --- // void _saveTodoList() { - // Cancel any existing timer if (_debounceTimer?.isActive ?? false) _debounceTimer!.cancel(); - // Start a new timer _debounceTimer = Timer(const Duration(milliseconds: 500), () { - // This code runs after 500ms of inactivity String todoList = _todoController.text; print("Debounced Save: Saving Todo list... [${todoList.length} chars]"); - // --- Your actual todo list persistence logic goes here --- - // Example: - // await saveTodoListToFile(todoList); - // -------------------------------------------------------- }); } - // Helper to set initial window config like aspect ratio Future _setWindowConfig() async { - // Wait a moment to ensure window manager is fully ready after init - // Might not be strictly necessary but can prevent race conditions - // await Future.delayed(const Duration(milliseconds: 100)); await windowManager.setAspectRatio(16 / 9); - // Optionally set min/max size if desired - // await windowManager.setMinimumSize(const Size(800, 450)); } - // --- UI Build --- // @override Widget build(BuildContext context) { - // Listen for keyboard events to close on Escape - return RawKeyboardListener( - focusNode: FocusNode(), // Need a focus node to receive keys - autofocus: true, // Ensure it can receive focus - onKey: (event) { - if (event.logicalKey == LogicalKeyboardKey.escape) { + return KeyboardListener( + focusNode: FocusNode(), + autofocus: true, + onKeyEvent: (event) { + if (event is KeyDownEvent && + event.logicalKey == LogicalKeyboardKey.escape) { debugPrint("Escape key pressed - hiding window."); windowManager.hide(); } }, child: Scaffold( - appBar: AppBar( - title: const Text('Journaler'), - actions: const [ - // Remove all buttons - // No actions needed anymore - ], - ), + appBar: AppBar(title: const Text('Journaler'), actions: const []), body: Padding( padding: const EdgeInsets.all(8.0), child: Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - // Main journal area (8-10 columns) Expanded( - flex: - 9, // Adjust flex factor (e.g., 8, 9, 10) for desired width ratio + flex: 9, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - // Previous Entry (read-only conceptually, but TextField for easy display) Expanded( child: TextField( controller: _previousEntryController, - maxLines: null, // Allows unlimited lines - expands: true, // Fills the available space - style: - Theme.of( - context, - ).textTheme.bodyMedium, // Apply theme text style + maxLines: null, + expands: true, + style: Theme.of(context).textTheme.bodyMedium, decoration: const InputDecoration( labelText: 'Previous Entry', - // border: OutlineInputBorder(), // Handled by theme - // contentPadding: EdgeInsets.all(8.0), // Handled by theme or default ), ), ), - const SizedBox(height: 8), // Spacing - // Current Entry + const SizedBox(height: 8), Expanded( child: TextField( controller: _currentEntryController, maxLines: null, expands: true, - autofocus: true, // Focus here when window appears - style: - Theme.of( - context, - ).textTheme.bodyMedium, // Apply theme text style + autofocus: true, + style: Theme.of(context).textTheme.bodyMedium, decoration: const InputDecoration( labelText: 'Current Entry (What\'s on your mind?)', - // border: OutlineInputBorder(), // Handled by theme - // contentPadding: EdgeInsets.all(8.0), // Handled by theme or default ), - onChanged: (text) { - // Optional: Add auto-save logic here if desired - }, + onChanged: (text) {}, ), ), ], ), ), - const SizedBox(width: 8), // Spacing between columns - // Todo List area (remaining columns) + const SizedBox(width: 8), Expanded( - flex: 3, // Adjust flex factor (12 - 9 = 3, or 12 - 8 = 4, etc.) + flex: 3, child: TextField( controller: _todoController, maxLines: null, @@ -446,19 +319,3 @@ class _MainPageState extends State with WindowListener { ); } } - -// REMOVED - Helper class for AppWindow interactions (optional, but good practice) -// class AppWindow { -// Future init() async { -// // Can add more window setup here if needed -// } -// -// Future show() async { -// await windowManager.show(); -// await windowManager.focus(); -// } -// -// Future hide() async { -// await windowManager.hide(); -// } -// }