Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replaced WalletConnect request popup with ActionSheet. #2417

Merged
merged 5 commits into from
Mar 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import android.text.Spannable;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
Expand Down Expand Up @@ -77,8 +76,6 @@
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import dagger.hilt.android.AndroidEntryPoint;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
Expand All @@ -104,6 +101,7 @@ public class WalletConnectActivity extends BaseActivity implements ActionSheetCa
private WCPeerMeta remotePeerMeta;

private ActionSheetDialog confirmationDialog;
private ActionSheetDialog walletConnectDialog;

private ImageView icon;
private TextView peerName;
Expand Down Expand Up @@ -663,7 +661,7 @@ private void displaySessionStatus(String sessionId)
if (result.getData() == null) return;
chainIdOverride = result.getData().getLongExtra(C.EXTRA_CHAIN_ID, MAINNET_ID);
Toast.makeText(this, getText(R.string.hint_network_name) + " " + EthereumNetworkBase.getShortChainName(chainIdOverride), Toast.LENGTH_LONG).show();
onSessionRequest(0L, remotePeerMeta, chainIdOverride);
walletConnectDialog.updateChain(chainIdOverride);
});

private void onSessionRequest(Long id, WCPeerMeta peer, long chainId)
Expand All @@ -672,6 +670,12 @@ private void onSessionRequest(Long id, WCPeerMeta peer, long chainId)

closeErrorDialog();

if (walletConnectDialog != null) {
if (walletConnectDialog.isShowing()) { // if already opened
walletConnectDialog.forceDismiss();
}
}

String[] accounts = {viewModel.getWallet().address};
String displayIcon = (peer.getIcons().size() > 0) ? peer.getIcons().get(0) : DEFAULT_IDON;

Expand All @@ -689,51 +693,9 @@ private void onSessionRequest(Long id, WCPeerMeta peer, long chainId)
chainIcon.bindData(viewModel.getTokensService().getServiceToken(chainIdOverride));
remotePeerMeta = peer;

AlertDialog.Builder builder = new AlertDialog.Builder(WalletConnectActivity.this);
AlertDialog dialog = builder
.setIcon(icon.getDrawable())
.setTitle(peer.getName())
.setMessage(buildMessage(peer.getUrl(), chainIdOverride))
.setPositiveButton(R.string.dialog_approve, (d, w) -> {
client.approveSession(Arrays.asList(accounts), chainIdOverride);
//update client in service
viewModel.putClient(this, getSessionId(), client);
viewModel.createNewSession(getSessionId(), client.getPeerId(), client.getRemotePeerId(),
new Gson().toJson(session), new Gson().toJson(peer), chainIdOverride);
progressBar.setVisibility(View.GONE);
functionBar.setVisibility(View.VISIBLE);
infoLayout.setVisibility(View.VISIBLE);
setupClient(getSessionId());
if (fromDappBrowser)
{
//switch back to dappBrowser
switchToDappBrowser();
}
})
.setNeutralButton(R.string.hint_network_chain_id, (d, w) -> {
//pop open the selection dialog
Intent intent = new Intent(this, SelectNetworkActivity.class);
intent.putExtra(C.EXTRA_SINGLE_ITEM, true);
intent.putExtra(C.EXTRA_CHAIN_ID, chainIdOverride);
getNetwork.launch(intent);
})
.setNegativeButton(R.string.dialog_reject, (d, w) -> {
client.rejectSession(getString(R.string.message_reject_request));
finish();
})
.setCancelable(false)
.create();
dialog.show();
}

private Spannable buildMessage(String url, long networkId)
{
StyledStringBuilder sb = new StyledStringBuilder();
sb.append(url);
sb.startStyleGroup().append("\n\n").append(EthereumNetworkBase.getShortChainName(networkId));
sb.setColor(ContextCompat.getColor(this, EthereumNetworkBase.getChainColour(networkId)));
sb.applyStyles();
return sb;
walletConnectDialog = new ActionSheetDialog(this, peer, chainId, displayIcon, this);
walletConnectDialog.show();
walletConnectDialog.fullExpand();
}

private void onEthSign(Long id, WCEthereumSignMessage message)
Expand Down Expand Up @@ -1222,4 +1184,43 @@ public void DAppReturn(byte[] data, Signable message)
viewModel.signTransaction(getBaseContext(), tx, dappFunction, peerUrl.getText().toString(), viewModel.getChainId(getSessionId()));
if (fromDappBrowser) switchToDappBrowser();
}

