Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
0594413
refactor: rename AiOrchestrator to AiHandler
VoidX3D May 28, 2026
8f26373
feat: integrate Anthropic and Ollama AI providers with improved key-o…
VoidX3D May 28, 2026
0ec3c63
feat(ai): add AiProviderEndpoints – centralize all hardcoded URLs and…
VoidX3D May 28, 2026
60582c8
cleanup: remove AI Metadata Editor remnants
VoidX3D May 28, 2026
cd622d5
feat: merge GeminiModelService logic into AiHandler
VoidX3D May 28, 2026
bfaa80d
refactor: update SettingsViewModel to use AiHandler and AiModel
VoidX3D May 28, 2026
e5bef74
cleanup: remove redundant GeminiModelService
VoidX3D May 28, 2026
86b6ba9
feat: add AI data preferences to repository
VoidX3D May 28, 2026
f960bc2
feat: implement AI preference handling in SettingsViewModel
VoidX3D May 28, 2026
32f36ef
feat: add AI Preferences category definition and strings
VoidX3D May 28, 2026
bd22bca
feat: add colors for AI Preferences in SettingsScreen
VoidX3D May 28, 2026
255559f
feat: implement AI Preferences screen
VoidX3D May 28, 2026
10d9cbd
chore: add AiPreferences route
VoidX3D May 28, 2026
ecc92f3
chore: register AiPreferences route in AppNavigation
VoidX3D May 28, 2026
d676cc5
feat: link AI Preferences screen in Settings
VoidX3D May 28, 2026
f6dc761
Merge pull request #1 from Zenx-d/feat(ai)-Powerful-Changes
VoidX3D May 28, 2026
69f60d6
Merge pull request #25 from Zenx-d/master
VoidX3D May 28, 2026
8d5f44d
simple fixes
VoidX3D May 28, 2026
9095f65
git author fix
VoidX3D May 28, 2026
3b96539
git author fix
VoidX3D May 28, 2026
b39141c
fix: resolve AiStateHolder metadata errors and strings formatting
VoidX3D May 28, 2026
ccbc611
chore: simpel fixes
VoidX3D May 28, 2026
df8364b
fix: resolve build errors from AI metadata removal
VoidX3D May 28, 2026
4e2eb90
chore: remove AiMetadataSheet - AI metadata generation feature removed
VoidX3D May 28, 2026
c5fa147
refactor: update song engagement database entities
VoidX3D May 28, 2026
b43d053
refactor: update AI preferences repository
VoidX3D May 28, 2026
e6f2824
refactor: update AppModule for AI dependencies
VoidX3D May 28, 2026
4cdcd4c
refactor: update AiStateHolder for AI features
VoidX3D May 28, 2026
f8875de
refactor: update listening stats and player state
VoidX3D May 28, 2026
db5d4f6
refactor: update DailyMixSection component
VoidX3D May 28, 2026
40a8478
refactor: update song info and player overlay components
VoidX3D May 28, 2026
acafd20
refactor: update album and artist detail screens
VoidX3D May 28, 2026
9a49b68
refactor: update daily mix and genre screens
VoidX3D May 28, 2026
2345a88
refactor: update library and playlist screens
VoidX3D May 28, 2026
4c931bc
refactor: update recently played and search screens
VoidX3D May 28, 2026
24509c1
refactor: update DailyMixManager for AI
VoidX3D May 28, 2026
28bf2e3
build: update dependencies for AI features
VoidX3D May 28, 2026
b23339e
feat: add local AI model configuration and catalog
VoidX3D May 28, 2026
79f2816
feat: add AI behavior data collector for user listening patterns
VoidX3D May 28, 2026
7ec0508
feat: add AI logger for operations, debugging and analytics
VoidX3D May 28, 2026
256eac6
feat: add AI device capabilities hardware survey
VoidX3D May 28, 2026
720c280
fix: remove LiteRT to resolve duplicate class conflicts with TensorFl…
VoidX3D May 28, 2026
cec5904
feat: add Ollama client for local LLM integration
VoidX3D May 28, 2026
9bb7d08
feat: add HuggingFace client for model integration
VoidX3D May 28, 2026
3860179
feat: add AI prompt template engine for music recommendations
VoidX3D May 28, 2026
26d4f0c
fix: remove LiteRT from dependencies and add AI cache manager
VoidX3D May 28, 2026
0b9d57e
feat: implement AiErrorHandler to provide automated error analysis an…
VoidX3D May 28, 2026
254f34f
feat: add AI configuration options for temperature, max tokens, strea…
VoidX3D May 28, 2026
6c4c21b
feat: add local AI model settings and preferences management
VoidX3D May 28, 2026
6312d60
feat: enhance AI device capabilities with runtime checks for TFLite, …
VoidX3D May 28, 2026
23ccd7d
fix: exclude conflicting litert-support-api from TensorFlow Lite depe…
VoidX3D May 28, 2026
f9f561c
chore: cleanup unnecessry files
VoidX3D May 28, 2026
896cdfd
feat: add local model support checks and update UI accordingly
VoidX3D May 28, 2026
2ff2d8d
feat: enhance AI settings management with local model support and err…
VoidX3D May 28, 2026
985952c
fix: syntex fix in library
VoidX3D May 28, 2026
1f07bdf
Merge branch 'theovilardo:master' into master
VoidX3D May 28, 2026
22fd61f
fix: import SmartImage component and update color scheme variables in…
VoidX3D May 28, 2026
b449c41
fix: resolve AI compilation errors
VoidX3D May 28, 2026
4b2edc6
Merge branch 'theovilardo:master' into master
VoidX3D May 28, 2026
564ae9b
Merge branch 'theovilardo:master' into master
VoidX3D May 28, 2026
1758003
feat: enhance AI functionality with developer options and logging imp…
VoidX3D May 28, 2026
3c268bd
fix: remove invalid aiError parameter from SongInfoBottomSheet
VoidX3D May 28, 2026
d69aaa0
refactor: remove unused PreferenceManager import and clean up AiLogge…
VoidX3D May 28, 2026
88056e2
Merge branch 'theovilardo:master' into master
VoidX3D May 28, 2026
e597dac
rollback
VoidX3D May 28, 2026
7d63479
feat: add ProGuard rules for TensorFlow Lite classes
VoidX3D May 28, 2026
e4407ff
chore: update proguard rules
VoidX3D May 28, 2026
60c8011
Merge branch 'theovilardo:master' into master
VoidX3D May 29, 2026
d85a9a6
fix(ai):simple refactoring
VoidX3D May 29, 2026
3c4fcde
feat: add API call tracking and usage analytics to AiUsageDao and AiP…
VoidX3D May 29, 2026
dc05e74
feat: enhance daily mix prompt with max songs limit from preferences
VoidX3D May 29, 2026
c1686d0
Merge branch 'theovilardo:master' into master
VoidX3D May 29, 2026
f63204a
refactor(ai): simplify model download handling and remove unused vari…
VoidX3D May 29, 2026
0f7b619
refactor(ai): remove deprecated local models settings from strings.xml
VoidX3D May 29, 2026
fa1965e
chore: add .claude/ to .gitignore
VoidX3D May 29, 2026
911f45f
feat(database): add ApiCallRecord entity and migration from version 4…
VoidX3D May 29, 2026
3a7c5a2
feat(ai): enhance model download handling and add validation for down…
VoidX3D May 29, 2026
5c792c5
feat(ai): enhance HuggingFace and Ollama clients for improved model f…
VoidX3D May 29, 2026
1a3a03b
feat(ai): update LocalModelConfig with new model sources, types, and …
VoidX3D May 29, 2026
3bcd5e7
refactor(database): streamline AiUsageDao methods and improve delete …
VoidX3D May 29, 2026
8ff5615
refactor(ai): remove LocalMlManager class to streamline AI model mana…
VoidX3D May 29, 2026
9305082
refactor(ai): remove redundant OptIn annotation from AiPreferencesScreen
VoidX3D May 29, 2026
2534cde
feat(ai): add Local Model option to SettingsCategoryScreen
VoidX3D May 29, 2026
7b98196
refactor(ai): rename LocalMlManager to LocalModelManager for consistency
VoidX3D May 29, 2026
eefae2e
feat(ai): enhance OllamaAiClient with API key support and custom endp…
VoidX3D May 29, 2026
2fea161
feat(ai): update createClient method to support custom endpoint for O…
VoidX3D May 29, 2026
5331697
fix(ai): update Ollama endpoint to use secure HTTPS URL
VoidX3D May 29, 2026
d0ed90f
fix(ai): update Ollama URL to use secure HTTPS endpoint
VoidX3D May 29, 2026
a9e5bfd
fix(ai): update Ollama URL placeholder to use secure HTTPS endpoint
VoidX3D May 29, 2026
633cc14
feat(ai): fix inport and simple parameter fixes
VoidX3D May 29, 2026
515c4ca
feat(ai): fix simple code functions and types
VoidX3D May 29, 2026
abaec63
fix(ai): fix maxModelSizeMb to recommendedModelSizeMb in AiSettingsMa…
VoidX3D May 29, 2026
281740a
fix(ai): comprehensive AI fixes and optimizations
VoidX3D May 29, 2026
84df63b
feat(ai): complete AI preferences UI overhaul
VoidX3D May 29, 2026
1d86fd7
fix: view model fix
VoidX3D May 29, 2026
fd5a5a9
feat(ai): expand provider model lists and add model info to enum
VoidX3D May 29, 2026
7b18da0
feat(ai): improve notification system with dedicated channels
VoidX3D May 29, 2026
4972d0c
fix(privacy): change telemetry defaults from opt-out to opt-in
VoidX3D May 29, 2026
879350b
refactor(ai): use dynamic model lists from AiProvider enum
VoidX3D May 29, 2026
801dfa0
feat(ai): redesign AI preferences UI with separated sections and impr…
VoidX3D May 29, 2026
edf0281
feat(backup): add AI context and settings backup module
VoidX3D May 29, 2026
8c0f3a8
fix(build): resolve compilation errors and clean up dead code
VoidX3D May 29, 2026
362577a
fix(build): add missing imports and exhaustive when branch
VoidX3D May 29, 2026
263a775
perf(ai): consolidate collectors, remove dead code, extract Collapsib…
VoidX3D May 29, 2026
395435f
feat(ai): add generation params, richer context, digest scaling, fix …
VoidX3D May 29, 2026
a8ca091
fix(build): add missing per-provider system prompt defaults and fix V…
VoidX3D May 29, 2026
8a35d43
fix(build): correct PlaybackStatsSummary type and add missing Dp import
VoidX3D May 29, 2026
4463c24
refactor(ai): strip dead StateFlows, compact templates, deduplicate U…
VoidX3D May 29, 2026
a2e890b
refactor(ai): compact provider clients, consolidate AiSettingsManager…
VoidX3D May 29, 2026
dd57a50
fix(build): remove @Composable from data class, add missing @Composab…
VoidX3D May 29, 2026
403c189
feat(ai): add download confirmation dialog, system notifications, fix…
VoidX3D May 29, 2026
1bd8b60
feat(ai): expand provider models, add Gemma/TinyLlama/Mistral downloa…
VoidX3D May 29, 2026
c35da16
fix(ai): lock local downloads, fix Ollama URL, clean up dead code and…
VoidX3D May 29, 2026
193a7a0
feat(ai): free no-auth models, separate download tab, Ollama cloud re…
VoidX3D May 29, 2026
72df8db
fix(ai): remove models larger than 16B params
VoidX3D May 29, 2026
20e1825
feat(ai): expand model catalog, rewrite download engine with speed/ET…
VoidX3D May 29, 2026
64cd68e
fix(build): resolve CI compilation errors in AiSettingsManager, Local…
VoidX3D May 29, 2026
2b9686c
feat(ai): enrich playlist lab with behavior data, skip rates, tempo/f…
VoidX3D May 29, 2026
7b75d88
fix: resolve Long/Int type mismatch in getPerSongStats
VoidX3D May 29, 2026
6cc9f55
fix: restore missing mutable map declarations in AiBehaviorDataCollector
VoidX3D May 29, 2026
58d14d9
fix: eliminate unnecessary safe calls and Elvis operators on non-null…
VoidX3D May 29, 2026
dac3a48
chore: baseline profile cleanup, remove dead code, trim unused imports
VoidX3D May 29, 2026
e98d6b3
fix: resolve pre-existing Kotlin warnings (unnecessary casts, safe ca…
VoidX3D May 29, 2026
e527492
fix: restore missing grouped.map lambda in GenreDetailViewModel build…
VoidX3D May 29, 2026
3f17e32
fix(ai):final touches
VoidX3D May 29, 2026
655257b
security: encrypt api key and update daily mix algorithm
VoidX3D May 29, 2026
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ CLAUDE.md
markdown.xml
.vscode/
.agents/
.claude/
18 changes: 17 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ dependencies {

// UI Utilities & Extra
implementation(libs.timber)
implementation(libs.generativeai)
implementation("com.google.genai:google-genai:${libs.versions.googleGenai.get()}")
implementation(libs.smooth.corner.rect.android.compose)
implementation(libs.reorderables)
implementation(libs.codeview)
Expand All @@ -294,6 +294,22 @@ dependencies {
exclude(group = "androidx.compose.ui")
}

// Local AI: TensorFlow Lite
implementation(libs.tensorflow.lite)
implementation(libs.tensorflow.lite.support) {
exclude(group = "com.google.ai.edge.litert", module = "litert-support-api")
}
implementation(libs.tensorflow.lite.gpu)
implementation(libs.tensorflow.lite.task.text) {
// Prevent duplicate runtime classes from mixing LiteRT and tensorflow-lite-api artifacts.
exclude(group = "org.tensorflow", module = "tensorflow-lite-api")
exclude(group = "org.tensorflow", module = "tensorflow-lite-support-api")
}

// Local AI: ML Kit
implementation(libs.mlkit.translate)
implementation(libs.mlkit.language.id)

// Projects
implementation(project(":shared"))

Expand Down
14 changes: 14 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,17 @@
public static int d(...);
public static int i(...);
}
# TensorFlow Lite
-keep class org.tensorflow.lite.** { *; }
-dontwarn org.tensorflow.lite.**

# TensorFlow Lite GPU Delegate
-keep class org.tensorflow.lite.gpu.GpuDelegateFactory$Options { *; }
-keep class org.tensorflow.lite.gpu.GpuDelegateFactory$Options$GpuBackend { *; }

# TensorFlow Lite Support
-keep class org.tensorflow.lite.support.label.Category { *; }
-keep class org.tensorflow.lite.support.** { *; }

# TensorFlow Lite Task
-keep class org.tensorflow.lite.task.** { *; }
16 changes: 5 additions & 11 deletions app/src/main/baseline-prof.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30668,7 +30668,6 @@ SPLcom/theveloper/pixelplay/DaggerPixelPlayApplication_HiltComponents_SingletonC
Lcom/theveloper/pixelplay/DaggerPixelPlayApplication_HiltComponents_SingletonC$SingletonCImpl;
SPLcom/theveloper/pixelplay/DaggerPixelPlayApplication_HiltComponents_SingletonC$SingletonCImpl;->-$$Nest$fgetapplicationContextModule(Lcom/theveloper/pixelplay/DaggerPixelPlayApplication_HiltComponents_SingletonC$SingletonCImpl;)Ldagger/hilt/android/internal/modules/ApplicationContextModule;
SPLcom/theveloper/pixelplay/DaggerPixelPlayApplication_HiltComponents_SingletonC$SingletonCImpl;-><init>(Ldagger/hilt/android/internal/modules/ApplicationContextModule;)V
SPLcom/theveloper/pixelplay/DaggerPixelPlayApplication_HiltComponents_SingletonC$SingletonCImpl;->aiMetadataGenerator()Lcom/theveloper/pixelplay/data/ai/AiMetadataGenerator;
SPLcom/theveloper/pixelplay/DaggerPixelPlayApplication_HiltComponents_SingletonC$SingletonCImpl;->aiPlaylistGenerator()Lcom/theveloper/pixelplay/data/ai/AiPlaylistGenerator;
SPLcom/theveloper/pixelplay/DaggerPixelPlayApplication_HiltComponents_SingletonC$SingletonCImpl;->aiUsageDao()Lcom/theveloper/pixelplay/data/database/AiUsageDao;
SPLcom/theveloper/pixelplay/DaggerPixelPlayApplication_HiltComponents_SingletonC$SingletonCImpl;->hiltWorkerFactory()Landroidx/hilt/work/HiltWorkerFactory;
Expand Down Expand Up @@ -31184,22 +31183,19 @@ SPLcom/theveloper/pixelplay/data/DailyMixManager$readEngagements$1;-><init>(Lcom
SPLcom/theveloper/pixelplay/data/DailyMixManager$readEngagements$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
Lcom/theveloper/pixelplay/data/DailyMixManager$statsType$1;
SPLcom/theveloper/pixelplay/data/DailyMixManager$statsType$1;-><init>()V
Lcom/theveloper/pixelplay/data/ai/AiMetadataGenerator;
SPLcom/theveloper/pixelplay/data/ai/AiMetadataGenerator;-><clinit>()V
SPLcom/theveloper/pixelplay/data/ai/AiMetadataGenerator;-><init>(Lcom/theveloper/pixelplay/data/ai/AiOrchestrator;Lkotlinx/serialization/json/Json;)V
Lcom/theveloper/pixelplay/data/ai/AiNotificationManager;
SPLcom/theveloper/pixelplay/data/ai/AiNotificationManager;-><clinit>()V
SPLcom/theveloper/pixelplay/data/ai/AiNotificationManager;-><init>(Landroid/content/Context;)V
SPLcom/theveloper/pixelplay/data/ai/AiNotificationManager;->createChannel()V
Lcom/theveloper/pixelplay/data/ai/AiNotificationManager$Companion;
SPLcom/theveloper/pixelplay/data/ai/AiNotificationManager$Companion;-><init>()V
SPLcom/theveloper/pixelplay/data/ai/AiNotificationManager$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
Lcom/theveloper/pixelplay/data/ai/AiOrchestrator;
SPLcom/theveloper/pixelplay/data/ai/AiOrchestrator;-><clinit>()V
SPLcom/theveloper/pixelplay/data/ai/AiOrchestrator;-><init>(Lcom/theveloper/pixelplay/data/preferences/AiPreferencesRepository;Lcom/theveloper/pixelplay/data/ai/provider/AiClientFactory;Lcom/theveloper/pixelplay/data/database/AiCacheDao;Lcom/theveloper/pixelplay/data/database/AiUsageDao;Lcom/theveloper/pixelplay/data/ai/AiSystemPromptEngine;Lkotlinx/coroutines/CoroutineScope;)V
Lcom/theveloper/pixelplay/data/ai/AiHandler;
SPLcom/theveloper/pixelplay/data/ai/AiHandler;-><clinit>()V
SPLcom/theveloper/pixelplay/data/ai/AiHandler;-><init>(Lcom/theveloper/pixelplay/data/preferences/AiPreferencesRepository;Lcom/theveloper/pixelplay/data/ai/provider/AiClientFactory;Lcom/theveloper/pixelplay/data/database/AiCacheDao;Lcom/theveloper/pixelplay/data/database/AiUsageDao;Lcom/theveloper/pixelplay/data/ai/AiSystemPromptEngine;Lkotlinx/coroutines/CoroutineScope;)V
Lcom/theveloper/pixelplay/data/ai/AiPlaylistGenerator;
SPLcom/theveloper/pixelplay/data/ai/AiPlaylistGenerator;-><clinit>()V
SPLcom/theveloper/pixelplay/data/ai/AiPlaylistGenerator;-><init>(Lcom/theveloper/pixelplay/data/DailyMixManager;Lcom/theveloper/pixelplay/data/ai/AiOrchestrator;Lcom/theveloper/pixelplay/data/ai/UserProfileDigestGenerator;Lcom/theveloper/pixelplay/data/preferences/AiPreferencesRepository;Lkotlinx/serialization/json/Json;)V
SPLcom/theveloper/pixelplay/data/ai/AiPlaylistGenerator;-><init>(Lcom/theveloper/pixelplay/data/DailyMixManager;Lcom/theveloper/pixelplay/data/ai/AiHandler;Lcom/theveloper/pixelplay/data/ai/UserProfileDigestGenerator;Lcom/theveloper/pixelplay/data/preferences/AiPreferencesRepository;Lcom/theveloper/pixelplay/data/stats/PlaybackStatsRepository;Lkotlinx/serialization/json/Json;)V
Lcom/theveloper/pixelplay/data/ai/AiSystemPromptEngine;
SPLcom/theveloper/pixelplay/data/ai/AiSystemPromptEngine;-><clinit>()V
SPLcom/theveloper/pixelplay/data/ai/AiSystemPromptEngine;-><init>()V
Expand Down Expand Up @@ -37714,15 +37710,13 @@ Lcom/theveloper/pixelplay/presentation/viewmodel/AccountsViewModel_HiltModules_K
SPLcom/theveloper/pixelplay/presentation/viewmodel/AccountsViewModel_HiltModules_KeyModule_Provide_LazyMapKey;-><clinit>()V
Lcom/theveloper/pixelplay/presentation/viewmodel/AiStateHolder;
SPLcom/theveloper/pixelplay/presentation/viewmodel/AiStateHolder;-><clinit>()V
SPLcom/theveloper/pixelplay/presentation/viewmodel/AiStateHolder;-><init>(Landroid/content/Context;Lcom/theveloper/pixelplay/data/ai/AiPlaylistGenerator;Lcom/theveloper/pixelplay/data/ai/AiMetadataGenerator;Lcom/theveloper/pixelplay/data/DailyMixManager;Lcom/theveloper/pixelplay/data/preferences/PlaylistPreferencesRepository;Lcom/theveloper/pixelplay/presentation/viewmodel/DailyMixStateHolder;Lcom/theveloper/pixelplay/data/ai/AiNotificationManager;)V
SPLcom/theveloper/pixelplay/presentation/viewmodel/AiStateHolder;-><init>(Landroid/content/Context;Lcom/theveloper/pixelplay/data/ai/AiPlaylistGenerator;Lcom/theveloper/pixelplay/data/DailyMixManager;Lcom/theveloper/pixelplay/data/preferences/PlaylistPreferencesRepository;Lcom/theveloper/pixelplay/presentation/viewmodel/DailyMixStateHolder;Lcom/theveloper/pixelplay/data/ai/AiNotificationManager;Lcom/theveloper/pixelplay/data/ai/AiHandler;)V
SPLcom/theveloper/pixelplay/presentation/viewmodel/AiStateHolder;->getAiError()Lkotlinx/coroutines/flow/StateFlow;
SPLcom/theveloper/pixelplay/presentation/viewmodel/AiStateHolder;->getAiMetadataSuccess()Lkotlinx/coroutines/flow/StateFlow;
SPLcom/theveloper/pixelplay/presentation/viewmodel/AiStateHolder;->getAiStatus()Lkotlinx/coroutines/flow/StateFlow;
SPLcom/theveloper/pixelplay/presentation/viewmodel/AiStateHolder;->getAiSuccess()Lkotlinx/coroutines/flow/StateFlow;
SPLcom/theveloper/pixelplay/presentation/viewmodel/AiStateHolder;->getShowAiPlaylistSheet()Lkotlinx/coroutines/flow/StateFlow;
SPLcom/theveloper/pixelplay/presentation/viewmodel/AiStateHolder;->initialize(Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function0;)V
SPLcom/theveloper/pixelplay/presentation/viewmodel/AiStateHolder;->isGeneratingAiPlaylist()Lkotlinx/coroutines/flow/StateFlow;
SPLcom/theveloper/pixelplay/presentation/viewmodel/AiStateHolder;->isGeneratingMetadata()Lkotlinx/coroutines/flow/StateFlow;
Lcom/theveloper/pixelplay/presentation/viewmodel/AiUiSnapshot;
SPLcom/theveloper/pixelplay/presentation/viewmodel/AiUiSnapshot;-><init>(ZZLjava/lang/String;Ljava/lang/String;Z)V
SPLcom/theveloper/pixelplay/presentation/viewmodel/AiUiSnapshot;->isGeneratingAiMetadata()Z
Expand Down
42 changes: 34 additions & 8 deletions app/src/main/java/com/theveloper/pixelplay/data/DailyMixManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ class DailyMixManager @Inject constructor(
data class SongEngagementStats(
val playCount: Int = 0,
val totalPlayDurationMs: Long = 0L,
val lastPlayedTimestamp: Long = 0L
val lastPlayedTimestamp: Long = 0L,
val skipCount: Int = 0,
val completedCount: Int = 0
)

init {
Expand Down Expand Up @@ -118,7 +120,9 @@ class DailyMixManager @Inject constructor(
entity.songId to SongEngagementStats(
playCount = entity.playCount,
totalPlayDurationMs = entity.totalPlayDurationMs,
lastPlayedTimestamp = entity.lastPlayedTimestamp
lastPlayedTimestamp = entity.lastPlayedTimestamp,
skipCount = entity.skipCount,
completedCount = entity.completedCount
)
}
}
Expand Down Expand Up @@ -237,7 +241,9 @@ class DailyMixManager @Inject constructor(
return stats.copy(
playCount = stats.playCount.coerceAtLeast(0),
totalPlayDurationMs = stats.totalPlayDurationMs.coerceAtLeast(0L),
lastPlayedTimestamp = stats.lastPlayedTimestamp.coerceAtLeast(0L)
lastPlayedTimestamp = stats.lastPlayedTimestamp.coerceAtLeast(0L),
skipCount = stats.skipCount.coerceAtLeast(0),
completedCount = stats.completedCount.coerceAtLeast(0)
)
}

Expand All @@ -257,6 +263,24 @@ class DailyMixManager @Inject constructor(
)
}

suspend fun recordEngagement(
songId: String,
playInc: Int,
songDurationMs: Long = 0L,
timestamp: Long = System.currentTimeMillis(),
skipInc: Int = 0,
completedInc: Int = 0
) {
engagementDao.recordEngagement(
songId = songId,
playInc = playInc,
durationMs = songDurationMs.coerceAtLeast(0L),
timestamp = timestamp.coerceAtLeast(0L),
skipInc = skipInc,
completedInc = completedInc
)
}

suspend fun incrementScore(songId: String) {
recordPlay(songId)
}
Expand All @@ -270,7 +294,9 @@ class DailyMixManager @Inject constructor(
SongEngagementStats(
playCount = entity.playCount,
totalPlayDurationMs = entity.totalPlayDurationMs,
lastPlayedTimestamp = entity.lastPlayedTimestamp
lastPlayedTimestamp = entity.lastPlayedTimestamp,
skipCount = entity.skipCount,
completedCount = entity.completedCount
)
}
}
Expand All @@ -282,7 +308,7 @@ class DailyMixManager @Inject constructor(
private suspend fun computeRankedSongs(
allSongs: List<Song>,
favoriteSongIds: Set<String>,
random: java.util.Random
random: kotlin.random.Random
): List<RankedSong> {
if (allSongs.isEmpty()) return emptyList()

Expand Down Expand Up @@ -367,7 +393,7 @@ class DailyMixManager @Inject constructor(

val calendar = Calendar.getInstance()
val seed = calendar.get(Calendar.YEAR) * 1000 + calendar.get(Calendar.DAY_OF_YEAR)
val random = java.util.Random(seed.toLong())
val random = kotlin.random.Random(seed.toLong())

val rankedSongs = computeRankedSongs(allSongs, favoriteSongIds, random)
if (rankedSongs.isEmpty()) {
Expand Down Expand Up @@ -398,7 +424,7 @@ class DailyMixManager @Inject constructor(

val calendar = Calendar.getInstance()
val seed = calendar.get(Calendar.YEAR) * 1000 + calendar.get(Calendar.DAY_OF_YEAR) + 17
val random = java.util.Random(seed.toLong())
val random = kotlin.random.Random(seed.toLong())
val rankedSongs = computeRankedSongs(allSongs, favoriteSongIds, random)

if (rankedSongs.isEmpty()) {
Expand Down Expand Up @@ -466,7 +492,7 @@ class DailyMixManager @Inject constructor(
// if called multiple times in one day, preserving prompt caching.
val calendar = Calendar.getInstance()
val seed = calendar.get(Calendar.YEAR) * 1000 + calendar.get(Calendar.DAY_OF_YEAR) + 42
val random = java.util.Random(seed.toLong())
val random = kotlin.random.Random(seed.toLong())

val rankedSongs = computeRankedSongs(allSongs, favoriteSongIds, random)
if (rankedSongs.isEmpty()) {
Expand Down
Loading
Loading