diff --git a/app/assets/countries.json b/app/assets/countries.json new file mode 100644 index 000000000..55f8b1e1d --- /dev/null +++ b/app/assets/countries.json @@ -0,0 +1,172 @@ +{ + "countries": [ + { + "name": "United States", + "code": "+1", + "currency": "USD", + "short": "us", + "top": 210, + "left": 210 + }, + { + "name": "United Kingdom", + "code": "+44", + "currency": "USD", + "short": "uk", + "top": 268, + "left": 132 + }, + { + "name": "Argentina", + "code": "+54", + "currency": "USD", + "short": "ar", + "top": 100, + "left": 194 + }, + { + "name": "Australia", + "code": "+61", + "currency": "USD", + "short": "au", + "top": 247, + "left": 33 + }, + { + "name": "Brazil", + "code": "+55", + "currency": "USD", + "short": "br", + "top": 63, + "left": 47 + }, + { + "name": "Canada", + "code": "+1", + "currency": "USD", + "short": "ca", + "top": 268, + "left": 55 + }, + { + "name": "China", + "code": "+86", + "currency": "USD", + "short": "cn", + "top": 105, + "left": 55 + }, + { + "name": "Germany", + "code": "+49", + "currency": "USD", + "short": "de", + "top": 42, + "left": 210 + }, + { + "name": "Ghana", + "code": "+233", + "currency": "USD", + "short": "gh", + "top": 105, + "left": 121 + }, + { + "name": "Hong Kong", + "code": "+852", + "currency": "USD", + "short": "hk", + "top": 147, + "left": 116 + }, + { + "name": "Latvia", + "code": "+371", + "currency": "USD", + "short": "lv", + "top": 147, + "left": 176 + }, + { + "name": "Malaysia", + "code": "+60", + "currency": "USD", + "short": "my", + "top": 268, + "left": 22 + }, + { + "name": "Mexico", + "code": "+52", + "currency": "USD", + "short": "mx", + "top": 268, + "left": 210 + }, + { + "name": "Nigeria", + "code": "+234", + "currency": "USD", + "short": "ng", + "top": 268, + "left": 110 + }, + { + "name": "Philippines", + "code": "+63", + "currency": "USD", + "short": "ph", + "top": 42, + "left": 234 + }, + { + "name": "Poland", + "code": "+48", + "currency": "USD", + "short": "pl", + "top": 142, + "left": 194 + }, + { + "name": "Portugal", + "code": "+351", + "currency": "USD", + "short": "pt", + "top": 147, + "left": 179 + }, + { + "name": "Romania", + "code": "+40", + "currency": "USD", + "short": "ro", + "top": 84, + "left": 179 + }, + { + "name": "Russia", + "code": "+7", + "currency": "USD", + "short": "ru", + "top": 189, + "left": 116 + }, + { + "name": "Singapore", + "code": "+65", + "currency": "USD", + "short": "sg", + "top": 168, + "left": 116 + }, + { + "name": "Spain", + "code": "+34", + "currency": "USD", + "short": "es", + "top": 123, + "left": 29 + } + ] +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index f2d5d59a9..96660ee4d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,7 +18,9 @@ android { lintOptions { abortOnError false } - + dataBinding { + enabled = true + } dexOptions { javaMaxHeapSize "4g" } @@ -44,7 +46,14 @@ android { } + packagingOptions { + exclude 'org/bitcoinj/crypto/mnemonic/wordlist/english.txt' + exclude 'org/bitcoinj/crypto/cacerts' + exclude 'org.bitcoin.production.checkpoints.txt' + exclude 'org.bitcoin.test.checkpoints.txt' + + } } @@ -87,4 +96,18 @@ dependencies { testCompile 'org.json:json:20170516' testCompile 'org.apache.httpcomponents:httpclient:4.5.3' testCompile 'org.mockito:mockito-core:2.8.9' + + + //wall of coins + compile 'com.squareup.retrofit2:retrofit:2.0.2' + compile 'com.squareup.retrofit2:converter-gson:2.0.2' + compile 'com.squareup.okhttp3:logging-interceptor:3.3.1' + compile 'com.squareup.okhttp:logging-interceptor:2.7.5' + compile 'com.google.code.findbugs:jsr305:2.0.3' + + //selling dependencies + + compile 'com.github.joielechong:countrycodepicker:2.1.5' + } + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0c969e496..62d07f63e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,95 +2,145 @@ - - - - - - - - + + + + + + + + - + android:theme="@style/AppTheme"> + - + - + android:screenOrientation="portrait"> - + - - - - - - - + + + + + + + - - - - - - + + + + + + - - + android:screenOrientation="portrait" /> + - + + + + + + + - - - - - - - + android:screenOrientation="portrait"> - - - + + + - - - + + + - @@ -105,7 +155,14 @@ android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_provider_paths" /> + + diff --git a/app/src/main/java/pivx/org/pivxwallet/PivxApplication.java b/app/src/main/java/pivx/org/pivxwallet/PivxApplication.java index d3956fa4d..7debab3d9 100644 --- a/app/src/main/java/pivx/org/pivxwallet/PivxApplication.java +++ b/app/src/main/java/pivx/org/pivxwallet/PivxApplication.java @@ -9,13 +9,9 @@ import android.net.Uri; import android.support.v4.content.FileProvider; -import com.github.anrwatchdog.ANRWatchDog; -import com.snappydb.SnappydbException; - import org.acra.ACRA; import org.acra.ReportingInteractionMode; import org.acra.annotation.ReportsCrashes; -import org.pivxj.store.BlockStore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,9 +23,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.atomic.AtomicBoolean; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.LoggerContext; @@ -48,17 +41,14 @@ import pivx.org.pivxwallet.module.PivxModule; import pivx.org.pivxwallet.module.PivxModuleImp; import pivx.org.pivxwallet.module.WalletConfImp; -import pivx.org.pivxwallet.module.store.SnappyBlockchainStore; import pivx.org.pivxwallet.rate.db.RateDb; import pivx.org.pivxwallet.service.PivxWalletService; import pivx.org.pivxwallet.utils.AppConf; import pivx.org.pivxwallet.utils.CentralFormats; import pivx.org.pivxwallet.utils.CrashReporter; -import store.AddressStore; import static pivx.org.pivxwallet.service.IntentsConstants.ACTION_RESET_BLOCKCHAIN; import static pivx.org.pivxwallet.utils.AndroidUtils.shareText; - /** * Created by mati on 18/04/17. */ diff --git a/app/src/main/java/pivx/org/pivxwallet/module/PivxModule.java b/app/src/main/java/pivx/org/pivxwallet/module/PivxModule.java index df8ed2fe9..993f75a3c 100644 --- a/app/src/main/java/pivx/org/pivxwallet/module/PivxModule.java +++ b/app/src/main/java/pivx/org/pivxwallet/module/PivxModule.java @@ -16,7 +16,6 @@ import java.io.File; import java.io.IOException; import java.math.BigDecimal; -import java.util.Collection; import java.util.List; import java.util.Set; @@ -25,9 +24,9 @@ import pivx.org.pivxwallet.rate.db.PivxRate; import pivx.org.pivxwallet.ui.transaction_send_activity.custom.inputs.InputWrapper; import pivx.org.pivxwallet.ui.wallet_activity.TransactionWrapper; +import wallet.exceptions.CantRestoreEncryptedWallet; import wallet.exceptions.InsufficientInputsException; import wallet.exceptions.TxNotFoundException; -import wallet.exceptions.CantRestoreEncryptedWallet; /** * Created by mati on 18/04/17. diff --git a/app/src/main/java/pivx/org/pivxwallet/ui/base/BaseDrawerActivity.java b/app/src/main/java/pivx/org/pivxwallet/ui/base/BaseDrawerActivity.java index e39cbef95..f92dc22a7 100644 --- a/app/src/main/java/pivx/org/pivxwallet/ui/base/BaseDrawerActivity.java +++ b/app/src/main/java/pivx/org/pivxwallet/ui/base/BaseDrawerActivity.java @@ -26,6 +26,7 @@ import pivx.org.pivxwallet.ui.donate.DonateActivity; import pivx.org.pivxwallet.ui.settings_activity.SettingsActivity; import pivx.org.pivxwallet.ui.wallet_activity.WalletActivity; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseActivity; import static pivx.org.pivxwallet.module.PivxContext.OUT_OF_SYNC_TIME; import static pivx.org.pivxwallet.service.IntentsConstants.ACTION_NOTIFICATION; @@ -50,7 +51,7 @@ public class BaseDrawerActivity extends PivxActivity implements NavigationView.O private BroadcastReceiver walletServiceReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (intent.hasExtra(INTENT_BROADCAST_DATA_TYPE)){ + if (intent.hasExtra(INTENT_BROADCAST_DATA_TYPE)) { if (intent.getStringExtra(INTENT_BROADCAST_DATA_TYPE).equals(INTENT_BROADCAST_DATA_BLOCKCHAIN_STATE)) { BlockchainState blockchainStateNew = (BlockchainState) intent.getSerializableExtra(INTENT_EXTRA_BLOCKCHAIN_STATE); onBlockchainStateChange(); @@ -60,7 +61,7 @@ public void onReceive(Context context, Intent intent) { } blockchainState = blockchainStateNew; updateBlockchainState(); - }else if(intent.getStringExtra(INTENT_BROADCAST_DATA_TYPE).equals(INTENT_BROADCAST_DATA_PEER_CONNECTED)){ + } else if (intent.getStringExtra(INTENT_BROADCAST_DATA_TYPE).equals(INTENT_BROADCAST_DATA_PEER_CONNECTED)) { checkState(); updateBlockchainState(); } @@ -91,39 +92,39 @@ protected void onCreate(Bundle savedInstanceState) { txt_app_version = (TextView) navigationView.findViewById(R.id.txt_app_version); txt_app_version.setText(BuildConfig.VERSION_NAME); - onCreateView(savedInstanceState,frameLayout); + onCreateView(savedInstanceState, frameLayout); - localBroadcastManager.registerReceiver(walletServiceReceiver,new IntentFilter(ACTION_NOTIFICATION)); + localBroadcastManager.registerReceiver(walletServiceReceiver, new IntentFilter(ACTION_NOTIFICATION)); } - private void checkState(){ + private void checkState() { long now = System.currentTimeMillis(); long lastBlockTime = pivxApplication.getAppConf().getLastBestChainBlockTime(); - if (lastBlockTime+OUT_OF_SYNC_TIME>now){ + if (lastBlockTime + OUT_OF_SYNC_TIME > now) { // check if i'm syncing or i'm synched long peerHeight = pivxModule.getConnectedPeerHeight(); - if (peerHeight!=-1){ - if (pivxModule.getChainHeight()+10>peerHeight) { + if (peerHeight != -1) { + if (pivxModule.getChainHeight() + 10 > peerHeight) { blockchainState = BlockchainState.SYNC; - }else { + } else { blockchainState = BlockchainState.SYNCING; } - }else { + } else { blockchainState = BlockchainState.NOT_CONNECTION; } - }else { + } else { if (pivxModule.isAnyPeerConnected()) { long peerHeight = pivxModule.getConnectedPeerHeight(); - if (peerHeight!=-1){ - if (pivxModule.getChainHeight()+10>peerHeight) { + if (peerHeight != -1) { + if (pivxModule.getChainHeight() + 10 > peerHeight) { blockchainState = BlockchainState.SYNC; - }else { + } else { blockchainState = BlockchainState.SYNCING; } - }else { + } else { blockchainState = BlockchainState.NOT_CONNECTION; } - }else { + } else { blockchainState = BlockchainState.NOT_CONNECTION; } } @@ -148,7 +149,7 @@ protected void onDestroy() { /** * Empty method to check some status before set the main layout of the activity */ - protected void beforeCreate(){ + protected void beforeCreate() { } @@ -157,7 +158,7 @@ protected void beforeCreate(){ * * @param savedInstanceState */ - protected void onCreateView(Bundle savedInstanceState, ViewGroup container){ + protected void onCreateView(Bundle savedInstanceState, ViewGroup container) { } @@ -192,13 +193,13 @@ public boolean onNavigationItemSelected(MenuItem item) { int id = item.getItemId(); //to prevent current item select over and over - if (item.isChecked()){ + if (item.isChecked()) { drawer.closeDrawer(GravityCompat.START); return false; } if (id == R.id.nav_wallet) { - Intent intent = new Intent(this,WalletActivity.class); + Intent intent = new Intent(this, WalletActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(intent); finish(); @@ -206,23 +207,26 @@ public boolean onNavigationItemSelected(MenuItem item) { startActivity(new Intent(this, ContactsActivity.class)); } else if (id == R.id.nav_settings) { startActivity(new Intent(this, SettingsActivity.class)); - } else if (id == R.id.nav_donations){ + } else if (id == R.id.nav_donations) { startActivity(new Intent(this, DonateActivity.class)); + } else if (id == R.id.nav_buywithcash) { + startActivity(new Intent(this, BuyingWizardBaseActivity.class)); } + drawer.closeDrawer(GravityCompat.START); return true; } - protected void setNavigationMenuItemChecked(int pos){ + protected void setNavigationMenuItemChecked(int pos) { navigationView.getMenu().getItem(pos).setChecked(true); } private void updateBlockchainState() { // Check if the activity is on foreground - if (!isOnForeground)return; + if (!isOnForeground) return; - if (txt_sync_status!=null) { + if (txt_sync_status != null) { String text = null; int color = 0; int imgSrc = 0; @@ -234,7 +238,7 @@ private void updateBlockchainState() { imgSrc = 0; break; case SYNCING: - text = getString(R.string.syncing)+" "+progress+"%"; + text = getString(R.string.syncing) + " " + progress + "%"; color = Color.parseColor("#f6a623"); imgSrc = R.drawable.ic_header_unsynced; break; @@ -246,21 +250,21 @@ private void updateBlockchainState() { } txt_sync_status.setText(text); txt_sync_status.setTextColor(color); - if (imgSrc!=0) { + if (imgSrc != 0) { img_sync.setImageResource(imgSrc); img_sync.setVisibility(View.VISIBLE); - }else + } else img_sync.setVisibility(View.INVISIBLE); } } private double calculateBlockchainSyncProgress() { long nodeHeight = pivxModule.getConnectedPeerHeight(); - if (nodeHeight>0){ + if (nodeHeight > 0) { // calculate the progress // nodeHeight -> 100 % // current height -> x % - return (pivxModule.getChainHeight()*100) / nodeHeight; + return (pivxModule.getChainHeight() * 100) / nodeHeight; } return -1; } diff --git a/app/src/main/java/pivx/org/pivxwallet/ui/base/BaseRecyclerFragment.java b/app/src/main/java/pivx/org/pivxwallet/ui/base/BaseRecyclerFragment.java index 76edbe438..15f82809f 100644 --- a/app/src/main/java/pivx/org/pivxwallet/ui/base/BaseRecyclerFragment.java +++ b/app/src/main/java/pivx/org/pivxwallet/ui/base/BaseRecyclerFragment.java @@ -35,8 +35,8 @@ public abstract class BaseRecyclerFragment extends BaseFragment { private RecyclerView recycler; private SwipeRefreshLayout swipeRefreshLayout; private View container_empty_screen; - private TextView txt_empty; - private ImageView imgEmptyView; + protected TextView txt_empty; + protected ImageView imgEmptyView; private BaseRecyclerAdapter adapter; protected List list; @@ -53,7 +53,7 @@ public BaseRecyclerFragment() { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - super.onCreateView(inflater,container,savedInstanceState); + super.onCreateView(inflater, container, savedInstanceState); root = inflater.inflate(R.layout.base_recycler_fragment, container, false); recycler = (RecyclerView) root.findViewById(R.id.recycler_contacts); swipeRefreshLayout = (SwipeRefreshLayout) root.findViewById(R.id.swipeRefresh); @@ -64,7 +64,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, layoutManager = new LinearLayoutManager(getActivity()); recycler.setLayoutManager(layoutManager); adapter = initAdapter(); - if (adapter==null) throw new IllegalStateException("Base adapter cannot be null"); + if (adapter == null) throw new IllegalStateException("Base adapter cannot be null"); recycler.setAdapter(adapter); swipeRefreshLayout.setEnabled(refreshSwipeEnabled); swipeRefreshLayout.setOnRefreshListener( @@ -75,13 +75,15 @@ public void onRefresh() { } } ); + + return root; } @Override public void onResume() { super.onResume(); - if (executor==null){ + if (executor == null) { executor = Executors.newSingleThreadExecutor(); } load(); @@ -92,11 +94,11 @@ public void onResume() { */ private void load() { swipeRefreshLayout.setRefreshing(true); - if (executor!=null) + if (executor != null) executor.execute(loadRunnable); } - public void refresh(){ + public void refresh() { load(); } @@ -104,32 +106,30 @@ public void refresh(){ @Override public void onStop() { super.onStop(); - if (executor!=null){ + if (executor != null) { executor.shutdownNow(); executor = null; } } /** - * * @return list of items */ protected abstract List onLoading(); /** - * * @return the main adapter */ - protected abstract BaseRecyclerAdapter initAdapter(); + protected abstract BaseRecyclerAdapter initAdapter(); - protected V findViewById(int id,Class clazz){ + protected V findViewById(int id, Class clazz) { return (V) root.findViewById(id); } protected Runnable loadRunnable = new Runnable() { @Override public void run() { - if (getActivity()!=null) { + if (getActivity() != null) { boolean res = false; try { list = onLoading(); @@ -160,37 +160,37 @@ public void run() { } }; - protected void setSwipeRefresh(boolean enable){ + protected void setSwipeRefresh(boolean enable) { this.refreshSwipeEnabled = enable; } - protected void setEmptyText(String text){ + protected void setEmptyText(String text) { this.emptyText = text; - if (txt_empty!=null){ + if (txt_empty != null) { txt_empty.setText(emptyText); } } - protected void setEmptyTextColor(int color){ - if (txt_empty!=null){ + protected void setEmptyTextColor(int color) { + if (txt_empty != null) { txt_empty.setTextColor(color); } } - protected void setEmptyView(int imgRes){ - if (imgEmptyView!=null){ + protected void setEmptyView(int imgRes) { + if (imgEmptyView != null) { imgEmptyView.setImageResource(imgRes); } } - private void showEmptyScreen(){ + private void showEmptyScreen() { // if (container_empty_screen!=null) // AnimationUtils.fadeInView(container_empty_screen,300); container_empty_screen.setVisibility(View.VISIBLE); } - private void hideEmptyScreen(){ + private void hideEmptyScreen() { container_empty_screen.setVisibility(View.GONE); // if (container_empty_screen!=null) // AnimationUtils.fadeOutView(container_empty_screen,300); diff --git a/app/src/main/java/pivx/org/pivxwallet/ui/qr_activity/MyAddressFragment.java b/app/src/main/java/pivx/org/pivxwallet/ui/qr_activity/MyAddressFragment.java index 9958f95b4..08e7abce3 100644 --- a/app/src/main/java/pivx/org/pivxwallet/ui/qr_activity/MyAddressFragment.java +++ b/app/src/main/java/pivx/org/pivxwallet/ui/qr_activity/MyAddressFragment.java @@ -25,6 +25,7 @@ import pivx.org.pivxwallet.PivxApplication; import pivx.org.pivxwallet.R; import pivx.org.pivxwallet.module.PivxModule; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseActivity; import static android.graphics.Color.WHITE; import static pivx.org.pivxwallet.utils.AndroidUtils.copyToClipboard; @@ -41,7 +42,7 @@ public class MyAddressFragment extends Fragment implements View.OnClickListener private View root; private TextView txt_address; private Button btn_share; - private Button btn_copy; + private Button btn_copy,btn_buy; private ImageView img_qr; private Address address; @@ -62,7 +63,9 @@ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, btn_copy = (Button) root.findViewById(R.id.btn_copy); btn_copy.setOnClickListener(this); img_qr = (ImageView) root.findViewById(R.id.img_qr); + btn_buy = (Button) root.findViewById(R.id.btn_buy); btn_share.setOnClickListener(this); + btn_buy.setOnClickListener(this); img_qr.setOnClickListener(this); return root; } @@ -132,5 +135,8 @@ public void onClick(View v) { copyToClipboard(getActivity(),address.toBase58()); Toast.makeText(v.getContext(), R.string.copy_message, Toast.LENGTH_LONG).show(); } + else if (id == R.id.btn_buy) { + startActivity(new Intent(getActivity(), BuyingWizardBaseActivity.class)); + } } } diff --git a/app/src/main/java/pivx/org/pivxwallet/ui/wallet_activity/TransactionsFragmentBase.java b/app/src/main/java/pivx/org/pivxwallet/ui/wallet_activity/TransactionsFragmentBase.java index b799bb349..c4f9c4e7c 100644 --- a/app/src/main/java/pivx/org/pivxwallet/ui/wallet_activity/TransactionsFragmentBase.java +++ b/app/src/main/java/pivx/org/pivxwallet/ui/wallet_activity/TransactionsFragmentBase.java @@ -25,6 +25,7 @@ import pivx.org.pivxwallet.ui.base.tools.adapter.BaseRecyclerViewHolder; import pivx.org.pivxwallet.ui.base.tools.adapter.ListItemListeners; import pivx.org.pivxwallet.ui.transaction_detail_activity.TransactionDetailActivity; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseActivity; import static pivx.org.pivxwallet.ui.transaction_detail_activity.FragmentTxDetail.IS_DETAIL; import static pivx.org.pivxwallet.ui.transaction_detail_activity.FragmentTxDetail.TX_WRAPPER; @@ -45,9 +46,25 @@ public class TransactionsFragmentBase extends BaseRecyclerFragment"); + + //setEmptyText("You don't have any transfers yet."); setEmptyTextColor(Color.parseColor("#cccccc")); + imgEmptyView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(getActivity(), BuyingWizardBaseActivity.class); + startActivity(intent); + } + }); + txt_empty.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(getActivity(), BuyingWizardBaseActivity.class); + startActivity(intent); + } + }); return view; } diff --git a/app/src/main/java/pivx/org/pivxwallet/ui/wallet_activity/WalletActivity.java b/app/src/main/java/pivx/org/pivxwallet/ui/wallet_activity/WalletActivity.java index 08f57f4e2..fb9455a26 100644 --- a/app/src/main/java/pivx/org/pivxwallet/ui/wallet_activity/WalletActivity.java +++ b/app/src/main/java/pivx/org/pivxwallet/ui/wallet_activity/WalletActivity.java @@ -1,6 +1,5 @@ package pivx.org.pivxwallet.ui.wallet_activity; -import android.app.DialogFragment; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -9,7 +8,6 @@ import android.graphics.Color; import android.os.Build; import android.os.Bundle; -import android.support.design.widget.FloatingActionButton; import android.support.v4.content.ContextCompat; import android.support.v4.content.LocalBroadcastManager; import android.view.Menu; @@ -28,7 +26,6 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; import pivx.org.pivxwallet.R; import pivx.org.pivxwallet.module.NoPeerConnectedException; diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/BuyPivPref.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/BuyPivPref.java new file mode 100644 index 000000000..17ecbdc0d --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/BuyPivPref.java @@ -0,0 +1,134 @@ +/* + * Copyright 2014-2015 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package pivx.org.pivxwallet.wallofcoins; + +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; + +import com.google.gson.Gson; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pivx.org.pivxwallet.wallofcoins.response.CreateHoldResp; + + +/** + * Class for Manage Buy SharedPreferences + * @author Andreas Schildbach + */ +public class BuyPivPref { + + private final SharedPreferences prefs; + private final Gson gson; + private static final String CREATE_HOLD_RESP = "create_hold_resp"; + private static final String AUTH_TOKEN = "auth_token"; + private static final String HOLD_ID = "hold_id"; + private static final String PHONE = "phone"; + private static final String EMAIL = "email"; + private static final String DEVICE_CODE = "device_code"; + private static final String DEVICE_ID = "device_id"; + + + private static final Logger log = LoggerFactory.getLogger(BuyPivPref.class); + + public BuyPivPref(final SharedPreferences prefs) { + this.prefs = prefs; + gson = new Gson(); + } + + public String getAuthToken() { + return prefs.getString(AUTH_TOKEN, ""); + } + + public void setAuthToken(String authToken) { + prefs.edit().putString(AUTH_TOKEN, authToken).apply(); + } + + public String getPhone() { + return prefs.getString(PHONE, ""); + } + + public void setPhone(String authToken) { + prefs.edit().putString(PHONE, authToken).apply(); + } + + public String getDeviceCode() { + return prefs.getString(DEVICE_CODE, ""); + } + + public void setDeviceCode(String deviceCode) { + prefs.edit().putString(DEVICE_CODE, deviceCode).apply(); + } + + public String getDeviceId() { + return prefs.getString(DEVICE_ID, ""); + } + + public void setDeviceId(String deviceId) { + prefs.edit().putString(DEVICE_ID, deviceId).apply(); + } + public String getEmail() { + return prefs.getString(EMAIL, ""); + } + + public void setEmail(String authToken) { + prefs.edit().putString(EMAIL, authToken).apply(); + } + + public String getHoldId() { + return prefs.getString(HOLD_ID, ""); + } + + public void setHoldId(String holdId) { + if (holdId != null) { + prefs.edit().putString(HOLD_ID, holdId).apply(); + } else { + prefs.edit().remove(HOLD_ID); + } + } + + public void clearAllPrefrance(){ + setDeviceId(""); + setAuthToken(""); + setDeviceCode(""); + setCreateHoldResp(null); + setPhone(""); + prefs.edit().clear(); + } + + public CreateHoldResp getCreateHoldResp() { + return gson.fromJson(prefs.getString(CREATE_HOLD_RESP, ""), CreateHoldResp.class); + } + + public void setCreateHoldResp(CreateHoldResp createHoldResp) { + if (createHoldResp != null) { + prefs.edit().putString(CREATE_HOLD_RESP, gson.toJson(createHoldResp)).apply(); + } else { + prefs.edit().remove(CREATE_HOLD_RESP); + } + } + + public void registerOnSharedPreferenceChangeListener(final OnSharedPreferenceChangeListener listener) { + prefs.registerOnSharedPreferenceChangeListener(listener); + } + + public void unregisterOnSharedPreferenceChangeListener(final OnSharedPreferenceChangeListener listener) { + prefs.unregisterOnSharedPreferenceChangeListener(listener); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/CustomAdapter.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/CustomAdapter.java new file mode 100644 index 000000000..9ba8fd52c --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/CustomAdapter.java @@ -0,0 +1,82 @@ +package pivx.org.pivxwallet.wallofcoins; + +import android.app.Activity; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.support.annotation.NonNull; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import java.util.List; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.wallofcoins.response.CountryData; + + +public class CustomAdapter extends ArrayAdapter { + + private Activity activity; + private List data; + private LayoutInflater inflater; + + public CustomAdapter( + Activity activitySpinner, + int textViewResourceId, + List objects + ) { + super(activitySpinner, textViewResourceId, objects); + + /********** Take passed values **********/ + activity = activitySpinner; + data = objects; + + /*********** Layout inflator to call external xml layout () **********************/ + inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + } + + @Override + public View getDropDownView(int position, View convertView, @NonNull ViewGroup parent) { + return getCustomView(position, convertView, parent); + } + + @Override + public View getView(int position, View convertView, @NonNull ViewGroup parent) { + return getCustomView(position, convertView, parent); + } + + // This funtion called for each row ( Called data.size() times ) + public View getCustomView(int position, View convertView, ViewGroup parent) { + + /********** Inflate spinner_rows.xml file for each row ( Defined below ) ************/ + View row = inflater.inflate(R.layout.spinner_row_country, parent, false); + + /***** Get each Model object from Arraylist ********/ + CountryData.CountriesBean bean = data.get(position); + + TextView label = (TextView) row.findViewById(R.id.tv_country); + ImageView ivCountry = (ImageView) row.findViewById(R.id.iv_country); + + label.setText(bean.name + " (" + bean.code + ")"); + ivCountry.setImageResource(R.drawable.flags); + ivCountry.setScaleType(ImageView.ScaleType.MATRIX); + + Drawable drawable = activity.getResources().getDrawable(R.drawable.flags); + + int height = drawable.getIntrinsicHeight(); + int width = drawable.getIntrinsicWidth(); + + int left = (bean.left * width) / 288; + int top = (bean.top * height) / 266; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + ivCountry.drawableHotspotChanged(left, top); + } + return row; + } + +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/WOCConstants.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/WOCConstants.java new file mode 100644 index 000000000..8d13233f6 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/WOCConstants.java @@ -0,0 +1,59 @@ +package pivx.org.pivxwallet.wallofcoins; + +/** + * Created by WOC on 27-Jan-18. + * Copyright (c) 2018 WOC Limited. All rights reserved. + */ + +public final class WOCConstants { + + + public static final String CRYPTO = "PIVX"; + + // REST FUll API KEY Constant + public static final String KEY_HEADER_AUTH_TOKEN = "X-Coins-Api-Token"; + public static final String KEY_HEADER_PUBLISHER_ID = "X-Coins-Publisher"; + public static final String KEY_HEADER_CONTENT_TYPE = "Content-Type"; + public static final String KEY_HEADER_CONTENT_TYPE_VALUE = "application/json"; + public static final String KEY_PUBLISHER_ID = "publisherId"; + public static final String KEY_VERIFICATION_CODE = "verificationCode"; + public static final String KEY_CRYPTO_ADDRESS = "cryptoAddress"; + public static final String KEY_USD_AMOUNT = "usdAmount"; + public static final String KEY_CRYPTO = "crypto"; + public static final String KEY_COUNTRY = "country"; + public static final String KEY_BANK = "bank"; + public static final String KEY_CRYPTO_AMOUNT = "cryptoAmount"; + public static final String KEY_ZIP_CODE = "zipCode"; + public static final String KEY_BROWSE_LOCATION = "browserLocation"; + public static final String KEY_LATITUDE = "latitude"; + public static final String KEY_LONGITUDE = "longitude"; + public static final String KEY_PASSWORD = "password"; + public static final String KEY_DEVICECODE = "deviceCode"; + public static final String KEY_DEVICEID = "deviceId"; + public static final String KEY_DEVICE_NAME = "name"; + public static final String KEY_DEVICE_CODE = "code"; + public static final String KEY_PHONE = "phone"; + public static final String KEY_DEVICE_NAME_VALUE = "Piv Wallet (Android)"; + public static final String KEY_OFFER = "offer"; + public static final String KEY_EMAIL = "email"; + public static final String KEY_deviceName = "deviceName"; + + //BuyPiv General Constants + public static final String KEY_WEB_URL = "https://wallofcoins.com/"; + public static final String KEY_FORGOT_PASSWORD_URL = "https://wallofcoins.com/forgotPassword/"; + public static final String SUPPORT_EMAIL = "support@wallofcoins.com"; + public static final String SEND_EMAIL = "Send email..."; + public static final String WOC_ADDRESS = "WallofCoins.com"; + public static final String KEY_SIGN_UP_URL = "https://wallofcoins.com/signup/"; + + + //buying wizard + public static String LATITUDE = "latitude"; + public static String LONGITUDE = "longitude"; + public static String ZIP = "zip"; + public static String BANK_ID = "bankId"; + public static String OFFER_ID = "offerId"; + public static String VERIFICATION_OTP = "otp"; + public static String SCREEN_TYPE = "screenType"; + +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/addressbook/AddressBookProvider.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/addressbook/AddressBookProvider.java new file mode 100644 index 000000000..c5953e333 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/addressbook/AddressBookProvider.java @@ -0,0 +1,246 @@ +/* + * Copyright 2011-2015 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package pivx.org.pivxwallet.wallofcoins.addressbook; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.database.sqlite.SQLiteQueryBuilder; +import android.net.Uri; + +import java.util.List; + +/** + * @author Andreas Schildbach + */ +public class AddressBookProvider extends ContentProvider +{ + private static final String DATABASE_TABLE = "address_book"; + + public static final String KEY_ROWID = "_id"; + public static final String KEY_ADDRESS = "address"; + public static final String KEY_LABEL = "label"; + + public static final String SELECTION_QUERY = "q"; + public static final String SELECTION_IN = "in"; + public static final String SELECTION_NOTIN = "notin"; + + public static Uri contentUri(final String packageName) + { + return Uri.parse("content://" + packageName + '.' + DATABASE_TABLE); + } + + public static String resolveLabel(final Context context, final String address) + { + String label = null; + + final Uri uri = contentUri(context.getPackageName()).buildUpon().appendPath(address).build(); + final Cursor cursor = context.getContentResolver().query(uri, null, null, null, null); + + if (cursor != null) + { + if (cursor.moveToFirst()) + label = cursor.getString(cursor.getColumnIndexOrThrow(AddressBookProvider.KEY_LABEL)); + + cursor.close(); + } + + return label; + } + + private Helper helper; + + @Override + public boolean onCreate() + { + helper = new Helper(getContext()); + return true; + } + + @Override + public String getType(final Uri uri) + { + throw new UnsupportedOperationException(); + } + + @Override + public Uri insert(final Uri uri, final ContentValues values) + { + if (uri.getPathSegments().size() != 1) + throw new IllegalArgumentException(uri.toString()); + + final String address = uri.getLastPathSegment(); + values.put(KEY_ADDRESS, address); + + long rowId = helper.getWritableDatabase().insertOrThrow(DATABASE_TABLE, null, values); + + final Uri rowUri = contentUri(getContext().getPackageName()).buildUpon().appendPath(address).appendPath(Long.toString(rowId)).build(); + + getContext().getContentResolver().notifyChange(rowUri, null); + + return rowUri; + } + + @Override + public int update(final Uri uri, final ContentValues values, final String selection, final String[] selectionArgs) + { + if (uri.getPathSegments().size() != 1) + throw new IllegalArgumentException(uri.toString()); + + final String address = uri.getLastPathSegment(); + + final int count = helper.getWritableDatabase().update(DATABASE_TABLE, values, KEY_ADDRESS + "=?", new String[] { address }); + + if (count > 0) + getContext().getContentResolver().notifyChange(uri, null); + + return count; + } + + @Override + public int delete(final Uri uri, final String selection, final String[] selectionArgs) + { + final List pathSegments = uri.getPathSegments(); + if (pathSegments.size() != 1) + throw new IllegalArgumentException(uri.toString()); + + final String address = uri.getLastPathSegment(); + + final int count = helper.getWritableDatabase().delete(DATABASE_TABLE, KEY_ADDRESS + "=?", new String[] { address }); + + if (count > 0) + getContext().getContentResolver().notifyChange(uri, null); + + return count; + } + + @Override + public Cursor query(final Uri uri, final String[] projection, final String originalSelection, final String[] originalSelectionArgs, + final String sortOrder) + { + final SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); + qb.setTables(DATABASE_TABLE); + + final List pathSegments = uri.getPathSegments(); + if (pathSegments.size() > 1) + throw new IllegalArgumentException(uri.toString()); + + String selection = null; + String[] selectionArgs = null; + + if (pathSegments.size() == 1) + { + final String address = uri.getLastPathSegment(); + + qb.appendWhere(KEY_ADDRESS + "="); + qb.appendWhereEscapeString(address); + } + else if (SELECTION_IN.equals(originalSelection)) + { + final String[] addresses = originalSelectionArgs[0].trim().split(","); + + qb.appendWhere(KEY_ADDRESS + " IN ("); + appendAddresses(qb, addresses); + qb.appendWhere(")"); + } + else if (SELECTION_NOTIN.equals(originalSelection)) + { + final String[] addresses = originalSelectionArgs[0].trim().split(","); + + qb.appendWhere(KEY_ADDRESS + " NOT IN ("); + appendAddresses(qb, addresses); + qb.appendWhere(")"); + } + else if (SELECTION_QUERY.equals(originalSelection)) + { + final String query = '%' + originalSelectionArgs[0].trim() + '%'; + selection = KEY_ADDRESS + " LIKE ? OR " + KEY_LABEL + " LIKE ?"; + selectionArgs = new String[] { query, query }; + } + + final Cursor cursor = qb.query(helper.getReadableDatabase(), projection, selection, selectionArgs, null, null, sortOrder); + + cursor.setNotificationUri(getContext().getContentResolver(), uri); + + return cursor; + } + + private static void appendAddresses(final SQLiteQueryBuilder qb, final String[] addresses) + { + for (final String address : addresses) + { + qb.appendWhereEscapeString(address.trim()); + if (!address.equals(addresses[addresses.length - 1])) + qb.appendWhere(","); + } + } + + private static class Helper extends SQLiteOpenHelper + { + private static final String DATABASE_NAME = "address_book"; + private static final int DATABASE_VERSION = 1; + + private static final String DATABASE_CREATE = "CREATE TABLE " + DATABASE_TABLE + " (" // + + KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " // + + KEY_ADDRESS + " TEXT NOT NULL, " // + + KEY_LABEL + " TEXT NULL);"; + + public Helper(final Context context) + { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(final SQLiteDatabase db) + { + db.execSQL(DATABASE_CREATE); + } + + @Override + public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) + { + db.beginTransaction(); + try + { + for (int v = oldVersion; v < newVersion; v++) + upgrade(db, v); + + db.setTransactionSuccessful(); + } + finally + { + db.endTransaction(); + } + } + + private void upgrade(final SQLiteDatabase db, final int oldVersion) + { + if (oldVersion == 1) + { + // future + } + else + { + throw new UnsupportedOperationException("old=" + oldVersion); + } + } + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/api/RestApi.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/api/RestApi.java new file mode 100644 index 000000000..f5d1f7de7 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/api/RestApi.java @@ -0,0 +1,93 @@ +package pivx.org.pivxwallet.wallofcoins.api; + +import java.util.List; +import java.util.Map; + +import pivx.org.pivxwallet.wallofcoins.response.CaptureHoldResp; +import pivx.org.pivxwallet.wallofcoins.response.CheckAuthResp; +import pivx.org.pivxwallet.wallofcoins.response.ConfirmDepositResp; +import pivx.org.pivxwallet.wallofcoins.response.CreateDeviceResp; +import pivx.org.pivxwallet.wallofcoins.response.CreateHoldResp; +import pivx.org.pivxwallet.wallofcoins.response.DiscoveryInputsResp; +import pivx.org.pivxwallet.wallofcoins.response.GetAuthTokenResp; +import pivx.org.pivxwallet.wallofcoins.response.GetCurrencyResp; +import pivx.org.pivxwallet.wallofcoins.response.GetHoldsResp; +import pivx.org.pivxwallet.wallofcoins.response.GetOffersResp; +import pivx.org.pivxwallet.wallofcoins.response.GetReceivingOptionsResp; +import pivx.org.pivxwallet.wallofcoins.response.OrderListResp; +import retrofit2.Call; +import retrofit2.http.DELETE; +import retrofit2.http.Field; +import retrofit2.http.FieldMap; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.POST; +import retrofit2.http.Path; +import retrofit2.http.Query; + +/** + * RestApi Client Interface For all WOC RestFull API with Method + * Get,Post,Update & Delete API call + */ +public interface RestApi { + + + @GET("api/v1/orders/") + Call> getOrders(@Query("publisherId") String publisherId); + + + @GET("api/v1/auth/{phone}/") + Call checkAuth(@Path("phone") String username, @Query("publisherId") String publisherId); + + @DELETE("api/v1/auth/{phone}/") + Call deleteAuth(@Path("phone") String username, @Query("publisherId") String publisherId); + + @DELETE("api/v1/orders/{orderId}/") + Call cancelOrder(@Path("orderId") String orderId, @Query("publisherId") String publisherId); + + @FormUrlEncoded + @POST("api/v1/auth/{phone}/authorize/") + Call getAuthToken(@Path("phone") String username, @FieldMap Map partMap); + + + //--------------buy wizard + @GET("api/v1/banks/") + Call> getReceivingOptions(); + //---------------------- + + @GET("api/v1/currency/") + Call> getCurrency(); + + @FormUrlEncoded + @POST("api/v1/discoveryInputs/") + Call discoveryInputs(@FieldMap Map partMap); + + @GET("api/v1/discoveryInputs/{discoveryId}/offers/") + Call getOffers(@Path("discoveryId") String discoveryId, @Query("publisherId") String publisherId); + + @FormUrlEncoded + @POST("api/v1/holds/") + Call createHold(@FieldMap Map partMap); + + @GET("api/v1/holds/") + Call> getHolds(); + + @DELETE("api/v1/holds/{id}/") + Call deleteHold(@Path("id") String id); + + @FormUrlEncoded + @POST("api/v1/holds/{id}/capture/") + Call> captureHold(@Path("id") String id, @FieldMap Map partMap); + + @FormUrlEncoded + @POST("api/v1/orders/{holdId}/confirmDeposit/") + Call confirmDeposit(@Path("holdId") String holdId, @Field("your_field") String yourField, @Query("publisherId") String publisherId); + + @FormUrlEncoded + @POST("api/v1/devices/") + Call createDevice(@FieldMap Map partMap); + + @GET("api/v1/devices/") + Call> getDevice(); + +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/api/WallofCoins.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/api/WallofCoins.java new file mode 100644 index 000000000..cac6141e2 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/api/WallofCoins.java @@ -0,0 +1,129 @@ +package pivx.org.pivxwallet.wallofcoins.api; + +import android.content.Context; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.security.KeyStore; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import pivx.org.pivxwallet.BuildConfig; +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.wallofcoins.response.GetReceivingOptionsResp; +import pivx.org.pivxwallet.wallofcoins.response.PayFieldsDeserializer; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +/** + * WalloCoins call for manage API call from Base URL + */ +public class WallofCoins { + + private static String API_BASE_URL; + + static final TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + @Override + public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { + + } + + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new java.security.cert.X509Certificate[]{}; + } + } + }; + + /** + * Method for Create RestAPI call + * @param interceptor + * @param context context object of parent class + * @return RestApi Client object + */ + public static RestApi createService(Interceptor interceptor, Context context) { + API_BASE_URL = context.getString(R.string.base_url); + return getClient(interceptor) + .create(RestApi.class); + } + + /** + * Method for Create RestAPI call + * @param context context object of parent class + * @return RestApi Client object + */ + public static RestApi createService(Context context) { + API_BASE_URL = context.getString(R.string.base_url); + return getClient(null) + .create(RestApi.class); + } + + /** + * Method for get retrofit + * @param interceptor + * @return Retrofit Object + */ + private static Retrofit getClient(Interceptor interceptor) { + + OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); + // add your other interceptors … + httpClient.connectTimeout(60, TimeUnit.SECONDS); + httpClient.readTimeout(60, TimeUnit.SECONDS); + try { + KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + keyStore.load(null, null); + + SSLContext sslContext = SSLContext.getInstance("TLS"); + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(keyStore); + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + keyManagerFactory.init(keyStore, "keystore_pass".toCharArray()); + sslContext.init(null, trustAllCerts, new SecureRandom()); + httpClient.sslSocketFactory(sslContext.getSocketFactory()) + .hostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + + HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); + // set your desired log level + logging.setLevel(HttpLoggingInterceptor.Level.BODY); + // add logging as last interceptor + if (BuildConfig.DEBUG) + httpClient.addInterceptor(logging); // <-- this is the important line! + if (null != interceptor) + httpClient.addInterceptor(interceptor); + + Gson gson = new GsonBuilder() + .registerTypeAdapter(GetReceivingOptionsResp.PayFieldsBeanX.class, new PayFieldsDeserializer()) + .create(); + + return new Retrofit.Builder() + .baseUrl(API_BASE_URL).client(httpClient.build()) + .addConverterFactory(GsonConverterFactory.create(gson)).build(); + } + +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/binder/ImageBinder.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/binder/ImageBinder.java new file mode 100644 index 000000000..0a6b62442 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/binder/ImageBinder.java @@ -0,0 +1,31 @@ +package pivx.org.pivxwallet.wallofcoins.binder; + +/** + * Created by on 30-Mar-18. + */ + +import android.content.Context; +import android.databinding.BindingAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; + +import pivx.org.pivxwallet.R; + +public final class ImageBinder { + + private ImageBinder() { + //NO-OP + } + + @BindingAdapter("imageUrl") + public static void setImageUrl(ImageView imageView, String url) { + Context context = imageView.getContext(); + + Glide.with(context) + .load(url) + .placeholder(R.drawable.ic_account_balance_black_24dp) + .error(R.drawable.ic_account_balance_black_24dp) + .into(imageView); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/BuyingWizardBaseActivity.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/BuyingWizardBaseActivity.java new file mode 100644 index 000000000..869cb6ffa --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/BuyingWizardBaseActivity.java @@ -0,0 +1,205 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard; + +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentTransaction; +import android.support.v7.app.AppCompatActivity; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import org.pivxj.core.Coin; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.wallofcoins.BuyPivPref; +import pivx.org.pivxwallet.wallofcoins.WOCConstants; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.email_phone.BuyingWizardEmailPhoneFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.location.BuyingWizardLocationFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.offer_amount.BuyingWizardOfferAmountFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.order_history.BuyingWizardOrderHistoryFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.utils.BuyingWizardFragmentUtils; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.verification_otp.BuyingWizardVerifycationOtpFragment; +import pivx.org.pivxwallet.wallofcoins.response.CreateHoldResp; +import pivx.org.pivxwallet.wallofcoins.ui.CurrencyTextView; +import pivx.org.pivxwallet.wallofcoins.utils.Constants; + + +/** + * Created on 6/3/18. + */ + +public class BuyingWizardBaseActivity extends AppCompatActivity implements + SharedPreferences.OnSharedPreferenceChangeListener, View.OnClickListener { + + private FragmentManager fragmentManager; + public BuyPivPref buyPivPref; + private ImageView imgViewToolbarBack; + private TextView appBarMessageView; + private LinearLayout viewBalance; + private CurrencyTextView viewBalanceBtc, viewBalanceLocal; + private ImageView viewBalanceTooMuch; + private static final Coin TOO_MUCH_BALANCE_THRESHOLD = Coin.COIN.multiply(30); + @javax.annotation.Nullable + private Coin balance = null; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_buying_base); + init(); + setListners(); + if (!TextUtils.isEmpty(buyPivPref.getAuthToken())) { + if (!TextUtils.isEmpty(buyPivPref.getHoldId())) { + CreateHoldResp createHoldResp = buyPivPref.getCreateHoldResp(); + Bundle bundle = new Bundle(); + bundle.putString(WOCConstants.VERIFICATION_OTP, createHoldResp.__PURCHASE_CODE); + BuyingWizardVerifycationOtpFragment otpFragment = new BuyingWizardVerifycationOtpFragment(); + otpFragment.setArguments(bundle); + replaceFragment(otpFragment, true, false); + } else { + replaceFragment(new BuyingWizardLocationFragment(), true, true); + } + } else + replaceFragment(new BuyingWizardLocationFragment(), true, true); + } + + private void init() { + this.buyPivPref = new BuyPivPref(PreferenceManager.getDefaultSharedPreferences(this)); + buyPivPref.registerOnSharedPreferenceChangeListener(this); + fragmentManager = getSupportFragmentManager(); + imgViewToolbarBack = (ImageView) findViewById(R.id.imgViewToolbarBack); + appBarMessageView = (TextView) findViewById(R.id.toolbar_message); + viewBalance = (LinearLayout) findViewById(R.id.wallet_balance); + viewBalanceBtc = (CurrencyTextView) findViewById(R.id.wallet_balance_btc); + viewBalanceLocal = (CurrencyTextView) findViewById(R.id.wallet_balance_local); + viewBalanceTooMuch = (ImageView) findViewById(R.id.wallet_balance_too_much_warning); + + viewBalanceBtc.setPrefixScaleX(0.9f); + viewBalanceLocal.setInsignificantRelativeSize(1); + viewBalanceLocal.setStrikeThru(Constants.TEST); + } + + private void setListners() { + imgViewToolbarBack.setOnClickListener(this); + viewBalance.setOnClickListener(this); + } + + public void replaceFragment(Fragment fragment, boolean withAnimation, boolean withBackStack) { + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + Log.e("Fragment name", fragment.getClass().getName()); + if (withAnimation) + fragmentTransaction.setCustomAnimations(R.anim.activity_in, R.anim.activity_out, R.anim.activity_backin, R.anim.activity_back_out); + if (withBackStack) + fragmentTransaction.replace(R.id.frame_container_buy_base, fragment).addToBackStack(fragment.getClass().getName()); + else + fragmentTransaction.replace(R.id.frame_container_buy_base, fragment); + fragmentTransaction.commitAllowingStateLoss(); + } + + public void popbackFragment() { + + if (fragmentManager.getBackStackEntryCount() > 0) { + Fragment fragment = fragmentManager.findFragmentById(R.id.frame_container_buy_base); + if (fragment instanceof BuyingWizardEmailPhoneFragment) + ((BuyingWizardEmailPhoneFragment) fragment).changeView(); + + else if (fragment instanceof BuyingWizardOfferAmountFragment) + ((BuyingWizardOfferAmountFragment) fragment).changeView(); + else if (fragment instanceof BuyingWizardLocationFragment) + this.finish(); + else if (fragment instanceof BuyingWizardOrderHistoryFragment) + ((BuyingWizardOrderHistoryFragment) fragment).changeView(); + else + fragmentManager.popBackStack(); + } else + this.finish(); + } + + public void popBackDirect() { + if (fragmentManager.getBackStackEntryCount() > 0) + fragmentManager.popBackStack(); + else + this.finish(); + } + + @Override + public void onBackPressed() { + popbackFragment(); + //super.onBackPressed(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + buyPivPref.unregisterOnSharedPreferenceChangeListener(this); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { + + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + + case R.id.imgViewToolbarBack: + popbackFragment(); + break; + case R.id.wallet_balance: + showWarningIfBalanceTooMuch(); + //showExchangeRatesActivity(); + break; + } + } + + @Override + public void onResume() { + super.onResume(); + } + + private void showWarningIfBalanceTooMuch() { + if (balance != null && balance.isGreaterThan(TOO_MUCH_BALANCE_THRESHOLD)) { + Toast.makeText(this, getString(R.string.wallet_balance_fragment_too_much), + Toast.LENGTH_LONG).show(); + } + } + + private void showAppBarMessage(CharSequence message) { + if (message != null) { + appBarMessageView.setVisibility(View.VISIBLE); + appBarMessageView.setText(message); + } else { + appBarMessageView.setVisibility(View.GONE); + } + } + + private void updateBalanceTooMuchWarning() { + if (balance == null) + return; + + boolean tooMuch = balance.isGreaterThan(TOO_MUCH_BALANCE_THRESHOLD); + viewBalanceTooMuch.setVisibility(tooMuch ? View.VISIBLE : View.GONE); + } + + public void popBackAllFragmentsExcept(String tag) { + fragmentManager.popBackStack(tag, FragmentManager.POP_BACK_STACK_INCLUSIVE); + } + + public void removeAllFragmentFromStack() { + if (fragmentManager.getBackStackEntryCount() > 0) { + BuyingWizardFragmentUtils.sDisableFragmentAnimations = true; + fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); + BuyingWizardFragmentUtils.sDisableFragmentAnimations = false; + } + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/BuyingWizardBaseFragment.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/BuyingWizardBaseFragment.java new file mode 100644 index 000000000..e984cf68e --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/BuyingWizardBaseFragment.java @@ -0,0 +1,302 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.location.LocationManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.provider.Settings; +import android.support.annotation.Nullable; +import android.support.v4.app.ActivityCompat; +import android.support.v4.app.Fragment; +import android.support.v4.content.ContextCompat; +import android.support.v7.app.AlertDialog; +import android.text.TextUtils; +import android.util.Base64; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.Toast; + +import com.google.common.base.Charsets; + +import org.pivxj.core.WrongNetworkException; + +import java.io.IOException; +import java.util.List; +import java.util.Locale; + +import okhttp3.Interceptor; +import okhttp3.Request; +import pivx.org.pivxwallet.PivxApplication; +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.module.PivxModule; +import pivx.org.pivxwallet.wallofcoins.BuyPivPref; +import pivx.org.pivxwallet.wallofcoins.WOCConstants; +import pivx.org.pivxwallet.wallofcoins.addressbook.AddressBookProvider; +import pivx.org.pivxwallet.wallofcoins.utils.Constants; + +/** + * Created on 6/3/18. + */ + +public class BuyingWizardBaseFragment extends Fragment { + + private final int PERMISSIONS_REQUEST_LOCATION = 8989; + protected Context mContext; + private PivxModule module; + private org.pivxj.core.Address address; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + module = PivxApplication.getInstance().getModule(); + address = module.getReceiveAddress(); + } + + + protected boolean checkPermissions() { + int permissionFineLoc = ActivityCompat.checkSelfPermission(mContext, + Manifest.permission.ACCESS_FINE_LOCATION); + int permissionCoarseLoc = ActivityCompat.checkSelfPermission(mContext, + Manifest.permission.ACCESS_COARSE_LOCATION); + + return permissionFineLoc == PackageManager.PERMISSION_GRANTED && + permissionCoarseLoc == PackageManager.PERMISSION_GRANTED; + } + + protected void requestLocationPermission() { + requestPermissions( + new String[]{Manifest.permission.ACCESS_FINE_LOCATION + , Manifest.permission.ACCESS_COARSE_LOCATION}, + PERMISSIONS_REQUEST_LOCATION); + } + + /** + * Get Last known best accurate location from available providers + * + * @return location object + */ + protected Location getLastKnownLocation() { + boolean gps_enabled; + boolean network_enabled; + LocationManager lm = (LocationManager) getActivity() + .getSystemService(Context.LOCATION_SERVICE); + gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER); + network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER); + + Location net_loc = null, gps_loc = null, finalLoc = null; + if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED + && ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { + if (gps_enabled) + gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); + if (network_enabled) + net_loc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); + + } else { + requestPermissions( + new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, + PERMISSIONS_REQUEST_LOCATION); + } + + if (gps_loc != null && net_loc != null) { + if (gps_loc.getAccuracy() > net_loc.getAccuracy()) + finalLoc = net_loc; + else + finalLoc = gps_loc; + } else { + + if (gps_loc != null) { + finalLoc = gps_loc; + } else if (net_loc != null) { + finalLoc = net_loc; + } + } + return finalLoc; + } + + /** + * Method for Open web url link in external browser app + * + * @param url + */ + protected void goToUrl(String url) { + Uri uriUrl = Uri.parse(url); + Intent launchBrowser = new Intent(Intent.ACTION_VIEW, uriUrl); + startActivity(launchBrowser); + } + + /** + * get country code form current latitude & longitude + * + * @return Country Code + */ + protected String getCountryCode(double latitude, double longitude) { + String countryCode = ""; + try { + Geocoder geo = new Geocoder(mContext, Locale.getDefault()); + List
addresses = geo.getFromLocation(latitude, longitude, 1); + Address obj = addresses.get(0); + countryCode = obj.getCountryCode(); + } catch (Exception e) { + e.printStackTrace(); + } + + if (countryCode.equals("")) { + return "us"; + } else { + return countryCode; + } + } + + /** + * Method for hide keyboard + */ + protected void hideKeyBoard() { + View view = getActivity().getCurrentFocus(); + if (view != null) { + InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(view.getWindowToken(), 0); + } + } + + /** + * Show a dialog to the user requesting that GPS be enabled + */ + protected void showDialogGPS() { + AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + builder.setCancelable(false); + builder.setTitle(getString(R.string.enable_gps)); + builder.setMessage(getString(R.string.enable_gps_location)); + builder.setPositiveButton(getString(R.string.enable_label), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + startActivity( + new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)); + } + }); + builder.setNegativeButton(getString(R.string.ignore_label), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + AlertDialog alert = builder.create(); + alert.show(); + } + + /** + * Method for Update Address book of Order Transaction + * + * @param KEY_ADDRESS + * @param newLabel + */ + protected void updateAddressBookValue(String KEY_ADDRESS, String newLabel) { + + try { + if (KEY_ADDRESS != null && newLabel != null) { + + org.pivxj.core.Address keyAddress = org.pivxj.core.Address.fromBase58(Constants.NETWORK_PARAMETERS, KEY_ADDRESS); + final Uri uri = AddressBookProvider.contentUri(mContext.getPackageName()).buildUpon().appendPath(keyAddress.toBase58()).build(); + final String addressLabel = AddressBookProvider.resolveLabel(mContext, keyAddress.toBase58()); + + ContentResolver contentResolver; + contentResolver = mContext.getContentResolver(); + + final ContentValues values = new ContentValues(); + + values.put(AddressBookProvider.KEY_LABEL, newLabel); + + if (addressLabel == null) { + contentResolver.insert(uri, values); + } else { + contentResolver.update(uri, values, null, null); + } + } + } catch (WrongNetworkException wrongNetworkException) { + wrongNetworkException.printStackTrace(); + } + + } + + @SuppressLint("HardwareIds") + protected String getDeviceCode(Context context, BuyPivPref buyPivPref) { + + String deviceUID = buyPivPref.getDeviceCode(); + if (TextUtils.isEmpty(deviceUID)) { + String deviceID; + deviceID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); + byte[] data = (deviceID + deviceID + deviceID).getBytes(Charsets.UTF_8); + deviceUID = Base64.encodeToString(data, Base64.DEFAULT).substring(0, 39); + buyPivPref.setDeviceCode(deviceUID); + } + + return deviceUID; + } + + protected void showToast(String msg) { + Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show(); + } + + /** + * Validate Email id + * + * @param target Email + * @return boolean for email valid or not + */ + protected boolean isValidEmail(CharSequence target) { + if (target == null) { + return false; + } else { + return android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches(); + } + } + + /** + * Show alert dialog wrong username or password + */ + protected void showAlertPasswordDialog() { + AlertDialog.Builder builder; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + builder = new AlertDialog.Builder(mContext, android.R.style.Theme_Material_Dialog_Alert); + } else { + builder = new AlertDialog.Builder(mContext); + } + builder.setTitle("") + .setMessage(getString(R.string.user_pass_wrong)) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }) + .show(); + } + + /** + * API Header parameter interceptor + */ + protected Interceptor interceptor = new Interceptor() { + @Override + public okhttp3.Response intercept(Chain chain) throws IOException { + Request original = chain.request(); + // Request customization: add request headers + Request.Builder requestBuilder = original.newBuilder(); + if (!TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext).buyPivPref.getAuthToken())) { + requestBuilder.addHeader(WOCConstants.KEY_HEADER_AUTH_TOKEN, ((BuyingWizardBaseActivity) mContext) + .buyPivPref.getAuthToken()); + } + requestBuilder.addHeader(WOCConstants.KEY_HEADER_PUBLISHER_ID, getString(R.string.WALLOFCOINS_PUBLISHER_ID)); + requestBuilder.addHeader(WOCConstants.KEY_HEADER_CONTENT_TYPE, WOCConstants.KEY_HEADER_CONTENT_TYPE_VALUE); + Request request = requestBuilder.build(); + return chain.proceed(request); + } + }; +} + diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/adapters/BuyingWizardOffersAdapter.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/adapters/BuyingWizardOffersAdapter.java new file mode 100644 index 000000000..e6b3cb87d --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/adapters/BuyingWizardOffersAdapter.java @@ -0,0 +1,281 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.adapters; + +import android.content.Context; +import android.content.Intent; +import android.databinding.DataBindingUtil; +import android.net.Uri; +import android.os.Build; +import android.support.v7.widget.RecyclerView; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.TextView; + +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.List; +import java.util.Locale; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.databinding.ItemBuyingWizardOffersBinding; +import pivx.org.pivxwallet.databinding.ItemBuyingWizardOffersDoubleBinding; +import pivx.org.pivxwallet.wallofcoins.response.GetOffersResp; +import pivx.org.pivxwallet.wallofcoins.utils.GenericUtils; + + +public class BuyingWizardOffersAdapter extends RecyclerView.Adapter { + + private Context context; + private List singleDepositBeenList; + private List doubleDeposit; + private AdapterView.OnItemSelectedListener onItemSelectedListener; + private String offerAmount; + private boolean incremented; + private DecimalFormat formatter; + + public BuyingWizardOffersAdapter(Context context, GetOffersResp getOffersResp, String offerAmount, + AdapterView.OnItemSelectedListener onItemSelectedListener) { + this.context = context; + this.singleDepositBeenList = getOffersResp.singleDeposit; + this.doubleDeposit = getOffersResp.doubleDeposit; + if (getOffersResp.multipleBanks != null && doubleDeposit != null) + this.doubleDeposit.addAll(getOffersResp.multipleBanks); + this.onItemSelectedListener = onItemSelectedListener; + this.incremented = getOffersResp.incremented; + this.offerAmount = offerAmount; + formatter = new DecimalFormat("#,###,###.##"); + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup group, int type) { + LayoutInflater layoutInflater = LayoutInflater.from(context); + + if (type == 1) { + View v = LayoutInflater.from(context) + .inflate(android.R.layout.simple_list_item_1, group, false); + return new VHolderMore(v); + } else if (type == 2) { + ItemBuyingWizardOffersDoubleBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.item_buying_wizard_offers_double, group, false); + return new VHolderDouble2(binding); + } else if (type == 3) { + ItemBuyingWizardOffersBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.item_buying_wizard_offers, group, false); + return new VHolderDouble1(binding); + } else { + ItemBuyingWizardOffersBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.item_buying_wizard_offers, group, false); + return new VHolderSingle(binding); + } + } + + @Override + public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) { + + if (holder instanceof VHolderSingle) { + final GetOffersResp.SingleDepositBean bean = singleDepositBeenList.get(holder.getAdapterPosition() - 1); + final VHolderSingle vholder = (VHolderSingle) holder; + vholder.binding.setItem(bean); + + if (getNumAmount(bean.deposit.amount) >= 200) { + double uPiv = Double.parseDouble(bean.amount.uPiv.replaceAll(",", "")); + vholder.binding.tvItrmOffer2.setText(context.getString(R.string.dotUnicode, formatter.format(uPiv), + GenericUtils.currencySymbol(bean.deposit.currency), getNumAmount(bean.deposit.amount) + / getNumAmount(bean.amount.PIVX))); + + } else { + double uPiv = Double.parseDouble(bean.amount.uPiv.replaceAll(",", "")); + vholder.binding.tvItrmOffer2.setText(context.getString(R.string.dotUnicodeNoRate, formatter.format(uPiv))); + } + + if (incremented) { + vholder.binding.txtAmount.setVisibility(View.VISIBLE); + } else { + vholder.binding.txtAmount.setVisibility(View.INVISIBLE); + } + + + vholder.binding.buttonItemOrder.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onItemSelectedListener.onItemSelected(null, vholder.binding.getRoot(), holder.getAdapterPosition(), 0); + } + }); + + vholder.binding.buttonItemLocation.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(bean.bankLocationUrl)); + context.startActivity(i); + } + }); + + } else if (holder instanceof VHolderDouble1) { + GetOffersResp.DoubleDepositBean beanTemp = doubleDeposit.get(holder.getAdapterPosition() - singleDepositBeenList.size() - 2); + final GetOffersResp.SingleDepositBean bean = new GetOffersResp.SingleDepositBean(); + bean.deposit = new GetOffersResp.DepositBean(); + bean.amount = new GetOffersResp.AmountBean(); + + if (beanTemp.secondOffer != null) { + bean.amount.PIVX = beanTemp.sumAmounts(beanTemp.firstOffer.amount.PIVX, beanTemp.secondOffer.amount.PIVX); + bean.amount.uPiv = beanTemp.sumAmounts(beanTemp.firstOffer.amount.uPiv, beanTemp.secondOffer.amount.uPiv); + bean.deposit.amount = beanTemp.sumAmounts(beanTemp.firstOffer.deposit.amount, beanTemp.secondOffer.deposit.amount); + } else { + bean.amount.PIVX = beanTemp.firstOffer.amount.PIVX; + bean.amount.uPiv = beanTemp.firstOffer.amount.uPiv; + bean.deposit.amount = beanTemp.firstOffer.deposit.amount; + } + + bean.bankName = beanTemp.firstOffer.bankName; + bean.bankLogo = beanTemp.firstOffer.bankLogo; + bean.address = beanTemp.firstOffer.address; + bean.distance = beanTemp.firstOffer.distance; + bean.city = beanTemp.firstOffer.city; + bean.state = beanTemp.firstOffer.state; + bean.bankLocationUrl = beanTemp.firstOffer.bankLocationUrl; + bean.deposit.currency = beanTemp.firstOffer.deposit.currency; + + + final VHolderDouble1 vholder = (VHolderDouble1) holder; + vholder.binding.setItem(bean); + + + if (getNumAmount(bean.deposit.amount) >= 200) { + //vholder.binding.tvItrmOffer2.setText(context.getString(R.string.dotUnicode, bean.amount.uPiv, GenericUtils.currencySymbol(bean.deposit.currency), getNumAmount(bean.deposit.amount) / getNumAmount(bean.amount.PIV))); + vholder.binding.tvItrmOffer2.setText(context.getString(R.string.dotUnicode, bean.amount.uPiv, GenericUtils.currencySymbol(bean.deposit.currency), getNumAmount(bean.deposit.amount) / getNumAmount(bean.amount.PIVX))); + + } else { + vholder.binding.tvItrmOffer2.setText(context.getString(R.string.dotUnicodeNoRate, bean.amount.uPiv)); + } + + vholder.binding.buttonItemOrder.setOnClickListener(new View.OnClickListener() { + @Override + + public void onClick(View v) { + onItemSelectedListener.onItemSelected(null, vholder.binding.getRoot(), holder.getAdapterPosition(), 0); + } + }); + + } else if (holder instanceof VHolderDouble2) { + final GetOffersResp.DoubleDepositBean bean = doubleDeposit.get(holder.getAdapterPosition() - singleDepositBeenList.size() - 2); + final VHolderDouble2 vholder = (VHolderDouble2) holder; + vholder.binding.setItem(bean); + + + vholder.binding.buttonItemOrder.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onItemSelectedListener.onItemSelected(null, vholder.binding.getRoot(), holder.getAdapterPosition(), 0); + } + }); + + } else { + + TextView more = (TextView) holder.itemView; + if (holder.getAdapterPosition() == 0 && singleDepositBeenList.size() > 0) { + if (incremented) { + more.setText("Below are offers for at least $" + + String.format("%.2f", Double.parseDouble(offerAmount)) + ". You must click the ORDER button before you receive instructions to pay at the Cash Payment center."); + } else { + more.setText("Below are offers for $" + + singleDepositBeenList.get(0).deposit.amount + ". You must click the ORDER button before you receive instructions to pay at the Cash Payment center."); + } + } else { + more.setText("Best Value Options: More PIV for $" + + String.format("%.2f", Double.parseDouble(offerAmount)) + " Cash"); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + more.setTextColor(context.getResources().getColor(R.color.colorPrimary, context.getTheme())); + } else { + more.setTextColor(context.getResources().getColor(R.color.colorPrimary)); + } + more.setGravity(Gravity.CENTER); + more.layout(30, 30, 30, 30); + + } + } + + private float getNumAmount(String strAmount) { + + float amount = 1; + + try { + amount = NumberFormat.getNumberInstance(Locale.getDefault()).parse(strAmount).floatValue(); + } catch (ParseException e) { + e.printStackTrace(); + } + +// return amount; + return amount; + } + + + @Override + public int getItemCount() { + + int count = singleDepositBeenList.size(); + + if (singleDepositBeenList.size() > 0) { + count++; + } + + if (null != doubleDeposit && doubleDeposit.size() > 0) { + count += doubleDeposit.size(); + count++; + } + + return count; + } + + @Override + public int getItemViewType(int position) { + if ((position == 0 && singleDepositBeenList.size() > 0) + || (singleDepositBeenList.size() + 1 == position)) { + return 1; + } + if (position > singleDepositBeenList.size() + 1) { + if (doubleDeposit.get(position - singleDepositBeenList.size() - 2).secondOffer == null + || doubleDeposit.get(position - singleDepositBeenList.size() - 2).secondOffer.bankName.equals(doubleDeposit.get(position - singleDepositBeenList.size() - 2).firstOffer.bankName)) { + return 3; + } else { + return 2; + } + } + return 0; + } + + private class VHolderSingle extends RecyclerView.ViewHolder { + private ItemBuyingWizardOffersBinding binding; + + private VHolderSingle(ItemBuyingWizardOffersBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } + + private class VHolderMore extends RecyclerView.ViewHolder { + + private VHolderMore(View v) { + super(v); + } + } + + private class VHolderDouble2 extends RecyclerView.ViewHolder { + private ItemBuyingWizardOffersDoubleBinding binding; + + private VHolderDouble2(ItemBuyingWizardOffersDoubleBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } + + private class VHolderDouble1 extends RecyclerView.ViewHolder { + private ItemBuyingWizardOffersBinding binding; + + private VHolderDouble1(ItemBuyingWizardOffersBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/adapters/BuyingWizardOrderListAdapter.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/adapters/BuyingWizardOrderListAdapter.java new file mode 100644 index 000000000..079d359c7 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/adapters/BuyingWizardOrderListAdapter.java @@ -0,0 +1,271 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.adapters; + +import android.content.Context; +import android.databinding.DataBindingUtil; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.databinding.LayoutItemOrderListBinding; +import pivx.org.pivxwallet.wallofcoins.BuyPivPref; +import pivx.org.pivxwallet.wallofcoins.WOCConstants; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.models.BuyingWizardAccountJson; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.order_history.BuyingWizardOrderHistoryFragment; +import pivx.org.pivxwallet.wallofcoins.response.OrderListResp; + + +/** + * Created on 08-Mar-18. + */ + +public class BuyingWizardOrderListAdapter extends RecyclerView.Adapter { + + private Context mContext; + private final List orderList; + private BuyingWizardOrderHistoryFragment historyFragment; + private BuyPivPref buyPivPref; + + public BuyingWizardOrderListAdapter(Context mContext, List orderList, + BuyingWizardOrderHistoryFragment historyFragment, + BuyPivPref buyPivPref) { + this.mContext = mContext; + this.orderList = orderList; + this.historyFragment = historyFragment; + this.buyPivPref = buyPivPref; + } + + @Override + public BuyingWizardOrderListAdapter.VHolder onCreateViewHolder(ViewGroup parent, int viewType) { + LayoutInflater layoutInflater = LayoutInflater.from(mContext); + LayoutItemOrderListBinding itemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.layout_item_order_list, parent, false); + return new BuyingWizardOrderListAdapter.VHolder(itemBinding); + } + + @Override + public void onBindViewHolder(BuyingWizardOrderListAdapter.VHolder holder, int position) { + final OrderListResp orderListResp = orderList.get(position); + if (orderListResp.id != -1 && orderListResp.id != -2 && orderListResp.id != -3) { + + holder.itemBinding.layLogout.setVisibility(View.GONE); + holder.itemBinding.layHelpInstruction.setVisibility(View.GONE); + holder.itemBinding.layOrderHistory.setVisibility(View.GONE); + holder.itemBinding.layoutCompletionDetail.setVisibility(View.VISIBLE); + holder.itemBinding.setItem(orderListResp); + + + Type listType = new TypeToken>() { + }.getType(); + + holder.itemBinding.linearAccountDetail.removeAllViews(); + try { + ArrayList accountList = new Gson().fromJson(orderListResp.account, listType); + + if (accountList != null && orderListResp.status.equals("WD")) { + for (int i = 0; i < accountList.size(); i++) { + TextView textView = new TextView(mContext); + textView.setTextSize(16); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + layoutParams.topMargin = 0; + textView.setLayoutParams(layoutParams); + textView.setText(accountList.get(i).getLabel() + ": " + accountList.get(i).getValue()); + holder.itemBinding.linearAccountDetail.addView(textView); + } + holder.itemBinding.textAccountNo.setVisibility(View.GONE); + holder.itemBinding.textNameAccount.setVisibility(View.GONE); + + } else { + holder.itemBinding.linearAccountDetail.setVisibility(View.GONE); + } + } catch (JsonSyntaxException e) { + e.printStackTrace(); + } + + if (orderListResp.account == null + || orderListResp.account.equals("")) { + holder.itemBinding.textAccountNo.setVisibility(View.GONE); + } + if (orderListResp.nameOnAccount == null + || orderListResp.nameOnAccount.equals("")) { + holder.itemBinding.textNameAccount.setVisibility(View.GONE); + } + + holder.itemBinding.btnDepositFinished.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + historyFragment.depositFinished(orderListResp); + } + }); + + holder.itemBinding.btnCancelOrder.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + historyFragment.cancelHoldOrder(orderListResp); + } + }); + + + if (orderListResp.nearestBranch != null) { + if ((orderListResp.nearestBranch.address == null + || orderListResp.nearestBranch.address.equals("")) + && orderListResp.status.equals("WD") + ) { + holder.itemBinding.buttonBuyPivItemLocation.setVisibility(View.VISIBLE); + holder.itemBinding.tvItrmOffer4.setVisibility(View.VISIBLE); + } else { + holder.itemBinding.buttonBuyPivItemLocation.setVisibility(View.GONE); + holder.itemBinding.tvItrmOffer4.setVisibility(View.GONE); + } + } + + holder.itemBinding.buttonBuyPivItemLocation.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + historyFragment.goToGivenUrl(orderListResp.bankUrl); + } + }); + +// you must deposit cash + double dots = Double.parseDouble(orderListResp.total) * 1000000; + DecimalFormat formatter = new DecimalFormat("#,###,###.##"); + String yourFormattedDots = formatter.format(dots); + + if (orderListResp.bankLogo != null + && !orderListResp.bankLogo.equals("")) { + Glide.with(mContext) + .load(orderListResp.bankLogo) + .placeholder(R.drawable.ic_account_balance_black_24dp) + .error(R.drawable.ic_account_balance_black_24dp) + .into(holder.itemBinding.imageBank); + } else { + holder.itemBinding.imageBank.setImageResource(R.drawable.ic_account_balance_black_24dp); + } + //Log.e(TAG, "onBindViewHolder: " + orderListResp.status); + + if (orderListResp.status.equals("WD")) { + + holder.itemBinding.orderPiv.setText("Total PIV: " + orderListResp.total + " (" + yourFormattedDots + " μⱣiv)\n" + + "You must deposit cash at the above Payment Center. Additional fees may apply. Paying in another method other than cash may delay your order."); + holder.itemBinding.orderPivInstruction.setVisibility(View.VISIBLE); + holder.itemBinding.btnCancelOrder.setVisibility(View.VISIBLE); + holder.itemBinding.btnDepositFinished.setVisibility(View.VISIBLE); + holder.itemBinding.layoutDueDate.setVisibility(View.VISIBLE); + + holder.itemBinding.textPaymentDueDate.setVisibility(View.VISIBLE); + historyFragment.countDownStart(orderListResp.paymentDue, holder.itemBinding.textPaymentDueDate); + + + holder.itemBinding.textContactInstruction.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // goToUrl(WOCConstants.KEY_WEB_URL); + historyFragment.goToGivenUrl(WOCConstants.KEY_WEB_URL); + } + }); + + } else { + + holder.itemBinding.orderPiv.setText("Total PIV: " + orderListResp.total + " (" + yourFormattedDots + " μⱣiv)"); + holder.itemBinding.layoutDueDate.setVisibility(View.GONE); + holder.itemBinding.textPaymentDueDate.setVisibility(View.GONE); + holder.itemBinding.orderPivInstruction.setVisibility(View.GONE); + holder.itemBinding.btnCancelOrder.setVisibility(View.GONE); + holder.itemBinding.btnDepositFinished.setVisibility(View.GONE); + holder.itemBinding.textContactInstruction.setVisibility(View.GONE); + holder.itemBinding.textAccountNo.setVisibility(View.GONE); + holder.itemBinding.textNameAccount.setVisibility(View.GONE); + } + + if (orderListResp.status.equals("WD")) { + holder.itemBinding.textTransactionStatus.setText(mContext.getString(R.string.status_waiting_deposit)); + } else if (orderListResp.status.equals("WDV")) { + holder.itemBinding.textTransactionStatus.setText(mContext.getString(R.string.status_waiting_deposit_verification)); + } else if (orderListResp.status.equals("RERR")) { + holder.itemBinding.textTransactionStatus.setText(mContext.getString(R.string.status_issue_with_receipt)); + } else if (orderListResp.status.equals("DERR")) { + holder.itemBinding.textTransactionStatus.setText(mContext.getString(R.string.status_issue_with_deposit)); + } else if (orderListResp.status.equals("RSD")) { + holder.itemBinding.textTransactionStatus.setText(mContext.getString(R.string.status_reserved_for_deposit)); + } else if (orderListResp.status.equals("RMIT")) { + holder.itemBinding.textTransactionStatus.setText(mContext.getString(R.string.status_remit_address_missing)); + } else if (orderListResp.status.equals("UCRV")) { + holder.itemBinding.textTransactionStatus.setText(mContext.getString(R.string.status_under_review)); + } else if (orderListResp.status.equals("PAYP")) { + holder.itemBinding.textTransactionStatus.setText(mContext.getString(R.string.status_done_pending_delivery)); + } else if (orderListResp.status.equals("SENT")) { + holder.itemBinding.textTransactionStatus.setText(mContext.getString(R.string.status_done_units_delivered)); + } + + } else if (orderListResp.id == -3) { + + holder.itemBinding.layoutCompletionDetail.setVisibility(View.GONE); + holder.itemBinding.layHelpInstruction.setVisibility(View.GONE); + holder.itemBinding.layLogout.setVisibility(View.GONE); + holder.itemBinding.layOrderHistory.setVisibility(View.VISIBLE); + + } else if (orderListResp.id == -2) { + + holder.itemBinding.layoutCompletionDetail.setVisibility(View.GONE); + holder.itemBinding.layHelpInstruction.setVisibility(View.GONE); + holder.itemBinding.layLogout.setVisibility(View.VISIBLE); + holder.itemBinding.layOrderHistory.setVisibility(View.GONE); + + holder.itemBinding.textMessage.setText(mContext.getString(R.string.wallet_is_signed) + " " + + buyPivPref.getPhone()); + + holder.itemBinding.btnSignout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + historyFragment.deleteAuthCall(false); + } + }); + + + } else if (orderListResp.id == -1) { + + holder.itemBinding.layoutCompletionDetail.setVisibility(View.GONE); + holder.itemBinding.layHelpInstruction.setVisibility(View.VISIBLE); + holder.itemBinding.layLogout.setVisibility(View.GONE); + holder.itemBinding.layOrderHistory.setVisibility(View.GONE); + + holder.itemBinding.textHelpMessage.setText(R.string.call_for_help); + holder.itemBinding.btnWebLink.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + //goToUrl(WOCConstants.KEY_WEB_URL); + historyFragment.goToGivenUrl(WOCConstants.KEY_WEB_URL); + } + }); + } + + } + + + @Override + public int getItemCount() { + return orderList.size(); + } + + public class VHolder extends RecyclerView.ViewHolder { + private LayoutItemOrderListBinding itemBinding; + + + public VHolder(LayoutItemOrderListBinding itemBinding) { + super(itemBinding.getRoot()); + this.itemBinding = itemBinding; + } + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/adapters/BuyingWizardPhoneListAdapter.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/adapters/BuyingWizardPhoneListAdapter.java new file mode 100644 index 000000000..24b77dacc --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/adapters/BuyingWizardPhoneListAdapter.java @@ -0,0 +1,68 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.adapters; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; + +import java.util.ArrayList; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.models.BuyingWizardPhoneListVO; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.phone_list.BuyingWizardPhoneListFragment; + +/** + * Created on 19-Mar-18. + */ + +public class BuyingWizardPhoneListAdapter extends RecyclerView.Adapter { + + private Context mContext; + private ArrayList buyingWizardPhoneListVOS; + private BuyingWizardPhoneListFragment fragment; + + public BuyingWizardPhoneListAdapter(Context context, ArrayList buyingWizardPhoneListVOS, BuyingWizardPhoneListFragment fragment) { + this.mContext = context; + this.buyingWizardPhoneListVOS = buyingWizardPhoneListVOS; + this.fragment = fragment; + } + + @Override + public BuyingWizardPhoneListAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View itemView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_phone_list, parent, false); + + return new MyViewHolder(itemView); + } + + @Override + public void onBindViewHolder(BuyingWizardPhoneListAdapter.MyViewHolder holder, int position) { + final BuyingWizardPhoneListVO buyingWizardPhoneListVO = buyingWizardPhoneListVOS.get(holder.getAdapterPosition()); + + holder.btnPhone.setText(mContext.getString(R.string.sign_in2, buyingWizardPhoneListVO.getPhoneNumber())); + + holder.btnPhone.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + fragment.getAuthTokenCall(buyingWizardPhoneListVO.getPhoneNumber(), buyingWizardPhoneListVO.getDeviceId()); + } + }); + + } + + @Override + public int getItemCount() { + return buyingWizardPhoneListVOS.size(); + } + + public class MyViewHolder extends RecyclerView.ViewHolder { + private Button btnPhone; + + private MyViewHolder(View view) { + super(view); + this.btnPhone = (Button) view.findViewById(R.id.btnPhone); + } + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/email_phone/BuyingWizardEmailPhoneFragment.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/email_phone/BuyingWizardEmailPhoneFragment.java new file mode 100644 index 000000000..058375607 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/email_phone/BuyingWizardEmailPhoneFragment.java @@ -0,0 +1,647 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.email_phone; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.annotation.Nullable; +import android.support.v7.app.AlertDialog; +import android.text.TextUtils; +import android.text.method.LinkMovementMethod; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.gson.Gson; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.wallofcoins.CustomAdapter; +import pivx.org.pivxwallet.wallofcoins.WOCConstants; +import pivx.org.pivxwallet.wallofcoins.api.WallofCoins; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseActivity; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.order_history.BuyingWizardOrderHistoryFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.utils.BuyingWizardFragmentUtils; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.utils.BuyingWizardPhoneListPref; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.verification_otp.BuyingWizardVerifycationOtpFragment; +import pivx.org.pivxwallet.wallofcoins.response.CheckAuthResp; +import pivx.org.pivxwallet.wallofcoins.response.CountryData; +import pivx.org.pivxwallet.wallofcoins.response.CreateDeviceResp; +import pivx.org.pivxwallet.wallofcoins.response.CreateHoldResp; +import pivx.org.pivxwallet.wallofcoins.response.GetAuthTokenResp; +import pivx.org.pivxwallet.wallofcoins.response.GetHoldsResp; +import pivx.org.pivxwallet.wallofcoins.utils.NetworkUtil; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +/** + * Created on 08-Mar-18. + */ + +public class BuyingWizardEmailPhoneFragment extends BuyingWizardBaseFragment implements View.OnClickListener, + SharedPreferences.OnSharedPreferenceChangeListener { + + private final String TAG = "EmailPhoneFragment"; + private View rootView; + private LinearLayout linearProgress, linear_email, linear_phone, layout_hold; + private CountryData countryData; + private Spinner sp_country; + private Button btn_next_phone, btn_next_email, btn_sign_in; + private String country_code = "", phone_no = "", email = "", password = "", offerId = ""; + private EditText edit_phone, edit_email; + private TextView tv_skip_email; + private CreateDeviceResp createDeviceResp; + private CreateHoldResp createHoldResp; + private BuyingWizardPhoneListPref credentilasPref; + private String fromScreen = ""; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + mContext = context; + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + if (rootView == null) { + rootView = inflater.inflate(R.layout.fragment_buying_email_and_phone, container, false); + init(); + addCountryCodeList(); + setListeners(); + readBundle(getArguments()); + return rootView; + } else + return rootView; + } + + private void init() { + credentilasPref = new BuyingWizardPhoneListPref(PreferenceManager.getDefaultSharedPreferences(mContext)); + + linearProgress = (LinearLayout) rootView.findViewById(R.id.linear_progress); + linear_email = (LinearLayout) rootView.findViewById(R.id.linear_email); + sp_country = (Spinner) rootView.findViewById(R.id.sp_country); + btn_next_phone = (Button) rootView.findViewById(R.id.btn_next_phone); + edit_phone = (EditText) rootView.findViewById(R.id.edit_phone); + btn_next_email = (Button) rootView.findViewById(R.id.btn_next_email); + edit_email = (EditText) rootView.findViewById(R.id.edit_email); + linear_phone = (LinearLayout) rootView.findViewById(R.id.linear_phone); + layout_hold = (LinearLayout) rootView.findViewById(R.id.layout_hold); + tv_skip_email = (TextView) rootView.findViewById(R.id.tv_skip_email); + btn_sign_in = (Button) rootView.findViewById(R.id.btn_sign_in); + } + + private void setListeners() { + btn_next_phone.setOnClickListener(this); + btn_next_email.setOnClickListener(this); + tv_skip_email.setOnClickListener(this); + btn_sign_in.setOnClickListener(this); + } + + /** + * handle the arguments according to user come from previos screen + */ + private void readBundle(Bundle bundle) { + if (bundle != null) { + if (bundle.containsKey(WOCConstants.OFFER_ID)) { + offerId = bundle.getString(WOCConstants.OFFER_ID); + } + if (bundle.containsKey(WOCConstants.SCREEN_TYPE)) { + fromScreen = bundle.getString(WOCConstants.SCREEN_TYPE); + } + } + } + + public void changeView() { + if (linear_email.getVisibility() == View.VISIBLE) + ((BuyingWizardBaseActivity) mContext).popBackDirect(); + else if (linear_phone.getVisibility() == View.GONE) { + layout_hold.setVisibility(View.GONE); + linear_phone.setVisibility(View.VISIBLE); + linear_email.setVisibility(View.GONE); + + } else if (linear_email.getVisibility() == View.GONE) { + linear_email.setVisibility(View.VISIBLE); + linear_phone.setVisibility(View.GONE); + layout_hold.setVisibility(View.GONE); + } + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.btn_next_phone: + if (isValidPhone()) { + hideKeyBoard(); + // if (!offerId.isEmpty()) { + country_code = countryData.countries.get(sp_country.getSelectedItemPosition()).code; + phone_no = edit_phone.getText().toString().trim(); + String phone = country_code + edit_phone.getText().toString().trim(); + ((BuyingWizardBaseActivity) mContext).buyPivPref.setPhone(phone); + + checkAuth(); + /*} else { + showToast(getString(R.string.offerid_not_available)); + ((BuyingWizardBaseActivity) mContext).popBackDirect(); + }*/ + } + break; + + case R.id.btn_next_email: + if (!edit_email.getText().toString().isEmpty() && isValidEmail(edit_email.getText().toString())) { + email = edit_email.getText().toString(); + linear_phone.setVisibility(View.VISIBLE); + linear_email.setVisibility(View.GONE); + } else { + showToast(mContext.getString(R.string.alert_enter_valid_email)); + } + break; + case R.id.tv_skip_email: + linear_phone.setVisibility(View.VISIBLE); + linear_email.setVisibility(View.GONE); + break; + case R.id.btn_sign_in: + goToUrl("https://wallofcoins.com/signin/" + country_code.replace("+", "") + "-" + phone_no + "/"); + break; + } + } + + private boolean isValidPhone() { + if (edit_phone.getText().toString().trim().isEmpty()) { + edit_phone.requestFocus(); + showToast(mContext.getString(R.string.please_enter_phone_no)); + return false; + } else if (edit_phone.getText().toString().trim().length() < 10) { + edit_phone.requestFocus(); + showToast(mContext.getString(R.string.please_enter_10_digits_phone_no)); + return false; + } + return true; + } + + //add country code list for phone + private void addCountryCodeList() { + String json; + try { + InputStream is = getActivity().getAssets().open("countries.json"); + int size = is.available(); + byte[] buffer = new byte[size]; + is.read(buffer); + is.close(); + json = new String(buffer, "UTF-8"); + } catch (IOException ex) { + ex.printStackTrace(); + return; + } + + countryData = new Gson().fromJson(json, CountryData.class); + + List stringList = new ArrayList<>(); + + for (CountryData.CountriesBean bean : countryData.countries) { + stringList.add(bean.name + " (" + bean.code + ")"); + } + CustomAdapter customAdapter = new CustomAdapter(getActivity(), R.layout.spinner_row_country, countryData.countries); + customAdapter.setDropDownViewResource(R.layout.spinner_row_country); + sp_country.setAdapter(customAdapter); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { + + } + + /** + * Method for check authentication type + */ + private void checkAuth() { + if (NetworkUtil.isOnline(mContext)) { + String phone = ((BuyingWizardBaseActivity) mContext).buyPivPref.getPhone(); + if (!TextUtils.isEmpty(phone)) { + linearProgress.setVisibility(View.VISIBLE); + + WallofCoins.createService(interceptor, mContext).checkAuth(phone, getString(R.string.WALLOFCOINS_PUBLISHER_ID)).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + Log.d(TAG, "onResponse: response code==>>" + response.code()); + linearProgress.setVisibility(View.GONE); + if (response.code() == 200) { + if (response.body() != null + && response.body().getAvailableAuthSources() != null + && response.body().getAvailableAuthSources().size() > 0) { + + if (response.body().getAvailableAuthSources().get(0).equals("password")) {//from wesite + showUserPasswordAuthenticationDialog(); + return; + } else if ((response.body().getAvailableAuthSources().size() >= 2//from mobile + && response.body().getAvailableAuthSources().get(1).equals("device")) + || (response.body().getAvailableAuthSources().get(0).equals("device"))) { + hideKeyBoard(); + createHold(); + } + } + } else if (response.code() == 404) { + hideKeyBoard(); + createHold(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + linearProgress.setVisibility(View.GONE); + showToast(mContext.getString(R.string.try_again)); + } + }); + } else { + showToast(mContext.getString(R.string.alert_phone)); + } + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + } + + /** + * User authentication custom dialog for authenticate user using password + */ + private void showUserPasswordAuthenticationDialog() { + + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mContext); + LayoutInflater inflater = getActivity().getLayoutInflater(); + View dialogView = inflater.inflate(R.layout.layout_authenticate_password_wallet_dialog, null); + dialogBuilder.setView(dialogView); + + final EditText edtPassword = (EditText) dialogView.findViewById(R.id.edt_woc_authenticaion_password); + TextView txtTitle = (TextView) dialogView.findViewById(R.id.txt_existing_user_dialog_message); + Button btnLogin = (Button) dialogView.findViewById(R.id.btnLogin); + Button btnForgotPassword = (Button) dialogView.findViewById(R.id.btnForgotPassword); + + txtTitle.setMovementMethod(LinkMovementMethod.getInstance()); + + final AlertDialog alertDialog = dialogBuilder.create(); + alertDialog.show(); + + ImageView imgClose = (ImageView) dialogView.findViewById(R.id.imgClose); + + imgClose.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + alertDialog.dismiss(); + } + }); + + btnForgotPassword.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + goToUrl(WOCConstants.KEY_FORGOT_PASSWORD_URL); + } + }); + + btnLogin.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + password = edtPassword.getText().toString().trim(); + if (password.length() > 0) { + getAuthTokenCall(password); + alertDialog.dismiss(); + } else { + showToast(mContext.getString(R.string.password_alert)); + } + } + }); + + } + + /** + * Authorized user using password or device code + * + * @param password + */ + private void getAuthTokenCall(final String password) { + if (NetworkUtil.isOnline(mContext)) { + String phone = ((BuyingWizardBaseActivity) mContext).buyPivPref.getPhone(); + + if (!TextUtils.isEmpty(phone)) { + + HashMap getAuthTokenReq = new HashMap<>(); + if (!TextUtils.isEmpty(password)) { + getAuthTokenReq.put(WOCConstants.KEY_PASSWORD, password); + } else { + getAuthTokenReq.put(WOCConstants.KEY_DEVICECODE, getDeviceCode(mContext, + ((BuyingWizardBaseActivity) mContext).buyPivPref)); + } + + if (!TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext).buyPivPref.getDeviceId())) { + getAuthTokenReq.put(WOCConstants.KEY_DEVICEID, ((BuyingWizardBaseActivity) mContext) + .buyPivPref.getDeviceId()); + } + + getAuthTokenReq.put(WOCConstants.KEY_PUBLISHER_ID, getString(R.string.WALLOFCOINS_PUBLISHER_ID)); + + linearProgress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, getActivity()).getAuthToken(phone, getAuthTokenReq) + .enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + linearProgress.setVisibility(View.GONE); + int code = response.code(); + + if (code >= 400 && response.body() == null) { + try { + if (!TextUtils.isEmpty(password)) { + showAlertPasswordDialog(); + } else { + createDevice(); + } + } catch (Exception e) { + e.printStackTrace(); + showToast(mContext.getString(R.string.try_again)); + } + return; + } + + if (!TextUtils.isEmpty(response.body().token)) { + ((BuyingWizardBaseActivity) mContext).buyPivPref.setAuthToken(response.body().token); + } + if (!TextUtils.isEmpty(password) && TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext) + .buyPivPref.getDeviceId())) { + getDevice(); + } else { + credentilasPref.addPhone(country_code + edit_phone.getText().toString().trim(), + ((BuyingWizardBaseActivity) mContext).buyPivPref.getDeviceId()); + if (fromScreen.equalsIgnoreCase("PhoneListFragment")) + ((BuyingWizardBaseActivity) mContext) + .popBackAllFragmentsExcept("pivx.org.pivxwallet.wallofcoins.buyingwizard.phone_list.PhoneListFragment"); + else + createHold(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + showToast(mContext.getString(R.string.try_again)); + linearProgress.setVisibility(View.GONE); + } + }); + + } else { + showToast(mContext.getString(R.string.alert_phone_password_required)); + } + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + } + + /** + * Method for create new hold + */ + public void createHold() { + if (NetworkUtil.isOnline(mContext)) { + String phone = ((BuyingWizardBaseActivity) mContext).buyPivPref.getPhone(); + + final HashMap createHoldPassReq = new HashMap<>(); + + if (TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext).buyPivPref.getAuthToken())) { + createHoldPassReq.put(WOCConstants.KEY_PHONE, phone); + createHoldPassReq.put(WOCConstants.KEY_PUBLISHER_ID, getString(R.string.WALLOFCOINS_PUBLISHER_ID)); + createHoldPassReq.put(WOCConstants.KEY_EMAIL, email); + createHoldPassReq.put(WOCConstants.KEY_deviceName, WOCConstants.KEY_DEVICE_NAME_VALUE); + createHoldPassReq.put(WOCConstants.KEY_DEVICECODE, + getDeviceCode(mContext, ((BuyingWizardBaseActivity) mContext).buyPivPref)); + } + createHoldPassReq.put(WOCConstants.KEY_OFFER, offerId); + + linearProgress.setVisibility(View.VISIBLE); + + WallofCoins.createService(interceptor, getActivity()).createHold(createHoldPassReq) + .enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + linearProgress.setVisibility(View.GONE); + + if (null != response.body() && response.code() < 299) { + + createHoldResp = response.body(); + ((BuyingWizardBaseActivity) mContext).buyPivPref.setHoldId(createHoldResp.id); + ((BuyingWizardBaseActivity) mContext).buyPivPref.setCreateHoldResp(createHoldResp); + if (TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext).buyPivPref.getDeviceId()) + && !TextUtils.isEmpty(createHoldResp.deviceId)) { + ((BuyingWizardBaseActivity) mContext).buyPivPref.setDeviceId(createHoldResp.deviceId); + + //added + String phone = country_code + edit_phone.getText().toString().trim(); + credentilasPref.addPhone(phone, ((BuyingWizardBaseActivity) mContext).buyPivPref.getDeviceId()); + } + if (!TextUtils.isEmpty(response.body().token)) { + ((BuyingWizardBaseActivity) mContext).buyPivPref.setAuthToken(createHoldResp.token); + } + navigateToVerifyOtp(createHoldResp.__PURCHASE_CODE); + + } else if (null != response.errorBody()) { + if (response.code() == 403 && TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext) + .buyPivPref.getAuthToken())) { + + layout_hold.setVisibility(View.VISIBLE); + linear_email.setVisibility(View.GONE); + linear_phone.setVisibility(View.GONE); + } else if (response.code() == 403 && !TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext) + .buyPivPref.getAuthToken())) { + getHolds(); + } else if (response.code() == 400) { + if (!TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext).buyPivPref.getAuthToken())) { + navigateToOrderList(false); + } else { + layout_hold.setVisibility(View.VISIBLE); + linear_email.setVisibility(View.GONE); + linear_phone.setVisibility(View.GONE); + } + } else { + try { + if (!TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext).buyPivPref.getAuthToken())) { + navigateToOrderList(false); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + @Override + public void onFailure(Call call, Throwable t) { + linearProgress.setVisibility(View.GONE); + Toast.makeText(getContext(), R.string.try_again, Toast.LENGTH_SHORT).show(); + } + }); + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + /** + * navigate to otp code screen with code + * + * @param otp + */ + private void navigateToVerifyOtp(String otp) { + Bundle bundle = new Bundle(); + bundle.putString(WOCConstants.VERIFICATION_OTP, otp); + BuyingWizardVerifycationOtpFragment otpFragment = new BuyingWizardVerifycationOtpFragment(); + otpFragment.setArguments(bundle); + + ((BuyingWizardBaseActivity) mContext).replaceFragment(otpFragment, true, true); + } + + /** + * Get all holds for delete active hold + */ + private void getHolds() { + linearProgress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, getActivity()).getHolds().enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200 && response.body() != null) { + linearProgress.setVisibility(View.GONE); + List holdsList = response.body(); + int holdCount = 0; + if (holdsList.size() > 0) { + for (int i = 0; i < holdsList.size(); i++) { + if (null != holdsList.get(i).status && holdsList.get(i).status.equals("AC")) { + deleteHold(holdsList.get(i).id); + holdCount++; + } + } + if (holdCount == 0) { + navigateToOrderList(false); + } + } else { + navigateToOrderList(false); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + linearProgress.setVisibility(View.GONE); + Log.e(TAG, "onFailure: ", t); + showToast(mContext.getString(R.string.try_again)); + } + }); + } + + private void navigateToOrderList(boolean isFromCreateHold) { + BuyingWizardOrderHistoryFragment historyFragment = new BuyingWizardOrderHistoryFragment(); + Bundle bundle = new Bundle(); + bundle.putBoolean("isFromCreateHold", isFromCreateHold); + historyFragment.setArguments(bundle); + ((BuyingWizardBaseActivity) mContext).replaceFragment(historyFragment, true, true); + } + + /** + * Method call for delete for provide holdId + * + * @param holdId + */ + private void deleteHold(String holdId) { + linearProgress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, getActivity()).deleteHold(holdId).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + createHold(); + } + + @Override + public void onFailure(Call call, Throwable t) { + linearProgress.setVisibility(View.GONE); + Log.e(TAG, "onFailure: ", t); + showToast(mContext.getString(R.string.try_again)); + } + }); + } + + /** + * Get Devices for Register user with password + */ + private void getDevice() { + + linearProgress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, getActivity()).getDevice().enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200 && response.body() != null) { + linearProgress.setVisibility(View.GONE); + List deviceList = response.body(); + if (deviceList.size() > 0) { + ((BuyingWizardBaseActivity) mContext).buyPivPref.setDeviceId( + deviceList.get(deviceList.size() - 1).getId() + ""); + getAuthTokenCall(""); + } else { + createDevice(); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + linearProgress.setVisibility(View.GONE); + Log.e(TAG, "onFailure: ", t); + showToast(mContext.getString(R.string.try_again)); + } + }); + + } + + /** + * Method for register new device + */ + private void createDevice() { + final HashMap createDeviceReq = new HashMap<>(); + createDeviceReq.put(WOCConstants.KEY_DEVICE_NAME, mContext.getString(R.string.pivx_wallet_name)); + createDeviceReq.put(WOCConstants.KEY_DEVICE_CODE, getDeviceCode(mContext, ((BuyingWizardBaseActivity) mContext) + .buyPivPref)); + createDeviceReq.put(WOCConstants.KEY_PUBLISHER_ID, getString(R.string.WALLOFCOINS_PUBLISHER_ID)); + linearProgress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, getActivity()).createDevice(createDeviceReq).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (null != response.body() && response.code() < 299) { + createDeviceResp = response.body(); + ((BuyingWizardBaseActivity) mContext).buyPivPref.setDeviceId(createDeviceResp.getId() + ""); + getAuthTokenCall(""); + } else { + showToast(mContext.getString(R.string.try_again)); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + showToast(mContext.getString(R.string.try_again)); + } + }); + } + + //this method remove animation when user want to clear whole back stack + @Override + public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { + if (BuyingWizardFragmentUtils.sDisableFragmentAnimations) { + Animation a = new Animation() { + }; + a.setDuration(0); + return a; + } + return super.onCreateAnimation(transit, enter, nextAnim); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/location/BuyingWizardLocationFragment.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/location/BuyingWizardLocationFragment.java new file mode 100644 index 000000000..ed0bd19bb --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/location/BuyingWizardLocationFragment.java @@ -0,0 +1,512 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.location; + +import android.content.Context; +import android.content.SharedPreferences; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.location.LocationManager; +import android.os.Bundle; +import android.support.v7.app.AlertDialog; +import android.text.TextUtils; +import android.text.method.LinkMovementMethod; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.wallofcoins.WOCConstants; +import pivx.org.pivxwallet.wallofcoins.api.WallofCoins; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseActivity; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.offer_amount.BuyingWizardOfferAmountFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.order_history.BuyingWizardOrderHistoryFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.phone_list.BuyingWizardPhoneListFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.utils.BuyingWizardFragmentUtils; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.verification_otp.BuyingWizardVerifycationOtpFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.zip.BuyingWizardZipFragment; +import pivx.org.pivxwallet.wallofcoins.response.CheckAuthResp; +import pivx.org.pivxwallet.wallofcoins.response.CreateDeviceResp; +import pivx.org.pivxwallet.wallofcoins.response.GetAuthTokenResp; +import pivx.org.pivxwallet.wallofcoins.utils.NetworkUtil; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +/** + * Created on 6/3/18. + */ + +public class BuyingWizardLocationFragment extends BuyingWizardBaseFragment implements View.OnClickListener, + SharedPreferences.OnSharedPreferenceChangeListener { + + + private View rootView; + private Button button_get_location, button_get_location_no, btn_sign_out_woc, + btn_order_history_woc, btn_sign_in_woc; + private TextView txtViewLocationMessage, text_message_sign_out, text_message_sign_in; + private String zipCode, password; + private double latitude, longitude; + private final String TAG = "LocationFragment"; + private LinearLayout layout_sign_out, linear_progress, layout_sign_in; + private CreateDeviceResp createDeviceResp; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + mContext = context; + } + + @Override + public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { + + if (rootView == null) { + rootView = inflater.inflate(R.layout.fragment_buying_location, container, false); + init(); + setListeners(); + + return rootView; + } else + return rootView; + } + + private void init() { + + button_get_location_no = (Button) rootView.findViewById(R.id.button_get_location_no); + button_get_location = (Button) rootView.findViewById(R.id.button_get_location); + txtViewLocationMessage = (TextView) rootView.findViewById(R.id.txtViewLocationMessage); + btn_sign_out_woc = (Button) rootView.findViewById(R.id.btn_sign_out_woc); + text_message_sign_out = (TextView) rootView.findViewById(R.id.text_message_sign_out); + layout_sign_out = (LinearLayout) rootView.findViewById(R.id.layout_sign_out); + linear_progress = (LinearLayout) rootView.findViewById(R.id.linear_progress); + btn_order_history_woc = (Button) rootView.findViewById(R.id.btn_order_history_woc); + layout_sign_in = (LinearLayout) rootView.findViewById(R.id.layout_sign_in); + text_message_sign_in = (TextView) rootView.findViewById(R.id.text_message_sign_in); + btn_sign_in_woc = (Button) rootView.findViewById(R.id.btn_sign_in_woc); + } + + private void setListeners() { + button_get_location.setOnClickListener(this); + button_get_location_no.setOnClickListener(this); + btn_sign_out_woc.setOnClickListener(this); + btn_order_history_woc.setOnClickListener(this); + btn_sign_in_woc.setOnClickListener(this); + } + + private void navigateToVerifyOtp(String otp) { + Bundle bundle = new Bundle(); + bundle.putString(WOCConstants.VERIFICATION_OTP, otp); + BuyingWizardVerifycationOtpFragment otpFragment = new BuyingWizardVerifycationOtpFragment(); + otpFragment.setArguments(bundle); + + ((BuyingWizardBaseActivity) mContext).replaceFragment(otpFragment, true, true); + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.button_get_location: + if (checkPermissions()) + getZip(); + else + requestLocationPermission(); + break; + + case R.id.button_get_location_no: + ((BuyingWizardBaseActivity) mContext).replaceFragment(new BuyingWizardZipFragment(), + true, true); + break; + case R.id.btn_sign_out_woc: + deleteAuthCall(false); + break; + case R.id.btn_order_history_woc: + navigateToOrderList(false); + break; + case R.id.btn_sign_in_woc: + ((BuyingWizardBaseActivity) mContext).replaceFragment(new BuyingWizardPhoneListFragment(), + true, true); + break; + + } + } + + private void navigateToOrderList(boolean isFromCreateHold) { + BuyingWizardOrderHistoryFragment historyFragment = new BuyingWizardOrderHistoryFragment(); + Bundle bundle = new Bundle(); + bundle.putBoolean("isFromCreateHold", isFromCreateHold); + historyFragment.setArguments(bundle); + ((BuyingWizardBaseActivity) mContext).replaceFragment(historyFragment, true, true); + } + + @Override + public void onResume() { + super.onResume(); + if (!TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext).buyPivPref.getAuthToken())) { + layout_sign_out.setVisibility(View.VISIBLE); + layout_sign_in.setVisibility(View.GONE); + String phone = mContext.getString(R.string.wallet_is_signed) + " " + + ((BuyingWizardBaseActivity) mContext).buyPivPref.getPhone(); + text_message_sign_out.setText(phone); + } else { + layout_sign_out.setVisibility(View.GONE); + layout_sign_in.setVisibility(View.VISIBLE); + } + } + + /** + * User authentication custom dialog for authenticate user using password + */ + private void showUserPasswordAuthenticationDialog() { + + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mContext); + LayoutInflater inflater = getActivity().getLayoutInflater(); + View dialogView = inflater.inflate(R.layout.layout_authenticate_password_wallet_dialog, null); + dialogBuilder.setView(dialogView); + + final EditText edtPassword = (EditText) dialogView.findViewById(R.id.edt_woc_authenticaion_password); + TextView txtTitle = (TextView) dialogView.findViewById(R.id.txt_existing_user_dialog_message); + Button btnLogin = (Button) dialogView.findViewById(R.id.btnLogin); + Button btnForgotPassword = (Button) dialogView.findViewById(R.id.btnForgotPassword); + + txtTitle.setMovementMethod(LinkMovementMethod.getInstance()); + + final AlertDialog alertDialog = dialogBuilder.create(); + alertDialog.show(); + + ImageView imgClose = (ImageView) dialogView.findViewById(R.id.imgClose); + + imgClose.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + alertDialog.dismiss(); + } + }); + + btnForgotPassword.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + goToUrl(WOCConstants.KEY_FORGOT_PASSWORD_URL); + } + }); + + btnLogin.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + password = edtPassword.getText().toString().trim(); + if (password.length() > 0) { + getAuthTokenCall(password); + alertDialog.dismiss(); + } else { + showToast(mContext.getString(R.string.password_alert)); + } + } + }); + + } + + /** + * Authorized user using password or device code + * + * @param password + */ + private void getAuthTokenCall(final String password) { + if (NetworkUtil.isOnline(mContext)) { + String phone = ((BuyingWizardBaseActivity) mContext).buyPivPref.getPhone(); + + if (!TextUtils.isEmpty(phone)) { + + HashMap getAuthTokenReq = new HashMap<>(); + if (!TextUtils.isEmpty(password)) { + getAuthTokenReq.put(WOCConstants.KEY_PASSWORD, password); + } else { + getAuthTokenReq.put(WOCConstants.KEY_DEVICECODE, getDeviceCode(mContext, + ((BuyingWizardBaseActivity) mContext).buyPivPref)); + } + + if (!TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext).buyPivPref.getDeviceId())) { + getAuthTokenReq.put(WOCConstants.KEY_DEVICEID, ((BuyingWizardBaseActivity) mContext).buyPivPref.getDeviceId()); + } + + getAuthTokenReq.put(WOCConstants.KEY_PUBLISHER_ID, getString(R.string.WALLOFCOINS_PUBLISHER_ID)); + + linear_progress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, getActivity()).getAuthToken(phone, getAuthTokenReq).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + linear_progress.setVisibility(View.GONE); + int code = response.code(); + + if (code >= 400 && response.body() == null) { + try { + if (!TextUtils.isEmpty(password)) { + showAlertPasswordDialog(); + } else { + createDevice(); + } + } catch (Exception e) { + e.printStackTrace(); + showToast(mContext.getString(R.string.try_again)); + } + return; + } + + if (!TextUtils.isEmpty(response.body().token)) { + ((BuyingWizardBaseActivity) mContext).buyPivPref.setAuthToken(response.body().token); + } + if (!TextUtils.isEmpty(password) && TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext) + .buyPivPref.getDeviceId())) { + getDevice(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + showToast(mContext.getString(R.string.try_again)); + linear_progress.setVisibility(View.GONE); + } + }); + + } else { + showToast(mContext.getString(R.string.alert_phone_password_required)); + } + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + /** + * Get Devices for Register user with password + */ + private void getDevice() { + if (NetworkUtil.isOnline(mContext)) { + linear_progress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, getActivity()).getDevice().enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200 && response.body() != null) { + List deviceList = response.body(); + if (deviceList.size() > 0) { + ((BuyingWizardBaseActivity) mContext) + .buyPivPref.setDeviceId(deviceList.get(deviceList.size() - 1).getId() + ""); + getAuthTokenCall(""); + } else { + createDevice(); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + linear_progress.setVisibility(View.GONE); + Log.e(TAG, "onFailure: ", t); + showToast(mContext.getString(R.string.try_again)); + } + }); + + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + /** + * Method for register new device + */ + private void createDevice() { + if (NetworkUtil.isOnline(mContext)) { + final HashMap createDeviceReq = new HashMap<>(); + createDeviceReq.put(WOCConstants.KEY_DEVICE_NAME, mContext.getString(R.string.pivx_wallet_name)); + createDeviceReq.put(WOCConstants.KEY_DEVICE_CODE, getDeviceCode(mContext, + ((BuyingWizardBaseActivity) mContext).buyPivPref)); + createDeviceReq.put(WOCConstants.KEY_PUBLISHER_ID, getString(R.string.WALLOFCOINS_PUBLISHER_ID)); + linear_progress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, getActivity()).createDevice(createDeviceReq).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (null != response.body() && response.code() < 299) { + createDeviceResp = response.body(); + ((BuyingWizardBaseActivity) mContext).buyPivPref.setDeviceId(createDeviceResp.getId() + ""); + getAuthTokenCall(""); + } else { + showToast(mContext.getString(R.string.try_again)); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + showToast(mContext.getString(R.string.try_again)); + } + }); + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + /** + * Method for check authentication type + */ + private void checkAuth() { + if (NetworkUtil.isOnline(mContext)) { + String phone = ((BuyingWizardBaseActivity) mContext).buyPivPref.getPhone(); + if (!TextUtils.isEmpty(phone)) { + linear_progress.setVisibility(View.VISIBLE); + + WallofCoins.createService(interceptor, mContext).checkAuth(phone, getString(R.string.WALLOFCOINS_PUBLISHER_ID)).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + Log.d(TAG, "onResponse: response code==>>" + response.code()); + linear_progress.setVisibility(View.GONE); + if (response.code() == 200) { + if (response.body() != null + && response.body().getAvailableAuthSources() != null + && response.body().getAvailableAuthSources().size() > 0) { + if (response.body().getAvailableAuthSources().get(0).equals("password")) { + showUserPasswordAuthenticationDialog(); + return; + } else if ((response.body().getAvailableAuthSources().size() >= 2 + && response.body().getAvailableAuthSources().get(1).equals("device")) + || (response.body().getAvailableAuthSources().get(0).equals("device"))) { + hideKeyBoard(); + } + } + } else if (response.code() == 404) { + hideKeyBoard(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + linear_progress.setVisibility(View.GONE); + showToast(mContext.getString(R.string.try_again)); + } + }); + } else { + showToast(mContext.getString(R.string.alert_phone)); + } + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + /** + * Method for singout user + * + * @param isPendingHold + */ + public void deleteAuthCall(final boolean isPendingHold) { + if (NetworkUtil.isOnline(mContext)) { + final String phone = ((BuyingWizardBaseActivity) mContext).buyPivPref.getPhone(); + if (!TextUtils.isEmpty(phone)) { + linear_progress.setVisibility(View.VISIBLE); + password = ""; + WallofCoins.createService(interceptor, mContext) + .deleteAuth(phone, getString(R.string.WALLOFCOINS_PUBLISHER_ID)) + .enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + Log.d(TAG, "onResponse: response code==>>" + response.code()); + linear_progress.setVisibility(View.GONE); + if (response.code() < 299) { + ((BuyingWizardBaseActivity) mContext).buyPivPref.setAuthToken(""); + password = ""; + ((BuyingWizardBaseActivity) mContext).buyPivPref.clearAllPrefrance(); + if (isPendingHold) { + checkAuth(); + } else { + showToast(mContext.getString(R.string.alert_sign_out)); + layout_sign_in.setVisibility(View.VISIBLE); + layout_sign_out.setVisibility(View.GONE); + + } + } else { + showToast(mContext.getString(R.string.try_again)); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + linear_progress.setVisibility(View.GONE); + showToast(mContext.getString(R.string.try_again)); + } + }); + } else { + showToast(mContext.getString(R.string.alert_phone)); + } + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + /** + * Get ZipCode for device current location + */ + private void getZip() { + + Location myLocation = getLastKnownLocation(); + if (myLocation != null) { + + Geocoder geocoder; + List
addresses; + geocoder = new Geocoder(mContext, Locale.getDefault()); + if (geocoder != null) { + try { + addresses = geocoder.getFromLocation(myLocation.getLatitude(), myLocation.getLongitude(), 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5 + latitude = myLocation.getLatitude(); + longitude = myLocation.getLongitude(); + zipCode = addresses.get(0).getPostalCode(); + navigateToOtherScreen(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + } else { + LocationManager mlocManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); + boolean enabled = mlocManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + + if (!enabled) { + showDialogGPS(); + } + } + } + + private void navigateToOtherScreen() { + Bundle bundle = new Bundle(); + bundle.putDouble(WOCConstants.LATITUDE, latitude); + bundle.putDouble(WOCConstants.LONGITUDE, longitude); + bundle.putString(WOCConstants.ZIP, zipCode); + BuyingWizardOfferAmountFragment offerAmountFragment = new BuyingWizardOfferAmountFragment(); + offerAmountFragment.setArguments(bundle); + + ((BuyingWizardBaseActivity) mContext).replaceFragment(offerAmountFragment, true, true); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { + + } + + //this method remove animation when user want to clear back stack + @Override + public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { + if (BuyingWizardFragmentUtils.sDisableFragmentAnimations) { + Animation a = new Animation() { + }; + a.setDuration(0); + return a; + } + return super.onCreateAnimation(transit, enter, nextAnim); + } + +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/models/BuyingWizardAccountJson.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/models/BuyingWizardAccountJson.java new file mode 100644 index 000000000..1dbc772a9 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/models/BuyingWizardAccountJson.java @@ -0,0 +1,52 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.models; + +/** + * Created on 08-Mar-18. + */ + +public class BuyingWizardAccountJson { + + /** + * displaySort : 0 + * name : fullName + * value : Ian Marshall + * label : Full Name + */ + + private String displaySort; + private String name; + private String value; + private String label; + + public String getDisplaySort() { + return displaySort; + } + + public void setDisplaySort(String displaySort) { + this.displaySort = displaySort; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } +} \ No newline at end of file diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/models/BuyingWizardPhoneListVO.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/models/BuyingWizardPhoneListVO.java new file mode 100644 index 000000000..16440ba05 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/models/BuyingWizardPhoneListVO.java @@ -0,0 +1,31 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.models; + +import java.io.Serializable; + +/** + * Created on 12-Mar-18. + */ + +public class BuyingWizardPhoneListVO implements Serializable { + + private String phoneNumber = ""; + private String deviceId = ""; + + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/offer_amount/BuyingWizardOfferAmountFragment.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/offer_amount/BuyingWizardOfferAmountFragment.java new file mode 100644 index 000000000..d0db10836 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/offer_amount/BuyingWizardOfferAmountFragment.java @@ -0,0 +1,518 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.offer_amount; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.annotation.Nullable; +import android.support.v4.app.LoaderManager; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.Toast; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import org.pivxj.core.Address; + +import java.util.HashMap; +import java.util.List; + +import pivx.org.pivxwallet.PivxApplication; +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.module.PivxModule; +import pivx.org.pivxwallet.wallofcoins.WOCConstants; +import pivx.org.pivxwallet.wallofcoins.api.WallofCoins; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseActivity; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.adapters.BuyingWizardOffersAdapter; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.email_phone.BuyingWizardEmailPhoneFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.order_history.BuyingWizardOrderHistoryFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.utils.BuyingWizardAddressPref; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.utils.BuyingWizardFragmentUtils; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.verification_otp.BuyingWizardVerifycationOtpFragment; +import pivx.org.pivxwallet.wallofcoins.response.CreateHoldResp; +import pivx.org.pivxwallet.wallofcoins.response.DiscoveryInputsResp; +import pivx.org.pivxwallet.wallofcoins.response.ErrorResp; +import pivx.org.pivxwallet.wallofcoins.response.GetHoldsResp; +import pivx.org.pivxwallet.wallofcoins.response.GetOffersResp; +import pivx.org.pivxwallet.wallofcoins.utils.NetworkUtil; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +/** + * Created on 07-Mar-18. + */ + +public class BuyingWizardOfferAmountFragment extends BuyingWizardBaseFragment implements View.OnClickListener, + SharedPreferences.OnSharedPreferenceChangeListener { + + private View rootView; + private String zipCode; + private double latitude, longitude; + private Button button_get_offers; + private EditText edtViewDollar; + private LinearLayout linearProgress, layout_create_hold; + private final String TAG = "OfferAmountFragment"; + private String keyAddress, offerId, pivAmount = "", bankId; + private RecyclerView rv_offers; + private LoaderManager loaderManager; + private final int ID_RATE_LOADER = 1; + private CreateHoldResp createHoldResp; + private BuyingWizardAddressPref wizardAddressPref; + private PivxModule module; + private Address address; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + mContext = context; + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + if (rootView == null) { + rootView = inflater.inflate(R.layout.fragment_buying_offer_amount, container, false); + init(); + setListeners(); + readBundle(getArguments()); + return rootView; + } else + return rootView; + } + + + private void init() { + module = PivxApplication.getInstance().getModule(); + address = module.getReceiveAddress(); + this.loaderManager = getLoaderManager(); + wizardAddressPref = new BuyingWizardAddressPref(PreferenceManager.getDefaultSharedPreferences(mContext)); + + button_get_offers = (Button) rootView.findViewById(R.id.button_get_offers); + linearProgress = (LinearLayout) rootView.findViewById(R.id.linear_progress); + layout_create_hold = (LinearLayout) rootView.findViewById(R.id.layout_create_hold); + edtViewDollar = (EditText) rootView.findViewById(R.id.edtViewDollar); + + rv_offers = (RecyclerView) rootView.findViewById(R.id.rv_offers); + rv_offers.setLayoutManager(new LinearLayoutManager(mContext)); + } + + private void setListeners() { + button_get_offers.setOnClickListener(this); + } + + /** + * handle the arguments according to user come from previos screen + */ + private void readBundle(Bundle bundle) { + if (bundle != null) { + if (bundle.containsKey(WOCConstants.LATITUDE)) { //user come from my location + latitude = bundle.getDouble(WOCConstants.LATITUDE); + longitude = bundle.getDouble(WOCConstants.LONGITUDE); + } + if (bundle.containsKey(WOCConstants.ZIP)) { // user come with only zip + zipCode = bundle.getString(WOCConstants.ZIP); + } + if (bundle.containsKey(WOCConstants.BANK_ID)) {// user come from bank list + bankId = bundle.getString(WOCConstants.BANK_ID); + } + } + } + + @Override + public void onResume() { + super.onResume(); + + } + + @Override + public void onPause() { + super.onPause(); + } + + @Override + public void onDestroy() { + loaderManager.destroyLoader(ID_RATE_LOADER); + super.onDestroy(); + } + + /** + * hide show view + */ + public void changeView() { + if (layout_create_hold.getVisibility() == View.GONE) { + layout_create_hold.setVisibility(View.VISIBLE); + rv_offers.setVisibility(View.GONE); + } else + ((BuyingWizardBaseActivity) mContext).popBackDirect(); + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.button_get_offers: + hideKeyBoard(); + if (isValidAmount()) + callDiscoveryInputs(); + break; + + + } + } + + private boolean isValidAmount() { + String amt = edtViewDollar.getText().toString().trim(); + + if (edtViewDollar.getText().toString().trim().isEmpty()) { + showToast(mContext.getString(R.string.alert_amount)); + return false; + } else if (amt.matches("^\\.$")) { + showToast(mContext.getString(R.string.enter_valid_amt)); + return false; + } else if (Double.parseDouble(edtViewDollar.getText().toString().trim()) < 5) { + showToast(mContext.getString(R.string.alert_puchase_amout)); + return false; + } else if (Double.parseDouble(edtViewDollar.getText().toString().trim()) > 1000000) { + showToast(mContext.getString(R.string.amount_less_than_1000000)); + return false; + } + return true; + } + + + private void callDiscoveryInputs() { + if (NetworkUtil.isOnline(mContext)) { + HashMap discoveryInputsReq = new HashMap<>(); + discoveryInputsReq.put(WOCConstants.KEY_PUBLISHER_ID, getString(R.string.WALLOFCOINS_PUBLISHER_ID)); + keyAddress = address.toBase58(); + wizardAddressPref.setBuyPivAddress(keyAddress); + + discoveryInputsReq.put(WOCConstants.KEY_CRYPTO_ADDRESS, keyAddress); + String offerAmount = "0"; + + discoveryInputsReq.put(WOCConstants.KEY_USD_AMOUNT, "" + edtViewDollar.getText().toString()); + offerAmount = "" + edtViewDollar.getText().toString(); + + if (latitude > 0.0) + discoveryInputsReq.put(WOCConstants.KEY_COUNTRY, getCountryCode(latitude, longitude).toLowerCase()); + + discoveryInputsReq.put(WOCConstants.KEY_CRYPTO, WOCConstants.CRYPTO); + if (bankId != null) + discoveryInputsReq.put(WOCConstants.KEY_BANK, bankId); + + if (zipCode != null) + discoveryInputsReq.put(WOCConstants.KEY_ZIP_CODE, zipCode); + + if (latitude > 0.0) { + JsonObject jObj = new JsonObject(); + jObj.addProperty(WOCConstants.KEY_LATITUDE, latitude + ""); + jObj.addProperty(WOCConstants.KEY_LONGITUDE, longitude + ""); + + discoveryInputsReq.put(WOCConstants.KEY_BROWSE_LOCATION, jObj.toString()); + } + discoveryInputsReq.put(WOCConstants.KEY_CRYPTO_AMOUNT, "0"); + linearProgress.setVisibility(View.VISIBLE); + + final String finalOfferAmount = offerAmount; + WallofCoins.createService(interceptor, getActivity()) + .discoveryInputs(discoveryInputsReq) + .enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + + if (null != response && null != response.body()) { + if (null != response.body().id) { + updateAddressBookValue(keyAddress, WOCConstants.WOC_ADDRESS);// Update Address Book for Order + + WallofCoins.createService(null, getActivity()).getOffers(response.body().id, getString(R.string.WALLOFCOINS_PUBLISHER_ID)).enqueue(new Callback() { + @Override + public void onResponse(Call call, final Response response) { + + if (null != response && null != response.body()) { + + linearProgress.setVisibility(View.GONE); + + if (null != response.body().singleDeposit && !response.body().singleDeposit.isEmpty()) { + rv_offers.setVisibility(View.VISIBLE); + layout_create_hold.setVisibility(View.GONE); + + BuyingWizardOffersAdapter wizardOffersAdapter = new BuyingWizardOffersAdapter(mContext, response.body(), finalOfferAmount, new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + hideKeyBoard(); + if (position < response.body().singleDeposit.size() + 1) { + offerId = response.body().singleDeposit.get(position - 1).id; + pivAmount = response.body().singleDeposit.get(position - 1).amount.PIVX; + } else { + offerId = response.body().doubleDeposit.get(position - response.body().singleDeposit.size() - 2).id; + pivAmount = response.body().doubleDeposit.get(position - response.body().singleDeposit.size() - 2).totalAmount.PIVX; + } + if (!TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext).buyPivPref.getAuthToken())) { + createHold(); + } else { + Bundle bundle = new Bundle(); + bundle.putString(WOCConstants.OFFER_ID, offerId); + BuyingWizardEmailPhoneFragment fragment = new BuyingWizardEmailPhoneFragment(); + fragment.setArguments(bundle); + + ((BuyingWizardBaseActivity) mContext).replaceFragment(fragment, true, + true); + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + linearProgress.setVisibility(View.GONE); + } + }); + rv_offers.setAdapter(wizardOffersAdapter); + } else { + showToast(mContext.getString(R.string.alert_no_offers)); + } + } else if (null != response && null != response.errorBody()) { + linearProgress.setVisibility(View.GONE); + try { + ErrorResp errorResp = new Gson().fromJson(response.errorBody().string(), ErrorResp.class); + Toast.makeText(getContext(), errorResp.detail, Toast.LENGTH_LONG).show(); + } catch (Exception e) { + e.printStackTrace(); + showToast(mContext.getString(R.string.try_again)); + } + + } else { + linearProgress.setVisibility(View.GONE); + showToast(mContext.getString(R.string.try_again)); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + linearProgress.setVisibility(View.GONE); + showToast(mContext.getString(R.string.try_again)); + } + }); + } else { + linearProgress.setVisibility(View.GONE); + showToast(mContext.getString(R.string.try_again)); + } + } else if (null != response && null != response.errorBody()) { + + linearProgress.setVisibility(View.GONE); + + try { + ErrorResp errorResp = new Gson().fromJson(response.errorBody().string(), ErrorResp.class); + if (errorResp.detail != null && !TextUtils.isEmpty(errorResp.detail)) { + Toast.makeText(getContext(), errorResp.detail, Toast.LENGTH_LONG).show(); + } else { + showToast(mContext.getString(R.string.try_again)); + } + } catch (Exception e) { + e.printStackTrace(); + showToast(mContext.getString(R.string.try_again)); + } + + } else { + linearProgress.setVisibility(View.GONE); + showToast(mContext.getString(R.string.try_again)); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + linearProgress.setVisibility(View.GONE); + String message = t.getMessage(); + Log.d("failure", message); + showToast(mContext.getString(R.string.try_again)); + } + }); + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + /** + * Method for create new hold + */ + public void createHold() { + if (NetworkUtil.isOnline(mContext)) { + String phone = ((BuyingWizardBaseActivity) mContext).buyPivPref.getPhone(); + + final HashMap createHoldPassReq = new HashMap<>(); + + if (TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext).buyPivPref.getAuthToken())) { + createHoldPassReq.put(WOCConstants.KEY_PHONE, phone); + createHoldPassReq.put(WOCConstants.KEY_PUBLISHER_ID, getString(R.string.WALLOFCOINS_PUBLISHER_ID)); + createHoldPassReq.put(WOCConstants.KEY_deviceName, WOCConstants.KEY_DEVICE_NAME_VALUE); + createHoldPassReq.put(WOCConstants.KEY_DEVICECODE, getDeviceCode(mContext, + ((BuyingWizardBaseActivity) mContext).buyPivPref)); + } + createHoldPassReq.put(WOCConstants.KEY_OFFER, offerId); + + linearProgress.setVisibility(View.VISIBLE); + + WallofCoins.createService(interceptor, getActivity()).createHold(createHoldPassReq).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + linearProgress.setVisibility(View.GONE); + + if (null != response.body() && response.code() < 299) { + + createHoldResp = response.body(); + ((BuyingWizardBaseActivity) mContext).buyPivPref.setHoldId(createHoldResp.id); + ((BuyingWizardBaseActivity) mContext).buyPivPref.setCreateHoldResp(createHoldResp); + if (TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext).buyPivPref.getDeviceId()) + && !TextUtils.isEmpty(createHoldResp.deviceId)) { + ((BuyingWizardBaseActivity) mContext).buyPivPref.setDeviceId(createHoldResp.deviceId); + } + if (!TextUtils.isEmpty(response.body().token)) { + ((BuyingWizardBaseActivity) mContext).buyPivPref.setAuthToken(createHoldResp.token); + } + navigateToVerifyOtp(createHoldResp.__PURCHASE_CODE); + + } else if (null != response.errorBody()) { + if (response.code() == 403 && TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext) + .buyPivPref.getAuthToken())) { + } else if (response.code() == 403 && !TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext) + .buyPivPref.getAuthToken())) { + getHolds(); + } else if (response.code() == 400) { + if (!TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext).buyPivPref.getAuthToken())) { + navigateToOrderList(false); + } + } else { + try { + if (!TextUtils.isEmpty(((BuyingWizardBaseActivity) mContext).buyPivPref.getAuthToken())) { + navigateToOrderList(false); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + @Override + public void onFailure(Call call, Throwable t) { + linearProgress.setVisibility(View.GONE); + showToast(mContext.getString(R.string.try_again)); + } + }); + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + + } + + /** + * Get all holds for delete active hold + */ + private void getHolds() { + if (NetworkUtil.isOnline(mContext)) { + linearProgress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, getActivity()).getHolds().enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + linearProgress.setVisibility(View.GONE); + if (response.code() == 200 && response.body() != null) { + List holdsList = response.body(); + int holdCount = 0; + if (holdsList.size() > 0) { + for (int i = 0; i < holdsList.size(); i++) { + if (null != holdsList.get(i).status && holdsList.get(i).status.equals("AC")) { + deleteHold(holdsList.get(i).id); + holdCount++; + } + } + if (holdCount == 0) { + navigateToOrderList(false); + } + } else { + navigateToOrderList(false); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + linearProgress.setVisibility(View.GONE); + Log.e(TAG, "onFailure: ", t); + showToast(mContext.getString(R.string.try_again)); + } + }); + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + /** + * Method call for delete for provide holdId + * + * @param holdId + */ + private void deleteHold(String holdId) { + if (NetworkUtil.isOnline(mContext)) { + linearProgress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, getActivity()).deleteHold(holdId).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + createHold(); + } + + @Override + public void onFailure(Call call, Throwable t) { + linearProgress.setVisibility(View.GONE); + Log.e(TAG, "onFailure: ", t); + showToast(mContext.getString(R.string.try_again)); + } + }); + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + private void navigateToOrderList(boolean isFromCreateHold) { + BuyingWizardOrderHistoryFragment historyFragment = new BuyingWizardOrderHistoryFragment(); + Bundle bundle = new Bundle(); + bundle.putBoolean("isFromCreateHold", isFromCreateHold); + historyFragment.setArguments(bundle); + ((BuyingWizardBaseActivity) mContext).replaceFragment(historyFragment, true, true); + } + + private void navigateToVerifyOtp(String otp) { + Bundle bundle = new Bundle(); + bundle.putString(WOCConstants.VERIFICATION_OTP, otp); + BuyingWizardVerifycationOtpFragment otpFragment = new BuyingWizardVerifycationOtpFragment(); + otpFragment.setArguments(bundle); + + ((BuyingWizardBaseActivity) mContext).replaceFragment(otpFragment, true, true); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { + + } + + //this method remove animation when user want to clear back stack + @Override + public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { + if (BuyingWizardFragmentUtils.sDisableFragmentAnimations) { + Animation a = new Animation() { + }; + a.setDuration(0); + return a; + } + return super.onCreateAnimation(transit, enter, nextAnim); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/order_history/BuyingWizardOrderHistoryFragment.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/order_history/BuyingWizardOrderHistoryFragment.java new file mode 100644 index 000000000..c97083632 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/order_history/BuyingWizardOrderHistoryFragment.java @@ -0,0 +1,607 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.order_history; + +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.support.annotation.Nullable; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.text.Html; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.gson.Gson; + +import java.lang.ref.WeakReference; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.wallofcoins.WOCConstants; +import pivx.org.pivxwallet.wallofcoins.api.WallofCoins; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseActivity; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.adapters.BuyingWizardOrderListAdapter; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.location.BuyingWizardLocationFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.utils.BuyingWizardFragmentUtils; +import pivx.org.pivxwallet.wallofcoins.response.CaptureHoldResp; +import pivx.org.pivxwallet.wallofcoins.response.CheckAuthResp; +import pivx.org.pivxwallet.wallofcoins.response.ConfirmDepositResp; +import pivx.org.pivxwallet.wallofcoins.response.ErrorResp; +import pivx.org.pivxwallet.wallofcoins.response.OrderListResp; +import pivx.org.pivxwallet.wallofcoins.utils.NetworkUtil; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +/** + * Created on 08-Mar-18. + */ + +public class BuyingWizardOrderHistoryFragment extends BuyingWizardBaseFragment + implements SharedPreferences.OnSharedPreferenceChangeListener, View.OnClickListener { + + private final String TAG = "OrderHistoryFragment"; + private View rootView; + private RecyclerView rv_order_list; + private LinearLayout linearProgress, layoutOrderHistory, layoutInstruction, layoutLogout; + private Button btn_buy_more, btnSignout, btnWebLink; + private boolean isFromCreateHold; + private BuyingWizardOrderHistoryFragment fragment; + private int countdownInterval = 1000; + private TextView text_email_receipt, text_no_order, text_message, textHelpMessage; + private Handler handler; + private MyRunnable myRunnable; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + mContext = context; + + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + if (rootView == null) { + rootView = inflater.inflate(R.layout.fragment_buying_order_history, container, false); + init(); + setListeners(); + readBundle(getArguments()); + getOrderList(isFromCreateHold); + return rootView; + } else + return rootView; + } + + private void init() { + fragment = this; + rv_order_list = (RecyclerView) rootView.findViewById(R.id.rv_order_list); + linearProgress = (LinearLayout) rootView.findViewById(R.id.linear_progress); + layoutOrderHistory = (LinearLayout) rootView.findViewById(R.id.layout_order_list); + layoutInstruction = (LinearLayout) rootView.findViewById(R.id.lay_help_instruction_order); + layoutLogout = (LinearLayout) rootView.findViewById(R.id.lay_logout_order); + text_message = (TextView) rootView.findViewById(R.id.text_message); + textHelpMessage = (TextView) rootView.findViewById(R.id.text_help_message); + btnSignout = (Button) rootView.findViewById(R.id.btn_signout); + btnWebLink = (Button) rootView.findViewById(R.id.btn_WebLink); + btn_buy_more = (Button) rootView.findViewById(R.id.btn_buy_more); + text_email_receipt = (TextView) rootView.findViewById(R.id.text_email_receipt); + text_no_order = (TextView) rootView.findViewById(R.id.text_no_order_history); + } + + private void setListeners() { + btn_buy_more.setOnClickListener(this); + btnSignout.setOnClickListener(this); + btnWebLink.setOnClickListener(this); + } + + //Read data from bundle + private void readBundle(Bundle bundle) { + + if (bundle != null && bundle.containsKey("isFromCreateHold")) + isFromCreateHold = bundle.getBoolean("isFromCreateHold"); + + } + + /** + * Get order list using auth token + * + * @param isFromCreateHold + */ + private void getOrderList(final boolean isFromCreateHold) { + if (NetworkUtil.isOnline(mContext)) { + linearProgress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, mContext) + .getOrders(getString(R.string.WALLOFCOINS_PUBLISHER_ID)) + .enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + linearProgress.setVisibility(View.GONE); + if (response.code() == 200 && response.body() != null) { + Log.d(TAG, "onResponse: boolean==>" + isFromCreateHold); + if (response.body() != null && response.body().size() > 0) { + if (isFromCreateHold) { + List orderList = new ArrayList<>(); + for (OrderListResp orderListResp : response.body()) { + if (orderListResp.status.equals("WD")) { + Log.d(TAG, "onResponse: status==>" + orderListResp.status); + orderList.add(orderListResp); + break; + } + } + if (orderList.size() > 0) { + manageOrderList(orderList, isFromCreateHold); + } else { + manageOrderList(response.body(), isFromCreateHold); + } + } else { + manageOrderList(response.body(), false); + } + } else { + blankOrderHistory(); + } + } else if (response.code() == 403) { + ((BuyingWizardBaseActivity) mContext).removeAllFragmentFromStack(); + navigateToLocationScreen(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + linearProgress.setVisibility(View.GONE); + Log.e(TAG, "onFailure: ", t); + showToast(mContext.getString(R.string.try_again)); + } + }); + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + /** + * Method for manage order list + * + * @param orderList + * @param isFromCreateHold + */ + private void manageOrderList(final List orderList, boolean isFromCreateHold) { + + if (orderList.size() > 0) { + for (OrderListResp orderListResp : orderList) { + if (orderListResp.status.equals("WD")) { + btn_buy_more.setVisibility(View.GONE); + break; + } else { + btn_buy_more.setVisibility(View.VISIBLE); + } + } + + int lastWDV = -1; + for (int i = 0; i < orderList.size(); i++) { + if (orderList.get(i).status.equals("WD")) { + if (i != 0) { + OrderListResp tempOrder = orderList.get(i); + orderList.remove(i); + orderList.add(0, tempOrder); + lastWDV = 0; + } else { + lastWDV = i; + } + + } + } + + OrderListResp orderListResp1 = new OrderListResp(); + orderListResp1.id = -1; + orderList.add(lastWDV + 1, orderListResp1); + + OrderListResp orderListResp = new OrderListResp(); + orderListResp.id = -2; + orderList.add(lastWDV + 2, orderListResp); + + if (orderList.size() - 2 == 1 && orderList.get(0).status != null && orderList.get(0).status.equals("WD")) { + isFromCreateHold = true; + } + + if (!isFromCreateHold) { + OrderListResp orderListResp2 = new OrderListResp(); + orderListResp2.id = -3; + orderList.add(lastWDV + 3, orderListResp2); + } + + + if (orderList.size() == 1 && orderList.get(0).status.equals("WD")) { + text_email_receipt.setVisibility(View.GONE); + } else { + + text_email_receipt.setVisibility(View.VISIBLE); + text_email_receipt.setText(Html.fromHtml(getString(R.string.text_send_email_receipt))); + + text_email_receipt.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts( + "mailto", WOCConstants.SUPPORT_EMAIL, null)); + emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{WOCConstants.SUPPORT_EMAIL}); + if (orderList.size() > 0) + emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Order #{" + orderList.get(0).id + "} - {" + + ((BuyingWizardBaseActivity) mContext).buyPivPref.getPhone() + "}."); + emailIntent.putExtra(Intent.EXTRA_TEXT, ""); + startActivity(Intent.createChooser(emailIntent, WOCConstants.SEND_EMAIL)); + } + }); + } + + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext); + rv_order_list.setLayoutManager(linearLayoutManager); + rv_order_list.setAdapter(new BuyingWizardOrderListAdapter(mContext, orderList, fragment, + ((BuyingWizardBaseActivity) mContext) + .buyPivPref)); + } else { + blankOrderHistory(); + } + } + + private void navigateToLocationScreen() { + ((BuyingWizardBaseActivity) mContext) + .replaceFragment(new BuyingWizardLocationFragment(), true, false); + } + + private void blankOrderHistory() { + layoutOrderHistory.setVisibility(View.VISIBLE); + text_no_order.setVisibility(View.VISIBLE); + btn_buy_more.setVisibility(View.VISIBLE); + layoutLogout.setVisibility(View.VISIBLE); + layoutInstruction.setVisibility(View.VISIBLE); + text_message.setText(mContext.getString(R.string.wallet_is_signed) + " " + + ((BuyingWizardBaseActivity) mContext).buyPivPref.getPhone()); + textHelpMessage.setText(R.string.call_for_help); + } + + /** + * hide show view + */ + public void changeView() { + if (isFromCreateHold) { + isFromCreateHold = false; + getOrderList(isFromCreateHold); + } else { + navigateToLocationScreen(); + } + } + + //runnable for count down timer + private static class MyRunnable implements Runnable { + WeakReference textDepositeDue1; + Handler handler; + String dueDateTime; + int countdownInterval; + + public MyRunnable(TextView tvText, Handler handler, String dueDateTime, int countdownInterval) { + this.textDepositeDue1 = new WeakReference<>(tvText); + this.handler = handler; + this.dueDateTime = dueDateTime; + this.countdownInterval = countdownInterval; + } + + @Override + public void run() { + //Save the TextView to a local variable because the weak referenced object could become empty at any time + TextView textDepositeDue = textDepositeDue1.get(); + handler.postDelayed(this, countdownInterval); + try { + //2018-03-21T19:03:51.900811+03:00 + SimpleDateFormat dateFormat = new SimpleDateFormat( + "yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZZ"); + /* SimpleDateFormat dateFormat = new SimpleDateFormat( + "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ");*/ +// + // Here Set your Event Date + //dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + //Date eventDate = dateFormat.parse(dueDateTime.replace("T", " ").substring(0, 19)); + Date eventDate = dateFormat.parse(dueDateTime); + Date currentDate = new Date(); + if (!currentDate.after(eventDate)) { + long diff = eventDate.getTime() + - currentDate.getTime(); + long hours = diff / (60 * 60 * 1000); + diff -= hours * (60 * 60 * 1000); + long minutes = diff / (60 * 1000); + diff -= minutes * (60 * 1000); + long seconds = diff / 1000; + + if (hours > 0) { + textDepositeDue.setText("Deposit Due: " + hours + " hours " + minutes + " minutes"); + countdownInterval = 60 * 1000; // call in minutes + } else { + if (minutes < 10) { + textDepositeDue.setTextColor(Color.parseColor("#DD0000")); + } else { + textDepositeDue.setTextColor(Color.parseColor("#000000")); + } + textDepositeDue.setText("Deposit Due: " + minutes + " minutes " + seconds + " seconds"); + countdownInterval = 1000; // call in seconds + } + } else { + textDepositeDue.setText("Deposit Due: 0 minutes 0 seconds"); + handler.removeMessages(0); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + + if (handler != null) { + handler.removeCallbacks(myRunnable); + myRunnable = null; + } + + } + + /** + * Count down timer for Hold Expire status + * + * @param dueDateTime + * @param textDepositeDue + */ + public void countDownStart(final String dueDateTime, final TextView textDepositeDue) { + Log.e(TAG, "countDownStart: " + dueDateTime); + countdownInterval = 1000; + + if (handler == null) { + handler = new Handler(); + myRunnable = new MyRunnable(textDepositeDue, handler, dueDateTime, countdownInterval); + handler.postDelayed(myRunnable, 0); + } + } + + /** + * Method for singout user + * + * @param isPendingHold + */ + public void deleteAuthCall(final boolean isPendingHold) { + if (NetworkUtil.isOnline(mContext)) { + final String phone = ((BuyingWizardBaseActivity) mContext).buyPivPref.getPhone(); + if (!TextUtils.isEmpty(phone)) { + linearProgress.setVisibility(View.VISIBLE); + //password = ""; + WallofCoins.createService(interceptor, mContext) + .deleteAuth(phone, getString(R.string.WALLOFCOINS_PUBLISHER_ID)) + .enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + Log.d(TAG, "onResponse: response code==>>" + response.code()); + linearProgress.setVisibility(View.GONE); + if (response.code() < 299) { + ((BuyingWizardBaseActivity) mContext).buyPivPref.setAuthToken(""); + // password = ""; + ((BuyingWizardBaseActivity) mContext).buyPivPref.clearAllPrefrance(); + if (isPendingHold) { + } else { + showToast(mContext.getString(R.string.alert_sign_out)); + navigateToLocationScreen(); + } + } else { + showToast(mContext.getString(R.string.try_again)); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + linearProgress.setVisibility(View.GONE); + showToast(mContext.getString(R.string.try_again)); + } + }); + } else { + showToast(mContext.getString(R.string.alert_phone)); + } + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + public void goToGivenUrl(String url) { + goToUrl(url); + } + + public void cancelHoldOrder(final OrderListResp orderListResp) { + AlertDialog.Builder builder; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + builder = new AlertDialog.Builder(mContext, android.R.style.Theme_Material_Dialog_Alert); + } else { + builder = new AlertDialog.Builder(mContext); + } + builder.setTitle(getString(R.string.deposit_cancel_confirmation_title)) + .setMessage(getString(R.string.deposit_cancel_confirmation_message)) + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + cancelOrder("" + orderListResp.id); + } + }) + .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }) + .show(); + } + + public void depositFinished(final OrderListResp orderListResp) { + hideKeyBoard(); + AlertDialog.Builder builder; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + builder = new AlertDialog.Builder(mContext, android.R.style.Theme_Material_Dialog_Alert); + } else { + builder = new AlertDialog.Builder(mContext); + } + builder.setTitle(getString(R.string.deposit_finish_confirmation_title)) + .setMessage(getString(R.string.deposit_finish_confirmation_message)) + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + CaptureHoldResp response = new CaptureHoldResp(); + response.id = orderListResp.id; + response.total = orderListResp.total; + response.payment = orderListResp.payment; + response.paymentDue = orderListResp.paymentDue; + response.bankName = orderListResp.bankName; + response.nameOnAccount = orderListResp.nameOnAccount; + response.account = orderListResp.account; + response.status = orderListResp.status; + CaptureHoldResp.NearestBranchBean nearestBranchBean = new CaptureHoldResp.NearestBranchBean(); + if (orderListResp.nearestBranch != null) { + nearestBranchBean.name = orderListResp.nearestBranch.name; + nearestBranchBean.city = orderListResp.nearestBranch.city; + nearestBranchBean.state = orderListResp.nearestBranch.state; + nearestBranchBean.phone = orderListResp.nearestBranch.phone; + nearestBranchBean.address = orderListResp.nearestBranch.address; + response.nearestBranch = nearestBranchBean; + } + response.bankUrl = orderListResp.account; + response.bankLogo = orderListResp.account; + response.bankIcon = orderListResp.account; + response.bankIconHq = orderListResp.account; + response.privateId = orderListResp.account; + confirmDeposit(response); + } + }) + .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }) + .show(); + } + + /** + * Method call for Cancel order with status code "WD" + * + * @param orderId + */ + private void cancelOrder(String orderId) { + if (NetworkUtil.isOnline(mContext)) { + linearProgress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, mContext).cancelOrder(orderId, getString(R.string.WALLOFCOINS_PUBLISHER_ID)).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + linearProgress.setVisibility(View.GONE); + if (response.code() == 204) { + showToast(mContext.getString(R.string.alert_cancel_order)); + navigateToLocationScreen(); + } else { + showToast(mContext.getString(R.string.try_again)); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + Log.e(TAG, "onFailure: ", t); + linearProgress.setVisibility(View.GONE); + showToast(mContext.getString(R.string.try_again)); + } + }); + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + /** + * Method call for confirm order deposit amount + * + * @param response + */ + private void confirmDeposit(CaptureHoldResp response) { + if (NetworkUtil.isOnline(mContext)) { + linearProgress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, getActivity()).confirmDeposit("" + response.id, "", getString(R.string.WALLOFCOINS_PUBLISHER_ID)).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + linearProgress.setVisibility(View.GONE); + + if (null != response && null != response.body()) { + showToast(mContext.getString(R.string.alert_payment_done)); + getOrderList(false); + } else if (null != response && null != response.errorBody()) { + try { + ErrorResp errorResp = new Gson().fromJson(response.errorBody().string(), ErrorResp.class); + Toast.makeText(getContext(), errorResp.detail, Toast.LENGTH_LONG).show(); + } catch (Exception e) { + e.printStackTrace(); + showToast(mContext.getString(R.string.try_again)); + } + + } else { + showToast(mContext.getString(R.string.try_again)); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + linearProgress.setVisibility(View.GONE); + Log.e(TAG, "onFailure: ", t); + showToast(mContext.getString(R.string.try_again)); + } + }); + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { + + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.btn_buy_more: + navigateToLocationScreen(); + break; + case R.id.btn_signout: + deleteAuthCall(false); + break; + case R.id.btn_WebLink: + goToGivenUrl(WOCConstants.KEY_WEB_URL); + break; + } + } + + //this method remove animation when user want to clear back stack + @Override + public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { + if (BuyingWizardFragmentUtils.sDisableFragmentAnimations) { + Animation a = new Animation() { + }; + a.setDuration(0); + return a; + } + return super.onCreateAnimation(transit, enter, nextAnim); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/payment_center/BuyingWizardPaymentCenterFragment.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/payment_center/BuyingWizardPaymentCenterFragment.java new file mode 100644 index 000000000..0414d097b --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/payment_center/BuyingWizardPaymentCenterFragment.java @@ -0,0 +1,189 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.payment_center; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.widget.AppCompatSpinner; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.LinearLayout; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.wallofcoins.WOCConstants; +import pivx.org.pivxwallet.wallofcoins.api.WallofCoins; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseActivity; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.offer_amount.BuyingWizardOfferAmountFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.utils.BuyingWizardFragmentUtils; +import pivx.org.pivxwallet.wallofcoins.response.GetReceivingOptionsResp; +import pivx.org.pivxwallet.wallofcoins.utils.NetworkUtil; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + + +/** + * Created on 07-Mar-18. + */ + +public class BuyingWizardPaymentCenterFragment extends BuyingWizardBaseFragment implements View.OnClickListener { + + private View rootView; + private LinearLayout linear_progress; + private final String TAG = "PaymentCenterFragment"; + private AppCompatSpinner sp_banks; + private String bankId; + private Button button_bank_next; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + mContext = context; + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + if (rootView == null) { + rootView = inflater.inflate(R.layout.fragment_buying_payment_center, container, false); + init(); + setListeners(); + getReceivingOptions(); + return rootView; + } else + return rootView; + } + + private void init() { + linear_progress = (LinearLayout) rootView.findViewById(R.id.linear_progress); + sp_banks = (AppCompatSpinner) rootView.findViewById(R.id.sp_banks); + button_bank_next = (Button) rootView.findViewById(R.id.button_bank_next); + } + + private void setListeners() { + button_bank_next.setOnClickListener(this); + } + + /** + * API call for get all receiving options by country code + */ + private void getReceivingOptions() { + if (NetworkUtil.isOnline(mContext)) { + String locale; + locale = getResources().getConfiguration().locale.getCountry(); + linear_progress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, getActivity()).getReceivingOptions() + .enqueue(new Callback>() { + + @Override + public void onResponse(Call> call, + Response> response) { + + if (response.body() != null) { + Log.e(TAG, "onResponse: " + response.body().size()); + linear_progress.setVisibility(View.GONE); + setPaymentOptNames(response.body()); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + linear_progress.setVisibility(View.GONE); + showToast(mContext.getString(R.string.try_again)); + t.printStackTrace(); + } + }); + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + /** + * Set Payment option name for Payment options + * + * @param receivingOptionsResps + */ + private void setPaymentOptNames(final List receivingOptionsResps) { + final ArrayList names = new ArrayList<>(); + GetReceivingOptionsResp optionsRespDefaultName = new GetReceivingOptionsResp(); + Collections.sort(receivingOptionsResps, new ContactComparator()); + + optionsRespDefaultName.name = getString(R.string.label_select_payment_center); + receivingOptionsResps.add(0, optionsRespDefaultName); + + for (GetReceivingOptionsResp receivingOptionsResp : receivingOptionsResps) { + names.add((receivingOptionsResp.name)); + } + ArrayAdapter adapter = new ArrayAdapter<>(mContext, android.R.layout.simple_spinner_dropdown_item, names); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + sp_banks.setAdapter(adapter); + + sp_banks.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + if (position == 0) return; + bankId = "" + receivingOptionsResps.get(position).id; + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + + } + + private class ContactComparator implements Comparator { + public int compare(GetReceivingOptionsResp optionsResp1, GetReceivingOptionsResp optionsResp2) { + //In the following line you set the criterion, + //which is the name of Contact in my example scenario + return optionsResp1.name.compareTo(optionsResp2.name); + } + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + + case R.id.button_bank_next: + if (sp_banks.getSelectedItemPosition() == 0) + showToast(mContext.getString(R.string.alert_select_any_payment_center)); + else + navigateToOtherScreen(); + break; + + } + } + + private void navigateToOtherScreen() { + Bundle bundle = new Bundle(); + bundle.putString(WOCConstants.BANK_ID, bankId); + BuyingWizardOfferAmountFragment offerAmountFragment = new BuyingWizardOfferAmountFragment(); + offerAmountFragment.setArguments(bundle); + + ((BuyingWizardBaseActivity) mContext).replaceFragment(offerAmountFragment, true, true); + } + + //this method remove animation when user want to clear back stack + @Override + public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { + if (BuyingWizardFragmentUtils.sDisableFragmentAnimations) { + Animation a = new Animation() { + }; + a.setDuration(0); + return a; + } + return super.onCreateAnimation(transit, enter, nextAnim); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/phone_list/BuyingWizardPhoneListFragment.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/phone_list/BuyingWizardPhoneListFragment.java new file mode 100644 index 000000000..491d3bebe --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/phone_list/BuyingWizardPhoneListFragment.java @@ -0,0 +1,154 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.phone_list; + +import android.content.Context; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.annotation.Nullable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.wallofcoins.WOCConstants; +import pivx.org.pivxwallet.wallofcoins.api.WallofCoins; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseActivity; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.adapters.BuyingWizardPhoneListAdapter; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.email_phone.BuyingWizardEmailPhoneFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.models.BuyingWizardPhoneListVO; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.utils.BuyingWizardPhoneListPref; +import pivx.org.pivxwallet.wallofcoins.response.GetAuthTokenResp; +import pivx.org.pivxwallet.wallofcoins.utils.NetworkUtil; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +/** + * Created on 19-Mar-18. + */ + +public class BuyingWizardPhoneListFragment extends BuyingWizardBaseFragment implements View.OnClickListener { + + private final String TAG = "OrderHistoryFragment"; + private View rootView; + private RecyclerView recyclerViewPhoneList; + private Button btnSignUp, btnExistingSignIn; + private BuyingWizardPhoneListFragment fragment; + private TextView txtViewNoData; + + + @Override + public void onAttach(Context context) { + super.onAttach(context); + mContext = context; + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + rootView = inflater.inflate(R.layout.fragment_buying_phone_list, container, false); + init(); + setListeners(); + setPhoneList(); + return rootView; + } + + private void init() { + fragment = this; + recyclerViewPhoneList = (RecyclerView) rootView.findViewById(R.id.recyclerViewPhoneList); + btnSignUp = (Button) rootView.findViewById(R.id.btnSignUp); + btnExistingSignIn = (Button) rootView.findViewById(R.id.btnExistingSignIn); + txtViewNoData = (TextView) rootView.findViewById(R.id.txtViewNoData); + recyclerViewPhoneList.setLayoutManager(new LinearLayoutManager(mContext)); + } + + private void setListeners() { + btnExistingSignIn.setOnClickListener(this); + btnSignUp.setOnClickListener(this); + } + + private void setPhoneList() { + BuyingWizardPhoneListPref credentialsPref = + new BuyingWizardPhoneListPref(PreferenceManager.getDefaultSharedPreferences(mContext)); + + ArrayList buyingWizardPhoneListVOS = credentialsPref.getStoredPhoneList(); + + HashSet hashSet = new HashSet<>(); + hashSet.addAll(buyingWizardPhoneListVOS); + buyingWizardPhoneListVOS.clear(); + buyingWizardPhoneListVOS.addAll(hashSet); + + if (buyingWizardPhoneListVOS != null & buyingWizardPhoneListVOS.size() > 0) { + recyclerViewPhoneList.setAdapter(new BuyingWizardPhoneListAdapter(mContext, + credentialsPref.getStoredPhoneList(), fragment)); + txtViewNoData.setVisibility(View.GONE); + } else + txtViewNoData.setVisibility(View.VISIBLE); + + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.btnExistingSignIn: + Bundle bundle = new Bundle(); + bundle.putString(WOCConstants.SCREEN_TYPE, "PhoneListFragment"); + BuyingWizardEmailPhoneFragment phoneFragment = new BuyingWizardEmailPhoneFragment(); + phoneFragment.setArguments(bundle); + + ((BuyingWizardBaseActivity) mContext).replaceFragment(phoneFragment, true, true); + break; + case R.id.btnSignUp: + goToUrl(WOCConstants.KEY_SIGN_UP_URL); + break; + } + } + + /** + * Authorized user using phone + * + * @param deviceId + */ + public void getAuthTokenCall(final String phone, String deviceId) { + if (NetworkUtil.isOnline(mContext)) { + + HashMap getAuthTokenReq = new HashMap<>(); + getAuthTokenReq.put(WOCConstants.KEY_DEVICEID, deviceId); + getAuthTokenReq.put(WOCConstants.KEY_PUBLISHER_ID, getString(R.string.WALLOFCOINS_PUBLISHER_ID)); + getAuthTokenReq.put(WOCConstants.KEY_DEVICECODE, getDeviceCode(mContext, + ((BuyingWizardBaseActivity) mContext).buyPivPref)); + + WallofCoins.createService(interceptor, getActivity()).getAuthToken(phone, getAuthTokenReq).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + int code = response.code(); + + if (code == 200) { + if (!TextUtils.isEmpty(response.body().token)) { + ((BuyingWizardBaseActivity) mContext).buyPivPref.setAuthToken(response.body().token); + ((BuyingWizardBaseActivity) mContext).buyPivPref.setPhone(phone); + ((BuyingWizardBaseActivity) mContext).buyPivPref.setDeviceId(response.body().deviceId); + ((BuyingWizardBaseActivity) mContext).popBackDirect(); + } + } + } + + @Override + public void onFailure(Call call, Throwable t) { + showToast(mContext.getString(R.string.try_again)); + } + }); + + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/utils/BuyingWizardAddressPref.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/utils/BuyingWizardAddressPref.java new file mode 100644 index 000000000..5814febaa --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/utils/BuyingWizardAddressPref.java @@ -0,0 +1,32 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.utils; + +import android.content.SharedPreferences; + +/** + * Created by on 13-Mar-18. + */ + +public class BuyingWizardAddressPref { + private final SharedPreferences prefs; + private static final String BUY_PIV_ADDRESS = "addres"; + + public BuyingWizardAddressPref(final SharedPreferences prefs) { + this.prefs = prefs; + } + + public void setBuyPivAddress(String address) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putString(BUY_PIV_ADDRESS, address); + editor.commit(); + } + + public String getBuyPivAddress() { + return prefs.getString(BUY_PIV_ADDRESS, ""); + } + + public void clearBuyPivAddress() { + SharedPreferences.Editor editor = prefs.edit(); + editor.clear(); + editor.commit(); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/utils/BuyingWizardFragmentUtils.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/utils/BuyingWizardFragmentUtils.java new file mode 100644 index 000000000..64704f939 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/utils/BuyingWizardFragmentUtils.java @@ -0,0 +1,9 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.utils; + +/** + * Created on 09-Mar-18. + */ + +public class BuyingWizardFragmentUtils { + public static boolean sDisableFragmentAnimations = false; +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/utils/BuyingWizardObjectSerializer.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/utils/BuyingWizardObjectSerializer.java new file mode 100644 index 000000000..1d5a2ef2d --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/utils/BuyingWizardObjectSerializer.java @@ -0,0 +1,52 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.utils; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** + * Created on 12-Mar-18. + */ + +public class BuyingWizardObjectSerializer { + public static String serialize(Serializable obj) throws IOException { + if (obj == null) return ""; + ByteArrayOutputStream serialObj = new ByteArrayOutputStream(); + ObjectOutputStream objStream = new ObjectOutputStream(serialObj); + objStream.writeObject(obj); + objStream.close(); + return encodeBytes(serialObj.toByteArray()); + } + + public static Object deserialize(String str) throws IOException, ClassNotFoundException { + if (str == null || str.length() == 0) return null; + ByteArrayInputStream serialObj = new ByteArrayInputStream(decodeBytes(str)); + ObjectInputStream objStream = new ObjectInputStream(serialObj); + return objStream.readObject(); + } + + public static String encodeBytes(byte[] bytes) { + StringBuffer strBuf = new StringBuffer(); + + for (int i = 0; i < bytes.length; i++) { + strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a'))); + strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a'))); + } + + return strBuf.toString(); + } + + public static byte[] decodeBytes(String str) { + byte[] bytes = new byte[str.length() / 2]; + for (int i = 0; i < str.length(); i += 2) { + char c = str.charAt(i); + bytes[i / 2] = (byte) ((c - 'a') << 4); + c = str.charAt(i + 1); + bytes[i / 2] += (c - 'a'); + } + return bytes; + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/utils/BuyingWizardPhoneListPref.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/utils/BuyingWizardPhoneListPref.java new file mode 100644 index 000000000..8493e5cd9 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/utils/BuyingWizardPhoneListPref.java @@ -0,0 +1,87 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.utils; + +import android.content.SharedPreferences; +import android.util.Log; + +import java.util.ArrayList; + +import pivx.org.pivxwallet.wallofcoins.buying_wizard.models.BuyingWizardPhoneListVO; + + +/** + * Created on 12-Mar-18. + */ + +public class BuyingWizardPhoneListPref { + + private final SharedPreferences prefs; + private static final String CREDENTIALS_LIST = "credentials_list"; + + public BuyingWizardPhoneListPref(final SharedPreferences prefs) { + this.prefs = prefs; + } + + + public void addPhone(String phone, String deviceId) { + ArrayList voArrayList; + + try { + voArrayList = (ArrayList) BuyingWizardObjectSerializer + .deserialize(prefs.getString(CREDENTIALS_LIST, + BuyingWizardObjectSerializer.serialize(new ArrayList()))); + BuyingWizardPhoneListVO createHoldResp = new BuyingWizardPhoneListVO(); + createHoldResp.setDeviceId(deviceId); + createHoldResp.setPhoneNumber(phone); + + voArrayList.add(createHoldResp); + + + SharedPreferences.Editor editor = prefs.edit(); + editor.putString(CREDENTIALS_LIST, BuyingWizardObjectSerializer.serialize(voArrayList)); + + editor.commit(); + + for (BuyingWizardPhoneListVO vo : voArrayList) { + Log.e("Auth id list", vo.getDeviceId()); + Log.e("phone no list", vo.getPhoneNumber()); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public ArrayList getStoredPhoneList() { + ArrayList voArrayList = new ArrayList<>(); + + try { + voArrayList = (ArrayList) BuyingWizardObjectSerializer.deserialize(prefs.getString(CREDENTIALS_LIST, + BuyingWizardObjectSerializer.serialize(new ArrayList()))); + } catch (Exception e) { + e.printStackTrace(); + } + return voArrayList; + } + + public String getDeviceIdFromPhone(String phone) { + String deviceId = ""; + ArrayList voArrayList; + + try { + voArrayList = (ArrayList) BuyingWizardObjectSerializer + .deserialize(prefs.getString(CREDENTIALS_LIST, + BuyingWizardObjectSerializer.serialize(new ArrayList()))); + + for (BuyingWizardPhoneListVO vo : voArrayList) { + Log.e("Stored phone",vo.getPhoneNumber()+"---"+"Stored deviceId"+vo.getDeviceId()); + if (vo.getPhoneNumber().equalsIgnoreCase(phone)) { + deviceId = vo.getDeviceId(); + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return deviceId; + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/verification_otp/BuyingWizardVerifycationOtpFragment.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/verification_otp/BuyingWizardVerifycationOtpFragment.java new file mode 100644 index 000000000..2ab0c60f3 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/verification_otp/BuyingWizardVerifycationOtpFragment.java @@ -0,0 +1,227 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.verification_otp; + +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.annotation.Nullable; +import android.support.v7.app.AlertDialog; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.Toast; + +import com.google.gson.Gson; + +import java.util.HashMap; +import java.util.List; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.wallofcoins.WOCConstants; +import pivx.org.pivxwallet.wallofcoins.api.WallofCoins; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseActivity; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.location.BuyingWizardLocationFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.order_history.BuyingWizardOrderHistoryFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.utils.BuyingWizardAddressPref; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.utils.BuyingWizardFragmentUtils; +import pivx.org.pivxwallet.wallofcoins.response.CaptureHoldResp; +import pivx.org.pivxwallet.wallofcoins.response.ErrorResp; +import pivx.org.pivxwallet.wallofcoins.utils.NetworkUtil; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +/** + * Created on 08-Mar-18. + */ + +public class BuyingWizardVerifycationOtpFragment extends BuyingWizardBaseFragment implements + View.OnClickListener, SharedPreferences.OnSharedPreferenceChangeListener { + + + private View rootView; + private Button button_verify_otp; + private EditText et_otp; + private LinearLayout linearProgress; + private final String TAG = "VerifycationOtpFragment"; + private String otp = "", keyAddress = ""; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + mContext = context; + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + if (rootView == null) { + rootView = inflater.inflate(R.layout.fragment_buying_verification_otp, container, false); + init(); + setListeners(); + readBundle(getArguments()); + return rootView; + } else + return rootView; + } + + private void init() { + + BuyingWizardAddressPref addressPref = + new BuyingWizardAddressPref(PreferenceManager.getDefaultSharedPreferences(mContext)); + keyAddress = addressPref.getBuyPivAddress(); + linearProgress = (LinearLayout) rootView.findViewById(R.id.linear_progress); + button_verify_otp = (Button) rootView.findViewById(R.id.button_verify_otp); + et_otp = (EditText) rootView.findViewById(R.id.et_otp); + } + + private void setListeners() { + button_verify_otp.setOnClickListener(this); + } + + //Read data from bundle + private void readBundle(Bundle bundle) { + if (bundle != null) + otp = bundle.getString(WOCConstants.VERIFICATION_OTP); + + et_otp.setText(otp); + } + + @Override + public void onClick(View view) { + + switch (view.getId()) { + case R.id.button_verify_otp: + verifyOTP(); + break; + } + } + + + /** + * API call for call for Capture Hold @POST("api/v1/holds/{id}/capture/") + */ + private void verifyOTP() { + + if (NetworkUtil.isOnline(mContext)) { + hideKeyBoard(); + HashMap captureHoldReq = new HashMap<>(); + String otp = et_otp.getText().toString().trim(); + + if (TextUtils.isEmpty(otp)) { + showToast(mContext.getString(R.string.alert_purchase_code)); + return; + } + + captureHoldReq.put(WOCConstants.KEY_PUBLISHER_ID, getString(R.string.WALLOFCOINS_PUBLISHER_ID)); + captureHoldReq.put(WOCConstants.KEY_VERIFICATION_CODE, otp); + linearProgress.setVisibility(View.VISIBLE); + WallofCoins.createService(interceptor, getActivity()).captureHold(( + (BuyingWizardBaseActivity) mContext).buyPivPref.getHoldId(), captureHoldReq) + .enqueue(new Callback>() { + @Override + public void onResponse(Call> call, final Response> response) { + linearProgress.setVisibility(View.GONE); + ((BuyingWizardBaseActivity) mContext).buyPivPref.setHoldId(""); + ((BuyingWizardBaseActivity) mContext).buyPivPref.setCreateHoldResp(null); + Log.e(TAG, "onResponse: " + ((BuyingWizardBaseActivity) mContext) + .buyPivPref.getHoldId() + " here"); + if (null != response && null != response.body() && !response.body().isEmpty()) { + if (response.body().get(0).account != null && !TextUtils.isEmpty(response.body().get(0).account)) { + updateAddressBookValue(keyAddress, "WallofCoins.com - Order " + + response.body().get(0).id); + navigateToOrderList(true); + } else { + navigateToOrderList(true); + } + } else if (null != response && null != response.errorBody()) { + linearProgress.setVisibility(View.GONE); + + if (response.code() == 404) { + AlertDialog.Builder builder; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + builder = new AlertDialog.Builder(mContext, android.R.style.Theme_Material_Dialog_Alert); + } else { + builder = new AlertDialog.Builder(mContext); + } + builder.setTitle(getString(R.string.alert_title_purchase_code)) + .setMessage(getString(R.string.alert_description_purchase_code)) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + navigateToLocation(); + + } + }) + .show(); + } else { + try { + ErrorResp errorResp = new Gson().fromJson(response.errorBody().string(), ErrorResp.class); + Toast.makeText(getContext(), errorResp.detail, Toast.LENGTH_LONG).show(); + } catch (Exception e) { + e.printStackTrace(); + showToast(mContext.getString(R.string.try_again)); + } + } + } else { + showToast(mContext.getString(R.string.try_again)); + linearProgress.setVisibility(View.GONE); + } + } + + @Override + public void onFailure + (Call> call, Throwable t) { + linearProgress.setVisibility(View.GONE); + showToast(mContext.getString(R.string.try_again)); + Log.e(TAG, "onFailure: ", t); + } + }); + } else + showToast(mContext.getString(R.string.network_not_avaialable)); + + } + + /** + * create hold screen + * + * @param + */ + private void navigateToLocation() { + BuyingWizardLocationFragment locationFragment = new BuyingWizardLocationFragment(); + ((BuyingWizardBaseActivity) mContext).replaceFragment(locationFragment, true, true); + } + + private void navigateToOrderList(boolean isFromCreateHold) { + BuyingWizardOrderHistoryFragment historyFragment = new BuyingWizardOrderHistoryFragment(); + Bundle bundle = new Bundle(); + bundle.putBoolean("isFromCreateHold", isFromCreateHold); + historyFragment.setArguments(bundle); + ((BuyingWizardBaseActivity) mContext).replaceFragment(historyFragment, true, true); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { + + } + + //this method remove animation when user want to clear back stack + @Override + public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { + if (BuyingWizardFragmentUtils.sDisableFragmentAnimations) { + Animation a = new Animation() { + }; + a.setDuration(0); + return a; + } + return super.onCreateAnimation(transit, enter, nextAnim); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/zip/BuyingWizardZipFragment.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/zip/BuyingWizardZipFragment.java new file mode 100644 index 000000000..b17619a8d --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/buying_wizard/zip/BuyingWizardZipFragment.java @@ -0,0 +1,112 @@ +package pivx.org.pivxwallet.wallofcoins.buying_wizard.zip; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.widget.Button; +import android.widget.EditText; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.wallofcoins.WOCConstants; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseActivity; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.BuyingWizardBaseFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.offer_amount.BuyingWizardOfferAmountFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.payment_center.BuyingWizardPaymentCenterFragment; +import pivx.org.pivxwallet.wallofcoins.buying_wizard.utils.BuyingWizardFragmentUtils; + + +/** + * Created on 6/3/18. + */ + +public class BuyingWizardZipFragment extends BuyingWizardBaseFragment implements View.OnClickListener { + + private View rootView; + private Button button_zip_next; + private String zipCode; + private EditText edit_zip; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + mContext = context; + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + if (rootView == null) { + rootView = inflater.inflate(R.layout.fragment_buying_zip, container, false); + init(); + setListeners(); + return rootView; + } else + return rootView; + } + + private void init() { + + button_zip_next = (Button) rootView.findViewById(R.id.button_zip_next); + edit_zip = (EditText) rootView.findViewById(R.id.edit_zip); + } + + private void setListeners() { + button_zip_next.setOnClickListener(this); + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.button_zip_next: + zipCode = edit_zip.getText().toString().trim(); + if (TextUtils.isEmpty(zipCode)) { // open bank list screen + navigateToBankListScreen(); + } else { + if (isValidZip()) + navigateToOtherScreen1(); + } + break; + } + } + + private boolean isValidZip() { + if (edit_zip.getText().toString().trim().length() < 5 || edit_zip.getText().toString().trim().length() > 6) { + edit_zip.requestFocus(); + showToast(getString(R.string.invalid_zip_code)); + return false; + } + return true; + } + + private void navigateToOtherScreen1() { + Bundle bundle = new Bundle(); + bundle.putString(WOCConstants.ZIP, zipCode); + BuyingWizardOfferAmountFragment offerAmountFragment = new BuyingWizardOfferAmountFragment(); + offerAmountFragment.setArguments(bundle); + + ((BuyingWizardBaseActivity) mContext).replaceFragment(offerAmountFragment, true, true); + } + + //if zip code is empty user navigate to all bank list screen + private void navigateToBankListScreen() { + BuyingWizardPaymentCenterFragment centerFragment = new BuyingWizardPaymentCenterFragment(); + ((BuyingWizardBaseActivity) mContext).replaceFragment(centerFragment, true, true); + } + + //this method remove animation when user want to clear back stack + @Override + public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { + if (BuyingWizardFragmentUtils.sDisableFragmentAnimations) { + Animation a = new Animation() { + }; + a.setDuration(0); + return a; + } + return super.onCreateAnimation(transit, enter, nextAnim); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CaptureHoldResp.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CaptureHoldResp.java new file mode 100644 index 000000000..2b540647d --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CaptureHoldResp.java @@ -0,0 +1,52 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +public class CaptureHoldResp { + + /** + * id : 70 + * total : 51.87391467 + * payment : 504.0000000193 + * paymentDue : 2017-08-09T14:42:46.565Z + * bankName : MoneyGram + * nameOnAccount : + * account : [{"displaySort": 2.0, "name": "birthCountry", "value": "US", "label": "Country of Birth"}, {"displaySort": 0.5, "name": "pickupState", "value": "Florida", "label": "Pick-up State"}, {"displaySort": 1.0, "name": "lastName", "value": "Genito", "label": "Last Name"}, {"displaySort": 0.0, "name": "firstName", "value": "Robert", "label": "First Name"}] + * status : WD + * nearestBranch : {"city":"","state":"","name":"MoneyGram","phone":null,"address":""} + * bankUrl : https://secure.moneygram.com + * bankLogo : /media/logos/logo_us_MoneyGram.png + * bankIcon : /media/logos/icon_us_MoneyGram.png + * bankIconHq : /media/logos/icon_us_MoneyGram%402x.png + * privateId : 8eca9b5b05b92925ba31cf4e1682d790871acd93 + */ + + public int id; + public String total; + public String payment; + public String paymentDue; + public String bankName; + public String nameOnAccount; + public String account; + public String status; + public NearestBranchBean nearestBranch; + public String bankUrl; + public String bankLogo; + public String bankIcon; + public String bankIconHq; + public String privateId; + + public static class NearestBranchBean { + /** + * city : + * state : + * name : MoneyGram + * phone : null + * address : + */ + + public String city; + public String state; + public String name; + public String phone; + public String address; + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CheckAuthResp.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CheckAuthResp.java new file mode 100644 index 000000000..fb278250b --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CheckAuthResp.java @@ -0,0 +1,34 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +import java.util.List; + +/** + * Created on 04-Sep-17. + */ + +public class CheckAuthResp { + + /** + * phone : 17439995953 + * availableAuthSources : ["deviceCode"] + */ + + private String phone; + private List availableAuthSources; + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public List getAvailableAuthSources() { + return availableAuthSources; + } + + public void setAvailableAuthSources(List availableAuthSources) { + this.availableAuthSources = availableAuthSources; + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/ConfirmDepositResp.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/ConfirmDepositResp.java new file mode 100644 index 000000000..140f432ea --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/ConfirmDepositResp.java @@ -0,0 +1,204 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +public class ConfirmDepositResp { + + /** + * id : 85243 + * total : 9.62314870 + * payment : 3344.4500006610 + * paymentDue : 2017-09-04T16:04:21.290Z + * bankName : Bank of America + * nameOnAccount : Gerald Verzosa + * account : 7475844139 + * status : WD + * nearestBranch : {"city":"Sarasota","state":"FL","name":"Bank of America","phone":"(941) 952-2868","address":"1605 Main St, #501"} + * bankUrl : http://bankofamerica.com + * bankLogo : https://wallofcoins-static.s3.amazonaws.com/logos/logo_11.png + * bankIcon : https://wallofcoins-static.s3.amazonaws.com/logos/icon_11.png + * bankIconHq : https://wallofcoins-static.s3.amazonaws.com/logos/icon_11%402x.png + * privateId : 05dbf8a622641ce60cb7b26543e7a9908209034d + */ + + private int id; + private String total; + private String payment; + private String paymentDue; + private String bankName; + private String nameOnAccount; + private String account; + private String status; + private NearestBranchBean nearestBranch; + private String bankUrl; + private String bankLogo; + private String bankIcon; + private String bankIconHq; + private String privateId; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getTotal() { + return total; + } + + public void setTotal(String total) { + this.total = total; + } + + public String getPayment() { + return payment; + } + + public void setPayment(String payment) { + this.payment = payment; + } + + public String getPaymentDue() { + return paymentDue; + } + + public void setPaymentDue(String paymentDue) { + this.paymentDue = paymentDue; + } + + public String getBankName() { + return bankName; + } + + public void setBankName(String bankName) { + this.bankName = bankName; + } + + public String getNameOnAccount() { + return nameOnAccount; + } + + public void setNameOnAccount(String nameOnAccount) { + this.nameOnAccount = nameOnAccount; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public NearestBranchBean getNearestBranch() { + return nearestBranch; + } + + public void setNearestBranch(NearestBranchBean nearestBranch) { + this.nearestBranch = nearestBranch; + } + + public String getBankUrl() { + return bankUrl; + } + + public void setBankUrl(String bankUrl) { + this.bankUrl = bankUrl; + } + + public String getBankLogo() { + return bankLogo; + } + + public void setBankLogo(String bankLogo) { + this.bankLogo = bankLogo; + } + + public String getBankIcon() { + return bankIcon; + } + + public void setBankIcon(String bankIcon) { + this.bankIcon = bankIcon; + } + + public String getBankIconHq() { + return bankIconHq; + } + + public void setBankIconHq(String bankIconHq) { + this.bankIconHq = bankIconHq; + } + + public String getPrivateId() { + return privateId; + } + + public void setPrivateId(String privateId) { + this.privateId = privateId; + } + + public static class NearestBranchBean { + /** + * city : Sarasota + * state : FL + * name : Bank of America + * phone : (941) 952-2868 + * address : 1605 Main St, #501 + */ + + private String city; + private String state; + private String name; + private String phone; + private String address; + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CountryData.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CountryData.java new file mode 100644 index 000000000..958156d6d --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CountryData.java @@ -0,0 +1,33 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class CountryData { + + + public List countries; + + public static class CountriesBean { + /** + * name : United States + * code : +1 + * currency : USD + * short : us + */ + + public String name; + public String code; + public String currency; + @SerializedName("short") + public String shortX; + public int top; + public int left; + + @Override + public String toString() { + return name + " (" + code + ")"; + } + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CreateDeviceResp.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CreateDeviceResp.java new file mode 100644 index 000000000..ea8dc3ae9 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CreateDeviceResp.java @@ -0,0 +1,38 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +public class CreateDeviceResp { + + /** + * id : 4 + * name : New iPhone + * createdOn : 2015-01-20T17:13:34.154Z + */ + + private int id; + private String name; + private String createdOn; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(String createdOn) { + this.createdOn = createdOn; + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CreateHoldResp.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CreateHoldResp.java new file mode 100644 index 000000000..938b73bb5 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/CreateHoldResp.java @@ -0,0 +1,38 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +import java.util.List; + +public class CreateHoldResp { + + + /** + * id : 5e179adf417275ef3e138d73f1fa39aa + * expirationTime : 2017-08-08T17:23:01.440Z + * discoveryInput : 5cb0c411f83f7c2fdb5a4af909bdb690 + * holds : [{"amount":"53.23435843","currentPrice":"9.43","status":""}] + * token : ZGV2aWNlOjM5NjoxNTAyMjIzNjAxfGIzNWZmOGYxOTlmYjRkNTM2YTdkZWNmZjJmNjY0MzNjN2M2NWZhOWQ= + * tokenExpiresAt : 2017-08-08T20:20:01.399Z + * __PURCHASE_CODE : AARXX + */ + + public String id; + public String expirationTime; + public String discoveryInput; + public String token; + public String tokenExpiresAt; + public String deviceId; + public String __PURCHASE_CODE; + public List holds; + + public static class HoldsBean { + /** + * amount : 53.23435843 + * currentPrice : 9.43 + * status : + */ + + public String amount; + public String currentPrice; + public String status; + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/DiscoveryInputsResp.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/DiscoveryInputsResp.java new file mode 100644 index 000000000..6ccb3566d --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/DiscoveryInputsResp.java @@ -0,0 +1,45 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +public class DiscoveryInputsResp { + + + /** + * id : 2948e301f2dbc2cd52c7284e2ebbd6bd + * usdAmount : 500 + * cryptoAmount : 0 + * crypto : PIVX + * fiat : USD + * zipCode : 34236 + * bank : null + * state : null + * cryptoAddress : null + * createdIp : 127.0.0.1 + * location : {"latitude":27.3331293,"longitude":-82.5456374} + * browserLocation : null + * publisher : null + */ + + public String id; + public String usdAmount; + public String cryptoAmount; + public String crypto; + public String fiat; + public String zipCode; + public String bank; + public String state; + public String cryptoAddress; + public String createdIp; + public LocationBean location; + //public String browserLocation; + public String publisher; + + public static class LocationBean { + /** + * latitude : 27.3331293 + * longitude : -82.5456374 + */ + + public double latitude; + public double longitude; + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/ErrorResp.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/ErrorResp.java new file mode 100644 index 000000000..7ed9d3e5c --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/ErrorResp.java @@ -0,0 +1,10 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +public class ErrorResp { + + /** + * detail : Not found + */ + + public String detail; +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetAuthTokenResp.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetAuthTokenResp.java new file mode 100644 index 000000000..ff8b948ef --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetAuthTokenResp.java @@ -0,0 +1,23 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +public class GetAuthTokenResp { + + /** + * createdOn : 2017-07-10T16:04:24.887Z + * tokenExpiresAt : 2017-07-10T20:14:55.642Z + * accessedOn : 2017-07-10T17:14:55.646Z + * phone : 19418555706 + * token : YXV0aDoxNzM6MTQ5OTcxNzY5NXwzZDljNDkxZDgwNmVjZDUzYTNmM2NjNzFiMTI0ZWE2ZGIzMTRlMjJk + * authSource : deviceCode + * email : demo@gmail.com + */ + + public String createdOn; + public String tokenExpiresAt; + public String accessedOn; + public String phone; + public String token; + public String authSource; + public String email; + public String deviceId; +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetCurrencyResp.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetCurrencyResp.java new file mode 100644 index 000000000..fee3c54bb --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetCurrencyResp.java @@ -0,0 +1,16 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +public class GetCurrencyResp { + + public String code; + public String name; + public String symbol; + + @Override + public String toString() { +// return name + " (" + symbol + ")"; + return symbol; + } + + +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetHoldsResp.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetHoldsResp.java new file mode 100644 index 000000000..32613a571 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetHoldsResp.java @@ -0,0 +1,19 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +public class GetHoldsResp { + + /** + * [ + { + "id": "ec11665efc6eeb8e8ca083360c70a659", + "expirationTime": "2018-02-16T06:38:14.408227Z", + "discoveryInput": "8f4a39a2ca29607da6d8c891e8318b26" + } + ] + */ + + public String id; + public String expirationTime; + public String discoveryInput; + public String status; +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetOffersResp.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetOffersResp.java new file mode 100644 index 000000000..b97ca75b7 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetOffersResp.java @@ -0,0 +1,184 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.List; +import java.util.Locale; + +public class GetOffersResp { + + /** + * singleDeposit : [{"id":"eyJ1c2QiOiAiNTAxLjAwIiwgImVhIjogdHJ1ZSwgImFkIjogMTAsICJkaSI6ICIyOTQ4ZTMwMWYyZGJjMmNkNTJjNzI4NGUyZWJiZDZiZCJ9fHxTaW5nbGVEZXBvc2l0T2ZmZXJ8fDA3ZGQzOGVhY2NlYTlhYmRiY2E1ZDNlM2Q2OWY4Mjky","deposit":{"currency":"USD","amount":"501.00"},"crypto":"PIVX","amount":{"PIVX":"51.562","dots":"51,562,544.25","bits":"51,562,544.25","BTC":"51.562"},"discoveryId":"2948e301f2dbc2cd52c7284e2ebbd6bd","distance":0,"address":"","state":"","bankName":"MoneyGram","bankLogo":"/media/logos/logo_us_MoneyGram.png","bankLogoHq":"/media/logos/logo_us_MoneyGram%402x.png","bankIcon":"/media/logos/icon_us_MoneyGram.png","bankIconHq":"/media/logos/icon_us_MoneyGram%402x.png","bankLocationUrl":"https://secure.moneygram.com/locations","city":""},{"id":"eyJ1c2QiOiAiNTAyLjAwIiwgImVhIjogdHJ1ZSwgImFkIjogMTEsICJkaSI6ICIyOTQ4ZTMwMWYyZGJjMmNkNTJjNzI4NGUyZWJiZDZiZCJ9fHxTaW5nbGVEZXBvc2l0T2ZmZXJ8fGU1N2JlOWUxZTFmNTZmY2VjYzBiMjkyYzI0ZjdjM2Zj","deposit":{"currency":"USD","amount":"502.00"},"crypto":"PIVX","amount":{"PIVX":"32.480","dots":"32,480,900.05","bits":"32,480,900.05","BTC":"32.480"},"discoveryId":"2948e301f2dbc2cd52c7284e2ebbd6bd","distance":0.9639473391774286,"address":"240 N Washington Blvd, #100","state":"FL","bankName":"Chase","bankLogo":"/media/logos/logo_us_Chase.png","bankLogoHq":"/media/logos/logo_us_Chase%402x.png","bankIcon":"/media/logos/icon_us_Chase.png","bankIconHq":"/media/logos/icon_us_Chase%402x.png","bankLocationUrl":null,"city":"Sarasota"},{"id":"eyJ1c2QiOiAiNTAwLjAwIiwgImVhIjogdHJ1ZSwgImFkIjogMzgsICJkaSI6ICIyOTQ4ZTMwMWYyZGJjMmNkNTJjNzI4NGUyZWJiZDZiZCJ9fHxTaW5nbGVEZXBvc2l0T2ZmZXJ8fDMwMzViOTI0ODliNTI2ZmI1MWU5NWJhZWE5YmM5NGRl","deposit":{"currency":"USD","amount":"500.00"},"crypto":"PIVX","amount":{"PIVX":"5.508","dots":"5,508,014.94","bits":"5,508,014.94","BTC":"5.508"},"discoveryId":"2948e301f2dbc2cd52c7284e2ebbd6bd","distance":0.495030456581863,"address":"1605 Main St, #501","state":"FL","bankName":"Bank of America","bankLogo":"/media/logos/logo_us_Bank%20of%20America.png","bankLogoHq":"/media/logos/logo_us_Bank%20of%20America%402x.png","bankIcon":"/media/logos/icon_us_Bank%20of%20America.png","bankIconHq":"/media/logos/icon_us_Bank%20of%20America%402x.png","bankLocationUrl":null,"city":"Sarasota"}] + * doubleDeposit : [{"id":"eyJkaSI6ICIyOTQ4ZTMwMWYyZGJjMmNkNTJjNzI4NGUyZWJiZDZiZCIsICJhZDIiOiAzMywgImFkMSI6IDQxfXx8RG91YmxlRGVwb3NpdE9mZmVyfHxlOGU2NzBmMTM2MmE5ZjQ5MGQzZGE0ZWI3MjIxNWE4MA==","firstOffer":{"deposit":{"currency":"USD","amount":"490.00"},"crypto":"PIVX","amount":{"PIVX":"47.547","dots":"47,547,115.08","bits":"47,547,115.08","BTC":"47.547"},"discoveryId":"2948e301f2dbc2cd52c7284e2ebbd6bd","distance":0.9639473391774286,"address":"240 N Washington Blvd, #100","state":"FL","bankName":"Chase","bankLogo":"/media/logos/logo_us_Chase.png","bankLogoHq":"/media/logos/logo_us_Chase%402x.png","bankIcon":"/media/logos/icon_us_Chase.png","bankIconHq":"/media/logos/icon_us_Chase%402x.png","bankLocationUrl":null,"city":"Sarasota"},"secondOffer":{"deposit":{"currency":"USD","amount":"10.00"},"crypto":"PIVX","amount":{"PIVX":"0.088","dots":"88,491.58","bits":"88,491.58","BTC":"0.088"},"discoveryId":"2948e301f2dbc2cd52c7284e2ebbd6bd","distance":0.9639473391774286,"address":"240 N Washington Blvd, #100","state":"FL","bankName":"Chase","bankLogo":"/media/logos/logo_us_Chase.png","bankLogoHq":"/media/logos/logo_us_Chase%402x.png","bankIcon":"/media/logos/icon_us_Chase.png","bankIconHq":"/media/logos/icon_us_Chase%402x.png","bankLocationUrl":null,"city":"Sarasota"},"totalAmount":{"bits":"47,635,606.67","BTC":"47.635"},"totalDeposit":{"currency":"USD","amount":"500.00"}}] + * multipleBanks : [] + * isExtendedSearch : false + * incremented : true + */ + + public boolean isExtendedSearch; + public boolean incremented; + public List singleDeposit; + public List doubleDeposit; + public List multipleBanks; + + public static class SingleDepositBean { + /** + * id : eyJ1c2QiOiAiNTAxLjAwIiwgImVhIjogdHJ1ZSwgImFkIjogMTAsICJkaSI6ICIyOTQ4ZTMwMWYyZGJjMmNkNTJjNzI4NGUyZWJiZDZiZCJ9fHxTaW5nbGVEZXBvc2l0T2ZmZXJ8fDA3ZGQzOGVhY2NlYTlhYmRiY2E1ZDNlM2Q2OWY4Mjky + * deposit : {"currency":"USD","amount":"501.00"} + * crypto : PIVX + * amount : {"PIVX":"51.562","dots":"51,562,544.25","bits":"51,562,544.25","BTC":"51.562"} + * discoveryId : 2948e301f2dbc2cd52c7284e2ebbd6bd + * distance : 0 + * address : + * state : + * bankName : MoneyGram + * bankLogo : /media/logos/logo_us_MoneyGram.png + * bankLogoHq : /media/logos/logo_us_MoneyGram%402x.png + * bankIcon : /media/logos/icon_us_MoneyGram.png + * bankIconHq : /media/logos/icon_us_MoneyGram%402x.png + * bankLocationUrl : https://secure.moneygram.com/locations + * city : + */ + + public String id; + public DepositBean deposit; + public String crypto; + public AmountBean amount; + public String discoveryId; + public double distance; + public String address; + public String state; + public String bankName; + public String bankLogo; + public String bankLogoHq; + public String bankIcon; + public String bankIconHq; + public String bankLocationUrl; + public String city; + + + } + + public static class DoubleDepositBean { + /** + * id : eyJkaSI6ICIyOTQ4ZTMwMWYyZGJjMmNkNTJjNzI4NGUyZWJiZDZiZCIsICJhZDIiOiAzMywgImFkMSI6IDQxfXx8RG91YmxlRGVwb3NpdE9mZmVyfHxlOGU2NzBmMTM2MmE5ZjQ5MGQzZGE0ZWI3MjIxNWE4MA== + * firstOffer : {"deposit":{"currency":"USD","amount":"490.00"},"crypto":"PIVX","amount":{"PIVX":"47.547","dots":"47,547,115.08","bits":"47,547,115.08","BTC":"47.547"},"discoveryId":"2948e301f2dbc2cd52c7284e2ebbd6bd","distance":0.9639473391774286,"address":"240 N Washington Blvd, #100","state":"FL","bankName":"Chase","bankLogo":"/media/logos/logo_us_Chase.png","bankLogoHq":"/media/logos/logo_us_Chase%402x.png","bankIcon":"/media/logos/icon_us_Chase.png","bankIconHq":"/media/logos/icon_us_Chase%402x.png","bankLocationUrl":null,"city":"Sarasota"} + * secondOffer : {"deposit":{"currency":"USD","amount":"10.00"},"crypto":"PIVX","amount":{"PIVX":"0.088","dots":"88,491.58","bits":"88,491.58","BTC":"0.088"},"discoveryId":"2948e301f2dbc2cd52c7284e2ebbd6bd","distance":0.9639473391774286,"address":"240 N Washington Blvd, #100","state":"FL","bankName":"Chase","bankLogo":"/media/logos/logo_us_Chase.png","bankLogoHq":"/media/logos/logo_us_Chase%402x.png","bankIcon":"/media/logos/icon_us_Chase.png","bankIconHq":"/media/logos/icon_us_Chase%402x.png","bankLocationUrl":null,"city":"Sarasota"} + * totalAmount : {"bits":"47,635,606.67","BTC":"47.635"} + * totalDeposit : {"currency":"USD","amount":"500.00"} + */ + + public String id; + public FirstOfferBean firstOffer; + public SecondOfferBean secondOffer; + public AmountBean totalAmount; + public DepositBean totalDeposit; + + public static class FirstOfferBean { + /** + * deposit : {"currency":"USD","amount":"490.00"} + * crypto : PIVX + * amount : {"PIVX":"47.547","dots":"47,547,115.08","bits":"47,547,115.08","BTC":"47.547"} + * discoveryId : 2948e301f2dbc2cd52c7284e2ebbd6bd + * distance : 0.9639473391774286 + * address : 240 N Washington Blvd, #100 + * state : FL + * bankName : Chase + * bankLogo : /media/logos/logo_us_Chase.png + * bankLogoHq : /media/logos/logo_us_Chase%402x.png + * bankIcon : /media/logos/icon_us_Chase.png + * bankIconHq : /media/logos/icon_us_Chase%402x.png + * bankLocationUrl : null + * city : Sarasota + */ + + public DepositBean deposit; + public String crypto; + public AmountBean amount; + public String discoveryId; + public double distance; + public String address; + public String state; + public String bankName; + public String bankLogo; + public String bankLogoHq; + public String bankIcon; + public String bankIconHq; + public String bankLocationUrl; + public String city; + } + + public static class SecondOfferBean { + /** + * deposit : {"currency":"USD","amount":"10.00"} + * crypto : PIVX + * amount : {"PIVX":"0.088","dots":"88,491.58","bits":"88,491.58","BTC":"0.088"} + * discoveryId : 2948e301f2dbc2cd52c7284e2ebbd6bd + * distance : 0.9639473391774286 + * address : 240 N Washington Blvd, #100 + * state : FL + * bankName : Chase + * bankLogo : /media/logos/logo_us_Chase.png + * bankLogoHq : /media/logos/logo_us_Chase%402x.png + * bankIcon : /media/logos/icon_us_Chase.png + * bankIconHq : /media/logos/icon_us_Chase%402x.png + * bankLocationUrl : null + * city : Sarasota + */ + + public DepositBean deposit; + public String crypto; + public AmountBean amount; + public String discoveryId; + public double distance; + public String address; + public String state; + public String bankName; + public String bankLogo; + public String bankLogoHq; + public String bankIcon; + public String bankIconHq; + public String bankLocationUrl; + public String city; + } + + public String sumAmounts(String... args) { + + double amount = 0; + + for (String s : args) { + try { + if (s != null) + amount += NumberFormat.getNumberInstance(Locale.getDefault()).parse(s.replaceAll(",","")).doubleValue(); + } catch (ParseException e) { + e.printStackTrace(); + } + } + return NumberFormat.getNumberInstance(Locale.getDefault()).format(amount); + } + } + + public static class DepositBean { + /** + * currency : USD + * amount : 501.00 + */ + + public String currency; + public String amount; + } + + public static class AmountBean { + /** + * dots : 51,562,544.25 + * bits : 51,562,544.25 + * BTC : 51.562 + */ + + public String dots; + public String bits; + public String BTC; + public String uPiv; + public String PIVX; + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetReceivingOptionsResp.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetReceivingOptionsResp.java new file mode 100644 index 000000000..2f7035ea1 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/GetReceivingOptionsResp.java @@ -0,0 +1,110 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class GetReceivingOptionsResp { + + /** + * id : 19 + * name : Axis Bank + * url : https://www.axisbank.com/ + * logo : https://woc.reference.genitrust.com/static/logos/logo_in_Axis%20Bank.png + * logoHq : https://woc.reference.genitrust.com/static/logos/logo_in_Axis%20Bank%402x.png + * icon : https://woc.reference.genitrust.com/static/logos/icon_in_Axis%20Bank.png + * iconHq : https://woc.reference.genitrust.com/static/logos/icon_in_Axis%20Bank%402x.png + * country : in + * payFields : {"payFields":[{"name":"birthCountry","label":"Country of Birth","parse":"","displaySort":2,"paymentDestination_id":17,"id":7},{"name":"pickupState","label":"Pick-up State","parse":"","displaySort":0.5,"paymentDestination_id":17,"id":6},{"name":"lastName","label":"Last Name","parse":"","displaySort":1,"paymentDestination_id":17,"id":5},{"name":"firstName","label":"First Name","parse":"","displaySort":0,"paymentDestination_id":17,"id":4}],"confirmFields":[{"name":"receiveCode","label":"Receive Code (Confirm)","parse":"","displaySort":0,"paymentDestination_id":17,"id":3}],"trigger":"Check here if this is a biller account (Business)","dynamicFields":[{"name":"accountNumber","label":"Customer Account #","parse":"","displaySort":2,"paymentDestination_id":17,"id":4},{"name":"receiveCode","label":"Receive Code","parse":"","displaySort":1.5,"paymentDestination_id":17,"id":3},{"name":"businessCity","label":"Business City/State","parse":"","displaySort":1,"paymentDestination_id":17,"id":2},{"name":"businessName","label":"Business Name","parse":"","displaySort":0,"paymentDestination_id":17,"id":1}]} + */ + + public int id; + public String name; + public String url; + public String logo; + public String logoHq; + public String icon; + public String iconHq; + public String country; + public PayFieldsBeanX payFields; + + + public static class PayFieldsBeanX { + /** + * payFields : [{"name":"birthCountry","label":"Country of Birth","parse":"","displaySort":2,"paymentDestination_id":17,"id":7},{"name":"pickupState","label":"Pick-up State","parse":"","displaySort":0.5,"paymentDestination_id":17,"id":6},{"name":"lastName","label":"Last Name","parse":"","displaySort":1,"paymentDestination_id":17,"id":5},{"name":"firstName","label":"First Name","parse":"","displaySort":0,"paymentDestination_id":17,"id":4}] + * confirmFields : [{"name":"receiveCode","label":"Receive Code (Confirm)","parse":"","displaySort":0,"paymentDestination_id":17,"id":3}] + * trigger : Check here if this is a biller account (Business) + * dynamicFields : [{"name":"accountNumber","label":"Customer Account #","parse":"","displaySort":2,"paymentDestination_id":17,"id":4},{"name":"receiveCode","label":"Receive Code","parse":"","displaySort":1.5,"paymentDestination_id":17,"id":3},{"name":"businessCity","label":"Business City/State","parse":"","displaySort":1,"paymentDestination_id":17,"id":2},{"name":"businessName","label":"Business Name","parse":"","displaySort":0,"paymentDestination_id":17,"id":1}] + */ + + + public String trigger; + @SerializedName("payFields") + public List payFieldsX; + public List confirmFields; + public List dynamicFields; + public Boolean payFieldsB; + + public static class PayFieldsBean { + /** + * name : birthCountry + * label : Country of Birth + * parse : + * displaySort : 2 + * paymentDestination_id : 17 + * id : 7 + */ + + @SerializedName("name") + public String nameX; + public String label; + public String parse; + public float displaySort; + public int paymentDestination_id; + @SerializedName("id") + public int idX; + + + @Override + public String toString() { + return "PayFieldsBean{" + + "nameX='" + nameX + '\'' + + ", label='" + label + '\'' + + ", parse='" + parse + '\'' + + ", displaySort=" + displaySort + + ", paymentDestination_id=" + paymentDestination_id + + ", idX=" + idX + + '}'; + } + } + + @Override + public String toString() { + return "PayFieldsBeanX{" + + "trigger='" + trigger + '\'' + + ", payFieldsX=" + payFieldsX + + ", confirmFields=" + confirmFields + + ", dynamicFields=" + dynamicFields + + '}'; + } + } + + public class JsonPayFieldsBeanX extends PayFieldsBeanX { + } + + + @Override + public String toString() { + return "GetReceivingOptionsResp{" + + "id=" + id + + ", name='" + name + '\'' + + ", url='" + url + '\'' + + ", logo='" + logo + '\'' + + ", logoHq='" + logoHq + '\'' + + ", icon='" + icon + '\'' + + ", iconHq='" + iconHq + '\'' + + ", country='" + country + '\'' + + ", payFields=" + payFields + + '}'; + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/OrderListResp.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/OrderListResp.java new file mode 100644 index 000000000..7491be99f --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/OrderListResp.java @@ -0,0 +1,56 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +/** + * Created on 05-Sep-17. + */ + +public class OrderListResp { + + /** + * id : 85337 + * total : 0.02747620 + * payment : 10.00 + * paymentDue : 2017-09-05T09:31:23.474Z + * bankName : Fifth Third + * nameOnAccount : Todd A Rogers + * account : 7914882944 + * status : WD + * nearestBranch : {"city":"Sarasota","state":"FL","name":"Fifth Third","phone":"(941) 365-6568","address":"50 Central Ave"} + * bankUrl : http://www.53.com + * bankLogo : https://wallofcoins-static.s3.amazonaws.com/logos/logo_18.png + * bankIcon : https://wallofcoins-static.s3.amazonaws.com/logos/icon_18.png + * bankIconHq : https://wallofcoins-static.s3.amazonaws.com/logos/icon_18%402x.png + * privateId : df5a5c438ffea5c36e899858cc33b828e4485a67 + */ + + public int id; + public String total; + public String payment; + public String paymentDue; + public String bankName; + public String nameOnAccount; + public String account; + public String status; + public NearestBranchBean nearestBranch; + public String bankUrl; + public String bankLogo; + public String bankIcon; + public String bankIconHq; + public String privateId; + + public static class NearestBranchBean { + /** + * city : Sarasota + * state : FL + * name : Fifth Third + * phone : (941) 365-6568 + * address : 50 Central Ave + */ + + public String city; + public String state; + public String name; + public String phone; + public String address; + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/PayFieldsDeserializer.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/PayFieldsDeserializer.java new file mode 100644 index 000000000..325ff4a9d --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/response/PayFieldsDeserializer.java @@ -0,0 +1,26 @@ +package pivx.org.pivxwallet.wallofcoins.response; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; + +import java.lang.reflect.Type; + + + +public class PayFieldsDeserializer implements JsonDeserializer { + + private static final String TAG = PayFieldsDeserializer.class.getSimpleName(); + + @Override + public GetReceivingOptionsResp.PayFieldsBeanX deserialize(JsonElement jsonElement, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + if (jsonElement.isJsonPrimitive()) { + GetReceivingOptionsResp.PayFieldsBeanX payFieldsBeanX = new GetReceivingOptionsResp.PayFieldsBeanX(); + payFieldsBeanX.payFieldsB = jsonElement.getAsBoolean(); + return payFieldsBeanX; + } + + return context.deserialize(jsonElement, GetReceivingOptionsResp.JsonPayFieldsBeanX.class); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/CurrencyAmountView.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/CurrencyAmountView.java new file mode 100644 index 000000000..c43e6731e --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/CurrencyAmountView.java @@ -0,0 +1,364 @@ +/* + * Copyright 2011-2015 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package pivx.org.pivxwallet.wallofcoins.ui; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.Parcelable; +import android.text.Editable; +import android.text.InputType; +import android.text.Spannable; +import android.text.TextWatcher; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.TextView; + + +import org.pivxj.core.Coin; +import org.pivxj.core.Monetary; +import org.pivxj.utils.MonetaryFormat; + +import javax.annotation.Nullable; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.wallofcoins.utils.Constants; +import pivx.org.pivxwallet.wallofcoins.utils.GenericUtils; +import pivx.org.pivxwallet.wallofcoins.utils.MonetarySpannable; + + +/** + * @author Andreas Schildbach + */ +public final class CurrencyAmountView extends FrameLayout { + public static interface Listener { + void changed(); + + void focusChanged(final boolean hasFocus); + } + + private int significantColor, lessSignificantColor, errorColor; + private Drawable deleteButtonDrawable, contextButtonDrawable; + private Drawable currencySymbolDrawable; + private String localCurrencyCode = null; + private MonetaryFormat inputFormat; + private Monetary hint = null; + private MonetaryFormat hintFormat = new MonetaryFormat().noCode(); + private boolean amountSigned = false; + private boolean validateAmount = true; + + private TextView textView; + private View contextButton; + private Listener listener; + private OnClickListener contextButtonClickListener; + + public CurrencyAmountView(final Context context) { + super(context); + init(context); + } + + public CurrencyAmountView(final Context context, final AttributeSet attrs) { + super(context, attrs); + init(context); + } + + private void init(final Context context) { + final Resources resources = context.getResources(); + significantColor = resources.getColor(R.color.fg_significant); + lessSignificantColor = resources.getColor(R.color.fg_less_significant); + errorColor = resources.getColor(R.color.fg_error); + deleteButtonDrawable = resources.getDrawable(R.drawable.ic_clear_grey600_24dp); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + final Context context = getContext(); + + textView = (TextView) getChildAt(0); + textView.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL); + textView.setHintTextColor(lessSignificantColor); + textView.setHorizontalFadingEdgeEnabled(true); + textView.setSingleLine(); + setValidateAmount(textView instanceof EditText); + textView.addTextChangedListener(textViewListener); + textView.setOnFocusChangeListener(textViewListener); + + contextButton = new View(context) { + @Override + protected void onMeasure(final int wMeasureSpec, final int hMeasureSpec) { + setMeasuredDimension(textView.getCompoundPaddingRight(), textView.getMeasuredHeight()); + } + }; + final LayoutParams chooseViewParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT); + chooseViewParams.gravity = Gravity.RIGHT; + contextButton.setLayoutParams(chooseViewParams); + this.addView(contextButton); + + updateAppearance(); + } + + public void setCurrencySymbol(@Nullable final String currencyCode) { + if (MonetaryFormat.CODE_BTC.equals(currencyCode)) { + currencySymbolDrawable = getResources().getDrawable(R.drawable.currency_symbol_btc); + localCurrencyCode = null; + } else if (MonetaryFormat.CODE_MBTC.equals(currencyCode)) { + currencySymbolDrawable = getResources().getDrawable(R.drawable.currency_symbol_mbtc); + localCurrencyCode = null; + } else if (MonetaryFormat.CODE_UBTC.equals(currencyCode)) { + currencySymbolDrawable = getResources().getDrawable(R.drawable.currency_symbol_ubtc); + localCurrencyCode = null; + } else if (currencyCode != null) // fiat + { + final String currencySymbol = GenericUtils.currencySymbol(currencyCode); + final float textSize = textView.getTextSize(); + final float smallerTextSize = textSize * (20f / 24f); + currencySymbolDrawable = new CurrencySymbolDrawable(currencySymbol, smallerTextSize, lessSignificantColor, + textSize * 0.37f); + localCurrencyCode = currencyCode; + } else { + currencySymbolDrawable = null; + localCurrencyCode = null; + } + + updateAppearance(); + } + + public void setInputFormat(final MonetaryFormat inputFormat) { + this.inputFormat = inputFormat.noCode(); + } + + public void setHintFormat(final MonetaryFormat hintFormat) { + this.hintFormat = hintFormat.noCode(); + updateAppearance(); + } + + public void setHint(@Nullable final Monetary hint) { + this.hint = hint; + updateAppearance(); + } + + public void setAmountSigned(final boolean amountSigned) { + this.amountSigned = amountSigned; + } + + public void setValidateAmount(final boolean validateAmount) { + this.validateAmount = validateAmount; + } + + public void setContextButton(final int contextButtonResId, final OnClickListener contextButtonClickListener) { + this.contextButtonDrawable = getContext().getResources().getDrawable(contextButtonResId); + this.contextButtonClickListener = contextButtonClickListener; + + updateAppearance(); + } + + public void setListener(final Listener listener) { + this.listener = listener; + } + + @Nullable + public Monetary getAmount() { + if (!isValidAmount(false)) + return null; + + final String amountStr = textView.getText().toString().trim(); + if (localCurrencyCode == null) + return inputFormat.parse(amountStr); + else + return inputFormat.parseFiat(localCurrencyCode, amountStr); + } + + public void setAmount(@Nullable final Monetary amount, final boolean fireListener) { + if (!fireListener) + textViewListener.setFire(false); + + if (amount != null) + textView.setText(new MonetarySpannable(inputFormat, amountSigned, amount)); + else + textView.setText(null); + + if (!fireListener) + textViewListener.setFire(true); + } + + @Override + public void setEnabled(final boolean enabled) { + super.setEnabled(enabled); + + textView.setEnabled(enabled); + + updateAppearance(); + } + + public void setTextColor(final int color) { + significantColor = color; + + updateAppearance(); + } + + public void setStrikeThru(final boolean strikeThru) { + if (strikeThru) + textView.setPaintFlags(textView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + else + textView.setPaintFlags(textView.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG); + } + + public TextView getTextView() { + return textView; + } + + public void setNextFocusId(final int nextFocusId) { + textView.setNextFocusDownId(nextFocusId); + textView.setNextFocusForwardId(nextFocusId); + } + + private boolean isValidAmount(final boolean zeroIsValid) { + final String str = textView.getText().toString().trim(); + + try { + if (!str.isEmpty()) { + final Monetary amount; + if (localCurrencyCode == null) { + amount = inputFormat.parse(str); + if (((Coin) amount).isGreaterThan(Constants.NETWORK_PARAMETERS.getMaxMoney())) + return false; + } else { + amount = inputFormat.parseFiat(localCurrencyCode, str); + } + + // exactly zero + return zeroIsValid || amount.signum() > 0; + } + } catch (final Exception x) { + } + + return false; + } + + private final OnClickListener deleteClickListener = new OnClickListener() { + @Override + public void onClick(final View v) { + setAmount(null, true); + textView.requestFocus(); + } + }; + + private void updateAppearance() { + final boolean enabled = textView.isEnabled(); + + contextButton.setEnabled(enabled); + + final String amount = textView.getText().toString().trim(); + + if (enabled && !amount.isEmpty()) { + textView.setCompoundDrawablesWithIntrinsicBounds(currencySymbolDrawable, null, deleteButtonDrawable, null); + contextButton.setOnClickListener(deleteClickListener); + } else if (enabled && contextButtonDrawable != null) { + textView.setCompoundDrawablesWithIntrinsicBounds(currencySymbolDrawable, null, contextButtonDrawable, null); + contextButton.setOnClickListener(contextButtonClickListener); + } else { + textView.setCompoundDrawablesWithIntrinsicBounds(currencySymbolDrawable, null, null, null); + contextButton.setOnClickListener(null); + } + + contextButton.requestLayout(); + + textView.setTextColor(!validateAmount || isValidAmount(true) ? significantColor : errorColor); + + final Spannable hintSpannable = new MonetarySpannable(hintFormat, hint != null ? hint : Coin.ZERO) + .applyMarkup(null, MonetarySpannable.STANDARD_INSIGNIFICANT_SPANS); + textView.setHint(hintSpannable); + } + + @Override + protected Parcelable onSaveInstanceState() { + final Bundle state = new Bundle(); + state.putParcelable("super_state", super.onSaveInstanceState()); + state.putParcelable("child_textview", textView.onSaveInstanceState()); + state.putSerializable("amount", getAmount()); + return state; + } + + @Override + protected void onRestoreInstanceState(final Parcelable state) { + if (state instanceof Bundle) { + final Bundle bundle = (Bundle) state; + super.onRestoreInstanceState(bundle.getParcelable("super_state")); + textView.onRestoreInstanceState(bundle.getParcelable("child_textview")); + setAmount((Monetary) bundle.getSerializable("amount"), false); + } else { + super.onRestoreInstanceState(state); + } + } + + private final TextViewListener textViewListener = new TextViewListener(); + + private final class TextViewListener implements TextWatcher, OnFocusChangeListener { + private boolean fire = true; + + public void setFire(final boolean fire) { + this.fire = fire; + } + + @Override + public void afterTextChanged(final Editable s) { + // workaround for German keyboards + final String original = s.toString(); + final String replaced = original.replace(',', '.'); + if (!replaced.equals(original)) { + s.clear(); + s.append(replaced); + } + + MonetarySpannable.applyMarkup(s, null, MonetarySpannable.STANDARD_SIGNIFICANT_SPANS, + MonetarySpannable.STANDARD_INSIGNIFICANT_SPANS); + } + + @Override + public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) { + } + + @Override + public void onTextChanged(final CharSequence s, final int start, final int before, final int count) { + updateAppearance(); + if (listener != null && fire) + listener.changed(); + } + + @Override + public void onFocusChange(final View v, final boolean hasFocus) { + if (!hasFocus) { + final Monetary amount = getAmount(); + if (amount != null) + setAmount(amount, false); + } + + if (listener != null && fire) + listener.focusChanged(hasFocus); + } + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/CurrencySymbolDrawable.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/CurrencySymbolDrawable.java new file mode 100644 index 000000000..e2574ccb7 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/CurrencySymbolDrawable.java @@ -0,0 +1,67 @@ +/* + * Copyright 2011-2015 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package pivx.org.pivxwallet.wallofcoins.ui; + +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; + +import pivx.org.pivxwallet.wallofcoins.utils.Constants; + + +/** + * @author Andreas Schildbach + */ +public final class CurrencySymbolDrawable extends Drawable { + private final Paint paint = new Paint(); + private final String symbol; + private final float y; + + public CurrencySymbolDrawable(final String symbol, final float textSize, final int color, final float y) { + paint.setColor(color); + paint.setAntiAlias(true); + paint.setTextSize(textSize); + + this.symbol = symbol + Constants.CHAR_HAIR_SPACE; + this.y = y; + } + + @Override + public void draw(final Canvas canvas) { + canvas.drawText(symbol, 0, y, paint); + } + + @Override + public int getIntrinsicWidth() { + return (int) paint.measureText(symbol); + } + + @Override + public int getOpacity() { + return 0; + } + + @Override + public void setAlpha(final int alpha) { + } + + @Override + public void setColorFilter(final ColorFilter cf) { + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/CurrencyTextView.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/CurrencyTextView.java new file mode 100644 index 000000000..6ed613d3d --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/CurrencyTextView.java @@ -0,0 +1,120 @@ +/* + * Copyright 2013-2015 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package pivx.org.pivxwallet.wallofcoins.ui; + +import android.content.Context; +import android.graphics.Paint; +import android.support.v7.widget.AppCompatTextView; +import android.text.style.ForegroundColorSpan; +import android.text.style.RelativeSizeSpan; +import android.text.style.ScaleXSpan; +import android.util.AttributeSet; + + +import org.pivxj.core.Monetary; +import org.pivxj.utils.MonetaryFormat; + +import pivx.org.pivxwallet.R; +import pivx.org.pivxwallet.wallofcoins.utils.Constants; +import pivx.org.pivxwallet.wallofcoins.utils.MonetarySpannable; + +/** + * @author Andreas Schildbach + */ +public class CurrencyTextView extends AppCompatTextView { + private Monetary amount = null; + private MonetaryFormat format = null; + private boolean alwaysSigned = false; + private RelativeSizeSpan prefixRelativeSizeSpan = null; + private ScaleXSpan prefixScaleXSpan = null; + private ForegroundColorSpan prefixColorSpan = null; + private RelativeSizeSpan insignificantRelativeSizeSpan = null; + + public CurrencyTextView(final Context context) { + super(context); + } + + public CurrencyTextView(final Context context, final AttributeSet attrs) { + super(context, attrs); + } + + public void setAmount(final Monetary amount) { + this.amount = amount; + updateView(); + } + + public void setFormat(final MonetaryFormat format) { + this.format = format.codeSeparator(Constants.CHAR_HAIR_SPACE); + updateView(); + } + + public void setAlwaysSigned(final boolean alwaysSigned) { + this.alwaysSigned = alwaysSigned; + updateView(); + } + + public void setStrikeThru(final boolean strikeThru) { + if (strikeThru) + setPaintFlags(getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); + else + setPaintFlags(getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG); + } + + public void setInsignificantRelativeSize(final float insignificantRelativeSize) { + if (insignificantRelativeSize != 1) { + this.prefixRelativeSizeSpan = new RelativeSizeSpan(insignificantRelativeSize); + this.insignificantRelativeSizeSpan = new RelativeSizeSpan(insignificantRelativeSize); + } else { + this.prefixRelativeSizeSpan = null; + this.insignificantRelativeSizeSpan = null; + } + } + + public void setPrefixColor(final int prefixColor) { + this.prefixColorSpan = new ForegroundColorSpan(prefixColor); + updateView(); + } + + public void setPrefixScaleX(final float prefixScaleX) { + this.prefixScaleXSpan = new ScaleXSpan(prefixScaleX); + updateView(); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + setPrefixColor(getResources().getColor(R.color.fg_less_significant)); + setPrefixScaleX(1); + setInsignificantRelativeSize(0.85f); + setSingleLine(); + } + + private void updateView() { + final MonetarySpannable text; + + if (amount != null) + text = new MonetarySpannable(format, alwaysSigned, amount).applyMarkup( + new Object[]{prefixRelativeSizeSpan, prefixScaleXSpan, prefixColorSpan}, + new Object[]{insignificantRelativeSizeSpan}); + else + text = null; + + setText(text); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/DividerItemDecoration.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/DividerItemDecoration.java new file mode 100644 index 000000000..b477963e6 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/DividerItemDecoration.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * 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 pivx.org.pivxwallet.wallofcoins.ui; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; + +public class DividerItemDecoration extends RecyclerView.ItemDecoration { + private static final int[] ATTRS = new int[] { android.R.attr.listDivider }; + + public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; + public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; + + private final Drawable mDivider; + private int mOrientation; + + public DividerItemDecoration(final Context context, final int orientation) { + final TypedArray a = context.obtainStyledAttributes(ATTRS); + mDivider = a.getDrawable(0); + a.recycle(); + setOrientation(orientation); + } + + public void setOrientation(final int orientation) { + if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) + throw new IllegalArgumentException("invalid orientation"); + + mOrientation = orientation; + } + + @Override + public void onDraw(final Canvas c, final RecyclerView parent) { + if (mOrientation == VERTICAL_LIST) + drawVertical(c, parent); + else + drawHorizontal(c, parent); + } + + public void drawVertical(final Canvas c, final RecyclerView parent) { + final int left = parent.getPaddingLeft(); + final int right = parent.getWidth() - parent.getPaddingRight(); + final int childCount = parent.getChildCount(); + + for (int i = 0; i < childCount; i++) { + final View child = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); + final int top = child.getBottom() + params.bottomMargin + Math.round(child.getTranslationY()); + final int bottom = top + mDivider.getIntrinsicHeight(); + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(c); + } + } + + public void drawHorizontal(final Canvas c, final RecyclerView parent) { + final int top = parent.getPaddingTop(); + final int bottom = parent.getHeight() - parent.getPaddingBottom(); + final int childCount = parent.getChildCount(); + + for (int i = 0; i < childCount; i++) { + final View child = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); + final int left = child.getRight() + params.rightMargin + Math.round(child.getTranslationX()); + final int right = left + mDivider.getIntrinsicHeight(); + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(c); + } + } + + @Override + public void getItemOffsets(final Rect outRect, final int itemPosition, final RecyclerView parent) { + if (mOrientation == VERTICAL_LIST) + outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); + else + outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/ToolbarCurrencyTextView.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/ToolbarCurrencyTextView.java new file mode 100644 index 000000000..2fa218420 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/ui/ToolbarCurrencyTextView.java @@ -0,0 +1,76 @@ +/* + * Copyright 2013-2015 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package pivx.org.pivxwallet.wallofcoins.ui; + +import android.content.Context; +import android.support.v4.content.ContextCompat; +import android.util.AttributeSet; + +import pivx.org.pivxwallet.R; + + +public class ToolbarCurrencyTextView extends CurrencyTextView +{ + + public ToolbarCurrencyTextView(final Context context) + { + super(context); + } + + public ToolbarCurrencyTextView(final Context context, final AttributeSet attrs) + { + super(context, attrs); + } + + @Override + protected void onFinishInflate() + { + super.onFinishInflate(); + + setPrefixColor(ContextCompat.getColor(getContext(), R.color.white)); + } + + /*@Override + protected void setTextFormat(CharSequence text) + { + if (text == null) + { + setText(null); + } + else + { + String textStr = text.toString(); + if (textStr.contains(MonetaryFormat.CODE_UBTC)) + { + textStr = textStr.replace(MonetaryFormat.CODE_UBTC, ""); + setCompoundDrawablesWithIntrinsicBounds(R.drawable.balance_prefix_micro, 0, 0, 0); + } + else if (textStr.contains(MonetaryFormat.CODE_MBTC)) + { + textStr = textStr.replace(MonetaryFormat.CODE_MBTC, ""); + setCompoundDrawablesWithIntrinsicBounds(R.drawable.balance_prefix_milli, 0, 0, 0); + } + else if (textStr.contains(MonetaryFormat.CODE_BTC)) + { + textStr = textStr.replace(MonetaryFormat.CODE_BTC, ""); + setCompoundDrawablesWithIntrinsicBounds(R.drawable.balance_prefix, 0, 0, 0); + } + setText(textStr); + } + }*/ +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/Configuration.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/Configuration.java new file mode 100644 index 000000000..9c2722f83 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/Configuration.java @@ -0,0 +1,301 @@ +/* + * Copyright 2014-2015 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package pivx.org.pivxwallet.wallofcoins.utils; + +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.content.res.Resources; +import android.net.Uri; +import android.text.format.DateUtils; + +import com.google.common.base.Strings; + +import org.pivxj.core.Coin; +import org.pivxj.utils.MonetaryFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pivx.org.pivxwallet.R; + + +/** + * @author Andreas Schildbach + */ +public class Configuration { + public final int lastVersionCode; + + private final SharedPreferences prefs; + private final Resources res; + + public static final String PREFS_KEY_BTC_PRECISION = "btc_precision"; + public static final String PREFS_KEY_OWN_NAME = "own_name"; + public static final String PREFS_KEY_SEND_COINS_AUTOCLOSE = "send_coins_autoclose"; + public static final String PREFS_KEY_CONNECTIVITY_NOTIFICATION = "connectivity_notification"; + public static final String PREFS_KEY_EXCHANGE_CURRENCY = "exchange_currency"; + public static final String PREFS_KEY_TRUSTED_PEER = "trusted_peer"; + public static final String PREFS_KEY_TRUSTED_PEER_ONLY = "trusted_peer_only"; + public static final String PREFS_KEY_BLOCK_EXPLORER = "block_explorer"; + public static final String PREFS_KEY_DATA_USAGE = "data_usage"; + public static final String PREFS_KEY_REMIND_BALANCE = "remind_balance"; + public static final String PREFS_KEY_DISCLAIMER = "disclaimer"; + private static final String PREFS_KEY_LABS_QR_PAYMENT_REQUEST = "labs_qr_payment_request"; + private static final String PREFS_KEY_LOOK_UP_WALLET_NAMES = "look_up_wallet_names"; + + private static final String PREFS_KEY_LAST_VERSION = "last_version"; + private static final String PREFS_KEY_LAST_USED = "last_used"; + private static final String PREFS_KEY_BEST_CHAIN_HEIGHT_EVER = "best_chain_height_ever"; + private static final String PREFS_KEY_CACHED_EXCHANGE_CURRENCY = "cached_exchange_currency"; + private static final String PREFS_KEY_CACHED_EXCHANGE_RATE_COIN = "cached_exchange_rate_coin"; + private static final String PREFS_KEY_CACHED_EXCHANGE_RATE_FIAT = "cached_exchange_rate_fiat"; + private static final String PREFS_KEY_LAST_EXCHANGE_DIRECTION = "last_exchange_direction"; + private static final String PREFS_KEY_CHANGE_LOG_VERSION = "change_log_version"; + public static final String PREFS_KEY_REMIND_BACKUP = "remind_backup"; + private static final String PREFS_KEY_LAST_BACKUP = "last_backup"; + public static final String PREFS_KEY_INSTANTX_ENABLED = "labs_instantx_enabled"; + public static final String PREFS_KEY_LITE_MODE = "labs_lite_mode"; + + private static final int PREFS_DEFAULT_BTC_SHIFT = 0; + private static final int PREFS_DEFAULT_BTC_PRECISION = 2; + + private static final Logger log = LoggerFactory.getLogger(Configuration.class); + + public Configuration(final SharedPreferences prefs, final Resources res) { + this.prefs = prefs; + this.res = res; + + this.lastVersionCode = prefs.getInt(PREFS_KEY_LAST_VERSION, 0); + } + + private int getBtcPrecision() { + final String precision = prefs.getString(PREFS_KEY_BTC_PRECISION, null); + if (precision != null) + return precision.charAt(0) - '0'; + else + return PREFS_DEFAULT_BTC_PRECISION; + } + + public int getBtcShift() { + final String precision = prefs.getString(PREFS_KEY_BTC_PRECISION, null); + if (precision != null) + return precision.length() == 3 ? precision.charAt(2) - '0' : 0; + else + return PREFS_DEFAULT_BTC_SHIFT; + } + + public Coin getBtcBase() { + final int shift = getBtcShift(); + if (shift == 0) + return Coin.COIN; + else if (shift == 3) + return Coin.MILLICOIN; + else if (shift == 6) + return Coin.MICROCOIN; + else + throw new IllegalStateException("cannot handle shift: " + shift); + } + + public MonetaryFormat getFormat() { + final int shift = getBtcShift(); + final int minPrecision = shift <= 3 ? 2 : 0; + final int decimalRepetitions = (getBtcPrecision() - minPrecision) / 2; + return new MonetaryFormat().shift(shift).minDecimals(minPrecision).repeatOptionalDecimals(2, + decimalRepetitions); + } + + public MonetaryFormat getMaxPrecisionFormat() { + final int shift = getBtcShift(); + if (shift == 0) + return new MonetaryFormat().shift(0).minDecimals(2).optionalDecimals(2, 2, 2); + else if (shift == 3) + return new MonetaryFormat().shift(3).minDecimals(2).optionalDecimals(2, 1); + else + return new MonetaryFormat().shift(6).minDecimals(0).optionalDecimals(2); + } + + public String getOwnName() { + return Strings.emptyToNull(prefs.getString(PREFS_KEY_OWN_NAME, "").trim()); + } + + public boolean getSendCoinsAutoclose() { + return prefs.getBoolean(PREFS_KEY_SEND_COINS_AUTOCLOSE, true); + } + + public boolean getConnectivityNotificationEnabled() { + return prefs.getBoolean(PREFS_KEY_CONNECTIVITY_NOTIFICATION, false); + } + + public String getTrustedPeerHost() { + return Strings.emptyToNull(prefs.getString(PREFS_KEY_TRUSTED_PEER, "").trim()); + } + + public boolean getTrustedPeerOnly() { + return prefs.getBoolean(PREFS_KEY_TRUSTED_PEER_ONLY, false); + } + + public Uri getBlockExplorer() { + return Uri.parse(prefs.getString(PREFS_KEY_BLOCK_EXPLORER, + res.getStringArray(Constants.TEST ? R.array.preferences_block_explorer_values_testnet : R.array.preferences_block_explorer_values)[0])); + } + + public boolean remindBalance() { + return prefs.getBoolean(PREFS_KEY_REMIND_BALANCE, true); + } + + public void setRemindBalance(final boolean remindBalance) { + prefs.edit().putBoolean(PREFS_KEY_REMIND_BALANCE, remindBalance).apply(); + } + + public boolean remindBackup() { + return prefs.getBoolean(PREFS_KEY_REMIND_BACKUP, true); + } + + public long getLastBackupTime() { + return prefs.getLong(PREFS_KEY_LAST_BACKUP, 0); + } + + public void armBackupReminder() { + prefs.edit().putBoolean(PREFS_KEY_REMIND_BACKUP, true).apply(); + } + + public void disarmBackupReminder() { + prefs.edit().putBoolean(PREFS_KEY_REMIND_BACKUP, false) + .putLong(PREFS_KEY_LAST_BACKUP, System.currentTimeMillis()).apply(); + } + + public boolean getDisclaimerEnabled() { + return prefs.getBoolean(PREFS_KEY_DISCLAIMER, true); + } + + public String getExchangeCurrencyCode() { + return prefs.getString(PREFS_KEY_EXCHANGE_CURRENCY, null); + } + + public void setExchangeCurrencyCode(final String exchangeCurrencyCode) { + prefs.edit().putString(PREFS_KEY_EXCHANGE_CURRENCY, exchangeCurrencyCode).apply(); + } + + public boolean getQrPaymentRequestEnabled() { + return prefs.getBoolean(PREFS_KEY_LABS_QR_PAYMENT_REQUEST, false); + } + + public boolean getLookUpWalletNames() { + return prefs.getBoolean(PREFS_KEY_LOOK_UP_WALLET_NAMES, false); + } + + public boolean versionCodeCrossed(final int currentVersionCode, final int triggeringVersionCode) { + final boolean wasBelow = lastVersionCode < triggeringVersionCode; + final boolean wasUsedBefore = lastVersionCode > 0; + final boolean isNowAbove = currentVersionCode >= triggeringVersionCode; + + return wasUsedBefore && wasBelow && isNowAbove; + } + + public void updateLastVersionCode(final int currentVersionCode) { + prefs.edit().putInt(PREFS_KEY_LAST_VERSION, currentVersionCode).apply(); + + if (currentVersionCode > lastVersionCode) + log.info("detected app upgrade: " + lastVersionCode + " -> " + currentVersionCode); + else if (currentVersionCode < lastVersionCode) + log.warn("detected app downgrade: " + lastVersionCode + " -> " + currentVersionCode); + } + + public boolean hasBeenUsed() { + return prefs.contains(PREFS_KEY_LAST_USED); + } + + public long getLastUsedAgo() { + final long now = System.currentTimeMillis(); + + return now - prefs.getLong(PREFS_KEY_LAST_USED, 0); + } + + public void touchLastUsed() { + final long prefsLastUsed = prefs.getLong(PREFS_KEY_LAST_USED, 0); + final long now = System.currentTimeMillis(); + prefs.edit().putLong(PREFS_KEY_LAST_USED, now).apply(); + + log.info("just being used - last used {} minutes ago", (now - prefsLastUsed) / DateUtils.MINUTE_IN_MILLIS); + } + + public int getBestChainHeightEver() { + return prefs.getInt(PREFS_KEY_BEST_CHAIN_HEIGHT_EVER, 0); + } + + public void maybeIncrementBestChainHeightEver(final int bestChainHeightEver) { + if (bestChainHeightEver > getBestChainHeightEver()) + prefs.edit().putInt(PREFS_KEY_BEST_CHAIN_HEIGHT_EVER, bestChainHeightEver).apply(); + } + + /*public ExchangeRate getCachedExchangeRate() { + if (prefs.contains(PREFS_KEY_CACHED_EXCHANGE_CURRENCY) && prefs.contains(PREFS_KEY_CACHED_EXCHANGE_RATE_COIN) + && prefs.contains(PREFS_KEY_CACHED_EXCHANGE_RATE_FIAT)) { + final String cachedExchangeCurrency = prefs.getString(PREFS_KEY_CACHED_EXCHANGE_CURRENCY, null); + final Coin cachedExchangeRateCoin = Coin.valueOf(prefs.getLong(PREFS_KEY_CACHED_EXCHANGE_RATE_COIN, 0)); + final Fiat cachedExchangeRateFiat = Fiat.valueOf(cachedExchangeCurrency, + prefs.getLong(PREFS_KEY_CACHED_EXCHANGE_RATE_FIAT, 0)); + return new ExchangeRate(new org.bitcoinj.utils.ExchangeRate(cachedExchangeRateCoin, cachedExchangeRateFiat), + null); + } else { + return null; + } + } + + public void setCachedExchangeRate(final ExchangeRate cachedExchangeRate) { + final Editor edit = prefs.edit(); + edit.putString(PREFS_KEY_CACHED_EXCHANGE_CURRENCY, cachedExchangeRate.getCurrencyCode()); + edit.putLong(PREFS_KEY_CACHED_EXCHANGE_RATE_COIN, cachedExchangeRate.rate.coin.value); + edit.putLong(PREFS_KEY_CACHED_EXCHANGE_RATE_FIAT, cachedExchangeRate.rate.fiat.value); + edit.apply(); + }*/ + + public boolean getLastExchangeDirection() { + return prefs.getBoolean(PREFS_KEY_LAST_EXCHANGE_DIRECTION, true); + } + + public void setLastExchangeDirection(final boolean exchangeDirection) { + prefs.edit().putBoolean(PREFS_KEY_LAST_EXCHANGE_DIRECTION, exchangeDirection).apply(); + } + + public boolean changeLogVersionCodeCrossed(final int currentVersionCode, final int triggeringVersionCode) { + final int changeLogVersion = prefs.getInt(PREFS_KEY_CHANGE_LOG_VERSION, 0); + + final boolean wasBelow = changeLogVersion < triggeringVersionCode; + final boolean wasUsedBefore = changeLogVersion > 0; + final boolean isNowAbove = currentVersionCode >= triggeringVersionCode; + + prefs.edit().putInt(PREFS_KEY_CHANGE_LOG_VERSION, currentVersionCode).apply(); + + return /* wasUsedBefore && */wasBelow && isNowAbove; + } + + public void registerOnSharedPreferenceChangeListener(final OnSharedPreferenceChangeListener listener) { + prefs.registerOnSharedPreferenceChangeListener(listener); + } + + public void unregisterOnSharedPreferenceChangeListener(final OnSharedPreferenceChangeListener listener) { + prefs.unregisterOnSharedPreferenceChangeListener(listener); + } + + public boolean getInstantXEnabled() { + return prefs.getBoolean(PREFS_KEY_INSTANTX_ENABLED, true); + } + + public boolean getLiteMode() { + return prefs.getBoolean(PREFS_KEY_LITE_MODE, true); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/Constants.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/Constants.java new file mode 100644 index 000000000..92f1026a2 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/Constants.java @@ -0,0 +1,298 @@ +/* + * Copyright 2011-2015 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package pivx.org.pivxwallet.wallofcoins.utils; + +import android.os.Build; +import android.os.Environment; +import android.text.format.DateUtils; + +import com.google.common.io.BaseEncoding; +import com.squareup.okhttp.HttpUrl; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.logging.HttpLoggingInterceptor; + +import org.pivxj.core.CoinDefinition; +import org.pivxj.core.Context; +import org.pivxj.core.NetworkParameters; +import org.pivxj.params.MainNetParams; +import org.pivxj.params.TestNet3Params; +import org.pivxj.utils.MonetaryFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.concurrent.TimeUnit; + +import pivx.org.pivxwallet.BuildConfig; + + +/** + * @author Andreas Schildbach + */ +public final class Constants { + public static final boolean TEST = BuildConfig.APPLICATION_ID.contains("_test"); + + /** + * Network this wallet is on (e.g. testnet or mainnet). + */ + public static final NetworkParameters NETWORK_PARAMETERS = TEST ? TestNet3Params.get() : MainNetParams.get(); + + /** + * Bitcoinj global context. + */ + public static final Context CONTEXT = new Context(NETWORK_PARAMETERS); + + public final static class Files { + private static final String FILENAME_NETWORK_SUFFIX = NETWORK_PARAMETERS.getId() + .equals(NetworkParameters.ID_MAINNET) ? "" : "-testnet"; + + /** + * Filename of the wallet. + */ + public static final String WALLET_FILENAME_PROTOBUF = "wallet-protobuf" + FILENAME_NETWORK_SUFFIX; + + /** + * How often the wallet is autosaved. + */ + public static final long WALLET_AUTOSAVE_DELAY_MS = 5 * DateUtils.SECOND_IN_MILLIS; + + /** + * Filename of the automatic key backup (old format, can only be read). + */ + public static final String WALLET_KEY_BACKUP_BASE58 = "key-backup-base58" + FILENAME_NETWORK_SUFFIX; + + /** + * Filename of the automatic wallet backup. + */ + public static final String WALLET_KEY_BACKUP_PROTOBUF = "key-backup-protobuf" + FILENAME_NETWORK_SUFFIX; + + /** + * Path to external storage + */ + public static final File EXTERNAL_STORAGE_DIR = Environment.getExternalStorageDirectory(); + + /** + * Manual backups go here. + */ + public static final File EXTERNAL_WALLET_BACKUP_DIR = Environment + .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + + /** + * Filename of the manual key backup (old format, can only be read). + */ + public static final String EXTERNAL_WALLET_KEY_BACKUP = CoinDefinition.coinName.toLowerCase() + "-wallet-keys" + FILENAME_NETWORK_SUFFIX; + + /** + * Filename of the manual wallet backup. + */ + public static final String EXTERNAL_WALLET_BACKUP = CoinDefinition.coinName + "-wallet-backup" + FILENAME_NETWORK_SUFFIX; + + /** + * Filename of the block store for storing the chain. + */ + public static final String BLOCKCHAIN_FILENAME = "blockchain" + FILENAME_NETWORK_SUFFIX; + + /** + * Filename of the block checkpoints file. + */ + public static final String CHECKPOINTS_FILENAME = "checkpoints" + FILENAME_NETWORK_SUFFIX + ".txt"; + + /** + * Filename of the fees files. + */ + public static final String FEES_FILENAME = "fees" + FILENAME_NETWORK_SUFFIX + ".txt"; + + /** + * Filename of the file containing Electrum servers. + */ + public static final String ELECTRUM_SERVERS_FILENAME = "electrum-servers.txt"; + } + + /** + * Maximum size of backups. Files larger will be rejected. + */ + public static final long BACKUP_MAX_CHARS = 10000000; + + private static final String EXPLORE_BASE_URL_PROD = CoinDefinition.BLOCKEXPLORER_BASE_URL_PROD; + private static final String EXPLORE_BASE_URL_TEST = CoinDefinition.BLOCKEXPLORER_BASE_URL_TEST; + + /** + * Base URL for browsing transactions, blocks or addresses. + */ + public static final String EXPLORE_BASE_URL = NETWORK_PARAMETERS.getId().equals(NetworkParameters.ID_MAINNET) ? EXPLORE_BASE_URL_PROD + : EXPLORE_BASE_URL_TEST; + public static final String EXPLORE_ADDRESS_PATH = CoinDefinition.BLOCKEXPLORER_ADDRESS_PATH; + public static final String EXPLORE_TRANSACTION_PATH = CoinDefinition.BLOCKEXPLORER_TRANSACTION_PATH; + public static final String EXPLORE_BLOCK_PATH = CoinDefinition.BLOCKEXPLORER_BLOCK_PATH; + + public static final String MIMETYPE_BACKUP_PRIVATE_KEYS = "x-" + CoinDefinition.coinName.toLowerCase() + "/private-keys"; + + private static final String BITEASY_API_URL_PROD = CoinDefinition.UNSPENT_API_URL;//"https://api.biteasy.com/blockchain/v1/"; + private static final String BITEASY_API_URL_TEST = "https://api.biteasy.com/testnet/v1/"; + /** + * Base URL for blockchain API. + */ + public static final String BITEASY_API_URL = NETWORK_PARAMETERS.getId().equals(NetworkParameters.ID_MAINNET) ? BITEASY_API_URL_PROD + : BITEASY_API_URL_TEST; + + /** + * Currency code for the wallet name resolver. + */ + public static final String WALLET_NAME_CURRENCY_CODE = NETWORK_PARAMETERS.getId() + .equals(NetworkParameters.ID_MAINNET) ? "piv" : "tpiv"; + + /** + * URL to fetch version alerts from. + */ + public static final HttpUrl VERSION_URL = HttpUrl.parse("https://wallet.schildbach.de/version"); + /** + * URL to fetch dynamic fees from. + */ + public static final HttpUrl DYNAMIC_FEES_URL = HttpUrl.parse("https://wallet.schildbach.de/fees"); + + /** + * MIME type used for transmitting single transactions. + */ + public static final String MIMETYPE_TRANSACTION = "application/x-" + CoinDefinition.coinTicker.toLowerCase() + "tx"; + + /** + * MIME type used for transmitting wallet backups. + */ + public static final String MIMETYPE_WALLET_BACKUP = "application/x-" + CoinDefinition.coinName.toLowerCase() + "-wallet-backup"; + + /** + * Number of confirmations until a transaction is fully confirmed. + */ + public static final int MAX_NUM_CONFIRMATIONS = 6; + + /** + * User-agent to use for network access. + */ + public static final String USER_AGENT = CoinDefinition.coinName + " Wallet"; + + /** + * Default currency to use if all default mechanisms fail. + */ + public static final String DEFAULT_EXCHANGE_CURRENCY = "USD"; + + /** + * Donation address for tip/donate action. + */ + public static final String DONATION_ADDRESS = NETWORK_PARAMETERS.getId().equals(NetworkParameters.ID_MAINNET) + ? CoinDefinition.DONATION_ADDRESS : null; + + /** + * Recipient e-mail address for reports. + */ + public static final String REPORT_EMAIL = "hashengineeringsolutions@gmail.com"; + + /** + * Subject line for manually reported issues. + */ + public static final String REPORT_SUBJECT_ISSUE = "Piv Wallet: Reported issue"; + + /** + * Subject line for crash reports. + */ + public static final String REPORT_SUBJECT_CRASH = "Crash report"; + + public static final char CHAR_HAIR_SPACE = '\u200a'; + public static final char CHAR_THIN_SPACE = '\u2009'; + public static final char CHAR_ALMOST_EQUAL_TO = '\u2248'; + public static final char CHAR_CHECKMARK = '\u2713'; + public static final char CURRENCY_PLUS_SIGN = '\uff0b'; + public static final char CURRENCY_MINUS_SIGN = '\uff0d'; + public static final String PREFIX_ALMOST_EQUAL_TO = Character.toString(CHAR_ALMOST_EQUAL_TO) + CHAR_THIN_SPACE; + public static final int ADDRESS_FORMAT_GROUP_SIZE = 4; + public static final int ADDRESS_FORMAT_LINE_SIZE = 12; + + public static final MonetaryFormat LOCAL_FORMAT = new MonetaryFormat().noCode().minDecimals(2).optionalDecimals(); + + public static final BaseEncoding HEX = BaseEncoding.base16().lowerCase(); + + public static final String SOURCE_URL = "https://github.com/HashEngineering/" + CoinDefinition.coinName.toLowerCase() + "-wallet"; + public static final String BINARY_URL = "https://github.com/HashEngineering/" + CoinDefinition.coinName.toLowerCase() + "-wallet/releases"; + public static final String MARKET_APP_URL = "market://details?id=%s"; + public static final String WEBMARKET_APP_URL = "https://play.google.com/store/apps/details?id=%s"; + + public static final int HTTP_TIMEOUT_MS = 15 * (int) DateUtils.SECOND_IN_MILLIS; + public static final int PEER_DISCOVERY_TIMEOUT_MS = 10 * (int) DateUtils.SECOND_IN_MILLIS; + public static final int PEER_TIMEOUT_MS = 15 * (int) DateUtils.SECOND_IN_MILLIS; + + public static final long LAST_USAGE_THRESHOLD_JUST_MS = DateUtils.HOUR_IN_MILLIS; + public static final long LAST_USAGE_THRESHOLD_RECENTLY_MS = 2 * DateUtils.DAY_IN_MILLIS; + public static final long LAST_USAGE_THRESHOLD_INACTIVE_MS = 4 * DateUtils.WEEK_IN_MILLIS; + + public static final long DELAYED_TRANSACTION_THRESHOLD_MS = 2 * DateUtils.HOUR_IN_MILLIS; + + public static final int SDK_DEPRECATED_BELOW = Build.VERSION_CODES.JELLY_BEAN; + + public static final int MEMORY_CLASS_LOWEND = 64; + + public static final int NOTIFICATION_ID_CONNECTED = 0; + public static final int NOTIFICATION_ID_COINS_RECEIVED = 1; + public static final int NOTIFICATION_ID_INACTIVITY = 2; + + /** + * Desired number of scrypt iterations for deriving the spending PIN + */ + public static final int SCRYPT_ITERATIONS_TARGET = 65536; + public static final int SCRYPT_ITERATIONS_TARGET_LOWRAM = 32768; + + /** + * Default ports for Electrum servers + */ + public static final int ELECTRUM_SERVER_DEFAULT_PORT_TCP = NETWORK_PARAMETERS.getId() + .equals(NetworkParameters.ID_MAINNET) ? 50001 : 51001; + public static final int ELECTRUM_SERVER_DEFAULT_PORT_TLS = NETWORK_PARAMETERS.getId() + .equals(NetworkParameters.ID_MAINNET) ? 50002 : 51002; + + /** + * Shared HTTP client, can reuse connections + */ + public static final OkHttpClient HTTP_CLIENT = new OkHttpClient(); + + static { + HTTP_CLIENT.setFollowRedirects(false); + HTTP_CLIENT.setFollowSslRedirects(true); + HTTP_CLIENT.setConnectTimeout(15, TimeUnit.SECONDS); + HTTP_CLIENT.setWriteTimeout(15, TimeUnit.SECONDS); + HTTP_CLIENT.setReadTimeout(15, TimeUnit.SECONDS); + + final HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor( + new HttpLoggingInterceptor.Logger() { + @Override + public void log(final String message) { + log.debug(message); + } + }); + loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC); + HTTP_CLIENT.interceptors().add(loggingInterceptor); + } + + private static final Logger log = LoggerFactory.getLogger(Constants.class); + + //piv Specific + public static long EARLIEST_HD_SEED_CREATION_TIME = 1427610960; + + public static String WALLET_URI_SCHEME = "pivwallet"; + + public static boolean ENABLE_ZERO_FEES = TEST; //Enable Zero Fee's on TestNet only. + + +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/CurrencyCalculatorLink.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/CurrencyCalculatorLink.java new file mode 100644 index 000000000..fb6e99232 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/CurrencyCalculatorLink.java @@ -0,0 +1,210 @@ +/* + * Copyright 2013-2015 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package pivx.org.pivxwallet.wallofcoins.utils; + +import android.view.View; + + +import org.pivxj.core.Coin; +import org.pivxj.utils.ExchangeRate; +import org.pivxj.utils.Fiat; + +import javax.annotation.Nullable; + +import pivx.org.pivxwallet.wallofcoins.ui.CurrencyAmountView; + +/** + * @author Andreas Schildbach + */ +public final class CurrencyCalculatorLink { + private final CurrencyAmountView btcAmountView; + private final CurrencyAmountView localAmountView; + + private CurrencyAmountView.Listener listener = null; + private boolean enabled = true; + private ExchangeRate exchangeRate = null; + private boolean exchangeDirection = true; + + private final CurrencyAmountView.Listener btcAmountViewListener = new CurrencyAmountView.Listener() { + @Override + public void changed() { + if (btcAmountView.getAmount() != null) + setExchangeDirection(true); + else + localAmountView.setHint(null); + + if (listener != null) + listener.changed(); + } + + @Override + public void focusChanged(final boolean hasFocus) { + if (listener != null) + listener.focusChanged(hasFocus); + } + }; + + private final CurrencyAmountView.Listener localAmountViewListener = new CurrencyAmountView.Listener() { + @Override + public void changed() { + if (localAmountView.getAmount() != null) + setExchangeDirection(false); + else + btcAmountView.setHint(null); + + if (listener != null) + listener.changed(); + } + + @Override + public void focusChanged(final boolean hasFocus) { + if (listener != null) + listener.focusChanged(hasFocus); + } + }; + + public CurrencyCalculatorLink(final CurrencyAmountView btcAmountView, final CurrencyAmountView localAmountView) { + this.btcAmountView = btcAmountView; + this.btcAmountView.setListener(btcAmountViewListener); + + this.localAmountView = localAmountView; + this.localAmountView.setListener(localAmountViewListener); + + update(); + } + + public void setListener(@Nullable final CurrencyAmountView.Listener listener) { + this.listener = listener; + } + + public void setEnabled(final boolean enabled) { + this.enabled = enabled; + + update(); + } + + public void setExchangeRate(final ExchangeRate exchangeRate) { + this.exchangeRate = exchangeRate; + + update(); + } + + public ExchangeRate getExchangeRate() { + return exchangeRate; + } + + @Nullable + public Coin getAmount() { + if (exchangeDirection) { + return (Coin) btcAmountView.getAmount(); + } else if (exchangeRate != null) { + final Fiat localAmount = (Fiat) localAmountView.getAmount(); + if (localAmount == null) + return null; + try { + final Coin btcAmount = exchangeRate.fiatToCoin(localAmount); + if (((Coin) btcAmount).isGreaterThan(Constants.NETWORK_PARAMETERS.getMaxMoney())) + throw new ArithmeticException(); + return btcAmount; + } catch (ArithmeticException x) { + return null; + } + } else { + return null; + } + } + + public boolean hasAmount() { + return getAmount() != null; + } + + private void update() { + btcAmountView.setEnabled(enabled); + + if (exchangeRate != null) { + localAmountView.setEnabled(enabled); + localAmountView.setCurrencySymbol(exchangeRate.fiat.currencyCode); + + if (exchangeDirection) { + final Coin btcAmount = (Coin) btcAmountView.getAmount(); + if (btcAmount != null) { + localAmountView.setAmount(null, false); + try { + localAmountView.setHint(exchangeRate.coinToFiat(btcAmount)); + } catch (ArithmeticException x) { + localAmountView.setHint(null); + } + btcAmountView.setHint(null); + } + } else { + final Fiat localAmount = (Fiat) localAmountView.getAmount(); + if (localAmount != null) { + localAmountView.setHint(null); + btcAmountView.setAmount(null, false); + try { + final Coin btcAmount = exchangeRate.fiatToCoin(localAmount); + if (((Coin) btcAmount).isGreaterThan(Constants.NETWORK_PARAMETERS.getMaxMoney())) + throw new ArithmeticException(); + btcAmountView.setHint(btcAmount); + } catch (final ArithmeticException x) { + btcAmountView.setHint(null); + } + } + } + } else { + localAmountView.setEnabled(false); + localAmountView.setHint(null); + btcAmountView.setHint(null); + } + } + + public void setExchangeDirection(final boolean exchangeDirection) { + this.exchangeDirection = exchangeDirection; + + update(); + } + + public boolean getExchangeDirection() { + return exchangeDirection; + } + + public View activeTextView() { + if (exchangeDirection) + return btcAmountView.getTextView(); + else + return localAmountView.getTextView(); + } + + public void requestFocus() { + activeTextView().requestFocus(); + } + + public void setBtcAmount(final Coin amount) { + final CurrencyAmountView.Listener listener = this.listener; + this.listener = null; + + btcAmountView.setAmount(amount, true); + + this.listener = listener; + } + + public void setNextFocusId(final int nextFocusId) { + btcAmountView.setNextFocusId(nextFocusId); + localAmountView.setNextFocusId(nextFocusId); + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/Formats.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/Formats.java new file mode 100644 index 000000000..590dae543 --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/Formats.java @@ -0,0 +1,55 @@ +/* + * Copyright 2014-2015 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package pivx.org.pivxwallet.wallofcoins.utils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.annotation.Nullable; + +/** + * @author Andreas Schildbach + */ +public final class Formats { + public static final Pattern PATTERN_MONETARY_SPANNABLE = Pattern.compile("(?:([\\p{Alpha}\\p{Sc}]++)\\s?+)?" // prefix + + "([\\+\\-" + Constants.CURRENCY_PLUS_SIGN + Constants.CURRENCY_MINUS_SIGN + + "]?+(?:\\d*+\\.\\d{0,2}+|\\d++))" // significant + + "(\\d++)?"); // insignificant + + public static int PATTERN_GROUP_PREFIX = 1; // optional + public static int PATTERN_GROUP_SIGNIFICANT = 2; // mandatory + public static int PATTERN_GROUP_INSIGNIFICANT = 3; // optional + + private static final Pattern PATTERN_MEMO = Pattern.compile( + "(?:Payment request for Coinbase order code: (.+)|Payment request for BitPay invoice (.+) for merchant (.+))", + Pattern.CASE_INSENSITIVE); + + @Nullable + public static String[] sanitizeMemo(final @Nullable String memo) { + if (memo == null) + return null; + + final Matcher m = PATTERN_MEMO.matcher(memo); + if (m.matches() && m.group(1) != null) + return new String[] { m.group(1) + " (via Coinbase)" }; + else if (m.matches() && m.group(2) != null) + return new String[] { m.group(2) + " (via BitPay)", m.group(3) }; + else + return new String[] { memo }; + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/GenericUtils.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/GenericUtils.java new file mode 100644 index 000000000..f3b2a6aaa --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/GenericUtils.java @@ -0,0 +1,38 @@ +/* + * Copyright 2011-2015 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package pivx.org.pivxwallet.wallofcoins.utils; + +import java.util.Currency; + +/** + * @author Andreas Schildbach + */ +public class GenericUtils { + public static boolean startsWithIgnoreCase(final String string, final String prefix) { + return string.regionMatches(true, 0, prefix, 0, prefix.length()); + } + + public static String currencySymbol(final String currencyCode) { + try { + final Currency currency = Currency.getInstance(currencyCode); + return currency.getSymbol(); + } catch (final IllegalArgumentException x) { + return currencyCode; + } + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/MonetarySpannable.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/MonetarySpannable.java new file mode 100644 index 000000000..d6235e10c --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/MonetarySpannable.java @@ -0,0 +1,115 @@ +/* + * Copyright 2014-2015 the original author or authors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package pivx.org.pivxwallet.wallofcoins.utils; + +import android.graphics.Typeface; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.style.RelativeSizeSpan; +import android.text.style.StyleSpan; + + +import org.pivxj.core.Monetary; +import org.pivxj.utils.MonetaryFormat; + +import java.util.regex.Matcher; + +import javax.annotation.Nullable; + + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * @author Andreas Schildbach + */ +public final class MonetarySpannable extends SpannableString { + public MonetarySpannable(final MonetaryFormat format, final boolean signed, @Nullable final Monetary monetary) { + super(format(format, signed, monetary)); + } + + public MonetarySpannable(final MonetaryFormat format, @Nullable final Monetary monetary) { + super(format(format, false, monetary)); + } + + private static CharSequence format(final MonetaryFormat format, final boolean signed, final Monetary monetary) { + if (monetary == null) + return ""; + + checkArgument(monetary.signum() >= 0 || signed); + + if (signed) + return format.negativeSign(Constants.CURRENCY_MINUS_SIGN).positiveSign(Constants.CURRENCY_PLUS_SIGN) + .format(monetary); + else + return format.format(monetary); + } + + public MonetarySpannable applyMarkup(@Nullable final Object[] prefixSpans, + @Nullable final Object[] insignificantSpans) { + applyMarkup(this, prefixSpans, STANDARD_SIGNIFICANT_SPANS, insignificantSpans); + return this; + } + + public static final Object BOLD_SPAN = new StyleSpan(Typeface.BOLD); + public static final RelativeSizeSpan SMALLER_SPAN = new RelativeSizeSpan(0.85f); + + public static final Object[] STANDARD_SIGNIFICANT_SPANS = new Object[] { BOLD_SPAN }; + public static final Object[] STANDARD_INSIGNIFICANT_SPANS = new Object[] { MonetarySpannable.SMALLER_SPAN }; + + public static void applyMarkup(final Spannable spannable, @Nullable final Object[] prefixSpans, + @Nullable final Object[] significantSpans, @Nullable final Object[] insignificantSpans) { + if (prefixSpans != null) + for (final Object span : prefixSpans) + spannable.removeSpan(span); + if (significantSpans != null) + for (final Object span : significantSpans) + spannable.removeSpan(span); + if (insignificantSpans != null) + for (final Object span : insignificantSpans) + spannable.removeSpan(span); + + final Matcher m = Formats.PATTERN_MONETARY_SPANNABLE.matcher(spannable); + if (m.find()) { + int i = 0; + + if (m.group(Formats.PATTERN_GROUP_PREFIX) != null) { + final int end = m.end(Formats.PATTERN_GROUP_PREFIX); + if (prefixSpans != null) + for (final Object span : prefixSpans) + spannable.setSpan(span, i, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + i = end; + } + + if (m.group(Formats.PATTERN_GROUP_SIGNIFICANT) != null) { + final int end = m.end(Formats.PATTERN_GROUP_SIGNIFICANT); + if (significantSpans != null) + for (final Object span : significantSpans) + spannable.setSpan(span, i, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + i = end; + } + + if (m.group(Formats.PATTERN_GROUP_INSIGNIFICANT) != null) { + final int end = m.end(Formats.PATTERN_GROUP_INSIGNIFICANT); + if (insignificantSpans != null) + for (final Object span : insignificantSpans) + spannable.setSpan(span, i, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + i = end; + } + } + } +} diff --git a/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/NetworkUtil.java b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/NetworkUtil.java new file mode 100644 index 000000000..63958072c --- /dev/null +++ b/app/src/main/java/pivx/org/pivxwallet/wallofcoins/utils/NetworkUtil.java @@ -0,0 +1,18 @@ +package pivx.org.pivxwallet.wallofcoins.utils; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; + +/** + * Created on 15-Mar-18. + */ + +public class NetworkUtil { + public static boolean isOnline(Context context) { + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo netInfo = cm.getActiveNetworkInfo(); /* NetworkInfo mWifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI); if(netInfo.equals(mWifi)){ if(mWifi.isAvailable()) return true; else return false; }else{ return true; }*/ + return netInfo != null && netInfo.isConnectedOrConnecting(); + } + +} diff --git a/app/src/main/res/anim/activity_back_out.xml b/app/src/main/res/anim/activity_back_out.xml new file mode 100644 index 000000000..4344ae837 --- /dev/null +++ b/app/src/main/res/anim/activity_back_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_backin.xml b/app/src/main/res/anim/activity_backin.xml new file mode 100644 index 000000000..592e2417a --- /dev/null +++ b/app/src/main/res/anim/activity_backin.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 000000000..515f2d13d --- /dev/null +++ b/app/src/main/res/anim/activity_in.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml new file mode 100644 index 000000000..121148922 --- /dev/null +++ b/app/src/main/res/anim/activity_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/ic_account_balance_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_account_balance_black_24dp.png new file mode 100644 index 000000000..7ff265a49 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_account_balance_black_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_pin_drop_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_pin_drop_white_24dp.png new file mode 100644 index 000000000..0dd78bed8 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_pin_drop_white_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/wall_of_coins.png b/app/src/main/res/drawable-hdpi/wall_of_coins.png new file mode 100644 index 000000000..9dd14b9cc Binary files /dev/null and b/app/src/main/res/drawable-hdpi/wall_of_coins.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_account_balance_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_account_balance_black_24dp.png new file mode 100644 index 000000000..b221ac2b1 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_account_balance_black_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/wall_of_coins.png b/app/src/main/res/drawable-mdpi/wall_of_coins.png new file mode 100644 index 000000000..e0b3365ce Binary files /dev/null and b/app/src/main/res/drawable-mdpi/wall_of_coins.png differ diff --git a/app/src/main/res/drawable-xhdpi/currency_symbol_btc.png b/app/src/main/res/drawable-xhdpi/currency_symbol_btc.png new file mode 100644 index 000000000..e07c4b4de Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/currency_symbol_btc.png differ diff --git a/app/src/main/res/drawable-xhdpi/currency_symbol_mbtc.png b/app/src/main/res/drawable-xhdpi/currency_symbol_mbtc.png new file mode 100644 index 000000000..16d15971a Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/currency_symbol_mbtc.png differ diff --git a/app/src/main/res/drawable-xhdpi/currency_symbol_ubtc.png b/app/src/main/res/drawable-xhdpi/currency_symbol_ubtc.png new file mode 100644 index 000000000..680316a7b Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/currency_symbol_ubtc.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_account_balance_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_account_balance_black_24dp.png new file mode 100644 index 000000000..3372ace32 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_account_balance_black_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_pin_drop_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_pin_drop_white_24dp.png new file mode 100644 index 000000000..1ebad4391 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_pin_drop_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/wall_of_coins.png b/app/src/main/res/drawable-xhdpi/wall_of_coins.png new file mode 100644 index 000000000..c4160e6b4 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/wall_of_coins.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_account_balance_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_account_balance_black_24dp.png new file mode 100644 index 000000000..2dcbf0a41 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_account_balance_black_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_pin_drop_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_pin_drop_white_24dp.png new file mode 100644 index 000000000..e3cf1038e Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_pin_drop_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/wall_of_coins.png b/app/src/main/res/drawable-xxhdpi/wall_of_coins.png new file mode 100644 index 000000000..d719828fd Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/wall_of_coins.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_account_balance_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_account_balance_black_24dp.png new file mode 100644 index 000000000..b89db1e12 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_account_balance_black_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/wall_of_coins.png b/app/src/main/res/drawable-xxxhdpi/wall_of_coins.png new file mode 100644 index 000000000..722734d3d Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/wall_of_coins.png differ diff --git a/app/src/main/res/drawable/divider_currency.xml b/app/src/main/res/drawable/divider_currency.xml new file mode 100644 index 000000000..340fe36e6 --- /dev/null +++ b/app/src/main/res/drawable/divider_currency.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/download.png b/app/src/main/res/drawable/download.png new file mode 100644 index 000000000..bc5de272d Binary files /dev/null and b/app/src/main/res/drawable/download.png differ diff --git a/app/src/main/res/drawable/flags.png b/app/src/main/res/drawable/flags.png new file mode 100644 index 000000000..471e6f74a Binary files /dev/null and b/app/src/main/res/drawable/flags.png differ diff --git a/app/src/main/res/drawable/ic_action_search.xml b/app/src/main/res/drawable/ic_action_search.xml new file mode 100644 index 000000000..47432c174 --- /dev/null +++ b/app/src/main/res/drawable/ic_action_search.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_arrow_back_white_24dp.xml b/app/src/main/res/drawable/ic_arrow_back_white_24dp.xml new file mode 100644 index 000000000..38fbc261b --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_back_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_clear_grey600_24dp.xml b/app/src/main/res/drawable/ic_clear_grey600_24dp.xml new file mode 100644 index 000000000..01752ddab --- /dev/null +++ b/app/src/main/res/drawable/ic_clear_grey600_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_menu_sell_piv.xml b/app/src/main/res/drawable/ic_menu_sell_piv.xml new file mode 100644 index 000000000..cd5b80da1 --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_sell_piv.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_more_vert_grey600_18dp.xml b/app/src/main/res/drawable/ic_more_vert_grey600_18dp.xml new file mode 100644 index 000000000..9baa3357d --- /dev/null +++ b/app/src/main/res/drawable/ic_more_vert_grey600_18dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_piv_d_white_bottom.xml b/app/src/main/res/drawable/ic_piv_d_white_bottom.xml new file mode 100644 index 000000000..2503914b8 --- /dev/null +++ b/app/src/main/res/drawable/ic_piv_d_white_bottom.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/ic_warning.xml b/app/src/main/res/drawable/ic_warning.xml new file mode 100644 index 000000000..12817b42c --- /dev/null +++ b/app/src/main/res/drawable/ic_warning.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/selectable_item_background.xml b/app/src/main/res/drawable/selectable_item_background.xml new file mode 100644 index 000000000..e59b30091 --- /dev/null +++ b/app/src/main/res/drawable/selectable_item_background.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_edit_btn.xml b/app/src/main/res/drawable/selector_edit_btn.xml new file mode 100644 index 000000000..3ef048e0d --- /dev/null +++ b/app/src/main/res/drawable/selector_edit_btn.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/stat_notify_received_24dp.xml b/app/src/main/res/drawable/stat_notify_received_24dp.xml new file mode 100644 index 000000000..cb96bd1ff --- /dev/null +++ b/app/src/main/res/drawable/stat_notify_received_24dp.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/app/src/main/res/drawable/white_progress.xml b/app/src/main/res/drawable/white_progress.xml new file mode 100644 index 000000000..e30c0fec1 --- /dev/null +++ b/app/src/main/res/drawable/white_progress.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_buying_base.xml b/app/src/main/res/layout/activity_buying_base.xml new file mode 100644 index 000000000..f88b998ba --- /dev/null +++ b/app/src/main/res/layout/activity_buying_base.xml @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/app/src/main/res/layout/exchange_rate_row.xml b/app/src/main/res/layout/exchange_rate_row.xml new file mode 100644 index 000000000..192e59c7a --- /dev/null +++ b/app/src/main/res/layout/exchange_rate_row.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/exchange_rates_content.xml b/app/src/main/res/layout/exchange_rates_content.xml new file mode 100644 index 000000000..4fe10a67c --- /dev/null +++ b/app/src/main/res/layout/exchange_rates_content.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/exchange_rates_fragment.xml b/app/src/main/res/layout/exchange_rates_fragment.xml new file mode 100644 index 000000000..9f578de0d --- /dev/null +++ b/app/src/main/res/layout/exchange_rates_fragment.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_buying_email_and_phone.xml b/app/src/main/res/layout/fragment_buying_email_and_phone.xml new file mode 100644 index 000000000..1b4ca33fd --- /dev/null +++ b/app/src/main/res/layout/fragment_buying_email_and_phone.xml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + +