Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c0ef7a788 | ||
|
|
960c2b4113 | ||
|
|
1eb85d4419 | ||
|
|
20bea76e6c | ||
|
|
866bd3b3a9 |
16
README.md
@@ -1,6 +1,4 @@
|
||||
# **Dantotsu** (🚧 ALPHA 🚧)
|
||||
|
||||
> ⚠️ **WARNING**: This project is in alpha stage. Things may not work as expected.
|
||||
# **Dantotsu**
|
||||
|
||||
<p align="center">
|
||||
<a href="https://discord.gg/4HPZ5nAWwM"><img src="https://img.shields.io/badge/Discord-7289DA?style=for-the-badge&logo=discord&logoColor=white"></a>
|
||||
@@ -26,14 +24,14 @@ Dantotsu is crafted from the ashes of Saikou and based on simplistic yet state-o
|
||||
| Type | Status |
|
||||
| ---------------- | ------- |
|
||||
| Anime Extensions | Working |
|
||||
| Manga Extensions | "Working" |
|
||||
| Manga Extensions | Working |
|
||||
| Light Novel Extensions | Not Working |
|
||||
|
||||
|
||||
|
||||
## APP FEATURES
|
||||
|
||||
- Easy and functional way to both, watch anime and read manga, ad-free.
|
||||
- Easy and functional way to both, watch anime and read manga.
|
||||
|
||||
- A completely open source app with a nice UI & Animations :)
|
||||
|
||||
@@ -59,14 +57,16 @@ add your own extensions in the settings menu (Dantotsu has no affiliation with a
|
||||
|
||||
## Planned Stuff
|
||||
|
||||
- get app out of alpha
|
||||
- TV Support
|
||||
|
||||
- Accent Color Change (RIP Hot Pink Supremacy.)
|
||||
- LN Support
|
||||
|
||||
- Offline Viewing
|
||||
|
||||
|
||||
## Rejected Stuff (still rejected)
|
||||
|
||||
- Sources of any language except English
|
||||
- Official support of any language except English
|
||||
|
||||
- News Section in the App
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ android {
|
||||
minSdk 23
|
||||
targetSdk 34
|
||||
versionCode ((System.currentTimeMillis() / 60000).toInteger())
|
||||
versionName "0.1.3"
|
||||
versionName "1.0.0"
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ dependencies {
|
||||
implementation 'com.davemorrissey.labs:subsampling-scale-image-view-androidx:3.10.0'
|
||||
implementation 'com.alexvasilkov:gesture-views:2.8.3'
|
||||
implementation 'com.github.VipulOG:ebook-reader:0.1.6'
|
||||
implementation 'androidx.paging:paging-runtime-ktx:3.2.1'
|
||||
|
||||
// string matching
|
||||
implementation 'me.xdrop:fuzzywuzzy:1.4.0'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Dantotsu α</string>
|
||||
<string name="app_name">Dantotsu</string>
|
||||
</resources>
|
||||
BIN
app/src/main/ic_launcher-playstore.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
@@ -188,6 +188,9 @@ fun Activity.hideStatusBar() {
|
||||
open class BottomSheetDialogFragment : BottomSheetDialogFragment() {
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val window = dialog?.window
|
||||
val decorView: View = window?.decorView ?: return
|
||||
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
if (this.resources.configuration.orientation != Configuration.ORIENTATION_PORTRAIT) {
|
||||
val behavior = BottomSheetBehavior.from(requireView().parent as View)
|
||||
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
|
||||
@@ -7,7 +7,10 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Animatable
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
@@ -21,6 +24,7 @@ import android.view.animation.AnticipateInterpolator
|
||||
import android.widget.TextView
|
||||
import androidx.activity.addCallback
|
||||
import androidx.activity.viewModels
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.animation.doOnEnd
|
||||
import androidx.core.app.ActivityCompat
|
||||
@@ -60,6 +64,8 @@ import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import nl.joery.animatedbottombar.AnimatedBottomBar
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.io.Serializable
|
||||
|
||||
@@ -70,9 +76,8 @@ class MainActivity : AppCompatActivity() {
|
||||
private var load = false
|
||||
|
||||
private var uiSettings = UserInterfaceSettings()
|
||||
private val animeExtensionManager: AnimeExtensionManager by injectLazy()
|
||||
private val mangaExtensionManager: MangaExtensionManager by injectLazy()
|
||||
|
||||
private val animeExtensionManager: AnimeExtensionManager = Injekt.get()
|
||||
private val mangaExtensionManager: MangaExtensionManager = Injekt.get()
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
@@ -80,6 +85,17 @@ class MainActivity : AppCompatActivity() {
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val bottomBar = findViewById<AnimatedBottomBar>(R.id.navbar)
|
||||
val backgroundDrawable = bottomBar.background as GradientDrawable
|
||||
val currentColor = backgroundDrawable.color?.defaultColor ?: 0
|
||||
val semiTransparentColor = (currentColor and 0x00FFFFFF) or 0xE8000000.toInt()
|
||||
backgroundDrawable.setColor(semiTransparentColor)
|
||||
bottomBar.background = backgroundDrawable
|
||||
}
|
||||
|
||||
|
||||
val animeScope = CoroutineScope(Dispatchers.Default)
|
||||
animeScope.launch {
|
||||
animeExtensionManager.findAvailableExtensions()
|
||||
@@ -109,24 +125,40 @@ class MainActivity : AppCompatActivity() {
|
||||
binding.root.isMotionEventSplittingEnabled = false
|
||||
|
||||
lifecycleScope.launch {
|
||||
val splash = SplashScreenBinding.inflate(layoutInflater)
|
||||
binding.root.addView(splash.root)
|
||||
(splash.splashImage.drawable as Animatable).start()
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||
val splash = SplashScreenBinding.inflate(layoutInflater)
|
||||
binding.root.addView(splash.root)
|
||||
(splash.splashImage.drawable as Animatable).start()
|
||||
|
||||
// Wait for 2 seconds (2000 milliseconds)
|
||||
delay(2000)
|
||||
delay(1200)
|
||||
|
||||
// Now perform the animation
|
||||
ObjectAnimator.ofFloat(
|
||||
splash.root,
|
||||
View.TRANSLATION_Y,
|
||||
0f,
|
||||
-splash.root.height.toFloat()
|
||||
).apply {
|
||||
interpolator = AnticipateInterpolator()
|
||||
duration = 200L
|
||||
doOnEnd { binding.root.removeView(splash.root) }
|
||||
start()
|
||||
ObjectAnimator.ofFloat(
|
||||
splash.root,
|
||||
View.TRANSLATION_Y,
|
||||
0f,
|
||||
-splash.root.height.toFloat()
|
||||
).apply {
|
||||
interpolator = AnticipateInterpolator()
|
||||
duration = 200L
|
||||
doOnEnd { binding.root.removeView(splash.root) }
|
||||
start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
splashScreen.setOnExitAnimationListener { splashScreenView ->
|
||||
ObjectAnimator.ofFloat(
|
||||
splashScreenView,
|
||||
View.TRANSLATION_Y,
|
||||
0f,
|
||||
-splashScreenView.height.toFloat()
|
||||
).apply {
|
||||
interpolator = AnticipateInterpolator()
|
||||
duration = 200L
|
||||
doOnEnd { splashScreenView.remove() }
|
||||
start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,13 +270,6 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (ActivityHelper.shouldRefreshMainActivity) {
|
||||
ActivityHelper.shouldRefreshMainActivity = false
|
||||
Refresh.all()
|
||||
finish()
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
initActivity(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -264,8 +289,4 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object ActivityHelper {
|
||||
var shouldRefreshMainActivity: Boolean = false
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ fun updateProgress(media: Media, number: String) {
|
||||
if (Anilist.userid != null) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val a = number.toFloatOrNull()?.roundToInt()
|
||||
if (a != media.userProgress) {
|
||||
if ((a?:0) > (media.userProgress?:0)) {
|
||||
Anilist.mutation.editList(
|
||||
media.id,
|
||||
a,
|
||||
|
||||
@@ -17,6 +17,7 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import ani.dantotsu.media.GenreActivity
|
||||
import ani.dantotsu.MediaPageTransformer
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.connections.anilist.Anilist
|
||||
import ani.dantotsu.databinding.ItemAnimePageBinding
|
||||
import ani.dantotsu.loadData
|
||||
@@ -31,6 +32,8 @@ import ani.dantotsu.setSlideUp
|
||||
import ani.dantotsu.settings.SettingsDialogFragment
|
||||
import ani.dantotsu.settings.UserInterfaceSettings
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
|
||||
class AnimePageAdapter : RecyclerView.Adapter<AnimePageAdapter.AnimePageViewHolder>() {
|
||||
val ready = MutableLiveData(false)
|
||||
@@ -49,6 +52,13 @@ class AnimePageAdapter : RecyclerView.Adapter<AnimePageAdapter.AnimePageViewHold
|
||||
binding = holder.binding
|
||||
trendingViewPager = binding.animeTrendingViewPager
|
||||
|
||||
val textInputLayout = holder.itemView.findViewById<TextInputLayout>(R.id.animeSearchBar)
|
||||
val currentColor = textInputLayout.boxBackgroundColor
|
||||
val semiTransparentColor = (currentColor and 0x00FFFFFF) or 0xA8000000.toInt()
|
||||
textInputLayout.boxBackgroundColor = semiTransparentColor
|
||||
val materialCardView = holder.itemView.findViewById<MaterialCardView>(R.id.animeUserAvatarContainer)
|
||||
materialCardView.setCardBackgroundColor(semiTransparentColor)
|
||||
|
||||
binding.animeTitleContainer.updatePadding(top = statusBarHeight)
|
||||
|
||||
if (uiSettings.smallView) binding.animeTrendingContainer.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
|
||||
@@ -31,6 +31,8 @@ import ani.dantotsu.setSlideUp
|
||||
import ani.dantotsu.settings.SettingsDialogFragment
|
||||
import ani.dantotsu.settings.UserInterfaceSettings
|
||||
import ani.dantotsu.statusBarHeight
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
|
||||
class MangaPageAdapter : RecyclerView.Adapter<MangaPageAdapter.MangaPageViewHolder>() {
|
||||
val ready = MutableLiveData(false)
|
||||
@@ -49,6 +51,13 @@ class MangaPageAdapter : RecyclerView.Adapter<MangaPageAdapter.MangaPageViewHold
|
||||
binding = holder.binding
|
||||
trendingViewPager = binding.mangaTrendingViewPager
|
||||
|
||||
val textInputLayout = holder.itemView.findViewById<TextInputLayout>(R.id.mangaSearchBar)
|
||||
val currentColor = textInputLayout.boxBackgroundColor
|
||||
val semiTransparentColor= (currentColor and 0x00FFFFFF) or 0xA8000000.toInt()
|
||||
textInputLayout.boxBackgroundColor = semiTransparentColor
|
||||
val materialCardView = holder.itemView.findViewById<MaterialCardView>(R.id.mangaUserAvatarContainer)
|
||||
materialCardView.setCardBackgroundColor(semiTransparentColor)
|
||||
|
||||
binding.mangaTitleContainer.updatePadding(top = statusBarHeight)
|
||||
|
||||
if (uiSettings.smallView) binding.mangaTrendingContainer.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
|
||||
@@ -4,6 +4,8 @@ import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
@@ -12,7 +14,9 @@ import androidx.lifecycle.lifecycleScope
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.Refresh
|
||||
import ani.dantotsu.databinding.ActivityListBinding
|
||||
import ani.dantotsu.loadData
|
||||
import ani.dantotsu.media.user.ListViewPagerAdapter
|
||||
import ani.dantotsu.settings.UserInterfaceSettings
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
@@ -31,16 +35,16 @@ class CalendarActivity : AppCompatActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
binding = ActivityListBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
|
||||
val typedValue = TypedValue()
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValue, true)
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorOnPrimary, typedValue, true)
|
||||
val primaryColor = typedValue.data
|
||||
val typedValue2 = TypedValue()
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorOnPrimary, typedValue2, true)
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValue2, true)
|
||||
val primaryTextColor = typedValue2.data
|
||||
val typedValue3 = TypedValue()
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorPrimaryContainer, typedValue3, true)
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorSecondary, typedValue3, true)
|
||||
val secondaryColor = typedValue3.data
|
||||
|
||||
window.statusBarColor = primaryColor
|
||||
@@ -48,8 +52,21 @@ class CalendarActivity : AppCompatActivity() {
|
||||
binding.listTabLayout.setBackgroundColor(primaryColor)
|
||||
binding.listAppBar.setBackgroundColor(primaryColor)
|
||||
binding.listTitle.setTextColor(primaryTextColor)
|
||||
binding.listTabLayout.setTabTextColors(primaryTextColor, secondaryColor)
|
||||
binding.listTabLayout.setTabTextColors(primaryTextColor, primaryTextColor)
|
||||
binding.listTabLayout.setSelectedTabIndicatorColor(primaryTextColor)
|
||||
val uiSettings = loadData<UserInterfaceSettings>("ui_settings") ?: UserInterfaceSettings()
|
||||
if (!uiSettings.immersiveMode) {
|
||||
this.window.statusBarColor =
|
||||
ContextCompat.getColor(this, R.color.nav_bg_inv)
|
||||
binding.root.fitsSystemWindows = true
|
||||
|
||||
}else{
|
||||
binding.root.fitsSystemWindows = false
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
}
|
||||
setContentView(binding.root)
|
||||
|
||||
binding.listTitle.setText(R.string.release_calendar)
|
||||
binding.listSort.visibility = View.GONE
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ class MediaDetailsActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedLi
|
||||
R.drawable.ic_round_favorite_24,
|
||||
R.drawable.ic_round_favorite_border_24,
|
||||
R.color.bg_opp,
|
||||
R.color.violet_400,
|
||||
R.color.violet_400,//TODO: Change to colorSecondary
|
||||
media.isFav
|
||||
) {
|
||||
media.isFav = it
|
||||
|
||||
@@ -10,6 +10,7 @@ import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import ani.dantotsu.*
|
||||
@@ -177,6 +178,7 @@ class AnimeWatchAdapter(
|
||||
binding.animeWatchChipScroll.smoothScrollTo((chip.left - screenWidth / 2) + (chip.width / 2), 0)
|
||||
}
|
||||
chip.text = "${names[limit * (position)]} - ${names[last - 1]}"
|
||||
chip.setTextColor(ContextCompat.getColorStateList(fragment.requireContext(), R.color.chip_text_color))
|
||||
|
||||
chip.setOnClickListener {
|
||||
selected()
|
||||
|
||||
@@ -1205,7 +1205,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener {
|
||||
else -> MimeTypes.TEXT_SSA
|
||||
}
|
||||
)
|
||||
.setId("2")
|
||||
.setId("69")
|
||||
.build()
|
||||
}
|
||||
println("sub: $sub")
|
||||
@@ -1221,7 +1221,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener {
|
||||
else -> MimeTypes.TEXT_UNKNOWN
|
||||
}
|
||||
)
|
||||
.setId("2")
|
||||
.setId("69")
|
||||
.build()
|
||||
}
|
||||
}
|
||||
@@ -1302,6 +1302,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener {
|
||||
)
|
||||
.setMaxVideoSize(1, 1)
|
||||
//.setOverrideForType(
|
||||
// TrackSelectionOverride(trackSelector, 2))
|
||||
)
|
||||
|
||||
if (playbackPosition != 0L && !changingServer && !settings.alwaysContinue) {
|
||||
@@ -1352,6 +1353,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener {
|
||||
}
|
||||
playerView.player = exoPlayer
|
||||
|
||||
|
||||
try {
|
||||
mediaSession = MediaSession.Builder(this, exoPlayer).build()
|
||||
} catch (e: Exception) {
|
||||
@@ -1572,6 +1574,27 @@ class ExoplayerView : AppCompatActivity(), Player.Listener {
|
||||
}
|
||||
|
||||
override fun onTracksChanged(tracks: Tracks) {
|
||||
tracks.groups.forEach {
|
||||
println("Track__: $it")
|
||||
println("Track__: ${it.length}")
|
||||
println("Track__: ${it.isSelected}")
|
||||
println("Track__: ${it.type}")
|
||||
println("Track__: ${it.mediaTrackGroup.id}")
|
||||
if (it.type == 3 && it.mediaTrackGroup.id == "1:"){
|
||||
playerView.player?.trackSelectionParameters =
|
||||
playerView.player?.trackSelectionParameters?.buildUpon()
|
||||
?.setOverrideForType(
|
||||
TrackSelectionOverride(it.mediaTrackGroup, it.length - 1))
|
||||
?.build()!!
|
||||
}else if(it.type == 3){
|
||||
playerView.player?.trackSelectionParameters =
|
||||
playerView.player?.trackSelectionParameters?.buildUpon()
|
||||
?.addOverride(
|
||||
TrackSelectionOverride(it.mediaTrackGroup, listOf()))
|
||||
?.build()!!
|
||||
}
|
||||
}
|
||||
println("Track: ${tracks.groups.size}")
|
||||
if (tracks.groups.size <= 2) exoQuality.visibility = View.GONE
|
||||
else {
|
||||
exoQuality.visibility = View.VISIBLE
|
||||
|
||||
@@ -63,7 +63,8 @@ class MangaChapterAdapter(
|
||||
val binding = holder.binding
|
||||
setAnimation(fragment.requireContext(), holder.binding.root, fragment.uiSettings)
|
||||
val ep = arr[position]
|
||||
binding.itemEpisodeNumber.text = ep.number
|
||||
val parsedNumber = MangaNameAdapter.findChapterNumber(ep.number)?.toInt()
|
||||
binding.itemEpisodeNumber.text = parsedNumber?.toString() ?: ep.number
|
||||
if (media.userProgress != null) {
|
||||
if ((MangaNameAdapter.findChapterNumber(ep.number) ?: 9999f) <= media.userProgress!!.toFloat())
|
||||
binding.itemEpisodeViewedCover.visibility = View.VISIBLE
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import ani.dantotsu.*
|
||||
@@ -145,6 +146,7 @@ class MangaReadAdapter(
|
||||
binding.animeWatchChipScroll.smoothScrollTo((chip.left - screenWidth / 2) + (chip.width / 2), 0)
|
||||
}
|
||||
chip.text = "${names[limit * (position)]} - ${names[last - 1]}"
|
||||
chip.setTextColor(ContextCompat.getColorStateList(fragment.requireContext(), R.color.chip_text_color))
|
||||
|
||||
chip.setOnClickListener {
|
||||
selected()
|
||||
|
||||
@@ -156,10 +156,6 @@ abstract class BaseImageAdapter(
|
||||
.skipMemoryCache(true)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
} else {
|
||||
println("bitmap from cache")
|
||||
println(link.url)
|
||||
println(mangaCache.get(link.url))
|
||||
println("cache size: ${mangaCache.size()}")
|
||||
mangaCache.get(link.url)?.let { imageData ->
|
||||
val bitmap = imageData.fetchAndProcessImage(imageData.page, imageData.source, context = this@loadBitmap)
|
||||
it.load(bitmap)
|
||||
|
||||
@@ -4,6 +4,8 @@ import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
@@ -13,6 +15,8 @@ import androidx.lifecycle.lifecycleScope
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.Refresh
|
||||
import ani.dantotsu.databinding.ActivityListBinding
|
||||
import ani.dantotsu.loadData
|
||||
import ani.dantotsu.settings.UserInterfaceSettings
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
@@ -30,16 +34,15 @@ class ListActivity : AppCompatActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
ThemeManager(this).applyTheme()
|
||||
binding = ActivityListBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
val typedValue = TypedValue()
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValue, true)
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorOnPrimary, typedValue, true)
|
||||
val primaryColor = typedValue.data
|
||||
val typedValue2 = TypedValue()
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorOnPrimary, typedValue2, true)
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValue2, true)
|
||||
val primaryTextColor = typedValue2.data
|
||||
val typedValue3 = TypedValue()
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorPrimaryContainer, typedValue3, true)
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorSecondary, typedValue3, true)
|
||||
val secondaryColor = typedValue3.data
|
||||
|
||||
window.statusBarColor = primaryColor
|
||||
@@ -47,8 +50,20 @@ class ListActivity : AppCompatActivity() {
|
||||
binding.listTabLayout.setBackgroundColor(primaryColor)
|
||||
binding.listAppBar.setBackgroundColor(primaryColor)
|
||||
binding.listTitle.setTextColor(primaryTextColor)
|
||||
binding.listTabLayout.setTabTextColors(primaryTextColor, secondaryColor)
|
||||
binding.listTabLayout.setTabTextColors(primaryTextColor, primaryTextColor)
|
||||
binding.listTabLayout.setSelectedTabIndicatorColor(primaryTextColor)
|
||||
val uiSettings = loadData<UserInterfaceSettings>("ui_settings") ?: UserInterfaceSettings()
|
||||
if (!uiSettings.immersiveMode) {
|
||||
this.window.statusBarColor =
|
||||
ContextCompat.getColor(this, R.color.nav_bg_inv)
|
||||
binding.root.fitsSystemWindows = true
|
||||
|
||||
}else{
|
||||
binding.root.fitsSystemWindows = false
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
}
|
||||
setContentView(binding.root)
|
||||
|
||||
val anime = intent.getBooleanExtra("anime", true)
|
||||
binding.listTitle.text = intent.getStringExtra("username") + "'s " + (if (anime) "Anime" else "Manga") + " List"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package ani.dantotsu.others
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -46,6 +48,12 @@ open class CustomBottomDialog : BottomSheetDialogFragment() {
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
_binding = BottomSheetCustomBinding.inflate(inflater, container, false)
|
||||
val window = dialog?.window
|
||||
window?.statusBarColor = Color.TRANSPARENT
|
||||
val typedValue = TypedValue()
|
||||
val theme = requireContext().theme
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorSurface, typedValue, true)
|
||||
window?.navigationBarColor = typedValue.data
|
||||
return binding.root
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import ani.dantotsu.BottomSheetDialogFragment
|
||||
import ani.dantotsu.FileUrl
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.BottomSheetImageBinding
|
||||
import ani.dantotsu.media.manga.mangareader.BaseImageAdapter.Companion.loadBitmap
|
||||
import ani.dantotsu.media.manga.mangareader.BaseImageAdapter.Companion.loadBitmap_old
|
||||
import ani.dantotsu.media.manga.mangareader.BaseImageAdapter.Companion.mergeBitmap
|
||||
import ani.dantotsu.openLinkInBrowser
|
||||
@@ -73,12 +74,17 @@ class ImageViewDialog : BottomSheetDialogFragment() {
|
||||
if (image2 != null) openLinkInBrowser(image2.url)
|
||||
true
|
||||
}
|
||||
val context = requireContext()
|
||||
|
||||
lifecycleScope.launch {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
val binding = _binding ?: return@launch
|
||||
|
||||
var bitmap = requireContext().loadBitmap_old(image, trans1 ?: listOf())
|
||||
val bitmap2 = if (image2 != null) requireContext().loadBitmap_old(image2, trans2 ?: listOf()) else null
|
||||
var bitmap = context.loadBitmap_old(image, trans1 ?: listOf())
|
||||
var bitmap2 = if (image2 != null) context.loadBitmap_old(image2, trans2 ?: listOf()) else null
|
||||
if (bitmap == null) {
|
||||
bitmap = context.loadBitmap(image, trans1 ?: listOf())
|
||||
bitmap2 = if (image2 != null) context.loadBitmap(image2, trans2 ?: listOf()) else null
|
||||
}
|
||||
|
||||
bitmap = if (bitmap2 != null && bitmap != null) mergeBitmap(bitmap, bitmap2,) else bitmap
|
||||
|
||||
|
||||
@@ -57,17 +57,17 @@ abstract class BaseParser {
|
||||
setUserText("Searching : ${mediaObj.mainName()}")
|
||||
val results = search(mediaObj.mainName())
|
||||
val sortedResults = if (results.isNotEmpty()) {
|
||||
results.sortedByDescending { FuzzySearch.ratio(it.name, mediaObj.mainName()) }
|
||||
results.sortedByDescending { FuzzySearch.ratio(it.name.lowercase(), mediaObj.mainName().lowercase()) }
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
response = sortedResults.firstOrNull()
|
||||
|
||||
if (response == null || FuzzySearch.ratio(response.name, mediaObj.mainName()) < 100) {
|
||||
if (response == null || FuzzySearch.ratio(response.name.lowercase(), mediaObj.mainName().lowercase()) < 100) {
|
||||
setUserText("Searching : ${mediaObj.nameRomaji}")
|
||||
val romajiResults = search(mediaObj.nameRomaji)
|
||||
val sortedRomajiResults = if (romajiResults.isNotEmpty()) {
|
||||
romajiResults.sortedByDescending { FuzzySearch.ratio(it.name, mediaObj.nameRomaji) }
|
||||
romajiResults.sortedByDescending { FuzzySearch.ratio(it.name.lowercase(), mediaObj.nameRomaji.lowercase()) }
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
@@ -78,10 +78,10 @@ abstract class BaseParser {
|
||||
logger("No exact match found in results. Using closest match from RomajiResults.")
|
||||
closestRomaji
|
||||
} else {
|
||||
val romajiRatio = FuzzySearch.ratio(closestRomaji?.name ?: "", mediaObj.nameRomaji)
|
||||
val mainNameRatio = FuzzySearch.ratio(response.name, mediaObj.mainName())
|
||||
logger("Fuzzy ratio for closest match in results: $mainNameRatio for ${response.name}")
|
||||
logger("Fuzzy ratio for closest match in RomajiResults: $romajiRatio for ${closestRomaji?.name ?: "None"}")
|
||||
val romajiRatio = FuzzySearch.ratio(closestRomaji?.name?.lowercase() ?: "", mediaObj.nameRomaji.lowercase())
|
||||
val mainNameRatio = FuzzySearch.ratio(response.name.lowercase(), mediaObj.mainName().lowercase())
|
||||
logger("Fuzzy ratio for closest match in results: $mainNameRatio for ${response.name.lowercase()}")
|
||||
logger("Fuzzy ratio for closest match in RomajiResults: $romajiRatio for ${closestRomaji?.name?.lowercase() ?: "None"}")
|
||||
|
||||
if (romajiRatio > mainNameRatio) {
|
||||
logger("RomajiResults has a closer match. Replacing response.")
|
||||
|
||||
@@ -2,110 +2,81 @@ package ani.dantotsu.settings
|
||||
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.ContextCompat.getSystemService
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.FragmentAnimeExtensionsBinding
|
||||
import ani.dantotsu.loadData
|
||||
import com.bumptech.glide.Glide
|
||||
import ani.dantotsu.settings.paging.AnimeExtensionAdapter
|
||||
import ani.dantotsu.settings.paging.AnimeExtensionsViewModel
|
||||
import ani.dantotsu.settings.paging.AnimeExtensionsViewModelFactory
|
||||
import ani.dantotsu.settings.paging.OnAnimeInstallClickListener
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class AnimeExtensionsFragment : Fragment(),
|
||||
SearchQueryHandler {
|
||||
SearchQueryHandler, OnAnimeInstallClickListener {
|
||||
private var _binding: FragmentAnimeExtensionsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
val skipIcons = loadData("skip_extension_icons") ?: false
|
||||
private val viewModel: AnimeExtensionsViewModel by viewModels {
|
||||
AnimeExtensionsViewModelFactory(animeExtensionManager)
|
||||
}
|
||||
|
||||
private lateinit var extensionsRecyclerView: RecyclerView
|
||||
private lateinit var allextenstionsRecyclerView: RecyclerView
|
||||
private val animeExtensionManager: AnimeExtensionManager = Injekt.get<AnimeExtensionManager>()
|
||||
private val extensionsAdapter = AnimeExtensionsAdapter({ pkg ->
|
||||
if (isAdded) { // Check if the fragment is currently added to its activity
|
||||
val context = requireContext() // Store context in a variable
|
||||
val notificationManager =
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // Initialize NotificationManager once
|
||||
private val adapter by lazy {
|
||||
AnimeExtensionAdapter(this)
|
||||
}
|
||||
|
||||
if (pkg.hasUpdate) {
|
||||
animeExtensionManager.updateExtension(pkg)
|
||||
.observeOn(AndroidSchedulers.mainThread()) // Observe on main thread
|
||||
.subscribe(
|
||||
{ installStep ->
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_sync_24)
|
||||
.setContentTitle("Updating extension")
|
||||
.setContentText("Step: $installStep")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{ error ->
|
||||
FirebaseCrashlytics.getInstance().recordException(error)
|
||||
Log.e("AnimeExtensionsAdapter", "Error: ", error) // Log the error
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_ERROR
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_info_24)
|
||||
.setContentTitle("Update failed: ${error.message}")
|
||||
.setContentText("Error: ${error.message}")
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(androidx.media3.ui.R.drawable.exo_ic_check)
|
||||
.setContentTitle("Update complete")
|
||||
.setContentText("The extension has been successfully updated.")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
}
|
||||
)
|
||||
} else {
|
||||
animeExtensionManager.uninstallExtension(pkg.pkgName)
|
||||
private val animeExtensionManager: AnimeExtensionManager = Injekt.get()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentAnimeExtensionsBinding.inflate(inflater, container, false)
|
||||
|
||||
binding.allAnimeExtensionsRecyclerView.isNestedScrollingEnabled = false
|
||||
binding.allAnimeExtensionsRecyclerView.adapter = adapter
|
||||
binding.allAnimeExtensionsRecyclerView.layoutManager = LinearLayoutManager(context)
|
||||
(binding.allAnimeExtensionsRecyclerView.layoutManager as LinearLayoutManager).isItemPrefetchEnabled = true
|
||||
|
||||
lifecycleScope.launch {
|
||||
viewModel.pagerFlow.collectLatest {
|
||||
adapter.submitData(it)
|
||||
}
|
||||
}
|
||||
}, skipIcons)
|
||||
|
||||
private val allExtensionsAdapter = AllAnimeExtensionsAdapter(lifecycleScope, { pkgName ->
|
||||
viewModel.invalidatePager() // Force a refresh of the pager
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun updateContentBasedOnQuery(query: String?) {
|
||||
viewModel.setSearchQuery(query ?: "")
|
||||
}
|
||||
|
||||
override fun onInstallClick(pkg: AnimeExtension.Available) {
|
||||
val context = requireContext()
|
||||
if (isAdded) {
|
||||
val notificationManager =
|
||||
requireContext().getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
||||
// Start the installation process
|
||||
animeExtensionManager.installExtension(pkgName)
|
||||
animeExtensionManager.installExtension(pkg)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{ installStep ->
|
||||
@@ -136,63 +107,15 @@ class AnimeExtensionsFragment : Fragment(),
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(androidx.media3.ui.R.drawable.exo_ic_check)
|
||||
.setSmallIcon(R.drawable.ic_round_download_24)
|
||||
.setContentTitle("Installation complete")
|
||||
.setContentText("The extension has been successfully installed.")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
viewModel.invalidatePager()
|
||||
}
|
||||
)
|
||||
}
|
||||
}, skipIcons)
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentAnimeExtensionsBinding.inflate(inflater, container, false)
|
||||
|
||||
extensionsRecyclerView = binding.animeExtensionsRecyclerView
|
||||
extensionsRecyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||
extensionsRecyclerView.adapter = extensionsAdapter
|
||||
|
||||
allextenstionsRecyclerView = binding.allAnimeExtensionsRecyclerView
|
||||
allextenstionsRecyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||
allextenstionsRecyclerView.adapter = allExtensionsAdapter
|
||||
|
||||
lifecycleScope.launch {
|
||||
animeExtensionManager.installedExtensionsFlow.collect { extensions ->
|
||||
extensionsAdapter.updateData(extensions)
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
combine(
|
||||
animeExtensionManager.availableExtensionsFlow,
|
||||
animeExtensionManager.installedExtensionsFlow
|
||||
) { availableExtensions, installedExtensions ->
|
||||
// Pair of available and installed extensions
|
||||
Pair(availableExtensions, installedExtensions)
|
||||
}.collect { pair ->
|
||||
val (availableExtensions, installedExtensions) = pair
|
||||
|
||||
allExtensionsAdapter.updateData(availableExtensions, installedExtensions)
|
||||
}
|
||||
}
|
||||
val extensionsRecyclerView: RecyclerView = binding.animeExtensionsRecyclerView
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun updateContentBasedOnQuery(query: String?) {
|
||||
if (query.isNullOrEmpty()) {
|
||||
allExtensionsAdapter.filter("") // Reset the filter
|
||||
allextenstionsRecyclerView.visibility = View.VISIBLE
|
||||
extensionsRecyclerView.visibility = View.VISIBLE
|
||||
} else {
|
||||
allExtensionsAdapter.filter(query)
|
||||
allextenstionsRecyclerView.visibility = View.VISIBLE
|
||||
extensionsRecyclerView.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
@@ -200,158 +123,4 @@ class AnimeExtensionsFragment : Fragment(),
|
||||
}
|
||||
|
||||
|
||||
private class AnimeExtensionsAdapter(
|
||||
private val onUninstallClicked: (AnimeExtension.Installed) -> Unit,
|
||||
skipIcons: Boolean
|
||||
) : ListAdapter<AnimeExtension.Installed, AnimeExtensionsAdapter.ViewHolder>(
|
||||
DIFF_CALLBACK_INSTALLED
|
||||
) {
|
||||
|
||||
val skipIcons = skipIcons
|
||||
|
||||
fun updateData(newExtensions: List<AnimeExtension.Installed>) {
|
||||
submitList(newExtensions) // Use submitList instead of manual list handling
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_extension, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val extension = getItem(position) // Use getItem() from ListAdapter
|
||||
holder.extensionNameTextView.text = extension.name
|
||||
if (!skipIcons) {
|
||||
holder.extensionIconImageView.setImageDrawable(extension.icon)
|
||||
}
|
||||
if (extension.hasUpdate) {
|
||||
holder.closeTextView.text = "Update"
|
||||
holder.closeTextView.setTextColor(
|
||||
ContextCompat.getColor(
|
||||
holder.itemView.context,
|
||||
R.color.warning
|
||||
)
|
||||
)
|
||||
} else {
|
||||
holder.closeTextView.text = "Uninstall"
|
||||
}
|
||||
holder.closeTextView.setOnClickListener {
|
||||
onUninstallClicked(extension)
|
||||
}
|
||||
}
|
||||
|
||||
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val extensionNameTextView: TextView = view.findViewById(R.id.extensionNameTextView)
|
||||
val extensionIconImageView: ImageView = view.findViewById(R.id.extensionIconImageView)
|
||||
val closeTextView: TextView = view.findViewById(R.id.closeTextView)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DIFF_CALLBACK_INSTALLED =
|
||||
object : DiffUtil.ItemCallback<AnimeExtension.Installed>() {
|
||||
override fun areItemsTheSame(
|
||||
oldItem: AnimeExtension.Installed,
|
||||
newItem: AnimeExtension.Installed
|
||||
): Boolean {
|
||||
return oldItem.pkgName == newItem.pkgName
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(
|
||||
oldItem: AnimeExtension.Installed,
|
||||
newItem: AnimeExtension.Installed
|
||||
): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class AllAnimeExtensionsAdapter(
|
||||
private val coroutineScope: CoroutineScope,
|
||||
private val onButtonClicked: (AnimeExtension.Available) -> Unit,
|
||||
skipIcons: Boolean
|
||||
) : ListAdapter<AnimeExtension.Available, AllAnimeExtensionsAdapter.ViewHolder>(
|
||||
DIFF_CALLBACK_AVAILABLE
|
||||
) {
|
||||
val skipIcons = skipIcons
|
||||
|
||||
fun updateData(
|
||||
newExtensions: List<AnimeExtension.Available>,
|
||||
installedExtensions: List<AnimeExtension.Installed> = emptyList()
|
||||
) {
|
||||
coroutineScope.launch(Dispatchers.Default) {
|
||||
val installedPkgNames = installedExtensions.map { it.pkgName }.toSet()
|
||||
val filteredExtensions = newExtensions.filter { it.pkgName !in installedPkgNames }
|
||||
|
||||
// Switch back to main thread to update UI
|
||||
withContext(Dispatchers.Main) {
|
||||
submitList(filteredExtensions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onCreateViewHolder(
|
||||
parent: ViewGroup,
|
||||
viewType: Int
|
||||
): AllAnimeExtensionsAdapter.ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_extension_all, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val extension = getItem(position)
|
||||
|
||||
holder.extensionNameTextView.text = extension.name
|
||||
|
||||
if (!skipIcons) {
|
||||
Glide.with(holder.itemView.context)
|
||||
.load(extension.iconUrl)
|
||||
.into(holder.extensionIconImageView)
|
||||
}
|
||||
|
||||
holder.closeTextView.text = "Install"
|
||||
holder.closeTextView.setOnClickListener {
|
||||
onButtonClicked(extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun filter(query: String) {
|
||||
val filteredExtensions = if (query.isEmpty()) {
|
||||
currentList
|
||||
} else {
|
||||
currentList.filter { it.name.contains(query, ignoreCase = true) }
|
||||
}
|
||||
submitList(filteredExtensions)
|
||||
}
|
||||
|
||||
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val extensionNameTextView: TextView = view.findViewById(R.id.extensionNameTextView)
|
||||
val extensionIconImageView: ImageView = view.findViewById(R.id.extensionIconImageView)
|
||||
val closeTextView: TextView = view.findViewById(R.id.closeTextView)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DIFF_CALLBACK_AVAILABLE =
|
||||
object : DiffUtil.ItemCallback<AnimeExtension.Available>() {
|
||||
override fun areItemsTheSame(
|
||||
oldItem: AnimeExtension.Available,
|
||||
newItem: AnimeExtension.Available
|
||||
): Boolean {
|
||||
return oldItem.pkgName == newItem.pkgName
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(
|
||||
oldItem: AnimeExtension.Available,
|
||||
newItem: AnimeExtension.Available
|
||||
): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,26 +13,8 @@ class DevelopersDialogFragment : BottomSheetDialogFragment() {
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val developers = arrayOf(
|
||||
Developer("vorobyovgabriel","https://avatars.githubusercontent.com/u/99561687?s=120&v=4","Owner","https://github.com/vorobyovgabriel"),
|
||||
Developer("brahmkshtriya","https://avatars.githubusercontent.com/u/69040506?s=120&v=4","Maintainer","https://github.com/brahmkshatriya"),
|
||||
Developer("jeelpatel231","https://avatars.githubusercontent.com/u/33726155?s=120&v=4","Contributor","https://github.com/jeelpatel231"),
|
||||
Developer("blatzar","https://avatars.githubusercontent.com/u/46196380?s=120&v=4","Contributor","https://github.com/Blatzar"),
|
||||
Developer("bilibox","https://avatars.githubusercontent.com/u/1800580?s=120&v=4","Contributor","https://github.com/Bilibox"),
|
||||
Developer("sutslec","https://avatars.githubusercontent.com/u/27722281?s=120&v=4","Contributor","https://github.com/Sutslec"),
|
||||
Developer("4jx","https://avatars.githubusercontent.com/u/79868816?s=120&v=4","Contributor","https://github.com/4JX"),
|
||||
Developer("xtrm-en","https://avatars.githubusercontent.com/u/26600206?s=120&v=4","Contributor","https://github.com/xtrm-en"),
|
||||
Developer("scrazzz","https://avatars.githubusercontent.com/u/70033559?s=120&v=4","Contributor","https://github.com/scrazzz"),
|
||||
Developer("defcoding","https://avatars.githubusercontent.com/u/39608887?s=120&v=4","Contributor","https://github.com/defcoding"),
|
||||
Developer("adolar0042","https://avatars.githubusercontent.com/u/39769465?s=120&v=4","Contributor","https://github.com/adolar0042"),
|
||||
Developer("diegopyl1209","https://avatars.githubusercontent.com/u/80992641?s=120&v=4","Contributor","https://github.com/diegopyl1209"),
|
||||
Developer("sreekrishna2001","https://avatars.githubusercontent.com/u/67505103?s=120&v=4","Contributor","https://github.com/Sreekrishna2001"),
|
||||
Developer("riimuru","https://avatars.githubusercontent.com/u/57333995?s=120&v=4","Contributor","https://github.com/riimuru"),
|
||||
Developer("vu nguyen","https://avatars.githubusercontent.com/u/68330291?s=120&v=4","Contributor","https://github.com/hoangvu12"),
|
||||
Developer("animejeff","https://avatars.githubusercontent.com/u/101831300?s=120&v=4","Contributor","https://github.com/AnimeJeff"),
|
||||
Developer("antonydp","https://avatars.githubusercontent.com/u/38143733?s=120&v=4","Contributor","https://github.com/antonydp"),
|
||||
Developer("tobybridle","https://avatars.githubusercontent.com/u/52335751?s=120&v=4","Contributor","https://github.com/TobyBridle"),
|
||||
Developer("enimax","https://avatars.githubusercontent.com/u/107899019?s=120&v=4","Contributor","https://github.com/enimax-anime"),
|
||||
Developer("vipulog","https://avatars.githubusercontent.com/u/90324465?s=120&v=4","Contributor","https://github.com/VipulOG")
|
||||
Developer("rebelonion","https://avatars.githubusercontent.com/u/87634197?v=4","Owner and Maintainer","https://github.com/rebelonion"),
|
||||
Developer("Wai What", "https://cdn.discordapp.com/avatars/928202695611908126/aeac4c867acbb8c3783356497055a426.webp?size=80", "Icon Designer", ""),
|
||||
)
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
|
||||
@@ -1,55 +1,26 @@
|
||||
package ani.dantotsu.settings
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Build.*
|
||||
import android.os.Build.VERSION.*
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.AutoCompleteTextView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.SearchView
|
||||
import android.widget.TextView
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import ani.dantotsu.*
|
||||
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
|
||||
import ani.dantotsu.databinding.ActivityExtensionsBinding
|
||||
import ani.dantotsu.home.AnimeFragment
|
||||
import ani.dantotsu.home.MangaFragment
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class ExtensionsActivity : AppCompatActivity() {
|
||||
private val restartMainActivity = object : OnBackPressedCallback(false) {
|
||||
@@ -70,12 +41,14 @@ class ExtensionsActivity : AppCompatActivity() {
|
||||
val viewPager = findViewById<ViewPager2>(R.id.viewPager)
|
||||
|
||||
viewPager.adapter = object : FragmentStateAdapter(this) {
|
||||
override fun getItemCount(): Int = 2
|
||||
override fun getItemCount(): Int = 4
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return when (position) {
|
||||
0 -> AnimeExtensionsFragment()
|
||||
1 -> MangaExtensionsFragment()
|
||||
0 -> InstalledAnimeExtensionsFragment()
|
||||
1 -> AnimeExtensionsFragment()
|
||||
2 -> InstalledMangaExtensionsFragment()
|
||||
3 -> MangaExtensionsFragment()
|
||||
else -> AnimeExtensionsFragment()
|
||||
}
|
||||
}
|
||||
@@ -83,28 +56,29 @@ class ExtensionsActivity : AppCompatActivity() {
|
||||
|
||||
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
|
||||
tab.text = when (position) {
|
||||
0 -> "Anime" // Your tab title
|
||||
1 -> "Manga" // Your tab title
|
||||
0 -> "Installed Anime"
|
||||
1 -> "Available Anime"
|
||||
2 -> "Installed Manga"
|
||||
3 -> "Available Manga"
|
||||
else -> null
|
||||
}
|
||||
}.attach()
|
||||
|
||||
|
||||
val searchView: SearchView = findViewById(R.id.searchView)
|
||||
val searchView: AutoCompleteTextView = findViewById(R.id.searchViewText)
|
||||
|
||||
val extensionsHeader: LinearLayout = findViewById(R.id.extensionsHeader)
|
||||
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||
return false
|
||||
searchView.addTextChangedListener(object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
val currentFragment = supportFragmentManager.findFragmentByTag("f${viewPager.currentItem}")
|
||||
if (currentFragment is SearchQueryHandler) {
|
||||
currentFragment.updateContentBasedOnQuery(newText)
|
||||
currentFragment.updateContentBasedOnQuery(s?.toString()?.trim())
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
package ani.dantotsu.settings
|
||||
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.FragmentAnimeExtensionsBinding
|
||||
import ani.dantotsu.loadData
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
|
||||
import kotlinx.coroutines.launch
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class InstalledAnimeExtensionsFragment : Fragment() {
|
||||
private var _binding: FragmentAnimeExtensionsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private lateinit var extensionsRecyclerView: RecyclerView
|
||||
val skipIcons = loadData("skip_extension_icons") ?: false
|
||||
private val animeExtensionManager: AnimeExtensionManager = Injekt.get()
|
||||
private val extensionsAdapter = AnimeExtensionsAdapter({ pkg ->
|
||||
if (isAdded) { // Check if the fragment is currently added to its activity
|
||||
val context = requireContext() // Store context in a variable
|
||||
val notificationManager =
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // Initialize NotificationManager once
|
||||
|
||||
if (pkg.hasUpdate) {
|
||||
animeExtensionManager.updateExtension(pkg)
|
||||
.observeOn(AndroidSchedulers.mainThread()) // Observe on main thread
|
||||
.subscribe(
|
||||
{ installStep ->
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_sync_24)
|
||||
.setContentTitle("Updating extension")
|
||||
.setContentText("Step: $installStep")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{ error ->
|
||||
FirebaseCrashlytics.getInstance().recordException(error)
|
||||
Log.e("AnimeExtensionsAdapter", "Error: ", error) // Log the error
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_ERROR
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_info_24)
|
||||
.setContentTitle("Update failed: ${error.message}")
|
||||
.setContentText("Error: ${error.message}")
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(androidx.media3.ui.R.drawable.exo_ic_check)
|
||||
.setContentTitle("Update complete")
|
||||
.setContentText("The extension has been successfully updated.")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
}
|
||||
)
|
||||
} else {
|
||||
animeExtensionManager.uninstallExtension(pkg.pkgName)
|
||||
}
|
||||
}
|
||||
}, skipIcons)
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentAnimeExtensionsBinding.inflate(inflater, container, false)
|
||||
|
||||
extensionsRecyclerView = binding.allAnimeExtensionsRecyclerView
|
||||
extensionsRecyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||
extensionsRecyclerView.adapter = extensionsAdapter
|
||||
|
||||
|
||||
lifecycleScope.launch {
|
||||
animeExtensionManager.installedExtensionsFlow.collect { extensions ->
|
||||
extensionsAdapter.updateData(extensions)
|
||||
}
|
||||
}
|
||||
val extensionsRecyclerView: RecyclerView = binding.allAnimeExtensionsRecyclerView
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView();_binding = null
|
||||
}
|
||||
|
||||
|
||||
private class AnimeExtensionsAdapter(
|
||||
private val onUninstallClicked: (AnimeExtension.Installed) -> Unit,
|
||||
skipIcons: Boolean
|
||||
) : ListAdapter<AnimeExtension.Installed, AnimeExtensionsAdapter.ViewHolder>(
|
||||
DIFF_CALLBACK_INSTALLED
|
||||
) {
|
||||
|
||||
val skipIcons = skipIcons
|
||||
|
||||
fun updateData(newExtensions: List<AnimeExtension.Installed>) {
|
||||
submitList(newExtensions) // Use submitList instead of manual list handling
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_extension, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val extension = getItem(position) // Use getItem() from ListAdapter
|
||||
holder.extensionNameTextView.text = extension.name
|
||||
if (!skipIcons) {
|
||||
holder.extensionIconImageView.setImageDrawable(extension.icon)
|
||||
}
|
||||
if (extension.hasUpdate) {
|
||||
holder.closeTextView.text = "Update"
|
||||
holder.closeTextView.setTextColor(
|
||||
ContextCompat.getColor(
|
||||
holder.itemView.context,
|
||||
R.color.warning
|
||||
)
|
||||
)
|
||||
} else {
|
||||
holder.closeTextView.text = "Uninstall"
|
||||
}
|
||||
holder.closeTextView.setOnClickListener {
|
||||
onUninstallClicked(extension)
|
||||
}
|
||||
}
|
||||
|
||||
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val extensionNameTextView: TextView = view.findViewById(R.id.extensionNameTextView)
|
||||
val extensionIconImageView: ImageView = view.findViewById(R.id.extensionIconImageView)
|
||||
val closeTextView: TextView = view.findViewById(R.id.closeTextView)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DIFF_CALLBACK_INSTALLED =
|
||||
object : DiffUtil.ItemCallback<AnimeExtension.Installed>() {
|
||||
override fun areItemsTheSame(
|
||||
oldItem: AnimeExtension.Installed,
|
||||
newItem: AnimeExtension.Installed
|
||||
): Boolean {
|
||||
return oldItem.pkgName == newItem.pkgName
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(
|
||||
oldItem: AnimeExtension.Installed,
|
||||
newItem: AnimeExtension.Installed
|
||||
): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package ani.dantotsu.settings
|
||||
|
||||
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.FragmentMangaExtensionsBinding
|
||||
import ani.dantotsu.loadData
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
|
||||
import kotlinx.coroutines.launch
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class InstalledMangaExtensionsFragment : Fragment() {
|
||||
private var _binding: FragmentMangaExtensionsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private lateinit var extensionsRecyclerView: RecyclerView
|
||||
val skipIcons = loadData("skip_extension_icons") ?: false
|
||||
private val mangaExtensionManager: MangaExtensionManager = Injekt.get()
|
||||
private val extensionsAdapter = MangaExtensionsAdapter({ pkg ->
|
||||
if (isAdded) { // Check if the fragment is currently added to its activity
|
||||
val context = requireContext() // Store context in a variable
|
||||
val notificationManager =
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // Initialize NotificationManager once
|
||||
|
||||
if (pkg.hasUpdate) {
|
||||
mangaExtensionManager.updateExtension(pkg)
|
||||
.observeOn(AndroidSchedulers.mainThread()) // Observe on main thread
|
||||
.subscribe(
|
||||
{ installStep ->
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_sync_24)
|
||||
.setContentTitle("Updating extension")
|
||||
.setContentText("Step: $installStep")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{ error ->
|
||||
FirebaseCrashlytics.getInstance().recordException(error)
|
||||
Log.e("MangaExtensionsAdapter", "Error: ", error) // Log the error
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_ERROR
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_info_24)
|
||||
.setContentTitle("Update failed: ${error.message}")
|
||||
.setContentText("Error: ${error.message}")
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(androidx.media3.ui.R.drawable.exo_ic_check)
|
||||
.setContentTitle("Update complete")
|
||||
.setContentText("The extension has been successfully updated.")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
}
|
||||
)
|
||||
} else {
|
||||
mangaExtensionManager.uninstallExtension(pkg.pkgName)
|
||||
}
|
||||
}
|
||||
}, skipIcons)
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentMangaExtensionsBinding.inflate(inflater, container, false)
|
||||
|
||||
extensionsRecyclerView = binding.allMangaExtensionsRecyclerView
|
||||
extensionsRecyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||
extensionsRecyclerView.adapter = extensionsAdapter
|
||||
|
||||
|
||||
lifecycleScope.launch {
|
||||
mangaExtensionManager.installedExtensionsFlow.collect { extensions ->
|
||||
extensionsAdapter.updateData(extensions)
|
||||
}
|
||||
}
|
||||
val extensionsRecyclerView: RecyclerView = binding.allMangaExtensionsRecyclerView
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView();_binding = null
|
||||
}
|
||||
|
||||
|
||||
private class MangaExtensionsAdapter(
|
||||
private val onUninstallClicked: (MangaExtension.Installed) -> Unit,
|
||||
skipIcons: Boolean
|
||||
) : ListAdapter<MangaExtension.Installed, MangaExtensionsAdapter.ViewHolder>(
|
||||
DIFF_CALLBACK_INSTALLED
|
||||
) {
|
||||
|
||||
val skipIcons = skipIcons
|
||||
|
||||
fun updateData(newExtensions: List<MangaExtension.Installed>) {
|
||||
submitList(newExtensions) // Use submitList instead of manual list handling
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_extension, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val extension = getItem(position) // Use getItem() from ListAdapter
|
||||
holder.extensionNameTextView.text = extension.name
|
||||
if (!skipIcons) {
|
||||
holder.extensionIconImageView.setImageDrawable(extension.icon)
|
||||
}
|
||||
if (extension.hasUpdate) {
|
||||
holder.closeTextView.text = "Update"
|
||||
holder.closeTextView.setTextColor(
|
||||
ContextCompat.getColor(
|
||||
holder.itemView.context,
|
||||
R.color.warning
|
||||
)
|
||||
)
|
||||
} else {
|
||||
holder.closeTextView.text = "Uninstall"
|
||||
}
|
||||
holder.closeTextView.setOnClickListener {
|
||||
onUninstallClicked(extension)
|
||||
}
|
||||
}
|
||||
|
||||
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val extensionNameTextView: TextView = view.findViewById(R.id.extensionNameTextView)
|
||||
val extensionIconImageView: ImageView = view.findViewById(R.id.extensionIconImageView)
|
||||
val closeTextView: TextView = view.findViewById(R.id.closeTextView)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DIFF_CALLBACK_INSTALLED =
|
||||
object : DiffUtil.ItemCallback<MangaExtension.Installed>() {
|
||||
override fun areItemsTheSame(
|
||||
oldItem: MangaExtension.Installed,
|
||||
newItem: MangaExtension.Installed
|
||||
): Boolean {
|
||||
return oldItem.pkgName == newItem.pkgName
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(
|
||||
oldItem: MangaExtension.Installed,
|
||||
newItem: MangaExtension.Installed
|
||||
): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -2,150 +2,48 @@ package ani.dantotsu.settings
|
||||
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.paging.PagingData
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.databinding.FragmentMangaBinding
|
||||
import ani.dantotsu.databinding.FragmentMangaExtensionsBinding
|
||||
import ani.dantotsu.loadData
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import ani.dantotsu.settings.paging.MangaExtensionAdapter
|
||||
import ani.dantotsu.settings.paging.MangaExtensionsViewModel
|
||||
import ani.dantotsu.settings.paging.MangaExtensionsViewModelFactory
|
||||
import ani.dantotsu.settings.paging.OnMangaInstallClickListener
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
|
||||
class MangaExtensionsFragment : Fragment(),
|
||||
SearchQueryHandler {
|
||||
SearchQueryHandler, OnMangaInstallClickListener {
|
||||
private var _binding: FragmentMangaExtensionsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
val skipIcons = loadData("skip_extension_icons") ?: false
|
||||
private val viewModel: MangaExtensionsViewModel by viewModels {
|
||||
MangaExtensionsViewModelFactory(mangaExtensionManager)
|
||||
}
|
||||
|
||||
private lateinit var extensionsRecyclerView: RecyclerView
|
||||
private lateinit var allextenstionsRecyclerView: RecyclerView
|
||||
private val mangaExtensionManager: MangaExtensionManager = Injekt.get<MangaExtensionManager>()
|
||||
private val extensionsAdapter = MangaExtensionsAdapter({ pkg ->
|
||||
if (isAdded) { // Check if the fragment is currently added to its activity
|
||||
val context = requireContext() // Store context in a variable
|
||||
val notificationManager =
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // Initialize NotificationManager once
|
||||
private val adapter by lazy {
|
||||
MangaExtensionAdapter(this)
|
||||
}
|
||||
|
||||
if (pkg.hasUpdate) {
|
||||
mangaExtensionManager.updateExtension(pkg)
|
||||
.observeOn(AndroidSchedulers.mainThread()) // Observe on main thread
|
||||
.subscribe(
|
||||
{ installStep ->
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_sync_24)
|
||||
.setContentTitle("Updating extension")
|
||||
.setContentText("Step: $installStep")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{ error ->
|
||||
FirebaseCrashlytics.getInstance().recordException(error)
|
||||
Log.e("MangaExtensionsAdapter", "Error: ", error) // Log the error
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_ERROR
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_info_24)
|
||||
.setContentTitle("Update failed")
|
||||
.setContentText("Error: ${error.message}")
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(androidx.media3.ui.R.drawable.exo_ic_check)
|
||||
.setContentTitle("Update complete")
|
||||
.setContentText("The extension has been successfully updated.")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
}
|
||||
)
|
||||
} else {
|
||||
mangaExtensionManager.uninstallExtension(pkg.pkgName)
|
||||
}
|
||||
}
|
||||
}, skipIcons)
|
||||
private val mangaExtensionManager: MangaExtensionManager = Injekt.get()
|
||||
|
||||
private val allExtensionsAdapter =
|
||||
AllMangaExtensionsAdapter(lifecycleScope, { pkgName ->
|
||||
if (isAdded) { // Check if the fragment is currently added to its activity
|
||||
val context = requireContext()
|
||||
val notificationManager =
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
||||
// Start the installation process
|
||||
mangaExtensionManager.installExtension(pkgName)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{ installStep ->
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_sync_24)
|
||||
.setContentTitle("Installing extension")
|
||||
.setContentText("Step: $installStep")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{ error ->
|
||||
FirebaseCrashlytics.getInstance().recordException(error)
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_ERROR
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_info_24)
|
||||
.setContentTitle("Installation failed: ${error.message}")
|
||||
.setContentText("Error: ${error.message}")
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(androidx.media3.ui.R.drawable.exo_ic_check)
|
||||
.setContentTitle("Installation complete")
|
||||
.setContentText("The extension has been successfully installed.")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
}
|
||||
)
|
||||
}
|
||||
}, skipIcons)
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@@ -154,44 +52,72 @@ class MangaExtensionsFragment : Fragment(),
|
||||
): View {
|
||||
_binding = FragmentMangaExtensionsBinding.inflate(inflater, container, false)
|
||||
|
||||
extensionsRecyclerView = binding.mangaExtensionsRecyclerView
|
||||
extensionsRecyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||
extensionsRecyclerView.adapter = extensionsAdapter
|
||||
|
||||
allextenstionsRecyclerView = binding.allMangaExtensionsRecyclerView
|
||||
allextenstionsRecyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||
allextenstionsRecyclerView.adapter = allExtensionsAdapter
|
||||
binding.allMangaExtensionsRecyclerView.isNestedScrollingEnabled = false
|
||||
binding.allMangaExtensionsRecyclerView.adapter = adapter
|
||||
binding.allMangaExtensionsRecyclerView.layoutManager = LinearLayoutManager(context)
|
||||
(binding.allMangaExtensionsRecyclerView.layoutManager as LinearLayoutManager).isItemPrefetchEnabled = true
|
||||
|
||||
lifecycleScope.launch {
|
||||
mangaExtensionManager.installedExtensionsFlow.collect { extensions ->
|
||||
extensionsAdapter.updateData(extensions)
|
||||
viewModel.pagerFlow.collectLatest { pagingData ->
|
||||
adapter.submitData(pagingData)
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
combine(
|
||||
mangaExtensionManager.availableExtensionsFlow,
|
||||
mangaExtensionManager.installedExtensionsFlow
|
||||
) { availableExtensions, installedExtensions ->
|
||||
// Pair of available and installed extensions
|
||||
Pair(availableExtensions, installedExtensions)
|
||||
}.collect { pair ->
|
||||
val (availableExtensions, installedExtensions) = pair
|
||||
allExtensionsAdapter.updateData(availableExtensions, installedExtensions)
|
||||
}
|
||||
}
|
||||
val extensionsRecyclerView: RecyclerView = binding.mangaExtensionsRecyclerView
|
||||
|
||||
viewModel.invalidatePager() // Force a refresh of the pager
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun updateContentBasedOnQuery(query: String?) {
|
||||
if (query.isNullOrEmpty()) {
|
||||
allExtensionsAdapter.filter("") // Reset the filter
|
||||
allextenstionsRecyclerView.visibility = View.VISIBLE
|
||||
extensionsRecyclerView.visibility = View.VISIBLE
|
||||
} else {
|
||||
allExtensionsAdapter.filter(query)
|
||||
allextenstionsRecyclerView.visibility = View.VISIBLE
|
||||
extensionsRecyclerView.visibility = View.GONE
|
||||
viewModel.setSearchQuery(query ?: "")
|
||||
}
|
||||
|
||||
override fun onInstallClick(pkg: MangaExtension.Available) {
|
||||
if (isAdded) { // Check if the fragment is currently added to its activity
|
||||
val context = requireContext()
|
||||
val notificationManager =
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
||||
// Start the installation process
|
||||
mangaExtensionManager.installExtension(pkg)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{ installStep ->
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_sync_24)
|
||||
.setContentTitle("Installing extension")
|
||||
.setContentText("Step: $installStep")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{ error ->
|
||||
FirebaseCrashlytics.getInstance().recordException(error)
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_ERROR
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_info_24)
|
||||
.setContentTitle("Installation failed: ${error.message}")
|
||||
.setContentText("Error: ${error.message}")
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_download_24)
|
||||
.setContentTitle("Installation complete")
|
||||
.setContentText("The extension has been successfully installed.")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
viewModel.invalidatePager()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,165 +125,6 @@ class MangaExtensionsFragment : Fragment(),
|
||||
super.onDestroyView();_binding = null
|
||||
}
|
||||
|
||||
private class MangaExtensionsAdapter(
|
||||
private val onUninstallClicked: (MangaExtension.Installed) -> Unit,
|
||||
skipIcons: Boolean
|
||||
) : ListAdapter<MangaExtension.Installed, MangaExtensionsAdapter.ViewHolder>(
|
||||
DIFF_CALLBACK_INSTALLED
|
||||
) {
|
||||
|
||||
val skipIcons = skipIcons
|
||||
|
||||
// Use submitList to update data
|
||||
fun updateData(newExtensions: List<MangaExtension.Installed>) {
|
||||
submitList(newExtensions)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_extension, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val extension = getItem(position) // Use getItem from ListAdapter
|
||||
|
||||
holder.extensionNameTextView.text = extension.name
|
||||
if (!skipIcons) {
|
||||
holder.extensionIconImageView.setImageDrawable(extension.icon)
|
||||
}
|
||||
|
||||
if (extension.hasUpdate) {
|
||||
holder.closeTextView.text = "Update"
|
||||
holder.closeTextView.setTextColor(
|
||||
ContextCompat.getColor(
|
||||
holder.itemView.context,
|
||||
R.color.warning
|
||||
)
|
||||
)
|
||||
} else {
|
||||
holder.closeTextView.text = "Uninstall"
|
||||
}
|
||||
|
||||
holder.closeTextView.setOnClickListener {
|
||||
onUninstallClicked(extension)
|
||||
}
|
||||
}
|
||||
|
||||
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val extensionNameTextView: TextView = view.findViewById(R.id.extensionNameTextView)
|
||||
val extensionIconImageView: ImageView = view.findViewById(R.id.extensionIconImageView)
|
||||
val closeTextView: TextView = view.findViewById(R.id.closeTextView)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DIFF_CALLBACK_INSTALLED =
|
||||
object : DiffUtil.ItemCallback<MangaExtension.Installed>() {
|
||||
override fun areItemsTheSame(
|
||||
oldItem: MangaExtension.Installed,
|
||||
newItem: MangaExtension.Installed
|
||||
): Boolean {
|
||||
return oldItem.pkgName == newItem.pkgName
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(
|
||||
oldItem: MangaExtension.Installed,
|
||||
newItem: MangaExtension.Installed
|
||||
): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class AllMangaExtensionsAdapter(
|
||||
private val coroutineScope: CoroutineScope,
|
||||
private val onButtonClicked: (MangaExtension.Available) -> Unit,
|
||||
skipIcons: Boolean
|
||||
) : ListAdapter<MangaExtension.Available, AllMangaExtensionsAdapter.ViewHolder>(
|
||||
DIFF_CALLBACK_AVAILABLE
|
||||
) {
|
||||
init {
|
||||
setHasStableIds(true)
|
||||
}
|
||||
|
||||
|
||||
val skipIcons = skipIcons
|
||||
|
||||
// Use submitList to update the data
|
||||
fun updateData(
|
||||
newExtensions: List<MangaExtension.Available>,
|
||||
installedExtensions: List<MangaExtension.Installed> = emptyList()
|
||||
) {
|
||||
coroutineScope.launch(Dispatchers.Default) {
|
||||
val installedPkgNames = installedExtensions.map { it.pkgName }.toSet()
|
||||
val filteredExtensions = newExtensions.filter { it.pkgName !in installedPkgNames }
|
||||
|
||||
// Switch back to main thread to update UI
|
||||
withContext(Dispatchers.Main) {
|
||||
submitList(filteredExtensions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_extension_all, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val extension = getItem(position) // Use getItem from ListAdapter
|
||||
|
||||
holder.extensionNameTextView.text = extension.name
|
||||
if (!skipIcons) {
|
||||
Glide.with(holder.itemView.context)
|
||||
.load(extension.iconUrl)
|
||||
.into(holder.extensionIconImageView)
|
||||
}
|
||||
|
||||
holder.closeTextView.text = "Install"
|
||||
holder.closeTextView.setOnClickListener {
|
||||
onButtonClicked(extension)
|
||||
}
|
||||
}
|
||||
|
||||
// Filtering function
|
||||
fun filter(query: String) {
|
||||
val filteredExtensions = if (query.isEmpty()) {
|
||||
currentList
|
||||
} else {
|
||||
currentList.filter { it.name.contains(query, ignoreCase = true) }
|
||||
}
|
||||
submitList(filteredExtensions)
|
||||
}
|
||||
|
||||
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val extensionNameTextView: TextView = view.findViewById(R.id.extensionNameTextView)
|
||||
val extensionIconImageView: ImageView = view.findViewById(R.id.extensionIconImageView)
|
||||
val closeTextView: TextView = view.findViewById(R.id.closeTextView)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DIFF_CALLBACK_AVAILABLE =
|
||||
object : DiffUtil.ItemCallback<MangaExtension.Available>() {
|
||||
override fun areItemsTheSame(
|
||||
oldItem: MangaExtension.Available,
|
||||
newItem: MangaExtension.Available
|
||||
): Boolean {
|
||||
return oldItem.pkgName == newItem.pkgName
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(
|
||||
oldItem: MangaExtension.Available,
|
||||
newItem: MangaExtension.Available
|
||||
): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import ani.dantotsu.subcriptions.Subscription.Companion.defaultTime
|
||||
import ani.dantotsu.subcriptions.Subscription.Companion.startSubscription
|
||||
import ani.dantotsu.subcriptions.Subscription.Companion.timeMinutes
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.tachiyomi.network.NetworkPreferences
|
||||
import io.noties.markwon.Markwon
|
||||
@@ -101,7 +102,13 @@ OS Version: $CODENAME $RELEASE ($SDK_INT)
|
||||
binding.settingsUseMaterialYou.isChecked = getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getBoolean("use_material_you", false)
|
||||
binding.settingsUseMaterialYou.setOnCheckedChangeListener { _, isChecked ->
|
||||
getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).edit().putBoolean("use_material_you", isChecked).apply()
|
||||
Toast.makeText(this, "Restart app to apply changes", Toast.LENGTH_LONG).show()
|
||||
restartApp()
|
||||
}
|
||||
|
||||
binding.settingsUseOLED.isChecked = getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getBoolean("use_oled", false)
|
||||
binding.settingsUseOLED.setOnCheckedChangeListener { _, isChecked ->
|
||||
getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).edit().putBoolean("use_oled", isChecked).apply()
|
||||
restartApp()
|
||||
}
|
||||
|
||||
val themeString = getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getString("theme", "PURPLE")!!
|
||||
@@ -111,12 +118,9 @@ OS Version: $CODENAME $RELEASE ($SDK_INT)
|
||||
|
||||
binding.themeSwitcher.setOnItemClickListener { _, _, i, _ ->
|
||||
getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).edit().putString("theme", ThemeManager.Companion.Theme.values()[i].theme).apply()
|
||||
ActivityHelper.shouldRefreshMainActivity = true
|
||||
//ActivityHelper.shouldRefreshMainActivity = true
|
||||
binding.themeSwitcher.clearFocus()
|
||||
Refresh.all()
|
||||
finish()
|
||||
startActivity(Intent(this, SettingsActivity::class.java))
|
||||
initActivity(this)
|
||||
restartApp()
|
||||
|
||||
}
|
||||
|
||||
@@ -410,7 +414,7 @@ OS Version: $CODENAME $RELEASE ($SDK_INT)
|
||||
}
|
||||
}
|
||||
|
||||
var curTime = loadData<Int>("subscriptions_time_r") ?: defaultTime
|
||||
var curTime = loadData<Int>("subscriptions_time_s") ?: defaultTime
|
||||
val timeNames = timeMinutes.map {
|
||||
val mins = it % 60
|
||||
val hours = it / 60
|
||||
@@ -423,7 +427,7 @@ OS Version: $CODENAME $RELEASE ($SDK_INT)
|
||||
speedDialog.setSingleChoiceItems(timeNames, curTime) { dialog, i ->
|
||||
curTime = i
|
||||
binding.settingsSubscriptionsTime.text = getString(R.string.subscriptions_checking_time_s, timeNames[i])
|
||||
saveData("subscriptions_time_r", curTime)
|
||||
saveData("subscriptions_time_s", curTime)
|
||||
dialog.dismiss()
|
||||
startSubscription(true)
|
||||
}.show()
|
||||
@@ -586,4 +590,18 @@ OS Version: $CODENAME $RELEASE ($SDK_INT)
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun restartApp() {
|
||||
Snackbar.make(
|
||||
binding.root,
|
||||
R.string.restart_app, Snackbar.LENGTH_SHORT
|
||||
).apply {
|
||||
val mainIntent =
|
||||
Intent.makeRestartActivityTask(context.packageManager.getLaunchIntentForPackage(context.packageName)!!.component)
|
||||
setAction("Do it!") {
|
||||
context.startActivity(mainIntent)
|
||||
Runtime.getRuntime().exit(0)
|
||||
}
|
||||
show()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,10 @@ package ani.dantotsu.settings
|
||||
import android.app.DownloadManager
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -26,6 +28,12 @@ class SettingsDialogFragment : BottomSheetDialogFragment() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val window = dialog?.window
|
||||
window?.statusBarColor = Color.CYAN
|
||||
val typedValue = TypedValue()
|
||||
val theme = requireContext().theme
|
||||
theme.resolveAttribute(com.google.android.material.R.attr.colorSurface, typedValue, true)
|
||||
window?.navigationBarColor = typedValue.data
|
||||
|
||||
if (Anilist.token != null) {
|
||||
binding.settingsLogin.setText(R.string.logout)
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
package ani.dantotsu.settings.paging
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.paging.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.PagingData
|
||||
import androidx.paging.PagingDataAdapter
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import androidx.paging.cachedIn
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import ani.dantotsu.databinding.ItemExtensionAllBinding
|
||||
import ani.dantotsu.loadData
|
||||
import com.bumptech.glide.Glide
|
||||
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
|
||||
|
||||
class AnimeExtensionsViewModelFactory(
|
||||
private val animeExtensionManager: AnimeExtensionManager
|
||||
) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return AnimeExtensionsViewModel(animeExtensionManager) as T
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class AnimeExtensionsViewModel(
|
||||
private val animeExtensionManager: AnimeExtensionManager
|
||||
) : ViewModel() {
|
||||
private val searchQuery = MutableStateFlow("")
|
||||
private var currentPagingSource: AnimeExtensionPagingSource? = null
|
||||
fun setSearchQuery(query: String) {
|
||||
searchQuery.value = query
|
||||
}
|
||||
fun invalidatePager() {
|
||||
currentPagingSource?.invalidate()
|
||||
}
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val pagerFlow: Flow<PagingData<AnimeExtension.Available>> = searchQuery.flatMapLatest { query ->
|
||||
Pager(
|
||||
PagingConfig(
|
||||
pageSize = 15,
|
||||
initialLoadSize = 15,
|
||||
prefetchDistance = 15
|
||||
)
|
||||
) {
|
||||
AnimeExtensionPagingSource(
|
||||
animeExtensionManager.availableExtensionsFlow,
|
||||
animeExtensionManager.installedExtensionsFlow,
|
||||
searchQuery
|
||||
).also { currentPagingSource = it }
|
||||
}.flow
|
||||
}.cachedIn(viewModelScope)
|
||||
}
|
||||
|
||||
class AnimeExtensionPagingSource(
|
||||
private val availableExtensionsFlow: StateFlow<List<AnimeExtension.Available>>,
|
||||
private val installedExtensionsFlow: StateFlow<List<AnimeExtension.Installed>>,
|
||||
private val searchQuery: StateFlow<String>
|
||||
) : PagingSource<Int, AnimeExtension.Available>() {
|
||||
|
||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, AnimeExtension.Available> {
|
||||
val position = params.key ?: 0
|
||||
val installedExtensions = installedExtensionsFlow.first().map { it.pkgName }.toSet()
|
||||
val availableExtensions = availableExtensionsFlow.first().filterNot { it.pkgName in installedExtensions }
|
||||
val query = searchQuery.first()
|
||||
val filteredExtensions = if (query.isEmpty()) {
|
||||
availableExtensions
|
||||
} else {
|
||||
availableExtensions.filter { it.name.contains(query, ignoreCase = true) }
|
||||
}
|
||||
|
||||
return try {
|
||||
val sublist = filteredExtensions.subList(
|
||||
fromIndex = position,
|
||||
toIndex = (position + params.loadSize).coerceAtMost(filteredExtensions.size)
|
||||
)
|
||||
LoadResult.Page(
|
||||
data = sublist,
|
||||
prevKey = if (position == 0) null else position - params.loadSize,
|
||||
nextKey = if (position + params.loadSize >= filteredExtensions.size) null else position + params.loadSize
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
LoadResult.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getRefreshKey(state: PagingState<Int, AnimeExtension.Available>): Int? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class AnimeExtensionAdapter(private val clickListener: OnAnimeInstallClickListener) :
|
||||
PagingDataAdapter<AnimeExtension.Available, AnimeExtensionAdapter.AnimeExtensionViewHolder>(
|
||||
DIFF_CALLBACK
|
||||
) {
|
||||
|
||||
private val skipIcons = loadData("skip_extension_icons") ?: false
|
||||
|
||||
companion object {
|
||||
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<AnimeExtension.Available>() {
|
||||
override fun areItemsTheSame(oldItem: AnimeExtension.Available, newItem: AnimeExtension.Available): Boolean {
|
||||
// Your logic here
|
||||
return oldItem.pkgName == newItem.pkgName
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: AnimeExtension.Available, newItem: AnimeExtension.Available): Boolean {
|
||||
// Your logic here
|
||||
return oldItem == newItem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AnimeExtensionViewHolder {
|
||||
val binding = ItemExtensionAllBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return AnimeExtensionViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: AnimeExtensionViewHolder, position: Int) {
|
||||
val extension = getItem(position)
|
||||
if (extension != null) {
|
||||
if (!skipIcons) {
|
||||
Glide.with(holder.itemView.context)
|
||||
.load(extension.iconUrl)
|
||||
.into(holder.extensionIconImageView)
|
||||
}
|
||||
holder.bind(extension)
|
||||
}
|
||||
}
|
||||
|
||||
inner class AnimeExtensionViewHolder(private val binding: ItemExtensionAllBinding) : RecyclerView.ViewHolder(binding.root) {
|
||||
init {
|
||||
binding.closeTextView.setOnClickListener {
|
||||
val extension = getItem(bindingAdapterPosition)
|
||||
if (extension != null) {
|
||||
clickListener.onInstallClick(extension)
|
||||
}
|
||||
}
|
||||
}
|
||||
val extensionIconImageView: ImageView = binding.extensionIconImageView
|
||||
fun bind(extension: AnimeExtension.Available) {
|
||||
binding.extensionNameTextView.text = extension.name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface OnAnimeInstallClickListener {
|
||||
fun onInstallClick(pkg: AnimeExtension.Available)
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package ani.dantotsu.settings.paging
|
||||
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.paging.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.PagingData
|
||||
import androidx.paging.PagingDataAdapter
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import androidx.paging.cachedIn
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import ani.dantotsu.databinding.ItemExtensionAllBinding
|
||||
import ani.dantotsu.loadData
|
||||
import com.bumptech.glide.Glide
|
||||
import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import java.lang.Math.min
|
||||
|
||||
class MangaExtensionsViewModelFactory(
|
||||
private val mangaExtensionManager: MangaExtensionManager
|
||||
) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return MangaExtensionsViewModel(mangaExtensionManager) as T
|
||||
}
|
||||
}
|
||||
|
||||
class MangaExtensionsViewModel(
|
||||
private val mangaExtensionManager: MangaExtensionManager
|
||||
) : ViewModel() {
|
||||
private val searchQuery = MutableStateFlow("")
|
||||
private var currentPagingSource: MangaExtensionPagingSource? = null
|
||||
|
||||
fun setSearchQuery(query: String) {
|
||||
searchQuery.value = query
|
||||
}
|
||||
|
||||
fun invalidatePager() {
|
||||
currentPagingSource?.invalidate()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val pagerFlow: Flow<PagingData<MangaExtension.Available>> = searchQuery.flatMapLatest { query ->
|
||||
Pager(
|
||||
PagingConfig(
|
||||
pageSize = 15,
|
||||
initialLoadSize = 15,
|
||||
prefetchDistance = 15
|
||||
)
|
||||
) {
|
||||
MangaExtensionPagingSource(
|
||||
mangaExtensionManager.availableExtensionsFlow,
|
||||
mangaExtensionManager.installedExtensionsFlow,
|
||||
searchQuery
|
||||
).also { currentPagingSource = it }
|
||||
}.flow
|
||||
}.cachedIn(viewModelScope)
|
||||
}
|
||||
|
||||
|
||||
class MangaExtensionPagingSource(
|
||||
private val availableExtensionsFlow: StateFlow<List<MangaExtension.Available>>,
|
||||
private val installedExtensionsFlow: StateFlow<List<MangaExtension.Installed>>,
|
||||
private val searchQuery: StateFlow<String>
|
||||
) : PagingSource<Int, MangaExtension.Available>() {
|
||||
|
||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MangaExtension.Available> {
|
||||
val position = params.key ?: 0
|
||||
val installedExtensions = installedExtensionsFlow.first().map { it.pkgName }.toSet()
|
||||
val availableExtensions = availableExtensionsFlow.first().filterNot { it.pkgName in installedExtensions }
|
||||
val query = searchQuery.first()
|
||||
val filteredExtensions = if (query.isEmpty()) {
|
||||
availableExtensions
|
||||
} else {
|
||||
availableExtensions.filter { it.name.contains(query, ignoreCase = true) }
|
||||
}
|
||||
|
||||
return try {
|
||||
val sublist = filteredExtensions.subList(
|
||||
fromIndex = position,
|
||||
toIndex = (position + params.loadSize).coerceAtMost(filteredExtensions.size)
|
||||
)
|
||||
LoadResult.Page(
|
||||
data = sublist,
|
||||
prevKey = if (position == 0) null else position - params.loadSize,
|
||||
nextKey = if (position + params.loadSize >= filteredExtensions.size) null else position + params.loadSize
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
LoadResult.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getRefreshKey(state: PagingState<Int, MangaExtension.Available>): Int? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class MangaExtensionAdapter(private val clickListener: OnMangaInstallClickListener) :
|
||||
PagingDataAdapter<MangaExtension.Available, MangaExtensionAdapter.MangaExtensionViewHolder>(
|
||||
DIFF_CALLBACK
|
||||
) {
|
||||
|
||||
private val skipIcons = loadData("skip_extension_icons") ?: false
|
||||
|
||||
companion object {
|
||||
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<MangaExtension.Available>() {
|
||||
override fun areItemsTheSame(oldItem: MangaExtension.Available, newItem: MangaExtension.Available): Boolean {
|
||||
return oldItem.pkgName == newItem.pkgName
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: MangaExtension.Available, newItem: MangaExtension.Available): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MangaExtensionViewHolder {
|
||||
val binding = ItemExtensionAllBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return MangaExtensionViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: MangaExtensionViewHolder, position: Int) {
|
||||
val extension = getItem(position)
|
||||
if (extension != null) {
|
||||
if (!skipIcons) {
|
||||
Glide.with(holder.itemView.context)
|
||||
.load(extension.iconUrl)
|
||||
.into(holder.extensionIconImageView)
|
||||
}
|
||||
holder.bind(extension)
|
||||
}
|
||||
}
|
||||
|
||||
inner class MangaExtensionViewHolder(private val binding: ItemExtensionAllBinding) : RecyclerView.ViewHolder(binding.root) {
|
||||
init {
|
||||
binding.closeTextView.setOnClickListener {
|
||||
val extension = getItem(bindingAdapterPosition)
|
||||
if (extension != null) {
|
||||
clickListener.onInstallClick(extension)
|
||||
}
|
||||
}
|
||||
}
|
||||
val extensionIconImageView: ImageView = binding.extensionIconImageView
|
||||
fun bind(extension: MangaExtension.Available) {
|
||||
binding.extensionNameTextView.text = extension.name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface OnMangaInstallClickListener {
|
||||
fun onInstallClick(pkg: MangaExtension.Available)
|
||||
}
|
||||
@@ -40,7 +40,7 @@ class AlarmReceiver : BroadcastReceiver() {
|
||||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||
)
|
||||
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
val curTime = loadData<Int>("subscriptions_time_r", context) ?: defaultTime
|
||||
val curTime = loadData<Int>("subscriptions_time_s", context) ?: defaultTime
|
||||
|
||||
if (timeMinutes[curTime] > 0)
|
||||
alarmManager.setRepeating(
|
||||
|
||||
@@ -16,8 +16,8 @@ import kotlinx.coroutines.launch
|
||||
@SuppressLint("MissingPermission")
|
||||
class Subscription {
|
||||
companion object {
|
||||
const val defaultTime = 3
|
||||
val timeMinutes = arrayOf(0L, 120, 180, 240, 360, 480, 720, 1440)
|
||||
const val defaultTime = 1
|
||||
val timeMinutes = arrayOf(0L, 720, 1440)
|
||||
|
||||
private var alreadyStarted = false
|
||||
fun Context.startSubscription(force: Boolean = false) {
|
||||
|
||||
@@ -22,7 +22,7 @@ class SubscriptionWorker(val context: Context, params: WorkerParameters) : Corou
|
||||
|
||||
private const val SUBSCRIPTION_WORK_NAME = "work_subscription"
|
||||
fun enqueue(context: Context) {
|
||||
val curTime = loadData<Int>("subscriptions_time_r") ?: defaultTime
|
||||
val curTime = loadData<Int>("subscriptions_time_s") ?: defaultTime
|
||||
if(timeMinutes[curTime]>0L) {
|
||||
val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
|
||||
val periodicSyncDataWork = PeriodicWorkRequest.Builder(
|
||||
|
||||
@@ -1,42 +1,50 @@
|
||||
package ani.dantotsu.themes
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import ani.dantotsu.R
|
||||
|
||||
class ThemeManager(private val context: Context) {
|
||||
fun applyTheme() {
|
||||
val useOLED = context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getBoolean("use_oled", false) && isDarkThemeActive(context)
|
||||
if(context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getBoolean("use_material_you", false)){
|
||||
return
|
||||
}
|
||||
when (context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getString("theme", "PURPLE")!!) {
|
||||
"PURPLE" -> {
|
||||
context.setTheme(R.style.Theme_Dantotsu_Purple)
|
||||
}
|
||||
//"MONOCHROME" -> {
|
||||
// context.setTheme(R.style.Theme_Dantotsu_Monochrome)
|
||||
//}
|
||||
"BLUE" -> {
|
||||
context.setTheme(R.style.Theme_Dantotsu_Blue)
|
||||
}
|
||||
"GREEN" -> {
|
||||
context.setTheme(R.style.Theme_Dantotsu_Green)
|
||||
}
|
||||
"PINK" -> {
|
||||
context.setTheme(R.style.Theme_Dantotsu_Pink)
|
||||
}
|
||||
else -> {
|
||||
context.setTheme(R.style.Theme_Dantotsu_Purple)
|
||||
}
|
||||
val theme = context.getSharedPreferences("Dantotsu", Context.MODE_PRIVATE).getString("theme", "PURPLE")!!
|
||||
|
||||
val themeToApply = when (theme) {
|
||||
"PURPLE" -> if (useOLED) R.style.Theme_Dantotsu_PurpleOLED else R.style.Theme_Dantotsu_Purple
|
||||
"BLUE" -> if (useOLED) R.style.Theme_Dantotsu_BlueOLED else R.style.Theme_Dantotsu_Blue
|
||||
"GREEN" -> if (useOLED) R.style.Theme_Dantotsu_GreenOLED else R.style.Theme_Dantotsu_Green
|
||||
"PINK" -> if (useOLED) R.style.Theme_Dantotsu_PinkOLED else R.style.Theme_Dantotsu_Pink
|
||||
"RED" -> if (useOLED) R.style.Theme_Dantotsu_RedOLED else R.style.Theme_Dantotsu_Red
|
||||
"LAVENDER" -> if (useOLED) R.style.Theme_Dantotsu_LavenderOLED else R.style.Theme_Dantotsu_Lavender
|
||||
"MONOCHROME (BETA)" -> if (useOLED) R.style.Theme_Dantotsu_MonochromeOLED else R.style.Theme_Dantotsu_Monochrome
|
||||
else -> if (useOLED) R.style.Theme_Dantotsu_PurpleOLED else R.style.Theme_Dantotsu_Purple
|
||||
}
|
||||
|
||||
context.setTheme(themeToApply)
|
||||
}
|
||||
|
||||
private fun isDarkThemeActive(context: Context): Boolean {
|
||||
return when (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
|
||||
Configuration.UI_MODE_NIGHT_YES -> true
|
||||
Configuration.UI_MODE_NIGHT_NO -> false
|
||||
Configuration.UI_MODE_NIGHT_UNDEFINED -> false
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object{
|
||||
enum class Theme(val theme: String) {
|
||||
PURPLE("PURPLE"),
|
||||
BLUE("BLUE"),
|
||||
GREEN("GREEN"),
|
||||
PINK("PINK");
|
||||
//MONOCHROME("MONOCHROME");
|
||||
PINK("PINK"),
|
||||
RED("RED"),
|
||||
LAVENDER("LAVENDER"),
|
||||
MONOCHROME("MONOCHROME (BETA)");
|
||||
|
||||
companion object {
|
||||
fun fromString(value: String): Theme {
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.io.ObjectInputStream
|
||||
import java.io.ObjectOutputStream
|
||||
import java.io.Serializable
|
||||
|
||||
data class Track(val url: String, val lang: String)
|
||||
data class Track(val url: String, val lang: String) : Serializable
|
||||
|
||||
open class Video(
|
||||
val url: String = "",
|
||||
|
||||
@@ -108,8 +108,11 @@ internal class AnimeExtensionInstaller(private val context: Context) {
|
||||
// Get the current download status
|
||||
.map {
|
||||
downloadManager.query(query).use { cursor ->
|
||||
cursor.moveToFirst()
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS))
|
||||
if (cursor.moveToFirst()) {
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS))
|
||||
} else {
|
||||
DownloadManager.STATUS_FAILED
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ignore duplicate results
|
||||
|
||||
7
app/src/main/res/color/chip_text_color.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Color when the chip is selected -->
|
||||
<item android:color="?attr/colorSurface" android:state_selected="true"/>
|
||||
<!-- Color when the chip is not selected -->
|
||||
<item android:color="?attr/colorOnSurface"/>
|
||||
</selector>
|
||||
@@ -1,173 +1,377 @@
|
||||
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<animated-vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt">
|
||||
<aapt:attr name="android:drawable">
|
||||
<vector
|
||||
android:viewportWidth="70"
|
||||
android:viewportHeight="70"
|
||||
android:width="248.0315dp"
|
||||
android:height="248.0315dp">
|
||||
android:name="vector"
|
||||
android:width="768dp"
|
||||
android:height="768dp"
|
||||
android:viewportWidth="768"
|
||||
android:viewportHeight="768">
|
||||
<group
|
||||
android:translateX="-73.31698"
|
||||
android:translateY="-111.8453">
|
||||
clip-path
|
||||
android:name="clip"
|
||||
android:pathData="M32,32m-32,0a32,32 0,1 1,64 0a32,32 0,1 1,-64 0" />
|
||||
<group
|
||||
android:name="zoomGroup_1"
|
||||
android:pivotX="32"
|
||||
android:pivotY="32"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0">
|
||||
<path
|
||||
android:fillColor="#5a189a"
|
||||
android:pathData="M140.3172 146.8457A32 32 0 0 1 76.31718 146.8457A32 32 0 0 1 140.3172 146.8457Z"
|
||||
android:strokeWidth="0.264583" />
|
||||
</group>
|
||||
<group
|
||||
android:name="zoomGroup_2"
|
||||
android:pivotX="32"
|
||||
android:pivotY="32"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0">
|
||||
<path
|
||||
android:fillColor="#7b2cbf"
|
||||
android:pathData="M128.3172 146.8457A20 20 0 0 1 88.31718 146.8457A20 20 0 0 1 128.3172 146.8457Z"
|
||||
android:strokeWidth="0.264583" />
|
||||
</group>
|
||||
<group
|
||||
android:name="zoomGroup_3"
|
||||
android:pivotX="32"
|
||||
android:pivotY="32"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0">
|
||||
<path
|
||||
android:fillColor="#9d4edd"
|
||||
android:pathData="M124.3172 146.8457A16 16 0 0 1 92.31718 146.8457A16 16 0 0 1 124.3172 146.8457Z"
|
||||
android:strokeWidth="0.264583" />
|
||||
</group>
|
||||
<group
|
||||
android:name="translateGroup_1"
|
||||
android:pivotX="32"
|
||||
android:pivotY="32"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
android:translateX="-35">
|
||||
<path
|
||||
android:fillColor="#10002b"
|
||||
android:pathData="M108.33606 114.84532a32 32 0 0 0 -31.99908 32.00011 32 32 0 0 0 7.100859 20.00033h24.898221zm-19.939351 27.35544l0.49196 0.925c0.01823 0.19615 -0.05452 0.22438 -0.218592 0.0842 -0.601567 0.19615 -1.212649 0.34989 -1.832446 0.46198v1.80765h2.18798v0.7984h-0.738456v5.12785h-0.546737v-5.12785h-0.902787v1.80764c0 1.42908 -0.327663 2.56382 -0.983919 3.40444l-0.410311 -0.71468 0.24598 -0.33642h-2.132687v0.79892h-0.547253v-8.74262h0.519865c0.145836 0.028 0.154993 0.11207 0.02739 0.25218v2.77399h1.011825v-3.19463h0.437183c0.14583 0.028 0.154993 0.11208 0.02739 0.25218v2.94245h1.039213v0.67231H85.03309v0.33642c0.401049 0.33625 0.720064 0.65862 0.957048 0.96686l-0.328146 0.7984c-0.164065 -0.28021 -0.373689 -0.60213 -0.628902 -0.96634v1.93321h-0.464571v-1.76527c-0.200525 0.5324 -0.419307 0.96652 -0.656291 1.30277l-0.300757 -0.67231c0.38282 -0.5324 0.692682 -1.17717 0.929659 -1.93374h-0.984436v3.44682h2.32389v0.50436c0.273436 -0.47636 0.41031 -1.17699 0.41031 -2.10168v-5.2958l0.519865 0.21033c0.619804 -0.11209 1.148442 -0.36476 1.58595 -0.75706zm3.636471 0.37827h0.547253c0.218753 0.028 0.245713 0.14027 0.08165 0.33641v2.6479c0.893241 0.3923 1.795859 0.92482 2.707328 1.59732l-0.328145 0.96687c-0.966157 -0.75657 -1.759385 -1.2609 -2.379183 -1.51309v4.37131H92.03318Zm-6.398576 0.37879l0.492476 0.2098c0.07292 0.0841 0.0546 0.15429 -0.05478 0.21033 -0.109377 0.5884 -0.246245 1.17681 -0.410311 1.76526l-0.437182 -0.25218c0.182291 -0.67249 0.318646 -1.31675 0.409794 -1.93321zm-1.531173 0.12609c0.145836 0.56042 0.246068 1.17648 0.300757 1.84898l-0.464571 0.25218c-0.09115 -0.84063 -0.191897 -1.45668 -0.301274 -1.84898zm15.50448 0.0419c0.273442 0.58844 0.537509 1.3311 0.792719 2.22778l-0.628905 0.50436c-0.255208 -0.89668 -0.519791 -1.65316 -0.793233 -2.26963zm2.296499 0.21033l0.65629 0.29404c0.1823 0.0841 0.1823 0.21014 0 0.37827 -0.21875 2.26971 -0.65632 3.92311 -1.31258 4.9599 -0.58334 0.92468 -1.376045 1.63916 -2.378665 2.14354l-0.492477 -0.88263c0.98439 -0.42032 1.740982 -1.0087 2.269632 -1.76527 0.65626 -0.95272 1.07551 -2.66202 1.2578 -5.12785zm-4.019391 0.37827c0.273441 0.67251 0.546664 1.48486 0.820105 2.43758l-0.628902 0.50436c-0.236984 -0.86865 -0.501046 -1.68101 -0.792717 -2.43758z"
|
||||
android:strokeWidth="0.264583" />
|
||||
<path
|
||||
android:fillColor="#10002b"
|
||||
android:pathData="M108.33574 170.84552H87.19698a32 32 0 0 0 21.13876 8.00003z"
|
||||
android:strokeWidth="0.264583" />
|
||||
</group>
|
||||
<group
|
||||
android:name="translateGroup_2"
|
||||
android:pivotX="32"
|
||||
android:pivotY="32"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
android:translateX="35">
|
||||
<path
|
||||
android:fillColor="#10002b"
|
||||
android:pathData="M108.29698 134.84565v23.99957a12 12 0 0 0 11.99979 -11.99979 12 12 0 0 0 -11.99979 -11.99978z"
|
||||
android:strokeWidth="0.264583" />
|
||||
<path
|
||||
android:fillColor="#10002b"
|
||||
android:pathData="M108.29698 178.84555a32 32 0 0 0 32.00012 -32.00012 32 32 0 0 0 -32.00012 -32.00011v8.00003a24 24 0 0 1 24.00009 24.00008 24 24 0 0 1 -24.00009 24.00009z"
|
||||
android:strokeWidth="0.264583" />
|
||||
android:name="wrapper"
|
||||
android:pivotX="384"
|
||||
android:pivotY="384">
|
||||
<clip-path
|
||||
android:name="clippath"
|
||||
android:pathData="M 384 128.04 C 329.836 127.869 276.99 144.889 233.11 176.638 C 189.23 208.387 156.539 253.255 139.769 304.75 C 122.999 356.244 122.999 411.756 139.769 463.25 C 156.539 514.745 189.23 559.613 233.11 591.362 C 276.99 623.111 329.836 640.131 384 639.96 C 451.869 639.96 517.028 612.974 565.019 564.991 C 613.01 517.008 640 451.859 640 384 C 640 316.141 613.01 250.992 565.019 203.009 C 517.028 155.026 451.869 128.04 384 128.04 Z"/>
|
||||
<group android:name="group">
|
||||
<group android:name="group_1">
|
||||
<path
|
||||
android:name="path"
|
||||
android:pathData="M 128 128 L 640 128 L 640 639.96 L 128 639.96 Z"
|
||||
android:fillColor="#ff00f4"
|
||||
android:strokeWidth="1"/>
|
||||
<group
|
||||
android:name="group_12"
|
||||
android:pivotX="384"
|
||||
android:pivotY="384">
|
||||
<path
|
||||
android:name="path_2"
|
||||
android:pathData="M 384 211.74 C 338.331 211.74 294.486 229.901 262.194 262.194 C 229.901 294.486 211.74 338.331 211.74 384 C 211.74 429.669 229.901 473.514 262.194 505.806 C 294.486 538.099 338.331 556.26 384 556.26 C 429.669 556.26 473.514 538.099 505.806 505.806 C 538.099 473.514 556.26 429.669 556.26 384 C 556.26 338.331 538.099 294.486 505.806 262.194 C 473.514 229.901 429.669 211.74 384 211.74 Z"
|
||||
android:fillColor="#d300e5"
|
||||
android:strokeWidth="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<group android:name="group_2">
|
||||
<group android:name="group_7">
|
||||
<group android:name="group_10">
|
||||
<group
|
||||
android:name="group_11"
|
||||
android:pivotX="94"
|
||||
android:pivotY="440"
|
||||
android:rotation="-90">
|
||||
<path
|
||||
android:name="path_1"
|
||||
android:pathData="M 128 128 L 128 463.26 C 151.32 466.96 175.23 468.89 199.58 468.89 C 411.17 468.89 588.92 323.99 639.01 128 L 128 128 Z"
|
||||
android:fillColor="#7000b8"
|
||||
android:strokeWidth="1"/>
|
||||
<clip-path
|
||||
android:name="mask_2"
|
||||
android:pathData="M 128 128 L 128 463.26 C 151.32 466.96 175.23 468.89 199.58 468.89 C 411.17 468.89 588.92 323.99 639.01 128 L 128 128 Z"/>
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:name="group_13"
|
||||
android:pivotX="384"
|
||||
android:pivotY="384">
|
||||
<clip-path
|
||||
android:name="mask_1"
|
||||
android:pathData="M 384 211.74 C 338.331 211.74 294.486 229.901 262.194 262.194 C 229.901 294.486 211.74 338.331 211.74 384 C 211.74 429.669 229.901 473.514 262.194 505.806 C 294.486 538.099 338.331 556.26 384 556.26 C 429.669 556.26 473.514 538.099 505.806 505.806 C 538.099 473.514 556.26 429.669 556.26 384 C 556.26 338.331 538.099 294.486 505.806 262.194 C 473.514 229.901 429.669 211.74 384 211.74 Z"/>
|
||||
<group
|
||||
android:name="group_9"
|
||||
android:pivotX="94"
|
||||
android:pivotY="440"
|
||||
android:rotation="-90">
|
||||
<path
|
||||
android:name="path_3"
|
||||
android:pathData="M 128 128 L 128 463.26 C 151.32 466.96 175.23 468.89 199.58 468.89 C 411.17 468.89 588.92 323.99 639.01 128 L 128 128 Z"
|
||||
android:fillColor="#9000d1"
|
||||
android:strokeWidth="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:name="group_6"
|
||||
android:pivotX="94"
|
||||
android:pivotY="440"
|
||||
android:scaleX="1.2"
|
||||
android:scaleY="1.2"
|
||||
android:rotation="-5"/>
|
||||
</group>
|
||||
<group
|
||||
android:name="group_8"
|
||||
android:pivotX="94"
|
||||
android:pivotY="440"
|
||||
android:rotation="-90">
|
||||
<group
|
||||
android:name="group_14"
|
||||
android:pivotX="94"
|
||||
android:pivotY="440">
|
||||
<path
|
||||
android:name="path_4"
|
||||
android:pathData="M 539.28 128 C 503.71 317.07 337.72 460.12 138.31 460.12 C 134.86 460.12 131.42 460.06 128 459.98 L 128 465.73 C 168.23 476.19 210.43 481.78 253.93 481.78 C 409.53 481.78 548.48 410.55 640 298.94 L 640 128.01 L 539.28 128.01 Z"
|
||||
android:fillColor="#a800d9"
|
||||
android:strokeWidth="1"/>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:name="group_3"
|
||||
android:translateX="-360">
|
||||
<path
|
||||
android:name="path_6"
|
||||
android:pathData="M 481.82 384 C 481.82 438.03 438.02 481.82 384 481.82 L 0 481.82 L 0 286.18 L 384 286.18 C 438.02 286.18 481.82 329.98 481.82 384 Z"
|
||||
android:fillColor="#1f1f30"
|
||||
android:strokeWidth="1"/>
|
||||
</group>
|
||||
<group
|
||||
android:name="group_4"
|
||||
android:pivotX="384"
|
||||
android:pivotY="384"
|
||||
android:scaleX="1.5"
|
||||
android:scaleY="1.5">
|
||||
<path
|
||||
android:name="path_5"
|
||||
android:pathData="M 44.26 128 C 44.26 174.25 81.75 211.74 128 211.74 L 384 211.74 C 479.13 211.74 556.26 288.86 556.26 384 C 556.26 479.13 479.14 556.26 384 556.26 L 128 556.26 C 81.76 556.26 44.28 593.73 44.26 639.97 L 768 639.97 L 768 128 L 44.26 128 Z"
|
||||
android:fillColor="#1f1f30"
|
||||
android:strokeWidth="1"/>
|
||||
</group>
|
||||
<group
|
||||
android:name="group_5"
|
||||
android:pivotX="384"
|
||||
android:pivotY="384"
|
||||
android:scaleX="3"
|
||||
android:scaleY="3"
|
||||
android:rotation="-15">
|
||||
<path
|
||||
android:name="path_7"
|
||||
android:pathData="M 442 366.7 L 365.98 322.81 C 352.66 315.12 336.02 324.73 336.02 340.11 L 336.02 427.89 C 336.02 443.27 352.67 452.88 365.98 445.19 L 442 401.3 C 455.32 393.61 455.32 374.39 442 366.7 Z"
|
||||
android:fillColor="#efe7ff"
|
||||
android:fillAlpha="0"
|
||||
android:strokeWidth="1"/>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</vector>
|
||||
</aapt:attr>
|
||||
<target android:name="zoomGroup_1">
|
||||
<target android:name="wrapper">
|
||||
<aapt:attr name="android:animation">
|
||||
<set>
|
||||
<objectAnimator
|
||||
android:duration="300"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"
|
||||
android:propertyName="scaleX"
|
||||
android:startOffset="600"
|
||||
android:duration="500"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType" />
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"/>
|
||||
<objectAnimator
|
||||
android:duration="300"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"
|
||||
android:propertyName="scaleY"
|
||||
android:startOffset="600"
|
||||
android:duration="500"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType" />
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"/>
|
||||
</set>
|
||||
</aapt:attr>
|
||||
</target>
|
||||
<target android:name="zoomGroup_2">
|
||||
<target android:name="group_6">
|
||||
<aapt:attr name="android:animation">
|
||||
<set>
|
||||
<objectAnimator
|
||||
android:duration="300"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"
|
||||
android:propertyName="scaleX"
|
||||
android:startOffset="300"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType" />
|
||||
android:propertyName="rotation"
|
||||
android:startOffset="350"
|
||||
android:duration="550"
|
||||
android:valueFrom="-10"
|
||||
android:valueTo="0"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"/>
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:startOffset="350"
|
||||
android:duration="300"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"
|
||||
android:propertyName="scaleY"
|
||||
android:startOffset="300"
|
||||
android:valueFrom="0"
|
||||
android:valueFrom="1.2"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType" />
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"/>
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:startOffset="350"
|
||||
android:duration="300"
|
||||
android:valueFrom="1.2"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"/>
|
||||
</set>
|
||||
</aapt:attr>
|
||||
</target>
|
||||
<target android:name="zoomGroup_3">
|
||||
<aapt:attr name="android:animation">
|
||||
<set>
|
||||
<objectAnimator
|
||||
android:duration="300"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"
|
||||
android:propertyName="scaleX"
|
||||
android:startOffset="0"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType" />
|
||||
<objectAnimator
|
||||
android:duration="300"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"
|
||||
android:propertyName="scaleY"
|
||||
android:startOffset="0"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType" />
|
||||
</set>
|
||||
</aapt:attr>
|
||||
</target>
|
||||
<target android:name="translateGroup_1">
|
||||
<target android:name="group_3">
|
||||
<aapt:attr name="android:animation">
|
||||
<objectAnimator
|
||||
android:duration="300"
|
||||
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
|
||||
android:propertyName="translateX"
|
||||
android:startOffset="900"
|
||||
android:valueFrom="-35"
|
||||
android:startOffset="250"
|
||||
android:duration="400"
|
||||
android:valueFrom="-360"
|
||||
android:valueTo="0"
|
||||
android:valueType="floatType" />
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"/>
|
||||
</aapt:attr>
|
||||
</target>
|
||||
<target android:name="translateGroup_2">
|
||||
<target android:name="group_4">
|
||||
<aapt:attr name="android:animation">
|
||||
<set>
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:startOffset="400"
|
||||
android:duration="350"
|
||||
android:valueFrom="1.5"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"/>
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:startOffset="400"
|
||||
android:duration="350"
|
||||
android:valueFrom="1.5"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"/>
|
||||
</set>
|
||||
</aapt:attr>
|
||||
</target>
|
||||
<target android:name="path_7">
|
||||
<aapt:attr name="android:animation">
|
||||
<objectAnimator
|
||||
android:duration="300"
|
||||
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
|
||||
android:propertyName="translateX"
|
||||
android:startOffset="900"
|
||||
android:valueFrom="35"
|
||||
android:propertyName="fillAlpha"
|
||||
android:startOffset="350"
|
||||
android:duration="550"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"/>
|
||||
</aapt:attr>
|
||||
</target>
|
||||
<target android:name="group_5">
|
||||
<aapt:attr name="android:animation">
|
||||
<set>
|
||||
<objectAnimator
|
||||
android:propertyName="rotation"
|
||||
android:startOffset="350"
|
||||
android:duration="550"
|
||||
android:valueFrom="-45"
|
||||
android:valueTo="0"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:anim/decelerate_interpolator"/>
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:startOffset="350"
|
||||
android:duration="550"
|
||||
android:valueFrom="3"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"/>
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:startOffset="350"
|
||||
android:duration="550"
|
||||
android:valueFrom="3"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"/>
|
||||
</set>
|
||||
</aapt:attr>
|
||||
</target>
|
||||
<target android:name="group_8">
|
||||
<aapt:attr name="android:animation">
|
||||
<objectAnimator
|
||||
android:propertyName="rotation"
|
||||
android:startOffset="100"
|
||||
android:duration="350"
|
||||
android:valueFrom="-90"
|
||||
android:valueTo="0"
|
||||
android:valueType="floatType" />
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"/>
|
||||
</aapt:attr>
|
||||
</target>
|
||||
<target android:name="group_9">
|
||||
<aapt:attr name="android:animation">
|
||||
<set>
|
||||
<objectAnimator
|
||||
android:propertyName="rotation"
|
||||
android:startOffset="100"
|
||||
android:duration="350"
|
||||
android:valueFrom="-90"
|
||||
android:valueTo="0"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"/>
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:duration="350"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"/>
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:duration="350"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"/>
|
||||
</set>
|
||||
</aapt:attr>
|
||||
</target>
|
||||
<target android:name="group_11">
|
||||
<aapt:attr name="android:animation">
|
||||
<objectAnimator
|
||||
android:propertyName="rotation"
|
||||
android:startOffset="100"
|
||||
android:duration="350"
|
||||
android:valueFrom="-90"
|
||||
android:valueTo="0"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"/>
|
||||
</aapt:attr>
|
||||
</target>
|
||||
<target android:name="group_12">
|
||||
<aapt:attr name="android:animation">
|
||||
<set>
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:duration="550"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"/>
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:duration="550"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"/>
|
||||
</set>
|
||||
</aapt:attr>
|
||||
</target>
|
||||
<target android:name="group_13">
|
||||
<aapt:attr name="android:animation">
|
||||
<set>
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:duration="550"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"/>
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:duration="550"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:anim/overshoot_interpolator"/>
|
||||
</set>
|
||||
</aapt:attr>
|
||||
</target>
|
||||
<target android:name="group_14">
|
||||
<aapt:attr name="android:animation">
|
||||
<set>
|
||||
<objectAnimator
|
||||
android:propertyName="rotation"
|
||||
android:startOffset="350"
|
||||
android:duration="200"
|
||||
android:valueFrom="5"
|
||||
android:valueTo="0"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>
|
||||
<objectAnimator
|
||||
android:propertyName="rotation"
|
||||
android:startOffset="250"
|
||||
android:duration="100"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="5"
|
||||
android:valueType="floatType"
|
||||
android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>
|
||||
</set>
|
||||
</aapt:attr>
|
||||
</target>
|
||||
</animated-vector>
|
||||
|
||||
15
app/src/main/res/drawable/card_outline.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item >
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="?attr/colorPrimaryContainer"/>
|
||||
<corners android:radius="16dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:right="2dp" android:left="2dp" android:top="2dp" android:bottom="2dp">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="?android:colorBackground"/>
|
||||
<corners android:radius="16dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
@@ -1,23 +1,30 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="70"
|
||||
android:viewportHeight="70">
|
||||
<group android:scaleX="0.73"
|
||||
android:scaleY="0.73"
|
||||
android:translateX="9.45"
|
||||
android:translateY="9.45">
|
||||
android:viewportWidth="768"
|
||||
android:viewportHeight="768">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M128,384a256,255.96 0,1 0,512 0a256,255.96 0,1 0,-512 0z"/>
|
||||
<path
|
||||
android:pathData="M35,35m-32,0a32,32 0,1 1,64 0a32,32 0,1 1,-64 0"
|
||||
android:strokeWidth="0.264583"
|
||||
android:fillColor="#5a189a"/>
|
||||
android:pathData="M128,128h512v511.96h-512z"
|
||||
android:strokeWidth="0"
|
||||
android:fillColor="#ff00f4"/>
|
||||
<path
|
||||
android:pathData="M35,35m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0"
|
||||
android:strokeWidth="0.264583"
|
||||
android:fillColor="#7b2cbf"/>
|
||||
android:pathData="m128,128v335.26c23.32,3.7 47.23,5.63 71.58,5.63 211.59,0 389.34,-144.9 439.43,-340.89H128Z"
|
||||
android:strokeWidth="0"
|
||||
android:fillColor="#7000b8"/>
|
||||
<path
|
||||
android:pathData="M35,35m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0"
|
||||
android:strokeWidth="0.264583"
|
||||
android:fillColor="#9d4edd"/>
|
||||
android:pathData="M384,384m-172.26,0a172.26,172.26 0,1 1,344.52 0a172.26,172.26 0,1 1,-344.52 0"
|
||||
android:strokeWidth="0"
|
||||
android:fillColor="#d300e5"/>
|
||||
<path
|
||||
android:pathData="m384,211.74c-95.13,0 -172.26,77.12 -172.26,172.26 0,24.51 5.13,47.83 14.37,68.93 89.21,-7.3 172.93,-33.96 246.97,-75.77 24.85,-18.81 47.7,-40.12 68.18,-63.56 -26.92,-60.04 -87.2,-101.86 -157.25,-101.86Z"
|
||||
android:strokeWidth="0"
|
||||
android:fillColor="#9000d1"/>
|
||||
<path
|
||||
android:pathData="m539.28,128c-35.57,189.07 -201.56,332.12 -400.97,332.12 -3.45,0 -6.89,-0.06 -10.31,-0.14v5.75c40.23,10.46 82.43,16.05 125.93,16.05 155.6,0 294.55,-71.23 386.07,-182.84v-170.93h-100.72Z"
|
||||
android:strokeWidth="0"
|
||||
android:fillColor="#a800d9"/>
|
||||
</group>
|
||||
</vector>
|
||||
|
||||
@@ -1,27 +1,22 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="70"
|
||||
android:viewportHeight="70">
|
||||
<group android:scaleX="0.73"
|
||||
android:scaleY="0.73"
|
||||
android:translateX="9.45"
|
||||
android:translateY="9.45">
|
||||
android:viewportWidth="768"
|
||||
android:viewportHeight="768">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M128,384a256,255.96 0,1 0,512 0a256,255.96 0,1 0,-512 0z"/>
|
||||
<path
|
||||
android:pathData="m35.019,3a32,32 0,0 0,-31.999 32,32 32,0 0,0 7.101,20h24.898zM15.08,30.355 L15.572,31.28c0.018,0.196 -0.055,0.224 -0.219,0.084 -0.602,0.196 -1.213,0.35 -1.832,0.462v1.808h2.188v0.798h-0.738v5.128h-0.547v-5.128h-0.903v1.808c0,1.429 -0.328,2.564 -0.984,3.404l-0.41,-0.715 0.246,-0.336h-2.133v0.799h-0.547v-8.743h0.52c0.146,0.028 0.155,0.112 0.027,0.252v2.774h1.012v-3.195h0.437c0.146,0.028 0.155,0.112 0.027,0.252v2.942h1.039v0.672L11.716,34.348v0.336c0.401,0.336 0.72,0.659 0.957,0.967l-0.328,0.798c-0.164,-0.28 -0.374,-0.602 -0.629,-0.966v1.933h-0.465v-1.765c-0.201,0.532 -0.419,0.967 -0.656,1.303l-0.301,-0.672c0.383,-0.532 0.693,-1.177 0.93,-1.934h-0.984v3.447h2.324v0.504c0.273,-0.476 0.41,-1.177 0.41,-2.102v-5.296l0.52,0.21c0.62,-0.112 1.148,-0.365 1.586,-0.757zM18.716,30.734h0.547c0.219,0.028 0.246,0.14 0.082,0.336v2.648c0.893,0.392 1.796,0.925 2.707,1.597l-0.328,0.967c-0.966,-0.757 -1.759,-1.261 -2.379,-1.513v4.371L18.716,39.14ZM12.318,31.112 L12.81,31.322c0.073,0.084 0.055,0.154 -0.055,0.21 -0.109,0.588 -0.246,1.177 -0.41,1.765l-0.437,-0.252c0.182,-0.672 0.319,-1.317 0.41,-1.933zM10.786,31.239c0.146,0.56 0.246,1.176 0.301,1.849l-0.465,0.252c-0.091,-0.841 -0.192,-1.457 -0.301,-1.849zM26.291,31.28c0.273,0.588 0.538,1.331 0.793,2.228l-0.629,0.504c-0.255,-0.897 -0.52,-1.653 -0.793,-2.27zM28.587,31.491 L29.244,31.785c0.182,0.084 0.182,0.21 0,0.378 -0.219,2.27 -0.656,3.923 -1.313,4.96 -0.583,0.925 -1.376,1.639 -2.379,2.144l-0.492,-0.883c0.984,-0.42 1.741,-1.009 2.27,-1.765 0.656,-0.953 1.076,-2.662 1.258,-5.128zM24.568,31.869c0.273,0.673 0.547,1.485 0.82,2.438l-0.629,0.504c-0.237,-0.869 -0.501,-1.681 -0.793,-2.438z"
|
||||
android:strokeWidth="0.264583"
|
||||
android:fillColor="#10002b"/>
|
||||
android:pathData="m44.26,128c0,46.25 37.49,83.74 83.74,83.74h256c95.13,0 172.26,77.12 172.26,172.26h0c0,95.13 -77.12,172.26 -172.26,172.26H128c-46.24,0 -83.72,37.47 -83.74,83.71h723.74V128H44.26Z"
|
||||
android:strokeWidth="0"
|
||||
android:fillColor="#1f1f30"/>
|
||||
<path
|
||||
android:pathData="m34.98,23v24a12,12 0,0 0,12 -12,12 12,0 0,0 -12,-12z"
|
||||
android:strokeWidth="0.264583"
|
||||
android:fillColor="#10002b"/>
|
||||
android:pathData="m481.82,384h0c0,54.03 -43.8,97.82 -97.82,97.82H0v-195.64h384c54.02,0 97.82,43.8 97.82,97.82Z"
|
||||
android:strokeWidth="0"
|
||||
android:fillColor="#1f1f30"/>
|
||||
<path
|
||||
android:pathData="m34.98,67a32,32 0,0 0,32 -32,32 32,0 0,0 -32,-32v8a24,24 0,0 1,24 24,24 24,0 0,1 -24,24z"
|
||||
android:strokeWidth="0.264583"
|
||||
android:fillColor="#10002b"/>
|
||||
<path
|
||||
android:pathData="M35.019,59L13.88,59a32,32 0,0 0,21.139 8z"
|
||||
android:strokeWidth="0.264583"
|
||||
android:fillColor="#10002b"/>
|
||||
android:pathData="m442,366.7l-76.02,-43.89c-13.32,-7.69 -29.96,1.92 -29.96,17.3v87.78c0,15.38 16.65,24.99 29.96,17.3l76.02,-43.89c13.32,-7.69 13.32,-26.91 0,-34.6Z"
|
||||
android:strokeWidth="0"
|
||||
android:fillColor="#efe7ff"/>
|
||||
</group>
|
||||
</vector>
|
||||
|
||||
@@ -1,27 +1,17 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="70"
|
||||
android:viewportHeight="70">
|
||||
<group android:scaleX="0.73"
|
||||
android:scaleY="0.73"
|
||||
android:translateX="9.45"
|
||||
android:translateY="9.45">
|
||||
<path
|
||||
android:pathData="m35.019,3a32,32 0,0 0,-31.999 32,32 32,0 0,0 7.101,20h24.898zM15.08,30.355 L15.572,31.28c0.018,0.196 -0.055,0.224 -0.219,0.084 -0.602,0.196 -1.213,0.35 -1.832,0.462v1.808h2.188v0.798h-0.738v5.128h-0.547v-5.128h-0.903v1.808c0,1.429 -0.328,2.564 -0.984,3.404l-0.41,-0.715 0.246,-0.336h-2.133v0.799h-0.547v-8.743h0.52c0.146,0.028 0.155,0.112 0.027,0.252v2.774h1.012v-3.195h0.437c0.146,0.028 0.155,0.112 0.027,0.252v2.942h1.039v0.672L11.716,34.348v0.336c0.401,0.336 0.72,0.659 0.957,0.967l-0.328,0.798c-0.164,-0.28 -0.374,-0.602 -0.629,-0.966v1.933h-0.465v-1.765c-0.201,0.532 -0.419,0.967 -0.656,1.303l-0.301,-0.672c0.383,-0.532 0.693,-1.177 0.93,-1.934h-0.984v3.447h2.324v0.504c0.273,-0.476 0.41,-1.177 0.41,-2.102v-5.296l0.52,0.21c0.62,-0.112 1.148,-0.365 1.586,-0.757zM18.716,30.734h0.547c0.219,0.028 0.246,0.14 0.082,0.336v2.648c0.893,0.392 1.796,0.925 2.707,1.597l-0.328,0.967c-0.966,-0.757 -1.759,-1.261 -2.379,-1.513v4.371L18.716,39.14ZM12.318,31.112 L12.81,31.322c0.073,0.084 0.055,0.154 -0.055,0.21 -0.109,0.588 -0.246,1.177 -0.41,1.765l-0.437,-0.252c0.182,-0.672 0.319,-1.317 0.41,-1.933zM10.786,31.239c0.146,0.56 0.246,1.176 0.301,1.849l-0.465,0.252c-0.091,-0.841 -0.192,-1.457 -0.301,-1.849zM26.291,31.28c0.273,0.588 0.538,1.331 0.793,2.228l-0.629,0.504c-0.255,-0.897 -0.52,-1.653 -0.793,-2.27zM28.587,31.491 L29.244,31.785c0.182,0.084 0.182,0.21 0,0.378 -0.219,2.27 -0.656,3.923 -1.313,4.96 -0.583,0.925 -1.376,1.639 -2.379,2.144l-0.492,-0.883c0.984,-0.42 1.741,-1.009 2.27,-1.765 0.656,-0.953 1.076,-2.662 1.258,-5.128zM24.568,31.869c0.273,0.673 0.547,1.485 0.82,2.438l-0.629,0.504c-0.237,-0.869 -0.501,-1.681 -0.793,-2.438z"
|
||||
android:strokeWidth="0.264583"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="m34.98,23v24a12,12 0,0 0,12 -12,12 12,0 0,0 -12,-12z"
|
||||
android:strokeWidth="0.264583"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="m34.98,67a32,32 0,0 0,32 -32,32 32,0 0,0 -32,-32v8a24,24 0,0 1,24 24,24 24,0 0,1 -24,24z"
|
||||
android:strokeWidth="0.264583"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M35.019,59L13.88,59a32,32 0,0 0,21.139 8z"
|
||||
android:strokeWidth="0.264583"
|
||||
android:fillColor="#000000"/>
|
||||
</group>
|
||||
android:width="768dp"
|
||||
android:height="768dp"
|
||||
android:viewportWidth="768"
|
||||
android:viewportHeight="768">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M128,384a256,255.96 0,1 0,512 0a256,255.96 0,1 0,-512 0z"/>
|
||||
<path
|
||||
android:pathData="M384,122.15A270.94,270.94 0,0 0,331.21 128L439.74,128A270.94,270.94 0,0 0,384 122.15zM183.16,211.74A270.94,270.94 0,0 0,135.74 286.18L384,286.18C438.02,286.18 481.82,329.98 481.82,384C481.82,438.03 438.02,481.82 384,481.82L128.98,481.82A270.94,270.94 0,0 0,168.56 556.26L384,556.26C479.14,556.26 556.26,479.13 556.26,384C556.26,288.86 479.13,211.74 384,211.74L183.16,211.74zM272.59,639.97A270.94,270.94 0,0 0,384 664.03A270.94,270.94 0,0 0,495.41 639.97L272.59,639.97z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="m442,366.7l-76.02,-43.89c-13.32,-7.69 -29.96,1.92 -29.96,17.3v87.78c0,15.38 16.65,24.99 29.96,17.3l76.02,-43.89c13.32,-7.69 13.32,-26.91 0,-34.6Z"
|
||||
android:strokeWidth="0"
|
||||
android:fillColor="#000000"/>
|
||||
</group>
|
||||
</vector>
|
||||
|
||||
@@ -51,13 +51,9 @@
|
||||
android:text="@string/extensions"
|
||||
android:textSize="28sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/settingsLogo"
|
||||
<Space
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_gravity="bottom"
|
||||
app:srcCompat="@drawable/anim_splash"
|
||||
tools:ignore="ContentDescription" />
|
||||
android:layout_height="80dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -69,13 +65,38 @@
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
</LinearLayout>
|
||||
|
||||
<SearchView
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/searchView"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layoutDirection="ltr" />
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:transitionName="@string/search"
|
||||
app:boxBackgroundColor="@color/bg"
|
||||
app:boxBackgroundMode="outline"
|
||||
app:boxCornerRadiusBottomEnd="28dp"
|
||||
app:boxCornerRadiusBottomStart="28dp"
|
||||
app:boxCornerRadiusTopEnd="28dp"
|
||||
app:boxCornerRadiusTopStart="28dp"
|
||||
app:endIconDrawable="@drawable/ic_round_search_24"
|
||||
app:hintAnimationEnabled="true">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/searchViewText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:imeOptions="actionSearch"
|
||||
android:inputType="textPersonName"
|
||||
android:selectAllOnFocus="true"
|
||||
android:padding="8dp"
|
||||
android:textSize="14sp"
|
||||
app:boxStrokeColor="@color/text_input_layout_stroke_color"
|
||||
tools:ignore="LabelFor,TextContrastCheck" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -84,15 +105,26 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:tabMode="fixed"
|
||||
app:tabTextColor="?attr/colorOnBackground"
|
||||
selectedTabIndicatorColor="?attr/colorPrimary"
|
||||
app:tabIndicatorColor="?attr/colorPrimary"
|
||||
app:tabGravity="fill">
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Anime"/>
|
||||
android:text="Installed Anime"/>
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Manga"/>
|
||||
android:text="Available Anime"/>
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Installed Manga"/>
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Available Manga"/>
|
||||
</com.google.android.material.tabs.TabLayout>
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".media.user.ListActivity">
|
||||
tools:context=".media.user.ListActivity"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/listProgressBar"
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
app:abb_animationDuration="300"
|
||||
app:abb_animationInterpolator="@anim/over_shoot"
|
||||
app:abb_badgeBackgroundColor="#F44336"
|
||||
app:abb_indicatorColor="?attr/colorSecondary"
|
||||
app:abb_indicatorColor="?attr/colorOnPrimaryContainer"
|
||||
app:abb_indicatorLocation="bottom"
|
||||
app:abb_indicatorMargin="28dp"
|
||||
app:abb_selectedTabType="text"
|
||||
app:abb_tabColor="?attr/colorSecondary"
|
||||
app:abb_tabColorDisabled="?attr/colorSecondaryContainer"
|
||||
app:abb_tabColorSelected="?attr/colorPrimary"
|
||||
app:abb_tabColor="?attr/colorOnPrimary"
|
||||
app:abb_tabColorDisabled="?attr/colorOnSecondary"
|
||||
app:abb_tabColorSelected="?attr/colorOnPrimaryContainer"
|
||||
app:abb_tabs="@menu/bottom_navbar_menu"
|
||||
app:abb_textAppearance="@style/NavBarText"
|
||||
tools:visibility="visible" />
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
app:cardBackgroundColor="#000000"
|
||||
app:cardBackgroundColor="?attr/colorSurface"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:contentPadding="8dp"
|
||||
app:strokeColor="?attr/colorSecondary"
|
||||
@@ -70,7 +70,7 @@
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="?android:colorBackground"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:textSize="16sp" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
app:cardBackgroundColor="#000000"
|
||||
app:cardBackgroundColor="?attr/colorSurface"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:contentPadding="8dp"
|
||||
app:strokeColor="?attr/colorSecondary"
|
||||
@@ -108,7 +108,7 @@
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="?android:colorBackground"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:textSize="16sp" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:cardBackgroundColor="#000000"
|
||||
app:cardBackgroundColor="?attr/colorSurface"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:contentPadding="8dp"
|
||||
app:strokeColor="?attr/colorSecondary"
|
||||
@@ -148,7 +148,7 @@
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="?android:colorBackground"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:textSize="16sp" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:cardBackgroundColor="#000000"
|
||||
app:cardBackgroundColor="?attr/colorSurface"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:contentPadding="8dp"
|
||||
app:strokeColor="?attr/colorSecondary"
|
||||
@@ -185,7 +185,7 @@
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="?android:colorBackground"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:textSize="16sp" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
@@ -268,7 +268,11 @@
|
||||
android:layout_marginEnd="48dp"
|
||||
android:fontFamily="@font/poppins"
|
||||
android:singleLine="false"
|
||||
android:textColor="?android:colorBackground"
|
||||
android:textColor="@color/bg_white"
|
||||
android:shadowColor="#000"
|
||||
android:shadowDx="1"
|
||||
android:shadowDy="1"
|
||||
android:shadowRadius="1"
|
||||
android:textSize="12sp"
|
||||
tools:ignore="TextContrastCheck"
|
||||
tools:text="@string/popular_anime" />
|
||||
|
||||
@@ -123,6 +123,7 @@
|
||||
android:text="@string/add"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="?attr/colorPrimary"
|
||||
app:strokeColor="?attr/colorPrimary"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
app:cornerRadius="16dp"
|
||||
@@ -242,14 +243,14 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="0dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="?attr/colorPrimaryContainer"
|
||||
android:background="?attr/colorSurface"
|
||||
android:translationZ="1dp"
|
||||
app:itemActiveIndicatorStyle="@style/BottomNavBar"
|
||||
app:itemIconTint="@color/tab_layout_icon"
|
||||
app:itemRippleColor="?attr/colorSecondary"
|
||||
app:itemRippleColor="?attr/colorPrimary"
|
||||
app:itemTextAppearanceActive="@style/NavBarText"
|
||||
app:itemTextAppearanceInactive="@style/NavBarText"
|
||||
app:itemTextColor="?attr/colorOnPrimaryContainer"
|
||||
app:itemTextColor="@color/tab_layout_icon"
|
||||
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
|
||||
@@ -161,16 +161,34 @@
|
||||
|
||||
</LinearLayout>
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/settingsUseMaterialYou"
|
||||
android:id="@+id/settingsUseMaterialYou"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:drawableStart="@drawable/ic_round_new_releases_24"
|
||||
android:drawablePadding="16dp"
|
||||
android:elegantTextHeight="true"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:minHeight="64dp"
|
||||
android:text="@string/use_material_you"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="?attr/colorOnBackground"
|
||||
app:cornerRadius="0dp"
|
||||
app:drawableTint="?attr/colorPrimary"
|
||||
app:showText="false"
|
||||
app:thumbTint="@color/button_switch_track" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/settingsUseOLED"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:drawableStart="@drawable/ic_round_new_releases_24"
|
||||
android:drawableStart="@drawable/ic_round_brightness_4_24"
|
||||
android:drawablePadding="16dp"
|
||||
android:elegantTextHeight="true"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:minHeight="64dp"
|
||||
android:text="@string/use_material_you"
|
||||
android:text="Use OLED theme variant"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="?attr/colorOnBackground"
|
||||
app:cornerRadius="0dp"
|
||||
|
||||
@@ -248,7 +248,8 @@
|
||||
android:valueTo="10"
|
||||
app:labelBehavior="gone"
|
||||
app:thumbElevation="0dp"
|
||||
app:trackColorInactive="?attr/colorSecondary"
|
||||
app:trackColorInactive="?attr/colorOnSecondary"
|
||||
app:trackColorActive="?attr/colorSecondary"
|
||||
app:trackHeight="24dp" />
|
||||
|
||||
<ImageView
|
||||
@@ -290,7 +291,8 @@
|
||||
android:valueTo="10"
|
||||
app:labelBehavior="gone"
|
||||
app:thumbElevation="0dp"
|
||||
app:trackColorInactive="?attr/colorSecondary"
|
||||
app:trackColorInactive="?attr/colorOnSecondary"
|
||||
app:trackColorActive="?attr/colorSecondary"
|
||||
app:trackHeight="24dp" />
|
||||
|
||||
<ImageView
|
||||
|
||||
@@ -1,34 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="32dp"
|
||||
android:paddingEnd="32dp">
|
||||
|
||||
<LinearLayout
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/allAnimeExtensionsRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="32dp"
|
||||
android:paddingEnd="32dp">
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/animeExtensionsRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:text="All Extensions"
|
||||
android:textSize="28sp" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/allAnimeExtensionsRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</LinearLayout>
|
||||
@@ -41,12 +41,13 @@
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:layout_margin="32dp"
|
||||
android:backgroundTint="?attr/colorPrimaryContainer"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:text="@string/login"
|
||||
android:textColor="?attr/colorOnPrimary"
|
||||
android:textColor="?attr/colorOnPrimaryContainer"
|
||||
app:cornerRadius="16dp"
|
||||
app:icon="@drawable/ic_anilist"
|
||||
app:iconTint="@color/button_icon" />
|
||||
app:iconTint="?attr/colorOnPrimaryContainer" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -1,35 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="32dp"
|
||||
android:paddingEnd="32dp">
|
||||
|
||||
<LinearLayout
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/allMangaExtensionsRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="32dp"
|
||||
android:paddingEnd="32dp">
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/mangaExtensionsRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:text="All Extensions"
|
||||
android:textSize="28sp" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/allMangaExtensionsRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -60,10 +60,12 @@
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/animeUserAvatarContainer"
|
||||
android:layout_width="52dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="4dp"
|
||||
android:backgroundTint="?attr/colorPrimaryContainer"
|
||||
app:strokeColor="@color/text_input_layout_stroke_color"
|
||||
app:cardCornerRadius="26dp">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
app:cardBackgroundColor="?android:colorBackground"
|
||||
android:background="@drawable/card_outline"
|
||||
app:cardCornerRadius="12dp">
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:layout_margin="8dp"
|
||||
app:cardBackgroundColor="?android:colorBackground"
|
||||
android:background="@drawable/card_outline"
|
||||
app:cardCornerRadius="16dp">
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
android:layout_margin="8dp"
|
||||
android:clipToPadding="false"
|
||||
android:translationZ="8dp"
|
||||
app:cardBackgroundColor="?android:colorBackground"
|
||||
android:background="@drawable/card_outline"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="4dp">
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
android:layout_margin="8dp"
|
||||
android:backgroundTintMode="src_atop"
|
||||
android:longClickable="true"
|
||||
app:cardBackgroundColor="?attr/colorSurface"
|
||||
android:background="@drawable/card_outline"
|
||||
app:cardCornerRadius="16dp">
|
||||
|
||||
<View
|
||||
|
||||
@@ -62,10 +62,12 @@
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/mangaUserAvatarContainer"
|
||||
android:layout_width="52dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="4dp"
|
||||
android:backgroundTint="?attr/colorPrimaryContainer"
|
||||
app:strokeColor="@color/text_input_layout_stroke_color"
|
||||
app:cardCornerRadius="26dp">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
android:layout_marginStart="2dp"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:paddingTop="2dp"
|
||||
android:textColor="@color/bg_white"
|
||||
android:textColor="?attr/colorOnPrimary"
|
||||
android:textSize="12sp"
|
||||
tools:ignore="TextContrastCheck"
|
||||
tools:text="0.0" />
|
||||
@@ -65,6 +65,7 @@
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="match_parent"
|
||||
app:srcCompat="@drawable/ic_round_star_24"
|
||||
app:tint="?attr/colorOnPrimary"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
android:layout_marginStart="2dp"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:paddingTop="2dp"
|
||||
android:textColor="@color/bg_white"
|
||||
android:textColor="?attr/colorOnPrimary"
|
||||
android:textSize="12sp"
|
||||
tools:ignore="TextContrastCheck"
|
||||
tools:text="0.0" />
|
||||
@@ -84,6 +84,7 @@
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="match_parent"
|
||||
app:srcCompat="@drawable/ic_round_star_24"
|
||||
app:tint="?attr/colorOnPrimary"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
android:layout_marginStart="2dp"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:paddingTop="2dp"
|
||||
android:textColor="@color/bg_white"
|
||||
android:textColor="?attr/colorOnPrimary"
|
||||
android:textSize="12sp"
|
||||
tools:ignore="TextContrastCheck"
|
||||
tools:text="0.0" />
|
||||
@@ -82,6 +82,7 @@
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="match_parent"
|
||||
app:srcCompat="@drawable/ic_round_star_24"
|
||||
app:tint="?attr/colorOnPrimary"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
android:layout_marginStart="2dp"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:paddingTop="2dp"
|
||||
android:textColor="@color/bg_white"
|
||||
android:textColor="?attr/colorOnPrimary"
|
||||
android:textSize="12sp"
|
||||
tools:ignore="TextContrastCheck"
|
||||
tools:text="0.0" />
|
||||
@@ -102,6 +102,7 @@
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="match_parent"
|
||||
app:srcCompat="@drawable/ic_round_star_24"
|
||||
app:tint="?attr/colorOnPrimary"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -60,6 +60,8 @@
|
||||
android:layout_weight="1"
|
||||
android:layoutDirection="inherit"
|
||||
android:text="@string/list_only"
|
||||
android:textColor="?attr/colorOnBackground"
|
||||
app:buttonTint="?attr/colorPrimary"
|
||||
android:visibility="visible"
|
||||
app:checkedState="indeterminate"
|
||||
tools:ignore="TextContrastCheck,TouchTargetSizeCheck" />
|
||||
@@ -75,7 +77,8 @@
|
||||
android:text="@string/adult"
|
||||
android:textAlignment="textEnd"
|
||||
android:visibility="visible"
|
||||
app:buttonTint="?attr/colorPrimaryContainer"
|
||||
android:textColor="?attr/colorOnBackground"
|
||||
app:buttonTint="?attr/colorPrimary"
|
||||
tools:ignore="TextContrastCheck,TouchTargetSizeCheck" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:colorBackground">
|
||||
android:background="@color/bg_black">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/splashImage"
|
||||
|
||||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.5 KiB |
@@ -143,11 +143,105 @@
|
||||
<item name="colorOnBackground">@color/bg_white</item>
|
||||
<item name="colorSurface">@color/bg_black</item>
|
||||
<item name="colorOnSurface">@color/bg_white</item>
|
||||
<item name="colorSurfaceVariant">@color/bg_white</item>
|
||||
<item name="colorOnSurfaceVariant">@color/bg_black</item>
|
||||
<item name="colorOutline">@color/bg_white</item>
|
||||
<item name="colorOnSurfaceInverse">@color/bg_black</item>
|
||||
<item name="colorSurfaceInverse">@color/bg_white</item>
|
||||
<item name="colorSurfaceVariant">@color/bg_black</item>
|
||||
<item name="colorOnSurfaceVariant">@color/bg_white</item>
|
||||
<item name="colorOutline">@color/bg_black</item>
|
||||
<item name="colorOnSurfaceInverse">@color/bg_white</item>
|
||||
<item name="colorSurfaceInverse">@color/bg_black</item>
|
||||
<item name="colorPrimaryInverse">@color/bg_black</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Dantotsu.Red" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/md_0_theme_dark_primary</item>
|
||||
<item name="colorOnPrimary">@color/md_0_theme_dark_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/md_0_theme_dark_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/md_0_theme_dark_onPrimaryContainer</item>
|
||||
<item name="colorSecondary">@color/md_0_theme_dark_secondary</item>
|
||||
<item name="colorOnSecondary">@color/md_0_theme_dark_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/md_0_theme_dark_secondaryContainer</item>
|
||||
<item name="colorOnSecondaryContainer">@color/md_0_theme_dark_onSecondaryContainer</item>
|
||||
<item name="colorTertiary">@color/md_0_theme_dark_tertiary</item>
|
||||
<item name="colorOnTertiary">@color/md_0_theme_dark_onTertiary</item>
|
||||
<item name="colorTertiaryContainer">@color/md_0_theme_dark_tertiaryContainer</item>
|
||||
<item name="colorOnTertiaryContainer">@color/md_0_theme_dark_onTertiaryContainer</item>
|
||||
<item name="colorError">@color/md_0_theme_dark_error</item>
|
||||
<item name="colorErrorContainer">@color/md_0_theme_dark_errorContainer</item>
|
||||
<item name="colorOnError">@color/md_0_theme_dark_onError</item>
|
||||
<item name="colorOnErrorContainer">@color/md_0_theme_dark_onErrorContainer</item>
|
||||
<item name="android:colorBackground">@color/md_0_theme_dark_background</item>
|
||||
<item name="colorOnBackground">@color/md_0_theme_dark_onBackground</item>
|
||||
<item name="colorSurface">@color/md_0_theme_dark_surface</item>
|
||||
<item name="colorOnSurface">@color/md_0_theme_dark_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/md_0_theme_dark_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/md_0_theme_dark_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/md_0_theme_dark_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/md_0_theme_dark_inverseOnSurface</item>
|
||||
<item name="colorSurfaceInverse">@color/md_0_theme_dark_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/md_0_theme_dark_inversePrimary</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Dantotsu.Lavender" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/md_1_theme_dark_primary</item>
|
||||
<item name="colorOnPrimary">@color/md_1_theme_dark_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/md_1_theme_dark_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/md_1_theme_dark_onPrimaryContainer</item>
|
||||
<item name="colorSecondary">@color/md_1_theme_dark_secondary</item>
|
||||
<item name="colorOnSecondary">@color/md_1_theme_dark_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/md_1_theme_dark_secondaryContainer</item>
|
||||
<item name="colorOnSecondaryContainer">@color/md_1_theme_dark_onSecondaryContainer</item>
|
||||
<item name="colorTertiary">@color/md_1_theme_dark_tertiary</item>
|
||||
<item name="colorOnTertiary">@color/md_1_theme_dark_onTertiary</item>
|
||||
<item name="colorTertiaryContainer">@color/md_1_theme_dark_tertiaryContainer</item>
|
||||
<item name="colorOnTertiaryContainer">@color/md_1_theme_dark_onTertiaryContainer</item>
|
||||
<item name="colorError">@color/md_1_theme_dark_error</item>
|
||||
<item name="colorErrorContainer">@color/md_1_theme_dark_errorContainer</item>
|
||||
<item name="colorOnError">@color/md_1_theme_dark_onError</item>
|
||||
<item name="colorOnErrorContainer">@color/md_1_theme_dark_onErrorContainer</item>
|
||||
<item name="android:colorBackground">@color/md_1_theme_dark_background</item>
|
||||
<item name="colorOnBackground">@color/md_1_theme_dark_onBackground</item>
|
||||
<item name="colorSurface">@color/md_1_theme_dark_surface</item>
|
||||
<item name="colorOnSurface">@color/md_1_theme_dark_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/md_1_theme_dark_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/md_1_theme_dark_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/md_1_theme_dark_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/md_1_theme_dark_inverseOnSurface</item>
|
||||
<item name="colorSurfaceInverse">@color/md_1_theme_dark_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/md_1_theme_dark_inversePrimary</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Dantotsu.BlueOLED" parent="Theme.Dantotsu.Blue">
|
||||
<item name="android:colorBackground">@color/darkest_Black</item>
|
||||
<item name="colorSurface">@color/darkest_Black</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Dantotsu.GreenOLED" parent="Theme.Dantotsu.Green">
|
||||
<item name="android:colorBackground">@color/darkest_Black</item>
|
||||
<item name="colorSurface">@color/darkest_Black</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Dantotsu.PurpleOLED" parent="Theme.Dantotsu.Purple">
|
||||
<item name="android:colorBackground">@color/darkest_Black</item>
|
||||
<item name="colorSurface">@color/darkest_Black</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Dantotsu.PinkOLED" parent="Theme.Dantotsu.Pink">
|
||||
<item name="android:colorBackground">@color/darkest_Black</item>
|
||||
<item name="colorSurface">@color/darkest_Black</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Dantotsu.MonochromeOLED" parent="Theme.Dantotsu.Monochrome">
|
||||
<item name="android:colorBackground">@color/darkest_Black</item>
|
||||
<item name="colorSurface">@color/darkest_Black</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Dantotsu.RedOLED" parent="Theme.Dantotsu.Red">
|
||||
<item name="android:colorBackground">@color/darkest_Black</item>
|
||||
<item name="colorSurface">@color/darkest_Black</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Dantotsu.LavenderOLED" parent="Theme.Dantotsu.Lavender">
|
||||
<item name="android:colorBackground">@color/darkest_Black</item>
|
||||
<item name="colorSurface">@color/darkest_Black</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -20,6 +20,7 @@
|
||||
<color name="warning">#FF0000</color>
|
||||
<color name="grey_20">#444444</color>
|
||||
<color name="grey_60">#999999</color>
|
||||
<color name="darkest_Black">#030201</color>
|
||||
|
||||
<!-- theme 1 -->
|
||||
<color name="seed_1">#00658e</color>
|
||||
@@ -269,4 +270,132 @@
|
||||
<color name="md_theme_dark_4_surfaceTint">#FFAED9</color>
|
||||
<color name="md_theme_dark_4_outlineVariant">#504349</color>
|
||||
<color name="md_theme_dark_4_scrim">#000000</color>
|
||||
|
||||
<color name="seed_5">#c9000b</color>
|
||||
<color name="md_0_theme_light_primary">#C0000A</color>
|
||||
<color name="md_0_theme_light_onPrimary">#FFFFFF</color>
|
||||
<color name="md_0_theme_light_primaryContainer">#FFDAD5</color>
|
||||
<color name="md_0_theme_light_onPrimaryContainer">#410001</color>
|
||||
<color name="md_0_theme_light_secondary">#775652</color>
|
||||
<color name="md_0_theme_light_onSecondary">#FFFFFF</color>
|
||||
<color name="md_0_theme_light_secondaryContainer">#FFDAD5</color>
|
||||
<color name="md_0_theme_light_onSecondaryContainer">#2C1512</color>
|
||||
<color name="md_0_theme_light_tertiary">#705C2E</color>
|
||||
<color name="md_0_theme_light_onTertiary">#FFFFFF</color>
|
||||
<color name="md_0_theme_light_tertiaryContainer">#FCDFA6</color>
|
||||
<color name="md_0_theme_light_onTertiaryContainer">#261A00</color>
|
||||
<color name="md_0_theme_light_error">#BA1A1A</color>
|
||||
<color name="md_0_theme_light_errorContainer">#FFDAD6</color>
|
||||
<color name="md_0_theme_light_onError">#FFFFFF</color>
|
||||
<color name="md_0_theme_light_onErrorContainer">#410002</color>
|
||||
<color name="md_0_theme_light_background">#FFFBFF</color>
|
||||
<color name="md_0_theme_light_onBackground">#201A19</color>
|
||||
<color name="md_0_theme_light_surface">#FFFBFF</color>
|
||||
<color name="md_0_theme_light_onSurface">#201A19</color>
|
||||
<color name="md_0_theme_light_surfaceVariant">#F5DDDA</color>
|
||||
<color name="md_0_theme_light_onSurfaceVariant">#534341</color>
|
||||
<color name="md_0_theme_light_outline">#857370</color>
|
||||
<color name="md_0_theme_light_inverseOnSurface">#FBEEEC</color>
|
||||
<color name="md_0_theme_light_inverseSurface">#362F2E</color>
|
||||
<color name="md_0_theme_light_inversePrimary">#FFB4AA</color>
|
||||
<color name="md_0_theme_light_shadow">#000000</color>
|
||||
<color name="md_0_theme_light_surfaceTint">#C0000A</color>
|
||||
<color name="md_0_theme_light_outlineVariant">#D8C2BE</color>
|
||||
<color name="md_0_theme_light_scrim">#000000</color>
|
||||
<color name="md_0_theme_dark_primary">#FFB4AA</color>
|
||||
<color name="md_0_theme_dark_onPrimary">#690003</color>
|
||||
<color name="md_0_theme_dark_primaryContainer">#930005</color>
|
||||
<color name="md_0_theme_dark_onPrimaryContainer">#FFDAD5</color>
|
||||
<color name="md_0_theme_dark_secondary">#E7BDB7</color>
|
||||
<color name="md_0_theme_dark_onSecondary">#442926</color>
|
||||
<color name="md_0_theme_dark_secondaryContainer">#5D3F3B</color>
|
||||
<color name="md_0_theme_dark_onSecondaryContainer">#FFDAD5</color>
|
||||
<color name="md_0_theme_dark_tertiary">#DFC38C</color>
|
||||
<color name="md_0_theme_dark_onTertiary">#3E2E04</color>
|
||||
<color name="md_0_theme_dark_tertiaryContainer">#574419</color>
|
||||
<color name="md_0_theme_dark_onTertiaryContainer">#FCDFA6</color>
|
||||
<color name="md_0_theme_dark_error">#FFB4AB</color>
|
||||
<color name="md_0_theme_dark_errorContainer">#93000A</color>
|
||||
<color name="md_0_theme_dark_onError">#690005</color>
|
||||
<color name="md_0_theme_dark_onErrorContainer">#FFDAD6</color>
|
||||
<color name="md_0_theme_dark_background">#201A19</color>
|
||||
<color name="md_0_theme_dark_onBackground">#EDE0DE</color>
|
||||
<color name="md_0_theme_dark_surface">#201A19</color>
|
||||
<color name="md_0_theme_dark_onSurface">#EDE0DE</color>
|
||||
<color name="md_0_theme_dark_surfaceVariant">#534341</color>
|
||||
<color name="md_0_theme_dark_onSurfaceVariant">#D8C2BE</color>
|
||||
<color name="md_0_theme_dark_outline">#A08C89</color>
|
||||
<color name="md_0_theme_dark_inverseOnSurface">#201A19</color>
|
||||
<color name="md_0_theme_dark_inverseSurface">#EDE0DE</color>
|
||||
<color name="md_0_theme_dark_inversePrimary">#C0000A</color>
|
||||
<color name="md_0_theme_dark_shadow">#000000</color>
|
||||
<color name="md_0_theme_dark_surfaceTint">#FFB4AA</color>
|
||||
<color name="md_0_theme_dark_outlineVariant">#534341</color>
|
||||
<color name="md_0_theme_dark_scrim">#000000</color>
|
||||
|
||||
<color name="seed_6">#6750A4</color>
|
||||
<color name="md_1_theme_light_primary">#6750A4</color>
|
||||
<color name="md_1_theme_light_onPrimary">#FFFFFF</color>
|
||||
<color name="md_1_theme_light_primaryContainer">#E9DDFF</color>
|
||||
<color name="md_1_theme_light_onPrimaryContainer">#22005D</color>
|
||||
<color name="md_1_theme_light_secondary">#625B71</color>
|
||||
<color name="md_1_theme_light_onSecondary">#FFFFFF</color>
|
||||
<color name="md_1_theme_light_secondaryContainer">#E8DEF8</color>
|
||||
<color name="md_1_theme_light_onSecondaryContainer">#1E192B</color>
|
||||
<color name="md_1_theme_light_tertiary">#7E5260</color>
|
||||
<color name="md_1_theme_light_onTertiary">#FFFFFF</color>
|
||||
<color name="md_1_theme_light_tertiaryContainer">#FFD9E3</color>
|
||||
<color name="md_1_theme_light_onTertiaryContainer">#31101D</color>
|
||||
<color name="md_1_theme_light_error">#BA1A1A</color>
|
||||
<color name="md_1_theme_light_errorContainer">#FFDAD6</color>
|
||||
<color name="md_1_theme_light_onError">#FFFFFF</color>
|
||||
<color name="md_1_theme_light_onErrorContainer">#410002</color>
|
||||
<color name="md_1_theme_light_background">#FFFBFF</color>
|
||||
<color name="md_1_theme_light_onBackground">#1C1B1E</color>
|
||||
<color name="md_1_theme_light_surface">#FFFBFF</color>
|
||||
<color name="md_1_theme_light_onSurface">#1C1B1E</color>
|
||||
<color name="md_1_theme_light_surfaceVariant">#E7E0EB</color>
|
||||
<color name="md_1_theme_light_onSurfaceVariant">#49454E</color>
|
||||
<color name="md_1_theme_light_outline">#7A757F</color>
|
||||
<color name="md_1_theme_light_inverseOnSurface">#F4EFF4</color>
|
||||
<color name="md_1_theme_light_inverseSurface">#313033</color>
|
||||
<color name="md_1_theme_light_inversePrimary">#CFBCFF</color>
|
||||
<color name="md_1_theme_light_shadow">#000000</color>
|
||||
<color name="md_1_theme_light_surfaceTint">#6750A4</color>
|
||||
<color name="md_1_theme_light_outlineVariant">#CAC4CF</color>
|
||||
<color name="md_1_theme_light_scrim">#000000</color>
|
||||
<color name="md_1_theme_dark_primary">#CFBCFF</color>
|
||||
<color name="md_1_theme_dark_onPrimary">#381E72</color>
|
||||
<color name="md_1_theme_dark_primaryContainer">#4F378A</color>
|
||||
<color name="md_1_theme_dark_onPrimaryContainer">#E9DDFF</color>
|
||||
<color name="md_1_theme_dark_secondary">#CBC2DB</color>
|
||||
<color name="md_1_theme_dark_onSecondary">#332D41</color>
|
||||
<color name="md_1_theme_dark_secondaryContainer">#4A4458</color>
|
||||
<color name="md_1_theme_dark_onSecondaryContainer">#E8DEF8</color>
|
||||
<color name="md_1_theme_dark_tertiary">#EFB8C8</color>
|
||||
<color name="md_1_theme_dark_onTertiary">#4A2532</color>
|
||||
<color name="md_1_theme_dark_tertiaryContainer">#633B48</color>
|
||||
<color name="md_1_theme_dark_onTertiaryContainer">#FFD9E3</color>
|
||||
<color name="md_1_theme_dark_error">#FFB4AB</color>
|
||||
<color name="md_1_theme_dark_errorContainer">#93000A</color>
|
||||
<color name="md_1_theme_dark_onError">#690005</color>
|
||||
<color name="md_1_theme_dark_onErrorContainer">#FFDAD6</color>
|
||||
<color name="md_1_theme_dark_background">#1C1B1E</color>
|
||||
<color name="md_1_theme_dark_onBackground">#E6E1E6</color>
|
||||
<color name="md_1_theme_dark_surface">#1C1B1E</color>
|
||||
<color name="md_1_theme_dark_onSurface">#E6E1E6</color>
|
||||
<color name="md_1_theme_dark_surfaceVariant">#49454E</color>
|
||||
<color name="md_1_theme_dark_onSurfaceVariant">#CAC4CF</color>
|
||||
<color name="md_1_theme_dark_outline">#948F99</color>
|
||||
<color name="md_1_theme_dark_inverseOnSurface">#1C1B1E</color>
|
||||
<color name="md_1_theme_dark_inverseSurface">#E6E1E6</color>
|
||||
<color name="md_1_theme_dark_inversePrimary">#6750A4</color>
|
||||
<color name="md_1_theme_dark_shadow">#000000</color>
|
||||
<color name="md_1_theme_dark_surfaceTint">#CFBCFF</color>
|
||||
<color name="md_1_theme_dark_outlineVariant">#49454E</color>
|
||||
<color name="md_1_theme_dark_scrim">#000000</color>
|
||||
<color name="CustomColor1">#93DB00</color>
|
||||
<color name="CustomColor2">#68AF86</color>
|
||||
<color name="CustomColor3">#0096AE</color>
|
||||
<color name="CustomColor4">#000000</color>
|
||||
</resources>
|
||||
@@ -53,5 +53,8 @@
|
||||
<item name="android:popupBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="BottomNavBar" parent="Widget.Material3.BottomNavigationView.ActiveIndicator"/>
|
||||
<style name="BottomNavBar" parent="">
|
||||
<!-- set background color to transparent -->
|
||||
<item name="android:background">@android:color/transparent</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -1,7 +1,7 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<style name="Theme.Base" parent="Theme.Material3.DayNight">
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">?android:colorBackground</item>
|
||||
<item name="android:windowTranslucentStatus">true</item>
|
||||
<item name="elevationOverlayEnabled">false</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
@@ -15,6 +15,8 @@
|
||||
<item name="snackbarButtonStyle">@style/Widget.MaterialComponents.Button.TextButton.Snackbar</item>
|
||||
<item name="snackbarTextViewStyle">@string/MySnackBarText</item>
|
||||
<item name="popupMenuStyle">@style/MyPopup</item>
|
||||
<item name="android:windowSplashScreenAnimationDuration" tools:targetApi="s">1000</item>
|
||||
<item name="android:windowSplashScreenAnimatedIcon" tools:targetApi="s">@drawable/anim_splash</item>
|
||||
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="o_mr1">shortEdges</item>
|
||||
</style>
|
||||
|
||||
@@ -190,13 +192,13 @@
|
||||
</style>
|
||||
|
||||
<style name="Theme.Dantotsu.Monochrome" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/grey_20</item>
|
||||
<item name="colorPrimary">@color/bg_black</item>
|
||||
<item name="colorOnPrimary">@color/bg_white</item>
|
||||
<item name="colorPrimaryContainer">@color/bg_black</item>
|
||||
<item name="colorOnPrimaryContainer">@color/bg_white</item>
|
||||
<item name="colorSecondary">@color/bg_black</item>
|
||||
<item name="colorOnSecondary">@color/bg_white</item>
|
||||
<item name="colorSecondaryContainer">@color/grey_60</item>
|
||||
<item name="colorSecondaryContainer">@color/bg_black</item>
|
||||
<item name="colorOnSecondaryContainer">@color/bg_white</item>
|
||||
<item name="colorTertiary">@color/bg_black</item>
|
||||
<item name="colorOnTertiary">@color/bg_white</item>
|
||||
@@ -218,5 +220,62 @@
|
||||
<item name="colorPrimaryInverse">@color/bg_white</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Dantotsu.Red" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/md_0_theme_light_primary</item>
|
||||
<item name="colorOnPrimary">@color/md_0_theme_light_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/md_0_theme_light_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/md_0_theme_light_onPrimaryContainer</item>
|
||||
<item name="colorSecondary">@color/md_0_theme_light_secondary</item>
|
||||
<item name="colorOnSecondary">@color/md_0_theme_light_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/md_0_theme_light_secondaryContainer</item>
|
||||
<item name="colorOnSecondaryContainer">@color/md_0_theme_light_onSecondaryContainer</item>
|
||||
<item name="colorTertiary">@color/md_0_theme_light_tertiary</item>
|
||||
<item name="colorOnTertiary">@color/md_0_theme_light_onTertiary</item>
|
||||
<item name="colorTertiaryContainer">@color/md_0_theme_light_tertiaryContainer</item>
|
||||
<item name="colorOnTertiaryContainer">@color/md_0_theme_light_onTertiaryContainer</item>
|
||||
<item name="colorError">@color/md_0_theme_light_error</item>
|
||||
<item name="colorErrorContainer">@color/md_0_theme_light_errorContainer</item>
|
||||
<item name="colorOnError">@color/md_0_theme_light_onError</item>
|
||||
<item name="colorOnErrorContainer">@color/md_0_theme_light_onErrorContainer</item>
|
||||
<item name="android:colorBackground">@color/md_0_theme_light_background</item>
|
||||
<item name="colorOnBackground">@color/md_0_theme_light_onBackground</item>
|
||||
<item name="colorSurface">@color/md_0_theme_light_surface</item>
|
||||
<item name="colorOnSurface">@color/md_0_theme_light_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/md_0_theme_light_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/md_0_theme_light_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/md_0_theme_light_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/md_0_theme_light_inverseOnSurface</item>
|
||||
<item name="colorSurfaceInverse">@color/md_0_theme_light_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/md_0_theme_light_inversePrimary</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Dantotsu.Lavender" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/md_1_theme_light_primary</item>
|
||||
<item name="colorOnPrimary">@color/md_1_theme_light_onPrimary</item>
|
||||
<item name="colorPrimaryContainer">@color/md_1_theme_light_primaryContainer</item>
|
||||
<item name="colorOnPrimaryContainer">@color/md_1_theme_light_onPrimaryContainer</item>
|
||||
<item name="colorSecondary">@color/md_1_theme_light_secondary</item>
|
||||
<item name="colorOnSecondary">@color/md_1_theme_light_onSecondary</item>
|
||||
<item name="colorSecondaryContainer">@color/md_1_theme_light_secondaryContainer</item>
|
||||
<item name="colorOnSecondaryContainer">@color/md_1_theme_light_onSecondaryContainer</item>
|
||||
<item name="colorTertiary">@color/md_1_theme_light_tertiary</item>
|
||||
<item name="colorOnTertiary">@color/md_1_theme_light_onTertiary</item>
|
||||
<item name="colorTertiaryContainer">@color/md_1_theme_light_tertiaryContainer</item>
|
||||
<item name="colorOnTertiaryContainer">@color/md_1_theme_light_onTertiaryContainer</item>
|
||||
<item name="colorError">@color/md_1_theme_light_error</item>
|
||||
<item name="colorErrorContainer">@color/md_1_theme_light_errorContainer</item>
|
||||
<item name="colorOnError">@color/md_1_theme_light_onError</item>
|
||||
<item name="colorOnErrorContainer">@color/md_1_theme_light_onErrorContainer</item>
|
||||
<item name="android:colorBackground">@color/md_1_theme_light_background</item>
|
||||
<item name="colorOnBackground">@color/md_1_theme_light_onBackground</item>
|
||||
<item name="colorSurface">@color/md_1_theme_light_surface</item>
|
||||
<item name="colorOnSurface">@color/md_1_theme_light_onSurface</item>
|
||||
<item name="colorSurfaceVariant">@color/md_1_theme_light_surfaceVariant</item>
|
||||
<item name="colorOnSurfaceVariant">@color/md_1_theme_light_onSurfaceVariant</item>
|
||||
<item name="colorOutline">@color/md_1_theme_light_outline</item>
|
||||
<item name="colorOnSurfaceInverse">@color/md_1_theme_light_inverseOnSurface</item>
|
||||
<item name="colorSurfaceInverse">@color/md_1_theme_light_inverseSurface</item>
|
||||
<item name="colorPrimaryInverse">@color/md_1_theme_light_inversePrimary</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
11
stable.md
@@ -1,3 +1,10 @@
|
||||
# 0.1.4
|
||||
# 1.0.0
|
||||
|
||||
- hotfix for those who crashed when opening an anime/manga
|
||||
- **Bugfixes:**
|
||||
- Fixed extension page hiding icons on first install
|
||||
- Various bug/crash fixes
|
||||
- Fixes for monochrome theme
|
||||
- General theme tweaks
|
||||
|
||||
- **New Features:**
|
||||
- added oled variant to all themes
|
||||