diff --git a/lib/main.dart b/lib/main.dart index a1a21f7..7083d3b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -43,6 +43,8 @@ class _MyAppState extends State { Future _loadSettings() async { SharedPreferences prefs = await SharedPreferences.getInstance(); + bool? savedSorting = prefs.getBool('sortAlphabetically'); + print('Saved sorting: $savedSorting'); // Debug print setState(() { settings.showTags = prefs.getBool('showTags') ?? true; settings.showIcons = prefs.getBool('showIcons') ?? true; @@ -98,12 +100,14 @@ class AppInfo { final String name; final String packageName; final List tags; + DateTime? lastUsed; // New field to track last used time AppInfo({ this.icon, required this.name, required this.packageName, required this.tags, + this.lastUsed, }); } @@ -131,25 +135,31 @@ class _AppLauncherScreenState extends State { } Future _loadInstalledApps() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); List installedApps = await DeviceApps.getInstalledApplications( includeAppIcons: true, onlyAppsWithLaunchIntent: true, ); List loadedApps = installedApps.map((app) { + final lastUsedMillis = prefs.getInt("lastUsed_${app.packageName}"); return AppInfo( icon: app is ApplicationWithIcon ? app.icon : null, name: app.appName, packageName: app.packageName, tags: [], + lastUsed: lastUsedMillis != null + ? DateTime.fromMillisecondsSinceEpoch(lastUsedMillis) + : null, ); }).toList(); setState(() { apps = loadedApps; - filteredApps = apps; isLoading = false; }); + // Force initial sorting (by last used if sortAlphabetically is false) + _filterApps(); } void _filterApps() { @@ -163,17 +173,38 @@ class _AppLauncherScreenState extends State { if (widget.settings.sortAlphabetically) { filteredApps.sort((a, b) => a.name.compareTo(b.name)); - } - - if (filteredApps.length == 1 && query.isNotEmpty) { - _launchApp(filteredApps.first); + print('Sorting alphabetically'); + } else { + filteredApps.sort((a, b) { + // If both have a lastUsed timestamp, sort descending. + if (a.lastUsed != null && b.lastUsed != null) { + int cmp = b.lastUsed!.compareTo(a.lastUsed!); + if (cmp != 0) return cmp; + return a.name.compareTo(b.name); + } + // If one has a timestamp, that one comes first. + if (a.lastUsed != null) return -1; + if (b.lastUsed != null) return 1; + // Both null: fallback alphabetical. + return a.name.compareTo(b.name); + }); + print('Sorting by last used, with fallback alphabetical'); } }); } Future _launchApp(AppInfo app) async { bool launched = await DeviceApps.openApp(app.packageName); - if (!launched) { + if (launched) { + DateTime now = DateTime.now(); + SharedPreferences prefs = await SharedPreferences.getInstance(); + await prefs.setInt("lastUsed_${app.packageName}", now.millisecondsSinceEpoch); + // Update the lastUsed timestamp and re-sort immediately. + setState(() { + app.lastUsed = now; + _filterApps(); + }); + } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Could not launch ${app.name}')), ); @@ -199,7 +230,8 @@ class _AppLauncherScreenState extends State { } void _editAppTags(AppInfo app) { - TextEditingController tagController = TextEditingController(text: app.tags.join(" ")); + TextEditingController tagController = + TextEditingController(text: app.tags.join(" ")); showDialog( context: context, builder: (_) => AlertDialog( @@ -216,7 +248,8 @@ class _AppLauncherScreenState extends State { setState(() { app.tags ..clear() - ..addAll(tagController.text.split(" ").where((t) => t.isNotEmpty)); + ..addAll( + tagController.text.split(" ").where((t) => t.isNotEmpty)); }); Navigator.of(context).pop(); _filterApps(); @@ -336,36 +369,54 @@ class _AppLauncherScreenState extends State { PopupMenuItem( value: 'Toggle Tags', child: ListTile( - leading: Icon(widget.settings.showTags ? Icons.short_text : Icons.tag), - title: Text(widget.settings.showTags ? 'Hide Tags' : 'Show Tags'), + leading: Icon(widget.settings.showTags + ? Icons.short_text + : Icons.tag), + title: Text(widget.settings.showTags + ? 'Hide Tags' + : 'Show Tags'), ), ), PopupMenuItem( value: 'Toggle Icons', child: ListTile( - leading: Icon(widget.settings.showIcons ? Icons.apps : Icons.apps_outlined), - title: Text(widget.settings.showIcons ? 'Hide Icons' : 'Show Icons'), + leading: Icon(widget.settings.showIcons + ? Icons.apps + : Icons.apps_outlined), + title: Text(widget.settings.showIcons + ? 'Hide Icons' + : 'Show Icons'), ), ), PopupMenuItem( value: 'Toggle Color Icons', child: ListTile( leading: Icon(Icons.palette), - title: Text(widget.settings.colorIcons ? 'Use Monochrome Icons' : 'Use Color Icons'), + title: Text(widget.settings.colorIcons + ? 'Use Monochrome Icons' + : 'Use Color Icons'), ), ), PopupMenuItem( value: 'Toggle Theme', child: ListTile( - leading: Icon(widget.settings.darkTheme ? Icons.light_mode : Icons.dark_mode), - title: Text(widget.settings.darkTheme ? 'Switch to Light Mode' : 'Switch to Dark Mode'), + leading: Icon(widget.settings.darkTheme + ? Icons.light_mode + : Icons.dark_mode), + title: Text(widget.settings.darkTheme + ? 'Switch to Light Mode' + : 'Switch to Dark Mode'), ), ), PopupMenuItem( value: 'Toggle Sorting', child: ListTile( - leading: Icon(widget.settings.sortAlphabetically ? Icons.access_time : Icons.sort_by_alpha), - title: Text(widget.settings.sortAlphabetically ? 'List by Last Used' : 'List Alphabetically'), + leading: Icon(widget.settings.sortAlphabetically + ? Icons.access_time + : Icons.sort_by_alpha), + title: Text(widget.settings.sortAlphabetically + ? 'Sort Alphabetically' + : 'Sort by Last Used'), ), ), ], @@ -395,9 +446,11 @@ class _AppLauncherScreenState extends State { child: Icon(Icons.info, color: Colors.white), ), child: ListTile( - leading: widget.settings.showIcons ? _buildAppIcon(app) : null, + leading: + widget.settings.showIcons ? _buildAppIcon(app) : null, title: Text(app.name), - subtitle: widget.settings.showTags ? Text(app.tags.join(" ")) : null, + subtitle: + widget.settings.showTags ? Text(app.tags.join(" ")) : null, onTap: () => _launchApp(app), ), );