Automatic Lint

This commit is contained in:
Syer10
2024-03-29 00:16:52 +00:00
parent 253095fab1
commit b93c96a85b
48 changed files with 204 additions and 145 deletions

View File

@@ -21,14 +21,13 @@ class ReaderActivity : AppCompatActivity() {
context: Context,
mangaId: Long,
chapterIndex: Int,
): Intent {
return Intent(context, ReaderActivity::class.java).apply {
): Intent =
Intent(context, ReaderActivity::class.java).apply {
putExtra("manga", mangaId)
putExtra("chapter", chapterIndex)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

View File

@@ -74,9 +74,7 @@ class AndroidDownloadService : Service() {
context.stopService(Intent(context, AndroidDownloadService::class.java))
}
fun isRunning(): Boolean {
return instance != null
}
fun isRunning(): Boolean = instance != null
private val json = Json {
ignoreUnknownKeys = true
@@ -87,9 +85,7 @@ class AndroidDownloadService : Service() {
private lateinit var ioScope: CoroutineScope
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onBind(intent: Intent): IBinder? = null
override fun onCreate() {
super.onCreate()
@@ -123,7 +119,9 @@ class AndroidDownloadService : Service() {
Actions.START.name,
Actions.RESTART.name,
-> startWebsocket()
Actions.STOP.name -> stopSelf()
else -> log.info { "This should never happen. No action in the received intent" }
}
} else {

View File

@@ -73,9 +73,7 @@ class AndroidLibraryService : Service() {
context.stopService(Intent(context, AndroidLibraryService::class.java))
}
fun isRunning(): Boolean {
return instance != null
}
fun isRunning(): Boolean = instance != null
private val json = Json {
ignoreUnknownKeys = true
@@ -86,9 +84,7 @@ class AndroidLibraryService : Service() {
private lateinit var ioScope: CoroutineScope
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onBind(intent: Intent): IBinder? = null
override fun onCreate() {
super.onCreate()
@@ -122,7 +118,9 @@ class AndroidLibraryService : Service() {
Actions.START.name,
Actions.RESTART.name,
-> startWebsocket()
Actions.STOP.name -> stopSelf()
else -> log.info { "This should never happen. No action in the received intent" }
}
} else {

View File

@@ -152,9 +152,11 @@ internal class PriorityChannelImpl<T>(
yield()
buffer.add(inChannel.receive())
}
buffer.isFull() -> {
outChannel.send(buffer.removeHead())
}
else -> {
while (buffer.isNotEmpty() && outChannel.trySend(buffer.head).isSuccess) {
buffer.removeHead()

View File

@@ -60,18 +60,14 @@ internal object StringAdapter : Adapter<String> {
key: String,
preferences: ObservableSettings,
callback: () -> Unit,
): SettingsListener {
return preferences.addStringOrNullListener(key) { callback() }
}
): SettingsListener = preferences.addStringOrNullListener(key) { callback() }
}
internal object LongAdapter : Adapter<Long> {
override fun get(
key: String,
preferences: ObservableSettings,
): Long {
return preferences.getLong(key, 0)
}
): Long = preferences.getLong(key, 0)
override fun set(
key: String,
@@ -85,18 +81,14 @@ internal object LongAdapter : Adapter<Long> {
key: String,
preferences: ObservableSettings,
callback: () -> Unit,
): SettingsListener {
return preferences.addLongOrNullListener(key) { callback() }
}
): SettingsListener = preferences.addLongOrNullListener(key) { callback() }
}
internal object IntAdapter : Adapter<Int> {
override fun get(
key: String,
preferences: ObservableSettings,
): Int {
return preferences.getInt(key, 0)
}
): Int = preferences.getInt(key, 0)
override fun set(
key: String,
@@ -110,18 +102,14 @@ internal object IntAdapter : Adapter<Int> {
key: String,
preferences: ObservableSettings,
callback: () -> Unit,
): SettingsListener {
return preferences.addIntOrNullListener(key) { callback() }
}
): SettingsListener = preferences.addIntOrNullListener(key) { callback() }
}
internal object FloatAdapter : Adapter<Float> {
override fun get(
key: String,
preferences: ObservableSettings,
): Float {
return preferences.getFloat(key, 0f)
}
): Float = preferences.getFloat(key, 0f)
override fun set(
key: String,
@@ -135,18 +123,14 @@ internal object FloatAdapter : Adapter<Float> {
key: String,
preferences: ObservableSettings,
callback: () -> Unit,
): SettingsListener {
return preferences.addFloatOrNullListener(key) { callback() }
}
): SettingsListener = preferences.addFloatOrNullListener(key) { callback() }
}
internal object BooleanAdapter : Adapter<Boolean> {
override fun get(
key: String,
preferences: ObservableSettings,
): Boolean {
return preferences.getBoolean(key, false)
}
): Boolean = preferences.getBoolean(key, false)
override fun set(
key: String,
@@ -160,9 +144,7 @@ internal object BooleanAdapter : Adapter<Boolean> {
key: String,
preferences: ObservableSettings,
callback: () -> Unit,
): SettingsListener {
return preferences.addBooleanOrNullListener(key) { callback() }
}
): SettingsListener = preferences.addBooleanOrNullListener(key) { callback() }
}
internal object StringSetAdapter : Adapter<Set<String>> {
@@ -189,9 +171,7 @@ internal object StringSetAdapter : Adapter<Set<String>> {
override fun isSet(
keys: Set<String>,
key: String,
): Boolean {
return keys.contains("$key.size")
}
): Boolean = keys.contains("$key.size")
/**
* Watching the regular key doesn't produce updates for a string set for some reason
@@ -201,9 +181,7 @@ internal object StringSetAdapter : Adapter<Set<String>> {
key: String,
preferences: ObservableSettings,
callback: () -> Unit,
): SettingsListener {
return preferences.addIntOrNullListener("$key.size") { callback() }
}
): SettingsListener = preferences.addIntOrNullListener("$key.size") { callback() }
}
internal class ObjectAdapter<T>(
@@ -229,9 +207,7 @@ internal class ObjectAdapter<T>(
key: String,
preferences: ObservableSettings,
callback: () -> Unit,
): SettingsListener {
return preferences.addStringOrNullListener(key) { callback() }
}
): SettingsListener = preferences.addStringOrNullListener(key) { callback() }
}
internal class JsonObjectAdapter<T>(
@@ -261,9 +237,7 @@ internal class JsonObjectAdapter<T>(
override fun isSet(
keys: Set<String>,
key: String,
): Boolean {
return keys.any { it.startsWith(key) }
}
): Boolean = keys.any { it.startsWith(key) }
/**
* Todo doesn't work

View File

@@ -19,9 +19,7 @@ class StandardPreferenceStore(
override fun getString(
key: String,
defaultValue: String,
): Preference<String> {
return StandardPreference(preferences, key, defaultValue, StringAdapter)
}
): Preference<String> = StandardPreference(preferences, key, defaultValue, StringAdapter)
/**
* Returns a [Long] preference for this [key].
@@ -29,9 +27,7 @@ class StandardPreferenceStore(
override fun getLong(
key: String,
defaultValue: Long,
): Preference<Long> {
return StandardPreference(preferences, key, defaultValue, LongAdapter)
}
): Preference<Long> = StandardPreference(preferences, key, defaultValue, LongAdapter)
/**
* Returns an [Int] preference for this [key].
@@ -39,9 +35,7 @@ class StandardPreferenceStore(
override fun getInt(
key: String,
defaultValue: Int,
): Preference<Int> {
return StandardPreference(preferences, key, defaultValue, IntAdapter)
}
): Preference<Int> = StandardPreference(preferences, key, defaultValue, IntAdapter)
/**
* Returns a [Float] preference for this [key].
@@ -49,9 +43,7 @@ class StandardPreferenceStore(
override fun getFloat(
key: String,
defaultValue: Float,
): Preference<Float> {
return StandardPreference(preferences, key, defaultValue, FloatAdapter)
}
): Preference<Float> = StandardPreference(preferences, key, defaultValue, FloatAdapter)
/**
* Returns a [Boolean] preference for this [key].
@@ -59,9 +51,7 @@ class StandardPreferenceStore(
override fun getBoolean(
key: String,
defaultValue: Boolean,
): Preference<Boolean> {
return StandardPreference(preferences, key, defaultValue, BooleanAdapter)
}
): Preference<Boolean> = StandardPreference(preferences, key, defaultValue, BooleanAdapter)
/**
* Returns a [Set<String>] preference for this [key].
@@ -69,9 +59,7 @@ class StandardPreferenceStore(
override fun getStringSet(
key: String,
defaultValue: Set<String>,
): Preference<Set<String>> {
return StandardPreference(preferences, key, defaultValue, StringSetAdapter)
}
): Preference<Set<String>> = StandardPreference(preferences, key, defaultValue, StringSetAdapter)
/**
* Returns preference of type [T] for this [key]. The [serializer] and [deserializer] function

View File

@@ -14,15 +14,14 @@ object ImageUtil {
private val gifMagic = "GIF8".toByteArray()
private val webpMagic = "RIFF".toByteArray()
fun findType(bytes: ByteArray): ImageType? {
return when {
fun findType(bytes: ByteArray): ImageType? =
when {
bytes.compareWith(jpgMagic) -> ImageType.JPG
bytes.compareWith(pngMagic) -> ImageType.PNG
bytes.compareWith(gifMagic) -> ImageType.GIF
bytes.compareWith(webpMagic) -> ImageType.WEBP
else -> null
}
}
private fun ByteArray.compareWith(magic: ByteArray): Boolean {
for (i in magic.indices) {

View File

@@ -22,8 +22,8 @@ class FlowConverterFactory : Converter.Factory {
val typeData: TypeData,
val ktorfit: Ktorfit,
) : Converter.ResponseConverter<HttpResponse, Flow<Any?>> {
override fun convert(getResponse: suspend () -> HttpResponse): Flow<Any?> {
return flow {
override fun convert(getResponse: suspend () -> HttpResponse): Flow<Any?> =
flow {
val response = getResponse()
val convertedBody = ktorfit.nextSuspendResponseConverter(
@@ -34,7 +34,6 @@ class FlowConverterFactory : Converter.Factory {
emit(convertedBody)
}.flowOn(Dispatchers.IO)
}
}
override fun responseConverter(
typeData: TypeData,

View File

@@ -35,6 +35,7 @@ actual class DateHandler
setTimeStyle(NSDateFormatterNoStyle)
setLocale(Locale.current.toPlatform())
}
else -> NSDateFormatter()
.apply {
setDateFormat(format)

View File

@@ -32,6 +32,7 @@ actual class DateHandler
"" -> DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
.withLocale(Locale.current.toPlatform())
.withZone(ZoneId.systemDefault())
else -> DateTimeFormatter.ofPattern(format)
.withZone(ZoneId.systemDefault())
}.let { formatter ->

View File

@@ -130,7 +130,9 @@ suspend fun main() {
SystemTheme.LIGHT, SystemTheme.UNKNOWN -> IntelliJTheme()
SystemTheme.DARK -> DarculaTheme()
}
ThemeMode.Light -> IntelliJTheme()
ThemeMode.Dark -> DarculaTheme()
}
withUIContext {
@@ -188,10 +190,12 @@ suspend fun main() {
// backPressHandler.handle()
false
}
Key.F3 -> {
displayDebugInfoFlow.value = !displayDebugInfoFlow.value
true
}
else -> false
}
} else {
@@ -220,6 +224,7 @@ suspend fun main() {
)
}
}
ServerResult.STARTING, ServerResult.FAILED -> {
Surface {
LoadingScreen(

View File

@@ -57,12 +57,14 @@ fun httpClient(
engine {
proxy = when (serverPreferences.proxy().get()) {
Proxy.NO_PROXY -> null
Proxy.HTTP_PROXY -> ProxyBuilder.http(
URLBuilder(
host = serverPreferences.proxyHttpHost().get(),
port = serverPreferences.proxyHttpPort().get(),
).build(),
)
Proxy.SOCKS_PROXY -> ProxyBuilder.socks(
serverPreferences.proxySocksHost().get(),
serverPreferences.proxySocksPort().get(),
@@ -71,6 +73,7 @@ fun httpClient(
}
when (serverPreferences.auth().get()) {
Auth.NONE -> Unit
Auth.BASIC -> AuthPlugin {
basic {
sendWithoutRequest {
@@ -84,6 +87,7 @@ fun httpClient(
}
}
}
Auth.DIGEST -> AuthPlugin {
digest {
credentials {

View File

@@ -143,6 +143,7 @@ class UpdatesPager
updates.map {
when (it) {
is Updates.Date -> it
is Updates.Update -> it.copy(
manga = changedManga[it.manga.id] ?: it.manga,
chapter = changedChapters[it.chapter.id] ?: it.chapter,

View File

@@ -77,12 +77,10 @@ class ServerService
}
}
private fun getRuntimeJava(): String? {
return System.getProperty("java.home")?.let { getJavaFromPath(it.toPath().resolve("bin")) }
}
private fun getRuntimeJava(): String? = System.getProperty("java.home")?.let { getJavaFromPath(it.toPath().resolve("bin")) }
private fun getPossibleJava(): String? {
return System.getProperty("java.library.path")?.split(pathSeparatorChar)
private fun getPossibleJava(): String? =
System.getProperty("java.library.path")?.split(pathSeparatorChar)
.orEmpty()
.asSequence()
.mapNotNull {
@@ -99,7 +97,6 @@ class ServerService
}
.mapNotNull { getJavaFromPath(it) }
.firstOrNull()
}
private suspend fun runService() {
process?.destroy()
@@ -154,6 +151,7 @@ class ServerService
when {
it.contains("Javalin started") ->
_initialized.value = ServerResult.STARTED
it.contains("Javalin has stopped") ->
_initialized.value = ServerResult.FAILED
}

View File

@@ -17,9 +17,7 @@ sealed class ServerHostPreference<T : Any> {
protected abstract val defaultValue: T
protected abstract val serverValue: T
private fun validate(value: T): Boolean {
return value != serverValue
}
private fun validate(value: T): Boolean = value != serverValue
fun getProperty(): String? {
val preference = preference().get().takeIf(::validate)

View File

@@ -117,12 +117,14 @@ fun ChapterDownloadIcon(
onClick = { onClickDelete(chapter.chapter) },
)
}
ChapterDownloadState.Downloading -> {
DownloadingIconButton(
downloadChapter,
onClick = { onClickStop(chapter.chapter) },
)
}
ChapterDownloadState.NotDownloaded -> {
DownloadIconButton(onClick = { onClickDownload(chapter.chapter) })
}
@@ -172,6 +174,7 @@ private fun DownloadingIconButton(
LocalContentColor.current.copy(alpha = ContentAlpha.disabled),
2.dp,
)
DownloadState.Downloading -> if (downloadChapter.progress != 0.0F) {
val animatedProgress by animateFloatAsState(
targetValue = downloadChapter.progress,
@@ -202,6 +205,7 @@ private fun DownloadingIconButton(
2.dp,
)
}
DownloadState.Error -> Surface(shape = CircleShape, color = LocalContentColor.current) {
Icon(
Icons.Rounded.Error,
@@ -212,6 +216,7 @@ private fun DownloadingIconButton(
Color.Red,
)
}
DownloadState.Finished -> Surface(shape = CircleShape, color = LocalContentColor.current) {
Icon(
Icons.Rounded.Check,

View File

@@ -40,8 +40,8 @@ class ImageLoaderProvider
@OptIn(DelicateCoroutinesApi::class)
val serverUrl = serverPreferences.serverUrl().stateIn(GlobalScope)
fun get(imageCache: ImageCache): ImageLoader {
return ImageLoader {
fun get(imageCache: ImageCache): ImageLoader =
ImageLoader {
components {
register(context, http)
add(MokoResourceFetcher.Factory())
@@ -60,7 +60,6 @@ class ImageLoaderProvider
bitmapMemoryCacheConfig { configure(context) }
}
}
}
inner class MangaCoverMapper : Mapper<Url> {
override fun map(

View File

@@ -103,6 +103,7 @@ fun ActionMenu(
is ActionGroup -> {
{ openGroup = item }
}
is ActionItem -> item.doAction
},
enabled = item.enabled,
@@ -158,6 +159,7 @@ fun ActionMenu(
onClick = {
when (item) {
is ActionGroup -> openGroup = item
is ActionItem -> {
openGroup = null
item()
@@ -200,9 +202,11 @@ private fun separateIntoIconAndOverflow(
OverflowMode.NEVER_OVERFLOW -> {
iconActions.add(item)
}
OverflowMode.ALWAYS_OVERFLOW -> {
overflowActions.add(item)
}
OverflowMode.IF_NECESSARY -> {
if (iconsAvailableBeforeOverflow > 0) {
iconActions.add(item)
@@ -211,6 +215,7 @@ private fun separateIntoIconAndOverflow(
overflowActions.add(item)
}
}
OverflowMode.NOT_SHOWN -> {
// skip
}

View File

@@ -208,10 +208,18 @@ private fun ColorPresetItem(
private fun getColorShades(color: Color): ImmutableList<Color> {
val f = color.toLong()
return listOf(
shadeColor(f, 0.9), shadeColor(f, 0.7), shadeColor(f, 0.5),
shadeColor(f, 0.333), shadeColor(f, 0.166), shadeColor(f, -0.125),
shadeColor(f, -0.25), shadeColor(f, -0.375), shadeColor(f, -0.5),
shadeColor(f, -0.675), shadeColor(f, -0.7), shadeColor(f, -0.775),
shadeColor(f, 0.9),
shadeColor(f, 0.7),
shadeColor(f, 0.5),
shadeColor(f, 0.333),
shadeColor(f, 0.166),
shadeColor(f, -0.125),
shadeColor(f, -0.25),
shadeColor(f, -0.375),
shadeColor(f, -0.5),
shadeColor(f, -0.675),
shadeColor(f, -0.7),
shadeColor(f, -0.775),
).toImmutableList()
}

View File

@@ -14,9 +14,7 @@ import kotlinx.coroutines.internal.synchronized
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
fun <T> SavedStateHandle.getStateFlow(initialValue: () -> T): SavedStateHandleDelegate<T> {
return SavedStateHandleDelegate(this, initialValue)
}
fun <T> SavedStateHandle.getStateFlow(initialValue: () -> T): SavedStateHandleDelegate<T> = SavedStateHandleDelegate(this, initialValue)
@OptIn(InternalCoroutinesApi::class)
class SavedStateHandleDelegate<T>(
@@ -30,8 +28,8 @@ class SavedStateHandleDelegate<T>(
override fun getValue(
thisRef: ViewModel,
property: KProperty<*>,
): SavedStateHandleStateFlow<T> {
return item ?: synchronized(synchronizedObject) {
): SavedStateHandleStateFlow<T> =
item ?: synchronized(synchronizedObject) {
if (item == null) {
savedStateHandle.getSavedStateFlow(property.name, initialValue)
.also { item = it }
@@ -40,7 +38,6 @@ class SavedStateHandleDelegate<T>(
}
}
}
}
class SavedStateHandleStateFlow<T>(
private val key: String,

View File

@@ -107,10 +107,9 @@ class AppThemeViewModel
fun getTheme(
id: Int,
isLight: Boolean,
): Theme {
return themes.find { it.id == id && it.colors.isLight == isLight }
): Theme =
themes.find { it.id == id && it.colors.isLight == isLight }
?: themes.first { it.colors.isLight == isLight }
}
return when (themeMode) {
ThemeMode.System -> if (!isSystemInDarkTheme()) {
@@ -118,7 +117,9 @@ class AppThemeViewModel
} else {
getTheme(darkTheme, false)
}
ThemeMode.Light -> getTheme(lightTheme, true)
ThemeMode.Dark -> getTheme(darkTheme, false)
}
}

View File

@@ -148,6 +148,7 @@ fun ExtensionsScreenContent(
modifier = Modifier.animateItemPlacement()
.padding(16.dp, 16.dp, 16.dp, 4.dp),
)
is ExtensionUI.ExtensionItem -> Column {
ExtensionItem(
Modifier.animateItemPlacement(),

View File

@@ -111,6 +111,7 @@ private fun LibraryMap.setManga(
val flow = getManga(id)
when (val state = flow.value) {
is CategoryState.Loaded -> state.unfilteredItems.value = manga
else -> {
val unfilteredItems = MutableStateFlow(manga)
flow.value = CategoryState.Loaded(getItemsFlow(unfilteredItems), unfilteredItems)
@@ -160,11 +161,13 @@ class LibraryScreenViewModel
FilterState.EXCLUDED -> manga.downloadCount == null || manga.downloadCount == 0
FilterState.INCLUDED -> manga.downloadCount != null && (manga.downloadCount ?: 0) > 0
FilterState.IGNORED -> true
} && when (unread) {
} &&
when (unread) {
FilterState.EXCLUDED -> manga.unreadCount == null || manga.unreadCount == 0
FilterState.INCLUDED -> manga.unreadCount != null && (manga.unreadCount ?: 0) > 0
FilterState.IGNORED -> true
} && when (completed) {
} &&
when (completed) {
FilterState.EXCLUDED -> manga.status != MangaStatus.COMPLETED
FilterState.INCLUDED -> manga.status == MangaStatus.COMPLETED
FilterState.IGNORED -> true
@@ -238,17 +241,22 @@ class LibraryScreenViewModel
collator.compare(a.title.toLowerCase(locale), b.title.toLowerCase(locale))
}
}
Sort.UNREAD -> {
{ a, b ->
when {
// Ensure unread content comes first
(a.unreadCount ?: 0) == (b.unreadCount ?: 0) -> 0
a.unreadCount == null || a.unreadCount == 0 -> if (ascending) 1 else -1
b.unreadCount == null || b.unreadCount == 0 -> if (ascending) -1 else 1
else -> (a.unreadCount ?: 0).compareTo(b.unreadCount ?: 0)
}
}
}
Sort.DATE_ADDED -> {
{ a, b ->
a.inLibraryAt.compareTo(b.inLibraryAt)

View File

@@ -40,7 +40,9 @@ fun LibraryPager(
HorizontalPager(state = pagerState) {
when (val library = getLibraryForPage(categories[it].id).value) {
CategoryState.Loading -> LoadingScreen()
is CategoryState.Failed -> ErrorScreen(library.e.message)
is CategoryState.Loaded -> LibraryLoadedPage(
library = library,
displayMode = displayMode,
@@ -83,6 +85,7 @@ private fun LibraryLoadedPage(
showLanguage = showLanguage,
showLocal = showLocal,
)
DisplayMode.ComfortableGrid -> LibraryMangaComfortableGrid(
library = items,
gridColumns = gridColumns,
@@ -94,6 +97,7 @@ private fun LibraryLoadedPage(
showLanguage = showLanguage,
showLocal = showLocal,
)
DisplayMode.CoverOnlyGrid -> LibraryMangaCoverOnlyGrid(
library = items,
gridColumns = gridColumns,
@@ -105,6 +109,7 @@ private fun LibraryLoadedPage(
showLanguage = showLanguage,
showLocal = showLocal,
)
DisplayMode.List -> LibraryMangaList(
library = items,
onClickManga = onClickManga,
@@ -114,6 +119,7 @@ private fun LibraryLoadedPage(
showLanguage = showLanguage,
showLocal = showLocal,
)
else -> Box {}
}
}

View File

@@ -220,9 +220,11 @@ fun WideLibraryScreenContent(
is LibraryState.Failed -> {
ErrorScreen(libraryState.e.message)
}
LibraryState.Loading -> {
LoadingScreen(true)
}
is LibraryState.Loaded -> {
LibraryPager(
pagerState = pagerState,
@@ -296,6 +298,7 @@ fun ThinLibraryScreenContent(
confirmValueChange = {
when (it) {
ModalBottomSheetValue.Hidden -> setShowingSheet(false)
ModalBottomSheetValue.Expanded,
ModalBottomSheetValue.HalfExpanded,
-> setShowingSheet(true)
@@ -359,9 +362,11 @@ fun ThinLibraryScreenContent(
LibraryState.Loading -> {
LoadingScreen(true)
}
is LibraryState.Failed -> {
ErrorScreen(libraryState.e.message)
}
is LibraryState.Loaded -> {
LibraryPager(
pagerState = pagerState,

View File

@@ -265,6 +265,7 @@ private fun LinkDisplay() {
contentDescription = name,
modifier = modifier,
)
is LinkIcon.Icon -> Icon(
imageVector = it.icon.icon,
contentDescription = name,
@@ -288,6 +289,7 @@ private fun LinkDisplay() {
contentDescription = name,
modifier = Modifier.fillMaxSize(),
)
is LinkIcon.Icon -> Icon(
imageVector = it.icon.icon,
contentDescription = name,

View File

@@ -39,6 +39,7 @@ fun DownloadsExtraInfo() {
val list by vm.downloadQueue.collectAsState()
val text = when (serviceStatus) {
WebsocketService.Status.STARTING -> stringResource(MR.strings.downloads_loading)
WebsocketService.Status.RUNNING -> {
if (list.isNotEmpty()) {
val remainingDownloads = stringResource(MR.strings.downloads_remaining, list.size)
@@ -51,6 +52,7 @@ fun DownloadsExtraInfo() {
null
}
}
WebsocketService.Status.STOPPED -> null
}
if (!text.isNullOrBlank()) {

View File

@@ -55,6 +55,7 @@ fun LibraryUpdatesExtraInfo() {
val text = when (serviceStatus) {
WebsocketService.Status.STARTING -> stringResource(MR.strings.downloads_loading)
WebsocketService.Status.RUNNING -> {
if (updateStatus.running) {
stringResource(MR.strings.notification_updating, current, total)
@@ -62,6 +63,7 @@ fun LibraryUpdatesExtraInfo() {
null
}
}
WebsocketService.Status.STOPPED -> null
}
if (!text.isNullOrBlank()) {

View File

@@ -615,6 +615,7 @@ fun ChapterSeparator(
previousChapter == null && nextChapter != null -> {
Text(stringResource(MR.strings.no_previous_chapter))
}
previousChapter != null && nextChapter != null -> {
val prevChapter by previousChapter.stateObserver.collectAsState()
when (prevChapter) {
@@ -624,6 +625,7 @@ fun ChapterSeparator(
}
CircularProgressIndicator()
}
else -> Unit
}
Text(stringResource(MR.strings.previous_chapter, previousChapter.chapter.name))
@@ -637,9 +639,11 @@ fun ChapterSeparator(
}
CircularProgressIndicator()
}
else -> Unit
}
}
previousChapter != null && nextChapter == null -> {
Text(stringResource(MR.strings.no_next_chapter))
}

View File

@@ -208,20 +208,26 @@ class ReaderMenuViewModel
setReaderSettingsMenuOpen(!readerSettingsMenuOpen.value)
null
}
Navigation.NEXT -> MoveTo.Next
Navigation.PREV -> MoveTo.Previous
Navigation.RIGHT -> when (readerModeSettings.direction.value) {
Direction.Left -> MoveTo.Previous
else -> MoveTo.Next
}
Navigation.LEFT -> when (readerModeSettings.direction.value) {
Direction.Left -> MoveTo.Next
else -> MoveTo.Previous
}
Navigation.DOWN -> when (readerModeSettings.direction.value) {
Direction.Up -> MoveTo.Previous
else -> MoveTo.Next
}
Navigation.UP -> when (readerModeSettings.direction.value) {
Direction.Up -> MoveTo.Next
else -> MoveTo.Previous

View File

@@ -154,8 +154,8 @@ class TachideskPageLoader(
}
}
private suspend fun getImageFromCache(page: ReaderPage): ReaderPage.ImageDecodeState {
return chapterCache.openSnapshot(page.cacheKey)?.use {
private suspend fun getImageFromCache(page: ReaderPage): ReaderPage.ImageDecodeState =
chapterCache.openSnapshot(page.cacheKey)?.use {
it.source().use { source ->
val decoder = bitmapDecoderFactory.create(
ImageResult.OfSource(
@@ -183,7 +183,6 @@ class TachideskPageLoader(
}
}
} ?: ReaderPage.ImageDecodeState.FailedToGetSnapShot
}
/**
* Preloads the given [amount] of pages after the [currentPage] with a lower priority.

View File

@@ -86,6 +86,7 @@ fun ContinuousReader(
)
Unit
}
is PageMove.Page -> {
val pageNumber = pages.indexOf(pageMove.page)
if (pageNumber > -1) {
@@ -155,6 +156,7 @@ fun ContinuousReader(
reverseLayout = direction == Direction.Up,
)
}
false -> {
LazyRow(
state = state,
@@ -217,6 +219,7 @@ private fun LazyListScope.items(
retry = retry,
)
}
is ReaderPageSeparator -> ChapterSeparator(
previousChapter = image.previousChapter,
nextChapter = image.nextChapter,

View File

@@ -63,6 +63,7 @@ fun PagerReader(
state.animateScrollToPage(page)
}
}
is PageMove.Page -> {
val pageNumber = pages.indexOf(pageMove.page)
if (pageNumber > -1) {
@@ -158,6 +159,7 @@ fun HandlePager(
contentScale = pageContentScale,
)
}
is ReaderPageSeparator -> ChapterSeparator(
previousChapter = image.previousChapter,
nextChapter = image.nextChapter,

View File

@@ -434,11 +434,13 @@ private fun PreferenceFile(
modifier = modifier,
tint = Color.Red,
)
Status.Success -> Icon(
Icons.Rounded.Check,
contentDescription = null,
modifier = modifier,
)
else -> Unit
}
}

View File

@@ -210,6 +210,7 @@ fun SettingsServerScreenContent(
}
when (proxyValue) {
Proxy.NO_PROXY -> Unit
Proxy.HTTP_PROXY -> {
item {
EditTextPreference(
@@ -226,6 +227,7 @@ fun SettingsServerScreenContent(
)
}
}
Proxy.SOCKS_PROXY -> {
item {
EditTextPreference(

View File

@@ -119,6 +119,7 @@ class SourceScreenViewModel(
)
}
}
isLatest.value -> {
{ page ->
getLatestManga.await(
@@ -128,6 +129,7 @@ class SourceScreenViewModel(
)
}
}
else -> {
{ page ->
getPopularManga.await(

View File

@@ -285,6 +285,7 @@ private fun SourceThinScreenContent(
confirmValueChange = {
when (it) {
ModalBottomSheetValue.Hidden -> setShowingFilters(false)
ModalBottomSheetValue.Expanded,
ModalBottomSheetValue.HalfExpanded,
-> setShowingFilters(true)
@@ -492,6 +493,7 @@ private fun MangaTable(
hasNextPage = hasNextPage,
onLoadNextPage = onLoadNextPage,
)
DisplayMode.ComfortableGrid -> SourceMangaComfortableGrid(
mangas = mangas,
gridColumns = gridColumns,
@@ -500,12 +502,14 @@ private fun MangaTable(
hasNextPage = hasNextPage,
onLoadNextPage = onLoadNextPage,
)
DisplayMode.List -> SourceMangaList(
mangas = mangas,
onClickManga = onMangaClick,
hasNextPage = hasNextPage,
onLoadNextPage = onLoadNextPage,
)
else -> Box {}
}
}

View File

@@ -155,11 +155,13 @@ fun SourcesSideMenu(
contentDescription = stringResource(MR.strings.sources_home),
modifier = modifier,
)
SourceNavigatorScreen.SearchScreen -> Icon(
imageVector = Icons.Rounded.Search,
contentDescription = stringResource(MR.strings.location_global_search),
modifier = modifier,
)
is SourceNavigatorScreen.SourceScreen -> Box(Modifier.align(Alignment.Center)) {
ImageLoaderImage(
data = screen.source,

View File

@@ -196,12 +196,14 @@ fun GlobalSearchItem(
) {
ErrorScreen(search.e)
}
Search.Searching -> Box(
Modifier.fillMaxWidth().padding(vertical = 8.dp, horizontal = 16.dp),
contentAlignment = Alignment.Center,
) {
CircularProgressIndicator()
}
is Search.Success -> Box(
Modifier
.fillMaxWidth()

View File

@@ -185,6 +185,7 @@ fun WideSourcesMenu(
sourceUI.header,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp),
)
is SourceUI.SourceItem -> WideSourceItem(
sourceUI,
onSourceClicked = onAddSource,
@@ -285,6 +286,7 @@ fun ThinSourcesMenu(
sourceUI.header,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp),
)
is SourceUI.SourceItem -> ThinSourceItem(
sourceUI,
onSourceClicked = onAddSource,

View File

@@ -87,12 +87,15 @@ fun SourceSettingsScreenContent(settings: ImmutableList<SourceSettingsView<*, *>
is CheckBox, is Switch -> {
TwoStatePreference(it as TwoState, it is CheckBox)
}
is List -> {
ListPreference(it)
}
is EditText -> {
EditTextPreference(it)
}
is MultiSelect -> {
MultiSelectPreference(it)
}

View File

@@ -184,6 +184,7 @@ fun UpdatesScreenContent(
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
fontWeight = FontWeight.Medium,
)
is UpdatesUI.Item -> {
val manga = item.chapterDownloadItem.manga!!
val chapter = item.chapterDownloadItem.chapter

View File

@@ -21,11 +21,17 @@ actual fun stringFormat(
@Suppress("MagicNumber")
return when (args.size) {
0 -> NSString.stringWithFormat(objcFormat)
1 -> NSString.stringWithFormat(objcFormat, args[0])
2 -> NSString.stringWithFormat(objcFormat, args[0], args[1])
3 -> NSString.stringWithFormat(objcFormat, args[0], args[1], args[2])
4 -> NSString.stringWithFormat(objcFormat, args[0], args[1], args[2], args[3])
5 -> NSString.stringWithFormat(objcFormat, args[0], args[1], args[2], args[3], args[4])
6 -> NSString.stringWithFormat(
objcFormat,
args[0],
@@ -35,6 +41,7 @@ actual fun stringFormat(
args[4],
args[5],
)
7 -> NSString.stringWithFormat(
objcFormat,
args[0],
@@ -45,6 +52,7 @@ actual fun stringFormat(
args[5],
args[6],
)
8 -> NSString.stringWithFormat(
objcFormat,
args[0],
@@ -56,6 +64,7 @@ actual fun stringFormat(
args[6],
args[7],
)
9 -> NSString.stringWithFormat(
objcFormat,
args[0],
@@ -68,6 +77,7 @@ actual fun stringFormat(
args[7],
args[8],
)
else -> throw IllegalArgumentException("can't handle more then 9 arguments now")
}
}

View File

@@ -82,12 +82,15 @@ internal actual fun RealVerticalScrollbar(
is ScrollStateScrollbarAdapter -> {
Modifier.drawScrollbar(adapter.scrollState, Orientation.Vertical, reverseLayout)
}
is LazyListStateScrollbarAdapter -> {
Modifier.drawScrollbar(adapter.lazyListState, Orientation.Vertical, reverseLayout)
}
is LazyGridStateScrollbarAdapter -> {
Modifier.drawScrollbar(adapter.lazyGridState, adapter.gridCells, adapter.spacing, Orientation.Vertical, reverseLayout)
}
else -> Modifier
}
Box(modifier then Modifier.fillMaxSize() then scrollbarModifier)
@@ -105,49 +108,47 @@ internal actual fun RealHorizontalScrollbar(
is ScrollStateScrollbarAdapter -> {
Modifier.drawScrollbar(adapter.scrollState, Orientation.Horizontal, reverseLayout)
}
is LazyListStateScrollbarAdapter -> {
Modifier.drawScrollbar(adapter.lazyListState, Orientation.Horizontal, reverseLayout)
}
else -> Modifier
}
Box(modifier then Modifier.fillMaxSize() then scrollbarModifier)
}
@Composable
actual fun rememberScrollbarAdapter(scrollState: ScrollState): ScrollbarAdapter {
return remember(scrollState) {
actual fun rememberScrollbarAdapter(scrollState: ScrollState): ScrollbarAdapter =
remember(scrollState) {
ScrollStateScrollbarAdapter(scrollState)
}
}
@Composable
actual fun rememberScrollbarAdapter(scrollState: LazyListState): ScrollbarAdapter {
return remember(scrollState) {
actual fun rememberScrollbarAdapter(scrollState: LazyListState): ScrollbarAdapter =
remember(scrollState) {
LazyListStateScrollbarAdapter(scrollState)
}
}
@Composable
internal actual fun realRememberVerticalScrollbarAdapter(
scrollState: LazyGridState,
gridCells: GridCells,
arrangement: Arrangement.Vertical?,
): ScrollbarAdapter {
return remember(scrollState, gridCells) {
): ScrollbarAdapter =
remember(scrollState, gridCells) {
LazyGridStateScrollbarAdapter(scrollState, gridCells, arrangement?.spacing ?: Dp.Hairline)
}
}
@Composable
internal actual fun realRememberHorizontalScrollbarAdapter(
scrollState: LazyGridState,
gridCells: GridCells,
arrangement: Arrangement.Horizontal?,
): ScrollbarAdapter {
return remember(scrollState, gridCells) {
): ScrollbarAdapter =
remember(scrollState, gridCells) {
LazyGridStateScrollbarAdapter(scrollState, gridCells, arrangement?.spacing ?: Dp.Hairline)
}
}
actual fun Modifier.scrollbarPadding() = this

View File

@@ -98,14 +98,17 @@ fun ImageLoaderImage(
error.value = action.error
ImageLoaderImageState.Failure
}
is ImageAction.Loading -> {
progress.value = 0.0F
ImageLoaderImageState.Loading
}
is ImageAction.Success -> {
progress.value = 1.0F
ImageLoaderImageState.Success
}
else -> {
ImageLoaderImageState.Loading
}
@@ -117,6 +120,7 @@ fun ImageLoaderImage(
ImageLoaderImageState.Loading -> if (onLoading != null) {
onLoading(progress.value)
}
ImageLoaderImageState.Success -> Image(
painter = rememberImageActionPainter(
imageAction,
@@ -129,6 +133,7 @@ fun ImageLoaderImage(
alpha = alpha,
colorFilter = colorFilter,
)
ImageLoaderImageState.Failure -> {
if (onFailure != null) {
onFailure(error.value ?: return@Crossfade)

View File

@@ -300,9 +300,7 @@ private fun lazyListSnapLayoutInfoProvider(
lowerBound: Float,
upperBound: Float,
): Float {
fun Float.isValidDistance(): Boolean {
return this != Float.POSITIVE_INFINITY && this != Float.NEGATIVE_INFINITY
}
fun Float.isValidDistance(): Boolean = this != Float.POSITIVE_INFINITY && this != Float.NEGATIVE_INFINITY
val finalDistance = when (sign(velocity)) {
0f -> {
@@ -314,7 +312,9 @@ private fun lazyListSnapLayoutInfoProvider(
}
1f -> upperBound
-1f -> lowerBound
else -> 0f
}

View File

@@ -81,12 +81,15 @@ internal actual fun RealVerticalScrollbar(
is ScrollStateScrollbarAdapter -> {
Modifier.drawScrollbar(adapter.scrollState, Orientation.Vertical, reverseLayout)
}
is LazyListStateScrollbarAdapter -> {
Modifier.drawScrollbar(adapter.lazyListState, Orientation.Vertical, reverseLayout)
}
is LazyGridStateScrollbarAdapter -> {
Modifier.drawScrollbar(adapter.lazyGridState, adapter.gridCells, adapter.spacing, Orientation.Vertical, reverseLayout)
}
else -> Modifier
}
Box(modifier then Modifier.fillMaxSize() then scrollbarModifier)
@@ -104,49 +107,47 @@ internal actual fun RealHorizontalScrollbar(
is ScrollStateScrollbarAdapter -> {
Modifier.drawScrollbar(adapter.scrollState, Orientation.Horizontal, reverseLayout)
}
is LazyListStateScrollbarAdapter -> {
Modifier.drawScrollbar(adapter.lazyListState, Orientation.Horizontal, reverseLayout)
}
else -> Modifier
}
Box(modifier then Modifier.fillMaxSize() then scrollbarModifier)
}
@Composable
actual fun rememberScrollbarAdapter(scrollState: ScrollState): ScrollbarAdapter {
return remember(scrollState) {
actual fun rememberScrollbarAdapter(scrollState: ScrollState): ScrollbarAdapter =
remember(scrollState) {
ScrollStateScrollbarAdapter(scrollState)
}
}
@Composable
actual fun rememberScrollbarAdapter(scrollState: LazyListState): ScrollbarAdapter {
return remember(scrollState) {
actual fun rememberScrollbarAdapter(scrollState: LazyListState): ScrollbarAdapter =
remember(scrollState) {
LazyListStateScrollbarAdapter(scrollState)
}
}
@Composable
internal actual fun realRememberVerticalScrollbarAdapter(
scrollState: LazyGridState,
gridCells: GridCells,
arrangement: Arrangement.Vertical?,
): ScrollbarAdapter {
return remember(scrollState, gridCells) {
): ScrollbarAdapter =
remember(scrollState, gridCells) {
LazyGridStateScrollbarAdapter(scrollState, gridCells, arrangement?.spacing ?: Dp.Hairline)
}
}
@Composable
internal actual fun realRememberHorizontalScrollbarAdapter(
scrollState: LazyGridState,
gridCells: GridCells,
arrangement: Arrangement.Horizontal?,
): ScrollbarAdapter {
return remember(scrollState, gridCells) {
): ScrollbarAdapter =
remember(scrollState, gridCells) {
LazyGridStateScrollbarAdapter(scrollState, gridCells, arrangement?.spacing ?: Dp.Hairline)
}
}
actual fun Modifier.scrollbarPadding() = this

View File

@@ -36,10 +36,9 @@ import platform.CoreGraphics.CGImageGetWidth
import platform.UIKit.UIImage
@Composable
actual fun ImageResource.toPainter(): Painter {
return remember { toUIImage()?.toSkiaImage()?.toComposeImageBitmap()?.let(::BitmapPainter) }
actual fun ImageResource.toPainter(): Painter =
remember { toUIImage()?.toSkiaImage()?.toComposeImageBitmap()?.let(::BitmapPainter) }
?: rememberVectorPainter(Icons.Rounded.BrokenImage)
}
// Taken from https://github.com/touchlab/DroidconKotlin/blob/main/shared-ui/src/iosMain/kotlin/co/touchlab/droidcon/ui/util/ToSkiaImage.kt
// TODO: Add support for remaining color spaces when the Skia library supports them.
@@ -60,13 +59,16 @@ private fun UIImage.toSkiaImage(): Image? {
CGImageAlphaInfo.kCGImageAlphaPremultipliedFirst,
CGImageAlphaInfo.kCGImageAlphaPremultipliedLast,
-> ColorAlphaType.PREMUL
CGImageAlphaInfo.kCGImageAlphaFirst,
CGImageAlphaInfo.kCGImageAlphaLast,
-> ColorAlphaType.UNPREMUL
CGImageAlphaInfo.kCGImageAlphaNone,
CGImageAlphaInfo.kCGImageAlphaNoneSkipFirst,
CGImageAlphaInfo.kCGImageAlphaNoneSkipLast,
-> ColorAlphaType.OPAQUE
else -> ColorAlphaType.UNKNOWN
}