Skip to content

Commit

Permalink
Merge pull request #220 from 07jasjeet/feed-section-phase-2.3
Browse files Browse the repository at this point in the history
Feed section phase 2.3 Part 1
  • Loading branch information
akshaaatt committed Aug 15, 2023
2 parents a20075c + 9688bc4 commit e692c8b
Show file tree
Hide file tree
Showing 28 changed files with 739 additions and 247 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Expand Up @@ -204,6 +204,7 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
testImplementation 'com.squareup.okhttp3:mockwebserver:5.0.0-alpha.11'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
testImplementation 'androidx.arch.core:core-testing:2.2.0'

// Mockito framework
testImplementation "org.mockito:mockito-core:5.3.1"
Expand All @@ -217,6 +218,7 @@ dependencies {
androidTestImplementation platform('androidx.compose:compose-bom:2023.03.00')
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
androidTestImplementation "androidx.work:work-testing:$work_version"
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.arch.core:core-testing:2.2.0'
Expand Down
Expand Up @@ -62,40 +62,34 @@ class YearInMusicActivityTest {
}

rule.onNodeWithText("Top Albums of 2022").assertExists()
nextPage()
nextPage(scrollToEnd = false)

verifyExistence(R.string.tt_yim_charts_heading)
scrollToEnd(R.string.tt_yim_charts_parent)
nextPage()

verifyExistence(R.string.tt_yim_statistics_heading)
nextPage()

verifyExistence(R.string.tt_yim_recommended_playlists_heading)
scrollToEnd(R.string.tt_yim_recommended_playlists_parent)
scrollToEnd(R.string.tt_yim_recommended_playlists_parent)
nextPage()

verifyExistence(R.string.tt_yim_discover_heading)
scrollToEnd(R.string.tt_yim_discover_parent)
nextPage()

verifyExistence(R.string.tt_yim_endgame_heading)
}

private fun scrollToEnd(@StringRes stringRes: Int){
rule.onNodeWithTag(activity.getString(stringRes)).performTouchInput {
down(bottomRight)
moveTo(topRight)
up()
}
}

private fun verifyExistence(@StringRes stringRes: Int){
rule.onNodeWithTag(activity.getString(stringRes)).assertExists()
}

private fun nextPage(){
rule.onNodeWithTag(activity.getString(R.string.tt_yim_next_button)).performClick()
private fun nextPage(scrollToEnd: Boolean = true){
rule.waitForIdle()
rule.onNodeWithTag(activity.getString(R.string.tt_yim_next_button)).apply {
if (scrollToEnd){
performScrollTo()
}
performClick()
}
}
}
@@ -1,7 +1,12 @@
package org.listenbrainz.android.di

import android.content.Context

