react-native-mp3 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/android/build.gradle +111 -0
  2. package/android/src/main/AndroidManifest.xml +44 -0
  3. package/android/src/main/java/com/reactnativemp3/Mp3Package.kt +23 -0
  4. package/android/src/main/java/com/reactnativemp3/Mp3TurboModule.kt +43 -0
  5. package/android/src/main/java/com/reactnativemp3/database/MusicDatabase.kt +48 -0
  6. package/android/src/main/java/com/reactnativemp3/database/dao/SongDao.kt +72 -0
  7. package/android/src/main/java/com/reactnativemp3/database/entities/PlaylistEntity.kt +58 -0
  8. package/android/src/main/java/com/reactnativemp3/database/entities/SongEntity.kt +104 -0
  9. package/android/src/main/java/com/reactnativemp3/database/entities/ThumbnailCacheEntity.kt +43 -0
  10. package/android/src/main/java/com/reactnativemp3/managers/CacheManager.kt +0 -0
  11. package/android/src/main/java/com/reactnativemp3/managers/EqualizerManager.kt +0 -0
  12. package/android/src/main/java/com/reactnativemp3/modules/MetadataModule.kt +330 -0
  13. package/android/src/main/java/com/reactnativemp3/modules/NotificationModule.kt +236 -0
  14. package/android/src/main/java/com/reactnativemp3/modules/PlayerModule.kt +710 -0
  15. package/android/src/main/java/com/reactnativemp3/modules/ScannerModule.kt +640 -0
  16. package/android/src/main/java/com/reactnativemp3/services/AudioFocusService.kt +0 -0
  17. package/android/src/main/java/com/reactnativemp3/services/FileObserverService.kt +0 -0
  18. package/android/src/main/java/com/reactnativemp3/services/MusicService.kt +309 -0
  19. package/android/src/main/java/com/reactnativemp3/utils/MediaStoreUtils.kt +0 -0
  20. package/android/src/main/java/com/reactnativemp3/utils/PermissionUtils.kt +0 -0
  21. package/android/src/main/jni/Mp3TurboModule.cpp +29 -0
  22. package/android/src/main/res/drawable/ic_music_note.xml +11 -0
  23. package/android/src/main/res/drawable/ic_pause.xml +11 -0
  24. package/android/src/main/res/drawable/ic_play.xml +11 -0
  25. package/android/src/main/res/drawable/ic_skip_next.xml +11 -0
  26. package/android/src/main/res/drawable/ic_skip_previous.xml +11 -0
  27. package/android/src/main/res/drawable/ic_stop.xml +11 -0
  28. package/lib/components/MusicList.d.ts +0 -0
  29. package/lib/components/MusicList.js +1 -0
  30. package/lib/components/MusicPlayerUI.d.ts +0 -0
  31. package/lib/components/MusicPlayerUI.js +1 -0
  32. package/lib/hooks/useMusicPlayer.d.ts +38 -0
  33. package/lib/hooks/useMusicPlayer.js +242 -0
  34. package/lib/hooks/useMusicScanner.d.ts +27 -0
  35. package/lib/hooks/useMusicScanner.js +217 -0
  36. package/lib/hooks/usePermissions.d.ts +9 -0
  37. package/lib/hooks/usePermissions.js +55 -0
  38. package/lib/index.d.ts +144 -0
  39. package/lib/index.js +148 -0
  40. package/lib/types/common.types.d.ts +79 -0
  41. package/lib/types/common.types.js +2 -0
  42. package/lib/types/index.d.ts +3 -0
  43. package/lib/types/index.js +2 -0
  44. package/lib/types/player.types.d.ts +35 -0
  45. package/lib/types/player.types.js +2 -0
  46. package/lib/types/scanner.types.d.ts +29 -0
  47. package/lib/types/scanner.types.js +2 -0
  48. package/lib/utils/constants.d.ts +31 -0
  49. package/lib/utils/constants.js +55 -0
  50. package/lib/utils/events.d.ts +0 -0
  51. package/lib/utils/events.js +1 -0
  52. package/package.json +62 -0
  53. package/src/components/MusicList.tsx +0 -0
  54. package/src/components/MusicPlayerUI.tsx +0 -0
  55. package/src/hooks/useMusicPlayer.ts +358 -0
  56. package/src/hooks/useMusicScanner.ts +286 -0
  57. package/src/hooks/usePermissions.ts +64 -0
  58. package/src/index.ts +214 -0
  59. package/src/types/common.types.ts +86 -0
  60. package/src/types/index.ts +4 -0
  61. package/src/types/player.types.ts +37 -0
  62. package/src/types/scanner.types.ts +31 -0
  63. package/src/utils/constants.ts +56 -0
  64. package/src/utils/events.ts +0 -0
