From daf4e5aca2d4162679d2fda4115a9e6f41970a38 Mon Sep 17 00:00:00 2001 From: Javi Rueda Date: Wed, 9 Dec 2020 20:54:02 +0100 Subject: [PATCH 1/5] Use ListView to show startup stage errors --- .../java/io/lbry/browser/MainActivity.java | 63 +++---- .../browser/adapter/StartupStageAdapter.java | 68 +++++++ .../io/lbry/browser/model/StartupStage.java | 11 ++ app/src/main/res/layout/app_bar_main.xml | 169 +----------------- .../res/layout/list_item_startupstage.xml | 25 +++ 5 files changed, 137 insertions(+), 199 deletions(-) create mode 100644 app/src/main/java/io/lbry/browser/adapter/StartupStageAdapter.java create mode 100644 app/src/main/java/io/lbry/browser/model/StartupStage.java create mode 100644 app/src/main/res/layout/list_item_startupstage.xml diff --git a/app/src/main/java/io/lbry/browser/MainActivity.java b/app/src/main/java/io/lbry/browser/MainActivity.java index ee95dd5c..39ec4a90 100644 --- a/app/src/main/java/io/lbry/browser/MainActivity.java +++ b/app/src/main/java/io/lbry/browser/MainActivity.java @@ -46,6 +46,7 @@ import android.view.inputmethod.InputMethodManager; import android.webkit.WebView; import android.widget.EditText; import android.widget.ImageView; +import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; @@ -136,6 +137,7 @@ import javax.net.ssl.SSLParameters; import io.lbry.browser.adapter.NavigationMenuAdapter; import io.lbry.browser.adapter.NotificationListAdapter; +import io.lbry.browser.adapter.StartupStageAdapter; import io.lbry.browser.adapter.UrlSuggestionListAdapter; import io.lbry.browser.data.DatabaseHelper; import io.lbry.browser.dialog.ContentScopeDialogFragment; @@ -155,6 +157,7 @@ import io.lbry.browser.listener.WalletBalanceListener; import io.lbry.browser.model.Claim; import io.lbry.browser.model.ClaimCacheKey; import io.lbry.browser.model.NavMenuItem; +import io.lbry.browser.model.StartupStage; import io.lbry.browser.model.Tag; import io.lbry.browser.model.UrlSuggestion; import io.lbry.browser.model.WalletBalance; @@ -2742,22 +2745,10 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener actionBar.show(); } } - private void renderStartupFailed(Map startupStages) { - Map startupStageIconIds = new HashMap<>(); - startupStageIconIds.put(STARTUP_STAGE_INSTALL_ID_LOADED, R.id.startup_stage_icon_install_id); - startupStageIconIds.put(STARTUP_STAGE_KNOWN_TAGS_LOADED, R.id.startup_stage_icon_known_tags); - startupStageIconIds.put(STARTUP_STAGE_EXCHANGE_RATE_LOADED, R.id.startup_stage_icon_exchange_rate); - startupStageIconIds.put(STARTUP_STAGE_USER_AUTHENTICATED, R.id.startup_stage_icon_user_authenticated); - startupStageIconIds.put(STARTUP_STAGE_NEW_INSTALL_DONE, R.id.startup_stage_icon_install_new); - startupStageIconIds.put(STARTUP_STAGE_SUBSCRIPTIONS_LOADED, R.id.startup_stage_icon_subscriptions_loaded); - startupStageIconIds.put(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED, R.id.startup_stage_icon_subscriptions_resolved); - - for (Integer key : startupStages.keySet()) { - boolean stageDone = startupStages.get(key); - ImageView icon = findViewById(startupStageIconIds.get(key)); - icon.setImageResource(stageDone ? R.drawable.ic_check : R.drawable.ic_close); - icon.setColorFilter(stageDone ? Color.WHITE : Color.RED); - } + private void renderStartupFailed(List startupStages) { + ListView listView = findViewById(R.id.startup_stage_error_listview); + StartupStageAdapter adapter = new StartupStageAdapter(this, startupStages); + listView.setAdapter(adapter); findViewById(R.id.splash_view_loading_container).setVisibility(View.GONE); findViewById(R.id.splash_view_error_container).setVisibility(View.VISIBLE); @@ -2770,16 +2761,16 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener // perform some tasks before launching (new AsyncTask() { - private Map startupStages = new HashMap<>(); + private final List startupStages = new ArrayList<>(7); private void initStartupStages() { - startupStages.put(STARTUP_STAGE_INSTALL_ID_LOADED, false); - startupStages.put(STARTUP_STAGE_KNOWN_TAGS_LOADED, false); - startupStages.put(STARTUP_STAGE_EXCHANGE_RATE_LOADED, false); - startupStages.put(STARTUP_STAGE_USER_AUTHENTICATED, false); - startupStages.put(STARTUP_STAGE_NEW_INSTALL_DONE, false); - startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_LOADED, false); - startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED, false); + startupStages.add(new StartupStage(STARTUP_STAGE_INSTALL_ID_LOADED, false)); + startupStages.add(new StartupStage(STARTUP_STAGE_KNOWN_TAGS_LOADED, false)); + startupStages.add(new StartupStage(STARTUP_STAGE_EXCHANGE_RATE_LOADED, false)); + startupStages.add(new StartupStage(STARTUP_STAGE_USER_AUTHENTICATED, false)); + startupStages.add(new StartupStage(STARTUP_STAGE_NEW_INSTALL_DONE, false)); + startupStages.add(new StartupStage(STARTUP_STAGE_SUBSCRIPTIONS_LOADED, false)); + startupStages.add(new StartupStage(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED, false)); } protected void onPreExecute() { hideActionBar(); @@ -2799,26 +2790,26 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener String installId = reader.readLine(); if (Helper.isNullOrEmpty(installId)) { // no install_id found (first run didn't start the sdk successfully?) - startupStages.put(STARTUP_STAGE_INSTALL_ID_LOADED, false); + startupStages.set(STARTUP_STAGE_INSTALL_ID_LOADED - 1, new StartupStage(STARTUP_STAGE_INSTALL_ID_LOADED, false)); return false; } Lbry.INSTALLATION_ID = installId; - startupStages.put(STARTUP_STAGE_INSTALL_ID_LOADED, true); + startupStages.set(STARTUP_STAGE_INSTALL_ID_LOADED - 1, new StartupStage(STARTUP_STAGE_INSTALL_ID_LOADED, true)); SQLiteDatabase db = dbHelper.getReadableDatabase(); List fetchedTags = DatabaseHelper.getTags(db); Lbry.knownTags = Helper.mergeKnownTags(fetchedTags); Collections.sort(Lbry.knownTags, new Tag()); Lbry.followedTags = Helper.filterFollowedTags(Lbry.knownTags); - startupStages.put(STARTUP_STAGE_KNOWN_TAGS_LOADED, true); + startupStages.set(STARTUP_STAGE_KNOWN_TAGS_LOADED - 1, new StartupStage(STARTUP_STAGE_KNOWN_TAGS_LOADED, true)); // load the exchange rate Lbryio.loadExchangeRate(); if (Lbryio.LBCUSDRate == 0) { return false; } - startupStages.put(STARTUP_STAGE_EXCHANGE_RATE_LOADED, true); + startupStages.set(STARTUP_STAGE_EXCHANGE_RATE_LOADED - 1, new StartupStage(STARTUP_STAGE_EXCHANGE_RATE_LOADED, true)); try { Lbryio.authenticate(context); @@ -2830,10 +2821,10 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener if (Lbryio.currentUser == null) { throw new Exception("Did not retrieve authenticated user."); } - startupStages.put(STARTUP_STAGE_USER_AUTHENTICATED, true); + startupStages.set(STARTUP_STAGE_USER_AUTHENTICATED - 1, new StartupStage(STARTUP_STAGE_USER_AUTHENTICATED, true)); Lbryio.newInstall(context); - startupStages.put(STARTUP_STAGE_NEW_INSTALL_DONE, true); + startupStages.set(STARTUP_STAGE_NEW_INSTALL_DONE - 1, new StartupStage(STARTUP_STAGE_NEW_INSTALL_DONE, true)); // (light) fetch subscriptions if (Lbryio.subscriptions.size() == 0) { @@ -2854,7 +2845,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener subUrls.add(url.toString()); } Lbryio.subscriptions = subscriptions; - startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_LOADED, true); + startupStages.set(STARTUP_STAGE_SUBSCRIPTIONS_LOADED - 1, new StartupStage(STARTUP_STAGE_SUBSCRIPTIONS_LOADED, true)); // resolve subscriptions if (subUrls.size() > 0 && Lbryio.cacheResolvedSubscriptions.size() != Lbryio.subscriptions.size()) { @@ -2862,15 +2853,15 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener Lbryio.cacheResolvedSubscriptions = resolvedSubs; } // if no exceptions occurred here, subscriptions have been loaded and resolved - startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED, true); + startupStages.set(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED - 1, new StartupStage(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED, true)); } else { // user has not subscribed to anything - startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_LOADED, true); - startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED, true); + startupStages.set(STARTUP_STAGE_SUBSCRIPTIONS_LOADED - 1, new StartupStage(STARTUP_STAGE_SUBSCRIPTIONS_LOADED, true)); + startupStages.set(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED - 1, new StartupStage(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED, true)); } } else { - startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_LOADED, true); - startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED, true); + startupStages.set(STARTUP_STAGE_SUBSCRIPTIONS_LOADED - 1, new StartupStage(STARTUP_STAGE_SUBSCRIPTIONS_LOADED, true)); + startupStages.set(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED - 1, new StartupStage(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED, true)); } } catch (Exception ex) { // nopecd diff --git a/app/src/main/java/io/lbry/browser/adapter/StartupStageAdapter.java b/app/src/main/java/io/lbry/browser/adapter/StartupStageAdapter.java new file mode 100644 index 00000000..b270991a --- /dev/null +++ b/app/src/main/java/io/lbry/browser/adapter/StartupStageAdapter.java @@ -0,0 +1,68 @@ +package io.lbry.browser.adapter; + +import android.content.Context; +import android.graphics.Color; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import java.util.List; + +import io.lbry.browser.R; +import io.lbry.browser.model.StartupStage; + +public class StartupStageAdapter extends BaseAdapter { + private final List list; + private final LayoutInflater inflater; + private final String[] stagesString; + + public StartupStageAdapter(Context ctx, List rows) { + this.list = rows; + this.inflater = LayoutInflater.from(ctx); + + stagesString = new String[7]; + + stagesString[0] = ctx.getResources().getString(R.string.installation_id_loaded); + stagesString[1] = ctx.getResources().getString(R.string.known_tags_loaded); + stagesString[2] = ctx.getResources().getString(R.string.exchange_rate_loaded); + stagesString[3] = ctx.getResources().getString(R.string.user_authenticated); + stagesString[4] = ctx.getResources().getString(R.string.installation_registered); + stagesString[5] = ctx.getResources().getString(R.string.subscriptions_loaded); + stagesString[6] = ctx.getResources().getString(R.string.subscriptions_resolved); + } + @Override + public int getCount() { + return list.size(); + } + + @Override + public Object getItem(int i) { + return list.get(i); + } + + @Override + public long getItemId(int i) { + return i; + } + + @Override + public View getView(int i, View view, ViewGroup viewGroup) { + if (view == null) { + view = inflater.inflate(R.layout.list_item_startupstage, viewGroup, false); + + ImageView iconView = view.findViewById(R.id.startup_stage_icon); + TextView textView = view.findViewById(R.id.startup_stage_text); + + StartupStage item = (StartupStage) getItem(i); + + iconView.setImageResource(item.stageDone ? R.drawable.ic_check : R.drawable.ic_close); + iconView.setColorFilter(item.stageDone ? Color.WHITE : Color.RED); + + textView.setText(stagesString[item.stage - 1]); + } + return view; + } +} diff --git a/app/src/main/java/io/lbry/browser/model/StartupStage.java b/app/src/main/java/io/lbry/browser/model/StartupStage.java new file mode 100644 index 00000000..955d239a --- /dev/null +++ b/app/src/main/java/io/lbry/browser/model/StartupStage.java @@ -0,0 +1,11 @@ +package io.lbry.browser.model; + +public class StartupStage { + public Integer stage; + public Boolean stageDone; + + public StartupStage(Integer stage, Boolean stageDone) { + this.stage = stage; + this.stageDone = stageDone; + } +} diff --git a/app/src/main/res/layout/app_bar_main.xml b/app/src/main/res/layout/app_bar_main.xml index 9a782b3d..a27be78f 100644 --- a/app/src/main/res/layout/app_bar_main.xml +++ b/app/src/main/res/layout/app_bar_main.xml @@ -156,173 +156,16 @@ android:textColor="@color/white" android:textFontWeight="300" android:textSize="14sp" /> - - - - + android:divider="@android:color/transparent" + android:dividerHeight="8dp" + tools:listitem="@layout/list_item_startupstage"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/app/src/main/res/layout/list_item_startupstage.xml b/app/src/main/res/layout/list_item_startupstage.xml new file mode 100644 index 00000000..331f21ed --- /dev/null +++ b/app/src/main/res/layout/list_item_startupstage.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file -- 2.45.3 From b2f5fec2932a90e282416ab9e9f6c5acb7452363 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Thu, 10 Dec 2020 09:57:27 +0100 Subject: [PATCH 2/5] make the channel filter name alphabet uppercase --- .../java/io/lbry/browser/adapter/ChannelFilterListAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/lbry/browser/adapter/ChannelFilterListAdapter.java b/app/src/main/java/io/lbry/browser/adapter/ChannelFilterListAdapter.java index a4b0873d..63e1f406 100644 --- a/app/src/main/java/io/lbry/browser/adapter/ChannelFilterListAdapter.java +++ b/app/src/main/java/io/lbry/browser/adapter/ChannelFilterListAdapter.java @@ -101,7 +101,7 @@ public class ChannelFilterListAdapter extends RecyclerView.Adapter Date: Sun, 13 Dec 2020 18:07:19 +0100 Subject: [PATCH 3/5] fix crash error when following doesn't exist in shared user state --- .../io/lbry/browser/tasks/wallet/LoadSharedUserStateTask.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/io/lbry/browser/tasks/wallet/LoadSharedUserStateTask.java b/app/src/main/java/io/lbry/browser/tasks/wallet/LoadSharedUserStateTask.java index 0bf93baa..323a1949 100644 --- a/app/src/main/java/io/lbry/browser/tasks/wallet/LoadSharedUserStateTask.java +++ b/app/src/main/java/io/lbry/browser/tasks/wallet/LoadSharedUserStateTask.java @@ -130,6 +130,10 @@ public class LoadSharedUserStateTask extends AsyncTask { } protected boolean isNotificationsDisabledForSubUrl(String url, JSONArray following) { + if (following == null) { + return true; + } + try { for (int i = 0; i < following.length(); i++) { JSONObject item = following.getJSONObject(i); -- 2.45.3 From a9aadbe6a89f0ef130e268404ac62071f4c23924 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Sun, 13 Dec 2020 18:08:10 +0100 Subject: [PATCH 4/5] bumpversion 0.16.10 --> 0.16.11 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 16350e27..9eb6f46c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId "io.lbry.browser" minSdkVersion 21 targetSdkVersion 29 - versionCode 1610 - versionName "0.16.10" + versionCode 1611 + versionName "0.16.11" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } -- 2.45.3 From 601031e55d6f0bcb6b75e17150dd166e1c539e04 Mon Sep 17 00:00:00 2001 From: Javi Rueda Date: Mon, 14 Dec 2020 18:17:13 +0100 Subject: [PATCH 5/5] Replace Hex class from GMS with the one from Apache --- app/build.gradle | 1 + app/src/main/java/io/lbry/browser/utils/Helper.java | 11 +++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 16350e27..58922d5b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -119,6 +119,7 @@ dependencies { implementation 'com.arthenica:mobile-ffmpeg-full-gpl:4.3.1.LTS' + implementation 'commons-codec:commons-codec:1.15' implementation 'org.bitcoinj:bitcoinj-tools:0.14.7' implementation 'org.java-websocket:Java-WebSocket:1.5.1' diff --git a/app/src/main/java/io/lbry/browser/utils/Helper.java b/app/src/main/java/io/lbry/browser/utils/Helper.java index 6d6a3862..73bfa10f 100644 --- a/app/src/main/java/io/lbry/browser/utils/Helper.java +++ b/app/src/main/java/io/lbry/browser/utils/Helper.java @@ -29,9 +29,8 @@ import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import com.google.android.gms.common.util.Hex; +import org.apache.commons.codec.binary.Hex; -import org.bitcoinj.core.Base58; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -39,7 +38,7 @@ import org.json.JSONObject; import java.io.Closeable; import java.io.File; import java.io.IOException; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.DecimalFormat; @@ -795,9 +794,9 @@ public final class Helper { public static String SHA256(String value) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); - byte[] hash = digest.digest(value.getBytes("UTF-8")); - return Hex.bytesToStringLowercase(hash); - } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) { + byte[] hash = digest.digest(value.getBytes(StandardCharsets.UTF_8)); + return Hex.encodeHexString(hash, true); + } catch (NoSuchAlgorithmException ex) { return null; } } -- 2.45.3