Skip to content

Commit

Permalink
[feature] Support displaying media previews on the reading page; supp…
Browse files Browse the repository at this point in the history
…ort partial media RSS fields (#49); support displaying category tags on the reading page
  • Loading branch information
SkyD666 committed Aug 31, 2024
1 parent 0e35333 commit 5528fbd
Show file tree
Hide file tree
Showing 39 changed files with 523 additions and 73 deletions.
6 changes: 4 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 21,8 @@ android {
applicationId = "com.skyd.anivu"
minSdk = 24
targetSdk = 35
versionCode = 22
versionName = "2.1-alpha26"
versionCode = 23
versionName = "2.1-alpha27"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

Expand Down Expand Up @@ -113,6 113,7 @@ android {
"META-INF/jdom-info.xml",
"kotlin-tooling-metadata.json",
"okhttp3/internal/publicsuffix/NOTICE",
"rome-utils-*.jar",
)
jniLibs {
excludes = mutableSetOf(
Expand Down Expand Up @@ -203,6 204,7 @@ dependencies {
implementation("io.coil-kt:coil-video:2.7.0")
implementation("com.airbnb.android:lottie-compose:6.5.1")
implementation("com.rometools:rome:2.1.0")
implementation("com.rometools:rome-modules:2.1.0")
implementation("be.ceau:opml-parser:3.1.0") {
exclude(group = "net.sf.kxml", module = "kxml2")
}
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/skyd/anivu/config/SearchConfig.kt
Original file line number Diff line number Diff line change
@@ -1,7 1,7 @@
package com.skyd.anivu.config

import com.skyd.anivu.model.bean.ARTICLE_TABLE_NAME
import com.skyd.anivu.model.bean.ArticleBean
import com.skyd.anivu.model.bean.article.ARTICLE_TABLE_NAME
import com.skyd.anivu.model.bean.article.ArticleBean
import com.skyd.anivu.model.bean.FEED_TABLE_NAME
import com.skyd.anivu.model.bean.FEED_VIEW_NAME
import com.skyd.anivu.model.bean.FeedBean
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/com/skyd/anivu/di/DatabaseModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 9,7 @@ import com.skyd.anivu.model.db.dao.EnclosureDao
import com.skyd.anivu.model.db.dao.FeedDao
import com.skyd.anivu.model.db.dao.GroupDao
import com.skyd.anivu.model.db.dao.MediaPlayHistoryDao
import com.skyd.anivu.model.db.dao.RssModuleDao
import com.skyd.anivu.model.db.dao.SearchDomainDao
import com.skyd.anivu.model.db.dao.SessionParamsDao
import com.skyd.anivu.model.db.dao.TorrentFileDao
Expand Down Expand Up @@ -62,6 63,10 @@ object DatabaseModule {
fun provideMediaPlayHistoryDao(database: AppDatabase): MediaPlayHistoryDao =
database.mediaPlayHistoryDao()

@Provides
@Singleton
fun provideRssModuleDao(database: AppDatabase): RssModuleDao = database.rssModuleDao()


@Provides
@Singleton
Expand Down
20 changes: 20 additions & 0 deletions app/src/main/java/com/skyd/anivu/ext/ContextExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 7,8 @@ import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Point
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
import android.os.Build.VERSION.SDK_INT
import android.view.Window
Expand All @@ -17,6 19,8 @@ import coil.decode.GifDecoder
import coil.decode.ImageDecoderDecoder
import coil.decode.SvgDecoder
import coil.decode.VideoFrameDecoder
import okhttp3.Interceptor
import okhttp3.OkHttpClient

val Context.activity: Activity
get() {
Expand Down Expand Up @@ -113,6 117,13 @@ fun Context.inDarkMode(): Boolean {
Configuration.UI_MODE_NIGHT_YES
}

fun Context.isWifi(): Boolean {
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkCapabilities =
connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
return networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true
}

fun Context.imageLoaderBuilder(): ImageLoader.Builder {
return ImageLoader.Builder(this)
.components {
Expand All @@ -124,4 135,13 @@ fun Context.imageLoaderBuilder(): ImageLoader.Builder {
add(SvgDecoder.Factory())
add(VideoFrameDecoder.Factory())
}
.okHttpClient {
OkHttpClient.Builder()
.addNetworkInterceptor(Interceptor { chain ->
chain.proceed(chain.request()).newBuilder()
.header("Cache-Control", "max-age=31536000,public")
.build()
})
.build()
}
}
2 changes: 2 additions & 0 deletions app/src/main/java/com/skyd/anivu/model/bean/FeedViewBean.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 5,8 @@ import androidx.room.ColumnInfo
import androidx.room.DatabaseView
import androidx.room.Embedded
import com.skyd.anivu.base.BaseBean
import com.skyd.anivu.model.bean.article.ARTICLE_TABLE_NAME
import com.skyd.anivu.model.bean.article.ArticleBean
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 2,8 @@ package com.skyd.anivu.model.bean

import androidx.room.Embedded
import androidx.room.Relation
import com.skyd.anivu.model.bean.article.ArticleBean
import com.skyd.anivu.model.bean.article.ArticleWithEnclosureBean

/**
* A [feed] contains many [articles].
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 1,12 @@
package com.skyd.anivu.model.bean

import com.skyd.anivu.base.BaseBean
import com.skyd.anivu.model.bean.article.EnclosureBean

data class LinkEnclosureBean(
val link: String,
) : BaseBean {
val isMedia: Boolean
get() = EnclosureBean.mediaExtensions.any { link.endsWith(it) }
get() = EnclosureBean.videoExtensions.any { link.endsWith(it) } ||
EnclosureBean.audioExtensions.any { link.endsWith(it) }
}
Original file line number Diff line number Diff line change
@@ -1,4 1,4 @@
package com.skyd.anivu.model.bean
package com.skyd.anivu.model.bean.article

import android.os.Parcelable
import androidx.room.ColumnInfo
Expand All @@ -7,6 7,7 @@ import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey
import com.skyd.anivu.base.BaseBean
import com.skyd.anivu.model.bean.FeedBean
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable

Expand Down Expand Up @@ -57,7 58,14 @@ data class ArticleBean(
var isRead: Boolean = false,
@ColumnInfo(name = IS_FAVORITE_COLUMN)
var isFavorite: Boolean = false,
@ColumnInfo(name = CATEGORIES_COLUMN)
var catrgories: Categories? = null,
) : BaseBean, Parcelable {

@Parcelize
@Serializable
data class Categories(val categories: List<String>) : BaseBean, Parcelable

companion object {
const val ARTICLE_ID_COLUMN = "articleId"
const val FEED_URL_COLUMN = "feedUrl"
Expand All @@ -72,5 80,6 @@ data class ArticleBean(
const val UPDATE_AT_COLUMN = "updateAt"
const val IS_READ_COLUMN = "isRead"
const val IS_FAVORITE_COLUMN = "isFavorite"
const val CATEGORIES_COLUMN = "catrgories"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 1,4 @@
package com.skyd.anivu.model.bean
package com.skyd.anivu.model.bean.article

import android.os.Parcelable
import androidx.room.Embedded
Expand All @@ -16,4 16,9 @@ data class ArticleWithEnclosureBean(
entityColumn = EnclosureBean.ARTICLE_ID_COLUMN,
)
var enclosures: List<EnclosureBean>,
@Relation(
parentColumn = ArticleBean.ARTICLE_ID_COLUMN,
entityColumn = RssMediaBean.ARTICLE_ID_COLUMN,
)
var media: RssMediaBean?,
) : Serializable, Parcelable
Original file line number Diff line number Diff line change
@@ -1,8 1,9 @@
package com.skyd.anivu.model.bean
package com.skyd.anivu.model.bean.article

import android.os.Parcelable
import androidx.room.Embedded
import androidx.room.Relation
import com.skyd.anivu.model.bean.FeedBean
import kotlinx.parcelize.Parcelize
import java.io.Serializable

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 1,4 @@
package com.skyd.anivu.model.bean
package com.skyd.anivu.model.bean.article

import android.os.Parcelable
import androidx.room.ColumnInfo
Expand Down Expand Up @@ -40,15 40,24 @@ data class EnclosureBean(
const val LENGTH_COLUMN = "length"
const val TYPE_COLUMN = "type"

val mediaExtensions = listOf(
".m3u8", ".ogg", ".mp3", ".flac", ".m4v", ".mov", ".avi", ".webm",
".mp4", ".mkv", ".m4a",
val videoExtensions = listOf(
".m3u8", ".m4v", ".mov", ".avi", ".webm",
".mp4", ".mkv",
)
val audioExtensions = listOf(
".ogg", ".mp3", ".flac", ".m4a",
)
}

val isMedia: Boolean
get() = type?.startsWith("audio/") == true ||
type?.startsWith("video/") == true ||
get() = isVideo || isAudio

val isVideo: Boolean
get() = type?.startsWith("video/") == true ||
type == "application/vnd.apple.mpegurl" ||
mediaExtensions.any { url.endsWith(it) }
videoExtensions.any { url.endsWith(it) }

val isAudio: Boolean
get() = type?.startsWith("audio/") == true ||
audioExtensions.any { url.endsWith(it) }
}
Original file line number Diff line number Diff line change
@@ -0,0 1,47 @@
package com.skyd.anivu.model.bean.article

import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey
import com.skyd.anivu.base.BaseBean
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable

const val RSS_MEDIA_TABLE_NAME = "RssMedia"

@Parcelize
@Serializable
@Entity(
tableName = RSS_MEDIA_TABLE_NAME,
foreignKeys = [
ForeignKey(
entity = ArticleBean::class,
parentColumns = [ArticleBean.ARTICLE_ID_COLUMN],
childColumns = [RssMediaBean.ARTICLE_ID_COLUMN],
onDelete = ForeignKey.CASCADE
)
],
)
data class RssMediaBean(
@PrimaryKey
@ColumnInfo(name = ARTICLE_ID_COLUMN)
val articleId: String,
@ColumnInfo(name = DURATION_COLUMN)
val duration: Long? = null,
@ColumnInfo(name = ADULT_COLUMN)
var adult: Boolean = false,
@ColumnInfo(name = IMAGE_COLUMN)
val image: String? = null,
@ColumnInfo(name = EPISODE_COLUMN)
var episode: String? = null,
) : BaseBean, Parcelable {
companion object {
const val ARTICLE_ID_COLUMN = "articleId"
const val DURATION_COLUMN = "duration"
const val ADULT_COLUMN = "adult"
const val IMAGE_COLUMN = "image"
const val EPISODE_COLUMN = "episode"
}
}
17 changes: 12 additions & 5 deletions app/src/main/java/com/skyd/anivu/model/db/AppDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 5,29 @@ import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import com.skyd.anivu.model.bean.ArticleBean
import com.skyd.anivu.model.bean.EnclosureBean
import com.skyd.anivu.model.bean.FeedBean
import com.skyd.anivu.model.bean.FeedViewBean
import com.skyd.anivu.model.bean.GroupBean
import com.skyd.anivu.model.bean.MediaPlayHistoryBean
import com.skyd.anivu.model.bean.article.ArticleBean
import com.skyd.anivu.model.bean.article.EnclosureBean
import com.skyd.anivu.model.bean.article.RssMediaBean
import com.skyd.anivu.model.bean.download.DownloadInfoBean
import com.skyd.anivu.model.bean.download.DownloadLinkUuidMapBean
import com.skyd.anivu.model.bean.download.SessionParamsBean
import com.skyd.anivu.model.bean.download.TorrentFileBean
import com.skyd.anivu.model.db.converter.CategoriesConverter
import com.skyd.anivu.model.db.dao.ArticleDao
import com.skyd.anivu.model.db.dao.DownloadInfoDao
import com.skyd.anivu.model.db.dao.EnclosureDao
import com.skyd.anivu.model.db.dao.FeedDao
import com.skyd.anivu.model.db.dao.GroupDao
import com.skyd.anivu.model.db.dao.MediaPlayHistoryDao
import com.skyd.anivu.model.db.dao.RssModuleDao
import com.skyd.anivu.model.db.dao.SessionParamsDao
import com.skyd.anivu.model.db.dao.TorrentFileDao
import com.skyd.anivu.model.db.migration.Migration10To11
import com.skyd.anivu.model.db.migration.Migration11To12
import com.skyd.anivu.model.db.migration.Migration1To2
import com.skyd.anivu.model.db.migration.Migration2To3
import com.skyd.anivu.model.db.migration.Migration3To4
Expand All @@ -47,12 51,14 @@ const val APP_DATA_BASE_FILE_NAME = "app.db"
TorrentFileBean::class,
GroupBean::class,
MediaPlayHistoryBean::class,

RssMediaBean::class,
],
views = [FeedViewBean::class],
version = 11,
version = 12,
)
@TypeConverters(
value = []
value = [CategoriesConverter::class]
)
abstract class AppDatabase : RoomDatabase() {
abstract fun groupDao(): GroupDao
Expand All @@ -63,6 69,7 @@ abstract class AppDatabase : RoomDatabase() {
abstract fun torrentFileDao(): TorrentFileDao
abstract fun sessionParamsDao(): SessionParamsDao
abstract fun mediaPlayHistoryDao(): MediaPlayHistoryDao
abstract fun rssModuleDao(): RssModuleDao

companion object {
@Volatile
Expand All @@ -71,7 78,7 @@ abstract class AppDatabase : RoomDatabase() {
private val migrations = arrayOf(
Migration1To2(), Migration2To3(), Migration3To4(), Migration4To5(),
Migration5To6(), Migration6To7(), Migration7To8(), Migration8To9(),
Migration9To10(), Migration10To11(),
Migration9To10(), Migration10To11(), Migration11To12(),
)

fun getInstance(context: Context): AppDatabase {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 1,20 @@
package com.skyd.anivu.model.db.converter

import androidx.room.TypeConverter
import com.skyd.anivu.model.bean.article.ArticleBean
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

class CategoriesConverter {
@TypeConverter
fun fromString(string: String?): ArticleBean.Categories? {
string ?: return null
return ArticleBean.Categories(categories = Json.decodeFromString(string))
}

@TypeConverter
fun categoriesToString(categories: ArticleBean.Categories?): String? {
val list = categories?.categories ?: return null
return Json.encodeToString(list)
}
}
Loading

0 comments on commit 5528fbd

Please sign in to comment.