Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
c0063e7
feat: add Arabic language support and restructure localized strings f…
adlifarizi Jun 13, 2026
77ca1d8
feat: add version 0.7.5 changelog entries and refine Indonesia transl…
adlifarizi Jun 13, 2026
c581610
refactor: replace language string resources with native names in AppL…
adlifarizi Jun 13, 2026
5bca974
feat(i18n): init pt-BR localization
retrozinndev Jun 14, 2026
a3335e2
Feat: the opt for tablet on StartPage
ZL114514 Jun 14, 2026
9e0d181
fix: clean the unstashed conflict
ZL114514 Jun 14, 2026
919a4f4
Update PlaylistContainer.kt
ZL114514 Jun 14, 2026
5e00b0b
feat: NavigationRail for tablet
ZL114514 Jun 15, 2026
e26ee58
feat: predictive back animation handler
ZL114514 Jun 15, 2026
13fab2a
opt: add padding animation back handler
ZL114514 Jun 15, 2026
c5e92a8
feat(removing library tabs): implement customizable tab management (a…
Ayaanh001 Jun 15, 2026
61ea819
minor fix
Ayaanh001 Jun 15, 2026
ca21993
Remove old Arabic translation
Hisham-Alzamzami Jun 17, 2026
358702f
Add Arabic localization for app strings
Hisham-Alzamzami Jun 17, 2026
266e466
Add new Arabic translation
Hisham-Alzamzami Jun 17, 2026
374395f
Merge branch 'PixelPlayerHQ:master' into master
Hisham-Alzamzami Jun 17, 2026
e899976
Add Arabic language support to AppLanguage
Hisham-Alzamzami Jun 17, 2026
f534598
Add Arabic language support to settings
Hisham-Alzamzami Jun 17, 2026
4bec3e7
feat: home screen box column
ZL114514 Jun 17, 2026
0113217
Merge branch 'PixelPlayerHQ:master' into master
Hisham-Alzamzami Jun 18, 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
b93d644
chore(deps): bump com.google.genai:google-genai
dependabot[bot] Jun 18, 2026
bb898f3
chore(deps): bump actions/checkout in the github-actions group
dependabot[bot] Jun 18, 2026
dcf2291
chore(deps): bump com.google.genai:google-genai
dependabot[bot] Jun 18, 2026
941f55d
Merge branch 'PixelPlayerHQ:master' into master
Hisham-Alzamzami Jun 19, 2026
9a262d9
Security hardening, error handling, AI client refactoring, test coverage
daedaevibin Jun 19, 2026
478d795
Fix JVM signature clash: rename defaultModel to providerDefaultModel
daedaevibin Jun 19, 2026
fbcb734
Merge pull request #39 from Veridian-Zenith/dependabot/github_actions…
daedaevibin Jun 19, 2026
a512452
Merge pull request #40 from Veridian-Zenith/dependabot/gradle/gradle-…
daedaevibin Jun 19, 2026
801d9ae
Additional quality, security, and performance improvements
daedaevibin Jun 19, 2026
b568ba3
Fix Netty version, parameter ordering, imports, and Spanish comments
daedaevibin Jun 19, 2026
fa3da6e
Merge pull request #41 from Veridian-Zenith/devin/1781834472-security…
daedaevibin Jun 19, 2026
8e0a8af
Merge upstream PR #2347: Update Strings to show beta 7.5
daedaevibin Jun 19, 2026
9a58434
Merge upstream PR #2352: Restructure Arabic localization resources
daedaevibin Jun 19, 2026
40359d1
Merge upstream PR #2353: Update French lyrics mode strings for consis…
daedaevibin Jun 19, 2026
e6b5616
Merge upstream PR #2355: feat(i18n): add pt-BR localization
daedaevibin Jun 19, 2026
9ab7507
Merge upstream PR #2363: Feat: the opt for tablet
daedaevibin Jun 19, 2026
71fa324
Merge upstream PR #2371: feat(ai): massive architecture overhaul, new…
daedaevibin Jun 19, 2026
459c648
Merge upstream PR #2373: feat(removing library tabs): implement custo…
daedaevibin Jun 19, 2026
e2f9e29
Merge upstream PR #2380: feat: Add complete Arabic translation and co…
daedaevibin Jun 19, 2026
33be37f
Merge upstream PR #2383: ui: fix layout jump when collapsing telegram…
daedaevibin Jun 19, 2026
6827738
Merge upstream PR #2396: Feature/localization ja (Japanese)
daedaevibin Jun 19, 2026
07afb84
Merge upstream PR #2397: chore(deps): bump com.google.genai:google-ge…
daedaevibin Jun 19, 2026
a04999a
Merge upstream PR #2400: fix(playlists): prevent lost playlist edits …
daedaevibin Jun 19, 2026
664fd91
Merge origin/master: resolve AI client conflicts with upstream #2371
daedaevibin Jun 19, 2026
36361c7
fix(i18n): rename values-pt-BR to values-pt-rBR for Android resource …
daedaevibin Jun 19, 2026
94c360d
Merge pull request #42 from Veridian-Zenith/devin/1781837668-consolid…
daedaevibin Jun 19, 2026
d57a233
feat: Added a frosted glass effect; added an option to hide the lyric…
shiqizhenyes Jun 19, 2026
60a2acd
Merge remote-tracking branch 'origin/master'
shiqizhenyes Jun 19, 2026
3c8ad29
chore(deps): bump gradle-wrapper in the gradle-dependencies group
dependabot[bot] Jun 19, 2026
3ccf221
Merge pull request #43 from Veridian-Zenith/dependabot/gradle/gradle-…
daedaevibin Jun 20, 2026
501f2b8
Merge PR #2413 and resolve conflicts in CloudMusicUtilsTest
daedaevibin Jun 20, 2026
f61c438
Merge PR #2415 and resolve conflicts in strings_settings.xml (Arabic)
daedaevibin Jun 20, 2026
3867cb4
Enabled CodeQL caching and added --no-build-cache to prevent stale ca…
daedaevibin Jun 20, 2026
f45533d
feat: Improve Gaussian blur and introduce music-synced EQ animation
shiqizhenyes Jun 20, 2026
e8fa3c3
fix(ui): resolve EQ visualizer freeze and optimize rendering
shiqizhenyes Jun 21, 2026
c7002f4
Merge branch 'pr-2415'
daedaevibin Jun 21, 2026
2dadfd1
Merge branch 'pr-2371'
daedaevibin Jun 21, 2026
fa3c639
Merge PR 2425 and resolve conflicts
daedaevibin Jun 21, 2026
e1b0f5c
chore: sync with upstream pull requests
daedaevibin Jun 21, 2026
62d8e80
Merge remote-tracking branch 'upstream/master'
daedaevibin Jun 22, 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
5 changes: 3 additions & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Set up JDK 21
uses: actions/setup-java@v5
Expand All @@ -47,9 +47,10 @@ jobs:
with:
languages: java-kotlin
build-mode: manual
cache: true

- name: Build with Gradle
run: ${{ github.workspace }}/gradlew :app:assembleDebug :wear:assembleDebug --no-daemon
run: ${{ github.workspace }}/gradlew :app:assembleDebug :wear:assembleDebug --no-daemon --no-build-cache

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly-apk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Set up JDK 21
uses: actions/setup-java@v5
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/phone-debug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Set up JDK 21
uses: actions/setup-java@v5
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/phone-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Set up JDK 21
uses: actions/setup-java@v5
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/wearos-apk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Set up JDK 21
uses: actions/setup-java@v5
Expand Down
29 changes: 0 additions & 29 deletions .idea/deploymentTargetSelector.xml

This file was deleted.

4 changes: 4 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ dependencies {
implementation(libs.androidx.media3.exoplayer.ffmpeg)
implementation(libs.androidx.media3.exoplayer.midi)
implementation(libs.androidx.media3.transformer)
implementation(libs.androidx.media3.common)
implementation(libs.androidx.media3.common.ktx)
implementation(libs.androidx.mediarouter)
implementation(libs.androidx.media)
implementation(libs.coil.compose)
Expand Down Expand Up @@ -298,6 +300,8 @@ dependencies {
exclude(group = "androidx.compose.runtime")
exclude(group = "androidx.compose.ui")
}
implementation(libs.haze)
implementation(libs.haze.materials)

// Projects
implementation(project(":shared"))
Expand Down
201 changes: 172 additions & 29 deletions app/src/main/java/com/theveloper/pixelplay/MainActivity.kt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.theveloper.pixelplay.data.backup
import android.content.Context
import android.net.Uri
import android.os.Build
import timber.log.Timber
import com.theveloper.pixelplay.data.backup.format.BackupReader
import com.theveloper.pixelplay.data.backup.format.BackupWriter
import com.theveloper.pixelplay.data.backup.history.BackupHistoryRepository
Expand Down Expand Up @@ -66,7 +67,7 @@ class BackupManager @Inject constructor(
// Build manifest
val packageInfo = try {
context.packageManager.getPackageInfo(context.packageName, 0)
} catch (_: Exception) { null }
} catch (e: Exception) { Timber.w(e, "Failed to get package info"); null }

val manifest = BackupManifest(
schemaVersion = BackupManifest.CURRENT_SCHEMA_VERSION,
Expand Down Expand Up @@ -183,8 +184,8 @@ class BackupManager @Inject constructor(
appVersion = plan.manifest.appVersion
)
)
} catch (_: Exception) {
// Non-critical; don't fail restore because of history persistence
} catch (e: Exception) {
Timber.w(e, "Failed to persist restore history entry")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.net.Uri
import com.google.gson.Gson
import com.theveloper.pixelplay.data.backup.model.BackupManifest
import com.theveloper.pixelplay.data.backup.model.BackupModuleInfo
import timber.log.Timber
import com.theveloper.pixelplay.di.BackupGson
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -85,7 +86,8 @@ class BackupWriter @Inject constructor(
} else {
1
}
} catch (_: Exception) {
} catch (e: Exception) {
Timber.w(e, "Failed to count items in backup module JSON")
0
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.google.gson.Gson
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import timber.log.Timber
import com.theveloper.pixelplay.data.backup.model.BackupManifest
import com.theveloper.pixelplay.data.backup.model.BackupModuleInfo
import com.theveloper.pixelplay.data.backup.model.DeviceInfo
Expand Down Expand Up @@ -120,7 +121,7 @@ class LegacyPayloadAdapter @Inject constructor() {
} else {
1
}
} catch (_: Exception) { 0 }
} catch (e: Exception) { Timber.w(e, "Failed to count legacy backup entries"); 0 }
}

