Compare commits

...

7 Commits

Author SHA1 Message Date
tom5079
a8de1429c1 Bug fix 2020-09-11 19:53:49 +09:00
tom5079
3ba6cb81ae Bug fix 2020-09-11 19:40:56 +09:00
tom5079
acc85da80f Bug fix 2020-09-10 22:47:57 +09:00
tom5079
b53de8624d Bug fix 2020-09-10 22:45:27 +09:00
tom5079
6e2eeb29cc Bug fix 2020-09-10 21:41:57 +09:00
tom5079
62eb28ac01 Bug fix 2020-09-10 19:44:08 +09:00
tom5079
fd298529bf Memory usage optimization 2020-09-10 19:16:42 +09:00
18 changed files with 126 additions and 89 deletions

1
.idea/vcs.xml generated
View File

@@ -2,5 +2,6 @@
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" /> <mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/gh-pages" vcs="Git" />
</component> </component>
</project> </project>

View File

@@ -20,8 +20,8 @@ android {
applicationId "xyz.quaver.pupil" applicationId "xyz.quaver.pupil"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 30 targetSdkVersion 30
versionCode 57 versionCode 58
versionName "5.0-beta8" versionName "5.0-hotfix4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
} }
@@ -99,7 +99,7 @@ dependencies {
implementation 'com.andrognito.patternlockview:patternlockview:1.0.0' implementation 'com.andrognito.patternlockview:patternlockview:1.0.0'
//implementation 'com.andrognito.pinlockview:pinlockview:2.1.0' //implementation 'com.andrognito.pinlockview:pinlockview:2.1.0'
implementation "ru.noties.markwon:core:3.1.0" implementation "ru.noties.markwon:core:3.1.0"
implementation ("xyz.quaver:libpupil:1.5") { implementation ("xyz.quaver:libpupil:1.6") {
exclude group: 'org.jetbrains.kotlinx', module: 'kotlinx-serialization-core-jvm' exclude group: 'org.jetbrains.kotlinx', module: 'kotlinx-serialization-core-jvm'
} }
implementation "xyz.quaver:documentfilex:0.2.15" implementation "xyz.quaver:documentfilex:0.2.15"

View File

@@ -11,8 +11,8 @@
"type": "SINGLE", "type": "SINGLE",
"filters": [], "filters": [],
"properties": [], "properties": [],
"versionCode": 57, "versionCode": 58,
"versionName": "5.0-beta8", "versionName": "5.0-hotfix4",
"enabled": true, "enabled": true,
"outputFile": "app-release.apk" "outputFile": "app-release.apk"
} }

View File

