diff --git a/androidApp/src/main/java/com/m3u/androidApp/AppPublisher.kt b/androidApp/src/main/java/com/m3u/androidApp/AppPublisher.kt index 13db11e72..b4e0510f4 100644 --- a/androidApp/src/main/java/com/m3u/androidApp/AppPublisher.kt +++ b/androidApp/src/main/java/com/m3u/androidApp/AppPublisher.kt @@ -4,7 +4,7 @@ import android.app.Application import android.os.Build import com.m3u.core.architecture.Abi import com.m3u.core.architecture.Publisher -import com.m3u.material.ktx.isTelevision +import com.m3u.core.util.context.isTv import javax.inject.Inject class AppPublisher @Inject constructor(private val application: Application) : Publisher { @@ -13,9 +13,9 @@ class AppPublisher @Inject constructor(private val application: Application) : P override val versionCode: Int = BuildConfig.VERSION_CODE override val debug: Boolean = BuildConfig.DEBUG override val snapshot: Boolean = BuildConfig.FLAVOR.contains("snapshotChannel", true) - override val lite: Boolean = BuildConfig.FLAVOR.contains("liteCodec" , true) + override val lite: Boolean = BuildConfig.FLAVOR.contains("liteCodec", true) override val model: String = Build.MODEL override val abi: Abi = Abi.of(Build.SUPPORTED_ABIS[0]) override val isTelevision: Boolean - get() = application.resources.configuration.isTelevision() + get() = application.resources.configuration.isTv } \ No newline at end of file diff --git a/core/src/main/java/com/m3u/core/architecture/logger/Logger.kt b/core/src/main/java/com/m3u/core/architecture/logger/Logger.kt index cbb3ed350..666d05742 100644 --- a/core/src/main/java/com/m3u/core/architecture/logger/Logger.kt +++ b/core/src/main/java/com/m3u/core/architecture/logger/Logger.kt @@ -24,3 +24,65 @@ interface Logger { @Retention(AnnotationRetention.BINARY) annotation class MessageImpl } + +inline fun Logger.sandBox(block: () -> Unit) { + runCatching { block() }.onFailure { log(it) } +} + +inline fun Logger.execute(block: () -> R): R? = runCatching { block() } + .onFailure { + log( + throwable = it, + level = Message.LEVEL_ERROR, + ) + } + .getOrNull() + +fun Logger.post(level: Int = Message.LEVEL_INFO, block: () -> Any?) { + val result = runCatching { block() } + if (result.isSuccess) { + log( + text = result.getOrNull().toString(), + level = level + ) + } else { + log( + throwable = result.exceptionOrNull()!!, + level = Message.LEVEL_ERROR + ) + } +} + +fun Logger.install(profile: Profile): Logger = PrefixLogger( + LevelLogger(this, profile.level), profile.name +) + +private class LevelLogger( + private val delegate: Logger, + private val limitLevel: Int +) : Logger { + override fun log(text: String, level: Int, tag: String, duration: Duration, type: Int) { + if (limitLevel <= level) { + delegate.log(text, level, tag, duration, type) + } + } + + override fun log(throwable: Throwable, level: Int, tag: String) { + if (limitLevel >= level) { + delegate.log(throwable, level, tag) + } + } +} + +private class PrefixLogger( + private val delegate: Logger, + private val prefix: String +) : Logger { + override fun log(text: String, level: Int, tag: String, duration: Duration, type: Int) { + delegate.log("${prefix}: $text", level, tag, duration, type) + } + + override fun log(throwable: Throwable, level: Int, tag: String) { + delegate.log(RuntimeException(prefix, throwable), level, tag) + } +} diff --git a/core/src/main/java/com/m3u/core/architecture/logger/Loggers.kt b/core/src/main/java/com/m3u/core/architecture/logger/Loggers.kt deleted file mode 100644 index 841f5a923..000000000 --- a/core/src/main/java/com/m3u/core/architecture/logger/Loggers.kt +++ /dev/null @@ -1,66 +0,0 @@ -package com.m3u.core.architecture.logger - -import com.m3u.core.wrapper.Message -import kotlin.time.Duration - -inline fun Logger.sandBox(block: () -> Unit) { - runCatching { block() }.onFailure { log(it) } -} - -inline fun Logger.execute(block: () -> R): R? = runCatching { block() } - .onFailure { - log( - throwable = it, - level = Message.LEVEL_ERROR, - ) - } - .getOrNull() - -fun Logger.post(level: Int = Message.LEVEL_INFO, block: () -> Any?) { - val result = runCatching { block() } - if (result.isSuccess) { - log( - text = result.getOrNull().toString(), - level = level - ) - } else { - log( - throwable = result.exceptionOrNull()!!, - level = Message.LEVEL_ERROR - ) - } -} - -fun Logger.install(profile: Profile): Logger = PrefixLogger( - LevelLogger(this, profile.level), profile.name -) - -private class LevelLogger( - private val delegate: Logger, - private val limitLevel: Int -) : Logger { - override fun log(text: String, level: Int, tag: String, duration: Duration, type: Int) { - if (limitLevel <= level) { - delegate.log(text, level, tag, duration, type) - } - } - - override fun log(throwable: Throwable, level: Int, tag: String) { - if (limitLevel >= level) { - delegate.log(throwable, level, tag) - } - } -} - -private class PrefixLogger( - private val delegate: Logger, - private val prefix: String -) : Logger { - override fun log(text: String, level: Int, tag: String, duration: Duration, type: Int) { - delegate.log("${prefix}: $text", level, tag, duration, type) - } - - override fun log(throwable: Throwable, level: Int, tag: String) { - delegate.log(RuntimeException(prefix, throwable), level, tag) - } -} diff --git a/core/src/main/java/com/m3u/core/architecture/preferences/annotation/ClipMode.kt b/core/src/main/java/com/m3u/core/architecture/preferences/ClipMode.kt similarity index 85% rename from core/src/main/java/com/m3u/core/architecture/preferences/annotation/ClipMode.kt rename to core/src/main/java/com/m3u/core/architecture/preferences/ClipMode.kt index 211d9b38a..1f7a81e28 100644 --- a/core/src/main/java/com/m3u/core/architecture/preferences/annotation/ClipMode.kt +++ b/core/src/main/java/com/m3u/core/architecture/preferences/ClipMode.kt @@ -1,4 +1,4 @@ -package com.m3u.core.architecture.preferences.annotation +package com.m3u.core.architecture.preferences @Target( AnnotationTarget.CLASS, diff --git a/core/src/main/java/com/m3u/core/architecture/preferences/annotation/ConnectTimeout.kt b/core/src/main/java/com/m3u/core/architecture/preferences/ConnectTimeout.kt similarity index 84% rename from core/src/main/java/com/m3u/core/architecture/preferences/annotation/ConnectTimeout.kt rename to core/src/main/java/com/m3u/core/architecture/preferences/ConnectTimeout.kt index 89e77a090..36fa4e8ce 100644 --- a/core/src/main/java/com/m3u/core/architecture/preferences/annotation/ConnectTimeout.kt +++ b/core/src/main/java/com/m3u/core/architecture/preferences/ConnectTimeout.kt @@ -1,4 +1,4 @@ -package com.m3u.core.architecture.preferences.annotation +package com.m3u.core.architecture.preferences @Target( AnnotationTarget.CLASS, diff --git a/core/src/main/java/com/m3u/core/architecture/preferences/LocalPreferences.kt b/core/src/main/java/com/m3u/core/architecture/preferences/LocalPreferences.kt deleted file mode 100644 index 77f136e7a..000000000 --- a/core/src/main/java/com/m3u/core/architecture/preferences/LocalPreferences.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.m3u.core.architecture.preferences - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.platform.LocalContext -import dagger.hilt.EntryPoint -import dagger.hilt.InstallIn -import dagger.hilt.android.EntryPointAccessors -import dagger.hilt.components.SingletonComponent - -@Composable -fun hiltPreferences(): Preferences { - val context = LocalContext.current - return remember { - val applicationContext = context.applicationContext ?: throw IllegalStateException() - EntryPointAccessors - .fromApplication(applicationContext) - .preferences - } -} - -@EntryPoint -@InstallIn(SingletonComponent::class) -private interface PreferencesEntryPoint { - val preferences: Preferences -} \ No newline at end of file diff --git a/core/src/main/java/com/m3u/core/architecture/preferences/annotation/PlaylistStrategy.kt b/core/src/main/java/com/m3u/core/architecture/preferences/PlaylistStrategy.kt similarity index 83% rename from core/src/main/java/com/m3u/core/architecture/preferences/annotation/PlaylistStrategy.kt rename to core/src/main/java/com/m3u/core/architecture/preferences/PlaylistStrategy.kt index e9ba098a8..da5f86a43 100644 --- a/core/src/main/java/com/m3u/core/architecture/preferences/annotation/PlaylistStrategy.kt +++ b/core/src/main/java/com/m3u/core/architecture/preferences/PlaylistStrategy.kt @@ -1,4 +1,4 @@ -package com.m3u.core.architecture.preferences.annotation +package com.m3u.core.architecture.preferences @Target( AnnotationTarget.CLASS, diff --git a/core/src/main/java/com/m3u/core/architecture/preferences/Preferences.kt b/core/src/main/java/com/m3u/core/architecture/preferences/Preferences.kt index 323558815..3870bba4f 100644 --- a/core/src/main/java/com/m3u/core/architecture/preferences/Preferences.kt +++ b/core/src/main/java/com/m3u/core/architecture/preferences/Preferences.kt @@ -2,21 +2,40 @@ package com.m3u.core.architecture.preferences import android.content.Context import android.content.SharedPreferences +import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import com.m3u.core.architecture.preferences.annotation.ClipMode -import com.m3u.core.architecture.preferences.annotation.ConnectTimeout -import com.m3u.core.architecture.preferences.annotation.PlaylistStrategy -import com.m3u.core.architecture.preferences.annotation.ReconnectMode -import com.m3u.core.architecture.preferences.annotation.UnseensMilliseconds +import androidx.compose.ui.platform.LocalContext import com.m3u.core.util.context.booleanAsState import com.m3u.core.util.context.intAsState import com.m3u.core.util.context.longAsState +import dagger.hilt.EntryPoint +import dagger.hilt.InstallIn +import dagger.hilt.android.EntryPointAccessors import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent import javax.inject.Inject import javax.inject.Singleton +@Composable +fun hiltPreferences(): Preferences { + val context = LocalContext.current + return remember { + val applicationContext = context.applicationContext ?: throw IllegalStateException() + EntryPointAccessors + .fromApplication(applicationContext) + .preferences + } +} + +@EntryPoint +@InstallIn(SingletonComponent::class) +private interface PreferencesEntryPoint { + val preferences: Preferences +} + @Stable @Singleton class Preferences @Inject constructor( diff --git a/core/src/main/java/com/m3u/core/architecture/preferences/annotation/ReconnectMode.kt b/core/src/main/java/com/m3u/core/architecture/preferences/ReconnectMode.kt similarity index 85% rename from core/src/main/java/com/m3u/core/architecture/preferences/annotation/ReconnectMode.kt rename to core/src/main/java/com/m3u/core/architecture/preferences/ReconnectMode.kt index 0f6ada1d8..5e4bef410 100644 --- a/core/src/main/java/com/m3u/core/architecture/preferences/annotation/ReconnectMode.kt +++ b/core/src/main/java/com/m3u/core/architecture/preferences/ReconnectMode.kt @@ -1,4 +1,4 @@ -package com.m3u.core.architecture.preferences.annotation +package com.m3u.core.architecture.preferences @Target( AnnotationTarget.CLASS, diff --git a/core/src/main/java/com/m3u/core/architecture/preferences/annotation/UnseensMilliseconds.kt b/core/src/main/java/com/m3u/core/architecture/preferences/UnseensMilliseconds.kt similarity index 88% rename from core/src/main/java/com/m3u/core/architecture/preferences/annotation/UnseensMilliseconds.kt rename to core/src/main/java/com/m3u/core/architecture/preferences/UnseensMilliseconds.kt index 7188b9abf..067cd26b7 100644 --- a/core/src/main/java/com/m3u/core/architecture/preferences/annotation/UnseensMilliseconds.kt +++ b/core/src/main/java/com/m3u/core/architecture/preferences/UnseensMilliseconds.kt @@ -1,4 +1,4 @@ -package com.m3u.core.architecture.preferences.annotation +package com.m3u.core.architecture.preferences @Target( AnnotationTarget.CLASS, diff --git a/core/src/main/java/com/m3u/core/util/Files.kt b/core/src/main/java/com/m3u/core/util/Files.kt index 8db0977d2..dc99f3853 100644 --- a/core/src/main/java/com/m3u/core/util/Files.kt +++ b/core/src/main/java/com/m3u/core/util/Files.kt @@ -32,4 +32,4 @@ fun Uri.readFileContent(resolver: ContentResolver): String? { else -> null } -} +} \ No newline at end of file diff --git a/core/src/main/java/com/m3u/core/util/Properties.kt b/core/src/main/java/com/m3u/core/util/Properties.kt deleted file mode 100644 index 2f539f3a5..000000000 --- a/core/src/main/java/com/m3u/core/util/Properties.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.m3u.core.util - -import java.util.Properties - -fun Properties.loadLine(line: String) { - val trim = line.trim() - val index = trim.indexOf("=") - if (index != -1) { - val key = trim.take(index) - val value = trim.drop(index + 1) - this.setProperty(key.trim(), value.trim()) - } -} diff --git a/core/src/main/java/com/m3u/core/util/basic/Strings.kt b/core/src/main/java/com/m3u/core/util/basic/Strings.kt index 32d383833..aede89692 100644 --- a/core/src/main/java/com/m3u/core/util/basic/Strings.kt +++ b/core/src/main/java/com/m3u/core/util/basic/Strings.kt @@ -5,13 +5,6 @@ package com.m3u.core.util.basic import androidx.compose.ui.text.capitalize import androidx.compose.ui.text.intl.Locale -fun String.trimBrackets(): String { - return if (this.isEmpty()) this - else if (this.length > 1 && this.firstOrNull() == '\"' && this.lastOrNull() == '\"') { - this.substring(1 until this.lastIndex) - } else this -} - fun String.title(): String { if (this.isEmpty()) return this val split = this.split(" ") @@ -21,44 +14,11 @@ fun String.title(): String { ) } -fun String.loopOutOfQuotation(block: (Char) -> Unit) { - var flag = false - this.forEach { - if (it == '\"' || it == '\'') flag = !flag - if (!flag) block(it) - } -} - -fun String.splitOutOfQuotation(delimiter: Char): List { - val list = mutableListOf() - var start = 0 - var inQuotes = false - var quoteChar: Char? = null - forEachIndexed { i, c -> - if (c == '\'' || c == '\"') { - if (!inQuotes) { - inQuotes = true - quoteChar = c - } else if (quoteChar == c) { - inQuotes = false - quoteChar = null - } - } - if (c == delimiter && !inQuotes) { - list.add(substring(start, i)) - start = i + 1 - } - } - list.add(substring(start)) - return list -} - fun String.startsWithAny(vararg prefix: String, ignoreCase: Boolean = false): Boolean { - prefix.forEach { - if (startsWith(it, ignoreCase)) return true - } - return false + return prefix.any { startsWith(it, ignoreCase) } } -fun String.startWithHttpScheme(): Boolean = - startsWithAny("http://", "https://", ignoreCase = true) \ No newline at end of file +fun String.startWithHttpScheme(): Boolean = startsWithAny( + "http://", "https://", + ignoreCase = true +) \ No newline at end of file diff --git a/core/src/main/java/com/m3u/core/util/collections/LoopIn.kt b/core/src/main/java/com/m3u/core/util/collections/LoopIn.kt deleted file mode 100644 index 56b943f07..000000000 --- a/core/src/main/java/com/m3u/core/util/collections/LoopIn.kt +++ /dev/null @@ -1,38 +0,0 @@ -@file:Suppress("unused") -package com.m3u.core.util.collections - -/** - * WARNING! This [loopIn] version may throw an error after block looping - * if the range is not suitable for your iterable. - * - * So make sure providing a suitable range. - * @see Collection.loopIn - */ -inline fun Iterable.loopIn(range: IntRange, block: (E) -> Unit) { - if (range.first < 0 || range.first > range.last) throw UnsuitableRangeForIterable(this, range) - var i = 0 - forEachIndexed { index, e -> - if (range.contains(index)) { - block(e) - i++ - } - } - - if (i != range.last - range.first + 1) { - throw UnsuitableRangeForIterable(this, range, true) - } -} - -inline fun Collection.loopIn(range: IntRange = indices, block: (E) -> Unit) { - if (range.first < 0 || range.first > range.last) { - throw UnsuitableRangeForIterable(this, range) - } - if (range.last > size - 1) { - throw UnsuitableRangeForIterable(this, range, true) - } - forEachIndexed { index, e -> - if (range.contains(index)) { - block(e) - } - } -} diff --git a/core/src/main/java/com/m3u/core/util/collections/Map.kt b/core/src/main/java/com/m3u/core/util/collections/Map.kt deleted file mode 100644 index 5916d9655..000000000 --- a/core/src/main/java/com/m3u/core/util/collections/Map.kt +++ /dev/null @@ -1,4 +0,0 @@ -package com.m3u.core.util.collections - -@Suppress("UNCHECKED_CAST") -fun Map.filterNotNullKeys(): Map = this.filterKeys { it != null } as Map diff --git a/core/src/main/java/com/m3u/core/util/collections/ReplaceIf.kt b/core/src/main/java/com/m3u/core/util/collections/ReplaceIf.kt deleted file mode 100644 index 4b93cf056..000000000 --- a/core/src/main/java/com/m3u/core/util/collections/ReplaceIf.kt +++ /dev/null @@ -1,23 +0,0 @@ -@file:Suppress("unused") -package com.m3u.core.util.collections - -inline fun Collection.replaceIf( - predicate: (E) -> Boolean, - transform: (E) -> E -): Collection { - val collection = this.toMutableList() - forEachIndexed { index, element -> - if (predicate(element)) { - val newElement = transform(element) - collection[index] = newElement - } - } - return collection -} - -inline fun List.replaceIf( - predicate: (E) -> Boolean, - transform: (E) -> E -): List { - return (this as Collection).replaceIf(predicate, transform).toList() -} diff --git a/core/src/main/java/com/m3u/core/util/collections/UnsuitableRangeForIterable.kt b/core/src/main/java/com/m3u/core/util/collections/UnsuitableRangeForIterable.kt deleted file mode 100644 index 99ed84d1c..000000000 --- a/core/src/main/java/com/m3u/core/util/collections/UnsuitableRangeForIterable.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.m3u.core.util.collections - -class UnsuitableRangeForIterable( - iterable: Iterable, - range: IntRange, - tryUntil: Boolean = false -) : Exception( - buildString { - append("The range($range) is not suit for your iterable($iterable).") - if (tryUntil) append(" Try \"util\" instead of \"..\".") - } -) diff --git a/core/src/main/java/com/m3u/core/util/collections/WithEach.kt b/core/src/main/java/com/m3u/core/util/collections/WithEach.kt deleted file mode 100644 index 412dc6d6a..000000000 --- a/core/src/main/java/com/m3u/core/util/collections/WithEach.kt +++ /dev/null @@ -1,18 +0,0 @@ -@file:Suppress("unused") -package com.m3u.core.util.collections - -inline fun Array.withEach(block: E.() -> Unit) { - forEach(block) -} - -inline fun Collection.withEach(block: E.() -> Unit) { - forEach(block) -} - -inline fun Array.withEachNotNull(block: E.() -> Unit) { - forEachNotNull(block) -} - -inline fun Collection.withEachNotNull(block: E.() -> Unit) { - forEachNotNull(block) -} diff --git a/core/src/main/java/com/m3u/core/util/context/Configuration.kt b/core/src/main/java/com/m3u/core/util/context/Configuration.kt index 32f84e6d5..8b06129b5 100644 --- a/core/src/main/java/com/m3u/core/util/context/Configuration.kt +++ b/core/src/main/java/com/m3u/core/util/context/Configuration.kt @@ -7,3 +7,9 @@ val Configuration.isPortraitMode: Boolean val Configuration.isDarkMode: Boolean get() = uiMode == Configuration.UI_MODE_NIGHT_YES + +val Configuration.isTv: Boolean + get() { + val type = uiMode and Configuration.UI_MODE_TYPE_MASK + return type == Configuration.UI_MODE_TYPE_TELEVISION + } \ No newline at end of file diff --git a/core/src/main/java/com/m3u/core/util/context/ResourceDecoder.kt b/core/src/main/java/com/m3u/core/util/context/ResourceDecoder.kt deleted file mode 100644 index 29af6cc47..000000000 --- a/core/src/main/java/com/m3u/core/util/context/ResourceDecoder.kt +++ /dev/null @@ -1,48 +0,0 @@ -@file:Suppress("unused") -package com.m3u.core.util.context - -import android.content.Context -import android.content.res.Resources - -object ResourceDecoder { - fun decodeDrawableIds(context: Context, clazz: Class<*>): List = - decodeDrawableIds( - resources = context.resources, - packageName = context.packageName, - clazz = clazz - ) - - fun decodeDrawableIds( - resources: Resources, - packageName: String, - clazz: Class<*> - ): List = decodeIds(resources, packageName, clazz, "drawable") - - fun decodeStringIds(context: Context, clazz: Class<*>): List = - decodeStringIds( - resources = context.resources, - packageName = context.packageName, - clazz = clazz - ) - - fun decodeStringIds( - resources: Resources, - packageName: String, - clazz: Class<*> - ): List = decodeIds(resources, packageName, clazz, "string") - - private fun decodeIds( - resources: Resources, - packageName: String, - clazz: Class<*>, - defType: String - ): List = clazz.declaredFields - .onEach { field -> - field.isAccessible = true - } - .map { field -> - val name = field.name - @Suppress("DiscouragedApi") - resources.getIdentifier(name, defType, packageName) - } -} diff --git a/core/src/main/java/com/m3u/core/util/coroutine/Element.kt b/core/src/main/java/com/m3u/core/util/coroutine/Element.kt deleted file mode 100644 index 9bede2c31..000000000 --- a/core/src/main/java/com/m3u/core/util/coroutine/Element.kt +++ /dev/null @@ -1,88 +0,0 @@ -@file:Suppress("unused") - -package com.m3u.core.util.coroutine - -import kotlinx.coroutines.Job -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch - -@JvmName("onIterableEachElement") -inline fun Flow>.onEachElement( - crossinline block: suspend (T) -> Unit -): Flow> { - var job: Job? = null - return onEach { collection -> - job?.cancel() - job = coroutineScope { - launch { - collection.forEach { - block(it) - } - } - } - } -} - -@JvmName("mapIterableElement") -inline fun Flow>.mapElement( - crossinline block: (T) -> R -): Flow> { - return map { element -> - element.map { - block(it) - } - } -} - -@JvmName("onCollectionEachElement") -inline fun Flow>.onEachElement( - crossinline block: suspend (T) -> Unit -): Flow> { - var job: Job? = null - return onEach { collection -> - job?.cancel() - job = coroutineScope { - launch { - collection.forEach { - block(it) - } - } - } - } -} - -@JvmName("mapCollectionElement") -inline fun Flow>.mapElement( - crossinline block: (T) -> R -): Flow> { - return map { element -> - element.map { - block(it) - } - } -} - -@JvmName("onListEachElement") -inline fun Flow>.onEachElement( - crossinline block: (T) -> Unit -): Flow> { - return onEach { collection -> - collection.forEach { - block(it) - } - } -} - -@JvmName("mapListElement") -inline fun Flow>.mapElement( - crossinline block: (T) -> R -): Flow> { - return map { element -> - element.map { - block(it) - } - } -} diff --git a/core/src/main/java/com/m3u/core/util/coroutine/Flows.kt b/core/src/main/java/com/m3u/core/util/coroutine/Flows.kt index f653188e4..2203fd5bc 100644 --- a/core/src/main/java/com/m3u/core/util/coroutine/Flows.kt +++ b/core/src/main/java/com/m3u/core/util/coroutine/Flows.kt @@ -11,8 +11,8 @@ import kotlinx.coroutines.flow.timeout import kotlin.time.Duration @OptIn(FlowPreview::class) -fun Flow.onTimeout(duration: Duration, block: FlowCollector.() -> Unit) = - timeout(duration).catch { +fun Flow.timeout(duration: Duration, block: FlowCollector.() -> Unit) = + this@timeout.timeout(duration).catch { if (it is TimeoutCancellationException) { block() } diff --git a/core/src/main/java/com/m3u/core/util/transform/IntIterativeTransferable.kt b/core/src/main/java/com/m3u/core/util/transform/IntIterativeTransferable.kt deleted file mode 100644 index db87bfaf4..000000000 --- a/core/src/main/java/com/m3u/core/util/transform/IntIterativeTransferable.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.m3u.core.util.transform - -object IntIterativeTransferable : IterativeTransferable() { - override fun transferElement(element: Int): String = element.toString() - override fun acceptElement(s: String): Int = s.toInt() - override fun affirmedElement(c: Char): Boolean = c.isDigit() -} diff --git a/core/src/main/java/com/m3u/core/util/transform/IterativeTransferable.kt b/core/src/main/java/com/m3u/core/util/transform/IterativeTransferable.kt deleted file mode 100644 index a15fe9bad..000000000 --- a/core/src/main/java/com/m3u/core/util/transform/IterativeTransferable.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.m3u.core.util.transform - -abstract class IterativeTransferable : Transferable> { - abstract fun affirmedElement(c: Char): Boolean - abstract fun transferElement(element: T): String - final override fun transfer(src: Iterable): String { - return src.joinToString( - prefix = "[", - postfix = "]", - separator = ",", - transform = ::transferElement - ) - } - - abstract fun acceptElement(s: String): T - final override fun accept(dest: String): Iterable = buildList { - var current = "" - dest.trim().forEachIndexed { index, c -> - if (index == 0 && c != '[') return emptyList() - if (index == dest.lastIndex && c != ']') return emptyList() - if (c == ',') { - if (current.isNotEmpty()) add(acceptElement(current)) - current = "" - } else if (affirmedElement(c)) { - current += c - } - } - if (current.isNotEmpty()) { - add(acceptElement(current)) - } - } -} diff --git a/core/src/main/java/com/m3u/core/util/transform/Transferable.kt b/core/src/main/java/com/m3u/core/util/transform/Transferable.kt deleted file mode 100644 index cb0ae59aa..000000000 --- a/core/src/main/java/com/m3u/core/util/transform/Transferable.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.m3u.core.util.transform - -interface Transferable { - fun transfer(src: T): String - fun accept(dest: String): T -} diff --git a/core/src/main/java/com/m3u/core/wrapper/Process.kt b/core/src/main/java/com/m3u/core/wrapper/Process.kt deleted file mode 100644 index 51aaa9dc6..000000000 --- a/core/src/main/java/com/m3u/core/wrapper/Process.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.m3u.core.wrapper - -import androidx.compose.runtime.Immutable -import kotlinx.coroutines.flow.FlowCollector -import kotlinx.coroutines.flow.flow -import kotlin.experimental.ExperimentalTypeInference - -@Immutable -sealed class Process { - data class Loading(val value: Percent) : Process() - data class Success(val data: T) : Process() - data class Failure(val message: String?) : Process() -} - -@JvmInline -value class Percent(val value: Int) { - init { - check(value in 0..100) - } -} - -val Int.pt: Percent get() = Percent(this) - -@OptIn(ExperimentalTypeInference::class) -fun processFlow(@BuilderInference block: suspend FlowCollector>.() -> Unit) = - flow { - emit(Process.Loading(0.pt)) - block() - } - - -suspend fun FlowCollector>.emitResource(value: T) = - emit(Process.Success(value)) - -suspend fun FlowCollector>.emitMessage(message: String?) = - emit(Process.Failure(message)) - -suspend fun FlowCollector>.emitException(exception: Exception?) = - emitMessage(exception?.message) diff --git a/core/src/main/java/com/m3u/core/wrapper/Stored.kt b/core/src/main/java/com/m3u/core/wrapper/Stored.kt deleted file mode 100644 index 00e48aec1..000000000 --- a/core/src/main/java/com/m3u/core/wrapper/Stored.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.m3u.core.wrapper - -interface Stored { - fun R.restore(): T - fun store(): R -} diff --git a/data/src/main/java/com/m3u/data/repository/playlist/PlaylistRepositoryImpl.kt b/data/src/main/java/com/m3u/data/repository/playlist/PlaylistRepositoryImpl.kt index 0324c4778..fd21c1ec6 100644 --- a/data/src/main/java/com/m3u/data/repository/playlist/PlaylistRepositoryImpl.kt +++ b/data/src/main/java/com/m3u/data/repository/playlist/PlaylistRepositoryImpl.kt @@ -14,7 +14,7 @@ import com.m3u.core.architecture.logger.install import com.m3u.core.architecture.logger.post import com.m3u.core.architecture.logger.sandBox import com.m3u.core.architecture.preferences.Preferences -import com.m3u.core.architecture.preferences.annotation.PlaylistStrategy +import com.m3u.core.architecture.preferences.PlaylistStrategy import com.m3u.core.util.basic.startsWithAny import com.m3u.core.util.readFileContent import com.m3u.core.util.readFileName diff --git a/data/src/main/java/com/m3u/data/repository/television/TelevisionRepositoryImpl.kt b/data/src/main/java/com/m3u/data/repository/television/TelevisionRepositoryImpl.kt index 09553c595..100aefce3 100644 --- a/data/src/main/java/com/m3u/data/repository/television/TelevisionRepositoryImpl.kt +++ b/data/src/main/java/com/m3u/data/repository/television/TelevisionRepositoryImpl.kt @@ -9,7 +9,7 @@ import com.m3u.core.architecture.logger.Logger import com.m3u.core.architecture.logger.Profiles import com.m3u.core.architecture.logger.install import com.m3u.core.architecture.preferences.Preferences -import com.m3u.core.util.coroutine.onTimeout +import com.m3u.core.util.coroutine.timeout import com.m3u.core.wrapper.Resource import com.m3u.core.wrapper.asResource import com.m3u.data.api.LocalPreparedService @@ -127,7 +127,7 @@ class TelevisionRepositoryImpl @Inject constructor( val completed = nsdDeviceManager .search() .onStart { trySendBlocking(ConnectionToTelevisionValue.Searching) } - .onTimeout(timeout) { + .timeout(timeout) { logger.log("pair: timeout") trySendBlocking(ConnectionToTelevisionValue.Timeout) } diff --git a/data/src/main/java/com/m3u/data/service/internal/FileProviderImpl.kt b/data/src/main/java/com/m3u/data/service/internal/FileProviderImpl.kt index d8c644e9a..df5630ab3 100644 --- a/data/src/main/java/com/m3u/data/service/internal/FileProviderImpl.kt +++ b/data/src/main/java/com/m3u/data/service/internal/FileProviderImpl.kt @@ -36,7 +36,7 @@ class FileProviderImpl @Inject constructor( infoMap["name"] = packageInfo.versionName infoMap["code"] = packageInfo.code - readconfiguration().forEach(infoMap::put) + readConfiguration().forEach(infoMap::put) val info = infoMap.joinToString() val trace = getStackTraceMessage(value) @@ -69,7 +69,7 @@ class FileProviderImpl @Inject constructor( versionCode.toString() } - private fun readconfiguration(): Map = buildMap { + private fun readConfiguration(): Map = buildMap { Build::class.java.declaredFields.forEachNotNull { field -> try { field.isAccessible = true diff --git a/data/src/main/java/com/m3u/data/service/internal/PlayerManagerImpl.kt b/data/src/main/java/com/m3u/data/service/internal/PlayerManagerImpl.kt index afde37cba..37dd2216c 100644 --- a/data/src/main/java/com/m3u/data/service/internal/PlayerManagerImpl.kt +++ b/data/src/main/java/com/m3u/data/service/internal/PlayerManagerImpl.kt @@ -39,7 +39,7 @@ import com.m3u.core.architecture.logger.Profiles import com.m3u.core.architecture.logger.install import com.m3u.core.architecture.logger.post import com.m3u.core.architecture.preferences.Preferences -import com.m3u.core.architecture.preferences.annotation.ReconnectMode +import com.m3u.core.architecture.preferences.ReconnectMode import com.m3u.data.SSLs import com.m3u.data.api.OkhttpClient import com.m3u.data.database.model.Playlist diff --git a/features/setting/src/main/java/com/m3u/features/setting/fragments/preferences/OptionalPreferences.kt b/features/setting/src/main/java/com/m3u/features/setting/fragments/preferences/OptionalPreferences.kt index 7899442bf..d20e3b3b1 100644 --- a/features/setting/src/main/java/com/m3u/features/setting/fragments/preferences/OptionalPreferences.kt +++ b/features/setting/src/main/java/com/m3u/features/setting/fragments/preferences/OptionalPreferences.kt @@ -27,7 +27,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import com.m3u.core.architecture.preferences.hiltPreferences -import com.m3u.core.architecture.preferences.annotation.ReconnectMode +import com.m3u.core.architecture.preferences.ReconnectMode import com.m3u.core.util.basic.title import com.m3u.features.setting.components.CheckBoxSharedPreference import com.m3u.i18n.R.string diff --git a/features/setting/src/main/java/com/m3u/features/setting/fragments/preferences/RegularPreferences.kt b/features/setting/src/main/java/com/m3u/features/setting/fragments/preferences/RegularPreferences.kt index 6f8acf905..f0999938b 100644 --- a/features/setting/src/main/java/com/m3u/features/setting/fragments/preferences/RegularPreferences.kt +++ b/features/setting/src/main/java/com/m3u/features/setting/fragments/preferences/RegularPreferences.kt @@ -19,10 +19,10 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource -import com.m3u.core.architecture.preferences.annotation.ClipMode -import com.m3u.core.architecture.preferences.annotation.ConnectTimeout -import com.m3u.core.architecture.preferences.annotation.PlaylistStrategy -import com.m3u.core.architecture.preferences.annotation.UnseensMilliseconds +import com.m3u.core.architecture.preferences.ClipMode +import com.m3u.core.architecture.preferences.ConnectTimeout +import com.m3u.core.architecture.preferences.PlaylistStrategy +import com.m3u.core.architecture.preferences.UnseensMilliseconds import com.m3u.core.architecture.preferences.hiltPreferences import com.m3u.core.util.basic.title import com.m3u.features.setting.components.CheckBoxSharedPreference diff --git a/material/src/main/java/com/m3u/material/ktx/Tv.kt b/material/src/main/java/com/m3u/material/ktx/Tv.kt index d580b2839..8d353c283 100644 --- a/material/src/main/java/com/m3u/material/ktx/Tv.kt +++ b/material/src/main/java/com/m3u/material/ktx/Tv.kt @@ -21,12 +21,12 @@ val LocalAlwaysTelevision = compositionLocalOf { false } fun isTelevision(): Boolean { val alwaysTelevision = LocalAlwaysTelevision.current return if (alwaysTelevision) true - else LocalConfiguration.current.isTelevision() -} - -fun Configuration.isTelevision(): Boolean { - val type = uiMode and Configuration.UI_MODE_TYPE_MASK - return type == Configuration.UI_MODE_TYPE_TELEVISION + else { + LocalConfiguration.current.run { + val type = uiMode and Configuration.UI_MODE_TYPE_MASK + return type == Configuration.UI_MODE_TYPE_TELEVISION + } + } } /** diff --git a/ui/src/main/java/com/m3u/ui/Player.kt b/ui/src/main/java/com/m3u/ui/Player.kt index 8dc59dd78..8d50f03f8 100644 --- a/ui/src/main/java/com/m3u/ui/Player.kt +++ b/ui/src/main/java/com/m3u/ui/Player.kt @@ -10,7 +10,7 @@ import androidx.media3.common.Player import androidx.media3.common.util.UnstableApi import androidx.media3.ui.AspectRatioFrameLayout import androidx.media3.ui.PlayerView -import com.m3u.core.architecture.preferences.annotation.ClipMode +import com.m3u.core.architecture.preferences.ClipMode @Immutable data class PlayerState(