@@ -0,0 +1,111 @@
1
+ buildscript {
2
+ ext {
3
+ kotlinVersion = "1.8.0"
4
+ minSdkVersion = 21
5
+ compileSdkVersion = 33
6
+ targetSdkVersion = 33
7
+ roomVersion = "2.5.0"
8
+ }
9
+ repositories {
10
+ google()
11
+ mavenCentral()
12
+ }
13
+ dependencies {
14
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
15
+ }
16
+ }
17
+
18
+ apply plugin: 'com.android.library'
19
+ apply plugin: 'kotlin-android'
20
+ apply plugin: 'kotlin-kapt'
21
+
22
+ android {
23
+ compileSdkVersion rootProject.ext.compileSdkVersion
24
+
25
+ defaultConfig {
26
+ minSdkVersion rootProject.ext.minSdkVersion
27
+ targetSdkVersion rootProject.ext.targetSdkVersion
28
+ versionCode 1
29
+ versionName "1.0"
30
+
31
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
32
+
33
+ if (isNewArchitectureEnabled()) {
34
+ externalNativeBuild {
35
+ ndkBuild {
36
+ arguments "APP_PLATFORM=android-21",
37
+ "APP_STL=c++_shared",
38
+ "NDK_TOOLCHAIN_VERSION=clang",
39
+ "GENERATED_SRC_DIR=$buildDir/generated/source",
40
+ "PROJECT_BUILD_DIR=$buildDir",
41
+ "REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
42
+ "REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build"
43
+ cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
44
+ cppFlags "-std=c++17"
45
+ targets "reactnativemp3"
46
+ }
47
+ }
48
+ }
49
+ }
50
+
51
+ externalNativeBuild {
52
+ ndkBuild {
53
+ path "src/main/jni/Android.mk"
54
+ }
55
+ }
56
+
57
+ buildFeatures {
58
+ buildConfig true
59
+ }
60
+
61
+ sourceSets {
62
+ main {
63
+ if (isNewArchitectureEnabled()) {
64
+ java.srcDirs += ["$buildDir/generated/source/codegen/java"]
65
+ }
66
+ }
67
+ }
68
+
69
+ compileOptions {
70
+ sourceCompatibility JavaVersion.VERSION_1_8
71
+ targetCompatibility JavaVersion.VERSION_1_8
72
+ }
73
+
74
+ kotlinOptions {
75
+ jvmTarget = "1.8"
76
+ }
77
+ }
78
+
79
+ dependencies {
80
+ implementation "com.facebook.react:react-native:+"
81
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
82
+
83
+ // Room Database
84
+ implementation "androidx.room:room-runtime:$roomVersion"
85
+ kapt "androidx.room:room-compiler:$roomVersion"
86
+ implementation "androidx.room:room-ktx:$roomVersion"
87
+
88
+ // Lifecycle components
89
+ implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
90
+ implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.1"
91
+ implementation "androidx.lifecycle:lifecycle-common-java8:2.6.1"
92
+
93
+ // WorkManager for background tasks
94
+ implementation "androidx.work:work-runtime-ktx:2.8.1"
95
+
96
+ // Coroutines
97
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
98
+
99
+ // Media and ExoPlayer for advanced features
100
+ implementation "androidx.media:media:1.6.0"
101
+ implementation "com.google.android.exoplayer:exoplayer-core:2.18.7"
102
+ implementation "com.google.android.exoplayer:exoplayer-ui:2.18.7"
103
+
104
+ // Glide for image loading/caching
105
+ implementation "com.github.bumptech.glide:glide:4.15.1"
106
+ kapt "com.github.bumptech.glide:compiler:4.15.1"
107
+ }
108
+
109
+ def isNewArchitectureEnabled() {
110
+ return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
111
+ }
@@ -0,0 +1,44 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ package="com.reactnativemp3">
4
+
5
+ <!-- Storage Permissions -->
6
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
7
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
8
+ <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
9
+ android:minSdkVersion="30" />
10
+
11
+ <!-- Audio Permissions -->
12
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
13
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
14
+
15
+ <!-- Network Permissions (for online streaming) -->
16
+ <uses-permission android:name="android.permission.INTERNET" />
17
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
18
+
19
+ <application>
20
+ <!-- Music Service for background playback -->
21
+ <service
22
+ android:name=".services.MusicService"
23
+ android:enabled="true"
24
+ android:exported="false"
25
+ android:foregroundServiceType="mediaPlayback">
26
+ <intent-filter>
27
+ <action android:name="android.intent.action.MEDIA_BUTTON" />
28
+ </intent-filter>
29
+ </service>
30
+
31
+ <!-- File Monitoring Service -->
32
+ <service
33
+ android:name=".services.FileObserverService"
34
+ android:enabled="true"
35
+ android:exported="false" />
36
+
37
+ <!-- Broadcast Receiver for Audio Focus -->
38
+ <receiver android:name=".services.AudioFocusReceiver">
39
+ <intent-filter>
40
+ <action android:name="android.media.AUDIO_BECOMING_NOISY" />
41
+ </intent-filter>
42
+ </receiver>
43
+ </application>
44
+ </manifest>
@@ -0,0 +1,23 @@
1
+ package com.reactnativemp3
2
+
3
+ import android.view.View
4
+ import com.facebook.react.ReactPackage
5
+ import com.facebook.react.bridge.NativeModule
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.uimanager.ReactShadowNode
8
+ import com.facebook.react.uimanager.ViewManager
9
+
10
+ class Mp3Package : ReactPackage {
11
+ override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
12
+ return listOf(
13
+ ScannerModule(reactContext),
14
+ PlayerModule(reactContext),
15
+ MetadataModule(reactContext),
16
+ NotificationModule(reactContext)
17
+ )
18
+ }
19
+
20
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<View, ReactShadowNode<*>>> {
21
+ return emptyList()
22
+ }
23
+ }
@@ -0,0 +1,43 @@
1
+ package com.reactnativemp3
2
+
3
+ import com.facebook.jni.HybridData
4
+ import com.facebook.proguard.annotations.DoNotStrip
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.bridge.WritableMap
7
+ import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
8
+ import com.facebook.react.turbomodule.core.interfaces.TurboModule
9
+ import java.lang.ref.WeakReference
10
+
11
+ @DoNotStrip
12
+ abstract class Mp3TurboModule(
13
+ reactContext: ReactApplicationContext,
14
+ moduleName: String
15
+ ) : TurboModule {
16
+
17
+ protected val reactContextRef: WeakReference<ReactApplicationContext> = WeakReference(reactContext)
18
+
19
+ @DoNotStrip
20
+ @Suppress("UNUSED")
21
+ private val mHybridData: HybridData
22
+
23
+ init {
24
+ mHybridData = initHybrid(reactContext.jsCallInvokerHolder as CallInvokerHolderImpl)
25
+ }
26
+
27
+ @DoNotStrip
28
+ private external fun initHybrid(callInvokerHolder: CallInvokerHolderImpl): HybridData
29
+
30
+ override fun getName(): String = moduleName
31
+
32
+ override fun invalidate() {
33
+ mHybridData.resetNative()
34
+ }
35
+
36
+ protected fun getReactApplicationContext(): ReactApplicationContext? {
37
+ return reactContextRef.get()
38
+ }
39
+
40
+ // Helper methods for emitting events to JS
41
+ @DoNotStrip
42
+ protected external fun emitEvent(eventName: String, params: WritableMap?)
43
+ }
@@ -0,0 +1,48 @@
1
+ package com.reactnativemp3.database
2
+
3
+ import android.content.Context
4
+ import androidx.room.Database
5
+ import androidx.room.Room
6
+ import androidx.room.RoomDatabase
7
+ import androidx.room.TypeConverters
8
+ import com.reactnativemp3.database.dao.*
9
+ import com.reactnativemp3.database.entities.*
10
+
11
+ @Database(
12
+ entities = [
13
+ SongEntity::class,
14
+ PlaylistEntity::class,
15
+ PlaylistSongEntity::class,
16
+ ThumbnailCacheEntity::class
17
+ ],
18
+ version = 1,
19
+ exportSchema = true
20
+ )
21
+ @TypeConverters(Converters::class)
22
+ abstract class MusicDatabase : RoomDatabase() {
23
+
24
+ abstract fun songDao(): SongDao
25
+ abstract fun playlistDao(): PlaylistDao
26
+ abstract fun thumbnailCacheDao(): ThumbnailCacheDao
27
+
28
+ companion object {
29
+ @Volatile
30
+ private var INSTANCE: MusicDatabase? = null
31
+
32
+ fun getInstance(context: Context): MusicDatabase {
33
+ return INSTANCE ?: synchronized(this) {
34
+ val instance = Room.databaseBuilder(
35
+ context.applicationContext,
36
+ MusicDatabase::class.java,
37
+ "music_database"
38
+ )
39
+ .addMigrations() // Add migrations here as needed
40
+ .setJournalMode(JournalMode.TRUNCATE)
41
+ .build()
42
+
43
+ INSTANCE = instance
44
+ instance
45
+ }
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,72 @@
1
+ package com.reactnativemp3.database.dao
2
+
3
+ import androidx.room.*
4
+ import com.reactnativemp3.database.entities.SongEntity
5
+ import kotlinx.coroutines.flow.Flow
6
+
7
+ @Dao
8
+ interface SongDao {
9
+
10
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
11
+ suspend fun insert(song: SongEntity)
12
+
13
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
14
+ suspend fun insertAll(songs: List<SongEntity>)
15
+
16
+ @Update
17
+ suspend fun update(song: SongEntity)
18
+
19
+ @Delete
20
+ suspend fun delete(song: SongEntity)
21
+
22
+ @Query("DELETE FROM songs WHERE id = :songId")
23
+ suspend fun deleteById(songId: String)
24
+
25
+ @Query("SELECT * FROM songs WHERE id = :songId")
26
+ suspend fun getById(songId: String): SongEntity?
27
+
28
+ @Query("SELECT * FROM songs ORDER BY title COLLATE NOCASE")
29
+ fun getAllSongs(): Flow<List<SongEntity>>
30
+
31
+ @Query("SELECT * FROM songs ORDER BY date_added DESC")
32
+ fun getRecentlyAdded(): Flow<List<SongEntity>>
33
+
34
+ @Query("SELECT * FROM songs WHERE last_played IS NOT NULL ORDER BY last_played DESC")
35
+ fun getRecentlyPlayed(): Flow<List<SongEntity>>
36
+
37
+ @Query("SELECT * FROM songs WHERE is_favorite = 1 ORDER BY title COLLATE NOCASE")
38
+ fun getFavorites(): Flow<List<SongEntity>>
39
+
40
+ @Query("SELECT * FROM songs WHERE album = :album ORDER BY track_number, title")
41
+ fun getSongsByAlbum(album: String): Flow<List<SongEntity>>
42
+
43
+ @Query("SELECT DISTINCT album FROM songs WHERE album IS NOT NULL AND album != '' ORDER BY album COLLATE NOCASE")
44
+ fun getAllAlbums(): Flow<List<String>>
45
+
46
+ @Query("SELECT DISTINCT artist FROM songs WHERE artist IS NOT NULL AND artist != '' ORDER BY artist COLLATE NOCASE")
47
+ fun getAllArtists(): Flow<List<String>>
48
+
49
+ @Query("SELECT DISTINCT genre FROM songs WHERE genre IS NOT NULL AND genre != '' ORDER BY genre COLLATE NOCASE")
50
+ fun getAllGenres(): Flow<List<String>>
51
+
52
+ @Query("SELECT COUNT(*) FROM songs")
53
+ suspend fun getCount(): Int
54
+
55
+ @Query("SELECT * FROM songs WHERE title LIKE :query OR artist LIKE :query OR album LIKE :query")
56
+ fun search(query: String): Flow<List<SongEntity>>
57
+
58
+ @Query("UPDATE songs SET play_count = play_count + 1, last_played = :timestamp WHERE id = :songId")
59
+ suspend fun incrementPlayCount(songId: String, timestamp: Long)
60
+
61
+ @Query("UPDATE songs SET is_favorite = :isFavorite WHERE id = :songId")
62
+ suspend fun setFavorite(songId: String, isFavorite: Boolean)
63
+
64
+ @Query("UPDATE songs SET bookmark = :position WHERE id = :songId")
65
+ suspend fun setBookmark(songId: String, position: Long)
66
+
67
+ @Query("SELECT * FROM songs WHERE path = :filePath")
68
+ suspend fun getByPath(filePath: String): SongEntity?
69
+
70
+ @Query("DELETE FROM songs WHERE path = :filePath")
71
+ suspend fun deleteByPath(filePath: String)
72
+ }
@@ -0,0 +1,58 @@
1
+ package com.reactnativemp3.database.entities
2
+
3
+ import androidx.room.*
4
+
5
+ @Entity(
6
+ tableName = "playlists",
7
+ indices = [Index(value = ["name"], unique = true)]
8
+ )
9
+ data class PlaylistEntity(
10
+ @PrimaryKey(autoGenerate = true)
11
+ @ColumnInfo(name = "id")
12
+ val id: Long = 0,
13
+
14
+ @ColumnInfo(name = "name")
15
+ val name: String,
16
+
17
+ @ColumnInfo(name = "created_at")
18
+ val createdAt: Long = System.currentTimeMillis(),
19
+
20
+ @ColumnInfo(name = "song_count")
21
+ val songCount: Int = 0,
22
+
23
+ @ColumnInfo(name = "thumbnail_uri")
24
+ val thumbnailUri: String? = null
25
+ )
26
+
27
+ @Entity(
28
+ tableName = "playlist_songs",
29
+ primaryKeys = ["playlist_id", "song_id"],
30
+ foreignKeys = [
31
+ ForeignKey(
32
+ entity = PlaylistEntity::class,
33
+ parentColumns = ["id"],
34
+ childColumns = ["playlist_id"],
35
+ onDelete = ForeignKey.CASCADE
36
+ ),
37
+ ForeignKey(
38
+ entity = SongEntity::class,
39
+ parentColumns = ["id"],
40
+ childColumns = ["song_id"],
41
+ onDelete = ForeignKey.CASCADE
42
+ )
43
+ ],
44
+ indices = [
45
+ Index(value = ["playlist_id"]),
46
+ Index(value = ["song_id"])
47
+ ]
48
+ )
49
+ data class PlaylistSongEntity(
50
+ @ColumnInfo(name = "playlist_id")
51
+ val playlistId: Long,
52
+
53
+ @ColumnInfo(name = "song_id")
54
+ val songId: String,
55
+
56
+ @ColumnInfo(name = "position")
57
+ val position: Int
58
+ )
@@ -0,0 +1,104 @@
1
+ package com.reactnativemp3.database.entities
2
+
3
+ import androidx.room.ColumnInfo
4
+ import androidx.room.Entity
5
+ import androidx.room.Index
6
+ import androidx.room.PrimaryKey
7
+ import java.util.*
8
+
9
+ @Entity(
10
+ tableName = "songs",
11
+ indices = [
12
+ Index(value = ["title"]),
13
+ Index(value = ["artist"]),
14
+ Index(value = ["album"]),
15
+ Index(value = ["date_added"], orders = [Index.Order.DESC]),
16
+ Index(value = ["last_played"], orders = [Index.Order.DESC])
17
+ ]
18
+ )
19
+ data class SongEntity(
20
+ @PrimaryKey
21
+ @ColumnInfo(name = "id")
22
+ val id: String,
23
+
24
+ @ColumnInfo(name = "title")
25
+ val title: String,
26
+
27
+ @ColumnInfo(name = "artist")
28
+ val artist: String = "Unknown Artist",
29
+
30
+ @ColumnInfo(name = "album")
31
+ val album: String = "Unknown Album",
32
+
33
+ @ColumnInfo(name = "duration")
34
+ val duration: Long,
35
+
36
+ @ColumnInfo(name = "path")
37
+ val path: String,
38
+
39
+ @ColumnInfo(name = "uri")
40
+ val uri: String,
41
+
42
+ @ColumnInfo(name = "album_art_uri")
43
+ val albumArtUri: String?,
44
+
45
+ @ColumnInfo(name = "size")
46
+ val size: Long,
47
+
48
+ @ColumnInfo(name = "mime_type")
49
+ val mimeType: String,
50
+
51
+ @ColumnInfo(name = "track_number")
52
+ val trackNumber: Int = 0,
53
+
54
+ @ColumnInfo(name = "year")
55
+ val year: Int? = null,
56
+
57
+ @ColumnInfo(name = "genre")
58
+ val genre: String? = null,
59
+
60
+ @ColumnInfo(name = "date_added")
61
+ val dateAdded: Long,
62
+
63
+ @ColumnInfo(name = "last_modified")
64
+ val lastModified: Long,
65
+
66
+ @ColumnInfo(name = "is_favorite")
67
+ val isFavorite: Boolean = false,
68
+
69
+ @ColumnInfo(name = "play_count")
70
+ val playCount: Int = 0,
71
+
72
+ @ColumnInfo(name = "last_played")
73
+ val lastPlayed: Long? = null,
74
+
75
+ @ColumnInfo(name = "bitrate")
76
+ val bitrate: Int? = null,
77
+
78
+ @ColumnInfo(name = "sample_rate")
79
+ val sampleRate: Int? = null,
80
+
81
+ @ColumnInfo(name = "channels")
82
+ val channels: Int? = null,
83
+
84
+ @ColumnInfo(name = "composer")
85
+ val composer: String? = null,
86
+
87
+ @ColumnInfo(name = "lyrics")
88
+ val lyrics: String? = null,
89
+
90
+ @ColumnInfo(name = "rating")
91
+ val rating: Int? = null,
92
+
93
+ @ColumnInfo(name = "is_podcast")
94
+ val isPodcast: Boolean = false,
95
+
96
+ @ColumnInfo(name = "bookmark")
97
+ val bookmark: Long = 0
98
+ ) {
99
+ companion object {
100
+ fun generateId(path: String): String {
101
+ return UUID.nameUUIDFromBytes(path.toByteArray()).toString()
102
+ }
103
+ }
104
+ }
@@ -0,0 +1,43 @@
1
+ package com.reactnativemp3.database.entities
2
+
3
+ import androidx.room.ColumnInfo
4
+ import androidx.room.Entity
5
+ import androidx.room.PrimaryKey
6
+
7
+ @Entity(tableName = "thumbnail_cache")
8
+ data class ThumbnailCacheEntity(
9
+ @PrimaryKey
10
+ @ColumnInfo(name = "song_id")
11
+ val songId: String,
12
+
13
+ @ColumnInfo(name = "thumbnail_data")
14
+ val thumbnailData: ByteArray,
15
+
16
+ @ColumnInfo(name = "last_accessed")
17
+ val lastAccessed: Long = System.currentTimeMillis(),
18
+
19
+ @ColumnInfo(name = "size")
20
+ val size: Int
21
+ ) {
22
+ override fun equals(other: Any?): Boolean {
23
+ if (this === other) return true
24
+ if (javaClass != other?.javaClass) return false
25
+
26
+ other as ThumbnailCacheEntity
27
+
28
+ if (songId != other.songId) return false
29
+ if (!thumbnailData.contentEquals(other.thumbnailData)) return false
30
+ if (lastAccessed != other.lastAccessed) return false
31
+ if (size != other.size) return false
32
+
33
+ return true
34
+ }
35
+
36
+ override fun hashCode(): Int {
37
+ var result = songId.hashCode()
38
+ result = 31 * result + thumbnailData.contentHashCode()
39
+ result = 31 * result + lastAccessed.hashCode()
40
+ result = 31 * result + size
41
+ return result
42
+ }
43
+ }