Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
13aaad9
Update French changelog strings and translations
rebornlokii Jun 13, 2026
5196043
Revise Italian changelog strings for clarity
rebornlokii Jun 13, 2026
31c9678
Update beta version to 0.7.5 in strings resource
rebornlokii Jun 13, 2026
70c42fc
Update beta version to 0.7.5 in Italian strings
rebornlokii Jun 13, 2026
ddade1d
Update strings_home_screen.xml
rebornlokii Jun 13, 2026
698ae10
Update beta version strings to 0.7.5
rebornlokii Jun 13, 2026
7e346a3
Update beta version strings to 0.7.5
rebornlokii Jun 13, 2026
2c376a8
Update beta version strings to 0.7.5
rebornlokii Jun 13, 2026
df83b66
Update beta version strings to 0.7.5 in russian strings
rebornlokii Jun 13, 2026
f99cb20
Update beta version strings to 0.7.5
rebornlokii Jun 13, 2026
b44ba5d
Update beta version strings to 0.7.5
rebornlokii Jun 13, 2026
3cc47db
Update beta version strings to 0.7.5
rebornlokii Jun 13, 2026
5325ea2
Update strings_home_screen.xml
rebornlokii Jun 13, 2026
432796a
Update French lyrics mode strings for consistency
rebornlokii Jun 13, 2026
402e457
refactor(ai): rename AiOrchestrator to AiHandler
VoidX3D Jun 15, 2026
71dd8fb
feat(ai): add UnifiedModelFilter for consistent model filtering acros…
VoidX3D Jun 15, 2026
d599acb
refactor(ai): unify DeepSeek/Groq/Mistral to GenericOpenAiClient
VoidX3D Jun 15, 2026
5d08f1b
feat(ai): add CUSTOM provider entry to AiProvider enum
VoidX3D Jun 15, 2026
b1f3c80
feat(ai): add CUSTOM provider and createClientWithUrl to AiClientFactory
VoidX3D Jun 15, 2026
a5fdfef
feat(ai): add CUSTOM to provider fallback chain in AiProviderSupport
VoidX3D Jun 15, 2026
cf7f4b5
feat(ai): add base URL support and CUSTOM provider prefs to AiPrefere…
VoidX3D Jun 15, 2026
c8fd759
feat(ai): add OLLAMA provider entry to AiProvider enum
VoidX3D Jun 15, 2026
c83cc4f
feat(ai): add OLLAMA provider implementation to AiClientFactory
VoidX3D Jun 15, 2026
f13e7da
feat(ai): add OLLAMA to provider fallback chain
VoidX3D Jun 15, 2026
452dcfe
feat(ai): add OLLAMA provider convenience flows to AiPreferencesRepos…
VoidX3D Jun 15, 2026
3abd56b
feat(ai): add SearchableModelSelector composable with search bar
VoidX3D Jun 15, 2026
775766d
feat(ai): add Ollama/Custom provider flows and base URL state to Sett…
VoidX3D Jun 15, 2026
ee57fae
feat(ui): add OLLAMA/CUSTOM provider labels, SearchableModelSelector,…
VoidX3D Jun 15, 2026
ca27d41
chore: remove unused DeepSeekAiClient, GroqAiClient, MistralAiClient …
VoidX3D Jun 15, 2026
bd711b5
feat(ai): add topP, topK, maxTokens, presencePenalty, frequencyPenalt…
VoidX3D Jun 15, 2026
70c756b
feat(ai): add topP, maxTokens, presencePenalty, frequencyPenalty to G…
VoidX3D Jun 15, 2026
479104f
feat(ai): add topP, topK, maxTokens, presencePenalty, frequencyPenalt…
VoidX3D Jun 15, 2026
9ddb02b
feat(ai): add generation parameter and song data configuration prefer…
VoidX3D Jun 15, 2026
fa1ccad
feat(ai): overhaul AiSystemPromptEngine with chain-of-thought, few-sh…
VoidX3D Jun 15, 2026
19df14f
feat(ai): fetch and pass generation parameters from preferences in Ai…
VoidX3D Jun 15, 2026
2963295
feat(ai): make digest sample size, mode, and extended fields configur…
VoidX3D Jun 15, 2026
e7a17b6
feat(ai): add generation parameter flows and handlers to SettingsView…
VoidX3D Jun 15, 2026
aba3bbf
feat(ui): add Generation Parameters and Song Data Configuration secti…
VoidX3D Jun 15, 2026
51049de
fix: resolve compilation errors in AI settings UI
VoidX3D Jun 15, 2026
3f10397
fix(ai): add AiResponseCleaner, fix usage tracking model name, robust…
VoidX3D Jun 15, 2026
9ad2e8d
refactor: remove AiMetadataGenerator and fix compilation errors
VoidX3D Jun 15, 2026
e771316
refactor: improve translateLyrics prompt with XML structure
VoidX3D Jun 15, 2026
49d890e
fix: restore playlist generation state tracking
VoidX3D Jun 15, 2026
43d79ca
fix: update API key messages and enhance AI provider key handling
VoidX3D Jun 15, 2026
97f6f34
ui: fix layout jump when collapsing telegram channel topics
Ayaanh001 Jun 17, 2026
10661f7
f
Ayaanh001 Jun 17, 2026
4616616
strings: add labels and content descriptions for About screen social …
Ayaanh001 Jun 17, 2026
7d20141
strings(es): translate About screen social links to Spanish
Ayaanh001 Jun 17, 2026
bff3ef9
strings: localize GitHub and Telegram social chips for Arabic
Ayaanh001 Jun 17, 2026
bf45b6f
strings: localize GitHub and Telegram social chips for German
Ayaanh001 Jun 17, 2026
f9da386
strings: localize GitHub and Telegram social chips for French
Ayaanh001 Jun 17, 2026
8ff5822
strings: localize GitHub and Telegram social chips for Indonesian
Ayaanh001 Jun 17, 2026
b237916
strings: localize GitHub and Telegram social chips for Italian
Ayaanh001 Jun 17, 2026
8334d64
strings: localize GitHub and Telegram social chips for Korean
Ayaanh001 Jun 17, 2026
7fc0883
strings: localize GitHub and Telegram social chips for Norwegian Bokmål
Ayaanh001 Jun 17, 2026
5e905f1
strings: localize GitHub and Telegram social chips for Russian
Ayaanh001 Jun 17, 2026
1a1b43c
strings: localize GitHub and Telegram social chips for Turkish
Ayaanh001 Jun 17, 2026
d3e73c0
strings: localize GitHub and Telegram social chips for Chinese (Simpl…
Ayaanh001 Jun 17, 2026
0d671d4
feat(i18n): add Japanese translation files (values-ja/)
fujimon0722 Jun 18, 2026
c7e2b0f
feat(i18n): register Japanese locale in AppLanguage and locales_config
fujimon0722 Jun 18, 2026
0deef6e
feat(i18n): add settings_language_japanese label to all language files
fujimon0722 Jun 18, 2026
fd0a3cb
fix(playlists): prevent lost updates when editing playlist songs conc…
AmrEldeeb5 Jun 18, 2026
1bbfde2
Refine artist parsing and album display metadata
lostf1sh Jun 19, 2026
7664278
feat(playback): add pause-on-volume-zero setting
Amonoman Jun 19, 2026
a19102e
feat(settings): add pause-on-volume-zero toggle to playback settings
Amonoman Jun 19, 2026
59a7538
fix(strings-tr): remove duplicate keys from strings.xml
Amonoman Jun 19, 2026
41e52e9
Merge branch 'PixelPlayerHQ:master' into master
VoidX3D Jun 20, 2026
761bac0
perf(sync): chunk Telegram sync to prevent OOM on large channels
Amonoman Jun 21, 2026
5bb4f6c
Merge branch 'PixelPlayerHQ:master' into master
rebornlokii Jun 21, 2026
17e15a0
Merge branch 'PixelPlayerHQ:master' into update-french-strings
rebornlokii Jun 21, 2026
2ae0e06
Merge pull request #2413 from PixelPlayerHQ/fish/delimiter-issues
theovilardo Jun 22, 2026
c45d4d8
Merge pull request #2415 from Amonoman/master
theovilardo Jun 22, 2026
4f23f4b
Merge pull request #2400 from AmrEldeeb5/fix/2391-playlist-song-count
theovilardo Jun 22, 2026
1a261d8
Merge pull request #2371 from VoidX3D/master
theovilardo Jun 22, 2026
bcf0944
Merge pull request #2353 from rebornlokii/update-french-strings
theovilardo Jun 22, 2026
51f23d7
Merge pull request #2347 from rebornlokii/master
theovilardo Jun 22, 2026
d43f0f7
Merge branch 'master' into master
theovilardo Jun 22, 2026
8b1f6aa
Merge pull request #2383 from Ayaanh001/master
theovilardo Jun 22, 2026
bc8ae59
fix: tag NetEase songs as remote source, request lossless, fix lyrics…
lostf1sh Jun 22, 2026
905974a
Merge pull request #2442 from PixelPlayerHQ/fix/netease-source-and-ly…
theovilardo Jun 22, 2026
83925e1
fix: Button color
Ayaanh001 Jun 23, 2026
1e61c18
Merge pull request #2450 from Ayaanh001/master
theovilardo Jun 23, 2026
c800c1e
fix(library): show home icon in folder breadcrumbs when at root level
Ayaanh001 Jun 23, 2026
8b91d99
Merge pull request #2451 from Ayaanh001/master
theovilardo Jun 23, 2026
dc4f224
Merge feature/localization-ja into master (Japanese localization)
fujimon0722 Jun 24, 2026
fa51e4d
feat(i18n): add missing Japanese translations for About and Volume se…
fujimon0722 Jun 25, 2026
ff6901b
fix(i18n): keep Material 3 Expressive in English in Japanese locale
fujimon0722 Jun 25, 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
17 changes: 17 additions & 0 deletions .idea/appInsightsSettings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions .idea/deploymentTargetSelector.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package com.theveloper.pixelplay.data.repository

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.preferencesDataStoreFile
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.theveloper.pixelplay.data.database.LocalPlaylistDao
import com.theveloper.pixelplay.data.database.PixelPlayDatabase
import com.theveloper.pixelplay.data.preferences.PlaylistPreferencesRepository
import com.theveloper.pixelplay.data.preferences.UserPreferencesRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import kotlinx.serialization.json.Json
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

/**
* Regression test for issue #2391:
* "Playlist song count doesn't update when removing songs — only when adding."
*
* Exercises the real PlaylistPreferencesRepository against an in-memory Room DB to
* verify that the song count exposed by userPlaylistsFlow (used by the Playlists menu)
* reflects removals as well as additions.
*/
@RunWith(AndroidJUnit4::class)
class PlaylistSongCountTest {

private lateinit var db: PixelPlayDatabase
private lateinit var dao: LocalPlaylistDao
private lateinit var dataStore: DataStore<Preferences>
private lateinit var repo: PlaylistPreferencesRepository

@Before
fun setup() {
val context = ApplicationProvider.getApplicationContext<Context>()
db = Room.inMemoryDatabaseBuilder(context, PixelPlayDatabase::class.java)
.addCallback(PixelPlayDatabase.createRuntimeArtifactsCallback())
.allowMainThreadQueries()
.build()
dao = db.localPlaylistDao()
dataStore = PreferenceDataStoreFactory.create {
context.preferencesDataStoreFile("test_settings_${System.nanoTime()}")
}
val userPrefs = UserPreferencesRepository(dataStore, Json { ignoreUnknownKeys = true })
repo = PlaylistPreferencesRepository(dao, userPrefs)
}

@After
fun teardown() {
db.close()
}

private suspend fun countFor(playlistId: String): Int =
repo.userPlaylistsFlow.first().first { it.id == playlistId }.songIds.size

@Test
fun menuSongCount_reflectsAddAndRemove() = runTest {
val playlist = repo.createPlaylist(name = "J-Pop", songIds = listOf("10", "20", "30"))
assertEquals("initial count", 3, countFor(playlist.id))

// Remove a song — the bug report says this does NOT update the count.
repo.removeSongFromPlaylist(playlist.id, "20")
assertEquals("after removing one song", 2, countFor(playlist.id))

// Remove another.
repo.removeSongFromPlaylist(playlist.id, "30")
assertEquals("after removing a second song", 1, countFor(playlist.id))

// Adding works per the report — verify it still does.
repo.addSongsToPlaylist(playlist.id, listOf("40"))
assertEquals("after adding one song", 2, countFor(playlist.id))
}

/**
* Reproduces the real-world trigger for issue #2391: removing several songs in
* quick succession. Each edit does an unsynchronized read-modify-write
* (userPlaylistsFlow.first() -> modify -> updatePlaylist), so concurrent removals
* all read the same original list and the last writer wins, silently dropping the
* other removals. The Playlists-menu count (songIds.size) then stays stuck high.
*/
@Test
fun concurrentRemovals_doNotLoseUpdates() = runBlocking {
val playlist = repo.createPlaylist(
name = "Race",
songIds = listOf("1", "2", "3", "4", "5")
)
assertEquals(5, countFor(playlist.id))

// Remove four songs concurrently — "remove one or two of them", fast.
coroutineScope {
listOf("1", "2", "3", "4").forEach { id ->
launch(Dispatchers.IO) { repo.removeSongFromPlaylist(playlist.id, id) }
}
}

assertEquals("All concurrent removals must persist", 1, countFor(playlist.id))
}

/**
* Walks the exact reproduction from issue #2391, asserting the fixed behaviour:
* the song count stays accurate after a quick removal of "one or two" songs, and
* a later addition does not preserve a phantom difference.
*/
@Test
fun issue2391_quickRemoveThenAdd_keepsCountAccurate() = runBlocking {
// Steps 2-3: create a playlist and add a few songs.
val playlist = repo.createPlaylist(
name = "J-Pop",
songIds = listOf("1", "2", "3", "4", "5", "6")
)
assertEquals(6, countFor(playlist.id))

// Step 4: remove one or two of them — quickly, as fast taps do.
coroutineScope {
launch(Dispatchers.IO) { repo.removeSongFromPlaylist(playlist.id, "2") }
launch(Dispatchers.IO) { repo.removeSongFromPlaylist(playlist.id, "4") }
}
// Step 5: the menu count must reflect BOTH removals (the bug left it stuck high).
assertEquals("count after removing two songs", 4, countFor(playlist.id))

// Steps 6-7: adding more must not carry over a phantom difference.
repo.addSongsToPlaylist(playlist.id, listOf("7", "8"))
assertEquals("count after adding two songs", 6, countFor(playlist.id))
}
}
3 changes: 3 additions & 0 deletions app/src/debug/res/values-de/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">PixelPlayer [D]</string>
<string name="settings_pause_on_volume_zero">Pausieren, wenn Lautstärke null erreicht</string>
<string name="settings_pause_on_volume_zero_desc">Wiedergabe automatisch pausieren, wenn die Lautstärke auf 0 gesetzt wird</string>
<string name="settings_volume_section">Lautstärke</string>
</resources>
3 changes: 3 additions & 0 deletions app/src/debug/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">PixelPlayer [D]</string>
<string name="settings_pause_on_volume_zero">Mettre en pause quand le volume atteint zéro</string>
<string name="settings_pause_on_volume_zero_desc">Mettre automatiquement en pause la lecture lorsque le volume est à 0</string>
<string name="settings_volume_section">Volume</string>
</resources>
3 changes: 3 additions & 0 deletions app/src/debug/res/values-ko/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">PixelPlayer [D]</string>
<string name="settings_pause_on_volume_zero">볼륨이 0이 되면 일시정지</string>
<string name="settings_pause_on_volume_zero_desc">볼륨이 0으로 설정되면 자동으로 재생을 일시정지합니다</string>
<string name="settings_volume_section">볼륨</string>
</resources>
3 changes: 3 additions & 0 deletions app/src/debug/res/values-nb/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">PixelPlayer [D]</string>
<string name="settings_pause_on_volume_zero">Sett på pause når volumet er null</string>
<string name="settings_pause_on_volume_zero_desc">Sett automatisk avspillingen på pause når volumet settes til 0</string>
<string name="settings_volume_section">Volum</string>
</resources>
3 changes: 3 additions & 0 deletions app/src/debug/res/values-ru/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">PixelPlayer [D]</string>
<string name="settings_pause_on_volume_zero">Пауза при нулевой громкости</string>
<string name="settings_pause_on_volume_zero_desc">Автоматически приостанавливать воспроизведение, когда громкость равна 0</string>
<string name="settings_volume_section">Громкость</string>
</resources>
3 changes: 3 additions & 0 deletions app/src/debug/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">PixelPlayer [D]</string>
<string name="settings_pause_on_volume_zero">Pause when volume reaches zero</string>
<string name="settings_pause_on_volume_zero_desc">Automatically pause playback when the volume is set to 0</string>
<string name="settings_volume_section">Volume</string>
</resources>
Loading