Skip to content

Commit

Permalink
[feature|fix] Support configuring the min-width of item for article l…
Browse files Browse the repository at this point in the history
…ist screen and search list screen (#63); fix crash caused by SwipeToDismissBox (#62); support verifying if a link is a torrent resource via mime type (#67)
  • Loading branch information
SkyD666 committed Jul 7, 2024
1 parent 48da0dd commit 2ee3bda
Show file tree
Hide file tree
Showing 17 changed files with 242 additions and 51 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ android {
minSdk = 24
targetSdk = 34
versionCode = 18
versionName = "1.1-beta50"
versionName = "1.1-beta51"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/com/skyd/anivu/ext/PreferenceExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.skyd.anivu.model.preference.appearance.DateStylePreference
import com.skyd.anivu.model.preference.appearance.NavigationBarLabelPreference
import com.skyd.anivu.model.preference.appearance.TextFieldStylePreference
import com.skyd.anivu.model.preference.appearance.ThemePreference
import com.skyd.anivu.model.preference.appearance.article.ArticleItemMinWidthPreference
import com.skyd.anivu.model.preference.appearance.article.ArticleItemTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.article.ArticleListTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.article.ArticleTopBarTonalElevationPreference
Expand All @@ -16,6 +17,7 @@ import com.skyd.anivu.model.preference.appearance.article.ShowArticleTopBarRefre
import com.skyd.anivu.model.preference.appearance.feed.FeedGroupExpandPreference
import com.skyd.anivu.model.preference.appearance.feed.FeedListTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.feed.FeedTopBarTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.search.SearchItemMinWidthPreference
import com.skyd.anivu.model.preference.appearance.search.SearchListTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.search.SearchTopBarTonalElevationPreference
import com.skyd.anivu.model.preference.behavior.PickImageMethodPreference
Expand Down Expand Up @@ -52,6 +54,8 @@ fun Preferences.toSettings(): Settings {
searchTopBarTonalElevation = SearchTopBarTonalElevationPreference.fromPreferences(this),
showArticleTopBarRefresh = ShowArticleTopBarRefreshPreference.fromPreferences(this),
showArticlePullRefresh = ShowArticlePullRefreshPreference.fromPreferences(this),
articleItemMinWidth = ArticleItemMinWidthPreference.fromPreferences(this),
searchItemMinWidth = SearchItemMinWidthPreference.fromPreferences(this),

// Update
ignoreUpdateVersion = IgnoreUpdateVersionPreference.fromPreferences(this),
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/java/com/skyd/anivu/model/preference/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.skyd.anivu.model.preference.appearance.DateStylePreference
import com.skyd.anivu.model.preference.appearance.NavigationBarLabelPreference
import com.skyd.anivu.model.preference.appearance.TextFieldStylePreference
import com.skyd.anivu.model.preference.appearance.ThemePreference
import com.skyd.anivu.model.preference.appearance.article.ArticleItemMinWidthPreference
import com.skyd.anivu.model.preference.appearance.article.ArticleItemTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.article.ArticleListTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.article.ArticleTopBarTonalElevationPreference
Expand All @@ -21,6 +22,7 @@ import com.skyd.anivu.model.preference.appearance.article.ShowArticleTopBarRefre
import com.skyd.anivu.model.preference.appearance.feed.FeedGroupExpandPreference
import com.skyd.anivu.model.preference.appearance.feed.FeedListTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.feed.FeedTopBarTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.search.SearchItemMinWidthPreference
import com.skyd.anivu.model.preference.appearance.search.SearchListTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.search.SearchTopBarTonalElevationPreference
import com.skyd.anivu.model.preference.behavior.PickImageMethodPreference
Expand All @@ -38,6 +40,7 @@ import com.skyd.anivu.model.preference.player.HardwareDecodePreference
import com.skyd.anivu.model.preference.player.PlayerDoubleTapPreference
import com.skyd.anivu.model.preference.player.PlayerShow85sButtonPreference
import com.skyd.anivu.model.preference.player.PlayerShowScreenshotButtonPreference
import com.skyd.anivu.ui.local.LocalArticleItemMinWidth
import com.skyd.anivu.ui.local.LocalArticleItemTonalElevation
import com.skyd.anivu.ui.local.LocalArticleListTonalElevation
import com.skyd.anivu.ui.local.LocalArticleSwipeLeftAction
Expand All @@ -62,6 +65,7 @@ import com.skyd.anivu.ui.local.LocalPickImageMethod
import com.skyd.anivu.ui.local.LocalPlayerDoubleTap
import com.skyd.anivu.ui.local.LocalPlayerShow85sButton
import com.skyd.anivu.ui.local.LocalPlayerShowScreenshotButton
import com.skyd.anivu.ui.local.LocalSearchItemMinWidth
import com.skyd.anivu.ui.local.LocalSearchListTonalElevation
import com.skyd.anivu.ui.local.LocalSearchTopBarTonalElevation
import com.skyd.anivu.ui.local.LocalShowArticlePullRefresh
Expand Down Expand Up @@ -89,6 +93,8 @@ data class Settings(
val searchTopBarTonalElevation: Float = SearchTopBarTonalElevationPreference.default,
val showArticleTopBarRefresh: Boolean = ShowArticleTopBarRefreshPreference.default,
val showArticlePullRefresh: Boolean = ShowArticlePullRefreshPreference.default,
val articleItemMinWidth: Float = ArticleItemMinWidthPreference.default,
val searchItemMinWidth: Float = SearchItemMinWidthPreference.default,
// Update
val ignoreUpdateVersion: Long = IgnoreUpdateVersionPreference.default,
// Behavior
Expand Down Expand Up @@ -136,6 +142,8 @@ fun SettingsProvider(
LocalSearchTopBarTonalElevation provides settings.searchTopBarTonalElevation,
LocalShowArticleTopBarRefresh provides settings.showArticleTopBarRefresh,
LocalShowArticlePullRefresh provides settings.showArticlePullRefresh,
LocalArticleItemMinWidth provides settings.articleItemMinWidth,
LocalSearchItemMinWidth provides settings.searchItemMinWidth,
// Update
LocalIgnoreUpdateVersion provides settings.ignoreUpdateVersion,
// Behavior
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.skyd.anivu.model.preference.appearance.article

import android.content.Context
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.floatPreferencesKey
import com.skyd.anivu.base.BasePreference
import com.skyd.anivu.ext.dataStore
import com.skyd.anivu.ext.put
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

object ArticleItemMinWidthPreference : BasePreference<Float> {
private const val ARTICLE_ITEM_MIN_WIDTH = "articleItemMinWidth"
override val default = 360f

val key = floatPreferencesKey(ARTICLE_ITEM_MIN_WIDTH)

fun put(context: Context, scope: CoroutineScope, value: Float) {
scope.launch(Dispatchers.IO) {
context.dataStore.put(key, value)
}
}

override fun fromPreferences(preferences: Preferences): Float = preferences[key] ?: default
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.skyd.anivu.model.preference.appearance.search

import android.content.Context
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.floatPreferencesKey
import com.skyd.anivu.base.BasePreference
import com.skyd.anivu.ext.dataStore
import com.skyd.anivu.ext.put
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

object SearchItemMinWidthPreference : BasePreference<Float> {
private const val SEARCH_ITEM_MIN_WIDTH = "searchItemMinWidth"
override val default = 360f

val key = floatPreferencesKey(SEARCH_ITEM_MIN_WIDTH)

fun put(context: Context, scope: CoroutineScope, value: Float) {
scope.launch(Dispatchers.IO) {
context.dataStore.put(key, value)
}
}

override fun fromPreferences(preferences: Preferences): Float = preferences[key] ?: default
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import org.libtorrent4j.AlertListener
import org.libtorrent4j.MoveFlags
import org.libtorrent4j.SessionManager
import org.libtorrent4j.SessionParams
import org.libtorrent4j.TorrentHandle
Expand Down Expand Up @@ -249,12 +248,12 @@ class DownloadTorrentWorker(context: Context, parameters: WorkerParameters) :
saveDir: File,
flags: torrent_flags_t = torrent_flags_t(),
) {
doIfMagnetOrTorrentLink(
ifMagnetLink(
link = link,
onMagnet = {
sessionManager.download(link, saveDir, flags)
},
onTorrent = {
onUnsupported = {
val tempTorrentFile = File(
Const.TEMP_TORRENT_DIR,
link.substringAfterLast('/').toDecodedUrl().validateFileName()
Expand All @@ -269,9 +268,6 @@ class DownloadTorrentWorker(context: Context, parameters: WorkerParameters) :
flags
)
},
onUnsupported = {
error("Unsupported link: $link")
},
)
}

Expand Down
37 changes: 30 additions & 7 deletions app/src/main/java/com/skyd/anivu/model/worker/download/Util.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,45 @@ import java.io.FileOutputStream
import java.io.IOException


fun isTorrentMimetype(mimetype: String?): Boolean {
return Regex("^application(s)?/x-bittorrent$").matches(mimetype.orEmpty())
}

fun doIfMagnetOrTorrentLink(
link: String,
mimetype: String? = null,
onMagnet: ((String) -> Unit)? = null,
onTorrent: ((String) -> Unit)? = null,
onSupported: ((String) -> Unit)? = null,
onUnsupported: ((String) -> Unit)? = null,
) {
ifMagnetLink(
link = link,
onMagnet = {
onMagnet?.invoke(link)
onSupported?.invoke(link)
},
onUnsupported = {
if (
isTorrentMimetype(mimetype) ||
Regex("^(http|https)://.*\\.torrent$").matches(link)
) {
onTorrent?.invoke(link)
onSupported?.invoke(link)
} else {
onUnsupported?.invoke(link)
}
},
)
}

fun ifMagnetLink(
link: String,
onMagnet: ((String) -> Unit)? = null,
onUnsupported: ((String) -> Unit)? = null,
) {
if (link.startsWith("magnet:")) {
onMagnet?.invoke(link)
onSupported?.invoke(link)
} else if (
(link.startsWith("http:") || link.startsWith("https:")) &&
link.endsWith(".torrent")
) {
onTorrent?.invoke(link)
onSupported?.invoke(link)
} else {
onUnsupported?.invoke(link)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class Enclosure1Proxy(
}
doIfMagnetOrTorrentLink(
link = data.url,
mimetype = data.type,
onSupported = {
btnEnclosure1Download.visible()
btnEnclosure1Download.setOnClickListener {
Expand Down
29 changes: 0 additions & 29 deletions app/src/main/java/com/skyd/anivu/ui/component/SwipeToDismissBox.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.SwipeToDismissBox
import androidx.compose.material3.SwipeToDismissBoxValue
import androidx.compose.material3.Text
import androidx.compose.material3.rememberSwipeToDismissBoxState
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
Expand Down Expand Up @@ -81,7 +82,6 @@ import com.skyd.anivu.model.preference.behavior.article.ArticleTapActionPreferen
import com.skyd.anivu.ui.component.AniVuImage
import com.skyd.anivu.ui.component.lazyverticalgrid.adapter.LazyGridAdapter
import com.skyd.anivu.ui.component.rememberAniVuImageLoader
import com.skyd.anivu.ui.component.rememberSwipeToDismissBoxState
import com.skyd.anivu.ui.fragment.read.EnclosureBottomSheet
import com.skyd.anivu.ui.fragment.read.ReadFragment
import com.skyd.anivu.ui.local.LocalArticleItemTonalElevation
Expand All @@ -90,6 +90,7 @@ import com.skyd.anivu.ui.local.LocalArticleSwipeRightAction
import com.skyd.anivu.ui.local.LocalArticleTapAction
import com.skyd.anivu.ui.local.LocalDeduplicateTitleInDesc
import com.skyd.anivu.ui.local.LocalNavController
import java.io.Serializable

class Article1Proxy(
private val onFavorite: (ArticleWithFeed, Boolean) -> Unit,
Expand All @@ -101,6 +102,7 @@ class Article1Proxy(
}
}


@Composable
fun Article1Item(
data: ArticleWithFeed,
Expand All @@ -109,11 +111,23 @@ fun Article1Item(
) {
val navController = LocalNavController.current
val context = LocalContext.current
val articleWithEnclosure = data.articleWithEnclosure
var expandMenu by rememberSaveable { mutableStateOf(false) }

/**
* SwipeToDismissBoxState doesn't recompose,
* so we need to pass in a "variable" that points to an object that doesn't change,
* hence the need to wrap the data (DataWrapper).
* When the data changes, we only change the fields inside the DataWrapper object,
* which ensures that SwipeToDismissBoxState gets the latest data from the DataWrapper object.
*/
class DataWrapper(
var data: ArticleWithFeed
) : Serializable

val dataWrapper = rememberSaveable { DataWrapper(data) }
LaunchedEffect(data) { dataWrapper.data = data }

val swipeToDismissBoxState = rememberSwipeToDismissBoxState(
inputs = arrayOf(data),
confirmValueChange = { dismissValue ->
val articleSwipeAction = context.dataStore.getOrDefault(
if (dismissValue == SwipeToDismissBoxValue.StartToEnd) {
Expand All @@ -124,14 +138,17 @@ fun Article1Item(
)
when (dismissValue) {
SwipeToDismissBoxValue.EndToStart, SwipeToDismissBoxValue.StartToEnd -> {
val articleWithEnclosure = dataWrapper.data.articleWithEnclosure
swipeAction(
articleSwipeAction = articleSwipeAction,
context = context,
navController = navController,
data = articleWithEnclosure,
onMarkAsRead = { onRead(data, !data.articleWithEnclosure.article.isRead) },
onMarkAsRead = {
onRead(dataWrapper.data, !articleWithEnclosure.article.isRead)
},
onMarkAsFavorite = {
onFavorite(data, !data.articleWithEnclosure.article.isFavorite)
onFavorite(dataWrapper.data, !articleWithEnclosure.article.isFavorite)
},
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ import com.skyd.anivu.ui.component.lazyverticalgrid.AniVuLazyVerticalGrid
import com.skyd.anivu.ui.component.lazyverticalgrid.adapter.LazyGridAdapter
import com.skyd.anivu.ui.component.lazyverticalgrid.adapter.proxy.Article1Proxy
import com.skyd.anivu.ui.fragment.search.SearchFragment
import com.skyd.anivu.ui.local.LocalArticleItemMinWidth
import com.skyd.anivu.ui.local.LocalArticleListTonalElevation
import com.skyd.anivu.ui.local.LocalArticleTopBarTonalElevation
import com.skyd.anivu.ui.local.LocalNavController
Expand Down Expand Up @@ -368,7 +369,7 @@ private fun ArticleList(
}
AniVuLazyVerticalGrid(
modifier = modifier.fillMaxSize(),
columns = GridCells.Adaptive(360.dp),
columns = GridCells.Adaptive(LocalArticleItemMinWidth.current.dp),
dataList = articles,
listState = listState,
adapter = adapter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ import com.skyd.anivu.ui.component.lazyverticalgrid.AniVuLazyVerticalGrid
import com.skyd.anivu.ui.component.lazyverticalgrid.adapter.LazyGridAdapter
import com.skyd.anivu.ui.component.lazyverticalgrid.adapter.proxy.Article1Proxy
import com.skyd.anivu.ui.component.lazyverticalgrid.adapter.proxy.Feed1Proxy
import com.skyd.anivu.ui.local.LocalSearchItemMinWidth
import com.skyd.anivu.ui.local.LocalSearchListTonalElevation
import com.skyd.anivu.ui.local.LocalSearchTopBarTonalElevation
import dagger.hilt.android.AndroidEntryPoint
Expand Down Expand Up @@ -270,7 +271,7 @@ private fun SearchResultList(
}
AniVuLazyVerticalGrid(
modifier = modifier,
columns = GridCells.Adaptive(360.dp),
columns = GridCells.Adaptive(LocalSearchItemMinWidth.current.dp),
dataList = result,
listState = listState,
adapter = adapter,
Expand Down
Loading

0 comments on commit 2ee3bda

Please sign in to comment.