diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5013ae03..3fc5baff 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -265,7 +265,11 @@ android:configChanges="keyboardHidden|orientation|screenSize" android:label="@string/action_about" android:theme="@style/AppThemeBar" /> - + . */ + + +import android.graphics.Canvas; +import android.os.Bundle; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; + +import androidx.appcompat.widget.LinearLayoutCompat; + +import com.github.mikephil.charting.components.Description; +import com.github.mikephil.charting.components.XAxis; +import com.github.mikephil.charting.data.Entry; +import com.github.mikephil.charting.data.LineData; +import com.github.mikephil.charting.data.LineDataSet; +import com.github.mikephil.charting.formatter.IndexAxisValueFormatter; +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet; +import com.github.mikephil.charting.renderer.XAxisRenderer; +import com.github.mikephil.charting.utils.MPPointF; +import com.github.mikephil.charting.utils.Transformer; +import com.github.mikephil.charting.utils.Utils; +import com.github.mikephil.charting.utils.ViewPortHandler; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import app.fedilab.android.R; +import app.fedilab.android.activities.MainActivity; +import app.fedilab.android.databinding.ActivityCheckHomeCachetBinding; +import app.fedilab.android.mastodon.client.entities.api.Status; +import app.fedilab.android.mastodon.client.entities.app.StatusCache; +import app.fedilab.android.mastodon.exception.DBException; +import app.fedilab.android.mastodon.helper.Helper; +import app.fedilab.android.mastodon.helper.ThemeHelper; +import es.dmoral.toasty.Toasty; + + +public class CheckHomeCacheActivity extends BaseBarActivity { + + + private ActivityCheckHomeCachetBinding binding; + private List statuses; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + binding = ActivityCheckHomeCachetBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + if (MainActivity.currentAccount == null || MainActivity.currentAccount.mastodon_account == null) { + finish(); + return; + } + binding.chart.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + binding.chart.getViewTreeObserver().removeOnGlobalLayoutListener(this); + int height = (binding.chart.getWidth()); + LinearLayoutCompat.LayoutParams params = new LinearLayoutCompat.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height); + binding.chart.setLayoutParams(params); + binding.chart.setVisibility(View.VISIBLE); + } + }); + + new Thread(() -> { + try { + statuses = new StatusCache(this).getHome(MainActivity.currentAccount); + if (statuses == null || statuses.size() < 2) { + runOnUiThread(() -> binding.noAction.setVisibility(View.VISIBLE)); + return; + } + + final ArrayList xVals = new ArrayList<>(); + String xDate; + int inc = 0; + //We loop through cache + List statusEntry = new ArrayList<>(); + int index = 0; + for (Status status : statuses) { + //We aggregate message in same hour range + boolean sameHourRange = true; + int count = 0; + while (inc < statuses.size() && sameHourRange) { + Calendar currentStatusDate = Calendar.getInstance(); + currentStatusDate.setTime(statuses.get(inc).created_at); + String xDateH = new SimpleDateFormat("hh", Locale.getDefault()).format(statuses.get(inc).created_at); + SimpleDateFormat df = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault()); + String xDateD = df.format(statuses.get(inc).created_at); + xDate = xDateD + " " + String.format(Locale.getDefault(), "%sh", xDateH); + if (inc + 1 < statuses.size()) { + Calendar nextStatusDate = Calendar.getInstance(); + nextStatusDate.setTime(statuses.get(inc + 1).created_at); + if (currentStatusDate.get(Calendar.HOUR) != nextStatusDate.get(Calendar.HOUR)) { + sameHourRange = false; + statusEntry.add(new Entry(index, count)); + index++; + xVals.add(xDate); + } else { + count++; + } + } else { //Last item + count++; + statusEntry.add(new Entry(index, count)); + xVals.add(xDate); + } + inc++; + } + } + List dataSets = new ArrayList<>(); + + LineDataSet dataStatus = new LineDataSet(statusEntry, getString(R.string.cached_messages)); + dataStatus.setDrawValues(false); + dataStatus.setDrawFilled(true); + dataStatus.setDrawCircles(false); + dataStatus.setDrawCircleHole(false); + dataStatus.setMode(LineDataSet.Mode.CUBIC_BEZIER); + dataSets.add(dataStatus); + + LineData data = new LineData(dataSets); + binding.chart.setData(data); + IndexAxisValueFormatter formatter = new IndexAxisValueFormatter() { + @Override + public String getFormattedValue(float value) { + if (value < xVals.size()) { + return xVals.get((int) value); + } else + return ""; + } + }; + binding.chart.setExtraBottomOffset(80); + // binding.chart.getXAxis().setGranularity(1f); + binding.chart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM); + binding.chart.getXAxis().setLabelRotationAngle(-45f); + binding.chart.getXAxis().setValueFormatter(formatter); + binding.chart.getXAxis().setEnabled(true); + binding.chart.getXAxis().setTextColor(ThemeHelper.getAttColor(CheckHomeCacheActivity.this, R.attr.colorOnBackground)); + binding.chart.getAxisLeft().setTextColor(ThemeHelper.getAttColor(CheckHomeCacheActivity.this, R.attr.colorOnBackground)); + binding.chart.getAxisRight().setTextColor(ThemeHelper.getAttColor(CheckHomeCacheActivity.this, R.attr.colorOnBackground)); + binding.chart.getLegend().setTextColor(ThemeHelper.getAttColor(CheckHomeCacheActivity.this, R.attr.colorOnBackground)); + binding.chart.getAxisLeft().setAxisMinimum(0f); + binding.chart.getAxisRight().setAxisMinimum(0f); + binding.chart.getXAxis().setLabelCount(10, true); + binding.chart.getLegend().setEnabled(false); + + Description description = binding.chart.getDescription(); + description.setEnabled(false); + + binding.chart.invalidate(); + + } catch (DBException | NegativeArraySizeException e) { + binding.noAction.setVisibility(View.VISIBLE); + Toasty.error(this, getString(R.string.toast_error), Toasty.LENGTH_SHORT).show(); + throw new RuntimeException(e); + } + }).start(); + + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + + public static class LineChartXAxisValueFormatter extends IndexAxisValueFormatter { + + @Override + public String getFormattedValue(float value) { + + long emissionsMilliSince1970Time = ((long) value); + Log.v(Helper.TAG, "value: " + value); + Date timeMilliseconds = new Date(emissionsMilliSince1970Time); + DateFormat dateTimeFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault()); + return dateTimeFormat.format(timeMilliseconds); + } + } + + public class CustomXAxisRenderer extends XAxisRenderer { + public CustomXAxisRenderer(ViewPortHandler viewPortHandler, XAxis xAxis, Transformer trans) { + super(viewPortHandler, xAxis, trans); + } + + @Override + protected void drawLabel(Canvas c, String formattedLabel, float x, float y, MPPointF anchor, float angleDegrees) { + String[] line = formattedLabel.split("\n"); + Utils.drawXAxisValue(c, line[0], x, y, mAxisLabelPaint, anchor, angleDegrees); + Utils.drawXAxisValue(c, line[1], x + mAxisLabelPaint.getTextSize(), y + mAxisLabelPaint.getTextSize(), mAxisLabelPaint, anchor, angleDegrees); + } + } +} diff --git a/app/src/main/java/app/fedilab/android/mastodon/client/entities/app/StatusCache.java b/app/src/main/java/app/fedilab/android/mastodon/client/entities/app/StatusCache.java index 5c7f3be2..1f1c004b 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/client/entities/app/StatusCache.java +++ b/app/src/main/java/app/fedilab/android/mastodon/client/entities/app/StatusCache.java @@ -229,6 +229,28 @@ public class StatusCache { return count; } + /** + * get all cache messages for home + * + * @param baseAccount Status {@link BaseAccount} + * @return List + * @throws DBException Exception + */ + public List getHome(BaseAccount baseAccount) throws DBException { + if (db == null) { + throw new DBException("db is null. Wrong initialization."); + } + String selection = Sqlite.COL_INSTANCE + "='" + baseAccount.instance + "' AND " + Sqlite.COL_USER_ID + "= '" + baseAccount.user_id + "' AND " + Sqlite.COL_SLUG + "= '" + Timeline.TimeLineEnum.HOME.getValue() + "' "; + try { + Cursor c = db.query(Sqlite.TABLE_STATUS_CACHE, null, selection, null, Sqlite.COL_STATUS_ID, null, Sqlite.COL_STATUS_ID + " ASC", null); + return cursorToListOfStatuses(c); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** * count messages for other timelines * diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentHomeCacheSettings.java b/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentHomeCacheSettings.java index 7cd2591b..9d05f83f 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentHomeCacheSettings.java +++ b/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentHomeCacheSettings.java @@ -15,10 +15,12 @@ package app.fedilab.android.mastodon.ui.fragment.settings; * see . */ +import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import androidx.preference.ListPreference; +import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; @@ -29,6 +31,7 @@ import androidx.work.WorkManager; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.R; import app.fedilab.android.activities.MainActivity; +import app.fedilab.android.mastodon.activities.CheckHomeCacheActivity; import app.fedilab.android.mastodon.helper.Helper; import app.fedilab.android.mastodon.jobs.FetchHomeWorker; import es.dmoral.toasty.Toasty; @@ -65,6 +68,15 @@ public class FragmentHomeCacheSettings extends PreferenceFragmentCompat implemen String timeRefresh = sharedpreferences.getString(getString(R.string.SET_FETCH_HOME_DELAY_VALUE) + MainActivity.currentUserID + MainActivity.currentInstance, "60"); SET_FETCH_HOME_DELAY_VALUE.setValue(timeRefresh); } + + + Preference pref_category_show_data = findPreference(getString(R.string.pref_category_show_data)); + if (pref_category_show_data != null) { + pref_category_show_data.setOnPreferenceClickListener(preference -> { + startActivity(new Intent(requireActivity(), CheckHomeCacheActivity.class)); + return false; + }); + } } diff --git a/app/src/main/res/layouts/mastodon/drawable/baseline_show_chart_24.xml b/app/src/main/res/layouts/mastodon/drawable/baseline_show_chart_24.xml new file mode 100644 index 00000000..248f8f5e --- /dev/null +++ b/app/src/main/res/layouts/mastodon/drawable/baseline_show_chart_24.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/layouts/mastodon/layout/activity_check_home_cachet.xml b/app/src/main/res/layouts/mastodon/layout/activity_check_home_cachet.xml new file mode 100644 index 00000000..a0a27860 --- /dev/null +++ b/app/src/main/res/layouts/mastodon/layout/activity_check_home_cachet.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7e93455e..8267c0c2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1645,6 +1645,8 @@ u+1f6a9 pref_category_account + pref_category_show_data + pref_category_timeline pref_category_notifications pref_category_interface @@ -1927,4 +1929,6 @@ Send anyway Ignore battery optimizations Autoplay animated media + No Home cached messages! + Check Home cache \ No newline at end of file diff --git a/app/src/main/res/xml/pref_home_cache.xml b/app/src/main/res/xml/pref_home_cache.xml index 0cd45df4..5bd761dc 100644 --- a/app/src/main/res/xml/pref_home_cache.xml +++ b/app/src/main/res/xml/pref_home_cache.xml @@ -23,4 +23,11 @@ app:title="@string/type_of_home_delay_title" app:useSimpleSummaryProvider="true" /> + \ No newline at end of file