mirror of https://github.com/m2049r/xmrwallet.git
tx notes added + tx details + tweaks
This commit is contained in:
parent
a37ca4c0e5
commit
37414be4bf
|
@ -774,7 +774,8 @@ Java_com_m2049r_xmrwallet_model_Wallet_createTransactionJ(JNIEnv *env, jobject i
|
|||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_createSweepUnmixableTransactionJ(JNIEnv *env, jobject instance) {
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_createSweepUnmixableTransactionJ(JNIEnv *env,
|
||||
jobject instance) {
|
||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||
Bitmonero::PendingTransaction *tx = wallet->createSweepUnmixableTransaction();
|
||||
return reinterpret_cast<jlong>(tx);
|
||||
|
@ -839,12 +840,40 @@ Java_com_m2049r_xmrwallet_model_Wallet_setDefaultMixin(JNIEnv *env, jobject inst
|
|||
return wallet->setDefaultMixin(mixin);
|
||||
}
|
||||
|
||||
//virtual bool setUserNote(const std::string &txid, const std::string ¬e) = 0;
|
||||
//virtual std::string getUserNote(const std::string &txid) const = 0;
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_setUserNote(JNIEnv *env, jobject instance,
|
||||
jstring txid, jstring note) {
|
||||
|
||||
const char *_txid = env->GetStringUTFChars(txid, JNI_FALSE);
|
||||
const char *_note = env->GetStringUTFChars(note, JNI_FALSE);
|
||||
|
||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||
|
||||
bool success = wallet->setUserNote(_txid, _note);
|
||||
|
||||
env->ReleaseStringUTFChars(txid, _txid);
|
||||
env->ReleaseStringUTFChars(note, _note);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_getUserNote(JNIEnv *env, jobject instance,
|
||||
jstring txid) {
|
||||
|
||||
const char *_txid = env->GetStringUTFChars(txid, JNI_FALSE);
|
||||
|
||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||
|
||||
std::string note = wallet->getUserNote(_txid);
|
||||
|
||||
env->ReleaseStringUTFChars(txid, _txid);
|
||||
return env->NewStringUTF(note.c_str());
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_getTxKey(JNIEnv *env, jobject instance,
|
||||
jstring txid) {
|
||||
jstring txid) {
|
||||
|
||||
const char *_txid = env->GetStringUTFChars(txid, JNI_FALSE);
|
||||
|
||||
|
@ -883,8 +912,10 @@ jobject newTransferInstance(JNIEnv *env, uint64_t amount, const std::string &add
|
|||
|
||||
jobject newTransferList(JNIEnv *env, Bitmonero::TransactionInfo *info) {
|
||||
const std::vector<Bitmonero::TransactionInfo::Transfer> &transfers = info->transfers();
|
||||
if (transfers.size()==0) { // don't create empty Lists
|
||||
return nullptr;
|
||||
}
|
||||
// make new ArrayList
|
||||
|
||||
jmethodID java_util_ArrayList_ = env->GetMethodID(class_ArrayList, "<init>", "(I)V");
|
||||
jmethodID java_util_ArrayList_add = env->GetMethodID(class_ArrayList, "add",
|
||||
"(Ljava/lang/Object;)Z");
|
||||
|
@ -932,8 +963,11 @@ jobject cpp2java(JNIEnv *env, std::vector<Bitmonero::TransactionInfo *> vector)
|
|||
|
||||
jobject arrayList = env->NewObject(class_ArrayList, java_util_ArrayList_, vector.size());
|
||||
for (Bitmonero::TransactionInfo *s: vector) {
|
||||
if (s->fee()>1) {
|
||||
LOGE("TX %s %" PRIu64 " %" PRIu64, s->hash().c_str(), s->fee(), s->amount());
|
||||
if (s->fee() > 1) {
|
||||
LOGE("TX %s %"
|
||||
PRIu64
|
||||
" %"
|
||||
PRIu64, s->hash().c_str(), s->fee(), s->amount());
|
||||
}
|
||||
jobject info = newTransactionInfo(env, s);
|
||||
env->CallBooleanMethod(arrayList, java_util_ArrayList_add, info);
|
||||
|
@ -995,13 +1029,20 @@ Java_com_m2049r_xmrwallet_model_PendingTransaction_getFee(JNIEnv *env, jobject i
|
|||
return tx->fee();
|
||||
}
|
||||
|
||||
/* TODO this returns a vector of strings - deal with this later
|
||||
// TODO this returns a vector of strings - deal with this later - for now return first one
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_PendingTransaction_getTxId(JNIEnv *env, jobject instance) {
|
||||
Java_com_m2049r_xmrwallet_model_PendingTransaction_getFirstTxId(JNIEnv *env, jobject instance) {
|
||||
Bitmonero::PendingTransaction *tx = getHandle<Bitmonero::PendingTransaction>(env, instance);
|
||||
return env->NewStringUTF(tx->txid().c_str());
|
||||
|
||||
std::vector<std::string> txids = tx->txid();
|
||||
|
||||
for (std::string &s: txids) {
|
||||
LOGD("TX %s", s.c_str());
|
||||
}
|
||||
|
||||
return env->NewStringUTF(txids.front().c_str());
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_PendingTransaction_getTxCount(JNIEnv *env, jobject instance) {
|
||||
|
|
|
@ -27,7 +27,6 @@ import android.content.Intent;
|
|||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.Log;
|
||||
|
@ -274,13 +273,13 @@ public class LoginActivity extends AppCompatActivity
|
|||
Log.d(TAG, "GenerateReviewFragment placed");
|
||||
}
|
||||
|
||||
void replaceFragment(Fragment newFragment, String name, Bundle extras) {
|
||||
void replaceFragment(Fragment newFragment, String stackName, Bundle extras) {
|
||||
if (extras != null) {
|
||||
newFragment.setArguments(extras);
|
||||
}
|
||||
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
||||
transaction.replace(R.id.fragment_container, newFragment);
|
||||
transaction.addToBackStack(name);
|
||||
transaction.addToBackStack(stackName);
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,12 @@
|
|||
package com.m2049r.xmrwallet;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
|
@ -36,6 +40,8 @@ import android.widget.Spinner;
|
|||
import android.widget.TextView;
|
||||
|
||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||
import com.m2049r.xmrwallet.model.Transfer;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
|
@ -56,6 +62,7 @@ public class SendFragment extends Fragment {
|
|||
TextView tvTxAmount;
|
||||
TextView tvTxFee;
|
||||
TextView tvTxDust;
|
||||
EditText etNotes;
|
||||
Button bSend;
|
||||
ProgressBar pbProgress;
|
||||
|
||||
|
@ -84,12 +91,14 @@ public class SendFragment extends Fragment {
|
|||
tvTxAmount = (TextView) view.findViewById(R.id.tvTxAmount);
|
||||
tvTxFee = (TextView) view.findViewById(R.id.tvTxFee);
|
||||
tvTxDust = (TextView) view.findViewById(R.id.tvTxDust);
|
||||
etNotes = (EditText) view.findViewById(R.id.etNotes);
|
||||
bSend = (Button) view.findViewById(R.id.bSend);
|
||||
|
||||
pbProgress = (ProgressBar) view.findViewById(R.id.pbProgress);
|
||||
|
||||
etAddress.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||
etPaymentId.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||
etNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||
|
||||
etAddress.setText("9tDC52GsMjTNt4dpnRCwAF7ekVBkbkgkXGaMKTcSTpBhGpqkPX56jCNRydLq9oGjbbAQBsZhLfgmTKsntmxRd3TaJFYM2f8");
|
||||
boolean testnet = WalletManager.getInstance().isTestNet();
|
||||
|
@ -143,6 +152,8 @@ public class SendFragment extends Fragment {
|
|||
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) {
|
||||
if (amountOk()) {
|
||||
Helper.hideKeyboard(getActivity());
|
||||
disableEdit();
|
||||
prepareSend();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -175,6 +186,7 @@ public class SendFragment extends Fragment {
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
Helper.hideKeyboard(getActivity());
|
||||
disableEdit();
|
||||
prepareSend();
|
||||
}
|
||||
});
|
||||
|
@ -196,11 +208,22 @@ public class SendFragment extends Fragment {
|
|||
}
|
||||
});
|
||||
|
||||
bSend.setOnClickListener(new View.OnClickListener()
|
||||
etNotes.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) {
|
||||
if (amountOk()) {
|
||||
Helper.hideKeyboard(getActivity());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
{
|
||||
bSend.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
bSend.setEnabled(false);
|
||||
send();
|
||||
}
|
||||
});
|
||||
|
@ -248,8 +271,6 @@ public class SendFragment extends Fragment {
|
|||
amount,
|
||||
mixin,
|
||||
priority);
|
||||
|
||||
disableEdit();
|
||||
showProgress();
|
||||
activityCallback.onPrepareSend(txData);
|
||||
}
|
||||
|
@ -286,8 +307,9 @@ public class SendFragment extends Fragment {
|
|||
}
|
||||
|
||||
private void send() {
|
||||
disableEdit(); // prevent this being sent more than once
|
||||
activityCallback.onSend();
|
||||
etNotes.setEnabled(false);
|
||||
String notes = etNotes.getText().toString();
|
||||
activityCallback.onSend(notes);
|
||||
}
|
||||
|
||||
SendFragment.Listener activityCallback;
|
||||
|
@ -297,7 +319,7 @@ public class SendFragment extends Fragment {
|
|||
|
||||
void onPrepareSweep();
|
||||
|
||||
void onSend();
|
||||
void onSend(String notes);
|
||||
|
||||
String generatePaymentId();
|
||||
|
||||
|
@ -331,6 +353,21 @@ public class SendFragment extends Fragment {
|
|||
bSend.setEnabled(true);
|
||||
}
|
||||
|
||||
public void onCreatedTransactionFailed(String errorText) {
|
||||
hideProgress();
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(getString(R.string.send_error_title));
|
||||
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
enableEdit();
|
||||
}
|
||||
});
|
||||
builder.setMessage(errorText);
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
public void showProgress() {
|
||||
pbProgress.setIndeterminate(true);
|
||||
pbProgress.setVisibility(View.VISIBLE);
|
||||
|
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* Copyright (c) 2017 m2049r
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||
import com.m2049r.xmrwallet.model.Transfer;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.service.MoneroHandlerThread;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class TxFragment extends Fragment {
|
||||
static final String TAG = "TxFragment";
|
||||
|
||||
static public final String ARG_INFO = "info";
|
||||
|
||||
private final SimpleDateFormat TS_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
public TxFragment() {
|
||||
super();
|
||||
Calendar cal = Calendar.getInstance();
|
||||
TimeZone tz = cal.getTimeZone(); //get the local time zone.
|
||||
TS_FORMATTER.setTimeZone(tz);
|
||||
}
|
||||
|
||||
TextView tvTxTimestamp;
|
||||
TextView tvTxId;
|
||||
TextView tvTxKey;
|
||||
TextView tvTxPaymentId;
|
||||
TextView tvTxBlockheight;
|
||||
TextView tvTxAmount;
|
||||
TextView tvTxFee;
|
||||
TextView tvTxTransfers;
|
||||
TextView etTxNotes;
|
||||
Button bCopy;
|
||||
Button bTxNotes;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
View view = inflater.inflate(R.layout.tx_fragment, container, false);
|
||||
|
||||
tvTxTimestamp = (TextView) view.findViewById(R.id.tvTxTimestamp);
|
||||
tvTxId = (TextView) view.findViewById(R.id.tvTxId);
|
||||
tvTxKey = (TextView) view.findViewById(R.id.tvTxKey);
|
||||
tvTxPaymentId = (TextView) view.findViewById(R.id.tvTxPaymentId);
|
||||
tvTxBlockheight = (TextView) view.findViewById(R.id.tvTxBlockheight);
|
||||
tvTxAmount = (TextView) view.findViewById(R.id.tvTxAmount);
|
||||
tvTxFee = (TextView) view.findViewById(R.id.tvTxFee);
|
||||
tvTxTransfers = (TextView) view.findViewById(R.id.tvTxTransfers);
|
||||
etTxNotes = (TextView) view.findViewById(R.id.etTxNotes);
|
||||
bCopy = (Button) view.findViewById(R.id.bCopy);
|
||||
bTxNotes = (Button) view.findViewById(R.id.bTxNotes);
|
||||
|
||||
etTxNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||
|
||||
bCopy.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
copyToClipboard();
|
||||
}
|
||||
});
|
||||
|
||||
bTxNotes.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
info.notes = null; // force reload on next view
|
||||
bTxNotes.setEnabled(false);
|
||||
etTxNotes.setEnabled(false);
|
||||
activityCallback.onSetNote(info.hash, etTxNotes.getText().toString());
|
||||
}
|
||||
});
|
||||
|
||||
Bundle args = getArguments();
|
||||
TransactionInfo info = args.getParcelable(ARG_INFO);
|
||||
show(info);
|
||||
return view;
|
||||
}
|
||||
|
||||
public void onNotesSet(boolean reload) {
|
||||
bTxNotes.setEnabled(true);
|
||||
etTxNotes.setEnabled(true);
|
||||
if (reload) {
|
||||
loadNotes(this.info);
|
||||
}
|
||||
}
|
||||
|
||||
void copyToClipboard() {
|
||||
if (this.info == null) return;
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(getString(R.string.tx_address)).append(": ");
|
||||
sb.append(activityCallback.getWalletAddress()).append("\n");
|
||||
sb.append(getString(R.string.tx_id)).append(": ");
|
||||
sb.append(info.hash).append("\n");
|
||||
sb.append(getString(R.string.tx_key)).append(": ");
|
||||
sb.append(info.txKey.isEmpty() ? "-" : info.txKey).append("\n");
|
||||
sb.append(getString(R.string.tx_paymentId)).append(": ");
|
||||
sb.append(info.paymentId).append("\n");
|
||||
sb.append(getString(R.string.tx_amount)).append(": ");
|
||||
sb.append(Wallet.getDisplayAmount(info.amount)).append("\n");
|
||||
sb.append(getString(R.string.tx_fee)).append(": ");
|
||||
sb.append(Wallet.getDisplayAmount(info.fee)).append("\n");
|
||||
sb.append(getString(R.string.tx_notes)).append(": ");
|
||||
String oneLineNotes = info.notes.replace("\n", " ; ");
|
||||
sb.append(oneLineNotes.isEmpty() ? "-" : oneLineNotes).append("\n");
|
||||
sb.append(getString(R.string.tx_timestamp)).append(": ");
|
||||
sb.append(TS_FORMATTER.format(new Date(info.timestamp * 1000))).append("\n");
|
||||
sb.append(getString(R.string.tx_blockheight)).append(": ");
|
||||
sb.append(info.blockheight).append("\n");
|
||||
sb.append(getString(R.string.tx_transfers)).append(": ");
|
||||
if (info.transfers != null) {
|
||||
boolean comma = false;
|
||||
for (int i = 0; i < 10; i++)
|
||||
for (Transfer transfer : info.transfers) {
|
||||
if (comma) {
|
||||
sb.append(",");
|
||||
} else {
|
||||
comma = true;
|
||||
}
|
||||
sb.append("[").append(transfer.address.substring(0, 6)).append("] ");
|
||||
sb.append(Wallet.getDisplayAmount(transfer.amount));
|
||||
}
|
||||
} else {
|
||||
sb.append("-");
|
||||
}
|
||||
sb.append("\n");
|
||||
ClipboardManager clipboardManager = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText(getString(R.string.tx_copy_label), sb.toString());
|
||||
clipboardManager.setPrimaryClip(clip);
|
||||
Toast.makeText(getActivity(), getString(R.string.tx_copy_message), Toast.LENGTH_SHORT).show();
|
||||
Log.d(TAG, sb.toString());
|
||||
}
|
||||
|
||||
TransactionInfo info = null;
|
||||
|
||||
void loadNotes(TransactionInfo info) {
|
||||
if (info.notes == null) {
|
||||
info.notes = activityCallback.getTxNotes(info.hash);
|
||||
//Log.d(TAG, "NOTES:" + info.notes + ":");
|
||||
}
|
||||
etTxNotes.setText(info.notes);
|
||||
}
|
||||
|
||||
private void show(TransactionInfo info) {
|
||||
if (info.txKey == null) {
|
||||
info.txKey = activityCallback.getTxKey(info.hash);
|
||||
//Log.d(TAG, "TXKEY:" + info.txKey + ":");
|
||||
}
|
||||
loadNotes(info);
|
||||
tvTxTimestamp.setText(TS_FORMATTER.format(new Date(info.timestamp * 1000)));
|
||||
tvTxId.setText(info.hash);
|
||||
tvTxKey.setText(info.txKey.isEmpty() ? "-" : info.txKey);
|
||||
tvTxPaymentId.setText(info.paymentId);
|
||||
tvTxBlockheight.setText("" + info.blockheight);
|
||||
tvTxAmount.setText(Wallet.getDisplayAmount(info.amount));
|
||||
tvTxFee.setText(Wallet.getDisplayAmount(info.fee));
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if (info.transfers != null) {
|
||||
boolean newline = false;
|
||||
for (int i = 0; i < 10; i++)
|
||||
for (Transfer transfer : info.transfers) {
|
||||
if (newline) {
|
||||
sb.append("\n");
|
||||
} else {
|
||||
newline = true;
|
||||
}
|
||||
sb.append("[").append(transfer.address.substring(0, 6)).append("] ");
|
||||
sb.append(Wallet.getDisplayAmount(transfer.amount));
|
||||
}
|
||||
} else {
|
||||
sb.append("-");
|
||||
}
|
||||
tvTxTransfers.setText(sb.toString());
|
||||
this.info = info;
|
||||
bCopy.setEnabled(true);
|
||||
}
|
||||
|
||||
TxFragment.Listener activityCallback;
|
||||
|
||||
public interface Listener {
|
||||
String getWalletAddress();
|
||||
|
||||
String getTxKey(String hash);
|
||||
|
||||
String getTxNotes(String hash);
|
||||
|
||||
void onSetNote(String txId, String notes);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
if (context instanceof TxFragment.Listener) {
|
||||
this.activityCallback = (TxFragment.Listener) context;
|
||||
} else {
|
||||
throw new ClassCastException(context.toString()
|
||||
+ " must implement Listener");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,12 +32,13 @@ import android.util.Log;
|
|||
import android.widget.Toast;
|
||||
|
||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.service.WalletService;
|
||||
import com.m2049r.xmrwallet.util.TxData;
|
||||
|
||||
public class WalletActivity extends AppCompatActivity implements WalletFragment.Listener,
|
||||
WalletService.Observer, SendFragment.Listener {
|
||||
WalletService.Observer, SendFragment.Listener, TxFragment.Listener {
|
||||
private static final String TAG = "WalletActivity";
|
||||
|
||||
static final int MIN_DAEMON_VERSION = 65544;
|
||||
|
@ -62,6 +63,11 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
|||
return getWallet().getTxKey(txId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTxNotes(String txId) {
|
||||
return getWallet().getUserNote(txId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
|
@ -258,6 +264,13 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
|||
replaceFragment(new SendFragment(), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTxDetailsRequest(TransactionInfo info) {
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable(TxFragment.ARG_INFO, info);
|
||||
replaceFragment(new TxFragment(), null, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forceUpdate() {
|
||||
try {
|
||||
|
@ -299,6 +312,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
|||
return true;
|
||||
} catch (ClassCastException ex) {
|
||||
// not in wallet fragment (probably send monero)
|
||||
Log.d(TAG, ex.getLocalizedMessage());
|
||||
// keep calm and carry on
|
||||
}
|
||||
return false;
|
||||
|
@ -319,18 +333,16 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
|||
|
||||
@Override
|
||||
public void onCreatedTransaction(final PendingTransaction pendingTransaction) {
|
||||
final PendingTransaction.Status status = pendingTransaction.getStatus();
|
||||
if (status != PendingTransaction.Status.Status_Ok) {
|
||||
getWallet().disposePendingTransaction();
|
||||
}
|
||||
try {
|
||||
final SendFragment sendFragment = (SendFragment)
|
||||
getFragmentManager().findFragmentById(R.id.fragment_container);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
PendingTransaction.Status status = pendingTransaction.getStatus();
|
||||
if (status != PendingTransaction.Status.Status_Ok) {
|
||||
Toast.makeText(WalletActivity.this, getString(R.string.status_transaction_prepare_failed), Toast.LENGTH_LONG).show();
|
||||
sendFragment.onCreatedTransaction(null);
|
||||
String errorText = pendingTransaction.getErrorString();
|
||||
getWallet().disposePendingTransaction();
|
||||
sendFragment.onCreatedTransactionFailed(errorText);
|
||||
} else {
|
||||
sendFragment.onCreatedTransaction(pendingTransaction);
|
||||
}
|
||||
|
@ -338,6 +350,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
|||
});
|
||||
} catch (ClassCastException ex) {
|
||||
// not in spend fragment
|
||||
Log.d(TAG, ex.getLocalizedMessage());
|
||||
// don't need the transaction any more
|
||||
getWallet().disposePendingTransaction();
|
||||
}
|
||||
|
@ -357,6 +370,26 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetNotes(final boolean success) {
|
||||
try {
|
||||
final TxFragment txFragment = (TxFragment)
|
||||
getFragmentManager().findFragmentById(R.id.fragment_container);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
if (!success) {
|
||||
Toast.makeText(WalletActivity.this, getString(R.string.tx_notes_set_failed), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
txFragment.onNotesSet(success);
|
||||
}
|
||||
});
|
||||
} catch (ClassCastException ex) {
|
||||
// not in tx fragment
|
||||
Log.d(TAG, ex.getLocalizedMessage());
|
||||
// never min
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(final String text) {
|
||||
try {
|
||||
|
@ -369,6 +402,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
|||
});
|
||||
} catch (ClassCastException ex) {
|
||||
// not in wallet fragment (probably send monero)
|
||||
Log.d(TAG, ex.getLocalizedMessage());
|
||||
// keep calm and carry on
|
||||
}
|
||||
}
|
||||
|
@ -385,6 +419,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
|||
});
|
||||
} catch (ClassCastException ex) {
|
||||
// not in wallet fragment (probably send monero)
|
||||
Log.d(TAG, ex.getLocalizedMessage());
|
||||
// keep calm and carry on
|
||||
}
|
||||
}
|
||||
|
@ -402,10 +437,11 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
|||
///////////////////////////
|
||||
|
||||
@Override
|
||||
public void onSend() {
|
||||
public void onSend(String notes) {
|
||||
if (mIsBound) { // no point in talking to unbound service
|
||||
Intent intent = new Intent(getApplicationContext(), WalletService.class);
|
||||
intent.putExtra(WalletService.REQUEST, WalletService.REQUEST_CMD_SEND);
|
||||
intent.putExtra(WalletService.REQUEST_CMD_SEND_NOTES, notes);
|
||||
startService(intent);
|
||||
Log.d(TAG, "SEND TX request sent");
|
||||
} else {
|
||||
|
@ -414,6 +450,21 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetNote(String txId, String notes) {
|
||||
if (mIsBound) { // no point in talking to unbound service
|
||||
Intent intent = new Intent(getApplicationContext(), WalletService.class);
|
||||
intent.putExtra(WalletService.REQUEST, WalletService.REQUEST_CMD_SETNOTE);
|
||||
intent.putExtra(WalletService.REQUEST_CMD_SETNOTE_TX, txId);
|
||||
intent.putExtra(WalletService.REQUEST_CMD_SETNOTE_NOTES, notes);
|
||||
startService(intent);
|
||||
Log.d(TAG, "SET NOTE request sent");
|
||||
} else {
|
||||
Log.e(TAG, "Service not bound");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareSend(TxData txData) {
|
||||
if (mIsBound) { // no point in talking to unbound service
|
||||
|
@ -462,13 +513,13 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
|||
}
|
||||
}
|
||||
|
||||
void replaceFragment(Fragment newFragment, String name, Bundle extras) {
|
||||
void replaceFragment(Fragment newFragment, String stackName, Bundle extras) {
|
||||
if (extras != null) {
|
||||
newFragment.setArguments(extras);
|
||||
}
|
||||
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
||||
transaction.replace(R.id.fragment_container, newFragment);
|
||||
transaction.addToBackStack(name);
|
||||
transaction.addToBackStack(stackName);
|
||||
transaction.commit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,61 +102,7 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
|||
// Callbacks from TransactionInfoAdapter
|
||||
@Override
|
||||
public void onInteraction(final View view, final TransactionInfo infoItem) {
|
||||
final Context ctx = view.getContext();
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
|
||||
builder.setTitle("Transaction details");
|
||||
|
||||
if (infoItem.txKey == null) {
|
||||
infoItem.txKey = activityCallback.getTxKey(infoItem.hash);
|
||||
}
|
||||
|
||||
builder.setPositiveButton("Copy TX ID", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
ClipboardManager clipboardManager = (ClipboardManager) ctx.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText("TXID", infoItem.hash);
|
||||
clipboardManager.setPrimaryClip(clip);
|
||||
}
|
||||
});
|
||||
|
||||
if (!infoItem.txKey.isEmpty()) {
|
||||
builder.setNegativeButton("Copy TX Key", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
ClipboardManager clipboardManager = (ClipboardManager) ctx.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText("TXKEY", infoItem.txKey);
|
||||
clipboardManager.setPrimaryClip(clip);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO use strings.xml
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("TX ID: ").append(infoItem.hash);
|
||||
sb.append("\nTX Key: ");
|
||||
if (!infoItem.txKey.isEmpty()) {
|
||||
sb.append(infoItem.txKey);
|
||||
} else {
|
||||
sb.append(" -");
|
||||
}
|
||||
sb.append("\nPayment ID: ").append(infoItem.paymentId);
|
||||
sb.append("\nBlockHeight: ").append(infoItem.blockheight);
|
||||
sb.append("\nAmount: ");
|
||||
sb.append(infoItem.direction == TransactionInfo.Direction.Direction_In ? "+" : "-");
|
||||
sb.append(Wallet.getDisplayAmount(infoItem.amount));
|
||||
sb.append("\nFee: ").append(Wallet.getDisplayAmount(infoItem.fee));
|
||||
sb.append("\nTransfers:");
|
||||
if (infoItem.transfers.size() > 0) {
|
||||
for (Transfer transfer : infoItem.transfers) {
|
||||
sb.append("\n[").append(transfer.address.substring(0, 6)).append("] ");
|
||||
sb.append(Wallet.getDisplayAmount(transfer.amount));
|
||||
}
|
||||
} else {
|
||||
sb.append(" -");
|
||||
}
|
||||
builder.setMessage(sb.toString());
|
||||
AlertDialog alert1 = builder.create();
|
||||
alert1.show();
|
||||
activityCallback.onTxDetailsRequest(infoItem);
|
||||
}
|
||||
|
||||
// called from activity
|
||||
|
@ -211,7 +157,9 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
|||
if (shortName.length() > 16) {
|
||||
shortName = shortName.substring(0, 14) + "...";
|
||||
}
|
||||
String title = (wallet.isWatchOnly() ? "X " : "") + "[" + wallet.getAddress().substring(0, 6) + "] " + shortName;
|
||||
String title = "[" + wallet.getAddress().substring(0, 6) + "] "
|
||||
+ shortName
|
||||
+ (wallet.isWatchOnly() ? " " + getString(R.string.watchonly_label) : "");
|
||||
activityCallback.setTitle(title);
|
||||
Log.d(TAG, "wallet title is " + title);
|
||||
return title;
|
||||
|
@ -269,6 +217,8 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
|||
|
||||
void onSendRequest();
|
||||
|
||||
void onTxDetailsRequest(TransactionInfo info);
|
||||
|
||||
boolean isSynced();
|
||||
|
||||
boolean isWatchOnly();
|
||||
|
|
|
@ -40,8 +40,8 @@ import java.util.TimeZone;
|
|||
public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfoAdapter.ViewHolder> {
|
||||
private static final String TAG = "TransactionInfoAdapter";
|
||||
|
||||
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
|
||||
private static final SimpleDateFormat TIME_FORMATTER = new SimpleDateFormat("HH:mm:ss");
|
||||
private final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
|
||||
private final SimpleDateFormat TIME_FORMATTER = new SimpleDateFormat("HH:mm:ss");
|
||||
|
||||
static final int TX_RED = Color.rgb(255, 79, 65);
|
||||
static final int TX_GREEN = Color.rgb(54, 176, 91);
|
||||
|
|
|
@ -39,16 +39,6 @@ public class PendingTransaction {
|
|||
Priority_High(3),
|
||||
Priority_Last(4);
|
||||
|
||||
private int value;
|
||||
|
||||
Priority(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Priority fromInteger(int n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
|
@ -60,6 +50,18 @@ public class PendingTransaction {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
private int value;
|
||||
|
||||
Priority(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
|
@ -79,7 +81,7 @@ public class PendingTransaction {
|
|||
|
||||
public native long getFee();
|
||||
|
||||
//public native String getTxId();
|
||||
public native String getFirstTxId();
|
||||
|
||||
public native long getTxCount();
|
||||
|
||||
|
|
|
@ -16,16 +16,40 @@
|
|||
|
||||
package com.m2049r.xmrwallet.model;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// this is not the TransactionInfo from the API as that is owned by the TransactionHistory
|
||||
// this is a POJO for the TransactionInfoAdapter
|
||||
public class TransactionInfo {
|
||||
public class TransactionInfo implements Parcelable {
|
||||
static final String TAG = "TransactionInfo";
|
||||
|
||||
public enum Direction {
|
||||
Direction_In,
|
||||
Direction_Out
|
||||
Direction_In(0),
|
||||
Direction_Out(1);
|
||||
|
||||
public static Direction fromInteger(int n) {
|
||||
switch (n) {
|
||||
case 0:
|
||||
return Direction_In;
|
||||
case 1:
|
||||
return Direction_Out;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
private int value;
|
||||
|
||||
Direction(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Direction direction;
|
||||
|
@ -41,6 +65,7 @@ public class TransactionInfo {
|
|||
public List<Transfer> transfers;
|
||||
|
||||
public String txKey = null;
|
||||
public String notes = null;
|
||||
|
||||
public TransactionInfo(
|
||||
int direction,
|
||||
|
@ -71,4 +96,52 @@ public class TransactionInfo {
|
|||
return direction + "@" + blockheight + " " + amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(direction.getValue());
|
||||
out.writeByte((byte) (isPending ? 1 : 0));
|
||||
out.writeByte((byte) (isFailed ? 1 : 0));
|
||||
out.writeLong(amount);
|
||||
out.writeLong(fee);
|
||||
out.writeLong(blockheight);
|
||||
out.writeString(hash);
|
||||
out.writeLong(timestamp);
|
||||
out.writeString(paymentId);
|
||||
out.writeLong(confirmations);
|
||||
out.writeList(transfers);
|
||||
out.writeString(txKey);
|
||||
out.writeString(notes);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<TransactionInfo> CREATOR = new Parcelable.Creator<TransactionInfo>() {
|
||||
public TransactionInfo createFromParcel(Parcel in) {
|
||||
return new TransactionInfo(in);
|
||||
}
|
||||
|
||||
public TransactionInfo[] newArray(int size) {
|
||||
return new TransactionInfo[size];
|
||||
}
|
||||
};
|
||||
|
||||
private TransactionInfo(Parcel in) {
|
||||
direction = Direction.fromInteger(in.readInt());
|
||||
isPending = in.readByte() != 0;
|
||||
isFailed = in.readByte() != 0;
|
||||
amount = in.readLong();
|
||||
fee = in.readLong();
|
||||
blockheight = in.readLong();
|
||||
hash = in.readString();
|
||||
timestamp = in.readLong();
|
||||
paymentId = in.readString();
|
||||
confirmations = in.readLong();
|
||||
transfers = in.readArrayList(Transfer.class.getClassLoader());
|
||||
txKey = in.readString();
|
||||
notes = in.readString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
|
||||
package com.m2049r.xmrwallet.model;
|
||||
|
||||
import android.util.Log;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
public class Transfer {
|
||||
import com.m2049r.xmrwallet.util.TxData;
|
||||
|
||||
public class Transfer implements Parcelable {
|
||||
public long amount;
|
||||
public String address;
|
||||
|
||||
|
@ -26,4 +29,31 @@ public class Transfer {
|
|||
this.amount = amount;
|
||||
this.address = address;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeLong(amount);
|
||||
out.writeString(address);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<Transfer> CREATOR = new Parcelable.Creator<Transfer>() {
|
||||
public Transfer createFromParcel(Parcel in) {
|
||||
return new Transfer(in);
|
||||
}
|
||||
|
||||
public Transfer[] newArray(int size) {
|
||||
return new Transfer[size];
|
||||
}
|
||||
};
|
||||
|
||||
private Transfer(Parcel in) {
|
||||
amount = in.readLong();
|
||||
address = in.readString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -233,8 +233,9 @@ public class Wallet {
|
|||
|
||||
public native void setDefaultMixin(int mixin);
|
||||
|
||||
//virtual bool setUserNote(const std::string &txid, const std::string ¬e) = 0;
|
||||
//virtual std::string getUserNote(const std::string &txid) const = 0;
|
||||
public native boolean setUserNote(String txid, String note);
|
||||
public native String getUserNote(String txid);
|
||||
|
||||
public native String getTxKey(String txid);
|
||||
|
||||
//virtual std::string signMessage(const std::string &message) = 0;
|
||||
|
|
|
@ -53,6 +53,11 @@ public class WalletService extends Service {
|
|||
public static final String REQUEST_CMD_SWEEP = "sweepTX";
|
||||
|
||||
public static final String REQUEST_CMD_SEND = "send";
|
||||
public static final String REQUEST_CMD_SEND_NOTES = "notes";
|
||||
|
||||
public static final String REQUEST_CMD_SETNOTE = "setnote";
|
||||
public static final String REQUEST_CMD_SETNOTE_TX = "tx";
|
||||
public static final String REQUEST_CMD_SETNOTE_NOTES = "notes";
|
||||
|
||||
public static final int START_SERVICE = 1;
|
||||
public static final int STOP_SERVICE = 2;
|
||||
|
@ -211,6 +216,8 @@ public class WalletService extends Service {
|
|||
void onCreatedTransaction(PendingTransaction pendingTransaction);
|
||||
|
||||
void onSentTransaction(boolean success);
|
||||
|
||||
void onSetNotes(boolean success);
|
||||
}
|
||||
|
||||
String progressText = null;
|
||||
|
@ -320,11 +327,15 @@ public class WalletService extends Service {
|
|||
myWallet.disposePendingTransaction(); // it's broken anyway
|
||||
return;
|
||||
}
|
||||
String txid = pendingTransaction.getFirstTxId();
|
||||
boolean success = pendingTransaction.commit("", true);
|
||||
myWallet.disposePendingTransaction();
|
||||
if (observer != null) observer.onSentTransaction(success);
|
||||
|
||||
if (success) {
|
||||
String notes = extras.getString(REQUEST_CMD_SEND_NOTES);
|
||||
if ((notes != null) && (!notes.isEmpty())) {
|
||||
myWallet.setUserNote(txid, notes);
|
||||
}
|
||||
boolean rc = myWallet.store();
|
||||
Log.d(TAG, "wallet stored: " + myWallet.getName() + " with rc=" + rc);
|
||||
if (!rc) {
|
||||
|
@ -332,6 +343,26 @@ public class WalletService extends Service {
|
|||
}
|
||||
if (observer != null) observer.onWalletStored(rc);
|
||||
}
|
||||
} else if (cmd.equals(REQUEST_CMD_SETNOTE)) {
|
||||
Wallet myWallet = getWallet();
|
||||
Log.d(TAG, "SET NOTE for wallet: " + myWallet.getName());
|
||||
String txId = extras.getString(REQUEST_CMD_SETNOTE_TX);
|
||||
String notes = extras.getString(REQUEST_CMD_SETNOTE_NOTES);
|
||||
if ((txId != null) && (notes != null)) {
|
||||
boolean success = myWallet.setUserNote(txId, notes);
|
||||
if (!success) {
|
||||
Log.e(TAG, myWallet.getErrorString());
|
||||
}
|
||||
if (observer != null) observer.onSetNotes(success);
|
||||
if (success) {
|
||||
boolean rc = myWallet.store();
|
||||
Log.d(TAG, "wallet stored: " + myWallet.getName() + " with rc=" + rc);
|
||||
if (!rc) {
|
||||
Log.d(TAG, "Wallet store failed: " + myWallet.getErrorString());
|
||||
}
|
||||
if (observer != null) observer.onWalletStored(rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -24,10 +24,10 @@ import com.m2049r.xmrwallet.model.PendingTransaction;
|
|||
// https://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents
|
||||
public class TxData implements Parcelable {
|
||||
public TxData(String dst_addr,
|
||||
String paymentId,
|
||||
long amount,
|
||||
int mixin,
|
||||
PendingTransaction.Priority priority) {
|
||||
String paymentId,
|
||||
long amount,
|
||||
int mixin,
|
||||
PendingTransaction.Priority priority) {
|
||||
this.dst_addr = dst_addr;
|
||||
this.paymentId = paymentId;
|
||||
this.amount = amount;
|
||||
|
@ -41,13 +41,6 @@ public class TxData implements Parcelable {
|
|||
public int mixin;
|
||||
public PendingTransaction.Priority priority;
|
||||
|
||||
// 99.9% of the time you can just ignore this
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// write your object's data to the passed-in Parcel
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(dst_addr);
|
||||
|
@ -68,7 +61,6 @@ public class TxData implements Parcelable {
|
|||
}
|
||||
};
|
||||
|
||||
// example constructor that takes a Parcel and gives you an object populated with it's values
|
||||
private TxData(Parcel in) {
|
||||
dst_addr = in.readString();
|
||||
paymentId = in.readString();
|
||||
|
@ -77,4 +69,10 @@ public class TxData implements Parcelable {
|
|||
priority = PendingTransaction.Priority.fromInteger(in.readInt());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="2">
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="2">
|
||||
|
@ -32,7 +32,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:orientation="horizontal"
|
||||
|
@ -59,7 +59,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:orientation="vertical">
|
||||
|
@ -67,7 +67,7 @@
|
|||
<ProgressBar
|
||||
android:id="@+id/pbProgress"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible" />
|
||||
</LinearLayout>
|
||||
|
@ -103,10 +103,10 @@
|
|||
android:id="@+id/tvWalletAddress"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/colorPrimaryDark"
|
||||
android:textIsSelectable="true"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
|
@ -123,10 +123,10 @@
|
|||
android:id="@+id/tvWalletViewKey"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/colorPrimaryDark"
|
||||
android:textIsSelectable="true"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
|
@ -143,10 +143,10 @@
|
|||
android:id="@+id/tvWalletSpendKey"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/colorPrimaryDark"
|
||||
android:textIsSelectable="true"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<Button
|
||||
|
@ -160,14 +160,14 @@
|
|||
|
||||
<LinearLayout
|
||||
android:id="@+id/llFunctions"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dip"
|
||||
android:background="@color/colorPrimary" />
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/layout_root"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="10dp" >
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="2">
|
||||
|
@ -39,7 +39,7 @@
|
|||
android:textSize="16sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="10">
|
||||
|
@ -69,7 +69,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="10">
|
||||
|
@ -94,6 +94,7 @@
|
|||
android:layout_weight="2"
|
||||
android:background="@color/colorPrimary"
|
||||
android:enabled="true"
|
||||
android:visibility="invisible"
|
||||
android:text="@string/send_sweep_hint" />
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -110,7 +111,7 @@
|
|||
<ProgressBar
|
||||
android:id="@+id/pbProgress"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:visibility="gone"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
|
@ -122,7 +123,7 @@
|
|||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="3">
|
||||
|
@ -149,7 +150,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="3">
|
||||
|
@ -176,7 +177,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="3">
|
||||
|
@ -191,7 +192,6 @@
|
|||
android:textAlignment="textEnd"
|
||||
android:textColor="@color/colorAccent"
|
||||
android:textSize="20sp" />
|
||||
c
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTxDust"
|
||||
|
@ -203,6 +203,17 @@
|
|||
android:textSize="20sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etNotes"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:hint="@string/send_notes_hint"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textMultiLine"
|
||||
android:textAlignment="center"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSend"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -212,6 +223,7 @@
|
|||
android:background="@color/colorPrimary"
|
||||
android:enabled="false"
|
||||
android:text="@string/send_send_hint" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fillViewport="true">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:shrinkColumns="1">
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:padding="8dp"
|
||||
android:text="@string/tx_id"
|
||||
android:textColor="@color/colorAccent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTxId"
|
||||
android:gravity="left"
|
||||
android:padding="8dip"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textIsSelectable="true" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:padding="8dp"
|
||||
android:text="@string/tx_key"
|
||||
android:textColor="@color/colorAccent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTxKey"
|
||||
android:gravity="left"
|
||||
android:padding="8dip"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textIsSelectable="true" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:padding="8dp"
|
||||
android:text="@string/tx_paymentId"
|
||||
android:textColor="@color/colorAccent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTxPaymentId"
|
||||
android:gravity="left"
|
||||
android:padding="8dip"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textIsSelectable="true" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:padding="8dp"
|
||||
android:selectAllOnFocus="true"
|
||||
android:text="@string/tx_amount"
|
||||
android:textColor="@color/colorAccent"
|
||||
android:textIsSelectable="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTxAmount"
|
||||
android:gravity="left"
|
||||
android:padding="8dip"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textIsSelectable="true" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:padding="8dp"
|
||||
android:text="@string/tx_fee"
|
||||
android:textColor="@color/colorAccent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTxFee"
|
||||
android:gravity="left"
|
||||
android:padding="8dip"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textIsSelectable="true" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:padding="8dp"
|
||||
android:text="@string/tx_notes"
|
||||
android:textColor="@color/colorAccent" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="10">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etTxNotes"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="8"
|
||||
android:hint="@string/tx_notes_hint"
|
||||
android:inputType="textMultiLine"
|
||||
android:textAlignment="textStart"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bTxNotes"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_weight="2"
|
||||
android:background="@color/colorPrimary"
|
||||
android:enabled="true"
|
||||
android:text="@string/tx_button_notes"
|
||||
android:textSize="8sp" />
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:padding="8dp"
|
||||
android:text="@string/tx_timestamp"
|
||||
android:textColor="@color/colorAccent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTxTimestamp"
|
||||
android:gravity="left"
|
||||
android:padding="8dip"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textIsSelectable="true" />
|
||||
</TableRow>
|
||||
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:padding="8dp"
|
||||
android:text="@string/tx_blockheight"
|
||||
android:textColor="@color/colorAccent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTxBlockheight"
|
||||
android:gravity="left"
|
||||
android:padding="8dip"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textIsSelectable="true" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:padding="8dp"
|
||||
android:text="@string/tx_transfers"
|
||||
android:textColor="@color/colorAccent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTxTransfers"
|
||||
android:gravity="left"
|
||||
android:padding="8dip"
|
||||
android:selectAllOnFocus="true"
|
||||
android:textIsSelectable="true" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bCopy"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@color/colorPrimary"
|
||||
android:enabled="false"
|
||||
android:text="@string/tx_button_copy" />
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
|
@ -96,7 +96,7 @@
|
|||
<ProgressBar
|
||||
android:id="@+id/pbProgress"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:progress="0" />
|
||||
</LinearLayout>
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
<string name="warn_daemon_unavailable">Cannot connect to daemon! Try again.</string>
|
||||
<string name="panic">Something\'s wrong!</string>
|
||||
|
||||
<string name="watchonly_label">(Watch Only)</string>
|
||||
|
||||
<string name="wallet_send_hint">Send some</string>
|
||||
|
||||
<string name="title_amount">Amount</string>
|
||||
|
@ -105,7 +107,7 @@
|
|||
<string name="send_sweep_hint">Sweep</string>
|
||||
<string name="send_generate_paymentid_hint">Generate</string>
|
||||
<string name="send_prepare_hint">Prepare</string>
|
||||
<string name="send_send_hint">Get rid of my Monero!</string>
|
||||
<string name="send_send_hint">Spend my sweet Moneroj</string>
|
||||
|
||||
<string name="send_preparing_progress">Preparing transaction</string>
|
||||
|
||||
|
@ -113,6 +115,26 @@
|
|||
<string name="send_fee_label">Fee</string>
|
||||
<string name="send_dust_label">Dust</string>
|
||||
|
||||
<string name="send_error_title">Trasaction Error</string>
|
||||
|
||||
<string name="tx_address">Address</string>
|
||||
<string name="tx_timestamp">Timestamp</string>
|
||||
<string name="tx_id">TX ID</string>
|
||||
<string name="tx_key">TX Key</string>
|
||||
<string name="tx_paymentId">Payment ID</string>
|
||||
<string name="tx_blockheight">Block</string>
|
||||
<string name="tx_amount">Amount</string>
|
||||
<string name="tx_fee">Fee</string>
|
||||
<string name="tx_transfers">Transfers</string>
|
||||
<string name="tx_notes">Notes</string>
|
||||
<string name="tx_button_copy">Copy to Clipboard</string>
|
||||
<string name="tx_copy_message">Copied to Clipboard</string>
|
||||
<string name="tx_copy_label">Transaction Details</string>
|
||||
<string name="tx_notes_hint">(optional)</string>
|
||||
<string name="tx_button_notes">Save</string>
|
||||
<string name="tx_notes_set">Notes saved</string>
|
||||
<string name="tx_notes_set_failed">Notes saved failed</string>
|
||||
|
||||
<string name="big_amount">999999.999999999999</string>
|
||||
|
||||
<string-array name="mixin">
|
||||
|
|
Loading…
Reference in New Issue