From ded46048bd176874ec3e0c75cf578cb2b28a0920 Mon Sep 17 00:00:00 2001
From: NoodleMage
Date: Tue, 26 Jan 2016 13:26:41 +0100
Subject: [PATCH 01/12] Code optimization. Added javadoc. Removed setSize for
it is not used
---
.../tachiyomi/data/cache/ChapterCache.java | 113 ++++++++++++++++--
1 file changed, 101 insertions(+), 12 deletions(-)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
index 9571c6020c..2f1c825b17 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
@@ -23,20 +23,39 @@ import rx.Observable;
public class ChapterCache {
+ /** Name of cache directory. */
private static final String PARAMETER_CACHE_DIRECTORY = "chapter_disk_cache";
+
+ /** Application version. */
private static final int PARAMETER_APP_VERSION = 1;
+
+ /** The number of values per cache entry. Must be positive. */
private static final int PARAMETER_VALUE_COUNT = 1;
+
+ /** The maximum number of bytes this cache should use to store. */
private static final int PARAMETER_CACHE_SIZE = 75 * 1024 * 1024;
- private Context context;
- private Gson gson;
+ /** Interface to global information about an application environment. */
+ private final Context context;
+ /** Google Json class used for parsing json files. */
+ private final Gson gson;
+
+ /** Cache class used for cache management. */
private DiskLruCache diskCache;
+ /**
+ * Constructor of ChapterCache.
+ * @param context application environment interface.
+ */
public ChapterCache(Context context) {
+ // Set context.
this.context = context;
+
+ // Initialize Json handler.
gson = new Gson();
+ // Try to open cache in default cache directory.
try {
diskCache = DiskLruCache.open(
new File(context.getCacheDir(), PARAMETER_CACHE_DIRECTORY),
@@ -45,15 +64,22 @@ public class ChapterCache {
PARAMETER_CACHE_SIZE
);
} catch (IOException e) {
- // Do Nothing.
+ // Do Nothing. TODO error handling?
}
}
+ /**
+ * Remove Chapter from cache.
+ * @param file name of chapter file.
+ * @return false if file is journal or error else returns true.
+ */
public boolean remove(String file) {
+ // Make sure we don't delete the journal file (keeps track of cache).
if (file.equals("journal") || file.startsWith("journal."))
return false;
try {
+ // Take dot(.) substring to avoid conflicts.
String key = file.substring(0, file.lastIndexOf("."));
return diskCache.remove(key);
} catch (IOException e) {
@@ -61,27 +87,43 @@ public class ChapterCache {
}
}
+ /**
+ * Returns directory of cache.
+ * @return directory of cache.
+ */
public File getCacheDir() {
return diskCache.getDirectory();
}
- public long getRealSize() {
+ /**
+ * Returns real size of directory.
+ * @return real size of directory.
+ */
+ private long getRealSize() {
return DiskUtils.getDirectorySize(getCacheDir());
}
+ /**
+ * Returns real size of directory in human readable format.
+ * @return real size of directory.
+ */
public String getReadableSize() {
return Formatter.formatFileSize(context, getRealSize());
}
- public void setSize(int value) {
- diskCache.setMaxSize(value * 1024 * 1024);
- }
-
+ /**
+ * Get page urls from cache.
+ * @param chapterUrl the url of the chapter.
+ * @return list of chapter pages.
+ */
public Observable> getPageUrlsFromDiskCache(final String chapterUrl) {
return Observable.create(subscriber -> {
try {
+ // Get list of pages from chapterUrl.
List pages = getPageUrlsFromDiskCacheImpl(chapterUrl);
+ // Provides the Observer with a new item to observe.
subscriber.onNext(pages);
+ // Notify the Observer that finished sending push-based notifications.
subscriber.onCompleted();
} catch (Throwable e) {
subscriber.onError(e);
@@ -89,18 +131,31 @@ public class ChapterCache {
});
}
- private List getPageUrlsFromDiskCacheImpl(String chapterUrl) throws IOException {
+ /**
+ * Implementation of the getPageUrlsFromDiskCache() function
+ * @param chapterUrl the url of the chapter
+ * @return returns list of chapter pages
+ * @throws IOException does nothing atm
+ */
+ private List getPageUrlsFromDiskCacheImpl(String chapterUrl) throws IOException /*TODO IOException never thrown*/ {
+ // Initialize snapshot (a snapshot of the values for an entry).
DiskLruCache.Snapshot snapshot = null;
+
+ // Initialize list of pages.
List pages = null;
try {
+ // Create md5 key and retrieve snapshot.
String key = DiskUtils.hashKeyForDisk(chapterUrl);
snapshot = diskCache.get(key);
+
+ // Convert JSON string to list of objects.
Type collectionType = new TypeToken>() {}.getType();
pages = gson.fromJson(snapshot.getString(0), collectionType);
+
} catch (IOException e) {
- // Do Nothing.
+ // Do Nothing. //TODO error handling?
} finally {
if (snapshot != null) {
snapshot.close();
@@ -109,18 +164,30 @@ public class ChapterCache {
return pages;
}
+ /**
+ * Add page urls to disk cache.
+ * @param chapterUrl the url of the chapter.
+ * @param pages list of chapter pages.
+ */
public void putPageUrlsToDiskCache(final String chapterUrl, final List pages) {
+ // Convert list of pages to json string.
String cachedValue = gson.toJson(pages);
+ // Initialize the editor (edits the values for an entry).
DiskLruCache.Editor editor = null;
+
+ // Initialize OutputStream.
OutputStream outputStream = null;
+
try {
+ // Get editor from md5 key.
String key = DiskUtils.hashKeyForDisk(chapterUrl);
editor = diskCache.edit(key);
if (editor == null) {
return;
}
+ // Write chapter urls to cache.
outputStream = new BufferedOutputStream(editor.newOutputStream(0));
outputStream.write(cachedValue.getBytes());
outputStream.flush();
@@ -128,7 +195,7 @@ public class ChapterCache {
diskCache.flush();
editor.commit();
} catch (Exception e) {
- // Do Nothing.
+ // Do Nothing. TODO error handling?
} finally {
if (editor != null) {
editor.abortUnlessCommitted();
@@ -137,12 +204,17 @@ public class ChapterCache {
try {
outputStream.close();
} catch (IOException ignore) {
- // Do Nothing.
+ // Do Nothing. TODO error handling?
}
}
}
}
+ /**
+ * Check if image is in cache.
+ * @param imageUrl url of image.
+ * @return true if in cache otherwise false.
+ */
public boolean isImageInCache(final String imageUrl) {
try {
return diskCache.get(DiskUtils.hashKeyForDisk(imageUrl)) != null;
@@ -152,8 +224,14 @@ public class ChapterCache {
return false;
}
+ /**
+ * Get image path from url.
+ * @param imageUrl url of image.
+ * @return path of image.
+ */
public String getImagePath(final String imageUrl) {
try {
+ // Get file from md5 key.
String imageName = DiskUtils.hashKeyForDisk(imageUrl) + ".0";
File file = new File(diskCache.getDirectory(), imageName);
return file.getCanonicalPath();
@@ -163,17 +241,28 @@ public class ChapterCache {
return null;
}
+ /**
+ * Add image to cache
+ * @param imageUrl url of image.
+ * @param response http response from page.
+ * @throws IOException image error.
+ */
public void putImageToDiskCache(final String imageUrl, final Response response) throws IOException {
+ // Initialize editor (edits the values for an entry).
DiskLruCache.Editor editor = null;
+
+ // Initialize BufferedSink (used for small writes).
BufferedSink sink = null;
try {
+ // Get editor from md5 key.
String key = DiskUtils.hashKeyForDisk(imageUrl);
editor = diskCache.edit(key);
if (editor == null) {
throw new IOException("Unable to edit key");
}
+ // Initialize OutputStream and write image.
OutputStream outputStream = new BufferedOutputStream(editor.newOutputStream(0));
sink = Okio.buffer(Okio.sink(outputStream));
sink.writeAll(response.body().source());
From 2014b228e8fae546660a801722d124f38e952101 Mon Sep 17 00:00:00 2001
From: NoodleMage
Date: Tue, 26 Jan 2016 13:54:43 +0100
Subject: [PATCH 02/12] Fixed some mistakes.
---
.../tachiyomi/data/cache/ChapterCache.java | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
index 2f1c825b17..278b2f18a2 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
@@ -21,6 +21,12 @@ import okio.BufferedSink;
import okio.Okio;
import rx.Observable;
+/**
+ * Class used to create chapter cache
+ * For each image in a chapter a file is created
+ * For each chapter a Json list is created and converted to a file.
+ * The files are in format *md5key*.0
+ */
public class ChapterCache {
/** Name of cache directory. */
@@ -69,18 +75,19 @@ public class ChapterCache {
}
/**
- * Remove Chapter from cache.
- * @param file name of chapter file.
- * @return false if file is journal or error else returns true.
+ * Remove file from cache.
+ * @param file name of chapter file md5.o.
+ * @return false if file is journal or error else returns status of deletion.
*/
- public boolean remove(String file) {
+ public boolean removeFileFromCache(String file) {
// Make sure we don't delete the journal file (keeps track of cache).
if (file.equals("journal") || file.startsWith("journal."))
return false;
try {
- // Take dot(.) substring to avoid conflicts.
+ // Take dot(.) substring to get filename without the .0 at the end.
String key = file.substring(0, file.lastIndexOf("."));
+ // Remove file from cache.
return diskCache.remove(key);
} catch (IOException e) {
return false;
@@ -112,7 +119,7 @@ public class ChapterCache {
}
/**
- * Get page urls from cache.
+ * Get page objects from cache.
* @param chapterUrl the url of the chapter.
* @return list of chapter pages.
*/
From 11b68f914f2780068cd36d4b51248ba37a8a8e56 Mon Sep 17 00:00:00 2001
From: NoodleMage
Date: Tue, 26 Jan 2016 15:02:16 +0100
Subject: [PATCH 03/12] Code optimization. Added comments. Few comment mistake
fixes
---
.../tachiyomi/data/cache/ChapterCache.java | 3 +-
.../tachiyomi/data/cache/CoverCache.java | 122 +++++++++++++++---
2 files changed, 105 insertions(+), 20 deletions(-)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
index 278b2f18a2..cece9a47d9 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
@@ -32,7 +32,7 @@ public class ChapterCache {
/** Name of cache directory. */
private static final String PARAMETER_CACHE_DIRECTORY = "chapter_disk_cache";
- /** Application version. */
+ /** Application cache version. */
private static final int PARAMETER_APP_VERSION = 1;
/** The number of values per cache entry. Must be positive. */
@@ -55,7 +55,6 @@ public class ChapterCache {
* @param context application environment interface.
*/
public ChapterCache(Context context) {
- // Set context.
this.context = context;
// Initialize Json handler.
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
index 7f2697a37f..8c3a14f946 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
@@ -20,33 +20,70 @@ import java.io.OutputStream;
import eu.kanade.tachiyomi.util.DiskUtils;
+/**
+ * Class used to create cover cache
+ * Makes us of Glide which can avoid repeating requests and save the file.
+ * It is not necessary to load the images to the cache.
+ * Names of files are created with the md5 of the thumbnailURL
+ */
public class CoverCache {
+ /** Name of cache directory. */
private static final String PARAMETER_CACHE_DIRECTORY = "cover_disk_cache";
- private Context context;
- private File cacheDir;
+ /** Interface to global information about an application environment. */
+ private final Context context;
+ /** Cache class used for cache management. */
+ private final File cacheDir;
+
+ /**
+ * Constructor of CoverCache.
+ * @param context application environment interface.
+ */
public CoverCache(Context context) {
this.context = context;
+
+ // Get cache directory from parameter.
cacheDir = new File(context.getCacheDir(), PARAMETER_CACHE_DIRECTORY);
+
+ // Create cache directory.
createCacheDir();
}
+ /**
+ * Check if cache dir exist if not create directory.
+ * @return true if cache dir exist or is created.
+ */
private boolean createCacheDir() {
+ // TODO return value never used.
return !cacheDir.exists() && cacheDir.mkdirs();
}
+ /**
+ * Download the cover with Glide (it can avoid repeating requests) and save the file.
+ * TODO maybe remove?
+ * @param thumbnailUrl url of thumbnail.
+ * @param headers headers included in Glide request.
+ */
public void save(String thumbnailUrl, LazyHeaders headers) {
save(thumbnailUrl, headers, null);
}
- // Download the cover with Glide (it can avoid repeating requests) and save the file on this cache
- // Optionally, load the image in the given image view when the resource is ready, if not null
- public void save(String thumbnailUrl, LazyHeaders headers, ImageView imageView) {
+ /**
+ * Download the cover with Glide (it can avoid repeating requests) and save the file.
+ * @param thumbnailUrl url of thumbnail.
+ * @param headers headers included in Glide request.
+ * @param imageView imageView where picture should be displayed.
+ */
+ private void save(String thumbnailUrl, LazyHeaders headers, ImageView imageView) {
+
+ // Check if url is empty.
if (TextUtils.isEmpty(thumbnailUrl))
+ // Do not try and create the string. Instead... only try to realize the truth. There is no string.
return;
+ // Download the cover with Glide and save the file.
GlideUrl url = new GlideUrl(thumbnailUrl, headers);
Glide.with(context)
.load(url)
@@ -54,7 +91,10 @@ public class CoverCache {
@Override
public void onResourceReady(File resource, GlideAnimation super File> anim) {
try {
+ // Copy the cover from Glide's cache to local cache.
add(thumbnailUrl, resource);
+
+ // Check if imageView isn't null and show picture in imageView.
if (imageView != null) {
loadFromCache(imageView, resource);
}
@@ -65,18 +105,31 @@ public class CoverCache {
});
}
- // Copy the cover from Glide's cache to this cache
- public void add(String thumbnailUrl, File source) throws IOException {
+
+ /**
+ * Copy the cover from Glide's cache to local cache.
+ * //TODO rename add => copyToLocalCache?
+ * @param thumbnailUrl url of thumbnail.
+ * @param source the cover image.
+ * @throws IOException TODO not returned atm?
+ */
+ private void add(String thumbnailUrl, File source) throws IOException {
+ // Create cache directory. TODO is this needed. Already called in constructor.
createCacheDir();
+
+ // Create destination file.
File dest = new File(cacheDir, DiskUtils.hashKeyForDisk(thumbnailUrl));
+
+ // Check if file already exists, if true delete it.
if (dest.exists())
dest.delete();
+ // Write thumbnail image to file.
InputStream in = new FileInputStream(source);
try {
OutputStream out = new FileOutputStream(dest);
try {
- // Transfer bytes from in to out
+ // Transfer bytes from in to out.
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
@@ -90,22 +143,40 @@ public class CoverCache {
}
}
- // Get the cover from cache
- public File get(String thumbnailUrl) {
+ /**
+ * Returns the cover from cache.
+ * TODO rename get => getCoverFromCache
+ * @param thumbnailUrl the thumbnail url.
+ * @return cover image.
+ */
+ private File get(String thumbnailUrl) {
return new File(cacheDir, DiskUtils.hashKeyForDisk(thumbnailUrl));
}
- // Delete the cover from cache
+ /**
+ * Delete the cover file from the cache.
+ * TODO rename delete => deleteCoverFromCache.
+ * @param thumbnailUrl the thumbnail url.
+ * @return status of deletion.
+ */
public boolean delete(String thumbnailUrl) {
+ // Check if url is empty.
if (TextUtils.isEmpty(thumbnailUrl))
return false;
+ // Remove file.
File file = new File(cacheDir, DiskUtils.hashKeyForDisk(thumbnailUrl));
return file.exists() && file.delete();
}
- // Save and load the image from cache
- public void saveAndLoadFromCache(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
+ /**
+ * Save or load the image from cache
+ * @param imageView imageView where picture should be displayed.
+ * @param thumbnailUrl the thumbnail url.
+ * @param headers headers included in Glide request.
+ */
+ public void saveOrLoadFromCache(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
+ // If file exist load it otherwise save it.
File localCover = get(thumbnailUrl);
if (localCover.exists()) {
loadFromCache(imageView, localCover);
@@ -114,8 +185,15 @@ public class CoverCache {
}
}
- // If the image is already in our cache, use it. If not, load it with glide
+ /**
+ * If the image is already in our cache, use it. If not, load it with glide.
+ * TODO not used atm.
+ * @param imageView imageView where picture should be displayed.
+ * @param thumbnailUrl url of thumbnail.
+ * @param headers headers included in Glide request.
+ */
public void loadFromCacheOrNetwork(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
+ // If localCover exist load it from cache otherwise load it from network.
File localCover = get(thumbnailUrl);
if (localCover.exists()) {
loadFromCache(imageView, localCover);
@@ -124,8 +202,11 @@ public class CoverCache {
}
}
- // Helper method to load the cover from the cache directory into the specified image view
- // The file must exist
+ /**
+ * Helper method to load the cover from the cache directory into the specified image view.
+ * @param imageView imageView where picture should be displayed.
+ * @param file file to load. Must exist!.
+ */
private void loadFromCache(ImageView imageView, File file) {
Glide.with(context)
.load(file)
@@ -134,8 +215,13 @@ public class CoverCache {
.into(imageView);
}
- // Helper method to load the cover from network into the specified image view.
- // It does NOT save the image in cache
+ /**
+ * Helper method to load the cover from network into the specified image view.
+ * It does NOT save the image in cache!
+ * @param imageView imageView where picture should be displayed.
+ * @param thumbnailUrl url of thumbnail.
+ * @param headers headers included in Glide request.
+ */
public void loadFromNetwork(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
GlideUrl url = new GlideUrl(thumbnailUrl, headers);
Glide.with(context)
From 5c59e553523b927938e921ef4b7826875b20cf84 Mon Sep 17 00:00:00 2001
From: NoodleMage
Date: Tue, 26 Jan 2016 15:04:38 +0100
Subject: [PATCH 04/12] Few comments
---
.../kanade/tachiyomi/data/cache/CoverGlideModule.java | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java
index c94397bcd9..1a890daa1b 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java
@@ -7,8 +7,16 @@ import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.module.GlideModule;
+/**
+ * Class used to update Glide module settings
+ */
public class CoverGlideModule implements GlideModule {
+
+ /**
+ * Bitmaps decoded from most image formats (other than GIFs with hidden configs), will be decoded with the
+ * ARGB_8888 config.
+ */
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
@@ -16,6 +24,6 @@ public class CoverGlideModule implements GlideModule {
@Override
public void registerComponents(Context context, Glide glide) {
-
+ //TODO empty class?
}
}
From 00e1dc8fca68e8afc2852a59dfa0f11e51ca76d6 Mon Sep 17 00:00:00 2001
From: NoodleMage
Date: Tue, 26 Jan 2016 15:10:30 +0100
Subject: [PATCH 05/12] Added classes because of renaming
---
.../java/eu/kanade/tachiyomi/data/cache/CoverCache.java | 4 ++--
.../eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java | 2 +-
.../java/eu/kanade/tachiyomi/ui/library/LibraryHolder.java | 2 +-
.../kanade/tachiyomi/ui/manga/info/MangaInfoFragment.java | 2 +-
.../reader/viewer/pager/vertical/VerticalViewPagerImpl.java | 6 +++---
.../tachiyomi/ui/setting/SettingsAdvancedFragment.java | 2 +-
.../java/eu/kanade/tachiyomi/util/ChapterRecognition.java | 2 +-
7 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
index 8c3a14f946..47ee660dc4 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
@@ -22,7 +22,7 @@ import eu.kanade.tachiyomi.util.DiskUtils;
/**
* Class used to create cover cache
- * Makes us of Glide which can avoid repeating requests and save the file.
+ * Makes us of Glide(which can avoid repeating requests) for saving the file.
* It is not necessary to load the images to the cache.
* Names of files are created with the md5 of the thumbnailURL
*/
@@ -62,7 +62,7 @@ public class CoverCache {
/**
* Download the cover with Glide (it can avoid repeating requests) and save the file.
- * TODO maybe remove?
+ * TODO maybe remove and update the call made to this method with ,null?
* @param thumbnailUrl url of thumbnail.
* @param headers headers included in Glide request.
*/
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java
index 914750a198..0dd11f26c5 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java
@@ -61,7 +61,7 @@ public class RxPresenter extends Presenter {
* Removes and unsubscribes a subscription that has been registered with {@link #add} previously.
* See {@link SubscriptionList#remove(Subscription)} for details.
*
- * @param subscription a subscription to remove.
+ * @param subscription a subscription to removeFileFromCache.
*/
public void remove(Subscription subscription) {
subscriptions.remove(subscription);
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHolder.java b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHolder.java
index 525c176a36..d115758ee4 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHolder.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHolder.java
@@ -44,7 +44,7 @@ public class LibraryHolder extends FlexibleViewHolder {
private void loadCover(Manga manga, Source source, CoverCache coverCache) {
if (manga.thumbnail_url != null) {
- coverCache.saveAndLoadFromCache(thumbnail, manga.thumbnail_url, source.getGlideHeaders());
+ coverCache.saveOrLoadFromCache(thumbnail, manga.thumbnail_url, source.getGlideHeaders());
} else {
thumbnail.setImageResource(android.R.color.transparent);
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.java
index bee8651f45..033e8e7ce8 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.java
@@ -88,7 +88,7 @@ public class MangaInfoFragment extends BaseRxFragment {
LazyHeaders headers = getPresenter().source.getGlideHeaders();
if (manga.thumbnail_url != null && cover.getDrawable() == null) {
if (manga.favorite) {
- coverCache.saveAndLoadFromCache(cover, manga.thumbnail_url, headers);
+ coverCache.saveOrLoadFromCache(cover, manga.thumbnail_url, headers);
} else {
coverCache.loadFromNetwork(cover, manga.thumbnail_url, headers);
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/vertical/VerticalViewPagerImpl.java b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/vertical/VerticalViewPagerImpl.java
index baded3360e..864c031356 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/vertical/VerticalViewPagerImpl.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/vertical/VerticalViewPagerImpl.java
@@ -607,9 +607,9 @@ public class VerticalViewPagerImpl extends ViewGroup {
* Add a listener that will be invoked whenever the page changes or is incrementally
* scrolled. See {@link OnPageChangeListener}.
*
- *
Components that add a listener should take care to remove it when finished.
+ *
Components that add a listener should take care to removeFileFromCache it when finished.
* Other components that take ownership of a view may call {@link #clearOnPageChangeListeners()}
- * to remove all attached listeners.
+ * to removeFileFromCache all attached listeners.
*
* @param listener listener to add
*/
@@ -624,7 +624,7 @@ public class VerticalViewPagerImpl extends ViewGroup {
* Remove a listener that was previously added via
* {@link #addOnPageChangeListener(OnPageChangeListener)}.
*
- * @param listener listener to remove
+ * @param listener listener to removeFileFromCache
*/
public void removeOnPageChangeListener(OnPageChangeListener listener) {
if (mOnPageChangeListeners != null) {
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedFragment.java
index eb9318820a..6feccd55bb 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedFragment.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedFragment.java
@@ -71,7 +71,7 @@ public class SettingsAdvancedFragment extends SettingsNestedFragment {
subscriptions.add(Observable.defer(() -> Observable.from(files))
.concatMap(file -> {
- if (chapterCache.remove(file.getName())) {
+ if (chapterCache.removeFileFromCache(file.getName())) {
deletedFiles.incrementAndGet();
}
return Observable.just(file);
diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ChapterRecognition.java b/app/src/main/java/eu/kanade/tachiyomi/util/ChapterRecognition.java
index 287c288edc..b3fb0052f6 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/util/ChapterRecognition.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/util/ChapterRecognition.java
@@ -55,7 +55,7 @@ public class ChapterRecognition {
// This can lead to issues if two numbers are separated by an space
name = name.replaceAll("\\s+", "");
- // Try to remove the manga name from the chapter, and try again
+ // Try to removeFileFromCache the manga name from the chapter, and try again
String mangaName = replaceIrrelevantCharacters(manga.title);
String nameWithoutManga = difference(mangaName, name);
if (!nameWithoutManga.isEmpty()) {
From ea2e8bfb6fceed130a295ab81580b98278d12bf9 Mon Sep 17 00:00:00 2001
From: NoodleMage
Date: Tue, 26 Jan 2016 15:18:22 +0100
Subject: [PATCH 06/12] Fixed refactor mistakes :(.
---
.../eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java | 2 +-
.../reader/viewer/pager/vertical/VerticalViewPagerImpl.java | 6 +++---
.../java/eu/kanade/tachiyomi/util/ChapterRecognition.java | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java
index 0dd11f26c5..914750a198 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java
@@ -61,7 +61,7 @@ public class RxPresenter extends Presenter {
* Removes and unsubscribes a subscription that has been registered with {@link #add} previously.
* See {@link SubscriptionList#remove(Subscription)} for details.
*
- * @param subscription a subscription to removeFileFromCache.
+ * @param subscription a subscription to remove.
*/
public void remove(Subscription subscription) {
subscriptions.remove(subscription);
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/vertical/VerticalViewPagerImpl.java b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/vertical/VerticalViewPagerImpl.java
index 864c031356..baded3360e 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/vertical/VerticalViewPagerImpl.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/vertical/VerticalViewPagerImpl.java
@@ -607,9 +607,9 @@ public class VerticalViewPagerImpl extends ViewGroup {
* Add a listener that will be invoked whenever the page changes or is incrementally
* scrolled. See {@link OnPageChangeListener}.
*
- *
Components that add a listener should take care to removeFileFromCache it when finished.
+ *
Components that add a listener should take care to remove it when finished.
* Other components that take ownership of a view may call {@link #clearOnPageChangeListeners()}
- * to removeFileFromCache all attached listeners.
+ * to remove all attached listeners.
*
* @param listener listener to add
*/
@@ -624,7 +624,7 @@ public class VerticalViewPagerImpl extends ViewGroup {
* Remove a listener that was previously added via
* {@link #addOnPageChangeListener(OnPageChangeListener)}.
*
- * @param listener listener to removeFileFromCache
+ * @param listener listener to remove
*/
public void removeOnPageChangeListener(OnPageChangeListener listener) {
if (mOnPageChangeListeners != null) {
diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ChapterRecognition.java b/app/src/main/java/eu/kanade/tachiyomi/util/ChapterRecognition.java
index b3fb0052f6..287c288edc 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/util/ChapterRecognition.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/util/ChapterRecognition.java
@@ -55,7 +55,7 @@ public class ChapterRecognition {
// This can lead to issues if two numbers are separated by an space
name = name.replaceAll("\\s+", "");
- // Try to removeFileFromCache the manga name from the chapter, and try again
+ // Try to remove the manga name from the chapter, and try again
String mangaName = replaceIrrelevantCharacters(manga.title);
String nameWithoutManga = difference(mangaName, name);
if (!nameWithoutManga.isEmpty()) {
From df3dde422b2d275097c7b1bca04ea2f91ffdd519 Mon Sep 17 00:00:00 2001
From: NoodleMage
Date: Tue, 26 Jan 2016 15:54:27 +0100
Subject: [PATCH 07/12] typo + removed todo empty class
---
.../main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java | 2 +-
.../java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
index 47ee660dc4..3425511f7c 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
@@ -22,7 +22,7 @@ import eu.kanade.tachiyomi.util.DiskUtils;
/**
* Class used to create cover cache
- * Makes us of Glide(which can avoid repeating requests) for saving the file.
+ * Makes use of Glide(which can avoid repeating requests) for saving the file.
* It is not necessary to load the images to the cache.
* Names of files are created with the md5 of the thumbnailURL
*/
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java
index 1a890daa1b..e3613ed560 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java
@@ -24,6 +24,6 @@ public class CoverGlideModule implements GlideModule {
@Override
public void registerComponents(Context context, Glide glide) {
- //TODO empty class?
+ // Nothing to see here!
}
}
From 2c293734f49721cdaa9b75e336c27d1db88d785a Mon Sep 17 00:00:00 2001
From: NoodleMage
Date: Wed, 27 Jan 2016 11:39:03 +0100
Subject: [PATCH 08/12] Changed o to 0. Some renaming. Checked for nullability
on string.isEmpty() function to prevent crashes
---
.../tachiyomi/data/cache/ChapterCache.java | 2 +-
.../tachiyomi/data/cache/CoverCache.java | 78 ++++++++++++-------
.../ui/manga/info/MangaInfoPresenter.java | 19 ++---
3 files changed, 59 insertions(+), 40 deletions(-)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
index cece9a47d9..ba995c23a4 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
@@ -69,7 +69,7 @@ public class ChapterCache {
PARAMETER_CACHE_SIZE
);
} catch (IOException e) {
- // Do Nothing. TODO error handling?
+ // Do Nothing. TODO error handling.
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
index 3425511f7c..f4f7b51e1c 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
@@ -28,17 +28,24 @@ import eu.kanade.tachiyomi.util.DiskUtils;
*/
public class CoverCache {
- /** Name of cache directory. */
+ /**
+ * Name of cache directory.
+ */
private static final String PARAMETER_CACHE_DIRECTORY = "cover_disk_cache";
- /** Interface to global information about an application environment. */
+ /**
+ * Interface to global information about an application environment.
+ */
private final Context context;
- /** Cache class used for cache management. */
+ /**
+ * Cache class used for cache management.
+ */
private final File cacheDir;
/**
* Constructor of CoverCache.
+ *
* @param context application environment interface.
*/
public CoverCache(Context context) {
@@ -53,18 +60,18 @@ public class CoverCache {
/**
* Check if cache dir exist if not create directory.
- * @return true if cache dir exist or is created.
+ *
+ * @return true if cache dir does exist and is created.
*/
private boolean createCacheDir() {
- // TODO return value never used.
return !cacheDir.exists() && cacheDir.mkdirs();
}
/**
* Download the cover with Glide (it can avoid repeating requests) and save the file.
- * TODO maybe remove and update the call made to this method with ,null?
+ *
* @param thumbnailUrl url of thumbnail.
- * @param headers headers included in Glide request.
+ * @param headers headers included in Glide request.
*/
public void save(String thumbnailUrl, LazyHeaders headers) {
save(thumbnailUrl, headers, null);
@@ -72,14 +79,15 @@ public class CoverCache {
/**
* Download the cover with Glide (it can avoid repeating requests) and save the file.
+ *
* @param thumbnailUrl url of thumbnail.
- * @param headers headers included in Glide request.
- * @param imageView imageView where picture should be displayed.
+ * @param headers headers included in Glide request.
+ * @param imageView imageView where picture should be displayed.
*/
private void save(String thumbnailUrl, LazyHeaders headers, ImageView imageView) {
// Check if url is empty.
- if (TextUtils.isEmpty(thumbnailUrl))
+ if (thumbnailUrl == null || TextUtils.isEmpty(thumbnailUrl))
// Do not try and create the string. Instead... only try to realize the truth. There is no string.
return;
@@ -92,7 +100,7 @@ public class CoverCache {
public void onResourceReady(File resource, GlideAnimation super File> anim) {
try {
// Copy the cover from Glide's cache to local cache.
- add(thumbnailUrl, resource);
+ copyToLocalCache(thumbnailUrl, resource);
// Check if imageView isn't null and show picture in imageView.
if (imageView != null) {
@@ -108,18 +116,19 @@ public class CoverCache {
/**
* Copy the cover from Glide's cache to local cache.
- * //TODO rename add => copyToLocalCache?
+ *
* @param thumbnailUrl url of thumbnail.
- * @param source the cover image.
+ * @param source the cover image.
* @throws IOException TODO not returned atm?
*/
- private void add(String thumbnailUrl, File source) throws IOException {
- // Create cache directory. TODO is this needed. Already called in constructor.
+ private void copyToLocalCache(String thumbnailUrl, File source) throws IOException {
+ // Create cache directory and check if directory exist
createCacheDir();
// Create destination file.
File dest = new File(cacheDir, DiskUtils.hashKeyForDisk(thumbnailUrl));
+
// Check if file already exists, if true delete it.
if (dest.exists())
dest.delete();
@@ -143,25 +152,26 @@ public class CoverCache {
}
}
+
/**
* Returns the cover from cache.
- * TODO rename get => getCoverFromCache
+ *
* @param thumbnailUrl the thumbnail url.
* @return cover image.
*/
- private File get(String thumbnailUrl) {
+ private File getCoverFromCache(String thumbnailUrl) {
return new File(cacheDir, DiskUtils.hashKeyForDisk(thumbnailUrl));
}
/**
* Delete the cover file from the cache.
- * TODO rename delete => deleteCoverFromCache.
+ *
* @param thumbnailUrl the thumbnail url.
* @return status of deletion.
*/
- public boolean delete(String thumbnailUrl) {
+ public boolean deleteCoverFromCache(String thumbnailUrl) {
// Check if url is empty.
- if (TextUtils.isEmpty(thumbnailUrl))
+ if (thumbnailUrl == null || TextUtils.isEmpty(thumbnailUrl))
return false;
// Remove file.
@@ -171,13 +181,14 @@ public class CoverCache {
/**
* Save or load the image from cache
- * @param imageView imageView where picture should be displayed.
+ *
+ * @param imageView imageView where picture should be displayed.
* @param thumbnailUrl the thumbnail url.
- * @param headers headers included in Glide request.
+ * @param headers headers included in Glide request.
*/
public void saveOrLoadFromCache(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
// If file exist load it otherwise save it.
- File localCover = get(thumbnailUrl);
+ File localCover = getCoverFromCache(thumbnailUrl);
if (localCover.exists()) {
loadFromCache(imageView, localCover);
} else {
@@ -188,13 +199,14 @@ public class CoverCache {
/**
* If the image is already in our cache, use it. If not, load it with glide.
* TODO not used atm.
- * @param imageView imageView where picture should be displayed.
+ *
+ * @param imageView imageView where picture should be displayed.
* @param thumbnailUrl url of thumbnail.
- * @param headers headers included in Glide request.
+ * @param headers headers included in Glide request.
*/
public void loadFromCacheOrNetwork(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
// If localCover exist load it from cache otherwise load it from network.
- File localCover = get(thumbnailUrl);
+ File localCover = getCoverFromCache(thumbnailUrl);
if (localCover.exists()) {
loadFromCache(imageView, localCover);
} else {
@@ -203,9 +215,10 @@ public class CoverCache {
}
/**
- * Helper method to load the cover from the cache directory into the specified image view.
+ * Helper method to load the cover from the cache directory into the specified image view.
+ *
* @param imageView imageView where picture should be displayed.
- * @param file file to load. Must exist!.
+ * @param file file to load. Must exist!.
*/
private void loadFromCache(ImageView imageView, File file) {
Glide.with(context)
@@ -218,11 +231,16 @@ public class CoverCache {
/**
* Helper method to load the cover from network into the specified image view.
* It does NOT save the image in cache!
- * @param imageView imageView where picture should be displayed.
+ *
+ * @param imageView imageView where picture should be displayed.
* @param thumbnailUrl url of thumbnail.
- * @param headers headers included in Glide request.
+ * @param headers headers included in Glide request.
*/
public void loadFromNetwork(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
+ // Check if url is empty.
+ if (thumbnailUrl == null || TextUtils.isEmpty(thumbnailUrl))
+ return;
+
GlideUrl url = new GlideUrl(thumbnailUrl, headers);
Glide.with(context)
.load(url)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.java
index ea69a76fcd..bfeb251be1 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.java
@@ -19,17 +19,18 @@ import rx.schedulers.Schedulers;
public class MangaInfoPresenter extends BasePresenter {
- @Inject DatabaseHelper db;
- @Inject SourceManager sourceManager;
- @Inject CoverCache coverCache;
-
- private Manga manga;
- protected Source source;
- private int count = -1;
-
private static final int GET_MANGA = 1;
private static final int GET_CHAPTER_COUNT = 2;
private static final int FETCH_MANGA_INFO = 3;
+ protected Source source;
+ @Inject
+ DatabaseHelper db;
+ @Inject
+ SourceManager sourceManager;
+ @Inject
+ CoverCache coverCache;
+ private Manga manga;
+ private int count = -1;
@Override
protected void onCreate(Bundle savedState) {
@@ -111,7 +112,7 @@ public class MangaInfoPresenter extends BasePresenter {
if (isFavorite) {
coverCache.save(manga.thumbnail_url, source.getGlideHeaders());
} else {
- coverCache.delete(manga.thumbnail_url);
+ coverCache.deleteCoverFromCache(manga.thumbnail_url);
}
}
From 6ba371500437c57c9e105d9f73bbf06ddab944a1 Mon Sep 17 00:00:00 2001
From: NoodleMage
Date: Wed, 27 Jan 2016 12:54:40 +0100
Subject: [PATCH 09/12] Update ChapterCache.java
Another o to 0 change. Damn this .o! :)
---
.../main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
index ba995c23a4..3a4e8c1503 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
@@ -75,7 +75,7 @@ public class ChapterCache {
/**
* Remove file from cache.
- * @param file name of chapter file md5.o.
+ * @param file name of chapter file md5.0.
* @return false if file is journal or error else returns status of deletion.
*/
public boolean removeFileFromCache(String file) {
From 424b64550eb132349f17a9ded0fb9c8228c30580 Mon Sep 17 00:00:00 2001
From: NoodleMage
Date: Wed, 27 Jan 2016 15:19:50 +0100
Subject: [PATCH 10/12] Removed redundant null check
---
.../java/eu/kanade/tachiyomi/data/cache/CoverCache.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
index f4f7b51e1c..e76bcf34d3 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
@@ -87,7 +87,7 @@ public class CoverCache {
private void save(String thumbnailUrl, LazyHeaders headers, ImageView imageView) {
// Check if url is empty.
- if (thumbnailUrl == null || TextUtils.isEmpty(thumbnailUrl))
+ if (TextUtils.isEmpty(thumbnailUrl))
// Do not try and create the string. Instead... only try to realize the truth. There is no string.
return;
@@ -171,7 +171,7 @@ public class CoverCache {
*/
public boolean deleteCoverFromCache(String thumbnailUrl) {
// Check if url is empty.
- if (thumbnailUrl == null || TextUtils.isEmpty(thumbnailUrl))
+ if (TextUtils.isEmpty(thumbnailUrl))
return false;
// Remove file.
@@ -238,7 +238,7 @@ public class CoverCache {
*/
public void loadFromNetwork(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
// Check if url is empty.
- if (thumbnailUrl == null || TextUtils.isEmpty(thumbnailUrl))
+ if (TextUtils.isEmpty(thumbnailUrl))
return;
GlideUrl url = new GlideUrl(thumbnailUrl, headers);
From 9c331e3f9c5b3e182c4cbf3591028550d2e07c6f Mon Sep 17 00:00:00 2001
From: NoodleMage
Date: Wed, 27 Jan 2016 15:30:26 +0100
Subject: [PATCH 11/12] Added comments
---
README.md | 2 +-
app/build.gradle | 8 +-
.../tachiyomi/data/cache/ChapterCache.java | 121 ++------------
.../tachiyomi/data/cache/CoverCache.java | 148 +++---------------
.../data/cache/CoverGlideModule.java | 10 +-
.../tachiyomi/data/database/models/Manga.java | 29 ----
.../resolvers/MangaChapterGetResolver.java | 1 -
.../data/download/DownloadManager.java | 33 ++--
.../data/preference/PreferencesHelper.java | 8 +-
.../eu/kanade/tachiyomi/event/MangaEvent.java | 12 --
.../ui/base/presenter/RxPresenter.java | 12 +-
.../ui/catalogue/CatalogueAdapter.java | 13 +-
.../ui/catalogue/CatalogueFragment.java | 107 +++----------
.../ui/catalogue/CatalogueGridHolder.java | 38 -----
.../ui/catalogue/CatalogueHolder.java | 29 +++-
.../ui/catalogue/CatalogueListHolder.java | 32 ----
.../ui/catalogue/CataloguePresenter.java | 44 ++----
.../ui/download/DownloadPresenter.java | 1 -
.../ui/library/LibraryCategoryAdapter.java | 4 +-
.../tachiyomi/ui/library/LibraryHolder.java | 6 +-
.../ui/library/LibraryPresenter.java | 2 +-
.../tachiyomi/ui/manga/MangaActivity.java | 29 ++--
.../tachiyomi/ui/manga/MangaPresenter.java | 32 ++--
.../ui/manga/chapter/ChaptersAdapter.java | 4 +-
.../ui/manga/chapter/ChaptersFragment.java | 92 +++--------
.../ui/manga/chapter/ChaptersHolder.java | 45 ++----
.../ui/manga/chapter/ChaptersPresenter.java | 36 ++---
.../ui/manga/info/MangaInfoFragment.java | 14 +-
.../ui/manga/info/MangaInfoPresenter.java | 43 +++--
.../myanimelist/MyAnimeListPresenter.java | 5 +-
.../tachiyomi/ui/reader/ReaderActivity.java | 4 -
.../tachiyomi/ui/reader/ReaderMenu.java | 2 +-
.../tachiyomi/ui/reader/ReaderPresenter.java | 14 +-
.../ui/setting/SettingsAdvancedFragment.java | 2 +-
.../eu/kanade/tachiyomi/util/UrlUtil.java | 37 -----
.../widget/EndlessListScrollListener.java | 49 ------
...ava => EndlessRecyclerScrollListener.java} | 4 +-
.../drawable-hdpi/ic_view_list_white_24dp.png | Bin 125 -> 0 bytes
.../ic_view_module_white_24dp.png | Bin 115 -> 0 bytes
.../drawable-ldpi/ic_view_list_white_24dp.png | Bin 187 -> 0 bytes
.../ic_view_module_white_24dp.png | Bin 278 -> 0 bytes
.../drawable-mdpi/ic_view_list_white_24dp.png | Bin 89 -> 0 bytes
.../ic_view_module_white_24dp.png | Bin 87 -> 0 bytes
.../ic_view_list_white_24dp.png | Bin 117 -> 0 bytes
.../ic_view_module_white_24dp.png | Bin 115 -> 0 bytes
.../ic_view_list_white_24dp.png | Bin 144 -> 0 bytes
.../ic_view_module_white_24dp.png | Bin 139 -> 0 bytes
.../ic_view_list_white_24dp.png | Bin 176 -> 0 bytes
.../ic_view_module_white_24dp.png | Bin 171 -> 0 bytes
app/src/main/res/drawable/gradient_shape.xml | 12 --
.../res/layout/activity_edit_categories.xml | 1 -
.../main/res/layout/fragment_catalogue.xml | 23 +--
.../res/layout/fragment_library_category.xml | 2 +-
.../main/res/layout/fragment_manga_info.xml | 28 +---
..._catalogue_grid.xml => item_catalogue.xml} | 71 ++++-----
.../main/res/layout/item_catalogue_list.xml | 16 --
app/src/main/res/layout/item_chapter.xml | 2 +-
app/src/main/res/layout/item_pager_reader.xml | 4 +-
app/src/main/res/layout/toolbar.xml | 4 +-
app/src/main/res/menu/catalogue_list.xml | 7 +-
app/src/main/res/menu/chapters.xml | 9 --
app/src/main/res/values/keys.xml | 2 -
app/src/main/res/values/strings.xml | 5 -
build.gradle | 2 +
libs/SubsamplingScaleImageView/build.gradle | 6 +-
65 files changed, 286 insertions(+), 980 deletions(-)
delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/event/MangaEvent.java
delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueGridHolder.java
delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueListHolder.java
delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/widget/EndlessListScrollListener.java
rename app/src/main/java/eu/kanade/tachiyomi/widget/{EndlessGridScrollListener.java => EndlessRecyclerScrollListener.java} (89%)
delete mode 100644 app/src/main/res/drawable-hdpi/ic_view_list_white_24dp.png
delete mode 100644 app/src/main/res/drawable-hdpi/ic_view_module_white_24dp.png
delete mode 100644 app/src/main/res/drawable-ldpi/ic_view_list_white_24dp.png
delete mode 100644 app/src/main/res/drawable-ldpi/ic_view_module_white_24dp.png
delete mode 100644 app/src/main/res/drawable-mdpi/ic_view_list_white_24dp.png
delete mode 100644 app/src/main/res/drawable-mdpi/ic_view_module_white_24dp.png
delete mode 100644 app/src/main/res/drawable-xhdpi/ic_view_list_white_24dp.png
delete mode 100644 app/src/main/res/drawable-xhdpi/ic_view_module_white_24dp.png
delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_view_list_white_24dp.png
delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_view_module_white_24dp.png
delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_view_list_white_24dp.png
delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_view_module_white_24dp.png
delete mode 100644 app/src/main/res/drawable/gradient_shape.xml
rename app/src/main/res/layout/{item_catalogue_grid.xml => item_catalogue.xml} (52%)
delete mode 100644 app/src/main/res/layout/item_catalogue_list.xml
delete mode 100644 app/src/main/res/menu/chapters.xml
diff --git a/README.md b/README.md
index 4981b0b66c..f4781b7a4a 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Current features:
## Download
-[![stable release](https://img.shields.io/badge/release-v0.1.2-blue.svg)](https://github.com/inorichi/tachiyomi/releases/download/v0.1.2/tachiyomi-v0.1.2.apk)
+[![stable release](https://img.shields.io/badge/release-v0.1.1-blue.svg)](https://github.com/inorichi/tachiyomi/releases/download/v0.1.1/tachiyomi-v0.1.1.apk)
[![latest debug build](https://img.shields.io/badge/debug-latest%20build-blue.svg)](http://tachiyomi.kanade.eu/latest/app-debug.apk)
## License
diff --git a/app/build.gradle b/app/build.gradle
index aeb407209b..f096687994 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -39,8 +39,8 @@ android {
minSdkVersion 16
targetSdkVersion 23
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- versionCode 3
- versionName "0.1.2"
+ versionCode 2
+ versionName "0.1.1"
buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\""
buildConfigField "String", "COMMIT_SHA", "\"${getGitSha()}\""
@@ -73,7 +73,6 @@ android {
lintOptions {
abortOnError false
- checkReleaseBuilds false
}
}
@@ -94,7 +93,6 @@ dependencies {
compile "com.android.support:design:$SUPPORT_LIBRARY_VERSION"
compile "com.android.support:recyclerview-v7:$SUPPORT_LIBRARY_VERSION"
compile "com.android.support:support-annotations:$SUPPORT_LIBRARY_VERSION"
- compile "com.android.support:percent:$SUPPORT_LIBRARY_VERSION"
compile 'com.squareup.okhttp:okhttp-urlconnection:2.7.2'
compile 'com.squareup.okhttp:okhttp:2.7.2'
compile 'com.squareup.okio:okio:1.6.0'
@@ -118,7 +116,7 @@ dependencies {
compile 'com.github.dmytrodanylyk.android-process-button:library:1.0.4'
compile 'eu.davidea:flexible-adapter:4.2.0'
compile 'com.nononsenseapps:filepicker:2.5.1'
- compile 'com.github.amulyakhare:TextDrawable:558677e'
+ compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
compile 'com.github.pwittchen:reactivenetwork:0.1.5'
compile "com.google.dagger:dagger:$DAGGER_VERSION"
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
index 3a4e8c1503..9571c6020c 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
@@ -21,46 +21,22 @@ import okio.BufferedSink;
import okio.Okio;
import rx.Observable;
-/**
- * Class used to create chapter cache
- * For each image in a chapter a file is created
- * For each chapter a Json list is created and converted to a file.
- * The files are in format *md5key*.0
- */
public class ChapterCache {
- /** Name of cache directory. */
private static final String PARAMETER_CACHE_DIRECTORY = "chapter_disk_cache";
-
- /** Application cache version. */
private static final int PARAMETER_APP_VERSION = 1;
-
- /** The number of values per cache entry. Must be positive. */
private static final int PARAMETER_VALUE_COUNT = 1;
-
- /** The maximum number of bytes this cache should use to store. */
private static final int PARAMETER_CACHE_SIZE = 75 * 1024 * 1024;
- /** Interface to global information about an application environment. */
- private final Context context;
+ private Context context;
+ private Gson gson;
- /** Google Json class used for parsing json files. */
- private final Gson gson;
-
- /** Cache class used for cache management. */
private DiskLruCache diskCache;
- /**
- * Constructor of ChapterCache.
- * @param context application environment interface.
- */
public ChapterCache(Context context) {
this.context = context;
-
- // Initialize Json handler.
gson = new Gson();
- // Try to open cache in default cache directory.
try {
diskCache = DiskLruCache.open(
new File(context.getCacheDir(), PARAMETER_CACHE_DIRECTORY),
@@ -69,67 +45,43 @@ public class ChapterCache {
PARAMETER_CACHE_SIZE
);
} catch (IOException e) {
- // Do Nothing. TODO error handling.
+ // Do Nothing.
}
}
- /**
- * Remove file from cache.
- * @param file name of chapter file md5.0.
- * @return false if file is journal or error else returns status of deletion.
- */
- public boolean removeFileFromCache(String file) {
- // Make sure we don't delete the journal file (keeps track of cache).
+ public boolean remove(String file) {
if (file.equals("journal") || file.startsWith("journal."))
return false;
try {
- // Take dot(.) substring to get filename without the .0 at the end.
String key = file.substring(0, file.lastIndexOf("."));
- // Remove file from cache.
return diskCache.remove(key);
} catch (IOException e) {
return false;
}
}
- /**
- * Returns directory of cache.
- * @return directory of cache.
- */
public File getCacheDir() {
return diskCache.getDirectory();
}
- /**
- * Returns real size of directory.
- * @return real size of directory.
- */
- private long getRealSize() {
+ public long getRealSize() {
return DiskUtils.getDirectorySize(getCacheDir());
}
- /**
- * Returns real size of directory in human readable format.
- * @return real size of directory.
- */
public String getReadableSize() {
return Formatter.formatFileSize(context, getRealSize());
}
- /**
- * Get page objects from cache.
- * @param chapterUrl the url of the chapter.
- * @return list of chapter pages.
- */
+ public void setSize(int value) {
+ diskCache.setMaxSize(value * 1024 * 1024);
+ }
+
public Observable> getPageUrlsFromDiskCache(final String chapterUrl) {
return Observable.create(subscriber -> {
try {
- // Get list of pages from chapterUrl.
List pages = getPageUrlsFromDiskCacheImpl(chapterUrl);
- // Provides the Observer with a new item to observe.
subscriber.onNext(pages);
- // Notify the Observer that finished sending push-based notifications.
subscriber.onCompleted();
} catch (Throwable e) {
subscriber.onError(e);
@@ -137,31 +89,18 @@ public class ChapterCache {
});
}
- /**
- * Implementation of the getPageUrlsFromDiskCache() function
- * @param chapterUrl the url of the chapter
- * @return returns list of chapter pages
- * @throws IOException does nothing atm
- */
- private List getPageUrlsFromDiskCacheImpl(String chapterUrl) throws IOException /*TODO IOException never thrown*/ {
- // Initialize snapshot (a snapshot of the values for an entry).
+ private List getPageUrlsFromDiskCacheImpl(String chapterUrl) throws IOException {
DiskLruCache.Snapshot snapshot = null;
-
- // Initialize list of pages.
List pages = null;
try {
- // Create md5 key and retrieve snapshot.
String key = DiskUtils.hashKeyForDisk(chapterUrl);
snapshot = diskCache.get(key);
-
- // Convert JSON string to list of objects.
Type collectionType = new TypeToken>() {}.getType();
pages = gson.fromJson(snapshot.getString(0), collectionType);
-
} catch (IOException e) {
- // Do Nothing. //TODO error handling?
+ // Do Nothing.
} finally {
if (snapshot != null) {
snapshot.close();
@@ -170,30 +109,18 @@ public class ChapterCache {
return pages;
}
- /**
- * Add page urls to disk cache.
- * @param chapterUrl the url of the chapter.
- * @param pages list of chapter pages.
- */
public void putPageUrlsToDiskCache(final String chapterUrl, final List pages) {
- // Convert list of pages to json string.
String cachedValue = gson.toJson(pages);
- // Initialize the editor (edits the values for an entry).
DiskLruCache.Editor editor = null;
-
- // Initialize OutputStream.
OutputStream outputStream = null;
-
try {
- // Get editor from md5 key.
String key = DiskUtils.hashKeyForDisk(chapterUrl);
editor = diskCache.edit(key);
if (editor == null) {
return;
}
- // Write chapter urls to cache.
outputStream = new BufferedOutputStream(editor.newOutputStream(0));
outputStream.write(cachedValue.getBytes());
outputStream.flush();
@@ -201,7 +128,7 @@ public class ChapterCache {
diskCache.flush();
editor.commit();
} catch (Exception e) {
- // Do Nothing. TODO error handling?
+ // Do Nothing.
} finally {
if (editor != null) {
editor.abortUnlessCommitted();
@@ -210,17 +137,12 @@ public class ChapterCache {
try {
outputStream.close();
} catch (IOException ignore) {
- // Do Nothing. TODO error handling?
+ // Do Nothing.
}
}
}
}
- /**
- * Check if image is in cache.
- * @param imageUrl url of image.
- * @return true if in cache otherwise false.
- */
public boolean isImageInCache(final String imageUrl) {
try {
return diskCache.get(DiskUtils.hashKeyForDisk(imageUrl)) != null;
@@ -230,14 +152,8 @@ public class ChapterCache {
return false;
}
- /**
- * Get image path from url.
- * @param imageUrl url of image.
- * @return path of image.
- */
public String getImagePath(final String imageUrl) {
try {
- // Get file from md5 key.
String imageName = DiskUtils.hashKeyForDisk(imageUrl) + ".0";
File file = new File(diskCache.getDirectory(), imageName);
return file.getCanonicalPath();
@@ -247,28 +163,17 @@ public class ChapterCache {
return null;
}
- /**
- * Add image to cache
- * @param imageUrl url of image.
- * @param response http response from page.
- * @throws IOException image error.
- */
public void putImageToDiskCache(final String imageUrl, final Response response) throws IOException {
- // Initialize editor (edits the values for an entry).
DiskLruCache.Editor editor = null;
-
- // Initialize BufferedSink (used for small writes).
BufferedSink sink = null;
try {
- // Get editor from md5 key.
String key = DiskUtils.hashKeyForDisk(imageUrl);
editor = diskCache.edit(key);
if (editor == null) {
throw new IOException("Unable to edit key");
}
- // Initialize OutputStream and write image.
OutputStream outputStream = new BufferedOutputStream(editor.newOutputStream(0));
sink = Okio.buffer(Okio.sink(outputStream));
sink.writeAll(response.body().source());
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
index e76bcf34d3..7f2697a37f 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
@@ -20,78 +20,33 @@ import java.io.OutputStream;
import eu.kanade.tachiyomi.util.DiskUtils;
-/**
- * Class used to create cover cache
- * Makes use of Glide(which can avoid repeating requests) for saving the file.
- * It is not necessary to load the images to the cache.
- * Names of files are created with the md5 of the thumbnailURL
- */
public class CoverCache {
- /**
- * Name of cache directory.
- */
private static final String PARAMETER_CACHE_DIRECTORY = "cover_disk_cache";
- /**
- * Interface to global information about an application environment.
- */
- private final Context context;
+ private Context context;
+ private File cacheDir;
- /**
- * Cache class used for cache management.
- */
- private final File cacheDir;
-
- /**
- * Constructor of CoverCache.
- *
- * @param context application environment interface.
- */
public CoverCache(Context context) {
this.context = context;
-
- // Get cache directory from parameter.
cacheDir = new File(context.getCacheDir(), PARAMETER_CACHE_DIRECTORY);
-
- // Create cache directory.
createCacheDir();
}
- /**
- * Check if cache dir exist if not create directory.
- *
- * @return true if cache dir does exist and is created.
- */
private boolean createCacheDir() {
return !cacheDir.exists() && cacheDir.mkdirs();
}
- /**
- * Download the cover with Glide (it can avoid repeating requests) and save the file.
- *
- * @param thumbnailUrl url of thumbnail.
- * @param headers headers included in Glide request.
- */
public void save(String thumbnailUrl, LazyHeaders headers) {
save(thumbnailUrl, headers, null);
}
- /**
- * Download the cover with Glide (it can avoid repeating requests) and save the file.
- *
- * @param thumbnailUrl url of thumbnail.
- * @param headers headers included in Glide request.
- * @param imageView imageView where picture should be displayed.
- */
- private void save(String thumbnailUrl, LazyHeaders headers, ImageView imageView) {
-
- // Check if url is empty.
+ // Download the cover with Glide (it can avoid repeating requests) and save the file on this cache
+ // Optionally, load the image in the given image view when the resource is ready, if not null
+ public void save(String thumbnailUrl, LazyHeaders headers, ImageView imageView) {
if (TextUtils.isEmpty(thumbnailUrl))
- // Do not try and create the string. Instead... only try to realize the truth. There is no string.
return;
- // Download the cover with Glide and save the file.
GlideUrl url = new GlideUrl(thumbnailUrl, headers);
Glide.with(context)
.load(url)
@@ -99,10 +54,7 @@ public class CoverCache {
@Override
public void onResourceReady(File resource, GlideAnimation super File> anim) {
try {
- // Copy the cover from Glide's cache to local cache.
- copyToLocalCache(thumbnailUrl, resource);
-
- // Check if imageView isn't null and show picture in imageView.
+ add(thumbnailUrl, resource);
if (imageView != null) {
loadFromCache(imageView, resource);
}
@@ -113,32 +65,18 @@ public class CoverCache {
});
}
-
- /**
- * Copy the cover from Glide's cache to local cache.
- *
- * @param thumbnailUrl url of thumbnail.
- * @param source the cover image.
- * @throws IOException TODO not returned atm?
- */
- private void copyToLocalCache(String thumbnailUrl, File source) throws IOException {
- // Create cache directory and check if directory exist
+ // Copy the cover from Glide's cache to this cache
+ public void add(String thumbnailUrl, File source) throws IOException {
createCacheDir();
-
- // Create destination file.
File dest = new File(cacheDir, DiskUtils.hashKeyForDisk(thumbnailUrl));
-
-
- // Check if file already exists, if true delete it.
if (dest.exists())
dest.delete();
- // Write thumbnail image to file.
InputStream in = new FileInputStream(source);
try {
OutputStream out = new FileOutputStream(dest);
try {
- // Transfer bytes from in to out.
+ // Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
@@ -152,43 +90,23 @@ public class CoverCache {
}
}
-
- /**
- * Returns the cover from cache.
- *
- * @param thumbnailUrl the thumbnail url.
- * @return cover image.
- */
- private File getCoverFromCache(String thumbnailUrl) {
+ // Get the cover from cache
+ public File get(String thumbnailUrl) {
return new File(cacheDir, DiskUtils.hashKeyForDisk(thumbnailUrl));
}
- /**
- * Delete the cover file from the cache.
- *
- * @param thumbnailUrl the thumbnail url.
- * @return status of deletion.
- */
- public boolean deleteCoverFromCache(String thumbnailUrl) {
- // Check if url is empty.
+ // Delete the cover from cache
+ public boolean delete(String thumbnailUrl) {
if (TextUtils.isEmpty(thumbnailUrl))
return false;
- // Remove file.
File file = new File(cacheDir, DiskUtils.hashKeyForDisk(thumbnailUrl));
return file.exists() && file.delete();
}
- /**
- * Save or load the image from cache
- *
- * @param imageView imageView where picture should be displayed.
- * @param thumbnailUrl the thumbnail url.
- * @param headers headers included in Glide request.
- */
- public void saveOrLoadFromCache(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
- // If file exist load it otherwise save it.
- File localCover = getCoverFromCache(thumbnailUrl);
+ // Save and load the image from cache
+ public void saveAndLoadFromCache(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
+ File localCover = get(thumbnailUrl);
if (localCover.exists()) {
loadFromCache(imageView, localCover);
} else {
@@ -196,17 +114,9 @@ public class CoverCache {
}
}
- /**
- * If the image is already in our cache, use it. If not, load it with glide.
- * TODO not used atm.
- *
- * @param imageView imageView where picture should be displayed.
- * @param thumbnailUrl url of thumbnail.
- * @param headers headers included in Glide request.
- */
+ // If the image is already in our cache, use it. If not, load it with glide
public void loadFromCacheOrNetwork(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
- // If localCover exist load it from cache otherwise load it from network.
- File localCover = getCoverFromCache(thumbnailUrl);
+ File localCover = get(thumbnailUrl);
if (localCover.exists()) {
loadFromCache(imageView, localCover);
} else {
@@ -214,12 +124,8 @@ public class CoverCache {
}
}
- /**
- * Helper method to load the cover from the cache directory into the specified image view.
- *
- * @param imageView imageView where picture should be displayed.
- * @param file file to load. Must exist!.
- */
+ // Helper method to load the cover from the cache directory into the specified image view
+ // The file must exist
private void loadFromCache(ImageView imageView, File file) {
Glide.with(context)
.load(file)
@@ -228,19 +134,9 @@ public class CoverCache {
.into(imageView);
}
- /**
- * Helper method to load the cover from network into the specified image view.
- * It does NOT save the image in cache!
- *
- * @param imageView imageView where picture should be displayed.
- * @param thumbnailUrl url of thumbnail.
- * @param headers headers included in Glide request.
- */
+ // Helper method to load the cover from network into the specified image view.
+ // It does NOT save the image in cache
public void loadFromNetwork(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
- // Check if url is empty.
- if (TextUtils.isEmpty(thumbnailUrl))
- return;
-
GlideUrl url = new GlideUrl(thumbnailUrl, headers);
Glide.with(context)
.load(url)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java
index e3613ed560..c94397bcd9 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java
@@ -7,16 +7,8 @@ import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.module.GlideModule;
-/**
- * Class used to update Glide module settings
- */
public class CoverGlideModule implements GlideModule {
-
- /**
- * Bitmaps decoded from most image formats (other than GIFs with hidden configs), will be decoded with the
- * ARGB_8888 config.
- */
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
@@ -24,6 +16,6 @@ public class CoverGlideModule implements GlideModule {
@Override
public void registerComponents(Context context, Glide glide) {
- // Nothing to see here!
+
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.java b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.java
index a8acba4994..5548f69ff8 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.java
@@ -68,14 +68,6 @@ public class Manga implements Serializable {
public static final int COMPLETED = 2;
public static final int LICENSED = 3;
- public static final int SORT_AZ = 0x00000000;
- public static final int SORT_ZA = 0x00000001;
- public static final int SORT_MASK = 0x00000001;
-
- public static final int DISPLAY_NAME = 0x00000000;
- public static final int DISPLAY_NUMBER = 0x00100000;
- public static final int DISPLAY_MASK = 0x00100000;
-
public Manga() {}
public static Manga create(String pathUrl) {
@@ -128,27 +120,6 @@ public class Manga implements Serializable {
}
}
- public void setChapterOrder(int order) {
- setFlags(order, SORT_MASK);
- }
-
- public void setDisplayMode(int mode) {
- setFlags(mode, DISPLAY_MASK);
- }
-
- private void setFlags(int flag, int mask) {
- chapter_flags = (chapter_flags & ~mask) | (flag & mask);
- }
-
- public boolean sortChaptersAZ() {
- return (chapter_flags & SORT_MASK) == SORT_AZ;
- }
-
- // Used to display the chapter's title one way or another
- public int getDisplayMode() {
- return chapter_flags & DISPLAY_MASK;
- }
-
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaChapterGetResolver.java b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaChapterGetResolver.java
index 2313f6bd38..67eb65e83f 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaChapterGetResolver.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaChapterGetResolver.java
@@ -49,7 +49,6 @@ public class MangaChapterGetResolver extends DefaultGetResolver {
public MangaChapter mapFromCursor(@NonNull Cursor cursor) {
final Manga manga = mangaGetResolver.mapFromCursor(cursor);
final Chapter chapter = chapterGetResolver.mapFromCursor(cursor);
- manga.id = chapter.manga_id;
return new MangaChapter(manga, chapter);
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.java b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.java
index da828f33ec..e4f71632bf 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.java
@@ -15,6 +15,8 @@ import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import eu.kanade.tachiyomi.data.database.models.Chapter;
import eu.kanade.tachiyomi.data.database.models.Manga;
@@ -26,8 +28,6 @@ import eu.kanade.tachiyomi.data.source.base.Source;
import eu.kanade.tachiyomi.data.source.model.Page;
import eu.kanade.tachiyomi.event.DownloadChaptersEvent;
import eu.kanade.tachiyomi.util.DiskUtils;
-import eu.kanade.tachiyomi.util.DynamicConcurrentMergeOperator;
-import eu.kanade.tachiyomi.util.UrlUtil;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
@@ -47,12 +47,11 @@ public class DownloadManager {
private BehaviorSubject runningSubject;
private Subscription downloadsSubscription;
- private BehaviorSubject threadsSubject;
- private Subscription threadsSubscription;
-
private DownloadQueue queue;
private volatile boolean isRunning;
+ private ExecutorService threadPool;
+
public static final String PAGE_LIST_FILE = "index.json";
public DownloadManager(Context context, SourceManager sourceManager, PreferencesHelper preferences) {
@@ -65,20 +64,17 @@ public class DownloadManager {
downloadsQueueSubject = PublishSubject.create();
runningSubject = BehaviorSubject.create();
- threadsSubject = BehaviorSubject.create();
}
private void initializeSubscriptions() {
if (downloadsSubscription != null && !downloadsSubscription.isUnsubscribed())
downloadsSubscription.unsubscribe();
- threadsSubscription = preferences.downloadThreads().asObservable()
- .subscribe(threadsSubject::onNext);
+ threadPool = Executors.newFixedThreadPool(preferences.downloadThreads());
downloadsSubscription = downloadsQueueSubject
.flatMap(Observable::from)
- .lift(new DynamicConcurrentMergeOperator<>(this::downloadChapter, threadsSubject))
- .onBackpressureBuffer()
+ .flatMap(c -> downloadChapter(c).subscribeOn(Schedulers.from(threadPool)))
.observeOn(AndroidSchedulers.mainThread())
.map(download -> areAllDownloadsFinished())
.subscribe(finished -> {
@@ -104,10 +100,9 @@ public class DownloadManager {
downloadsSubscription = null;
}
- if (threadsSubscription != null && !threadsSubscription.isUnsubscribed()) {
- threadsSubscription.unsubscribe();
+ if (threadPool != null && !threadPool.isShutdown()) {
+ threadPool.shutdown();
}
-
}
// Create a download object for every chapter in the event and add them to the downloads queue
@@ -212,8 +207,7 @@ public class DownloadManager {
.onErrorResumeNext(error -> {
download.setStatus(Download.ERROR);
return Observable.just(download);
- }))
- .subscribeOn(Schedulers.io());
+ }));
}
// Get the image from the filesystem if it exists or download from network
@@ -285,15 +279,6 @@ public class DownloadManager {
// Get the filename for an image given the page
private String getImageFilename(Page page) {
String url = page.getImageUrl();
- int number = page.getPageNumber() + 1;
- // Try to preserve file extension
- if (UrlUtil.isJpg(url)) {
- return number + ".jpg";
- } else if (UrlUtil.isPng(url)) {
- return number + ".png";
- } else if (UrlUtil.isGif(url)) {
- return number + ".gif";
- }
return Uri.parse(url).getLastPathSegment().replaceAll("[^\\sa-zA-Z0-9.-]", "_");
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.java b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.java
index af8001c573..896883c4dd 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.java
@@ -116,10 +116,6 @@ public class PreferencesHelper {
return rxPrefs.getInteger(getKey(R.string.pref_reader_theme_key), 0);
}
- public Preference catalogueAsList() {
- return rxPrefs.getBoolean(getKey(R.string.pref_display_catalogue_as_list), false);
- }
-
public String getSourceUsername(Source source) {
return prefs.getString(SOURCE_ACCOUNT_USERNAME + source.getId(), "");
}
@@ -159,8 +155,8 @@ public class PreferencesHelper {
prefs.edit().putString(getKey(R.string.pref_download_directory_key), path).apply();
}
- public Preference downloadThreads() {
- return rxPrefs.getInteger(getKey(R.string.pref_download_slots_key), 1);
+ public int downloadThreads() {
+ return prefs.getInt(getKey(R.string.pref_download_slots_key), 1);
}
public boolean downloadOnlyOverWifi() {
diff --git a/app/src/main/java/eu/kanade/tachiyomi/event/MangaEvent.java b/app/src/main/java/eu/kanade/tachiyomi/event/MangaEvent.java
deleted file mode 100644
index 9cfa8d1734..0000000000
--- a/app/src/main/java/eu/kanade/tachiyomi/event/MangaEvent.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package eu.kanade.tachiyomi.event;
-
-import eu.kanade.tachiyomi.data.database.models.Manga;
-
-public class MangaEvent {
-
- public final Manga manga;
-
- public MangaEvent(Manga manga) {
- this.manga = manga;
- }
-}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java
index 914750a198..57ba302deb 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java
@@ -107,14 +107,14 @@ public class RxPresenter extends Presenter {
}
/**
- * Checks if a restartable is unsubscribed.
+ * Checks if a restartable is subscribed.
*
- * @param restartableId id of the restartable.
- * @return true if the subscription is null or unsubscribed, false otherwise.
+ * @param restartableId id of a restartable.
+ * @return True if the restartable is subscribed, false otherwise.
*/
- public boolean isUnsubscribed(int restartableId) {
- Subscription subscription = restartableSubscriptions.get(restartableId);
- return subscription == null || subscription.isUnsubscribed();
+ public boolean isSubscribed(int restartableId) {
+ Subscription s = restartableSubscriptions.get(restartableId);
+ return s != null && !s.isUnsubscribed();
}
/**
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueAdapter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueAdapter.java
index 9d7cd6f704..69871e28fa 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueAdapter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueAdapter.java
@@ -31,10 +31,6 @@ public class CatalogueAdapter extends FlexibleAdapter {
notifyDataSetChanged();
}
- public List getItems() {
- return mItems;
- }
-
@Override
public long getItemId(int position) {
return mItems.get(position).id;
@@ -48,13 +44,8 @@ public class CatalogueAdapter extends FlexibleAdapter {
@Override
public CatalogueHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = fragment.getActivity().getLayoutInflater();
- if (parent.getId() == R.id.catalogue_grid) {
- View v = inflater.inflate(R.layout.item_catalogue_grid, parent, false);
- return new CatalogueGridHolder(v, this, fragment);
- } else {
- View v = inflater.inflate(R.layout.item_catalogue_list, parent, false);
- return new CatalogueListHolder(v, this, fragment);
- }
+ View v = inflater.inflate(R.layout.item_catalogue, parent, false);
+ return new CatalogueHolder(v, this, fragment);
}
@Override
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueFragment.java
index fff75b078c..8b2460023f 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueFragment.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueFragment.java
@@ -4,10 +4,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
-import android.support.v4.content.ContextCompat;
import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
@@ -17,12 +14,9 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.ProgressBar;
import android.widget.Spinner;
-import android.widget.ViewSwitcher;
import com.afollestad.materialdialogs.MaterialDialog;
@@ -36,13 +30,11 @@ import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.source.base.Source;
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder;
import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment;
-import eu.kanade.tachiyomi.ui.decoration.DividerItemDecoration;
import eu.kanade.tachiyomi.ui.main.MainActivity;
import eu.kanade.tachiyomi.ui.manga.MangaActivity;
import eu.kanade.tachiyomi.util.ToastUtil;
import eu.kanade.tachiyomi.widget.AutofitRecyclerView;
-import eu.kanade.tachiyomi.widget.EndlessGridScrollListener;
-import eu.kanade.tachiyomi.widget.EndlessListScrollListener;
+import eu.kanade.tachiyomi.widget.EndlessRecyclerScrollListener;
import icepick.State;
import nucleus.factory.RequiresPresenter;
import rx.Subscription;
@@ -53,17 +45,14 @@ import rx.subjects.PublishSubject;
public class CatalogueFragment extends BaseRxFragment
implements FlexibleViewHolder.OnListItemClickListener {
- @Bind(R.id.switcher) ViewSwitcher switcher;
- @Bind(R.id.catalogue_grid) AutofitRecyclerView catalogueGrid;
- @Bind(R.id.catalogue_list) RecyclerView catalogueList;
+ @Bind(R.id.recycler) AutofitRecyclerView recycler;
@Bind(R.id.progress) ProgressBar progress;
@Bind(R.id.progress_grid) ProgressBar progressGrid;
private Toolbar toolbar;
private Spinner spinner;
private CatalogueAdapter adapter;
- private EndlessGridScrollListener gridScrollListener;
- private EndlessListScrollListener listScrollListener;
+ private EndlessRecyclerScrollListener scrollListener;
@State String query = "";
@State int selectedIndex = -1;
@@ -72,9 +61,6 @@ public class CatalogueFragment extends BaseRxFragment
private PublishSubject queryDebouncerSubject;
private Subscription queryDebouncerSubscription;
- private MenuItem displayMode;
- private MenuItem searchItem;
-
public static CatalogueFragment newInstance() {
return new CatalogueFragment();
}
@@ -91,32 +77,13 @@ public class CatalogueFragment extends BaseRxFragment
View view = inflater.inflate(R.layout.fragment_catalogue, container, false);
ButterKnife.bind(this, view);
- // Initialize adapter, scroll listener and recycler views
+ // Initialize adapter and scroll listener
+ GridLayoutManager layoutManager = (GridLayoutManager) recycler.getLayoutManager();
adapter = new CatalogueAdapter(this);
-
- GridLayoutManager glm = (GridLayoutManager) catalogueGrid.getLayoutManager();
- gridScrollListener = new EndlessGridScrollListener(glm, this::requestNextPage);
- catalogueGrid.setHasFixedSize(true);
- catalogueGrid.setAdapter(adapter);
- catalogueGrid.addOnScrollListener(gridScrollListener);
-
- LinearLayoutManager llm = new LinearLayoutManager(getActivity());
- listScrollListener = new EndlessListScrollListener(llm, this::requestNextPage);
- catalogueList.setHasFixedSize(true);
- catalogueList.setAdapter(adapter);
- catalogueList.setLayoutManager(llm);
- catalogueList.addOnScrollListener(listScrollListener);
- catalogueList.addItemDecoration(new DividerItemDecoration(
- ContextCompat.getDrawable(getContext(), R.drawable.line_divider)));
-
- if (getPresenter().isListMode()) {
- switcher.showNext();
- }
-
- Animation inAnim = AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in);
- Animation outAnim = AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out);
- switcher.setInAnimation(inAnim);
- switcher.setOutAnimation(outAnim);
+ scrollListener = new EndlessRecyclerScrollListener(layoutManager, this::requestNextPage);
+ recycler.setHasFixedSize(true);
+ recycler.setAdapter(adapter);
+ recycler.addOnScrollListener(scrollListener);
// Create toolbar spinner
Context themedContext = getBaseActivity().getSupportActionBar() != null ?
@@ -142,8 +109,7 @@ public class CatalogueFragment extends BaseRxFragment
} else {
selectedIndex = position;
showProgressBar();
- glm.scrollToPositionWithOffset(0, 0);
- llm.scrollToPositionWithOffset(0, 0);
+ recycler.setAdapter(adapter);
getPresenter().startRequesting(source);
}
}
@@ -165,7 +131,7 @@ public class CatalogueFragment extends BaseRxFragment
inflater.inflate(R.menu.catalogue_list, menu);
// Initialize search menu
- searchItem = menu.findItem(R.id.action_search);
+ MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) searchItem.getActionView();
if (!TextUtils.isEmpty(query)) {
@@ -186,22 +152,6 @@ public class CatalogueFragment extends BaseRxFragment
return true;
}
});
-
- // Show next display mode
- displayMode = menu.findItem(R.id.action_display_mode);
- int icon = getPresenter().isListMode() ?
- R.drawable.ic_view_module_white_24dp : R.drawable.ic_view_list_white_24dp;
- displayMode.setIcon(icon);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.action_display_mode:
- swapDisplayMode();
- break;
- }
- return super.onOptionsItemSelected(item);
}
@Override
@@ -218,9 +168,6 @@ public class CatalogueFragment extends BaseRxFragment
@Override
public void onDestroyView() {
- if (searchItem != null && searchItem.isActionViewExpanded()) {
- searchItem.collapseActionView();
- }
toolbar.removeView(spinner);
super.onDestroyView();
}
@@ -247,13 +194,11 @@ public class CatalogueFragment extends BaseRxFragment
private void restartRequest(String newQuery) {
// If text didn't change, do nothing
- if (query.equals(newQuery) || getPresenter().getSource() == null)
- return;
+ if (query.equals(newQuery)) return;
query = newQuery;
showProgressBar();
- catalogueGrid.getLayoutManager().scrollToPosition(0);
- catalogueList.getLayoutManager().scrollToPosition(0);
+ recycler.getLayoutManager().scrollToPosition(0);
getPresenter().restartRequest(query);
}
@@ -269,8 +214,7 @@ public class CatalogueFragment extends BaseRxFragment
hideProgressBar();
if (page == 0) {
adapter.clear();
- gridScrollListener.resetScroll();
- listScrollListener.resetScroll();
+ scrollListener.resetScroll();
}
adapter.addItems(mangas);
}
@@ -280,28 +224,15 @@ public class CatalogueFragment extends BaseRxFragment
}
public void updateImage(Manga manga) {
- CatalogueGridHolder holder = getHolder(manga);
+ CatalogueHolder holder = getHolder(manga);
if (holder != null) {
holder.setImage(manga, getPresenter());
}
}
- public void swapDisplayMode() {
- getPresenter().swapDisplayMode();
- boolean isListMode = getPresenter().isListMode();
- int icon = isListMode ?
- R.drawable.ic_view_module_white_24dp : R.drawable.ic_view_list_white_24dp;
- displayMode.setIcon(icon);
- switcher.showNext();
- if (!isListMode) {
- // Initialize mangas if going to grid view
- getPresenter().initializeMangas(adapter.getItems());
- }
- }
-
@Nullable
- private CatalogueGridHolder getHolder(Manga manga) {
- return (CatalogueGridHolder) catalogueGrid.findViewHolderForItemId(manga.id);
+ private CatalogueHolder getHolder(Manga manga) {
+ return (CatalogueHolder) recycler.findViewHolderForItemId(manga.id);
}
private void showProgressBar() {
@@ -330,8 +261,9 @@ public class CatalogueFragment extends BaseRxFragment
@Override
public void onListItemLongClick(int position) {
final Manga selectedManga = adapter.getItem(position);
+ final Manga dbManga = getPresenter().getDbManga(selectedManga.id);
- int textRes = selectedManga.favorite ? R.string.remove_from_library : R.string.add_to_library;
+ int textRes = dbManga.favorite ? R.string.remove_from_library : R.string.add_to_library;
new MaterialDialog.Builder(getActivity())
.items(getString(textRes))
@@ -339,7 +271,6 @@ public class CatalogueFragment extends BaseRxFragment
switch (which) {
case 0:
getPresenter().changeMangaFavorite(selectedManga);
- adapter.notifyItemChanged(position);
break;
}
})
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueGridHolder.java b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueGridHolder.java
deleted file mode 100644
index b45fe51e6d..0000000000
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueGridHolder.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package eu.kanade.tachiyomi.ui.catalogue;
-
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import butterknife.Bind;
-import butterknife.ButterKnife;
-import eu.kanade.tachiyomi.R;
-import eu.kanade.tachiyomi.data.database.models.Manga;
-
-public class CatalogueGridHolder extends CatalogueHolder {
-
- @Bind(R.id.title) TextView title;
- @Bind(R.id.thumbnail) ImageView thumbnail;
- @Bind(R.id.favorite_sticker) ImageView favoriteSticker;
-
- public CatalogueGridHolder(View view, CatalogueAdapter adapter, OnListItemClickListener listener) {
- super(view, adapter, listener);
- ButterKnife.bind(this, view);
- }
-
- @Override
- public void onSetValues(Manga manga, CataloguePresenter presenter) {
- title.setText(manga.title);
- favoriteSticker.setVisibility(manga.favorite ? View.VISIBLE : View.GONE);
- setImage(manga, presenter);
- }
-
- public void setImage(Manga manga, CataloguePresenter presenter) {
- if (manga.thumbnail_url != null) {
- presenter.coverCache.loadFromNetwork(thumbnail, manga.thumbnail_url,
- presenter.getSource().getGlideHeaders());
- } else {
- thumbnail.setImageResource(android.R.color.transparent);
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueHolder.java b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueHolder.java
index 8de83acee1..243b6d8041 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueHolder.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueHolder.java
@@ -1,15 +1,38 @@
package eu.kanade.tachiyomi.ui.catalogue;
import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+import butterknife.Bind;
+import butterknife.ButterKnife;
+import eu.kanade.tachiyomi.R;
import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder;
-public abstract class CatalogueHolder extends FlexibleViewHolder {
+public class CatalogueHolder extends FlexibleViewHolder {
+
+ @Bind(R.id.title) TextView title;
+ @Bind(R.id.thumbnail) ImageView thumbnail;
+ @Bind(R.id.favorite_sticker) ImageView favoriteSticker;
public CatalogueHolder(View view, CatalogueAdapter adapter, OnListItemClickListener listener) {
super(view, adapter, listener);
+ ButterKnife.bind(this, view);
}
- abstract void onSetValues(Manga manga, CataloguePresenter presenter);
-}
+ public void onSetValues(Manga manga, CataloguePresenter presenter) {
+ title.setText(manga.title);
+ favoriteSticker.setVisibility(manga.favorite ? View.VISIBLE : View.GONE);
+ setImage(manga, presenter);
+ }
+
+ public void setImage(Manga manga, CataloguePresenter presenter) {
+ if (manga.thumbnail_url != null) {
+ presenter.coverCache.loadFromNetwork(thumbnail, manga.thumbnail_url,
+ presenter.getSource().getGlideHeaders());
+ } else {
+ thumbnail.setImageResource(android.R.color.transparent);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueListHolder.java b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueListHolder.java
deleted file mode 100644
index 94042c4494..0000000000
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueListHolder.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package eu.kanade.tachiyomi.ui.catalogue;
-
-import android.support.v4.content.ContextCompat;
-import android.view.View;
-import android.widget.TextView;
-
-import butterknife.Bind;
-import butterknife.ButterKnife;
-import eu.kanade.tachiyomi.R;
-import eu.kanade.tachiyomi.data.database.models.Manga;
-
-public class CatalogueListHolder extends CatalogueHolder {
-
- @Bind(R.id.title) TextView title;
-
- private final int favoriteColor;
- private final int unfavoriteColor;
-
- public CatalogueListHolder(View view, CatalogueAdapter adapter, OnListItemClickListener listener) {
- super(view, adapter, listener);
- ButterKnife.bind(this, view);
-
- favoriteColor = ContextCompat.getColor(view.getContext(), R.color.hint_text);
- unfavoriteColor = ContextCompat.getColor(view.getContext(), R.color.primary_text);
- }
-
- @Override
- public void onSetValues(Manga manga, CataloguePresenter presenter) {
- title.setText(manga.title);
- title.setTextColor(manga.favorite ? favoriteColor : unfavoriteColor);
- }
-}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CataloguePresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CataloguePresenter.java
index 97e835c204..bc30ba7602 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CataloguePresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CataloguePresenter.java
@@ -42,8 +42,6 @@ public class CataloguePresenter extends BasePresenter {
private PublishSubject> mangaDetailSubject;
- private boolean isListMode;
-
private static final int GET_MANGA_LIST = 1;
private static final int GET_MANGA_DETAIL = 2;
private static final int GET_MANGA_PAGE = 3;
@@ -74,14 +72,12 @@ public class CataloguePresenter extends BasePresenter {
.observeOn(Schedulers.io())
.flatMap(Observable::from)
.filter(manga -> !manga.initialized)
- .concatMap(this::getMangaDetails)
+ .window(3)
+ .concatMap(pack -> pack.concatMap(this::getMangaDetails))
.onBackpressureBuffer()
.observeOn(AndroidSchedulers.mainThread()),
CatalogueFragment::updateImage,
(view, error) -> Timber.e(error.getMessage()));
-
- add(prefs.catalogueAsList().asObservable()
- .subscribe(this::setDisplayMode));
}
private void onProcessRestart() {
@@ -91,15 +87,6 @@ public class CataloguePresenter extends BasePresenter {
stop(GET_MANGA_PAGE);
}
- private void setDisplayMode(boolean asList) {
- this.isListMode = asList;
- if (asList) {
- stop(GET_MANGA_DETAIL);
- } else {
- start(GET_MANGA_DETAIL);
- }
- }
-
public void startRequesting(Source source) {
this.source = source;
sourceId = source.getId();
@@ -111,9 +98,7 @@ public class CataloguePresenter extends BasePresenter {
stop(GET_MANGA_PAGE);
lastMangasPage = null;
- if (!isListMode) {
- start(GET_MANGA_DETAIL);
- }
+ start(GET_MANGA_DETAIL);
start(GET_MANGA_LIST);
start(GET_MANGA_PAGE);
}
@@ -139,7 +124,10 @@ public class CataloguePresenter extends BasePresenter {
.flatMap(mangasPage -> Observable.from(mangasPage.mangas))
.map(this::networkToLocalManga)
.toList()
- .doOnNext(this::initializeMangas)
+ .doOnNext(mangas -> {
+ if (mangaDetailSubject != null)
+ mangaDetailSubject.onNext(mangas);
+ })
.observeOn(AndroidSchedulers.mainThread());
}
@@ -153,12 +141,9 @@ public class CataloguePresenter extends BasePresenter {
return localManga;
}
- public void initializeMangas(List mangas) {
- mangaDetailSubject.onNext(mangas);
- }
-
private Observable getMangaDetails(final Manga manga) {
return source.pullMangaFromNetwork(manga.url)
+ .subscribeOn(Schedulers.io())
.flatMap(networkManga -> {
manga.copyFrom(networkManga);
db.insertManga(manga).executeAsBlocking();
@@ -167,6 +152,10 @@ public class CataloguePresenter extends BasePresenter {
.onErrorResumeNext(error -> Observable.just(manga));
}
+ public Manga getDbManga(long id) {
+ return db.getManga(id).executeAsBlocking();
+ }
+
public Source getSource() {
return source;
}
@@ -192,13 +181,4 @@ public class CataloguePresenter extends BasePresenter {
manga.favorite = !manga.favorite;
db.insertManga(manga).executeAsBlocking();
}
-
- public boolean isListMode() {
- return isListMode;
- }
-
- public void swapDisplayMode() {
- prefs.catalogueAsList().set(!isListMode);
- }
-
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.java
index fe69bc884d..429180f758 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.java
@@ -90,7 +90,6 @@ public class DownloadPresenter extends BasePresenter {
.flatMap(tick -> Observable.from(download.pages)
.map(Page::getProgress)
.reduce((x, y) -> x + y))
- .onBackpressureLatest()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(progress -> {
if (download.totalProgress != progress) {
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.java
index d4cbfd4eee..9319e9db93 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.java
@@ -52,7 +52,7 @@ public class LibraryCategoryAdapter extends FlexibleAdapter {
@Override
protected void onTakeView(LibraryFragment libraryFragment) {
super.onTakeView(libraryFragment);
- if (isUnsubscribed(GET_LIBRARY)) {
+ if (!isSubscribed(GET_LIBRARY)) {
start(GET_LIBRARY);
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaActivity.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaActivity.java
index 7a550b536d..8899cf04f6 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaActivity.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaActivity.java
@@ -14,7 +14,6 @@ import javax.inject.Inject;
import butterknife.Bind;
import butterknife.ButterKnife;
-import de.greenrobot.event.EventBus;
import eu.kanade.tachiyomi.App;
import eu.kanade.tachiyomi.R;
import eu.kanade.tachiyomi.data.database.models.Manga;
@@ -31,21 +30,21 @@ public class MangaActivity extends BaseRxActivity {
@Bind(R.id.toolbar) Toolbar toolbar;
@Bind(R.id.tabs) TabLayout tabs;
- @Bind(R.id.view_pager) ViewPager viewPager;
+ @Bind(R.id.view_pager) ViewPager view_pager;
@Inject PreferencesHelper preferences;
@Inject MangaSyncManager mangaSyncManager;
private MangaDetailAdapter adapter;
- private boolean isOnline;
+ private long manga_id;
+ private boolean is_online;
+ public final static String MANGA_ID = "manga_id";
public final static String MANGA_ONLINE = "manga_online";
public static Intent newIntent(Context context, Manga manga) {
Intent intent = new Intent(context, MangaActivity.class);
- if (manga != null) {
- EventBus.getDefault().postSticky(manga);
- }
+ intent.putExtra(MANGA_ID, manga.id);
return intent;
}
@@ -60,19 +59,23 @@ public class MangaActivity extends BaseRxActivity {
Intent intent = getIntent();
- isOnline = intent.getBooleanExtra(MANGA_ONLINE, false);
+ manga_id = intent.getLongExtra(MANGA_ID, -1);
+ is_online = intent.getBooleanExtra(MANGA_ONLINE, false);
setupViewPager();
+
+ if (savedState == null)
+ getPresenter().queryManga(manga_id);
}
private void setupViewPager() {
adapter = new MangaDetailAdapter(getSupportFragmentManager(), this);
- viewPager.setAdapter(adapter);
- tabs.setupWithViewPager(viewPager);
+ view_pager.setAdapter(adapter);
+ tabs.setupWithViewPager(view_pager);
- if (!isOnline)
- viewPager.setCurrentItem(MangaDetailAdapter.CHAPTERS_FRAGMENT);
+ if (!is_online)
+ view_pager.setCurrentItem(MangaDetailAdapter.CHAPTERS_FRAGMENT);
}
public void setManga(Manga manga) {
@@ -80,7 +83,7 @@ public class MangaActivity extends BaseRxActivity {
}
public boolean isCatalogueManga() {
- return isOnline;
+ return is_online;
}
class MangaDetailAdapter extends FragmentPagerAdapter {
@@ -101,7 +104,7 @@ public class MangaActivity extends BaseRxActivity {
};
pageCount = 2;
- if (!isOnline && mangaSyncManager.getMyAnimeList().isLogged())
+ if (!is_online && mangaSyncManager.getMyAnimeList().isLogged())
pageCount++;
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.java
index a24f093e71..15faffb3ea 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.java
@@ -7,48 +7,44 @@ import javax.inject.Inject;
import de.greenrobot.event.EventBus;
import eu.kanade.tachiyomi.data.database.DatabaseHelper;
import eu.kanade.tachiyomi.data.database.models.Manga;
-import eu.kanade.tachiyomi.event.MangaEvent;
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter;
-import eu.kanade.tachiyomi.util.EventBusHook;
import icepick.State;
import rx.Observable;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
public class MangaPresenter extends BasePresenter {
@Inject DatabaseHelper db;
- @State Manga manga;
+ @State long mangaId;
- private static final int GET_MANGA = 1;
+ private static final int DB_MANGA = 1;
@Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
- restartableLatestCache(GET_MANGA, this::getMangaObservable, MangaActivity::setManga);
-
- if (savedState == null)
- registerForStickyEvents();
+ restartableLatestCache(DB_MANGA, this::getDbMangaObservable, MangaActivity::setManga);
}
@Override
protected void onDestroy() {
super.onDestroy();
// Avoid new instances receiving wrong manga
- EventBus.getDefault().removeStickyEvent(MangaEvent.class);
+ EventBus.getDefault().removeStickyEvent(Manga.class);
}
- private Observable getMangaObservable() {
- return Observable.just(manga)
- .doOnNext(manga -> EventBus.getDefault().postSticky(new MangaEvent(manga)));
+ private Observable getDbMangaObservable() {
+ return db.getManga(mangaId).asRxObservable()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .doOnNext(manga -> EventBus.getDefault().postSticky(manga));
}
- @EventBusHook
- public void onEventMainThread(Manga manga) {
- EventBus.getDefault().removeStickyEvent(manga);
- unregisterForEvents();
- this.manga = manga;
- start(GET_MANGA);
+ public void queryManga(long mangaId) {
+ this.mangaId = mangaId;
+ start(DB_MANGA);
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.java
index ba7db26bcb..0e0e64392a 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.java
@@ -10,7 +10,6 @@ import java.util.List;
import eu.davidea.flexibleadapter.FlexibleAdapter;
import eu.kanade.tachiyomi.R;
import eu.kanade.tachiyomi.data.database.models.Chapter;
-import eu.kanade.tachiyomi.data.database.models.Manga;
public class ChaptersAdapter extends FlexibleAdapter {
@@ -34,8 +33,7 @@ public class ChaptersAdapter extends FlexibleAdapter {
@Override
public void onBindViewHolder(ChaptersHolder holder, int position) {
final Chapter chapter = getItem(position);
- final Manga manga = fragment.getPresenter().getManga();
- holder.onSetValues(chapter, manga);
+ holder.onSetValues(fragment.getActivity(), chapter);
//When user scrolls this bind the correct selection status
holder.itemView.setActivated(isSelected(position));
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.java
index 682aa34a50..0ecd4e9395 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.java
@@ -10,7 +10,6 @@ import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@@ -25,7 +24,6 @@ import butterknife.Bind;
import butterknife.ButterKnife;
import eu.kanade.tachiyomi.R;
import eu.kanade.tachiyomi.data.database.models.Chapter;
-import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.download.DownloadService;
import eu.kanade.tachiyomi.data.download.model.Download;
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder;
@@ -63,12 +61,6 @@ public class ChaptersFragment extends BaseRxFragment implemen
return new ChaptersFragment();
}
- @Override
- public void onCreate(Bundle bundle) {
- super.onCreate(bundle);
- setHasOptionsMenu(true);
- }
-
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -79,14 +71,26 @@ public class ChaptersFragment extends BaseRxFragment implemen
// Init RecyclerView and adapter
linearLayout = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(linearLayout);
- recyclerView.addItemDecoration(new DividerItemDecoration(
- ContextCompat.getDrawable(getContext(), R.drawable.line_divider)));
+ recyclerView.addItemDecoration(new DividerItemDecoration(ContextCompat.getDrawable(getContext(), R.drawable.line_divider)));
recyclerView.setHasFixedSize(true);
adapter = new ChaptersAdapter(this);
recyclerView.setAdapter(adapter);
- swipeRefresh.setOnRefreshListener(this::fetchChapters);
+ // Set initial values
+ setReadFilter();
+ setDownloadedFilter();
+ setSortIcon();
+ // Init listeners
+ swipeRefresh.setOnRefreshListener(this::fetchChapters);
+ readCb.setOnCheckedChangeListener((arg, isChecked) ->
+ getPresenter().setReadFilter(isChecked));
+ downloadedCb.setOnCheckedChangeListener((v, isChecked) ->
+ getPresenter().setDownloadedFilter(isChecked));
+ sortBtn.setOnClickListener(v -> {
+ getPresenter().revertSortOrder();
+ setSortIcon();
+ });
nextUnreadBtn.setOnClickListener(v -> {
Chapter chapter = getPresenter().getNextUnreadChapter();
if (chapter != null) {
@@ -100,40 +104,15 @@ public class ChaptersFragment extends BaseRxFragment implemen
}
@Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- inflater.inflate(R.menu.chapters, menu);
+ public void onResume() {
+ super.onResume();
+ observeChapterDownloadProgress();
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.action_display_mode:
- showDisplayModeDialog();
- return true;
- }
- return false;
- }
-
- public void onNextManga(Manga manga) {
- // Remove listeners before setting the values
- readCb.setOnCheckedChangeListener(null);
- downloadedCb.setOnCheckedChangeListener(null);
- sortBtn.setOnClickListener(null);
-
- // Set initial values
- setReadFilter();
- setDownloadedFilter();
- setSortIcon();
-
- // Init listeners
- readCb.setOnCheckedChangeListener((arg, isChecked) ->
- getPresenter().setReadFilter(isChecked));
- downloadedCb.setOnCheckedChangeListener((v, isChecked) ->
- getPresenter().setDownloadedFilter(isChecked));
- sortBtn.setOnClickListener(v -> {
- getPresenter().revertSortOrder();
- setSortIcon();
- });
+ public void onPause() {
+ unsubscribeChapterDownloadProgress();
+ super.onPause();
}
public void onNextChapters(List chapters) {
@@ -179,29 +158,6 @@ public class ChaptersFragment extends BaseRxFragment implemen
startActivity(intent);
}
- private void showDisplayModeDialog() {
- final Manga manga = getPresenter().getManga();
- if (manga == null)
- return;
-
- // Get available modes, ids and the selected mode
- String[] modes = {getString(R.string.show_title), getString(R.string.show_chapter_number)};
- int[] ids = {Manga.DISPLAY_NAME, Manga.DISPLAY_NUMBER};
- int selectedIndex = manga.getDisplayMode() == Manga.DISPLAY_NAME ? 0 : 1;
-
- new MaterialDialog.Builder(getActivity())
- .items(modes)
- .itemsIds(ids)
- .itemsCallbackSingleChoice(selectedIndex, (dialog, itemView, which, text) -> {
- // Save the new display mode
- getPresenter().setDisplayMode(itemView.getId());
- // Refresh ui
- adapter.notifyDataSetChanged();
- return true;
- })
- .show();
- }
-
private void observeChapterDownloadProgress() {
downloadProgressSubscription = getPresenter().getDownloadProgressObs()
.subscribe(this::onDownloadProgressChange,
@@ -219,10 +175,10 @@ public class ChaptersFragment extends BaseRxFragment implemen
holder.onProgressChange(getContext(), download.downloadedImages, download.pages.size());
}
- public void onChapterStatusChange(Download download) {
- ChaptersHolder holder = getHolder(download.chapter);
+ public void onChapterStatusChange(Chapter chapter) {
+ ChaptersHolder holder = getHolder(chapter);
if (holder != null)
- holder.onStatusChange(download.getStatus());
+ holder.onStatusChange(chapter.status);
}
@Nullable
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersHolder.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersHolder.java
index a8c76fa82f..b57813e821 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersHolder.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersHolder.java
@@ -7,8 +7,6 @@ import android.widget.PopupMenu;
import android.widget.RelativeLayout;
import android.widget.TextView;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -16,61 +14,40 @@ import butterknife.Bind;
import butterknife.ButterKnife;
import eu.kanade.tachiyomi.R;
import eu.kanade.tachiyomi.data.database.models.Chapter;
-import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.download.model.Download;
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder;
import rx.Observable;
public class ChaptersHolder extends FlexibleViewHolder {
+ private final ChaptersAdapter adapter;
+ private Chapter item;
+
@Bind(R.id.chapter_title) TextView title;
@Bind(R.id.download_text) TextView downloadText;
@Bind(R.id.chapter_menu) RelativeLayout chapterMenu;
@Bind(R.id.chapter_pages) TextView pages;
@Bind(R.id.chapter_date) TextView date;
- private Context context;
-
- private final ChaptersAdapter adapter;
- private Chapter item;
-
- private final int readColor;
- private final int unreadColor;
-
- private final DecimalFormat decimalFormat;
- private SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
+ SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
public ChaptersHolder(View view, ChaptersAdapter adapter, OnListItemClickListener listener) {
super(view, adapter, listener);
this.adapter = adapter;
- context = view.getContext();
ButterKnife.bind(this, view);
- readColor = ContextCompat.getColor(view.getContext(), R.color.hint_text);
- unreadColor = ContextCompat.getColor(view.getContext(), R.color.primary_text);
-
- DecimalFormatSymbols symbols = new DecimalFormatSymbols();
- symbols.setDecimalSeparator('.');
- decimalFormat = new DecimalFormat("#.###", symbols);
-
chapterMenu.setOnClickListener(v -> v.post(() -> showPopupMenu(v)));
}
- public void onSetValues(Chapter chapter, Manga manga) {
+ public void onSetValues(Context context, Chapter chapter) {
this.item = chapter;
- String name;
- switch (manga.getDisplayMode()) {
- case Manga.DISPLAY_NAME:
- default:
- name = chapter.name;
- break;
- case Manga.DISPLAY_NUMBER:
- String formattedNumber = decimalFormat.format(chapter.chapter_number);
- name = context.getString(R.string.display_mode_chapter, formattedNumber);
- break;
+ title.setText(chapter.name);
+
+ if (chapter.read) {
+ title.setTextColor(ContextCompat.getColor(context, R.color.hint_text));
+ } else {
+ title.setTextColor(ContextCompat.getColor(context, R.color.primary_text));
}
- title.setText(name);
- title.setTextColor(chapter.read ? readColor : unreadColor);
if (!chapter.read && chapter.last_page_read > 0) {
pages.setText(context.getString(R.string.chapter_progress, chapter.last_page_read + 1));
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.java
index e981ec0e7b..de89c1c796 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.java
@@ -18,7 +18,6 @@ import eu.kanade.tachiyomi.data.source.SourceManager;
import eu.kanade.tachiyomi.data.source.base.Source;
import eu.kanade.tachiyomi.event.ChapterCountEvent;
import eu.kanade.tachiyomi.event.DownloadChaptersEvent;
-import eu.kanade.tachiyomi.event.MangaEvent;
import eu.kanade.tachiyomi.event.ReaderEvent;
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter;
import eu.kanade.tachiyomi.util.EventBusHook;
@@ -39,16 +38,16 @@ public class ChaptersPresenter extends BasePresenter {
private Manga manga;
private Source source;
private List chapters;
+ private boolean sortOrderAToZ = true;
private boolean onlyUnread = true;
private boolean onlyDownloaded;
@State boolean hasRequested;
private PublishSubject> chaptersSubject;
- private static final int GET_MANGA = 1;
- private static final int DB_CHAPTERS = 2;
- private static final int FETCH_CHAPTERS = 3;
- private static final int CHAPTER_STATUS_CHANGES = 4;
+ private static final int DB_CHAPTERS = 1;
+ private static final int FETCH_CHAPTERS = 2;
+ private static final int CHAPTER_STATUS_CHANGES = 3;
@Override
protected void onCreate(Bundle savedState) {
@@ -60,10 +59,6 @@ public class ChaptersPresenter extends BasePresenter {
chaptersSubject = PublishSubject.create();
- restartableLatestCache(GET_MANGA,
- () -> Observable.just(manga),
- ChaptersFragment::onNextManga);
-
restartableLatestCache(DB_CHAPTERS,
this::getDbChaptersObs,
ChaptersFragment::onNextChapters);
@@ -75,14 +70,13 @@ public class ChaptersPresenter extends BasePresenter {
restartableLatestCache(CHAPTER_STATUS_CHANGES,
this::getChapterStatusObs,
- (view, download) -> view.onChapterStatusChange(download),
+ (view, download) -> view.onChapterStatusChange(download.chapter),
(view, error) -> Timber.e(error.getCause(), error.getMessage()));
registerForStickyEvents();
}
private void onProcessRestart() {
- stop(GET_MANGA);
stop(DB_CHAPTERS);
stop(FETCH_CHAPTERS);
stop(CHAPTER_STATUS_CHANGES);
@@ -96,11 +90,10 @@ public class ChaptersPresenter extends BasePresenter {
}
@EventBusHook
- public void onEventMainThread(MangaEvent event) {
- this.manga = event.manga;
- start(GET_MANGA);
+ public void onEventMainThread(Manga manga) {
+ this.manga = manga;
- if (isUnsubscribed(DB_CHAPTERS)) {
+ if (!isSubscribed(DB_CHAPTERS)) {
source = sourceManager.get(manga.source);
start(DB_CHAPTERS);
@@ -148,7 +141,7 @@ public class ChaptersPresenter extends BasePresenter {
if (onlyDownloaded) {
observable = observable.filter(chapter -> chapter.status == Download.DOWNLOADED);
}
- return observable.toSortedList((chapter, chapter2) -> getSortOrder() ?
+ return observable.toSortedList((chapter, chapter2) -> sortOrderAToZ ?
Float.compare(chapter2.chapter_number, chapter.chapter_number) :
Float.compare(chapter.chapter_number, chapter2.chapter_number));
}
@@ -248,8 +241,8 @@ public class ChaptersPresenter extends BasePresenter {
}
public void revertSortOrder() {
- manga.setChapterOrder(getSortOrder() ? Manga.SORT_ZA : Manga.SORT_AZ);
- db.insertManga(manga).executeAsBlocking();
+ //TODO manga.chapter_order
+ sortOrderAToZ = !sortOrderAToZ;
refreshChapters();
}
@@ -264,13 +257,8 @@ public class ChaptersPresenter extends BasePresenter {
refreshChapters();
}
- public void setDisplayMode(int mode) {
- manga.setDisplayMode(mode);
- db.insertManga(manga).executeAsBlocking();
- }
-
public boolean getSortOrder() {
- return manga.sortChaptersAZ();
+ return sortOrderAToZ;
}
public boolean getReadFilter() {
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.java
index 033e8e7ce8..16aaeee9e0 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.java
@@ -16,7 +16,6 @@ import butterknife.ButterKnife;
import eu.kanade.tachiyomi.R;
import eu.kanade.tachiyomi.data.cache.CoverCache;
import eu.kanade.tachiyomi.data.database.models.Manga;
-import eu.kanade.tachiyomi.data.source.base.Source;
import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment;
import nucleus.factory.RequiresPresenter;
@@ -30,7 +29,6 @@ public class MangaInfoFragment extends BaseRxFragment {
@Bind(R.id.manga_chapters) TextView chapterCount;
@Bind(R.id.manga_genres) TextView genres;
@Bind(R.id.manga_status) TextView status;
- @Bind(R.id.manga_source) TextView source;
@Bind(R.id.manga_summary) TextView description;
@Bind(R.id.manga_cover) ImageView cover;
@@ -62,22 +60,18 @@ public class MangaInfoFragment extends BaseRxFragment {
return view;
}
- public void onNextManga(Manga manga, Source source) {
+ public void onNextManga(Manga manga) {
if (manga.initialized) {
- setMangaInfo(manga, source);
+ setMangaInfo(manga);
} else {
// Initialize manga
fetchMangaFromSource();
}
}
- private void setMangaInfo(Manga manga, Source mangaSource) {
+ private void setMangaInfo(Manga manga) {
artist.setText(manga.artist);
author.setText(manga.author);
-
- if (mangaSource != null) {
- source.setText(mangaSource.getName());
- }
genres.setText(manga.genre);
status.setText(manga.getStatus(getActivity()));
description.setText(manga.description);
@@ -88,7 +82,7 @@ public class MangaInfoFragment extends BaseRxFragment {
LazyHeaders headers = getPresenter().source.getGlideHeaders();
if (manga.thumbnail_url != null && cover.getDrawable() == null) {
if (manga.favorite) {
- coverCache.saveOrLoadFromCache(cover, manga.thumbnail_url, headers);
+ coverCache.saveAndLoadFromCache(cover, manga.thumbnail_url, headers);
} else {
coverCache.loadFromNetwork(cover, manga.thumbnail_url, headers);
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.java
index bfeb251be1..8965419059 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.java
@@ -10,7 +10,6 @@ import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.source.SourceManager;
import eu.kanade.tachiyomi.data.source.base.Source;
import eu.kanade.tachiyomi.event.ChapterCountEvent;
-import eu.kanade.tachiyomi.event.MangaEvent;
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter;
import eu.kanade.tachiyomi.util.EventBusHook;
import rx.Observable;
@@ -19,18 +18,19 @@ import rx.schedulers.Schedulers;
public class MangaInfoPresenter extends BasePresenter {
+ @Inject DatabaseHelper db;
+ @Inject SourceManager sourceManager;
+ @Inject CoverCache coverCache;
+
+ private Manga manga;
+ protected Source source;
+ private int count = -1;
+
+ private boolean isFetching;
+
private static final int GET_MANGA = 1;
private static final int GET_CHAPTER_COUNT = 2;
private static final int FETCH_MANGA_INFO = 3;
- protected Source source;
- @Inject
- DatabaseHelper db;
- @Inject
- SourceManager sourceManager;
- @Inject
- CoverCache coverCache;
- private Manga manga;
- private int count = -1;
@Override
protected void onCreate(Bundle savedState) {
@@ -42,7 +42,7 @@ public class MangaInfoPresenter extends BasePresenter {
restartableLatestCache(GET_MANGA,
() -> Observable.just(manga),
- (view, manga) -> view.onNextManga(manga, source));
+ MangaInfoFragment::onNextManga);
restartableLatestCache(GET_CHAPTER_COUNT,
() -> Observable.just(count),
@@ -69,10 +69,10 @@ public class MangaInfoPresenter extends BasePresenter {
}
@EventBusHook
- public void onEventMainThread(MangaEvent event) {
- this.manga = event.manga;
+ public void onEventMainThread(Manga manga) {
+ this.manga = manga;
source = sourceManager.get(manga.source);
- refreshManga();
+ start(GET_MANGA);
}
@EventBusHook
@@ -84,7 +84,8 @@ public class MangaInfoPresenter extends BasePresenter {
}
public void fetchMangaFromSource() {
- if (isUnsubscribed(FETCH_MANGA_INFO)) {
+ if (!isFetching) {
+ isFetching = true;
start(FETCH_MANGA_INFO);
}
}
@@ -96,29 +97,23 @@ public class MangaInfoPresenter extends BasePresenter {
db.insertManga(manga).executeAsBlocking();
return Observable.just(manga);
})
+ .finallyDo(() -> isFetching = false)
.subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .doOnNext(manga -> refreshManga());
+ .observeOn(AndroidSchedulers.mainThread());
}
public void toggleFavorite() {
manga.favorite = !manga.favorite;
onMangaFavoriteChange(manga.favorite);
db.insertManga(manga).executeAsBlocking();
- refreshManga();
}
private void onMangaFavoriteChange(boolean isFavorite) {
if (isFavorite) {
coverCache.save(manga.thumbnail_url, source.getGlideHeaders());
} else {
- coverCache.deleteCoverFromCache(manga.thumbnail_url);
+ coverCache.delete(manga.thumbnail_url);
}
}
- // Used to refresh the view
- private void refreshManga() {
- start(GET_MANGA);
- }
-
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/myanimelist/MyAnimeListPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/myanimelist/MyAnimeListPresenter.java
index db23a4e651..a49b169cde 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/myanimelist/MyAnimeListPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/myanimelist/MyAnimeListPresenter.java
@@ -12,7 +12,6 @@ import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.database.models.MangaSync;
import eu.kanade.tachiyomi.data.mangasync.MangaSyncManager;
import eu.kanade.tachiyomi.data.mangasync.services.MyAnimeList;
-import eu.kanade.tachiyomi.event.MangaEvent;
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter;
import eu.kanade.tachiyomi.util.EventBusHook;
import eu.kanade.tachiyomi.util.ToastUtil;
@@ -103,8 +102,8 @@ public class MyAnimeListPresenter extends BasePresenter {
}
@EventBusHook
- public void onEventMainThread(MangaEvent event) {
- this.manga = event.manga;
+ public void onEventMainThread(Manga manga) {
+ this.manga = manga;
start(GET_MANGA_SYNC);
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.java b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.java
index aa27e2e523..cbe7eabde5 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.java
@@ -164,10 +164,6 @@ public class ReaderActivity extends BaseRxActivity {
}
public void onChapterReady(List pages, Manga manga, Chapter chapter, int currentPage) {
- if (currentPage == -1) {
- currentPage = pages.size() - 1;
- }
-
if (viewer == null) {
viewer = createViewer(manga);
getSupportFragmentManager().beginTransaction().replace(R.id.reader, viewer).commit();
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderMenu.java b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderMenu.java
index 938cc2b9f8..8f8a840a0f 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderMenu.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderMenu.java
@@ -70,7 +70,7 @@ public class ReaderMenu {
bottomMenu.setOnTouchListener((v, event) -> true);
seekBar.setOnSeekBarChangeListener(new PageSeekBarChangeListener());
- decimalFormat = new DecimalFormat("#.###");
+ decimalFormat = new DecimalFormat("#.##");
inverted = false;
initializeOptions();
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.java
index 4834a5fd27..7022d12918 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.java
@@ -215,12 +215,8 @@ public class ReaderPresenter extends BasePresenter {
.doOnNext(mangaSync -> this.mangaSyncList = mangaSync);
}
- private void loadChapter(Chapter chapter) {
- loadChapter(chapter, 0);
- }
-
// Loads the given chapter
- private void loadChapter(Chapter chapter, int requestedPage) {
+ private void loadChapter(Chapter chapter) {
// Before loading the chapter, stop preloading (if it's working) and save current progress
stopPreloadingNextChapter();
@@ -231,7 +227,7 @@ public class ReaderPresenter extends BasePresenter {
if (!chapter.read && chapter.last_page_read != 0)
currentPage = chapter.last_page_read;
else
- currentPage = requestedPage;
+ currentPage = 0;
// Reset next and previous chapter. They have to be fetched again
nextChapter = null;
@@ -316,7 +312,7 @@ public class ReaderPresenter extends BasePresenter {
public boolean loadNextChapter() {
if (hasNextChapter()) {
onChapterLeft();
- loadChapter(nextChapter, 0);
+ loadChapter(nextChapter);
return true;
}
return false;
@@ -325,7 +321,7 @@ public class ReaderPresenter extends BasePresenter {
public boolean loadPreviousChapter() {
if (hasPreviousChapter()) {
onChapterLeft();
- loadChapter(previousChapter, -1);
+ loadChapter(previousChapter);
return true;
}
return false;
@@ -346,7 +342,7 @@ public class ReaderPresenter extends BasePresenter {
}
private void stopPreloadingNextChapter() {
- if (!isUnsubscribed(PRELOAD_NEXT_CHAPTER)) {
+ if (isSubscribed(PRELOAD_NEXT_CHAPTER)) {
stop(PRELOAD_NEXT_CHAPTER);
if (nextChapterPageList != null)
source.savePageList(nextChapter.url, nextChapterPageList);
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedFragment.java
index 6feccd55bb..eb9318820a 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedFragment.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedFragment.java
@@ -71,7 +71,7 @@ public class SettingsAdvancedFragment extends SettingsNestedFragment {
subscriptions.add(Observable.defer(() -> Observable.from(files))
.concatMap(file -> {
- if (chapterCache.removeFileFromCache(file.getName())) {
+ if (chapterCache.remove(file.getName())) {
deletedFiles.incrementAndGet();
}
return Observable.just(file);
diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/UrlUtil.java b/app/src/main/java/eu/kanade/tachiyomi/util/UrlUtil.java
index baf7ce9dce..65e0ea618d 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/util/UrlUtil.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/util/UrlUtil.java
@@ -5,10 +5,6 @@ import java.net.URISyntaxException;
public class UrlUtil {
- private static final String JPG = ".jpg";
- private static final String PNG = ".png";
- private static final String GIF = ".gif";
-
public static String getPath(String s) {
try {
URI uri = new URI(s);
@@ -22,37 +18,4 @@ public class UrlUtil {
return s;
}
}
-
- public static boolean isJpg(String url) {
- return containsIgnoreCase(url, JPG);
- }
-
- public static boolean isPng(String url) {
- return containsIgnoreCase(url, PNG);
- }
-
- public static boolean isGif(String url) {
- return containsIgnoreCase(url, GIF);
- }
-
- public static boolean containsIgnoreCase(String src, String what) {
- final int length = what.length();
- if (length == 0)
- return true; // Empty string is contained
-
- final char firstLo = Character.toLowerCase(what.charAt(0));
- final char firstUp = Character.toUpperCase(what.charAt(0));
-
- for (int i = src.length() - length; i >= 0; i--) {
- // Quick check before calling the more expensive regionMatches() method:
- final char ch = src.charAt(i);
- if (ch != firstLo && ch != firstUp)
- continue;
-
- if (src.regionMatches(true, i, what, 0, length))
- return true;
- }
-
- return false;
- }
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessListScrollListener.java b/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessListScrollListener.java
deleted file mode 100644
index b5fcfa9408..0000000000
--- a/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessListScrollListener.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package eu.kanade.tachiyomi.widget;
-
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-
-import rx.functions.Action0;
-
-public class EndlessListScrollListener extends RecyclerView.OnScrollListener {
-
- private int previousTotal = 0; // The total number of items in the dataset after the last load
- private boolean loading = true; // True if we are still waiting for the last set of data to load.
- private int visibleThreshold = 5; // The minimum amount of items to have below your current scroll position before loading more.
- int firstVisibleItem, visibleItemCount, totalItemCount;
-
- private LinearLayoutManager layoutManager;
-
- private Action0 requestNext;
-
- public EndlessListScrollListener(LinearLayoutManager layoutManager, Action0 requestNext) {
- this.layoutManager = layoutManager;
- this.requestNext = requestNext;
- }
-
- public void resetScroll() {
- previousTotal = 0;
- loading = true;
- }
-
- @Override
- public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
- super.onScrolled(recyclerView, dx, dy);
-
- visibleItemCount = recyclerView.getChildCount();
- totalItemCount = layoutManager.getItemCount();
- firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
-
- if (loading && (totalItemCount > previousTotal)) {
- loading = false;
- previousTotal = totalItemCount;
- }
- if (!loading && (totalItemCount - visibleItemCount)
- <= (firstVisibleItem + visibleThreshold)) {
- // End has been reached
- requestNext.call();
- loading = true;
- }
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessGridScrollListener.java b/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessRecyclerScrollListener.java
similarity index 89%
rename from app/src/main/java/eu/kanade/tachiyomi/widget/EndlessGridScrollListener.java
rename to app/src/main/java/eu/kanade/tachiyomi/widget/EndlessRecyclerScrollListener.java
index a4d74d5502..d55b2a5834 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessGridScrollListener.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessRecyclerScrollListener.java
@@ -5,7 +5,7 @@ import android.support.v7.widget.RecyclerView;
import rx.functions.Action0;
-public class EndlessGridScrollListener extends RecyclerView.OnScrollListener {
+public class EndlessRecyclerScrollListener extends RecyclerView.OnScrollListener {
private int previousTotal = 0; // The total number of items in the dataset after the last load
private boolean loading = true; // True if we are still waiting for the last set of data to load.
@@ -16,7 +16,7 @@ public class EndlessGridScrollListener extends RecyclerView.OnScrollListener {
private Action0 requestNext;
- public EndlessGridScrollListener(GridLayoutManager layoutManager, Action0 requestNext) {
+ public EndlessRecyclerScrollListener(GridLayoutManager layoutManager, Action0 requestNext) {
this.layoutManager = layoutManager;
this.requestNext = requestNext;
}
diff --git a/app/src/main/res/drawable-hdpi/ic_view_list_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_view_list_white_24dp.png
deleted file mode 100644
index 98c45924adc61322072a0058cb4911b6f69aa87f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 125
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K;i>HfYNX4z>ALkupPZ(rfm|(tw
zk<;i;xx>TccD@_DPHYOvoXu^4%_mGdvNpPHEisYGcD}gaVp7T$3CWP7CssH*A68(H
XVAy%vs;MpuXdZ*7tDnm{r-UW|K|k0wldT1B8K;m8XkiNX4z>ALkupPZ(rfm|(tw
zk=05-v+1Zp$OVTbCssHvX1l227^K_XbL`d%$L3QDE>`7US-@z~-m}O2k5>Rq
OVeoYIb6Mw<&;$VPJ0+I@
diff --git a/app/src/main/res/drawable-ldpi/ic_view_list_white_24dp.png b/app/src/main/res/drawable-ldpi/ic_view_list_white_24dp.png
deleted file mode 100644
index 35df0ba80137b2af3a32cfa80269140acbbcf40a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 187
zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a)4CQlc~kcwN$2@2vJ9UTP@hQd?Q
z+z%<(ad$n+zP@hh{;IE9!X2g!7OWk{6AGjP?#V?qa|C?2w!i-WJLW2tDnm{r-UW|1BO7w
diff --git a/app/src/main/res/drawable-ldpi/ic_view_module_white_24dp.png b/app/src/main/res/drawable-ldpi/ic_view_module_white_24dp.png
deleted file mode 100644
index 7bf1e34eeed3c2e7158784eac74781a6684b9ca9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 278
zcmV+x0qOpUP)8xd@Ux8#UvtJgv4wyia}6@x(v6#A~CrLF<7_&n<#_$ih)*Q5?kYc8ogh$Wwo|t2g
zD>}Hrr5^Oh>JOCeOzKnr=9ne^pz}J@`>nO$GYxz;z*{WhaP$h$>tDnm{r-UW|HCz?x
diff --git a/app/src/main/res/drawable-xhdpi/ic_view_list_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_view_list_white_24dp.png
deleted file mode 100644
index 8ce8a806c4f9c9bc791d7122365de2a6a37bbb0e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 117
zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}t8&4Op@B2u{L3FVdQ&MBb@09c476951J
diff --git a/app/src/main/res/drawable-xhdpi/ic_view_module_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_view_module_white_24dp.png
deleted file mode 100644
index 89980e2620249af35757014a33be50f23fe85882..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 115
zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}tD^C~4kcwMxuNZOxC72KV`G5Hv
z^IR?0mhR|j(JCwd>}6nR;CwJ`x*SMtgXvdS28IK(m>3%79$?(sdgPjuh4O!(41=eu
KpUXO@geCyl&?8|0
diff --git a/app/src/main/res/drawable-xxhdpi/ic_view_list_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_view_list_white_24dp.png
deleted file mode 100644
index 6082dad61711ad208e576b363ddbf4f0b396caba..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 144
zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhaw!aZFaLn>~)y|$5)!GMG1!2SA6
zV@D=2#)FqHJ>xp+pBl!_0R|bmFT&nuZf^jCe~mTO9}iDu1c6R@hiOtEB_4kS>><((
aw`v*8Zar%^?y3P~)y|z%0!GMG1;QRfV
zmmEV_8d~)y}pr?!GOc{;Qs%Y
z(pp$lnhI{+ic#JZQkD-?g9Pdr^FCKymqmy)R5mCvUpTT)04~&^7M8*=>xMWJT;#%$
gE*>}s$Vjk%!0>|M(xD^XWz#_7p00i_>zopr0Mmym!vFvP
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_view_module_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_view_module_white_24dp.png
deleted file mode 100644
index 02cd1b32145ee129e393340d21f1514af93b4ebe..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 171
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%xcgiacE$Ln>~)y|Iv&!GVM2;OqUF
z84u4+c3{&<<4Fp>xt9^B1_6GsR?J;ljo?FA4U!E;>
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_edit_categories.xml b/app/src/main/res/layout/activity_edit_categories.xml
index c709d07735..564865341f 100644
--- a/app/src/main/res/layout/activity_edit_categories.xml
+++ b/app/src/main/res/layout/activity_edit_categories.xml
@@ -23,7 +23,6 @@
android:layout_gravity="bottom|right"
android:layout_margin="@dimen/fab_margin"
android:src="@drawable/ic_action_add_18dp"
- app:backgroundTint="@color/colorPrimary"
app:layout_anchor="@id/categories_list"
app:layout_anchorGravity="bottom|right|end"
app:layout_behavior="eu.kanade.tachiyomi.ui.base.fab.ScrollAwareFABBehavior"/>
diff --git a/app/src/main/res/layout/fragment_catalogue.xml b/app/src/main/res/layout/fragment_catalogue.xml
index 38956c3f0f..ad7b10cd24 100644
--- a/app/src/main/res/layout/fragment_catalogue.xml
+++ b/app/src/main/res/layout/fragment_catalogue.xml
@@ -11,28 +11,17 @@
android:id="@+id/progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_height="fill_parent"
android:layout_gravity="center_vertical|center_horizontal"
android:visibility="gone"/>
-
-
-
-
-
-
-
+ android:columnWidth="140dp"
+ tools:listitem="@layout/item_catalogue" />
+ tools:listitem="@layout/item_catalogue" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_manga_info.xml b/app/src/main/res/layout/fragment_manga_info.xml
index f5eaeabf15..2631044ba0 100644
--- a/app/src/main/res/layout/fragment_manga_info.xml
+++ b/app/src/main/res/layout/fragment_manga_info.xml
@@ -154,31 +154,7 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/manga_status_label"
- android:layout_toRightOf="@id/manga_status_label"
- android:ellipsize="end"
- android:focusable="false"
- android:focusableInTouchMode="false"
- android:maxLines="1"
- android:singleLine="true" />
-
-
-
-
diff --git a/app/src/main/res/layout/item_catalogue_grid.xml b/app/src/main/res/layout/item_catalogue.xml
similarity index 52%
rename from app/src/main/res/layout/item_catalogue_grid.xml
rename to app/src/main/res/layout/item_catalogue.xml
index 9836b21f71..a4197e5aaa 100644
--- a/app/src/main/res/layout/item_catalogue_grid.xml
+++ b/app/src/main/res/layout/item_catalogue.xml
@@ -12,27 +12,13 @@
android:layout_height="wrap_content"
android:background="@drawable/card_background">
-
-
-
-
-
-
-
+ android:background="@color/white"
+ tools:background="@color/md_red_100"
+ tools:src="@mipmap/ic_launcher"/>
-
+ android:layout_alignBottom="@+id/thumbnail"
+ android:background="@color/manga_cover_title_background">
+
+
+
+
diff --git a/app/src/main/res/layout/item_catalogue_list.xml b/app/src/main/res/layout/item_catalogue_list.xml
deleted file mode 100644
index 409714fe62..0000000000
--- a/app/src/main/res/layout/item_catalogue_list.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_chapter.xml b/app/src/main/res/layout/item_chapter.xml
index 4ceac37b00..6c873cbbb4 100644
--- a/app/src/main/res/layout/item_chapter.xml
+++ b/app/src/main/res/layout/item_chapter.xml
@@ -66,7 +66,7 @@
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:layout_marginRight="30dp"
- android:ellipsize="middle"
+ android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:textSize="17sp"
diff --git a/app/src/main/res/layout/item_pager_reader.xml b/app/src/main/res/layout/item_pager_reader.xml
index 4fefdc9b19..6813bcb2de 100644
--- a/app/src/main/res/layout/item_pager_reader.xml
+++ b/app/src/main/res/layout/item_pager_reader.xml
@@ -30,8 +30,6 @@
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/toolbar.xml b/app/src/main/res/layout/toolbar.xml
index c621b5a32b..c3e28cc0d2 100644
--- a/app/src/main/res/layout/toolbar.xml
+++ b/app/src/main/res/layout/toolbar.xml
@@ -1,7 +1,9 @@
\ No newline at end of file
+ android:theme="@style/AppTheme.ActionBar"
+ app:layout_scrollFlags="scroll|enterAlways|snap"/>
\ No newline at end of file
diff --git a/app/src/main/res/menu/catalogue_list.xml b/app/src/main/res/menu/catalogue_list.xml
index 668f162618..c0b1a7c5eb 100644
--- a/app/src/main/res/menu/catalogue_list.xml
+++ b/app/src/main/res/menu/catalogue_list.xml
@@ -1,16 +1,11 @@
diff --git a/app/src/main/res/menu/chapters.xml b/app/src/main/res/menu/chapters.xml
deleted file mode 100644
index 1d56f62b39..0000000000
--- a/app/src/main/res/menu/chapters.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
\ No newline at end of file
diff --git a/app/src/main/res/values/keys.xml b/app/src/main/res/values/keys.xml
index e1013b9025..6ccd1552b8 100644
--- a/app/src/main/res/values/keys.xml
+++ b/app/src/main/res/values/keys.xml
@@ -35,6 +35,4 @@
pref_versionpref_build_time
-
- pref_display_catalogue_as_list
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index bb72d2f5bc..025323e9d1 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -38,7 +38,6 @@
Previous chapterNext chapterRetry
- Change display mode
@@ -144,7 +143,6 @@
AuthorChaptersGenres
- SourceArtistDescriptionStatus
@@ -157,15 +155,12 @@
ChaptersNo title
- Chapter %1$sDownloadedQueuedDownloadingDownloading (%1$d/%2$d)ErrorError while fetching chapters
- Show title
- Show chapter numberReading
diff --git a/build.gradle b/build.gradle
index 0bbade5918..150d005340 100644
--- a/build.gradle
+++ b/build.gradle
@@ -21,5 +21,7 @@ allprojects {
jcenter()
maven { url "https://clojars.org/repo/" }
maven { url "https://jitpack.io" }
+ maven { url 'http://dl.bintray.com/amulyakhare/maven' }
+ maven { url 'https://github.com/suckgamony/RapidDecoder/raw/master/repository' }
}
}
diff --git a/libs/SubsamplingScaleImageView/build.gradle b/libs/SubsamplingScaleImageView/build.gradle
index 971dbea647..abdacff135 100644
--- a/libs/SubsamplingScaleImageView/build.gradle
+++ b/libs/SubsamplingScaleImageView/build.gradle
@@ -6,9 +6,9 @@ version = '3.4.1'
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile "com.android.support:support-annotations:23.1.1"
- compile 'com.github.suckgamony.RapidDecoder:library:7cdfca4'
- compile 'com.github.suckgamony.RapidDecoder:jpeg-decoder:7cdfca4'
- compile 'com.github.suckgamony.RapidDecoder:png-decoder:7cdfca4'
+ compile 'rapid.decoder:library:0.3.0'
+ compile 'rapid.decoder:jpeg-decoder:0.3.0'
+ compile 'rapid.decoder:png-decoder:0.3.0'
}
android {
From 8c1c7a9964673ecb86567a7f4eec9f708e1de0b2 Mon Sep 17 00:00:00 2001
From: NoodleMage
Date: Wed, 27 Jan 2016 15:34:43 +0100
Subject: [PATCH 12/12] Fixed I hope
---
README.md | 2 +-
app/build.gradle | 8 +-
.../tachiyomi/data/cache/ChapterCache.java | 121 ++++++++++++--
.../tachiyomi/data/cache/CoverCache.java | 148 +++++++++++++++---
.../data/cache/CoverGlideModule.java | 10 +-
.../tachiyomi/data/database/models/Manga.java | 29 ++++
.../resolvers/MangaChapterGetResolver.java | 1 +
.../data/download/DownloadManager.java | 33 ++--
.../data/preference/PreferencesHelper.java | 8 +-
.../eu/kanade/tachiyomi/event/MangaEvent.java | 12 ++
.../ui/base/presenter/RxPresenter.java | 12 +-
.../ui/catalogue/CatalogueAdapter.java | 13 +-
.../ui/catalogue/CatalogueFragment.java | 107 ++++++++++---
.../ui/catalogue/CatalogueGridHolder.java | 38 +++++
.../ui/catalogue/CatalogueHolder.java | 29 +---
.../ui/catalogue/CatalogueListHolder.java | 32 ++++
.../ui/catalogue/CataloguePresenter.java | 44 ++++--
.../ui/download/DownloadPresenter.java | 1 +
.../ui/library/LibraryCategoryAdapter.java | 4 +-
.../tachiyomi/ui/library/LibraryHolder.java | 6 +-
.../ui/library/LibraryPresenter.java | 2 +-
.../tachiyomi/ui/manga/MangaActivity.java | 29 ++--
.../tachiyomi/ui/manga/MangaPresenter.java | 32 ++--
.../ui/manga/chapter/ChaptersAdapter.java | 4 +-
.../ui/manga/chapter/ChaptersFragment.java | 92 ++++++++---
.../ui/manga/chapter/ChaptersHolder.java | 45 ++++--
.../ui/manga/chapter/ChaptersPresenter.java | 36 +++--
.../ui/manga/info/MangaInfoFragment.java | 14 +-
.../ui/manga/info/MangaInfoPresenter.java | 43 ++---
.../myanimelist/MyAnimeListPresenter.java | 5 +-
.../tachiyomi/ui/reader/ReaderActivity.java | 4 +
.../tachiyomi/ui/reader/ReaderMenu.java | 2 +-
.../tachiyomi/ui/reader/ReaderPresenter.java | 14 +-
.../ui/setting/SettingsAdvancedFragment.java | 2 +-
.../eu/kanade/tachiyomi/util/UrlUtil.java | 37 +++++
...er.java => EndlessGridScrollListener.java} | 4 +-
.../widget/EndlessListScrollListener.java | 49 ++++++
.../drawable-hdpi/ic_view_list_white_24dp.png | Bin 0 -> 125 bytes
.../ic_view_module_white_24dp.png | Bin 0 -> 115 bytes
.../drawable-ldpi/ic_view_list_white_24dp.png | Bin 0 -> 187 bytes
.../ic_view_module_white_24dp.png | Bin 0 -> 278 bytes
.../drawable-mdpi/ic_view_list_white_24dp.png | Bin 0 -> 89 bytes
.../ic_view_module_white_24dp.png | Bin 0 -> 87 bytes
.../ic_view_list_white_24dp.png | Bin 0 -> 117 bytes
.../ic_view_module_white_24dp.png | Bin 0 -> 115 bytes
.../ic_view_list_white_24dp.png | Bin 0 -> 144 bytes
.../ic_view_module_white_24dp.png | Bin 0 -> 139 bytes
.../ic_view_list_white_24dp.png | Bin 0 -> 176 bytes
.../ic_view_module_white_24dp.png | Bin 0 -> 171 bytes
app/src/main/res/drawable/gradient_shape.xml | 12 ++
.../res/layout/activity_edit_categories.xml | 1 +
.../main/res/layout/fragment_catalogue.xml | 23 ++-
.../res/layout/fragment_library_category.xml | 2 +-
.../main/res/layout/fragment_manga_info.xml | 28 +++-
..._catalogue.xml => item_catalogue_grid.xml} | 71 +++++----
.../main/res/layout/item_catalogue_list.xml | 16 ++
app/src/main/res/layout/item_chapter.xml | 2 +-
app/src/main/res/layout/item_pager_reader.xml | 4 +-
app/src/main/res/layout/toolbar.xml | 4 +-
app/src/main/res/menu/catalogue_list.xml | 7 +-
app/src/main/res/menu/chapters.xml | 9 ++
app/src/main/res/values/keys.xml | 2 +
app/src/main/res/values/strings.xml | 5 +
build.gradle | 2 -
libs/SubsamplingScaleImageView/build.gradle | 6 +-
65 files changed, 980 insertions(+), 286 deletions(-)
create mode 100644 app/src/main/java/eu/kanade/tachiyomi/event/MangaEvent.java
create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueGridHolder.java
create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueListHolder.java
rename app/src/main/java/eu/kanade/tachiyomi/widget/{EndlessRecyclerScrollListener.java => EndlessGridScrollListener.java} (89%)
create mode 100644 app/src/main/java/eu/kanade/tachiyomi/widget/EndlessListScrollListener.java
create mode 100644 app/src/main/res/drawable-hdpi/ic_view_list_white_24dp.png
create mode 100644 app/src/main/res/drawable-hdpi/ic_view_module_white_24dp.png
create mode 100644 app/src/main/res/drawable-ldpi/ic_view_list_white_24dp.png
create mode 100644 app/src/main/res/drawable-ldpi/ic_view_module_white_24dp.png
create mode 100644 app/src/main/res/drawable-mdpi/ic_view_list_white_24dp.png
create mode 100644 app/src/main/res/drawable-mdpi/ic_view_module_white_24dp.png
create mode 100644 app/src/main/res/drawable-xhdpi/ic_view_list_white_24dp.png
create mode 100644 app/src/main/res/drawable-xhdpi/ic_view_module_white_24dp.png
create mode 100644 app/src/main/res/drawable-xxhdpi/ic_view_list_white_24dp.png
create mode 100644 app/src/main/res/drawable-xxhdpi/ic_view_module_white_24dp.png
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_view_list_white_24dp.png
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_view_module_white_24dp.png
create mode 100644 app/src/main/res/drawable/gradient_shape.xml
rename app/src/main/res/layout/{item_catalogue.xml => item_catalogue_grid.xml} (52%)
create mode 100644 app/src/main/res/layout/item_catalogue_list.xml
create mode 100644 app/src/main/res/menu/chapters.xml
diff --git a/README.md b/README.md
index f4781b7a4a..4981b0b66c 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Current features:
## Download
-[![stable release](https://img.shields.io/badge/release-v0.1.1-blue.svg)](https://github.com/inorichi/tachiyomi/releases/download/v0.1.1/tachiyomi-v0.1.1.apk)
+[![stable release](https://img.shields.io/badge/release-v0.1.2-blue.svg)](https://github.com/inorichi/tachiyomi/releases/download/v0.1.2/tachiyomi-v0.1.2.apk)
[![latest debug build](https://img.shields.io/badge/debug-latest%20build-blue.svg)](http://tachiyomi.kanade.eu/latest/app-debug.apk)
## License
diff --git a/app/build.gradle b/app/build.gradle
index f096687994..aeb407209b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -39,8 +39,8 @@ android {
minSdkVersion 16
targetSdkVersion 23
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- versionCode 2
- versionName "0.1.1"
+ versionCode 3
+ versionName "0.1.2"
buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\""
buildConfigField "String", "COMMIT_SHA", "\"${getGitSha()}\""
@@ -73,6 +73,7 @@ android {
lintOptions {
abortOnError false
+ checkReleaseBuilds false
}
}
@@ -93,6 +94,7 @@ dependencies {
compile "com.android.support:design:$SUPPORT_LIBRARY_VERSION"
compile "com.android.support:recyclerview-v7:$SUPPORT_LIBRARY_VERSION"
compile "com.android.support:support-annotations:$SUPPORT_LIBRARY_VERSION"
+ compile "com.android.support:percent:$SUPPORT_LIBRARY_VERSION"
compile 'com.squareup.okhttp:okhttp-urlconnection:2.7.2'
compile 'com.squareup.okhttp:okhttp:2.7.2'
compile 'com.squareup.okio:okio:1.6.0'
@@ -116,7 +118,7 @@ dependencies {
compile 'com.github.dmytrodanylyk.android-process-button:library:1.0.4'
compile 'eu.davidea:flexible-adapter:4.2.0'
compile 'com.nononsenseapps:filepicker:2.5.1'
- compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
+ compile 'com.github.amulyakhare:TextDrawable:558677e'
compile 'com.github.pwittchen:reactivenetwork:0.1.5'
compile "com.google.dagger:dagger:$DAGGER_VERSION"
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
index 9571c6020c..3a4e8c1503 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.java
@@ -21,22 +21,46 @@ import okio.BufferedSink;
import okio.Okio;
import rx.Observable;
+/**
+ * Class used to create chapter cache
+ * For each image in a chapter a file is created
+ * For each chapter a Json list is created and converted to a file.
+ * The files are in format *md5key*.0
+ */
public class ChapterCache {
+ /** Name of cache directory. */
private static final String PARAMETER_CACHE_DIRECTORY = "chapter_disk_cache";
+
+ /** Application cache version. */
private static final int PARAMETER_APP_VERSION = 1;
+
+ /** The number of values per cache entry. Must be positive. */
private static final int PARAMETER_VALUE_COUNT = 1;
+
+ /** The maximum number of bytes this cache should use to store. */
private static final int PARAMETER_CACHE_SIZE = 75 * 1024 * 1024;
- private Context context;
- private Gson gson;
+ /** Interface to global information about an application environment. */
+ private final Context context;
+ /** Google Json class used for parsing json files. */
+ private final Gson gson;
+
+ /** Cache class used for cache management. */
private DiskLruCache diskCache;
+ /**
+ * Constructor of ChapterCache.
+ * @param context application environment interface.
+ */
public ChapterCache(Context context) {
this.context = context;
+
+ // Initialize Json handler.
gson = new Gson();
+ // Try to open cache in default cache directory.
try {
diskCache = DiskLruCache.open(
new File(context.getCacheDir(), PARAMETER_CACHE_DIRECTORY),
@@ -45,43 +69,67 @@ public class ChapterCache {
PARAMETER_CACHE_SIZE
);
} catch (IOException e) {
- // Do Nothing.
+ // Do Nothing. TODO error handling.
}
}
- public boolean remove(String file) {
+ /**
+ * Remove file from cache.
+ * @param file name of chapter file md5.0.
+ * @return false if file is journal or error else returns status of deletion.
+ */
+ public boolean removeFileFromCache(String file) {
+ // Make sure we don't delete the journal file (keeps track of cache).
if (file.equals("journal") || file.startsWith("journal."))
return false;
try {
+ // Take dot(.) substring to get filename without the .0 at the end.
String key = file.substring(0, file.lastIndexOf("."));
+ // Remove file from cache.
return diskCache.remove(key);
} catch (IOException e) {
return false;
}
}
+ /**
+ * Returns directory of cache.
+ * @return directory of cache.
+ */
public File getCacheDir() {
return diskCache.getDirectory();
}
- public long getRealSize() {
+ /**
+ * Returns real size of directory.
+ * @return real size of directory.
+ */
+ private long getRealSize() {
return DiskUtils.getDirectorySize(getCacheDir());
}
+ /**
+ * Returns real size of directory in human readable format.
+ * @return real size of directory.
+ */
public String getReadableSize() {
return Formatter.formatFileSize(context, getRealSize());
}
- public void setSize(int value) {
- diskCache.setMaxSize(value * 1024 * 1024);
- }
-
+ /**
+ * Get page objects from cache.
+ * @param chapterUrl the url of the chapter.
+ * @return list of chapter pages.
+ */
public Observable> getPageUrlsFromDiskCache(final String chapterUrl) {
return Observable.create(subscriber -> {
try {
+ // Get list of pages from chapterUrl.
List pages = getPageUrlsFromDiskCacheImpl(chapterUrl);
+ // Provides the Observer with a new item to observe.
subscriber.onNext(pages);
+ // Notify the Observer that finished sending push-based notifications.
subscriber.onCompleted();
} catch (Throwable e) {
subscriber.onError(e);
@@ -89,18 +137,31 @@ public class ChapterCache {
});
}
- private List getPageUrlsFromDiskCacheImpl(String chapterUrl) throws IOException {
+ /**
+ * Implementation of the getPageUrlsFromDiskCache() function
+ * @param chapterUrl the url of the chapter
+ * @return returns list of chapter pages
+ * @throws IOException does nothing atm
+ */
+ private List getPageUrlsFromDiskCacheImpl(String chapterUrl) throws IOException /*TODO IOException never thrown*/ {
+ // Initialize snapshot (a snapshot of the values for an entry).
DiskLruCache.Snapshot snapshot = null;
+
+ // Initialize list of pages.
List pages = null;
try {
+ // Create md5 key and retrieve snapshot.
String key = DiskUtils.hashKeyForDisk(chapterUrl);
snapshot = diskCache.get(key);
+
+ // Convert JSON string to list of objects.
Type collectionType = new TypeToken>() {}.getType();
pages = gson.fromJson(snapshot.getString(0), collectionType);
+
} catch (IOException e) {
- // Do Nothing.
+ // Do Nothing. //TODO error handling?
} finally {
if (snapshot != null) {
snapshot.close();
@@ -109,18 +170,30 @@ public class ChapterCache {
return pages;
}
+ /**
+ * Add page urls to disk cache.
+ * @param chapterUrl the url of the chapter.
+ * @param pages list of chapter pages.
+ */
public void putPageUrlsToDiskCache(final String chapterUrl, final List pages) {
+ // Convert list of pages to json string.
String cachedValue = gson.toJson(pages);
+ // Initialize the editor (edits the values for an entry).
DiskLruCache.Editor editor = null;
+
+ // Initialize OutputStream.
OutputStream outputStream = null;
+
try {
+ // Get editor from md5 key.
String key = DiskUtils.hashKeyForDisk(chapterUrl);
editor = diskCache.edit(key);
if (editor == null) {
return;
}
+ // Write chapter urls to cache.
outputStream = new BufferedOutputStream(editor.newOutputStream(0));
outputStream.write(cachedValue.getBytes());
outputStream.flush();
@@ -128,7 +201,7 @@ public class ChapterCache {
diskCache.flush();
editor.commit();
} catch (Exception e) {
- // Do Nothing.
+ // Do Nothing. TODO error handling?
} finally {
if (editor != null) {
editor.abortUnlessCommitted();
@@ -137,12 +210,17 @@ public class ChapterCache {
try {
outputStream.close();
} catch (IOException ignore) {
- // Do Nothing.
+ // Do Nothing. TODO error handling?
}
}
}
}
+ /**
+ * Check if image is in cache.
+ * @param imageUrl url of image.
+ * @return true if in cache otherwise false.
+ */
public boolean isImageInCache(final String imageUrl) {
try {
return diskCache.get(DiskUtils.hashKeyForDisk(imageUrl)) != null;
@@ -152,8 +230,14 @@ public class ChapterCache {
return false;
}
+ /**
+ * Get image path from url.
+ * @param imageUrl url of image.
+ * @return path of image.
+ */
public String getImagePath(final String imageUrl) {
try {
+ // Get file from md5 key.
String imageName = DiskUtils.hashKeyForDisk(imageUrl) + ".0";
File file = new File(diskCache.getDirectory(), imageName);
return file.getCanonicalPath();
@@ -163,17 +247,28 @@ public class ChapterCache {
return null;
}
+ /**
+ * Add image to cache
+ * @param imageUrl url of image.
+ * @param response http response from page.
+ * @throws IOException image error.
+ */
public void putImageToDiskCache(final String imageUrl, final Response response) throws IOException {
+ // Initialize editor (edits the values for an entry).
DiskLruCache.Editor editor = null;
+
+ // Initialize BufferedSink (used for small writes).
BufferedSink sink = null;
try {
+ // Get editor from md5 key.
String key = DiskUtils.hashKeyForDisk(imageUrl);
editor = diskCache.edit(key);
if (editor == null) {
throw new IOException("Unable to edit key");
}
+ // Initialize OutputStream and write image.
OutputStream outputStream = new BufferedOutputStream(editor.newOutputStream(0));
sink = Okio.buffer(Okio.sink(outputStream));
sink.writeAll(response.body().source());
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
index 7f2697a37f..e76bcf34d3 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.java
@@ -20,33 +20,78 @@ import java.io.OutputStream;
import eu.kanade.tachiyomi.util.DiskUtils;
+/**
+ * Class used to create cover cache
+ * Makes use of Glide(which can avoid repeating requests) for saving the file.
+ * It is not necessary to load the images to the cache.
+ * Names of files are created with the md5 of the thumbnailURL
+ */
public class CoverCache {
+ /**
+ * Name of cache directory.
+ */
private static final String PARAMETER_CACHE_DIRECTORY = "cover_disk_cache";
- private Context context;
- private File cacheDir;
+ /**
+ * Interface to global information about an application environment.
+ */
+ private final Context context;
+ /**
+ * Cache class used for cache management.
+ */
+ private final File cacheDir;
+
+ /**
+ * Constructor of CoverCache.
+ *
+ * @param context application environment interface.
+ */
public CoverCache(Context context) {
this.context = context;
+
+ // Get cache directory from parameter.
cacheDir = new File(context.getCacheDir(), PARAMETER_CACHE_DIRECTORY);
+
+ // Create cache directory.
createCacheDir();
}
+ /**
+ * Check if cache dir exist if not create directory.
+ *
+ * @return true if cache dir does exist and is created.
+ */
private boolean createCacheDir() {
return !cacheDir.exists() && cacheDir.mkdirs();
}
+ /**
+ * Download the cover with Glide (it can avoid repeating requests) and save the file.
+ *
+ * @param thumbnailUrl url of thumbnail.
+ * @param headers headers included in Glide request.
+ */
public void save(String thumbnailUrl, LazyHeaders headers) {
save(thumbnailUrl, headers, null);
}
- // Download the cover with Glide (it can avoid repeating requests) and save the file on this cache
- // Optionally, load the image in the given image view when the resource is ready, if not null
- public void save(String thumbnailUrl, LazyHeaders headers, ImageView imageView) {
+ /**
+ * Download the cover with Glide (it can avoid repeating requests) and save the file.
+ *
+ * @param thumbnailUrl url of thumbnail.
+ * @param headers headers included in Glide request.
+ * @param imageView imageView where picture should be displayed.
+ */
+ private void save(String thumbnailUrl, LazyHeaders headers, ImageView imageView) {
+
+ // Check if url is empty.
if (TextUtils.isEmpty(thumbnailUrl))
+ // Do not try and create the string. Instead... only try to realize the truth. There is no string.
return;
+ // Download the cover with Glide and save the file.
GlideUrl url = new GlideUrl(thumbnailUrl, headers);
Glide.with(context)
.load(url)
@@ -54,7 +99,10 @@ public class CoverCache {
@Override
public void onResourceReady(File resource, GlideAnimation super File> anim) {
try {
- add(thumbnailUrl, resource);
+ // Copy the cover from Glide's cache to local cache.
+ copyToLocalCache(thumbnailUrl, resource);
+
+ // Check if imageView isn't null and show picture in imageView.
if (imageView != null) {
loadFromCache(imageView, resource);
}
@@ -65,18 +113,32 @@ public class CoverCache {
});
}
- // Copy the cover from Glide's cache to this cache
- public void add(String thumbnailUrl, File source) throws IOException {
+
+ /**
+ * Copy the cover from Glide's cache to local cache.
+ *
+ * @param thumbnailUrl url of thumbnail.
+ * @param source the cover image.
+ * @throws IOException TODO not returned atm?
+ */
+ private void copyToLocalCache(String thumbnailUrl, File source) throws IOException {
+ // Create cache directory and check if directory exist
createCacheDir();
+
+ // Create destination file.
File dest = new File(cacheDir, DiskUtils.hashKeyForDisk(thumbnailUrl));
+
+
+ // Check if file already exists, if true delete it.
if (dest.exists())
dest.delete();
+ // Write thumbnail image to file.
InputStream in = new FileInputStream(source);
try {
OutputStream out = new FileOutputStream(dest);
try {
- // Transfer bytes from in to out
+ // Transfer bytes from in to out.
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
@@ -90,23 +152,43 @@ public class CoverCache {
}
}
- // Get the cover from cache
- public File get(String thumbnailUrl) {
+
+ /**
+ * Returns the cover from cache.
+ *
+ * @param thumbnailUrl the thumbnail url.
+ * @return cover image.
+ */
+ private File getCoverFromCache(String thumbnailUrl) {
return new File(cacheDir, DiskUtils.hashKeyForDisk(thumbnailUrl));
}
- // Delete the cover from cache
- public boolean delete(String thumbnailUrl) {
+ /**
+ * Delete the cover file from the cache.
+ *
+ * @param thumbnailUrl the thumbnail url.
+ * @return status of deletion.
+ */
+ public boolean deleteCoverFromCache(String thumbnailUrl) {
+ // Check if url is empty.
if (TextUtils.isEmpty(thumbnailUrl))
return false;
+ // Remove file.
File file = new File(cacheDir, DiskUtils.hashKeyForDisk(thumbnailUrl));
return file.exists() && file.delete();
}
- // Save and load the image from cache
- public void saveAndLoadFromCache(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
- File localCover = get(thumbnailUrl);
+ /**
+ * Save or load the image from cache
+ *
+ * @param imageView imageView where picture should be displayed.
+ * @param thumbnailUrl the thumbnail url.
+ * @param headers headers included in Glide request.
+ */
+ public void saveOrLoadFromCache(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
+ // If file exist load it otherwise save it.
+ File localCover = getCoverFromCache(thumbnailUrl);
if (localCover.exists()) {
loadFromCache(imageView, localCover);
} else {
@@ -114,9 +196,17 @@ public class CoverCache {
}
}
- // If the image is already in our cache, use it. If not, load it with glide
+ /**
+ * If the image is already in our cache, use it. If not, load it with glide.
+ * TODO not used atm.
+ *
+ * @param imageView imageView where picture should be displayed.
+ * @param thumbnailUrl url of thumbnail.
+ * @param headers headers included in Glide request.
+ */
public void loadFromCacheOrNetwork(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
- File localCover = get(thumbnailUrl);
+ // If localCover exist load it from cache otherwise load it from network.
+ File localCover = getCoverFromCache(thumbnailUrl);
if (localCover.exists()) {
loadFromCache(imageView, localCover);
} else {
@@ -124,8 +214,12 @@ public class CoverCache {
}
}
- // Helper method to load the cover from the cache directory into the specified image view
- // The file must exist
+ /**
+ * Helper method to load the cover from the cache directory into the specified image view.
+ *
+ * @param imageView imageView where picture should be displayed.
+ * @param file file to load. Must exist!.
+ */
private void loadFromCache(ImageView imageView, File file) {
Glide.with(context)
.load(file)
@@ -134,9 +228,19 @@ public class CoverCache {
.into(imageView);
}
- // Helper method to load the cover from network into the specified image view.
- // It does NOT save the image in cache
+ /**
+ * Helper method to load the cover from network into the specified image view.
+ * It does NOT save the image in cache!
+ *
+ * @param imageView imageView where picture should be displayed.
+ * @param thumbnailUrl url of thumbnail.
+ * @param headers headers included in Glide request.
+ */
public void loadFromNetwork(ImageView imageView, String thumbnailUrl, LazyHeaders headers) {
+ // Check if url is empty.
+ if (TextUtils.isEmpty(thumbnailUrl))
+ return;
+
GlideUrl url = new GlideUrl(thumbnailUrl, headers);
Glide.with(context)
.load(url)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java
index c94397bcd9..e3613ed560 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverGlideModule.java
@@ -7,8 +7,16 @@ import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.module.GlideModule;
+/**
+ * Class used to update Glide module settings
+ */
public class CoverGlideModule implements GlideModule {
+
+ /**
+ * Bitmaps decoded from most image formats (other than GIFs with hidden configs), will be decoded with the
+ * ARGB_8888 config.
+ */
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
@@ -16,6 +24,6 @@ public class CoverGlideModule implements GlideModule {
@Override
public void registerComponents(Context context, Glide glide) {
-
+ // Nothing to see here!
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.java b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.java
index 5548f69ff8..a8acba4994 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.java
@@ -68,6 +68,14 @@ public class Manga implements Serializable {
public static final int COMPLETED = 2;
public static final int LICENSED = 3;
+ public static final int SORT_AZ = 0x00000000;
+ public static final int SORT_ZA = 0x00000001;
+ public static final int SORT_MASK = 0x00000001;
+
+ public static final int DISPLAY_NAME = 0x00000000;
+ public static final int DISPLAY_NUMBER = 0x00100000;
+ public static final int DISPLAY_MASK = 0x00100000;
+
public Manga() {}
public static Manga create(String pathUrl) {
@@ -120,6 +128,27 @@ public class Manga implements Serializable {
}
}
+ public void setChapterOrder(int order) {
+ setFlags(order, SORT_MASK);
+ }
+
+ public void setDisplayMode(int mode) {
+ setFlags(mode, DISPLAY_MASK);
+ }
+
+ private void setFlags(int flag, int mask) {
+ chapter_flags = (chapter_flags & ~mask) | (flag & mask);
+ }
+
+ public boolean sortChaptersAZ() {
+ return (chapter_flags & SORT_MASK) == SORT_AZ;
+ }
+
+ // Used to display the chapter's title one way or another
+ public int getDisplayMode() {
+ return chapter_flags & DISPLAY_MASK;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaChapterGetResolver.java b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaChapterGetResolver.java
index 67eb65e83f..2313f6bd38 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaChapterGetResolver.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaChapterGetResolver.java
@@ -49,6 +49,7 @@ public class MangaChapterGetResolver extends DefaultGetResolver {
public MangaChapter mapFromCursor(@NonNull Cursor cursor) {
final Manga manga = mangaGetResolver.mapFromCursor(cursor);
final Chapter chapter = chapterGetResolver.mapFromCursor(cursor);
+ manga.id = chapter.manga_id;
return new MangaChapter(manga, chapter);
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.java b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.java
index e4f71632bf..da828f33ec 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.java
@@ -15,8 +15,6 @@ import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import eu.kanade.tachiyomi.data.database.models.Chapter;
import eu.kanade.tachiyomi.data.database.models.Manga;
@@ -28,6 +26,8 @@ import eu.kanade.tachiyomi.data.source.base.Source;
import eu.kanade.tachiyomi.data.source.model.Page;
import eu.kanade.tachiyomi.event.DownloadChaptersEvent;
import eu.kanade.tachiyomi.util.DiskUtils;
+import eu.kanade.tachiyomi.util.DynamicConcurrentMergeOperator;
+import eu.kanade.tachiyomi.util.UrlUtil;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
@@ -47,11 +47,12 @@ public class DownloadManager {
private BehaviorSubject runningSubject;
private Subscription downloadsSubscription;
+ private BehaviorSubject threadsSubject;
+ private Subscription threadsSubscription;
+
private DownloadQueue queue;
private volatile boolean isRunning;
- private ExecutorService threadPool;
-
public static final String PAGE_LIST_FILE = "index.json";
public DownloadManager(Context context, SourceManager sourceManager, PreferencesHelper preferences) {
@@ -64,17 +65,20 @@ public class DownloadManager {
downloadsQueueSubject = PublishSubject.create();
runningSubject = BehaviorSubject.create();
+ threadsSubject = BehaviorSubject.create();
}
private void initializeSubscriptions() {
if (downloadsSubscription != null && !downloadsSubscription.isUnsubscribed())
downloadsSubscription.unsubscribe();
- threadPool = Executors.newFixedThreadPool(preferences.downloadThreads());
+ threadsSubscription = preferences.downloadThreads().asObservable()
+ .subscribe(threadsSubject::onNext);
downloadsSubscription = downloadsQueueSubject
.flatMap(Observable::from)
- .flatMap(c -> downloadChapter(c).subscribeOn(Schedulers.from(threadPool)))
+ .lift(new DynamicConcurrentMergeOperator<>(this::downloadChapter, threadsSubject))
+ .onBackpressureBuffer()
.observeOn(AndroidSchedulers.mainThread())
.map(download -> areAllDownloadsFinished())
.subscribe(finished -> {
@@ -100,9 +104,10 @@ public class DownloadManager {
downloadsSubscription = null;
}
- if (threadPool != null && !threadPool.isShutdown()) {
- threadPool.shutdown();
+ if (threadsSubscription != null && !threadsSubscription.isUnsubscribed()) {
+ threadsSubscription.unsubscribe();
}
+
}
// Create a download object for every chapter in the event and add them to the downloads queue
@@ -207,7 +212,8 @@ public class DownloadManager {
.onErrorResumeNext(error -> {
download.setStatus(Download.ERROR);
return Observable.just(download);
- }));
+ }))
+ .subscribeOn(Schedulers.io());
}
// Get the image from the filesystem if it exists or download from network
@@ -279,6 +285,15 @@ public class DownloadManager {
// Get the filename for an image given the page
private String getImageFilename(Page page) {
String url = page.getImageUrl();
+ int number = page.getPageNumber() + 1;
+ // Try to preserve file extension
+ if (UrlUtil.isJpg(url)) {
+ return number + ".jpg";
+ } else if (UrlUtil.isPng(url)) {
+ return number + ".png";
+ } else if (UrlUtil.isGif(url)) {
+ return number + ".gif";
+ }
return Uri.parse(url).getLastPathSegment().replaceAll("[^\\sa-zA-Z0-9.-]", "_");
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.java b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.java
index 896883c4dd..af8001c573 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.java
@@ -116,6 +116,10 @@ public class PreferencesHelper {
return rxPrefs.getInteger(getKey(R.string.pref_reader_theme_key), 0);
}
+ public Preference catalogueAsList() {
+ return rxPrefs.getBoolean(getKey(R.string.pref_display_catalogue_as_list), false);
+ }
+
public String getSourceUsername(Source source) {
return prefs.getString(SOURCE_ACCOUNT_USERNAME + source.getId(), "");
}
@@ -155,8 +159,8 @@ public class PreferencesHelper {
prefs.edit().putString(getKey(R.string.pref_download_directory_key), path).apply();
}
- public int downloadThreads() {
- return prefs.getInt(getKey(R.string.pref_download_slots_key), 1);
+ public Preference downloadThreads() {
+ return rxPrefs.getInteger(getKey(R.string.pref_download_slots_key), 1);
}
public boolean downloadOnlyOverWifi() {
diff --git a/app/src/main/java/eu/kanade/tachiyomi/event/MangaEvent.java b/app/src/main/java/eu/kanade/tachiyomi/event/MangaEvent.java
new file mode 100644
index 0000000000..9cfa8d1734
--- /dev/null
+++ b/app/src/main/java/eu/kanade/tachiyomi/event/MangaEvent.java
@@ -0,0 +1,12 @@
+package eu.kanade.tachiyomi.event;
+
+import eu.kanade.tachiyomi.data.database.models.Manga;
+
+public class MangaEvent {
+
+ public final Manga manga;
+
+ public MangaEvent(Manga manga) {
+ this.manga = manga;
+ }
+}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java
index 57ba302deb..914750a198 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java
@@ -107,14 +107,14 @@ public class RxPresenter extends Presenter {
}
/**
- * Checks if a restartable is subscribed.
+ * Checks if a restartable is unsubscribed.
*
- * @param restartableId id of a restartable.
- * @return True if the restartable is subscribed, false otherwise.
+ * @param restartableId id of the restartable.
+ * @return true if the subscription is null or unsubscribed, false otherwise.
*/
- public boolean isSubscribed(int restartableId) {
- Subscription s = restartableSubscriptions.get(restartableId);
- return s != null && !s.isUnsubscribed();
+ public boolean isUnsubscribed(int restartableId) {
+ Subscription subscription = restartableSubscriptions.get(restartableId);
+ return subscription == null || subscription.isUnsubscribed();
}
/**
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueAdapter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueAdapter.java
index 69871e28fa..9d7cd6f704 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueAdapter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueAdapter.java
@@ -31,6 +31,10 @@ public class CatalogueAdapter extends FlexibleAdapter {
notifyDataSetChanged();
}
+ public List getItems() {
+ return mItems;
+ }
+
@Override
public long getItemId(int position) {
return mItems.get(position).id;
@@ -44,8 +48,13 @@ public class CatalogueAdapter extends FlexibleAdapter {
@Override
public CatalogueHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = fragment.getActivity().getLayoutInflater();
- View v = inflater.inflate(R.layout.item_catalogue, parent, false);
- return new CatalogueHolder(v, this, fragment);
+ if (parent.getId() == R.id.catalogue_grid) {
+ View v = inflater.inflate(R.layout.item_catalogue_grid, parent, false);
+ return new CatalogueGridHolder(v, this, fragment);
+ } else {
+ View v = inflater.inflate(R.layout.item_catalogue_list, parent, false);
+ return new CatalogueListHolder(v, this, fragment);
+ }
}
@Override
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueFragment.java
index 8b2460023f..fff75b078c 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueFragment.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueFragment.java
@@ -4,7 +4,10 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
+import android.support.v4.content.ContextCompat;
import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
@@ -14,9 +17,12 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.ProgressBar;
import android.widget.Spinner;
+import android.widget.ViewSwitcher;
import com.afollestad.materialdialogs.MaterialDialog;
@@ -30,11 +36,13 @@ import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.source.base.Source;
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder;
import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment;
+import eu.kanade.tachiyomi.ui.decoration.DividerItemDecoration;
import eu.kanade.tachiyomi.ui.main.MainActivity;
import eu.kanade.tachiyomi.ui.manga.MangaActivity;
import eu.kanade.tachiyomi.util.ToastUtil;
import eu.kanade.tachiyomi.widget.AutofitRecyclerView;
-import eu.kanade.tachiyomi.widget.EndlessRecyclerScrollListener;
+import eu.kanade.tachiyomi.widget.EndlessGridScrollListener;
+import eu.kanade.tachiyomi.widget.EndlessListScrollListener;
import icepick.State;
import nucleus.factory.RequiresPresenter;
import rx.Subscription;
@@ -45,14 +53,17 @@ import rx.subjects.PublishSubject;
public class CatalogueFragment extends BaseRxFragment
implements FlexibleViewHolder.OnListItemClickListener {
- @Bind(R.id.recycler) AutofitRecyclerView recycler;
+ @Bind(R.id.switcher) ViewSwitcher switcher;
+ @Bind(R.id.catalogue_grid) AutofitRecyclerView catalogueGrid;
+ @Bind(R.id.catalogue_list) RecyclerView catalogueList;
@Bind(R.id.progress) ProgressBar progress;
@Bind(R.id.progress_grid) ProgressBar progressGrid;
private Toolbar toolbar;
private Spinner spinner;
private CatalogueAdapter adapter;
- private EndlessRecyclerScrollListener scrollListener;
+ private EndlessGridScrollListener gridScrollListener;
+ private EndlessListScrollListener listScrollListener;
@State String query = "";
@State int selectedIndex = -1;
@@ -61,6 +72,9 @@ public class CatalogueFragment extends BaseRxFragment
private PublishSubject queryDebouncerSubject;
private Subscription queryDebouncerSubscription;
+ private MenuItem displayMode;
+ private MenuItem searchItem;
+
public static CatalogueFragment newInstance() {
return new CatalogueFragment();
}
@@ -77,13 +91,32 @@ public class CatalogueFragment extends BaseRxFragment
View view = inflater.inflate(R.layout.fragment_catalogue, container, false);
ButterKnife.bind(this, view);
- // Initialize adapter and scroll listener
- GridLayoutManager layoutManager = (GridLayoutManager) recycler.getLayoutManager();
+ // Initialize adapter, scroll listener and recycler views
adapter = new CatalogueAdapter(this);
- scrollListener = new EndlessRecyclerScrollListener(layoutManager, this::requestNextPage);
- recycler.setHasFixedSize(true);
- recycler.setAdapter(adapter);
- recycler.addOnScrollListener(scrollListener);
+
+ GridLayoutManager glm = (GridLayoutManager) catalogueGrid.getLayoutManager();
+ gridScrollListener = new EndlessGridScrollListener(glm, this::requestNextPage);
+ catalogueGrid.setHasFixedSize(true);
+ catalogueGrid.setAdapter(adapter);
+ catalogueGrid.addOnScrollListener(gridScrollListener);
+
+ LinearLayoutManager llm = new LinearLayoutManager(getActivity());
+ listScrollListener = new EndlessListScrollListener(llm, this::requestNextPage);
+ catalogueList.setHasFixedSize(true);
+ catalogueList.setAdapter(adapter);
+ catalogueList.setLayoutManager(llm);
+ catalogueList.addOnScrollListener(listScrollListener);
+ catalogueList.addItemDecoration(new DividerItemDecoration(
+ ContextCompat.getDrawable(getContext(), R.drawable.line_divider)));
+
+ if (getPresenter().isListMode()) {
+ switcher.showNext();
+ }
+
+ Animation inAnim = AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in);
+ Animation outAnim = AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out);
+ switcher.setInAnimation(inAnim);
+ switcher.setOutAnimation(outAnim);
// Create toolbar spinner
Context themedContext = getBaseActivity().getSupportActionBar() != null ?
@@ -109,7 +142,8 @@ public class CatalogueFragment extends BaseRxFragment
} else {
selectedIndex = position;
showProgressBar();
- recycler.setAdapter(adapter);
+ glm.scrollToPositionWithOffset(0, 0);
+ llm.scrollToPositionWithOffset(0, 0);
getPresenter().startRequesting(source);
}
}
@@ -131,7 +165,7 @@ public class CatalogueFragment extends BaseRxFragment
inflater.inflate(R.menu.catalogue_list, menu);
// Initialize search menu
- MenuItem searchItem = menu.findItem(R.id.action_search);
+ searchItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) searchItem.getActionView();
if (!TextUtils.isEmpty(query)) {
@@ -152,6 +186,22 @@ public class CatalogueFragment extends BaseRxFragment
return true;
}
});
+
+ // Show next display mode
+ displayMode = menu.findItem(R.id.action_display_mode);
+ int icon = getPresenter().isListMode() ?
+ R.drawable.ic_view_module_white_24dp : R.drawable.ic_view_list_white_24dp;
+ displayMode.setIcon(icon);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.action_display_mode:
+ swapDisplayMode();
+ break;
+ }
+ return super.onOptionsItemSelected(item);
}
@Override
@@ -168,6 +218,9 @@ public class CatalogueFragment extends BaseRxFragment
@Override
public void onDestroyView() {
+ if (searchItem != null && searchItem.isActionViewExpanded()) {
+ searchItem.collapseActionView();
+ }
toolbar.removeView(spinner);
super.onDestroyView();
}
@@ -194,11 +247,13 @@ public class CatalogueFragment extends BaseRxFragment
private void restartRequest(String newQuery) {
// If text didn't change, do nothing
- if (query.equals(newQuery)) return;
+ if (query.equals(newQuery) || getPresenter().getSource() == null)
+ return;
query = newQuery;
showProgressBar();
- recycler.getLayoutManager().scrollToPosition(0);
+ catalogueGrid.getLayoutManager().scrollToPosition(0);
+ catalogueList.getLayoutManager().scrollToPosition(0);
getPresenter().restartRequest(query);
}
@@ -214,7 +269,8 @@ public class CatalogueFragment extends BaseRxFragment
hideProgressBar();
if (page == 0) {
adapter.clear();
- scrollListener.resetScroll();
+ gridScrollListener.resetScroll();
+ listScrollListener.resetScroll();
}
adapter.addItems(mangas);
}
@@ -224,15 +280,28 @@ public class CatalogueFragment extends BaseRxFragment
}
public void updateImage(Manga manga) {
- CatalogueHolder holder = getHolder(manga);
+ CatalogueGridHolder holder = getHolder(manga);
if (holder != null) {
holder.setImage(manga, getPresenter());
}
}
+ public void swapDisplayMode() {
+ getPresenter().swapDisplayMode();
+ boolean isListMode = getPresenter().isListMode();
+ int icon = isListMode ?
+ R.drawable.ic_view_module_white_24dp : R.drawable.ic_view_list_white_24dp;
+ displayMode.setIcon(icon);
+ switcher.showNext();
+ if (!isListMode) {
+ // Initialize mangas if going to grid view
+ getPresenter().initializeMangas(adapter.getItems());
+ }
+ }
+
@Nullable
- private CatalogueHolder getHolder(Manga manga) {
- return (CatalogueHolder) recycler.findViewHolderForItemId(manga.id);
+ private CatalogueGridHolder getHolder(Manga manga) {
+ return (CatalogueGridHolder) catalogueGrid.findViewHolderForItemId(manga.id);
}
private void showProgressBar() {
@@ -261,9 +330,8 @@ public class CatalogueFragment extends BaseRxFragment
@Override
public void onListItemLongClick(int position) {
final Manga selectedManga = adapter.getItem(position);
- final Manga dbManga = getPresenter().getDbManga(selectedManga.id);
- int textRes = dbManga.favorite ? R.string.remove_from_library : R.string.add_to_library;
+ int textRes = selectedManga.favorite ? R.string.remove_from_library : R.string.add_to_library;
new MaterialDialog.Builder(getActivity())
.items(getString(textRes))
@@ -271,6 +339,7 @@ public class CatalogueFragment extends BaseRxFragment
switch (which) {
case 0:
getPresenter().changeMangaFavorite(selectedManga);
+ adapter.notifyItemChanged(position);
break;
}
})
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueGridHolder.java b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueGridHolder.java
new file mode 100644
index 0000000000..b45fe51e6d
--- /dev/null
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueGridHolder.java
@@ -0,0 +1,38 @@
+package eu.kanade.tachiyomi.ui.catalogue;
+
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import butterknife.Bind;
+import butterknife.ButterKnife;
+import eu.kanade.tachiyomi.R;
+import eu.kanade.tachiyomi.data.database.models.Manga;
+
+public class CatalogueGridHolder extends CatalogueHolder {
+
+ @Bind(R.id.title) TextView title;
+ @Bind(R.id.thumbnail) ImageView thumbnail;
+ @Bind(R.id.favorite_sticker) ImageView favoriteSticker;
+
+ public CatalogueGridHolder(View view, CatalogueAdapter adapter, OnListItemClickListener listener) {
+ super(view, adapter, listener);
+ ButterKnife.bind(this, view);
+ }
+
+ @Override
+ public void onSetValues(Manga manga, CataloguePresenter presenter) {
+ title.setText(manga.title);
+ favoriteSticker.setVisibility(manga.favorite ? View.VISIBLE : View.GONE);
+ setImage(manga, presenter);
+ }
+
+ public void setImage(Manga manga, CataloguePresenter presenter) {
+ if (manga.thumbnail_url != null) {
+ presenter.coverCache.loadFromNetwork(thumbnail, manga.thumbnail_url,
+ presenter.getSource().getGlideHeaders());
+ } else {
+ thumbnail.setImageResource(android.R.color.transparent);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueHolder.java b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueHolder.java
index 243b6d8041..8de83acee1 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueHolder.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueHolder.java
@@ -1,38 +1,15 @@
package eu.kanade.tachiyomi.ui.catalogue;
import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-import butterknife.Bind;
-import butterknife.ButterKnife;
-import eu.kanade.tachiyomi.R;
import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder;
-public class CatalogueHolder extends FlexibleViewHolder {
-
- @Bind(R.id.title) TextView title;
- @Bind(R.id.thumbnail) ImageView thumbnail;
- @Bind(R.id.favorite_sticker) ImageView favoriteSticker;
+public abstract class CatalogueHolder extends FlexibleViewHolder {
public CatalogueHolder(View view, CatalogueAdapter adapter, OnListItemClickListener listener) {
super(view, adapter, listener);
- ButterKnife.bind(this, view);
}
- public void onSetValues(Manga manga, CataloguePresenter presenter) {
- title.setText(manga.title);
- favoriteSticker.setVisibility(manga.favorite ? View.VISIBLE : View.GONE);
- setImage(manga, presenter);
- }
-
- public void setImage(Manga manga, CataloguePresenter presenter) {
- if (manga.thumbnail_url != null) {
- presenter.coverCache.loadFromNetwork(thumbnail, manga.thumbnail_url,
- presenter.getSource().getGlideHeaders());
- } else {
- thumbnail.setImageResource(android.R.color.transparent);
- }
- }
-}
\ No newline at end of file
+ abstract void onSetValues(Manga manga, CataloguePresenter presenter);
+}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueListHolder.java b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueListHolder.java
new file mode 100644
index 0000000000..94042c4494
--- /dev/null
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueListHolder.java
@@ -0,0 +1,32 @@
+package eu.kanade.tachiyomi.ui.catalogue;
+
+import android.support.v4.content.ContextCompat;
+import android.view.View;
+import android.widget.TextView;
+
+import butterknife.Bind;
+import butterknife.ButterKnife;
+import eu.kanade.tachiyomi.R;
+import eu.kanade.tachiyomi.data.database.models.Manga;
+
+public class CatalogueListHolder extends CatalogueHolder {
+
+ @Bind(R.id.title) TextView title;
+
+ private final int favoriteColor;
+ private final int unfavoriteColor;
+
+ public CatalogueListHolder(View view, CatalogueAdapter adapter, OnListItemClickListener listener) {
+ super(view, adapter, listener);
+ ButterKnife.bind(this, view);
+
+ favoriteColor = ContextCompat.getColor(view.getContext(), R.color.hint_text);
+ unfavoriteColor = ContextCompat.getColor(view.getContext(), R.color.primary_text);
+ }
+
+ @Override
+ public void onSetValues(Manga manga, CataloguePresenter presenter) {
+ title.setText(manga.title);
+ title.setTextColor(manga.favorite ? favoriteColor : unfavoriteColor);
+ }
+}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CataloguePresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CataloguePresenter.java
index bc30ba7602..97e835c204 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CataloguePresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CataloguePresenter.java
@@ -42,6 +42,8 @@ public class CataloguePresenter extends BasePresenter {
private PublishSubject> mangaDetailSubject;
+ private boolean isListMode;
+
private static final int GET_MANGA_LIST = 1;
private static final int GET_MANGA_DETAIL = 2;
private static final int GET_MANGA_PAGE = 3;
@@ -72,12 +74,14 @@ public class CataloguePresenter extends BasePresenter {
.observeOn(Schedulers.io())
.flatMap(Observable::from)
.filter(manga -> !manga.initialized)
- .window(3)
- .concatMap(pack -> pack.concatMap(this::getMangaDetails))
+ .concatMap(this::getMangaDetails)
.onBackpressureBuffer()
.observeOn(AndroidSchedulers.mainThread()),
CatalogueFragment::updateImage,
(view, error) -> Timber.e(error.getMessage()));
+
+ add(prefs.catalogueAsList().asObservable()
+ .subscribe(this::setDisplayMode));
}
private void onProcessRestart() {
@@ -87,6 +91,15 @@ public class CataloguePresenter extends BasePresenter {
stop(GET_MANGA_PAGE);
}
+ private void setDisplayMode(boolean asList) {
+ this.isListMode = asList;
+ if (asList) {
+ stop(GET_MANGA_DETAIL);
+ } else {
+ start(GET_MANGA_DETAIL);
+ }
+ }
+
public void startRequesting(Source source) {
this.source = source;
sourceId = source.getId();
@@ -98,7 +111,9 @@ public class CataloguePresenter extends BasePresenter {
stop(GET_MANGA_PAGE);
lastMangasPage = null;
- start(GET_MANGA_DETAIL);
+ if (!isListMode) {
+ start(GET_MANGA_DETAIL);
+ }
start(GET_MANGA_LIST);
start(GET_MANGA_PAGE);
}
@@ -124,10 +139,7 @@ public class CataloguePresenter extends BasePresenter {
.flatMap(mangasPage -> Observable.from(mangasPage.mangas))
.map(this::networkToLocalManga)
.toList()
- .doOnNext(mangas -> {
- if (mangaDetailSubject != null)
- mangaDetailSubject.onNext(mangas);
- })
+ .doOnNext(this::initializeMangas)
.observeOn(AndroidSchedulers.mainThread());
}
@@ -141,9 +153,12 @@ public class CataloguePresenter extends BasePresenter {
return localManga;
}
+ public void initializeMangas(List mangas) {
+ mangaDetailSubject.onNext(mangas);
+ }
+
private Observable getMangaDetails(final Manga manga) {
return source.pullMangaFromNetwork(manga.url)
- .subscribeOn(Schedulers.io())
.flatMap(networkManga -> {
manga.copyFrom(networkManga);
db.insertManga(manga).executeAsBlocking();
@@ -152,10 +167,6 @@ public class CataloguePresenter extends BasePresenter {
.onErrorResumeNext(error -> Observable.just(manga));
}
- public Manga getDbManga(long id) {
- return db.getManga(id).executeAsBlocking();
- }
-
public Source getSource() {
return source;
}
@@ -181,4 +192,13 @@ public class CataloguePresenter extends BasePresenter {
manga.favorite = !manga.favorite;
db.insertManga(manga).executeAsBlocking();
}
+
+ public boolean isListMode() {
+ return isListMode;
+ }
+
+ public void swapDisplayMode() {
+ prefs.catalogueAsList().set(!isListMode);
+ }
+
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.java
index 429180f758..fe69bc884d 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadPresenter.java
@@ -90,6 +90,7 @@ public class DownloadPresenter extends BasePresenter {
.flatMap(tick -> Observable.from(download.pages)
.map(Page::getProgress)
.reduce((x, y) -> x + y))
+ .onBackpressureLatest()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(progress -> {
if (download.totalProgress != progress) {
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.java
index 9319e9db93..d4cbfd4eee 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.java
@@ -52,7 +52,7 @@ public class LibraryCategoryAdapter extends FlexibleAdapter {
@Override
protected void onTakeView(LibraryFragment libraryFragment) {
super.onTakeView(libraryFragment);
- if (!isSubscribed(GET_LIBRARY)) {
+ if (isUnsubscribed(GET_LIBRARY)) {
start(GET_LIBRARY);
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaActivity.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaActivity.java
index 8899cf04f6..7a550b536d 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaActivity.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaActivity.java
@@ -14,6 +14,7 @@ import javax.inject.Inject;
import butterknife.Bind;
import butterknife.ButterKnife;
+import de.greenrobot.event.EventBus;
import eu.kanade.tachiyomi.App;
import eu.kanade.tachiyomi.R;
import eu.kanade.tachiyomi.data.database.models.Manga;
@@ -30,21 +31,21 @@ public class MangaActivity extends BaseRxActivity {
@Bind(R.id.toolbar) Toolbar toolbar;
@Bind(R.id.tabs) TabLayout tabs;
- @Bind(R.id.view_pager) ViewPager view_pager;
+ @Bind(R.id.view_pager) ViewPager viewPager;
@Inject PreferencesHelper preferences;
@Inject MangaSyncManager mangaSyncManager;
private MangaDetailAdapter adapter;
- private long manga_id;
- private boolean is_online;
+ private boolean isOnline;
- public final static String MANGA_ID = "manga_id";
public final static String MANGA_ONLINE = "manga_online";
public static Intent newIntent(Context context, Manga manga) {
Intent intent = new Intent(context, MangaActivity.class);
- intent.putExtra(MANGA_ID, manga.id);
+ if (manga != null) {
+ EventBus.getDefault().postSticky(manga);
+ }
return intent;
}
@@ -59,23 +60,19 @@ public class MangaActivity extends BaseRxActivity {
Intent intent = getIntent();
- manga_id = intent.getLongExtra(MANGA_ID, -1);
- is_online = intent.getBooleanExtra(MANGA_ONLINE, false);
+ isOnline = intent.getBooleanExtra(MANGA_ONLINE, false);
setupViewPager();
-
- if (savedState == null)
- getPresenter().queryManga(manga_id);
}
private void setupViewPager() {
adapter = new MangaDetailAdapter(getSupportFragmentManager(), this);
- view_pager.setAdapter(adapter);
- tabs.setupWithViewPager(view_pager);
+ viewPager.setAdapter(adapter);
+ tabs.setupWithViewPager(viewPager);
- if (!is_online)
- view_pager.setCurrentItem(MangaDetailAdapter.CHAPTERS_FRAGMENT);
+ if (!isOnline)
+ viewPager.setCurrentItem(MangaDetailAdapter.CHAPTERS_FRAGMENT);
}
public void setManga(Manga manga) {
@@ -83,7 +80,7 @@ public class MangaActivity extends BaseRxActivity {
}
public boolean isCatalogueManga() {
- return is_online;
+ return isOnline;
}
class MangaDetailAdapter extends FragmentPagerAdapter {
@@ -104,7 +101,7 @@ public class MangaActivity extends BaseRxActivity {
};
pageCount = 2;
- if (!is_online && mangaSyncManager.getMyAnimeList().isLogged())
+ if (!isOnline && mangaSyncManager.getMyAnimeList().isLogged())
pageCount++;
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.java
index 15faffb3ea..a24f093e71 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.java
@@ -7,44 +7,48 @@ import javax.inject.Inject;
import de.greenrobot.event.EventBus;
import eu.kanade.tachiyomi.data.database.DatabaseHelper;
import eu.kanade.tachiyomi.data.database.models.Manga;
+import eu.kanade.tachiyomi.event.MangaEvent;
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter;
+import eu.kanade.tachiyomi.util.EventBusHook;
import icepick.State;
import rx.Observable;
-import rx.android.schedulers.AndroidSchedulers;
-import rx.schedulers.Schedulers;
public class MangaPresenter extends BasePresenter {
@Inject DatabaseHelper db;
- @State long mangaId;
+ @State Manga manga;
- private static final int DB_MANGA = 1;
+ private static final int GET_MANGA = 1;
@Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
- restartableLatestCache(DB_MANGA, this::getDbMangaObservable, MangaActivity::setManga);
+ restartableLatestCache(GET_MANGA, this::getMangaObservable, MangaActivity::setManga);
+
+ if (savedState == null)
+ registerForStickyEvents();
}
@Override
protected void onDestroy() {
super.onDestroy();
// Avoid new instances receiving wrong manga
- EventBus.getDefault().removeStickyEvent(Manga.class);
+ EventBus.getDefault().removeStickyEvent(MangaEvent.class);
}
- private Observable getDbMangaObservable() {
- return db.getManga(mangaId).asRxObservable()
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .doOnNext(manga -> EventBus.getDefault().postSticky(manga));
+ private Observable getMangaObservable() {
+ return Observable.just(manga)
+ .doOnNext(manga -> EventBus.getDefault().postSticky(new MangaEvent(manga)));
}
- public void queryManga(long mangaId) {
- this.mangaId = mangaId;
- start(DB_MANGA);
+ @EventBusHook
+ public void onEventMainThread(Manga manga) {
+ EventBus.getDefault().removeStickyEvent(manga);
+ unregisterForEvents();
+ this.manga = manga;
+ start(GET_MANGA);
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.java
index 0e0e64392a..ba7db26bcb 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersAdapter.java
@@ -10,6 +10,7 @@ import java.util.List;
import eu.davidea.flexibleadapter.FlexibleAdapter;
import eu.kanade.tachiyomi.R;
import eu.kanade.tachiyomi.data.database.models.Chapter;
+import eu.kanade.tachiyomi.data.database.models.Manga;
public class ChaptersAdapter extends FlexibleAdapter {
@@ -33,7 +34,8 @@ public class ChaptersAdapter extends FlexibleAdapter {
@Override
public void onBindViewHolder(ChaptersHolder holder, int position) {
final Chapter chapter = getItem(position);
- holder.onSetValues(fragment.getActivity(), chapter);
+ final Manga manga = fragment.getPresenter().getManga();
+ holder.onSetValues(chapter, manga);
//When user scrolls this bind the correct selection status
holder.itemView.setActivated(isSelected(position));
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.java
index 0ecd4e9395..682aa34a50 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersFragment.java
@@ -10,6 +10,7 @@ import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@@ -24,6 +25,7 @@ import butterknife.Bind;
import butterknife.ButterKnife;
import eu.kanade.tachiyomi.R;
import eu.kanade.tachiyomi.data.database.models.Chapter;
+import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.download.DownloadService;
import eu.kanade.tachiyomi.data.download.model.Download;
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder;
@@ -61,6 +63,12 @@ public class ChaptersFragment extends BaseRxFragment implemen
return new ChaptersFragment();
}
+ @Override
+ public void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+ setHasOptionsMenu(true);
+ }
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -71,26 +79,14 @@ public class ChaptersFragment extends BaseRxFragment implemen
// Init RecyclerView and adapter
linearLayout = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(linearLayout);
- recyclerView.addItemDecoration(new DividerItemDecoration(ContextCompat.getDrawable(getContext(), R.drawable.line_divider)));
+ recyclerView.addItemDecoration(new DividerItemDecoration(
+ ContextCompat.getDrawable(getContext(), R.drawable.line_divider)));
recyclerView.setHasFixedSize(true);
adapter = new ChaptersAdapter(this);
recyclerView.setAdapter(adapter);
- // Set initial values
- setReadFilter();
- setDownloadedFilter();
- setSortIcon();
-
- // Init listeners
swipeRefresh.setOnRefreshListener(this::fetchChapters);
- readCb.setOnCheckedChangeListener((arg, isChecked) ->
- getPresenter().setReadFilter(isChecked));
- downloadedCb.setOnCheckedChangeListener((v, isChecked) ->
- getPresenter().setDownloadedFilter(isChecked));
- sortBtn.setOnClickListener(v -> {
- getPresenter().revertSortOrder();
- setSortIcon();
- });
+
nextUnreadBtn.setOnClickListener(v -> {
Chapter chapter = getPresenter().getNextUnreadChapter();
if (chapter != null) {
@@ -104,15 +100,40 @@ public class ChaptersFragment extends BaseRxFragment implemen
}
@Override
- public void onResume() {
- super.onResume();
- observeChapterDownloadProgress();
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ inflater.inflate(R.menu.chapters, menu);
}
@Override
- public void onPause() {
- unsubscribeChapterDownloadProgress();
- super.onPause();
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.action_display_mode:
+ showDisplayModeDialog();
+ return true;
+ }
+ return false;
+ }
+
+ public void onNextManga(Manga manga) {
+ // Remove listeners before setting the values
+ readCb.setOnCheckedChangeListener(null);
+ downloadedCb.setOnCheckedChangeListener(null);
+ sortBtn.setOnClickListener(null);
+
+ // Set initial values
+ setReadFilter();
+ setDownloadedFilter();
+ setSortIcon();
+
+ // Init listeners
+ readCb.setOnCheckedChangeListener((arg, isChecked) ->
+ getPresenter().setReadFilter(isChecked));
+ downloadedCb.setOnCheckedChangeListener((v, isChecked) ->
+ getPresenter().setDownloadedFilter(isChecked));
+ sortBtn.setOnClickListener(v -> {
+ getPresenter().revertSortOrder();
+ setSortIcon();
+ });
}
public void onNextChapters(List chapters) {
@@ -158,6 +179,29 @@ public class ChaptersFragment extends BaseRxFragment implemen
startActivity(intent);
}
+ private void showDisplayModeDialog() {
+ final Manga manga = getPresenter().getManga();
+ if (manga == null)
+ return;
+
+ // Get available modes, ids and the selected mode
+ String[] modes = {getString(R.string.show_title), getString(R.string.show_chapter_number)};
+ int[] ids = {Manga.DISPLAY_NAME, Manga.DISPLAY_NUMBER};
+ int selectedIndex = manga.getDisplayMode() == Manga.DISPLAY_NAME ? 0 : 1;
+
+ new MaterialDialog.Builder(getActivity())
+ .items(modes)
+ .itemsIds(ids)
+ .itemsCallbackSingleChoice(selectedIndex, (dialog, itemView, which, text) -> {
+ // Save the new display mode
+ getPresenter().setDisplayMode(itemView.getId());
+ // Refresh ui
+ adapter.notifyDataSetChanged();
+ return true;
+ })
+ .show();
+ }
+
private void observeChapterDownloadProgress() {
downloadProgressSubscription = getPresenter().getDownloadProgressObs()
.subscribe(this::onDownloadProgressChange,
@@ -175,10 +219,10 @@ public class ChaptersFragment extends BaseRxFragment implemen
holder.onProgressChange(getContext(), download.downloadedImages, download.pages.size());
}
- public void onChapterStatusChange(Chapter chapter) {
- ChaptersHolder holder = getHolder(chapter);
+ public void onChapterStatusChange(Download download) {
+ ChaptersHolder holder = getHolder(download.chapter);
if (holder != null)
- holder.onStatusChange(chapter.status);
+ holder.onStatusChange(download.getStatus());
}
@Nullable
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersHolder.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersHolder.java
index b57813e821..a8c76fa82f 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersHolder.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersHolder.java
@@ -7,6 +7,8 @@ import android.widget.PopupMenu;
import android.widget.RelativeLayout;
import android.widget.TextView;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -14,40 +16,61 @@ import butterknife.Bind;
import butterknife.ButterKnife;
import eu.kanade.tachiyomi.R;
import eu.kanade.tachiyomi.data.database.models.Chapter;
+import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.download.model.Download;
import eu.kanade.tachiyomi.ui.base.adapter.FlexibleViewHolder;
import rx.Observable;
public class ChaptersHolder extends FlexibleViewHolder {
- private final ChaptersAdapter adapter;
- private Chapter item;
-
@Bind(R.id.chapter_title) TextView title;
@Bind(R.id.download_text) TextView downloadText;
@Bind(R.id.chapter_menu) RelativeLayout chapterMenu;
@Bind(R.id.chapter_pages) TextView pages;
@Bind(R.id.chapter_date) TextView date;
- SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
+ private Context context;
+
+ private final ChaptersAdapter adapter;
+ private Chapter item;
+
+ private final int readColor;
+ private final int unreadColor;
+
+ private final DecimalFormat decimalFormat;
+ private SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
public ChaptersHolder(View view, ChaptersAdapter adapter, OnListItemClickListener listener) {
super(view, adapter, listener);
this.adapter = adapter;
+ context = view.getContext();
ButterKnife.bind(this, view);
+ readColor = ContextCompat.getColor(view.getContext(), R.color.hint_text);
+ unreadColor = ContextCompat.getColor(view.getContext(), R.color.primary_text);
+
+ DecimalFormatSymbols symbols = new DecimalFormatSymbols();
+ symbols.setDecimalSeparator('.');
+ decimalFormat = new DecimalFormat("#.###", symbols);
+
chapterMenu.setOnClickListener(v -> v.post(() -> showPopupMenu(v)));
}
- public void onSetValues(Context context, Chapter chapter) {
+ public void onSetValues(Chapter chapter, Manga manga) {
this.item = chapter;
- title.setText(chapter.name);
-
- if (chapter.read) {
- title.setTextColor(ContextCompat.getColor(context, R.color.hint_text));
- } else {
- title.setTextColor(ContextCompat.getColor(context, R.color.primary_text));
+ String name;
+ switch (manga.getDisplayMode()) {
+ case Manga.DISPLAY_NAME:
+ default:
+ name = chapter.name;
+ break;
+ case Manga.DISPLAY_NUMBER:
+ String formattedNumber = decimalFormat.format(chapter.chapter_number);
+ name = context.getString(R.string.display_mode_chapter, formattedNumber);
+ break;
}
+ title.setText(name);
+ title.setTextColor(chapter.read ? readColor : unreadColor);
if (!chapter.read && chapter.last_page_read > 0) {
pages.setText(context.getString(R.string.chapter_progress, chapter.last_page_read + 1));
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.java
index de89c1c796..e981ec0e7b 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.java
@@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.data.source.SourceManager;
import eu.kanade.tachiyomi.data.source.base.Source;
import eu.kanade.tachiyomi.event.ChapterCountEvent;
import eu.kanade.tachiyomi.event.DownloadChaptersEvent;
+import eu.kanade.tachiyomi.event.MangaEvent;
import eu.kanade.tachiyomi.event.ReaderEvent;
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter;
import eu.kanade.tachiyomi.util.EventBusHook;
@@ -38,16 +39,16 @@ public class ChaptersPresenter extends BasePresenter {
private Manga manga;
private Source source;
private List chapters;
- private boolean sortOrderAToZ = true;
private boolean onlyUnread = true;
private boolean onlyDownloaded;
@State boolean hasRequested;
private PublishSubject> chaptersSubject;
- private static final int DB_CHAPTERS = 1;
- private static final int FETCH_CHAPTERS = 2;
- private static final int CHAPTER_STATUS_CHANGES = 3;
+ private static final int GET_MANGA = 1;
+ private static final int DB_CHAPTERS = 2;
+ private static final int FETCH_CHAPTERS = 3;
+ private static final int CHAPTER_STATUS_CHANGES = 4;
@Override
protected void onCreate(Bundle savedState) {
@@ -59,6 +60,10 @@ public class ChaptersPresenter extends BasePresenter {
chaptersSubject = PublishSubject.create();
+ restartableLatestCache(GET_MANGA,
+ () -> Observable.just(manga),
+ ChaptersFragment::onNextManga);
+
restartableLatestCache(DB_CHAPTERS,
this::getDbChaptersObs,
ChaptersFragment::onNextChapters);
@@ -70,13 +75,14 @@ public class ChaptersPresenter extends BasePresenter {
restartableLatestCache(CHAPTER_STATUS_CHANGES,
this::getChapterStatusObs,
- (view, download) -> view.onChapterStatusChange(download.chapter),
+ (view, download) -> view.onChapterStatusChange(download),
(view, error) -> Timber.e(error.getCause(), error.getMessage()));
registerForStickyEvents();
}
private void onProcessRestart() {
+ stop(GET_MANGA);
stop(DB_CHAPTERS);
stop(FETCH_CHAPTERS);
stop(CHAPTER_STATUS_CHANGES);
@@ -90,10 +96,11 @@ public class ChaptersPresenter extends BasePresenter {
}
@EventBusHook
- public void onEventMainThread(Manga manga) {
- this.manga = manga;
+ public void onEventMainThread(MangaEvent event) {
+ this.manga = event.manga;
+ start(GET_MANGA);
- if (!isSubscribed(DB_CHAPTERS)) {
+ if (isUnsubscribed(DB_CHAPTERS)) {
source = sourceManager.get(manga.source);
start(DB_CHAPTERS);
@@ -141,7 +148,7 @@ public class ChaptersPresenter extends BasePresenter {
if (onlyDownloaded) {
observable = observable.filter(chapter -> chapter.status == Download.DOWNLOADED);
}
- return observable.toSortedList((chapter, chapter2) -> sortOrderAToZ ?
+ return observable.toSortedList((chapter, chapter2) -> getSortOrder() ?
Float.compare(chapter2.chapter_number, chapter.chapter_number) :
Float.compare(chapter.chapter_number, chapter2.chapter_number));
}
@@ -241,8 +248,8 @@ public class ChaptersPresenter extends BasePresenter {
}
public void revertSortOrder() {
- //TODO manga.chapter_order
- sortOrderAToZ = !sortOrderAToZ;
+ manga.setChapterOrder(getSortOrder() ? Manga.SORT_ZA : Manga.SORT_AZ);
+ db.insertManga(manga).executeAsBlocking();
refreshChapters();
}
@@ -257,8 +264,13 @@ public class ChaptersPresenter extends BasePresenter {
refreshChapters();
}
+ public void setDisplayMode(int mode) {
+ manga.setDisplayMode(mode);
+ db.insertManga(manga).executeAsBlocking();
+ }
+
public boolean getSortOrder() {
- return sortOrderAToZ;
+ return manga.sortChaptersAZ();
}
public boolean getReadFilter() {
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.java
index 16aaeee9e0..033e8e7ce8 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoFragment.java
@@ -16,6 +16,7 @@ import butterknife.ButterKnife;
import eu.kanade.tachiyomi.R;
import eu.kanade.tachiyomi.data.cache.CoverCache;
import eu.kanade.tachiyomi.data.database.models.Manga;
+import eu.kanade.tachiyomi.data.source.base.Source;
import eu.kanade.tachiyomi.ui.base.fragment.BaseRxFragment;
import nucleus.factory.RequiresPresenter;
@@ -29,6 +30,7 @@ public class MangaInfoFragment extends BaseRxFragment {
@Bind(R.id.manga_chapters) TextView chapterCount;
@Bind(R.id.manga_genres) TextView genres;
@Bind(R.id.manga_status) TextView status;
+ @Bind(R.id.manga_source) TextView source;
@Bind(R.id.manga_summary) TextView description;
@Bind(R.id.manga_cover) ImageView cover;
@@ -60,18 +62,22 @@ public class MangaInfoFragment extends BaseRxFragment {
return view;
}
- public void onNextManga(Manga manga) {
+ public void onNextManga(Manga manga, Source source) {
if (manga.initialized) {
- setMangaInfo(manga);
+ setMangaInfo(manga, source);
} else {
// Initialize manga
fetchMangaFromSource();
}
}
- private void setMangaInfo(Manga manga) {
+ private void setMangaInfo(Manga manga, Source mangaSource) {
artist.setText(manga.artist);
author.setText(manga.author);
+
+ if (mangaSource != null) {
+ source.setText(mangaSource.getName());
+ }
genres.setText(manga.genre);
status.setText(manga.getStatus(getActivity()));
description.setText(manga.description);
@@ -82,7 +88,7 @@ public class MangaInfoFragment extends BaseRxFragment {
LazyHeaders headers = getPresenter().source.getGlideHeaders();
if (manga.thumbnail_url != null && cover.getDrawable() == null) {
if (manga.favorite) {
- coverCache.saveAndLoadFromCache(cover, manga.thumbnail_url, headers);
+ coverCache.saveOrLoadFromCache(cover, manga.thumbnail_url, headers);
} else {
coverCache.loadFromNetwork(cover, manga.thumbnail_url, headers);
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.java
index 8965419059..bfeb251be1 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.java
@@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.source.SourceManager;
import eu.kanade.tachiyomi.data.source.base.Source;
import eu.kanade.tachiyomi.event.ChapterCountEvent;
+import eu.kanade.tachiyomi.event.MangaEvent;
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter;
import eu.kanade.tachiyomi.util.EventBusHook;
import rx.Observable;
@@ -18,19 +19,18 @@ import rx.schedulers.Schedulers;
public class MangaInfoPresenter extends BasePresenter {
- @Inject DatabaseHelper db;
- @Inject SourceManager sourceManager;
- @Inject CoverCache coverCache;
-
- private Manga manga;
- protected Source source;
- private int count = -1;
-
- private boolean isFetching;
-
private static final int GET_MANGA = 1;
private static final int GET_CHAPTER_COUNT = 2;
private static final int FETCH_MANGA_INFO = 3;
+ protected Source source;
+ @Inject
+ DatabaseHelper db;
+ @Inject
+ SourceManager sourceManager;
+ @Inject
+ CoverCache coverCache;
+ private Manga manga;
+ private int count = -1;
@Override
protected void onCreate(Bundle savedState) {
@@ -42,7 +42,7 @@ public class MangaInfoPresenter extends BasePresenter {
restartableLatestCache(GET_MANGA,
() -> Observable.just(manga),
- MangaInfoFragment::onNextManga);
+ (view, manga) -> view.onNextManga(manga, source));
restartableLatestCache(GET_CHAPTER_COUNT,
() -> Observable.just(count),
@@ -69,10 +69,10 @@ public class MangaInfoPresenter extends BasePresenter {
}
@EventBusHook
- public void onEventMainThread(Manga manga) {
- this.manga = manga;
+ public void onEventMainThread(MangaEvent event) {
+ this.manga = event.manga;
source = sourceManager.get(manga.source);
- start(GET_MANGA);
+ refreshManga();
}
@EventBusHook
@@ -84,8 +84,7 @@ public class MangaInfoPresenter extends BasePresenter {
}
public void fetchMangaFromSource() {
- if (!isFetching) {
- isFetching = true;
+ if (isUnsubscribed(FETCH_MANGA_INFO)) {
start(FETCH_MANGA_INFO);
}
}
@@ -97,23 +96,29 @@ public class MangaInfoPresenter extends BasePresenter {
db.insertManga(manga).executeAsBlocking();
return Observable.just(manga);
})
- .finallyDo(() -> isFetching = false)
.subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread());
+ .observeOn(AndroidSchedulers.mainThread())
+ .doOnNext(manga -> refreshManga());
}
public void toggleFavorite() {
manga.favorite = !manga.favorite;
onMangaFavoriteChange(manga.favorite);
db.insertManga(manga).executeAsBlocking();
+ refreshManga();
}
private void onMangaFavoriteChange(boolean isFavorite) {
if (isFavorite) {
coverCache.save(manga.thumbnail_url, source.getGlideHeaders());
} else {
- coverCache.delete(manga.thumbnail_url);
+ coverCache.deleteCoverFromCache(manga.thumbnail_url);
}
}
+ // Used to refresh the view
+ private void refreshManga() {
+ start(GET_MANGA);
+ }
+
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/myanimelist/MyAnimeListPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/myanimelist/MyAnimeListPresenter.java
index a49b169cde..db23a4e651 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/myanimelist/MyAnimeListPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/myanimelist/MyAnimeListPresenter.java
@@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.database.models.MangaSync;
import eu.kanade.tachiyomi.data.mangasync.MangaSyncManager;
import eu.kanade.tachiyomi.data.mangasync.services.MyAnimeList;
+import eu.kanade.tachiyomi.event.MangaEvent;
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter;
import eu.kanade.tachiyomi.util.EventBusHook;
import eu.kanade.tachiyomi.util.ToastUtil;
@@ -102,8 +103,8 @@ public class MyAnimeListPresenter extends BasePresenter {
}
@EventBusHook
- public void onEventMainThread(Manga manga) {
- this.manga = manga;
+ public void onEventMainThread(MangaEvent event) {
+ this.manga = event.manga;
start(GET_MANGA_SYNC);
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.java b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.java
index cbe7eabde5..aa27e2e523 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.java
@@ -164,6 +164,10 @@ public class ReaderActivity extends BaseRxActivity {
}
public void onChapterReady(List pages, Manga manga, Chapter chapter, int currentPage) {
+ if (currentPage == -1) {
+ currentPage = pages.size() - 1;
+ }
+
if (viewer == null) {
viewer = createViewer(manga);
getSupportFragmentManager().beginTransaction().replace(R.id.reader, viewer).commit();
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderMenu.java b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderMenu.java
index 8f8a840a0f..938cc2b9f8 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderMenu.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderMenu.java
@@ -70,7 +70,7 @@ public class ReaderMenu {
bottomMenu.setOnTouchListener((v, event) -> true);
seekBar.setOnSeekBarChangeListener(new PageSeekBarChangeListener());
- decimalFormat = new DecimalFormat("#.##");
+ decimalFormat = new DecimalFormat("#.###");
inverted = false;
initializeOptions();
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.java
index 7022d12918..4834a5fd27 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.java
@@ -215,8 +215,12 @@ public class ReaderPresenter extends BasePresenter {
.doOnNext(mangaSync -> this.mangaSyncList = mangaSync);
}
- // Loads the given chapter
private void loadChapter(Chapter chapter) {
+ loadChapter(chapter, 0);
+ }
+
+ // Loads the given chapter
+ private void loadChapter(Chapter chapter, int requestedPage) {
// Before loading the chapter, stop preloading (if it's working) and save current progress
stopPreloadingNextChapter();
@@ -227,7 +231,7 @@ public class ReaderPresenter extends BasePresenter {
if (!chapter.read && chapter.last_page_read != 0)
currentPage = chapter.last_page_read;
else
- currentPage = 0;
+ currentPage = requestedPage;
// Reset next and previous chapter. They have to be fetched again
nextChapter = null;
@@ -312,7 +316,7 @@ public class ReaderPresenter extends BasePresenter {
public boolean loadNextChapter() {
if (hasNextChapter()) {
onChapterLeft();
- loadChapter(nextChapter);
+ loadChapter(nextChapter, 0);
return true;
}
return false;
@@ -321,7 +325,7 @@ public class ReaderPresenter extends BasePresenter {
public boolean loadPreviousChapter() {
if (hasPreviousChapter()) {
onChapterLeft();
- loadChapter(previousChapter);
+ loadChapter(previousChapter, -1);
return true;
}
return false;
@@ -342,7 +346,7 @@ public class ReaderPresenter extends BasePresenter {
}
private void stopPreloadingNextChapter() {
- if (isSubscribed(PRELOAD_NEXT_CHAPTER)) {
+ if (!isUnsubscribed(PRELOAD_NEXT_CHAPTER)) {
stop(PRELOAD_NEXT_CHAPTER);
if (nextChapterPageList != null)
source.savePageList(nextChapter.url, nextChapterPageList);
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedFragment.java
index eb9318820a..6feccd55bb 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedFragment.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedFragment.java
@@ -71,7 +71,7 @@ public class SettingsAdvancedFragment extends SettingsNestedFragment {
subscriptions.add(Observable.defer(() -> Observable.from(files))
.concatMap(file -> {
- if (chapterCache.remove(file.getName())) {
+ if (chapterCache.removeFileFromCache(file.getName())) {
deletedFiles.incrementAndGet();
}
return Observable.just(file);
diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/UrlUtil.java b/app/src/main/java/eu/kanade/tachiyomi/util/UrlUtil.java
index 65e0ea618d..baf7ce9dce 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/util/UrlUtil.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/util/UrlUtil.java
@@ -5,6 +5,10 @@ import java.net.URISyntaxException;
public class UrlUtil {
+ private static final String JPG = ".jpg";
+ private static final String PNG = ".png";
+ private static final String GIF = ".gif";
+
public static String getPath(String s) {
try {
URI uri = new URI(s);
@@ -18,4 +22,37 @@ public class UrlUtil {
return s;
}
}
+
+ public static boolean isJpg(String url) {
+ return containsIgnoreCase(url, JPG);
+ }
+
+ public static boolean isPng(String url) {
+ return containsIgnoreCase(url, PNG);
+ }
+
+ public static boolean isGif(String url) {
+ return containsIgnoreCase(url, GIF);
+ }
+
+ public static boolean containsIgnoreCase(String src, String what) {
+ final int length = what.length();
+ if (length == 0)
+ return true; // Empty string is contained
+
+ final char firstLo = Character.toLowerCase(what.charAt(0));
+ final char firstUp = Character.toUpperCase(what.charAt(0));
+
+ for (int i = src.length() - length; i >= 0; i--) {
+ // Quick check before calling the more expensive regionMatches() method:
+ final char ch = src.charAt(i);
+ if (ch != firstLo && ch != firstUp)
+ continue;
+
+ if (src.regionMatches(true, i, what, 0, length))
+ return true;
+ }
+
+ return false;
+ }
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessRecyclerScrollListener.java b/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessGridScrollListener.java
similarity index 89%
rename from app/src/main/java/eu/kanade/tachiyomi/widget/EndlessRecyclerScrollListener.java
rename to app/src/main/java/eu/kanade/tachiyomi/widget/EndlessGridScrollListener.java
index d55b2a5834..a4d74d5502 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessRecyclerScrollListener.java
+++ b/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessGridScrollListener.java
@@ -5,7 +5,7 @@ import android.support.v7.widget.RecyclerView;
import rx.functions.Action0;
-public class EndlessRecyclerScrollListener extends RecyclerView.OnScrollListener {
+public class EndlessGridScrollListener extends RecyclerView.OnScrollListener {
private int previousTotal = 0; // The total number of items in the dataset after the last load
private boolean loading = true; // True if we are still waiting for the last set of data to load.
@@ -16,7 +16,7 @@ public class EndlessRecyclerScrollListener extends RecyclerView.OnScrollListener
private Action0 requestNext;
- public EndlessRecyclerScrollListener(GridLayoutManager layoutManager, Action0 requestNext) {
+ public EndlessGridScrollListener(GridLayoutManager layoutManager, Action0 requestNext) {
this.layoutManager = layoutManager;
this.requestNext = requestNext;
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessListScrollListener.java b/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessListScrollListener.java
new file mode 100644
index 0000000000..b5fcfa9408
--- /dev/null
+++ b/app/src/main/java/eu/kanade/tachiyomi/widget/EndlessListScrollListener.java
@@ -0,0 +1,49 @@
+package eu.kanade.tachiyomi.widget;
+
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+
+import rx.functions.Action0;
+
+public class EndlessListScrollListener extends RecyclerView.OnScrollListener {
+
+ private int previousTotal = 0; // The total number of items in the dataset after the last load
+ private boolean loading = true; // True if we are still waiting for the last set of data to load.
+ private int visibleThreshold = 5; // The minimum amount of items to have below your current scroll position before loading more.
+ int firstVisibleItem, visibleItemCount, totalItemCount;
+
+ private LinearLayoutManager layoutManager;
+
+ private Action0 requestNext;
+
+ public EndlessListScrollListener(LinearLayoutManager layoutManager, Action0 requestNext) {
+ this.layoutManager = layoutManager;
+ this.requestNext = requestNext;
+ }
+
+ public void resetScroll() {
+ previousTotal = 0;
+ loading = true;
+ }
+
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ super.onScrolled(recyclerView, dx, dy);
+
+ visibleItemCount = recyclerView.getChildCount();
+ totalItemCount = layoutManager.getItemCount();
+ firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
+
+ if (loading && (totalItemCount > previousTotal)) {
+ loading = false;
+ previousTotal = totalItemCount;
+ }
+ if (!loading && (totalItemCount - visibleItemCount)
+ <= (firstVisibleItem + visibleThreshold)) {
+ // End has been reached
+ requestNext.call();
+ loading = true;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-hdpi/ic_view_list_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_view_list_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..98c45924adc61322072a0058cb4911b6f69aa87f
GIT binary patch
literal 125
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K;i>HfYNX4z>ALkupPZ(rfm|(tw
zk<;i;xx>TccD@_DPHYOvoXu^4%_mGdvNpPHEisYGcD}gaVp7T$3CWP7CssH*A68(H
XVAy%vs;MpuXdZ*7tDnm{r-UW|K|k0wldT1B8K;m8XkiNX4z>ALkupPZ(rfm|(tw
zk=05-v+1Zp$OVTbCssHvX1l227^K_XbL`d%$L3QDE>`7US-@z~-m}O2k5>Rq
OVeoYIb6Mw<&;$VPJ0+I@
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-ldpi/ic_view_list_white_24dp.png b/app/src/main/res/drawable-ldpi/ic_view_list_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..35df0ba80137b2af3a32cfa80269140acbbcf40a
GIT binary patch
literal 187
zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a)4CQlc~kcwN$2@2vJ9UTP@hQd?Q
z+z%<(ad$n+zP@hh{;IE9!X2g!7OWk{6AGjP?#V?qa|C?2w!i-WJLW2tDnm{r-UW|1BO7w
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-ldpi/ic_view_module_white_24dp.png b/app/src/main/res/drawable-ldpi/ic_view_module_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..7bf1e34eeed3c2e7158784eac74781a6684b9ca9
GIT binary patch
literal 278
zcmV+x0qOpUP)8xd@Ux8#UvtJgv4wyia}6@x(v6#A~CrLF<7_&n<#_$ih)*Q5?kYc8ogh$Wwo|t2g
zD>}Hrr5^Oh>JOCeOzKnr=9ne^pz}J@`>nO$GYxz;z*{WhaP$h$>tDnm{r-UW|HCz?x
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-xhdpi/ic_view_list_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_view_list_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..8ce8a806c4f9c9bc791d7122365de2a6a37bbb0e
GIT binary patch
literal 117
zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}t8&4Op@B2u{L3FVdQ&MBb@09c476951J
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-xhdpi/ic_view_module_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_view_module_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..89980e2620249af35757014a33be50f23fe85882
GIT binary patch
literal 115
zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}tD^C~4kcwMxuNZOxC72KV`G5Hv
z^IR?0mhR|j(JCwd>}6nR;CwJ`x*SMtgXvdS28IK(m>3%79$?(sdgPjuh4O!(41=eu
KpUXO@geCyl&?8|0
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-xxhdpi/ic_view_list_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_view_list_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..6082dad61711ad208e576b363ddbf4f0b396caba
GIT binary patch
literal 144
zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhaw!aZFaLn>~)y|$5)!GMG1!2SA6
zV@D=2#)FqHJ>xp+pBl!_0R|bmFT&nuZf^jCe~mTO9}iDu1c6R@hiOtEB_4kS>><((
aw`v*8Zar%^?y3P~)y|z%0!GMG1;QRfV
zmmEV_8d~)y}pr?!GOc{;Qs%Y
z(pp$lnhI{+ic#JZQkD-?g9Pdr^FCKymqmy)R5mCvUpTT)04~&^7M8*=>xMWJT;#%$
gE*>}s$Vjk%!0>|M(xD^XWz#_7p00i_>zopr0Mmym!vFvP
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_view_module_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_view_module_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..02cd1b32145ee129e393340d21f1514af93b4ebe
GIT binary patch
literal 171
zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%xcgiacE$Ln>~)y|Iv&!GVM2;OqUF
z84u4+c3{&<<4Fp>xt9^B1_6GsR?J;ljo?FA4U!E;>
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_edit_categories.xml b/app/src/main/res/layout/activity_edit_categories.xml
index 564865341f..c709d07735 100644
--- a/app/src/main/res/layout/activity_edit_categories.xml
+++ b/app/src/main/res/layout/activity_edit_categories.xml
@@ -23,6 +23,7 @@
android:layout_gravity="bottom|right"
android:layout_margin="@dimen/fab_margin"
android:src="@drawable/ic_action_add_18dp"
+ app:backgroundTint="@color/colorPrimary"
app:layout_anchor="@id/categories_list"
app:layout_anchorGravity="bottom|right|end"
app:layout_behavior="eu.kanade.tachiyomi.ui.base.fab.ScrollAwareFABBehavior"/>
diff --git a/app/src/main/res/layout/fragment_catalogue.xml b/app/src/main/res/layout/fragment_catalogue.xml
index ad7b10cd24..38956c3f0f 100644
--- a/app/src/main/res/layout/fragment_catalogue.xml
+++ b/app/src/main/res/layout/fragment_catalogue.xml
@@ -11,17 +11,28 @@
android:id="@+id/progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
- android:layout_height="fill_parent"
+ android:layout_height="match_parent"
android:layout_gravity="center_vertical|center_horizontal"
android:visibility="gone"/>
-
+ android:id="@+id/switcher">
+
+
+
+
+
+
+ tools:listitem="@layout/item_catalogue_grid" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_manga_info.xml b/app/src/main/res/layout/fragment_manga_info.xml
index 2631044ba0..f5eaeabf15 100644
--- a/app/src/main/res/layout/fragment_manga_info.xml
+++ b/app/src/main/res/layout/fragment_manga_info.xml
@@ -154,7 +154,31 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/manga_status_label"
- android:layout_toRightOf="@id/manga_chapters_label"
+ android:layout_toRightOf="@id/manga_status_label"
+ android:ellipsize="end"
+ android:focusable="false"
+ android:focusableInTouchMode="false"
+ android:maxLines="1"
+ android:singleLine="true" />
+
+
+
+
diff --git a/app/src/main/res/layout/item_catalogue.xml b/app/src/main/res/layout/item_catalogue_grid.xml
similarity index 52%
rename from app/src/main/res/layout/item_catalogue.xml
rename to app/src/main/res/layout/item_catalogue_grid.xml
index a4197e5aaa..9836b21f71 100644
--- a/app/src/main/res/layout/item_catalogue.xml
+++ b/app/src/main/res/layout/item_catalogue_grid.xml
@@ -12,13 +12,27 @@
android:layout_height="wrap_content"
android:background="@drawable/card_background">
-
+ android:id="@+id/image_container">
+
+
+
+
+
+
-
-
-
-
-
+ android:layout_gravity="center_vertical"
+ app:typeface="ptsansNarrowBold"
+ android:lineSpacingExtra="-4dp"
+ android:ellipsize="end"
+ android:maxLines="2"
+ android:padding="8dp"
+ android:textColor="@color/white"
+ android:textSize="14sp"
+ android:shadowDx="0"
+ android:shadowDy="0"
+ android:shadowColor="@color/primary_text"
+ android:shadowRadius="4"
+ android:layout_alignBottom="@+id/image_container"
+ tools:text="Sample name"/>
diff --git a/app/src/main/res/layout/item_catalogue_list.xml b/app/src/main/res/layout/item_catalogue_list.xml
new file mode 100644
index 0000000000..409714fe62
--- /dev/null
+++ b/app/src/main/res/layout/item_catalogue_list.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_chapter.xml b/app/src/main/res/layout/item_chapter.xml
index 6c873cbbb4..4ceac37b00 100644
--- a/app/src/main/res/layout/item_chapter.xml
+++ b/app/src/main/res/layout/item_chapter.xml
@@ -66,7 +66,7 @@
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:layout_marginRight="30dp"
- android:ellipsize="end"
+ android:ellipsize="middle"
android:gravity="center_vertical"
android:maxLines="1"
android:textSize="17sp"
diff --git a/app/src/main/res/layout/item_pager_reader.xml b/app/src/main/res/layout/item_pager_reader.xml
index 6813bcb2de..4fefdc9b19 100644
--- a/app/src/main/res/layout/item_pager_reader.xml
+++ b/app/src/main/res/layout/item_pager_reader.xml
@@ -30,6 +30,8 @@
+
+
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/toolbar.xml b/app/src/main/res/layout/toolbar.xml
index c3e28cc0d2..c621b5a32b 100644
--- a/app/src/main/res/layout/toolbar.xml
+++ b/app/src/main/res/layout/toolbar.xml
@@ -1,9 +1,7 @@
\ No newline at end of file
+ android:theme="@style/AppTheme.ActionBar"/>
\ No newline at end of file
diff --git a/app/src/main/res/menu/catalogue_list.xml b/app/src/main/res/menu/catalogue_list.xml
index c0b1a7c5eb..668f162618 100644
--- a/app/src/main/res/menu/catalogue_list.xml
+++ b/app/src/main/res/menu/catalogue_list.xml
@@ -1,11 +1,16 @@
diff --git a/app/src/main/res/menu/chapters.xml b/app/src/main/res/menu/chapters.xml
new file mode 100644
index 0000000000..1d56f62b39
--- /dev/null
+++ b/app/src/main/res/menu/chapters.xml
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/keys.xml b/app/src/main/res/values/keys.xml
index 6ccd1552b8..e1013b9025 100644
--- a/app/src/main/res/values/keys.xml
+++ b/app/src/main/res/values/keys.xml
@@ -35,4 +35,6 @@
pref_versionpref_build_time
+
+ pref_display_catalogue_as_list
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 025323e9d1..bb72d2f5bc 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -38,6 +38,7 @@
Previous chapterNext chapterRetry
+ Change display mode
@@ -143,6 +144,7 @@
AuthorChaptersGenres
+ SourceArtistDescriptionStatus
@@ -155,12 +157,15 @@
ChaptersNo title
+ Chapter %1$sDownloadedQueuedDownloadingDownloading (%1$d/%2$d)ErrorError while fetching chapters
+ Show title
+ Show chapter numberReading
diff --git a/build.gradle b/build.gradle
index 150d005340..0bbade5918 100644
--- a/build.gradle
+++ b/build.gradle
@@ -21,7 +21,5 @@ allprojects {
jcenter()
maven { url "https://clojars.org/repo/" }
maven { url "https://jitpack.io" }
- maven { url 'http://dl.bintray.com/amulyakhare/maven' }
- maven { url 'https://github.com/suckgamony/RapidDecoder/raw/master/repository' }
}
}
diff --git a/libs/SubsamplingScaleImageView/build.gradle b/libs/SubsamplingScaleImageView/build.gradle
index abdacff135..971dbea647 100644
--- a/libs/SubsamplingScaleImageView/build.gradle
+++ b/libs/SubsamplingScaleImageView/build.gradle
@@ -6,9 +6,9 @@ version = '3.4.1'
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile "com.android.support:support-annotations:23.1.1"
- compile 'rapid.decoder:library:0.3.0'
- compile 'rapid.decoder:jpeg-decoder:0.3.0'
- compile 'rapid.decoder:png-decoder:0.3.0'
+ compile 'com.github.suckgamony.RapidDecoder:library:7cdfca4'
+ compile 'com.github.suckgamony.RapidDecoder:jpeg-decoder:7cdfca4'
+ compile 'com.github.suckgamony.RapidDecoder:png-decoder:7cdfca4'
}
android {