diff --git a/app/src/main/java/me/ash/reader/App.kt b/app/src/main/java/me/ash/reader/App.kt index e0a8903..6790bad 100644 --- a/app/src/main/java/me/ash/reader/App.kt +++ b/app/src/main/java/me/ash/reader/App.kt @@ -14,6 +14,9 @@ import me.ash.reader.data.repository.* import me.ash.reader.data.source.OpmlLocalDataSource import me.ash.reader.data.source.ReaderDatabase import me.ash.reader.data.source.RssNetworkDataSource +import me.ash.reader.ui.ext.DataStoreKeys +import me.ash.reader.ui.ext.dataStore +import me.ash.reader.ui.ext.put import javax.inject.Inject @HiltAndroidApp diff --git a/app/src/main/java/me/ash/reader/NumberExt.kt b/app/src/main/java/me/ash/reader/NumberExt.kt deleted file mode 100644 index d5e5438..0000000 --- a/app/src/main/java/me/ash/reader/NumberExt.kt +++ /dev/null @@ -1,3 +0,0 @@ -package me.ash.reader - -fun Int.spacerDollar(str: Any): String = "$this$$str" \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/data/Converters.kt b/app/src/main/java/me/ash/reader/data/Converters.kt deleted file mode 100644 index c914f5d..0000000 --- a/app/src/main/java/me/ash/reader/data/Converters.kt +++ /dev/null @@ -1,17 +0,0 @@ -package me.ash.reader.data - -import androidx.room.TypeConverter -import java.util.* - -class Converters { - - @TypeConverter - fun toDate(dateLong: Long?): Date? { - return dateLong?.let { Date(it) } - } - - @TypeConverter - fun fromDate(date: Date?): Long? { - return date?.time - } -} \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/data/account/AccountDao.kt b/app/src/main/java/me/ash/reader/data/dao/AccountDao.kt similarity index 88% rename from app/src/main/java/me/ash/reader/data/account/AccountDao.kt rename to app/src/main/java/me/ash/reader/data/dao/AccountDao.kt index 07d80ec..37bb4b5 100644 --- a/app/src/main/java/me/ash/reader/data/account/AccountDao.kt +++ b/app/src/main/java/me/ash/reader/data/dao/AccountDao.kt @@ -1,6 +1,7 @@ -package me.ash.reader.data.account +package me.ash.reader.data.dao import androidx.room.* +import me.ash.reader.data.entity.Account @Dao interface AccountDao { diff --git a/app/src/main/java/me/ash/reader/data/article/ArticleDao.kt b/app/src/main/java/me/ash/reader/data/dao/ArticleDao.kt similarity index 98% rename from app/src/main/java/me/ash/reader/data/article/ArticleDao.kt rename to app/src/main/java/me/ash/reader/data/dao/ArticleDao.kt index 1a0eb44..92641a8 100644 --- a/app/src/main/java/me/ash/reader/data/article/ArticleDao.kt +++ b/app/src/main/java/me/ash/reader/data/dao/ArticleDao.kt @@ -1,8 +1,11 @@ -package me.ash.reader.data.article +package me.ash.reader.data.dao import androidx.paging.PagingSource import androidx.room.* import kotlinx.coroutines.flow.Flow +import me.ash.reader.data.entity.Article +import me.ash.reader.data.entity.ArticleWithFeed +import me.ash.reader.data.entity.ImportantCount @Dao interface ArticleDao { diff --git a/app/src/main/java/me/ash/reader/data/feed/FeedDao.kt b/app/src/main/java/me/ash/reader/data/dao/FeedDao.kt similarity index 91% rename from app/src/main/java/me/ash/reader/data/feed/FeedDao.kt rename to app/src/main/java/me/ash/reader/data/dao/FeedDao.kt index 3be1c97..cbe4c05 100644 --- a/app/src/main/java/me/ash/reader/data/feed/FeedDao.kt +++ b/app/src/main/java/me/ash/reader/data/dao/FeedDao.kt @@ -1,6 +1,7 @@ -package me.ash.reader.data.feed +package me.ash.reader.data.dao import androidx.room.* +import me.ash.reader.data.entity.Feed @Dao interface FeedDao { diff --git a/app/src/main/java/me/ash/reader/data/group/GroupDao.kt b/app/src/main/java/me/ash/reader/data/dao/GroupDao.kt similarity index 90% rename from app/src/main/java/me/ash/reader/data/group/GroupDao.kt rename to app/src/main/java/me/ash/reader/data/dao/GroupDao.kt index 66147bd..3936ebc 100644 --- a/app/src/main/java/me/ash/reader/data/group/GroupDao.kt +++ b/app/src/main/java/me/ash/reader/data/dao/GroupDao.kt @@ -1,7 +1,9 @@ -package me.ash.reader.data.group +package me.ash.reader.data.dao import androidx.room.* import kotlinx.coroutines.flow.Flow +import me.ash.reader.data.entity.Group +import me.ash.reader.data.entity.GroupWithFeed @Dao interface GroupDao { diff --git a/app/src/main/java/me/ash/reader/data/account/Account.kt b/app/src/main/java/me/ash/reader/data/entity/Account.kt similarity index 92% rename from app/src/main/java/me/ash/reader/data/account/Account.kt rename to app/src/main/java/me/ash/reader/data/entity/Account.kt index 902512a..86e558c 100644 --- a/app/src/main/java/me/ash/reader/data/account/Account.kt +++ b/app/src/main/java/me/ash/reader/data/entity/Account.kt @@ -1,4 +1,4 @@ -package me.ash.reader.data.account +package me.ash.reader.data.entity import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/app/src/main/java/me/ash/reader/data/article/Article.kt b/app/src/main/java/me/ash/reader/data/entity/Article.kt similarity index 93% rename from app/src/main/java/me/ash/reader/data/article/Article.kt rename to app/src/main/java/me/ash/reader/data/entity/Article.kt index 2024bcf..2c0cdd5 100644 --- a/app/src/main/java/me/ash/reader/data/article/Article.kt +++ b/app/src/main/java/me/ash/reader/data/entity/Article.kt @@ -1,10 +1,9 @@ -package me.ash.reader.data.article +package me.ash.reader.data.entity import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.ForeignKey import androidx.room.PrimaryKey -import me.ash.reader.data.feed.Feed import java.util.* @Entity( diff --git a/app/src/main/java/me/ash/reader/data/article/ArticleWithFeed.kt b/app/src/main/java/me/ash/reader/data/entity/ArticleWithFeed.kt similarity index 74% rename from app/src/main/java/me/ash/reader/data/article/ArticleWithFeed.kt rename to app/src/main/java/me/ash/reader/data/entity/ArticleWithFeed.kt index e92d49f..4910ceb 100644 --- a/app/src/main/java/me/ash/reader/data/article/ArticleWithFeed.kt +++ b/app/src/main/java/me/ash/reader/data/entity/ArticleWithFeed.kt @@ -1,8 +1,7 @@ -package me.ash.reader.data.article +package me.ash.reader.data.entity import androidx.room.Embedded import androidx.room.Relation -import me.ash.reader.data.feed.Feed data class ArticleWithFeed( @Embedded diff --git a/app/src/main/java/me/ash/reader/data/feed/Feed.kt b/app/src/main/java/me/ash/reader/data/entity/Feed.kt similarity index 96% rename from app/src/main/java/me/ash/reader/data/feed/Feed.kt rename to app/src/main/java/me/ash/reader/data/entity/Feed.kt index f3e3a66..e251150 100644 --- a/app/src/main/java/me/ash/reader/data/feed/Feed.kt +++ b/app/src/main/java/me/ash/reader/data/entity/Feed.kt @@ -1,7 +1,6 @@ -package me.ash.reader.data.feed +package me.ash.reader.data.entity import androidx.room.* -import me.ash.reader.data.group.Group @Entity( tableName = "feed", diff --git a/app/src/main/java/me/ash/reader/data/feed/FeedWithArticle.kt b/app/src/main/java/me/ash/reader/data/entity/FeedWithArticle.kt similarity index 74% rename from app/src/main/java/me/ash/reader/data/feed/FeedWithArticle.kt rename to app/src/main/java/me/ash/reader/data/entity/FeedWithArticle.kt index 9a28d73..48ee0ab 100644 --- a/app/src/main/java/me/ash/reader/data/feed/FeedWithArticle.kt +++ b/app/src/main/java/me/ash/reader/data/entity/FeedWithArticle.kt @@ -1,8 +1,7 @@ -package me.ash.reader.data.feed +package me.ash.reader.data.entity import androidx.room.Embedded import androidx.room.Relation -import me.ash.reader.data.article.Article data class FeedWithArticle( @Embedded diff --git a/app/src/main/java/me/ash/reader/data/feed/FeedWithGroup.kt b/app/src/main/java/me/ash/reader/data/entity/FeedWithGroup.kt similarity index 74% rename from app/src/main/java/me/ash/reader/data/feed/FeedWithGroup.kt rename to app/src/main/java/me/ash/reader/data/entity/FeedWithGroup.kt index 2cdae84..01d4087 100644 --- a/app/src/main/java/me/ash/reader/data/feed/FeedWithGroup.kt +++ b/app/src/main/java/me/ash/reader/data/entity/FeedWithGroup.kt @@ -1,8 +1,7 @@ -package me.ash.reader.data.feed +package me.ash.reader.data.entity import androidx.room.Embedded import androidx.room.Relation -import me.ash.reader.data.group.Group data class FeedWithGroup( @Embedded diff --git a/app/src/main/java/me/ash/reader/data/constant/Filter.kt b/app/src/main/java/me/ash/reader/data/entity/Filter.kt similarity index 97% rename from app/src/main/java/me/ash/reader/data/constant/Filter.kt rename to app/src/main/java/me/ash/reader/data/entity/Filter.kt index c433113..cb197f2 100644 --- a/app/src/main/java/me/ash/reader/data/constant/Filter.kt +++ b/app/src/main/java/me/ash/reader/data/entity/Filter.kt @@ -1,4 +1,4 @@ -package me.ash.reader.data.constant +package me.ash.reader.data.entity import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.FiberManualRecord diff --git a/app/src/main/java/me/ash/reader/data/group/Group.kt b/app/src/main/java/me/ash/reader/data/entity/Group.kt similarity index 90% rename from app/src/main/java/me/ash/reader/data/group/Group.kt rename to app/src/main/java/me/ash/reader/data/entity/Group.kt index cc5276a..5aa7962 100644 --- a/app/src/main/java/me/ash/reader/data/group/Group.kt +++ b/app/src/main/java/me/ash/reader/data/entity/Group.kt @@ -1,4 +1,4 @@ -package me.ash.reader.data.group +package me.ash.reader.data.entity import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/app/src/main/java/me/ash/reader/data/group/GroupWithFeed.kt b/app/src/main/java/me/ash/reader/data/entity/GroupWithFeed.kt similarity index 76% rename from app/src/main/java/me/ash/reader/data/group/GroupWithFeed.kt rename to app/src/main/java/me/ash/reader/data/entity/GroupWithFeed.kt index c3bb985..28f2c47 100644 --- a/app/src/main/java/me/ash/reader/data/group/GroupWithFeed.kt +++ b/app/src/main/java/me/ash/reader/data/entity/GroupWithFeed.kt @@ -1,8 +1,7 @@ -package me.ash.reader.data.group +package me.ash.reader.data.entity import androidx.room.Embedded import androidx.room.Relation -import me.ash.reader.data.feed.Feed data class GroupWithFeed( @Embedded diff --git a/app/src/main/java/me/ash/reader/data/article/ImportantCount.kt b/app/src/main/java/me/ash/reader/data/entity/ImportantCount.kt similarity index 74% rename from app/src/main/java/me/ash/reader/data/article/ImportantCount.kt rename to app/src/main/java/me/ash/reader/data/entity/ImportantCount.kt index 7d94987..c876bb6 100644 --- a/app/src/main/java/me/ash/reader/data/article/ImportantCount.kt +++ b/app/src/main/java/me/ash/reader/data/entity/ImportantCount.kt @@ -1,4 +1,4 @@ -package me.ash.reader.data.article +package me.ash.reader.data.entity data class ImportantCount( val important: Int, diff --git a/app/src/main/java/me/ash/reader/data/module/DatabaseModule.kt b/app/src/main/java/me/ash/reader/data/module/DatabaseModule.kt index 1922e64..6da4d8b 100644 --- a/app/src/main/java/me/ash/reader/data/module/DatabaseModule.kt +++ b/app/src/main/java/me/ash/reader/data/module/DatabaseModule.kt @@ -6,10 +6,10 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent -import me.ash.reader.data.account.AccountDao -import me.ash.reader.data.article.ArticleDao -import me.ash.reader.data.feed.FeedDao -import me.ash.reader.data.group.GroupDao +import me.ash.reader.data.dao.AccountDao +import me.ash.reader.data.dao.ArticleDao +import me.ash.reader.data.dao.FeedDao +import me.ash.reader.data.dao.GroupDao import me.ash.reader.data.source.ReaderDatabase import javax.inject.Singleton diff --git a/app/src/main/java/me/ash/reader/data/repository/AbstractRssRepository.kt b/app/src/main/java/me/ash/reader/data/repository/AbstractRssRepository.kt index a0253e1..ba57a8d 100644 --- a/app/src/main/java/me/ash/reader/data/repository/AbstractRssRepository.kt +++ b/app/src/main/java/me/ash/reader/data/repository/AbstractRssRepository.kt @@ -10,18 +10,13 @@ import dagger.assisted.AssistedInject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.* import kotlinx.coroutines.sync.Mutex -import me.ash.reader.currentAccountId -import me.ash.reader.data.account.AccountDao -import me.ash.reader.data.article.Article -import me.ash.reader.data.article.ArticleDao -import me.ash.reader.data.article.ArticleWithFeed -import me.ash.reader.data.article.ImportantCount -import me.ash.reader.data.feed.Feed -import me.ash.reader.data.feed.FeedDao -import me.ash.reader.data.group.Group -import me.ash.reader.data.group.GroupDao -import me.ash.reader.data.group.GroupWithFeed +import me.ash.reader.data.dao.AccountDao +import me.ash.reader.data.dao.ArticleDao +import me.ash.reader.data.dao.FeedDao +import me.ash.reader.data.dao.GroupDao +import me.ash.reader.data.entity.* import me.ash.reader.data.source.RssNetworkDataSource +import me.ash.reader.ui.ext.currentAccountId import java.util.concurrent.TimeUnit abstract class AbstractRssRepository constructor( diff --git a/app/src/main/java/me/ash/reader/data/repository/AccountRepository.kt b/app/src/main/java/me/ash/reader/data/repository/AccountRepository.kt index 378d991..c4f3871 100644 --- a/app/src/main/java/me/ash/reader/data/repository/AccountRepository.kt +++ b/app/src/main/java/me/ash/reader/data/repository/AccountRepository.kt @@ -3,12 +3,12 @@ package me.ash.reader.data.repository import android.content.Context import dagger.hilt.android.qualifiers.ApplicationContext import me.ash.reader.R -import me.ash.reader.currentAccountId -import me.ash.reader.data.account.Account -import me.ash.reader.data.account.AccountDao -import me.ash.reader.data.group.Group -import me.ash.reader.data.group.GroupDao -import me.ash.reader.spacerDollar +import me.ash.reader.data.dao.AccountDao +import me.ash.reader.data.dao.GroupDao +import me.ash.reader.data.entity.Account +import me.ash.reader.data.entity.Group +import me.ash.reader.ui.ext.currentAccountId +import me.ash.reader.ui.ext.spacerDollar import javax.inject.Inject class AccountRepository @Inject constructor( diff --git a/app/src/main/java/me/ash/reader/data/repository/FeverRssRepository.kt b/app/src/main/java/me/ash/reader/data/repository/FeverRssRepository.kt index 6a64c2a..91ea2d3 100644 --- a/app/src/main/java/me/ash/reader/data/repository/FeverRssRepository.kt +++ b/app/src/main/java/me/ash/reader/data/repository/FeverRssRepository.kt @@ -8,20 +8,20 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.sync.withLock -import me.ash.reader.currentAccountId -import me.ash.reader.data.account.AccountDao -import me.ash.reader.data.article.Article -import me.ash.reader.data.article.ArticleDao -import me.ash.reader.data.feed.Feed -import me.ash.reader.data.feed.FeedDao -import me.ash.reader.data.group.Group -import me.ash.reader.data.group.GroupDao +import me.ash.reader.data.dao.AccountDao +import me.ash.reader.data.dao.ArticleDao +import me.ash.reader.data.dao.FeedDao +import me.ash.reader.data.dao.GroupDao +import me.ash.reader.data.entity.Article +import me.ash.reader.data.entity.Feed +import me.ash.reader.data.entity.Group import me.ash.reader.data.module.ApplicationScope import me.ash.reader.data.module.DispatcherDefault import me.ash.reader.data.module.DispatcherIO import me.ash.reader.data.source.FeverApiDataSource import me.ash.reader.data.source.RssNetworkDataSource -import me.ash.reader.spacerDollar +import me.ash.reader.ui.ext.currentAccountId +import me.ash.reader.ui.ext.spacerDollar import net.dankito.readability4j.extended.Readability4JExtended import java.util.* import javax.inject.Inject diff --git a/app/src/main/java/me/ash/reader/data/repository/LocalRssRepository.kt b/app/src/main/java/me/ash/reader/data/repository/LocalRssRepository.kt index ad7daf1..6bb3b7e 100644 --- a/app/src/main/java/me/ash/reader/data/repository/LocalRssRepository.kt +++ b/app/src/main/java/me/ash/reader/data/repository/LocalRssRepository.kt @@ -14,18 +14,18 @@ import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.* import me.ash.reader.MainActivity import me.ash.reader.R -import me.ash.reader.currentAccountId -import me.ash.reader.data.account.AccountDao -import me.ash.reader.data.article.Article -import me.ash.reader.data.article.ArticleDao -import me.ash.reader.data.feed.Feed -import me.ash.reader.data.feed.FeedDao -import me.ash.reader.data.group.Group -import me.ash.reader.data.group.GroupDao +import me.ash.reader.data.dao.AccountDao +import me.ash.reader.data.dao.ArticleDao +import me.ash.reader.data.dao.FeedDao +import me.ash.reader.data.dao.GroupDao +import me.ash.reader.data.entity.Article +import me.ash.reader.data.entity.Feed +import me.ash.reader.data.entity.Group import me.ash.reader.data.module.ApplicationScope import me.ash.reader.data.module.DispatcherDefault import me.ash.reader.data.module.DispatcherIO import me.ash.reader.data.source.RssNetworkDataSource +import me.ash.reader.ui.ext.currentAccountId import me.ash.reader.ui.page.common.ExtraName import me.ash.reader.ui.page.common.NotificationGroupName import java.util.* diff --git a/app/src/main/java/me/ash/reader/data/repository/OpmlRepository.kt b/app/src/main/java/me/ash/reader/data/repository/OpmlRepository.kt index cd52a3e..33ee8c2 100644 --- a/app/src/main/java/me/ash/reader/data/repository/OpmlRepository.kt +++ b/app/src/main/java/me/ash/reader/data/repository/OpmlRepository.kt @@ -8,13 +8,13 @@ import be.ceau.opml.entity.Opml import be.ceau.opml.entity.Outline import dagger.hilt.android.qualifiers.ApplicationContext import me.ash.reader.R -import me.ash.reader.currentAccountId -import me.ash.reader.data.account.AccountDao -import me.ash.reader.data.feed.Feed -import me.ash.reader.data.feed.FeedDao -import me.ash.reader.data.group.GroupDao +import me.ash.reader.data.dao.AccountDao +import me.ash.reader.data.dao.FeedDao +import me.ash.reader.data.dao.GroupDao +import me.ash.reader.data.entity.Feed import me.ash.reader.data.source.OpmlLocalDataSource -import me.ash.reader.spacerDollar +import me.ash.reader.ui.ext.currentAccountId +import me.ash.reader.ui.ext.spacerDollar import java.io.InputStream import java.util.* import javax.inject.Inject diff --git a/app/src/main/java/me/ash/reader/data/repository/RssHelper.kt b/app/src/main/java/me/ash/reader/data/repository/RssHelper.kt index faad558..da0459e 100644 --- a/app/src/main/java/me/ash/reader/data/repository/RssHelper.kt +++ b/app/src/main/java/me/ash/reader/data/repository/RssHelper.kt @@ -6,14 +6,14 @@ import android.util.Log import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.withContext -import me.ash.reader.currentAccountId -import me.ash.reader.data.article.Article -import me.ash.reader.data.feed.Feed -import me.ash.reader.data.feed.FeedDao -import me.ash.reader.data.feed.FeedWithArticle +import me.ash.reader.data.dao.FeedDao +import me.ash.reader.data.entity.Article +import me.ash.reader.data.entity.Feed +import me.ash.reader.data.entity.FeedWithArticle import me.ash.reader.data.module.DispatcherIO import me.ash.reader.data.source.RssNetworkDataSource -import me.ash.reader.spacerDollar +import me.ash.reader.ui.ext.currentAccountId +import me.ash.reader.ui.ext.spacerDollar import net.dankito.readability4j.Readability4J import net.dankito.readability4j.extended.Readability4JExtended import okhttp3.OkHttpClient diff --git a/app/src/main/java/me/ash/reader/data/repository/RssRepository.kt b/app/src/main/java/me/ash/reader/data/repository/RssRepository.kt index 68abe0f..0e247c1 100644 --- a/app/src/main/java/me/ash/reader/data/repository/RssRepository.kt +++ b/app/src/main/java/me/ash/reader/data/repository/RssRepository.kt @@ -2,8 +2,8 @@ package me.ash.reader.data.repository import android.content.Context import dagger.hilt.android.qualifiers.ApplicationContext -import me.ash.reader.currentAccountType -import me.ash.reader.data.account.Account +import me.ash.reader.data.entity.Account +import me.ash.reader.ui.ext.currentAccountType import javax.inject.Inject class RssRepository @Inject constructor( diff --git a/app/src/main/java/me/ash/reader/data/source/OpmlLocalDataSource.kt b/app/src/main/java/me/ash/reader/data/source/OpmlLocalDataSource.kt index 54a7e2d..5632993 100644 --- a/app/src/main/java/me/ash/reader/data/source/OpmlLocalDataSource.kt +++ b/app/src/main/java/me/ash/reader/data/source/OpmlLocalDataSource.kt @@ -5,11 +5,11 @@ import be.ceau.opml.OpmlParser import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.withContext -import me.ash.reader.currentAccountId -import me.ash.reader.data.feed.Feed -import me.ash.reader.data.group.Group -import me.ash.reader.data.group.GroupWithFeed +import me.ash.reader.data.entity.Feed +import me.ash.reader.data.entity.Group +import me.ash.reader.data.entity.GroupWithFeed import me.ash.reader.data.module.DispatcherIO +import me.ash.reader.ui.ext.currentAccountId import java.io.InputStream import java.util.* import javax.inject.Inject diff --git a/app/src/main/java/me/ash/reader/data/source/ReaderDatabase.kt b/app/src/main/java/me/ash/reader/data/source/ReaderDatabase.kt index 62faca4..76a4734 100644 --- a/app/src/main/java/me/ash/reader/data/source/ReaderDatabase.kt +++ b/app/src/main/java/me/ash/reader/data/source/ReaderDatabase.kt @@ -1,26 +1,23 @@ package me.ash.reader.data.source import android.content.Context -import androidx.room.Database -import androidx.room.Room -import androidx.room.RoomDatabase -import androidx.room.TypeConverters -import me.ash.reader.data.Converters -import me.ash.reader.data.account.Account -import me.ash.reader.data.account.AccountDao -import me.ash.reader.data.article.Article -import me.ash.reader.data.article.ArticleDao -import me.ash.reader.data.feed.Feed -import me.ash.reader.data.feed.FeedDao -import me.ash.reader.data.group.Group -import me.ash.reader.data.group.GroupDao +import androidx.room.* +import me.ash.reader.data.dao.AccountDao +import me.ash.reader.data.dao.ArticleDao +import me.ash.reader.data.dao.FeedDao +import me.ash.reader.data.dao.GroupDao +import me.ash.reader.data.entity.Account +import me.ash.reader.data.entity.Article +import me.ash.reader.data.entity.Feed +import me.ash.reader.data.entity.Group +import java.util.* @Database( entities = [Account::class, Feed::class, Article::class, Group::class], version = 1, exportSchema = false, ) -@TypeConverters(Converters::class) +@TypeConverters(ReaderDatabase.Converters::class) abstract class ReaderDatabase : RoomDatabase() { abstract fun accountDao(): AccountDao abstract fun feedDao(): FeedDao @@ -42,4 +39,17 @@ abstract class ReaderDatabase : RoomDatabase() { } } } + + class Converters { + + @TypeConverter + fun toDate(dateLong: Long?): Date? { + return dateLong?.let { Date(it) } + } + + @TypeConverter + fun fromDate(date: Date?): Long? { + return date?.time + } + } } \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/ui/widget/AnimatedText.kt b/app/src/main/java/me/ash/reader/ui/component/AnimatedText.kt similarity index 98% rename from app/src/main/java/me/ash/reader/ui/widget/AnimatedText.kt rename to app/src/main/java/me/ash/reader/ui/component/AnimatedText.kt index 3fcfd26..614543c 100644 --- a/app/src/main/java/me/ash/reader/ui/widget/AnimatedText.kt +++ b/app/src/main/java/me/ash/reader/ui/component/AnimatedText.kt @@ -1,4 +1,4 @@ -package me.ash.reader.ui.widget +package me.ash.reader.ui.component import androidx.compose.animation.* import androidx.compose.animation.core.FastOutSlowInEasing diff --git a/app/src/main/java/me/ash/reader/ui/widget/Banner.kt b/app/src/main/java/me/ash/reader/ui/component/Banner.kt similarity index 98% rename from app/src/main/java/me/ash/reader/ui/widget/Banner.kt rename to app/src/main/java/me/ash/reader/ui/component/Banner.kt index 9b0c904..2c3583a 100644 --- a/app/src/main/java/me/ash/reader/ui/widget/Banner.kt +++ b/app/src/main/java/me/ash/reader/ui/component/Banner.kt @@ -1,4 +1,4 @@ -package me.ash.reader.ui.widget +package me.ash.reader.ui.component import androidx.compose.animation.Crossfade import androidx.compose.foundation.background diff --git a/app/src/main/java/me/ash/reader/ui/widget/BottomDrawer.kt b/app/src/main/java/me/ash/reader/ui/component/BottomDrawer.kt similarity index 98% rename from app/src/main/java/me/ash/reader/ui/widget/BottomDrawer.kt rename to app/src/main/java/me/ash/reader/ui/component/BottomDrawer.kt index 79317de..4043ef9 100644 --- a/app/src/main/java/me/ash/reader/ui/widget/BottomDrawer.kt +++ b/app/src/main/java/me/ash/reader/ui/component/BottomDrawer.kt @@ -1,4 +1,4 @@ -package me.ash.reader.ui.widget +package me.ash.reader.ui.component import androidx.compose.foundation.background import androidx.compose.foundation.layout.* diff --git a/app/src/main/java/me/ash/reader/ui/widget/CanBeDisabledIconButton.kt b/app/src/main/java/me/ash/reader/ui/component/CanBeDisabledIconButton.kt similarity index 97% rename from app/src/main/java/me/ash/reader/ui/widget/CanBeDisabledIconButton.kt rename to app/src/main/java/me/ash/reader/ui/component/CanBeDisabledIconButton.kt index 9bbb81b..9d5852d 100644 --- a/app/src/main/java/me/ash/reader/ui/widget/CanBeDisabledIconButton.kt +++ b/app/src/main/java/me/ash/reader/ui/component/CanBeDisabledIconButton.kt @@ -1,4 +1,4 @@ -package me.ash.reader.ui.widget +package me.ash.reader.ui.component import androidx.compose.foundation.layout.size import androidx.compose.material3.Icon diff --git a/app/src/main/java/me/ash/reader/ui/widget/Dialog.kt b/app/src/main/java/me/ash/reader/ui/component/Dialog.kt similarity index 96% rename from app/src/main/java/me/ash/reader/ui/widget/Dialog.kt rename to app/src/main/java/me/ash/reader/ui/component/Dialog.kt index 11e23e7..5d90164 100644 --- a/app/src/main/java/me/ash/reader/ui/widget/Dialog.kt +++ b/app/src/main/java/me/ash/reader/ui/component/Dialog.kt @@ -1,4 +1,4 @@ -package me.ash.reader.ui.widget +package me.ash.reader.ui.component import androidx.compose.material3.AlertDialog import androidx.compose.runtime.Composable diff --git a/app/src/main/java/me/ash/reader/ui/widget/LottieAnimation.kt b/app/src/main/java/me/ash/reader/ui/component/LottieAnimation.kt similarity index 94% rename from app/src/main/java/me/ash/reader/ui/widget/LottieAnimation.kt rename to app/src/main/java/me/ash/reader/ui/component/LottieAnimation.kt index eab95f0..0ef4ed4 100644 --- a/app/src/main/java/me/ash/reader/ui/widget/LottieAnimation.kt +++ b/app/src/main/java/me/ash/reader/ui/component/LottieAnimation.kt @@ -1,4 +1,4 @@ -package me.ash.reader.ui.widget +package me.ash.reader.ui.component import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue diff --git a/app/src/main/java/me/ash/reader/ui/widget/Menu.kt b/app/src/main/java/me/ash/reader/ui/component/Menu.kt similarity index 97% rename from app/src/main/java/me/ash/reader/ui/widget/Menu.kt rename to app/src/main/java/me/ash/reader/ui/component/Menu.kt index 2d69104..984b225 100644 --- a/app/src/main/java/me/ash/reader/ui/widget/Menu.kt +++ b/app/src/main/java/me/ash/reader/ui/component/Menu.kt @@ -1,4 +1,4 @@ -package me.ash.reader.ui.widget +package me.ash.reader.ui.component import androidx.compose.foundation.layout.Box import androidx.compose.material3.DropdownMenu diff --git a/app/src/main/java/me/ash/reader/ui/widget/SelectionChip.kt b/app/src/main/java/me/ash/reader/ui/component/SelectionChip.kt similarity index 98% rename from app/src/main/java/me/ash/reader/ui/widget/SelectionChip.kt rename to app/src/main/java/me/ash/reader/ui/component/SelectionChip.kt index 0959ccc..e77775b 100644 --- a/app/src/main/java/me/ash/reader/ui/widget/SelectionChip.kt +++ b/app/src/main/java/me/ash/reader/ui/component/SelectionChip.kt @@ -1,4 +1,4 @@ -package me.ash.reader.ui.widget +package me.ash.reader.ui.component import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.interaction.MutableInteractionSource @@ -153,7 +153,7 @@ fun SelectionEditorChip( onValueChange = { onValueChange(it) }, cursorBrush = SolidColor(MaterialTheme.colorScheme.onSurfaceVariant), textStyle = MaterialTheme.typography.titleSmall.copy( - color = MaterialTheme.colorScheme.onSurfaceVariant, + color = MaterialTheme.colorScheme.onSurfaceVariant, ), decorationBox = { innerTextField -> Row( diff --git a/app/src/main/java/me/ash/reader/ui/widget/SubTitle.kt b/app/src/main/java/me/ash/reader/ui/component/SubTitle.kt similarity index 95% rename from app/src/main/java/me/ash/reader/ui/widget/SubTitle.kt rename to app/src/main/java/me/ash/reader/ui/component/SubTitle.kt index a78da2f..ec50ae2 100644 --- a/app/src/main/java/me/ash/reader/ui/widget/SubTitle.kt +++ b/app/src/main/java/me/ash/reader/ui/component/SubTitle.kt @@ -1,4 +1,4 @@ -package me.ash.reader.ui.widget +package me.ash.reader.ui.component import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding diff --git a/app/src/main/java/me/ash/reader/ui/widget/ViewPager.kt b/app/src/main/java/me/ash/reader/ui/component/ViewPager.kt similarity index 96% rename from app/src/main/java/me/ash/reader/ui/widget/ViewPager.kt rename to app/src/main/java/me/ash/reader/ui/component/ViewPager.kt index c825a76..4836c07 100644 --- a/app/src/main/java/me/ash/reader/ui/widget/ViewPager.kt +++ b/app/src/main/java/me/ash/reader/ui/component/ViewPager.kt @@ -1,4 +1,4 @@ -package me.ash.reader.ui.widget +package me.ash.reader.ui.component import androidx.compose.animation.animateContentSize import androidx.compose.foundation.layout.fillMaxWidth diff --git a/app/src/main/java/me/ash/reader/ui/widget/WebView.kt b/app/src/main/java/me/ash/reader/ui/component/WebView.kt similarity index 52% rename from app/src/main/java/me/ash/reader/ui/widget/WebView.kt rename to app/src/main/java/me/ash/reader/ui/component/WebView.kt index a694ebb..33cebdd 100644 --- a/app/src/main/java/me/ash/reader/ui/widget/WebView.kt +++ b/app/src/main/java/me/ash/reader/ui/component/WebView.kt @@ -1,4 +1,4 @@ -package me.ash.reader.ui.widget +package me.ash.reader.ui.component import android.content.Intent import android.graphics.Bitmap @@ -8,6 +8,9 @@ import android.util.Log import android.webkit.* import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext @@ -29,80 +32,94 @@ fun WebView( val context = LocalContext.current val color = MaterialTheme.colorScheme.onSurfaceVariant.toArgb() val backgroundColor = MaterialTheme.colorScheme.surface.toArgb() - val webViewClient = object : WebViewClient() { + val webViewClient by remember { + mutableStateOf(object : WebViewClient() { - override fun shouldInterceptRequest(view: WebView?, url: String?): WebResourceResponse? { - if (url != null && url.contains(INJECTION_TOKEN)) { - try { - val assetPath = url.substring( - url.indexOf(INJECTION_TOKEN) + INJECTION_TOKEN.length, - url.length - ) - return WebResourceResponse( - "text/HTML", - "UTF-8", - context.assets.open(assetPath) - ) - } catch (e: Exception) { - Log.e("RLog", "WebView shouldInterceptRequest: $e") + override fun shouldInterceptRequest( + view: WebView?, + url: String? + ): WebResourceResponse? { + if (url != null && url.contains(INJECTION_TOKEN)) { + try { + val assetPath = url.substring( + url.indexOf(INJECTION_TOKEN) + INJECTION_TOKEN.length, + url.length + ) + return WebResourceResponse( + "text/HTML", + "UTF-8", + context.assets.open(assetPath) + ) + } catch (e: Exception) { + Log.e("RLog", "WebView shouldInterceptRequest: $e") + } } + return super.shouldInterceptRequest(view, url); } - return super.shouldInterceptRequest(view, url); - } - override fun onPageStarted( - view: WebView?, - url: String?, - favicon: Bitmap? - ) { - super.onPageStarted(view, url, favicon) + override fun onPageStarted( + view: WebView?, + url: String?, + favicon: Bitmap? + ) { + super.onPageStarted(view, url, favicon) // _isLoading = true - onProgressChange(-1) - } + onProgressChange(-1) + } - override fun onPageFinished(view: WebView?, url: String?) { - super.onPageFinished(view, url) - val jsCode = "javascript:(function(){" + - "var imgs=document.getElementsByTagName(\"img\");" + - "for(var i=0;i StateFlow.collectAsStateValue( + context: CoroutineContext = Dispatchers.Default +): T = collectAsState(context).value \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/StringExt.kt b/app/src/main/java/me/ash/reader/ui/ext/StringExt.kt similarity index 93% rename from app/src/main/java/me/ash/reader/StringExt.kt rename to app/src/main/java/me/ash/reader/ui/ext/StringExt.kt index 9a67a60..eb8aa3e 100644 --- a/app/src/main/java/me/ash/reader/StringExt.kt +++ b/app/src/main/java/me/ash/reader/ui/ext/StringExt.kt @@ -1,4 +1,4 @@ -package me.ash.reader +package me.ash.reader.ui.ext fun String.formatUrl(): String { if (this.startsWith("//")) { diff --git a/app/src/main/java/me/ash/reader/ui/extension/StateFlowExt.kt b/app/src/main/java/me/ash/reader/ui/extension/StateFlowExt.kt deleted file mode 100644 index 7708bc7..0000000 --- a/app/src/main/java/me/ash/reader/ui/extension/StateFlowExt.kt +++ /dev/null @@ -1,23 +0,0 @@ -package me.ash.reader.ui.extension - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.State -import androidx.compose.runtime.collectAsState -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.StateFlow -import kotlin.coroutines.CoroutineContext -import kotlin.reflect.KProperty - -@Composable -fun StateFlow.collectAsStateValue( - context: CoroutineContext = Dispatchers.Default -): T = collectAsState(context).value - -@Suppress("NOTHING_TO_INLINE") -inline operator fun State.getValue(thisObj: Any?, property: KProperty<*>): T = value - -@Suppress("NOTHING_TO_INLINE") -inline operator fun MutableState.setValue(thisObj: Any?, property: KProperty<*>, value: T) { - this.value = value -} \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/ui/page/home/FilterBar.kt b/app/src/main/java/me/ash/reader/ui/page/home/FilterBar.kt index 13ceb10..ffe62a4 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/FilterBar.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/FilterBar.kt @@ -7,8 +7,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import com.google.accompanist.pager.ExperimentalPagerApi -import me.ash.reader.data.constant.Filter -import me.ash.reader.ui.extension.getName +import me.ash.reader.data.entity.Filter +import me.ash.reader.ui.ext.getName @OptIn(ExperimentalPagerApi::class) @Composable @@ -21,7 +21,10 @@ fun FilterBar( modifier = Modifier.height(60.dp) ) { Divider( - modifier = Modifier.fillMaxWidth().height(1.dp).zIndex(1f), + modifier = Modifier + .fillMaxWidth() + .height(1.dp) + .zIndex(1f), color = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.24f) ) NavigationBar( diff --git a/app/src/main/java/me/ash/reader/ui/page/home/HomePage.kt b/app/src/main/java/me/ash/reader/ui/page/home/HomePage.kt index e2c8546..d0c75c8 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/HomePage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/HomePage.kt @@ -10,8 +10,9 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController import com.google.accompanist.pager.ExperimentalPagerApi import kotlinx.coroutines.launch -import me.ash.reader.ui.extension.collectAsStateValue -import me.ash.reader.ui.extension.findActivity +import me.ash.reader.ui.component.ViewPager +import me.ash.reader.ui.ext.collectAsStateValue +import me.ash.reader.ui.ext.findActivity import me.ash.reader.ui.page.common.ExtraName import me.ash.reader.ui.page.home.drawer.feed.FeedOptionDrawer import me.ash.reader.ui.page.home.drawer.feed.FeedOptionViewAction @@ -21,7 +22,6 @@ import me.ash.reader.ui.page.home.flow.FlowPage import me.ash.reader.ui.page.home.read.ReadPage import me.ash.reader.ui.page.home.read.ReadViewAction import me.ash.reader.ui.page.home.read.ReadViewModel -import me.ash.reader.ui.widget.ViewPager @OptIn(ExperimentalPagerApi::class, androidx.compose.material.ExperimentalMaterialApi::class) @Composable diff --git a/app/src/main/java/me/ash/reader/ui/page/home/HomeViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/HomeViewModel.kt index 4ce0512..9af62bc 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/HomeViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/HomeViewModel.kt @@ -9,12 +9,12 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update -import me.ash.reader.data.constant.Filter -import me.ash.reader.data.feed.Feed -import me.ash.reader.data.group.Group +import me.ash.reader.data.entity.Feed +import me.ash.reader.data.entity.Filter +import me.ash.reader.data.entity.Group import me.ash.reader.data.repository.AbstractRssRepository import me.ash.reader.data.repository.RssRepository -import me.ash.reader.ui.extension.animateScrollToPage +import me.ash.reader.ui.ext.animateScrollToPage import javax.inject.Inject @OptIn(ExperimentalPagerApi::class) diff --git a/app/src/main/java/me/ash/reader/ui/page/home/drawer/feed/DeleteFeedDialog.kt b/app/src/main/java/me/ash/reader/ui/page/home/drawer/feed/DeleteFeedDialog.kt index 51e1985..c0c2803 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/drawer/feed/DeleteFeedDialog.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/drawer/feed/DeleteFeedDialog.kt @@ -14,8 +14,8 @@ import androidx.compose.ui.res.stringResource import androidx.hilt.navigation.compose.hiltViewModel import com.google.accompanist.pager.ExperimentalPagerApi import me.ash.reader.R -import me.ash.reader.ui.extension.collectAsStateValue -import me.ash.reader.ui.widget.Dialog +import me.ash.reader.ui.component.Dialog +import me.ash.reader.ui.ext.collectAsStateValue @OptIn(ExperimentalPagerApi::class) @Composable diff --git a/app/src/main/java/me/ash/reader/ui/page/home/drawer/feed/FeedOptionDrawer.kt b/app/src/main/java/me/ash/reader/ui/page/home/drawer/feed/FeedOptionDrawer.kt index 214bf61..7485742 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/drawer/feed/FeedOptionDrawer.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/drawer/feed/FeedOptionDrawer.kt @@ -17,11 +17,11 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import me.ash.reader.R -import me.ash.reader.ui.extension.collectAsStateValue -import me.ash.reader.ui.extension.roundClick +import me.ash.reader.ui.component.BottomDrawer +import me.ash.reader.ui.component.Subtitle +import me.ash.reader.ui.ext.collectAsStateValue +import me.ash.reader.ui.ext.roundClick import me.ash.reader.ui.page.home.feeds.subscribe.ResultViewPage -import me.ash.reader.ui.widget.BottomDrawer -import me.ash.reader.ui.widget.Subtitle @OptIn(ExperimentalMaterialApi::class) @Composable diff --git a/app/src/main/java/me/ash/reader/ui/page/home/drawer/feed/FeedOptionViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/drawer/feed/FeedOptionViewModel.kt index 2d48eb1..40ea545 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/drawer/feed/FeedOptionViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/drawer/feed/FeedOptionViewModel.kt @@ -15,8 +15,8 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import me.ash.reader.data.feed.Feed -import me.ash.reader.data.group.Group +import me.ash.reader.data.entity.Feed +import me.ash.reader.data.entity.Group import me.ash.reader.data.repository.RssRepository import javax.inject.Inject diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedItem.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedItem.kt index c489c70..7270d36 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedItem.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedItem.kt @@ -18,7 +18,7 @@ import androidx.compose.ui.platform.LocalView import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel -import me.ash.reader.data.feed.Feed +import me.ash.reader.data.entity.Feed import me.ash.reader.ui.page.home.drawer.feed.FeedOptionViewAction import me.ash.reader.ui.page.home.drawer.feed.FeedOptionViewModel diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsPage.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsPage.kt index b6c6e79..1ab0017 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsPage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsPage.kt @@ -28,16 +28,16 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController import me.ash.reader.R import me.ash.reader.data.repository.AbstractRssRepository -import me.ash.reader.ui.extension.collectAsStateValue -import me.ash.reader.ui.extension.getDesc -import me.ash.reader.ui.extension.getName +import me.ash.reader.ui.component.Banner +import me.ash.reader.ui.component.Subtitle +import me.ash.reader.ui.ext.collectAsStateValue +import me.ash.reader.ui.ext.getDesc +import me.ash.reader.ui.ext.getName import me.ash.reader.ui.page.home.FilterBar import me.ash.reader.ui.page.home.FilterState import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeDialog import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewAction import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewModel -import me.ash.reader.ui.widget.Banner -import me.ash.reader.ui.widget.Subtitle @OptIn( ExperimentalMaterial3Api::class, com.google.accompanist.pager.ExperimentalPagerApi::class, diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsViewModel.kt index c44f641..0b81c58 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsViewModel.kt @@ -8,9 +8,9 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch -import me.ash.reader.data.account.Account -import me.ash.reader.data.constant.Filter -import me.ash.reader.data.group.GroupWithFeed +import me.ash.reader.data.entity.Account +import me.ash.reader.data.entity.Filter +import me.ash.reader.data.entity.GroupWithFeed import me.ash.reader.data.repository.AccountRepository import me.ash.reader.data.repository.OpmlRepository import me.ash.reader.data.repository.RssRepository diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/GroupItem.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/GroupItem.kt index d268327..25e852a 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/GroupItem.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/GroupItem.kt @@ -22,7 +22,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import me.ash.reader.R -import me.ash.reader.data.feed.Feed +import me.ash.reader.data.entity.Feed @OptIn(ExperimentalMaterialApi::class, androidx.compose.foundation.ExperimentalFoundationApi::class) @Composable @@ -57,7 +57,9 @@ fun GroupItem( verticalAlignment = Alignment.CenterVertically, ) { Text( - modifier = Modifier.weight(1f).padding(start = 28.dp), + modifier = Modifier + .weight(1f) + .padding(start = 28.dp), text = text, style = MaterialTheme.typography.titleMedium, color = MaterialTheme.colorScheme.onSecondaryContainer, diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/ResultViewPage.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/ResultViewPage.kt index 8b7367d..990d2f1 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/ResultViewPage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/ResultViewPage.kt @@ -22,11 +22,11 @@ import androidx.compose.ui.unit.dp import com.google.accompanist.flowlayout.FlowRow import com.google.accompanist.flowlayout.MainAxisAlignment import me.ash.reader.R -import me.ash.reader.data.group.Group -import me.ash.reader.ui.extension.roundClick -import me.ash.reader.ui.widget.SelectionChip -import me.ash.reader.ui.widget.SelectionEditorChip -import me.ash.reader.ui.widget.Subtitle +import me.ash.reader.data.entity.Group +import me.ash.reader.ui.component.SelectionChip +import me.ash.reader.ui.component.SelectionEditorChip +import me.ash.reader.ui.component.Subtitle +import me.ash.reader.ui.ext.roundClick @Composable fun ResultViewPage( diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeDialog.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeDialog.kt index ea057be..00a3990 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeDialog.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeDialog.kt @@ -21,10 +21,9 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.window.DialogProperties import androidx.hilt.navigation.compose.hiltViewModel import com.google.accompanist.pager.ExperimentalPagerApi -import me.ash.reader.* import me.ash.reader.R -import me.ash.reader.ui.extension.collectAsStateValue -import me.ash.reader.ui.widget.Dialog +import me.ash.reader.ui.component.Dialog +import me.ash.reader.ui.ext.* @OptIn(ExperimentalPagerApi::class, androidx.compose.ui.ExperimentalComposeUiApi::class) @Composable diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewModel.kt index 6eb33de..28504b8 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewModel.kt @@ -9,15 +9,15 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import me.ash.reader.R -import me.ash.reader.data.article.Article -import me.ash.reader.data.feed.Feed -import me.ash.reader.data.group.Group +import me.ash.reader.data.entity.Article +import me.ash.reader.data.entity.Feed +import me.ash.reader.data.entity.Group import me.ash.reader.data.repository.OpmlRepository import me.ash.reader.data.repository.RssHelper import me.ash.reader.data.repository.RssRepository import me.ash.reader.data.repository.StringsRepository -import me.ash.reader.formatUrl -import me.ash.reader.ui.extension.animateScrollToPage +import me.ash.reader.ui.ext.animateScrollToPage +import me.ash.reader.ui.ext.formatUrl import java.io.InputStream import javax.inject.Inject diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewPager.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewPager.kt index d4562c6..dc277ba 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewPager.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewPager.kt @@ -6,8 +6,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalFocusManager import com.google.accompanist.pager.ExperimentalPagerApi -import me.ash.reader.data.group.Group -import me.ash.reader.ui.widget.ViewPager +import me.ash.reader.data.entity.Group +import me.ash.reader.ui.component.ViewPager @OptIn(ExperimentalPagerApi::class) @Composable diff --git a/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleItem.kt b/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleItem.kt index cf442fc..a5ef4b7 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleItem.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleItem.kt @@ -15,8 +15,8 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import me.ash.reader.data.article.ArticleWithFeed -import me.ash.reader.formatToString +import me.ash.reader.data.entity.ArticleWithFeed +import me.ash.reader.ui.ext.formatAsString @Composable fun ArticleItem( @@ -40,7 +40,9 @@ fun ArticleItem( verticalAlignment = Alignment.CenterVertically, ) { Text( - modifier = Modifier.weight(1f).padding(start = 30.dp), + modifier = Modifier + .weight(1f) + .padding(start = 30.dp), text = articleWithFeed.feed.name, color = MaterialTheme.colorScheme.tertiary, style = MaterialTheme.typography.labelMedium, @@ -49,7 +51,7 @@ fun ArticleItem( ) Text( modifier = Modifier.padding(start = 6.dp), - text = articleWithFeed.article.date.formatToString(context, onlyHourMinute = true), + text = articleWithFeed.article.date.formatAsString(context, onlyHourMinute = true), color = MaterialTheme.colorScheme.outline.copy(alpha = 0.7f), style = MaterialTheme.typography.labelMedium, ) diff --git a/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleList.kt b/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleList.kt index 8831acf..1b33079 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleList.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/flow/ArticleList.kt @@ -8,8 +8,8 @@ import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.paging.compose.LazyPagingItems -import me.ash.reader.data.article.ArticleWithFeed -import me.ash.reader.formatToString +import me.ash.reader.data.entity.ArticleWithFeed +import me.ash.reader.ui.ext.formatAsString @OptIn(ExperimentalFoundationApi::class) fun LazyListScope.generateArticleList( @@ -20,7 +20,7 @@ fun LazyListScope.generateArticleList( var lastItemDay: String? = null for (itemIndex in 0 until pagingItems.itemCount) { val currentItem = pagingItems.peek(itemIndex) ?: continue - val currentItemDay = currentItem.article.date.formatToString(context) + val currentItemDay = currentItem.article.date.formatAsString(context) if (lastItemDay != currentItemDay) { if (itemIndex != 0) { item { Spacer(modifier = Modifier.height(40.dp)) } diff --git a/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt b/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt index bd82921..317b077 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowPage.kt @@ -24,9 +24,9 @@ import androidx.paging.LoadState import androidx.paging.compose.collectAsLazyPagingItems import kotlinx.coroutines.launch import me.ash.reader.R -import me.ash.reader.data.article.ArticleWithFeed -import me.ash.reader.ui.extension.collectAsStateValue -import me.ash.reader.ui.extension.getName +import me.ash.reader.data.entity.ArticleWithFeed +import me.ash.reader.ui.ext.collectAsStateValue +import me.ash.reader.ui.ext.getName import me.ash.reader.ui.page.home.FilterBar import me.ash.reader.ui.page.home.FilterState diff --git a/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowViewModel.kt index bf32807..a41f8bd 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/flow/FlowViewModel.kt @@ -11,7 +11,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch -import me.ash.reader.data.article.ArticleWithFeed +import me.ash.reader.data.entity.ArticleWithFeed import me.ash.reader.data.repository.RssRepository import me.ash.reader.ui.page.home.FilterState import javax.inject.Inject diff --git a/app/src/main/java/me/ash/reader/ui/page/home/read/Header.kt b/app/src/main/java/me/ash/reader/ui/page/home/read/Header.kt index fee1897..6a92cd7 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/read/Header.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/read/Header.kt @@ -9,9 +9,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp -import me.ash.reader.data.article.ArticleWithFeed -import me.ash.reader.formatToString -import me.ash.reader.ui.extension.roundClick +import me.ash.reader.data.entity.ArticleWithFeed +import me.ash.reader.ui.ext.formatAsString +import me.ash.reader.ui.ext.roundClick @Composable fun Header( @@ -30,7 +30,7 @@ fun Header( .padding(12.dp) ) { Text( - text = articleWithFeed.article.date.formatToString(context, atHourMinute = true), + text = articleWithFeed.article.date.formatAsString(context, atHourMinute = true), color = MaterialTheme.colorScheme.outline.copy(alpha = 0.7f), style = MaterialTheme.typography.labelMedium, ) diff --git a/app/src/main/java/me/ash/reader/ui/page/home/read/ReadBar.kt b/app/src/main/java/me/ash/reader/ui/page/home/read/ReadBar.kt index 3424eda..57de11d 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/read/ReadBar.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/read/ReadBar.kt @@ -22,7 +22,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import me.ash.reader.R -import me.ash.reader.ui.widget.CanBeDisabledIconButton +import me.ash.reader.ui.component.CanBeDisabledIconButton @Composable fun ReadBar( diff --git a/app/src/main/java/me/ash/reader/ui/page/home/read/ReadPage.kt b/app/src/main/java/me/ash/reader/ui/page/home/read/ReadPage.kt index 98d6a78..8caa2ea 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/read/ReadPage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/read/ReadPage.kt @@ -21,9 +21,9 @@ import androidx.compose.ui.zIndex import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController import me.ash.reader.R -import me.ash.reader.data.article.ArticleWithFeed -import me.ash.reader.ui.extension.collectAsStateValue -import me.ash.reader.ui.widget.WebView +import me.ash.reader.data.entity.ArticleWithFeed +import me.ash.reader.ui.component.WebView +import me.ash.reader.ui.ext.collectAsStateValue @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/app/src/main/java/me/ash/reader/ui/page/home/read/ReadViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/read/ReadViewModel.kt index 13a5b28..a949705 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/read/ReadViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/read/ReadViewModel.kt @@ -11,7 +11,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import me.ash.reader.data.article.ArticleWithFeed +import me.ash.reader.data.entity.ArticleWithFeed import me.ash.reader.data.repository.RssHelper import me.ash.reader.data.repository.RssRepository import javax.inject.Inject diff --git a/app/src/main/java/me/ash/reader/ui/page/settings/SettingsPage.kt b/app/src/main/java/me/ash/reader/ui/page/settings/SettingsPage.kt index 0da50b3..5e42dc4 100644 --- a/app/src/main/java/me/ash/reader/ui/page/settings/SettingsPage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/settings/SettingsPage.kt @@ -11,7 +11,6 @@ import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -20,9 +19,8 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavHostController import me.ash.reader.R -import me.ash.reader.ui.extension.paddingFixedHorizontal -import me.ash.reader.ui.extension.roundClick -import me.ash.reader.ui.widget.TopTitleBox +import me.ash.reader.ui.ext.paddingFixedHorizontal +import me.ash.reader.ui.ext.roundClick @Composable fun SettingsPage( @@ -33,17 +31,6 @@ fun SettingsPage( // LargeTopAppBar( // title = { Text(text = "Settings") } // ) - TopTitleBox( - title = "Settings", - description = "", - listState = listState, - startOffset = Offset(20f, 78f), - startHeight = 72f, - startTitleFontSize = 36f, - startDescriptionFontSize = 0f, - ) { - - } Column { SmallTopAppBar( title = {}, diff --git a/app/src/main/java/me/ash/reader/ui/widget/AnimateLazyColumn.kt b/app/src/main/java/me/ash/reader/ui/widget/AnimateLazyColumn.kt deleted file mode 100644 index 819b9fa..0000000 --- a/app/src/main/java/me/ash/reader/ui/widget/AnimateLazyColumn.kt +++ /dev/null @@ -1,41 +0,0 @@ -package me.ash.reader.ui.widget - -import android.util.Log -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.expandVertically -import androidx.compose.animation.fadeIn -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier - -@Composable -fun AnimateLazyColumn( - modifier: Modifier = Modifier, - state: LazyListState = rememberLazyListState(), - reference: Any?, - content: LazyListScope.() -> Unit, -) { - var visible by remember { mutableStateOf(true) } - LaunchedEffect(reference) { - Log.i("RLog", "reference change") - visible = false -// delay(50) - visible = true - } - - AnimatedVisibility( - modifier = modifier.fillMaxSize(), - visible = visible, - enter = fadeIn() + expandVertically(), - ) { - LazyColumn( - modifier = modifier, - state = state, - content = content, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/ui/widget/AnimatedItemsIndexed.kt b/app/src/main/java/me/ash/reader/ui/widget/AnimatedItemsIndexed.kt deleted file mode 100644 index a34a3c6..0000000 --- a/app/src/main/java/me/ash/reader/ui/widget/AnimatedItemsIndexed.kt +++ /dev/null @@ -1,134 +0,0 @@ -import android.annotation.SuppressLint -import androidx.compose.animation.* -import androidx.compose.animation.core.Animatable -import androidx.compose.animation.core.MutableTransitionState -import androidx.compose.foundation.lazy.LazyItemScope -import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.runtime.* -import androidx.recyclerview.widget.DiffUtil -import androidx.recyclerview.widget.ListUpdateCallback -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext - -@Suppress("UpdateTransitionLabel", "TransitionPropertiesLabel") -@SuppressLint("ComposableNaming", "UnusedTransitionTargetStateParameter") -/** - * @param state Use [updateAnimatedItemsState]. - */ -inline fun LazyListScope.animatedItemsIndexed( - state: List>, - enterTransition: EnterTransition = expandVertically(), - exitTransition: ExitTransition = shrinkVertically(), - noinline key: ((item: T) -> Any)? = null, - crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit -) { - items( - state.size, - if (key != null) { keyIndex: Int -> key(state[keyIndex].item) } else null - ) { index -> - - val item = state[index] - val visibility = item.visibility - - key(key?.invoke(item.item)) { - AnimatedVisibility( - visibleState = visibility, - enter = enterTransition, - exit = exitTransition - ) { - itemContent(index, item.item) - } - } - } -} - -@Composable -fun updateAnimatedItemsState( - newList: List -): State>> { - - val state = remember { mutableStateOf(emptyList>()) } - LaunchedEffect(newList) { - if (state.value == newList) { - return@LaunchedEffect - } - val oldList = state.value.toList() - - val diffCb = object : DiffUtil.Callback() { - override fun getOldListSize(): Int = oldList.size - override fun getNewListSize(): Int = newList.size - override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean = - oldList[oldItemPosition].item == newList[newItemPosition] - - override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean = - oldList[oldItemPosition].item == newList[newItemPosition] - } - val diffResult = calculateDiff(false, diffCb) - val compositeList = oldList.toMutableList() - - diffResult.dispatchUpdatesTo(object : ListUpdateCallback { - override fun onInserted(position: Int, count: Int) { - for (i in 0 until count) { - val newItem = AnimatedItem( - visibility = MutableTransitionState(false), - newList[position + i] - ) - newItem.visibility.targetState = true - compositeList.add(position + i, newItem) - } - } - - override fun onRemoved(position: Int, count: Int) { - for (i in 0 until count) { - compositeList[position + i].visibility.targetState = false - } - } - - override fun onMoved(fromPosition: Int, toPosition: Int) { - // not detecting moves. - } - - override fun onChanged(position: Int, count: Int, payload: Any?) { - // irrelevant with compose. - } - }) - if (state.value != compositeList) { - state.value = compositeList - } - val initialAnimation = Animatable(1.0f) - initialAnimation.animateTo(0f) - state.value = state.value.filter { it.visibility.targetState } - } - - return state -} - -data class AnimatedItem( - val visibility: MutableTransitionState, - val item: T, -) { - - override fun hashCode(): Int { - return item?.hashCode() ?: 0 - } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as AnimatedItem<*> - - if (item != other.item) return false - - return true - } -} - -suspend fun calculateDiff( - detectMoves: Boolean = true, - diffCb: DiffUtil.Callback -): DiffUtil.DiffResult { - return withContext(Dispatchers.Unconfined) { - DiffUtil.calculateDiff(diffCb, detectMoves) - } -} diff --git a/app/src/main/java/me/ash/reader/ui/widget/CustomPager.kt b/app/src/main/java/me/ash/reader/ui/widget/CustomPager.kt deleted file mode 100644 index 6e6b641..0000000 --- a/app/src/main/java/me/ash/reader/ui/widget/CustomPager.kt +++ /dev/null @@ -1,305 +0,0 @@ -package me.ash.reader.ui.widget - -import androidx.compose.animation.core.Animatable -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.SpringSpec -import androidx.compose.animation.core.calculateTargetValue -import androidx.compose.animation.splineBasedDecay -import androidx.compose.foundation.gestures.* -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clipToBounds -import androidx.compose.ui.input.pointer.PointerInputChange -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.input.pointer.positionChange -import androidx.compose.ui.input.pointer.util.VelocityTracker -import androidx.compose.ui.layout.Layout -import androidx.compose.ui.layout.Placeable -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.unit.Constraints -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.dp -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch -import kotlin.math.absoluteValue -import kotlin.math.ceil -import kotlin.math.roundToInt -import kotlin.math.sign - -//val items = listOf( -// Color.Red, -// Color.Blue, -// Color.Green, -// Color.Yellow, -// Color.Cyan, -// Color.Magenta, -//) - -@Composable -fun CustomPager( - items: List, - modifier: Modifier = Modifier, - orientation: Orientation = Orientation.Horizontal, - initialIndex: Int = 0, - /*@FloatRange(from = 0.0, to = 1.0)*/ - itemFraction: Float = 1f, - itemSpacing: Dp = 0.dp, - /*@FloatRange(from = 0.0, to = 1.0)*/ - overshootFraction: Float = .5f, - onItemSelect: (T) -> Unit = {}, - contentFactory: @Composable (T) -> Unit, -) { - Pager( - items, - modifier, - orientation, - initialIndex, - itemFraction, - itemSpacing, - overshootFraction, - onItemSelect = { index -> onItemSelect(items[index]) }, - ) { - items.forEach { item -> - Box( - modifier = when (orientation) { - Orientation.Horizontal -> Modifier.fillMaxWidth() - Orientation.Vertical -> Modifier.fillMaxHeight() - }, - contentAlignment = Alignment.Center, - ) { - contentFactory(item) - } - } - } -} - -@Composable -fun Pager( - items: List, - modifier: Modifier = Modifier, - orientation: Orientation = Orientation.Horizontal, - initialIndex: Int = 0, - /*@FloatRange(from = 0.0, to = 1.0)*/ - itemFraction: Float = 1f, - itemSpacing: Dp = 0.dp, - /*@FloatRange(from = 0.0, to = 1.0)*/ - overshootFraction: Float = .5f, - onItemSelect: (Int) -> Unit = {}, - content: @Composable () -> Unit, -) { - require(initialIndex in 0..items.lastIndex) { "Initial index out of bounds" } - require(itemFraction > 0f && itemFraction <= 1f) { "Item fraction must be in the (0f, 1f] range" } - require(overshootFraction > 0f && itemFraction <= 1f) { "Overshoot fraction must be in the (0f, 1f] range" } - val scope = rememberCoroutineScope() - val state = rememberPagerState() - state.currentIndex = initialIndex - state.numberOfItems = items.size - state.itemFraction = itemFraction - state.overshootFraction = overshootFraction - state.itemSpacing = with(LocalDensity.current) { itemSpacing.toPx() } - state.orientation = orientation - state.listener = onItemSelect - state.scope = scope - - Layout( - content = content, - modifier = modifier - .clipToBounds() - .then(state.inputModifier), - ) { measurables, constraints -> - val dimension = constraints.dimension(orientation) - val looseConstraints = constraints.toLooseConstraints(orientation, state.itemFraction) - val placeables = measurables.map { measurable -> measurable.measure(looseConstraints) } - val size = placeables.getSize(orientation, dimension) - val itemDimension = (dimension * state.itemFraction).roundToInt() - state.itemDimension = itemDimension - val halfItemDimension = itemDimension / 2 - layout(size.width, size.height) { - val centerOffset = dimension / 2 - halfItemDimension - val dragOffset = state.dragOffset.value - val roundedDragOffset = dragOffset.roundToInt() - val spacing = state.itemSpacing.roundToInt() - val itemDimensionWithSpace = itemDimension + state.itemSpacing - val first = ceil( - (dragOffset - itemDimension - centerOffset) / itemDimensionWithSpace - ).toInt().coerceAtLeast(0) - val last = ((dimension + dragOffset - centerOffset) / itemDimensionWithSpace).toInt() - .coerceAtMost(items.lastIndex) - for (i in first..last) { - val offset = i * (itemDimension + spacing) - roundedDragOffset + centerOffset - placeables[i].place( - x = when (orientation) { - Orientation.Horizontal -> offset - Orientation.Vertical -> 0 - }, - y = when (orientation) { - Orientation.Horizontal -> 0 - Orientation.Vertical -> offset - } - ) - } - } - } - - LaunchedEffect(key1 = items, key2 = initialIndex) { - state.snapTo(initialIndex) - } -} - -@Composable -private fun rememberPagerState(): PagerState = remember { PagerState() } - -private fun Constraints.dimension(orientation: Orientation) = when (orientation) { - Orientation.Horizontal -> maxWidth - Orientation.Vertical -> maxHeight -} - -private fun Constraints.toLooseConstraints( - orientation: Orientation, - itemFraction: Float, -): Constraints { - val dimension = dimension(orientation) - return when (orientation) { - Orientation.Horizontal -> copy( - minWidth = (dimension * itemFraction).roundToInt(), - maxWidth = (dimension * itemFraction).roundToInt(), - minHeight = 0, - ) - Orientation.Vertical -> copy( - minWidth = 0, - minHeight = (dimension * itemFraction).roundToInt(), - maxHeight = (dimension * itemFraction).roundToInt(), - ) - } -} - -private fun List.getSize( - orientation: Orientation, - dimension: Int, -): IntSize { - return when (orientation) { - Orientation.Horizontal -> IntSize( - dimension, - maxByOrNull { it.height }?.height ?: 0 - ) - Orientation.Vertical -> IntSize( - maxByOrNull { it.width }?.width ?: 0, - dimension - ) - } -} - -private class PagerState { - var currentIndex by mutableStateOf(0) - var numberOfItems by mutableStateOf(0) - var itemFraction by mutableStateOf(0f) - var overshootFraction by mutableStateOf(0f) - var itemSpacing by mutableStateOf(0f) - var itemDimension by mutableStateOf(0) - var orientation by mutableStateOf(Orientation.Horizontal) - var scope: CoroutineScope? by mutableStateOf(null) - var listener: (Int) -> Unit by mutableStateOf({}) - val dragOffset = Animatable(0f) - - private val animationSpec = SpringSpec( - dampingRatio = Spring.DampingRatioLowBouncy, - stiffness = Spring.StiffnessLow, - ) - - suspend fun snapTo(index: Int) { - dragOffset.snapTo(index.toFloat() * (itemDimension + itemSpacing)) - } - - val inputModifier = Modifier.pointerInput(numberOfItems) { - fun itemIndex(offset: Int): Int = (offset / (itemDimension + itemSpacing)).roundToInt() - .coerceIn(0, numberOfItems - 1) - - fun updateIndex(offset: Float) { - val index = itemIndex(offset.roundToInt()) - if (index != currentIndex) { - currentIndex = index - listener(index) - } - } - - fun calculateOffsetLimit(): OffsetLimit { - val dimension = when (orientation) { - Orientation.Horizontal -> size.width - Orientation.Vertical -> size.height - } - val itemSideMargin = (dimension - itemDimension) / 2f - return OffsetLimit( - min = -dimension * overshootFraction + itemSideMargin, - max = numberOfItems * (itemDimension + itemSpacing) - (1f - overshootFraction) * dimension + itemSideMargin, - ) - } - - forEachGesture { - awaitPointerEventScope { - val tracker = VelocityTracker() - val decay = splineBasedDecay(this) - val down = awaitFirstDown() - val offsetLimit = calculateOffsetLimit() - val dragHandler = { change: PointerInputChange -> - scope?.launch { - val dragChange = change.calculateDragChange(orientation) - dragOffset.snapTo( - (dragOffset.value - dragChange).coerceIn( - offsetLimit.min, - offsetLimit.max - ) - ) - updateIndex(dragOffset.value) - } - tracker.addPosition(change.uptimeMillis, change.position) - } - when (orientation) { - Orientation.Horizontal -> horizontalDrag(down.id, dragHandler) - Orientation.Vertical -> verticalDrag(down.id, dragHandler) - } - val velocity = tracker.calculateVelocity(orientation) - scope?.launch { - var targetOffset = decay.calculateTargetValue(dragOffset.value, -velocity) - val remainder = targetOffset.toInt().absoluteValue % itemDimension - val extra = if (remainder > itemDimension / 2f) 1 else 0 - val lastVisibleIndex = - (targetOffset.absoluteValue / itemDimension.toFloat()).toInt() + extra - targetOffset = - (lastVisibleIndex * (itemDimension + itemSpacing) * targetOffset.sign) - .coerceIn( - 0f, - (numberOfItems - 1).toFloat() * (itemDimension + itemSpacing) - ) - dragOffset.animateTo( - animationSpec = animationSpec, - targetValue = targetOffset, - initialVelocity = -velocity - ) { - updateIndex(value) - } - } - } - } - } - - data class OffsetLimit( - val min: Float, - val max: Float, - ) -} - -private fun VelocityTracker.calculateVelocity(orientation: Orientation) = when (orientation) { - Orientation.Horizontal -> calculateVelocity().x - Orientation.Vertical -> calculateVelocity().y -} - -private fun PointerInputChange.calculateDragChange(orientation: Orientation) = - when (orientation) { - Orientation.Horizontal -> positionChange().x - Orientation.Vertical -> positionChange().y - } \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/ui/widget/MaskBox.kt b/app/src/main/java/me/ash/reader/ui/widget/MaskBox.kt deleted file mode 100644 index 4e38a32..0000000 --- a/app/src/main/java/me/ash/reader/ui/widget/MaskBox.kt +++ /dev/null @@ -1,58 +0,0 @@ -package me.ash.reader.ui.widget - -import androidx.compose.animation.core.animateFloat -import androidx.compose.animation.core.spring -import androidx.compose.animation.core.updateTransition -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.BoxScope -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import com.google.accompanist.pager.ExperimentalPagerApi -import com.google.accompanist.pager.PagerState -import kotlin.math.absoluteValue - -@OptIn(ExperimentalPagerApi::class) -@Composable -fun BoxScope.MaskBox( - modifier: Modifier = Modifier, - pagerState: PagerState, - currentPage: Int = 0, -) { - val transition = updateTransition(targetState = pagerState, label = "") - val maskAlpha by transition.animateFloat( - label = "", - transitionSpec = { - spring() - } - ) { - when { - it.targetPage == currentPage -> { - if (it.currentPage > currentPage) { - 1f - it.currentPageOffset.absoluteValue - } else { - 0f - } - } - it.targetPage > currentPage -> { - it.currentPageOffset.absoluteValue - } - else -> 0f - } - } - - Box( - modifier - .alpha(maskAlpha) - ) { - Box( - modifier = modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.surfaceVariant) - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/ui/widget/TopTitleBox.kt b/app/src/main/java/me/ash/reader/ui/widget/TopTitleBox.kt deleted file mode 100644 index f9a73f5..0000000 --- a/app/src/main/java/me/ash/reader/ui/widget/TopTitleBox.kt +++ /dev/null @@ -1,97 +0,0 @@ -package me.ash.reader.ui.widget - -import androidx.compose.animation.core.* -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.zIndex -import me.ash.reader.ui.extension.calculateTopBarAnimateValue - -@Composable -fun BoxScope.TopTitleBox( - title: String, - description: String, - listState: LazyListState, - SpacerHeight: Float = Float.NaN, - startOffset: Offset, - startHeight: Float, - startTitleFontSize: Float, - startDescriptionFontSize: Float, - clickable: () -> Unit = {}, -) { - val transition = updateTransition(targetState = listState, label = "") - val offset by transition.animateOffset( - label = "", - transitionSpec = { spring() } - ) { - Offset( - x = it.calculateTopBarAnimateValue(startOffset.x, 56f), - y = it.calculateTopBarAnimateValue(startOffset.y, 0f) - ) - } - - val height by transition.animateFloat( - label = "", - transitionSpec = { spring() } - ) { - it.calculateTopBarAnimateValue(startHeight, 64f) - } - - val titleFontSize by transition.animateFloat( - label = "", - transitionSpec = { spring(stiffness = Spring.StiffnessHigh) } - ) { - it.calculateTopBarAnimateValue(startTitleFontSize, 16f) - } - - val descriptionFontSize by transition.animateFloat( - label = "", - transitionSpec = { spring(stiffness = Spring.StiffnessHigh) } - ) { - it.calculateTopBarAnimateValue(startDescriptionFontSize, 12f) - } - - Box( - modifier = Modifier - .zIndex(1f) - .height(height.dp) - .offset(offset.x.dp, offset.y.dp) - .clickable( - interactionSource = MutableInteractionSource(), - indication = null, - onClickLabel = "回到顶部", - onClick = clickable - ), - contentAlignment = Alignment.Center - ) { - Column { - AnimatedText( - text = title, - fontWeight = FontWeight.Bold, - fontSize = titleFontSize.sp, - color = MaterialTheme.colorScheme.primary - ) - Spacer(modifier = Modifier.height(SpacerHeight.dp)) - AnimatedText( - modifier = Modifier.width(200.dp), - text = description, - fontWeight = FontWeight.SemiBold, - fontSize = descriptionFontSize.sp, - color = MaterialTheme.colorScheme.secondary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - } - } -} \ No newline at end of file