Native rewrite #878
34 changed files with 1451 additions and 42 deletions
|
@ -65,7 +65,6 @@ import java.io.BufferedReader;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.ConnectException;
|
||||
import java.nio.channels.Channel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -95,7 +94,7 @@ import io.lbry.browser.model.lbryinc.Reward;
|
|||
import io.lbry.browser.model.lbryinc.Subscription;
|
||||
import io.lbry.browser.tasks.ClaimListResultHandler;
|
||||
import io.lbry.browser.tasks.ClaimListTask;
|
||||
import io.lbry.browser.tasks.FetchRewardsTask;
|
||||
import io.lbry.browser.tasks.lbryinc.FetchRewardsTask;
|
||||
import io.lbry.browser.tasks.LighthouseAutoCompleteTask;
|
||||
import io.lbry.browser.tasks.MergeSubscriptionsTask;
|
||||
import io.lbry.browser.tasks.ResolveTask;
|
||||
|
@ -115,6 +114,7 @@ import io.lbry.browser.ui.following.FollowingFragment;
|
|||
import io.lbry.browser.ui.search.SearchFragment;
|
||||
import io.lbry.browser.ui.settings.SettingsFragment;
|
||||
import io.lbry.browser.ui.allcontent.AllContentFragment;
|
||||
import io.lbry.browser.ui.wallet.InvitesFragment;
|
||||
import io.lbry.browser.ui.wallet.RewardsFragment;
|
||||
import io.lbry.browser.ui.wallet.WalletFragment;
|
||||
import io.lbry.browser.utils.Helper;
|
||||
|
@ -229,6 +229,16 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
private String pendingChannelUrl;
|
||||
private boolean pendingFollowingReload;
|
||||
|
||||
// startup stages (to be able to determine how far a user made it if startup fails)
|
||||
// and display a more useful message for troubleshooting
|
||||
private static final int STARTUP_STAGE_INSTALL_ID_LOADED = 1;
|
||||
private static final int STARTUP_STAGE_KNOWN_TAGS_LOADED = 2;
|
||||
private static final int STARTUP_STAGE_EXCHANGE_RATE_LOADED = 3;
|
||||
private static final int STARTUP_STAGE_USER_AUTHENTICATED = 4;
|
||||
private static final int STARTUP_STAGE_NEW_INSTALL_DONE = 5;
|
||||
private static final int STARTUP_STAGE_SUBSCRIPTIONS_LOADED = 6;
|
||||
private static final int STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED = 7;
|
||||
|
||||
private final List<Integer> supportedMenuItemIds = Arrays.asList(
|
||||
// find content
|
||||
NavMenuItem.ID_ITEM_FOLLOWING,
|
||||
|
@ -241,7 +251,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
// wallet
|
||||
NavMenuItem.ID_ITEM_WALLET,
|
||||
NavMenuItem.ID_ITEM_REWARDS,
|
||||
|
||||
NavMenuItem.ID_ITEM_INVITES,
|
||||
|
||||
NavMenuItem.ID_ITEM_SETTINGS
|
||||
);
|
||||
|
@ -432,6 +442,9 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
case NavMenuItem.ID_ITEM_REWARDS:
|
||||
openFragment(RewardsFragment.class, true, NavMenuItem.ID_ITEM_REWARDS);
|
||||
break;
|
||||
case NavMenuItem.ID_ITEM_INVITES:
|
||||
openFragment(InvitesFragment.class, true, NavMenuItem.ID_ITEM_INVITES);
|
||||
break;
|
||||
|
||||
case NavMenuItem.ID_ITEM_SETTINGS:
|
||||
openFragment(SettingsFragment.class, true, NavMenuItem.ID_ITEM_SETTINGS);
|
||||
|
@ -1471,6 +1484,11 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
if (Lbryio.currentUser == null) {
|
||||
Lbryio.authenticate(context);
|
||||
}
|
||||
if (Lbryio.currentUser == null) {
|
||||
throw new Exception("Did not retrieve authenticated user.");
|
||||
}
|
||||
|
||||
|
||||
Lbryio.newInstall(context);
|
||||
|
||||
// (light) fetch subscriptions
|
||||
|
@ -1546,8 +1564,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
}
|
||||
|
||||
if (Lbryio.totalUnclaimedRewardAmount > 0) {
|
||||
((TextView) findViewById(R.id.floating_reward_value)).setText(Helper.shortCurrencyFormat(Lbryio.totalUnclaimedRewardAmount));
|
||||
findViewById(R.id.floating_reward_container).setVisibility(View.VISIBLE);
|
||||
showFloatingUnclaimedRewards();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1558,6 +1575,11 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
public void showFloatingUnclaimedRewards() {
|
||||
((TextView) findViewById(R.id.floating_reward_value)).setText(Helper.shortCurrencyFormat(Lbryio.totalUnclaimedRewardAmount));
|
||||
findViewById(R.id.floating_reward_container).setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void checkUrlIntent(Intent intent) {
|
||||
if (intent != null) {
|
||||
Uri data = intent.getData();
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.lbry.browser;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.AsyncTask;
|
||||
|
@ -8,27 +7,17 @@ import android.os.Bundle;
|
|||
import android.view.View;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import io.lbry.browser.adapter.ClaimListAdapter;
|
||||
import io.lbry.browser.adapter.VerificationPagerAdapter;
|
||||
import io.lbry.browser.listener.SignInListener;
|
||||
import io.lbry.browser.listener.WalletSyncListener;
|
||||
import io.lbry.browser.model.Claim;
|
||||
import io.lbry.browser.model.lbryinc.User;
|
||||
import io.lbry.browser.tasks.ClaimListResultHandler;
|
||||
import io.lbry.browser.tasks.ClaimListTask;
|
||||
import io.lbry.browser.tasks.FetchCurrentUserTask;
|
||||
import io.lbry.browser.ui.channel.ChannelManagerFragment;
|
||||
import io.lbry.browser.utils.Helper;
|
||||
import io.lbry.browser.utils.Lbry;
|
||||
import io.lbry.browser.tasks.lbryinc.FetchCurrentUserTask;
|
||||
import io.lbry.browser.utils.Lbryio;
|
||||
|
||||
public class VerificationActivity extends FragmentActivity implements SignInListener, WalletSyncListener {
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package io.lbry.browser.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.DataSetObserver;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.SpinnerAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.lbry.browser.R;
|
||||
import io.lbry.browser.model.Claim;
|
||||
|
||||
public class InlineChannelSpinnerAdapter extends ArrayAdapter<Claim> {
|
||||
|
||||
private List<Claim> channels;
|
||||
private int layoutResourceId;
|
||||
private LayoutInflater inflater;
|
||||
|
||||
public InlineChannelSpinnerAdapter(Context context, int resource, List<Claim> channels) {
|
||||
super(context, resource, 0, channels);
|
||||
inflater = LayoutInflater.from(context);
|
||||
layoutResourceId = resource;
|
||||
this.channels = new ArrayList<>(channels);
|
||||
}
|
||||
public void addPlaceholder(boolean includeAnonymous) {
|
||||
Claim placeholder = new Claim();
|
||||
placeholder.setPlaceholder(true);
|
||||
insert(placeholder, 0);
|
||||
channels.add(0, placeholder);
|
||||
|
||||
if (includeAnonymous) {
|
||||
Claim anonymous = new Claim();
|
||||
anonymous.setPlaceholderAnonymous(true);
|
||||
insert(anonymous, 1);
|
||||
channels.add(1, anonymous);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getDropDownView(int position, View view, ViewGroup parent) {
|
||||
return createView(position, view, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View view, ViewGroup parent) {
|
||||
return createView(position, view, parent);
|
||||
}
|
||||
private View createView(int position, View convertView, ViewGroup parent){
|
||||
View view = inflater.inflate(layoutResourceId, parent, false);
|
||||
|
||||
Context context = getContext();
|
||||
Claim channel = getItem(position);
|
||||
String name = channel.getName();
|
||||
if (channel.isPlaceholder()) {
|
||||
name = context.getString(R.string.create_a_channel);
|
||||
} else if (channel.isPlaceholderAnonymous()) {
|
||||
name = context.getString(R.string.anonymous);
|
||||
}
|
||||
|
||||
TextView label = view.findViewById(R.id.channel_item_name);
|
||||
label.setText(name);
|
||||
|
||||
return view;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package io.lbry.browser.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.net.Uri;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.lbry.browser.R;
|
||||
import io.lbry.browser.model.lbryinc.Invitee;
|
||||
import io.lbry.browser.utils.Helper;
|
||||
import io.lbry.browser.utils.LbryUri;
|
||||
import lombok.Setter;
|
||||
|
||||
public class InviteeListAdapter extends RecyclerView.Adapter<InviteeListAdapter.ViewHolder> {
|
||||
|
||||
private Context context;
|
||||
private List<Invitee> items;
|
||||
|
||||
public InviteeListAdapter(List<Invitee> invitees, Context context) {
|
||||
this.context = context;
|
||||
this.items = new ArrayList<>(invitees);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
items.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public List<Invitee> getItems() {
|
||||
return new ArrayList<>(items);
|
||||
}
|
||||
|
||||
public void addHeader() {
|
||||
Invitee header = new Invitee();
|
||||
header.setHeader(true);
|
||||
items.add(0, header);
|
||||
}
|
||||
|
||||
public void addInvitees(List<Invitee> Invitees) {
|
||||
for (Invitee tx : Invitees) {
|
||||
if (!items.contains(tx)) {
|
||||
items.add(tx);
|
||||
}
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public int getItemCount() {
|
||||
return items != null ? items.size() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InviteeListAdapter.ViewHolder onCreateViewHolder(ViewGroup root, int viewType) {
|
||||
View v = LayoutInflater.from(context).inflate(R.layout.list_item_invitee, root, false);
|
||||
return new InviteeListAdapter.ViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(InviteeListAdapter.ViewHolder vh, int position) {
|
||||
Invitee item = items.get(position);
|
||||
vh.emailView.setText(item.isHeader() ? context.getString(R.string.email) : item.getEmail());
|
||||
vh.emailView.setTypeface(null, item.isHeader() ? Typeface.BOLD : Typeface.NORMAL);
|
||||
|
||||
String rewardText = context.getString(
|
||||
item.isInviteRewardClaimed() ? R.string.claimed :
|
||||
(item.isInviteRewardClaimable() ? R.string.claimable : R.string.unclaimable));
|
||||
vh.rewardView.setText(item.isHeader() ? context.getString(R.string.reward) : rewardText);
|
||||
vh.rewardView.setTypeface(null, item.isHeader() ? Typeface.BOLD : Typeface.NORMAL);
|
||||
}
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
protected TextView emailView;
|
||||
protected TextView rewardView;
|
||||
|
||||
public ViewHolder(View v) {
|
||||
super(v);
|
||||
emailView = v.findViewById(R.id.invitee_email);
|
||||
rewardView = v.findViewById(R.id.invitee_reward);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -138,14 +138,13 @@ public class RewardListAdapter extends RecyclerView.Adapter<RewardListAdapter.Vi
|
|||
if (!"?".equals(displayAmount)) {
|
||||
rewardAmount = Double.valueOf(displayAmount);
|
||||
}
|
||||
boolean hasTransaction = !Helper.isNullOrEmpty(reward.getTransactionId());
|
||||
|
||||
boolean hasTransaction = !Helper.isNullOrEmpty(reward.getTransactionId()) && reward.getTransactionId().length() > 7;
|
||||
vh.iconClaimed.setVisibility(reward.isClaimed() ? View.VISIBLE : View.INVISIBLE);
|
||||
vh.inputCustomCode.setVisibility(reward.isCustom() ? View.VISIBLE : View.GONE);
|
||||
vh.buttonClaimCustom.setVisibility(reward.isCustom() ? View.VISIBLE : View.GONE);
|
||||
vh.textTitle.setText(reward.getRewardTitle());
|
||||
vh.textDescription.setText(reward.getRewardDescription());
|
||||
vh.upTo.setVisibility(reward.shouldDisplayRange() ? View.VISIBLE : View.INVISIBLE);
|
||||
vh.upTo.setVisibility(reward.shouldDisplayRange() ? View.VISIBLE : View.GONE);
|
||||
vh.textLbcValue.setText(reward.isCustom() ? "?" : Helper.LBC_CURRENCY_FORMAT.format(Helper.parseDouble(reward.getDisplayAmount(), 0)));
|
||||
vh.textLinkTransaction.setVisibility(hasTransaction ? View.VISIBLE : View.GONE);
|
||||
vh.textLinkTransaction.setText(hasTransaction ? reward.getTransactionId().substring(0, 7) : null);
|
||||
|
|
|
@ -51,6 +51,7 @@ public class Claim {
|
|||
|
||||
@EqualsAndHashCode.Include
|
||||
private boolean placeholder;
|
||||
private boolean placeholderAnonymous;
|
||||
private boolean featured;
|
||||
private boolean unresolved; // used for featured
|
||||
private String address;
|
||||
|
|
|
@ -41,6 +41,7 @@ public class NavMenuItem {
|
|||
private boolean group;
|
||||
private int icon;
|
||||
private String title;
|
||||
private String extraLabel;
|
||||
private String name; // same as title, but only as en lang for events
|
||||
private List<NavMenuItem> items;
|
||||
|
||||
|
|
11
app/src/main/java/io/lbry/browser/model/lbryinc/Invitee.java
Normal file
11
app/src/main/java/io/lbry/browser/model/lbryinc/Invitee.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
package io.lbry.browser.model.lbryinc;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Invitee {
|
||||
private boolean header;
|
||||
private String email;
|
||||
private boolean inviteRewardClaimed;
|
||||
private boolean inviteRewardClaimable;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.lbry.browser.tasks;
|
||||
package io.lbry.browser.tasks.lbryinc;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
|
@ -1,4 +1,4 @@
|
|||
package io.lbry.browser.tasks;
|
||||
package io.lbry.browser.tasks.lbryinc;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
|
@ -1,4 +1,4 @@
|
|||
package io.lbry.browser.tasks;
|
||||
package io.lbry.browser.tasks.lbryinc;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package io.lbry.browser.tasks.lbryinc;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.view.View;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.lbry.browser.exceptions.LbryioRequestException;
|
||||
import io.lbry.browser.exceptions.LbryioResponseException;
|
||||
import io.lbry.browser.model.lbryinc.Invitee;
|
||||
import io.lbry.browser.utils.Helper;
|
||||
import io.lbry.browser.utils.Lbryio;
|
||||
|
||||
public class FetchInviteStatusTask extends AsyncTask<Void, Void, List<Invitee>> {
|
||||
private FetchInviteStatusHandler handler;
|
||||
private View progressView;
|
||||
private Exception error;
|
||||
|
||||
public FetchInviteStatusTask(View progressView, FetchInviteStatusHandler handler) {
|
||||
this.progressView = progressView;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
protected void onPreExecute() {
|
||||
Helper.setViewVisibility(progressView, View.VISIBLE);
|
||||
}
|
||||
|
||||
protected List<Invitee> doInBackground(Void... params) {
|
||||
List<Invitee> invitees = null;
|
||||
try {
|
||||
JSONObject status = (JSONObject) Lbryio.parseResponse(Lbryio.call("user", "invite_status", null, null));
|
||||
JSONArray inviteesArray = status.getJSONArray("invitees");
|
||||
invitees = new ArrayList<>();
|
||||
for (int i = 0; i < inviteesArray.length(); i++) {
|
||||
JSONObject inviteeObject = inviteesArray.getJSONObject(i);
|
||||
Invitee invitee = new Invitee();
|
||||
invitee.setEmail(Helper.getJSONString("email", null, inviteeObject));
|
||||
invitee.setInviteRewardClaimable(Helper.getJSONBoolean("invite_reward_claimable", false, inviteeObject));
|
||||
invitee.setInviteRewardClaimed(Helper.getJSONBoolean("invite_reward_claimed", false, inviteeObject));
|
||||
|
||||
if (!Helper.isNullOrEmpty(invitee.getEmail())) {
|
||||
invitees.add(invitee);
|
||||
}
|
||||
}
|
||||
} catch (ClassCastException | LbryioRequestException | LbryioResponseException | JSONException ex) {
|
||||
error = ex;
|
||||
}
|
||||
|
||||
return invitees;
|
||||
}
|
||||
|
||||
protected void onPostExecute(List<Invitee> invitees) {
|
||||
Helper.setViewVisibility(progressView, View.GONE);
|
||||
if (handler != null) {
|
||||
if (invitees != null) {
|
||||
handler.onSuccess(invitees);
|
||||
} else {
|
||||
handler.onError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface FetchInviteStatusHandler {
|
||||
void onSuccess(List<Invitee> invitees);
|
||||
void onError(Exception error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package io.lbry.browser.tasks.lbryinc;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.view.View;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
import io.lbry.browser.exceptions.LbryioRequestException;
|
||||
import io.lbry.browser.exceptions.LbryioResponseException;
|
||||
import io.lbry.browser.utils.Helper;
|
||||
import io.lbry.browser.utils.Lbryio;
|
||||
|
||||
public class FetchReferralCodeTask extends AsyncTask<Void, Void, String> {
|
||||
private FetchReferralCodeHandler handler;
|
||||
private View progressView;
|
||||
private Exception error;
|
||||
|
||||
public FetchReferralCodeTask(View progressView, FetchReferralCodeHandler handler) {
|
||||
this.progressView = progressView;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
protected void onPreExecute() {
|
||||
Helper.setViewVisibility(progressView, View.VISIBLE);
|
||||
}
|
||||
|
||||
protected String doInBackground(Void... params) {
|
||||
String referralCode = null;
|
||||
try {
|
||||
JSONArray results = (JSONArray) Lbryio.parseResponse(Lbryio.call("user_referral_code", "list", null, null));
|
||||
if (results.length() > 0) {
|
||||
referralCode = results.getString(0);
|
||||
}
|
||||
} catch (ClassCastException | LbryioRequestException | LbryioResponseException | JSONException ex) {
|
||||
error = ex;
|
||||
}
|
||||
|
||||
return referralCode;
|
||||
}
|
||||
|
||||
protected void onPostExecute(String referralCode) {
|
||||
Helper.setViewVisibility(progressView, View.GONE);
|
||||
if (handler != null) {
|
||||
if (!Helper.isNullOrEmpty(referralCode)) {
|
||||
handler.onSuccess(referralCode);
|
||||
} else {
|
||||
handler.onError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface FetchReferralCodeHandler {
|
||||
void onSuccess(String referralCode);
|
||||
void onError(Exception error);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.lbry.browser.tasks;
|
||||
package io.lbry.browser.tasks.lbryinc;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.view.View;
|
|
@ -1,4 +1,4 @@
|
|||
package io.lbry.browser.tasks;
|
||||
package io.lbry.browser.tasks.lbryinc;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
|
@ -0,0 +1,55 @@
|
|||
package io.lbry.browser.tasks.lbryinc;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.view.View;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.lbry.browser.exceptions.LbryioRequestException;
|
||||
import io.lbry.browser.exceptions.LbryioResponseException;
|
||||
import io.lbry.browser.tasks.GenericTaskHandler;
|
||||
import io.lbry.browser.utils.Helper;
|
||||
import io.lbry.browser.utils.Lbryio;
|
||||
|
||||
public class InviteByEmailTask extends AsyncTask<Void, Void, Boolean> {
|
||||
private String email;
|
||||
private View progressView;
|
||||
private GenericTaskHandler handler;
|
||||
private Exception error;
|
||||
|
||||
public InviteByEmailTask(String email, View progressView, GenericTaskHandler handler) {
|
||||
this.email = email;
|
||||
this.progressView = progressView;
|
||||
this.handler = handler;
|
||||
}
|
||||
protected void onPreExecute() {
|
||||
Helper.setViewVisibility(progressView, View.VISIBLE);
|
||||
if (handler != null) {
|
||||
handler.beforeStart();
|
||||
}
|
||||
}
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
try {
|
||||
Map<String, String> options = new HashMap<>();
|
||||
options.put("email", email);
|
||||
Lbryio.parseResponse(Lbryio.call("user", "invite", options, Helper.METHOD_POST, null));
|
||||
} catch (LbryioRequestException | LbryioResponseException ex) {
|
||||
error = ex;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected void onPostExecute(Boolean result) {
|
||||
Helper.setViewVisibility(progressView, View.GONE);
|
||||
if (handler != null) {
|
||||
if (result) {
|
||||
handler.onSuccess();
|
||||
} else {
|
||||
handler.onError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package io.lbry.browser.ui.channel;
|
|||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
|
@ -342,13 +343,10 @@ public class ChannelFormFragment extends BaseFragment implements WalletBalanceLi
|
|||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void showError(String message) {
|
||||
Context context = getContext();
|
||||
if (context != null) {
|
||||
Snackbar.make(getView(), message, Snackbar.LENGTH_LONG).setBackgroundTint(
|
||||
ContextCompat.getColor(context, R.color.red)).show();
|
||||
Snackbar.make(getView(), message, Snackbar.LENGTH_LONG).setBackgroundTint(Color.RED).show();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,10 +33,9 @@ import io.lbry.browser.R;
|
|||
import io.lbry.browser.dialog.SendTipDialogFragment;
|
||||
import io.lbry.browser.exceptions.LbryUriException;
|
||||
import io.lbry.browser.listener.FetchChannelsListener;
|
||||
import io.lbry.browser.listener.SdkStatusListener;
|
||||
import io.lbry.browser.model.Claim;
|
||||
import io.lbry.browser.model.lbryinc.Subscription;
|
||||
import io.lbry.browser.tasks.ChannelSubscribeTask;
|
||||
import io.lbry.browser.tasks.lbryinc.ChannelSubscribeTask;
|
||||
import io.lbry.browser.tasks.ClaimListResultHandler;
|
||||
import io.lbry.browser.tasks.ResolveTask;
|
||||
import io.lbry.browser.ui.BaseFragment;
|
||||
|
|
|
@ -37,10 +37,10 @@ import io.lbry.browser.dialog.DiscoverDialogFragment;
|
|||
import io.lbry.browser.exceptions.LbryUriException;
|
||||
import io.lbry.browser.model.Claim;
|
||||
import io.lbry.browser.model.lbryinc.Subscription;
|
||||
import io.lbry.browser.tasks.ChannelSubscribeTask;
|
||||
import io.lbry.browser.tasks.lbryinc.ChannelSubscribeTask;
|
||||
import io.lbry.browser.tasks.ClaimListResultHandler;
|
||||
import io.lbry.browser.tasks.ClaimSearchTask;
|
||||
import io.lbry.browser.tasks.FetchSubscriptionsTask;
|
||||
import io.lbry.browser.tasks.lbryinc.FetchSubscriptionsTask;
|
||||
import io.lbry.browser.tasks.ResolveTask;
|
||||
import io.lbry.browser.listener.ChannelItemSelectionListener;
|
||||
import io.lbry.browser.ui.BaseFragment;
|
||||
|
|
553
app/src/main/java/io/lbry/browser/ui/wallet/InvitesFragment.java
Normal file
553
app/src/main/java/io/lbry/browser/ui/wallet/InvitesFragment.java
Normal file
|
@ -0,0 +1,553 @@
|
|||
package io.lbry.browser.ui.wallet;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
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.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.AppCompatSpinner;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.lbry.browser.BuildConfig;
|
||||
import io.lbry.browser.MainActivity;
|
||||
import io.lbry.browser.R;
|
||||
import io.lbry.browser.adapter.InlineChannelSpinnerAdapter;
|
||||
import io.lbry.browser.adapter.InviteeListAdapter;
|
||||
import io.lbry.browser.listener.SdkStatusListener;
|
||||
import io.lbry.browser.listener.WalletBalanceListener;
|
||||
import io.lbry.browser.model.Claim;
|
||||
import io.lbry.browser.model.WalletBalance;
|
||||
import io.lbry.browser.model.lbryinc.Invitee;
|
||||
import io.lbry.browser.tasks.ClaimListResultHandler;
|
||||
import io.lbry.browser.tasks.ClaimListTask;
|
||||
import io.lbry.browser.tasks.GenericTaskHandler;
|
||||
import io.lbry.browser.tasks.content.ChannelCreateUpdateTask;
|
||||
import io.lbry.browser.tasks.content.ClaimResultHandler;
|
||||
import io.lbry.browser.tasks.content.LogPublishTask;
|
||||
import io.lbry.browser.tasks.lbryinc.FetchInviteStatusTask;
|
||||
import io.lbry.browser.tasks.lbryinc.FetchReferralCodeTask;
|
||||
import io.lbry.browser.tasks.lbryinc.InviteByEmailTask;
|
||||
import io.lbry.browser.ui.BaseFragment;
|
||||
import io.lbry.browser.utils.Helper;
|
||||
import io.lbry.browser.utils.Lbry;
|
||||
import io.lbry.browser.utils.LbryUri;
|
||||
import io.lbry.browser.utils.Lbryio;
|
||||
|
||||
public class InvitesFragment extends BaseFragment implements SdkStatusListener, WalletBalanceListener {
|
||||
|
||||
private static final String INVITE_LINK_FORMAT = "https://lbry.tv/$/invite/%s:%s";
|
||||
|
||||
private boolean fetchingChannels;
|
||||
private View layoutAccountDriver;
|
||||
private View layoutSdkInitializing;
|
||||
private TextView textLearnMoreLink;
|
||||
private MaterialButton buttonGetStarted;
|
||||
|
||||
private View buttonCopyInviteLink;
|
||||
private TextView textInviteLink;
|
||||
private TextInputLayout layoutInputEmail;
|
||||
private TextInputEditText inputEmail;
|
||||
private MaterialButton buttonInviteByEmail;
|
||||
|
||||
private RecyclerView inviteHistoryList;
|
||||
private InviteeListAdapter inviteHistoryAdapter;
|
||||
private InlineChannelSpinnerAdapter channelSpinnerAdapter;
|
||||
private AppCompatSpinner channelSpinner;
|
||||
private View progressLoadingChannels;
|
||||
private View progressLoadingInviteByEmail;
|
||||
private View progressLoadingStatus;
|
||||
|
||||
private View inlineChannelCreator;
|
||||
private TextInputEditText inlineChannelCreatorInputName;
|
||||
private TextInputEditText inlineChannelCreatorInputDeposit;
|
||||
private View inlineChannelCreatorInlineBalance;
|
||||
private TextView inlineChannelCreatorInlineBalanceValue;
|
||||
private View inlineChannelCreatorCancelLink;
|
||||
private View inlineChannelCreatorProgress;
|
||||
private MaterialButton inlineChannelCreatorCreateButton;
|
||||
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
View root = inflater.inflate(R.layout.fragment_invites, container, false);
|
||||
|
||||
layoutAccountDriver = root.findViewById(R.id.invites_account_driver_container);
|
||||
layoutSdkInitializing = root.findViewById(R.id.container_sdk_initializing);
|
||||
textLearnMoreLink = root.findViewById(R.id.invites_account_driver_learn_more);
|
||||
buttonGetStarted = root.findViewById(R.id.invites_get_started_button);
|
||||
|
||||
textInviteLink = root.findViewById(R.id.invites_invite_link);
|
||||
buttonCopyInviteLink = root.findViewById(R.id.invites_copy_invite_link);
|
||||
layoutInputEmail = root.findViewById(R.id.invites_email_input_layout);
|
||||
inputEmail = root.findViewById(R.id.invites_email_input);
|
||||
buttonInviteByEmail = root.findViewById(R.id.invites_email_button);
|
||||
|
||||
progressLoadingChannels = root.findViewById(R.id.invites_loading_channels_progress);
|
||||
progressLoadingInviteByEmail = root.findViewById(R.id.invites_loading_invite_by_email_progress);
|
||||
progressLoadingStatus = root.findViewById(R.id.invites_loading_status_progress);
|
||||
|
||||
inviteHistoryList = root.findViewById(R.id.invite_history_list);
|
||||
LinearLayoutManager llm = new LinearLayoutManager(getContext());
|
||||
inviteHistoryList.setLayoutManager(llm);
|
||||
|
||||
channelSpinner = root.findViewById(R.id.invites_channel_spinner);
|
||||
|
||||
inlineChannelCreator = root.findViewById(R.id.container_inline_channel_form_create);
|
||||
inlineChannelCreatorInputName = root.findViewById(R.id.inline_channel_form_input_name);
|
||||
inlineChannelCreatorInputDeposit = root.findViewById(R.id.inline_channel_form_input_deposit);
|
||||
inlineChannelCreatorInlineBalance = root.findViewById(R.id.inline_channel_form_inline_balance_container);
|
||||
inlineChannelCreatorInlineBalanceValue = root.findViewById(R.id.inline_channel_form_inline_balance_value);
|
||||
inlineChannelCreatorProgress = root.findViewById(R.id.inline_channel_form_create_progress);
|
||||
inlineChannelCreatorCancelLink = root.findViewById(R.id.inline_channel_form_cancel_link);
|
||||
inlineChannelCreatorCreateButton = root.findViewById(R.id.inline_channel_form_create_button);
|
||||
|
||||
initUi();
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private void initUi() {
|
||||
layoutAccountDriver.setVisibility(Lbryio.isSignedIn() ? View.GONE : View.VISIBLE);
|
||||
layoutSdkInitializing.setVisibility(Lbry.SDK_READY ? View.GONE : View.VISIBLE);
|
||||
Helper.applyHtmlForTextView(textLearnMoreLink);
|
||||
|
||||
inputEmail.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View view, boolean hasFocus) {
|
||||
layoutInputEmail.setHint(hasFocus ? getString(R.string.email) :
|
||||
Helper.getValue(inputEmail.getText()).length() > 0 ?
|
||||
getString(R.string.email) : getString(R.string.invite_email_placeholder));
|
||||
}
|
||||
});
|
||||
inputEmail.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) {
|
||||
Helper.setViewEnabled(buttonInviteByEmail, charSequence.length() > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
|
||||
}
|
||||
});
|
||||
buttonInviteByEmail.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
String email = Helper.getValue(inputEmail.getText());
|
||||
if (email.indexOf("@") == -1) {
|
||||
showError(getString(R.string.provide_valid_email));
|
||||
return;
|
||||
}
|
||||
|
||||
InviteByEmailTask task = new InviteByEmailTask(email, progressLoadingInviteByEmail, new GenericTaskHandler() {
|
||||
@Override
|
||||
public void beforeStart() {
|
||||
Helper.setViewEnabled(buttonInviteByEmail, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
Snackbar.make(getView(), getString(R.string.invite_sent_to, email), Snackbar.LENGTH_LONG).show();
|
||||
Helper.setViewText(inputEmail, null);
|
||||
Helper.setViewEnabled(buttonInviteByEmail, true);
|
||||
fetchInviteStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception error) {
|
||||
showError(error.getMessage());
|
||||
Helper.setViewEnabled(buttonInviteByEmail, true);
|
||||
}
|
||||
});
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
});
|
||||
|
||||
buttonGetStarted.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Context context = getContext();
|
||||
if (context instanceof MainActivity) {
|
||||
((MainActivity) context).simpleSignIn();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (Lbry.ownChannels != null) {
|
||||
updateChannelList(Lbry.ownChannels);
|
||||
}
|
||||
|
||||
channelSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
|
||||
Object item = adapterView.getItemAtPosition(position);
|
||||
if (item instanceof Claim) {
|
||||
Claim claim = (Claim) item;
|
||||
if (claim.isPlaceholder()) {
|
||||
if (!fetchingChannels) {
|
||||
showInlineChannelCreator();
|
||||
}
|
||||
} else {
|
||||
hideInlineChannelCreator();
|
||||
// build invite link
|
||||
updateInviteLink(claim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
textInviteLink.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
copyInviteLink();
|
||||
}
|
||||
});
|
||||
buttonCopyInviteLink.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
copyInviteLink();
|
||||
}
|
||||
});
|
||||
|
||||
setupInlineChannelCreator(
|
||||
inlineChannelCreator,
|
||||
inlineChannelCreatorInputName,
|
||||
inlineChannelCreatorInputDeposit,
|
||||
inlineChannelCreatorInlineBalance,
|
||||
inlineChannelCreatorInlineBalanceValue,
|
||||
inlineChannelCreatorCancelLink,
|
||||
inlineChannelCreatorCreateButton,
|
||||
inlineChannelCreatorProgress
|
||||
);
|
||||
}
|
||||
|
||||
private void updateInviteLink(Claim claim) {
|
||||
String link = String.format(INVITE_LINK_FORMAT, claim.getName(), claim.getClaimId());
|
||||
textInviteLink.setText(link);
|
||||
}
|
||||
private void copyInviteLink() {
|
||||
Context context = getContext();
|
||||
if (context != null && textInviteLink != null) {
|
||||
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData data = ClipData.newPlainText("inviteLink", textInviteLink.getText());
|
||||
clipboard.setPrimaryClip(data);
|
||||
}
|
||||
Snackbar.make(getView(), R.string.invite_link_copied, Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private void updateChannelList(List<Claim> channels) {
|
||||
if (channelSpinnerAdapter == null) {
|
||||
Context context = getContext();
|
||||
channelSpinnerAdapter = new InlineChannelSpinnerAdapter(context, R.layout.spinner_item_channel, channels);
|
||||
channelSpinnerAdapter.addPlaceholder(false);
|
||||
channelSpinner.setAdapter(channelSpinnerAdapter);
|
||||
channelSpinnerAdapter.notifyDataSetChanged();
|
||||
} else {
|
||||
channelSpinnerAdapter.clear();
|
||||
channelSpinnerAdapter.addAll(channels);
|
||||
channelSpinnerAdapter.addPlaceholder(false);
|
||||
channelSpinnerAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
if (channelSpinnerAdapter.getCount() > 1) {
|
||||
channelSpinner.setSelection(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
layoutAccountDriver.setVisibility(Lbryio.isSignedIn() ? View.GONE : View.VISIBLE);
|
||||
|
||||
fetchInviteStatus();
|
||||
if (!Lbry.SDK_READY) {
|
||||
Context context = getContext();
|
||||
if (context instanceof MainActivity) {
|
||||
MainActivity activity = (MainActivity) context;
|
||||
activity.addSdkStatusListener(this);
|
||||
activity.addWalletBalanceListener(this);
|
||||
}
|
||||
} else {
|
||||
onSdkReady();
|
||||
}
|
||||
}
|
||||
|
||||
public void onSdkReady() {
|
||||
Helper.setViewVisibility(layoutSdkInitializing, View.GONE);
|
||||
fetchChannels();
|
||||
}
|
||||
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
Context context = getContext();
|
||||
if (context instanceof MainActivity) {
|
||||
MainActivity activity = (MainActivity) context;
|
||||
activity.setWunderbarValue(null);
|
||||
activity.hideFloatingWalletBalance();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearInputFocus() {
|
||||
inputEmail.clearFocus();
|
||||
inlineChannelCreatorInputName.clearFocus();
|
||||
inlineChannelCreatorInputDeposit.clearFocus();
|
||||
}
|
||||
|
||||
public void onStop() {
|
||||
clearInputFocus();
|
||||
|
||||
Context context = getContext();
|
||||
if (context instanceof MainActivity) {
|
||||
MainActivity activity = (MainActivity) context;
|
||||
activity.removeSdkStatusListener(this);
|
||||
activity.removeWalletBalanceListener(this);
|
||||
activity.showFloatingWalletBalance();
|
||||
}
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
private void showInlineChannelCreator() {
|
||||
Helper.setViewVisibility(inlineChannelCreator, View.VISIBLE);
|
||||
}
|
||||
private void hideInlineChannelCreator() {
|
||||
Helper.setViewVisibility(inlineChannelCreator, View.GONE);
|
||||
}
|
||||
|
||||
private void fetchDefaultInviteLink() {
|
||||
FetchReferralCodeTask task = new FetchReferralCodeTask(null, new FetchReferralCodeTask.FetchReferralCodeHandler() {
|
||||
@Override
|
||||
public void onSuccess(String referralCode) {
|
||||
String previousLink = Helper.getValue(textInviteLink.getText());
|
||||
if (Helper.isNullOrEmpty(previousLink)) {
|
||||
Helper.setViewText(textInviteLink, String.format("https://lbry.tv/$/invite/%s", referralCode));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception error) {
|
||||
// pass
|
||||
}
|
||||
});
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void disableChannelSpinner() {
|
||||
Helper.setViewEnabled(channelSpinner, false);
|
||||
hideInlineChannelCreator();
|
||||
}
|
||||
private void enableChannelSpinner() {
|
||||
Helper.setViewEnabled(channelSpinner, true);
|
||||
Claim selectedClaim = (Claim) channelSpinner.getSelectedItem();
|
||||
if (selectedClaim != null) {
|
||||
if (selectedClaim.isPlaceholder()) {
|
||||
showInlineChannelCreator();
|
||||
} else {
|
||||
hideInlineChannelCreator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchChannels() {
|
||||
fetchingChannels = true;
|
||||
disableChannelSpinner();
|
||||
ClaimListTask task = new ClaimListTask(Claim.TYPE_CHANNEL, progressLoadingChannels, new ClaimListResultHandler() {
|
||||
@Override
|
||||
public void onSuccess(List<Claim> claims) {
|
||||
Lbry.ownChannels = new ArrayList<>(claims);
|
||||
updateChannelList(Lbry.ownChannels);
|
||||
if (Lbry.ownChannels == null || Lbry.ownChannels.size() == 0) {
|
||||
fetchDefaultInviteLink();
|
||||
}
|
||||
enableChannelSpinner();
|
||||
fetchingChannels = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception error) {
|
||||
fetchDefaultInviteLink();
|
||||
enableChannelSpinner();
|
||||
fetchingChannels = false;
|
||||
}
|
||||
});
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void fetchInviteStatus() {
|
||||
FetchInviteStatusTask task = new FetchInviteStatusTask(progressLoadingStatus, new FetchInviteStatusTask.FetchInviteStatusHandler() {
|
||||
@Override
|
||||
public void onSuccess(List<Invitee> invitees) {
|
||||
if (inviteHistoryAdapter == null) {
|
||||
inviteHistoryAdapter = new InviteeListAdapter(invitees, getContext());
|
||||
inviteHistoryAdapter.addHeader();
|
||||
inviteHistoryList.setAdapter(inviteHistoryAdapter);
|
||||
} else {
|
||||
inviteHistoryAdapter.addInvitees(invitees);
|
||||
}
|
||||
Helper.setViewVisibility(inviteHistoryList,
|
||||
inviteHistoryAdapter == null || inviteHistoryAdapter.getItemCount() == 0 ? View.GONE : View.VISIBLE
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception error) {
|
||||
Helper.setViewVisibility(inviteHistoryList,
|
||||
inviteHistoryAdapter == null || inviteHistoryAdapter.getItemCount() == 0 ? View.GONE : View.VISIBLE
|
||||
);
|
||||
}
|
||||
});
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void setupInlineChannelCreator(
|
||||
View container,
|
||||
TextInputEditText inputChannelName,
|
||||
TextInputEditText inputDeposit,
|
||||
View inlineBalanceView,
|
||||
TextView inlineBalanceValue,
|
||||
View linkCancel,
|
||||
MaterialButton buttonCreate,
|
||||
View progressView) {
|
||||
inputDeposit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View view, boolean hasFocus) {
|
||||
Helper.setViewVisibility(inlineBalanceView, hasFocus ? View.VISIBLE : View.INVISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
linkCancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Helper.setViewText(inputChannelName, null);
|
||||
Helper.setViewText(inputDeposit, null);
|
||||
Helper.setViewVisibility(container, View.GONE);
|
||||
}
|
||||
});
|
||||
|
||||
buttonCreate.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
// validate deposit and channel name
|
||||
String channelNameString = Helper.getValue(inputChannelName.getText());
|
||||
if (!channelNameString.startsWith("@")) {
|
||||
channelNameString = String.format("@%s", channelNameString);
|
||||
}
|
||||
Claim claimToSave = new Claim();
|
||||
claimToSave.setName(channelNameString);
|
||||
String channelName = claimToSave.getName().startsWith("@") ? claimToSave.getName().substring(1) : claimToSave.getName();
|
||||
String depositString = Helper.getValue(inputDeposit.getText());
|
||||
if (Helper.isNullOrEmpty(channelName)) {
|
||||
showError(getString(R.string.please_enter_channel_name));
|
||||
return;
|
||||
}
|
||||
if (!LbryUri.isNameValid(channelName)) {
|
||||
showError(getString(R.string.channel_name_invalid_characters));
|
||||
return;
|
||||
}
|
||||
if (Helper.channelExists(channelName)) {
|
||||
showError(getString(R.string.channel_name_already_created));
|
||||
return;
|
||||
}
|
||||
|
||||
double depositAmount = 0;
|
||||
try {
|
||||
depositAmount = Double.valueOf(depositString);
|
||||
} catch (NumberFormatException ex) {
|
||||
// pass
|
||||
showError(getString(R.string.please_enter_valid_deposit));
|
||||
return;
|
||||
}
|
||||
if (depositAmount == 0) {
|
||||
String error = getResources().getQuantityString(R.plurals.min_deposit_required, depositAmount == 1 ? 1 : 2, String.valueOf(Helper.MIN_DEPOSIT));
|
||||
showError(error);
|
||||
return;
|
||||
}
|
||||
if (Lbry.walletBalance == null || Lbry.walletBalance.getAvailable().doubleValue() < depositAmount) {
|
||||
showError(getString(R.string.deposit_more_than_balance));
|
||||
return;
|
||||
}
|
||||
|
||||
ChannelCreateUpdateTask task = new ChannelCreateUpdateTask(
|
||||
claimToSave, new BigDecimal(depositString), false, progressView, new ClaimResultHandler() {
|
||||
@Override
|
||||
public void beforeStart() {
|
||||
Helper.setViewEnabled(inputChannelName, false);
|
||||
Helper.setViewEnabled(inputDeposit, false);
|
||||
Helper.setViewEnabled(buttonCreate, false);
|
||||
Helper.setViewEnabled(linkCancel, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Claim claimResult) {
|
||||
if (!BuildConfig.DEBUG) {
|
||||
LogPublishTask logPublishTask = new LogPublishTask(claimResult);
|
||||
logPublishTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
// add the claim to the channel list and set it as the selected item
|
||||
channelSpinnerAdapter.add(claimResult);
|
||||
channelSpinner.setSelection(channelSpinnerAdapter.getCount() - 1);
|
||||
|
||||
Helper.setViewEnabled(inputChannelName, true);
|
||||
Helper.setViewEnabled(inputDeposit, true);
|
||||
Helper.setViewEnabled(buttonCreate, true);
|
||||
Helper.setViewEnabled(linkCancel, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception error) {
|
||||
Helper.setViewEnabled(inputChannelName, true);
|
||||
Helper.setViewEnabled(inputDeposit, true);
|
||||
Helper.setViewEnabled(buttonCreate, true);
|
||||
Helper.setViewEnabled(linkCancel, true);
|
||||
showError(error.getMessage());
|
||||
}
|
||||
});
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
});
|
||||
|
||||
Helper.setViewText(inlineBalanceValue, Helper.shortCurrencyFormat(Lbry.walletBalance.getAvailable().doubleValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWalletBalanceUpdated(WalletBalance walletBalance) {
|
||||
if (walletBalance != null && inlineChannelCreatorInlineBalanceValue != null) {
|
||||
inlineChannelCreatorInlineBalanceValue.setText(Helper.shortCurrencyFormat(walletBalance.getAvailable().doubleValue()));
|
||||
}
|
||||
}
|
||||
|
||||
private void showError(String message) {
|
||||
Context context = getContext();
|
||||
if (context != null) {
|
||||
Snackbar.make(getView(), message, Snackbar.LENGTH_LONG).setBackgroundTint(Color.RED).show();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,8 +27,8 @@ import io.lbry.browser.R;
|
|||
import io.lbry.browser.adapter.RewardListAdapter;
|
||||
import io.lbry.browser.listener.SdkStatusListener;
|
||||
import io.lbry.browser.model.lbryinc.Reward;
|
||||
import io.lbry.browser.tasks.ClaimRewardTask;
|
||||
import io.lbry.browser.tasks.FetchRewardsTask;
|
||||
import io.lbry.browser.tasks.lbryinc.ClaimRewardTask;
|
||||
import io.lbry.browser.tasks.lbryinc.FetchRewardsTask;
|
||||
import io.lbry.browser.ui.BaseFragment;
|
||||
import io.lbry.browser.utils.Helper;
|
||||
import io.lbry.browser.utils.Lbry;
|
||||
|
@ -130,6 +130,11 @@ public class RewardsFragment extends BaseFragment implements RewardListAdapter.R
|
|||
Lbryio.updateRewardsLists(rewards);
|
||||
updateUnclaimedRewardsValue();
|
||||
|
||||
Context context = getContext();
|
||||
if (context instanceof MainActivity) {
|
||||
((MainActivity) context).showFloatingUnclaimedRewards();
|
||||
}
|
||||
|
||||
if (adapter == null) {
|
||||
adapter = new RewardListAdapter(rewards, getContext());
|
||||
adapter.setClickListener(RewardsFragment.this);
|
||||
|
|
|
@ -250,7 +250,7 @@ public final class Lbryio {
|
|||
JSONObject response = (JSONObject) parseResponse(Lbryio.call("lbc", "exchange_rate", null));
|
||||
LBCUSDRate = Helper.getJSONDouble("lbc_usd", 0, response);
|
||||
} catch (LbryioResponseException | LbryioRequestException | ClassCastException ex) {
|
||||
|
||||
// pass
|
||||
}
|
||||
}
|
||||
|
||||
|
|
62
app/src/main/res/layout/card_invites_by_email.xml
Normal file
62
app/src/main/res/layout/card_invites_by_email.xml
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/invite_by_email"
|
||||
android:textSize="20sp"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="@string/invite_someone"
|
||||
android:textSize="14sp"
|
||||
android:textFontWeight="300" />
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/invites_email_input_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp">
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/invites_email_input"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:hint="@string/invite_email_placeholder"
|
||||
android:textSize="14sp"
|
||||
android:textFontWeight="300" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp">
|
||||
<ProgressBar
|
||||
android:id="@+id/invites_loading_invite_by_email_progress"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginRight="24dp"
|
||||
android:layout_toLeftOf="@id/invites_email_button"
|
||||
android:visibility="gone" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/invites_email_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:enabled="false"
|
||||
android:text="@string/invite" />
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
101
app/src/main/res/layout/card_invites_by_link.xml
Normal file
101
app/src/main/res/layout/card_invites_by_link.xml
Normal file
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/invite_link"
|
||||
android:textSize="20sp"/>
|
||||
<ProgressBar
|
||||
android:id="@+id/invites_loading_channels_progress"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:visibility="gone" />
|
||||
</RelativeLayout>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="@string/share_this_link"
|
||||
android:textSize="14sp"
|
||||
android:textFontWeight="300" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="@string/your_invite_link"
|
||||
android:textSize="14sp"
|
||||
android:textFontWeight="300" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:orientation="horizontal">
|
||||
<LinearLayout
|
||||
android:background="@drawable/bg_copyable_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toLeftOf="@id/invites_copy_invite_link"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingRight="12dp">
|
||||
<TextView
|
||||
android:id="@+id/invites_invite_link"
|
||||
android:clickable="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="14sp"
|
||||
android:letterSpacing="0.05"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="middle" />
|
||||
</LinearLayout>
|
||||
<ImageButton
|
||||
android:id="@+id/invites_copy_invite_link"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="@null"
|
||||
android:src="@drawable/ic_copy"
|
||||
android:tint="@color/lbryGreen"
|
||||
android:layout_alignParentRight="true" />
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="@string/customize_invite_link"
|
||||
android:textSize="14sp"
|
||||
android:textFontWeight="300" />
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/invites_channel_spinner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp" />
|
||||
|
||||
<include layout="@layout/container_inline_channel_form" />
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
45
app/src/main/res/layout/card_invites_history.xml
Normal file
45
app/src/main/res/layout/card_invites_history.xml
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="12dp">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/invite_history"
|
||||
android:textSize="20sp"/>
|
||||
<ProgressBar
|
||||
android:id="@+id/invites_loading_status_progress"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:visibility="gone" />
|
||||
</RelativeLayout>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="@string/earn_credits_for_inviting"
|
||||
android:textSize="14sp"
|
||||
android:textFontWeight="300" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/invite_history_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
|
@ -40,7 +40,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:background="@drawable/bg_wallet_address"
|
||||
android:background="@drawable/bg_copyable_text"
|
||||
android:textSize="14sp"
|
||||
android:letterSpacing="0.05"
|
||||
android:paddingTop="8dp"
|
||||
|
|
119
app/src/main/res/layout/container_inline_channel_form.xml
Normal file
119
app/src/main/res/layout/container_inline_channel_form.xml
Normal file
|
@ -0,0 +1,119 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/container_inline_channel_form_create"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/inline_channel_form_input_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:hint="@string/channel_name"
|
||||
android:textFontWeight="300"
|
||||
android:textSize="14sp" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/inline_channel_form_layout_deposit"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/deposit">
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/inline_channel_form_input_deposit"
|
||||
android:fontFamily="@font/inter"
|
||||
android:singleLine="true"
|
||||
android:textSize="14sp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="numberDecimal" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/inline_channel_form_inline_currency"
|
||||
android:layout_toRightOf="@id/inline_channel_form_layout_deposit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="@string/lbc"
|
||||
android:textAllCaps="true"
|
||||
android:textSize="10sp"
|
||||
android:textFontWeight="300" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/inline_channel_form_inline_balance_container"
|
||||
android:layout_toRightOf="@id/inline_channel_form_inline_currency"
|
||||
android:layout_marginLeft="24dp"
|
||||
android:layout_marginTop="28dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="invisible">
|
||||
<io.lbry.browser.ui.controls.SolidIconView
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:text="@string/fa_coins" />
|
||||
<TextView
|
||||
android:id="@+id/inline_channel_form_inline_balance_value"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textFontWeight="300"
|
||||
android:layout_marginLeft="2dp" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="@string/deposit_remains_yours"
|
||||
android:textFontWeight="300"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp">
|
||||
<TextView
|
||||
android:id="@+id/inline_channel_form_cancel_link"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="12sp"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/inline_channel_form_create_progress"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginRight="24dp"
|
||||
android:layout_toLeftOf="@id/inline_channel_form_create_button"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/inline_channel_form_create_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="@string/create"/>
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
85
app/src/main/res/layout/fragment_invites.xml
Normal file
85
app/src/main/res/layout/fragment_invites.xml
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/pageBackground">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
<include layout="@layout/card_invites_by_link" />
|
||||
|
||||
<include layout="@layout/card_invites_by_email" />
|
||||
|
||||
<include layout="@layout/card_invites_history" />
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<include layout="@layout/container_sdk_initializing" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/invites_account_driver_container"
|
||||
android:background="@color/lbryGreen"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@id/invites_account_driver_actions"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/invites_account_driver_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="@string/lbry_invite_program"
|
||||
android:textSize="24sp"
|
||||
android:textColor="@color/white" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/earn_extra_credits_invites"
|
||||
android:textColor="@color/white"
|
||||
android:textFontWeight="300" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/invites_account_driver_learn_more"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/invites_learn_more"
|
||||
android:textColor="@color/white"
|
||||
android:textFontWeight="300" />
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/invites_account_driver_actions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true">
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/invites_get_started_button"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/inter"
|
||||
android:text="@string/get_started" />
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
|
@ -4,7 +4,6 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/pageBackground">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
37
app/src/main/res/layout/list_item_invitee.xml
Normal file
37
app/src/main/res/layout/list_item_invitee.xml
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:weightSum="10">
|
||||
<RelativeLayout
|
||||
android:layout_weight="6"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="4dp">
|
||||
<TextView
|
||||
android:id="@+id/invitee_email"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="middle"
|
||||
android:fontFamily="@font/inter"
|
||||
android:singleLine="true"
|
||||
android:textSize="14sp"
|
||||
android:textFontWeight="300" />
|
||||
</RelativeLayout>
|
||||
<RelativeLayout
|
||||
android:layout_weight="4"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="4dp">
|
||||
<TextView
|
||||
android:id="@+id/invitee_reward"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="14sp"
|
||||
android:textFontWeight="300" />
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
|
@ -9,8 +9,8 @@
|
|||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="10">
|
||||
<RelativeLayout
|
||||
|
@ -109,7 +109,7 @@
|
|||
android:fontFamily="@font/inter"
|
||||
android:textSize="10sp"
|
||||
android:textFontWeight="300"
|
||||
android:visibility="invisible" />
|
||||
android:visibility="gone" />
|
||||
<TextView
|
||||
android:id="@+id/reward_item_lbc_value"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -129,7 +129,7 @@
|
|||
android:id="@+id/reward_item_usd_value"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="12sp"
|
||||
|
|
14
app/src/main/res/layout/spinner_item_channel.xml
Normal file
14
app/src/main/res/layout/spinner_item_channel.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="12dp">
|
||||
<TextView
|
||||
android:id="@+id/channel_item_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="14sp"
|
||||
android:textFontWeight="300" />
|
||||
</LinearLayout>
|
|
@ -247,6 +247,7 @@
|
|||
<!-- Channels -->
|
||||
<string name="no_channel_created">You have not created a channel.\nStart now by creating a new channel!</string>
|
||||
<string name="create_a_channel">Create a channel</string>
|
||||
<string name="create_a_channel_item">Create a channel...</string>
|
||||
<string name="edit_channel">Edit channel</string>
|
||||
<string name="delete_selection">Delete selection?</string>
|
||||
<string name="description">Description</string>
|
||||
|
@ -278,6 +279,7 @@
|
|||
<string name="channel_save_successful">The channel was successfully saved.</string>
|
||||
<string name="item_pending_blockchain">The claim is pending publish on the blockchain. You will be able to access or edit the claim in a few moments.</string>
|
||||
<string name="pending">Pending</string>
|
||||
<string name="create">Create</string>
|
||||
<plurals name="min_deposit_required">
|
||||
<item quantity="one">A minimum deposit of %1$s credit is required.</item>
|
||||
<item quantity="other">A minimum deposit of %1$s credits is required.</item>
|
||||
|
@ -308,6 +310,27 @@
|
|||
<item quantity="other">%1$s available credits</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Invites -->
|
||||
<string name="lbry_invite_program">LBRY Invite Program</string>
|
||||
<string name="earn_extra_credits_invites">You can earn extra credits for each person you invite to use LBRY.</string>
|
||||
<string name="invites_learn_more"><a href="https://lbry.com/faq/invites">Learn more</a>.</string>
|
||||
<string name="invite_link">Invite Link</string>
|
||||
<string name="share_this_link">Share this link with friends (or enemies) and get credits when they join lbry.tv.</string>
|
||||
<string name="your_invite_link">Your invite link</string>
|
||||
<string name="customize_invite_link">Customize invite link</string>
|
||||
<string name="invite_by_email">Invite by Email</string>
|
||||
<string name="invite_someone">Invite someone you know by email and earn credits when they join lbry.tv.</string>
|
||||
<string name="invite_email_placeholder">imaginary@friend.com</string>
|
||||
<string name="invite">Invite</string>
|
||||
<string name="invite_history">Invite History</string>
|
||||
<string name="earn_credits_for_inviting">Earn credits for invite a friend, an enemy, a frenemy, or an enefriend. Everyone needs content freedom.</string>
|
||||
<string name="reward">Reward</string>
|
||||
<string name="claimed">Claimed</string>
|
||||
<string name="claimable">Claimable</string>
|
||||
<string name="unclaimable">Unclaimable</string>
|
||||
<string name="invite_link_copied">Invite link copied.</string>
|
||||
<string name="invite_sent_to">Invite sent to %1$s</string>
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<string name="fa_gift"></string>
|
||||
<string name="fa_lock"></string>
|
||||
|
|
Loading…
Reference in a new issue