Verified Commit c458ec36 authored by Sarath's avatar Sarath
Browse files

Manage paynym follow state and removed directory task

parent fa1148ea
package com.samourai.wallet.bip47;
import android.content.Context;
import android.util.Log;
import com.samourai.wallet.bip47.rpc.PaymentCode;
......@@ -48,6 +49,7 @@ public class BIP47Meta {
private static ConcurrentHashMap<String,String> pcodeIncomingStatus = null;
private static ConcurrentHashMap<String,String> pcodeLatestEvent = null;
private static ConcurrentHashMap<String,Boolean> pcodeSegwit = null;
private static ArrayList<String> followingPcodes = new ArrayList();
private static BIP47Meta instance = null;
......@@ -99,6 +101,15 @@ public class BIP47Meta {
}
}
public void addFollowings(ArrayList<String> pcodes){
followingPcodes.clear();
followingPcodes.addAll(pcodes);
}
public boolean isFollowing(String pcode){
return followingPcodes.contains(pcode);
}
public String getDisplayLabel(String pcode) {
String label = getLabel(pcode);
if(label.length() == 0 || pcode.equals(label)) {
......
......@@ -99,7 +99,6 @@ class PayNymHome : SamouraiActivity() {
}
payNymViewModel.pcode.observe(this, { paymentCode: String? -> paynym?.text = paymentCode })
payNymViewModel.loaderLiveData.observe(this, {
Log.i(TAG, "onCreate: ${it}")
swipeToRefreshPaynym?.isRefreshing = it
})
......@@ -107,7 +106,7 @@ class PayNymHome : SamouraiActivity() {
Snackbar.make(paynym!!, "Error : ${it}", Snackbar.LENGTH_LONG).show()
})
payNymViewModel.followers.observe(this, { followersList: ArrayList<String>? ->
if (followersList == null || followersList.size == 0) {
if (followersList == null) {
return@observe
}
val filtered = filterArchived(followersList)
......@@ -117,7 +116,7 @@ class PayNymHome : SamouraiActivity() {
followers = followersList
})
payNymViewModel.following.observe(this, { followingList: ArrayList<String>? ->
if (followingList == null || followingList.size == 0) {
if (followingList == null ) {
return@observe
}
val filtered = filterArchived(followingList)
......
......@@ -3,15 +3,15 @@ package com.samourai.wallet.paynym
import android.app.Application
import android.util.Log
import androidx.lifecycle.*
import com.google.gson.Gson
import com.samourai.wallet.access.AccessFactory
import com.samourai.wallet.bip47.BIP47Meta
import com.samourai.wallet.bip47.BIP47Util
import com.samourai.wallet.bip47.paynym.WebUtil
import com.samourai.wallet.payload.PayloadUtil
import com.samourai.wallet.paynym.api.PayNymApiService
import com.samourai.wallet.util.AppUtil
import com.samourai.wallet.util.LogUtil
import com.samourai.wallet.util.MessageSignUtil
import com.samourai.wallet.util.PrefsUtil
import com.samourai.wallet.paynym.models.NymResponse
import com.samourai.wallet.util.*
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
......@@ -23,6 +23,7 @@ import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.util.*
import kotlin.collections.ArrayList
class PayNymViewModel(application: Application) : AndroidViewModel(application) {
......@@ -56,11 +57,10 @@ class PayNymViewModel(application: Application) : AndroidViewModel(application)
private suspend fun setPaynymPayload(jsonObject: JSONObject) = withContext(Dispatchers.IO) {
val _pcodes = BIP47Meta.getInstance().getSortedByLabels(false)
var array = JSONArray()
val followings = ArrayList<String>()
val followers = ArrayList<String>()
try {
val nym = Gson().fromJson(jsonObject.toString(), NymResponse::class.java);
array = jsonObject.getJSONArray("codes")
if (array.getJSONObject(0).has("claimed") && array.getJSONObject(0).getBoolean("claimed")) {
val strNymName = jsonObject.getString("nymName")
......@@ -68,46 +68,35 @@ class PayNymViewModel(application: Application) : AndroidViewModel(application)
paymentCode.postValue(strNymName)
}
}
if (jsonObject.has("following")) {
val _following = jsonObject.getJSONArray("following")
for (i in 0 until _following.length()) {
followings.add((_following[i] as JSONObject).getString("code"))
if ((_following[i] as JSONObject).has("segwit")) {
BIP47Meta.getInstance().setSegwit((_following[i] as JSONObject).getString("code"), (_following[i] as JSONObject).getBoolean("segwit"))
}
val paynym = _following[i] as JSONObject
if (BIP47Meta.getInstance().getDisplayLabel(paynym.getString("code")).contains(paynym.getString("code").substring(0, 4))) {
BIP47Meta.getInstance().setLabel(paynym.getString("code"), paynym.getString("nymName"))
nym.following?.let { codes ->
codes.forEach { paynym ->
BIP47Meta.getInstance().setSegwit(paynym.code, paynym.segwit)
if (BIP47Meta.getInstance().getDisplayLabel(paynym.code).contains(paynym.code.substring(0, 4))) {
BIP47Meta.getInstance().setLabel(paynym.code, paynym.nymName)
}
}
for (pcode in _pcodes) {
if (!followings.contains(pcode)) {
followings.add(pcode)
}
}
sortByLabel(followings)
val followings = ArrayList(codes.distinctBy { it.code }.map { it.code })
BIP47Meta.getInstance().addFollowings(followings)
sortByLabel(followings);
viewModelScope.launch(Dispatchers.Main) {
followingList.postValue(followings)
}
}
if (jsonObject.has("followers")) {
val _follower = jsonObject.getJSONArray("followers")
for (i in 0 until _follower.length()) {
followers.add((_follower[i] as JSONObject).getString("code"))
if ((_follower[i] as JSONObject).has("segwit")) {
BIP47Meta.getInstance().setSegwit((_follower[i] as JSONObject).getString("code"), (_follower[i] as JSONObject).getBoolean("segwit"))
}
val paynym = _follower[i] as JSONObject
if (BIP47Meta.getInstance().getDisplayLabel(paynym.getString("code")).contains(paynym.getString("code").substring(0, 4))) {
BIP47Meta.getInstance().setLabel(paynym.getString("code"), paynym.getString("nymName"))
nym.followers?.let { codes ->
codes.forEach { paynym ->
BIP47Meta.getInstance().setSegwit(paynym.code, paynym.segwit)
if (BIP47Meta.getInstance().getDisplayLabel(paynym.code).contains(paynym.code.substring(0, 4))) {
BIP47Meta.getInstance().setLabel(paynym.code, paynym.nymName)
}
}
sortByLabel(followers)
val followers = ArrayList(codes.distinctBy { it.code }.map { it.code })
sortByLabel(followers);
viewModelScope.launch(Dispatchers.Main) {
followersList.postValue(followers)
}
}
PayloadUtil.getInstance(getApplication()).serializePayNyms(jsonObject);
} catch (e: JSONException) {
e.printStackTrace()
}
......@@ -139,9 +128,6 @@ class PayNymViewModel(application: Application) : AndroidViewModel(application)
else
throw Exception("Invalid response ")
}
if (!BIP47Meta.directoryTaskCompleted) {
directoryTask()
}
} catch (ex: Exception) {
LogUtil.error(TAG, ex)
}
......@@ -153,17 +139,17 @@ class PayNymViewModel(application: Application) : AndroidViewModel(application)
}
refreshJob = viewModelScope.launch(Dispatchers.Main) {
loader.postValue(true)
val job = withContext(Dispatchers.IO) {
withContext(Dispatchers.IO) {
try {
getPayNymData()
} catch (error: Exception) {
error.printStackTrace()
// throw CancellationException(error.message)
throw CancellationException(error.message)
}
}
}
refreshJob.invokeOnCompletion {
viewModelScope.launch(Dispatchers.Main){
viewModelScope.launch(Dispatchers.Main) {
loader.postValue(false)
}
}
......@@ -208,33 +194,6 @@ class PayNymViewModel(application: Application) : AndroidViewModel(application)
}
}
private fun directoryTask() {
val strPaymentCode = BIP47Util.getInstance(getApplication()).paymentCode.toString()
viewModelScope.launch(Dispatchers.IO) {
try {
val pcodes = BIP47Meta.getInstance().getSortedByLabels(true)
val apiService = PayNymApiService.getInstance(strPaymentCode, getApplication())
val jobs = arrayListOf<Deferred<Response>>()
pcodes.forEach {
val job = async { apiService.follow(it) }
jobs.add(job)
job.invokeOnCompletion {
if (it == null) {
BIP47Meta.directoryTaskCompleted = true
}
}
}
jobs.awaitAll()
} catch (ex: Exception) {
ex.printStackTrace()
}
}
}
fun init() {
paymentCode.postValue("")
......@@ -242,15 +201,6 @@ class PayNymViewModel(application: Application) : AndroidViewModel(application)
viewModelScope.launch {
withContext(Dispatchers.IO) {
try {
val _pcodes = BIP47Meta.getInstance().getSortedByLabels(false)
val list: ArrayList<String> = ArrayList<String>()
for (pcode in _pcodes) {
list.add(pcode)
}
sortByLabel(list)
viewModelScope.launch(Dispatchers.Main) {
followingList.postValue(list)
}
val res = PayloadUtil.getInstance(getApplication()).deserializePayNyms().toString()
setPaynymPayload(JSONObject(res))
} catch (ex: Exception) {
......@@ -262,7 +212,7 @@ class PayNymViewModel(application: Application) : AndroidViewModel(application)
public fun doFollow(pcode: String) {
viewModelScope.launch {
withContext(Dispatchers.Main){
withContext(Dispatchers.Main) {
loader.postValue(true)
}
withContext(Dispatchers.IO) {
......@@ -271,6 +221,7 @@ class PayNymViewModel(application: Application) : AndroidViewModel(application)
val apiService = PayNymApiService.getInstance(strPaymentCode, getApplication())
apiService.follow(pcode)
BIP47Meta.getInstance().isRequiredRefresh = true
PayloadUtil.getInstance(getApplication()).saveWalletToJSON(CharSequenceX(AccessFactory.getInstance(getApplication()).guid + AccessFactory.getInstance(getApplication()).pin))
//Refresh
getPayNymData()
} catch (ex: Exception) {
......@@ -278,18 +229,18 @@ class PayNymViewModel(application: Application) : AndroidViewModel(application)
}
}
}.invokeOnCompletion {
viewModelScope.launch (Dispatchers.Main){
viewModelScope.launch(Dispatchers.Main) {
loader.postValue(false)
}
if(it != null){
if (it != null) {
errors.postValue(it.message)
}
}
}
public fun doUnFollow(pcode: String): Job {
val job = viewModelScope.launch {
withContext(Dispatchers.Main){
val job = viewModelScope.launch {
withContext(Dispatchers.Main) {
loader.postValue(true)
}
withContext(Dispatchers.IO) {
......@@ -300,6 +251,7 @@ class PayNymViewModel(application: Application) : AndroidViewModel(application)
BIP47Meta.getInstance().remove(pcode)
BIP47Meta.getInstance().isRequiredRefresh = true
//Refresh
PayloadUtil.getInstance(getApplication()).saveWalletToJSON(CharSequenceX(AccessFactory.getInstance(getApplication()).guid + AccessFactory.getInstance(getApplication()).pin))
getPayNymData()
} catch (ex: Exception) {
throw CancellationException(ex.message)
......@@ -307,10 +259,10 @@ class PayNymViewModel(application: Application) : AndroidViewModel(application)
}
}
job.invokeOnCompletion {
viewModelScope.launch (Dispatchers.Main){
viewModelScope.launch(Dispatchers.Main) {
loader.postValue(false)
}
if(it != null){
if (it != null) {
errors.postValue(it.message)
}
}
......
package com.samourai.wallet.paynym.fragments;
import androidx.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
......@@ -10,6 +9,7 @@ import androidx.core.app.ActivityOptionsCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
......@@ -21,15 +21,14 @@ import com.samourai.wallet.bip47.paynym.WebUtil;
import com.samourai.wallet.paynym.paynymDetails.PayNymDetailsActivity;
import com.samourai.wallet.widgets.CircleImageView;
import com.samourai.wallet.widgets.ItemDividerDecorator;
import com.squareup.picasso.NetworkPolicy;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class PaynymListFragment extends Fragment {
private PaynymListFragmentViewModel mViewModel;
private RecyclerView list;
private static final String TAG = "PaynymListFragment";
private PaynymAdapter paynymAdapter;
......@@ -57,18 +56,15 @@ public class PaynymListFragment extends Fragment {
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = ViewModelProviders.of(this).get(PaynymListFragmentViewModel.class);
paynymAdapter = new PaynymAdapter();
list.setAdapter(paynymAdapter);
mViewModel.pcodes.observe(this, paynymAdapter::setPcodes);
}
public void addPcodes(ArrayList<String> list) {
if (mViewModel == null) {
mViewModel = ViewModelProviders.of(this).get(PaynymListFragmentViewModel.class);
if(isAdded()){
paynymAdapter.setPcodes(list);
}
mViewModel.addPcodes(list);
}
private ArrayList<String> filterArchived(ArrayList<String> list) {
......
package com.samourai.wallet.paynym.fragments;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.ArrayList;
public class PaynymListFragmentViewModel extends ViewModel {
MutableLiveData<ArrayList<String>> pcodes = new MutableLiveData<>();
public PaynymListFragmentViewModel() {
this.pcodes.setValue(new ArrayList<>());
}
void addPcodes(ArrayList<String> list) {
this.pcodes.setValue(list);
}
}
package com.samourai.wallet.paynym.models
/**
* samourai-wallet-android
*/
data class PayNym(val code: String,
val nymName: String?,
val claimed: Boolean? = false,
val segwit: Boolean = false,
val nymId: String?)
data class NymResponse(
val codes: ArrayList<PayNym>?,
val followers: ArrayList<PayNym>?,
val following: ArrayList<PayNym>?,
val nymAvatar: String,
val nymID: String,
val nymName: String,
val segwit: Boolean?,
)
\ No newline at end of file
......@@ -133,15 +133,17 @@ class PayNymDetailsActivity : SamouraiActivity() {
if (BIP47Meta.getInstance().getIncomingIdx(pcode) >= 0) {
historyLayout!!.visibility = View.VISIBLE
}
if (BIP47Meta.getInstance().exists(pcode, true)) {
if (BIP47Meta.getInstance().isFollowing(pcode)) {
followBtn.text = getString(R.string.connect)
feeMessage.text = getString(R.string.connect_paynym_fee)
followMessage.text = "${getString(R.string.blockchain_connect_with)} ${getLabel()} ${resources.getText(R.string.paynym_connect_message)}"
followMessage.text = "${getString(R.string.blockchain_connect_with)} ${getLabel()} ${resources.getText(R.string.paynym_connect_message)}"
if (!following)
addChip(getString(R.string.following))
following = true
} else {
feeMessage.text = getString(R.string.follow_paynym_fee_free)
if (!BIP47Meta.getInstance().exists(pcode, true)) {
feeMessage.text = getString(R.string.follow_paynym_fee_free)
}
}
paynymCode.text = BIP47Meta.getInstance().getAbbreviatedPcode(pcode)
title = getLabel()
......@@ -235,9 +237,8 @@ class PayNymDetailsActivity : SamouraiActivity() {
}
private fun followPaynym() {
if (BIP47Meta.getInstance().exists(pcode, true)) {
doNotifTx()
if (BIP47Meta.getInstance().isFollowing(pcode)) {
doNotifTx()
} else {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.confirm)
......@@ -250,6 +251,7 @@ class PayNymDetailsActivity : SamouraiActivity() {
.setNegativeButton("No") { _, _ -> }
.show()
}
}
private fun getLabel(): String {
......@@ -689,18 +691,12 @@ class PayNymDetailsActivity : SamouraiActivity() {
var tx = SendFactory.getInstance(this@PayNymDetailsActivity).makeTransaction(0, outpoints, receivers)
if (tx != null) {
val input0hash = tx.getInput(0L).outpoint.hash.toString()
Log.d("PayNymDetailsActivity", "input0 hash:$input0hash")
Log.d("PayNymDetailsActivity", "_outPoint hash:" + _outPoint.txHash.toString())
val input0index = tx.getInput(0L).outpoint.index.toInt()
Log.d("PayNymDetailsActivity", "input0 index:$input0index")
Log.d("PayNymDetailsActivity", "_outPoint index:" + _outPoint.txOutputN)
if (input0hash != _outPoint.txHash.toString() || input0index != _outPoint.txOutputN) {
throw Exception(getString(R.string.bip47_cannot_compose_notif_tx))
}
tx = SendFactory.getInstance(this@PayNymDetailsActivity).signTransaction(tx, 0)
val hexTx = String(Hex.encode(tx.bitcoinSerialize()))
Log.d("SendActivity", tx.hashAsString)
Log.d("SendActivity", hexTx)
var isOK = false
var response: String? = null
try {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment