Skip to content

Commit

Permalink
Feature/no issue clean up (#38)
Browse files Browse the repository at this point in the history
* Clean up ABS responses
* Book title could be nullable (!)
* Remove Lucid Library
* Remove room annotation processor
* Change user Agent
* Stable keys for Library Screen
* Fix time extension locale
* remove broken in-memory cache
* update foreground
  • Loading branch information
GrakovNe authored Nov 6, 2024
1 parent 8539bee commit 5b34211
Show file tree
Hide file tree
Showing 19 changed files with 133 additions and 133 deletions.
7 changes: 2 additions & 5 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ android {
applicationId = "org.grakovne.lissen"
minSdk = 28
targetSdk = 35
versionCode = 23
versionName = "1.0.22"
versionCode = 24
versionName = "1.0.23"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down Expand Up @@ -98,8 +98,6 @@ dependencies {
implementation(libs.androidx.media3.session)
kapt(libs.hilt.android.compiler)

implementation(libs.icons.lucide)

implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
Expand All @@ -121,7 +119,6 @@ dependencies {

implementation(libs.androidx.room.runtime)
implementation(libs.androidx.room.ktx)
annotationProcessor(libs.androidx.room.compiler)
ksp(libs.androidx.room.compiler)

testImplementation(libs.junit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.net.Uri
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import org.grakovne.lissen.BuildConfig
import org.grakovne.lissen.channel.audiobookshelf.api.AudioBookshelfDataRepository
import org.grakovne.lissen.channel.audiobookshelf.api.AudioBookshelfMediaRepository
import org.grakovne.lissen.channel.audiobookshelf.api.AudioBookshelfSyncService
Expand All @@ -13,7 +14,9 @@ import org.grakovne.lissen.channel.audiobookshelf.converter.LibraryResponseConve
import org.grakovne.lissen.channel.audiobookshelf.converter.LibrarySearchItemsConverter
import org.grakovne.lissen.channel.audiobookshelf.converter.PlaybackSessionResponseConverter
import org.grakovne.lissen.channel.audiobookshelf.converter.RecentBookResponseConverter
import org.grakovne.lissen.channel.audiobookshelf.model.DeviceInfo
import org.grakovne.lissen.channel.audiobookshelf.model.LibraryResponse
import org.grakovne.lissen.channel.audiobookshelf.model.StartPlaybackRequest
import org.grakovne.lissen.channel.common.ApiResult
import org.grakovne.lissen.channel.common.ApiResult.Success
import org.grakovne.lissen.channel.common.ChannelCode
Expand Down Expand Up @@ -147,9 +150,9 @@ class AudiobookshelfChannel @Inject constructor(
supportedMimeTypes: List<String>,
deviceId: String
): ApiResult<PlaybackSession> {
val request = org.grakovne.lissen.channel.audiobookshelf.model.StartPlaybackRequest(
val request = StartPlaybackRequest(
supportedMimeTypes = supportedMimeTypes,
deviceInfo = org.grakovne.lissen.channel.audiobookshelf.model.DeviceInfo(
deviceInfo = DeviceInfo(
clientName = getClientName(),
deviceId = deviceId,
deviceName = getClientName()
Expand Down Expand Up @@ -195,7 +198,7 @@ class AudiobookshelfChannel @Inject constructor(
password: String
): ApiResult<UserAccount> = dataRepository.authorize(host, username, password)

private fun getClientName() = "Lissen App Android"
private fun getClientName() = "Lissen App ${BuildConfig.VERSION_NAME}"

private val supportedLibraryTypes = listOf("book")
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,23 @@ class LibraryItemIdResponseConverter @Inject constructor() {
}

val filesAsChapters: () -> List<BookChapter> = {
item.media.audioFiles.fold(0.0 to mutableListOf<BookChapter>()) { (accDuration, chapters), file ->
chapters.add(
BookChapter(
start = accDuration,
end = accDuration + file.duration,
title = file.metaTags?.tagTitle
?: file.metadata.filename.removeSuffix(file.metadata.ext),
duration = file.duration,
id = file.ino
item
.media
.audioFiles
.sortedBy { it.index }
.fold(0.0 to mutableListOf<BookChapter>()) { (accDuration, chapters), file ->
chapters.add(
BookChapter(
start = accDuration,
end = accDuration + file.duration,
title = file.metaTags?.tagTitle
?: file.metadata.filename.removeSuffix(file.metadata.ext),
duration = file.duration,
id = file.ino
)
)
)
accDuration + file.duration to chapters
}.second
accDuration + file.duration to chapters
}.second
}

return DetailedBook(
Expand All @@ -54,6 +58,7 @@ class LibraryItemIdResponseConverter @Inject constructor() {
files = item
.media
.audioFiles
.sortedBy { it.index }
.map {
BookFile(
id = it.ino,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ class LibraryItemResponseConverter @Inject constructor() {

fun apply(response: LibraryItemsResponse): PagedItems<Book> = response
.results
.map {
.mapNotNull {
val title = it.media.metadata.title ?: return@mapNotNull null

Book(
id = it.id,
title = it.media.metadata.title,
title = title,
author = it.media.metadata.authorName,
cachedState = BookCachedState.ABLE_TO_CACHE,
duration = it.media.duration.toInt()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import javax.inject.Singleton
class LibrarySearchItemsConverter @Inject constructor() {
fun apply(response: List<LibraryItem>): List<Book> {
return response
.map {
.mapNotNull {
val title = it.media.metadata.title ?: return@mapNotNull null

Book(
id = it.id,
title = it.media.metadata.title,
title = title,
author = it.media.metadata.authorName,
cachedState = BookCachedState.ABLE_TO_CACHE,
duration = it.media.duration.toInt()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,20 @@ package org.grakovne.lissen.channel.audiobookshelf.model

data class LibraryItemsResponse(
val results: List<LibraryItem>,
val total: Int,
val limit: Int,
val page: Int,
val sortBy: String,
val sortDesc: Boolean,
val filterBy: String,
val mediaType: String,
val minified: Boolean,
val collapseseries: Boolean,
val include: String
val page: Int
)

data class LibraryItem(
val id: String,
val libraryId: String,
val folderId: String,
val path: String,
val relPath: String,
val isFile: Boolean,
val mtimeMs: Long,
val ctimeMs: Long,
val birthtimeMs: Long,
val addedAt: Long,
val updatedAt: Long,
val isMissing: Boolean,
val isInvalid: Boolean,
val mediaType: String,
val media: Media
)

data class Media(
val numTracks: Int,
val numAudioFiles: Int,
val numChapters: Int,
val duration: Double,
val metadata: Metadata,
val size: Long
val metadata: Metadata
)

data class Metadata(
val title: String,
val titleIgnorePrefix: String,
val subtitle: String?,
val authorName: String?,
val genres: List<String>,
val publishedYear: String?,
val publishedDate: String?,
val publisher: String?,
val description: String?,
val isbn: String?,
val asin: String?,
val language: String?,
val explicit: Boolean
val title: String?,
val authorName: String?
)
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,5 @@ data class LibraryResponse(
data class Library(
val id: String,
val name: String,
val folders: List<Folder>,
val displayOrder: Int,
val icon: String,
val mediaType: String,
val provider: String,
val createdAt: Long,
val lastUpdate: Long
)

data class Folder(
val id: String,
val fullPath: String,
val libraryId: String
val mediaType: String
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.grakovne.lissen.channel.common

import android.os.Build
import org.grakovne.lissen.BuildConfig

val USER_AGENT = "Lissen (Android ${Build.VERSION.RELEASE}; ${Build.MODEL}"
val USER_AGENT = "Lissen/${BuildConfig.VERSION_NAME} (Linux; Android ${Build.VERSION.RELEASE}; ${Build.MODEL}) ExoPlayer/1.4.1"
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.RewriteQueriesToDropUnusedColumns
import androidx.room.Transaction
import androidx.room.Update
import org.grakovne.lissen.content.cache.entity.BookChapterEntity
Expand Down Expand Up @@ -82,6 +83,7 @@ interface CachedBookDao {
): List<BookEntity>

@Transaction
@RewriteQueriesToDropUnusedColumns
@Query(
"""
SELECT * FROM detailed_books
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.Looper
import androidx.core.content.ContextCompat
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.localbroadcastmanager.content.LocalBroadcastManager
Expand Down Expand Up @@ -130,7 +129,7 @@ class MediaRepository @Inject constructor(
val intent = Intent(context, PlaybackService::class.java).apply {
action = PlaybackService.ACTION_PLAY
}
ContextCompat.startForegroundService(context, intent)
context.startForegroundService(intent)
}

fun pauseAudio() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import androidx.compose.ui.layout.ContentScale
import coil.ImageLoader
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.valentinilk.shimmer.shimmer

@Composable
fun AsyncShimmeringImage(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ import android.content.Context
import android.net.Uri
import coil.ImageLoader
import coil.decode.ImageSource
import coil.disk.DiskCache
import coil.fetch.FetchResult
import coil.fetch.Fetcher
import coil.fetch.SourceResult
import coil.memory.MemoryCache
import coil.request.Options
import dagger.Module
import dagger.Provides
Expand Down Expand Up @@ -72,17 +70,7 @@ object ImageLoaderModule {
): ImageLoader {
return ImageLoader
.Builder(context)
.components {
add(bookCoverFetcherFactory)
}
.memoryCache {
MemoryCache.Builder(context).build()
}
.diskCache {
DiskCache.Builder()
.directory(context.cacheDir.resolve("сover_cache"))
.build()
}
.components { add(bookCoverFetcherFactory) }
.build()
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
package org.grakovne.lissen.ui.extensions

import android.annotation.SuppressLint
import java.util.Locale

@SuppressLint("DefaultLocale")
fun Int.formatFully(): String {
val hours = this / 3600
val minutes = (this % 3600) / 60
val remainingSeconds = this % 60
val seconds = this % 60
return if (hours > 0) {
String.format("%02d:%02d:%02d", hours, minutes, remainingSeconds)
String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, seconds)
} else {
String.format("%02d:%02d", minutes, remainingSeconds)
String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds)
}
}

@SuppressLint("DefaultLocale")
fun Int.formatShortly(): String {
val hours = this / 3600
val minutes = (this % 3600) / 60

return String.format("%02dh %02dm", hours, minutes)
return String.format(Locale.getDefault(), "%02dh %02dm", hours, minutes)
}

@SuppressLint("DefaultLocale")
fun Int.formatLeadingMinutes(): String {
val minutes = this / 60
val remainingSeconds = this % 60
val seconds = this % 60

return String.format("%02d:%02d", minutes, remainingSeconds)
return String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds)
}
Loading

0 comments on commit 5b34211

Please sign in to comment.