├── app ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── dimens.xml │ │ │ └── styles.xml │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-hdpi │ │ │ ├── ic_star_black_24dp.png │ │ │ ├── ic_star_white_24dp.png │ │ │ ├── ic_clear_white_24dp.png │ │ │ ├── ic_history_black_18dp.png │ │ │ ├── ic_history_white_24dp.png │ │ │ ├── ic_search_white_24dp.png │ │ │ ├── ic_settings_white_24dp.png │ │ │ ├── ic_star_border_black_24dp.png │ │ │ ├── ic_visibility_black_18dp.png │ │ │ └── ic_visibility_white_24dp.png │ │ ├── drawable-mdpi │ │ │ ├── ic_star_black_24dp.png │ │ │ ├── ic_star_white_24dp.png │ │ │ ├── ic_clear_white_24dp.png │ │ │ ├── ic_history_black_18dp.png │ │ │ ├── ic_history_white_24dp.png │ │ │ ├── ic_search_white_24dp.png │ │ │ ├── ic_settings_white_24dp.png │ │ │ ├── ic_star_border_black_24dp.png │ │ │ ├── ic_visibility_black_18dp.png │ │ │ └── ic_visibility_white_24dp.png │ │ ├── drawable-xhdpi │ │ │ ├── ic_clear_white_24dp.png │ │ │ ├── ic_search_white_24dp.png │ │ │ ├── ic_star_black_24dp.png │ │ │ ├── ic_star_white_24dp.png │ │ │ ├── ic_history_black_18dp.png │ │ │ ├── ic_history_white_24dp.png │ │ │ ├── ic_settings_white_24dp.png │ │ │ ├── ic_star_border_black_24dp.png │ │ │ ├── ic_visibility_black_18dp.png │ │ │ └── ic_visibility_white_24dp.png │ │ ├── drawable-xxhdpi │ │ │ ├── ic_clear_white_24dp.png │ │ │ ├── ic_star_black_24dp.png │ │ │ ├── ic_star_white_24dp.png │ │ │ ├── ic_history_black_18dp.png │ │ │ ├── ic_history_white_24dp.png │ │ │ ├── ic_search_white_24dp.png │ │ │ ├── ic_settings_white_24dp.png │ │ │ ├── ic_visibility_black_18dp.png │ │ │ ├── ic_visibility_white_24dp.png │ │ │ └── ic_star_border_black_24dp.png │ │ ├── drawable-xxxhdpi │ │ │ ├── ic_star_black_24dp.png │ │ │ ├── ic_star_white_24dp.png │ │ │ ├── ic_clear_white_24dp.png │ │ │ ├── ic_search_white_24dp.png │ │ │ ├── ic_history_black_18dp.png │ │ │ ├── ic_history_white_24dp.png │ │ │ ├── ic_settings_white_24dp.png │ │ │ ├── ic_star_border_black_24dp.png │ │ │ ├── ic_visibility_black_18dp.png │ │ │ └── ic_visibility_white_24dp.png │ │ ├── drawable │ │ │ ├── ic_history_black_18dp_tint.xml │ │ │ ├── ic_visibility_black_18dp_tint.xml │ │ │ ├── book_starred_selector.xml │ │ │ ├── ic_baseline_save_alt_24.xml │ │ │ ├── baseline_favorite_18.xml │ │ │ ├── baseline_favorite_24.xml │ │ │ └── ic_baseline_settings_backup_restore_24.xml │ │ ├── values-w820dp │ │ │ └── dimens.xml │ │ ├── layout │ │ │ ├── node_view.xml │ │ │ ├── outline_node_view.xml │ │ │ ├── database_management_fragment.xml │ │ │ ├── activity_reading_story.xml │ │ │ ├── activity_books.xml │ │ │ ├── item_book.xml │ │ │ └── activity_indexing.xml │ │ ├── layout-sw600dp │ │ │ ├── node_view.xml │ │ │ ├── outline_node_view.xml │ │ │ └── item_book.xml │ │ └── menu │ │ │ └── list_menu.xml │ │ ├── ic_launcher-web.png │ │ ├── java │ │ └── net │ │ │ └── bloople │ │ │ └── stories │ │ │ ├── Indexable.kt │ │ │ ├── StoryParser.kt │ │ │ ├── IndexViewModel.kt │ │ │ ├── NodesAdapter.kt │ │ │ ├── NodesHelper.kt │ │ │ ├── OutlineAdapter.kt │ │ │ ├── IndexingTask.kt │ │ │ ├── BooksSearcher.kt │ │ │ ├── DatabaseManagementFragment.kt │ │ │ ├── BooksAdapter.kt │ │ │ ├── DatabaseHelper.kt │ │ │ ├── Book.kt │ │ │ ├── IndexingActivity.kt │ │ │ ├── CursorRecyclerAdapter.kt │ │ │ ├── ReadingStoryActivity.kt │ │ │ └── BooksActivity.kt │ │ └── AndroidManifest.xml ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── .gitignore ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── LICENSE ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Stories 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | /app/release 9 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_star_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-hdpi/ic_star_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_star_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-hdpi/ic_star_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_star_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-mdpi/ic_star_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_star_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-mdpi/ic_star_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_clear_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-hdpi/ic_clear_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_history_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-hdpi/ic_history_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_history_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-hdpi/ic_history_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_search_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-hdpi/ic_search_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_clear_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-mdpi/ic_clear_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_history_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-mdpi/ic_history_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_history_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-mdpi/ic_history_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_search_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-mdpi/ic_search_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_clear_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xhdpi/ic_clear_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_search_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xhdpi/ic_search_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_star_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xhdpi/ic_star_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_star_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xhdpi/ic_star_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_clear_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxhdpi/ic_clear_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_star_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxhdpi/ic_star_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_star_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxhdpi/ic_star_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_star_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxxhdpi/ic_star_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_star_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxxhdpi/ic_star_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-hdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-mdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_history_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xhdpi/ic_history_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_history_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xhdpi/ic_history_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xhdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_history_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxhdpi/ic_history_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_history_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxhdpi/ic_history_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_clear_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxxhdpi/ic_clear_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_star_border_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-hdpi/ic_star_border_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_visibility_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-hdpi/ic_visibility_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_visibility_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-hdpi/ic_visibility_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_star_border_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-mdpi/ic_star_border_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_visibility_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-mdpi/ic_visibility_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_visibility_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-mdpi/ic_visibility_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_star_border_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xhdpi/ic_star_border_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_visibility_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xhdpi/ic_visibility_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_visibility_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xhdpi/ic_visibility_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxhdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_visibility_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxhdpi/ic_visibility_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_visibility_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxhdpi/ic_visibility_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_history_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxxhdpi/ic_history_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_history_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxxhdpi/ic_history_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxxhdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_star_border_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxhdpi/ic_star_border_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_star_border_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxxhdpi/ic_star_border_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_visibility_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxxhdpi/ic_visibility_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_visibility_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/stories-app/master/app/src/main/res/drawable-xxxhdpi/ic_visibility_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/java/net/bloople/stories/Indexable.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.stories 2 | 3 | internal interface Indexable { 4 | fun onIndexingProgress(progress: Int, max: Int) 5 | fun onIndexingComplete(count: Int) 6 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_history_black_18dp_tint.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_visibility_black_18dp_tint.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Nov 12 16:10:28 AEDT 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip 7 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/book_starred_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_save_alt_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_favorite_18.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/node_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp/node_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout-sw600dp/outline_node_view.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/outline_node_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_favorite_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_settings_backup_restore_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/net/bloople/stories/StoryParser.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.stories 2 | 3 | import java.io.IOException 4 | import java.io.Reader 5 | import java.util.* 6 | import kotlin.Throws 7 | 8 | internal class StoryParser(reader: Reader) { 9 | private val scanner: Scanner 10 | 11 | @Throws(IOException::class) 12 | operator fun hasNext(): Boolean { 13 | return scanner.hasNext() 14 | } 15 | 16 | @Throws(IOException::class) 17 | operator fun next(): String { 18 | return scanner.next() 19 | } 20 | 21 | init { 22 | scanner = Scanner(reader) 23 | scanner.useDelimiter("(?:\r?\n[\u200B\uFEFF]*){2,}+") 24 | } 25 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/database_management_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 14 | 15 | 21 | 22 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | android.enableJetifier=true 20 | android.useAndroidX=true -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Brenton Fletcher (http://bloople.net i@bloople.net) 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_reading_story.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 16 | 17 | 24 | 29 | 30 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | } 5 | 6 | android { 7 | compileSdkVersion 31 8 | buildToolsVersion "31.0.0" 9 | 10 | defaultConfig { 11 | applicationId "net.bloople.stories" 12 | minSdkVersion 28 13 | targetSdkVersion 28 14 | final def version = 23 15 | versionCode version 16 | versionName version.toString() 17 | } 18 | compileOptions { 19 | sourceCompatibility JavaVersion.VERSION_1_8 20 | targetCompatibility JavaVersion.VERSION_1_8 21 | } 22 | lintOptions { 23 | abortOnError false 24 | } 25 | buildTypes { 26 | release { 27 | minifyEnabled false 28 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 29 | } 30 | debug { 31 | applicationIdSuffix ".debug" 32 | } 33 | } 34 | } 35 | 36 | dependencies { 37 | implementation fileTree(dir: 'libs', include: ['*.jar']) 38 | 39 | implementation "androidx.core:core-ktx:1.7.0" 40 | 41 | implementation 'androidx.recyclerview:recyclerview:1.2.1' 42 | implementation 'androidx.appcompat:appcompat:1.4.0' 43 | implementation 'com.google.android.material:material:1.4.0' 44 | 45 | implementation 'androidx.drawerlayout:drawerlayout:1.1.1' 46 | 47 | final def markwon_version = '4.1.2' 48 | implementation "io.noties.markwon:core:$markwon_version" 49 | } 50 | repositories { 51 | mavenCentral() 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/net/bloople/stories/IndexViewModel.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.stories 2 | 3 | import android.app.Application 4 | import android.database.Cursor 5 | import androidx.lifecycle.AndroidViewModel 6 | import androidx.lifecycle.MutableLiveData 7 | import java.util.concurrent.Executors 8 | 9 | class IndexViewModel(application: Application) : AndroidViewModel(application) { 10 | val searchResults: MutableLiveData by lazy { 11 | MutableLiveData().also { resolve() } 12 | } 13 | 14 | val sorterDescription: MutableLiveData by lazy { 15 | MutableLiveData(searcher.description()) 16 | } 17 | 18 | private val searcher = BooksSearcher() 19 | 20 | val sortMethod: Int 21 | get() = searcher.sortMethod 22 | 23 | val sortDirectionAsc: Boolean 24 | get() = searcher.sortDirectionAsc 25 | 26 | fun setSearchText(searchText: String) { 27 | searcher.setSearchText(searchText) 28 | resolve() 29 | } 30 | 31 | fun setSort(sortMethod: Int, sortDirectionAsc: Boolean) { 32 | searcher.sortMethod = sortMethod 33 | searcher.sortDirectionAsc = sortDirectionAsc 34 | sorterDescription.value = searcher.description() 35 | resolve() 36 | } 37 | 38 | fun refresh() { 39 | resolve() 40 | } 41 | 42 | private fun resolve() { 43 | val service = Executors.newSingleThreadExecutor() 44 | service.submit { searchResults.postValue(searcher.search(getApplication())) } 45 | } 46 | } -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 26 | 27 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/menu/list_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 13 | 18 | 23 | 28 | 33 | 34 | 35 | 36 | 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/java/net/bloople/stories/NodesAdapter.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.stories 2 | 3 | import android.view.View 4 | import net.bloople.stories.NodesHelper.createNodeView 5 | import io.noties.markwon.Markwon 6 | import androidx.recyclerview.widget.RecyclerView 7 | import android.widget.TextView 8 | import android.view.ViewGroup 9 | import org.commonmark.node.Node 10 | import java.util.ArrayList 11 | 12 | internal class NodesAdapter(private val markwon: Markwon) : RecyclerView.Adapter() { 13 | private val nodes: MutableList 14 | 15 | internal class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { 16 | var textView: TextView = view.findViewById(R.id.text_view) 17 | } 18 | 19 | fun addAll(newNodes: List) { 20 | nodes.addAll(newNodes) 21 | notifyItemRangeInserted(nodes.size - 1, newNodes.size) 22 | } 23 | 24 | // Create new views (invoked by the layout manager) 25 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { 26 | return ViewHolder(createNodeView(parent)) 27 | } 28 | 29 | // Replace the contents of a view (invoked by the layout manager) 30 | override fun onBindViewHolder(holder: ViewHolder, position: Int) { 31 | val tv = holder.textView 32 | markwon.setParsedMarkdown(tv, markwon.render(nodes[position])) 33 | tv.setPadding( 34 | tv.paddingLeft, 35 | if (position == 0) tv.paddingBottom else 0, 36 | tv.paddingRight, 37 | tv.paddingBottom 38 | ) 39 | } 40 | 41 | // Return the size of your dataset (invoked by the layout manager) 42 | override fun getItemCount(): Int { 43 | return nodes.size 44 | } 45 | 46 | init { 47 | nodes = ArrayList() 48 | } 49 | } -------------------------------------------------------------------------------- /app/src/main/java/net/bloople/stories/NodesHelper.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.stories 2 | 3 | import android.view.ViewGroup 4 | import io.noties.markwon.Markwon 5 | import android.widget.TextView 6 | import io.noties.markwon.AbstractMarkwonPlugin 7 | import io.noties.markwon.core.MarkwonTheme 8 | import android.graphics.Typeface 9 | import android.view.LayoutInflater 10 | import android.view.View 11 | import org.commonmark.node.Heading 12 | import org.commonmark.node.Node 13 | 14 | internal object NodesHelper { 15 | private val HEADER_SIZES = floatArrayOf( 16 | 1.5f, 1.4f, 1.3f, 1.2f, 1.1f, 1f 17 | ) 18 | 19 | @JvmStatic 20 | fun buildMarkwon(parent: ViewGroup): Markwon { 21 | val nodeView = createNodeView(parent) 22 | val textView = nodeView.findViewById(R.id.text_view) 23 | return Markwon.builder(parent.context).usePlugin(object : AbstractMarkwonPlugin() { 24 | override fun configureTheme(builder: MarkwonTheme.Builder) { 25 | builder.blockMargin(textView.paddingBottom) 26 | builder.blockQuoteColor(textView.currentTextColor) 27 | builder.bulletWidth(Math.round(textView.paddingBottom * 0.4).toInt()) 28 | builder.headingBreakHeight(0) 29 | builder.headingTextSizeMultipliers(HEADER_SIZES) 30 | builder.headingTypeface(Typeface.create(textView.typeface, Typeface.BOLD)) 31 | builder.thematicBreakColor(textView.currentTextColor) 32 | } 33 | }).build() 34 | } 35 | 36 | @JvmStatic 37 | fun createNodeView(parent: ViewGroup): View { 38 | return LayoutInflater.from(parent.context).inflate(R.layout.node_view, parent,false) 39 | } 40 | 41 | @JvmStatic 42 | fun findFirstHeading(node: Node): Heading? { 43 | if (node is Heading) return node 44 | var node: Node? = node.firstChild 45 | while (node != null) { 46 | val heading = findFirstHeading(node) 47 | if (heading != null) return heading 48 | node = node.next 49 | } 50 | return null 51 | } 52 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_books.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 21 | 31 | 32 | 43 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/java/net/bloople/stories/OutlineAdapter.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.stories 2 | 3 | import io.noties.markwon.Markwon 4 | import androidx.recyclerview.widget.RecyclerView 5 | import android.widget.TextView 6 | import android.view.ViewGroup 7 | import android.view.LayoutInflater 8 | import android.view.View 9 | import org.commonmark.node.Node 10 | import java.util.ArrayList 11 | 12 | internal class OutlineAdapter(private val markwon: Markwon) : RecyclerView.Adapter() { 13 | private val nodes: MutableList 14 | private val nodeIndexes: MutableList 15 | 16 | internal inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { 17 | var textView: TextView = view.findViewById(R.id.text_view) 18 | 19 | init { 20 | textView.setOnClickListener { view -> 21 | val activity = view.context as ReadingStoryActivity 22 | activity.scrollToPosition(nodeIndexes[bindingAdapterPosition]) 23 | activity.closeDrawers() 24 | } 25 | } 26 | } 27 | 28 | fun addAll(newNodes: List, newNodeIndexes: List) { 29 | nodes.addAll(newNodes) 30 | nodeIndexes.addAll(newNodeIndexes) 31 | notifyItemRangeInserted(nodes.size - 1, newNodes.size) 32 | } 33 | 34 | // Create new views (invoked by the layout manager) 35 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { 36 | val view = LayoutInflater.from(parent.context).inflate(R.layout.outline_node_view, parent,false) 37 | return ViewHolder(view) 38 | } 39 | 40 | // Replace the contents of a view (invoked by the layout manager) 41 | override fun onBindViewHolder(holder: ViewHolder, position: Int) { 42 | val tv = holder.textView 43 | markwon.setParsedMarkdown(tv, markwon.render(nodes[position])) 44 | tv.setPadding( 45 | tv.paddingLeft, 46 | if (position == 0) tv.paddingBottom else 0, 47 | tv.paddingRight, 48 | tv.paddingBottom 49 | ) 50 | } 51 | 52 | // Return the size of your dataset (invoked by the layout manager) 53 | override fun getItemCount(): Int { 54 | return nodes.size 55 | } 56 | 57 | init { 58 | nodes = ArrayList() 59 | nodeIndexes = ArrayList() 60 | } 61 | } -------------------------------------------------------------------------------- /app/src/main/java/net/bloople/stories/IndexingTask.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.stories 2 | 3 | import android.content.Context 4 | import android.os.AsyncTask 5 | import java.io.File 6 | import java.io.IOException 7 | import java.util.ArrayList 8 | 9 | internal class IndexingTask(private val context: Context, private val indexable: Indexable) : 10 | AsyncTask() { 11 | private var progress = 0 12 | private var max = 0 13 | private var indexed = 0 14 | 15 | override fun doInBackground(vararg params: String?): Void? { 16 | destroyDeleted() 17 | indexDirectory(File(params[0]!!)) 18 | publishProgress(progress, max) 19 | return null 20 | } 21 | 22 | override fun onProgressUpdate(vararg args: Int?) { 23 | indexable.onIndexingProgress(args[0]!!, args[1]!!) 24 | } 25 | 26 | override fun onPostExecute(result: Void?) { 27 | indexable.onIndexingComplete(indexed) 28 | } 29 | 30 | private fun destroyDeleted() { 31 | val db = DatabaseHelper.instance(context) 32 | db.query("books", null, null, null, null, null, null).use { 33 | max += it.count 34 | while(it.moveToNext()) { 35 | val book = Book(it) 36 | val file = File(book.path!!) 37 | if(!file.exists()) book.destroy(context) 38 | progress++ 39 | publishProgress(progress, max) 40 | } 41 | } 42 | } 43 | 44 | private fun indexDirectory(directory: File) { 45 | val files = directory.listFiles() ?: return 46 | val filesToIndex = ArrayList() 47 | 48 | for(f in files) { 49 | if(f.isDirectory) { 50 | indexDirectory(f) 51 | } 52 | else { 53 | val name = f.name 54 | val ext = name.substring(name.lastIndexOf('.') + 1) 55 | if(ext == "txt") filesToIndex.add(f) 56 | } 57 | } 58 | 59 | max += filesToIndex.size 60 | publishProgress(progress, max) 61 | 62 | for(f in filesToIndex) indexFile(f) 63 | } 64 | 65 | private fun indexFile(file: File) { 66 | (Book.findByPathOrNull(context, file.canonicalPath) ?: Book()).edit(context) { 67 | val filePath = file.canonicalPath 68 | path = filePath 69 | title = file.name.replace("\\.txt$".toRegex(), "") 70 | mtime = file.lastModified() 71 | size = file.length() 72 | } 73 | progress++ 74 | indexed++ 75 | 76 | publishProgress(progress, max) 77 | } 78 | } -------------------------------------------------------------------------------- /app/src/main/java/net/bloople/stories/BooksSearcher.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.stories 2 | 3 | import android.content.Context 4 | import android.database.Cursor 5 | import java.lang.IllegalStateException 6 | 7 | class BooksSearcher internal constructor() { 8 | private var searchText = "" 9 | var sortMethod = SORT_AGE 10 | var sortDirectionAsc = false 11 | 12 | fun setSearchText(inSearchText: String) { 13 | searchText = inSearchText 14 | } 15 | 16 | fun flipSortDirection() { 17 | sortDirectionAsc = !sortDirectionAsc 18 | } 19 | 20 | fun description(): String { 21 | return "Sorted by " + sortMethodDescription().lowercase() + " " + sortDirectionDescription().lowercase() 22 | } 23 | 24 | private fun sortMethodDescription(): String { 25 | return when (sortMethod) { 26 | SORT_ALPHABETIC -> "Title" 27 | SORT_AGE -> "Published Date" 28 | SORT_SIZE -> "Size" 29 | SORT_LAST_OPENED -> "Last Opened At" 30 | SORT_OPENED_COUNT -> "Opened Count" 31 | SORT_STARRED -> "Starred" 32 | else -> throw IllegalStateException("sort_method not in valid range") 33 | } 34 | } 35 | 36 | private fun sortDirectionDescription(): String { 37 | return if (sortDirectionAsc) "Ascending" else "Descending" 38 | } 39 | 40 | private fun orderBy(): String { 41 | var orderBy = "" 42 | when (sortMethod) { 43 | SORT_ALPHABETIC -> orderBy += "title" 44 | SORT_AGE -> orderBy += "mtime" 45 | SORT_SIZE -> orderBy += "size" 46 | SORT_LAST_OPENED -> orderBy += "last_opened_at" 47 | SORT_STARRED -> orderBy += "starred" 48 | SORT_OPENED_COUNT -> orderBy += "opened_count" 49 | } 50 | orderBy += if (sortDirectionAsc) " ASC" else " DESC" 51 | orderBy += ", title ASC" 52 | return orderBy 53 | } 54 | 55 | fun search(context: Context): Cursor { 56 | val db = DatabaseHelper.instance(context) 57 | val cursor: Cursor = if (searchText != "") { 58 | db.query("books", null, "title LIKE ?", arrayOf("%$searchText%"), null, null, orderBy()) 59 | } else { 60 | db.query("books", null, null, null, null, null, orderBy()) 61 | } 62 | cursor.moveToFirst() 63 | return cursor 64 | } 65 | 66 | companion object { 67 | const val SORT_ALPHABETIC = 0 68 | const val SORT_AGE = 1 69 | const val SORT_SIZE = 2 70 | const val SORT_LAST_OPENED = 3 71 | const val SORT_STARRED = 4 72 | const val SORT_OPENED_COUNT = 5 73 | } 74 | } -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_book.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 16 | 17 | 26 | 27 | 31 | 32 | 43 | 44 | 58 | 59 | 60 | 61 | 67 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_indexing.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 19 | 26 | 27 | 28 | 33 | 40 | 41 | 45 | 46 |