Added export feature
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
package="xyz.quaver.pupil">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
||||
@@ -3,10 +3,10 @@ package xyz.quaver.pupil
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.preference.PreferenceManager
|
||||
import android.text.*
|
||||
import android.text.style.AlignmentSpan
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageView
|
||||
@@ -16,16 +16,19 @@ import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.cardview.widget.CardView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.view.GravityCompat
|
||||
import com.arlib.floatingsearchview.FloatingSearchView
|
||||
import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion
|
||||
import com.arlib.floatingsearchview.util.view.SearchInputView
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import kotlinx.android.synthetic.main.activity_main_content.*
|
||||
import kotlinx.android.synthetic.main.dialog_galleryblock.view.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.io.IOException
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonConfiguration
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
@@ -36,9 +39,12 @@ import xyz.quaver.pupil.adapters.GalleryBlockAdapter
|
||||
import xyz.quaver.pupil.types.TagSuggestion
|
||||
import xyz.quaver.pupil.util.*
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.net.URL
|
||||
import java.util.*
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.math.roundToInt
|
||||
@@ -281,12 +287,7 @@ class MainActivity : AppCompatActivity() {
|
||||
loadBlocks()
|
||||
}
|
||||
R.id.main_drawer_help -> {
|
||||
AlertDialog.Builder(this@MainActivity).apply {
|
||||
title = getString(R.string.help_dialog_title)
|
||||
setMessage(R.string.help_dialog_message)
|
||||
|
||||
setPositiveButton(android.R.string.ok) { _, _ -> }
|
||||
}.show()
|
||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.help))))
|
||||
}
|
||||
R.id.main_drawer_github -> {
|
||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.github))))
|
||||
@@ -398,6 +399,73 @@ class MainActivity : AppCompatActivity() {
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
with(view.main_dialog_export) {
|
||||
val images = File(ContextCompat.getDataDir(this@MainActivity), "images/${galleryBlock.id}/images").let {
|
||||
when {
|
||||
it.exists() -> it
|
||||
else -> File(cacheDir, "imageCache/${galleryBlock.id}/images")
|
||||
}
|
||||
}
|
||||
isEnabled = images.exists()
|
||||
|
||||
setOnClickListener {
|
||||
CoroutineScope(Dispatchers.Default).launch {
|
||||
val preference = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val zip = preference.getBoolean("export_zip", false)
|
||||
|
||||
if (zip) {
|
||||
var target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id} ${galleryBlock.title}.zip")
|
||||
|
||||
try {
|
||||
target.createNewFile()
|
||||
} catch (e: IOException) {
|
||||
target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}.zip")
|
||||
|
||||
try {
|
||||
target.createNewFile()
|
||||
} catch (e: IOException) {
|
||||
Snackbar.make(main_layout, getString(R.string.main_export_error), Snackbar.LENGTH_LONG).show()
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
|
||||
FileOutputStream(target).use { targetStream ->
|
||||
ZipOutputStream(targetStream).use {zipStream ->
|
||||
images.listFiles().forEach {
|
||||
zipStream.putNextEntry(ZipEntry(it.name))
|
||||
|
||||
FileInputStream(it).use { fileStream ->
|
||||
fileStream.copyTo(zipStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id} ${galleryBlock.title}")
|
||||
|
||||
try {
|
||||
target.canonicalPath
|
||||
} catch (e: IOException) {
|
||||
target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}")
|
||||
|
||||
try {
|
||||
target.canonicalPath
|
||||
} catch (e: IOException) {
|
||||
Snackbar.make(main_layout, getString(R.string.main_export_error), Snackbar.LENGTH_LONG).show()
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
|
||||
images.copyRecursively(target, true)
|
||||
}
|
||||
|
||||
Snackbar.make(main_layout, getString(R.string.main_export_complete), Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
dialog.show()
|
||||
|
||||
true
|
||||
|
||||
@@ -2,6 +2,7 @@ package xyz.quaver.pupil
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.view.*
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
@@ -26,6 +27,11 @@ import xyz.quaver.hitomi.GalleryBlock
|
||||
import xyz.quaver.pupil.adapters.ReaderAdapter
|
||||
import xyz.quaver.pupil.util.GalleryDownloader
|
||||
import xyz.quaver.pupil.util.ItemClickSupport
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
|
||||
class ReaderActivity : AppCompatActivity() {
|
||||
|
||||
@@ -274,6 +280,14 @@ class ReaderActivity : AppCompatActivity() {
|
||||
if (!downloader.download)
|
||||
downloader.clearNotification()
|
||||
}
|
||||
|
||||
reader_fab_export.setOnClickListener {
|
||||
downloader.export( {
|
||||
Snackbar.make(reader_layout, getString(R.string.main_export_complete), Snackbar.LENGTH_LONG).show()
|
||||
}, {
|
||||
Snackbar.make(reader_layout, getString(R.string.main_export_error), Snackbar.LENGTH_LONG).show()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun fullscreen(isFullscreen: Boolean) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.Intent
|
||||
import android.os.Environment
|
||||
import android.util.SparseArray
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
@@ -20,9 +21,12 @@ import xyz.quaver.pupil.Pupil
|
||||
import xyz.quaver.pupil.R
|
||||
import xyz.quaver.pupil.ReaderActivity
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.net.URL
|
||||
import java.util.*
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.concurrent.schedule
|
||||
@@ -284,4 +288,69 @@ class GalleryDownloader(
|
||||
notificationManager = NotificationManagerCompat.from(this)
|
||||
}
|
||||
|
||||
fun export(onSuccess: (() -> Unit)? = null, onError: (() -> Unit)? = null) {
|
||||
val images = File(ContextCompat.getDataDir(this), "images/${galleryBlock.id}/images").let {
|
||||
when {
|
||||
it.exists() -> it
|
||||
else -> File(cacheDir, "imageCache/${galleryBlock.id}/images")
|
||||
}
|
||||
}
|
||||
|
||||
if (!images.exists())
|
||||
return
|
||||
|
||||
CoroutineScope(Dispatchers.Default).launch {
|
||||
val preference = PreferenceManager.getDefaultSharedPreferences(this@GalleryDownloader)
|
||||
val zip = preference.getBoolean("export_zip", false)
|
||||
|
||||
if (zip) {
|
||||
var target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id} ${galleryBlock.title}.zip")
|
||||
|
||||
try {
|
||||
target.createNewFile()
|
||||
} catch (e: IOException) {
|
||||
target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}.zip")
|
||||
|
||||
try {
|
||||
target.createNewFile()
|
||||
} catch (e: IOException) {
|
||||
onError?.invoke()
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
|
||||
FileOutputStream(target).use { targetStream ->
|
||||
ZipOutputStream(targetStream).use { zipStream ->
|
||||
images.listFiles().forEach {
|
||||
zipStream.putNextEntry(ZipEntry(it.name))
|
||||
|
||||
FileInputStream(it).use { fileStream ->
|
||||
fileStream.copyTo(zipStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id} ${galleryBlock.title}")
|
||||
|
||||
try {
|
||||
target.canonicalPath
|
||||
} catch (e: IOException) {
|
||||
target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}")
|
||||
|
||||
try {
|
||||
target.canonicalPath
|
||||
} catch (e: IOException) {
|
||||
onError?.invoke()
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
|
||||
images.copyRecursively(target, true)
|
||||
}
|
||||
|
||||
onSuccess?.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
8
app/src/main/res/drawable/ic_export.xml
Normal file
8
app/src/main/res/drawable/ic_export.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<!-- drawable/export.xml -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path android:fillColor="#fff" android:pathData="M23,12L19,8V11H10V13H19V16M1,18V6C1,4.89 1.9,4 3,4H15A2,2 0 0,1 17,6V9H15V6H3V18H15V15H17V18A2,2 0 0,1 15,20H3A2,2 0 0,1 1,18Z" />
|
||||
</vector>
|
||||
@@ -51,6 +51,14 @@
|
||||
app:fab_label="@string/reader_fab_download"
|
||||
app:fab_size="mini"/>
|
||||
|
||||
<com.github.clans.fab.FloatingActionButton
|
||||
android:id="@+id/reader_fab_export"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_export"
|
||||
app:fab_label="@string/main_dialog_export"
|
||||
app:fab_size="mini"/>
|
||||
|
||||
<com.github.clans.fab.FloatingActionButton
|
||||
android:id="@+id/reader_fab_fullscreen"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/main_dialog_download"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/main_export"
|
||||
android:id="@+id/main_dialog_export"
|
||||
style="?borderlessButtonStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -41,8 +41,6 @@
|
||||
<string name="main_drawer_group_contact_help">ヘルプ</string>
|
||||
<string name="main_drawer_group_contact_github">Github</string>
|
||||
<string name="main_drawer_group_contact_email">メールを送る</string>
|
||||
<string name="help_dialog_title">準備中</string>
|
||||
<string name="help_dialog_message">準備中です。</string>
|
||||
<string name="reader_fab_fullscreen">フルスクリーン</string>
|
||||
<string name="channel_download">ダウンロード</string>
|
||||
<string name="channel_download_description">ダウンロードの進行を通知</string>
|
||||
@@ -60,4 +58,9 @@
|
||||
<string name="https_block_alert_title">(Korean only)</string>
|
||||
<string name="https_block_alert">(Korean only)</string>
|
||||
<string name="main_dialog_export">ギャラリーエクスポート</string>
|
||||
<string name="main_export_complete">エクスポート完了</string>
|
||||
<string name="main_export_open_folder">フォルダを開く</string>
|
||||
<string name="main_export_error">エクスポートエラーが発生しました</string>
|
||||
<string name="settings_export_zip_title">zipエクスポート</string>
|
||||
<string name="settings_export_zip_summary">イメージフォルダの代わりzipファイルでエクスポート</string>
|
||||
</resources>
|
||||
@@ -41,8 +41,6 @@
|
||||
<string name="main_drawer_group_contact_help">도움말</string>
|
||||
<string name="main_drawer_group_contact_homepage">홈페이지</string>
|
||||
<string name="main_drawer_group_contact_title">문의</string>
|
||||
<string name="help_dialog_title">준비 중</string>
|
||||
<string name="help_dialog_message">준비중입니다.</string>
|
||||
<string name="reader_fab_fullscreen">전체 화면</string>
|
||||
<string name="channel_download">다운로드</string>
|
||||
<string name="channel_download_description">다운로드 상태 알림</string>
|
||||
@@ -59,5 +57,10 @@
|
||||
<string name="main_move">%1$d 페이지로 이동</string>
|
||||
<string name="https_block_alert_title">접속 불가 현상 안내</string>
|
||||
<string name="https_block_alert">최근 https 차단으로 접속이 안 되는 경우가 발생하고 있습니다\n이 경우 플레이스토어에서 SNIper앱을 이용하시면 정상이용이 가능합니다.</string>
|
||||
<string name="main_dialog_export">갤러리 저장</string>
|
||||
<string name="main_dialog_export">갤러리 내보내기</string>
|
||||
<string name="main_export_complete">내보내기 완료</string>
|
||||
<string name="main_export_open_folder">폴더 열기</string>
|
||||
<string name="main_export_error">내보내기 오류가 발생했습니다</string>
|
||||
<string name="settings_export_zip_title">zip 파일로 내보내기</string>
|
||||
<string name="settings_export_zip_summary">이미지 폴더 대신 zip 파일로 내보내기</string>
|
||||
</resources>
|
||||
@@ -5,6 +5,7 @@
|
||||
<string name="release_name" translatable="false">Pupil-v(\\d+\\.)+\\d+\\.apk</string>
|
||||
|
||||
<string name="home_page" translatable="false">https://tom5079.github.io/Pupil</string>
|
||||
<string name="help" translatable="false">https://tom5079.github.io/Pupil/2019/06/02/manual-kr.html</string>
|
||||
<string name="github" translatable="false">https://github.com/tom5079/Pupil-issue/issues/new/choose</string>
|
||||
<string name="email" translatable="false">mailto:pupil.hentai@gmail.com</string>
|
||||
|
||||
@@ -48,8 +49,9 @@
|
||||
<string name="main_dialog_delete">Delete this gallery</string>
|
||||
<string name="main_dialog_export">Export this gallery</string>
|
||||
|
||||
<string name="help_dialog_title">WIP</string>
|
||||
<string name="help_dialog_message">While in progress!</string>
|
||||
<string name="main_export_complete">Export completed</string>
|
||||
<string name="main_export_open_folder">Open Folder</string>
|
||||
<string name="main_export_error">Error occurred during export</string>
|
||||
|
||||
<string name="update_title">Update available</string>
|
||||
<string name="update_download_started">Download started</string>
|
||||
@@ -85,6 +87,8 @@
|
||||
<string name="settings_miscellaneous_title">Miscellaneous</string>
|
||||
<string name="settings_use_hiyobi_title">Use hiyobi.me</string>
|
||||
<string name="settings_use_hiyobi_summary">Load images from hiyobi.me to improve loading speed (if available)</string>
|
||||
<string name="settings_export_zip_title">Export zip</string>
|
||||
<string name="settings_export_zip_summary">Export to zip instead of image folder</string>
|
||||
<string name="settings_security_mode_title">Enable security mode</string>
|
||||
<string name="settings_security_mode_summary">Enable security mode to make the screen invisible on recent app window</string>
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<external-path name="Download" path="Download"/>
|
||||
</paths>
|
||||
@@ -42,6 +42,11 @@
|
||||
app:title="@string/settings_use_hiyobi_title"
|
||||
app:summary="@string/settings_use_hiyobi_summary"/>
|
||||
|
||||
<SwitchPreference
|
||||
app:key="export_zip"
|
||||
app:title="@string/settings_export_zip_title"
|
||||
app:summary="@string/settings_export_zip_summary"/>
|
||||
|
||||
<SwitchPreference
|
||||
app:key="security_mode"
|
||||
app:title="@string/settings_security_mode_title"
|
||||
|
||||
Reference in New Issue
Block a user