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
|
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::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
Bitmonero::PendingTransaction *tx = wallet->createSweepUnmixableTransaction();
|
Bitmonero::PendingTransaction *tx = wallet->createSweepUnmixableTransaction();
|
||||||
return reinterpret_cast<jlong>(tx);
|
return reinterpret_cast<jlong>(tx);
|
||||||
|
@ -839,8 +840,36 @@ Java_com_m2049r_xmrwallet_model_Wallet_setDefaultMixin(JNIEnv *env, jobject inst
|
||||||
return wallet->setDefaultMixin(mixin);
|
return wallet->setDefaultMixin(mixin);
|
||||||
}
|
}
|
||||||
|
|
||||||
//virtual bool setUserNote(const std::string &txid, const std::string ¬e) = 0;
|
JNIEXPORT jboolean JNICALL
|
||||||
//virtual std::string getUserNote(const std::string &txid) const = 0;
|
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
|
JNIEXPORT jstring JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_getTxKey(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_Wallet_getTxKey(JNIEnv *env, jobject instance,
|
||||||
|
@ -883,8 +912,10 @@ jobject newTransferInstance(JNIEnv *env, uint64_t amount, const std::string &add
|
||||||
|
|
||||||
jobject newTransferList(JNIEnv *env, Bitmonero::TransactionInfo *info) {
|
jobject newTransferList(JNIEnv *env, Bitmonero::TransactionInfo *info) {
|
||||||
const std::vector<Bitmonero::TransactionInfo::Transfer> &transfers = info->transfers();
|
const std::vector<Bitmonero::TransactionInfo::Transfer> &transfers = info->transfers();
|
||||||
|
if (transfers.size()==0) { // don't create empty Lists
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
// make new ArrayList
|
// make new ArrayList
|
||||||
|
|
||||||
jmethodID java_util_ArrayList_ = env->GetMethodID(class_ArrayList, "<init>", "(I)V");
|
jmethodID java_util_ArrayList_ = env->GetMethodID(class_ArrayList, "<init>", "(I)V");
|
||||||
jmethodID java_util_ArrayList_add = env->GetMethodID(class_ArrayList, "add",
|
jmethodID java_util_ArrayList_add = env->GetMethodID(class_ArrayList, "add",
|
||||||
"(Ljava/lang/Object;)Z");
|
"(Ljava/lang/Object;)Z");
|
||||||
|
@ -933,7 +964,10 @@ jobject cpp2java(JNIEnv *env, std::vector<Bitmonero::TransactionInfo *> vector)
|
||||||
jobject arrayList = env->NewObject(class_ArrayList, java_util_ArrayList_, vector.size());
|
jobject arrayList = env->NewObject(class_ArrayList, java_util_ArrayList_, vector.size());
|
||||||
for (Bitmonero::TransactionInfo *s: vector) {
|
for (Bitmonero::TransactionInfo *s: vector) {
|
||||||
if (s->fee() > 1) {
|
if (s->fee() > 1) {
|
||||||
LOGE("TX %s %" PRIu64 " %" PRIu64, s->hash().c_str(), s->fee(), s->amount());
|
LOGE("TX %s %"
|
||||||
|
PRIu64
|
||||||
|
" %"
|
||||||
|
PRIu64, s->hash().c_str(), s->fee(), s->amount());
|
||||||
}
|
}
|
||||||
jobject info = newTransactionInfo(env, s);
|
jobject info = newTransactionInfo(env, s);
|
||||||
env->CallBooleanMethod(arrayList, java_util_ArrayList_add, info);
|
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();
|
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
|
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);
|
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
|
JNIEXPORT jlong JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_PendingTransaction_getTxCount(JNIEnv *env, jobject instance) {
|
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.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.MediaStore;
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -274,13 +273,13 @@ public class LoginActivity extends AppCompatActivity
|
||||||
Log.d(TAG, "GenerateReviewFragment placed");
|
Log.d(TAG, "GenerateReviewFragment placed");
|
||||||
}
|
}
|
||||||
|
|
||||||
void replaceFragment(Fragment newFragment, String name, Bundle extras) {
|
void replaceFragment(Fragment newFragment, String stackName, Bundle extras) {
|
||||||
if (extras != null) {
|
if (extras != null) {
|
||||||
newFragment.setArguments(extras);
|
newFragment.setArguments(extras);
|
||||||
}
|
}
|
||||||
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
||||||
transaction.replace(R.id.fragment_container, newFragment);
|
transaction.replace(R.id.fragment_container, newFragment);
|
||||||
transaction.addToBackStack(name);
|
transaction.addToBackStack(stackName);
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,12 @@
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
|
@ -36,6 +40,8 @@ import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
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.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
@ -56,6 +62,7 @@ public class SendFragment extends Fragment {
|
||||||
TextView tvTxAmount;
|
TextView tvTxAmount;
|
||||||
TextView tvTxFee;
|
TextView tvTxFee;
|
||||||
TextView tvTxDust;
|
TextView tvTxDust;
|
||||||
|
EditText etNotes;
|
||||||
Button bSend;
|
Button bSend;
|
||||||
ProgressBar pbProgress;
|
ProgressBar pbProgress;
|
||||||
|
|
||||||
|
@ -84,12 +91,14 @@ public class SendFragment extends Fragment {
|
||||||
tvTxAmount = (TextView) view.findViewById(R.id.tvTxAmount);
|
tvTxAmount = (TextView) view.findViewById(R.id.tvTxAmount);
|
||||||
tvTxFee = (TextView) view.findViewById(R.id.tvTxFee);
|
tvTxFee = (TextView) view.findViewById(R.id.tvTxFee);
|
||||||
tvTxDust = (TextView) view.findViewById(R.id.tvTxDust);
|
tvTxDust = (TextView) view.findViewById(R.id.tvTxDust);
|
||||||
|
etNotes = (EditText) view.findViewById(R.id.etNotes);
|
||||||
bSend = (Button) view.findViewById(R.id.bSend);
|
bSend = (Button) view.findViewById(R.id.bSend);
|
||||||
|
|
||||||
pbProgress = (ProgressBar) view.findViewById(R.id.pbProgress);
|
pbProgress = (ProgressBar) view.findViewById(R.id.pbProgress);
|
||||||
|
|
||||||
etAddress.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
etAddress.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
etPaymentId.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
etPaymentId.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
|
etNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
|
|
||||||
etAddress.setText("9tDC52GsMjTNt4dpnRCwAF7ekVBkbkgkXGaMKTcSTpBhGpqkPX56jCNRydLq9oGjbbAQBsZhLfgmTKsntmxRd3TaJFYM2f8");
|
etAddress.setText("9tDC52GsMjTNt4dpnRCwAF7ekVBkbkgkXGaMKTcSTpBhGpqkPX56jCNRydLq9oGjbbAQBsZhLfgmTKsntmxRd3TaJFYM2f8");
|
||||||
boolean testnet = WalletManager.getInstance().isTestNet();
|
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 ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) {
|
||||||
if (amountOk()) {
|
if (amountOk()) {
|
||||||
Helper.hideKeyboard(getActivity());
|
Helper.hideKeyboard(getActivity());
|
||||||
|
disableEdit();
|
||||||
|
prepareSend();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -175,6 +186,7 @@ public class SendFragment extends Fragment {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Helper.hideKeyboard(getActivity());
|
Helper.hideKeyboard(getActivity());
|
||||||
|
disableEdit();
|
||||||
prepareSend();
|
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
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
bSend.setEnabled(false);
|
||||||
send();
|
send();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -248,8 +271,6 @@ public class SendFragment extends Fragment {
|
||||||
amount,
|
amount,
|
||||||
mixin,
|
mixin,
|
||||||
priority);
|
priority);
|
||||||
|
|
||||||
disableEdit();
|
|
||||||
showProgress();
|
showProgress();
|
||||||
activityCallback.onPrepareSend(txData);
|
activityCallback.onPrepareSend(txData);
|
||||||
}
|
}
|
||||||
|
@ -286,8 +307,9 @@ public class SendFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void send() {
|
private void send() {
|
||||||
disableEdit(); // prevent this being sent more than once
|
etNotes.setEnabled(false);
|
||||||
activityCallback.onSend();
|
String notes = etNotes.getText().toString();
|
||||||
|
activityCallback.onSend(notes);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendFragment.Listener activityCallback;
|
SendFragment.Listener activityCallback;
|
||||||
|
@ -297,7 +319,7 @@ public class SendFragment extends Fragment {
|
||||||
|
|
||||||
void onPrepareSweep();
|
void onPrepareSweep();
|
||||||
|
|
||||||
void onSend();
|
void onSend(String notes);
|
||||||
|
|
||||||
String generatePaymentId();
|
String generatePaymentId();
|
||||||
|
|
||||||
|
@ -331,6 +353,21 @@ public class SendFragment extends Fragment {
|
||||||
bSend.setEnabled(true);
|
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() {
|
public void showProgress() {
|
||||||
pbProgress.setIndeterminate(true);
|
pbProgress.setIndeterminate(true);
|
||||||
pbProgress.setVisibility(View.VISIBLE);
|
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 android.widget.Toast;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||||
|
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.service.WalletService;
|
import com.m2049r.xmrwallet.service.WalletService;
|
||||||
import com.m2049r.xmrwallet.util.TxData;
|
import com.m2049r.xmrwallet.util.TxData;
|
||||||
|
|
||||||
public class WalletActivity extends AppCompatActivity implements WalletFragment.Listener,
|
public class WalletActivity extends AppCompatActivity implements WalletFragment.Listener,
|
||||||
WalletService.Observer, SendFragment.Listener {
|
WalletService.Observer, SendFragment.Listener, TxFragment.Listener {
|
||||||
private static final String TAG = "WalletActivity";
|
private static final String TAG = "WalletActivity";
|
||||||
|
|
||||||
static final int MIN_DAEMON_VERSION = 65544;
|
static final int MIN_DAEMON_VERSION = 65544;
|
||||||
|
@ -62,6 +63,11 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||||
return getWallet().getTxKey(txId);
|
return getWallet().getTxKey(txId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTxNotes(String txId) {
|
||||||
|
return getWallet().getUserNote(txId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
@ -258,6 +264,13 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||||
replaceFragment(new SendFragment(), null, null);
|
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
|
@Override
|
||||||
public void forceUpdate() {
|
public void forceUpdate() {
|
||||||
try {
|
try {
|
||||||
|
@ -299,6 +312,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||||
return true;
|
return true;
|
||||||
} catch (ClassCastException ex) {
|
} catch (ClassCastException ex) {
|
||||||
// not in wallet fragment (probably send monero)
|
// not in wallet fragment (probably send monero)
|
||||||
|
Log.d(TAG, ex.getLocalizedMessage());
|
||||||
// keep calm and carry on
|
// keep calm and carry on
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -319,18 +333,16 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreatedTransaction(final PendingTransaction pendingTransaction) {
|
public void onCreatedTransaction(final PendingTransaction pendingTransaction) {
|
||||||
final PendingTransaction.Status status = pendingTransaction.getStatus();
|
|
||||||
if (status != PendingTransaction.Status.Status_Ok) {
|
|
||||||
getWallet().disposePendingTransaction();
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
final SendFragment sendFragment = (SendFragment)
|
final SendFragment sendFragment = (SendFragment)
|
||||||
getFragmentManager().findFragmentById(R.id.fragment_container);
|
getFragmentManager().findFragmentById(R.id.fragment_container);
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
PendingTransaction.Status status = pendingTransaction.getStatus();
|
||||||
if (status != PendingTransaction.Status.Status_Ok) {
|
if (status != PendingTransaction.Status.Status_Ok) {
|
||||||
Toast.makeText(WalletActivity.this, getString(R.string.status_transaction_prepare_failed), Toast.LENGTH_LONG).show();
|
String errorText = pendingTransaction.getErrorString();
|
||||||
sendFragment.onCreatedTransaction(null);
|
getWallet().disposePendingTransaction();
|
||||||
|
sendFragment.onCreatedTransactionFailed(errorText);
|
||||||
} else {
|
} else {
|
||||||
sendFragment.onCreatedTransaction(pendingTransaction);
|
sendFragment.onCreatedTransaction(pendingTransaction);
|
||||||
}
|
}
|
||||||
|
@ -338,6 +350,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||||
});
|
});
|
||||||
} catch (ClassCastException ex) {
|
} catch (ClassCastException ex) {
|
||||||
// not in spend fragment
|
// not in spend fragment
|
||||||
|
Log.d(TAG, ex.getLocalizedMessage());
|
||||||
// don't need the transaction any more
|
// don't need the transaction any more
|
||||||
getWallet().disposePendingTransaction();
|
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
|
@Override
|
||||||
public void onProgress(final String text) {
|
public void onProgress(final String text) {
|
||||||
try {
|
try {
|
||||||
|
@ -369,6 +402,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||||
});
|
});
|
||||||
} catch (ClassCastException ex) {
|
} catch (ClassCastException ex) {
|
||||||
// not in wallet fragment (probably send monero)
|
// not in wallet fragment (probably send monero)
|
||||||
|
Log.d(TAG, ex.getLocalizedMessage());
|
||||||
// keep calm and carry on
|
// keep calm and carry on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -385,6 +419,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||||
});
|
});
|
||||||
} catch (ClassCastException ex) {
|
} catch (ClassCastException ex) {
|
||||||
// not in wallet fragment (probably send monero)
|
// not in wallet fragment (probably send monero)
|
||||||
|
Log.d(TAG, ex.getLocalizedMessage());
|
||||||
// keep calm and carry on
|
// keep calm and carry on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,10 +437,11 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSend() {
|
public void onSend(String notes) {
|
||||||
if (mIsBound) { // no point in talking to unbound service
|
if (mIsBound) { // no point in talking to unbound service
|
||||||
Intent intent = new Intent(getApplicationContext(), WalletService.class);
|
Intent intent = new Intent(getApplicationContext(), WalletService.class);
|
||||||
intent.putExtra(WalletService.REQUEST, WalletService.REQUEST_CMD_SEND);
|
intent.putExtra(WalletService.REQUEST, WalletService.REQUEST_CMD_SEND);
|
||||||
|
intent.putExtra(WalletService.REQUEST_CMD_SEND_NOTES, notes);
|
||||||
startService(intent);
|
startService(intent);
|
||||||
Log.d(TAG, "SEND TX request sent");
|
Log.d(TAG, "SEND TX request sent");
|
||||||
} else {
|
} 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
|
@Override
|
||||||
public void onPrepareSend(TxData txData) {
|
public void onPrepareSend(TxData txData) {
|
||||||
if (mIsBound) { // no point in talking to unbound service
|
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) {
|
if (extras != null) {
|
||||||
newFragment.setArguments(extras);
|
newFragment.setArguments(extras);
|
||||||
}
|
}
|
||||||
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
||||||
transaction.replace(R.id.fragment_container, newFragment);
|
transaction.replace(R.id.fragment_container, newFragment);
|
||||||
transaction.addToBackStack(name);
|
transaction.addToBackStack(stackName);
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,61 +102,7 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
||||||
// Callbacks from TransactionInfoAdapter
|
// Callbacks from TransactionInfoAdapter
|
||||||
@Override
|
@Override
|
||||||
public void onInteraction(final View view, final TransactionInfo infoItem) {
|
public void onInteraction(final View view, final TransactionInfo infoItem) {
|
||||||
final Context ctx = view.getContext();
|
activityCallback.onTxDetailsRequest(infoItem);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from activity
|
// called from activity
|
||||||
|
@ -211,7 +157,9 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
||||||
if (shortName.length() > 16) {
|
if (shortName.length() > 16) {
|
||||||
shortName = shortName.substring(0, 14) + "...";
|
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);
|
activityCallback.setTitle(title);
|
||||||
Log.d(TAG, "wallet title is " + title);
|
Log.d(TAG, "wallet title is " + title);
|
||||||
return title;
|
return title;
|
||||||
|
@ -269,6 +217,8 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
||||||
|
|
||||||
void onSendRequest();
|
void onSendRequest();
|
||||||
|
|
||||||
|
void onTxDetailsRequest(TransactionInfo info);
|
||||||
|
|
||||||
boolean isSynced();
|
boolean isSynced();
|
||||||
|
|
||||||
boolean isWatchOnly();
|
boolean isWatchOnly();
|
||||||
|
|
|
@ -40,8 +40,8 @@ import java.util.TimeZone;
|
||||||
public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfoAdapter.ViewHolder> {
|
public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfoAdapter.ViewHolder> {
|
||||||
private static final String TAG = "TransactionInfoAdapter";
|
private static final String TAG = "TransactionInfoAdapter";
|
||||||
|
|
||||||
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
|
private final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
private static final SimpleDateFormat TIME_FORMATTER = new SimpleDateFormat("HH:mm:ss");
|
private final SimpleDateFormat TIME_FORMATTER = new SimpleDateFormat("HH:mm:ss");
|
||||||
|
|
||||||
static final int TX_RED = Color.rgb(255, 79, 65);
|
static final int TX_RED = Color.rgb(255, 79, 65);
|
||||||
static final int TX_GREEN = Color.rgb(54, 176, 91);
|
static final int TX_GREEN = Color.rgb(54, 176, 91);
|
||||||
|
|
|
@ -39,16 +39,6 @@ public class PendingTransaction {
|
||||||
Priority_High(3),
|
Priority_High(3),
|
||||||
Priority_Last(4);
|
Priority_Last(4);
|
||||||
|
|
||||||
private int value;
|
|
||||||
|
|
||||||
Priority(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Priority fromInteger(int n) {
|
public static Priority fromInteger(int n) {
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -60,6 +50,18 @@ public class PendingTransaction {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int value;
|
||||||
|
|
||||||
|
Priority(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Status getStatus() {
|
public Status getStatus() {
|
||||||
|
@ -79,7 +81,7 @@ public class PendingTransaction {
|
||||||
|
|
||||||
public native long getFee();
|
public native long getFee();
|
||||||
|
|
||||||
//public native String getTxId();
|
public native String getFirstTxId();
|
||||||
|
|
||||||
public native long getTxCount();
|
public native long getTxCount();
|
||||||
|
|
||||||
|
|
|
@ -16,16 +16,40 @@
|
||||||
|
|
||||||
package com.m2049r.xmrwallet.model;
|
package com.m2049r.xmrwallet.model;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
// this is not the TransactionInfo from the API as that is owned by the TransactionHistory
|
// this is not the TransactionInfo from the API as that is owned by the TransactionHistory
|
||||||
// this is a POJO for the TransactionInfoAdapter
|
// this is a POJO for the TransactionInfoAdapter
|
||||||
public class TransactionInfo {
|
public class TransactionInfo implements Parcelable {
|
||||||
static final String TAG = "TransactionInfo";
|
static final String TAG = "TransactionInfo";
|
||||||
|
|
||||||
public enum Direction {
|
public enum Direction {
|
||||||
Direction_In,
|
Direction_In(0),
|
||||||
Direction_Out
|
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;
|
public Direction direction;
|
||||||
|
@ -41,6 +65,7 @@ public class TransactionInfo {
|
||||||
public List<Transfer> transfers;
|
public List<Transfer> transfers;
|
||||||
|
|
||||||
public String txKey = null;
|
public String txKey = null;
|
||||||
|
public String notes = null;
|
||||||
|
|
||||||
public TransactionInfo(
|
public TransactionInfo(
|
||||||
int direction,
|
int direction,
|
||||||
|
@ -71,4 +96,52 @@ public class TransactionInfo {
|
||||||
return direction + "@" + blockheight + " " + amount;
|
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;
|
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 long amount;
|
||||||
public String address;
|
public String address;
|
||||||
|
|
||||||
|
@ -26,4 +29,31 @@ public class Transfer {
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.address = address;
|
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);
|
public native void setDefaultMixin(int mixin);
|
||||||
|
|
||||||
//virtual bool setUserNote(const std::string &txid, const std::string ¬e) = 0;
|
public native boolean setUserNote(String txid, String note);
|
||||||
//virtual std::string getUserNote(const std::string &txid) const = 0;
|
public native String getUserNote(String txid);
|
||||||
|
|
||||||
public native String getTxKey(String txid);
|
public native String getTxKey(String txid);
|
||||||
|
|
||||||
//virtual std::string signMessage(const std::string &message) = 0;
|
//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_SWEEP = "sweepTX";
|
||||||
|
|
||||||
public static final String REQUEST_CMD_SEND = "send";
|
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 START_SERVICE = 1;
|
||||||
public static final int STOP_SERVICE = 2;
|
public static final int STOP_SERVICE = 2;
|
||||||
|
@ -211,6 +216,8 @@ public class WalletService extends Service {
|
||||||
void onCreatedTransaction(PendingTransaction pendingTransaction);
|
void onCreatedTransaction(PendingTransaction pendingTransaction);
|
||||||
|
|
||||||
void onSentTransaction(boolean success);
|
void onSentTransaction(boolean success);
|
||||||
|
|
||||||
|
void onSetNotes(boolean success);
|
||||||
}
|
}
|
||||||
|
|
||||||
String progressText = null;
|
String progressText = null;
|
||||||
|
@ -320,10 +327,33 @@ public class WalletService extends Service {
|
||||||
myWallet.disposePendingTransaction(); // it's broken anyway
|
myWallet.disposePendingTransaction(); // it's broken anyway
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
String txid = pendingTransaction.getFirstTxId();
|
||||||
boolean success = pendingTransaction.commit("", true);
|
boolean success = pendingTransaction.commit("", true);
|
||||||
myWallet.disposePendingTransaction();
|
myWallet.disposePendingTransaction();
|
||||||
if (observer != null) observer.onSentTransaction(success);
|
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) {
|
||||||
|
Log.d(TAG, "Wallet store failed: " + myWallet.getErrorString());
|
||||||
|
}
|
||||||
|
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) {
|
if (success) {
|
||||||
boolean rc = myWallet.store();
|
boolean rc = myWallet.store();
|
||||||
Log.d(TAG, "wallet stored: " + myWallet.getName() + " with rc=" + rc);
|
Log.d(TAG, "wallet stored: " + myWallet.getName() + " with rc=" + rc);
|
||||||
|
@ -334,6 +364,7 @@ public class WalletService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case STOP_SERVICE:
|
case STOP_SERVICE:
|
||||||
stop();
|
stop();
|
||||||
|
|
|
@ -41,13 +41,6 @@ public class TxData implements Parcelable {
|
||||||
public int mixin;
|
public int mixin;
|
||||||
public PendingTransaction.Priority priority;
|
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
|
@Override
|
||||||
public void writeToParcel(Parcel out, int flags) {
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
out.writeString(dst_addr);
|
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) {
|
private TxData(Parcel in) {
|
||||||
dst_addr = in.readString();
|
dst_addr = in.readString();
|
||||||
paymentId = in.readString();
|
paymentId = in.readString();
|
||||||
|
@ -77,4 +69,10 @@ public class TxData implements Parcelable {
|
||||||
priority = PendingTransaction.Priority.fromInteger(in.readInt());
|
priority = PendingTransaction.Priority.fromInteger(in.readInt());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:weightSum="2">
|
android:weightSum="2">
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:weightSum="2">
|
android:weightSum="2">
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/pbProgress"
|
android:id="@+id/pbProgress"
|
||||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:visibility="invisible" />
|
android:visibility="invisible" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -103,10 +103,10 @@
|
||||||
android:id="@+id/tvWalletAddress"
|
android:id="@+id/tvWalletAddress"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:selectAllOnFocus="true"
|
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textColor="@color/colorPrimaryDark"
|
android:textColor="@color/colorPrimaryDark"
|
||||||
android:textIsSelectable="true"
|
android:textIsSelectable="true"
|
||||||
|
android:selectAllOnFocus="true"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -123,10 +123,10 @@
|
||||||
android:id="@+id/tvWalletViewKey"
|
android:id="@+id/tvWalletViewKey"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:selectAllOnFocus="true"
|
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textColor="@color/colorPrimaryDark"
|
android:textColor="@color/colorPrimaryDark"
|
||||||
android:textIsSelectable="true"
|
android:textIsSelectable="true"
|
||||||
|
android:selectAllOnFocus="true"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -143,10 +143,10 @@
|
||||||
android:id="@+id/tvWalletSpendKey"
|
android:id="@+id/tvWalletSpendKey"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:selectAllOnFocus="true"
|
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textColor="@color/colorPrimaryDark"
|
android:textColor="@color/colorPrimaryDark"
|
||||||
android:textIsSelectable="true"
|
android:textIsSelectable="true"
|
||||||
|
android:selectAllOnFocus="true"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
@ -160,14 +160,14 @@
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/llFunctions"
|
android:id="@+id/llFunctions"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:visibility="gone">
|
android:visibility="gone">
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="2dip"
|
android:layout_height="2dip"
|
||||||
android:background="@color/colorPrimary" />
|
android:background="@color/colorPrimary" />
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/layout_root"
|
android:id="@+id/layout_root"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="10dp" >
|
android:padding="10dp" >
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:weightSum="2">
|
android:weightSum="2">
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:weightSum="10">
|
android:weightSum="10">
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:weightSum="10">
|
android:weightSum="10">
|
||||||
|
@ -94,6 +94,7 @@
|
||||||
android:layout_weight="2"
|
android:layout_weight="2"
|
||||||
android:background="@color/colorPrimary"
|
android:background="@color/colorPrimary"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
|
android:visibility="invisible"
|
||||||
android:text="@string/send_sweep_hint" />
|
android:text="@string/send_sweep_hint" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -110,7 +111,7 @@
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/pbProgress"
|
android:id="@+id/pbProgress"
|
||||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@
|
||||||
android:visibility="gone">
|
android:visibility="gone">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:weightSum="3">
|
android:weightSum="3">
|
||||||
|
@ -149,7 +150,7 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:weightSum="3">
|
android:weightSum="3">
|
||||||
|
@ -176,7 +177,7 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:weightSum="3">
|
android:weightSum="3">
|
||||||
|
@ -191,7 +192,6 @@
|
||||||
android:textAlignment="textEnd"
|
android:textAlignment="textEnd"
|
||||||
android:textColor="@color/colorAccent"
|
android:textColor="@color/colorAccent"
|
||||||
android:textSize="20sp" />
|
android:textSize="20sp" />
|
||||||
c
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvTxDust"
|
android:id="@+id/tvTxDust"
|
||||||
|
@ -203,6 +203,17 @@
|
||||||
android:textSize="20sp" />
|
android:textSize="20sp" />
|
||||||
</LinearLayout>
|
</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
|
<Button
|
||||||
android:id="@+id/bSend"
|
android:id="@+id/bSend"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -212,6 +223,7 @@
|
||||||
android:background="@color/colorPrimary"
|
android:background="@color/colorPrimary"
|
||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
android:text="@string/send_send_hint" />
|
android:text="@string/send_send_hint" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</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
|
<ProgressBar
|
||||||
android:id="@+id/pbProgress"
|
android:id="@+id/pbProgress"
|
||||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:progress="0" />
|
android:progress="0" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
<string name="warn_daemon_unavailable">Cannot connect to daemon! Try again.</string>
|
<string name="warn_daemon_unavailable">Cannot connect to daemon! Try again.</string>
|
||||||
<string name="panic">Something\'s wrong!</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="wallet_send_hint">Send some</string>
|
||||||
|
|
||||||
<string name="title_amount">Amount</string>
|
<string name="title_amount">Amount</string>
|
||||||
|
@ -105,7 +107,7 @@
|
||||||
<string name="send_sweep_hint">Sweep</string>
|
<string name="send_sweep_hint">Sweep</string>
|
||||||
<string name="send_generate_paymentid_hint">Generate</string>
|
<string name="send_generate_paymentid_hint">Generate</string>
|
||||||
<string name="send_prepare_hint">Prepare</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>
|
<string name="send_preparing_progress">Preparing transaction</string>
|
||||||
|
|
||||||
|
@ -113,6 +115,26 @@
|
||||||
<string name="send_fee_label">Fee</string>
|
<string name="send_fee_label">Fee</string>
|
||||||
<string name="send_dust_label">Dust</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 name="big_amount">999999.999999999999</string>
|
||||||
|
|
||||||
<string-array name="mixin">
|
<string-array name="mixin">
|
||||||
|
|
Loading…
Reference in New Issue