Commit 197dba16 authored by Thomas's avatar Thomas
Browse files

Improve cache

parent 154cc63f
Loading
Loading
Loading
Loading
+38 −3
Original line number Diff line number Diff line
@@ -19,27 +19,34 @@ import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.Menu;
import android.view.MenuItem;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import app.fedilab.android.R;
import app.fedilab.android.client.entities.app.Account;
import app.fedilab.android.client.entities.app.BaseAccount;
import app.fedilab.android.client.entities.app.CacheAccount;
import app.fedilab.android.databinding.ActivityCacheBinding;
import app.fedilab.android.helper.CacheHelper;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.helper.ThemeHelper;
import app.fedilab.android.ui.drawer.CacheAdapter;

public class CacheActivity extends BaseActivity {

    private ActivityCacheBinding binding;

    private List<CacheAccount> cacheAccounts;
    private CacheAdapter cacheAdapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -61,24 +68,52 @@ public class CacheActivity extends BaseActivity {

        new Thread(() -> {
            List<BaseAccount> accounts = new Account(CacheActivity.this).getPushNotificationAccounts();
            cacheAccounts = new ArrayList<>();
            for (BaseAccount baseAccount : accounts) {
                CacheAccount cacheAccount = new CacheAccount();
                cacheAccount.account = baseAccount;
                cacheAccounts.add(cacheAccount);
            }
            Handler mainHandler = new Handler(Looper.getMainLooper());
            Runnable myRunnable = () -> {
                CacheAdapter cacheAdapter = new CacheAdapter(accounts);
                cacheAdapter = new CacheAdapter(cacheAccounts);
                binding.cacheRecyclerview.setAdapter(cacheAdapter);
                LinearLayoutManager mLayoutManager = new LinearLayoutManager(CacheActivity.this);
                binding.cacheRecyclerview.setLayoutManager(mLayoutManager);
                binding.cacheRecyclerview.setAdapter(cacheAdapter);
            };
            mainHandler.post(myRunnable);
        }).start();

    }