private fun sha256(data: ByteArray): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.theveloper.pixelplay.data.backup.model.BackupHistoryEntry
import com.theveloper.pixelplay.di.BackupGson
import timber.log.Timber
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject
Expand All @@ -30,7 +31,8 @@ class BackupHistoryRepository @Inject constructor(
if (json != null) {
try {
gson.fromJson<List<BackupHistoryEntry>>(json, listType)
} catch (_: Exception) {
} catch (e: Exception) {
Timber.w(e, "Failed to parse backup history")
emptyList()
}
} else {
Expand Down Expand Up @@ -68,7 +70,8 @@ class BackupHistoryRepository @Inject constructor(
val json = preferences[BACKUP_HISTORY_KEY] ?: return emptyList()
return try {
gson.fromJson(json, listType)
} catch (_: Exception) {
} catch (e: Exception) {
Timber.w(e, "Failed to read backup history")
emptyList()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.theveloper.pixelplay.data.database
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import timber.log.Timber
import androidx.sqlite.db.SupportSQLiteDatabase

@Database(
Expand Down Expand Up @@ -759,9 +760,8 @@ abstract class PixelPlayDatabase : RoomDatabase() {

try {
db.execSQL("ALTER TABLE songs ADD COLUMN date_added INTEGER NOT NULL DEFAULT 0")
} catch (_: Exception) {
// Some restored databases report the right version but still carry
// a drifted songs table. If ALTER TABLE did not stick, rebuild it.
} catch (e: Exception) {
Timber.w(e, "ALTER TABLE songs ADD date_added failed; will recreate table")
}

if ("date_added" !in getTableColumns(db, "songs")) {
Expand Down Expand Up @@ -1133,8 +1133,8 @@ abstract class PixelPlayDatabase : RoomDatabase() {
if ("disc_number" !in columns) {
try {
db.execSQL("ALTER TABLE songs ADD COLUMN disc_number INTEGER DEFAULT null")
} catch (_: Exception) {
// Restored/drifted databases may already contain a partially applied column.
} catch (e: Exception) {
Timber.w(e, "ALTER TABLE songs ADD disc_number failed; may already exist")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.theveloper.pixelplay.data.database
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import timber.log.Timber
import androidx.room.Index
import androidx.room.PrimaryKey
import com.theveloper.pixelplay.data.model.ArtistRef
Expand Down Expand Up @@ -57,15 +58,13 @@ object SourceType {
entity = AlbumEntity::class,
parentColumns = ["id"],
childColumns = ["album_id"],
onDelete = ForeignKey.CASCADE // Si un álbum se borra, sus canciones también
onDelete = ForeignKey.CASCADE // Deleting an album cascades to its songs
),
ForeignKey(
entity = ArtistEntity::class,
parentColumns = ["id"],
childColumns = ["artist_id"],
onDelete = ForeignKey.SET_NULL // Si un artista se borra, el artist_id de la canción se pone a null
// o podrías elegir CASCADE si las canciones no deben existir sin artista.
// SET_NULL es más flexible si las canciones pueden ser de "Artista Desconocido".
onDelete = ForeignKey.SET_NULL // Nullify artist_id when artist is deleted (keeps song as "Unknown Artist")
)
]
)
Expand All @@ -76,7 +75,7 @@ data class SongEntity(
@ColumnInfo(name = "artist_id") val artistId: Long, // Primary artist ID for backward compatibility
@ColumnInfo(name = "album_artist") val albumArtist: String? = null, // Album artist from metadata
@ColumnInfo(name = "album_name") val albumName: String,
@ColumnInfo(name = "album_id") val albumId: Long, // index = true eliminado
@ColumnInfo(name = "album_id") val albumId: Long,
@ColumnInfo(name = "content_uri_string") val contentUriString: String,
@ColumnInfo(name = "album_art_uri_string") val albumArtUriString: String?,
@ColumnInfo(name = "duration") val duration: Long,
Expand Down Expand Up @@ -171,7 +170,8 @@ private fun parseArtistsJson(json: String?): List<ArtistRef> {
isPrimary = obj.optBoolean("primary", false)
)
}
} catch (_: Exception) {
} catch (e: Exception) {
Timber.w(e, "Failed to parse artist refs JSON")
emptyList()
}
}
Expand Down Expand Up @@ -212,9 +212,8 @@ fun List<SongEntity>.toSongs(): List<Song> {
return this.map { it.toSong() }
}

// El modelo Song usa id como String, pero la entidad lo necesita como Long (de MediaStore)
// El modelo Song no tiene filePath, así que no se puede mapear desde ahí directamente.
// filePath y parentDirectoryPath se poblarán desde MediaStore en el SyncWorker.
// Song model uses String id but the entity needs Long (from MediaStore).
// filePath and parentDirectoryPath are populated from MediaStore in SyncWorker.
fun Song.toEntity(filePathFromMediaStore: String, parentDirFromMediaStore: String): SongEntity {
return SongEntity(
id = this.id.toLong(),
Expand Down Expand Up @@ -252,8 +251,7 @@ data class SongSummary(
val duration: Long
)

// Sobrecarga o alternativa si los paths no están disponibles o no son necesarios al convertir de Modelo a Entidad
// (menos probable que se use si la entidad siempre requiere los paths)
// Fallback when file paths are unavailable during Song-to-Entity conversion.
fun Song.toEntityWithoutPaths(): SongEntity {
return SongEntity(
id = this.id.toLong(),
Expand Down
Loading
Loading