Fixes always showing non-featured apps last in FeaturedViewController

This commit is contained in:
Riley Testut
2023-12-08 19:18:50 -06:00
parent 8df2f52c3c
commit f76e3a12b6
2 changed files with 40 additions and 21 deletions

View File

@@ -348,11 +348,6 @@ private extension FeaturedViewController
// Instead, sort by StoreApp.installedApp.storeApp.source.sourceIdentifier, which will be either nil OR source ID.
NSSortDescriptor(keyPath: \StoreApp.installedApp?.storeApp?.sourceIdentifier, ascending: true),
// Show featured apps first.
// Sorting by StoreApp.featuringSource crashes because Source does not respond to compare:
// Instead, sort by StoreApp.featuringSource.identifier, which will be either nil OR source ID.
NSSortDescriptor(keyPath: \StoreApp.featuringSource?.identifier, ascending: false),
// Randomize order within sections.
NSSortDescriptor(keyPath: \StoreApp.featuredSortID, ascending: true),

View File

@@ -190,11 +190,15 @@ public extension DatabaseManager
{
// Randomize source order
let fetchRequest = Source.fetchRequest()
let sources = try context.fetch(fetchRequest)
fetchRequest.relationshipKeyPathsForPrefetching = [#keyPath(Source._apps)]
let sources = try context.fetch(fetchRequest)
for source in sources
{
source.featuredSortID = UUID().uuidString
// Randomize app order
self.updateAppFeaturedSortIDs(for: source)
}
try context.save()
@@ -203,23 +207,43 @@ public extension DatabaseManager
{
Logger.main.error("Failed to update source order. \(error.localizedDescription, privacy: .public)")
}
do
{
// Randomize app order
let fetchRequest = StoreApp.fetchRequest()
let apps = try context.fetch(fetchRequest)
for app in apps
{
app.featuredSortID = UUID().uuidString
}
try context.save()
}
}
private func updateAppFeaturedSortIDs(for source: Source)
{
let featuredAppSlots = 5
// Filter out already installed apps.
var featuredApps = Set(source.effectiveFeaturedApps.filter { $0.installedApp == nil }.prefix(featuredAppSlots)) // Take just first 5 featured apps
var otherApps = source.apps.filter { $0.installedApp == nil && !featuredApps.contains($0) }
let remainingSlots = featuredAppSlots - featuredApps.count
// Fill in remaining featured app slots with random uninstalled apps.
for _ in 0 ..< remainingSlots
{
guard let index = otherApps.indices.randomElement() else {
// No remaining apps, so stop filling in slots.
break
}
catch
let randomApp = otherApps[index]
featuredApps.insert(randomApp)
otherApps.remove(at: index)
}
for storeApp in source.apps
{
if featuredApps.contains(storeApp)
{
Logger.main.error("Failed to update app order. \(error.localizedDescription, privacy: .public)")
storeApp.featuredSortID = UUID().uuidString
}
else
{
// Prepend "_" to ensure it's sorted after featuredApps.
storeApp.featuredSortID = "_" + UUID().uuidString
}
}
}