Merge pull request #888 from lbryio/unlock-tips

add option to unlock all tips
This commit is contained in:
Akinwale Ariwodola 2020-05-23 23:39:16 +01:00 committed by GitHub
commit 20f8f3852d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 228 additions and 17 deletions

View file

@ -66,7 +66,6 @@ import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import androidx.core.content.res.ResourcesCompat; import androidx.core.content.res.ResourcesCompat;
import androidx.core.graphics.TypefaceCompat;
import androidx.core.graphics.drawable.DrawableCompat; import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.view.GravityCompat; import androidx.core.view.GravityCompat;
import androidx.core.view.OnApplyWindowInsetsListener; import androidx.core.view.OnApplyWindowInsetsListener;
@ -129,6 +128,7 @@ import io.lbry.browser.model.WalletBalance;
import io.lbry.browser.model.WalletSync; import io.lbry.browser.model.WalletSync;
import io.lbry.browser.model.lbryinc.Reward; import io.lbry.browser.model.lbryinc.Reward;
import io.lbry.browser.model.lbryinc.Subscription; import io.lbry.browser.model.lbryinc.Subscription;
import io.lbry.browser.tasks.GenericTaskHandler;
import io.lbry.browser.tasks.claim.ClaimListResultHandler; import io.lbry.browser.tasks.claim.ClaimListResultHandler;
import io.lbry.browser.tasks.claim.ClaimListTask; import io.lbry.browser.tasks.claim.ClaimListTask;
import io.lbry.browser.tasks.lbryinc.ClaimRewardTask; import io.lbry.browser.tasks.lbryinc.ClaimRewardTask;
@ -143,6 +143,7 @@ import io.lbry.browser.tasks.wallet.SaveSharedUserStateTask;
import io.lbry.browser.tasks.wallet.SyncApplyTask; import io.lbry.browser.tasks.wallet.SyncApplyTask;
import io.lbry.browser.tasks.wallet.SyncGetTask; import io.lbry.browser.tasks.wallet.SyncGetTask;
import io.lbry.browser.tasks.wallet.SyncSetTask; import io.lbry.browser.tasks.wallet.SyncSetTask;
import io.lbry.browser.tasks.wallet.UnlockTipsTask;
import io.lbry.browser.tasks.wallet.WalletBalanceTask; import io.lbry.browser.tasks.wallet.WalletBalanceTask;
import io.lbry.browser.ui.BaseFragment; import io.lbry.browser.ui.BaseFragment;
import io.lbry.browser.ui.channel.ChannelFormFragment; import io.lbry.browser.ui.channel.ChannelFormFragment;
@ -182,6 +183,10 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
private boolean inPictureInPictureMode; private boolean inPictureInPictureMode;
@Getter @Getter
private boolean inFullscreenMode; private boolean inFullscreenMode;
// make tip unlock a global operation
@Getter
private boolean unlockingTips;
public static SimpleExoPlayer appPlayer; public static SimpleExoPlayer appPlayer;
public static Cache playerCache; public static Cache playerCache;
public static boolean playerReassigned; public static boolean playerReassigned;
@ -2812,6 +2817,41 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
public void unlockTips() {
if (unlockingTips) {
return;
}
UnlockTipsTask task = new UnlockTipsTask(new GenericTaskHandler() {
@Override
public void beforeStart() {
unlockingTips = true;
}
@Override
public void onSuccess() {
unlockingTips = false;
for (Fragment fragment : openNavFragments.values()) {
if (fragment instanceof WalletFragment) {
((WalletFragment) fragment).checkTips(true);
}
}
}
@Override
public void onError(Exception error) {
unlockingTips = false;
for (Fragment fragment : openNavFragments.values()) {
if (fragment instanceof WalletFragment) {
((WalletFragment) fragment).checkTips();
}
}
// fail silently?
//showError(error.getMessage());
}
});
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private void checkSyncedWallet() { private void checkSyncedWallet() {
String password = Utils.getSecureValue(SECURE_VALUE_KEY_SAVED_PASSWORD, this, Lbry.KEYSTORE); String password = Utils.getSecureValue(SECURE_VALUE_KEY_SAVED_PASSWORD, this, Lbry.KEYSTORE);
// Just check if the current user has a synced wallet, no need to do anything else here // Just check if the current user has a synced wallet, no need to do anything else here

View file

@ -1,7 +1,10 @@
package io.lbry.browser.model; package io.lbry.browser.model;
import org.json.JSONObject;
import java.math.BigDecimal; import java.math.BigDecimal;
import io.lbry.browser.utils.Helper;
import lombok.Data; import lombok.Data;
@Data @Data
@ -21,4 +24,18 @@ public class WalletBalance {
tips = new BigDecimal(0); tips = new BigDecimal(0);
total = new BigDecimal(0); total = new BigDecimal(0);
} }
public static WalletBalance fromJSONObject(JSONObject json) {
WalletBalance balance = new WalletBalance();
JSONObject reservedSubtotals = Helper.getJSONObject("reserved_subtotals", json);
balance.setAvailable(new BigDecimal(Helper.getJSONString("available", "0", json)));
balance.setReserved(new BigDecimal(Helper.getJSONString("reserved", "0", json)));
balance.setTotal(new BigDecimal(Helper.getJSONString("total", "0", json)));
if (reservedSubtotals != null) {
balance.setClaims(new BigDecimal(Helper.getJSONString("claims", "0", reservedSubtotals)));
balance.setSupports(new BigDecimal(Helper.getJSONString("supports", "0", reservedSubtotals)));
balance.setTips(new BigDecimal(Helper.getJSONString("tips", "0", reservedSubtotals)));
}
return balance;
}
} }

View file

@ -0,0 +1,76 @@
package io.lbry.browser.tasks.wallet;
import android.os.AsyncTask;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.lbry.browser.exceptions.ApiCallException;
import io.lbry.browser.model.WalletBalance;
import io.lbry.browser.tasks.GenericTaskHandler;
import io.lbry.browser.utils.Helper;
import io.lbry.browser.utils.Lbry;
public class UnlockTipsTask extends AsyncTask<Void, Void, Boolean> {
private GenericTaskHandler handler;
private Exception error;
public UnlockTipsTask(GenericTaskHandler handler) {
this.handler = handler;
}
public Boolean doInBackground(Void... params) {
List<String> txids = new ArrayList<>();
List<String> claimIds = new ArrayList<>();
try {
Map<String, Object> options = new HashMap<>();
options.put("type", "support");
options.put("is_not_my_input", true);
options.put("is_my_output", true);
JSONObject result = (JSONObject) Lbry.genericApiCall(Lbry.METHOD_TXO_LIST, options);
if (result.has("items") && !result.isNull("items")) {
JSONArray items = result.getJSONArray("items");
for (int i = 0; i < items.length(); i++) {
JSONObject item = items.getJSONObject(i);
String txid = Helper.getJSONString("txid", null, item);
String claimId = Helper.getJSONString("claim_id", null, item);
if (!Helper.isNullOrEmpty(txid) && !Helper.isNullOrEmpty(claimId)) {
txids.add(txid);
claimIds.add(claimId);
}
}
}
if (txids.size() > 0 && txids.size() == claimIds.size()) {
options = new HashMap<>();
options.put("txid", txids);
options.put("claim_id", claimIds);
Lbry.genericApiCall(Lbry.METHOD_TXO_SPEND, options);
}
return true;
} catch (ApiCallException | ClassCastException | JSONException ex) {
error = ex;
return false;
}
}
protected void onPostExecute(Boolean result) {
if (handler != null) {
if (result) {
handler.onSuccess();
} else {
handler.onError(error);
}
}
}
}

View file

@ -23,16 +23,7 @@ public class WalletBalanceTask extends AsyncTask<Void, Void, WalletBalance> {
WalletBalance balance = new WalletBalance(); WalletBalance balance = new WalletBalance();
try { try {
JSONObject json = (JSONObject) Lbry.genericApiCall(Lbry.METHOD_WALLET_BALANCE); JSONObject json = (JSONObject) Lbry.genericApiCall(Lbry.METHOD_WALLET_BALANCE);
JSONObject reservedSubtotals = Helper.getJSONObject("reserved_subtotals", json); balance = WalletBalance.fromJSONObject(json);
balance.setAvailable(new BigDecimal(Helper.getJSONString("available", "0", json)));
balance.setReserved(new BigDecimal(Helper.getJSONString("reserved", "0", json)));
balance.setTotal(new BigDecimal(Helper.getJSONString("total", "0", json)));
if (reservedSubtotals != null) {
balance.setClaims(new BigDecimal(Helper.getJSONString("claims", "0", reservedSubtotals)));
balance.setSupports(new BigDecimal(Helper.getJSONString("supports", "0", reservedSubtotals)));
balance.setTips(new BigDecimal(Helper.getJSONString("tips", "0", reservedSubtotals)));
}
} catch (ApiCallException | ClassCastException ex) { } catch (ApiCallException | ClassCastException ex) {
error = ex; error = ex;
return null; return null;

View file

@ -3,6 +3,7 @@ package io.lbry.browser.ui.wallet;
import android.content.ClipData; import android.content.ClipData;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Color; import android.graphics.Color;
import android.os.AsyncTask; import android.os.AsyncTask;
@ -17,6 +18,7 @@ import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.DividerItemDecoration;
@ -66,6 +68,9 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
private TextView textSupportsBalance; private TextView textSupportsBalance;
private ProgressBar walletSendProgress; private ProgressBar walletSendProgress;
private TextView linkUnlockTips;
private ProgressBar progressUnlockTips;
private View loadingRecentContainer; private View loadingRecentContainer;
private View inlineBalanceContainer; private View inlineBalanceContainer;
private TextView textWalletInlineBalance; private TextView textWalletInlineBalance;
@ -114,6 +119,9 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
textSupportsBalance = root.findViewById(R.id.wallet_balance_staked_supports); textSupportsBalance = root.findViewById(R.id.wallet_balance_staked_supports);
textWalletHintSyncStatus = root.findViewById(R.id.wallet_hint_sync_status); textWalletHintSyncStatus = root.findViewById(R.id.wallet_hint_sync_status);
linkUnlockTips = root.findViewById(R.id.wallet_unlock_tips_link);
progressUnlockTips = root.findViewById(R.id.wallet_unlock_tips_progress);
recentTransactionsList = root.findViewById(R.id.wallet_recent_transactions_list); recentTransactionsList = root.findViewById(R.id.wallet_recent_transactions_list);
linkViewAll = root.findViewById(R.id.wallet_link_view_all); linkViewAll = root.findViewById(R.id.wallet_link_view_all);
textNoRecentTransactions = root.findViewById(R.id.wallet_no_recent_transactions); textNoRecentTransactions = root.findViewById(R.id.wallet_no_recent_transactions);
@ -242,6 +250,24 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
itemDecoration.setDrawable(ContextCompat.getDrawable(context, R.drawable.thin_divider)); itemDecoration.setDrawable(ContextCompat.getDrawable(context, R.drawable.thin_divider));
recentTransactionsList.addItemDecoration(itemDecoration); recentTransactionsList.addItemDecoration(itemDecoration);
linkUnlockTips.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (context != null) {
AlertDialog.Builder builder = new AlertDialog.Builder(context).
setTitle(R.string.unlock_tips).
setMessage(R.string.confirm_unlock_tips)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
unlockTips();
}
}).setNegativeButton(R.string.no, null);
builder.show();
}
}
});
textEarnMoreTips.setOnClickListener(new View.OnClickListener() { textEarnMoreTips.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
@ -492,6 +518,7 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
checkReceiveAddress(); checkReceiveAddress();
checkRewardsDriver(); checkRewardsDriver();
checkTips();
fetchRecentTransactions(); fetchRecentTransactions();
} }
@ -535,9 +562,37 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
Helper.setViewText(textTipsBalanceUSD, String.format("≈$%s", Helper.SIMPLE_CURRENCY_FORMAT.format(tipsUsdBalance))); Helper.setViewText(textTipsBalanceUSD, String.format("≈$%s", Helper.SIMPLE_CURRENCY_FORMAT.format(tipsUsdBalance)));
} }
checkTips();
checkRewardsDriver(); checkRewardsDriver();
} }
private void unlockTips() {
Context context = getContext();
if (context instanceof MainActivity) {
linkUnlockTips.setVisibility(View.GONE);
progressUnlockTips.setVisibility(View.VISIBLE);
((MainActivity) context).unlockTips();
}
}
public void checkTips() {
checkTips(false);
}
public void checkTips(boolean forceHideLink) {
WalletBalance walletBalance = Lbry.walletBalance;
double tipBalance = walletBalance == null ? 0 : walletBalance.getTips().doubleValue();
boolean unlocking = false;
Context context = getContext();
if (context instanceof MainActivity) {
MainActivity activity = (MainActivity) context;
unlocking = activity.isUnlockingTips();
}
Helper.setViewVisibility(linkUnlockTips, !forceHideLink && tipBalance > 0 && !unlocking ? View.VISIBLE : View.GONE);
Helper.setViewVisibility(progressUnlockTips, unlocking ? View.VISIBLE : View.GONE);
}
private void checkRewardsDriver() { private void checkRewardsDriver() {
// check rewards driver // check rewards driver
Context ctx = getContext(); Context ctx = getContext();

View file

@ -88,6 +88,9 @@ public final class Lbry {
public static final String METHOD_PREFERENCE_GET = "preference_get"; public static final String METHOD_PREFERENCE_GET = "preference_get";
public static final String METHOD_PREFERENCE_SET = "preference_set"; public static final String METHOD_PREFERENCE_SET = "preference_set";
public static final String METHOD_TXO_LIST = "txo_list";
public static final String METHOD_TXO_SPEND = "txo_spend";
public static final String METHOD_CHANNEL_ABANDON = "channel_abandon"; public static final String METHOD_CHANNEL_ABANDON = "channel_abandon";
public static final String METHOD_CHANNEL_CREATE = "channel_create"; public static final String METHOD_CHANNEL_CREATE = "channel_create";
public static final String METHOD_CHANNEL_UPDATE = "channel_update"; public static final String METHOD_CHANNEL_UPDATE = "channel_update";

View file

@ -160,12 +160,41 @@
android:textFontWeight="300" android:textFontWeight="300"
android:textSize="14sp" /> android:textSize="14sp" />
<TextView <RelativeLayout
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="16dp">
android:fontFamily="@font/inter" <TextView
android:text="@string/in_tips" android:id="@+id/wallet_in_tips_label"
android:textSize="14sp" /> android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/inter"
android:text="@string/in_tips"
android:textSize="14sp" />
<TextView
android:id="@+id/wallet_unlock_tips_link"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/wallet_in_tips_label"
android:fontFamily="@font/inter"
android:layout_marginLeft="24dp"
android:text="@string/unlock"
android:textColor="@color/lbryGreen"
android:textSize="14sp"
android:visibility="gone" />
<ProgressBar
android:id="@+id/wallet_unlock_tips_progress"
android:layout_centerVertical="true"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginLeft="24dp"
android:layout_toRightOf="@id/wallet_in_tips_label"
android:visibility="gone" />
</RelativeLayout>
<TextView <TextView
android:id="@+id/wallet_hint_earn_more_tips" android:id="@+id/wallet_hint_earn_more_tips"