浏览代码

Add an option to change cache size and clear the cache

inorichi 9 年之前
父节点
当前提交
8f7443a686
共有 22 个文件被更改,包括 331 次插入158 次删除
  1. 6 0
      app/build.gradle
  2. 40 56
      app/src/main/java/eu/kanade/mangafeed/data/cache/CacheManager.java
  3. 4 0
      app/src/main/java/eu/kanade/mangafeed/data/preference/PreferencesHelper.java
  4. 5 5
      app/src/main/java/eu/kanade/mangafeed/injection/component/AppComponent.java
  5. 2 2
      app/src/main/java/eu/kanade/mangafeed/injection/module/DataModule.java
  6. 7 19
      app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsAccountsFragment.java
  7. 52 0
      app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsActivity.java
  8. 92 0
      app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsCacheFragment.java
  9. 5 21
      app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsDownloadsFragment.java
  10. 0 44
      app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsMainFragment.java
  11. 17 6
      app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsNestedFragment.java
  12. 1 1
      app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/ChapterSyncLoginDialog.java
  13. 35 0
      app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/IntListPreference.java
  14. 1 1
      app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/LoginDialogPreference.java
  15. 1 1
      app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/SourceLoginDialog.java
  16. 13 0
      app/src/main/java/eu/kanade/mangafeed/util/DiskUtils.java
  17. 12 0
      app/src/main/res/values/arrays.xml
  18. 4 0
      app/src/main/res/values/keys.xml
  19. 12 2
      app/src/main/res/values/strings.xml
  20. 16 0
      app/src/main/res/xml/pref_cache.xml
  21. 5 0
      app/src/main/res/xml/pref_main.xml
  22. 1 0
      build.gradle

+ 6 - 0
app/build.gradle

@@ -95,6 +95,12 @@ dependencies {
     compile('com.mikepenz:materialdrawer:4.4.8@aar') {
         transitive = true
     }
+    compile('com.github.afollestad.material-dialogs:core:0.8.5.2@aar') {
+        transitive = true
+    }
+    compile('com.github.afollestad.material-dialogs:commons:0.8.5.2@aar') {
+        transitive = true
+    }
 
     testCompile 'junit:junit:4.12'
     testCompile "org.hamcrest:hamcrest-core:$HAMCREST_VERSION"

+ 40 - 56
app/src/main/java/eu/kanade/mangafeed/data/cache/CacheManager.java

@@ -1,8 +1,8 @@
 package eu.kanade.mangafeed.data.cache;
 
 import android.content.Context;
+import android.text.format.Formatter;
 
-import com.bumptech.glide.Glide;
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 import com.jakewharton.disklrucache.DiskLruCache;
@@ -15,6 +15,7 @@ import java.io.OutputStream;
 import java.lang.reflect.Type;
 import java.util.List;
 
+import eu.kanade.mangafeed.data.preference.PreferencesHelper;
 import eu.kanade.mangafeed.data.source.model.Page;
 import eu.kanade.mangafeed.util.DiskUtils;
 import okio.BufferedSink;
@@ -26,67 +27,54 @@ public class CacheManager {
     private static final String PARAMETER_CACHE_DIRECTORY = "chapter_disk_cache";
     private static final int PARAMETER_APP_VERSION = 1;
     private static final int PARAMETER_VALUE_COUNT = 1;
-    private static final long PARAMETER_CACHE_SIZE = 100 * 1024 * 1024;
-    private static final int READ_TIMEOUT = 60;
 
-    private Context mContext;
-    private Gson mGson;
+    private Context context;
+    private Gson gson;
 
-    private DiskLruCache mDiskCache;
+    private DiskLruCache diskCache;
 
-    public CacheManager(Context context) {
-        mContext = context;
-        mGson = new Gson();
+    public CacheManager(Context context, PreferencesHelper preferences) {
+        this.context = context;
+        gson = new Gson();
 
         try {
-            mDiskCache = DiskLruCache.open(
+            diskCache = DiskLruCache.open(
                     new File(context.getCacheDir(), PARAMETER_CACHE_DIRECTORY),
                     PARAMETER_APP_VERSION,
                     PARAMETER_VALUE_COUNT,
-                    PARAMETER_CACHE_SIZE
+                    preferences.cacheSize() * 1024 * 1024
             );
         } catch (IOException e) {
             // Do Nothing.
         }
     }
 
-    public Observable<Boolean> clearImageCache() {
-        return Observable.create(subscriber -> {
-            try {
-                subscriber.onNext(clearImageCacheImpl());
-                subscriber.onCompleted();
-            } catch (Throwable e) {
-                subscriber.onError(e);
-            }
-        });
+    public boolean remove(String file) {
+        if (file.equals("journal") || file.startsWith("journal."))
+            return false;
+
+        try {
+            String key = file.substring(0, file.lastIndexOf("."));
+            return diskCache.remove(key);
+        } catch (IOException e) {
+            return false;
+        }
     }
 
-    private boolean clearImageCacheImpl() {
-        boolean isSuccessful = true;
+    public File getCacheDir() {
+        return diskCache.getDirectory();
+    }
 
-        File imageCacheDirectory = Glide.getPhotoCacheDir(mContext);
-        if (imageCacheDirectory.isDirectory()) {
-            for (File cachedFile : imageCacheDirectory.listFiles()) {
-                if (!cachedFile.delete()) {
-                    isSuccessful = false;
-                }
-            }
-        } else {
-            isSuccessful = false;
-        }
+    public long getRealSize() {
+        return DiskUtils.getDirectorySize(getCacheDir());
+    }
 
-        File urlCacheDirectory = getCacheDir();
-        if (urlCacheDirectory.isDirectory()) {
-            for (File cachedFile : urlCacheDirectory.listFiles()) {
-                if (!cachedFile.delete()) {
-                    isSuccessful = false;
-                }
-            }
-        } else {
-            isSuccessful = false;
-        }
+    public String getReadableSize() {
+        return Formatter.formatFileSize(context, getRealSize());
+    }
 
-        return isSuccessful;
+    public void setSize(int value) {
+        diskCache.setMaxSize(value * 1024 * 1024);
     }
 
     public Observable<List<Page>> getPageUrlsFromDiskCache(final String chapterUrl) {
@@ -107,10 +95,10 @@ public class CacheManager {
 
         try {
             String key = DiskUtils.hashKeyForDisk(chapterUrl);
-            snapshot = mDiskCache.get(key);
+            snapshot = diskCache.get(key);
 
             Type collectionType = new TypeToken<List<Page>>() {}.getType();
-            pages = mGson.fromJson(snapshot.getString(0), collectionType);
+            pages = gson.fromJson(snapshot.getString(0), collectionType);
         } catch (IOException e) {
             // Do Nothing.
         } finally {
@@ -122,13 +110,13 @@ public class CacheManager {
     }
 
     public void putPageUrlsToDiskCache(final String chapterUrl, final List<Page> pages) {
-        String cachedValue = mGson.toJson(pages);
+        String cachedValue = gson.toJson(pages);
 
         DiskLruCache.Editor editor = null;
         OutputStream outputStream = null;
         try {
             String key = DiskUtils.hashKeyForDisk(chapterUrl);
-            editor = mDiskCache.edit(key);
+            editor = diskCache.edit(key);
             if (editor == null) {
                 return;
             }
@@ -137,7 +125,7 @@ public class CacheManager {
             outputStream.write(cachedValue.getBytes());
             outputStream.flush();
 
-            mDiskCache.flush();
+            diskCache.flush();
             editor.commit();
         } catch (Exception e) {
             // Do Nothing.
@@ -155,13 +143,9 @@ public class CacheManager {
         }
     }
 
-    public File getCacheDir() {
-        return mDiskCache.getDirectory();
-    }
-
     public boolean isImageInCache(final String imageUrl) {
         try {
-            return mDiskCache.get(DiskUtils.hashKeyForDisk(imageUrl)) != null;
+            return diskCache.get(DiskUtils.hashKeyForDisk(imageUrl)) != null;
         } catch (IOException e) {
             e.printStackTrace();
         }
@@ -171,7 +155,7 @@ public class CacheManager {
     public String getImagePath(final String imageUrl) {
         try {
             String imageName = DiskUtils.hashKeyForDisk(imageUrl) + ".0";
-            File file = new File(mDiskCache.getDirectory(), imageName);
+            File file = new File(diskCache.getDirectory(), imageName);
             return file.getCanonicalPath();
         } catch (IOException e) {
             e.printStackTrace();
@@ -185,7 +169,7 @@ public class CacheManager {
 
         try {
             String key = DiskUtils.hashKeyForDisk(imageUrl);
-            editor = mDiskCache.edit(key);
+            editor = diskCache.edit(key);
             if (editor == null) {
                 throw new IOException("Unable to edit key");
             }
@@ -194,7 +178,7 @@ public class CacheManager {
             sink = Okio.buffer(Okio.sink(outputStream));
             sink.writeAll(response.body().source());
 
-            mDiskCache.flush();
+            diskCache.flush();
             editor.commit();
         } catch (Exception e) {
             throw new IOException("Unable to save image");

+ 4 - 0
app/src/main/java/eu/kanade/mangafeed/data/preference/PreferencesHelper.java

@@ -40,6 +40,10 @@ public class PreferencesHelper {
         prefs.edit().clear().apply();
     }
 
+    public int cacheSize() {
+        return prefs.getInt(getKey(R.string.pref_chapter_cache_size_key), 75);
+    }
+
     public Preference<Boolean> lockOrientation() {
         return rxPrefs.getBoolean(getKey(R.string.pref_lock_orientation_key), true);
     }

+ 5 - 5
app/src/main/java/eu/kanade/mangafeed/injection/component/AppComponent.java

@@ -8,10 +8,12 @@ import dagger.Component;
 import eu.kanade.mangafeed.data.chaptersync.MyAnimeList;
 import eu.kanade.mangafeed.data.chaptersync.UpdateChapterSyncService;
 import eu.kanade.mangafeed.data.download.DownloadService;
+import eu.kanade.mangafeed.data.source.base.Source;
 import eu.kanade.mangafeed.data.sync.LibraryUpdateService;
 import eu.kanade.mangafeed.injection.module.AppModule;
 import eu.kanade.mangafeed.injection.module.DataModule;
 import eu.kanade.mangafeed.ui.catalogue.CataloguePresenter;
+import eu.kanade.mangafeed.ui.catalogue.SourcePresenter;
 import eu.kanade.mangafeed.ui.download.DownloadPresenter;
 import eu.kanade.mangafeed.ui.library.LibraryPresenter;
 import eu.kanade.mangafeed.ui.manga.MangaActivity;
@@ -19,12 +21,10 @@ import eu.kanade.mangafeed.ui.manga.MangaPresenter;
 import eu.kanade.mangafeed.ui.manga.chapter.ChaptersPresenter;
 import eu.kanade.mangafeed.ui.manga.info.MangaInfoPresenter;
 import eu.kanade.mangafeed.ui.manga.myanimelist.MyAnimeListPresenter;
-import eu.kanade.mangafeed.ui.reader.ReaderPresenter;
-import eu.kanade.mangafeed.ui.catalogue.SourcePresenter;
-import eu.kanade.mangafeed.data.source.base.Source;
 import eu.kanade.mangafeed.ui.reader.ReaderActivity;
+import eu.kanade.mangafeed.ui.reader.ReaderPresenter;
 import eu.kanade.mangafeed.ui.setting.SettingsAccountsFragment;
-import eu.kanade.mangafeed.ui.setting.SettingsDownloadsFragment;
+import eu.kanade.mangafeed.ui.setting.SettingsActivity;
 
 @Singleton
 @Component(
@@ -48,7 +48,7 @@ public interface AppComponent {
     void inject(ReaderActivity readerActivity);
     void inject(MangaActivity mangaActivity);
     void inject(SettingsAccountsFragment settingsAccountsFragment);
-    void inject(SettingsDownloadsFragment settingsDownloadsFragment);
+    void inject(SettingsActivity settingsActivity);
 
     void inject(Source source);
 

+ 2 - 2
app/src/main/java/eu/kanade/mangafeed/injection/module/DataModule.java

@@ -35,8 +35,8 @@ public class DataModule {
 
     @Provides
     @Singleton
-    CacheManager provideCacheManager(Application app) {
-        return new CacheManager(app);
+    CacheManager provideCacheManager(Application app, PreferencesHelper preferences) {
+        return new CacheManager(app, preferences);
     }
 
     @Provides

+ 7 - 19
app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsAccountsFragment.java

@@ -2,7 +2,6 @@ package eu.kanade.mangafeed.ui.setting;
 
 import android.os.Bundle;
 import android.preference.PreferenceCategory;
-import android.preference.PreferenceFragment;
 import android.preference.PreferenceScreen;
 
 import java.util.List;
@@ -10,33 +9,29 @@ import java.util.List;
 import javax.inject.Inject;
 
 import eu.kanade.mangafeed.App;
-import eu.kanade.mangafeed.R;
 import eu.kanade.mangafeed.data.chaptersync.BaseChapterSync;
 import eu.kanade.mangafeed.data.chaptersync.ChapterSyncManager;
-import eu.kanade.mangafeed.data.preference.PreferencesHelper;
 import eu.kanade.mangafeed.data.source.SourceManager;
 import eu.kanade.mangafeed.data.source.base.Source;
-import eu.kanade.mangafeed.ui.base.activity.BaseActivity;
-import eu.kanade.mangafeed.ui.setting.dialog.ChapterSyncLoginDialog;
-import eu.kanade.mangafeed.ui.setting.dialog.SourceLoginDialog;
+import eu.kanade.mangafeed.ui.setting.preference.ChapterSyncLoginDialog;
+import eu.kanade.mangafeed.ui.setting.preference.SourceLoginDialog;
 import rx.Observable;
 
-public class SettingsAccountsFragment extends PreferenceFragment {
+public class SettingsAccountsFragment extends SettingsNestedFragment {
 
-    @Inject PreferencesHelper preferences;
     @Inject SourceManager sourceManager;
     @Inject ChapterSyncManager syncManager;
 
-    public static SettingsAccountsFragment newInstance() {
-        return new SettingsAccountsFragment();
+    public static SettingsNestedFragment newInstance(int resourcePreference, int resourceTitle) {
+        SettingsNestedFragment fragment = new SettingsAccountsFragment();
+        fragment.setBundle(resourcePreference, resourceTitle);
+        return fragment;
     }
 
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         App.get(getActivity()).getComponent().inject(this);
 
-        addPreferencesFromResource(R.xml.pref_accounts);
-
         PreferenceScreen screen = getPreferenceScreen();
 
         List<Source> sourceAccounts = getSourcesWithLogin();
@@ -67,13 +62,6 @@ public class SettingsAccountsFragment extends PreferenceFragment {
 
     }
 
-    @Override
-    public void onResume() {
-        super.onResume();
-        ((BaseActivity)getActivity())
-                .setToolbarTitle(getString(R.string.pref_category_accounts));
-    }
-
     private List<Source> getSourcesWithLogin() {
         return Observable.from(sourceManager.getSources())
                 .filter(Source::isLoginRequired)

+ 52 - 0
app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsActivity.java

@@ -1,20 +1,30 @@
 package eu.kanade.mangafeed.ui.setting;
 
 import android.os.Bundle;
+import android.preference.PreferenceFragment;
 import android.support.v7.widget.Toolbar;
 
+import javax.inject.Inject;
+
 import butterknife.Bind;
 import butterknife.ButterKnife;
+import eu.kanade.mangafeed.App;
 import eu.kanade.mangafeed.R;
+import eu.kanade.mangafeed.data.cache.CacheManager;
+import eu.kanade.mangafeed.data.preference.PreferencesHelper;
 import eu.kanade.mangafeed.ui.base.activity.BaseActivity;
 
 public class SettingsActivity extends BaseActivity {
 
+    @Inject PreferencesHelper preferences;
+    @Inject CacheManager cacheManager;
+
     @Bind(R.id.toolbar) Toolbar toolbar;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        App.get(getActivity()).getComponent().inject(this);
         setContentView(R.layout.activity_preferences);
         ButterKnife.bind(this);
 
@@ -31,4 +41,46 @@ public class SettingsActivity extends BaseActivity {
         if( !getFragmentManager().popBackStackImmediate() ) super.onBackPressed();
     }
 
+    public static class SettingsMainFragment extends PreferenceFragment {
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            addPreferencesFromResource(R.xml.pref_main);
+
+            registerSubpreference(R.string.pref_category_reader_key,
+                    SettingsNestedFragment.newInstance(
+                        R.xml.pref_reader, R.string.pref_category_reader));
+
+            registerSubpreference(R.string.pref_category_downloads_key,
+                    SettingsDownloadsFragment.newInstance(
+                        R.xml.pref_downloads, R.string.pref_category_downloads));
+
+            registerSubpreference(R.string.pref_category_accounts_key,
+                    SettingsAccountsFragment.newInstance(
+                        R.xml.pref_accounts, R.string.pref_category_accounts));
+
+            registerSubpreference(R.string.pref_category_cache_key,
+                    SettingsCacheFragment.newInstance(
+                            R.xml.pref_cache, R.string.pref_category_cache));
+        }
+
+        @Override
+        public void onResume() {
+            super.onResume();
+            ((BaseActivity) getActivity()).setToolbarTitle(getString(R.string.label_settings));
+        }
+
+        private void registerSubpreference(int preferenceResource, PreferenceFragment fragment) {
+            findPreference(getString(preferenceResource))
+                    .setOnPreferenceClickListener(preference -> {
+                        getFragmentManager().beginTransaction()
+                                .replace(R.id.settings_content, fragment)
+                                .addToBackStack(fragment.getClass().getSimpleName()).commit();
+                        return true;
+                    });
+        }
+
+    }
+
 }

+ 92 - 0
app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsCacheFragment.java

@@ -0,0 +1,92 @@
+package eu.kanade.mangafeed.ui.setting;
+
+import android.os.Bundle;
+import android.preference.Preference;
+
+import com.afollestad.materialdialogs.MaterialDialog;
+
+import java.io.File;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import eu.kanade.mangafeed.R;
+import eu.kanade.mangafeed.data.cache.CacheManager;
+import eu.kanade.mangafeed.ui.setting.preference.IntListPreference;
+import eu.kanade.mangafeed.util.ToastUtil;
+import rx.Observable;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
+
+public class SettingsCacheFragment extends SettingsNestedFragment implements Preference.OnPreferenceClickListener {
+
+    private CacheManager cacheManager;
+    private Preference clearCache;
+    private Subscription clearChapterCacheSubscription;
+
+    public static SettingsNestedFragment newInstance(int resourcePreference, int resourceTitle) {
+        SettingsNestedFragment fragment = new SettingsCacheFragment();
+        fragment.setBundle(resourcePreference, resourceTitle);
+        return fragment;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        cacheManager = getSettingsActivity().cacheManager;
+
+        IntListPreference cacheSize = (IntListPreference)findPreference(getString(R.string.pref_chapter_cache_size_key));
+        cacheSize.setOnPreferenceChangeListener(
+                (preference, newValue) -> {
+                    cacheManager.setSize(Integer.parseInt(newValue.toString()));
+                    return true;
+                });
+
+        clearCache = findPreference(getString(R.string.pref_clear_chapter_cache_key));
+        clearCache.setOnPreferenceClickListener(this);
+        clearCache.setSummary(getString(R.string.used_cache, cacheManager.getReadableSize()));
+    }
+
+    @Override
+    public boolean onPreferenceClick(Preference preference) {
+        if (preference.equals(clearCache)) {
+            clearChapterCache();
+        }
+        return true;
+    }
+
+    private void clearChapterCache() {
+        final AtomicInteger deletedFiles = new AtomicInteger();
+
+        File[] files = cacheManager.getCacheDir().listFiles();
+
+        MaterialDialog dialog = new MaterialDialog.Builder(getActivity())
+                .title(R.string.deleting_files)
+                .progress(false, files.length, true)
+                .cancelable(false)
+                .dismissListener(d -> {
+                    if (clearChapterCacheSubscription != null && !clearChapterCacheSubscription.isUnsubscribed())
+                        clearChapterCacheSubscription.unsubscribe();
+                })
+                .show();
+
+        clearChapterCacheSubscription = Observable.defer(() -> Observable.from(files))
+                .concatMap(file -> {
+                    if (cacheManager.remove(file.getName())) {
+                        deletedFiles.incrementAndGet();
+                    }
+                    return Observable.just(file);
+                })
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(file -> dialog.incrementProgress(1),
+                        error -> {
+                            dialog.dismiss();
+                            ToastUtil.showShort(getActivity(), getString(R.string.cache_delete_error));
+                        }, () -> {
+                            dialog.dismiss();
+                            ToastUtil.showShort(getActivity(), getString(R.string.cache_deleted, deletedFiles.get()));
+                            clearCache.setSummary(getString(R.string.used_cache, cacheManager.getReadableSize()));
+                        });
+    }
+
+}

+ 5 - 21
app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsDownloadsFragment.java

@@ -2,30 +2,21 @@ package eu.kanade.mangafeed.ui.setting;
 
 import android.os.Bundle;
 import android.preference.ListPreference;
-import android.preference.PreferenceFragment;
 import android.preference.PreferenceScreen;
 
-import javax.inject.Inject;
-
-import eu.kanade.mangafeed.App;
 import eu.kanade.mangafeed.R;
-import eu.kanade.mangafeed.data.preference.PreferencesHelper;
-import eu.kanade.mangafeed.ui.base.activity.BaseActivity;
 import eu.kanade.mangafeed.util.DiskUtils;
 
-public class SettingsDownloadsFragment extends PreferenceFragment {
-
-    @Inject PreferencesHelper preferences;
+public class SettingsDownloadsFragment extends SettingsNestedFragment {
 
-    public static SettingsDownloadsFragment newInstance() {
-        return new SettingsDownloadsFragment();
+    public static SettingsNestedFragment newInstance(int resourcePreference, int resourceTitle) {
+        SettingsNestedFragment fragment = new SettingsDownloadsFragment();
+        fragment.setBundle(resourcePreference, resourceTitle);
+        return fragment;
     }
 
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        App.get(getActivity()).getComponent().inject(this);
-
-        addPreferencesFromResource(R.xml.pref_downloads);
 
         PreferenceScreen screen = getPreferenceScreen();
 
@@ -46,11 +37,4 @@ public class SettingsDownloadsFragment extends PreferenceFragment {
         screen.addPreference(directoriesPref);
     }
 
-    @Override
-    public void onResume() {
-        super.onResume();
-        ((BaseActivity)getActivity())
-                .setToolbarTitle(getString(R.string.pref_category_downloads));
-    }
-
 }

+ 0 - 44
app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsMainFragment.java

@@ -1,44 +0,0 @@
-package eu.kanade.mangafeed.ui.setting;
-
-import android.os.Bundle;
-import android.preference.PreferenceFragment;
-
-import eu.kanade.mangafeed.R;
-import eu.kanade.mangafeed.ui.base.activity.BaseActivity;
-
-public class SettingsMainFragment extends PreferenceFragment {
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.pref_main);
-
-        registerSubpreference(R.string.pref_category_reader_key,
-                SettingsNestedFragment.newInstance(
-                        R.xml.pref_reader, R.string.pref_category_reader));
-
-        registerSubpreference(R.string.pref_category_downloads_key,
-                SettingsDownloadsFragment.newInstance());
-
-        registerSubpreference(R.string.pref_category_accounts_key,
-                SettingsAccountsFragment.newInstance());
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        ((BaseActivity)getActivity())
-                .setToolbarTitle(getString(R.string.label_settings));
-    }
-
-    private void registerSubpreference(int preferenceResource, PreferenceFragment fragment) {
-        findPreference(getString(preferenceResource))
-                .setOnPreferenceClickListener(preference -> {
-                    getFragmentManager().beginTransaction()
-                            .replace(R.id.settings_content, fragment)
-                            .addToBackStack(fragment.getClass().getSimpleName()).commit();
-                    return true;
-                });
-    }
-
-}

+ 17 - 6
app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsNestedFragment.java

@@ -3,34 +3,45 @@ package eu.kanade.mangafeed.ui.setting;
 import android.os.Bundle;
 import android.preference.PreferenceFragment;
 
+import eu.kanade.mangafeed.data.preference.PreferencesHelper;
 import eu.kanade.mangafeed.ui.base.activity.BaseActivity;
 
 public class SettingsNestedFragment extends PreferenceFragment {
 
+    protected PreferencesHelper preferences;
+
     private static final String RESOURCE_FILE = "resource_file";
     private static final String TOOLBAR_TITLE = "toolbar_title";
 
     public static SettingsNestedFragment newInstance(int resourcePreference, int resourceTitle) {
         SettingsNestedFragment fragment = new SettingsNestedFragment();
-        Bundle args = new Bundle();
-        args.putInt(RESOURCE_FILE, resourcePreference);
-        args.putInt(TOOLBAR_TITLE, resourceTitle);
-        fragment.setArguments(args);
+        fragment.setBundle(resourcePreference, resourceTitle);
         return fragment;
     }
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        preferences = getSettingsActivity().preferences;
         addPreferencesFromResource(getArguments().getInt(RESOURCE_FILE));
-
     }
 
     @Override
     public void onResume() {
         super.onResume();
-        ((BaseActivity)getActivity())
+        ((BaseActivity) getActivity())
                 .setToolbarTitle(getString(getArguments().getInt(TOOLBAR_TITLE)));
     }
 
+    public void setBundle(int resourcePreference, int resourceTitle) {
+        Bundle args = new Bundle();
+        args.putInt(RESOURCE_FILE, resourcePreference);
+        args.putInt(TOOLBAR_TITLE, resourceTitle);
+        setArguments(args);
+    }
+
+    public SettingsActivity getSettingsActivity() {
+        return (SettingsActivity) getActivity();
+    }
+
 }

+ 1 - 1
app/src/main/java/eu/kanade/mangafeed/ui/setting/dialog/ChapterSyncLoginDialog.java → app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/ChapterSyncLoginDialog.java

@@ -1,4 +1,4 @@
-package eu.kanade.mangafeed.ui.setting.dialog;
+package eu.kanade.mangafeed.ui.setting.preference;
 
 import android.content.Context;
 import android.content.DialogInterface;

+ 35 - 0
app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/IntListPreference.java

@@ -0,0 +1,35 @@
+package eu.kanade.mangafeed.ui.setting.preference;
+
+import android.content.Context;
+import android.preference.ListPreference;
+import android.util.AttributeSet;
+
+public class IntListPreference extends ListPreference
+{
+    public IntListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public IntListPreference(Context context) {
+        super(context);
+    }
+
+    @Override
+    protected boolean persistString(String value) {
+        if(value == null) {
+            return false;
+        } else {
+            return persistInt(Integer.valueOf(value));
+        }
+    }
+
+    @Override
+    protected String getPersistedString(String defaultReturnValue) {
+        if(getSharedPreferences().contains(getKey())) {
+            int intValue = getPersistedInt(0);
+            return String.valueOf(intValue);
+        } else {
+            return defaultReturnValue;
+        }
+    }
+}

+ 1 - 1
app/src/main/java/eu/kanade/mangafeed/ui/setting/dialog/LoginDialogPreference.java → app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/LoginDialogPreference.java

@@ -1,4 +1,4 @@
-package eu.kanade.mangafeed.ui.setting.dialog;
+package eu.kanade.mangafeed.ui.setting.preference;
 
 import android.app.AlertDialog;
 import android.content.Context;

+ 1 - 1
app/src/main/java/eu/kanade/mangafeed/ui/setting/dialog/SourceLoginDialog.java → app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/SourceLoginDialog.java

@@ -1,4 +1,4 @@
-package eu.kanade.mangafeed.ui.setting.dialog;
+package eu.kanade.mangafeed.ui.setting.preference;
 
 import android.content.Context;
 import android.content.DialogInterface;

+ 13 - 0
app/src/main/java/eu/kanade/mangafeed/util/DiskUtils.java

@@ -158,5 +158,18 @@ public final class DiskUtils {
         }
 
     }
+
+    public static long getDirectorySize(File f) {
+        long size = 0;
+        if (f.isDirectory()) {
+            for (File file : f.listFiles()) {
+                size += getDirectorySize(file);
+            }
+        } else {
+            size=f.length();
+        }
+        return size;
+    }
+
 }
 

+ 12 - 0
app/src/main/res/values/arrays.xml

@@ -27,4 +27,16 @@
         <item>2</item>
         <item>3</item>
     </string-array>
+
+    <string-array name="cache_size">
+        <item>50 MB</item>
+        <item>75 MB</item>
+        <item>100 MB</item>
+    </string-array>
+
+    <string-array name="cache_values">
+        <item>50</item>
+        <item>75</item>
+        <item>100</item>
+    </string-array>
 </resources>

+ 4 - 0
app/src/main/res/values/keys.xml

@@ -3,6 +3,7 @@
     <string name="pref_category_reader_key">pref_category_reader_key</string>
     <string name="pref_category_accounts_key">pref_category_accounts_key</string>
     <string name="pref_category_downloads_key">pref_category_downloads_key</string>
+    <string name="pref_category_cache_key">pref_category_cache_key</string>
 
     <string name="pref_default_viewer_key">pref_default_viewer_key</string>
     <string name="pref_hide_status_bar_key">pref_hide_status_bar_key</string>
@@ -15,4 +16,7 @@
 
     <string name="pref_download_directory_key">pref_download_directory_key</string>
     <string name="pref_download_threads_key">pref_download_threads_key</string>
+
+    <string name="pref_chapter_cache_size_key">pref_chapter_cache_size_key</string>
+    <string name="pref_clear_chapter_cache_key">pref_clear_chapter_cache_key</string>
 </resources>

+ 12 - 2
app/src/main/res/values/strings.xml

@@ -29,12 +29,16 @@
     <string name="button_ok">OK</string>
     <string name="button_cancel">Cancel</string>
 
+    <!-- Operations -->
+    <string name="deleting_files">Deleting files…</string>
+    <string name="loading">Loading…</string>
 
     <!-- Preferences -->
       <!-- Subsections -->
     <string name="pref_category_reader">Reader</string>
     <string name="pref_category_accounts">Accounts</string>
     <string name="pref_category_downloads">Downloads</string>
+    <string name="pref_category_cache">Cache</string>
 
       <!-- Reader section -->
     <string name="pref_hide_status_bar">Hide status bar</string>
@@ -53,16 +57,22 @@
     <string name="pref_download_directory">Downloads directory</string>
     <string name="pref_download_threads">Download threads</string>
 
+      <!-- Cache section -->
+    <string name="pref_chapter_cache_size">Chapters cache size</string>
+    <string name="pref_clear_chapter_cache">Clear chapter cache</string>
+    <string name="used_cache">Used: %1$s</string>
+    <string name="cache_deleted">Cache cleared. %1$d files have been deleted</string>
+    <string name="cache_delete_error">An error occurred clearing cache</string>
+
+
     <!-- Login dialog -->
     <string name="accounts_login_title">Login for %1$s</string>
     <string name="username">Username</string>
     <string name="password">Password</string>
     <string name="show_password">Show password</string>
-    <string name="check_credentials">Check credentials</string>
     <string name="login">Login</string>
     <string name="login_success">Login successful</string>
     <string name="invalid_login">Login error</string>
-    <string name="loading">Loading…</string>
     <string name="unknown_error">Unknown error</string>
 
     <!-- Library fragment -->

+ 16 - 0
app/src/main/res/xml/pref_cache.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <eu.kanade.mangafeed.ui.setting.preference.IntListPreference
+        android:title="@string/pref_chapter_cache_size"
+        android:key="@string/pref_chapter_cache_size_key"
+        android:entries="@array/cache_size"
+        android:entryValues="@array/cache_values"
+        android:summary="%s"
+        android:defaultValue="75"/>
+
+    <Preference
+        android:title="@string/pref_clear_chapter_cache"
+        android:key="@string/pref_clear_chapter_cache_key" />
+
+</PreferenceScreen>

+ 5 - 0
app/src/main/res/xml/pref_main.xml

@@ -16,4 +16,9 @@
         android:persistent="false"
         android:title="@string/pref_category_accounts" />
 
+    <Preference
+        android:key="@string/pref_category_cache_key"
+        android:persistent="false"
+        android:title="@string/pref_category_cache" />
+
 </PreferenceScreen>

+ 1 - 0
build.gradle

@@ -20,5 +20,6 @@ allprojects {
         jcenter()
         maven { url "https://clojars.org/repo/" }
         maven { url "http://dl.bintray.com/davideas/maven" }
+        maven { url "https://jitpack.io" }
     }
 }