From 64ab2c122270c9fe3d505896244cb3e72a08cd2b Mon Sep 17 00:00:00 2001 From: Katie Dektar Date: Thu, 27 Feb 2025 21:51:13 -0800 Subject: [PATCH 1/3] Stats page improvements * Show graph only after a few days of calls have happened * Show top issues before contacts * Don't share graph if there isn't one --- .../a5calls/controller/StatsActivity.java | 71 ++++++++++++------- .../src/main/res/layout/activity_stats.xml | 20 ++++++ ...ct_stat_textview.xml => stat_textview.xml} | 0 5calls/app/src/main/res/values/strings.xml | 8 ++- 5calls/app/src/main/res/values/styles.xml | 5 +- 5 files changed, 75 insertions(+), 29 deletions(-) rename 5calls/app/src/main/res/layout/{contact_stat_textview.xml => stat_textview.xml} (100%) diff --git a/5calls/app/src/main/java/org/a5calls/android/a5calls/controller/StatsActivity.java b/5calls/app/src/main/java/org/a5calls/android/a5calls/controller/StatsActivity.java index 1720072..c7caac9 100644 --- a/5calls/app/src/main/java/org/a5calls/android/a5calls/controller/StatsActivity.java +++ b/5calls/app/src/main/java/org/a5calls/android/a5calls/controller/StatsActivity.java @@ -54,6 +54,8 @@ public class StatsActivity extends AppCompatActivity { private static final String TAG = "StatsActivity"; private static final int NUM_CONTACTS_TO_SHOW = 3; + private static final int NUM_ISSUES_TO_SHOW = 5; + private static final long MIN_DAYS_FOR_LINE_GRAPH = 3; private SimpleDateFormat dateFormat; private int mCallCount = 0; private ShareActionProvider mShareActionProvider; @@ -85,6 +87,7 @@ private void initializeUI(DatabaseHelper db) { // Show a "no impact yet!" message. binding.noCallsMessage.setVisibility(View.VISIBLE); binding.statsHolder.setVisibility(View.GONE); + binding.lineChart.setVisibility(View.GONE); return; } @@ -111,48 +114,64 @@ private void initializeUI(DatabaseHelper db) { LayoutInflater inflater = LayoutInflater.from(this); String callFormatString = getResources().getString(R.string.contact_call_stat); String callFormatStringOne = getResources().getString(R.string.contact_call_stat_one); - int numToShow = Math.min(NUM_CONTACTS_TO_SHOW, contactStats.size()); - for (int i = 0; i < numToShow; i++) { - String name = db.getContactName(contactStats.get(i).first); + int numContactsShown = 0; + for (Pair contactStat : contactStats) { + String name = db.getContactName(contactStat.first); if (TextUtils.isEmpty(name)) { name = getResources().getString(R.string.unknown_contact); } - TextView contactStat = (TextView) inflater.inflate(R.layout.contact_stat_textview, + TextView contactStatView = (TextView) inflater.inflate(R.layout.stat_textview, null); - binding.statsHolder.addView(contactStat); - contactStat.setText(contactStats.get(i).second == 1 ? + binding.repStats.addView(contactStatView); + contactStatView.setText(contactStat.second == 1 ? String.format(callFormatStringOne, name) : - String.format(callFormatString, contactStats.get(i).second, name)); + String.format(callFormatString, contactStat.second, name)); + numContactsShown++; + if (numContactsShown >= NUM_CONTACTS_TO_SHOW) { + break; + } } - /* - // Listing issues called doesn't seem so useful since most people will make 1-3 calls per - // issue to the same set of contacts. - // Can add this in later if there is need. List> issueStats = db.getCallCountsByIssue(); - for (int i = 0; i < issueStats.size(); i++) { - String name = db.getIssueName(issueStats.get(i).first); + int numIssuesShown = 0; + for (Pair issueStat : issueStats) { + String name = db.getIssueName(issueStat.first); if (TextUtils.isEmpty(name)) { name = getResources().getString(R.string.unknown_issue); } - Log.d(TAG, name + " had " + issueStats.get(i).second + " calls"); + TextView issueStatView = (TextView) inflater.inflate(R.layout.stat_textview, + null); + binding.callStats.addView(issueStatView); + issueStatView.setText(issueStat.second == 1 ? + String.format(callFormatStringOne, name) : + String.format(callFormatString, issueStat.second, name)); + numIssuesShown++; + if (numIssuesShown >= NUM_ISSUES_TO_SHOW) { + break; + } } - */ // Find first time when user made any call. long firstTimestamp = Long.MAX_VALUE; - if (contacts.size() > 0) { + long lastTimestamp = Long.MIN_VALUE; + if (!contacts.isEmpty()) { firstTimestamp = Math.min(firstTimestamp, contacts.get(0)); + lastTimestamp = Math.max(lastTimestamp, contacts.get(contacts.size() - 1)); } - if (voicemails.size() > 0) { + if (!voicemails.isEmpty()) { firstTimestamp = Math.min(firstTimestamp, voicemails.get(0)); + lastTimestamp = Math.max(lastTimestamp, voicemails.get(voicemails.size() - 1)); } - if (unavailables.size() > 0) { + if (!unavailables.isEmpty()) { firstTimestamp = Math.min(firstTimestamp, unavailables.get(0)); + lastTimestamp = Math.max(lastTimestamp, unavailables.get(unavailables.size() - 1)); } createPieChart(contacts, voicemails, unavailables, firstTimestamp); - createLineGraph(contacts, voicemails, unavailables, firstTimestamp); + + if (lastTimestamp - firstTimestamp > MIN_DAYS_FOR_LINE_GRAPH * 24 * 60 * 60 * 1000) { + createLineGraph(contacts, voicemails, unavailables, firstTimestamp); + } // Show the share button. invalidateOptionsMenu(); @@ -219,6 +238,8 @@ private void createPieChart(List contacts, List voicemails, List contacts, List voicemails, List unavailables, long firstTimestamp) { + binding.lineChart.setVisibility(View.VISIBLE); + binding.lineChartTitle.setVisibility(View.VISIBLE); LineGraphSeries contactedSeries = makeSeries(contacts, firstTimestamp, R.color.contacted_color); contactedSeries.setTitle(getResources().getString(R.string.outcome_contact)); @@ -306,21 +327,19 @@ public boolean onOptionsItemSelected(MenuItem item) { } private void sendShare() { - Uri imageUri = saveGraphImage(); Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); shareIntent.putExtra(Intent.EXTRA_SUBJECT, getResources().getString( R.string.share_subject)); shareIntent.putExtra(Intent.EXTRA_TEXT, String.format(getResources().getString(R.string.share_content), mCallCount)); - shareIntent.setDataAndType(imageUri, "image/png"); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - // Needed to avoid security exception on KitKat. - shareIntent.setClipData(ClipData.newRawUri(null, imageUri)); + if (binding.lineChart.getVisibility() == View.VISIBLE) { + Uri imageUri = saveGraphImage(); + shareIntent.setDataAndType(imageUri, "image/png"); + shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } - shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri); - shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(Intent.createChooser(shareIntent, getResources().getString(R.string.share_chooser_title))); diff --git a/5calls/app/src/main/res/layout/activity_stats.xml b/5calls/app/src/main/res/layout/activity_stats.xml index 1adad0f..23812c6 100644 --- a/5calls/app/src/main/res/layout/activity_stats.xml +++ b/5calls/app/src/main/res/layout/activity_stats.xml @@ -44,18 +44,38 @@ + + + + + + + + diff --git a/5calls/app/src/main/res/layout/contact_stat_textview.xml b/5calls/app/src/main/res/layout/stat_textview.xml similarity index 100% rename from 5calls/app/src/main/res/layout/contact_stat_textview.xml rename to 5calls/app/src/main/res/layout/stat_textview.xml diff --git a/5calls/app/src/main/res/values/strings.xml b/5calls/app/src/main/res/values/strings.xml index 8bbb61a..0d9dc30 100644 --- a/5calls/app/src/main/res/values/strings.xml +++ b/5calls/app/src/main/res/values/strings.xml @@ -235,8 +235,11 @@ Unknown location - - Your most contacted representatives are: + + Your most called representatives are: + + + Your top issues are: %1$d calls: %2$s @@ -634,4 +637,5 @@ %1$s is from %2$s. + diff --git a/5calls/app/src/main/res/values/styles.xml b/5calls/app/src/main/res/values/styles.xml index 4276095..c588e63 100644 --- a/5calls/app/src/main/res/values/styles.xml +++ b/5calls/app/src/main/res/values/styles.xml @@ -677,10 +677,13 @@ vertical - + +