    @Override
    public boolean onCreateOptionsMenu(@NonNull Menu menu) {
        getMenuInflater().inflate(R.menu.menu_cache, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
            return true;
        } else if (item.getItemId() == R.id.action_clear) {
            AlertDialog.Builder deleteConfirm = new AlertDialog.Builder(CacheActivity.this, Helper.dialogStyle());
            deleteConfirm.setTitle(getString(R.string.delete_cache));
            deleteConfirm.setMessage(getString(R.string.delete_cache_message));
            deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
            deleteConfirm.setPositiveButton(R.string.delete, (dialog, which) -> {
                CacheHelper.clearCache(CacheActivity.this, binding.labelFileCache.isChecked(), cacheAccounts, () -> CacheHelper.getCacheValues(CacheActivity.this, size -> {
                    if (size > 0) {
                        size = size / 1000000.0f;
                    }
                    binding.fileCacheSize.setText(String.format("%s %s", String.format(Locale.getDefault(), "%.2f", size), getString(R.string.cache_units)));
                    cacheAdapter.notifyDataSetChanged();
                }));
                dialog.dismiss();
            });
            deleteConfirm.create().show();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
+31 −0
Original line number Diff line number Diff line
package app.fedilab.android.client.entities.app;
/* Copyright 2022 Thomas Schneider
 *
 * This file is a part of Fedilab
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with Fedilab; if not,
 * see <http://www.gnu.org/licenses>. */

import com.google.gson.annotations.SerializedName;

import java.io.Serializable;

public class CacheAccount implements Serializable {

    @SerializedName("clear_home")
    public boolean clear_home = true;
    @SerializedName("clear_other")
    public boolean clear_other = true;
    @SerializedName("clear_drafts")
    public boolean clear_drafts = false;
    @SerializedName("account")
    public BaseAccount account;
}
+11 −0
Original line number Diff line number Diff line
@@ -191,6 +191,17 @@ public class StatusDraft implements Serializable {
        return db.delete(Sqlite.TABLE_STATUS_DRAFT, Sqlite.COL_USER_ID + " = '" + BaseMainActivity.currentUserID + "' AND " + Sqlite.COL_INSTANCE + " = '" + BaseMainActivity.currentInstance + "'", null);
    }

    /**
     * Remove all drafts for an account from db
     *
     * @return int
     */
    public int removeAllDraftFor(BaseAccount account) throws DBException {
        if (db == null) {
            throw new DBException("db is null. Wrong initialization.");
        }
        return db.delete(Sqlite.TABLE_STATUS_DRAFT, Sqlite.COL_USER_ID + " = '" + account.user_id + "' AND " + Sqlite.COL_INSTANCE + " = '" + account.instance + "'", null);
    }

    public int count(BaseAccount account) throws DBException {
        if (db == null) {
+39 −72
Original line number Diff line number Diff line
@@ -14,35 +14,21 @@ package app.fedilab.android.helper;
 * You should have received a copy of the GNU General Public License along with Fedilab; if not,
 * see <http://www.gnu.org/licenses>. */

import static app.fedilab.android.helper.Helper.getCurrentAccount;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.SwitchCompat;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.R;
import app.fedilab.android.client.entities.app.BaseAccount;
import app.fedilab.android.client.entities.app.CacheAccount;
import app.fedilab.android.client.entities.app.QuickLoad;
import app.fedilab.android.client.entities.app.StatusCache;
import app.fedilab.android.client.entities.app.StatusDraft;
import app.fedilab.android.exception.DBException;
import es.dmoral.toasty.Toasty;

public class CacheHelper {

@@ -133,65 +119,46 @@ public class CacheHelper {
        void getcount(List<Integer> countStatuses);
    }

    public static class CacheTask {
        private final WeakReference<Context> contextReference;
        private float cacheSize;

        public CacheTask(Context context) {
            contextReference = new WeakReference<>(context);
            doInBackground();
        }

        protected void doInBackground() {
    public static void clearCache(Context context, boolean clearFiles, List<CacheAccount> cacheAccounts, CallbackClear callbackClear) {
        new Thread(() -> {
                long sizeCache = cacheSize(contextReference.get().getCacheDir().getParentFile());
                cacheSize = 0;
                if (sizeCache > 0) {
                    cacheSize = (float) sizeCache / 1000000.0f;
                }
                Handler mainHandler = new Handler(Looper.getMainLooper());
                Runnable myRunnable = () -> {
                    AlertDialog.Builder builder = new AlertDialog.Builder(contextReference.get(), Helper.dialogStyle());
                    LayoutInflater inflater = ((BaseMainActivity) contextReference.get()).getLayoutInflater();
                    View dialogView = inflater.inflate(R.layout.popup_cache, new LinearLayout(contextReference.get()), false);
                    TextView message = dialogView.findViewById(R.id.message);
                    message.setText(contextReference.get().getString(R.string.cache_message, String.format("%s %s", String.format(Locale.getDefault(), "%.2f", cacheSize), contextReference.get().getString(R.string.cache_units))));
                    builder.setView(dialogView);
                    builder.setTitle(R.string.cache_title);

                    final SwitchCompat clean_all = dialogView.findViewById(R.id.clean_all);
                    final float finalCacheSize = cacheSize;
                    builder
                            .setPositiveButton(R.string.clear, (dialog, which) -> new Thread(() -> {
                                try {
                                    String path = Objects.requireNonNull(contextReference.get().getCacheDir().getParentFile()).getPath();
            if (clearFiles) {
                String path = context.getCacheDir().getParentFile().getPath();
                File dir = new File(path);
                if (dir.isDirectory()) {
                    deleteDir(dir);
                }
                                    if (clean_all.isChecked()) {
                                        new QuickLoad(contextReference.get()).deleteForAllAccount();
                                        new StatusCache(contextReference.get()).deleteForAllAccount();
                                    } else {
                                        new QuickLoad(contextReference.get()).deleteForAccount(getCurrentAccount(contextReference.get()));
                                        new StatusCache(contextReference.get()).deleteForAccount(getCurrentAccount(contextReference.get()));
                                    }
                                    Handler mainHandler2 = new Handler(Looper.getMainLooper());
                                    Runnable myRunnable2 = () -> {
                                        Toasty.success(contextReference.get(), contextReference.get().getString(R.string.toast_cache_clear, String.format("%s %s", String.format(Locale.getDefault(), "%.2f", finalCacheSize), contextReference.get().getString(R.string.cache_units))), Toast.LENGTH_LONG).show();
                                        dialog.dismiss();
                                    };
                                    mainHandler2.post(myRunnable2);
                                } catch (Exception ignored) {
                                }
                            }).start())
                            .setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss())
                            .setIcon(android.R.drawable.ic_dialog_alert)
                            .show();
                };
            }
            for (CacheAccount cacheAccount : cacheAccounts) {
                if (cacheAccount.clear_home) {
                    try {
                        new StatusCache(context).deleteForAccount(cacheAccount.account);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                }
                if (cacheAccount.clear_other) {
                    try {
                        new QuickLoad(context).deleteForAccount(cacheAccount.account);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                }
                if (cacheAccount.clear_drafts) {
                    try {
                        new StatusDraft(context).removeAllDraftFor(cacheAccount.account);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                }
            }
            Handler mainHandler = new Handler(Looper.getMainLooper());
            Runnable myRunnable = callbackClear::onCleared;
            mainHandler.post(myRunnable);
        }).start();
    }

    public interface CallbackClear {
        void onCleared();
    }

}
+16 −11
Original line number Diff line number Diff line
@@ -24,8 +24,7 @@ import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

import app.fedilab.android.activities.ProfileActivity;
import app.fedilab.android.client.entities.app.BaseAccount;
import app.fedilab.android.client.entities.app.CacheAccount;
import app.fedilab.android.databinding.DrawerCacheBinding;
import app.fedilab.android.helper.CacheHelper;
import app.fedilab.android.helper.MastodonHelper;
@@ -33,11 +32,10 @@ import app.fedilab.android.helper.MastodonHelper;

public class CacheAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static ProfileActivity.action doAction;
    private final List<BaseAccount> accountList;
    private final List<CacheAccount> accountList;
    private Context context;

    public CacheAdapter(List<BaseAccount> accountList) {
    public CacheAdapter(List<CacheAccount> accountList) {
        this.accountList = accountList;
    }

@@ -46,10 +44,11 @@ public class CacheAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
        return accountList.size();
    }

    public BaseAccount getItem(int position) {
    public CacheAccount getItem(int position) {
        return accountList.get(position);
    }


    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@@ -60,18 +59,24 @@ public class CacheAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
        BaseAccount account = accountList.get(position);
        CacheAccount cacheAccount = accountList.get(position);
        AccountCacheViewHolder holder = (AccountCacheViewHolder) viewHolder;
        MastodonHelper.loadPPMastodon(holder.binding.pp, account.mastodon_account);
        holder.binding.acct.setText(String.format("@%s@%s", account.mastodon_account.username, account.instance));
        holder.binding.displayName.setText(account.mastodon_account.display_name);
        CacheHelper.getTimelineValues(context, account, countStatuses -> {
        MastodonHelper.loadPPMastodon(holder.binding.pp, cacheAccount.account.mastodon_account);
        holder.binding.acct.setText(String.format("@%s@%s", cacheAccount.account.mastodon_account.username, cacheAccount.account.instance));
        holder.binding.displayName.setText(cacheAccount.account.mastodon_account.display_name);
        CacheHelper.getTimelineValues(context, cacheAccount.account, countStatuses -> {
            if (countStatuses != null && countStatuses.size() == 3) {
                holder.binding.homeCount.setText(String.valueOf(countStatuses.get(0)));
                holder.binding.otherCount.setText(String.valueOf(countStatuses.get(1)));
                holder.binding.draftCount.setText(String.valueOf(countStatuses.get(2)));
            }
        });
        holder.binding.labelHomeTimelineCacheCount.setChecked(cacheAccount.clear_home);
        holder.binding.labelTimelinesCacheCount.setChecked(cacheAccount.clear_other);
        holder.binding.labelDraftsCount.setChecked(cacheAccount.clear_drafts);
        holder.binding.labelHomeTimelineCacheCount.setOnCheckedChangeListener((compoundButton, checked) -> cacheAccount.clear_home = checked);
        holder.binding.labelTimelinesCacheCount.setOnCheckedChangeListener((compoundButton, checked) -> cacheAccount.clear_other = checked);
        holder.binding.labelDraftsCount.setOnCheckedChangeListener((compoundButton, checked) -> cacheAccount.clear_drafts = checked);
    }

    public long getItemId(int position) {
Loading