@Override
public void notifyWalletConnectApproval(long selectedChain)
{
client.approveSession(Collections.singletonList(viewModel.getWallet().address), selectedChain);
//update client in service
viewModel.putClient(WalletConnectActivity.this, getSessionId(), client);
viewModel.createNewSession(getSessionId(), client.getPeerId(), client.getRemotePeerId(),
new Gson().toJson(session), new Gson().toJson(remotePeerMeta), selectedChain);
chainName.setChainID(selectedChain);
chainIcon.setVisibility(View.VISIBLE);
chainIcon.bindData(viewModel.getTokensService().getServiceToken(selectedChain));
progressBar.setVisibility(View.GONE);
functionBar.setVisibility(View.VISIBLE);
infoLayout.setVisibility(View.VISIBLE);
chainIdOverride = selectedChain;
setupClient(getSessionId()); //should populate this activity
if (fromDappBrowser)
{
//switch back to dappBrowser
switchToDappBrowser();
}
}

@Override
public void denyWalletConnect()
{
client.rejectSession(getString(R.string.message_reject_request));
finish();
}

@Override
public void openChainSelection() {
ActionSheetCallback.super.openChainSelection();
Intent intent = new Intent(WalletConnectActivity.this, SelectNetworkActivity.class);
intent.putExtra(C.EXTRA_SINGLE_ITEM, true);
intent.putExtra(C.EXTRA_CHAIN_ID, chainIdOverride);
getNetwork.launch(intent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import com.alphawallet.app.entity.SignAuthenticationCallback;
import com.alphawallet.app.entity.tokens.Token;
import com.alphawallet.app.walletconnect.entity.WCPeerMeta;
import com.alphawallet.app.web3.entity.Web3Transaction;

/**
Expand All @@ -18,4 +19,8 @@ public interface ActionSheetCallback
default void signTransaction(Web3Transaction tx) { } // only WalletConnect uses this so far

default void buttonClick(long callbackId, Token baseToken) { }; //for message only actionsheet

default void notifyWalletConnectApproval(long chainId) { }; // used by WalletConnectRequest
default void denyWalletConnect() { };
default void openChainSelection() { }; // used by WalletConnectRequest
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.alphawallet.app.ui.widget.entity;

public interface WalletConnectWidgetCallback {
void openChainSelection();
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
import android.widget.ImageView;
import android.widget.TextView;

import androidx.activity.ComponentActivity;
import androidx.annotation.NonNull;

import com.alphawallet.app.C;
import com.alphawallet.app.R;
import com.alphawallet.app.entity.ActionSheetInterface;
import com.alphawallet.app.entity.ContractType;
import com.alphawallet.app.entity.GlideApp;
import com.alphawallet.app.entity.SignAuthenticationCallback;
import com.alphawallet.app.entity.StandardFunctionInterface;
import com.alphawallet.app.entity.Transaction;
Expand All @@ -26,8 +28,10 @@
import com.alphawallet.app.ui.WalletConnectActivity;
import com.alphawallet.app.ui.widget.entity.ActionSheetCallback;
import com.alphawallet.app.util.Utils;
import com.alphawallet.app.walletconnect.entity.WCPeerMeta;
import com.alphawallet.app.web3.entity.Web3Transaction;
import com.alphawallet.token.entity.Signable;
import com.bumptech.glide.Glide;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.bottomsheet.BottomSheetDialog;

Expand Down Expand Up @@ -57,6 +61,7 @@ public class ActionSheetDialog extends BottomSheetDialog implements StandardFunc
private final AssetDetailView assetDetailView;
private final FunctionButtonBar functionBar;
private final TransactionDetailWidget detailWidget;
private final WalletConnectRequestWidget walletConnectRequestWidget; // TODO final
private final Activity activity;

private final Token token;
Expand Down Expand Up @@ -108,6 +113,7 @@ else if (activity instanceof WalletConnectActivity)
}

signCallback = null;
walletConnectRequestWidget = null;

actionSheetCallback = aCallBack;
actionCompleted = false;
Expand Down Expand Up @@ -178,6 +184,7 @@ public ActionSheetDialog(@NonNull Activity activity, ActionSheetCallback aCallba
tokensService = null;
candidateTransaction = null;
actionCompleted = false;
walletConnectRequestWidget = null;

addressDetail.setupRequester(message.getOrigin());
SignDataWidget signWidget = findViewById(R.id.sign_widget);
Expand Down Expand Up @@ -222,13 +229,63 @@ public ActionSheetDialog(@NonNull Activity activity, ActionSheetCallback aCallba
token = baseToken;
tokensService = null;
candidateTransaction = null;
walletConnectRequestWidget = null;

functionBar.setupFunctions(this, new ArrayList<>(Collections.singletonList(buttonTextId)));
functionBar.revealButtons();
setupCancelListeners();
isAttached = true;
}

// wallet connect request
public ActionSheetDialog(Activity activity, WCPeerMeta wcPeerMeta, long chainIdOverride, String iconUrl, ActionSheetCallback actionSheetCallback) {
super(activity);
setContentView(R.layout.dialog_wallet_connect_sheet);
mode = ActionSheetMode.WALLET_CONNECT_REQUEST;

ImageView logo = findViewById(R.id.image_logo);
cancelButton = findViewById(R.id.image_close);
functionBar = findViewById(R.id.layoutButtons);


this.activity = activity;
this.actionSheetCallback = actionSheetCallback;

walletConnectRequestWidget = findViewById(R.id.wallet_connect_widget);
gasWidget = null;
balanceDisplay = null;
confirmationWidget = null;
addressDetail = null;
amountDisplay = null;
assetDetailView = null;
detailWidget = null;
token = null;
tokensService = null;
candidateTransaction = null;
callbackId = 0;
isAttached = true;

Glide.with(activity)
.load(iconUrl)
.circleCrop()
.into(logo);

TextView title = findViewById(R.id.text_title);
title.setText(wcPeerMeta.getName());

cancelButton.setOnClickListener( v -> {
actionSheetCallback.denyWalletConnect();
});

walletConnectRequestWidget.setupWidget(wcPeerMeta, chainIdOverride, actionSheetCallback::openChainSelection);

ArrayList<Integer> functionList = new ArrayList<>();
functionList.add(R.string.approve);
functionList.add(R.string.dialog_reject);
functionBar.setupFunctions(this, functionList);
functionBar.revealButtons();
}

public void setSignOnly()
{
//sign only, and return signature to process
Expand Down Expand Up @@ -326,6 +383,17 @@ public void handleClick(String action, int id)
case MESSAGE:
actionSheetCallback.buttonClick(callbackId, token);
break;
case WALLET_CONNECT_REQUEST:
if (id == R.string.approve)
{
actionSheetCallback.notifyWalletConnectApproval(walletConnectRequestWidget.getChainIdOverride());
tryDismiss();
}
else
{
actionSheetCallback.denyWalletConnect();
}
break;
}

actionSheetCallback.notifyConfirm(mode.toString());
Expand Down Expand Up @@ -650,4 +718,8 @@ public void waitForEstimate()
{
functionBar.setPrimaryButtonWaiting();
}

public void updateChain(long chainId) {
walletConnectRequestWidget.updateChain(chainId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ public enum ActionSheetMode
SIGN_TRANSACTION,
SPEEDUP_TRANSACTION,
CANCEL_TRANSACTION,
MESSAGE
MESSAGE,
WALLET_CONNECT_REQUEST
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.alphawallet.app.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.ColorRes;
import androidx.core.content.ContextCompat;

import com.alphawallet.app.R;

import org.w3c.dom.Text;

import javax.annotation.Nullable;

public class DialogInfoItem extends LinearLayout {

private final TextView label;
private final TextView message;
private final TextView actionText;

public DialogInfoItem(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
inflate(context, R.layout.item_dialog_info, this);
label = findViewById(R.id.text_label);
message = findViewById(R.id.text_message);
actionText = findViewById(R.id.text_action);
getAttrs(context, attrs);
}

private void getAttrs(Context context, AttributeSet attrs) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.DialogInfoItem,
0, 0);

boolean showAction = a.getBoolean(R.styleable.DialogInfoItem_showActionText, false);
setLabel(a.getString(R.styleable.DialogInfoItem_title));
setMessage(a.getString(R.styleable.DialogInfoItem_text));
actionText.setVisibility( showAction ? VISIBLE : GONE);
}

public void setLabel(String label) {
this.label.setText(label);
}

public void setMessage(String msg) {
this.message.setText(msg);
}

public void setMessageTextColor(@ColorRes int color) {
this.message.setTextColor(ContextCompat.getColor(getContext(), color));
}

public void setActionText(String text) {
this.actionText.setText(text);
}

public void setActionListener(View.OnClickListener listener) {
actionText.setOnClickListener(listener);
}
}
Loading