diff --git a/app/build.gradle b/app/build.gradle index 3935d108..da8a39ab 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "xyz.quaver.pupil" minSdkVersion 16 targetSdkVersion 28 - versionCode 14 - versionName "2.7" + versionCode 15 + versionName "2.8" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/app/release/output.json b/app/release/output.json new file mode 100644 index 00000000..456cc06e --- /dev/null +++ b/app/release/output.json @@ -0,0 +1 @@ +[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":15,"versionName":"2.8","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt index feaa0bab..1933c54e 100644 --- a/app/src/main/java/xyz/quaver/pupil/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/MainActivity.kt @@ -6,7 +6,6 @@ import android.content.pm.PackageManager import android.graphics.drawable.Animatable import android.net.Uri import android.os.Bundle -import android.os.Environment import android.preference.PreferenceManager import android.text.* import android.text.style.AlignmentSpan @@ -32,14 +31,12 @@ 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.ImplicitReflectionSerializer import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonConfiguration import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.content import kotlinx.serialization.list -import kotlinx.serialization.parseList import kotlinx.serialization.stringify import ru.noties.markwon.Markwon import xyz.quaver.hitomi.* @@ -49,12 +46,9 @@ import xyz.quaver.pupil.types.TagSuggestion import xyz.quaver.pupil.types.Tags 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 @@ -116,6 +110,13 @@ class MainActivity : AppCompatActivity() { initView() } + override fun onDestroy() { + super.onDestroy() + + if (cacheDir.exists()) + cacheDir.deleteRecursively() + } + override fun onBackPressed() { when { main_drawer_layout.isDrawerOpen(GravityCompat.START) -> main_drawer_layout.closeDrawer(GravityCompat.START) @@ -249,7 +250,7 @@ class MainActivity : AppCompatActivity() { val msg = extractReleaseNote(update, Locale.getDefault().language) setMessage(Markwon.create(context).toMarkdown(msg)) setPositiveButton(android.R.string.yes) { _, _ -> - startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.home_page)))) + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.update)))) } setNegativeButton(android.R.string.no) { _, _ ->} } @@ -330,6 +331,9 @@ class MainActivity : AppCompatActivity() { R.id.main_drawer_email -> { startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.email)))) } + R.id.main_drawer_kakaotalk -> { + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.kakaotalk)))) + } } } @@ -411,7 +415,7 @@ class MainActivity : AppCompatActivity() { this?.clearNotification() } val cache = File(cacheDir, "imageCache/${galleryBlock.id}") - val data = File(ContextCompat.getDataDir(this@MainActivity), "images/${galleryBlock.id}") + val data = getCachedGallery(context, galleryBlock.id) cache.deleteRecursively() data.deleteRecursively() @@ -431,73 +435,6 @@ 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 @@ -1058,18 +995,18 @@ class MainActivity : AppCompatActivity() { galleryIDs.slice(currentPage*perPage until Math.min(currentPage*perPage+perPage, galleryIDs.size)) }.chunked(5).let { chunks -> for (chunk in chunks) - chunk.map { + chunk.map { galleryID -> async { try { val json = Json(JsonConfiguration.Stable) val serializer = GalleryBlock.serializer() val galleryBlock = - File(cacheDir, "imageCache/$it/galleryBlock.json").let { cache -> + File(getCachedGallery(this@MainActivity, galleryID), "galleryBlock.json").let { cache -> when { cache.exists() -> json.parse(serializer, cache.readText()) else -> { - getGalleryBlock(it).apply { + getGalleryBlock(galleryID).apply { this ?: return@apply if (!cache.parentFile.exists()) @@ -1083,19 +1020,17 @@ class MainActivity : AppCompatActivity() { val thumbnail = async { val ext = galleryBlock.thumbnails[0].split('.').last() - File(cacheDir, "imageCache/$it/thumbnail.$ext").apply { - val cache = this - - if (!cache.exists()) + File(getCachedGallery(this@MainActivity, galleryBlock.id), "thumbnail.$ext").apply { + if (!exists()) try { with(URL(galleryBlock.thumbnails[0]).openConnection() as HttpsURLConnection) { - if (!cache.parentFile.exists()) - cache.parentFile.mkdirs() + if (!this@apply.parentFile.exists()) + this@apply.parentFile.mkdirs() - inputStream.copyTo(FileOutputStream(cache)) + inputStream.copyTo(FileOutputStream(this@apply)) } } catch (e: Exception) { - cache.delete() + delete() } }.absolutePath } diff --git a/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt b/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt index 263eebd1..d5d92b2f 100644 --- a/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ReaderActivity.kt @@ -6,7 +6,6 @@ import android.os.Bundle import android.view.* import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity -import androidx.core.content.ContextCompat import androidx.preference.PreferenceManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearSmoothScroller @@ -25,16 +24,11 @@ import kotlinx.io.IOException import kotlinx.serialization.ImplicitReflectionSerializer import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonConfiguration -import kotlinx.serialization.list -import kotlinx.serialization.stringify import xyz.quaver.hitomi.GalleryBlock import xyz.quaver.pupil.adapters.ReaderAdapter -import xyz.quaver.pupil.types.Tag -import xyz.quaver.pupil.types.Tags import xyz.quaver.pupil.util.GalleryDownloader import xyz.quaver.pupil.util.Histories import xyz.quaver.pupil.util.ItemClickSupport -import java.io.File class ReaderActivity : AppCompatActivity() { @@ -309,14 +303,6 @@ 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) { diff --git a/app/src/main/java/xyz/quaver/pupil/SettingsActivity.kt b/app/src/main/java/xyz/quaver/pupil/SettingsActivity.kt index 9f7b30be..e93b0166 100644 --- a/app/src/main/java/xyz/quaver/pupil/SettingsActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/SettingsActivity.kt @@ -1,6 +1,7 @@ package xyz.quaver.pupil import android.os.Bundle +import android.os.Environment import android.preference.PreferenceManager import android.text.Editable import android.text.TextWatcher @@ -12,7 +13,6 @@ import android.widget.LinearLayout import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity -import androidx.core.content.ContextCompat import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import kotlinx.android.synthetic.main.dialog_default_query.view.* @@ -67,39 +67,16 @@ class SettingsActivity : AppCompatActivity() { suffixIndex++ } - return getString(R.string.settings_clear_cache_summary, size, suffix[suffixIndex]) + return getString(R.string.settings_clear_downloads_summary, size, suffix[suffixIndex]) } override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.root_preferences, rootKey) - with(findPreference("delete_image_cache")) { - this ?: return@with - - val dir = File(context.cacheDir, "imageCache") - - summary = getCacheSize(dir) - - setOnPreferenceClickListener { - AlertDialog.Builder(context).apply { - setTitle(R.string.warning) - setMessage(R.string.settings_clear_cache_alert_message) - setPositiveButton(android.R.string.yes) { _, _ -> - if (dir.exists()) - dir.deleteRecursively() - - summary = getCacheSize(dir) - } - setNegativeButton(android.R.string.no) { _, _ -> } - }.show() - - true - } - } with(findPreference("delete_downloads")) { this ?: return@with - val dir = File(ContextCompat.getDataDir(context), "images") + val dir = File(Environment.getExternalStorageDirectory(), "Pupil") summary = getCacheSize(dir) diff --git a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt index 96f5b609..12080356 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt @@ -1,12 +1,13 @@ package xyz.quaver.pupil.adapters +import android.app.AlertDialog import android.graphics.BitmapFactory import android.graphics.drawable.Animatable -import android.util.Log import android.util.SparseBooleanArray import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.ArrayAdapter import android.widget.LinearLayout import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat @@ -27,6 +28,7 @@ import xyz.quaver.pupil.Pupil import xyz.quaver.pupil.R import xyz.quaver.pupil.types.Tag import xyz.quaver.pupil.util.Histories +import xyz.quaver.pupil.util.getCachedGallery import java.io.File import java.util.* import kotlin.collections.ArrayList @@ -53,10 +55,10 @@ class GalleryBlockAdapter(private val galleries: List) = item + val (galleryBlock: GalleryBlock, thumbnail: Deferred) = item - val artists = gallery.artists - val series = gallery.series + val artists = galleryBlock.artists + val series = galleryBlock.series CoroutineScope(Dispatchers.Default).launch { val cache = thumbnail.await() @@ -72,22 +74,8 @@ class GalleryBlockAdapter(private val galleries: List it - else -> File(context.cacheDir, "imageCache/${gallery.id}/reader.json") - } - } - } - val imageCache = { - File(ContextCompat.getDataDir(context), "images/${gallery.id}/images").let { - when { - it.exists() -> it - else -> File(context.cacheDir, "imageCache/${gallery.id}/images") - } - } - } + val readerCache = { File(getCachedGallery(context, galleryBlock.id), "reader.json") } + val imageCache = { File(getCachedGallery(context, galleryBlock.id), "images") } if (readerCache.invoke().exists()) { val reader = Json(JsonConfiguration.Stable) @@ -124,7 +112,7 @@ class GalleryBlockAdapter(private val galleries: List View.VISIBLE else -> View.GONE } + setOnClickListener { + if (artists.size > 1) { + AlertDialog.Builder(context).apply { + setAdapter(ArrayAdapter(context, android.R.layout.select_dialog_item, artists)) { _, index -> + for (callback in onChipClickedHandler) + callback.invoke(Tag("artist", artists[index])) + } + }.show() + } else { + for(callback in onChipClickedHandler) + callback.invoke(Tag("artist", artists.first())) + } + } } with(galleryblock_series) { text = @@ -167,20 +168,54 @@ class GalleryBlockAdapter(private val galleries: List View.VISIBLE else -> View.GONE } + setOnClickListener { + setOnClickListener { + if (series.size > 1) { + AlertDialog.Builder(context).apply { + setAdapter(ArrayAdapter(context, android.R.layout.select_dialog_item, series)) { _, index -> + for (callback in onChipClickedHandler) + callback.invoke(Tag("series", series[index])) + } + }.show() + } else { + for(callback in onChipClickedHandler) + callback.invoke(Tag("series", series.first())) + } + } + } + } + with(galleryblock_type) { + text = resources.getString(R.string.galleryblock_type, galleryBlock.type).wordCapitalize() + setOnClickListener { + setOnClickListener { + for(callback in onChipClickedHandler) + callback.invoke(Tag("type", galleryBlock.type)) + } + } } - galleryblock_type.text = resources.getString(R.string.galleryblock_type, gallery.type).wordCapitalize() with(galleryblock_language) { text = - resources.getString(R.string.galleryblock_language, languages[gallery.language]) + resources.getString(R.string.galleryblock_language, languages[galleryBlock.language]) visibility = when { - gallery.language.isNotEmpty() -> View.VISIBLE + galleryBlock.language.isNotEmpty() -> View.VISIBLE else -> View.GONE } + setOnClickListener { + setOnClickListener { + for(callback in onChipClickedHandler) + callback.invoke(Tag("language", galleryBlock.language)) + } + } } galleryblock_tag_group.removeAllViews() - gallery.relatedTags.forEach { - val tag = Tag.parse(it) + galleryBlock.relatedTags.forEach { + val tag = Tag.parse(it).let { tag -> + when { + tag.area != null -> tag + else -> Tag("tag", it) + } + } val chip = LayoutInflater.from(context) .inflate(R.layout.tag_chip, this, false) as Chip @@ -209,17 +244,19 @@ class GalleryBlockAdapter(private val galleries: List favorites.add(gallery.id) - else -> favorites.remove(gallery.id) + isChecked -> favorites.add(galleryBlock.id) + else -> favorites.remove(galleryBlock.id) } } setOnCheckedChangeListener { _, isChecked -> diff --git a/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt b/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt index 7fe99463..a579865e 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt @@ -1,6 +1,5 @@ package xyz.quaver.pupil.adapters -import android.graphics.Bitmap import android.graphics.BitmapFactory import android.view.LayoutInflater import android.view.View diff --git a/app/src/main/java/xyz/quaver/pupil/util/GalleryDownloader.kt b/app/src/main/java/xyz/quaver/pupil/util/GalleryDownloader.kt index 3b5a892e..f4e08369 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/GalleryDownloader.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/GalleryDownloader.kt @@ -9,7 +9,6 @@ import android.util.SparseArray import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.core.app.TaskStackBuilder -import androidx.core.content.ContextCompat import androidx.preference.PreferenceManager import kotlinx.coroutines.* import kotlinx.io.IOException @@ -23,12 +22,9 @@ 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 @@ -48,10 +44,10 @@ class GalleryDownloader( field = true notificationManager.notify(galleryBlock.id, notificationBuilder.build()) - val data = File(ContextCompat.getDataDir(this), "images/${galleryBlock.id}") + val data = getCachedGallery(this, galleryBlock.id) val cache = File(cacheDir, "imageCache/${galleryBlock.id}") - if (cache.exists() && !data.exists()) { + if (File(cache, "images").exists() && !data.exists()) { cache.copyRecursively(data, true) cache.deleteRecursively() } @@ -93,12 +89,7 @@ class GalleryDownloader( val serializer = ReaderItem.serializer().list //Check cache - val cache = File(ContextCompat.getDataDir(this@GalleryDownloader), "images/${galleryBlock.id}/reader.json").let { - when { - it.exists() -> it - else -> File(cacheDir, "imageCache/${galleryBlock.id}/reader.json") - } - } + val cache = File(getCachedGallery(this@GalleryDownloader, galleryBlock.id), "reader.json") if (cache.exists()) { val cached = json.parse(serializer, cache.readText()) @@ -181,12 +172,7 @@ class GalleryDownloader( val name = "$index".padStart(4, '0') val ext = url.split('.').last() - val cache = File(ContextCompat.getDataDir(this@GalleryDownloader), "images/${galleryBlock.id}/images/$name.$ext").let { - when { - it.exists() -> it - else -> File(cacheDir, "/imageCache/${galleryBlock.id}/images/$name.$ext") - } - } + val cache = File(getCachedGallery(this@GalleryDownloader, galleryBlock.id), "images/$name.$ext") if (!cache.exists()) try { @@ -234,31 +220,17 @@ class GalleryDownloader( if (download) { File(cacheDir, "imageCache/${galleryBlock.id}").let { if (it.exists()) { - it.copyRecursively( - File(ContextCompat.getDataDir(this@GalleryDownloader), "images/${galleryBlock.id}"), - true - ) + val target = File(Environment.getExternalStorageDirectory(), "Pupil/${galleryBlock.id}") + + if (!target.exists()) + target.mkdirs() + + it.copyRecursively(target, true) it.deleteRecursively() } } - val preference = PreferenceManager.getDefaultSharedPreferences(this@GalleryDownloader) - val autoExport = preference.getBoolean("auto_export", false) - - if (autoExport) { - export({ - notificationManager.notify(galleryBlock.id, notificationBuilder.build()) - }, { - notificationBuilder - .setContentTitle(galleryBlock.title) - .setContentText(getString(R.string.main_export_error)) - .setProgress(0, 0, false) - - notificationManager.notify(galleryBlock.id, notificationBuilder.build()) - }) - } else { - notificationManager.notify(galleryBlock.id, notificationBuilder.build()) - } + notificationManager.notify(galleryBlock.id, notificationBuilder.build()) } download = false @@ -314,69 +286,4 @@ 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() - } - } - } \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/util/file.kt b/app/src/main/java/xyz/quaver/pupil/util/file.kt new file mode 100644 index 00000000..7e085650 --- /dev/null +++ b/app/src/main/java/xyz/quaver/pupil/util/file.kt @@ -0,0 +1,14 @@ +package xyz.quaver.pupil.util + +import android.content.Context +import android.os.Environment +import java.io.File + +fun getCachedGallery(context: Context, galleryID: Int): File { + return File(Environment.getExternalStorageDirectory(), "Pupil/$galleryID").let { + when { + it.exists() -> it + else -> File(context.cacheDir, "imageCache/$galleryID") + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_message.xml b/app/src/main/res/drawable/ic_message.xml new file mode 100644 index 00000000..9536776c --- /dev/null +++ b/app/src/main/res/drawable/ic_message.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_numeric.xml b/app/src/main/res/drawable/ic_numeric.xml new file mode 100644 index 00000000..fc54c34a --- /dev/null +++ b/app/src/main/res/drawable/ic_numeric.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_reader.xml b/app/src/main/res/layout/activity_reader.xml index e9827e8d..9e49df68 100644 --- a/app/src/main/res/layout/activity_reader.xml +++ b/app/src/main/res/layout/activity_reader.xml @@ -51,14 +51,6 @@ app:fab_label="@string/reader_fab_download" app:fab_size="mini"/> - - -