mirror of
https://github.com/mihonapp/mihon.git
synced 2025-01-28 19:04:55 +01:00
Merge branch 'mihonapp:main' into Add-Hikka-Tracker
This commit is contained in:
commit
32db1da753
11
.github/workflows/build_pull_request.yml
vendored
11
.github/workflows/build_pull_request.yml
vendored
@ -1,10 +1,13 @@
|
|||||||
name: PR build check
|
name: PR build check
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
paths-ignore:
|
paths:
|
||||||
- '**.md'
|
- '**'
|
||||||
- 'i18n/src/commonMain/moko-resources/**/strings.xml'
|
- '!**.md'
|
||||||
- 'i18n/src/commonMain/moko-resources/**/plurals.xml'
|
- '!i18n/src/commonMain/moko-resources/**/strings.xml'
|
||||||
|
- '!i18n/src/commonMain/moko-resources/**/plurals.xml'
|
||||||
|
- 'i18n/src/commonMain/moko-resources/base/strings.xml'
|
||||||
|
- 'i18n/src/commonMain/moko-resources/base/plurals.xml'
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
|
||||||
|
22
.gitignore
vendored
22
.gitignore
vendored
@ -1,18 +1,16 @@
|
|||||||
|
# Build files
|
||||||
.gradle
|
.gradle
|
||||||
.kotlin
|
.kotlin
|
||||||
/local.properties
|
build
|
||||||
/.idea/workspace.xml
|
|
||||||
.DS_Store
|
# IDE files
|
||||||
|
*.iml
|
||||||
.idea/*
|
.idea/*
|
||||||
!.idea/icon.png
|
!.idea/icon.png
|
||||||
*iml
|
/captures
|
||||||
*.iml
|
|
||||||
|
|
||||||
# Built files
|
# Configuration files
|
||||||
*/build
|
local.properties
|
||||||
/build
|
|
||||||
*.apk
|
|
||||||
app/**/output.json
|
|
||||||
|
|
||||||
# Unnecessary file
|
# macOS specific files
|
||||||
*.swp
|
.DS_Store
|
||||||
|
3
app/.gitignore
vendored
3
app/.gitignore
vendored
@ -1,3 +0,0 @@
|
|||||||
/build
|
|
||||||
*iml
|
|
||||||
*.iml
|
|
@ -5,6 +5,7 @@ import eu.kanade.domain.track.model.toDomainTrack
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.EnhancedTracker
|
import eu.kanade.tachiyomi.data.track.EnhancedTracker
|
||||||
import eu.kanade.tachiyomi.data.track.Tracker
|
import eu.kanade.tachiyomi.data.track.Tracker
|
||||||
|
import eu.kanade.tachiyomi.data.track.TrackerManager
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.util.lang.convertEpochMillisZone
|
import eu.kanade.tachiyomi.util.lang.convertEpochMillisZone
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
@ -14,17 +15,16 @@ import tachiyomi.core.common.util.system.logcat
|
|||||||
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
|
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
|
||||||
import tachiyomi.domain.history.interactor.GetHistory
|
import tachiyomi.domain.history.interactor.GetHistory
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.track.interactor.GetTracks
|
|
||||||
import tachiyomi.domain.track.interactor.InsertTrack
|
import tachiyomi.domain.track.interactor.InsertTrack
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.time.ZoneOffset
|
import java.time.ZoneOffset
|
||||||
|
|
||||||
class AddTracks(
|
class AddTracks(
|
||||||
private val getTracks: GetTracks,
|
|
||||||
private val insertTrack: InsertTrack,
|
private val insertTrack: InsertTrack,
|
||||||
private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack,
|
private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack,
|
||||||
private val getChaptersByMangaId: GetChaptersByMangaId,
|
private val getChaptersByMangaId: GetChaptersByMangaId,
|
||||||
|
private val trackerManager: TrackerManager,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// TODO: update all trackers based on common data
|
// TODO: update all trackers based on common data
|
||||||
@ -79,7 +79,7 @@ class AddTracks(
|
|||||||
|
|
||||||
suspend fun bindEnhancedTrackers(manga: Manga, source: Source) = withNonCancellableContext {
|
suspend fun bindEnhancedTrackers(manga: Manga, source: Source) = withNonCancellableContext {
|
||||||
withIOContext {
|
withIOContext {
|
||||||
getTracks.await(manga.id)
|
trackerManager.loggedInTrackers()
|
||||||
.filterIsInstance<EnhancedTracker>()
|
.filterIsInstance<EnhancedTracker>()
|
||||||
.filter { it.accept(source) }
|
.filter { it.accept(source) }
|
||||||
.forEach { service ->
|
.forEach { service ->
|
||||||
@ -87,11 +87,11 @@ class AddTracks(
|
|||||||
service.match(manga)?.let { track ->
|
service.match(manga)?.let { track ->
|
||||||
track.manga_id = manga.id
|
track.manga_id = manga.id
|
||||||
(service as Tracker).bind(track)
|
(service as Tracker).bind(track)
|
||||||
insertTrack.await(track.toDomainTrack()!!)
|
insertTrack.await(track.toDomainTrack(idRequired = false)!!)
|
||||||
|
|
||||||
syncChapterProgressWithTrack.await(
|
syncChapterProgressWithTrack.await(
|
||||||
manga.id,
|
manga.id,
|
||||||
track.toDomainTrack()!!,
|
track.toDomainTrack(idRequired = false)!!,
|
||||||
service,
|
service,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -166,23 +166,27 @@ private fun ColumnScope.SortPage(
|
|||||||
val sortingMode = category.sort.type
|
val sortingMode = category.sort.type
|
||||||
val sortDescending = !category.sort.isAscending
|
val sortDescending = !category.sort.isAscending
|
||||||
|
|
||||||
val trackerSortOption = if (trackers.isEmpty()) {
|
val options = remember(trackers.isEmpty()) {
|
||||||
emptyList()
|
val trackerMeanPair = if (trackers.isNotEmpty()) {
|
||||||
} else {
|
MR.strings.action_sort_tracker_score to LibrarySort.Type.TrackerMean
|
||||||
listOf(MR.strings.action_sort_tracker_score to LibrarySort.Type.TrackerMean)
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
listOfNotNull(
|
||||||
|
MR.strings.action_sort_alpha to LibrarySort.Type.Alphabetical,
|
||||||
|
MR.strings.action_sort_total to LibrarySort.Type.TotalChapters,
|
||||||
|
MR.strings.action_sort_last_read to LibrarySort.Type.LastRead,
|
||||||
|
MR.strings.action_sort_last_manga_update to LibrarySort.Type.LastUpdate,
|
||||||
|
MR.strings.action_sort_unread_count to LibrarySort.Type.UnreadCount,
|
||||||
|
MR.strings.action_sort_latest_chapter to LibrarySort.Type.LatestChapter,
|
||||||
|
MR.strings.action_sort_chapter_fetch_date to LibrarySort.Type.ChapterFetchDate,
|
||||||
|
MR.strings.action_sort_date_added to LibrarySort.Type.DateAdded,
|
||||||
|
trackerMeanPair,
|
||||||
|
MR.strings.action_sort_random to LibrarySort.Type.Random,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
listOf(
|
options.map { (titleRes, mode) ->
|
||||||
MR.strings.action_sort_alpha to LibrarySort.Type.Alphabetical,
|
|
||||||
MR.strings.action_sort_total to LibrarySort.Type.TotalChapters,
|
|
||||||
MR.strings.action_sort_last_read to LibrarySort.Type.LastRead,
|
|
||||||
MR.strings.action_sort_last_manga_update to LibrarySort.Type.LastUpdate,
|
|
||||||
MR.strings.action_sort_unread_count to LibrarySort.Type.UnreadCount,
|
|
||||||
MR.strings.action_sort_latest_chapter to LibrarySort.Type.LatestChapter,
|
|
||||||
MR.strings.action_sort_chapter_fetch_date to LibrarySort.Type.ChapterFetchDate,
|
|
||||||
MR.strings.action_sort_date_added to LibrarySort.Type.DateAdded,
|
|
||||||
MR.strings.action_sort_random to LibrarySort.Type.Random,
|
|
||||||
).plus(trackerSortOption).map { (titleRes, mode) ->
|
|
||||||
if (mode == LibrarySort.Type.Random) {
|
if (mode == LibrarySort.Type.Random) {
|
||||||
BaseSortItem(
|
BaseSortItem(
|
||||||
label = stringResource(titleRes),
|
label = stringResource(titleRes),
|
||||||
|
@ -45,8 +45,8 @@ fun ReaderAppBars(
|
|||||||
onClickTopAppBar: () -> Unit,
|
onClickTopAppBar: () -> Unit,
|
||||||
bookmarked: Boolean,
|
bookmarked: Boolean,
|
||||||
onToggleBookmarked: () -> Unit,
|
onToggleBookmarked: () -> Unit,
|
||||||
onOpenInBrowser: (() -> Unit)?,
|
|
||||||
onOpenInWebView: (() -> Unit)?,
|
onOpenInWebView: (() -> Unit)?,
|
||||||
|
onOpenInBrowser: (() -> Unit)?,
|
||||||
onShare: (() -> Unit)?,
|
onShare: (() -> Unit)?,
|
||||||
|
|
||||||
viewer: Viewer?,
|
viewer: Viewer?,
|
||||||
@ -120,14 +120,6 @@ fun ReaderAppBars(
|
|||||||
onClick = onToggleBookmarked,
|
onClick = onToggleBookmarked,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
onOpenInBrowser?.let {
|
|
||||||
add(
|
|
||||||
AppBar.OverflowAction(
|
|
||||||
title = stringResource(MR.strings.action_open_in_browser),
|
|
||||||
onClick = it,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
onOpenInWebView?.let {
|
onOpenInWebView?.let {
|
||||||
add(
|
add(
|
||||||
AppBar.OverflowAction(
|
AppBar.OverflowAction(
|
||||||
@ -136,6 +128,14 @@ fun ReaderAppBars(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
onOpenInBrowser?.let {
|
||||||
|
add(
|
||||||
|
AppBar.OverflowAction(
|
||||||
|
title = stringResource(MR.strings.action_open_in_browser),
|
||||||
|
onClick = it,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
onShare?.let {
|
onShare?.let {
|
||||||
add(
|
add(
|
||||||
AppBar.OverflowAction(
|
AppBar.OverflowAction(
|
||||||
|
@ -27,6 +27,7 @@ import tachiyomi.core.common.util.system.logcat
|
|||||||
import tachiyomi.domain.backup.service.BackupPreferences
|
import tachiyomi.domain.backup.service.BackupPreferences
|
||||||
import tachiyomi.domain.manga.interactor.GetFavorites
|
import tachiyomi.domain.manga.interactor.GetFavorites
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
@ -43,6 +44,7 @@ class BackupCreator(
|
|||||||
private val parser: ProtoBuf = Injekt.get(),
|
private val parser: ProtoBuf = Injekt.get(),
|
||||||
private val getFavorites: GetFavorites = Injekt.get(),
|
private val getFavorites: GetFavorites = Injekt.get(),
|
||||||
private val backupPreferences: BackupPreferences = Injekt.get(),
|
private val backupPreferences: BackupPreferences = Injekt.get(),
|
||||||
|
private val mangaRepository: MangaRepository = Injekt.get(),
|
||||||
|
|
||||||
private val categoriesBackupCreator: CategoriesBackupCreator = CategoriesBackupCreator(),
|
private val categoriesBackupCreator: CategoriesBackupCreator = CategoriesBackupCreator(),
|
||||||
private val mangaBackupCreator: MangaBackupCreator = MangaBackupCreator(),
|
private val mangaBackupCreator: MangaBackupCreator = MangaBackupCreator(),
|
||||||
@ -75,7 +77,9 @@ class BackupCreator(
|
|||||||
throw IllegalStateException(context.stringResource(MR.strings.create_backup_file_error))
|
throw IllegalStateException(context.stringResource(MR.strings.create_backup_file_error))
|
||||||
}
|
}
|
||||||
|
|
||||||
val backupManga = backupMangas(getFavorites.await(), options)
|
val nonFavoriteManga = if (options.readEntries) mangaRepository.getReadMangaNotInLibrary() else emptyList()
|
||||||
|
val backupManga = backupMangas(getFavorites.await() + nonFavoriteManga, options)
|
||||||
|
|
||||||
val backup = Backup(
|
val backup = Backup(
|
||||||
backupManga = backupManga,
|
backupManga = backupManga,
|
||||||
backupCategories = backupCategories(options),
|
backupCategories = backupCategories(options),
|
||||||
|
@ -10,6 +10,7 @@ data class BackupOptions(
|
|||||||
val chapters: Boolean = true,
|
val chapters: Boolean = true,
|
||||||
val tracking: Boolean = true,
|
val tracking: Boolean = true,
|
||||||
val history: Boolean = true,
|
val history: Boolean = true,
|
||||||
|
val readEntries: Boolean = true,
|
||||||
val appSettings: Boolean = true,
|
val appSettings: Boolean = true,
|
||||||
val extensionRepoSettings: Boolean = true,
|
val extensionRepoSettings: Boolean = true,
|
||||||
val sourceSettings: Boolean = true,
|
val sourceSettings: Boolean = true,
|
||||||
@ -22,6 +23,7 @@ data class BackupOptions(
|
|||||||
chapters,
|
chapters,
|
||||||
tracking,
|
tracking,
|
||||||
history,
|
history,
|
||||||
|
readEntries,
|
||||||
appSettings,
|
appSettings,
|
||||||
extensionRepoSettings,
|
extensionRepoSettings,
|
||||||
sourceSettings,
|
sourceSettings,
|
||||||
@ -60,6 +62,12 @@ data class BackupOptions(
|
|||||||
getter = BackupOptions::categories,
|
getter = BackupOptions::categories,
|
||||||
setter = { options, enabled -> options.copy(categories = enabled) },
|
setter = { options, enabled -> options.copy(categories = enabled) },
|
||||||
),
|
),
|
||||||
|
Entry(
|
||||||
|
label = MR.strings.non_library_settings,
|
||||||
|
getter = BackupOptions::readEntries,
|
||||||
|
setter = { options, enabled -> options.copy(readEntries = enabled) },
|
||||||
|
enabled = { it.libraryEntries },
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
val settingsOptions = persistentListOf(
|
val settingsOptions = persistentListOf(
|
||||||
@ -92,10 +100,11 @@ data class BackupOptions(
|
|||||||
chapters = array[2],
|
chapters = array[2],
|
||||||
tracking = array[3],
|
tracking = array[3],
|
||||||
history = array[4],
|
history = array[4],
|
||||||
appSettings = array[5],
|
readEntries = array[5],
|
||||||
extensionRepoSettings = array[6],
|
appSettings = array[6],
|
||||||
sourceSettings = array[7],
|
extensionRepoSettings = array[7],
|
||||||
privateSettings = array[8],
|
sourceSettings = array[8],
|
||||||
|
privateSettings = array[9],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,8 +390,8 @@ class ReaderActivity : BaseActivity() {
|
|||||||
onClickTopAppBar = ::openMangaScreen,
|
onClickTopAppBar = ::openMangaScreen,
|
||||||
bookmarked = state.bookmarked,
|
bookmarked = state.bookmarked,
|
||||||
onToggleBookmarked = viewModel::toggleChapterBookmark,
|
onToggleBookmarked = viewModel::toggleChapterBookmark,
|
||||||
onOpenInBrowser = ::openChapterInBrowser.takeIf { isHttpSource },
|
|
||||||
onOpenInWebView = ::openChapterInWebView.takeIf { isHttpSource },
|
onOpenInWebView = ::openChapterInWebView.takeIf { isHttpSource },
|
||||||
|
onOpenInBrowser = ::openChapterInBrowser.takeIf { isHttpSource },
|
||||||
onShare = ::shareChapter.takeIf { isHttpSource },
|
onShare = ::shareChapter.takeIf { isHttpSource },
|
||||||
|
|
||||||
viewer = state.viewer,
|
viewer = state.viewer,
|
||||||
@ -565,12 +565,6 @@ class ReaderActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openChapterInBrowser() {
|
|
||||||
assistUrl?.let {
|
|
||||||
openInBrowser(it.toUri(), forceDefaultBrowser = false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun openChapterInWebView() {
|
private fun openChapterInWebView() {
|
||||||
val manga = viewModel.manga ?: return
|
val manga = viewModel.manga ?: return
|
||||||
val source = viewModel.getSource() ?: return
|
val source = viewModel.getSource() ?: return
|
||||||
@ -580,6 +574,12 @@ class ReaderActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun openChapterInBrowser() {
|
||||||
|
assistUrl?.let {
|
||||||
|
openInBrowser(it.toUri(), forceDefaultBrowser = false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun shareChapter() {
|
private fun shareChapter() {
|
||||||
assistUrl?.let {
|
assistUrl?.let {
|
||||||
val intent = it.toUri().toShareIntent(this, type = "text/plain")
|
val intent = it.toUri().toShareIntent(this, type = "text/plain")
|
||||||
|
1
buildSrc/.gitignore
vendored
1
buildSrc/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
@ -6,6 +6,18 @@ plugins {
|
|||||||
|
|
||||||
val libs = the<LibrariesForLibs>()
|
val libs = the<LibrariesForLibs>()
|
||||||
|
|
||||||
|
val xmlFormatExclude = buildList(2) {
|
||||||
|
add("**/build/**/*.xml")
|
||||||
|
|
||||||
|
projectDir
|
||||||
|
.resolve("src/commonMain/moko-resources")
|
||||||
|
.takeIf { it.isDirectory }
|
||||||
|
?.let(::fileTree)
|
||||||
|
?.matching { exclude("/base/**") }
|
||||||
|
?.let(::add)
|
||||||
|
}
|
||||||
|
.toTypedArray()
|
||||||
|
|
||||||
spotless {
|
spotless {
|
||||||
kotlin {
|
kotlin {
|
||||||
target("**/*.kt", "**/*.kts")
|
target("**/*.kt", "**/*.kts")
|
||||||
@ -23,7 +35,7 @@ spotless {
|
|||||||
}
|
}
|
||||||
format("xml") {
|
format("xml") {
|
||||||
target("**/*.xml")
|
target("**/*.xml")
|
||||||
targetExclude("**/build/**/*.xml")
|
targetExclude(*xmlFormatExclude)
|
||||||
trimTrailingWhitespace()
|
trimTrailingWhitespace()
|
||||||
endWithNewline()
|
endWithNewline()
|
||||||
}
|
}
|
||||||
|
1
core-metadata/.gitignore
vendored
1
core-metadata/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
1
core/archive/.gitignore
vendored
1
core/archive/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
1
core/common/.gitignore
vendored
1
core/common/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
1
data/.gitignore
vendored
1
data/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
@ -49,6 +49,10 @@ class MangaRepositoryImpl(
|
|||||||
return handler.awaitList { mangasQueries.getFavorites(MangaMapper::mapManga) }
|
return handler.awaitList { mangasQueries.getFavorites(MangaMapper::mapManga) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getReadMangaNotInLibrary(): List<Manga> {
|
||||||
|
return handler.awaitList { mangasQueries.getReadMangaNotInLibrary(MangaMapper::mapManga) }
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun getLibraryManga(): List<LibraryManga> {
|
override suspend fun getLibraryManga(): List<LibraryManga> {
|
||||||
return handler.awaitList { libraryViewQueries.library(MangaMapper::mapLibraryManga) }
|
return handler.awaitList { libraryViewQueries.library(MangaMapper::mapLibraryManga) }
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,15 @@ SELECT *
|
|||||||
FROM mangas
|
FROM mangas
|
||||||
WHERE favorite = 1;
|
WHERE favorite = 1;
|
||||||
|
|
||||||
|
getReadMangaNotInLibrary:
|
||||||
|
SELECT *
|
||||||
|
FROM mangas
|
||||||
|
WHERE favorite = 0 AND _id IN (
|
||||||
|
SELECT DISTINCT chapters.manga_id
|
||||||
|
FROM chapters
|
||||||
|
WHERE read = 1 OR last_page_read != 0
|
||||||
|
);
|
||||||
|
|
||||||
getAllManga:
|
getAllManga:
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM mangas;
|
FROM mangas;
|
||||||
|
1
domain/.gitignore
vendored
1
domain/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
@ -17,6 +17,8 @@ interface MangaRepository {
|
|||||||
|
|
||||||
suspend fun getFavorites(): List<Manga>
|
suspend fun getFavorites(): List<Manga>
|
||||||
|
|
||||||
|
suspend fun getReadMangaNotInLibrary(): List<Manga>
|
||||||
|
|
||||||
suspend fun getLibraryManga(): List<LibraryManga>
|
suspend fun getLibraryManga(): List<LibraryManga>
|
||||||
|
|
||||||
fun getLibraryMangaAsFlow(): Flow<List<LibraryManga>>
|
fun getLibraryMangaAsFlow(): Flow<List<LibraryManga>>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp_version = "8.7.0"
|
agp_version = "8.7.1"
|
||||||
lifecycle_version = "2.8.6"
|
lifecycle_version = "2.8.6"
|
||||||
paging_version = "3.3.2"
|
paging_version = "3.3.2"
|
||||||
interpolator_version = "1.0.0"
|
interpolator_version = "1.0.0"
|
||||||
|
0
i18n/.gitignore
vendored
0
i18n/.gitignore
vendored
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
This module houses the string resources and translations.
|
This module houses the string resources and translations.
|
||||||
|
|
||||||
Original English strings are manged in `src/commonMain/resources/MR/base/`. Translations are done externally via Weblate. See [our website](https://mihon.app/docs/contribute#translation) for more details.
|
Original English strings are managed in `src/commonMain/moko-resources/base/`. Translations are done externally via Weblate. See [our website](https://mihon.app/docs/contribute#translation) for more details.
|
@ -546,6 +546,7 @@
|
|||||||
<string name="source_settings">Source settings</string>
|
<string name="source_settings">Source settings</string>
|
||||||
<string name="extensionRepo_settings">Extension repos</string>
|
<string name="extensionRepo_settings">Extension repos</string>
|
||||||
<string name="private_settings">Include sensitive settings (e.g., tracker login tokens)</string>
|
<string name="private_settings">Include sensitive settings (e.g., tracker login tokens)</string>
|
||||||
|
<string name="non_library_settings">All read entries</string>
|
||||||
<string name="creating_backup">Creating backup</string>
|
<string name="creating_backup">Creating backup</string>
|
||||||
<string name="creating_backup_error">Backup failed</string>
|
<string name="creating_backup_error">Backup failed</string>
|
||||||
<string name="missing_storage_permission">Storage permissions not granted</string>
|
<string name="missing_storage_permission">Storage permissions not granted</string>
|
||||||
|
1
macrobenchmark/.gitignore
vendored
1
macrobenchmark/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
1
presentation-core/.gitignore
vendored
1
presentation-core/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
@ -9,11 +9,11 @@ import androidx.compose.animation.fadeIn
|
|||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.animation.shrinkHorizontally
|
import androidx.compose.animation.shrinkHorizontally
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.sizeIn
|
import androidx.compose.foundation.layout.sizeIn
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.material3.FloatingActionButton
|
import androidx.compose.material3.FloatingActionButton
|
||||||
import androidx.compose.material3.FloatingActionButtonDefaults
|
import androidx.compose.material3.FloatingActionButtonDefaults
|
||||||
import androidx.compose.material3.FloatingActionButtonElevation
|
import androidx.compose.material3.FloatingActionButtonElevation
|
||||||
@ -46,12 +46,8 @@ fun ExtendedFloatingActionButton(
|
|||||||
contentColor: Color = contentColorFor(containerColor),
|
contentColor: Color = contentColorFor(containerColor),
|
||||||
elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
|
elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
|
||||||
) {
|
) {
|
||||||
val minWidth by animateDpAsState(
|
|
||||||
targetValue = if (expanded) ExtendedFabMinimumWidth else FabContainerWidth,
|
|
||||||
label = "minWidth",
|
|
||||||
)
|
|
||||||
FloatingActionButton(
|
FloatingActionButton(
|
||||||
modifier = modifier.sizeIn(minWidth = minWidth),
|
modifier = modifier,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
interactionSource = interactionSource,
|
interactionSource = interactionSource,
|
||||||
shape = shape,
|
shape = shape,
|
||||||
@ -59,18 +55,29 @@ fun ExtendedFloatingActionButton(
|
|||||||
contentColor = contentColor,
|
contentColor = contentColor,
|
||||||
elevation = elevation,
|
elevation = elevation,
|
||||||
) {
|
) {
|
||||||
|
val minWidth by animateDpAsState(
|
||||||
|
targetValue = if (expanded) ExtendedFabMinimumWidth else FabContainerWidth,
|
||||||
|
animationSpec = tween(
|
||||||
|
durationMillis = 500,
|
||||||
|
easing = EasingEmphasizedCubicBezier,
|
||||||
|
),
|
||||||
|
label = "minWidth",
|
||||||
|
)
|
||||||
val startPadding by animateDpAsState(
|
val startPadding by animateDpAsState(
|
||||||
targetValue = if (expanded) ExtendedFabIconSize / 2 else 0.dp,
|
targetValue = if (expanded) ExtendedFabIconSize / 2 else 0.dp,
|
||||||
|
animationSpec = tween(
|
||||||
|
durationMillis = if (expanded) 300 else 900,
|
||||||
|
easing = EasingEmphasizedCubicBezier,
|
||||||
|
),
|
||||||
label = "startPadding",
|
label = "startPadding",
|
||||||
)
|
)
|
||||||
val endPadding by animateDpAsState(
|
|
||||||
targetValue = if (expanded) ExtendedFabTextPadding else 0.dp,
|
|
||||||
label = "endPadding",
|
|
||||||
)
|
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.padding(start = startPadding, end = endPadding),
|
modifier = Modifier
|
||||||
|
.sizeIn(minWidth = minWidth)
|
||||||
|
.padding(start = startPadding),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
) {
|
) {
|
||||||
icon()
|
icon()
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
@ -78,8 +85,7 @@ fun ExtendedFloatingActionButton(
|
|||||||
enter = ExtendedFabExpandAnimation,
|
enter = ExtendedFabExpandAnimation,
|
||||||
exit = ExtendedFabCollapseAnimation,
|
exit = ExtendedFabCollapseAnimation,
|
||||||
) {
|
) {
|
||||||
Row {
|
Box(modifier = Modifier.padding(start = ExtendedFabIconPadding, end = ExtendedFabTextPadding)) {
|
||||||
Spacer(Modifier.width(ExtendedFabIconPadding))
|
|
||||||
text()
|
text()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
presentation-widget/.gitignore
vendored
1
presentation-widget/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
1
source-api/.gitignore
vendored
1
source-api/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
1
source-local/.gitignore
vendored
1
source-local/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
Loading…
x
Reference in New Issue
Block a user