@@ -18,10 +18,7 @@
package xyz.quaver.pupil package xyz.quaver.pupil
import android.app.Application import android.app.*
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
@@ -43,6 +40,7 @@ import okhttp3.Response
import xyz.quaver.io.FileX import xyz.quaver.io.FileX
import xyz.quaver.pupil.types.Tag import xyz.quaver.pupil.types.Tag
import xyz.quaver.pupil.util.* import xyz.quaver.pupil.util.*
import xyz.quaver.pupil.util.downloader.DownloadManager
import xyz.quaver.setClient import xyz.quaver.setClient
import java.io.File import java.io.File
import java.util.* import java.util.*
@@ -110,6 +108,8 @@ class Pupil : Application() {
if (!FileX(this, it).canWrite()) if (!FileX(this, it).canWrite())
throw Exception() throw Exception()
DownloadManager.getInstance(this).migrate()
} }
} catch (e: Exception) { } catch (e: Exception) {
Preferences.remove("download_folder") Preferences.remove("download_folder")

View File

@@ -42,6 +42,7 @@ import xyz.quaver.hitomi.getReferer
import xyz.quaver.hitomi.imageUrlFromImage import xyz.quaver.hitomi.imageUrlFromImage
import xyz.quaver.hiyobi.createImgList import xyz.quaver.hiyobi.createImgList
import xyz.quaver.io.util.readBytes import xyz.quaver.io.util.readBytes
import xyz.quaver.pupil.BuildConfig
import xyz.quaver.pupil.R import xyz.quaver.pupil.R
import xyz.quaver.pupil.services.DownloadService import xyz.quaver.pupil.services.DownloadService
import xyz.quaver.pupil.ui.ReaderActivity import xyz.quaver.pupil.ui.ReaderActivity
@@ -81,14 +82,9 @@ class ReaderAdapter(private val activity: ReaderActivity,
cache = Cache.getInstance(holder.view.context, galleryID) cache = Cache.getInstance(holder.view.context, galleryID)
if (isFullScreen) { if (isFullScreen) {
holder.view.layoutParams.height = RecyclerView.LayoutParams.MATCH_PARENT
holder.view.container.layoutParams.height = ConstraintLayout.LayoutParams.MATCH_PARENT holder.view.container.layoutParams.height = ConstraintLayout.LayoutParams.MATCH_PARENT
} else { } else {
holder.view.layoutParams.height = RecyclerView.LayoutParams.WRAP_CONTENT holder.view.container.layoutParams.height = ConstraintLayout.LayoutParams.WRAP_CONTENT
holder.view.container.layoutParams.height = 0
(holder.view.container.layoutParams as ConstraintLayout.LayoutParams)
.dimensionRatio = "W,${reader!!.galleryInfo.files[position].width}:${reader!!.galleryInfo.files[position].height}"
} }
holder.view.image.setOnPhotoTapListener { _, _, _ -> holder.view.image.setOnPhotoTapListener { _, _, _ ->
@@ -122,7 +118,16 @@ class ReaderAdapter(private val activity: ReaderActivity,
.load(url!!) .load(url!!)
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(false) .skipMemoryCache(false)
.fitCenter() .error(R.drawable.image_broken_variant)
.apply {
if (BuildConfig.CENSOR)
override(5, 8)
else
override(
holder.view.context.resources.displayMetrics.widthPixels,
holder.view.context.resources.getDimensionPixelSize(R.dimen.reader_max_height)
)
}
.error(R.drawable.image_broken_variant) .error(R.drawable.image_broken_variant)
.into(holder.view.image) .into(holder.view.image)
} }
@@ -138,7 +143,15 @@ class ReaderAdapter(private val activity: ReaderActivity,
.load(image.readBytes()) .load(image.readBytes())
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true) .skipMemoryCache(true)
.fitCenter() .apply {
if (BuildConfig.CENSOR)
override(5, 8)
else
override(
holder.view.context.resources.displayMetrics.widthPixels,
holder.view.context.resources.getDimensionPixelSize(R.dimen.reader_max_height)
)
}
.error(R.drawable.image_broken_variant) .error(R.drawable.image_broken_variant)
.listener(object: RequestListener<Drawable> { .listener(object: RequestListener<Drawable> {
override fun onLoadFailed( override fun onLoadFailed(
@@ -154,8 +167,13 @@ class ReaderAdapter(private val activity: ReaderActivity,
return true return true
} }
override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean) = override fun onResourceReady(
false resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
dataSource: DataSource?,
isFirstResource: Boolean
) = false
}).let { launch(Dispatchers.Main) { it.into(holder.view.image) } } }).let { launch(Dispatchers.Main) { it.into(holder.view.image) } }
} }
} else { } else {

View File

@@ -27,6 +27,7 @@ import android.util.SparseArray
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import androidx.core.app.TaskStackBuilder import androidx.core.app.TaskStackBuilder
import androidx.core.content.ContextCompat
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@@ -46,7 +47,6 @@ import xyz.quaver.pupil.util.downloader.DownloadManager
import xyz.quaver.pupil.util.ellipsize import xyz.quaver.pupil.util.ellipsize
import xyz.quaver.pupil.util.normalizeID import xyz.quaver.pupil.util.normalizeID
import xyz.quaver.pupil.util.requestBuilders import xyz.quaver.pupil.util.requestBuilders
import xyz.quaver.pupil.util.startForegroundServiceCompat
import java.io.IOException import java.io.IOException
private typealias ProgressListener = (DownloadService.Tag, Long, Long, Boolean) -> Unit private typealias ProgressListener = (DownloadService.Tag, Long, Long, Boolean) -> Unit
@@ -215,7 +215,7 @@ class DownloadService : Service() {
val ext = call.request().url().encodedPath().split('.').last() val ext = call.request().url().encodedPath().split('.').last()
kotlin.runCatching { kotlin.runCatching {
val image = response.body()?.use { it.bytes() } ?: throw Exception() val image = response.also { if (it.code() != 200) throw IOException() }.body()?.use { it.bytes() } ?: throw Exception()
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
kotlin.runCatching { kotlin.runCatching {
@@ -354,7 +354,7 @@ class DownloadService : Service() {
const val COMMAND_DELETE = "DELETE" const val COMMAND_DELETE = "DELETE"
private fun command(context: Context, extras: Intent.() -> Unit) { private fun command(context: Context, extras: Intent.() -> Unit) {
context.startForegroundServiceCompat(Intent(context, DownloadService::class.java).apply(extras)) ContextCompat.startForegroundService(context, Intent(context, DownloadService::class.java).apply(extras))
} }
fun download(context: Context, galleryID: Int, priority: Boolean = false) { fun download(context: Context, galleryID: Int, priority: Boolean = false) {
@@ -381,6 +381,8 @@ class DownloadService : Service() {
} }
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
startForeground(R.id.downloader_notification_id, serviceNotification.build())
when (intent?.getStringExtra(KEY_COMMAND)) { when (intent?.getStringExtra(KEY_COMMAND)) {
COMMAND_DOWNLOAD -> intent.getIntExtra(KEY_ID, -1).let { if (it > 0) COMMAND_DOWNLOAD -> intent.getIntExtra(KEY_ID, -1).let { if (it > 0)
download(it, intent.getBooleanExtra(KEY_PRIORITY, false), startId) download(it, intent.getBooleanExtra(KEY_PRIORITY, false), startId)

View File

@@ -39,10 +39,10 @@ import xyz.quaver.pupil.util.Lock
import xyz.quaver.pupil.util.LockManager import xyz.quaver.pupil.util.LockManager
import xyz.quaver.pupil.util.Preferences import xyz.quaver.pupil.util.Preferences
private var lastUnlocked = 0L
class LockActivity : AppCompatActivity() { class LockActivity : AppCompatActivity() {
private lateinit var lockManager: LockManager private lateinit var lockManager: LockManager
private var lastUnlocked = 0L
private var mode: String? = null private var mode: String? = null
private val patternLockFragment = PatternLockFragment().apply { private val patternLockFragment = PatternLockFragment().apply {

View File

@@ -968,4 +968,14 @@ class MainActivity :
} }
} }
} }
override fun onLowMemory() {
super.onLowMemory()
Glide.get(this).onLowMemory()
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
Glide.get(this).onTrimMemory(level)
}
} }

View File

@@ -35,6 +35,7 @@ import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.vectordrawable.graphics.drawable.Animatable2Compat import androidx.vectordrawable.graphics.drawable.Animatable2Compat
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
import com.bumptech.glide.Glide
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.firebase.crashlytics.FirebaseCrashlytics import com.google.firebase.crashlytics.FirebaseCrashlytics
import kotlinx.android.synthetic.main.activity_reader.* import kotlinx.android.synthetic.main.activity_reader.*
@@ -473,4 +474,14 @@ class ReaderActivity : BaseActivity() {
} }
} }
} }
override fun onLowMemory() {
super.onLowMemory()
Glide.get(this).onLowMemory()
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
Glide.get(this).onTrimMemory(level)
}
} }

View File

@@ -123,7 +123,7 @@ class DownloadLocationDialogFragment : DialogFragment() {
.setView(build()) .setView(build())
.setPositiveButton(requireContext().getText(android.R.string.ok)) { _, _ -> .setPositiveButton(requireContext().getText(android.R.string.ok)) { _, _ ->
if (Preferences["download_folder", ""].isEmpty()) if (Preferences["download_folder", ""].isEmpty())
Preferences["download_folder"] = context?.getExternalFilesDir(null)?.canonicalPath ?: "" Preferences["download_folder"] = context?.getExternalFilesDir(null)?.toUri()?.toString() ?: ""
DownloadManager.getInstance(requireContext()).migrate() DownloadManager.getInstance(requireContext()).migrate()
} }

View File

@@ -62,6 +62,11 @@ class ManageFavoritesFragment : PreferenceFragmentCompat() {
} }
override fun onResponse(call: Call, response: Response) { override fun onResponse(call: Call, response: Response) {
if (response.code() != 200) {
response.close()
return
}
Intent(Intent.ACTION_SEND).apply { Intent(Intent.ACTION_SEND).apply {
type = "text/plain" type = "text/plain"
putExtra(Intent.EXTRA_TEXT, response.body()?.use { it.string() }?.replace("\n", "")) putExtra(Intent.EXTRA_TEXT, response.body()?.use { it.string() }?.replace("\n", ""))

View File

@@ -277,6 +277,12 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
} }
override fun onResponse(call: Call, response: Response) { override fun onResponse(call: Call, response: Response) {
if (response.code() != 200) {
response.close()
onFailure(call, IOException())
return
}
val ext = call.request().url().encodedPath().split('.').last() val ext = call.request().url().encodedPath().split('.').last()
try { try {

View File

@@ -37,6 +37,7 @@ import xyz.quaver.io.FileX
import xyz.quaver.io.util.* import xyz.quaver.io.util.*
import xyz.quaver.pupil.client import xyz.quaver.pupil.client
import xyz.quaver.pupil.util.Preferences import xyz.quaver.pupil.util.Preferences
import java.io.IOException
@Serializable @Serializable
data class Metadata( data class Metadata(
@@ -138,7 +139,7 @@ class Cache private constructor(context: Context, val galleryID: Int) : ContextW
.url(it) .url(it)
.build() .build()
client.newCall(request).execute().body()?.use { it.bytes() } client.newCall(request).execute().also { if (it.code() != 200) throw IOException() }.body()?.use { it.bytes() }
}.getOrNull()?.also { kotlin.run { }.getOrNull()?.also { kotlin.run {
cacheFolder.getChild(".thumbnail").writeBytes(it) cacheFolder.getChild(".thumbnail").writeBytes(it)
} } } }

View File

@@ -75,7 +75,6 @@ class DownloadManager private constructor(context: Context) : ContextWrapper(con
data ?: { data ?: {
file.createNewFile() file.createNewFile()
file.writeText("{}")
mutableMapOf<Int, String>() mutableMapOf<Int, String>()
}.invoke() }.invoke()
}.invoke() }.invoke()
@@ -99,9 +98,6 @@ class DownloadManager private constructor(context: Context) : ContextWrapper(con
@Synchronized @Synchronized
fun addDownloadFolder(galleryID: Int) { fun addDownloadFolder(galleryID: Int) {
if (downloadFolderMap.containsKey(galleryID))
return
val name = runBlocking { val name = runBlocking {
Cache.getInstance(this@DownloadManager, galleryID).getGalleryBlock() Cache.getInstance(this@DownloadManager, galleryID).getGalleryBlock()
}?.formatDownloadFolder() ?: return }?.formatDownloadFolder() ?: return
@@ -119,9 +115,6 @@ class DownloadManager private constructor(context: Context) : ContextWrapper(con
@Synchronized @Synchronized
fun deleteDownloadFolder(galleryID: Int) { fun deleteDownloadFolder(galleryID: Int) {
if (!downloadFolderMap.containsKey(galleryID))
return
downloadFolderMap[galleryID]?.let { downloadFolderMap[galleryID]?.let {
kotlin.runCatching { kotlin.runCatching {
downloadFolder.getChild(it).deleteRecursively() downloadFolder.getChild(it).deleteRecursively()

View File

@@ -22,6 +22,7 @@ import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import androidx.core.content.ContextCompat
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import xyz.quaver.Code import xyz.quaver.Code
@@ -92,21 +93,14 @@ fun GalleryBlock.formatDownloadFolder(): String =
formatMap.entries.fold(it) { str, (k, v) -> formatMap.entries.fold(it) { str, (k, v) ->
str.replace(k, v.invoke(this), true) str.replace(k, v.invoke(this), true)
} }
} }.replace("/", "")
fun GalleryBlock.formatDownloadFolderTest(format: String): String = fun GalleryBlock.formatDownloadFolderTest(format: String): String =
format.let { format.let {
formatMap.entries.fold(it) { str, (k, v) -> formatMap.entries.fold(it) { str, (k, v) ->
str.replace(k, v.invoke(this), true) str.replace(k, v.invoke(this), true)
} }
} }.replace("/", "")
fun Context.startForegroundServiceCompat(service: Intent) {
if (Build.VERSION.SDK_INT >= 26)
startForegroundService(service)
else
startService(service)
}
val Reader.requestBuilders: List<Request.Builder> val Reader.requestBuilders: List<Request.Builder>
get() { get() {

View File

@@ -214,7 +214,7 @@ fun restore(url: String, onFailure: ((Throwable) -> Unit)? = null, onSuccess: ((
override fun onResponse(call: Call, response: Response) { override fun onResponse(call: Call, response: Response) {
kotlin.runCatching { kotlin.runCatching {
Json.decodeFromString<List<Int>>(response.body().use { it?.string() } ?: "[]").let { Json.decodeFromString<List<Int>>(response.also { if (it.code() != 200) throw IOException() }.body().use { it?.string() } ?: "[]").let {
favorites.addAll(it) favorites.addAll(it)
onSuccess?.invoke(it) onSuccess?.invoke(it)
} }
@@ -258,7 +258,12 @@ fun xyz.quaver.pupil.util.downloader.DownloadManager.migrate() {
job?.cancel() job?.cancel()
job = CoroutineScope(Dispatchers.IO).launch { job = CoroutineScope(Dispatchers.IO).launch {
val downloadFolders = downloadFolder.listFiles { folder -> val downloadFolders = downloadFolder.listFiles { folder ->
(folder as? FileX)?.isDirectory == true && !downloadFolderMap.values.contains(folder.name) folder.isDirectory && !downloadFolderMap.values.contains(folder.name)
}?.map {
if (it !is FileX)
FileX(this@migrate, it)
else
it
} }
if (downloadFolders.isNullOrEmpty()) return@launch if (downloadFolders.isNullOrEmpty()) return@launch
@@ -270,8 +275,6 @@ fun xyz.quaver.pupil.util.downloader.DownloadManager.migrate() {
notificationManager.notify(R.id.notification_id_import, notification.build()) notificationManager.notify(R.id.notification_id_import, notification.build())
kotlin.runCatching { kotlin.runCatching {
if (folder !is FileX) return@runCatching
val metadata = kotlin.runCatching { val metadata = kotlin.runCatching {
folder.getChild(".metadata").readText()?.let { Json.parseToJsonElement(it).jsonObject } folder.getChild(".metadata").readText()?.let { Json.parseToJsonElement(it).jsonObject }
}.getOrNull() }.getOrNull()

View File

@@ -17,61 +17,52 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"> app:layout_constraintHeight_max="2000dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:paddingBottom="8dp"
android:background="@drawable/reader_item_boundary">
<androidx.constraintlayout.widget.ConstraintLayout <LinearLayout
android:id="@+id/container" android:layout_width="wrap_content"
android:layout_width="0dp" android:layout_height="wrap_content"
android:layout_height="0dp"
app:layout_constraintHeight_max="2000dp"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintEnd_toEndOf="parent"
android:background="@drawable/reader_item_boundary"> android:gravity="center_horizontal"
android:orientation="vertical">
<LinearLayout <ProgressBar
android:id="@+id/reader_item_progressbar"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent" style="?android:progressBarStyleHorizontal"
app:layout_constraintBottom_toBottomOf="parent" android:indeterminate="false"
app:layout_constraintStart_toStartOf="parent" android:progress="0"
app:layout_constraintEnd_toEndOf="parent" android:max="100"
android:gravity="center_horizontal" android:visibility="visible"/>
android:orientation="vertical">
<ProgressBar <TextView
android:id="@+id/reader_item_progressbar" android:id="@+id/reader_index"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
style="?android:progressBarStyleHorizontal" style="@style/TextAppearance.AppCompat.Caption"/>
android:indeterminate="false"
android:progress="0"
android:max="100"
android:visibility="visible"/>
<TextView </LinearLayout>
android:id="@+id/reader_index"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/TextAppearance.AppCompat.Caption"/>
</LinearLayout> <com.github.chrisbanes.photoview.PhotoView
android:id="@+id/image"
<com.github.chrisbanes.photoview.PhotoView android:adjustViewBounds="true"
android:id="@+id/image" android:scaleType="fitXY"
android:adjustViewBounds="true" android:layout_width="match_parent"
android:scaleType="fitCenter" android:layout_height="wrap_content"
android:layout_width="match_parent" app:layout_constraintTop_toTopOf="parent"
android:layout_height="match_parent" app:layout_constraintBottom_toBottomOf="parent"/>
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:paddingBottom="8dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -5,4 +5,6 @@
<dimen name="activity_vertical_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="galleryblock_thumbnail_thin">100dp</dimen> <dimen name="galleryblock_thumbnail_thin">100dp</dimen>
<dimen name="reader_max_height">2000dp</dimen>
</resources> </resources>