Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 72 additions & 55 deletions lib/providers/apps_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class AppsService extends ChangeNotifier

_initialized = true;
notifyListeners();

// Pre-cache icons for visible apps
_preCacheIcons();
}
Expand Down Expand Up @@ -216,29 +216,29 @@ class AppsService extends ChangeNotifier
}

Future<void> _initDefaultCategories() {
final tvApplications = _applications.values.where((application) => application.sideloaded == false);
final nonTvApplications = _applications.values.where((application) => application.sideloaded == true);
final tvApplications =
_applications.values.where((application) => !application.sideloaded);
final nonTvApplications =
_applications.values.where((application) => application.sideloaded);

return _database.transaction(() async {
if (nonTvApplications.isNotEmpty) {
int categoryId = await addCategory("Non-TV Apps",
int categoryId = await addCategory(
"Non-TV Apps",
shouldNotifyListeners: false,
);
Category nonTvAppsCategory = _categoriesById[categoryId]!;
for (final app in nonTvApplications) {
await addToCategory(app, nonTvAppsCategory, shouldNotifyListeners: false);
}
await addAppsToCategory(nonTvApplications, nonTvAppsCategory,
shouldNotifyListeners: false);
}

if (tvApplications.isNotEmpty) {
int categoryId = await addCategory("TV Apps",
type: CategoryType.grid, shouldNotifyListeners: false
);
type: CategoryType.grid, shouldNotifyListeners: false);

Category tvAppsCategory = _categoriesById[categoryId]!;
for (final app in tvApplications) {
await addToCategory(app, tvAppsCategory, shouldNotifyListeners: false);
}
await addAppsToCategory(tvApplications, tvAppsCategory,
shouldNotifyListeners: false);
}

await addCategory("Favorites", shouldNotifyListeners: false);
Expand Down Expand Up @@ -457,20 +457,36 @@ class AppsService extends ChangeNotifier

Future<void> startAmbientMode() => _fLauncherChannel.startAmbientMode();

Future<void> addToCategory(App app, Category category, {bool shouldNotifyListeners = true}) async {
int index = await _database.nextAppCategoryOrder(category.id) ?? 0;
await _database.insertAppsCategories([
AppsCategoriesCompanion.insert(
Future<void> addToCategory(App app, Category category,
{bool shouldNotifyListeners = true}) async {
await addAppsToCategory([app], category,
shouldNotifyListeners: shouldNotifyListeners);
}

Future<void> addAppsToCategory(Iterable<App> apps, Category category,
{bool shouldNotifyListeners = true}) async {
if (apps.isEmpty) return;

int nextIndex = await _database.nextAppCategoryOrder(category.id) ?? 0;
List<AppsCategoriesCompanion> companions = [];

for (final app in apps) {
companions.add(AppsCategoriesCompanion.insert(
categoryId: category.id,
appPackageName: app.packageName,
order: index,
)
]);
order: nextIndex++,
));
}

if (_categoriesById.containsKey(category.id)) {
Category categoryFound = _categoriesById[category.id]!;
app.categoryOrders[categoryFound.id] = index;
categoryFound.applications.add(app);
await _database.insertAppsCategories(companions);

final categoryFound = _categoriesById[category.id];
if (categoryFound != null) {
int index = nextIndex - apps.length;
for (final app in apps) {
app.categoryOrders[categoryFound.id] = index++;
categoryFound.applications.add(app);
}

if (shouldNotifyListeners) {
sortCategory(categoryFound);
Expand All @@ -481,8 +497,8 @@ class AppsService extends ChangeNotifier

Future<void> removeFromCategory(App application, Category category) async {
await _database.deleteAppCategory(category.id, application.packageName);
if (_categoriesById.containsKey(category.id)) {
Category categoryFound = _categoriesById[category.id]!;
final categoryFound = _categoriesById[category.id];
if (categoryFound != null) {
application.categoryOrders.remove(categoryFound.id);
categoryFound.applications.remove(application);

Expand All @@ -499,79 +515,80 @@ class AppsService extends ChangeNotifier
return;
}
Category actualCategory = _categoriesById[category.id]!;

Iterable<App> appsToAdd;

switch (actualCategory.name) {
case 'TV Apps':
appsToAdd = _applications.values.where((app) => !app.sideloaded && !app.hidden);
appsToAdd =
_applications.values.where((app) => !app.sideloaded && !app.hidden);
break;
case 'Non-TV Apps':
appsToAdd = _applications.values.where((app) => app.sideloaded && !app.hidden);
appsToAdd =
_applications.values.where((app) => app.sideloaded && !app.hidden);
break;
default:
return; // Not a special category
}

for (final app in appsToAdd) {
await addToCategory(app, actualCategory, shouldNotifyListeners: false);
}


await addAppsToCategory(appsToAdd, actualCategory,
shouldNotifyListeners: false);

notifyListeners();
}

// === FAVORITES METHODS ===

/// Gets the Favorites category, creating it if it doesn't exist
Future<Category> getOrCreateFavoritesCategory() async {
// Look for existing Favorites category
Category? favorites = _categoriesById.values.firstWhereOrNull(
(category) => category.name == 'Favorites'
);

if (favorites != null) {
return favorites;
}

// Create Favorites category if it doesn't exist
int categoryId = await addCategory('Favorites', shouldNotifyListeners: false);
return _categoriesById[categoryId]!;
}

/// Checks if an app is in the Favorites category
bool isAppInFavorites(App app) {
Category? favorites = _categoriesById.values.firstWhereOrNull(
(category) => category.name == 'Favorites'
);

if (favorites == null) {
return false;
}

return favorites.applications.any((a) => a.packageName == app.packageName);
}

/// Adds an app to Favorites
Future<void> addToFavorites(App app) async {
Category favorites = await getOrCreateFavoritesCategory();

// Check if already in favorites
if (!favorites.applications.any((a) => a.packageName == app.packageName)) {
await addToCategory(app, favorites);
}
}

/// Removes an app from Favorites
Future<void> removeFromFavorites(App app) async {
Category? favorites = _categoriesById.values.firstWhereOrNull(
(category) => category.name == 'Favorites'
);

if (favorites != null) {
await removeFromCategory(app, favorites);
}
}

/// Toggles an app in/out of Favorites
Future<void> toggleFavorite(App app) async {
if (isAppInFavorites(app)) {
Expand All @@ -585,7 +602,7 @@ class AppsService extends ChangeNotifier
if (!_categoriesById.containsKey(category.id)) {
return;
}

Category categoryFound = _categoriesById[category.id]!;
List<App> applications = categoryFound.applications;
List<AppsCategoriesCompanion> orderedAppCategories = [];
Expand Down Expand Up @@ -635,10 +652,10 @@ class AppsService extends ChangeNotifier

// Remove from current
await removeFromCategory(app, currentCategory);

// Set pending focus package so AppCard can reclaim focus and reorder mode
_pendingReorderFocusPackage = app.packageName;

// Add to target
int newIndex = 0;
if (direction == AxisDirection.up) {
Expand All @@ -652,14 +669,14 @@ class AppsService extends ChangeNotifier
// DB Insert Logic
// 1. Get current items in target
List<App> targetApps = targetCategory.applications;

// 2. Adjust local list
if (direction == AxisDirection.down) {
targetApps.insert(0, app); // Insert at top
} else {
targetApps.add(app); // Insert at bottom
}

// 3. Update orders for all items in target category
List<AppsCategoriesCompanion> orderedAppCategories = [];
for (int i = 0; i < targetApps.length; ++i) {
Expand All @@ -671,10 +688,10 @@ class AppsService extends ChangeNotifier
order: Value(i),
));
}

// 4. Batch DB update
await _database.replaceAppsCategories(orderedAppCategories);

notifyListeners();
}

Expand Down Expand Up @@ -828,7 +845,7 @@ class AppsService extends ChangeNotifier
else {
await _database.deleteSpacer(section.id);
}

_launcherSections.removeAt(index);

notifyListeners();
Expand All @@ -837,7 +854,7 @@ class AppsService extends ChangeNotifier
void moveSectionInMemory(int oldIndex, int newIndex) {
if (oldIndex < 0 || oldIndex >= _launcherSections.length ||
newIndex < 0 || newIndex >= _launcherSections.length) return;

final section = _launcherSections.removeAt(oldIndex);
_launcherSections.insert(newIndex, section);
notifyListeners();
Expand All @@ -846,7 +863,7 @@ class AppsService extends ChangeNotifier
Future<void> persistSectionsOrder() async {
List<CategoriesCompanion> orderedCategories = [];
List<LauncherSpacersCompanion> orderedSpacers = [];

for (int i = 0; i < _launcherSections.length; ++i) {
LauncherSection section = _launcherSections[i];
// Update the order property on the object itself
Expand Down