ReaderScreen saveImage
This commit is contained in:
1 parent
38651eba1d
commit
28160608ec
2 files changed
+61
-2
No files matched your search
@@ -1,9 +1,13 @@
|
||||
package com.hippo.ehviewer.ui.reader
|
||||
|
||||
import android.Manifest
|
||||
import android.content.ClipData
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Environment
|
||||
import android.provider.MediaStore
|
||||
import android.webkit.MimeTypeMap
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.core.content.FileProvider
|
||||
@@ -14,10 +18,14 @@ import com.hippo.ehviewer.client.data.GalleryInfo
|
||||
import com.hippo.ehviewer.gallery.PageLoader2
|
||||
import com.hippo.ehviewer.util.AppConfig
|
||||
import com.hippo.ehviewer.util.FileUtils
|
||||
import com.hippo.ehviewer.util.isAtLeastQ
|
||||
import com.hippo.ehviewer.util.isAtLeastT
|
||||
import com.hippo.ehviewer.util.requestPermission
|
||||
import com.hippo.unifile.asUniFile
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import java.io.File
|
||||
import kotlinx.datetime.Clock
|
||||
import splitties.systemservices.clipboardManager
|
||||
|
||||
context(PageLoader2)
|
||||
@@ -67,3 +75,53 @@ suspend fun copy(page: ReaderPage) {
|
||||
showSnackbar(copied)
|
||||
}
|
||||
}
|
||||
|
||||
context(SnackbarHostState, Context, PageLoader2)
|
||||
suspend fun save(page: ReaderPage) {
|
||||
val granted = isAtLeastQ || requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
val cannotSave = getString(R.string.error_cant_save_image)
|
||||
if (granted) {
|
||||
val filename = getImageFilename(page.index)
|
||||
val extension = FileUtils.getExtensionFromFilename(filename)
|
||||
val mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) ?: "image/jpeg"
|
||||
val values = ContentValues()
|
||||
val realPath: String
|
||||
values.put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
|
||||
values.put(MediaStore.Images.Media.DATE_ADDED, Clock.System.now().toEpochMilliseconds())
|
||||
values.put(MediaStore.MediaColumns.MIME_TYPE, mimeType)
|
||||
if (isAtLeastQ) {
|
||||
realPath = Environment.DIRECTORY_PICTURES + File.separator + AppConfig.APP_DIRNAME
|
||||
values.put(MediaStore.MediaColumns.RELATIVE_PATH, realPath)
|
||||
values.put(MediaStore.MediaColumns.IS_PENDING, 1)
|
||||
} else {
|
||||
val dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
|
||||
val path = File(dir, AppConfig.APP_DIRNAME)
|
||||
realPath = path.toString()
|
||||
if (!FileUtils.ensureDirectory(path)) {
|
||||
showSnackbar(cannotSave)
|
||||
return
|
||||
}
|
||||
values.put(MediaStore.MediaColumns.DATA, realPath + File.separator + filename)
|
||||
}
|
||||
val imageUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
|
||||
if (imageUri != null) {
|
||||
if (!save(page.index, imageUri.asUniFile())) {
|
||||
try {
|
||||
contentResolver.delete(imageUri, null, null)
|
||||
} catch (e: Exception) {
|
||||
e.logcat(e)
|
||||
}
|
||||
showSnackbar(cannotSave)
|
||||
} else if (isAtLeastQ) {
|
||||
val contentValues = ContentValues()
|
||||
contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0)
|
||||
contentResolver.update(imageUri, contentValues, null, null)
|
||||
}
|
||||
showSnackbar(getString(R.string.image_saved, realPath + File.separator + filename))
|
||||
} else {
|
||||
showSnackbar(cannotSave)
|
||||
}
|
||||
} else {
|
||||
showSnackbar(getString(R.string.permission_denied))
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import eu.kanade.tachiyomi.ui.reader.ReaderAppBars
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderPageSheetMeta
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import kotlin.coroutines.resume
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Destination
|
||||
@@ -103,7 +104,7 @@ fun ReaderScreen(info: BaseGalleryInfo, page: Int = -1, navigator: DestinationsN
|
||||
onSelectPage = { page ->
|
||||
launch {
|
||||
dialog { cont ->
|
||||
fun dispose() = cont.cancel()
|
||||
fun dispose() = cont.resume(Unit)
|
||||
val state = rememberModalBottomSheetState()
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = { dispose() },
|
||||
@@ -115,7 +116,7 @@ fun ReaderScreen(info: BaseGalleryInfo, page: Int = -1, navigator: DestinationsN
|
||||
retryOrigin = { pageLoader.retryPage(page.index, true) },
|
||||
share = { launchIO { with(pageLoader) { shareImage(page, info) } } },
|
||||
copy = { launchIO { with(pageLoader) { copy(page) } } },
|
||||
save = {},
|
||||
save = { launchIO { with(pageLoader) { save(page) } } },
|
||||
saveTo = {},
|
||||
dismiss = { launch { state.hide().also { dispose() } } },
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user