Added base

This commit is contained in:
h4h13 2019-12-20 00:25:41 +05:30
parent 598364b8e0
commit 98fd663e25
11 changed files with 258 additions and 53 deletions

View file

@ -116,22 +116,22 @@ dependencies {
implementation "androidx.palette:palette:1.0.0"
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.preference:preference:1.1.0'
implementation 'androidx.palette:palette-ktx:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'com.google.android.material:material:1.2.0-alpha01'
implementation 'com.google.android.play:core:1.6.4'
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.2'
def retrofit_version = "2.6.2"
implementation "com.squareup.retrofit2:retrofit:${retrofit_version}"
implementation "com.squareup.retrofit2:converter-gson:${retrofit_version}"
implementation "com.squareup.retrofit2:adapter-rxjava2:${retrofit_version}"
implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
implementation 'com.afollestad.material-dialogs:core:3.1.1'
implementation 'com.afollestad.material-dialogs:input:3.1.1'
implementation 'com.afollestad.material-dialogs:color:3.1.1'
implementation 'com.afollestad.material-dialogs:bottomsheets:3.1.1'
def material_dialog_version = "3.1.1"
implementation "com.afollestad.material-dialogs:core:${material_dialog_version}"
implementation "com.afollestad.material-dialogs:input:${material_dialog_version}"
implementation "com.afollestad.material-dialogs:color:${material_dialog_version}"
implementation "com.afollestad.material-dialogs:bottomsheets:${material_dialog_version}"
implementation 'com.afollestad:material-cab:0.1.12'
@ -150,8 +150,12 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1"
implementation 'androidx.palette:palette-ktx:1.0.0'
implementation 'androidx.core:core-ktx:1.1.0'
def kotlin_coroutines_version = "1.3.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${kotlin_coroutines_version}"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${kotlin_coroutines_version}"
implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:3.4.0.201406110918-r'
@ -165,8 +169,13 @@ dependencies {
implementation 'com.r0adkll:slidableactivity:2.1.0'
implementation 'com.heinrichreimersoftware:material-intro:1.6'
implementation 'com.google.dagger:dagger:2.23.1'
kapt 'com.google.dagger:dagger-compiler:2.23.1'
def dagger_version = "2.23.1"
implementation "com.google.dagger:dagger:${dagger_version}"
kapt "com.google.dagger:dagger-compiler:${dagger_version}"
def room_version = "2.2.3"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
}

View file

@ -31,9 +31,6 @@ class App : MultiDexApplication() {
lateinit var billingProcessor: BillingProcessor
override fun onCreate() {
/* if (MissingSplitsManagerFactory.create(this).disableAppIfMissingRequiredSplits()) {
return
}*/
super.onCreate()
instance = this
musicComponent = DaggerMusicComponent.builder()

View file

@ -14,22 +14,33 @@
package code.name.monkey.retromusic.model
import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.android.parcel.Parcelize
@Entity(tableName = "songs")
@Parcelize
open class Song(
val id: Int,
val title: String,
val trackNumber: Int,
val year: Int,
val duration: Long,
val data: String,
val dateModified: Long,
val albumId: Int,
val albumName: String,
val artistId: Int,
val artistName: String,
val composer: String?
@PrimaryKey
val id: Int = -1,
val title: String = "",
@ColumnInfo(name = "track_number")
val trackNumber: Int = -1,
val year: Int = -1,
val duration: Long = -1,
val data: String = "",
@ColumnInfo(name = "date_modified")
val dateModified: Long = -1,
@ColumnInfo(name = "album_id")
val albumId: Int = -1,
@ColumnInfo(name = "album_name")
val albumName: String = "",
@ColumnInfo(name = "artist_id")
val artistId: Int = -1,
@ColumnInfo(name = "artist_name")
val artistName: String = "",
val composer: String? = ""
) : Parcelable {

View file

@ -16,7 +16,8 @@ package code.name.monkey.retromusic.mvp.presenter
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.mvp.*
import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository
import kotlinx.coroutines.*
import java.util.*
@ -27,36 +28,38 @@ import kotlin.coroutines.CoroutineContext
* Created by hemanths on 10/08/17.
*/
interface SongView {
fun songs(songs: ArrayList<Song>)
fun songs(songs: ArrayList<Song>)
fun showEmptyView()
fun showEmptyView()
}
interface SongPresenter : Presenter<SongView> {
fun loadSongs()
class SongPresenterImpl @Inject constructor(
private val repository: Repository
) : PresenterImpl<SongView>(), SongPresenter, CoroutineScope {
fun loadSongs()
class SongPresenterImpl @Inject constructor(
private val repository: Repository
) : PresenterImpl<SongView>(), SongPresenter, CoroutineScope {
private var job: Job = Job()
private var job: Job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
override fun loadSongs() {
launch {
when (val songs = repository.allSongs()) {
is Result.Success -> withContext(Dispatchers.Main) { view?.songs(songs.data) }
is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
}
}
}
override fun loadSongs() {
launch {
val temp = repository.playlistEntities()
println("Playlists ${temp.size}")
when (val songs = repository.allSongs()) {
is Result.Success -> withContext(Dispatchers.Main) { view?.songs(songs.data) }
is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
}
}
}
override fun detachView() {
super.detachView()
job.cancel();
}
}
override fun detachView() {
super.detachView()
job.cancel();
}
}
}

View file

@ -25,12 +25,19 @@ import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.providers.interfaces.Repository
import code.name.monkey.retromusic.rest.LastFMRestClient
import code.name.monkey.retromusic.rest.model.LastFmArtist
import code.name.monkey.retromusic.room.PlaylistEntity
import code.name.monkey.retromusic.room.PlaylistEntityRepository
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import java.io.IOException
class RepositoryImpl(private val context: Context) : Repository {
private val playlistEntityRepository: PlaylistEntityRepository = PlaylistEntityRepository(context)
fun insertSong(song: Song) {
playlistEntityRepository.insertSong(song)
}
override suspend fun allAlbums(): Result<ArrayList<Album>> {
return try {
@ -247,6 +254,10 @@ class RepositoryImpl(private val context: Context) : Repository {
}
}
override suspend fun playlistEntities(): List<PlaylistEntity> {
return playlistEntityRepository.playlistEntries()
}
override fun getAlbumFlowable(albumId: Int): Observable<Album> {
return AlbumLoader.getAlbumFlowable(context, albumId)
.subscribeOn(Schedulers.io())

View file

@ -17,6 +17,7 @@ package code.name.monkey.retromusic.providers.interfaces
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.rest.model.LastFmArtist
import code.name.monkey.retromusic.room.PlaylistEntity
import io.reactivex.Observable
/**
@ -55,6 +56,8 @@ interface Repository {
suspend fun artistById(artistId: Int): Result<Artist>
suspend fun playlistEntities(): List<PlaylistEntity>
fun getSong(id: Int): Song
fun getAlbumFlowable(albumId: Int): Observable<Album>

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2019 Hemanth Savarala.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
package code.name.monkey.retromusic.room
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import code.name.monkey.retromusic.model.Song
/**
* Created by hemanths on 2019-12-19.
*/
@Dao
interface PlaylistDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertSongs(songs: List<Song>)
@Insert
suspend fun insertSong(song: Song)
@Query("SELECT * FROM playlist_entity ORDER BY playlist_name ASC")
suspend fun playlistEntities(): List<PlaylistEntity>
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2019 Hemanth Savarala.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
package code.name.monkey.retromusic.room
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import code.name.monkey.retromusic.model.Song
/**
* Created by hemanths on 2019-12-19.
*/
@Database(entities = [PlaylistEntity::class, Song::class], version = 1, exportSchema = false)
abstract class PlaylistDatabase : RoomDatabase() {
abstract fun playlistDao(): PlaylistDao
companion object {
@Volatile
private var INSTANCE: PlaylistDatabase? = null
fun getInstance(context: Context): PlaylistDatabase {
val tempInstance = INSTANCE
if (tempInstance != null) {
return tempInstance
}
synchronized(PlaylistDatabase::class) {
val instance = Room.databaseBuilder(context.applicationContext, PlaylistDatabase::class.java, "playlist_database").build()
INSTANCE = instance
return instance
}
}
}
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2019 Hemanth Savarala.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
package code.name.monkey.retromusic.room
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import code.name.monkey.retromusic.model.Song
/**
* Created by hemanths on 2019-12-19.
*/
@Entity(tableName = "playlist_entity")
data class PlaylistEntity(
@PrimaryKey(autoGenerate = false)
@ColumnInfo(name = "playlist_name")
val playlistName: String,
@ColumnInfo(name = "playlist_songs")
val songs: List<Song> = listOf()
)

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2019 Hemanth Savarala.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
package code.name.monkey.retromusic.room
import android.content.Context
import code.name.monkey.retromusic.model.Song
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.coroutines.CoroutineContext
/**
* Created by hemanths on 2019-12-19.
*/
class PlaylistEntityRepository(context: Context) : CoroutineScope {
private var playlistDatabase: PlaylistDatabase = PlaylistDatabase.getInstance(context)
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO
fun playlistEntries(): List<PlaylistEntity> = runBlocking {
playlistDatabase.playlistDao().playlistEntities()
}
fun insertSongs(songs: List<Song>) {
launch {
playlistDatabase.playlistDao().insertSongs(songs)
}
}
fun insertSong(song: Song) {
launch {
playlistDatabase.playlistDao().insertSong(song)
}
}
}

View file

@ -9,7 +9,6 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.5.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.android.tools.build:bundletool:0.9.0'
}
}