Skip to content

Commit

Permalink
Merge pull request #27 from icefields/dev
Browse files Browse the repository at this point in the history
fixed download batch issue
  • Loading branch information
icefields committed Feb 1, 2024
2 parents f61129e + 034d9f5 commit 52c92f7
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 24 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ android {
applicationId = "luci.sixsixsix.powerampache2"
minSdk = 28
targetSdk = 34
versionCode = 8
versionName = "0.07-beta"
versionCode = 9
versionName = "0.08-beta"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

Expand Down
Binary file not shown.
4 changes: 2 additions & 2 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 8,
"versionName": "0.07-beta",
"versionCode": 9,
"versionName": "0.08-beta",
"outputFile": "app-release.apk"
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
package luci.sixsixsix.powerampache2.data

import android.app.Application
import androidx.core.app.PendingIntentCompat.send
import androidx.lifecycle.map
import kotlinx.coroutines.channels.ProducerScope
import kotlinx.coroutines.flow.Flow
Expand Down Expand Up @@ -52,8 +53,10 @@ import luci.sixsixsix.powerampache2.domain.models.Session
import luci.sixsixsix.powerampache2.domain.models.Song
import okhttp3.internal.http.HTTP_OK
import java.lang.ref.WeakReference
import java.util.UUID
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.jvm.Throws

/**
* the source of truth is the database, stick to the single source of truth pattern, only return
Expand Down Expand Up @@ -291,29 +294,54 @@ class SongsRepositoryImpl @Inject constructor(
// I don't need any result from this function
override suspend fun downloadSong(song: Song): Flow<Resource<Any>> = channelFlow {
send(Resource.Loading(true))
startDownloadingSong(song)?.let {
// retrieve the requestID
} ?: run {
// duplicate download
}
send(Resource.Success(data = Any(), networkData = Any()))
send(Resource.Loading(false))
}.catch { e -> errorHandler("downloadSong()", e, this) }

val isSongDownloadedAlready =
dao.getDownloadedSong(song.mediaId, song.artist.id, song.album.id) != null
/**
* @return a UUID if download started successfully or null if it's a duplicate
* @throws and exception in any other case
*/
@Throws(Exception::class)
private suspend fun startDownloadingSong(song: Song): UUID? {
val isSongDownloadedAlready = dao.getDownloadedSong(song.mediaId, song.artist.id, song.album.id) != null
if (isSongDownloadedAlready) {
send(Resource.Loading(false))
return@channelFlow
return null
}

val auth = getSession()!!
weakContext.get()?.let { context ->
return weakContext.get()?.let { context ->
val requestId = startSongDownloadWorker(
context = context,
authToken = auth.auth,
username = musicRepository.getUser()?.username!!,
song = song
)
L(requestId)
requestId
} ?: run {
throw NullPointerException("context was null")
}
send(Resource.Success(data = Any(), networkData = Any()))
send(Resource.Loading(false))
}.catch { e -> errorHandler("downloadSong()", e, this) }
}

override suspend fun downloadSongs(songs: List<Song>) {
songs.forEach { song ->
try {
startDownloadingSong(song)?.let {
// retrieve the requestID
} ?: run {
// duplicate download
}
} catch (e: Exception) {
errorHandler.logError(e)
}
}
}

private suspend fun emitDownloadSuccess(fc: ProducerScope<Resource<Any>>){
fc.send(Resource.Success(data = Any(), networkData = Any()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ interface SongsRepository {
suspend fun getRandomSongs(): Flow<Resource<List<Song>>>
suspend fun getSongUri(song: Song): String
suspend fun downloadSong(song: Song): Flow<Resource<Any>>
suspend fun downloadSongs(songs: List<Song>)
suspend fun deleteDownloadedSong(song: Song): Flow<Resource<Any>>
suspend fun isSongAvailableOffline(song: Song): Boolean
suspend fun getSongShareLink(song: Song): Flow<Resource<String>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,7 @@ class MainViewModel @Inject constructor(
when (result) {
is Resource.Success -> {
result.data?.let {
// song downloaded

// song download started successfully
}
}
is Resource.Error -> state = state.copy(isDownloading = false)
Expand All @@ -346,7 +345,11 @@ class MainViewModel @Inject constructor(
}
}

private fun downloadSongs(songs: List<Song>) = songs.forEach { song -> downloadSong(song) }
private fun downloadSongs(songs: List<Song>) = viewModelScope.launch {
songsRepository.downloadSongs(songs)
}

//private fun downloadSongs(songs: List<Song>) = songs.forEach { song -> downloadSong(song) }

private fun deleteDownloadedSong(song: Song) = viewModelScope.launch {
songsRepository.deleteDownloadedSong(song).collect { result ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
/**
* Copyright (C) 2024 Antonio Tari
*
* This file is a part of Power Ampache 2
* Ampache Android client application
* @author Antonio Tari
*
* This program 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 program 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package luci.sixsixsix.powerampache2.presentation.main.screens

import androidx.annotation.StringRes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ fun PlaylistDetailScreen(
),
playlist = playlist,
isPlayingPlaylist = isPlayingPlaylist,
isDownloading = mainViewModel.state.isDownloading,
songs = viewModel.state.getSongList(),
eventListener = { event ->
when(event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,31 +44,35 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import luci.sixsixsix.powerampache2.R
import luci.sixsixsix.powerampache2.domain.models.Playlist
import luci.sixsixsix.powerampache2.presentation.common.ButtonWithLoadingIndicator
import luci.sixsixsix.powerampache2.presentation.screens_detail.album_detail.components.AlbumInfoViewEvents

@Composable
fun PlaylistInfoButtonsRow(
modifier: Modifier = Modifier,
playlist: Playlist,
isPlayingPlaylist: Boolean,
isDownloading: Boolean,
eventListener: (playlistInfoViewEvents: PlaylistInfoViewEvents) -> Unit) {
Row(modifier = modifier
.padding(horizontal = dimensionResource(R.dimen.albumDetailScreen_infoSection_chipsRow_padding)),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly
) {
IconButton(
onClick = {
eventListener(PlaylistInfoViewEvents.DOWNLOAD_PLAYLIST)
}) {
Icon(
imageVector = Icons.Outlined.DownloadForOffline,
contentDescription = "Download"
)
ButtonWithLoadingIndicator(
imageVector = Icons.Outlined.DownloadForOffline,
imageContentDescription= "Download",
background = Color.Transparent,
isLoading = isDownloading,
showBoth = true
) {
eventListener(PlaylistInfoViewEvents.DOWNLOAD_PLAYLIST)
}

IconButton(modifier = Modifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ fun PlaylistInfoSection(
modifier: Modifier,
playlist: Playlist,
isPlayingPlaylist: Boolean,
isDownloading: Boolean,
songs: List<Song>,
eventListener: (playlistInfoViewEvents: PlaylistInfoViewEvents) -> Unit
) {
Expand Down Expand Up @@ -116,7 +117,8 @@ fun PlaylistInfoSection(
modifier = Modifier.fillMaxWidth(),
isPlayingPlaylist = isPlayingPlaylist,
playlist = playlist,
eventListener = eventListener
eventListener = eventListener,
isDownloading = isDownloading,
)
Spacer(modifier = Modifier.width(20.dp))
}
Expand All @@ -129,6 +131,7 @@ fun PlaylistInfoSectionPreview() {
Modifier,
Playlist.mock(),
isPlayingPlaylist = true,
isDownloading = false,
listOf(Song.mockSong),
eventListener = {}
)
Expand Down

0 comments on commit 52c92f7

Please sign in to comment.