Skip to content

Commit

Permalink
[feature|optimize] Optimize RSS edit screen; support custom RSS icon …
Browse files Browse the repository at this point in the history
…and description; fix known bugs (#51)

Feedicon
  • Loading branch information
SkyD666 authored Jun 2, 2024
2 parents ad555a1 + eb4cf03 commit 0719b8b
Show file tree
Hide file tree
Showing 35 changed files with 1,181 additions and 179 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ android {
applicationId = "com.skyd.anivu"
minSdk = 24
targetSdk = 34
versionCode = 16
versionName = "1.1-beta41"
versionCode = 17
versionName = "1.1-beta43"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/com/skyd/anivu/config/Const.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ object Const {

const val BASE_URL = "https://github.com/SkyD666/"

val FEED_ICON_DIR = File(appContext.filesDir.path, "Pictures/FeedIcon").apply {
if (!exists()) mkdirs()
}

val TEMP_TORRENT_DIR = File(appContext.cacheDir.path, "Torrent").apply {
if (!exists()) mkdirs()
}
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/java/com/skyd/anivu/ext/ColorExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.Stable
import androidx.compose.ui.graphics.Color
import com.materialkolor.ktx.from
import com.materialkolor.palettes.TonalPalette
import com.skyd.anivu.model.preference.appearance.DarkModePreference
import com.skyd.anivu.ui.local.LocalDarkMode

Expand Down Expand Up @@ -46,4 +48,6 @@ infix fun Color.alwaysLight(isAlways: Boolean): Color {
} else {
this
}
}
}

fun Color.tone(tone: Int) = Color(TonalPalette.from(this).tone(tone))
5 changes: 5 additions & 0 deletions app/src/main/java/com/skyd/anivu/ext/IOExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.Context
import android.content.Intent
import android.net.Uri
import android.provider.OpenableColumns
import android.webkit.URLUtil
import android.widget.Toast
import androidx.core.content.ContextCompat
import com.skyd.anivu.R
Expand Down Expand Up @@ -89,6 +90,10 @@ private fun Uri.openChooser(context: Context, action: String, chooserTitle: Char
}
}

fun Uri.isLocal(): Boolean = URLUtil.isFileUrl(toString()) || URLUtil.isContentUrl(toString())

fun Uri.isNetwork(): Boolean = URLUtil.isNetworkUrl(toString())

