parent
f0f25a4d48
commit
02cc6c8bf2
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho
|
package org.xtimms.etsudoku
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho
|
package org.xtimms.etsudoku
|
||||||
|
|
||||||
import android.app.Instrumentation
|
import android.app.Instrumentation
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core
|
package org.xtimms.etsudoku.core
|
||||||
|
|
||||||
import androidx.compose.animation.core.Animatable
|
import androidx.compose.animation.core.Animatable
|
||||||
import androidx.compose.animation.core.AnimationVector1D
|
import androidx.compose.animation.core.AnimationVector1D
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
package org.xtimms.etsudoku.core.base
|
||||||
|
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.annotation.CallSuper
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
|
||||||
|
abstract class AlertDialogFragment<B : ViewBinding> : DialogFragment() {
|
||||||
|
|
||||||
|
var viewBinding: B? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
@Deprecated("", ReplaceWith("requireViewBinding()"))
|
||||||
|
protected val binding: B
|
||||||
|
get() = requireViewBinding()
|
||||||
|
|
||||||
|
final override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
val binding = onCreateViewBinding(layoutInflater, null)
|
||||||
|
viewBinding = binding
|
||||||
|
return MaterialAlertDialogBuilder(requireContext(), theme)
|
||||||
|
.setView(binding.root)
|
||||||
|
.run(::onBuildDialog)
|
||||||
|
.create()
|
||||||
|
.also(::onDialogCreated)
|
||||||
|
}
|
||||||
|
|
||||||
|
final override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?,
|
||||||
|
) = viewBinding?.root
|
||||||
|
|
||||||
|
final override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
onViewBindingCreated(requireViewBinding(), savedInstanceState)
|
||||||
|
}
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
|
override fun onDestroyView() {
|
||||||
|
viewBinding = null
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun onBuildDialog(builder: MaterialAlertDialogBuilder): MaterialAlertDialogBuilder = builder
|
||||||
|
|
||||||
|
open fun onDialogCreated(dialog: AlertDialog) = Unit
|
||||||
|
|
||||||
|
@Deprecated("", ReplaceWith("viewBinding"))
|
||||||
|
protected fun bindingOrNull() = viewBinding
|
||||||
|
|
||||||
|
fun requireViewBinding(): B = checkNotNull(viewBinding) {
|
||||||
|
"Fragment $this did not return a ViewBinding from onCreateView() or this was called before onCreateView()."
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun onCreateViewBinding(inflater: LayoutInflater, container: ViewGroup?): B
|
||||||
|
|
||||||
|
protected open fun onViewBindingCreated(binding: B, savedInstanceState: Bundle?) = Unit
|
||||||
|
}
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
package org.xtimms.etsudoku.core.base
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.WindowCompat
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
|
|
||||||
|
@Suppress("LeakingThis")
|
||||||
|
abstract class BaseActivity<B : ViewBinding> :
|
||||||
|
AppCompatActivity() {
|
||||||
|
|
||||||
|
lateinit var viewBinding: B
|
||||||
|
private set
|
||||||
|
|
||||||
|
private var defaultStatusBarColor = Color.TRANSPARENT
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
putDataToExtras(intent)
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNewIntent(intent: Intent?) {
|
||||||
|
putDataToExtras(intent)
|
||||||
|
super.onNewIntent(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("Use ViewBinding", level = DeprecationLevel.ERROR)
|
||||||
|
override fun setContentView(layoutResID: Int) {
|
||||||
|
super.setContentView(layoutResID)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("Use ViewBinding", level = DeprecationLevel.ERROR)
|
||||||
|
override fun setContentView(view: View?) {
|
||||||
|
super.setContentView(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun setContentView(binding: B) {
|
||||||
|
this.viewBinding = binding
|
||||||
|
super.setContentView(binding.root)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSupportNavigateUp(): Boolean {
|
||||||
|
dispatchNavigateUp()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun isDarkAmoledTheme(): Boolean {
|
||||||
|
val uiMode = resources.configuration.uiMode
|
||||||
|
return uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun dispatchNavigateUp() {
|
||||||
|
val upIntent = parentActivityIntent
|
||||||
|
if (upIntent != null) {
|
||||||
|
if (!navigateUpTo(upIntent)) {
|
||||||
|
startActivity(upIntent)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
finishAfterTransition()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun putDataToExtras(intent: Intent?) {
|
||||||
|
intent?.putExtra(EXTRA_DATA, intent.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
const val EXTRA_DATA = "data"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.base.event
|
package org.xtimms.etsudoku.core.base.event
|
||||||
|
|
||||||
interface PagedUiEvent : UiEvent {
|
interface PagedUiEvent : UiEvent {
|
||||||
fun loadMore()
|
fun loadMore()
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.base.event
|
package org.xtimms.etsudoku.core.base.event
|
||||||
|
|
||||||
interface UiEvent {
|
interface UiEvent {
|
||||||
fun showMessage(message: String?)
|
fun showMessage(message: String?)
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.base.state
|
package org.xtimms.etsudoku.core.base.state
|
||||||
|
|
||||||
abstract class PagedUiState : UiState() {
|
abstract class PagedUiState : UiState() {
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.base.state
|
package org.xtimms.etsudoku.core.base.state
|
||||||
|
|
||||||
abstract class UiState {
|
abstract class UiState {
|
||||||
abstract val isLoading: Boolean
|
abstract val isLoading: Boolean
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.cache
|
package org.xtimms.etsudoku.core.cache
|
||||||
|
|
||||||
enum class CacheDir(val dir: String) {
|
enum class CacheDir(val dir: String) {
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.cache
|
package org.xtimms.etsudoku.core.cache
|
||||||
|
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaPage
|
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.cache
|
package org.xtimms.etsudoku.core.cache
|
||||||
|
|
||||||
import androidx.collection.LruCache
|
import androidx.collection.LruCache
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.cache
|
package org.xtimms.etsudoku.core.cache
|
||||||
|
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.cache
|
package org.xtimms.etsudoku.core.cache
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.ComponentCallbacks2
|
import android.content.ComponentCallbacks2
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.cache
|
package org.xtimms.etsudoku.core.cache
|
||||||
|
|
||||||
import kotlinx.coroutines.Deferred
|
import kotlinx.coroutines.Deferred
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.cache
|
package org.xtimms.etsudoku.core.cache
|
||||||
|
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaPage
|
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedContent
|
import androidx.compose.animation.AnimatedContent
|
||||||
import androidx.compose.animation.SizeTransform
|
import androidx.compose.animation.SizeTransform
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
import androidx.compose.animation.core.animateDpAsState
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.core.CubicBezierEasing
|
import androidx.compose.animation.core.CubicBezierEasing
|
||||||
@ -0,0 +1,144 @@
|
|||||||
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
|
import android.text.Spanned
|
||||||
|
import android.text.style.BulletSpan
|
||||||
|
import android.text.style.ForegroundColorSpan
|
||||||
|
import android.text.style.RelativeSizeSpan
|
||||||
|
import android.text.style.StrikethroughSpan
|
||||||
|
import android.text.style.StyleSpan
|
||||||
|
import android.text.style.SubscriptSpan
|
||||||
|
import android.text.style.SuperscriptSpan
|
||||||
|
import android.text.style.TypefaceSpan
|
||||||
|
import android.text.style.URLSpan
|
||||||
|
import android.text.style.UnderlineSpan
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.compose.foundation.text.ClickableText
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
|
import androidx.compose.ui.text.SpanStyle
|
||||||
|
import androidx.compose.ui.text.TextLayoutResult
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
|
import androidx.compose.ui.text.style.TextDecoration
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.unit.TextUnit
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.core.text.HtmlCompat
|
||||||
|
import org.xtimms.etsudoku.utils.spanStyle
|
||||||
|
|
||||||
|
private const val URL_TAG = "url_tag"
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun HtmlTextField(
|
||||||
|
text: String,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
style: TextStyle = TextStyle.Default,
|
||||||
|
softWrap: Boolean = true,
|
||||||
|
overflow: TextOverflow = TextOverflow.Clip,
|
||||||
|
maxLines: Int = Int.MAX_VALUE,
|
||||||
|
onTextLayout: (TextLayoutResult) -> Unit = {},
|
||||||
|
linkClicked: ((String) -> Unit)? = null,
|
||||||
|
fontSize: TextUnit = 14.sp,
|
||||||
|
flags: Int = HtmlCompat.FROM_HTML_MODE_COMPACT,
|
||||||
|
urlSpanStyle: SpanStyle = SpanStyle(
|
||||||
|
color = linkTextColor(),
|
||||||
|
textDecoration = TextDecoration.Underline
|
||||||
|
),
|
||||||
|
customSpannedHandler: ((Spanned) -> AnnotatedString)? = null
|
||||||
|
) {
|
||||||
|
val content = text.asHTML(fontSize, flags, urlSpanStyle, customSpannedHandler)
|
||||||
|
if (linkClicked != null) {
|
||||||
|
ClickableText(
|
||||||
|
modifier = modifier,
|
||||||
|
text = content,
|
||||||
|
style = style,
|
||||||
|
softWrap = softWrap,
|
||||||
|
overflow = overflow,
|
||||||
|
maxLines = maxLines,
|
||||||
|
onTextLayout = onTextLayout,
|
||||||
|
onClick = {
|
||||||
|
content
|
||||||
|
.getStringAnnotations(URL_TAG, it, it)
|
||||||
|
.firstOrNull()
|
||||||
|
?.let { stringAnnotation -> linkClicked(stringAnnotation.item) }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Text(
|
||||||
|
modifier = modifier,
|
||||||
|
text = content,
|
||||||
|
style = style,
|
||||||
|
softWrap = softWrap,
|
||||||
|
overflow = overflow,
|
||||||
|
maxLines = maxLines,
|
||||||
|
onTextLayout = onTextLayout
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun linkTextColor() = Color(
|
||||||
|
TextView(LocalContext.current).linkTextColors.defaultColor
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun String.asHTML(
|
||||||
|
fontSize: TextUnit,
|
||||||
|
flags: Int,
|
||||||
|
URLSpanStyle: SpanStyle,
|
||||||
|
customSpannedHandler: ((Spanned) -> AnnotatedString)? = null
|
||||||
|
) = buildAnnotatedString {
|
||||||
|
val spanned = HtmlCompat.fromHtml(this@asHTML, flags)
|
||||||
|
val spans = spanned.getSpans(0, spanned.length, Any::class.java)
|
||||||
|
|
||||||
|
if (customSpannedHandler != null) {
|
||||||
|
append(customSpannedHandler(spanned))
|
||||||
|
} else {
|
||||||
|
append(spanned.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
spans
|
||||||
|
.filter { it !is BulletSpan }
|
||||||
|
.forEach { span ->
|
||||||
|
val start = spanned.getSpanStart(span)
|
||||||
|
val end = spanned.getSpanEnd(span)
|
||||||
|
when (span) {
|
||||||
|
is RelativeSizeSpan -> span.spanStyle(fontSize)
|
||||||
|
is StyleSpan -> span.spanStyle()
|
||||||
|
is UnderlineSpan -> span.spanStyle()
|
||||||
|
is ForegroundColorSpan -> span.spanStyle()
|
||||||
|
is TypefaceSpan -> span.spanStyle()
|
||||||
|
is StrikethroughSpan -> span.spanStyle()
|
||||||
|
is SuperscriptSpan -> span.spanStyle()
|
||||||
|
is SubscriptSpan -> span.spanStyle()
|
||||||
|
is URLSpan -> {
|
||||||
|
addStringAnnotation(
|
||||||
|
tag = URL_TAG,
|
||||||
|
annotation = span.url,
|
||||||
|
start = start,
|
||||||
|
end = end
|
||||||
|
)
|
||||||
|
URLSpanStyle
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}?.let { spanStyle ->
|
||||||
|
addStyle(spanStyle, start, end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun UnderlineSpan.spanStyle(): SpanStyle =
|
||||||
|
SpanStyle(textDecoration = TextDecoration.Underline)
|
||||||
|
|
||||||
|
internal fun ForegroundColorSpan.spanStyle(): SpanStyle =
|
||||||
|
SpanStyle(color = Color(foregroundColor))
|
||||||
|
|
||||||
|
internal fun StrikethroughSpan.spanStyle(): SpanStyle =
|
||||||
|
SpanStyle(textDecoration = TextDecoration.LineThrough)
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
import androidx.compose.animation.core.animate
|
import androidx.compose.animation.core.animate
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@ -0,0 +1,244 @@
|
|||||||
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
|
import android.content.res.Configuration.UI_MODE_NIGHT_YES
|
||||||
|
import androidx.compose.animation.AnimatedContent
|
||||||
|
import androidx.compose.animation.animateColorAsState
|
||||||
|
import androidx.compose.animation.core.Animatable
|
||||||
|
import androidx.compose.animation.core.FloatTweenSpec
|
||||||
|
import androidx.compose.animation.core.LinearEasing
|
||||||
|
import androidx.compose.animation.core.RepeatMode
|
||||||
|
import androidx.compose.animation.core.TweenSpec
|
||||||
|
import androidx.compose.animation.core.VectorConverter
|
||||||
|
import androidx.compose.animation.core.animateValue
|
||||||
|
import androidx.compose.animation.core.infiniteRepeatable
|
||||||
|
import androidx.compose.animation.core.rememberInfiniteTransition
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.RowScope
|
||||||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.material3.Card
|
||||||
|
import androidx.compose.material3.CardDefaults
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.drawWithContent
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
import androidx.compose.ui.geometry.Size
|
||||||
|
import androidx.compose.ui.graphics.BlendMode
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
|
||||||
|
import androidx.compose.ui.graphics.nativeCanvas
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.xtimms.etsudoku.R
|
||||||
|
import org.xtimms.etsudoku.core.model.MangaHistory
|
||||||
|
import org.xtimms.etsudoku.sections.details.model.HistoryInfo
|
||||||
|
import org.xtimms.etsudoku.ui.theme.EtsudokuTheme
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun RowScope.ReadButton(
|
||||||
|
info: HistoryInfo,
|
||||||
|
estimatedReadTime: String
|
||||||
|
) {
|
||||||
|
|
||||||
|
val shift = remember { Animatable(0f) }
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
val animatedCardContainerColor = animateColorAsState(
|
||||||
|
label = "animatedCardContainerColor",
|
||||||
|
targetValue = if (info.totalChapters == 0) MaterialTheme.colorScheme.errorContainer else MaterialTheme.colorScheme.primaryContainer,
|
||||||
|
animationSpec = TweenSpec(500)
|
||||||
|
).value
|
||||||
|
|
||||||
|
val animatedCardContentColor = animateColorAsState(
|
||||||
|
label = "animatedCardContentColor",
|
||||||
|
targetValue = if (info.totalChapters == 0) MaterialTheme.colorScheme.onErrorContainer else MaterialTheme.colorScheme.onPrimaryContainer,
|
||||||
|
animationSpec = TweenSpec(500)
|
||||||
|
).value
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
fun anim() {
|
||||||
|
coroutineScope.launch {
|
||||||
|
shift.animateTo(
|
||||||
|
1f,
|
||||||
|
animationSpec = FloatTweenSpec(4000, 0, LinearEasing)
|
||||||
|
)
|
||||||
|
shift.snapTo(0f)
|
||||||
|
anim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
anim()
|
||||||
|
}
|
||||||
|
|
||||||
|
Card(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1F)
|
||||||
|
.height(54.dp),
|
||||||
|
shape = CircleShape,
|
||||||
|
colors = CardDefaults.cardColors(
|
||||||
|
containerColor = animatedCardContainerColor,
|
||||||
|
contentColor = animatedCardContentColor,
|
||||||
|
),
|
||||||
|
onClick = {
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxHeight(),
|
||||||
|
contentAlignment = Alignment.CenterEnd,
|
||||||
|
) {
|
||||||
|
BackgroundProgress(
|
||||||
|
if (info.totalChapters == 0) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary,
|
||||||
|
if (!info.isValid) 0.1f else 0.33f,
|
||||||
|
info.history?.percent?.coerceIn(0f, 1f) ?: 0f
|
||||||
|
)
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.drawWithLayer {
|
||||||
|
drawContent()
|
||||||
|
val leftOffset = size.width - 20.dp.toPx()
|
||||||
|
drawRect(
|
||||||
|
topLeft = Offset(leftOffset, 0f),
|
||||||
|
size = Size(
|
||||||
|
20.dp.toPx(),
|
||||||
|
size.height,
|
||||||
|
),
|
||||||
|
blendMode = BlendMode.SrcIn,
|
||||||
|
brush = Brush.horizontalGradient(
|
||||||
|
colors = listOf(
|
||||||
|
Color.Black,
|
||||||
|
Color.Black.copy(alpha = 0f),
|
||||||
|
),
|
||||||
|
startX = leftOffset,
|
||||||
|
endX = leftOffset + 14.dp.toPx()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
) {
|
||||||
|
val infiniteTransition by rememberInfiniteTransition("infiniteTransition").animateValue(
|
||||||
|
label = "infiniteTransition",
|
||||||
|
initialValue = 0,
|
||||||
|
targetValue = 2,
|
||||||
|
typeConverter = Int.VectorConverter,
|
||||||
|
animationSpec = infiniteRepeatable(tween(15000), RepeatMode.Restart)
|
||||||
|
)
|
||||||
|
val chaptersSubtitle = when {
|
||||||
|
!info.isValid -> stringResource(R.string.loading_)
|
||||||
|
info.currentChapter >= 0 -> when (infiniteTransition) {
|
||||||
|
1 -> stringResource(
|
||||||
|
R.string.chapter_d_of_d,
|
||||||
|
info.currentChapter + 1,
|
||||||
|
info.totalChapters,
|
||||||
|
)
|
||||||
|
0 -> estimatedReadTime
|
||||||
|
else -> estimatedReadTime
|
||||||
|
}
|
||||||
|
|
||||||
|
info.totalChapters == 0 -> stringResource(R.string.no_chapters)
|
||||||
|
else -> LocalContext.current.resources.getQuantityString(
|
||||||
|
R.plurals.chapters,
|
||||||
|
info.totalChapters,
|
||||||
|
info.totalChapters,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = if (info.history != null) {
|
||||||
|
stringResource(R.string.continue_reading)
|
||||||
|
} else {
|
||||||
|
stringResource(R.string.read)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
AnimatedContent(targetState = chaptersSubtitle, label = "Subtitle animation") {
|
||||||
|
Text(
|
||||||
|
text = it,
|
||||||
|
style = MaterialTheme.typography.labelMedium,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ContentDrawScope.drawWithLayer(block: ContentDrawScope.() -> Unit) {
|
||||||
|
with(drawContext.canvas.nativeCanvas) {
|
||||||
|
val checkPoint = saveLayer(null, null)
|
||||||
|
block()
|
||||||
|
restoreToCount(checkPoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Modifier.drawWithLayer(block: ContentDrawScope.() -> Unit) = this.then(
|
||||||
|
Modifier.drawWithContent {
|
||||||
|
drawWithLayer {
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun Preview() {
|
||||||
|
EtsudokuTheme {
|
||||||
|
Row {
|
||||||
|
ReadButton(
|
||||||
|
HistoryInfo(
|
||||||
|
100,
|
||||||
|
33,
|
||||||
|
MangaHistory(
|
||||||
|
Instant.now(),
|
||||||
|
Instant.now(),
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
1,
|
||||||
|
50f
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"123"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(name = "Night mode", uiMode = UI_MODE_NIGHT_YES)
|
||||||
|
@Composable
|
||||||
|
private fun PreviewNightMode() {
|
||||||
|
EtsudokuTheme {
|
||||||
|
Row {
|
||||||
|
ReadButton(
|
||||||
|
HistoryInfo(
|
||||||
|
100,
|
||||||
|
33,
|
||||||
|
MangaHistory(
|
||||||
|
Instant.now(),
|
||||||
|
Instant.now(),
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
1,
|
||||||
|
50f
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"123"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.RowScope
|
import androidx.compose.foundation.layout.RowScope
|
||||||
@ -0,0 +1,116 @@
|
|||||||
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
|
import androidx.compose.animation.animateContentSize
|
||||||
|
import androidx.compose.animation.core.Spring
|
||||||
|
import androidx.compose.animation.core.spring
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
|
||||||
|
import androidx.compose.material.icons.outlined.Close
|
||||||
|
import androidx.compose.material.icons.outlined.Search
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.SearchBar
|
||||||
|
import androidx.compose.material3.SearchBarDefaults
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import org.xtimms.etsudoku.R
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
fun EmbeddedSearchBar(
|
||||||
|
onQueryChange: (String) -> Unit,
|
||||||
|
isSearchActive: Boolean,
|
||||||
|
onActiveChanged: (Boolean) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
onSearch: ((String) -> Unit)? = null,
|
||||||
|
) {
|
||||||
|
var searchQuery by rememberSaveable { mutableStateOf("") }
|
||||||
|
val activeChanged: (Boolean) -> Unit = { active ->
|
||||||
|
searchQuery = ""
|
||||||
|
onQueryChange("")
|
||||||
|
onActiveChanged(active)
|
||||||
|
}
|
||||||
|
SearchBar(
|
||||||
|
query = searchQuery,
|
||||||
|
onQueryChange = { query ->
|
||||||
|
searchQuery = query
|
||||||
|
onQueryChange(query)
|
||||||
|
},
|
||||||
|
onSearch = onSearch ?: { activeChanged(false) },
|
||||||
|
active = isSearchActive,
|
||||||
|
onActiveChange = activeChanged,
|
||||||
|
modifier = if (isSearchActive) {
|
||||||
|
modifier
|
||||||
|
.animateContentSize(spring(stiffness = Spring.StiffnessHigh))
|
||||||
|
} else {
|
||||||
|
modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.animateContentSize(spring(stiffness = Spring.StiffnessHigh))
|
||||||
|
},
|
||||||
|
placeholder = { Text("Search") },
|
||||||
|
leadingIcon = {
|
||||||
|
if (isSearchActive) {
|
||||||
|
IconButton(
|
||||||
|
onClick = { activeChanged(false) },
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.AutoMirrored.Rounded.ArrowBack,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Search,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trailingIcon = if (isSearchActive && searchQuery.isNotEmpty()) {
|
||||||
|
{
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
searchQuery = ""
|
||||||
|
onQueryChange("")
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Close,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
},
|
||||||
|
colors = SearchBarDefaults.colors(
|
||||||
|
containerColor = if (isSearchActive) {
|
||||||
|
MaterialTheme.colorScheme.background
|
||||||
|
} else {
|
||||||
|
MaterialTheme.colorScheme.surfaceContainerLow
|
||||||
|
},
|
||||||
|
),
|
||||||
|
tonalElevation = 0.dp,
|
||||||
|
windowInsets = if (isSearchActive) {
|
||||||
|
SearchBarDefaults.windowInsets
|
||||||
|
} else {
|
||||||
|
WindowInsets(0.dp)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
// Search suggestions or results
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components
|
package org.xtimms.etsudoku.core.components
|
||||||
|
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components.effects
|
package org.xtimms.etsudoku.core.components.effects
|
||||||
|
|
||||||
import androidx.compose.animation.core.LinearEasing
|
import androidx.compose.animation.core.LinearEasing
|
||||||
import androidx.compose.animation.core.RepeatMode
|
import androidx.compose.animation.core.RepeatMode
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components.icons
|
package org.xtimms.etsudoku.core.components.icons
|
||||||
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.materialIcon
|
import androidx.compose.material.icons.materialIcon
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components.icons
|
package org.xtimms.etsudoku.core.components.icons
|
||||||
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.materialIcon
|
import androidx.compose.material.icons.materialIcon
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components.icons
|
package org.xtimms.etsudoku.core.components.icons
|
||||||
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.components.shape
|
package org.xtimms.etsudoku.core.components.shape
|
||||||
|
|
||||||
import androidx.compose.ui.geometry.Offset
|
import androidx.compose.ui.geometry.Offset
|
||||||
import androidx.compose.ui.geometry.Rect
|
import androidx.compose.ui.geometry.Rect
|
||||||
@ -1,10 +1,10 @@
|
|||||||
package org.xtimms.tokusho.core.database
|
package org.xtimms.etsudoku.core.database
|
||||||
|
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||||
import org.xtimms.tokusho.R
|
import org.xtimms.etsudoku.R
|
||||||
|
|
||||||
class DatabasePrePopulateCallback(private val resources: Resources) : RoomDatabase.Callback() {
|
class DatabasePrePopulateCallback(private val resources: Resources) : RoomDatabase.Callback() {
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.database
|
package org.xtimms.etsudoku.core.database
|
||||||
|
|
||||||
const val TABLE_MANGA = "manga"
|
const val TABLE_MANGA = "manga"
|
||||||
const val TABLE_TAGS = "tags"
|
const val TABLE_TAGS = "tags"
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package org.xtimms.tokusho.core.database.dao
|
package org.xtimms.etsudoku.core.database.dao
|
||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Upsert
|
import androidx.room.Upsert
|
||||||
import org.xtimms.tokusho.core.database.entity.TagEntity
|
import org.xtimms.etsudoku.core.database.entity.TagEntity
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
abstract class TagsDao {
|
abstract class TagsDao {
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import org.xtimms.tokusho.core.database.TABLE_FAVOURITE_CATEGORIES
|
import org.xtimms.etsudoku.core.database.TABLE_FAVOURITE_CATEGORIES
|
||||||
|
|
||||||
@Entity(tableName = TABLE_FAVOURITE_CATEGORIES)
|
@Entity(tableName = TABLE_FAVOURITE_CATEGORIES)
|
||||||
data class FavouriteCategoryEntity(
|
data class FavouriteCategoryEntity(
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.ForeignKey
|
import androidx.room.ForeignKey
|
||||||
import org.xtimms.tokusho.core.database.TABLE_FAVOURITES
|
import org.xtimms.etsudoku.core.database.TABLE_FAVOURITES
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = TABLE_FAVOURITES,
|
tableName = TABLE_FAVOURITES,
|
||||||
@ -1,10 +1,10 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.ForeignKey
|
import androidx.room.ForeignKey
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import org.xtimms.tokusho.core.database.TABLE_HISTORY
|
import org.xtimms.etsudoku.core.database.TABLE_HISTORY
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = TABLE_HISTORY,
|
tableName = TABLE_HISTORY,
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.Embedded
|
import androidx.room.Embedded
|
||||||
import androidx.room.Junction
|
import androidx.room.Junction
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import org.xtimms.tokusho.core.database.TABLE_MANGA
|
import org.xtimms.etsudoku.core.database.TABLE_MANGA
|
||||||
|
|
||||||
@Entity(tableName = TABLE_MANGA)
|
@Entity(tableName = TABLE_MANGA)
|
||||||
data class MangaEntity(
|
data class MangaEntity(
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import org.xtimms.tokusho.core.database.TABLE_SOURCES
|
import org.xtimms.etsudoku.core.database.TABLE_SOURCES
|
||||||
|
|
||||||
@Entity(tableName = TABLE_SOURCES)
|
@Entity(tableName = TABLE_SOURCES)
|
||||||
data class MangaSourceEntity(
|
data class MangaSourceEntity(
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.ForeignKey
|
import androidx.room.ForeignKey
|
||||||
import org.xtimms.tokusho.core.database.TABLE_MANGA_TAGS
|
import org.xtimms.etsudoku.core.database.TABLE_MANGA_TAGS
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = TABLE_MANGA_TAGS,
|
tableName = TABLE_MANGA_TAGS,
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.Embedded
|
import androidx.room.Embedded
|
||||||
import androidx.room.Junction
|
import androidx.room.Junction
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.annotation.FloatRange
|
import androidx.annotation.FloatRange
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.Embedded
|
import androidx.room.Embedded
|
||||||
import androidx.room.Junction
|
import androidx.room.Junction
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import org.xtimms.tokusho.core.database.TABLE_TAGS
|
import org.xtimms.etsudoku.core.database.TABLE_TAGS
|
||||||
|
|
||||||
@Entity(tableName = TABLE_TAGS)
|
@Entity(tableName = TABLE_TAGS)
|
||||||
data class TagEntity(
|
data class TagEntity(
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.database.entity
|
package org.xtimms.etsudoku.core.database.entity
|
||||||
|
|
||||||
import androidx.room.Embedded
|
import androidx.room.Embedded
|
||||||
import androidx.room.Junction
|
import androidx.room.Junction
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.exceptions
|
package org.xtimms.etsudoku.core.exceptions
|
||||||
|
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okio.IOException
|
import okio.IOException
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package org.xtimms.etsudoku.core.exceptions
|
||||||
|
|
||||||
|
class SyncApiException(
|
||||||
|
message: String,
|
||||||
|
val code: Int,
|
||||||
|
) : RuntimeException(message)
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.xtimms.tokusho.core.exceptions
|
package org.xtimms.etsudoku.core.exceptions
|
||||||
|
|
||||||
import okio.IOException
|
import okio.IOException
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue