From 1cab87a43036ae76f9c2eb8931ff8c67d4b5d783 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Fri, 19 Jun 2020 07:12:06 +0100 Subject: [PATCH 1/7] fix subscriptions sync --- .../java/io/lbry/browser/MainActivity.java | 17 ++++++++--- .../io/lbry/browser/data/DatabaseHelper.java | 4 +++ .../browser/tasks/MergeSubscriptionsTask.java | 29 +++++++++++++------ 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/io/lbry/browser/MainActivity.java b/app/src/main/java/io/lbry/browser/MainActivity.java index 65809429..a31597de 100644 --- a/app/src/main/java/io/lbry/browser/MainActivity.java +++ b/app/src/main/java/io/lbry/browser/MainActivity.java @@ -47,9 +47,7 @@ import android.widget.TextView; import android.widget.Toast; import com.bumptech.glide.Glide; -import com.bumptech.glide.request.target.BitmapImageViewTarget; import com.bumptech.glide.request.target.CustomTarget; -import com.bumptech.glide.request.target.ImageViewTarget; import com.bumptech.glide.request.transition.Transition; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.SimpleExoPlayer; @@ -109,7 +107,6 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -296,6 +293,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener public static final String PREFERENCE_KEY_INTERNAL_WALLET_RECEIVE_ADDRESS = "io.lbry.browser.preference.internal.WalletReceiveAddress"; public static final String PREFERENCE_KEY_INTERNAL_REWARDS_NOT_INTERESTED = "io.lbry.browser.preference.internal.RewardsNotInterested"; public static final String PREFERENCE_KEY_INTERNAL_NEW_ANDROID_REWARD_CLAIMED = "io.lbry.browser.preference.internal.NewAndroidRewardClaimed"; + public static final String PREFERENCE_KEY_INTERNAL_INITIAL_SUBSCRIPTION_MERGE_DONE = "io.lbry.browser.preference.internal.InitialSubscriptionMergeDone"; public static final String PREFERENCE_KEY_INTERNAL_FIRST_RUN_COMPLETED = "io.lbry.browser.preference.internal.FirstRunCompleted"; public static final String PREFERENCE_KEY_INTERNAL_FIRST_AUTH_COMPLETED = "io.lbry.browser.preference.internal.FirstAuthCompleted"; @@ -554,6 +552,11 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener return sp.getBoolean(PREFERENCE_KEY_BACKGROUND_PLAYBACK, false); } + public boolean initialSubscriptionMergeDone() { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); + return sp.getBoolean(PREFERENCE_KEY_INTERNAL_INITIAL_SUBSCRIPTION_MERGE_DONE, false); + } + private void initSpecialRouteMap() { specialRouteFragmentClassMap = new HashMap<>(); specialRouteFragmentClassMap.put("about", AboutFragment.class); @@ -1780,13 +1783,19 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener // reload subscriptions if wallet fragment is FollowingFragment //openNavFragments.get MergeSubscriptionsTask mergeTask = new MergeSubscriptionsTask( - subscriptions, MainActivity.this, new MergeSubscriptionsTask.MergeSubscriptionsHandler() { + subscriptions, + !initialSubscriptionMergeDone(), + MainActivity.this, new MergeSubscriptionsTask.MergeSubscriptionsHandler() { @Override public void onSuccess(List subscriptions, List diff) { Lbryio.subscriptions = new ArrayList<>(subscriptions); if (diff != null && diff.size() > 0) { saveSharedUserState(); } + + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); + sp.edit().putBoolean(PREFERENCE_KEY_INTERNAL_INITIAL_SUBSCRIPTION_MERGE_DONE, true).apply(); + for (Fragment fragment : openNavFragments.values()) { if (fragment instanceof FollowingFragment) { // reload local subscriptions diff --git a/app/src/main/java/io/lbry/browser/data/DatabaseHelper.java b/app/src/main/java/io/lbry/browser/data/DatabaseHelper.java index 2087a7ff..e755b10b 100644 --- a/app/src/main/java/io/lbry/browser/data/DatabaseHelper.java +++ b/app/src/main/java/io/lbry/browser/data/DatabaseHelper.java @@ -64,6 +64,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { }; private static final String SQL_INSERT_SUBSCRIPTION = "REPLACE INTO subscriptions (channel_name, url) VALUES (?, ?)"; + private static final String SQL_CLEAR_SUBSCRIPTIONS = "DELETE FROM subscriptions"; private static final String SQL_DELETE_SUBSCRIPTION = "DELETE FROM subscriptions WHERE url = ?"; private static final String SQL_GET_SUBSCRIPTIONS = "SELECT channel_name, url FROM subscriptions"; @@ -230,6 +231,9 @@ public class DatabaseHelper extends SQLiteOpenHelper { public static void deleteSubscription(Subscription subscription, SQLiteDatabase db) { db.execSQL(SQL_DELETE_SUBSCRIPTION, new Object[] { subscription.getUrl() }); } + public static void clearSubscriptions(SQLiteDatabase db) { + db.execSQL(SQL_CLEAR_SUBSCRIPTIONS, null); + } public static List getSubscriptions(SQLiteDatabase db) { List subscriptions = new ArrayList<>(); Cursor cursor = null; diff --git a/app/src/main/java/io/lbry/browser/tasks/MergeSubscriptionsTask.java b/app/src/main/java/io/lbry/browser/tasks/MergeSubscriptionsTask.java index 3d3a49c8..c82d728a 100644 --- a/app/src/main/java/io/lbry/browser/tasks/MergeSubscriptionsTask.java +++ b/app/src/main/java/io/lbry/browser/tasks/MergeSubscriptionsTask.java @@ -34,9 +34,11 @@ public class MergeSubscriptionsTask extends AsyncTask diff; private MergeSubscriptionsHandler handler; private Exception error; + private boolean replaceLocal; - public MergeSubscriptionsTask(List base, Context context, MergeSubscriptionsHandler handler) { + public MergeSubscriptionsTask(List base, boolean replaceLocal, Context context, MergeSubscriptionsHandler handler) { this.base = base; + this.replaceLocal = replaceLocal; this.context = context; this.handler = handler; } @@ -53,10 +55,17 @@ public class MergeSubscriptionsTask extends AsyncTask Date: Fri, 19 Jun 2020 07:18:19 +0100 Subject: [PATCH 2/7] make FontAwesome strings non-translatable --- app/src/main/res/values/strings.xml | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 09da5fbf..f0ce3b7b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -594,26 +594,26 @@ The lbrynet.log file cannot be shared due to permission restrictions. - - - - - - - + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + -- 2.45.3 From 0a2769859a162cc81355d5dbeb811bc89be44034 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Wed, 24 Jun 2020 10:45:29 +0100 Subject: [PATCH 3/7] fix issue with featured search result crash --- .../main/java/io/lbry/browser/adapter/ClaimListAdapter.java | 5 +++-- .../java/io/lbry/browser/ui/findcontent/SearchFragment.java | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/lbry/browser/adapter/ClaimListAdapter.java b/app/src/main/java/io/lbry/browser/adapter/ClaimListAdapter.java index 74f9df1b..05f6eb90 100644 --- a/app/src/main/java/io/lbry/browser/adapter/ClaimListAdapter.java +++ b/app/src/main/java/io/lbry/browser/adapter/ClaimListAdapter.java @@ -308,7 +308,8 @@ public class ClaimListAdapter extends RecyclerView.Adapter Date: Thu, 25 Jun 2020 20:15:58 +0100 Subject: [PATCH 4/7] combined tip / support dialog and signed supports (#944) * combined tip / support dialog and signed supports * update button label when amount is updated --- .../adapter/InlineChannelSpinnerAdapter.java | 6 + .../dialog/CreateSupportDialogFragment.java | 346 ++++++++++++++++++ .../browser/dialog/SendTipDialogFragment.java | 200 ---------- .../tasks/wallet/SupportCreateTask.java | 7 +- .../browser/ui/channel/ChannelFragment.java | 13 +- .../ui/findcontent/FileViewFragment.java | 12 +- ...send_tip.xml => dialog_create_support.xml} | 78 +++- .../main/res/layout/fragment_file_view.xml | 2 +- app/src/main/res/values/strings.xml | 12 +- 9 files changed, 441 insertions(+), 235 deletions(-) create mode 100644 app/src/main/java/io/lbry/browser/dialog/CreateSupportDialogFragment.java delete mode 100644 app/src/main/java/io/lbry/browser/dialog/SendTipDialogFragment.java rename app/src/main/res/layout/{dialog_send_tip.xml => dialog_create_support.xml} (63%) diff --git a/app/src/main/java/io/lbry/browser/adapter/InlineChannelSpinnerAdapter.java b/app/src/main/java/io/lbry/browser/adapter/InlineChannelSpinnerAdapter.java index 457749ad..5a1069fa 100644 --- a/app/src/main/java/io/lbry/browser/adapter/InlineChannelSpinnerAdapter.java +++ b/app/src/main/java/io/lbry/browser/adapter/InlineChannelSpinnerAdapter.java @@ -41,6 +41,12 @@ public class InlineChannelSpinnerAdapter extends ArrayAdapter { channels.add(1, anonymous); } } + public void addAnonymousPlaceholder() { + Claim anonymous = new Claim(); + anonymous.setPlaceholderAnonymous(true); + insert(anonymous, 0); + channels.add(0, anonymous); + } public void addAll(Collection collection) { for (Claim claim : collection) { diff --git a/app/src/main/java/io/lbry/browser/dialog/CreateSupportDialogFragment.java b/app/src/main/java/io/lbry/browser/dialog/CreateSupportDialogFragment.java new file mode 100644 index 00000000..51e63ec2 --- /dev/null +++ b/app/src/main/java/io/lbry/browser/dialog/CreateSupportDialogFragment.java @@ -0,0 +1,346 @@ +package io.lbry.browser.dialog; + +import android.app.Dialog; +import android.content.Context; +import android.graphics.Color; +import android.os.AsyncTask; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.text.method.LinkMovementMethod; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CompoundButton; +import android.widget.ProgressBar; +import android.widget.Switch; +import android.widget.TextView; + +import androidx.appcompat.widget.AppCompatSpinner; +import androidx.core.text.HtmlCompat; + +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import com.google.android.material.button.MaterialButton; +import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.switchmaterial.SwitchMaterial; +import com.google.android.material.textfield.TextInputEditText; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import io.lbry.browser.MainActivity; +import io.lbry.browser.R; +import io.lbry.browser.adapter.InlineChannelSpinnerAdapter; +import io.lbry.browser.listener.WalletBalanceListener; +import io.lbry.browser.model.Claim; +import io.lbry.browser.model.WalletBalance; +import io.lbry.browser.tasks.GenericTaskHandler; +import io.lbry.browser.tasks.claim.ClaimListResultHandler; +import io.lbry.browser.tasks.claim.ClaimListTask; +import io.lbry.browser.tasks.wallet.SupportCreateTask; +import io.lbry.browser.utils.Helper; +import io.lbry.browser.utils.Lbry; +import lombok.Setter; + +public class CreateSupportDialogFragment extends BottomSheetDialogFragment implements WalletBalanceListener { + public static final String TAG = "CreateSupportDialog"; + + private MaterialButton sendButton; + private View cancelLink; + private TextInputEditText inputAmount; + private View inlineBalanceContainer; + private TextView inlineBalanceValue; + private ProgressBar sendProgress; + + private InlineChannelSpinnerAdapter channelSpinnerAdapter; + private AppCompatSpinner channelSpinner; + private SwitchMaterial switchTip; + + private boolean fetchingChannels; + private ProgressBar progressLoadingChannels; + + + @Setter + private CreateSupportListener listener; + @Setter + private Claim claim; + + public static CreateSupportDialogFragment newInstance() { + return new CreateSupportDialogFragment(); + } + + private void disableControls() { + Dialog dialog = getDialog(); + if (dialog != null) { + dialog.setCanceledOnTouchOutside(false); + } + channelSpinner.setEnabled(false); + switchTip.setEnabled(false); + sendButton.setEnabled(false); + cancelLink.setEnabled(false); + } + private void enableControls() { + Dialog dialog = getDialog(); + if (dialog != null) { + dialog.setCanceledOnTouchOutside(true); + } + channelSpinner.setEnabled(true); + switchTip.setEnabled(true); + sendButton.setEnabled(true); + cancelLink.setEnabled(true); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.dialog_create_support, container, false); + + inputAmount = view.findViewById(R.id.create_support_input_amount); + inlineBalanceContainer = view.findViewById(R.id.create_support_inline_balance_container); + inlineBalanceValue = view.findViewById(R.id.create_support_inline_balance_value); + sendProgress = view.findViewById(R.id.create_support_progress); + cancelLink = view.findViewById(R.id.create_support_cancel_link); + sendButton = view.findViewById(R.id.create_support_send); + + channelSpinner = view.findViewById(R.id.create_support_channel_spinner); + switchTip = view.findViewById(R.id.create_support_make_tip_switch); + progressLoadingChannels = view.findViewById(R.id.create_support_channel_progress); + + inputAmount.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View view, boolean hasFocus) { + inputAmount.setHint(hasFocus ? getString(R.string.zero) : ""); + inlineBalanceContainer.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE); + } + }); + inputAmount.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + updateSendButtonText(); + } + + @Override + public void afterTextChanged(Editable editable) { + + } + }); + updateInfoText(); + updateSendButtonText(); + + String channel = null; + if (Claim.TYPE_CHANNEL.equalsIgnoreCase(claim.getValueType())) { + channel = claim.getTitleOrName(); + } else if (claim.getSigningChannel() != null) { + channel = claim.getPublisherTitle(); + } + TextView titleView = view.findViewById(R.id.create_support_title); + String tipTitleText = Helper.isNullOrEmpty(channel) ? getString(R.string.send_a_tip) : getString(R.string.send_a_tip_to, channel); + titleView.setText(tipTitleText); + + switchTip.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + if (checked) { + // show tip info + titleView.setText(tipTitleText); + updateSendButtonText(); + } else { + // show support info + titleView.setText(R.string.support_this_content); + sendButton.setText(R.string.send_revocable_support); + } + updateInfoText(); + } + }); + + sendButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + String amountString = Helper.getValue(inputAmount.getText()); + if (Helper.isNullOrEmpty(amountString)) { + showError(getString(R.string.invalid_amount)); + return; + } + + BigDecimal amount = new BigDecimal(amountString); + if (amount.doubleValue() > Lbry.walletBalance.getAvailable().doubleValue()) { + showError(getString(R.string.insufficient_balance)); + return; + } + if (amount.doubleValue() < Helper.MIN_SPEND) { + showError(getString(R.string.min_spend_required)); + return; + } + + Claim selectedChannel = (Claim) channelSpinner.getSelectedItem(); + String channelId = !fetchingChannels && selectedChannel != null ? selectedChannel.getClaimId() : null; + boolean isTip = switchTip.isChecked(); + SupportCreateTask task = new SupportCreateTask( + claim.getClaimId(), channelId, amount, isTip, sendProgress, new GenericTaskHandler() { + @Override + public void beforeStart() { + disableControls(); + } + + @Override + public void onSuccess() { + enableControls(); + if (listener != null) { + listener.onSupportCreated(amount, isTip); + } + + dismiss(); + } + + @Override + public void onError(Exception error) { + showError(error.getMessage()); + enableControls(); + } + }); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + }); + + cancelLink.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dismiss(); + } + }); + + onWalletBalanceUpdated(Lbry.walletBalance); + updateInfoText(); + + return view; + } + + private void updateSendButtonText() { + boolean isTip = switchTip.isChecked(); + if (!isTip) { + sendButton.setText(R.string.send_revocable_support); + } else { + String amountString = Helper.getValue(inputAmount.getText()); + double parsedAmount = Helper.parseDouble(amountString, 0); + sendButton.setText(parsedAmount == 0 ? getString(R.string.send_a_tip) : getString(R.string.send_lbc_tip, amountString)); + } + } + + private void updateInfoText() { + View view = getView(); + if (view != null && switchTip != null) { + TextView infoText = view.findViewById(R.id.create_support_info); + boolean isTip = switchTip.isChecked(); + + infoText.setMovementMethod(LinkMovementMethod.getInstance()); + if (!isTip) { + infoText.setText(HtmlCompat.fromHtml(getString(R.string.support_info), HtmlCompat.FROM_HTML_MODE_LEGACY)); + } else if (claim != null) { + infoText.setText(HtmlCompat.fromHtml( + Claim.TYPE_CHANNEL.equalsIgnoreCase(claim.getValueType()) ? + getString(R.string.send_tip_info_channel, claim.getTitleOrName()) : + getString(R.string.send_tip_info_content, claim.getTitleOrName()), + HtmlCompat.FROM_HTML_MODE_LEGACY)); + } + } + } + + private void fetchChannels() { + if (Lbry.ownChannels != null && Lbry.ownChannels.size() > 0) { + updateChannelList(Lbry.ownChannels); + return; + } + + fetchingChannels = true; + disableChannelSpinner(); + ClaimListTask task = new ClaimListTask(Claim.TYPE_CHANNEL, progressLoadingChannels, new ClaimListResultHandler() { + @Override + public void onSuccess(List claims) { + Lbry.ownChannels = new ArrayList<>(claims); + updateChannelList(Lbry.ownChannels); + enableChannelSpinner(); + fetchingChannels = false; + } + + @Override + public void onError(Exception error) { + enableChannelSpinner(); + fetchingChannels = false; + } + }); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + private void disableChannelSpinner() { + Helper.setViewEnabled(channelSpinner, false); + } + private void enableChannelSpinner() { + Helper.setViewEnabled(channelSpinner, true); + } + + private void updateChannelList(List channels) { + if (channelSpinnerAdapter == null) { + Context context = getContext(); + if (context != null) { + channelSpinnerAdapter = new InlineChannelSpinnerAdapter(context, R.layout.spinner_item_channel, new ArrayList<>(channels)); + channelSpinnerAdapter.addAnonymousPlaceholder(); + channelSpinnerAdapter.notifyDataSetChanged(); + } + } else { + channelSpinnerAdapter.clear(); + channelSpinnerAdapter.addAll(channels); + channelSpinnerAdapter.addAnonymousPlaceholder(); + channelSpinnerAdapter.notifyDataSetChanged(); + } + + if (channelSpinner != null) { + channelSpinner.setAdapter(channelSpinnerAdapter); + } + + if (channelSpinnerAdapter != null && channelSpinner != null) { + if (channelSpinnerAdapter.getCount() > 1) { + channelSpinner.setSelection(1); + } + } + } + + public void onResume() { + super.onResume(); + Context context = getContext(); + if (context instanceof MainActivity) { + ((MainActivity) context).addWalletBalanceListener(this); + } + updateInfoText(); + fetchChannels(); + } + + public void onPause() { + Context context = getContext(); + if (context instanceof MainActivity) { + ((MainActivity) context).removeWalletBalanceListener(this); + } + super.onPause(); + } + + @Override + public void onWalletBalanceUpdated(WalletBalance walletBalance) { + if (walletBalance != null && inlineBalanceValue != null) { + inlineBalanceValue.setText(Helper.shortCurrencyFormat(walletBalance.getAvailable().doubleValue())); + } + } + + private void showError(String message) { + Snackbar.make(getView(), message, Snackbar.LENGTH_LONG). + setBackgroundTint(Color.RED). + setTextColor(Color.WHITE). + show(); + } + + public interface CreateSupportListener { + void onSupportCreated(BigDecimal amount, boolean isTip); + } +} diff --git a/app/src/main/java/io/lbry/browser/dialog/SendTipDialogFragment.java b/app/src/main/java/io/lbry/browser/dialog/SendTipDialogFragment.java deleted file mode 100644 index eed10265..00000000 --- a/app/src/main/java/io/lbry/browser/dialog/SendTipDialogFragment.java +++ /dev/null @@ -1,200 +0,0 @@ -package io.lbry.browser.dialog; - -import android.app.Dialog; -import android.content.Context; -import android.graphics.Color; -import android.os.AsyncTask; -import android.os.Bundle; -import android.text.method.LinkMovementMethod; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ProgressBar; -import android.widget.TextView; - -import androidx.core.text.HtmlCompat; - -import com.google.android.material.bottomsheet.BottomSheetDialogFragment; -import com.google.android.material.button.MaterialButton; -import com.google.android.material.snackbar.Snackbar; -import com.google.android.material.textfield.TextInputEditText; - -import java.math.BigDecimal; - -import io.lbry.browser.MainActivity; -import io.lbry.browser.R; -import io.lbry.browser.listener.WalletBalanceListener; -import io.lbry.browser.model.Claim; -import io.lbry.browser.model.WalletBalance; -import io.lbry.browser.tasks.GenericTaskHandler; -import io.lbry.browser.tasks.wallet.SupportCreateTask; -import io.lbry.browser.utils.Helper; -import io.lbry.browser.utils.Lbry; -import lombok.Setter; - -public class SendTipDialogFragment extends BottomSheetDialogFragment implements WalletBalanceListener { - public static final String TAG = "SendTipDialog"; - - private MaterialButton sendButton; - private View cancelLink; - private TextInputEditText inputAmount; - private View inlineBalanceContainer; - private TextView inlineBalanceValue; - private ProgressBar sendProgress; - - @Setter - private SendTipListener listener; - @Setter - private Claim claim; - - public static SendTipDialogFragment newInstance() { - return new SendTipDialogFragment(); - } - - private void disableControls() { - Dialog dialog = getDialog(); - if (dialog != null) { - dialog.setCanceledOnTouchOutside(false); - } - sendButton.setEnabled(false); - cancelLink.setEnabled(false); - } - private void enableControls() { - Dialog dialog = getDialog(); - if (dialog != null) { - dialog.setCanceledOnTouchOutside(true); - } - sendButton.setEnabled(true); - cancelLink.setEnabled(true); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.dialog_send_tip, container, false); - - inputAmount = view.findViewById(R.id.tip_input_amount); - inlineBalanceContainer = view.findViewById(R.id.tip_inline_balance_container); - inlineBalanceValue = view.findViewById(R.id.tip_inline_balance_value); - sendProgress = view.findViewById(R.id.tip_send_progress); - cancelLink = view.findViewById(R.id.tip_cancel_link); - sendButton = view.findViewById(R.id.tip_send); - - inputAmount.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View view, boolean hasFocus) { - inputAmount.setHint(hasFocus ? getString(R.string.zero) : ""); - inlineBalanceContainer.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE); - } - }); - - TextView infoText = view.findViewById(R.id.tip_info); - infoText.setMovementMethod(LinkMovementMethod.getInstance()); - if (claim != null) { - infoText.setText(HtmlCompat.fromHtml( - Claim.TYPE_CHANNEL.equalsIgnoreCase(claim.getValueType()) ? - getString(R.string.send_tip_info_channel, claim.getTitleOrName()) : - getString(R.string.send_tip_info_content, claim.getTitleOrName()), - HtmlCompat.FROM_HTML_MODE_LEGACY)); - } - - sendButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - String amountString = Helper.getValue(inputAmount.getText()); - if (Helper.isNullOrEmpty(amountString)) { - showError(getString(R.string.invalid_amount)); - return; - } - - BigDecimal amount = new BigDecimal(amountString); - if (amount.doubleValue() > Lbry.walletBalance.getAvailable().doubleValue()) { - showError(getString(R.string.insufficient_balance)); - return; - } - if (amount.doubleValue() < Helper.MIN_SPEND) { - showError(getString(R.string.min_spend_required)); - return; - } - - SupportCreateTask task = new SupportCreateTask(claim.getClaimId(), amount, true, sendProgress, new GenericTaskHandler() { - @Override - public void beforeStart() { - disableControls(); - } - - @Override - public void onSuccess() { - enableControls(); - if (listener != null) { - listener.onTipSent(amount); - } - - dismiss(); - } - - @Override - public void onError(Exception error) { - showError(error.getMessage()); - enableControls(); - } - }); - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - }); - - cancelLink.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - dismiss(); - } - }); - - String channel = null; - if (Claim.TYPE_CHANNEL.equalsIgnoreCase(claim.getValueType())) { - channel = claim.getTitleOrName(); - } else if (claim.getSigningChannel() != null) { - channel = claim.getPublisherTitle(); - } - ((TextView) view.findViewById(R.id.tip_send_title)).setText( - Helper.isNullOrEmpty(channel) ? getString(R.string.send_a_tip) : getString(R.string.send_a_tip_to, channel) - ); - - onWalletBalanceUpdated(Lbry.walletBalance); - - return view; - } - - public void onResume() { - super.onResume(); - Context context = getContext(); - if (context instanceof MainActivity) { - ((MainActivity) context).addWalletBalanceListener(this); - } - } - - public void onPause() { - Context context = getContext(); - if (context instanceof MainActivity) { - ((MainActivity) context).removeWalletBalanceListener(this); - } - super.onPause(); - } - - @Override - public void onWalletBalanceUpdated(WalletBalance walletBalance) { - if (walletBalance != null && inlineBalanceValue != null) { - inlineBalanceValue.setText(Helper.shortCurrencyFormat(walletBalance.getAvailable().doubleValue())); - } - } - - private void showError(String message) { - Snackbar.make(getView(), message, Snackbar.LENGTH_LONG). - setBackgroundTint(Color.RED). - setTextColor(Color.WHITE). - show(); - } - - public interface SendTipListener { - void onTipSent(BigDecimal amount); - } -} diff --git a/app/src/main/java/io/lbry/browser/tasks/wallet/SupportCreateTask.java b/app/src/main/java/io/lbry/browser/tasks/wallet/SupportCreateTask.java index d11fb937..5426f0cb 100644 --- a/app/src/main/java/io/lbry/browser/tasks/wallet/SupportCreateTask.java +++ b/app/src/main/java/io/lbry/browser/tasks/wallet/SupportCreateTask.java @@ -17,14 +17,16 @@ import io.lbry.browser.utils.Lbry; public class SupportCreateTask extends AsyncTask { private String claimId; + private String channelId; private BigDecimal amount; private boolean tip; private View progressView; private GenericTaskHandler handler; private Exception error; - public SupportCreateTask(String claimId, BigDecimal amount, boolean tip, View progressView, GenericTaskHandler handler) { + public SupportCreateTask(String claimId, String channelId, BigDecimal amount, boolean tip, View progressView, GenericTaskHandler handler) { this.claimId = claimId; + this.channelId = channelId; this.amount = amount; this.tip = tip; this.progressView = progressView; @@ -44,6 +46,9 @@ public class SupportCreateTask extends AsyncTask { options.put("claim_id", claimId); options.put("amount", new DecimalFormat(Helper.SDK_AMOUNT_FORMAT, new DecimalFormatSymbols(Locale.US)).format(amount.doubleValue())); options.put("tip", tip); + if (!Helper.isNullOrEmpty(channelId)) { + options.put("channel_id", channelId); + } Lbry.genericApiCall(Lbry.METHOD_SUPPORT_CREATE, options); } catch (ApiCallException ex) { error = ex; diff --git a/app/src/main/java/io/lbry/browser/ui/channel/ChannelFragment.java b/app/src/main/java/io/lbry/browser/ui/channel/ChannelFragment.java index 789317fe..5c5d9aed 100644 --- a/app/src/main/java/io/lbry/browser/ui/channel/ChannelFragment.java +++ b/app/src/main/java/io/lbry/browser/ui/channel/ChannelFragment.java @@ -11,7 +11,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; @@ -36,7 +35,7 @@ import java.util.Map; import io.lbry.browser.MainActivity; import io.lbry.browser.R; -import io.lbry.browser.dialog.SendTipDialogFragment; +import io.lbry.browser.dialog.CreateSupportDialogFragment; import io.lbry.browser.exceptions.LbryUriException; import io.lbry.browser.listener.FetchChannelsListener; import io.lbry.browser.model.Claim; @@ -174,16 +173,16 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen } if (claim != null) { - SendTipDialogFragment dialog = SendTipDialogFragment.newInstance(); + CreateSupportDialogFragment dialog = CreateSupportDialogFragment.newInstance(); dialog.setClaim(claim); - dialog.setListener(new SendTipDialogFragment.SendTipListener() { + dialog.setListener(new CreateSupportDialogFragment.CreateSupportListener() { @Override - public void onTipSent(BigDecimal amount) { + public void onSupportCreated(BigDecimal amount, boolean isTip) { double sentAmount = amount.doubleValue(); View view = getView(); if (view != null) { String message = getResources().getQuantityString( - R.plurals.you_sent_a_tip, sentAmount == 1.0 ? 1 : 2, + isTip ? R.plurals.you_sent_a_tip : R.plurals.you_sent_a_support, sentAmount == 1.0 ? 1 : 2, new DecimalFormat("#,###.##").format(sentAmount)); Snackbar.make(view, message, Snackbar.LENGTH_LONG).show(); } @@ -191,7 +190,7 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen }); Context context = getContext(); if (context instanceof MainActivity) { - dialog.show(((MainActivity) context).getSupportFragmentManager(), SendTipDialogFragment.TAG); + dialog.show(((MainActivity) context).getSupportFragmentManager(), CreateSupportDialogFragment.TAG); } } } diff --git a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java index efb61061..561da67c 100644 --- a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java +++ b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java @@ -99,7 +99,7 @@ import io.lbry.browser.adapter.CommentListAdapter; import io.lbry.browser.adapter.InlineChannelSpinnerAdapter; import io.lbry.browser.adapter.TagListAdapter; import io.lbry.browser.dialog.RepostClaimDialogFragment; -import io.lbry.browser.dialog.SendTipDialogFragment; +import io.lbry.browser.dialog.CreateSupportDialogFragment; import io.lbry.browser.exceptions.LbryUriException; import io.lbry.browser.listener.DownloadActionListener; import io.lbry.browser.listener.FetchClaimsListener; @@ -845,21 +845,21 @@ public class FileViewFragment extends BaseFragment implements } if (claim != null) { - SendTipDialogFragment dialog = SendTipDialogFragment.newInstance(); + CreateSupportDialogFragment dialog = CreateSupportDialogFragment.newInstance(); dialog.setClaim(claim); - dialog.setListener(new SendTipDialogFragment.SendTipListener() { + dialog.setListener(new CreateSupportDialogFragment.CreateSupportListener() { @Override - public void onTipSent(BigDecimal amount) { + public void onSupportCreated(BigDecimal amount, boolean isTip) { double sentAmount = amount.doubleValue(); String message = getResources().getQuantityString( - R.plurals.you_sent_a_tip, sentAmount == 1.0 ? 1 : 2, + isTip ? R.plurals.you_sent_a_tip : R.plurals.you_sent_a_support, sentAmount == 1.0 ? 1 : 2, new DecimalFormat("#,###.##").format(sentAmount)); Snackbar.make(root.findViewById(R.id.file_view_claim_display_area), message, Snackbar.LENGTH_LONG).show(); } }); Context context = getContext(); if (context instanceof MainActivity) { - dialog.show(((MainActivity) context).getSupportFragmentManager(), SendTipDialogFragment.TAG); + dialog.show(((MainActivity) context).getSupportFragmentManager(), CreateSupportDialogFragment.TAG); } } } diff --git a/app/src/main/res/layout/dialog_send_tip.xml b/app/src/main/res/layout/dialog_create_support.xml similarity index 63% rename from app/src/main/res/layout/dialog_send_tip.xml rename to app/src/main/res/layout/dialog_create_support.xml index 04c0168d..db693d94 100644 --- a/app/src/main/res/layout/dialog_send_tip.xml +++ b/app/src/main/res/layout/dialog_create_support.xml @@ -9,7 +9,7 @@ android:orientation="vertical" android:padding="16dp"> + android:layout_marginBottom="12dp" /> + + + + + + + + + + + - @@ -93,7 +133,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> diff --git a/app/src/main/res/layout/fragment_file_view.xml b/app/src/main/res/layout/fragment_file_view.xml index dc6b1467..ebac1449 100644 --- a/app/src/main/res/layout/fragment_file_view.xml +++ b/app/src/main/res/layout/fragment_file_view.xml @@ -295,7 +295,7 @@ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f0ce3b7b..637c2a6a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -363,7 +363,7 @@ Filter for Everyone Tags you follow - Customize + CustomizeSend a tip The selected view is not yet available. It looks like you have not followed any tags yet. Search for more tags @@ -373,6 +373,12 @@ You cannot add more than 5 tags. Send a tip Send a tip to %1$s + Support this content + This will increase the overall bid amount for this content, which will boost its ability to be discovered while active. <a href="https://lbry.com/faq/tipping">Learn more</a>. + Channel to show support as + Make this a tip + Send Revocable Support + Send a %1$s LBC Tip This will appear as a tip for %1$s, which will boost its ability to be discovered while active. <a href="https://lbry.com/faq/tipping">Learn more</a>. This will appear as a tip for %1$s, which will boost the channel\'s ability to be discovered while active. <a href="https://lbry.com/faq/tipping">Learn more</a>. Cancel @@ -389,6 +395,10 @@ You sent %1$s credit as a tip, Mahalo! You sent %1$s credits as a tip, Mahalo! + + You staked %1$s credit as a support. You can revoke your support at any time. + You staked %1$s credits as a support. You can revoke your support at any time. + Please provide an email address. -- 2.45.3 From a2b6d4e5704d999607ddec13f8e412bc8922a70d Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Thu, 25 Jun 2020 20:16:38 +0100 Subject: [PATCH 5/7] bumpversion 0.15.13 --> 0.15.14 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 55db7e4a..d557b510 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId "io.lbry.browser" minSdkVersion 21 targetSdkVersion 29 - versionCode 1513 - versionName "0.15.13" + versionCode 1514 + versionName "0.15.14" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } -- 2.45.3 From 07630ca97bbd51a31ed6a3094a829426ce3ae3ef Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Thu, 25 Jun 2020 20:23:24 +0100 Subject: [PATCH 6/7] fix: crash bugs --- .../lbry/browser/adapter/ClaimListAdapter.java | 17 ++++++++++++++--- .../ui/findcontent/FileViewFragment.java | 12 +++++++++--- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/io/lbry/browser/adapter/ClaimListAdapter.java b/app/src/main/java/io/lbry/browser/adapter/ClaimListAdapter.java index 05f6eb90..f5fe2613 100644 --- a/app/src/main/java/io/lbry/browser/adapter/ClaimListAdapter.java +++ b/app/src/main/java/io/lbry/browser/adapter/ClaimListAdapter.java @@ -60,7 +60,13 @@ public class ClaimListAdapter extends RecyclerView.Adapter items, Context context) { this.context = context; - this.items = new ArrayList<>(items); + this.items = new ArrayList<>(); + for (Claim item : items) { + if (item != null) { + items.add(item); + } + } + this.selectedItems = new ArrayList<>(); quickClaimIdMap = new HashMap<>(); quickClaimUrlMap = new HashMap<>(); @@ -139,7 +145,7 @@ public class ClaimListAdapter extends RecyclerView.Adapter claims) { for (Claim claim : claims) { - if (!items.contains(claim)) { + if (claim != null && !items.contains(claim)) { items.add(claim); } } @@ -149,7 +155,12 @@ public class ClaimListAdapter extends RecyclerView.Adapter claims) { - items = new ArrayList<>(claims); + items = new ArrayList<>(); + for (Claim claim : claims) { + if (claim != null) { + items.add(claim); + } + } notifyDataSetChanged(); } diff --git a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java index 561da67c..a3d0a1d1 100644 --- a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java +++ b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java @@ -1678,15 +1678,21 @@ public class FileViewFragment extends BaseFragment implements } if (claim.getFile() == null && !claim.isFree()) { if (!Lbry.SDK_READY) { - Snackbar.make(getView().findViewById(R.id.file_view_global_layout), R.string.sdk_initializing_functionality, Snackbar.LENGTH_LONG).show(); + if (root != null) { + Snackbar.make(root.findViewById(R.id.file_view_global_layout), + R.string.sdk_initializing_functionality, Snackbar.LENGTH_LONG).show(); + } restoreMainActionButton(); return; } checkAndConfirmPurchaseUrl(); } else { - if (!claim.isPlayable() && !Lbry.SDK_READY) { - Snackbar.make(getView().findViewById(R.id.file_view_global_layout), R.string.sdk_initializing_functionality, Snackbar.LENGTH_LONG).show(); + if (claim != null && !claim.isPlayable() && !Lbry.SDK_READY) { + if (root != null) { + Snackbar.make(root.findViewById(R.id.file_view_global_layout), + R.string.sdk_initializing_functionality, Snackbar.LENGTH_LONG).show(); + } restoreMainActionButton(); return; } -- 2.45.3 From fa78c80592ee86f05559843b2de2645c4e16f05d Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Thu, 25 Jun 2020 20:42:55 +0100 Subject: [PATCH 7/7] fix ClaimListAdapter and strings.xml --- app/src/main/java/io/lbry/browser/adapter/ClaimListAdapter.java | 2 +- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/lbry/browser/adapter/ClaimListAdapter.java b/app/src/main/java/io/lbry/browser/adapter/ClaimListAdapter.java index f5fe2613..c21bbf20 100644 --- a/app/src/main/java/io/lbry/browser/adapter/ClaimListAdapter.java +++ b/app/src/main/java/io/lbry/browser/adapter/ClaimListAdapter.java @@ -63,7 +63,7 @@ public class ClaimListAdapter extends RecyclerView.Adapter(); for (Claim item : items) { if (item != null) { - items.add(item); + this.items.add(item); } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 637c2a6a..8d11777f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -363,7 +363,7 @@ Filter for Everyone Tags you follow - CustomizeSend a tip + Customize The selected view is not yet available. It looks like you have not followed any tags yet. Search for more tags -- 2.45.3