fun InputStream.saveTo(target: File): File {
val parentFile = target.parentFile
if (parentFile?.exists() == false) {
Expand Down
2 changes: 2 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 @@ -12,6 +12,7 @@ import com.skyd.anivu.model.preference.appearance.feed.FeedGroupExpandPreference
import com.skyd.anivu.model.preference.autodelete.AutoDeleteArticleBeforePreference
import com.skyd.anivu.model.preference.autodelete.AutoDeleteArticleFrequencyPreference
import com.skyd.anivu.model.preference.autodelete.UseAutoDeletePreference
import com.skyd.anivu.model.preference.behavior.PickImageMethodPreference
import com.skyd.anivu.model.preference.behavior.article.ArticleSwipeLeftActionPreference
import com.skyd.anivu.model.preference.behavior.article.ArticleTapActionPreference
import com.skyd.anivu.model.preference.behavior.article.DeduplicateTitleInDescPreference
Expand Down Expand Up @@ -39,6 +40,7 @@ fun Preferences.toSettings(): Settings {
articleTapAction = ArticleTapActionPreference.fromPreferences(this),
articleSwipeLeftAction = ArticleSwipeLeftActionPreference.fromPreferences(this),
hideEmptyDefault = HideEmptyDefaultPreference.fromPreferences(this),
pickImageMethod = PickImageMethodPreference.fromPreferences(this),

// Player
playerDoubleTap = PlayerDoubleTapPreference.fromPreferences(this),
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/java/com/skyd/anivu/model/bean/ArticleBean.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ data class ArticleBean(
var link: String? = null,
@ColumnInfo(name = UPDATE_AT_COLUMN)
var updateAt: Long? = null,
@ColumnInfo(name = IS_READ_COLUMN)
var isRead: Boolean = false,
@ColumnInfo(name = IS_FAVORITE_COLUMN)
var isFavorite: Boolean = false,
) : BaseBean, Parcelable {
companion object {
const val ARTICLE_ID_COLUMN = "articleId"
Expand All @@ -63,5 +67,7 @@ data class ArticleBean(
const val IMAGE_COLUMN = "image"
const val LINK_COLUMN = "link"
const val UPDATE_AT_COLUMN = "updateAt"
const val IS_READ_COLUMN = "isRead"
const val IS_FAVORITE_COLUMN = "isFavorite"
}
}
6 changes: 6 additions & 0 deletions app/src/main/java/com/skyd/anivu/model/bean/FeedBean.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ data class FeedBean(
var groupId: String? = null,
@ColumnInfo(name = NICKNAME_COLUMN)
var nickname: String? = null,
@ColumnInfo(name = CUSTOM_DESCRIPTION_COLUMN)
val customDescription: String? = null,
@ColumnInfo(name = CUSTOM_ICON_COLUMN)
val customIcon: String? = null,
) : BaseBean, Parcelable {
companion object {
const val URL_COLUMN = "url"
Expand All @@ -38,6 +42,8 @@ data class FeedBean(
const val ICON_COLUMN = "icon"
const val GROUP_ID_COLUMN = "groupId"
const val NICKNAME_COLUMN = "nickname"
const val CUSTOM_DESCRIPTION_COLUMN = "customDescription"
const val CUSTOM_ICON_COLUMN = "customIcon"

fun FeedBean.isDefaultGroup(): Boolean =
this.groupId == null || this.groupId == GroupBean.DEFAULT_GROUP_ID
Expand Down
9 changes: 6 additions & 3 deletions app/src/main/java/com/skyd/anivu/model/db/AppDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.skyd.anivu.model.db.migration.Migration1To2
import com.skyd.anivu.model.db.migration.Migration2To3
import com.skyd.anivu.model.db.migration.Migration3To4
import com.skyd.anivu.model.db.migration.Migration4To5
import com.skyd.anivu.model.db.migration.Migration5To6

const val APP_DATA_BASE_FILE_NAME = "app.db"

Expand All @@ -40,7 +41,7 @@ const val APP_DATA_BASE_FILE_NAME = "app.db"
GroupBean::class,
],
views = [FeedViewBean::class],
version = 5,
version = 6,
)
@TypeConverters(
value = []
Expand All @@ -58,8 +59,10 @@ abstract class AppDatabase : RoomDatabase() {
@Volatile
private var instance: AppDatabase? = null

private val migrations =
arrayOf(Migration1To2(), Migration2To3(), Migration3To4(), Migration4To5())
private val migrations = arrayOf(
Migration1To2(), Migration2To3(), Migration3To4(), Migration4To5(),
Migration5To6()
)

fun getInstance(context: Context): AppDatabase {
return instance ?: synchronized(this) {
Expand Down
23 changes: 13 additions & 10 deletions app/src/main/java/com/skyd/anivu/model/db/dao/FeedDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,6 @@ interface FeedDao {
@Query("DELETE FROM $FEED_TABLE_NAME WHERE ${FeedBean.GROUP_ID_COLUMN} = :groupId")
suspend fun removeFeedByGroupId(groupId: String): Int

@Transaction
@Query(
"""
UPDATE $FEED_TABLE_NAME
SET ${FeedBean.NICKNAME_COLUMN} = :nickname, ${FeedBean.GROUP_ID_COLUMN} = :groupId
WHERE ${FeedBean.URL_COLUMN} = :feedUrl
"""
)
suspend fun updateFeedGroupId(feedUrl: String, nickname: String?, groupId: String?): Int

@Transaction
@Query(
"""
Expand Down Expand Up @@ -123,6 +113,15 @@ interface FeedDao {
@Query("SELECT * FROM $FEED_TABLE_NAME WHERE ${FeedBean.URL_COLUMN} = :feedUrl")
suspend fun getFeed(feedUrl: String): FeedBean

@Transaction
@Query(
"""
SELECT * FROM $FEED_VIEW_NAME
WHERE ${FeedBean.GROUP_ID_COLUMN} IN (:groupIds)
"""
)
suspend fun getFeedsIn(groupIds: List<String>): List<FeedViewBean>

@Transaction
@Query(
"""
Expand All @@ -148,4 +147,8 @@ interface FeedDao {
@Transaction
@Query("SELECT COUNT(*) FROM $FEED_TABLE_NAME WHERE ${FeedBean.URL_COLUMN} LIKE :url")
fun containsByUrl(url: String): Int

@Transaction
@Query("SELECT COUNT(*) FROM $FEED_TABLE_NAME WHERE ${FeedBean.CUSTOM_ICON_COLUMN} LIKE :customIcon")
fun containsByCustomIcon(customIcon: String): Int
}
4 changes: 4 additions & 0 deletions app/src/main/java/com/skyd/anivu/model/db/dao/GroupDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.skyd.anivu.appContext
import com.skyd.anivu.model.bean.GROUP_TABLE_NAME
import com.skyd.anivu.model.bean.GroupBean
import com.skyd.anivu.model.bean.GroupWithFeedBean
import com.skyd.anivu.model.repository.tryDeleteFeedIconFile
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.EntryPointAccessors
Expand Down Expand Up @@ -40,6 +41,9 @@ interface GroupDao {
suspend fun removeGroupWithFeed(groupId: String): Int {
removeGroup(groupId)
return EntryPointAccessors.fromApplication(appContext, GroupDaoEntryPoint::class.java).run {
feedDao.getFeedsIn(listOf(groupId)).forEach {
it.feed.customIcon?.let { icon -> tryDeleteFeedIconFile(icon) }
}
feedDao.removeFeedByGroupId(groupId)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.skyd.anivu.model.db.migration

import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.skyd.anivu.model.bean.ARTICLE_TABLE_NAME
import com.skyd.anivu.model.bean.ArticleBean
import com.skyd.anivu.model.bean.FEED_TABLE_NAME
import com.skyd.anivu.model.bean.FeedBean

class Migration5To6 : Migration(5, 6) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE $FEED_TABLE_NAME ADD ${FeedBean.CUSTOM_DESCRIPTION_COLUMN} TEXT")
db.execSQL("ALTER TABLE $FEED_TABLE_NAME ADD ${FeedBean.CUSTOM_ICON_COLUMN} TEXT")

db.execSQL("ALTER TABLE $ARTICLE_TABLE_NAME ADD ${ArticleBean.IS_READ_COLUMN} INTEGER NOT NULL DEFAULT 0")
db.execSQL("ALTER TABLE $ARTICLE_TABLE_NAME ADD ${ArticleBean.IS_FAVORITE_COLUMN} INTEGER NOT NULL DEFAULT 0")
}
}
4 changes: 4 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 @@ -17,6 +17,7 @@ import com.skyd.anivu.model.preference.appearance.feed.FeedGroupExpandPreference
import com.skyd.anivu.model.preference.autodelete.AutoDeleteArticleBeforePreference
import com.skyd.anivu.model.preference.autodelete.AutoDeleteArticleFrequencyPreference
import com.skyd.anivu.model.preference.autodelete.UseAutoDeletePreference
import com.skyd.anivu.model.preference.behavior.PickImageMethodPreference
import com.skyd.anivu.model.preference.behavior.article.ArticleSwipeLeftActionPreference
import com.skyd.anivu.model.preference.behavior.article.ArticleTapActionPreference
import com.skyd.anivu.model.preference.behavior.article.DeduplicateTitleInDescPreference
Expand All @@ -37,6 +38,7 @@ import com.skyd.anivu.ui.local.LocalHardwareDecode
import com.skyd.anivu.ui.local.LocalHideEmptyDefault
import com.skyd.anivu.ui.local.LocalIgnoreUpdateVersion
import com.skyd.anivu.ui.local.LocalNavigationBarLabel
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
Expand All @@ -61,6 +63,7 @@ data class Settings(
val articleTapAction: String = ArticleTapActionPreference.default,
val articleSwipeLeftAction: String = ArticleSwipeLeftActionPreference.default,
val hideEmptyDefault: Boolean = HideEmptyDefaultPreference.default,
val pickImageMethod: String = PickImageMethodPreference.default,
// Player
val playerDoubleTap: String = PlayerDoubleTapPreference.default,
val playerShow85sButton: Boolean = PlayerShow85sButtonPreference.default,
Expand Down Expand Up @@ -95,6 +98,7 @@ fun SettingsProvider(
LocalArticleTapAction provides settings.articleTapAction,
LocalArticleSwipeLeftAction provides settings.articleSwipeLeftAction,
LocalHideEmptyDefault provides settings.hideEmptyDefault,
LocalPickImageMethod provides settings.pickImageMethod,
// Player
LocalPlayerDoubleTap provides settings.playerDoubleTap,
LocalPlayerShow85sButton provides settings.playerShow85sButton,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.skyd.anivu.model.preference.behavior

import android.content.Context
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.stringPreferencesKey
import com.skyd.anivu.R
import com.skyd.anivu.appContext
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 PickImageMethodPreference : BasePreference<String> {
val methodList = arrayOf(
"PickVisualMedia",
"PickFromGallery",
"OpenDocument",
"GetContent",
)

private const val PICK_IMAGE_METHOD = "pickImageMethod"
override val default = methodList[0]

val key = stringPreferencesKey(PICK_IMAGE_METHOD)

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

override fun fromPreferences(preferences: Preferences): String = preferences[key] ?: default

fun toDisplayName(method: String) = appContext.getString(
when (method) {
"PickVisualMedia" -> R.string.pick_image_method_pick_visual_media
"PickFromGallery" -> R.string.pick_image_method_pick_from_gallery
"OpenDocument" -> R.string.pick_image_method_open_document
"GetContent" -> R.string.pick_image_method_get_content
else -> R.string.pick_image_method_pick_visual_media
}, method
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.skyd.anivu.base.BaseRepository
import com.skyd.anivu.config.Const
import com.skyd.anivu.ext.deleteRecursivelyExclude
import com.skyd.anivu.model.db.dao.ArticleDao
import com.skyd.anivu.model.db.dao.FeedDao
import com.skyd.anivu.model.db.dao.TorrentFileDao
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
Expand All @@ -13,6 +14,7 @@ import javax.inject.Inject

class DataRepository @Inject constructor(
private val torrentFileDao: TorrentFileDao,
private val feedDao: FeedDao,
private val articleDao: ArticleDao,
) : BaseRepository() {
fun requestClearCache(): Flow<Long> {
Expand All @@ -32,6 +34,17 @@ class DataRepository @Inject constructor(
}
}
}
Const.FEED_ICON_DIR.walkBottomUp().forEach {
if (it.path!=Const.FEED_ICON_DIR.path) {
val contains = feedDao.containsByCustomIcon(it.path)
if (contains == 0) {
val s = it.length()
if (it.delete()) {
size += s
}
}
}
}
emit(size)
}.flowOn(Dispatchers.IO)
}
Expand Down
Loading

0 comments on commit 0719b8b

Please sign in to comment.