import android.util.Log
import androidx.work.Configuration
import androidx.work.WorkManager
import androidx.work.testing.SynchronousExecutor
import androidx.work.testing.WorkManagerTestInitHelper
import dagger.Module
import dagger.Provides
import dagger.hilt.android.qualifiers.ApplicationContext
Expand All @@ -21,11 +26,22 @@ class TestAppModule {

@Singleton
@Provides
fun providesServiceConnection(
@ApplicationContext context: Context,
appPreferences: AppPreferences,
workManager: WorkManager
) = BrainzPlayerServiceConnection(context, appPreferences, workManager)
fun providesServiceConnection(@ApplicationContext context: Context, appPreferences: AppPreferences, workManager: WorkManager): BrainzPlayerServiceConnection {
return BrainzPlayerServiceConnection(context, appPreferences, workManager)
}

@Provides
@Singleton
fun providesWorkManager(@ApplicationContext context: Context): WorkManager {
val config = Configuration.Builder()
.setMinimumLoggingLevel(Log.DEBUG)
.setExecutor(SynchronousExecutor())
.build()

// Initialize WorkManager for instrumentation tests.
WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
return WorkManager.getInstance(context)
}

@Singleton
@Provides
Expand All @@ -34,9 +50,5 @@ class TestAppModule {
@Singleton
@Provides
fun providesAppPreferences() : AppPreferences = MockAppPreferences()

@Provides
@Singleton
fun providesWorkManager(@ApplicationContext context: Context): WorkManager =
WorkManager.getInstance(context)

}
17 changes: 13 additions & 4 deletions app/src/main/AndroidManifest.xml
Expand Up @@ -89,11 +89,20 @@
</activity>

<activity
android:name=".ui.screens.dashboard.DonateActivity"
android:label="@string/donate_title" />
android:name=".ui.screens.about.AboutActivity"
android:label="@string/about_title"
android:theme="@style/AppTheme"/>
<activity
android:name=".ui.screens.profile.LoginActivity"
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar" /> <!-- Sentry Setup -->
android:name=".ui.screens.dashboard.DonateActivity"
android:label="@string/donate_title"
android:theme="@style/AppTheme"/>

<activity
android:name="org.listenbrainz.android.ui.screens.profile.LoginActivity"
android:theme="@style/AppTheme"/>

<!-- Sentry Setup -->

<meta-data
android:name="io.sentry.dsn"
android:value="@string/sentryDsn" />
Expand Down
@@ -0,0 +1,17 @@
package org.listenbrainz.android.di

import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import org.listenbrainz.android.repository.remoteplayer.RemotePlayerRepository
import org.listenbrainz.android.repository.remoteplayer.RemotePlayerRepositoryImpl

@Module
@InstallIn(SingletonComponent::class)
abstract class RemotePlayerRepositoryModule {

@Binds
abstract fun bindsRemotePlayerRepository(repository: RemotePlayerRepositoryImpl?): RemotePlayerRepository?

}
23 changes: 23 additions & 0 deletions app/src/main/java/org/listenbrainz/android/di/ServiceModule.kt
@@ -1,5 +1,6 @@
package org.listenbrainz.android.di

import android.content.Context
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonDeserializationContext
Expand All @@ -8,6 +9,7 @@ import com.google.gson.JsonElement
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
Expand All @@ -18,8 +20,10 @@ import org.listenbrainz.android.service.FeedService
import org.listenbrainz.android.service.ListensService
import org.listenbrainz.android.service.SocialService
import org.listenbrainz.android.service.YimService
import org.listenbrainz.android.service.YouTubeApiService
import org.listenbrainz.android.util.Constants.LISTENBRAINZ_API_BASE_URL
import org.listenbrainz.android.util.HeaderInterceptor
import org.listenbrainz.android.util.Utils
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.lang.reflect.Type
Expand Down Expand Up @@ -71,6 +75,25 @@ class ServiceModule {
constructRetrofit(appPreferences)
.create(FeedService::class.java)

@Singleton
@Provides
fun providesYoutubeApiService(@ApplicationContext context: Context): YouTubeApiService =
Retrofit.Builder()
.baseUrl("https://www.googleapis.com/")
.addConverterFactory(GsonConverterFactory.create())
.client( OkHttpClient.Builder()
.addInterceptor { chain ->
val request = chain.request().newBuilder()
.addHeader("X-Android-Package", context.packageName)
.addHeader("X-Android-Cert", Utils.getSHA1(context, context.packageName) ?: "")
.build()
chain.proceed(request)
}
.build()
)
.build()
.create(YouTubeApiService::class.java)

/* YIM */

private val yimGson: Gson by lazy {
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/org/listenbrainz/android/model/Listen.kt
Expand Up @@ -4,9 +4,9 @@ import com.google.gson.annotations.SerializedName

data class Listen(
@SerializedName("inserted_at") val insertedAt: String,
@SerializedName("listened_at") val listenedAt: Int,
@SerializedName("listened_at") val listenedAt: Int? = null,
@SerializedName("recording_msid") val recordingMsid: String,
@SerializedName("track_metadata") val trackMetadata: TrackMetadata,
@SerializedName("user_name") val userName: String,
@SerializedName("cover_art") var coverArt: CoverArt? = null
@SerializedName("cover_art") val coverArt: CoverArt? = null
)
Expand Up @@ -3,6 +3,6 @@ package org.listenbrainz.android.model
import android.graphics.Bitmap

data class ListenBitmap(
val bitmap: Bitmap?=null,
val id:String?=""
val bitmap: Bitmap? = null,
val id:String? = ""
)
Expand Up @@ -23,6 +23,8 @@ enum class ResponseError(val genericToast: String, var actualResponse: String? =

BAD_GATEWAY(genericToast = "Error! Bad gateway."),

REMOTE_PLAYER_ERROR(genericToast = "Error! Could not play the requested listen."),

SERVICE_UNAVAILABLE(genericToast = "Server outage detected. Please try again later."),

NETWORK_ERROR(genericToast = "Network issues detected. Make sure device is connected to internet."),
Expand Down
@@ -0,0 +1,26 @@
package org.listenbrainz.android.repository.remoteplayer

import com.spotify.protocol.types.PlayerState
import org.listenbrainz.android.model.ListenBitmap
import org.listenbrainz.android.model.ResponseError
import org.listenbrainz.android.util.Resource

interface RemotePlayerRepository {

suspend fun searchYoutubeMusicVideoId(
trackName: String,
artist: String
): Resource<String>

suspend fun playOnYoutube(
getYoutubeMusicVideoId: suspend () -> Resource<String>
): Resource<Unit>

suspend fun connectToSpotify(onError: (ResponseError) -> Unit = {})

fun disconnectSpotify()

suspend fun updateTrackCoverArt(playerState: PlayerState): ListenBitmap

fun playUri(trackId: String, onFailure: () -> Unit)
}

0 comments on commit e692c8b

Please sign in to comment.