Compare commits

...

91 Commits

Author SHA1 Message Date
aa8717946a Several fixes
- CurrencySelectionActivity renamed to CurrencyListActivity
- Allow refresh from the Update snackbar button in Summary after an error
- Code cleaning
- Typo
2018-11-19 16:43:42 +01:00
cb428937d4
Fix decode feature in the app (MUST BE CHECKED) 2018-10-02 15:36:56 +02:00
1cb7c03d63 Remove useless code 2018-09-02 02:08:59 +02:00
3e56c6f90e Prepare suffix code for some inputs 2018-09-02 01:54:48 +02:00
f837372551 Add icon displaying animation 2018-09-02 01:03:29 +02:00
8ca63b5e85 Rework icon loading
- Icons are now downloaded after displaying the whole list
2018-09-01 23:31:17 +02:00
e6d69a01ce Update chart color definition algorithm
Everything comes now from the MoodlUtilBox
2018-09-01 23:30:19 +02:00
16eafc075a Update version name for BETA 2018-08-29 01:12:47 +02:00
b97b8e7645 Add logos to exchange accounts list 2018-08-29 01:11:25 +02:00
2a4ba215e6 Fix 'infinity' balance percentage when hiding the balance 2018-08-28 13:43:14 +02:00
9395ec7425 Fix transaction history not displaying correctly
- Fix deducted transactions not being displayed
- Fix pairs not displayed properly
2018-08-27 04:01:12 +02:00
7623012353 Fix total value calculus and allow fiat display
- Fix Deduct switch not being updated when editing a transaction

Previous commit tested and working
2018-08-27 03:41:33 +02:00
4738a65dcc [Untested] Fix balance deductions 2018-08-27 02:48:16 +02:00
2654b044b2 Minor fixs
- Icon size fix
- Fix details activity crash
2018-08-24 04:05:05 +02:00
dd9f4d2141 Rework labels in transaction history
- Summary now updates after importing data
- Fix crash when exiting the details activity too quickly
2018-08-22 21:27:58 +02:00
518df666f4 Multiple fixs
[DetailsActivity]
- Fix crash when finishing the activity before all transactions and trades are updated

[MarketCapitalizationActivity]
- Fix some views not visible for little screens

[RecordTransactionActivity]
- Fix crash when editing a sell transaction
2018-08-21 02:00:09 +02:00
ac7fb545ec [DetailsActivity] Merge Transactions and Trades in the same list 2018-08-21 00:19:29 +02:00
e80c9f4046 Code sorting 2018-08-20 22:45:03 +02:00
d79a76f13b [DetailsActivity] Enable binance trade update
- Add support for multiple binance accounts
2018-08-20 22:35:37 +02:00
b25e44d3ef Fix transaction edition
- Fee format was not displayed correctly in Buy and Sell tabs
2018-08-20 21:54:12 +02:00
10c3a0a67b UI fix
[RecordTransactionActivity]
- Fix tab color when editing a transaction
- Disable tab swiping
- Fix crash when editing a sell transaction
2018-08-20 20:32:59 +02:00
4c65596718 Add transaction indicator 2018-08-20 18:12:35 +02:00
ffd103fad3 Fix transfer equation 2018-08-20 16:16:23 +02:00
b22aa6bc12
Merge pull request #8 from TanguyHerbron/unstable
Rework SettingsActivity and RecordTransactionActivity + several fixs
2018-08-20 05:10:06 +02:00
2dd608ecc8 Complete french translation 2018-08-20 04:54:50 +02:00
7f0518a96a Transfer edition and several fixs
[RecordTransactionActivity]
- Fix Buy tab crash when editing a transaction
- Fix Sell transaction edition not working at all
- Add Transfer edition
- Add 'Deduct from holdings' switch to all tabs

[SettingsActivity]
- Fix manual entires import not filling all database columns

[General]
- Fix balance calculation not working properly
2018-08-20 04:54:16 +02:00
f907a4bdb1 Update transfer tab in RecordTransactionActivity
- Add backend code to the Transfer tab

TODO :
- Support for %/fixed fees for transfers
- Edition support for transfers
2018-08-19 02:48:52 +02:00
40210fdbf0 Code cleaning / sorting 2018-08-19 02:46:53 +02:00
43171cd428 Fix RecordTransactionActivity crash
- The intent is now cleared after editing a transaction, avoiding a crash in certain scenarios
2018-08-19 02:15:48 +02:00
8ba9cc2ff9 Update icon
Smoother corners
2018-08-18 21:31:43 +02:00
1d4324bec2 Update transfert tab in RecordTransactionActivity
- Prepare 'from' and 'to' fields
- Setup date field

- Update tab text colors
2018-08-18 02:34:02 +02:00
de38e5dea4 Remove layout duplicates 2018-08-17 05:14:23 +02:00
b14b98eb97 Fix balance calculus for sell transaction 2018-08-17 04:52:27 +02:00
cdff187910 Fix sell fees equation 2018-08-17 04:44:49 +02:00
1efbaea351 Update Sell tab in the RecordTransactionActivity allowing to register sell transaction 2018-08-17 04:38:49 +02:00
1f433ba708 Fix buy fees display in the RecordTransactionActivity
- Fix fixed fees equation
2018-08-17 03:09:45 +02:00
89246e0919 Fix amount and total value equation when adding a fee while recording a transaction 2018-08-16 04:06:15 +02:00
6194ff501a Fix price update when picking a new date while recording a transaction 2018-08-16 03:29:14 +02:00
e194d362ba Add badge in the drawer when an exchange account is disabled 2018-08-16 03:23:19 +02:00
727e803b8b Fix balance not being displayed properly for some fee format 2018-08-16 02:50:40 +02:00
f32270cc4b RecordTransactionActivity fixs
- Dynamic amount when filling the total value
- Fix fee calcul when using the pair percentage option
2018-08-16 02:24:29 +02:00
e308e962d7 Fix fee format when editing a transaction 2018-08-15 22:39:12 +02:00
4bdffe22c4 Fix negative balance not displaying 2018-08-15 22:37:43 +02:00
91418b73fa Fix SDK 19 crash 2018-08-15 04:23:54 +02:00
85dd10a177 Fix app crash for SDK 19 2018-08-15 04:14:04 +02:00
df9ab11410 Fix transaction edition
- Fix crash when trying to edit a transaction
- Update the code when editing a transaction to match the new interface
2018-08-15 02:51:28 +02:00
74cae8fa67 Update database design 2018-08-14 21:19:01 +02:00
3a1ac3c80b Major updates
- Fix code typos
- Add a 'fromSym' field in the transactions table
- Fix translation in the drawer

[RecordTransactionActivity rework]
- New currency selection
- Add Exchange selection
- Add corresponding Pair selection
- Add tabs to select Buy/Sell/Transaction
> Buy fragment
- Add note field
- Add fee format selection
- Limit date selection to the past (it's no longer possible to add a futur transaction)
- Auto fill the price after date selection
2018-08-14 04:14:18 +02:00
7b5fd6e786 Update french translation 2018-08-04 05:05:12 +02:00
d0041a87ba Fix cardview margins for 19-23 SDK 2018-08-04 04:01:06 +02:00
1d18847c3c Fix AddExchangeActivity crash for 19-23 SDK
- Update the exchange connexion error icon
2018-08-04 03:54:45 +02:00
ae3ab48c58 Fix compatibility issues for 19-23 SDK 2018-08-04 03:35:35 +02:00
cf8cc29329 Add exchange/pair selection after each parent choice in the RecordTransactionActivity 2018-08-04 03:04:07 +02:00
ac3ad43775 Details are now accessible even when there is no chart data 2018-08-03 16:17:15 +02:00
92f08e00ed Update code with new interfaces for a clearer code (I hope so...)
- Preview of the RecordTransactionActivity buying UI
- MarketCapManager.java and CoinmarketCapAPIManager are now merged
2018-08-03 03:22:20 +02:00
10888c4c54 Rework RecordTransactionActivity's UI 2018-08-02 13:12:05 +02:00
b919e164e5 Exchange activities fix
- Refresh balance after exchange update
- Invalid HitBTC accounts are now disabled after balance refresh
2018-08-01 16:14:20 +02:00
34ff605de2 Fix exchange list not updating correctly 2018-08-01 16:03:43 +02:00
3efa225e5c Add support for multiple Binance accounts
- Small UI improvement for the Exchange list activity
- New Binance API jar created from this [fork](https://github.com/TanguyHerbron/binance-java-api)
- Disable VET display, waiting for the swap to be completely done
2018-08-01 15:57:30 +02:00
2d12cc3dbe Fix exchange connexion status not showing properly 2018-08-01 13:56:54 +02:00
b7d10011ef Fix exchange type not being processed properly 2018-08-01 13:08:16 +02:00
8778290135 Add API keys importation 2018-08-01 01:17:29 +02:00
380716f7ea Exchange config rework
- Fix crash when binance sync error
- New exchange list UI
- New exchange configuration UI
- Fix gradient background for Settings activity

The new exchange configuration interface allows you to add (it should work) multiple accounts for each exchange
If an account's keys are incorrect, the account and disabled and it's notified in the exchange list
You can edit the exchange account later from the exchange list activity
2018-08-01 01:02:41 +02:00
af2eeed241 Merge branch 'unstable' of https://github.com/TanguyHerbron/Coinfolio into unstable 2018-07-31 13:17:33 +02:00
a64aed4729 Update exchange activity 2018-07-31 13:16:42 +02:00
38723b7dca
Merge pull request #7 from TanguyHerbron/master
Update unstable to correct some bugs hot fixed
2018-07-31 13:14:30 +02:00
93f0a700fb WIP
- Prepare RecordTransactionActivity rework
- Lock Touch ID if not supported/not configured
- Prepare API storage rework
- Fix CurrencyTickerList and CurrencyDetailsList crash
-
2018-07-31 01:48:03 +02:00
6fe8831c69 Several fixes/adjustments
- LineCharts are now smooth
- The splashscreens works 'properly' even when there is no cached icons
- Edit mode is disabled when adding a coin in the watchlist
- Add option to clear cache in the settings menu when in debug mode
2018-07-31 01:19:00 +02:00
533aea5bb6 Ripple effect on watchlist/holdings add button 2018-07-23 23:44:44 +02:00
188d924c18 Watchlist : Edit button animations 2018-07-23 19:43:42 +02:00
1c670d6e5d
Merge pull request #6 from TanguyHerbron/master
Update the branch for new code coming
2018-07-21 21:56:30 +02:00
08434128b1 Fix status bar flash when starting the app 2018-07-21 21:49:41 +02:00
2df677c947 Add gradient to the status bar
- Rework some labels
- Gradient orientation changed
2018-07-21 21:26:58 +02:00
582a155c8b Fix refreshing indicator not being displayed properly in the holding section 2018-07-21 18:26:41 +02:00
7f1a318a70 Data backup UI rework
- Fix balance hiding not working properly after restarting the app
- An error is displayed when no proper password is entered for backup encryption
- Add Watchlist, Manual entries and API keys backup and restore options
- Add wipe old data for Watchlist, Manual entries and API keys option
- Add encode checker to know whether or not the backup is encrypted
- Fix unproper import/export labels
- Add round corners to the top of each main layout (Holdings/Watchlist/MarketCap/List)
2018-07-21 14:56:26 +02:00
b53d52daeb Update placeholders and translations 2018-07-19 23:59:29 +02:00
47c4fb0daf Backup encryption feature
- Add encryption option when exporting and importing backup
- Add wipe data option when importing backup
2018-07-18 23:54:04 +02:00
f8bb7b0487 Add some label translations (EN/FR) 2018-07-17 00:43:45 +02:00
aa10defb03 Major detail activity fix
- Fix details activity chart loading error
- Fix some non translated strings
2018-07-17 00:33:29 +02:00
2b165ba2a0 Bug fixes
- Rework SettingsActivity code to make it clearer
- Fix crash when loading app icon as default icon
2018-07-15 21:20:26 +02:00
7946ba4897 New features
- App loading animation generated from cached icons
- Import backups (data format will be reworked)
- Fix cryptocompare crash because of an API update
2018-07-15 00:32:51 +02:00
e173e48612 Export feature
You can now export (it's an early stage) your manual entries to a file to restore it later
- Choose where to put your backup
- Code for encrypting data (will be enabled soon)
- Update version number to 0.0.6
2018-07-11 23:57:55 +02:00
de6fc36e6c Import data implementation (begining)
- Adds an interface for the data import feature (not final)
- Can read data from a manually created backup file
2018-07-09 23:47:30 +02:00
7b9282bfef Rework settings activity
- Clearer settings activity
- Data import/export buttons
2018-07-05 23:26:40 +02:00
87d02b5365 Code cleaning 2018-06-18 08:44:04 +02:00
e8d30e41f8 Fix fluctuation percentage 2018-06-17 19:30:33 +02:00
91a1551fa7 Fix color glich 2018-06-17 03:45:26 +02:00
5a512a304a Fix margins and paddings 2018-06-17 02:12:33 +02:00
40e511a576
Merge pull request #5 from TanguyHerbron/MPAndroidChart_full
Merge pull request #4 from TanguyHerbron/FragmentRework
2018-06-16 21:31:04 +02:00
0cd2053bb4
Merge pull request #4 from TanguyHerbron/FragmentRework
Fragment rework
2018-06-16 21:29:59 +02:00
3827329ca9 Fix delete animation in listview | Add input security while registering a transaction 2018-06-12 23:28:07 +02:00
176 changed files with 11640 additions and 3929 deletions

75
.gitignore vendored
View File

@ -1,10 +1,69 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild
# Built application files
*.apk
*.ap_
*.aab
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# IntelliJ
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/assetWizardSettings.xml
.idea/dictionaries
.idea/libraries
.idea/caches
# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
#*.jks
#*.keystore
# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
# Google Services (e.g. APIs or Firebase)
google-services.json
# Freeline
freeline.py
freeline/
freeline_project_description.json
# fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md

136
.idea/assetWizardSettings.xml generated Normal file
View File

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="imageWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="imageAssetPanel">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="actionbar">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="image">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="paddingPercent" value="-10" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="assetType" value="IMAGE" />
<entry key="imageAsset" value="D:\Projets Adobe\Photoshop\Moodl_background_textonly.png" />
<entry key="outputName" value="moodl_background" />
<entry key="theme" value="CUSTOM" />
<entry key="themeColor" value="ffffff" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="launcher">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="foregroundImage">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="scalingPercent" value="72" />
<entry key="trimmed" value="true" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="backgroundAssetType" value="COLOR" />
<entry key="backgroundColor" value="004e92" />
<entry key="backgroundLayerName" value="ic_launcher_background" />
<entry key="foregroundImage" value="D:\Projets Adobe\Photoshop\Moodl_icon_white.png" />
<entry key="foregroundLayerName" value="ic_launcher_foreground" />
<entry key="outputName" value="ic_launcher_moodl" />
<entry key="previewDensity" value="MEDIUM" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="outputIconType" value="ACTIONBAR" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="vectorWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="vectorAssetStep">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipartAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/navigation/ic_arrow_upward_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="assetSourceType" value="FILE" />
<entry key="color" value="ffffff" />
<entry key="outputName" value="exchange_logo_hitbtc" />
<entry key="sourceFile" value="D:\Téléchargement\hitbtc.svg" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>

Binary file not shown.

2
.idea/gradle.xml generated
View File

@ -5,7 +5,7 @@
<GradleProjectSettings>
<option name="distributionType" value="LOCAL" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-4.7" />
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-4.9" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

View File

@ -1,17 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="HardCodedStringLiteral" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreForAssertStatements" value="true" />
<option name="ignoreForExceptionConstructors" value="true" />
<option name="ignoreForSpecifiedExceptionConstructors" value="" />
<option name="ignoreForJUnitAsserts" value="true" />
<option name="ignoreForClassReferences" value="true" />
<option name="ignoreForPropertyKeyReferences" value="true" />
<option name="ignoreForNonAlpha" value="true" />
<option name="ignoreAssignedToConstants" value="false" />
<option name="ignoreToString" value="false" />
<option name="nonNlsCommentPattern" value="NON-NLS" />
</inspection_tool>
</profile>
</component>

28
.idea/misc.xml generated
View File

@ -1,20 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<list size="1">
<item index="0" class="java.lang.String" itemvalue="org.greenrobot.eventbus.Subscribe" />
</list>
<component name="JavadocGenerationManager">
<option name="OUTPUT_DIRECTORY" value="F:/Export AS" />
<option name="OPTION_SCOPE" value="protected" />
<option name="OPTION_HIERARCHY" value="true" />
<option name="OPTION_NAVIGATOR" value="true" />
<option name="OPTION_INDEX" value="true" />
<option name="OPTION_SEPARATE_INDEX" value="true" />
<option name="OPTION_DOCUMENT_TAG_USE" value="false" />
<option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
<option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
<option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
<option name="OPTION_DEPRECATED_LIST" value="true" />
<option name="OTHER_OPTIONS" />
<option name="HEAP_SIZE" />
<option name="LOCALE" />
<option name="OPEN_IN_BROWSER" value="true" />
<option name="OPTION_INCLUDE_LIBS" value="false" />
</component>
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<list size="5">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>

12
.idea/statistic.xml generated
View File

@ -1,20 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Statistic">
<option name="fileTypes" value="class;svn-base;svn-work;Extra;gif;png;jpg;jpeg;bmp;tga;tiff;ear;war;zip;jar;iml;iws;ipr;bz2;gz;gitignore;gradle;md;pro;properties;" />
<option name="fileTypes" value="class;svn-base;svn-work;Extra;gif;png;jpg;jpeg;bmp;tga;tiff;ear;war;zip;jar;iml;iws;ipr;bz2;gz;ap;apk;bin;dex;flat;gitignore;gson;json;md;pro;store;ttf;txt;ap_;" />
<option name="excludedDirectories">
<list>
<option value="$PROJECT_DIR$/build" />
<option value="$PROJECT_DIR$/.idea" />
<option value="$PROJECT_DIR$/.gradle" />
<option value="$PROJECT_DIR$/export" />
<option value="$PROJECT_DIR$/gource" />
<option value="$PROJECT_DIR$/gradle" />
<option value="$PROJECT_DIR$/libs" />
<option value="$PROJECT_DIR$/.idea" />
<option value="$PROJECT_DIR$/.gradle" />
<option value="$PROJECT_DIR$/app/build" />
<option value="$PROJECT_DIR$/app/release" />
<option value="$PROJECT_DIR$/app/src/androidTest" />
<option value="$PROJECT_DIR$/app/src/test" />
<option value="$PROJECT_DIR$/app/src/androidTest" />
<option value="$PROJECT_DIR$/app/build" />
</list>
</option>
</component>

2
.idea/vcs.xml generated
View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -6,16 +6,27 @@ android {
applicationId "com.herbron.moodl"
minSdkVersion 19
targetSdkVersion 27
versionCode 5
versionName "0.0.5"
versionCode 7
versionName "0.1.7"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
aaptOptions {
additionalParameters "--no-version-vectors"
}
dataBinding {
enabled = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
lintOptions {
disable 'MissingTranslation'
checkReleaseBuilds false
//disable 'MissingTranslation'
}
}
}
@ -28,12 +39,12 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.mcxiaoke.volley:library:1.0.19'
implementation 'com.diogobernardino:williamchart:2.5.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.android.support:palette-v7:27.1.1'
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.8.5'
@ -45,11 +56,15 @@ dependencies {
implementation 'org.apache.commons:commons-lang3:3.6'
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'
implementation 'com.mattprecious.swirl:swirl:1.1.0'
implementation 'com.wdullaer:materialdatetimepicker:3.5.2'
implementation 'com.wdullaer:materialdatetimepicker:3.6.3'
implementation 'com.jmedeisis:draglinearlayout:1.1.0'
implementation 'com.applandeo:material-file-picker:1.0.0'
implementation 'com.daasuu:EasingInterpolator:1.0.0'
implementation 'com.android.support:support-vector-drawable:27.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation files('../libs/binance-api.jar')
implementation files('../libs/binance-api-forked.jar')
implementation files('../libs/commons-codec-1.11.jar')
}

View File

@ -2,11 +2,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.herbron.moodl">
<uses-feature android:name="android.hardware.fingerprint"
android:required="false"/>
<uses-feature
android:name="android.hardware.fingerprint"
android:required="false" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
@ -16,11 +18,11 @@
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name="com.herbron.moodl.Activities.HomeActivity"
android:name=".Activities.HomeActivity"
android:label="@string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"
android:launchMode="singleTop">
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -28,31 +30,38 @@
</intent-filter>
</activity>
<activity
android:name="com.herbron.moodl.Activities.SettingsActivity"
android:name=".Activities.SettingsActivity"
android:label="@string/title_activity_settings"
android:screenOrientation="portrait" />
<activity
android:name="com.herbron.moodl.Activities.CurrencySelectionActivity"
android:name=".Activities.CurrencyListActivity"
android:screenOrientation="portrait">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.herbron.moodl.Activities.HomeActivity"/>
android:value="com.herbron.moodl.Activities.HomeActivity" />
</activity>
<activity
android:name="com.herbron.moodl.Activities.RecordTransactionActivity"
android:screenOrientation="portrait">
android:name=".Activities.RecordTransactionActivity"
android:screenOrientation="portrait"
android:theme="@style/InputActivityTheme">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.herbron.moodl.Activities.HomeActivity"/>
android:value="com.herbron.moodl.Activities.HomeActivity" />
</activity>
<activity
android:name="com.herbron.moodl.Activities.CurrencyDetailsActivity"
android:name=".Activities.CurrencyDetailsActivity"
android:label="@string/title_activity_currency_details"
android:screenOrientation="portrait">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.herbron.moodl.Activities.HomeActivity"/>
android:value="com.herbron.moodl.Activities.HomeActivity" />
</activity>
<activity
android:name=".Activities.ExchangeListActivity"
android:label="@string/title_activity_exchange_list"
android:theme="@style/InputActivityTheme"/>
<activity android:name=".Activities.AddExchangeActivity"
android:theme="@style/InputActivityTheme"></activity>
</application>
</manifest>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,180 @@
package com.herbron.moodl.Activities;
import android.content.Intent;
import android.support.design.widget.TextInputEditText;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.AppCompatButton;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Spinner;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.ExchangeManager.Exchange;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.R;
public class AddExchangeActivity extends AppCompatActivity {
private LinearLayout setupExchangeLayout;
private Spinner exchangeSpinner;
private DatabaseManager databaseManager;
private TextInputEditText accountLabelEditText;
private TextInputEditText accountDescriptionEditText;
private TextInputEditText publicKeyEditText;
private TextInputEditText secretKeyEditText;
private AppCompatButton saveExchangeButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getApplicationContext().setTheme(R.style.InputActivityTheme);
setContentView(R.layout.activity_add_exchange);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
databaseManager = new DatabaseManager(getBaseContext());
exchangeSpinner = findViewById(R.id.exchange_spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.supported_exchanges, R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
setupExchangeLayout = findViewById(R.id.exchange_setup_layout);
exchangeSpinner.setAdapter(adapter);
Intent callingIntent = getIntent();
if(callingIntent.getBooleanExtra("isEdit", false))
{
startExchangeEditionForId(callingIntent.getIntExtra("exchangeId", -1));
}
else
{
exchangeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
loadLayoutFor(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
setupBackButton();
}
private void loadLayoutFor(int exchangeType)
{
setupExchangeLayout.removeAllViews();
exchangeSpinner.setSelection(exchangeType);
switch (exchangeType)
{
case DatabaseManager.BINANCE_TYPE:
setupExchangeLayout = (LinearLayout) LayoutInflater.from(getBaseContext()).inflate(R.layout.binance_exchange_setup_layout, setupExchangeLayout, true);
bindSetupViews();
break;
case DatabaseManager.HITBTC_TYPE:
setupExchangeLayout = (LinearLayout) LayoutInflater.from(getBaseContext()).inflate(R.layout.hitbtc_exchange_setup_layout, setupExchangeLayout, true);
bindSetupViews();
break;
}
}
private void startExchangeEditionForId(int exchangeId)
{
Exchange exchangeInfos = databaseManager.getExchangeFromId(exchangeId);
loadLayoutFor(exchangeInfos.getType());
exchangeSpinner.setEnabled(false);
accountLabelEditText.setText(exchangeInfos.getName());
accountDescriptionEditText.setText(exchangeInfos.getDescription());
publicKeyEditText.setText(exchangeInfos.getPublicKey());
secretKeyEditText.setText(exchangeInfos.getPrivateKey());
saveExchangeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isEditTextFilled(accountLabelEditText) && isEditTextFilled(publicKeyEditText) && isEditTextFilled(secretKeyEditText))
{
PreferencesManager preferencesManager = new PreferencesManager(getBaseContext());
preferencesManager.setMustUpdateSummary(true);
databaseManager.deleteExchangeAccountFromId(exchangeInfos.getId());
databaseManager.addExchange(accountLabelEditText.getText().toString(), exchangeSpinner.getSelectedItemPosition()
, accountDescriptionEditText.getText().toString(), publicKeyEditText.getText().toString()
, secretKeyEditText.getText().toString());
finish();
}
}
});
}
private void bindSetupViews()
{
accountLabelEditText = findViewById(R.id.account_label_editText);
accountDescriptionEditText = findViewById(R.id.account_description_editText);
publicKeyEditText = findViewById(R.id.publicKey_editText);
secretKeyEditText = findViewById(R.id.secretKey_editText);
saveExchangeButton = findViewById(R.id.saveExchangeButton);
saveExchangeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isEditTextFilled(accountLabelEditText) && isEditTextFilled(publicKeyEditText) && isEditTextFilled(secretKeyEditText))
{
PreferencesManager preferencesManager = new PreferencesManager(getBaseContext());
preferencesManager.setMustUpdateSummary(true);
databaseManager.addExchange(accountLabelEditText.getText().toString(), exchangeSpinner.getSelectedItemPosition()
, accountDescriptionEditText.getText().toString(), publicKeyEditText.getText().toString()
, secretKeyEditText.getText().toString());
finish();
}
}
});
}
private boolean isEditTextFilled(TextInputEditText editText)
{
if(editText.getText().toString().equals("") || editText.getText().toString().equals(" "))
{
editText.setError(getResources().getString(R.string.must_be_filled));
return false;
}
return true;
}
private void setupBackButton()
{
ImageButton backButton = findViewById(R.id.back_button);
backButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}

View File

@ -1,11 +1,11 @@
package com.herbron.moodl.Activities;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.CardView;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
@ -16,24 +16,33 @@ import android.widget.ListView;
import android.widget.SearchView;
import android.widget.Toast;
import com.herbron.moodl.DataManagers.BalanceManager;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CoinmarketCapAPIManager;
import com.herbron.moodl.DataNotifiers.CoinmarketcapNotifierInterface;
import com.herbron.moodl.DataNotifiers.CryptocompareNotifierInterface;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyDetailsList;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CryptocompareApiManager;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.LayoutManagers.CurrencyListAdapter;
import com.herbron.moodl.CustomAdapters.CoinWatchlistAdapter;
import com.herbron.moodl.R;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
public class CurrencySelectionActivity extends AppCompatActivity implements SearchView.OnQueryTextListener{
public class CurrencyListActivity extends AppCompatActivity implements SearchView.OnQueryTextListener, CryptocompareNotifierInterface, CoinmarketcapNotifierInterface {
private CurrencyListAdapter adapter;
private CoinWatchlistAdapter adapter;
private ListView listView;
private android.widget.Filter filter;
private CurrencyDetailsList currencyDetailsList;
private boolean isWatchList;
private CryptocompareApiManager cryptocompareApiManager;
private CoinmarketCapAPIManager coinmarketCapAPIManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -42,14 +51,15 @@ public class CurrencySelectionActivity extends AppCompatActivity implements Sear
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_add_currency);
setContentView(R.layout.activity_currency_list);
currencyDetailsList = CurrencyDetailsList.getInstance(this);
cryptocompareApiManager = CryptocompareApiManager.getInstance(this);
cryptocompareApiManager.addListener(this);
setTitle("Select a coin");
coinmarketCapAPIManager = CoinmarketCapAPIManager.getInstance(this);
coinmarketCapAPIManager.addListener(this);
Intent intent = getIntent();
isWatchList = intent.getBooleanExtra("isWatchList", false);
setTitle(getString(R.string.select_coin));
ListLoader listLoader = new ListLoader();
listLoader.execute();
@ -67,17 +77,7 @@ public class CurrencySelectionActivity extends AppCompatActivity implements Sear
private void setupAdapter()
{
List<String> currencyNames = currencyDetailsList.getCurrenciesName();
List<String> currencySymbols = currencyDetailsList.getCurrenciesSymbol();
ArrayList<Currency> currencyArrayList = new ArrayList<>();
for(int i = 0; i < currencyNames.size(); i++)
{
currencyArrayList.add(new Currency(currencyNames.get(i), currencySymbols.get(i)));
}
adapter = new CurrencyListAdapter(this, currencyArrayList);
adapter = new CoinWatchlistAdapter(this, new ArrayList<>(coinmarketCapAPIManager.getTotalListing()));
}
private void setupList()
@ -92,26 +92,16 @@ public class CurrencySelectionActivity extends AppCompatActivity implements Sear
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Currency selectedCurrency = (Currency) adapterView.getItemAtPosition(i);
if(isWatchList)
{
PreferencesManager preferencesManager = new PreferencesManager(getApplicationContext());
DatabaseManager databaseManager = new DatabaseManager(getApplicationContext());
PreferencesManager preferencesManager = new PreferencesManager(getApplicationContext());
DatabaseManager databaseManager = new DatabaseManager(getApplicationContext());
if(databaseManager.addCurrencyToWatchlist(selectedCurrency))
{
preferencesManager.setMustUpdateWatchlist(true);
}
else
{
Toast.makeText(getApplicationContext(), "Currency already in watchlist.", Toast.LENGTH_SHORT).show();
}
if(databaseManager.addCurrencyToWatchlist(selectedCurrency))
{
preferencesManager.setMustUpdateWatchlist(true);
}
else
{
Intent intent = new Intent(CurrencySelectionActivity.this, RecordTransactionActivity.class);
intent.putExtra("coin", selectedCurrency.getName());
intent.putExtra("symbol", selectedCurrency.getSymbol());
startActivity(intent);
Toast.makeText(getApplicationContext(), getString(R.string.already_watchlist), Toast.LENGTH_SHORT).show();
}
finish();
@ -165,17 +155,50 @@ public class CurrencySelectionActivity extends AppCompatActivity implements Sear
private void detailsEvent()
{
runOnUiThread(new Runnable() {
@Override
public void run() {
setupAdapter();
setupList();
setupSearchView();
if(coinmarketCapAPIManager.isUpToDate() && cryptocompareApiManager.isDetailsUpToDate())
{
runOnUiThread(new Runnable() {
@Override
public void run() {
setupAdapter();
setupList();
setupSearchView();
expand(findViewById(R.id.listContainerLayout));
findViewById(R.id.currencyListProgressBar).setVisibility(View.GONE);
}
});
expand(findViewById(R.id.listContainerLayout));
findViewById(R.id.currencyListProgressBar).setVisibility(View.GONE);
}
});
}
}
@Override
public void onDetailsUpdated() {
detailsEvent();
}
@Override
public void onExchangesUpdated() {
}
@Override
public void onCurrenciesRetrieved(List<Currency> currencyList) {
}
@Override
public void onTopCurrenciesUpdated() {
}
@Override
public void onMarketCapUpdated() {
}
@Override
public void onListingUpdated() {
detailsEvent();
}
private class ListLoader extends AsyncTask<Void, Integer, Void>
@ -200,14 +223,17 @@ public class CurrencySelectionActivity extends AppCompatActivity implements Sear
Looper.prepare();
}
if(!currencyDetailsList.isUpToDate())
if(!cryptocompareApiManager.isDetailsUpToDate() || !coinmarketCapAPIManager.isUpToDate())
{
currencyDetailsList.update(new BalanceManager.IconCallBack() {
@Override
public void onSuccess() {
detailsEvent();
}
});
if(!cryptocompareApiManager.isDetailsUpToDate())
{
cryptocompareApiManager.updateDetails();
}
if(!coinmarketCapAPIManager.isUpToDate())
{
coinmarketCapAPIManager.updateListing();
}
}
else
{

View File

@ -2,7 +2,6 @@ package com.herbron.moodl.Activities.DetailsActivityFragments;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -11,8 +10,10 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import com.github.mikephil.charting.charts.BarChart;
@ -29,12 +30,13 @@ import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.herbron.moodl.CurrencyInfoUpdateNotifierInterface;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyDataChart;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.LayoutManagers.CustomViewPager;
import com.herbron.moodl.CustomLayouts.CustomViewPager;
import com.herbron.moodl.MoodlBox;
import com.herbron.moodl.PlaceholderManager;
import com.herbron.moodl.Utils.PlaceholderUtils;
import com.herbron.moodl.R;
import java.util.ArrayList;
@ -47,7 +49,7 @@ import static com.herbron.moodl.MoodlBox.numberConformer;
* Created by Tiji on 13/05/2018.
*/
public class Home extends Fragment {
public class ChartsFragment extends Fragment implements CurrencyInfoUpdateNotifierInterface {
private final static int HOUR = 0;
private final static int DAY = 1;
@ -68,20 +70,24 @@ public class Home extends Fragment {
private Button lineChartButton;
private Button candleStickChartButton;
private Spinner timeIntervalSpinner;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
view = inflater.inflate(R.layout.fragment_home_detailsactivity, container, false);
view = inflater.inflate(R.layout.detailsactivity_fragment_charts, container, false);
currency = getActivity().getIntent().getParcelableExtra("currency");
currency.setListener(this);
lineChart = view.findViewById(R.id.chartPriceView);
candleStickChart = view.findViewById(R.id.chartCandleStickView);
lineChartButton = view.findViewById(R.id.lineChartButton);
candleStickChartButton = view.findViewById(R.id.candleStickChartButton);
barChart = view.findViewById(R.id.chartVolumeView);
preferencesManager = new PreferencesManager(getContext());
preferencesManager = new PreferencesManager(getActivity().getBaseContext());
displayLineChart = true;
@ -111,15 +117,78 @@ public class Home extends Fragment {
}
});
initializeButtons();
initializeLineChart(lineChart);
initializeCandleStickChart(candleStickChart);
updateChartTab(DAY, 1);
initializeSpinners();
return view;
}
private void initializeSpinners()
{
timeIntervalSpinner = view.findViewById(R.id.timeIntervalSinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getActivity().getBaseContext(),
R.array.time_interval_string_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
timeIntervalSpinner.setAdapter(adapter);
timeIntervalSpinner.setSelection(2);
timeIntervalSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
updateCharts(i);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
private void updateCharts(int index)
{
view.findViewById(R.id.chartPriceView).setVisibility(View.GONE);
view.findViewById(R.id.chartCandleStickView).setVisibility(View.GONE);
view.findViewById(R.id.chartVolumeView).setVisibility(View.GONE);
view.findViewById(R.id.progressLayoutChart).setVisibility(View.VISIBLE);
switch (index)
{
case 0:
currency.updateHistoryMinutes(getActivity().getBaseContext(), preferencesManager.getDefaultCurrency());
break;
case 1:
currency.updateHistoryMinutes(getActivity().getBaseContext(), preferencesManager.getDefaultCurrency());
break;
case 2:
currency.updateHistoryMinutes(getActivity().getBaseContext(), preferencesManager.getDefaultCurrency());
break;
case 3:
currency.updateHistoryHours(getActivity().getBaseContext(), preferencesManager.getDefaultCurrency());
break;
case 4:
currency.updateHistoryHours(getActivity().getBaseContext(), preferencesManager.getDefaultCurrency());
break;
case 5:
currency.updateHistoryHours(getActivity().getBaseContext(), preferencesManager.getDefaultCurrency());
break;
case 6:
currency.updateHistoryDays(getActivity().getBaseContext(), preferencesManager.getDefaultCurrency());
break;
case 7:
currency.updateHistoryDays(getActivity().getBaseContext(), preferencesManager.getDefaultCurrency());
break;
case 8:
currency.updateHistoryDays(getActivity().getBaseContext(), preferencesManager.getDefaultCurrency());
break;
}
}
private void initializeCandleStickChart(CandleStickChart candleStickChart)
{
candleStickChart.setDrawGridBackground(false);
@ -148,189 +217,20 @@ public class Home extends Fragment {
lineChart.getLegend().setEnabled(false);
lineChart.getXAxis().setEnabled(false);
lineChart.setViewPortOffsets(0, 0, 0, 0);
}
private void initializeButtons()
{
LinearLayout buttonLayout = view.findViewById(R.id.layoutChartButtons);
for(int i = 0; i < buttonLayout.getChildCount(); i++)
{
final Button button = (Button) buttonLayout.getChildAt(i);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
buttonEvent(v);
}
});
}
}
private void buttonEvent(View v)
{
v.setEnabled(false);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
v.setElevation(MoodlBox.convertDpToPx(8, getResources()));
}
LinearLayout buttonLayout = (LinearLayout) v.getParent();
for(int i = 0; i < buttonLayout.getChildCount(); i++)
{
Button button = (Button) buttonLayout.getChildAt(i);
if(button != v)
{
button.setEnabled(true);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
button.setElevation(MoodlBox.convertDpToPx(2, getResources()));
}
}
}
updateCharts((Button) v);
}
private void updateCharts(Button button)
{
view.findViewById(R.id.chartPriceView).setVisibility(View.GONE);
view.findViewById(R.id.chartCandleStickView).setVisibility(View.GONE);
view.findViewById(R.id.chartVolumeView).setVisibility(View.GONE);
view.findViewById(R.id.progressLayoutChart).setVisibility(View.VISIBLE);
String interval = button.getText().toString().substring(button.getText().toString().length()-2);
switch (interval)
{
case "1h":
currency.updateHistoryMinutes(getContext(), preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
@Override
public void onSuccess(Currency currency) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateChartTab(Home.HOUR, 1);
}
});
}
});
break;
case "3h":
currency.updateHistoryMinutes(getContext(), preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
@Override
public void onSuccess(Currency currency) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateChartTab(Home.HOUR, 3);
}
});
}
});
break;
case "1d":
currency.updateHistoryMinutes(getContext(), preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
@Override
public void onSuccess(Currency currency) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateChartTab(Home.DAY, 1);
}
});
}
});
break;
case "3d":
currency.updateHistoryHours(getContext(), preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
@Override
public void onSuccess(Currency currency) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateChartTab(Home.DAY, 3);
}
});
}
});
break;
case "1w":
currency.updateHistoryHours(getContext(), preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
@Override
public void onSuccess(Currency currency) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateChartTab(Home.WEEK, 11);
}
});
}
});
break;
case "1M":
currency.updateHistoryHours(getContext(), preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
@Override
public void onSuccess(Currency currency) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateChartTab(Home.MONTH, 1);
}
});
}
});
break;
case "3M":
currency.updateHistoryDays(getContext(), preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
@Override
public void onSuccess(Currency currency) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateChartTab(Home.MONTH, 3);
}
});
}
});
break;
case "6M":
currency.updateHistoryDays(getContext(), preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
@Override
public void onSuccess(Currency currency) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateChartTab(Home.MONTH, 6);
}
});
}
});
break;
case "1y":
currency.updateHistoryDays(getContext(), preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
@Override
public void onSuccess(Currency currency) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateChartTab(Home.YEAR, 1);
}
});
}
});
break;
}
lineChart.setNoDataTextColor(currency.getChartColor());
}
private void updateChartTab(int timeUnit, int amount)
{
updateChartsData(timeUnit, amount);
drawPriceLineChart();
drawPriceCandleStickChart();
if(currency.getHistoryMinutes() != null)
{
drawPriceLineChart();
drawPriceCandleStickChart();
drawVolumeChart();
updateGeneralData(lineChart.getData().getDataSets().get(0).getEntryForIndex(0).getY(), lineChart.getData().getDataSets().get(0).getEntryForIndex(lineChart.getData().getDataSets().get(0).getEntryCount() - 1).getY());
}
if(displayLineChart)
{
@ -342,9 +242,6 @@ public class Home extends Fragment {
view.findViewById(R.id.chartCandleStickView).setVisibility(View.VISIBLE);
view.findViewById(R.id.progressLayoutChart).setVisibility(View.GONE);
}
drawVolumeChart();
updateGeneralData(lineChart.getData().getDataSets().get(0).getEntryForIndex(0).getY(), lineChart.getData().getDataSets().get(0).getEntryForIndex(lineChart.getData().getDataSets().get(0).getEntryCount() - 1).getY());
}
private void updateGeneralData(float start, float end)
@ -355,8 +252,8 @@ public class Home extends Fragment {
updateFluctuation(start, end);
((TextView) view.findViewById(R.id.txtViewPriceStart)).setText(PlaceholderManager.getValueString(numberConformer(start), getContext()));
((TextView) view.findViewById(R.id.txtViewPriceNow)).setText(PlaceholderManager.getValueString(numberConformer(end), getContext()));
((TextView) view.findViewById(R.id.txtViewPriceStart)).setText(PlaceholderUtils.getValueString(numberConformer(start), getActivity().getBaseContext()));
((TextView) view.findViewById(R.id.txtViewPriceNow)).setText(PlaceholderUtils.getValueString(numberConformer(end), getActivity().getBaseContext()));
for(int i = 1; i < dataChartList.size(); i++)
{
@ -373,9 +270,9 @@ public class Home extends Fragment {
}
}
((TextView) view.findViewById(R.id.totalVolume)).setText(PlaceholderManager.getValueString(numberConformer(totalVolume), getContext()));
((TextView) view.findViewById(R.id.highestPrice)).setText(PlaceholderManager.getValueString(numberConformer(highestPrice), getContext()));
((TextView) view.findViewById(R.id.lowestPrice)).setText(PlaceholderManager.getValueString(numberConformer(lowestPrice), getContext()));
((TextView) view.findViewById(R.id.totalVolume)).setText(PlaceholderUtils.getValueString(numberConformer(totalVolume), getActivity().getBaseContext()));
((TextView) view.findViewById(R.id.highestPrice)).setText(PlaceholderUtils.getValueString(numberConformer(highestPrice), getActivity().getBaseContext()));
((TextView) view.findViewById(R.id.lowestPrice)).setText(PlaceholderUtils.getValueString(numberConformer(lowestPrice), getActivity().getBaseContext()));
}
private void updateFluctuation(float start, float end)
@ -560,9 +457,9 @@ public class Home extends Fragment {
date = getDateFromTimestamp(dataChartList.get(index).getTimestamp() * 1000);
}
volumePlaceholder = PlaceholderManager.getVolumeString(numberConformer(barChart.getData().getDataSets().get(0).getEntryForIndex(index).getY()), getContext());
pricePlaceholder = PlaceholderManager.getPriceString(numberConformer((lineChart.getHighlighted())[0].getY()), getContext());
timestampPlaceholder = PlaceholderManager.getTimestampString(date, getContext());
volumePlaceholder = PlaceholderUtils.getVolumeString(numberConformer(barChart.getData().getDataSets().get(0).getEntryForIndex(index).getY()), getActivity().getBaseContext());
pricePlaceholder = PlaceholderUtils.getPriceString(numberConformer((lineChart.getHighlighted())[0].getY()), getActivity().getBaseContext());
timestampPlaceholder = PlaceholderUtils.getTimestampString(date, getActivity().getBaseContext());
((TextView) view.findViewById(R.id.volumeHightlight)).setText(volumePlaceholder);
view.findViewById(R.id.volumeHightlight).setVisibility(View.VISIBLE);
@ -602,6 +499,7 @@ public class Home extends Fragment {
dataSet.setHighlightEnabled(true);
dataSet.setDrawHorizontalHighlightIndicator(false);
dataSet.setHighLightColor(currency.getChartColor());
dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
return new LineData(dataSet);
}
@ -647,14 +545,14 @@ public class Home extends Fragment {
dataSet = new CandleDataSet(values, "");
dataSet.setDrawIcons(false);
dataSet.setDrawValues(false);
dataSet.setDecreasingColor(MoodlBox.getColor(R.color.decreaseCandle, getContext()));
dataSet.setDecreasingColor(MoodlBox.getColor(R.color.decreaseCandle, getActivity().getBaseContext()));
dataSet.setShowCandleBar(true);
dataSet.setShadowColorSameAsCandle(true);
dataSet.setDecreasingPaintStyle(Paint.Style.FILL);
dataSet.setIncreasingColor(MoodlBox.getColor(R.color.increaseCandle, getContext()));
dataSet.setIncreasingColor(MoodlBox.getColor(R.color.increaseCandle, getActivity().getBaseContext()));
dataSet.setIncreasingPaintStyle(Paint.Style.STROKE);
dataSet.setNeutralColor(MoodlBox.getColor(R.color.increaseCandle, getContext()));
dataSet.setHighLightColor(MoodlBox.getColor(R.color.colorAccent, getContext()));
dataSet.setNeutralColor(MoodlBox.getColor(R.color.increaseCandle, getActivity().getBaseContext()));
dataSet.setHighLightColor(MoodlBox.getColor(R.color.colorAccent, getActivity().getBaseContext()));
dataSet.setDrawHorizontalHighlightIndicator(false);
return new CandleData(dataSet);
@ -662,12 +560,15 @@ public class Home extends Fragment {
private void updateChartsData(int timeUnit, int amount)
{
dataChartList = new ArrayList<>();
dataChartList = null;
switch (timeUnit)
{
case HOUR:
dataChartList = currency.getHistoryMinutes().subList(currency.getHistoryMinutes().size()-(60*amount), currency.getHistoryMinutes().size());
if(currency.getHistoryMinutes() != null)
{
dataChartList = currency.getHistoryMinutes().subList(currency.getHistoryMinutes().size()-(60*amount), currency.getHistoryMinutes().size());
}
break;
case DAY:
if(amount == 1)
@ -676,11 +577,17 @@ public class Home extends Fragment {
}
else
{
dataChartList = currency.getHistoryHours().subList(currency.getHistoryHours().size()-(24*amount), currency.getHistoryHours().size());
if(currency.getHistoryHours() != null)
{
dataChartList = currency.getHistoryHours().subList(currency.getHistoryHours().size()-(24*amount), currency.getHistoryHours().size());
}
}
break;
case WEEK:
dataChartList = currency.getHistoryHours().subList(currency.getHistoryHours().size()-168, currency.getHistoryHours().size());
if(currency.getHistoryHours() != null)
{
dataChartList = currency.getHistoryHours().subList(currency.getHistoryHours().size()-168, currency.getHistoryHours().size());
}
break;
case MONTH:
switch (amount)
@ -689,10 +596,16 @@ public class Home extends Fragment {
dataChartList = currency.getHistoryHours();
break;
case 3:
dataChartList = currency.getHistoryDays().subList(currency.getHistoryDays().size()-93, currency.getHistoryDays().size());
if(currency.getHistoryDays() != null)
{
dataChartList = currency.getHistoryDays().subList(currency.getHistoryDays().size()-93, currency.getHistoryDays().size());
}
break;
case 6:
dataChartList = currency.getHistoryDays().subList(currency.getHistoryDays().size()-186, currency.getHistoryDays().size());
if(currency.getHistoryDays() != null)
{
dataChartList = currency.getHistoryDays().subList(currency.getHistoryDays().size()-186, currency.getHistoryDays().size());
}
break;
}
break;
@ -702,4 +615,52 @@ public class Home extends Fragment {
}
}
@Override
public void onTimestampPriceUpdated(String price) {
}
@Override
public void onHistoryDataUpdated() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
switch (timeIntervalSpinner.getSelectedItemPosition())
{
case 0:
updateChartTab(ChartsFragment.HOUR, 1);
break;
case 1:
updateChartTab(ChartsFragment.HOUR, 3);
break;
case 2:
updateChartTab(ChartsFragment.DAY, 1);
break;
case 3:
updateChartTab(ChartsFragment.DAY, 3);
break;
case 4:
updateChartTab(ChartsFragment.WEEK, 11);
break;
case 5:
updateChartTab(ChartsFragment.MONTH, 1);
break;
case 6:
updateChartTab(ChartsFragment.MONTH, 3);
break;
case 7:
updateChartTab(ChartsFragment.MONTH, 6);
break;
case 8:
updateChartTab(ChartsFragment.YEAR, 1);
break;
}
}
});
}
@Override
public void onPriceUpdated(Currency currency) {
}
}

View File

@ -9,6 +9,7 @@ import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -17,7 +18,7 @@ import android.widget.TextView;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.PlaceholderManager;
import com.herbron.moodl.Utils.PlaceholderUtils;
import com.herbron.moodl.R;
import static com.herbron.moodl.MoodlBox.numberConformer;
@ -26,7 +27,7 @@ import static com.herbron.moodl.MoodlBox.numberConformer;
* Created by Tiji on 13/05/2018.
*/
public class Informations extends Fragment {
public class InformationFragment extends Fragment {
private Currency currency;
private View view;
@ -38,13 +39,13 @@ public class Informations extends Fragment {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
view = inflater.inflate(R.layout.fragment_informations_detailsactivity, container, false);
view = inflater.inflate(R.layout.detailsactivity_fragment_informations, container, false);
isSnapshotUpdated = false;
isTickerUpdated = false;
currency = getActivity().getIntent().getParcelableExtra("currency");
preferencesManager = new PreferencesManager(getContext());
preferencesManager = new PreferencesManager(getActivity().getBaseContext());
updateInfoTab();
@ -53,7 +54,7 @@ public class Informations extends Fragment {
private void updateInfoTab()
{
currency.updateSnapshot(getContext(), new Currency.CurrencyCallBack() {
currency.updateSnapshot(getActivity().getBaseContext(), new Currency.CurrencyCallBack() {
@Override
public void onSuccess(final Currency currency) {
isSnapshotUpdated = true;
@ -61,7 +62,7 @@ public class Informations extends Fragment {
}
});
currency.updateTicker(getContext(), preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
currency.updateTicker(getActivity().getBaseContext(), preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
@Override
public void onSuccess(Currency currency) {
isTickerUpdated = true;
@ -74,12 +75,16 @@ public class Informations extends Fragment {
{
if(isTickerUpdated && isSnapshotUpdated)
{
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
refreshInfoTab();
}
});
try {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
refreshInfoTab();
}
});
} catch (NullPointerException e) {
Log.d("moodl", "Information tab do not needs to be updated anymore");
}
}
}
@ -120,12 +125,12 @@ public class Informations extends Fragment {
((TextView) view.findViewById(R.id.txtViewDescription))
.setMovementMethod(LinkMovementMethod.getInstance());
((TextView) view.findViewById(R.id.txtViewPercentageCoinEmited))
.setText("Percentage of coin emited : " + numberConformer(currency.getMinedCoinSupply() / currency.getMaxCoinSupply() * 100) + "%");
.setText(PlaceholderUtils.getEmitedPercentageString(numberConformer(currency.getMinedCoinSupply() / currency.getMaxCoinSupply() * 100), getActivity().getBaseContext()));
if(currency.getMarketCapitalization() != 0)
{
((TextView) view.findViewById(R.id.txtViewMarketCapitalization))
.setText(PlaceholderManager.getValueString(numberConformer(currency.getMarketCapitalization()), getContext()));
.setText(PlaceholderUtils.getValueString(numberConformer(currency.getMarketCapitalization()), getActivity().getBaseContext()));
view.findViewById(R.id.linearMarketCap).setVisibility(View.VISIBLE);
}
@ -139,15 +144,15 @@ public class Informations extends Fragment {
if(currency.getMaxCoinSupply() == 0)
{
((TextView) view.findViewById(R.id.txtViewTotalSupply))
.setText(PlaceholderManager.getSymbolString("Infinity", getActivity()));
.setText(PlaceholderUtils.getSymbolString(getString(R.string.infinity), getActivity()));
}
else
{
((TextView) view.findViewById(R.id.txtViewTotalSupply))
.setText(PlaceholderManager.getSymbolString(numberConformer(currency.getMaxCoinSupply()), getActivity()));
.setText(PlaceholderUtils.getSymbolString(numberConformer(currency.getMaxCoinSupply()), getActivity()));
}
((TextView) view.findViewById(R.id.txtViewCirculatingSupply))
.setText(PlaceholderManager.getSymbolString(numberConformer(currency.getMinedCoinSupply()), getActivity()));
.setText(PlaceholderUtils.getSymbolString(numberConformer(currency.getMinedCoinSupply()), getActivity()));
}
}

View File

@ -1,79 +1,355 @@
package com.herbron.moodl.Activities.DetailsActivityFragments;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.ProgressBar;
import com.herbron.moodl.DataNotifiers.BinanceUpdateNotifierInterface;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.Trade;
import com.herbron.moodl.DataManagers.CurrencyData.Transaction;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.ExchangeManager.BinanceManager;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.LayoutManagers.TradeListAdapter;
import com.herbron.moodl.LayoutManagers.TransactionListAdapter;
import com.herbron.moodl.CustomAdapters.TransactionListAdapter;
import com.herbron.moodl.R;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Created by Tiji on 13/05/2018.
*/
public class Transactions extends Fragment {
public class TransactionsFragment extends Fragment {
private Currency currency;
private View loadingFooter;
private View view;
private ListView tradeLayout;
//private ListView tradeLayout;
private ListView transactionLayout;
private boolean flag_loading;
private BinanceManager binanceManager;
private List<BinanceManager> binanceManagerList;
private DatabaseManager databaseManager;
private TradeListAdapter tradeListAdapter;
private ArrayList<com.herbron.moodl.DataManagers.CurrencyData.Trade> returnedTrades;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
view = inflater.inflate(R.layout.fragment_transactions_detailsactivity, container, false);
view = inflater.inflate(R.layout.detailsactivity_fragment_transactions, container, false);
PreferencesManager preferencesManager = new PreferencesManager(getContext());
PreferencesManager preferencesManager = new PreferencesManager(getActivity().getBaseContext());
currency = getActivity().getIntent().getParcelableExtra("currency");
databaseManager = new DatabaseManager(getContext());
binanceManager = new BinanceManager(preferencesManager.getBinancePublicKey(), preferencesManager.getBinancePrivateKey());
tradeLayout = view.findViewById(R.id.listTrades);
databaseManager = new DatabaseManager(getActivity().getBaseContext());
binanceManagerList = databaseManager.getBinanceAccounts();
//tradeLayout = view.findViewById(R.id.listTrades);
transactionLayout = view.findViewById(R.id.listTransactions);
flag_loading = false;
TransactionUpdater transactionUpdater = new TransactionUpdater();
transactionUpdater.execute();
TradeUpdater updater = new TradeUpdater();
updater.execute();
return view;
}
private void loadingIndicatorGenerator()
private class TransactionUpdater extends AsyncTask<Void, Integer, Void> implements BinanceUpdateNotifierInterface
{
loadingFooter = LayoutInflater.from(getContext()).inflate(R.layout.listview_loading_indicator, null, false);
private ArrayList<Object> displayedTransactions;
private int nbTradeAccountUpdated;
private int nbTransactionAccountUpdated;
@Override
protected void onPreExecute() {
super.onPreExecute();
displayedTransactions = new ArrayList<>();
nbTradeAccountUpdated = 0;
nbTransactionAccountUpdated = 0;
}
@Override
protected Void doInBackground(Void... voids) {
if(Looper.myLooper() == null)
{
Looper.prepare();
}
displayedTransactions.addAll(databaseManager.getCurrencyTransactionsForSymbol(currency.getSymbol()));
for(int i = 0; i < binanceManagerList.size(); i++)
{
binanceManagerList.get(i).addListener(this);
binanceManagerList.get(i).updateTrades(currency.getSymbol());
binanceManagerList.get(i).updateTransactions(currency.getSymbol());
}
if(nbTradeAccountUpdated == binanceManagerList.size())
{
drawTransactionList(displayedTransactions);
}
return null;
}
@Override
public void onBinanceTradesUpdated(List<Trade> trades) {
nbTradeAccountUpdated++;
displayedTransactions.addAll(trades);
if(nbTradeAccountUpdated == binanceManagerList.size())
{
drawTransactionList(displayedTransactions);
}
}
@Override
public void onBinanceBalanceUpdateSuccess() {
}
@Override
public void onBinanceBalanceUpdateError(int accountId, String error) {
}
private void drawTransactionList(ArrayList<Object> transactions)
{
Collections.sort(transactions, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
Long time1;
Long time2;
if(o1 instanceof Transaction)
{
time1 = ((Transaction) o1).getTimestamp();
}
else
{
time1 = ((Trade) o1).getTime();
}
if(o2 instanceof Transaction)
{
time2 = ((Transaction) o2).getTimestamp();
}
else
{
time2 = ((Trade) o2).getTime();
}
return time2.compareTo(time1);
}
});
if(getActivity() != null)
{
TransactionListAdapter transactionListAdapter = new TransactionListAdapter(getActivity(), transactions);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
transactionLayout.setAdapter(transactionListAdapter);
transactionLayout.setTextFilterEnabled(false);
}
});
}
}
}
/*public class TransactionUpdater extends AsyncTask<Void, Integer, Void>
{
@Override
protected Void doInBackground(Void... voids) {
if(Looper.myLooper() == null)
{
Looper.prepare();
}
//binanceManager.updateTransactions(currency.getSymbol());
final ArrayList<Transaction> transactionList = databaseManager.getCurrencyTransactionsForSymbol(currency.getSymbol());
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
drawTransactionList(transactionList);
}
});
return null;
}
}*/
/*private class TradeAdder extends AsyncTask<Void, Integer, Void>
{
@Override
protected void onPreExecute()
{
super.onPreExecute();
loadingIndicatorGenerator();
}
@Override
protected Void doInBackground(Void... voids) {
final ArrayList<Trade> trades = new ArrayList<>();
for(int i = tradeLayout.getCount(); i < tradeLayout.getCount() + 20 && i < returnedTrades.size(); i++)
{
trades.add(returnedTrades.get(i));
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
tradeListAdapter.addAll(trades);
tradeListAdapter.notifyDataSetChanged();
flag_loading = false;
tradeLayout.removeFooterView(loadingFooter);
}
});
binanceManager.updateTrades(new BinanceManager.BinanceCallBack() {
@Override
public void onSuccess() {
ArrayList<com.nauk.moodl.DataManagers.CurrencyData.Trade> trades = binanceManager.getTrades();
final ArrayList<com.nauk.moodl.DataManagers.CurrencyData.Trade> returnedTrades = new ArrayList<>();
for(int i = trades.size() - 1; i > 0 ; i--)
{
returnedTrades.add(trades.get(i));
}
runOnUiThread(new Runnable() {
@Override
public void run() {
tradeListAdapter.addAll(returnedTrades);
tradeListAdapter.notifyDataSetChanged();
flag_loading = false;
tradeLayout.removeFooterView(loadingFooter);
}
});
}
@Override
public void onError(String error) {
}
}, currency.getSymbol(), tradeListAdapter.getItem(tradeListAdapter.getCount() - 1).getId());
return null;
}
}*/
/*private void drawTransactionList(ArrayList<Transaction> transactions)
{
TransactionListAdapter transactionListAdapter = new TransactionListAdapter(getActivity(), transactions);
transactionLayout.setAdapter(transactionListAdapter);
transactionLayout.setTextFilterEnabled(false);
}
private class TradeUpdater extends AsyncTask<Void, Integer, Void> implements BinanceUpdateNotifierInterface
{
private List<Trade> trades;
private int nbResponse;
@Override
protected void onPreExecute()
{
super.onPreExecute();
trades = new ArrayList<>();
nbResponse = 0;
}
@Override
protected void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
}
@Override
protected Void doInBackground(Void... params)
{
for(int i = 0; i < binanceManagerList.size(); i++)
{
binanceManagerList.get(i).addListener(this);
binanceManagerList.get(i).updateTrades(currency.getSymbol());
}
return null;
}
@Override
protected void onPostExecute(Void result)
{
}
@Override
public void onBinanceTradesUpdated(List<Trade> newTrades) {
trades.addAll(newTrades);
nbResponse++;
if(nbResponse == binanceManagerList.size())
{
returnedTrades = new ArrayList<>();
for(int i = trades.size() - 1; i >= 0 ; i--)
{
returnedTrades.add(trades.get(i));
}
try {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
ArrayList<Trade> trades = new ArrayList<>();
for(int i = 0; i < 20 && i < returnedTrades.size(); i++)
{
trades.add(returnedTrades.get(i));
}
//drawTradeList(trades);
}
});
} catch (NullPointerException e) {
Log.d("moodl", "TransactionsFragment do not need to be updated anymore");
}
}
}
@Override
public void onBinanceBalanceUpdateSuccess() {
}
@Override
public void onBinanceBalanceUpdateError(int accountId, String error) {
}
}*/
/*private void loadingIndicatorGenerator()
{
loadingFooter = LayoutInflater.from(getActivity().getBaseContext()).inflate(R.layout.listview_loading_indicator, null, false);
Drawable drawable = ((ProgressBar) loadingFooter.findViewById(R.id.progressIndicator)).getIndeterminateDrawable();
drawable.mutate();
@ -109,166 +385,11 @@ public class Transactions extends Fragment {
});
}
tradeListAdapter = new TradeListAdapter(getContext(), trades);
tradeListAdapter = new TradeListAdapter(getActivity().getBaseContext(), trades);
tradeLayout.setAdapter(tradeListAdapter);
tradeLayout.setTextFilterEnabled(false);
view.findViewById(R.id.tradeLoaderIndicator).setVisibility(View.GONE);
}
private class TradeAdder extends AsyncTask<Void, Integer, Void>
{
@Override
protected void onPreExecute()
{
super.onPreExecute();
loadingIndicatorGenerator();
}
@Override
protected Void doInBackground(Void... voids) {
final ArrayList<Trade> trades = new ArrayList<>();
for(int i = tradeLayout.getCount(); i < tradeLayout.getCount() + 20 && i < returnedTrades.size(); i++)
{
trades.add(returnedTrades.get(i));
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
tradeListAdapter.addAll(trades);
tradeListAdapter.notifyDataSetChanged();
flag_loading = false;
tradeLayout.removeFooterView(loadingFooter);
}
});
/*binanceManager.updateTrades(new BinanceManager.BinanceCallBack() {
@Override
public void onSuccess() {
ArrayList<com.nauk.moodl.DataManagers.CurrencyData.Trade> trades = binanceManager.getTrades();
final ArrayList<com.nauk.moodl.DataManagers.CurrencyData.Trade> returnedTrades = new ArrayList<>();
for(int i = trades.size() - 1; i > 0 ; i--)
{
returnedTrades.add(trades.get(i));
}
runOnUiThread(new Runnable() {
@Override
public void run() {
tradeListAdapter.addAll(returnedTrades);
tradeListAdapter.notifyDataSetChanged();
flag_loading = false;
tradeLayout.removeFooterView(loadingFooter);
}
});
}
@Override
public void onError(String error) {
}
}, currency.getSymbol(), tradeListAdapter.getItem(tradeListAdapter.getCount() - 1).getId());*/
return null;
}
}
private void drawTransactionList(ArrayList<Transaction> transactions)
{
TransactionListAdapter transactionListAdapter = new TransactionListAdapter(getContext(), transactions);
transactionLayout.setAdapter(transactionListAdapter);
transactionLayout.setTextFilterEnabled(false);
}
public class TransactionUpdater extends AsyncTask<Void, Integer, Void>
{
@Override
protected Void doInBackground(Void... voids) {
if(Looper.myLooper() == null)
{
Looper.prepare();
}
final ArrayList<Transaction> transactionList = databaseManager.getCurrencyTransactionsForSymbol(currency.getSymbol());
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
drawTransactionList(transactionList);
}
});
return null;
}
}
private class TradeUpdater extends AsyncTask<Void, Integer, Void>
{
@Override
protected void onPreExecute()
{
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
}
@Override
protected Void doInBackground(Void... params)
{
binanceManager.updateTrades(new BinanceManager.BinanceCallBack() {
@Override
public void onSuccess() {
ArrayList<Trade> trades = binanceManager.getTrades();
returnedTrades = new ArrayList<>();
for(int i = trades.size() - 1; i >= 0 ; i--)
{
returnedTrades.add(trades.get(i));
}
try {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
ArrayList<Trade> trades = new ArrayList<>();
for(int i = 0; i < 20 && i < returnedTrades.size(); i++)
{
trades.add(returnedTrades.get(i));
}
drawTradeList(trades);
}
});
} catch (NullPointerException e) {
Log.d("moodl", "Transactions do not need to be updated anymore");
}
}
@Override
public void onError(String error) {
}
}, currency.getSymbol());
return null;
}
@Override
protected void onPostExecute(Void result)
{
}
}
}*/
}

View File

@ -0,0 +1,66 @@
package com.herbron.moodl.Activities;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.CustomAdapters.ExchangeDescriptionListAdapter;
import com.herbron.moodl.R;
public class ExchangeListActivity extends AppCompatActivity {
private DatabaseManager databaseManager;
private ListView exchangeListView;
private ExchangeDescriptionListAdapter exchangeDescriptionListAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exchange_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
databaseManager = new DatabaseManager(this);
exchangeListView = findViewById(R.id.exchange_listView);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(ExchangeListActivity.this, AddExchangeActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onResume() {
super.onResume();
exchangeDescriptionListAdapter = new ExchangeDescriptionListAdapter(getApplicationContext(), databaseManager.getExchanges());
exchangeListView.setAdapter(exchangeDescriptionListAdapter);
exchangeDescriptionListAdapter.notifyDataSetChanged();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@ -1,9 +1,13 @@
package com.herbron.moodl.Activities;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.preference.PreferenceActivity;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
@ -12,7 +16,8 @@ import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.support.v7.app.AppCompatDelegate;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
@ -27,8 +32,9 @@ import com.herbron.moodl.Activities.HomeActivityFragments.Summary;
import com.herbron.moodl.Activities.HomeActivityFragments.Watchlist;
import com.herbron.moodl.BalanceSwitchManagerInterface;
import com.herbron.moodl.BalanceUpdateInterface;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.PlaceholderManager;
import com.herbron.moodl.Utils.PlaceholderUtils;
import com.herbron.moodl.R;
import static com.herbron.moodl.MoodlBox.numberConformer;
@ -43,6 +49,10 @@ import static com.herbron.moodl.MoodlBox.numberConformer;
public class HomeActivity extends AppCompatActivity implements BalanceUpdateInterface {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
private DrawerLayout drawerLayout;
private Fragment watchlistFragment;
private Fragment holdingsFragment;
@ -50,6 +60,8 @@ public class HomeActivity extends AppCompatActivity implements BalanceUpdateInte
private Fragment overviewFragment;
private Fragment currentFragment;
private DatabaseManager databaseManager;
private TextView alertTextView;
private BalanceSwitchManagerInterface switchInterface;
@ -57,8 +69,9 @@ public class HomeActivity extends AppCompatActivity implements BalanceUpdateInte
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStatusBarGradiant(this);
/**Interface setup**/
Window w = getWindow();
setContentView(R.layout.activity_currency_summary);
@ -69,6 +82,7 @@ public class HomeActivity extends AppCompatActivity implements BalanceUpdateInte
drawerLayout = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
databaseManager = new DatabaseManager(this);
setListener((BalanceSwitchManagerInterface) holdingsFragment);
@ -98,6 +112,8 @@ public class HomeActivity extends AppCompatActivity implements BalanceUpdateInte
break;
case R.id.navigation_settings:
Intent settingIntent = new Intent(getApplicationContext(), SettingsActivity.class);
settingIntent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.MainPreferenceFragment.class.getName() );
settingIntent.putExtra(PreferenceActivity.EXTRA_NO_HEADERS, true );
startActivity(settingIntent);
item.setChecked(false);
break;
@ -109,9 +125,47 @@ public class HomeActivity extends AppCompatActivity implements BalanceUpdateInte
}
});
setupSettingsAlert(navigationView);
setupBalanceSwitch();
}
private void setupSettingsAlert(NavigationView navigationView)
{
alertTextView = (TextView) navigationView.getMenu().findItem(R.id.navigation_settings).getActionView();
alertTextView.setTextColor(getResources().getColor(R.color.decreaseCandle));
alertTextView.setGravity(Gravity.CENTER);
alertTextView.setTypeface(null, Typeface.BOLD);
updateSettingsAlertNumber();
}
private void updateSettingsAlertNumber()
{
int disabledNumber = databaseManager.getDisabledExchangeAccountsNumber();
if(disabledNumber > 0)
{
alertTextView.setText(String.valueOf(disabledNumber));
}
else
{
alertTextView.setText("");
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static void setStatusBarGradiant(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
Drawable background = activity.getResources().getDrawable(R.drawable.gradient_background);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(activity.getResources().getColor(android.R.color.transparent));
window.setNavigationBarColor(activity.getResources().getColor(android.R.color.transparent));
window.setBackgroundDrawable(background);
}
}
@Override
public void onBackPressed() {
drawerLayout.openDrawer(GravityCompat.START);
@ -126,6 +180,10 @@ public class HomeActivity extends AppCompatActivity implements BalanceUpdateInte
{
Switch balanceSwitch = findViewById(R.id.switchHideBalance);
PreferencesManager preferencesManager = new PreferencesManager(getBaseContext());
balanceSwitch.setChecked(preferencesManager.isBalanceHidden());
balanceSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
@ -158,10 +216,16 @@ public class HomeActivity extends AppCompatActivity implements BalanceUpdateInte
currentFragment = fragment;
}
public Fragment getHoldingsFragment()
{
return holdingsFragment;
}
@Override
protected void onResume() {
super.onResume();
updateSettingsAlertNumber();
}
@Override
@ -179,16 +243,11 @@ public class HomeActivity extends AppCompatActivity implements BalanceUpdateInte
if(preferencesManager.isBalanceHidden())
{
drawerBalanceTextView.setText(PlaceholderManager.getPercentageString(numberConformer(value), getApplicationContext()));
drawerBalanceTextView.setText(PlaceholderUtils.getPercentageString(numberConformer(value), getApplicationContext()));
}
else
{
drawerBalanceTextView.setText(PlaceholderManager.getValueString(numberConformer(value), getApplicationContext()));
drawerBalanceTextView.setText(PlaceholderUtils.getValueString(numberConformer(value), getApplicationContext()));
}
}
public interface IconCallBack
{
void onSuccess(Bitmap bitmap);
}
}

View File

@ -9,6 +9,7 @@ import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.NestedScrollView;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.graphics.Palette;
import android.text.SpannableString;
@ -27,36 +28,38 @@ import com.github.mikephil.charting.data.PieEntry;
import com.github.mikephil.charting.formatter.PercentFormatter;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.herbron.moodl.Activities.HomeActivity;
import com.herbron.moodl.DataManagers.BalanceManager;
import com.herbron.moodl.DataNotifiers.CoinmarketcapNotifierInterface;
import com.herbron.moodl.DataNotifiers.CryptocompareNotifierInterface;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyDetailsList;
import com.herbron.moodl.DataManagers.MarketCapManager;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CoinmarketCapAPIManager;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CryptocompareApiManager;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.LayoutManagers.CustomPieChart;
import com.herbron.moodl.CustomLayouts.CustomPieChart;
import com.herbron.moodl.MoodlBox;
import com.herbron.moodl.PlaceholderManager;
import com.herbron.moodl.DataNotifiers.MoodlboxNotifierInterface;
import com.herbron.moodl.Utils.PlaceholderUtils;
import com.herbron.moodl.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import static com.herbron.moodl.MoodlBox.getColor;
import static com.herbron.moodl.MoodlBox.getIconDominantColor;
import static java.lang.Math.abs;
/**
* Created by Tiji on 13/04/2018.
*/
public class MarketCapitalization extends Fragment {
public class MarketCapitalization extends Fragment implements CryptocompareNotifierInterface, CoinmarketcapNotifierInterface {
private PreferencesManager preferencesManager;
private MarketCapManager marketCapManager;
private HashMap<String, Integer> dominantCurrenciesColors;
private CoinmarketCapAPIManager coinmarketCapAPIManager;
private SwipeRefreshLayout refreshLayout;
private NestedScrollView nestedScrollView;
private long lastTimestamp;
private String defaultCurrency;
private CurrencyDetailsList currencyDetailsList;
private CryptocompareApiManager cryptocompareApiManager;
private boolean isDetailsUpdated;
private boolean isTopCurrenciesUpdated;
private boolean isMarketpCapUpdated;
@ -67,22 +70,18 @@ public class MarketCapitalization extends Fragment {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
view = inflater.inflate(R.layout.fragment_marketcap_homeactivity, container, false);
view = inflater.inflate(R.layout.homeactivity_fragment_marketcap, container, false);
preferencesManager = new PreferencesManager(getContext());
marketCapManager = new MarketCapManager(getContext());
preferencesManager = new PreferencesManager(getActivity().getBaseContext());
coinmarketCapAPIManager = CoinmarketCapAPIManager.getInstance(getActivity().getBaseContext());
coinmarketCapAPIManager.addListener(this);
currencyDetailsList = CurrencyDetailsList.getInstance(getContext());
cryptocompareApiManager = CryptocompareApiManager.getInstance(getActivity().getBaseContext());
cryptocompareApiManager.addListener(this);
if(!currencyDetailsList.isUpToDate())
if(!cryptocompareApiManager.isDetailsUpToDate())
{
currencyDetailsList.update(new BalanceManager.IconCallBack() {
@Override
public void onSuccess() {
isDetailsUpdated = true;
countCompletedMarketCapRequest();
}
});
cryptocompareApiManager.updateDetails();
}
else
{
@ -93,6 +92,8 @@ public class MarketCapitalization extends Fragment {
defaultCurrency = preferencesManager.getDefaultCurrency();
lastTimestamp = 0;
nestedScrollView = view.findViewById(R.id.nestedMarketCap);
setupRefreshLayout();
setupDrawerButton();
@ -151,7 +152,6 @@ public class MarketCapitalization extends Fragment {
{
updateMarketCap(false);
}
}
private void updateMarketCap(boolean mustUpdate)
@ -170,22 +170,9 @@ public class MarketCapitalization extends Fragment {
lastTimestamp = System.currentTimeMillis() / 1000;
marketCapManager.updateTopCurrencies(new MarketCapManager.VolleyCallBack() {
@Override
public void onSuccess()
{
isTopCurrenciesUpdated = true;
countCompletedMarketCapRequest();
}
}, preferencesManager.getDefaultCurrency());
coinmarketCapAPIManager.updateTopCurrencies(preferencesManager.getDefaultCurrency());
marketCapManager.updateMarketCap(new MarketCapManager.VolleyCallBack() {
@Override
public void onSuccess() {
isMarketpCapUpdated = true;
countCompletedMarketCapRequest();
}
}, preferencesManager.getDefaultCurrency());
coinmarketCapAPIManager.updateMarketCap(preferencesManager.getDefaultCurrency());
}
else
{
@ -216,14 +203,14 @@ public class MarketCapitalization extends Fragment {
private PieDataSet getMarketDominanceDataSet()
{
List<PieEntry> entries = new ArrayList<>();
List<Currency> topCurrencies = marketCapManager.getTopCurrencies();
List<Currency> topCurrencies = coinmarketCapAPIManager.getTopCurrencies();
ArrayList<Integer> colors = new ArrayList<>();
float topCurrenciesDominance = 0;
for(int i = 0; i < topCurrencies.size(); i++)
{
PieEntry pieEntry = new PieEntry(topCurrencies.get(i).getDominance(marketCapManager.getMarketCap()), topCurrencies.get(i).getSymbol(), topCurrencies.get(i).getSymbol());
PieEntry pieEntry = new PieEntry(topCurrencies.get(i).getDominance(coinmarketCapAPIManager.getMarketCap()), topCurrencies.get(i).getSymbol(), topCurrencies.get(i).getSymbol());
if(pieEntry.getValue() < 3)
{
@ -231,14 +218,14 @@ public class MarketCapitalization extends Fragment {
}
entries.add(pieEntry);
topCurrenciesDominance += topCurrencies.get(i).getDominance(marketCapManager.getMarketCap());
topCurrenciesDominance += topCurrencies.get(i).getDominance(coinmarketCapAPIManager.getMarketCap());
colors.add(topCurrencies.get(i).getChartColor());
}
entries.add(new PieEntry(100-topCurrenciesDominance, "Others", "others"));
entries.add(new PieEntry(100-topCurrenciesDominance, getString(R.string.others), "others"));
colors.add(-12369084);
PieDataSet set = new PieDataSet(entries, "Market Cap Dominance");
PieDataSet set = new PieDataSet(entries, getString(R.string.market_dominance));
set.setColors(colors);
set.setSliceSpace(1);
set.setDrawValues(false);
@ -259,7 +246,7 @@ public class MarketCapitalization extends Fragment {
{
iconCounter++;
if(iconCounter >= marketCapManager.getTopCurrencies().size())
if(iconCounter >= coinmarketCapAPIManager.getTopCurrencies().size())
{
refreshDisplayedData();
}
@ -267,24 +254,23 @@ public class MarketCapitalization extends Fragment {
private void updateIcons()
{
for(int i = 0; i < marketCapManager.getTopCurrencies().size(); i++)
for(int i = 0; i < coinmarketCapAPIManager.getTopCurrencies().size(); i++)
{
final Currency localCurrency = marketCapManager.getTopCurrencies().get(i);
final Currency localCurrency = coinmarketCapAPIManager.getTopCurrencies().get(i);
final int index = i;
String iconUrl = MoodlBox.getIconUrl(marketCapManager.getTopCurrencies().get(i).getSymbol(), 500, currencyDetailsList);
String iconUrl = MoodlBox.getIconUrl(coinmarketCapAPIManager.getTopCurrencies().get(i).getSymbol(), 500, cryptocompareApiManager);
if(iconUrl != null)
{
MoodlBox.getBitmapFromURL(iconUrl, localCurrency.getSymbol(), getResources(), getContext(), new HomeActivity.IconCallBack() {
MoodlBox.getBitmapFromURL(iconUrl, localCurrency.getSymbol(), getResources(), getActivity().getBaseContext(), new MoodlboxNotifierInterface() {
@Override
public void onSuccess(Bitmap bitmapIcon) {
Palette.Builder builder = Palette.from(bitmapIcon);
marketCapManager.getTopCurrencies().get(index).setIcon(bitmapIcon);
marketCapManager.getTopCurrencies().get(index).setChartColor(builder.generate().getDominantColor(0));
public void onBitmapDownloaded(Bitmap bitmapIcon) {
coinmarketCapAPIManager.getTopCurrencies().get(index).setIcon(bitmapIcon);
coinmarketCapAPIManager.getTopCurrencies().get(index).setChartColor(getIconDominantColor(getContext(), bitmapIcon));
countIcons();
}
});
}
@ -309,11 +295,11 @@ public class MarketCapitalization extends Fragment {
pieChart.setTouchEnabled(true);
pieChart.setEntryLabelColor(Color.WHITE);
updateDetails(marketCapManager.getMarketCap(), marketCapManager.getDayVolume(), "Global", 0);
updateDetails(coinmarketCapAPIManager.getMarketCap(), coinmarketCapAPIManager.getDayVolume(), getString(R.string.global), 0);
((TextView) view.findViewById(R.id.textViewActiveCrypto))
.setText(marketCapManager.getActive_crypto());
.setText(coinmarketCapAPIManager.getActive_crypto());
((TextView) view.findViewById(R.id.textViewActiveMarkets))
.setText(marketCapManager.getActive_markets());
.setText(coinmarketCapAPIManager.getActive_markets());
pieChart.setOnTouchListener(new View.OnTouchListener() {
@Override
@ -321,12 +307,12 @@ public class MarketCapitalization extends Fragment {
switch (motionEvent.getAction())
{
case MotionEvent.ACTION_DOWN:
refreshLayout.setEnabled(false);
nestedScrollView.setEnabled(false);
break;
case MotionEvent.ACTION_MOVE:
break;
default:
refreshLayout.setEnabled(true);
nestedScrollView.setEnabled(true);
break;
}
@ -348,7 +334,7 @@ public class MarketCapitalization extends Fragment {
if(!e.getData().equals("others"))
{
Currency currency = marketCapManager.getCurrencyFromSymbol((String) e.getData());
Currency currency = coinmarketCapAPIManager.getCurrencyFromSymbol((String) e.getData());
view.findViewById(R.id.currencyIcon).setVisibility(View.VISIBLE);
view.findViewById(R.id.layoutPercentageDominance).setVisibility(View.VISIBLE);
@ -361,19 +347,19 @@ public class MarketCapitalization extends Fragment {
}
else
{
double othersMarketCap = marketCapManager.getMarketCap();
double othersVolume = marketCapManager.getDayVolume();
double othersMarketCap = coinmarketCapAPIManager.getMarketCap();
double othersVolume = coinmarketCapAPIManager.getDayVolume();
for(int i = 0; i < marketCapManager.getTopCurrencies().size(); i++)
for(int i = 0; i < coinmarketCapAPIManager.getTopCurrencies().size(); i++)
{
othersMarketCap -= marketCapManager.getTopCurrencies().get(i).getMarketCapitalization();
othersVolume -= marketCapManager.getTopCurrencies().get(i).getVolume24h();
othersMarketCap -= coinmarketCapAPIManager.getTopCurrencies().get(i).getMarketCapitalization();
othersVolume -= coinmarketCapAPIManager.getTopCurrencies().get(i).getVolume24h();
}
view.findViewById(R.id.currencyIcon).setVisibility(View.GONE);
view.findViewById(R.id.layoutPercentageDominance).setVisibility(View.VISIBLE);
updateDetails(othersMarketCap, othersVolume, "Other coins", h.getY());
updateDetails(othersMarketCap, othersVolume, getString(R.string.other_coins), h.getY());
pieChart.setDrawCenterText(true);
}
@ -389,7 +375,7 @@ public class MarketCapitalization extends Fragment {
view.findViewById(R.id.layoutActiveCrypto).setVisibility(View.VISIBLE);
view.findViewById(R.id.layoutActiveMarkets).setVisibility(View.VISIBLE);
updateDetails(marketCapManager.getMarketCap(), marketCapManager.getDayVolume(), "Global", 0);
updateDetails(coinmarketCapAPIManager.getMarketCap(), coinmarketCapAPIManager.getDayVolume(), getString(R.string.global), 0);
pieChart.setDrawCenterText(true);
}
@ -404,18 +390,51 @@ public class MarketCapitalization extends Fragment {
private void updateDetails(double marketCap, double volume, String title, double percentage)
{
((TextView) view.findViewById(R.id.textViewMarketCap))
.setText(PlaceholderManager.getValueString(MoodlBox.numberConformer(marketCap), getContext()));
.setText(PlaceholderUtils.getValueString(MoodlBox.numberConformer(marketCap), getActivity().getBaseContext()));
((TextView) view.findViewById(R.id.textViewVolume))
.setText(PlaceholderManager.getValueString(MoodlBox.numberConformer(volume), getContext()));
.setText(PlaceholderUtils.getValueString(MoodlBox.numberConformer(volume), getActivity().getBaseContext()));
((TextView) view.findViewById(R.id.textViewTitle))
.setText(title);
((TextView) view.findViewById(R.id.textViewDominancePercentage))
.setText(PlaceholderManager.getPercentageString(MoodlBox.numberConformer(percentage), getContext()));
.setText(PlaceholderUtils.getPercentageString(MoodlBox.numberConformer(percentage), getActivity().getBaseContext()));
}
private SpannableString generateCenterSpannableText() {
SpannableString spannableString = new SpannableString("Market Capitalization Dominance");
SpannableString spannableString = new SpannableString(getString(R.string.market_dominance));
return spannableString;
}
@Override
public void onDetailsUpdated() {
isDetailsUpdated = true;
countCompletedMarketCapRequest();
}
@Override
public void onExchangesUpdated() {
}
@Override
public void onCurrenciesRetrieved(List<Currency> currencyList) {
}
@Override
public void onTopCurrenciesUpdated() {
isTopCurrenciesUpdated = true;
countCompletedMarketCapRequest();
}
@Override
public void onMarketCapUpdated() {
isMarketpCapUpdated = true;
countCompletedMarketCapRequest();
}
@Override
public void onListingUpdated() {
}
}

View File

@ -1,7 +1,8 @@
package com.herbron.moodl.Activities.HomeActivityFragments;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.support.v4.app.Fragment;
import android.os.Bundle;
@ -16,25 +17,29 @@ import android.widget.AbsListView;
import android.widget.ImageButton;
import android.widget.ListView;
import com.herbron.moodl.Activities.HomeActivity;
import com.herbron.moodl.DataNotifiers.CoinmarketcapNotifierInterface;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyDetailsList;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyTickerList;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CryptocompareApiManager;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CoinmarketCapAPIManager;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.LayoutManagers.OverviewListAdapter;
import com.herbron.moodl.CustomAdapters.OverviewListAdapter;
import com.herbron.moodl.MoodlBox;
import com.herbron.moodl.DataNotifiers.MoodlboxNotifierInterface;
import com.herbron.moodl.R;
import java.util.List;
import static com.herbron.moodl.MoodlBox.getDrawable;
import static com.herbron.moodl.MoodlBox.getIconDominantColor;
/**
* Created by Administrator on 27/05/2018.
*/
public class Overview extends Fragment {
public class Overview extends Fragment implements CoinmarketcapNotifierInterface {
private CurrencyTickerList currencyTickerList;
private CurrencyDetailsList currencyDetailsList;
private CoinmarketCapAPIManager coinmarketCapAPIManager;
private CryptocompareApiManager cryptocompareApiManager;
private PreferencesManager preferenceManager;
private OverviewListAdapter overviewListAdapter;
@ -48,12 +53,16 @@ public class Overview extends Fragment {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View fragmentView = inflater.inflate(R.layout.fragment_overview_homeactivity, container, false);
View fragmentView = inflater.inflate(R.layout.homeactivity_fragment_overview, container, false);
currencyTickerList = CurrencyTickerList.getInstance(getContext());
currencyDetailsList = CurrencyDetailsList.getInstance(getContext());
coinmarketCapAPIManager = CoinmarketCapAPIManager.getInstance(getActivity().getBaseContext());
cryptocompareApiManager = CryptocompareApiManager.getInstance(getActivity().getBaseContext());
preferenceManager = new PreferencesManager(getContext());
coinmarketCapAPIManager.addListener(this);
fragmentView.findViewById(R.id.toolbar).bringToFront();
preferenceManager = new PreferencesManager(getActivity().getBaseContext());
listLayout = fragmentView.findViewById(R.id.linearLayoutOverview);
@ -86,6 +95,7 @@ public class Overview extends Fragment {
return fragmentView;
}
private void setupDrawerButton(View view)
{
ImageButton drawerButton = view.findViewById(R.id.drawer_button);
@ -112,32 +122,34 @@ public class Overview extends Fragment {
currencyLoader.execute();
}
private void updateChartColor(Currency currency)
{
if(currency.getIcon() != null)
{
Palette.Builder builder = Palette.from(currency.getIcon());
currency.setChartColor(builder.generate().getDominantColor(0));
}
else
{
currency.setChartColor(12369084);
}
}
public interface UpdateCallBack
{
void onSuccess(List<Currency> currencyList);
}
private void loadingIndicatorGenerator()
{
loadingFooter = LayoutInflater.from(getContext()).inflate(R.layout.listview_loading_indicator, null, false);
loadingFooter = LayoutInflater.from(getActivity().getBaseContext()).inflate(R.layout.listview_loading_indicator, null, false);
listLayout.addFooterView(loadingFooter);
}
@Override
public void onCurrenciesRetrieved(List<Currency> currencyList) {
IconDownloader iconDownloader = new IconDownloader();
iconDownloader.execute(currencyList);
}
@Override
public void onTopCurrenciesUpdated() {
}
@Override
public void onMarketCapUpdated() {
}
@Override
public void onListingUpdated() {
}
private class CurrencyLoader extends AsyncTask<Void, Void, Void>
{
@Override
@ -149,14 +161,7 @@ public class Overview extends Fragment {
@Override
protected Void doInBackground(Void... voids) {
currencyTickerList.getCurrenciesFrom(listLayout.getCount(), preferenceManager.getDefaultCurrency(), new UpdateCallBack() {
@Override
public void onSuccess(List<Currency> currencyList)
{
IconDownloader iconDownloader = new IconDownloader();
iconDownloader.execute(currencyList);
}
});
coinmarketCapAPIManager.getCurrenciesFrom(listLayout.getCount(), preferenceManager.getDefaultCurrency());
return null;
}
}
@ -168,28 +173,37 @@ public class Overview extends Fragment {
@Override
protected Void doInBackground(List<Currency>... currencies) {
iconCounter = 0;
for(Currency currency : currencies[0])
{
String iconUrl = MoodlBox.getIconUrl(currency.getSymbol(), currencyDetailsList);
String iconUrl = MoodlBox.getIconUrl(currency.getSymbol(), cryptocompareApiManager);
if(iconUrl != null)
{
MoodlBox.getBitmapFromURL(iconUrl, currency.getSymbol(), getResources(), getContext(), new HomeActivity.IconCallBack() {
MoodlBox.getBitmapFromURL(iconUrl, currency.getSymbol(), getResources(), getActivity().getBaseContext(), new MoodlboxNotifierInterface() {
@Override
public void onSuccess(Bitmap bitmap) {
public void onBitmapDownloaded(Bitmap bitmap) {
currency.setIcon(bitmap);
updateChartColor(currency);
currency.setChartColor(getIconDominantColor(getContext(), bitmap));
countIcons(currencies[0]);
}
});
}
else
{
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_moodl);
Drawable drawable = getDrawable(R.drawable.ic_panorama_fish_eye_24dp, getActivity().getBaseContext());
Bitmap icon = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(icon);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
icon = Bitmap.createScaledBitmap(icon, 50, 50, false);
currency.setIcon(icon);
updateChartColor(currency);
currency.setChartColor(getIconDominantColor(getContext(), icon));
countIcons(currencies[0]);
}
}
@ -206,9 +220,10 @@ public class Overview extends Fragment {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if(overviewListAdapter == null)
{
overviewListAdapter = new OverviewListAdapter(getContext(), currencyList, getActivity());
overviewListAdapter = new OverviewListAdapter(Overview.this.getContext(), currencyList, getActivity());
listLayout.setAdapter(overviewListAdapter);
listLayout.setTextFilterEnabled(false);

View File

@ -1,17 +1,25 @@
package com.herbron.moodl.Activities.HomeActivityFragments;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.SwipeRefreshLayout;
@ -23,25 +31,38 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.herbron.moodl.Activities.CurrencySelectionActivity;
import com.herbron.moodl.Activities.HomeActivity;
import com.daasuu.ei.Ease;
import com.daasuu.ei.EasingInterpolator;
import com.herbron.moodl.Activities.RecordTransactionActivity;
import com.herbron.moodl.BalanceUpdateInterface;
import com.herbron.moodl.DataNotifiers.CoinmarketcapNotifierInterface;
import com.herbron.moodl.DataNotifiers.CryptocompareNotifierInterface;
import com.herbron.moodl.CurrencyInfoUpdateNotifierInterface;
import com.herbron.moodl.DataManagers.BalanceManager;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyCardview;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyTickerList;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CoinmarketCapAPIManager;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CryptocompareApiManager;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.BalanceSwitchManagerInterface;
import com.herbron.moodl.DataNotifiers.BalanceUpdateNotifierInterface;
import com.herbron.moodl.MoodlBox;
import com.herbron.moodl.PlaceholderManager;
import com.herbron.moodl.DataNotifiers.MoodlboxNotifierInterface;
import com.herbron.moodl.Utils.PlaceholderUtils;
import com.herbron.moodl.R;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import static com.herbron.moodl.MoodlBox.getColor;
import static com.herbron.moodl.MoodlBox.getDrawable;
import static com.herbron.moodl.MoodlBox.getIconDominantColor;
import static com.herbron.moodl.MoodlBox.numberConformer;
import static java.lang.Math.abs;
@ -49,25 +70,24 @@ import static java.lang.Math.abs;
* Created by Tiji on 13/04/2018.
*/
public class Summary extends Fragment implements BalanceSwitchManagerInterface {
public class Summary extends Fragment implements BalanceSwitchManagerInterface, BalanceUpdateNotifierInterface, CryptocompareNotifierInterface, CoinmarketcapNotifierInterface {
private LinearLayout currencyLayout;
private PreferencesManager preferencesManager;
private com.herbron.moodl.DataManagers.BalanceManager balanceManager;
private BalanceManager balanceManager;
private SwipeRefreshLayout refreshLayout;
private Dialog loadingDialog;
private String defaultCurrency;
private CurrencyTickerList currencyTickerList;
private TextView toolbarSubtitle;
private CollapsingToolbarLayout toolbarLayout;
private Handler handler;
private Runnable updateRunnable;
private Runnable layoutRefresherRunnable;
private int coinCounter;
private int iconCounter;
private float totalValue;
private boolean detailsChecker;
private boolean tickersChecker;
@ -75,16 +95,19 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
private long lastTimestamp;
private BalanceUpdateInterface balanceUpdateInterface;
private CoinmarketCapAPIManager coinmarketCapAPIManager;
private CryptocompareApiManager cryptocompareApiManager;
@NonNull
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View fragmentView = inflater.inflate(R.layout.fragment_summary_homeactivity, container, false);
View fragmentView = inflater.inflate(R.layout.homeactivity_fragment_summary, container, false);
preferencesManager = new PreferencesManager(getActivity());
balanceManager = new com.herbron.moodl.DataManagers.BalanceManager(getActivity());
currencyTickerList = CurrencyTickerList.getInstance(getActivity());
balanceManager = new BalanceManager(getActivity());
coinmarketCapAPIManager = CoinmarketCapAPIManager.getInstance(getActivity());
cryptocompareApiManager = CryptocompareApiManager.getInstance(getActivity());
currencyLayout = fragmentView.findViewById(R.id.currencyListLayout);
refreshLayout = fragmentView.findViewById(R.id.swiperefreshsummary);
@ -96,12 +119,13 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
defaultCurrency = preferencesManager.getDefaultCurrency();
cryptocompareApiManager.addListener(this);
coinmarketCapAPIManager.addListener(this);
handler = new Handler();
initiateUpdateRunnable();
initiateLayoutRefresherRunnable();
refreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
@Override
@ -163,6 +187,7 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
refreshLayout.setRefreshing(false);
showErrorSnackbar();
Log.d("moodl", "Error > Refresh out of time");
}
if (loadingDialog.isShowing())
@ -170,54 +195,12 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
loadingDialog.dismiss();
showErrorSnackbar();
Log.d("moodl", "Error > Refresh out of time");
}
}
};
}
private void initiateLayoutRefresherRunnable()
{
layoutRefresherRunnable = new Runnable() {
@Override
public void run() {
final List<View> currencyView = new ArrayList<>();
final List<Currency> renderedCurrencies = new ArrayList<>();
if (balanceManager.getTotalBalance() != null)
{
for (int i = 0; i < balanceManager.getTotalBalance().size(); i++) {
final Currency currency = balanceManager.getTotalBalance().get(i);
if (!currency.getSymbol().equals("USD") && ((currency.getBalance() * currency.getValue()) >= preferencesManager.getMinimumAmount())) {
//currencyView.add(layoutGenerator.getInfoLayout(currency, totalValue, preferencesManager.isBalanceHidden()));
renderedCurrencies.add(currency);
}
}
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
currencyLayout.removeAllViews();
for(int i = 0; i < renderedCurrencies.size(); i++)
{
//currencyLayout.addView(currencyView.get(i));
currencyLayout.addView(new CurrencyCardview(getActivity(), renderedCurrencies.get(i), totalValue, preferencesManager.isBalanceHidden()));
}
if(loadingDialog.isShowing())
{
loadingDialog.dismiss();
}
handler.removeCallbacks(updateRunnable);
}
});
}
};
}
private void setupAddCurrencyButton(View fragmentView)
{
Button addCurrencyButton = fragmentView.findViewById(R.id.buttonAddTransaction);
@ -225,7 +208,7 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
addCurrencyButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent addIntent = new Intent(getActivity(), CurrencySelectionActivity.class);
Intent addIntent = new Intent(getActivity(), RecordTransactionActivity.class);
startActivity(addIntent);
}
@ -234,28 +217,57 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
private void generateSplashScreen()
{
LinearLayout loadingLayout = new LinearLayout(getActivity());
loadingLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
loadingLayout.setGravity(Gravity.CENTER);
loadingLayout.setOrientation(LinearLayout.VERTICAL);
loadingDialog = new Dialog(getActivity(), android.R.style.Theme_Black_NoTitleBar_Fullscreen);
TextView txtView = new TextView(getActivity());
txtView.setText("Loading data...");
txtView.setTextSize(20);
txtView.setGravity(Gravity.CENTER);
txtView.setTextColor(this.getResources().getColor(R.color.cardview_light_background));
Random random = new Random();
ProgressBar progressBar = new ProgressBar(getActivity());
progressBar.setIndeterminate(true);
LinearLayout splashLayout = (LinearLayout) LayoutInflater.from(getActivity().getBaseContext()).inflate(R.layout.splash_screen, null, true);
LinearLayout animatedLayout = splashLayout.findViewById(R.id.animatedViewsLayout);
loadingLayout.setBackgroundColor(getActivity().getResources().getColor(R.color.colorPrimaryDark));
loadingLayout.addView(txtView);
loadingLayout.addView(progressBar);
File cacheDir = new File(getActivity().getBaseContext().getCacheDir().getAbsolutePath());
File[] cacheFiles = cacheDir.listFiles();
loadingDialog.setContentView(loadingLayout);
if(cacheFiles.length > 4)
{
for(int i = 0; i < 4; i++)
{
File cachedIcon = null;
while(cachedIcon == null || cachedIcon.isDirectory())
{
cachedIcon = cacheFiles[random.nextInt(cacheFiles.length)];
}
Bitmap icon = BitmapFactory.decodeFile(cachedIcon.getAbsolutePath());
Bitmap result = Bitmap.createBitmap(150, 150, icon.getConfig());
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(ContextCompat.getColor(getActivity().getBaseContext(), R.color.white));
Canvas canvas = new Canvas(result);
canvas.drawCircle(result.getHeight()/2, result.getWidth()/2, 75, paint);
canvas.drawBitmap(Bitmap.createScaledBitmap(icon, 100, 100, false), result.getHeight()/2 - 50, result.getWidth()/2 - 50, null);
((ImageView) animatedLayout.getChildAt(i)).setImageBitmap(result);
ObjectAnimator animator = ObjectAnimator.ofFloat(animatedLayout.getChildAt(i), "translationY", 0, -100, 0);
animator.setInterpolator(new EasingInterpolator(Ease.CIRC_IN_OUT));
animator.setStartDelay(i*200);
animator.setDuration(1500);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.start();
}
}
else
{
/*ImageView appNameImageView = splashLayout.findViewById(R.id.appNameImageView);
appNameImageView.setVisibility(View.VISIBLE);*/
animatedLayout.setVisibility(View.GONE);
}
loadingDialog.setContentView(splashLayout);
loadingDialog.show();
}
@ -287,7 +299,6 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
}
lastTimestamp = System.currentTimeMillis() / 1000;
balanceManager.updateExchangeKeys();
resetCounters();
DataUpdater updater = new DataUpdater();
@ -304,28 +315,59 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
private void showErrorSnackbar()
{
/*Snackbar.make(getActivity().findViewById(R.id.snackbar_placer), "Error while updating data", Snackbar.LENGTH_LONG)
.setAction("Update", new View.OnClickListener() {
Snackbar.make(getActivity().findViewById(R.id.content_frame), getString(R.string.error_update_data), Snackbar.LENGTH_LONG)
.setAction(getString(R.string.update), new View.OnClickListener() {
@Override
public void onClick(View view) {
updateAll(true);
}
})
.show();*/
.show();
}
private void resetCounters()
{
coinCounter = 0;
iconCounter = 0;
totalValue = 0;
totalFluctuation = 0;
}
private void adaptView()
private void adaptView(float totalValue, float totalFluctuation)
{
layoutRefresherRunnable.run();
this.totalValue = totalValue;
this.totalFluctuation = totalFluctuation;
final List<Currency> renderedCurrencies = new ArrayList<>();
if (balanceManager.getTotalBalance() != null)
{
for (int i = 0; i < balanceManager.getTotalBalance().size(); i++) {
final Currency currency = balanceManager.getTotalBalance().get(i);
if ((Math.abs(currency.getBalance() * currency.getValue()) >= preferencesManager.getMinimumAmount())) {
//currencyView.add(layoutGenerator.getInfoLayout(currency, totalValue, preferencesManager.isBalanceHidden()));
renderedCurrencies.add(currency);
}
}
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
currencyLayout.removeAllViews();
for(int i = 0; i < renderedCurrencies.size(); i++)
{
currencyLayout.addView(new CurrencyCardview(getActivity(), renderedCurrencies.get(i), getActivity(), preferencesManager.isBalanceHidden()));
}
if(loadingDialog.isShowing())
{
loadingDialog.dismiss();
}
updateTitle();
handler.removeCallbacks(updateRunnable);
}
});
}
private void countCoins(boolean isCoin, boolean isDetails, boolean isTickers)
@ -349,46 +391,22 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
{
if(balanceManager.getTotalBalance().size() == 0)
{
countIcons();
updateNoBalance();
}
else
{
if(coinCounter >= balanceManager.getTotalBalance().size() && detailsChecker && tickersChecker)
{
IconDownloader iconDownloader = new IconDownloader();
iconDownloader.execute();
}
}
}
}
private void countIcons()
{
int offset = 0;
for(int i = 0; i < balanceManager.getTotalBalance().size(); i++)
{
if(balanceManager.getTotalBalance().get(i).getSymbol().equals("USD"))
{
offset++;
}
}
iconCounter++;
if(balanceManager.getTotalBalance() != null)
{
if(balanceManager.getTotalBalance().size() == 0)
{
updateNoBalance();
}
else
{
if(iconCounter == balanceManager.getTotalBalance().size() - offset)
{
UiHeavyLoadCalculator uiHeavyLoadCalculator = new UiHeavyLoadCalculator();
uiHeavyLoadCalculator.execute();
uiHeavyLoadCalculator.setOnUiEndListener(new UiHeavyLoadCalculator.OnUiEndListener() {
@Override
public void onEnd(float totalValue, float totalFluctuation) {
refreshLayout.setRefreshing(false);
adaptView(totalValue, totalFluctuation);
}
});
uiHeavyLoadCalculator.execute(getActivity().getBaseContext(), balanceManager, coinmarketCapAPIManager);
}
}
}
@ -413,8 +431,21 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
});
}
private void computeTotalValue()
{
for(int i = 0; i < currencyLayout.getChildCount(); i++)
{
if(currencyLayout.getChildAt(i) instanceof CurrencyCardview)
{
((CurrencyCardview) currencyLayout.getChildAt(i)).updateOwnedValues(totalValue, preferencesManager.isBalanceHidden());
}
}
}
protected void updateTitle()
{
computeTotalValue();
float totalFluctuationPercentage = totalFluctuation / (totalValue - totalFluctuation) * 100;
if(preferencesManager.isBalanceHidden())
@ -439,7 +470,7 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
}
else
{
updateBalanceDisplayedTitle(totalValue);
updateBalanceDisplayedTitle(totalFluctuationPercentage);
balanceUpdateInterface.onBalanceUpdated(totalValue);
}
}
@ -447,7 +478,7 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
public void updateBalanceDisplayedTitle(float totalFluctuationPercentage)
{
toolbarLayout.setTitle(PlaceholderManager.getValueString(numberConformer(totalValue), getActivity()));
toolbarLayout.setTitle(PlaceholderUtils.getValueString(numberConformer(totalValue), getActivity()));
toolbarLayout.setCollapsedTitleTextColor(Color.WHITE);
toolbarLayout.setExpandedTitleColor(Color.WHITE);
@ -464,18 +495,18 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
if(totalFluctuation == 0)
{
toolbarSubtitle.setText(PlaceholderManager.getValueString(numberConformer(totalValue), getActivity()));
toolbarSubtitle.setText(PlaceholderUtils.getValueString(numberConformer(totalValue), getActivity()));
toolbarSubtitle.setTextColor(-1275068417);
}
else
{
toolbarSubtitle.setText(PlaceholderManager.getValuePercentageString(numberConformer(totalFluctuation), numberConformer(totalFluctuationPercentage), getActivity()));
toolbarSubtitle.setText(PlaceholderUtils.getValuePercentageString(numberConformer(totalFluctuation), numberConformer(totalFluctuationPercentage), getActivity()));
}
}
private void updateHideBalanceTitle(float totalFluctuationPercentage)
{
toolbarLayout.setTitle(PlaceholderManager.getPercentageString(numberConformer(totalFluctuationPercentage), getActivity()));
toolbarLayout.setTitle(PlaceholderUtils.getPercentageString(numberConformer(totalFluctuationPercentage), getActivity()));
toolbarSubtitle.setVisibility(View.GONE);
if(totalFluctuation > 0)
@ -496,8 +527,138 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
displayBalance(preferencesManager.isBalanceHidden());
}
private class UiHeavyLoadCalculator extends AsyncTask<Void, Integer, Void>
@Override
public void onBalanceDataUpdated() {
final List<Currency> balance = balanceManager.getTotalBalance();
if(balance != null && balance.size() > 0)
{
for(int i = 0; i < balance.size(); i++)
{
balance.get(i).updatePrice(getActivity(), defaultCurrency, new CurrencyInfoUpdateNotifierInterface() {
@Override
public void onTimestampPriceUpdated(String price) {
}
@Override
public void onHistoryDataUpdated() {
}
@Override
public void onPriceUpdated(Currency currency) {
countCoins(true, false, false);
}
});
}
}
else
{
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
countCoins(false, false, false);
}
});
}
}
@Override
public void onBalanceError(String error)
{
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
generateSnackBarError(error);
}
});
}
private void generateSnackBarError(String error)
{
View view = getActivity().findViewById(R.id.content_frame);
switch (error)
{
case "com.android.volley.AuthFailureError":
preferencesManager.disableHitBTC();
Snackbar.make(view, getString(R.string.invalid_keys_hitbtc), Snackbar.LENGTH_LONG)
.show();
refreshLayout.setRefreshing(false);
updateAll(true);
break;
case "API-key format invalid.":
preferencesManager.disableBinance();
Snackbar.make(view, getString(R.string.invalid_keys_binance), Snackbar.LENGTH_LONG)
.show();
updateAll(true);
break;
case "com.android.volley.NoConnectionError: java.net.UnknownHostException: Unable to resolve host \"api.hitbtc.com\": No address associated with hostname":
Snackbar.make(view, getString(R.string.cannot_resole_host), Snackbar.LENGTH_LONG)
.show();
break;
case "com.android.volley.TimeoutError":
break;
default:
Snackbar.make(view, R.string.unexpected, Snackbar.LENGTH_LONG)
.show();
Log.d("moodl", error);
updateAll(false);
}
}
@Override
public void onDetailsUpdated() {
countCoins(false, true, false);
}
@Override
public void onExchangesUpdated() {
}
@Override
public void onCurrenciesRetrieved(List<Currency> currencyList) {
}
@Override
public void onTopCurrenciesUpdated() {
}
@Override
public void onMarketCapUpdated() {
}
@Override
public void onListingUpdated() {
countCoins(false, false, true);
}
private static class UiHeavyLoadCalculator extends AsyncTask<Object, Integer, Void>
{
private float totalValue = 0;
private float totalFluctuation = 0;
private BalanceManager balanceManager;
private CoinmarketCapAPIManager coinmarketCapAPIManager;
private OnUiEndListener onUiEndListener;
public void setOnUiEndListener(OnUiEndListener onUiEndListener)
{
this.onUiEndListener = onUiEndListener;
}
@Override
protected void onPreExecute()
@ -514,81 +675,55 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
super.onProgressUpdate(values);
}
private void updateChartColor(Currency currency)
{
if(currency.getIcon() != null)
{
Palette.Builder builder = Palette.from(currency.getIcon());
currency.setChartColor(builder.generate().getDominantColor(0));
}
else
{
currency.setChartColor(12369084);
}
}
private void loadCurrency(Currency currency)
{
if(!currency.getSymbol().equals("USD"))
{
currency.setName(balanceManager.getCurrencyName(currency.getSymbol()));
currency.setId(balanceManager.getCurrencyId(currency.getSymbol()));
totalValue += currency.getValue() * currency.getBalance();
totalFluctuation += (currency.getValue() * currency.getBalance()) * (currency.getDayFluctuationPercentage() / 100);
}
}
@Override
protected Void doInBackground(Void... params)
protected Void doInBackground(Object... params)
{
if(Looper.myLooper() == null)
{
Looper.prepare();
}
Context baseContext = (Context) params[0];
balanceManager = (BalanceManager) params[1];
coinmarketCapAPIManager = (CoinmarketCapAPIManager) params[2];
balanceManager.sortCoins();
for(int i = 0; i < balanceManager.getTotalBalance().size(); i++)
{
final Currency localCurrency = balanceManager.getTotalBalance().get(i);
localCurrency.setTickerId(currencyTickerList.getTickerIdForSymbol(localCurrency.getSymbol()));
localCurrency.setTickerId(coinmarketCapAPIManager.getTickerIdForSymbol(localCurrency.getSymbol()));
updateChartColor(localCurrency);
localCurrency.setChartColor(getIconDominantColor(baseContext, localCurrency.getIcon()));
loadCurrency(localCurrency);
totalValue += localCurrency.getValue() * localCurrency.getBalance();
totalFluctuation += localCurrency.getValue() * localCurrency.getBalance() * (localCurrency.getDayFluctuationPercentage() / 100);
balanceManager.getTotalBalance().set(i, localCurrency);
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updateTitle();
}
});
return null;
}
private void loadCurrency(Currency currency)
{
currency.setName(balanceManager.getCurrencyName(currency.getSymbol()));
currency.setId(balanceManager.getCurrencyId(currency.getSymbol()));
}
@Override
protected void onPostExecute(Void result)
{
refreshLayout.setRefreshing(false);
new AsyncTask<Void, Integer, Void>() {
onUiEndListener.onEnd(totalValue, totalFluctuation);
}
@Override
protected Void doInBackground(Void... voids) {
if(Looper.myLooper() == null)
{
Looper.prepare();
}
adaptView();
return null;
}
}.execute();
public interface OnUiEndListener
{
void onEnd(float totalValue, float totalFluctuation);
}
}
@ -616,152 +751,31 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface {
}
}
private class IconDownloader extends AsyncTask<Void, Integer, Void>
{
@Override
protected void onPreExecute()
{
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
}
@Override
protected Void doInBackground(Void... params)
{
for (int i = 0; i < balanceManager.getTotalBalance().size(); i++)
{
final Currency localCurrency = balanceManager.getTotalBalance().get(i);
String iconUrl = MoodlBox.getIconUrl(localCurrency.getSymbol(), balanceManager.getCurrencyDetailList());
if(iconUrl != null)
{
MoodlBox.getBitmapFromURL(iconUrl, localCurrency.getSymbol(), getResources(), getContext(), new HomeActivity.IconCallBack() {
@Override
public void onSuccess(Bitmap bitmapIcon) {
localCurrency.setIcon(bitmapIcon);
countIcons();
}
});
}
else
{
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_moodl);
icon = Bitmap.createScaledBitmap(icon, 50, 50, false);
localCurrency.setIcon(icon);
countIcons();
}
}
return null;
}
}
private class DataUpdater extends AsyncTask<Void, Integer, Void>
{
private void generateSnackBarError(String error)
{
/*View view = getActivity().findViewById(R.id.snackbar_placer);
switch (error)
{
case "com.android.volley.AuthFailureError":
preferencesManager.disableHitBTC();
Snackbar.make(view, "HitBTC synchronization error : Invalid keys", Snackbar.LENGTH_LONG)
.show();
refreshLayout.setRefreshing(false);
updateAll(true);
break;
case "API-key format invalid.":
preferencesManager.disableBinance();
Snackbar.make(view, "Binance synchronization error : Invalid keys", Snackbar.LENGTH_LONG)
.show();
updateAll(true);
break;
case "com.android.volley.NoConnectionError: java.net.UnknownHostException: Unable to resolve host \"api.hitbtc.com\": No address associated with hostname":
Snackbar.make(view, "Can't resolve host", Snackbar.LENGTH_LONG)
.show();
break;
case "com.android.volley.TimeoutError":
break;
default:
Snackbar.make(view, "Unexpected error", Snackbar.LENGTH_LONG)
.show();
Log.d("moodl", error);
updateAll(false);
}*/
}
@Override
protected Void doInBackground(Void... params)
{
if(!currencyTickerList.isUpToDate())
if(!coinmarketCapAPIManager.isUpToDate())
{
currencyTickerList.updateListing(new com.herbron.moodl.DataManagers.BalanceManager.IconCallBack() {
@Override
public void onSuccess() {
countCoins(false, false, true);
}
});
coinmarketCapAPIManager.updateListing();
}
else
{
countCoins(false, false, true);
}
balanceManager.updateDetails(new com.herbron.moodl.DataManagers.BalanceManager.IconCallBack() {
@Override
public void onSuccess()
{
countCoins(false, true, false);
}
});
if(!cryptocompareApiManager.isDetailsUpToDate())
{
cryptocompareApiManager.updateDetails();
}
else
{
countCoins(false, true, false);
}
balanceManager.updateTotalBalance(new com.herbron.moodl.DataManagers.BalanceManager.VolleyCallBack() {
@Override
public void onSuccess() {
final List<Currency> balance = balanceManager.getTotalBalance();
if(balanceManager.getTotalBalance().size() > 0)
{
for(int i = 0; i < balanceManager.getTotalBalance().size(); i++)
{
balance.get(i).updatePrice(getActivity(), defaultCurrency, new Currency.CurrencyCallBack() {
@Override
public void onSuccess(Currency currency) {
countCoins(true, false, false);
}
});
}
}
else
{
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
countCoins(false, false, false);
}
});
}
}
public void onError(String error)
{
generateSnackBarError(error);
}
});
balanceManager.updateTotalBalance();
return null;
}

View File

@ -3,80 +3,85 @@ package com.herbron.moodl.Activities.HomeActivityFragments;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.os.AsyncTask;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.graphics.Palette;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.herbron.moodl.Activities.CurrencySelectionActivity;
import com.herbron.moodl.Activities.HomeActivity;
import com.herbron.moodl.DataManagers.BalanceManager;
import com.herbron.moodl.Activities.CurrencyListActivity;
import com.herbron.moodl.DataNotifiers.CoinmarketcapNotifierInterface;
import com.herbron.moodl.DataNotifiers.CryptocompareNotifierInterface;
import com.herbron.moodl.CurrencyInfoUpdateNotifierInterface;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyCardview;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyDetailsList;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyTickerList;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CryptocompareApiManager;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CoinmarketCapAPIManager;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.DataManagers.WatchlistManager;
import com.herbron.moodl.MoodlBox;
import com.herbron.moodl.DataNotifiers.MoodlboxNotifierInterface;
import com.herbron.moodl.R;
import com.jmedeisis.draglinearlayout.DragLinearLayout;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;
import static com.herbron.moodl.MoodlBox.collapseW;
import static com.herbron.moodl.MoodlBox.expandW;
import static java.lang.Math.abs;
import static com.herbron.moodl.MoodlBox.getIconDominantColor;
/**
* Created by Tiji on 13/04/2018.
*/
public class Watchlist extends Fragment {
public class Watchlist extends Fragment implements CryptocompareNotifierInterface {
private WatchlistManager watchlistManager;
private View view;
private int watchlistCounter;
private CurrencyDetailsList currencyDetailsList;
private CryptocompareApiManager cryptocompareApiManager;
private SwipeRefreshLayout refreshLayout;
private DragLinearLayout dragLinearLayout;
private long lastTimestamp;
private PreferencesManager preferencesManager;
private String defaultCurrency;
private CurrencyTickerList currencyTickerList;
private CoinmarketCapAPIManager coinmarketCapAPIManager;
private boolean tickerUpdated;
private boolean detailsUpdated;
private boolean editModeEnabled;
private DatabaseManager databaseManager;
private ImageButton editButton;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
view = inflater.inflate(R.layout.fragment_watchlist_homeactivity, container, false);
view = inflater.inflate(R.layout.homeactivity_fragment_watchlist, container, false);
refreshLayout = view.findViewById(R.id.swiperefreshwatchlist);
dragLinearLayout = view.findViewById(R.id.linearLayoutWatchlist);
currencyDetailsList = CurrencyDetailsList.getInstance(getContext());
preferencesManager = new PreferencesManager(getContext());
databaseManager = new DatabaseManager(getContext());
cryptocompareApiManager = CryptocompareApiManager.getInstance(getActivity().getBaseContext());
preferencesManager = new PreferencesManager(getActivity().getBaseContext());
databaseManager = new DatabaseManager(getActivity().getBaseContext());
lastTimestamp = 0;
defaultCurrency = preferencesManager.getDefaultCurrency();
currencyTickerList = CurrencyTickerList.getInstance(getActivity());
coinmarketCapAPIManager = CoinmarketCapAPIManager.getInstance(getActivity());
tickerUpdated = false;
cryptocompareApiManager.addListener(this);
updateTickerList();
dragLinearLayout.setOnViewSwapListener(new DragLinearLayout.OnViewSwapListener() {
@ -92,7 +97,7 @@ public class Watchlist extends Fragment {
editModeEnabled = false;
watchlistManager = new WatchlistManager(getContext());
watchlistManager = new WatchlistManager(getActivity().getBaseContext());
updateWatchlist(true);
@ -114,74 +119,120 @@ public class Watchlist extends Fragment {
private void updateTickerList()
{
AsyncTask<Void, Integer, Void> updater = new AsyncTask<Void, Integer, Void>() {
@Override
protected Void doInBackground(Void... voids) {
if(!currencyTickerList.isUpToDate())
{
currencyTickerList.updateListing(new BalanceManager.IconCallBack() {
@Override
public void onSuccess() {
tickerUpdated = true;
checkUpdatedData();
}
});
}
else
{
tickerUpdated = true;
checkUpdatedData();
}
ListingUpdater listingUpdater = new ListingUpdater();
listingUpdater.execute();
}
return null;
private class ListingUpdater extends AsyncTask<Void, Integer, Void> implements CoinmarketcapNotifierInterface {
@Override
protected Void doInBackground(Void... voids) {
coinmarketCapAPIManager.addListener(this);
if(!coinmarketCapAPIManager.isUpToDate())
{
coinmarketCapAPIManager.updateListing();
}
};
else
{
tickerUpdated = true;
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
checkUpdatedData();
}
});
}
return null;
}
updater.execute();
@Override
public void onCurrenciesRetrieved(List<Currency> currencyList) {
}
@Override
public void onTopCurrenciesUpdated() {
}
@Override
public void onMarketCapUpdated() {
}
@Override
public void onListingUpdated() {
tickerUpdated = true;
checkUpdatedData();
}
}
private void disableEdition()
{
editButton.setBackground(MoodlBox.getDrawable(R.drawable.check_to_edit, getActivity().getBaseContext()));
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
AnimatedVectorDrawable animatedVectorDrawable = (AnimatedVectorDrawable) editButton.getBackground();
animatedVectorDrawable.start();
}
editModeEnabled = false;
for(int i = 0; i < dragLinearLayout.getChildCount(); i++)
{
View watchlistElement = dragLinearLayout.getChildAt(i);
if(watchlistElement instanceof CurrencyCardview)
{
watchlistElement.setClickable(true);
collapseW(watchlistElement.findViewById(R.id.deleteCardWatchlist));
collapseW(watchlistElement.findViewById(R.id.dragCardWatchlist));
}
}
}
private void enableEdition()
{
editButton.setBackground(MoodlBox.getDrawable(R.drawable.edit_to_check, getActivity().getBaseContext()));
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
AnimatedVectorDrawable animatedVectorDrawable = (AnimatedVectorDrawable) editButton.getBackground();
animatedVectorDrawable.start();
}
editModeEnabled = true;
for(int i = 0; i < dragLinearLayout.getChildCount(); i++)
{
View watchlistElement = dragLinearLayout.getChildAt(i);
if(watchlistElement instanceof CurrencyCardview)
{
watchlistElement.setClickable(false);
expandW(watchlistElement.findViewById(R.id.deleteCardWatchlist));
expandW(watchlistElement.findViewById(R.id.dragCardWatchlist));
}
}
}
private void setupEditButton()
{
ImageButton editButton = view.findViewById(R.id.edit_button);
editButton = view.findViewById(R.id.edit_button);
editButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(editModeEnabled)
{
((ImageView) view.findViewById(R.id.edit_button)).setBackground(MoodlBox.getDrawable(R.drawable.ic_mode_edit_white_24dp, getContext()));
editModeEnabled = false;
for(int i = 0; i < dragLinearLayout.getChildCount(); i++)
{
View watchlistElement = dragLinearLayout.getChildAt(i);
if(watchlistElement instanceof CurrencyCardview)
{
watchlistElement.setClickable(true);
collapseW(watchlistElement.findViewById(R.id.deleteCardWatchlist));
collapseW(watchlistElement.findViewById(R.id.dragCardWatchlist));
}
}
disableEdition();
}
else
{
((ImageView) view.findViewById(R.id.edit_button)).setBackground(MoodlBox.getDrawable(R.drawable.ic_check_white_24dp, getContext()));
editModeEnabled = true;
for(int i = 0; i < dragLinearLayout.getChildCount(); i++)
{
View watchlistElement = dragLinearLayout.getChildAt(i);
if(watchlistElement instanceof CurrencyCardview)
{
watchlistElement.setClickable(false);
expandW(watchlistElement.findViewById(R.id.deleteCardWatchlist));
expandW(watchlistElement.findViewById(R.id.dragCardWatchlist));
}
}
enableEdition();
}
}
});
@ -193,7 +244,12 @@ public class Watchlist extends Fragment {
addWatchlistButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent selectionIntent = new Intent(getActivity(), CurrencySelectionActivity.class);
if(editModeEnabled)
{
disableEdition();
}
Intent selectionIntent = new Intent(getActivity(), CurrencyListActivity.class);
selectionIntent.putExtra("isWatchList", true);
startActivity(selectionIntent);
}
@ -253,15 +309,9 @@ public class Watchlist extends Fragment {
protected Void doInBackground(Void... voids) {
watchlistManager.updateWatchlist();
if(!currencyDetailsList.isUpToDate())
if(!cryptocompareApiManager.isDetailsUpToDate())
{
currencyDetailsList.update(new BalanceManager.IconCallBack() {
@Override
public void onSuccess() {
detailsUpdated = true;
checkUpdatedData();
}
});
cryptocompareApiManager.updateDetails();
}
else
{
@ -304,10 +354,11 @@ public class Watchlist extends Fragment {
public void run() {
dragLinearLayout.removeAllViews();
view.findViewById(R.id.progressBarWatchlist).setVisibility(View.GONE);
view.findViewById(R.id.buttonAddWatchlist).setVisibility(View.VISIBLE);
for(Currency currency : watchlistManager.getWatchlist())
{
View addedView = new CurrencyCardview(getContext(), currency, getActivity());
View addedView = new CurrencyCardview(getActivity().getBaseContext(), currency, getActivity());
dragLinearLayout.addDragView(addedView, addedView.findViewById(R.id.dragCardWatchlist));
}
@ -330,52 +381,34 @@ public class Watchlist extends Fragment {
}
}
private String getIconUrl(String symbol)
{
String url;
try {
JSONObject jsonObject = new JSONObject(currencyDetailsList.getCoinInfosHashmap().get(symbol));
url = "https://www.cryptocompare.com" + jsonObject.getString("ImageUrl") + "?width=50";
} catch (NullPointerException e) {
Log.d(getContext().getResources().getString(R.string.debug), symbol + " has no icon URL");
url = null;
} catch (JSONException e) {
Log.d(getContext().getResources().getString(R.string.debug), "Url parsing error for " + symbol);
url = null;
}
return url;
}
private void updateChartColor(Currency currency)
{
if(currency.getIcon() != null)
{
Palette.Builder builder = Palette.from(currency.getIcon());
currency.setChartColor(builder.generate().getDominantColor(0));
}
else
{
currency.setChartColor(12369084);
}
}
public int getCurrencyId(String symbol)
{
int id = 0;
try {
JSONObject jsonObject = new JSONObject(currencyDetailsList.getCoinInfosHashmap().get(symbol));
JSONObject jsonObject = new JSONObject(cryptocompareApiManager.getCoinInfosHashmap().get(symbol));
id = jsonObject.getInt("Id");
} catch (JSONException e) {
e.printStackTrace();
} catch (NullPointerException e) {
Log.d("moodl", "ID not found");
e.printStackTrace();
}
return id;
}
@Override
public void onDetailsUpdated() {
detailsUpdated = true;
checkUpdatedData();
}
@Override
public void onExchangesUpdated() {
}
private class WatchlistUpdater extends AsyncTask<Void, Integer, Void>
{
@Override
@ -388,34 +421,31 @@ public class Watchlist extends Fragment {
protected Void doInBackground(Void... voids) {
for(final Currency currency : watchlistManager.getWatchlist())
{
currency.setTickerId(currencyTickerList.getTickerIdForSymbol(currency.getSymbol()));
currency.setTickerId(coinmarketCapAPIManager.getTickerIdForSymbol(currency.getSymbol()));
currency.setId(getCurrencyId(currency.getSymbol()));
currency.updatePrice(getActivity(), preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
currency.updatePrice(getActivity(), preferencesManager.getDefaultCurrency(), new CurrencyInfoUpdateNotifierInterface() {
@Override
public void onSuccess(final Currency sucessCurrency) {
public void onTimestampPriceUpdated(String price) {
String iconUrl = MoodlBox.getIconUrl(sucessCurrency.getSymbol(), currencyDetailsList);
}
if(iconUrl != null)
{
MoodlBox.getBitmapFromURL(iconUrl, sucessCurrency.getSymbol(), getResources(), getContext(), new HomeActivity.IconCallBack() {
@Override
public void onSuccess(Bitmap bitmapIcon) {
sucessCurrency.setIcon(bitmapIcon);
updateChartColor(currency);
countWatchlist();
}
});
}
else
{
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_moodl);
icon = Bitmap.createScaledBitmap(icon, 50, 50, false);
@Override
public void onHistoryDataUpdated() {
sucessCurrency.setIcon(icon);
updateChartColor(currency);
countWatchlist();
}
}
@Override
public void onPriceUpdated(Currency successCurrency) {
String iconUrl = MoodlBox.getIconUrl(currency.getSymbol(), cryptocompareApiManager);
MoodlBox.getBitmapFromURL(iconUrl, currency.getSymbol(), getResources(), getActivity().getBaseContext(), new MoodlboxNotifierInterface() {
@Override
public void onBitmapDownloaded(Bitmap bitmapIcon) {
currency.setIcon(bitmapIcon);
currency.setChartColor(getIconDominantColor(getContext(), bitmapIcon));
countWatchlist();
}
});
}
});
}

View File

@ -1,168 +1,676 @@
package com.herbron.moodl.Activities;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.TextInputLayout;
import android.support.design.widget.TabLayout;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.TimePicker;
import com.herbron.moodl.Activities.RecordTransactionFragments.BuyFragment;
import com.herbron.moodl.Activities.RecordTransactionFragments.SellFragment;
import com.herbron.moodl.CurrencyInfoUpdateNotifierInterface;
import com.herbron.moodl.CustomAdapters.PairRecordListAdapter;
import com.herbron.moodl.CustomLayouts.CustomRecordFragment;
import com.herbron.moodl.CustomLayouts.CustomViewPager;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.Transaction;
import com.herbron.moodl.DataManagers.ExchangeManager.Exchange;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CryptocompareApiManager;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.DataManagers.InfoAPIManagers.Pair;
import com.herbron.moodl.DataNotifiers.CryptocompareNotifierInterface;
import com.herbron.moodl.CustomAdapters.CoinRecordListAdapter;
import com.herbron.moodl.CustomLayouts.CustomTabLayout;
import com.herbron.moodl.CustomAdapters.ExchangeRecordListAdapter;
import com.herbron.moodl.CustomAdapters.RecordTransactionPageAdapter;
import com.herbron.moodl.MoodlBox;
import com.herbron.moodl.DataNotifiers.MoodlboxNotifierInterface;
import com.herbron.moodl.Utils.PlaceholderUtils;
import com.herbron.moodl.R;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.ArrayList;
import java.util.List;
public class RecordTransactionActivity extends AppCompatActivity {
public class RecordTransactionActivity extends AppCompatActivity implements CurrencyInfoUpdateNotifierInterface, CryptocompareNotifierInterface {
private Toolbar toolbar;
private ImageView currencyIconImageView;
private String coin;
private String symbol;
private TextView symbolTxtView;
private TextInputLayout purchasedDateLayout;
private EditText purchaseDate;
private TextView feesTxtView;
private EditText amountTxtView;
private Button buyButton;
private Button sellButton;
private Button transferButton;
private DatabaseManager databaseManager;
private Calendar calendar;
private SimpleDateFormat sdf;
private PreferencesManager preferenceManager;
private EditText purchasedPriceEditText;
private Currency currency;
private int transactionId;
private Exchange exchange;
private Pair pair;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_record_action, menu);
return true;
}
private CryptocompareApiManager cryptocompareApiManager;
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_record:
private AutoCompleteTextView coin_autoCompleteTextView;
private AutoCompleteTextView exchange_autoCompleteTextView;
private AutoCompleteTextView pair_autoCompleteTextView;
if(checkAmountText() && checkPriceText())
{
double amount = Double.parseDouble(amountTxtView.getText().toString());
double purchasedPrice = Double.parseDouble(purchasedPriceEditText.getText().toString());
double fees = Double.parseDouble(feesTxtView.getText().toString());
private CustomTabLayout tabLayout;
private CustomViewPager viewPager;
if(!sellButton.isEnabled())
{
amount *= -1;
}
private RecordTransactionPageAdapter pageAdapter;
if(transactionId != -1)
{
databaseManager.updateTransactionWithId(transactionId, amount, calendar.getTime(), purchasedPrice, fees);
}
else
{
databaseManager.addCurrencyToManualCurrency(symbol, amount, calendar.getTime(), purchasedPrice, fees);
}
private Animation revealAnimation;
private Animation dismissAnimation;
preferenceManager.setMustUpdateSummary(true);
Intent intent = new Intent(RecordTransactionActivity.this, HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
finish();
}
break;
case android.R.id.home:
//NavUtils.navigateUpFromSameTask(this);
finish();
break;
default:
break;
}
return true;
}
private LinearLayout globalTabLayouts;
private boolean checkPriceText()
{
String purchasedPriceText = purchasedPriceEditText.getText().toString();
private boolean isGlobalLayoutVisible;
try {
Double.parseDouble(purchasedPriceText);
} catch (NumberFormatException e) {
purchasedPriceEditText.setError(getResources().getString(R.string.field_nan));
private Intent callingIntent;
private TextWatcher coinTextWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
return false;
}
if(purchasedPriceText.equals(""))
{
purchasedPriceEditText.setError(getResources().getString(R.string.field_empty));
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
currencyIconImageView.setImageBitmap(null);
exchange_autoCompleteTextView.setEnabled(false);
exchange_autoCompleteTextView.setText("");
return false;
((LinearLayout) tabLayout.getChildAt(0)).getChildAt(2).setEnabled(false);
((TextView) tabLayout.getTabAt(2).getCustomView()).setTextColor(getResources().getColor(R.color.separationColor));
if(isGlobalLayoutVisible && globalTabLayouts.getAnimation().hasEnded())
{
globalTabLayouts.startAnimation(dismissAnimation);
}
}
return true;
}
@Override
public void afterTextChanged(Editable s) {
private boolean checkAmountText()
{
String amountText = amountTxtView.getText().toString();
try {
Double.parseDouble(amountText);
} catch (NumberFormatException e) {
amountTxtView.setError(getResources().getString(R.string.field_nan));
return false;
}
if(amountText.equals(""))
{
amountTxtView.setError(getResources().getString(R.string.field_empty));
return false;
}
return true;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_record_transaction);
Intent intent = getIntent();
toolbar = findViewById(R.id.toolbar);
sdf = new SimpleDateFormat(" HH:mm dd/MM/yyyy", Locale.UK);
currencyIconImageView = findViewById(R.id.currencyIconImageView);
cryptocompareApiManager = CryptocompareApiManager.getInstance(this);
calendar = Calendar.getInstance();
cryptocompareApiManager.addListener(this);
databaseManager = new DatabaseManager(this);
preferenceManager = new PreferencesManager(this);
cryptocompareApiManager.updateExchangeList();
initializeViewElements();
coin_autoCompleteTextView = findViewById(R.id.coin_autoCompleteTextView);
exchange_autoCompleteTextView = findViewById(R.id.exchange_autoCompleteTextView);
pair_autoCompleteTextView = findViewById(R.id.pair_autoCompleteTextView);
coin = intent.getStringExtra("coin");
symbol = intent.getStringExtra("symbol");
setSupportActionBar(toolbar);
transactionId = intent.getIntExtra("transactionId", -1);
setupTabLayout();
setupCoinAutoCompleteTextView();
setupExchangeAutoCompleteTextView();
setupPairAutoCompleteTextView();
setupBackButton();
}
@Override
protected void onStop() {
super.onStop();
if(callingIntent != null)
{
callingIntent.removeExtra("transactionId");
}
}
private void checkCallingIntent()
{
callingIntent = getIntent();
int transactionId = callingIntent.getIntExtra("transactionId", -1);
if(transactionId != -1)
{
setTitle("Edit " + coin + " transaction");
List<Exchange> exchangeList;
List<Pair> pairList;
DatabaseManager databaseManager = new DatabaseManager(getBaseContext());
Transaction transaction = databaseManager.getCurrencyTransactionById(transactionId);
List<Currency> denominationList = cryptocompareApiManager.getCurrenciesDenomination();
boolean found = false;
int index = 0;
while(index < denominationList.size() && !found)
{
if(denominationList.get(index).getSymbol().equals(transaction.getSymbol()))
{
currency = denominationList.get(index);
found = true;
currency.setListener(RecordTransactionActivity.this);
updateExchangeAdapter(currency.getSymbol());
exchange_autoCompleteTextView.setEnabled(true);
IconDownloaderTask iconDownloaderTask = new IconDownloaderTask();
iconDownloaderTask.execute();
coin_autoCompleteTextView.removeTextChangedListener(coinTextWatcher);
coin_autoCompleteTextView.setText(PlaceholderUtils.getDenomination(currency.getName(), currency.getSymbol(), getBaseContext()));
coin_autoCompleteTextView.setEnabled(false);
if(globalTabLayouts.getVisibility() == View.GONE)
{
globalTabLayouts.setVisibility(View.VISIBLE);
}
globalTabLayouts.startAnimation(revealAnimation);
isGlobalLayoutVisible = true;
updateCurrencyData();
}
index++;
}
found = false;
index = 0;
switch (transaction.getType())
{
case "b":
exchangeList = cryptocompareApiManager.getExchangeList(currency.getSymbol());
while(index < exchangeList.size() && !found)
{
if(exchangeList.get(index).getName().equals(transaction.getSource()))
{
exchange = exchangeList.get(index);
exchange_autoCompleteTextView.setText(exchange.getName());
exchange_autoCompleteTextView.setEnabled(true);
updateExchangeData();
updatePairAdapter();
found = true;
}
index++;
}
pairList = exchange.getPairsFor(currency.getSymbol());
found = false;
index = 0;
while(index < pairList.size() && !found)
{
if(pairList.get(index).contains(currency.getSymbol()) && pairList.get(index).contains(transaction.getSymPair()))
{
pair = pairList.get(index);
pair_autoCompleteTextView.setText(PlaceholderUtils.getPairString(pair.getFrom(), pair.getTo(), getBaseContext()));
pair_autoCompleteTextView.setEnabled(true);
((BuyFragment) pageAdapter.getItem(0)).updatePair(pair);
//updatePairData();
found = true;
}
index++;
}
tabLayout.getTabAt(0).select();
((TextView) tabLayout.getTabAt(0).getCustomView()).setTextColor(getResources().getColor(R.color.white));
break;
case "s":
exchangeList = cryptocompareApiManager.getExchangeList(currency.getSymbol());
while(index < exchangeList.size() && !found)
{
if(exchangeList.get(index).getName().equals(transaction.getSource()))
{
exchange = exchangeList.get(index);
exchange_autoCompleteTextView.setText(exchange.getName());
exchange_autoCompleteTextView.setEnabled(true);
updateExchangeData();
updatePairAdapter();
found = true;
}
index++;
}
pairList = exchange.getPairsFor(currency.getSymbol());
found = false;
index = 0;
while(index < pairList.size() && !found)
{
if(pairList.get(index).contains(currency.getSymbol()) && pairList.get(index).contains(transaction.getSymPair()))
{
pair = pairList.get(index);
pair_autoCompleteTextView.setText(PlaceholderUtils.getPairString(pair.getFrom(), pair.getTo(), getBaseContext()));
pair_autoCompleteTextView.setEnabled(true);
((SellFragment) pageAdapter.getItem(1)).updatePair(pair);
//updatePairData();
found = true;
}
index++;
}
tabLayout.getTabAt(1).select();
((TextView) tabLayout.getTabAt(1).getCustomView()).setTextColor(getResources().getColor(R.color.white));
break;
case "t":
tabLayout.getTabAt(2).select();
((TextView) tabLayout.getTabAt(2).getCustomView()).setTextColor(getResources().getColor(R.color.white));
break;
}
}
}
public Currency getCurrency()
{
return currency;
}
private void setupTabLayout()
{
globalTabLayouts = findViewById(R.id.globalTabLayouts);
tabLayout = findViewById(R.id.transactionsTabLayout);
tabLayout.addTab(0, getResources().getString(R.string.buyText));
tabLayout.addTab(1, getResources().getString(R.string.sellText));
tabLayout.addTab(2, getResources().getString(R.string.transferText));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
viewPager = findViewById(R.id.transactionsViewPager);
pageAdapter = new RecordTransactionPageAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pageAdapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
viewPager.setPagingEnabled(false);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
LinearLayout tabLayoutChildren = (LinearLayout) tabLayout.getChildAt(0);
for(int i = 0; i < tabLayoutChildren.getChildCount(); i++)
{
tabLayoutChildren.getChildAt(i).setEnabled(false);
((TextView) tabLayout.getTabAt(i).getCustomView()).setTextColor(getResources().getColor(R.color.separationColor));
}
revealAnimation = AnimationUtils.loadAnimation(this, R.anim.reveal);
dismissAnimation = AnimationUtils.loadAnimation(this, R.anim.dismiss);
dismissAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
isGlobalLayoutVisible = false;
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
private void setupPairAutoCompleteTextView()
{
pair_autoCompleteTextView.setThreshold(0);
pair_autoCompleteTextView.setTextColor(getResources().getColor(R.color.white));
pair_autoCompleteTextView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
((LinearLayout) tabLayout.getChildAt(0)).getChildAt(0).setEnabled(false);
((TextView) tabLayout.getTabAt(0).getCustomView()).setTextColor(getResources().getColor(R.color.separationColor));
((LinearLayout) tabLayout.getChildAt(0)).getChildAt(1).setEnabled(false);
((TextView) tabLayout.getTabAt(1).getCustomView()).setTextColor(getResources().getColor(R.color.separationColor));
tabLayout.getTabAt(2).select();
}
@Override
public void afterTextChanged(Editable s) {
}
});
pair_autoCompleteTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pair_autoCompleteTextView.showDropDown();
}
});
pair_autoCompleteTextView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus)
{
pair_autoCompleteTextView.showDropDown();
}
else
{
pair_autoCompleteTextView.dismissDropDown();
}
}
});
pair_autoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
pair = (Pair) pair_autoCompleteTextView.getAdapter().getItem(position);
pair_autoCompleteTextView.setText(PlaceholderUtils.getPairString(pair.getFrom(), pair.getTo(), getBaseContext()));
toolbar.requestFocus();
hideSoftKeyboard(RecordTransactionActivity.this);
updatePairData();
((LinearLayout) tabLayout.getChildAt(0)).getChildAt(0).setEnabled(true);
((TextView) tabLayout.getTabAt(0).getCustomView()).setTextColor(getResources().getColor(R.color.white));
((LinearLayout) tabLayout.getChildAt(0)).getChildAt(1).setEnabled(true);
((TextView) tabLayout.getTabAt(1).getCustomView()).setTextColor(getResources().getColor(R.color.white));
tabLayout.getTabAt(0).select();
}
});
}
private void setupExchangeAutoCompleteTextView()
{
exchange_autoCompleteTextView.setThreshold(0);
exchange_autoCompleteTextView.setTextColor(getResources().getColor(R.color.white));
exchange_autoCompleteTextView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
pair_autoCompleteTextView.setEnabled(false);
pair_autoCompleteTextView.setText("");
((LinearLayout) tabLayout.getChildAt(0)).getChildAt(0).setEnabled(false);
((TextView) tabLayout.getTabAt(0).getCustomView()).setTextColor(getResources().getColor(R.color.separationColor));
((LinearLayout) tabLayout.getChildAt(0)).getChildAt(1).setEnabled(false);
((TextView) tabLayout.getTabAt(1).getCustomView()).setTextColor(getResources().getColor(R.color.separationColor));
tabLayout.getTabAt(2).select();
}
@Override
public void afterTextChanged(Editable s) {
}
});
exchange_autoCompleteTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
exchange_autoCompleteTextView.showDropDown();
}
});
exchange_autoCompleteTextView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus)
{
exchange_autoCompleteTextView.showDropDown();
}
else
{
exchange_autoCompleteTextView.dismissDropDown();
}
}
});
exchange_autoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
exchange = (Exchange) exchange_autoCompleteTextView.getAdapter().getItem(position);
exchange_autoCompleteTextView.setText(exchange.getName());
toolbar.requestFocus();
hideSoftKeyboard(RecordTransactionActivity.this);
updatePairAdapter();
pair_autoCompleteTextView.setEnabled(true);
updateExchangeData();
}
});
}
private void updatePairAdapter()
{
PairRecordListAdapter pairAdapter = new PairRecordListAdapter(this, android.R.layout.simple_list_item_1, new ArrayList<>(exchange.getPairsFor(currency.getSymbol())));
pair_autoCompleteTextView.setAdapter(pairAdapter);
}
private void updateExchangeAdapter(String symbol)
{
ExchangeRecordListAdapter exchangeAdapter = new ExchangeRecordListAdapter(this, android.R.layout.simple_list_item_1, new ArrayList<>(cryptocompareApiManager.getExchangeList(symbol)));
exchange_autoCompleteTextView.setAdapter(exchangeAdapter);
}
private void setupCoinAutoCompleteTextView()
{
CoinRecordListAdapter adapter = new CoinRecordListAdapter(getBaseContext(), R.layout.custom_summary_coin_row, new ArrayList<>(cryptocompareApiManager.getCurrenciesDenomination()));
coin_autoCompleteTextView.setThreshold(0);
coin_autoCompleteTextView.setAdapter(adapter);
coin_autoCompleteTextView.setTextColor(getResources().getColor(R.color.white));
coin_autoCompleteTextView.addTextChangedListener(coinTextWatcher);
coin_autoCompleteTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
coin_autoCompleteTextView.showDropDown();
}
});
coin_autoCompleteTextView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus)
{
coin_autoCompleteTextView.showDropDown();
}
else
{
coin_autoCompleteTextView.dismissDropDown();
}
}
});
coin_autoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
currency = (Currency) coin_autoCompleteTextView.getAdapter().getItem(position);
coin_autoCompleteTextView.setText(PlaceholderUtils.getDenomination(currency.getName(), currency.getSymbol(), getBaseContext()));
toolbar.requestFocus();
hideSoftKeyboard(RecordTransactionActivity.this);
currency.setListener(RecordTransactionActivity.this);
updateExchangeAdapter(currency.getSymbol());
exchange_autoCompleteTextView.setEnabled(true);
IconDownloaderTask iconDownloaderTask = new IconDownloaderTask();
iconDownloaderTask.execute();
((LinearLayout) tabLayout.getChildAt(0)).getChildAt(0).setEnabled(false);
((TextView) tabLayout.getTabAt(0).getCustomView()).setTextColor(getResources().getColor(R.color.separationColor));
((LinearLayout) tabLayout.getChildAt(0)).getChildAt(1).setEnabled(false);
((TextView) tabLayout.getTabAt(1).getCustomView()).setTextColor(getResources().getColor(R.color.separationColor));
((LinearLayout) tabLayout.getChildAt(0)).getChildAt(2).setEnabled(true);
((TextView) tabLayout.getTabAt(2).getCustomView()).setTextColor(getResources().getColor(R.color.white));
tabLayout.getTabAt(2).select();
updateCurrencyData();
if(globalTabLayouts.getVisibility() == View.GONE)
{
globalTabLayouts.setVisibility(View.VISIBLE);
}
globalTabLayouts.startAnimation(revealAnimation);
isGlobalLayoutVisible = true;
}
});
}
private void updateCurrencyData()
{
for(int i = 0; i < pageAdapter.getCount(); i++)
{
((CustomRecordFragment) pageAdapter.getItem(i)).setCurrency(currency);
}
}
private void updateExchangeData()
{
for(int i = 0; i < pageAdapter.getCount(); i++)
{
((CustomRecordFragment) pageAdapter.getItem(i)).setExchange(exchange);
}
}
private void updatePairData()
{
for(int i = 0; i < pageAdapter.getCount(); i++)
{
((CustomRecordFragment) pageAdapter.getItem(i)).setPair(pair);
}
}
@Override
public void onTimestampPriceUpdated(String price) {
//purchasedPriceEditText.setText(price);
}
@Override
public void onHistoryDataUpdated() {
}
@Override
public void onPriceUpdated(Currency currency) {
}
@Override
public void onDetailsUpdated() {
}
@Override
public void onExchangesUpdated() {
checkCallingIntent();
}
private class IconDownloaderTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
String iconUrl = MoodlBox.getIconUrl(currency.getSymbol(), 500, cryptocompareApiManager);
if(iconUrl != null)
{
MoodlBox.getBitmapFromURL(iconUrl, currency.getSymbol(), getResources(), getBaseContext(), new MoodlboxNotifierInterface() {
@Override
public void onBitmapDownloaded(Bitmap bitmapIcon) {
runOnUiThread(new Runnable() {
@Override
public void run() {
currencyIconImageView.setImageBitmap(bitmapIcon);
}
});
}
});
}
else
{
runOnUiThread(new Runnable() {
@Override
public void run() {
currencyIconImageView.setBackground(getResources().getDrawable(R.mipmap.ic_launcher_moodl));
}
});
}
return null;
}
}
/*if(transactionId != -1)
{
setTitle(PlaceholderUtils.getEditTransactionString(coin, getBaseContext()));
DatabaseManager databaseManager = new DatabaseManager(this);
Transaction transaction = databaseManager.getCurrencyTransactionById(transactionId);
@ -174,7 +682,7 @@ public class RecordTransactionActivity extends AppCompatActivity {
}
else
{
setTitle("Add " + coin + " transaction");
setTitle(getString(R.string.new_transaction));
purchaseDate.setText(sdf.format(calendar.getTime()));
symbolTxtView.setText(symbol);
@ -199,107 +707,31 @@ public class RecordTransactionActivity extends AppCompatActivity {
}
});
initializeButtons();
//initializeButtons();
currency.getTimestampPrice(this, preferenceManager.getDefaultCurrency(), new Currency.PriceCallBack() {
@Override
public void onSuccess(String price) {
purchasedPriceEditText.setText(price);
}
}, calendar.getTimeInMillis() / 1000);
}, calendar.getTimeInMillis() / 1000);*/
public static void hideSoftKeyboard(Activity activity) {
InputMethodManager inputMethodManager =
(InputMethodManager) activity.getSystemService(
Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(
activity.getCurrentFocus().getWindowToken(), 0);
}
private void initializeButtons()
private void setupBackButton()
{
buyButton.setOnClickListener(new View.OnClickListener() {
ImageButton backButton = findViewById(R.id.back_button);
backButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
buyButton.setEnabled(false);
sellButton.setEnabled(true);
transferButton.setEnabled(true);
findViewById(R.id.input_purchase_price).setVisibility(View.VISIBLE);
findViewById(R.id.input_fees).setVisibility(View.GONE);
public void onClick(View v) {
finish();
}
});
sellButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
buyButton.setEnabled(true);
sellButton.setEnabled(false);
transferButton.setEnabled(true);
findViewById(R.id.input_purchase_price).setVisibility(View.GONE);
findViewById(R.id.input_fees).setVisibility(View.VISIBLE);
}
});
transferButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
buyButton.setEnabled(true);
sellButton.setEnabled(true);
transferButton.setEnabled(false);
// Prepare transfer interface
}
});
}
private void initializeViewElements()
{
symbolTxtView = findViewById(R.id.currencySymbol);
amountTxtView = findViewById(R.id.currencyAmount);
feesTxtView = findViewById(R.id.feesTextView);
purchasedDateLayout = findViewById(R.id.input_purchase_date);
purchaseDate = findViewById(R.id.purchaseDate);
purchasedPriceEditText = findViewById(R.id.purchasePrice);
buyButton = findViewById(R.id.buyButton);
sellButton = findViewById(R.id.sellButton);
transferButton = findViewById(R.id.transfertButton);
}
private void createDatePicker()
{
new android.app.DatePickerDialog(
RecordTransactionActivity.this,
new android.app.DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
purchaseDate.setText(sdf.format(calendar.getTime()));
createTimePicker();
}
},
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH)
).show();
}
private void createTimePicker()
{
new android.app.TimePickerDialog(
RecordTransactionActivity.this,
new android.app.TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hour, int minute) {
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
purchaseDate.setText(sdf.format(calendar.getTime()));
currency.getTimestampPrice(RecordTransactionActivity.this, preferenceManager.getDefaultCurrency(), new Currency.PriceCallBack() {
@Override
public void onSuccess(String price) {
purchasedPriceEditText.setText(price);
}
}, calendar.getTimeInMillis() / 1000);
Log.d("moodl", "Time : " + calendar.getTimeInMillis());
}
},
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
true
).show();
}
}

View File

@ -0,0 +1,586 @@
package com.herbron.moodl.Activities.RecordTransactionFragments;
import android.app.DatePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputEditText;
import android.support.v7.widget.AppCompatButton;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.DatePicker;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TimePicker;
import com.herbron.moodl.Activities.HomeActivity;
import com.herbron.moodl.CustomLayouts.CustomRecordFragment;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.Transaction;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.ExchangeManager.Exchange;
import com.herbron.moodl.DataManagers.InfoAPIManagers.Pair;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.Utils.PlaceholderUtils;
import com.herbron.moodl.R;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
public class BuyFragment extends CustomRecordFragment {
private TextInputEditText amoutEditText;
private TextInputEditText buyPriceEditText;
private TextInputEditText buyDateEditText;
private TextInputEditText totalValueEditText;
private TextInputEditText fees_editText;
private TextInputEditText note_editText;
private AppCompatButton saveBuyButton;
private static Spinner feesCurrencySpinner;
private static View view;
private Switch deductHoldingsSwitch;
private ArrayAdapter<String> currencyFeeAdapter;
private SimpleDateFormat sdf;
private Calendar calendar;
private PreferencesManager preferenceManager;
private static Context context;
private static Currency fragmentCurrency;
private static Exchange fragmentExchange;
private static Pair fragmentPair;
private List<String> symbolStrings;
private int transactionId;
private static Transaction transaction;
private boolean isAmountLastUpdated;
private TextWatcher amountTextWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
totalValueEditText.removeTextChangedListener(totalValueTextWatcher);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(isFieldCorrectlyFilled(buyPriceEditText, false) && isFieldCorrectlyFilled(amoutEditText, false))
{
if(Double.parseDouble(amoutEditText.getText().toString()) > 0)
{
Double totalValue = Double.parseDouble(buyPriceEditText.getText().toString()) * Double.parseDouble(s.toString());
totalValueEditText.setText(String.format("%f", totalValue));
}
else
{
totalValueEditText.setText("0");
}
}
else
{
totalValueEditText.setText("");
}
}
@Override
public void afterTextChanged(Editable s) {
totalValueEditText.addTextChangedListener(totalValueTextWatcher);
isAmountLastUpdated = true;
}
};
private TextWatcher totalValueTextWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
amoutEditText.removeTextChangedListener(amountTextWatcher);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(isFieldCorrectlyFilled(buyPriceEditText, false) && isFieldCorrectlyFilled(totalValueEditText, false))
{
if(Double.parseDouble(totalValueEditText.getText().toString()) > 0)
{
Double amount = Double.parseDouble(s.toString()) / Double.parseDouble(buyPriceEditText.getText().toString());
amoutEditText.setText(String.format("%f", amount));
}
else
{
amoutEditText.setText("0");
}
}
else
{
amoutEditText.setText("");
}
}
@Override
public void afterTextChanged(Editable s) {
amoutEditText.addTextChangedListener(amountTextWatcher);
isAmountLastUpdated = false;
}
};
private TextWatcher feesTextWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
totalValueEditText.removeTextChangedListener(totalValueTextWatcher);
amoutEditText.removeTextChangedListener(amountTextWatcher);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if((isFieldCorrectlyFilled(amoutEditText, false) || isFieldCorrectlyFilled(totalValueEditText, false)) && isFieldCorrectlyFilled(buyPriceEditText, false))
{
double amount = Double.parseDouble(amoutEditText.getText().toString());
double purchasePrice = Double.parseDouble(buyPriceEditText.getText().toString());
double fees;
double totalValue = Double.parseDouble(totalValueEditText.getText().toString());
String feeCurrency;
if(isAmountLastUpdated)
{
totalValue = amount * purchasePrice;
}
else
{
amount = totalValue / purchasePrice;
}
if(fees_editText.getText().toString().equals("0") || (start == 0 && before == 1 && count == 0))
{
if(isAmountLastUpdated)
{
totalValueEditText.setText(String.valueOf(amount * purchasePrice));
}
else
{
amoutEditText.setText(String.valueOf(totalValue / purchasePrice));
}
}
else
{
if(feesCurrencySpinner.getSelectedItemPosition() < 2)
{
feeCurrency = fragmentPair.getFrom();
}
else
{
feeCurrency = fragmentPair.getTo();
}
fees = getFees(feeCurrency, amount, purchasePrice);
if(feesCurrencySpinner.getSelectedItemPosition() % 2 == 0)
{
if(isAmountLastUpdated)
{
totalValueEditText.setText(String.valueOf(totalValue + fees));
}
else
{
amoutEditText.setText(String.valueOf(amount - (fees / purchasePrice)));
}
}
else
{
if(fragmentCurrency.getSymbol().equals(feeCurrency))
{
if(isAmountLastUpdated)
{
totalValueEditText.setText(String.valueOf(totalValue + (fees * purchasePrice)));
}
else
{
amoutEditText.setText(String.valueOf((totalValue / purchasePrice) - fees));
}
}
else
{
if(isAmountLastUpdated)
{
totalValueEditText.setText(String.valueOf(totalValue + fees));
}
else
{
amoutEditText.setText(String.valueOf((totalValue - fees) / purchasePrice));
}
}
}
}
}
}
@Override
public void afterTextChanged(Editable s) {
totalValueEditText.addTextChangedListener(totalValueTextWatcher);
amoutEditText.addTextChangedListener(amountTextWatcher);
}
};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.record_transaction_fragment_buy, container, false);
context = getActivity().getApplicationContext();
calendar = Calendar.getInstance();
sdf = new SimpleDateFormat("HH:mm dd/MM/yyyy", Locale.UK);
preferenceManager = new PreferencesManager(getContext());
initializeViewElements();
return view;
}
private void checkCallingIntent()
{
Intent intent = getActivity().getIntent();
transactionId = intent.getIntExtra("transactionId", -1);
if(transactionId != -1)
{
DatabaseManager databaseManager = new DatabaseManager(context);
transaction = databaseManager.getCurrencyTransactionById(transactionId);
if(transaction.getType() == null || transaction.getType().equals("b"))
{
fillFields();
}
}
}
private void fillFields()
{
amoutEditText.setText(String.valueOf(transaction.getAmount()));
buyPriceEditText.setText(String.valueOf(transaction.getPrice()));
calendar.setTimeInMillis(transaction.getTimestamp());
buyDateEditText.setText(sdf.format(calendar.getTime()));
totalValueEditText.setText(String.valueOf(transaction.getAmount() * transaction.getPrice()));
fees_editText.setText(String.valueOf(transaction.getFees()));
note_editText.setText(transaction.getNote());
deductHoldingsSwitch.setChecked(transaction.isDeducted());
}
private void initializeViewElements()
{
totalValueEditText = view.findViewById(R.id.totalValue_editText_buy);
amoutEditText = view.findViewById(R.id.amount_editText_buy);
buyPriceEditText = view.findViewById(R.id.buyPrice_editText);
buyDateEditText = view.findViewById(R.id.buyDate_editText);
buyDateEditText.setText(sdf.format(calendar.getTime()));
buyDateEditText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createDatePicker();
}
});
feesCurrencySpinner = view.findViewById(R.id.feesCurrency_editText_buy);
currencyFeeAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item, new ArrayList<>());
currencyFeeAdapter.setDropDownViewResource(R.layout.spinner_dropdown_black);
feesCurrencySpinner.setAdapter(currencyFeeAdapter);
deductHoldingsSwitch = view.findViewById(R.id.deductHoldingsBuy);
if(fragmentPair != null)
{
updateAdapter();
}
saveBuyButton = view.findViewById(R.id.saveBuyButton);
saveBuyButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isFieldCorrectlyFilled(amoutEditText, true) && isFieldCorrectlyFilled(buyPriceEditText, true) && isFieldCorrectlyFilled(totalValueEditText, true))
{
double amount = Double.parseDouble(amoutEditText.getText().toString());
double purchasePrice = Double.parseDouble(buyPriceEditText.getText().toString());
double fees;
String feeCurrency;
if(feesCurrencySpinner.getSelectedItemPosition() < 1)
{
feeCurrency = fragmentPair.getFrom();
}
else
{
feeCurrency = fragmentPair.getTo();
}
fees = getFees(feeCurrency, amount, purchasePrice);
String note = note_editText.getText().toString();
DatabaseManager databaseManager = new DatabaseManager(getContext());
preferenceManager.setMustUpdateSummary(true);
if(transactionId == -1)
{
databaseManager.addTransaction(fragmentCurrency.getSymbol()
, amount
, calendar.getTime()
, purchasePrice
, fees
, note
, fragmentPair.getFrom().equals(fragmentCurrency.getSymbol()) ? fragmentPair.getTo() : fragmentPair.getFrom()
, feeCurrency
, ""
, fragmentExchange.getName()
, "b"
, feesCurrencySpinner.getSelectedItemPosition() % 2 == 0 ? "p" : "f"
, deductHoldingsSwitch.isChecked());
Intent intent = new Intent(getActivity(), HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
else
{
databaseManager.updateTransactionWithId(transactionId
, amount
, calendar.getTime()
, purchasePrice
, fees
, note
, fragmentPair.getFrom().equals(fragmentCurrency.getSymbol()) ? fragmentPair.getTo() : fragmentPair.getFrom()
, feeCurrency
, ""
, fragmentExchange.getName()
,"b"
, feesCurrencySpinner.getSelectedItemPosition() % 2 == 0 ? "p" : "f"
, deductHoldingsSwitch.isChecked());
}
getActivity().finish();
}
}
});
fees_editText = view.findViewById(R.id.fees_editText_buy);
note_editText = view.findViewById(R.id.note_editText_buy);
checkCallingIntent();
setupTextWatchers();
}
private void setupTextWatchers()
{
totalValueEditText.addTextChangedListener(totalValueTextWatcher);
amoutEditText.addTextChangedListener(amountTextWatcher);
fees_editText.addTextChangedListener(feesTextWatcher);
}
private double getFees(String feeCurrency, double amount, double purchasedPrice)
{
double fees = 0;
if(!fees_editText.getText().toString().equals(""))
{
fees = Double.parseDouble(fees_editText.getText().toString());
if(feesCurrencySpinner.getSelectedItemPosition() % 2 == 0)
{
if(fragmentCurrency.getSymbol().equals(feeCurrency))
{
fees = (100 * amount) / (100 + fees);
}
else
{
double base = (100 * purchasedPrice * amount) / (100 + fees);
fees = purchasedPrice * amount - base;
}
}
}
return fees;
}
private boolean isFieldCorrectlyFilled(TextInputEditText editText, boolean displayError)
{
String purchasedPriceText = editText.getText().toString();
double purchasedPrice;
try {
purchasedPrice = Double.parseDouble(purchasedPriceText);
if(purchasedPrice < 0)
{
if(displayError) editText.setError(getResources().getString(R.string.field_negative));
return false;
}
} catch (NumberFormatException e) {
if(displayError) editText.setError(getResources().getString(R.string.field_nan));
return false;
}
if(purchasedPriceText.equals(""))
{
if(displayError) editText.setError(getResources().getString(R.string.field_empty));
return false;
}
return true;
}
private void updateAdapter()
{
symbolStrings = new ArrayList<>();
symbolStrings.addAll(PlaceholderUtils.getFeeOptionsForSymbol(fragmentPair.getFrom(), getSecureContext()));
symbolStrings.addAll(PlaceholderUtils.getFeeOptionsForSymbol(fragmentPair.getTo(), getSecureContext()));
currencyFeeAdapter.clear();
currencyFeeAdapter.addAll(symbolStrings);
currencyFeeAdapter.notifyDataSetChanged();
}
private void createDatePicker()
{
DatePickerDialog datePickerDialog = new DatePickerDialog(
getContext(),
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
buyDateEditText.setText(sdf.format(calendar.getTime()));
createTimePicker();
}
},
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH)
);
datePickerDialog.getDatePicker().setMaxDate(Calendar.getInstance().getTimeInMillis());
datePickerDialog.show();
}
private void createTimePicker()
{
new android.app.TimePickerDialog(
getContext(),
new android.app.TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hour, int minute) {
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
buyDateEditText.setText(sdf.format(calendar.getTime()));
if(fragmentCurrency != null)
{
fragmentCurrency.getTimestampPrice(getContext(), fragmentCurrency.getSymbol().equals(fragmentPair.getFrom()) ? fragmentPair.getTo() : fragmentPair.getFrom(),calendar.getTimeInMillis() / 1000);
}
}
},
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
true
).show();
}
private static Context getSecureContext()
{
return context;
}
@Override
public void onCurrencyUpdated() {
fragmentCurrency = currency;
}
@Override
public void onExchangeUpdated() {
fragmentExchange = exchange;
}
public void updatePair(Pair pair)
{
fragmentPair = pair;
currencyFeeAdapter = new ArrayAdapter<String>(getSecureContext(), android.R.layout.simple_spinner_item, new ArrayList<>());
currencyFeeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
feesCurrencySpinner.setAdapter(currencyFeeAdapter);
symbolStrings = new ArrayList<>();
symbolStrings.addAll(PlaceholderUtils.getFeeOptionsForSymbol(pair.getFrom(), getSecureContext()));
symbolStrings.addAll(PlaceholderUtils.getFeeOptionsForSymbol(pair.getTo(), getSecureContext()));
currencyFeeAdapter.addAll(symbolStrings);
currencyFeeAdapter.notifyDataSetChanged();
if(transaction != null)
{
if(transaction.getFeeCurrency().equals(fragmentPair.getFrom()))
{
if(transaction.getFeeFormat().equals("p"))
{
feesCurrencySpinner.setSelection(0);
}
else
{
feesCurrencySpinner.setSelection(1);
}
}
else
{
if(transaction.getFeeFormat().equals("p"))
{
feesCurrencySpinner.setSelection(2);
}
else
{
feesCurrencySpinner.setSelection(3);
}
}
}
}
@Override
public void onPairUpdated() {
fragmentPair = pair;
fragmentCurrency.addOnTimestampPriceUpdatedListener(new Currency.OnTimestampPriceUpdatedListener() {
@Override
public void onTimeStampPriceUpdated(String price) {
((TextInputEditText) view.findViewById(R.id.buyPrice_editText)).setText(price);
updatePair(fragmentPair);
}
});
if(calendar == null)
{
calendar = Calendar.getInstance();
}
fragmentCurrency.getTimestampPrice(getSecureContext(), fragmentCurrency.getSymbol().equals(fragmentPair.getFrom()) ? fragmentPair.getTo() : fragmentPair.getFrom(), calendar.getTimeInMillis() / 1000);
}
}

View File

@ -0,0 +1,589 @@
package com.herbron.moodl.Activities.RecordTransactionFragments;
import android.app.DatePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputEditText;
import android.support.v7.widget.AppCompatButton;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.DatePicker;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TimePicker;
import com.herbron.moodl.Activities.HomeActivity;
import com.herbron.moodl.CustomLayouts.CustomRecordFragment;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.Transaction;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.ExchangeManager.Exchange;
import com.herbron.moodl.DataManagers.InfoAPIManagers.Pair;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.Utils.PlaceholderUtils;
import com.herbron.moodl.R;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
public class SellFragment extends CustomRecordFragment {
private TextInputEditText amoutEditText;
private TextInputEditText sellPriceEditText;
private TextInputEditText sellDateEditText;
private TextInputEditText totalValueEditText;
private TextInputEditText fees_editText;
private TextInputEditText note_editText;
private AppCompatButton saveSellButton;
private static Spinner feesCurrencySpinner;
private static View view;
private Switch deductHoldingsSwitch;
private ArrayAdapter<String> currencyFeeAdapter;
private SimpleDateFormat sdf;
private Calendar calendar;
private PreferencesManager preferenceManager;
private static Context context;
private static Currency fragmentCurrency;
private static Exchange fragmentExchange;
private static Pair fragmentPair;
private List<String> symbolStrings;
private int transactionId;
private static Transaction transaction;
private boolean isAmountLastUpdated;
private TextWatcher amountTextWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
totalValueEditText.removeTextChangedListener(totalValueTextWatcher);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(isFieldCorrectlyFilled(sellPriceEditText, false) && isFieldCorrectlyFilled(amoutEditText, false))
{
if(Double.parseDouble(amoutEditText.getText().toString()) > 0)
{
Double totalValue = Double.parseDouble(sellPriceEditText.getText().toString()) * Double.parseDouble(s.toString());
totalValueEditText.setText(String.format("%f", totalValue));
}
else
{
totalValueEditText.setText("0");
}
}
else
{
totalValueEditText.setText("");
}
}
@Override
public void afterTextChanged(Editable s) {
totalValueEditText.addTextChangedListener(totalValueTextWatcher);
isAmountLastUpdated = true;
}
};
private TextWatcher totalValueTextWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
amoutEditText.removeTextChangedListener(amountTextWatcher);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(isFieldCorrectlyFilled(sellPriceEditText, false) && isFieldCorrectlyFilled(totalValueEditText, false))
{
if(Double.parseDouble(totalValueEditText.getText().toString()) > 0)
{
Double amount = Double.parseDouble(s.toString()) / Double.parseDouble(sellPriceEditText.getText().toString());
amoutEditText.setText(String.format("%f", amount));
}
else
{
amoutEditText.setText("0");
}
}
else
{
amoutEditText.setText("");
}
}
@Override
public void afterTextChanged(Editable s) {
amoutEditText.addTextChangedListener(amountTextWatcher);
isAmountLastUpdated = false;
}
};
private TextWatcher feesTextWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
totalValueEditText.removeTextChangedListener(totalValueTextWatcher);
amoutEditText.removeTextChangedListener(amountTextWatcher);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if((isFieldCorrectlyFilled(amoutEditText, false) || isFieldCorrectlyFilled(totalValueEditText, false)) && isFieldCorrectlyFilled(sellPriceEditText, false))
{
double amount = Double.parseDouble(amoutEditText.getText().toString());
double purchasePrice = Double.parseDouble(sellPriceEditText.getText().toString());
double fees;
double totalValue = Double.parseDouble(totalValueEditText.getText().toString());
String feeCurrency;
if(isAmountLastUpdated)
{
totalValue = amount * purchasePrice;
}
else
{
amount = totalValue / purchasePrice;
}
if(fees_editText.getText().toString().equals("0") || (start == 0 && before == 1 && count == 0))
{
if(isAmountLastUpdated)
{
totalValueEditText.setText(String.valueOf(amount * purchasePrice));
}
else
{
amoutEditText.setText(String.valueOf(totalValue / purchasePrice));
}
}
else
{
if(feesCurrencySpinner.getSelectedItemPosition() < 2)
{
feeCurrency = fragmentPair.getFrom();
}
else
{
feeCurrency = fragmentPair.getTo();
}
fees = getFees(feeCurrency, amount, purchasePrice);
if(feesCurrencySpinner.getSelectedItemPosition() % 2 == 0)
{
if(isAmountLastUpdated)
{
totalValueEditText.setText(String.valueOf(totalValue - fees));
}
else
{
amoutEditText.setText(String.valueOf(amount + (fees / purchasePrice)));
}
}
else
{
if(fragmentCurrency.getSymbol().equals(feeCurrency))
{
if(isAmountLastUpdated)
{
totalValueEditText.setText(String.valueOf(totalValue - (fees * purchasePrice)));
}
else
{
amoutEditText.setText(String.valueOf((totalValue / purchasePrice) + fees));
}
}
else
{
if(isAmountLastUpdated)
{
totalValueEditText.setText(String.valueOf(totalValue - fees));
}
else
{
amoutEditText.setText(String.valueOf((totalValue + fees) / purchasePrice));
}
}
}
}
}
}
@Override
public void afterTextChanged(Editable s) {
totalValueEditText.addTextChangedListener(totalValueTextWatcher);
amoutEditText.addTextChangedListener(amountTextWatcher);
}
};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.record_transaction_fragment_sell, container, false);
context = getActivity().getApplicationContext();
calendar = Calendar.getInstance();
sdf = new SimpleDateFormat("HH:mm dd/MM/yyyy", Locale.UK);
preferenceManager = new PreferencesManager(getContext());
initializeViewElements();
return view;
}
private void initializeViewElements()
{
totalValueEditText = view.findViewById(R.id.totalValue_editText_sell);
amoutEditText = view.findViewById(R.id.amount_editText_sell);
sellPriceEditText = view.findViewById(R.id.sellPrice_editText);
sellDateEditText = view.findViewById(R.id.sellDate_editText);
sellDateEditText.setText(sdf.format(calendar.getTime()));
sellDateEditText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createDatePicker();
}
});
feesCurrencySpinner = view.findViewById(R.id.feesCurrency_editText_sell);
currencyFeeAdapter = new ArrayAdapter<String>(getSecureContext(), android.R.layout.simple_spinner_item, new ArrayList<>());
currencyFeeAdapter.setDropDownViewResource(R.layout.spinner_dropdown_black);
feesCurrencySpinner.setAdapter(currencyFeeAdapter);
if(fragmentPair != null)
{
updateAdapter();
}
deductHoldingsSwitch = view.findViewById(R.id.deductHoldingsSell);
saveSellButton = view.findViewById(R.id.saveSellButton);
saveSellButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isFieldCorrectlyFilled(amoutEditText, true) && isFieldCorrectlyFilled(sellPriceEditText, true) && isFieldCorrectlyFilled(totalValueEditText, true))
{
double amount = Double.parseDouble(amoutEditText.getText().toString());
double purchasePrice = Double.parseDouble(sellPriceEditText.getText().toString());
double fees;
String feeCurrency;
if(feesCurrencySpinner.getSelectedItemPosition() < 1)
{
feeCurrency = fragmentPair.getFrom();
}
else
{
feeCurrency = fragmentPair.getTo();
}
fees = getFees(feeCurrency, amount, purchasePrice);
String note = note_editText.getText().toString();
DatabaseManager databaseManager = new DatabaseManager(getContext());
preferenceManager.setMustUpdateSummary(true);
if(transactionId == -1)
{
databaseManager.addTransaction(fragmentCurrency.getSymbol()
, amount
, calendar.getTime()
, purchasePrice
, fees
, note
, fragmentPair.getFrom().equals(fragmentCurrency.getSymbol()) ? fragmentPair.getTo() : fragmentPair.getFrom()
, feeCurrency
, ""
, fragmentExchange.getName()
, "s"
, feesCurrencySpinner.getSelectedItemPosition() % 2 == 0 ? "p" : "f"
, deductHoldingsSwitch.isChecked());
Intent intent = new Intent(getActivity(), HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
else
{
databaseManager.updateTransactionWithId(transactionId
, amount
, calendar.getTime()
, purchasePrice
, fees
, note
, fragmentPair.getFrom().equals(fragmentCurrency.getSymbol()) ? fragmentPair.getTo() : fragmentPair.getFrom()
, feeCurrency
, ""
, fragmentExchange.getName()
,"s"
, feesCurrencySpinner.getSelectedItemPosition() % 2 == 0 ? "p" : "f"
, deductHoldingsSwitch.isChecked());
}
getActivity().finish();
}
}
});
fees_editText = view.findViewById(R.id.fees_editText_sell);
note_editText = view.findViewById(R.id.note_editText_sell);
checkCallingIntent();
setupTextWatchers();
}
private void setupTextWatchers()
{
totalValueEditText.addTextChangedListener(totalValueTextWatcher);
amoutEditText.addTextChangedListener(amountTextWatcher);
fees_editText.addTextChangedListener(feesTextWatcher);
}
private double getFees(String feeCurrency, double amount, double purchasedPrice)
{
double fees = 0;
if(!fees_editText.getText().toString().equals(""))
{
fees = Double.parseDouble(fees_editText.getText().toString());
if(feesCurrencySpinner.getSelectedItemPosition() % 2 == 0)
{
if(fragmentCurrency.getSymbol().equals(feeCurrency))
{
fees = (100 * amount) / (100 + fees);
}
else
{
double base = (100 * purchasedPrice * amount) / (100 + fees);
fees = purchasedPrice * amount - base;
}
}
}
return fees;
}
private void checkCallingIntent()
{
Intent intent = getActivity().getIntent();
transactionId = intent.getIntExtra("transactionId", -1);
if(transactionId != -1)
{
DatabaseManager databaseManager = new DatabaseManager(context);
transaction = databaseManager.getCurrencyTransactionById(transactionId);
if(transaction.getType().equals("s"))
{
fillFields();
}
}
}
private void fillFields()
{
amoutEditText.setText(String.valueOf(transaction.getAmount()));
sellPriceEditText.setText(String.valueOf(transaction.getPrice()));
calendar.setTimeInMillis(transaction.getTimestamp());
sellDateEditText.setText(sdf.format(calendar.getTime()));
totalValueEditText.setText(String.valueOf(transaction.getAmount() * transaction.getPrice()));
fees_editText.setText(String.valueOf(transaction.getFees()));
note_editText.setText(transaction.getNote());
}
private void updateAdapter()
{
symbolStrings = new ArrayList<>();
symbolStrings.addAll(PlaceholderUtils.getFeeOptionsForSymbol(fragmentPair.getFrom(), getSecureContext()));
symbolStrings.addAll(PlaceholderUtils.getFeeOptionsForSymbol(fragmentPair.getTo(), getSecureContext()));
currencyFeeAdapter.clear();
currencyFeeAdapter.addAll(symbolStrings);
currencyFeeAdapter.notifyDataSetChanged();
}
private static Context getSecureContext()
{
return context;
}
private void createDatePicker()
{
DatePickerDialog datePickerDialog = new DatePickerDialog(
getContext(),
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
sellDateEditText.setText(sdf.format(calendar.getTime()));
createTimePicker();
}
},
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH)
);
datePickerDialog.getDatePicker().setMaxDate(Calendar.getInstance().getTimeInMillis());
datePickerDialog.show();
}
private void createTimePicker()
{
new android.app.TimePickerDialog(
getContext(),
new android.app.TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hour, int minute) {
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
sellDateEditText.setText(sdf.format(calendar.getTime()));
if(fragmentCurrency != null)
{
fragmentCurrency.getTimestampPrice(getContext(), fragmentCurrency.getSymbol().equals(fragmentPair.getFrom()) ? fragmentPair.getTo() : fragmentPair.getFrom(),calendar.getTimeInMillis() / 1000);
}
}
},
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
true
).show();
}
private boolean isFieldCorrectlyFilled(TextInputEditText editText, boolean displayError)
{
String purchasedPriceText = editText.getText().toString();
double purchasedPrice;
try {
purchasedPrice = Double.parseDouble(purchasedPriceText);
if(purchasedPrice < 0)
{
if(displayError) editText.setError(getResources().getString(R.string.field_negative));
return false;
}
} catch (NumberFormatException e) {
if(displayError) editText.setError(getResources().getString(R.string.field_nan));
return false;
}
if(purchasedPriceText.equals(""))
{
if(displayError) editText.setError(getResources().getString(R.string.field_empty));
return false;
}
return true;
}
@Override
public void onCurrencyUpdated() {
fragmentCurrency = currency;
}
@Override
public void onExchangeUpdated() {
fragmentExchange = exchange;
}
public void updatePair(Pair pair)
{
fragmentPair = pair;
currencyFeeAdapter = new ArrayAdapter<String>(getSecureContext(), android.R.layout.simple_spinner_item, new ArrayList<>());
currencyFeeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
feesCurrencySpinner.setAdapter(currencyFeeAdapter);
symbolStrings = new ArrayList<>();
symbolStrings.addAll(PlaceholderUtils.getFeeOptionsForSymbol(pair.getFrom(), getSecureContext()));
symbolStrings.addAll(PlaceholderUtils.getFeeOptionsForSymbol(pair.getTo(), getSecureContext()));
currencyFeeAdapter.addAll(symbolStrings);
currencyFeeAdapter.notifyDataSetChanged();
if(transaction != null)
{
if(transaction.getFeeCurrency().equals(fragmentPair.getFrom()))
{
if(transaction.getFeeFormat().equals("p"))
{
feesCurrencySpinner.setSelection(0);
}
else
{
feesCurrencySpinner.setSelection(1);
}
}
else
{
if(transaction.getFeeFormat().equals("p"))
{
feesCurrencySpinner.setSelection(2);
}
else
{
feesCurrencySpinner.setSelection(3);
}
}
}
}
@Override
public void onPairUpdated() {
fragmentPair = pair;
fragmentCurrency.addOnTimestampPriceUpdatedListener(new Currency.OnTimestampPriceUpdatedListener() {
@Override
public void onTimeStampPriceUpdated(String price) {
((TextInputEditText) view.findViewById(R.id.sellPrice_editText)).setText(price);
updatePair(fragmentPair);
}
});
if(preferenceManager == null)
{
preferenceManager = new PreferencesManager(getSecureContext());
}
if(calendar == null)
{
calendar = Calendar.getInstance();
}
fragmentCurrency.getTimestampPrice(getSecureContext(), fragmentCurrency.getSymbol().equals(fragmentPair.getFrom()) ? fragmentPair.getTo() : fragmentPair.getFrom(), calendar.getTimeInMillis() / 1000);
}
}

View File

@ -0,0 +1,471 @@
package com.herbron.moodl.Activities.RecordTransactionFragments;
import android.app.DatePickerDialog;
import android.content.Intent;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputEditText;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TimePicker;
import com.herbron.moodl.Activities.HomeActivity;
import com.herbron.moodl.CustomLayouts.CustomRecordFragment;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.Transaction;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.ExchangeManager.Exchange;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.R;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
public class TransferFragment extends CustomRecordFragment {
private static Currency fragmentCurrency;
private static Exchange fragmentExchange;
private Spinner fromSpinner;
private Spinner toSpinner;
private Spinner feeSpinner;
private Switch deductHoldingsSwitch;
private Button saveButton;
private int transactionId;
private Transaction transaction;
private TextInputEditText transferDateEditText;
private TextInputEditText amountEditText;
private TextInputEditText feesEditText;
private TextInputEditText noteEditText;
private SimpleDateFormat sdf;
private Calendar calendar;
private View view;
public static final String EXCHANGE_CODE = "stra:e";
public static final String WALLET_CODE = "stra:mw";
public static final String MINING_CODE = "stra:m";
public static final String ELSE_WALLET_CODE = "stra:smew";
public static final String AIRDROP_CODE = "stra:a";
public static final String UNKNOWN_CODE = "stra:unk";
public static final String FORK_CODE = "stra:fo";
private View.OnClickListener saveButtonClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isFieldCorrectlyFilled(amountEditText, true))
{
if(isTransactionPossible())
{
PreferencesManager preferencesManager = new PreferencesManager(getContext());
DatabaseManager databaseManager = new DatabaseManager(getContext());
double amount = Double.valueOf(amountEditText.getText().toString());
double fees = getFees();
if(transactionId == -1)
{
databaseManager.addTransaction(fragmentCurrency.getSymbol()
, amount
, calendar.getTime()
, 0
, fees
, noteEditText.getText().toString()
, ""
, fragmentCurrency.getSymbol()
, getDestination()
, getSource()
, "t"
, feeSpinner.getSelectedItemPosition() == 0 ? "p" : "f"
, deductHoldingsSwitch.isChecked());
Intent intent = new Intent(getActivity(), HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
else
{
databaseManager.updateTransactionWithId(transactionId
, amount
, calendar.getTime()
, 0
, fees
, noteEditText.getText().toString()
, ""
, fragmentCurrency.getSymbol()
, getDestination()
, getSource()
,"t"
, feeSpinner.getSelectedItemPosition() == 0 ? "p" : "f"
, deductHoldingsSwitch.isChecked());
}
preferencesManager.setMustUpdateSummary(true);
getActivity().finish();
}
else
{
Drawable backgroundDrawableTo = toSpinner.getBackground();
backgroundDrawableTo.mutate();
backgroundDrawableTo.setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.error), PorterDuff.Mode.SRC_ATOP));
backgroundDrawableTo.invalidateSelf();
Drawable backgroundDrawableFrom = fromSpinner.getBackground();
backgroundDrawableFrom.mutate();
backgroundDrawableFrom.setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.error), PorterDuff.Mode.SRC_ATOP));
backgroundDrawableFrom.invalidateSelf();
view.findViewById(R.id.errorLayouts).setVisibility(View.VISIBLE);
}
}
}
};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.record_transaction_fragment_transfer, container, false);
calendar = Calendar.getInstance();
sdf = new SimpleDateFormat("HH:mm dd/MM/yyyy", Locale.UK);
initializeViewElements();
return view;
}
private void initializeViewElements()
{
fromSpinner = view.findViewById(R.id.from_transfer_spinner);
toSpinner = view.findViewById(R.id.to_transfer_spinner);
feeSpinner = view.findViewById(R.id.feesFormat_editText_transfer);
setupSpinnesr();
feesEditText = view.findViewById(R.id.fees_editText_transfer);
noteEditText = view.findViewById(R.id.note_editText_transfer);
amountEditText = view.findViewById(R.id.amount_editText_transfer);
transferDateEditText = view.findViewById(R.id.transfertDate_editText);
transferDateEditText.setText(sdf.format(calendar.getTime()));
transferDateEditText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createDatePicker();
}
});
saveButton = view.findViewById(R.id.saveTransferButton);
saveButton.setOnClickListener(saveButtonClickListener);
deductHoldingsSwitch = view.findViewById(R.id.deductHoldingsTransfer);
checkCallingIntent();
}
private void checkCallingIntent()
{
Intent intent = getActivity().getIntent();
transactionId = intent.getIntExtra("transactionId", -1);
if(transactionId != -1)
{
DatabaseManager databaseManager = new DatabaseManager(getContext());
transaction = databaseManager.getCurrencyTransactionById(transactionId);
if(transaction.getType() != null && transaction.getType().equals("t"))
{
fillFields();
}
}
}
private void fillFields()
{
setupFromSpinner();
setupToSpinner();
amountEditText.setText(String.valueOf(transaction.getAmount()));
calendar.setTimeInMillis(transaction.getTimestamp());
transferDateEditText.setText(sdf.format(calendar.getTime()));
feesEditText.setText(String.format(Locale.UK, "%f", transaction.getFees()));
noteEditText.setText(transaction.getNote());
feeSpinner.setSelection(transaction.getFeeFormat().equals("p") ? 0 : 1);
}
private void setupFromSpinner()
{
switch (transaction.getSource())
{
case EXCHANGE_CODE:
fromSpinner.setSelection(0);
break;
case WALLET_CODE:
fromSpinner.setSelection(1);
break;
case MINING_CODE:
fromSpinner.setSelection(2);
break;
case ELSE_WALLET_CODE:
fromSpinner.setSelection(3);
break;
case AIRDROP_CODE:
fromSpinner.setSelection(4);
break;
case UNKNOWN_CODE:
fromSpinner.setSelection(5);
break;
case FORK_CODE:
fromSpinner.setSelection(6);
break;
}
}
private void setupToSpinner()
{
switch (transaction.getDestination())
{
case EXCHANGE_CODE:
toSpinner.setSelection(0);
break;
case WALLET_CODE:
toSpinner.setSelection(1);
break;
case ELSE_WALLET_CODE:
toSpinner.setSelection(2);
break;
case UNKNOWN_CODE:
toSpinner.setSelection(3);
break;
}
}
private void setupSpinnesr()
{
ArrayAdapter<String> fromAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, getResources().getStringArray(R.array.from_transfer_options_string_array));
fromAdapter.setDropDownViewResource(R.layout.spinner_dropdown_black);
fromSpinner.setAdapter(fromAdapter);
ArrayAdapter<String> toAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, getResources().getStringArray(R.array.to_transfer_options_string_array));
toAdapter.setDropDownViewResource(R.layout.spinner_dropdown_black);
toSpinner.setAdapter(toAdapter);
ArrayAdapter<String> feeAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, getResources().getStringArray(R.array.fees_options));
feeAdapter.setDropDownViewResource(R.layout.spinner_dropdown_black);
feeSpinner.setAdapter(feeAdapter);
fromSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
Drawable backgroundDrawableFrom = fromSpinner.getBackground();
backgroundDrawableFrom.mutate();
backgroundDrawableFrom.setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.separationColor), PorterDuff.Mode.SRC_ATOP));
backgroundDrawableFrom.invalidateSelf();
view.findViewById(R.id.errorLayouts).setVisibility(View.INVISIBLE);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
toSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
Drawable backgroundDrawableTo = toSpinner.getBackground();
backgroundDrawableTo.mutate();
backgroundDrawableTo.setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.separationColor), PorterDuff.Mode.SRC_ATOP));
backgroundDrawableTo.invalidateSelf();
view.findViewById(R.id.errorLayouts).setVisibility(View.INVISIBLE);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
private double getFees()
{
double fees = 0;
if(!feesEditText.getText().toString().equals(""))
{
fees = Double.parseDouble(feesEditText.getText().toString());
}
return fees;
}
private boolean isTransactionPossible()
{
Set<Integer> conflictFrom = new HashSet<>(Arrays.asList(2, 3, 4, 5, 6));
Set<Integer> conflictTo = new HashSet<>(Arrays.asList(2, 3));
return !(conflictFrom.contains(fromSpinner.getSelectedItemPosition()) && conflictTo.contains(toSpinner.getSelectedItemPosition()));
}
private String getDestination()
{
String destination = "";
switch (toSpinner.getSelectedItemPosition())
{
case 0:
destination = EXCHANGE_CODE;
break;
case 1:
destination = WALLET_CODE;
break;
case 2:
destination = ELSE_WALLET_CODE;
break;
case 3:
destination = UNKNOWN_CODE;
break;
}
return destination;
}
private String getSource()
{
String source = "";
switch (fromSpinner.getSelectedItemPosition())
{
case 0:
source = EXCHANGE_CODE;
break;
case 1:
source = WALLET_CODE;
break;
case 2:
source = MINING_CODE;
break;
case 3:
source = ELSE_WALLET_CODE;
break;
case 4:
source = AIRDROP_CODE;
break;
case 5:
source = UNKNOWN_CODE;
break;
case 6:
source = FORK_CODE;
break;
}
return source;
}
private boolean isFieldCorrectlyFilled(TextInputEditText editText, boolean displayError)
{
String purchasedPriceText = editText.getText().toString();
double purchasedPrice;
try {
purchasedPrice = Double.parseDouble(purchasedPriceText);
if(purchasedPrice < 0)
{
if(displayError) editText.setError(getResources().getString(R.string.field_negative));
return false;
}
} catch (NumberFormatException e) {
if(displayError) editText.setError(getResources().getString(R.string.field_nan));
return false;
}
if(purchasedPriceText.equals(""))
{
if(displayError) editText.setError(getResources().getString(R.string.field_empty));
return false;
}
return true;
}
private void createDatePicker()
{
DatePickerDialog datePickerDialog = new DatePickerDialog(
getContext(),
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
transferDateEditText.setText(sdf.format(calendar.getTime()));
createTimePicker();
}
},
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH)
);
datePickerDialog.getDatePicker().setMaxDate(Calendar.getInstance().getTimeInMillis());
datePickerDialog.show();
}
private void createTimePicker()
{
new android.app.TimePickerDialog(
getContext(),
new android.app.TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hour, int minute) {
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
transferDateEditText.setText(sdf.format(calendar.getTime()));
}
},
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
true
).show();
}
@Override
public void onCurrencyUpdated() {
fragmentCurrency = currency;
}
@Override
public void onExchangeUpdated() {
fragmentExchange = exchange;
}
@Override
public void onPairUpdated() {
}
}

View File

@ -2,40 +2,64 @@ package com.herbron.moodl.Activities;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.hardware.fingerprint.FingerprintManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.RingtonePreference;
import android.preference.PreferenceScreen;
import android.preference.SwitchPreference;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import com.applandeo.FilePicker;
import com.applandeo.listeners.OnSelectFileListener;
import com.herbron.moodl.BuildConfig;
import com.herbron.moodl.DataManagers.DataCrypter;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.FingerprintToolkit.FingerprintDialogFragment;
import com.herbron.moodl.FingerprintToolkit.FingerprintHandler;
import com.herbron.moodl.MoodlBox;
import com.herbron.moodl.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
@ -44,7 +68,11 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
@ -150,6 +178,10 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
// Show the Up button in the action bar.
actionBar.setDisplayHomeAsUpEnabled(true);
}
Drawable gradientDrawable = getResources().getDrawable(R.drawable.gradient_background);
actionBar.setBackgroundDrawable(gradientDrawable);
}
/**
@ -166,7 +198,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.pref_headers, target);
//loadHeadersFromResource(R.xml.pref_headers, target);
}
/**
@ -175,41 +207,8 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
*/
protected boolean isValidFragment(String fragmentName) {
return PreferenceFragment.class.getName().equals(fragmentName)
|| GeneralPreferenceFragment.class.getName().equals(fragmentName)
|| ExchangePreferenceFragment.class.getName().equals(fragmentName);
}
/**
* This fragment shows general preferences only. It is used when the
* activity is showing a two-pane settings UI.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class GeneralPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_general);
setHasOptionsMenu(true);
findPreference("version").setSummary(BuildConfig.VERSION_NAME);
bindPreferenceSummaryToValue(findPreference("default_currency"));
bindPreferenceSummaryToValue(findPreference("minimum_value_displayed"));
EditTextPreference editTextPreference = (EditTextPreference) findPreference("minimum_value_displayed");
editTextPreference.setPositiveButtonText("Save");
editTextPreference.setNegativeButtonText("Cancel");
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
//startActivity(new Intent(getActivity(), SettingsActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
|| ExchangePreferenceFragment.class.getName().equals(fragmentName)
|| MainPreferenceFragment.class.getName().equals(fragmentName);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@ -236,12 +235,22 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
bindPreferenceSummaryToValue(findPreference("hitbtc_privatekey"));
bindPreferenceSummaryToValue(findPreference("binance_privatekey"));
findPreference("enable_fingerprint").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object o) {
Log.d("moodl", "> " + o + " " + preference);
return (boolean) o;
}
});
findPreference("enable_hitbtc").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
boolean isChecked = ((SwitchPreference) findPreference("enable_hitbtc")).isChecked();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getBaseContext());
SharedPreferences.Editor editor = preferences.edit();
@ -257,7 +266,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
public boolean onPreferenceClick(Preference preference) {
boolean isChecked = ((SwitchPreference) findPreference("enable_binance")).isChecked();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getBaseContext());
SharedPreferences.Editor editor = preferences.edit();
@ -284,62 +293,64 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
private void startFingerprintProtocol()
{
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this.getContext());
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this.getActivity().getBaseContext());
FingerprintDialogFragment newFragment = FingerprintDialogFragment.newInstance();
SwitchPreference touchdIdSwitch = (SwitchPreference) findPreference("enable_fingerprint");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
keyguardManager = (KeyguardManager) this.getActivity().getSystemService(KEYGUARD_SERVICE);
fingerprintManager = (FingerprintManager) this.getActivity().getSystemService(FINGERPRINT_SERVICE);
try {
if(!fingerprintManager.isHardwareDetected())
{
touchdIdSwitch.setEnabled(false);
}
if(ActivityCompat.checkSelfPermission(this.getActivity().getBaseContext(), Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED)
{
touchdIdSwitch.setEnabled(false);
}
if(!fingerprintManager.hasEnrolledFingerprints())
{
touchdIdSwitch.setEnabled(false);
}
if(!keyguardManager.isKeyguardSecure())
{
touchdIdSwitch.setEnabled(false);
}
else
{
try {
generateKey();
} catch (FingerprintException e) {
e.printStackTrace();
}
if(initCipher())
{
cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(this.getActivity().getBaseContext(), newFragment);
helper.startAuth(fingerprintManager, cryptoObject);
}
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
if(preferences.getBoolean("enable_fingerprint", false))
{
newFragment.setCancelable(false);
newFragment.show(getFragmentManager(), "dialog");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
keyguardManager = (KeyguardManager) this.getActivity().getSystemService(KEYGUARD_SERVICE);
fingerprintManager = (FingerprintManager) this.getActivity().getSystemService(FINGERPRINT_SERVICE);
try {
if(!fingerprintManager.isHardwareDetected())
{
this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
}
if(ActivityCompat.checkSelfPermission(this.getContext(), Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED)
{
this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
}
if(!fingerprintManager.hasEnrolledFingerprints())
{
this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
}
if(!keyguardManager.isKeyguardSecure())
{
this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
}
else
{
try {
generateKey();
} catch (FingerprintException e) {
e.printStackTrace();
}
if(initCipher())
{
cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(this.getContext(), newFragment);
helper.startAuth(fingerprintManager, cryptoObject);
}
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
}
@TargetApi(23)
private void generateKey() throws FingerprintException
{
try {
@ -365,6 +376,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
}
}
@TargetApi(23)
public boolean initCipher()
{
try {
@ -397,4 +409,492 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
}
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class MainPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_main);
findPreference("version").setSummary(BuildConfig.VERSION_NAME);
bindPreferenceSummaryToValue(findPreference("default_currency"));
bindPreferenceSummaryToValue(findPreference("minimum_value_displayed"));
PreferenceCategory developperCategory = (PreferenceCategory) findPreference("developper_category");
if(!BuildConfig.DEBUG)
{
getPreferenceScreen().removePreference(developperCategory);
}
else
{
developperCategory.getPreference(0).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
File cacheDir = getActivity().getBaseContext().getCacheDir();
File[] cachedFiles = cacheDir.listFiles();
for(int i = 0; i < cachedFiles.length; i++)
{
if(cachedFiles[i].isFile())
{
cachedFiles[i].delete();
}
}
return false;
}
});
}
findPreference("export").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Context context = getActivity().getBaseContext();
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(MainPreferenceFragment.this.getActivity());
View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_export_data, null, true);
dialogBuilder.setView(dialogView);
final CheckBox backupManualEntriesCheckbox = dialogView.findViewById(R.id.checkboxBackupManualEntries);
final CheckBox backupWatchlistCheckbox = dialogView.findViewById(R.id.checkboxBackupWatchlist);
final CheckBox backupKeysCheckbox = dialogView.findViewById(R.id.checkboxBackupKeys);
final CheckBox enterPasswordCheckbox = dialogView.findViewById(R.id.checkboxEnterPassword);
final TextInputLayout textInputLayoutPassword = dialogView.findViewById(R.id.textInputLayoutPassword);
final TextView textViewFilePath = dialogView.findViewById(R.id.textViewFilePath);
File backupDirectory = new File(Environment.getExternalStorageDirectory(), getString(R.string.app_name));
createDefaultBackupDirectory(backupDirectory);
textViewFilePath.setText(backupDirectory.getAbsolutePath());
textViewFilePath.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new FilePicker.Builder(getActivity(), new OnSelectFileListener() {
@Override
public void onSelect(File file) {
textViewFilePath.setText(file.getAbsolutePath());
}
}).fileType(".moodl")
.hideFiles(true)
.directory(backupDirectory.getAbsolutePath())
.mainDirectory(Environment.getExternalStorageDirectory().getAbsolutePath())
.show();
}
});
enterPasswordCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b && textInputLayoutPassword.getVisibility() == View.GONE)
{
MoodlBox.expandH(textInputLayoutPassword);
}
if(!b && textInputLayoutPassword.getVisibility() == View.VISIBLE)
{
MoodlBox.collapseH(textInputLayoutPassword);
}
}
});
dialogBuilder.setTitle(getString(R.string.create_backup));
dialogBuilder.setPositiveButton(getString(R.string.confirm), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
checkPermissions();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.getDefault());
Date currentDate = new Date();
String fileName = "Bakup_" + formatter.format(currentDate) + ".moodl";
DatabaseManager databaseManager = new DatabaseManager(getActivity().getBaseContext());
if(enterPasswordCheckbox.isChecked())
{
if(textInputLayoutPassword.getEditText().getText().equals(""))
{
textInputLayoutPassword.setError(getString(R.string.must_be_filled));
}
else
{
DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString());
}
}
File backupFile = new File(textViewFilePath.getText() + "/" + fileName);
try (PrintWriter printWriter = new PrintWriter(new FileWriter(backupFile, true))) {
try {
JSONObject backupJson = new JSONObject();
initiateJsonBackup(backupJson, enterPasswordCheckbox.isChecked());
if(backupManualEntriesCheckbox.isChecked())
{
backupJson.put("transactions",
databaseManager.getDatabaseBackup(getActivity().getBaseContext(),
DatabaseManager.TABLE_MANUAL_TRANSACTIONS,
enterPasswordCheckbox.isChecked()));
}
if(backupWatchlistCheckbox.isChecked())
{
backupJson.put("watchlist",
databaseManager.getDatabaseBackup(getActivity().getBaseContext(),
DatabaseManager.TABLE_WATCHLIST,
enterPasswordCheckbox.isChecked()));
}
if(backupKeysCheckbox.isChecked())
{
backupJson.put("apiKeys",
databaseManager.getDatabaseBackup(getActivity().getBaseContext(),
DatabaseManager.TABLE_EXCHANGE_KEYS,
enterPasswordCheckbox.isChecked()));
}
printWriter.write(backupJson.toString());
} catch (JSONException e) {
Log.d("moodl", "Error while creating backup json " + e.getMessage());
}
printWriter.close();
} catch (IOException e) {
Log.d("moodl", "Error > " + e);
}
dialog.dismiss();
}
});
dialogBuilder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
});
AlertDialog alertDialog = dialogBuilder.create();
alertDialog.show();
return false;
}
});
findPreference("import").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Context context = getActivity().getBaseContext();
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(MainPreferenceFragment.this.getActivity());
View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_import_data, null, true);
dialogBuilder.setView(dialogView);
final TextView textViewFilePath = dialogView.findViewById(R.id.textViewFilePath);
final TextInputLayout textInputLayoutPassword = dialogView.findViewById(R.id.textInputLayoutPassword);
final CheckBox enterPasswordCheckbox = dialogView.findViewById(R.id.checkboxEnterPassword);
final CheckBox restoreManualEntriesCheckbox = dialogView.findViewById(R.id.checkboxRestoreEntries);
final CheckBox restoreWatchlistCheckbox = dialogView.findViewById(R.id.checkboxRestoreWatchlist);
final CheckBox restoreApiKeysCheckbox = dialogView.findViewById(R.id.checkboxRestoreKeys);
final CheckBox wipeManualEntriesCheckbox = dialogView.findViewById(R.id.checkboxWipeManualEntries);
final CheckBox wipeWatchlistCheckbox = dialogView.findViewById(R.id.checkboxWipeWatchlist);
final CheckBox wipeApiKeyxCheckbox = dialogView.findViewById(R.id.checkboxWipeAPIKeys);
restoreManualEntriesCheckbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(restoreManualEntriesCheckbox.isChecked())
{
MoodlBox.expandH(wipeManualEntriesCheckbox);
}
else
{
MoodlBox.collapseH(wipeManualEntriesCheckbox);
}
}
});
restoreWatchlistCheckbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(restoreWatchlistCheckbox.isChecked())
{
MoodlBox.expandH(wipeWatchlistCheckbox);
}
else
{
MoodlBox.collapseH(wipeWatchlistCheckbox);
}
}
});
restoreApiKeysCheckbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(restoreApiKeysCheckbox.isChecked())
{
MoodlBox.expandH(wipeApiKeyxCheckbox);
}
else
{
MoodlBox.collapseH(wipeApiKeyxCheckbox);
}
}
});
enterPasswordCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b && textInputLayoutPassword.getVisibility() == View.GONE)
{
MoodlBox.expandH(textInputLayoutPassword);
}
if(!b && textInputLayoutPassword.getVisibility() == View.VISIBLE)
{
MoodlBox.collapseH(textInputLayoutPassword);
}
}
});
File backupDirectory = new File(Environment.getExternalStorageDirectory(), getString(R.string.app_name));
createDefaultBackupDirectory(backupDirectory);
textViewFilePath.setText(backupDirectory.getAbsolutePath());
textViewFilePath.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new FilePicker.Builder(getActivity(), new OnSelectFileListener() {
@Override
public void onSelect(File file) {
textViewFilePath.setText(file.getAbsolutePath());
}
}).hideFiles(false)
.directory(backupDirectory.getAbsolutePath())
.mainDirectory(Environment.getExternalStorageDirectory().getAbsolutePath())
.show();
}
});
dialogBuilder.setTitle(getString(R.string.restoreBackup));
dialogBuilder.setPositiveButton(getString(R.string.confirm), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int whichButton) {
checkPermissions();
DatabaseManager databaseManager = new DatabaseManager(context);
if(enterPasswordCheckbox.isChecked())
{
DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString());
}
File backupFile = new File(textViewFilePath.getText().toString());
try {
FileReader fileReader = new FileReader(backupFile);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String str;
String completeFile = "";
while ((str = bufferedReader.readLine()) != null) {
completeFile += str;
}
try {
JSONObject backupJson = new JSONObject(completeFile);
String checker;
if(enterPasswordCheckbox.isChecked())
{
checker = DataCrypter.decrypt(getActivity().getBaseContext(), backupJson.getString("encodeChecker"));
}
else
{
checker = backupJson.getString("encodeChecker");
}
if(checker.equals("NaukVerification"))
{
if(restoreManualEntriesCheckbox.isChecked())
{
if(wipeManualEntriesCheckbox.isChecked())
{
databaseManager.wipeData(DatabaseManager.TABLE_MANUAL_TRANSACTIONS);
}
if(backupJson.has("transactions"))
{
JSONArray transactionsArray = backupJson.getJSONArray("transactions");
for(int i = 0; i < transactionsArray.length(); i++)
{
JSONObject transactionObject = transactionsArray.getJSONObject(i);
databaseManager.addRowTransaction(transactionObject, getActivity().getBaseContext(), enterPasswordCheckbox.isChecked());
}
}
}
if(restoreWatchlistCheckbox.isChecked())
{
if(wipeWatchlistCheckbox.isChecked())
{
databaseManager.wipeData(DatabaseManager.TABLE_WATCHLIST);
}
if(backupJson.has("watchlist"))
{
JSONArray watchlistArray = backupJson.getJSONArray("watchlist");
for(int i = 0; i < watchlistArray.length(); i++)
{
JSONObject watchlistObject = watchlistArray.getJSONObject(i);
databaseManager.addRowWatchlist(watchlistObject, getActivity().getBaseContext(), enterPasswordCheckbox.isChecked());
}
}
}
if(restoreApiKeysCheckbox.isChecked())
{
if(wipeApiKeyxCheckbox.isChecked())
{
databaseManager.wipeData(DatabaseManager.TABLE_EXCHANGE_KEYS);
}
if(backupJson.has("apiKeys"))
{
JSONArray apiArray = backupJson.getJSONArray("apiKeys");
for(int i = 0; i < apiArray.length(); i++)
{
JSONObject apiKeysObject = apiArray.getJSONObject(i);
databaseManager.addRowApiKeys(apiKeysObject, getActivity().getBaseContext(), enterPasswordCheckbox.isChecked());
}
}
}
PreferencesManager preferencesManager = new PreferencesManager(getContext());
preferencesManager.setMustUpdateSummary(true);
}
else
{
textInputLayoutPassword.setError(getString(R.string.wrong_password));
}
} catch (JSONException e) {
Log.d("moodl", "Error while creating backup json " + e);
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
dialogBuilder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
AlertDialog alertDialog = dialogBuilder.create();
alertDialog.show();
return false;
}
});
DatabaseManager databaseManager = new DatabaseManager(getActivity().getBaseContext());
int disabledAcount = databaseManager.getDisabledExchangeAccountsNumber();
PreferenceScreen preferenceScreen = (PreferenceScreen) findPreference("exchange");
if(disabledAcount > 0)
{
preferenceScreen.setWidgetLayoutResource(R.layout.alert_layout);
}
preferenceScreen.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent exchangeListIntent = new Intent(getActivity().getBaseContext(), ExchangeListActivity.class);
startActivity(exchangeListIntent);
return false;
}
});
EditTextPreference editTextPreference = (EditTextPreference) findPreference("minimum_value_displayed");
editTextPreference.setPositiveButtonText(getString(R.string.save));
editTextPreference.setNegativeButtonText(getString(R.string.cancel));
}
private void initiateJsonBackup(JSONObject backupJson, boolean mustEncrypt) throws JSONException
{
if(mustEncrypt)
{
backupJson.put("encodeChecker", DataCrypter.encrypt(getActivity().getBaseContext(), "NaukVerification"));
}
else
{
backupJson.put("encodeChecker", "NaukVerification");
}
}
private void createDefaultBackupDirectory(File backupDirectory)
{
if (!backupDirectory.exists()) {
if (!backupDirectory.mkdirs()) {
Log.d("moodl", "Error while creating directory");
}
}
}
private boolean checkPermissions() {
String[] permissions = new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
};
int result;
List<String> listPermissionsNeeded = new ArrayList<>();
for (String p : permissions) {
result = ContextCompat.checkSelfPermission(getActivity().getBaseContext(), p);
if (result != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(p);
}
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(getActivity(), listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), 100);
return false;
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
//startActivity(new Intent(getActivity(), SettingsActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
}
}

View File

@ -0,0 +1,13 @@
package com.herbron.moodl;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
public interface CurrencyInfoUpdateNotifierInterface {
void onTimestampPriceUpdated(String price);
void onHistoryDataUpdated();
void onPriceUpdated(Currency currency);
}

View File

@ -0,0 +1,120 @@
package com.herbron.moodl.CustomAdapters;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.R;
import java.util.ArrayList;
public class CoinRecordListAdapter extends ArrayAdapter<Currency> {
private CustomFilter filter;
private ArrayList<Currency> currencies, suggestions;
public CoinRecordListAdapter(@NonNull Context context, int resource, @NonNull ArrayList<Currency> currencies) {
super(context, resource, currencies);
this.currencies = currencies;
this.suggestions = currencies;
}
@Override
public int getCount() {
return currencies.size();
}
@Override
public Currency getItem(int position) {
return currencies.get(position);
}
@Override
public long getItemId(int position) {
return currencies.indexOf(getItem(position));
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Currency currency = getItem(position);
if(convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom_summary_coin_row, parent, false);
}
TextView nameTxtview = convertView.findViewById(R.id.currencyName);
TextView symbolTxtView = convertView.findViewById(R.id.currencySymbol);
nameTxtview.setText(currency.getName());
symbolTxtView.setText(currency.getSymbol());
return convertView;
}
@NonNull
@Override
public Filter getFilter() {
if(filter == null)
{
filter = new CustomFilter();
}
return filter;
}
private class CustomFilter extends Filter
{
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(constraint != null && constraint.length() > 0)
{
constraint = constraint.toString().toLowerCase();
ArrayList<Currency> filters = new ArrayList<>();
for(int i = 0; i < suggestions.size(); i++)
{
if(suggestions.get(i).getName().toLowerCase().contains(constraint) || suggestions.get(i).getSymbol().toLowerCase().contains(constraint))
{
Currency currency = new Currency(suggestions.get(i).getName(), suggestions.get(i).getSymbol());
filters.add(currency);
}
}
results.count = filters.size();
results.values = filters;
}
else
{
results.count = suggestions.size();
results.values = suggestions;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if(results != null)
{
currencies = (ArrayList<Currency>) results.values;
}
notifyDataSetChanged();
}
}
}

View File

@ -1,4 +1,4 @@
package com.herbron.moodl.LayoutManagers;
package com.herbron.moodl.CustomAdapters;
import android.content.Context;
import android.support.annotation.NonNull;
@ -19,13 +19,13 @@ import java.util.ArrayList;
* Created by Guitoune on 17/01/2018.
*/
public class CurrencyListAdapter extends BaseAdapter implements Filterable {
public class CoinWatchlistAdapter extends BaseAdapter implements Filterable {
private ArrayList<Currency> currencies, suggestions;
private Context context;
private CustomFilter filter;
public CurrencyListAdapter(Context context, ArrayList<Currency> currencies) {
public CoinWatchlistAdapter(Context context, ArrayList<Currency> currencies) {
this.context = context;
this.currencies = currencies;
this.suggestions = currencies;
@ -53,7 +53,7 @@ public class CurrencyListAdapter extends BaseAdapter implements Filterable {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.custom_currency_row, parent, false);
convertView = inflater.inflate(R.layout.custom_watchlist_coin_row, parent, false);
}
TextView currencyName = convertView.findViewById(R.id.currencyName);
@ -68,7 +68,7 @@ public class CurrencyListAdapter extends BaseAdapter implements Filterable {
}
if (position % 2 == 0)
convertView.setBackgroundColor(context.getResources().getColor(R.color.listBackground2));
convertView.setBackgroundColor(context.getResources().getColor(R.color.white));
else
convertView.setBackgroundColor(context.getResources().getColor(R.color.listBackground));

View File

@ -0,0 +1,92 @@
package com.herbron.moodl.CustomAdapters;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
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 com.herbron.moodl.Activities.AddExchangeActivity;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.ExchangeManager.Exchange;
import com.herbron.moodl.R;
import java.util.ArrayList;
import static com.herbron.moodl.DataManagers.DatabaseManager.BINANCE_TYPE;
import static com.herbron.moodl.DataManagers.DatabaseManager.HITBTC_TYPE;
public class ExchangeDescriptionListAdapter extends ArrayAdapter<Exchange> {
private Context context;
public ExchangeDescriptionListAdapter(Context context, ArrayList<Exchange> exchanges)
{
super(context, android.R.layout.simple_list_item_1, exchanges);
this.context = context;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Exchange exchange = getItem(position);
if(convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout.exchange_cell, parent, false);
}
TextView exchangeNameTextView = convertView.findViewById(R.id.exchange_name);
TextView exchangeDescriptionTextView = convertView.findViewById(R.id.exchange_description);
ImageView accountOffImageView = convertView.findViewById(R.id.exchange_account_off_imageView);
ImageView exchangeImageView = convertView.findViewById(R.id.exchange_icon_imageView);
exchangeNameTextView.setText(exchange.getName());
exchangeDescriptionTextView.setText(exchange.getDescription());
switch (exchange.getType())
{
case BINANCE_TYPE:
exchangeImageView.setImageDrawable(context.getResources().getDrawable(R.drawable.exchange_logo_binance));
break;
case HITBTC_TYPE:
exchangeImageView.setImageDrawable(context.getResources().getDrawable(R.drawable.exchange_logo_hitbtc));
break;
}
if(!exchange.isEnabled())
{
accountOffImageView.setVisibility(View.VISIBLE);
}
convertView.findViewById(R.id.editExchangeInfosLayout).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent editExchangeAccountIntent = new Intent(context, AddExchangeActivity.class);
editExchangeAccountIntent.putExtra("isEdit", true);
editExchangeAccountIntent.putExtra("exchangeId", exchange.getId());
editExchangeAccountIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(editExchangeAccountIntent);
}
});
convertView.findViewById(R.id.deleteExchangeInfosLayout).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DatabaseManager databaseManager = new DatabaseManager(getContext());
databaseManager.deleteExchangeAccountFromId(exchange.getId());
remove(exchange);
notifyDataSetChanged();
}
});
return convertView;
}
}

View File

@ -0,0 +1,120 @@
package com.herbron.moodl.CustomAdapters;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;
import com.herbron.moodl.DataManagers.ExchangeManager.Exchange;
import com.herbron.moodl.R;
import java.util.ArrayList;
public class ExchangeRecordListAdapter extends ArrayAdapter<Exchange> {
private CustomFilter filter;
private ArrayList<Exchange> exchanges, suggestions;
public ExchangeRecordListAdapter(@NonNull Context context, int resource, @NonNull ArrayList<Exchange> exchanges) {
super(context, resource, exchanges);
this.exchanges = exchanges;
this.suggestions = exchanges;
}
@NonNull
@Override
public Filter getFilter() {
if(filter == null)
{
filter = new CustomFilter();
}
return filter;
}
@Override
public int getCount() {
return exchanges.size();
}
@Nullable
@Override
public Exchange getItem(int position) {
return exchanges.get(position);
}
@Override
public long getItemId(int position) {
return exchanges.indexOf(getItem(position));
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Exchange exchange = getItem(position);
if(convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout.simple_spinner_item, parent, false);
}
TextView nameTxtview = convertView.findViewById(R.id.textView);
nameTxtview.setTextColor(getContext().getResources().getColor(android.R.color.tab_indicator_text));
nameTxtview.setText(exchange.getName());
return convertView;
}
private class CustomFilter extends Filter
{
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(constraint != null && constraint.length() > 0)
{
constraint = constraint.toString().toLowerCase();
ArrayList<Exchange> filters = new ArrayList<>();
for(int i = 0; i < suggestions.size(); i++)
{
if(suggestions.get(i).getName().toLowerCase().contains(constraint))
{
Exchange exchange = new Exchange(suggestions.get(i));
filters.add(exchange);
}
}
results.count = filters.size();
results.values = filters;
}
else
{
results.count = suggestions.size();
results.values = suggestions;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if(results != null)
{
exchanges = (ArrayList<Exchange>) results.values;
}
notifyDataSetChanged();
}
}
}

View File

@ -1,4 +1,4 @@
package com.herbron.moodl.LayoutManagers;
package com.herbron.moodl.CustomAdapters;
import android.app.Activity;
import android.content.Context;
@ -11,7 +11,7 @@ import android.widget.LinearLayout;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyCardview;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyDetailsList;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CryptocompareApiManager;
import java.util.List;
@ -22,14 +22,14 @@ import java.util.List;
public class OverviewListAdapter extends ArrayAdapter<Currency> {
private Activity activity;
private CurrencyDetailsList currencyDetailsList;
private CryptocompareApiManager cryptocompareApiManager;
public OverviewListAdapter(Context context, List<Currency> currencies, Activity activity)
{
super(context, android.R.layout.simple_expandable_list_item_1, currencies);
this.activity = activity;
currencyDetailsList = CurrencyDetailsList.getInstance(getContext());
cryptocompareApiManager = CryptocompareApiManager.getInstance(getContext());
}
@NonNull
@ -38,7 +38,7 @@ public class OverviewListAdapter extends ArrayAdapter<Currency> {
{
Currency currency = getItem(position);
currencyDetailsList.getCurrencyDetailsFromSymbol(currency.getSymbol());
cryptocompareApiManager.getCurrencyDetailsFromSymbol(currency.getSymbol());
CurrencyCardview currencyCardview = new CurrencyCardview(getContext(), currency, activity);
LinearLayout linearLayout = new LinearLayout(getContext());

View File

@ -0,0 +1,121 @@
package com.herbron.moodl.CustomAdapters;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;
import com.herbron.moodl.DataManagers.InfoAPIManagers.Pair;
import com.herbron.moodl.Utils.PlaceholderUtils;
import com.herbron.moodl.R;
import java.util.ArrayList;
public class PairRecordListAdapter extends ArrayAdapter<Pair> {
private CustomFilter filter;
private ArrayList<Pair> pairs, suggestions;
public PairRecordListAdapter(@NonNull Context context, int resource, @NonNull ArrayList<Pair> pairs) {
super(context, resource, pairs);
this.pairs = pairs;
this.suggestions = pairs;
}
@NonNull
@Override
public Filter getFilter() {
if(filter == null)
{
filter = new CustomFilter();
}
return filter;
}
@Override
public int getCount() {
return pairs.size();
}
@Nullable
@Override
public Pair getItem(int position) {
return pairs.get(position);
}
@Override
public long getItemId(int position) {
return pairs.indexOf(getItem(position));
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Pair pair = getItem(position);
if(convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout.simple_spinner_item, parent, false);
}
TextView pairTxtView = convertView.findViewById(R.id.textView);
pairTxtView.setTextColor(getContext().getResources().getColor(android.R.color.tab_indicator_text));
pairTxtView.setText(PlaceholderUtils.getPairString(pair.getFrom(), pair.getTo(), getContext()));
return convertView;
}
private class CustomFilter extends Filter
{
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(constraint != null && constraint.length() > 0)
{
constraint = constraint.toString().toUpperCase();
ArrayList<Pair> filters = new ArrayList<>();
for(int i = 0; i < suggestions.size(); i++)
{
if(suggestions.get(i).getFrom().contains(constraint) || suggestions.get(i).getTo().contains(constraint))
{
Pair pair = new Pair(suggestions.get(i));
filters.add(pair);
}
}
results.count = filters.size();
results.values = filters;
}
else
{
results.count = suggestions.size();
results.values = suggestions;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if(results != null)
{
pairs = (ArrayList<Pair>) results.values;
}
notifyDataSetChanged();
}
}
}

View File

@ -0,0 +1,44 @@
package com.herbron.moodl.CustomAdapters;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import com.herbron.moodl.Activities.RecordTransactionFragments.BuyFragment;
import com.herbron.moodl.Activities.RecordTransactionFragments.SellFragment;
import com.herbron.moodl.Activities.RecordTransactionFragments.TransferFragment;
public class RecordTransactionPageAdapter extends FragmentStatePagerAdapter {
private int tabsNumber;
public RecordTransactionPageAdapter(FragmentManager fm, int tabsNumber) {
super(fm);
this.tabsNumber = tabsNumber;
}
@Override
public Fragment getItem(int position) {
switch (position)
{
case 0:
BuyFragment buyFragment = new BuyFragment();
return buyFragment;
case 1:
SellFragment sellFragment = new SellFragment();
return sellFragment;
case 2:
TransferFragment transferFragment = new TransferFragment();
return transferFragment;
default:
return null;
}
}
@Override
public int getCount() {
return tabsNumber;
}
}

View File

@ -0,0 +1,228 @@
package com.herbron.moodl.CustomAdapters;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.daimajia.swipe.SwipeLayout;
import com.herbron.moodl.Activities.RecordTransactionActivity;
import com.herbron.moodl.DataManagers.CurrencyData.Trade;
import com.herbron.moodl.DataManagers.CurrencyData.Transaction;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.R;
import com.herbron.moodl.Utils.PlaceholderUtils;
import com.herbron.moodl.Utils.TransferUtils;
import java.util.ArrayList;
import static com.herbron.moodl.MoodlBox.collapseH;
import static com.herbron.moodl.MoodlBox.getDateFromTimestamp;
import static com.herbron.moodl.MoodlBox.numberConformer;
import static java.lang.Math.abs;
import static com.herbron.moodl.Utils.TransferUtils.isBalanceRelated;
/**
* Created by Guitoune on 24/04/2018.
*/
public class TransactionListAdapter extends ArrayAdapter<Object> {
private Context context;
public TransactionListAdapter(Context context, ArrayList<Object> transactions)
{
super(context, android.R.layout.simple_list_item_1, transactions);
this.context = context;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
if(getItem(position) instanceof Transaction)
{
return generateTransactionLayout(position, parent);
}
else
{
return generateTradeLayout(position, parent);
}
}
private View generateTradeLayout(int position, ViewGroup parent)
{
Trade trade = (Trade) getItem(position);
View convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom_trade_row, parent, false);
TextView amountTxtView = convertView.findViewById(R.id.amountPurchased);
TextView purchasedPrice = convertView.findViewById(R.id.purchasePrice);
TextView tradePair = convertView.findViewById(R.id.pair);
TextView dateTxtView = convertView.findViewById(R.id.tradeDate);
View tradeIndicator = convertView.findViewById(R.id.tradeIndicator);
amountTxtView.setText(String.valueOf(trade.getQty()));
purchasedPrice.setText(trade.getPrice());
dateTxtView.setText(getDateFromTimestamp(trade.getTime()));
tradePair.setText(trade.getSymbol() + "/" + trade.getPairSymbol());
if(trade.isBuyer())
{
tradeIndicator.setBackgroundColor(context.getResources().getColor(R.color.green));
}
else
{
tradeIndicator.setBackgroundColor(context.getResources().getColor(R.color.red));
}
return convertView;
}
private View generateTransactionLayout(int position, ViewGroup parent)
{
final Transaction transaction = (Transaction) getItem(position);
View convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom_transaction_row, parent, false);
TextView topLeftTextView = convertView.findViewById(R.id.transactionTLTV);
TextView bottomLeftTextView = convertView.findViewById(R.id.transactionBLTV);
TextView dateTxtView = convertView.findViewById(R.id.transactionDateTextView);
TextView amountTxtView = convertView.findViewById(R.id.transactionAmountTextView);
amountTxtView.setText(String.valueOf(transaction.getAmount()));
dateTxtView.setText(getDateFromTimestamp(transaction.getTimestamp()));
LinearLayout deleteLayout = convertView.findViewById(R.id.deleteTransactionLayout);
deleteLayout.setTag(transaction.getTransactionId());
deleteLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
PreferencesManager preferencesManager = new PreferencesManager(context);
DatabaseManager databaseManager = new DatabaseManager(context);
preferencesManager.setMustUpdateSummary(true);
databaseManager.deleteTransactionFromId(Integer.parseInt(view.getTag().toString()));
collapseH((View) view.getParent().getParent().getParent());
}
});
LinearLayout editLayout = convertView.findViewById(R.id.editTransactionLayout);
editLayout.setTag(transaction.getTransactionId());
editLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String name = ((Activity) context).getTitle().toString();
name = name.substring(1, name.indexOf("|") - 1);
Intent intent = new Intent(context, RecordTransactionActivity.class);
intent.putExtra("coin", name);
intent.putExtra("symbol", transaction.getSymbol());
intent.putExtra("transactionId", transaction.getTransactionId());
context.startActivity(intent);
}
});
View transactionIndicator = convertView.findViewById(R.id.transactionIndicator);
switch (transaction.getType())
{
case "b":
transactionIndicator.setBackgroundColor(context.getResources().getColor(R.color.increaseCandle));
topLeftTextView.setText(transaction.getSource());
bottomLeftTextView.setText(PlaceholderUtils.getToPairString(transaction.getSymPair(), transaction.getSymbol(), context));
break;
case "s":
transactionIndicator.setBackgroundColor(context.getResources().getColor(R.color.decreaseCandle));
topLeftTextView.setText(transaction.getSource());
bottomLeftTextView.setText(PlaceholderUtils.getToPairString(transaction.getSymbol(), transaction.getSymPair(), context));
break;
case "t":
transactionIndicator.setBackgroundColor(context.getResources().getColor(R.color.blue));
if(isBalanceRelated(transaction.getDestination()) && isBalanceRelated(transaction.getSource()))
{
topLeftTextView.setText(context.getString(R.string.transferText));
bottomLeftTextView.setText(PlaceholderUtils.getFromToString(TransferUtils.getLabelFor(context, transaction.getSource()), TransferUtils.getLabelFor(context, transaction.getDestination()), context));
}
else
{
if(isBalanceRelated(transaction.getDestination()))
{
topLeftTextView.setText(context.getString(R.string.depositText));
bottomLeftTextView.setText(PlaceholderUtils.getFromString(TransferUtils.getLabelFor(context, transaction.getSource()), context));
}
else
{
if(isBalanceRelated(transaction.getSource()))
{
topLeftTextView.setText(context.getString(R.string.withdrawText));
bottomLeftTextView.setText(PlaceholderUtils.getToString(TransferUtils.getLabelFor(context, transaction.getDestination()), context));
}
}
}
break;
}
setupSwipeView(convertView);
return convertView;
}
private void setupSwipeView(View view)
{
SwipeLayout swipeLayout = view.findViewById(R.id.swipeLayout);
//set show mode.
swipeLayout.setShowMode(SwipeLayout.ShowMode.LayDown);
//add drag edge.(If the BottomView has 'layout_gravity' attribute, this line is unnecessary)
swipeLayout.addDrag(SwipeLayout.DragEdge.Left, view.findViewById(R.id.bottom_wrapper));
swipeLayout.addSwipeListener(new SwipeLayout.SwipeListener() {
@Override
public void onClose(SwipeLayout layout) {
//when the SurfaceView totally cover the BottomView.
}
@Override
public void onUpdate(SwipeLayout layout, int leftOffset, int topOffset) {
//you are swiping.
}
@Override
public void onStartOpen(SwipeLayout layout) {
}
@Override
public void onOpen(SwipeLayout layout) {
//when the BottomView totally show.
}
@Override
public void onStartClose(SwipeLayout layout) {
}
@Override
public void onHandRelease(SwipeLayout layout, float xvel, float yvel) {
//when user's hand released.
}
});
}
}

View File

@ -1,4 +1,4 @@
package com.herbron.moodl.LayoutManagers;
package com.herbron.moodl.CustomLayouts;
import android.content.Context;
import android.util.AttributeSet;

View File

@ -0,0 +1,41 @@
package com.herbron.moodl.CustomLayouts;
import android.support.v4.app.Fragment;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.ExchangeManager.Exchange;
import com.herbron.moodl.DataManagers.InfoAPIManagers.Pair;
public abstract class CustomRecordFragment extends Fragment {
protected Currency currency;
protected Exchange exchange;
protected Pair pair;
public void setCurrency(Currency currency)
{
this.currency = currency;
onCurrencyUpdated();
}
public void setExchange(Exchange exchange)
{
this.exchange = exchange;
onExchangeUpdated();
}
public void setPair(Pair pair)
{
this.pair = pair;
onPairUpdated();
}
public abstract void onCurrencyUpdated();
public abstract void onExchangeUpdated();
public abstract void onPairUpdated();
}

View File

@ -0,0 +1,92 @@
package com.herbron.moodl.CustomLayouts;
import android.content.Context;
import android.graphics.drawable.StateListDrawable;
import android.support.design.widget.TabLayout;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.herbron.moodl.R;
public class CustomTabLayout extends TabLayout {
private LinearLayout linearLayout;
private Context context;
public CustomTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
linearLayout = (LinearLayout) getChildAt(0);
this.context = context;
}
private StateListDrawable getSellStateListDrawable() {
StateListDrawable sld = new StateListDrawable();
sld.addState(new int[] {android.R.attr.state_pressed},
ContextCompat.getDrawable(context, R.drawable.unselected_tab_background));
sld.addState(new int[] {android.R.attr.state_selected},
ContextCompat.getDrawable(context, R.drawable.record_transaction_tab_background_sell));
sld.addState(new int[] {android.R.attr.state_enabled },
ContextCompat.getDrawable(context, R.drawable.unselected_tab_background));
sld.addState(new int[] { },
ContextCompat.getDrawable(context, R.drawable.disabled_tab_background));
return sld;
}
private StateListDrawable getBuyStateListDrawable() {
StateListDrawable sld = new StateListDrawable();
sld.addState(new int[] {android.R.attr.state_pressed},
ContextCompat.getDrawable(context, R.drawable.unselected_tab_background));
sld.addState(new int[] {android.R.attr.state_selected},
ContextCompat.getDrawable(context, R.drawable.record_transaction_tab_background_buy));
sld.addState(new int[] {android.R.attr.state_enabled },
ContextCompat.getDrawable(context, R.drawable.unselected_tab_background));
sld.addState(new int[] { },
ContextCompat.getDrawable(context, R.drawable.disabled_tab_background));
return sld;
}
private StateListDrawable getTransferStateListDrawable() {
StateListDrawable sld = new StateListDrawable();
sld.addState(new int[] {android.R.attr.state_pressed},
ContextCompat.getDrawable(context, R.drawable.unselected_tab_background));
sld.addState(new int[] {android.R.attr.state_selected},
ContextCompat.getDrawable(context, R.drawable.record_transaction_tab_background_transfer));
sld.addState(new int[] {android.R.attr.state_enabled },
ContextCompat.getDrawable(context, R.drawable.unselected_tab_background));
sld.addState(new int[] { },
ContextCompat.getDrawable(context, R.drawable.disabled_tab_background));
return sld;
}
public void addTab(int index, String label) {
TextView textView = new TextView(context);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setText(label);
textView.setGravity(GRAVITY_CENTER);
textView.setTextColor(getResources().getColor(R.color.separationColor));
addTab(newTab().setCustomView(textView));
View tabView = linearLayout.getChildAt(linearLayout.getChildCount() - 1);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tabView.getLayoutParams();
params.setMargins(2, 0, 2, 0);
tabView.setLayoutParams(params);
switch (index)
{
case 0:
tabView.setBackground(getBuyStateListDrawable());
break;
case 1:
tabView.setBackground(getSellStateListDrawable());
break;
case 2:
tabView.setBackground(getTransferStateListDrawable());
break;
}
}
}

View File

@ -1,4 +1,4 @@
package com.herbron.moodl.LayoutManagers;
package com.herbron.moodl.CustomLayouts;
import android.content.Context;
import android.support.v4.view.ViewPager;

View File

@ -0,0 +1,51 @@
package com.herbron.moodl.CustomLayouts;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.design.widget.TextInputEditText;
import android.text.TextPaint;
import android.util.AttributeSet;
public class TextInputEditTextSuffix extends TextInputEditText {
private TextPaint textPaint = new TextPaint();
private String suffix = "";
public TextInputEditTextSuffix(Context context) {
super(context);
}
public TextInputEditTextSuffix(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TextInputEditTextSuffix(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(!getText().toString().equals(""))
{
int suffixXPosition = (int) textPaint.measureText(getText().toString() + getPaddingLeft());
canvas.drawText(suffix, Math.max(suffixXPosition, 0), getBaseline(), textPaint);
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
textPaint.setColor(getCurrentTextColor());
textPaint.setTextSize(getTextSize());
textPaint.setTextAlign(Paint.Align.LEFT);
}
public void setSuffix(String suffix)
{
this.suffix = suffix;
}
}

View File

@ -1,109 +1,69 @@
package com.herbron.moodl.DataManagers;
import android.util.Log;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
import com.herbron.moodl.Activities.HomeActivity;
import com.herbron.moodl.DataManagers.CurrencyData.Trade;
import com.herbron.moodl.DataNotifiers.BinanceUpdateNotifierInterface;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyDetailsList;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CryptocompareApiManager;
import com.herbron.moodl.DataManagers.ExchangeManager.BinanceManager;
import com.herbron.moodl.DataManagers.ExchangeManager.HitBtcManager;
import com.herbron.moodl.R;
import com.herbron.moodl.DataNotifiers.BalanceUpdateNotifierInterface;
import com.herbron.moodl.DataNotifiers.HitBTCUpdateNotifierInterface;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
/**
* Created by Tiji on 25/12/2017.
*/
public class BalanceManager {
public class BalanceManager implements BinanceUpdateNotifierInterface, HitBTCUpdateNotifierInterface {
private String publicHitKey;
private String publicBinanceKey;
private String publicPoloniex;
private String privateHitKey;
private String privateBinanceKey;
private String privatePoloniex;
final private String hitBalanceUrl = "https://api.hitbtc.com/api/2/trading/balance";
final private String detailUrl = "https://www.cryptocompare.com/api/data/coinlist/";
private RequestQueue requestQueue;
private List<Currency> binanceBalance;
private List<Currency> hitBalance;
private List<Currency> manualBalances;
private List<Currency> totalBalance;
private android.content.Context context;
private LinkedHashMap<String, String> coinInfosHashmap;
private PreferencesManager preferenceManager;
private DatabaseManager databaseManager;
private CurrencyDetailsList currencyDetailsList;
private CryptocompareApiManager cryptocompareApiManager;
private int balanceCounter;
//NEW IMPLEMENTATION
private List<HitBtcManager> hitBtcManagers;
private List<BinanceManager> binanceManagers;
private BalanceUpdateNotifierInterface balanceUpdateNotifierInterface;
public BalanceManager(android.content.Context context)
{
this.context = context;
preferenceManager = new PreferencesManager(context);
requestQueue = Volley.newRequestQueue(context);
binanceBalance = new ArrayList<Currency>();
hitBalance = new ArrayList<Currency>();
manualBalances = new ArrayList<Currency>();
databaseManager = new DatabaseManager(context);
hitBtcManagers = new ArrayList<>();
binanceManagers = new ArrayList<>();
currencyDetailsList = CurrencyDetailsList.getInstance(context);
cryptocompareApiManager = CryptocompareApiManager.getInstance(context);
balanceCounter = 0;
setListener((BalanceUpdateNotifierInterface) ((HomeActivity) context).getHoldingsFragment());
}
public List<String> getBiggestCurrencies()
public void setListener(BalanceUpdateNotifierInterface balanceUpdateNotifierInterface)
{
List<String> currenciesDetails = new ArrayList<>();
int index = 0;
Iterator<String> coinIterator = currencyDetailsList.getCoinInfosHashmap().keySet().iterator();
while(index < 11)
{
index++;
Log.d("moodl", "For " + index + " : " + coinIterator.next());
}
return currenciesDetails;
this.balanceUpdateNotifierInterface = balanceUpdateNotifierInterface;
}
public void updateExchangeKeys()
{
String publicKey = preferenceManager.getHitBTCPublicKey();
String privateKey = preferenceManager.getHitBTCPrivateKey();
hitBtcManagers.clear();
if(preferenceManager.isHitBTCActivated() && publicKey != null && privateKey != null)
{
hitBtcManagers.add(new HitBtcManager(context, publicKey, privateKey));
}
publicKey = preferenceManager.getBinancePublicKey();
privateKey = preferenceManager.getBinancePrivateKey();
hitBtcManagers = databaseManager.getHitBtcAccounts(context);
binanceManagers.clear();
if(preferenceManager.isBinanceActivated() && publicKey != null && privateKey != null)
{
binanceManagers.add(new BinanceManager(publicKey, privateKey));
}
binanceManagers = databaseManager.getBinanceAccounts();
}
public List<Currency> getTotalBalance()
@ -111,13 +71,15 @@ public class BalanceManager {
return totalBalance;
}
public void updateTotalBalance(final VolleyCallBack callBack)
public void updateTotalBalance()
{
boolean isUpdated = false;
updateExchangeKeys();
balanceCounter = 0;
manualBalances = databaseManager.getAllCurrenciesFromManualCurrency();
manualBalances = databaseManager.getAllCurrenciesFromTransactions();
if(binanceManagers.size() > 0)
{
@ -125,17 +87,9 @@ public class BalanceManager {
for(int i = 0; i < binanceManagers.size(); i++)
{
binanceManagers.get(i).updateBalance(new BinanceManager.BinanceCallBack() {
@Override
public void onSuccess() {
countBalances(callBack);
}
@Override
public void onError(String error) {
callBack.onError(error);
}
});
BinanceManager binanceManager = binanceManagers.get(i);
binanceManager.addListener(this);
binanceManager.updateBalance();
}
}
@ -145,39 +99,31 @@ public class BalanceManager {
for(int i = 0; i < hitBtcManagers.size(); i++)
{
hitBtcManagers.get(i).updateGlobalBalance(new HitBtcManager.HitBtcCallBack() {
@Override
public void onSuccess() {
countBalances(callBack);
}
@Override
public void onError(String error) {
callBack.onError(error);
}
});
final HitBtcManager hitBtcManager = hitBtcManagers.get(i);
hitBtcManager.addListener(this);
hitBtcManager.updateGlobalBalance();
}
}
if(!isUpdated)
{
refreshAllBalances(callBack);
refreshAllBalances();
}
}
private void countBalances(VolleyCallBack callBack)
private void countBalances()
{
balanceCounter++;
if(balanceCounter == hitBtcManagers.size() + binanceManagers.size())
{
refreshAllBalances(callBack);
refreshAllBalances();
balanceCounter = 0;
}
}
private void refreshAllBalances(final VolleyCallBack callBack)
private void refreshAllBalances()
{
totalBalance = new ArrayList<>();
@ -193,7 +139,7 @@ public class BalanceManager {
mergeBalanceTotal(manualBalances);
callBack.onSuccess();
balanceUpdateNotifierInterface.onBalanceDataUpdated();
}
private void mergeBalanceTotal(List<Currency> balance)
@ -222,13 +168,31 @@ public class BalanceManager {
}
}
public interface VolleyCallBack {
void onSuccess();
void onError(String error);
@Override
public void onBinanceTradesUpdated(List<Trade> trades) {
}
public interface IconCallBack {
void onSuccess();
@Override
public void onBinanceBalanceUpdateSuccess() {
countBalances();
}
@Override
public void onBinanceBalanceUpdateError(int accountId, String error) {
databaseManager.disableExchangeAccount(accountId);
balanceUpdateNotifierInterface.onBalanceError(error);
}
@Override
public void onHitBTCBalanceUpdateSuccess() {
countBalances();
}
@Override
public void onHitBTCBalanceUpdateError(int accountId, String error) {
databaseManager.disableExchangeAccount(accountId);
balanceUpdateNotifierInterface.onBalanceError(error);
}
public void sortCoins()
@ -247,64 +211,9 @@ public class BalanceManager {
}
}
public void updateDetails(final IconCallBack callBack)
public CryptocompareApiManager getCryptocompareApiManager()
{
if(!currencyDetailsList.isUpToDate())
{
currencyDetailsList.update(callBack);
}
else
{
callBack.onSuccess();
}
/*StringRequest strRequest = new StringRequest(Request.Method.GET, detailUrl,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response.length() > 0) {
processDetailResult(response, callBack);
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(strRequest);*/
}
public String getIconUrl(String symbol)
{
String url;
try {
switch (symbol)
{
case "IOTA":
url = "https://www.cryptocompare.com/media/1383540/iota_logo.png?width=50";
break;
default:
JSONObject jsonObject = new JSONObject(currencyDetailsList.getCoinInfosHashmap().get(symbol));
url = "https://www.cryptocompare.com" + jsonObject.getString("ImageUrl") + "?width=50";
break;
}
} catch (NullPointerException e) {
Log.d(context.getResources().getString(R.string.debug), symbol + " has no icon URL");
url = null;
} catch (JSONException e) {
Log.d(context.getResources().getString(R.string.debug), "Url parsing error for " + symbol);
url = null;
}
return url;
}
public CurrencyDetailsList getCurrencyDetailList()
{
return currencyDetailsList;
return cryptocompareApiManager;
}
public String getCurrencyName(String symbol)
@ -312,10 +221,12 @@ public class BalanceManager {
String currencyName = null;
try {
JSONObject jsonObject = new JSONObject(currencyDetailsList.getCoinInfosHashmap().get(symbol));
JSONObject jsonObject = new JSONObject(cryptocompareApiManager.getCoinInfosHashmap().get(symbol));
currencyName = jsonObject.getString("CoinName");
} catch (JSONException e) {
e.printStackTrace();
} catch (NullPointerException e) {
currencyName = symbol;
}
return currencyName;
@ -326,40 +237,14 @@ public class BalanceManager {
int id = 0;
try {
JSONObject jsonObject = new JSONObject(currencyDetailsList.getCoinInfosHashmap().get(symbol));
JSONObject jsonObject = new JSONObject(cryptocompareApiManager.getCoinInfosHashmap().get(symbol));
id = jsonObject.getInt("Id");
} catch (JSONException e) {
e.printStackTrace();
} catch (NullPointerException e) {
id = -1;
}
return id;
}
private void sortDetails()
{
LinkedHashMap<String, String> sortedHashmap = new LinkedHashMap<>();
List<String> listInfos = new ArrayList<>(coinInfosHashmap.values());
List<String> listSymbols = new ArrayList<>(coinInfosHashmap.keySet());
for(int i = 0; i < coinInfosHashmap.keySet().size(); i++)
{
try {
JSONObject jsonObject = new JSONObject(listInfos.get(i));
int index = jsonObject.getInt("SortOrder");
listInfos.add(index, listInfos.get(i));
listSymbols.add(index, listSymbols.get(i));
} catch (JSONException e) {
e.printStackTrace();
}
}
for(int i = 0; i < listInfos.size(); i++)
{
sortedHashmap.put(listSymbols.get(i), listInfos.get(i));
}
coinInfosHashmap = sortedHashmap;
}
}

View File

@ -5,8 +5,7 @@ import android.graphics.Color;
import android.os.Parcel;
import android.os.Parcelable;
import org.json.JSONException;
import org.json.JSONObject;
import com.herbron.moodl.CurrencyInfoUpdateNotifierInterface;
import java.lang.reflect.Field;
import java.util.ArrayList;
@ -45,8 +44,11 @@ public class Currency implements Parcelable {
private int rank;
private String startDate;
private List<String> socialMediaLinks;
private List<OnTimestampPriceUpdatedListener> onTimestampPriceUpdatedListenerList;
//private String proofType
private CurrencyInfoUpdateNotifierInterface currencyInfoUpdateNotifierInterface;
public Currency() {}
public Currency(String symbol, double balance)
@ -75,9 +77,12 @@ public class Currency implements Parcelable {
this.tickerId = tickerId;
}
//public Currency(int id, String symbol, String name, String algorithm, String proofType, )
public void setListener(CurrencyInfoUpdateNotifierInterface currencyInfoUpdateNotifierInterface)
{
this.currencyInfoUpdateNotifierInterface = currencyInfoUpdateNotifierInterface;
}
public void getTimestampPrice(android.content.Context context, String toSymbol, final PriceCallBack callBack, long timestamp)
public void getTimestampPrice(android.content.Context context, String toSymbol, long timestamp)
{
dataRetriver = new CurrencyDataRetriever(context);
@ -87,31 +92,20 @@ public class Currency implements Parcelable {
@Override
public void onSuccess(String price) {
callBack.onSuccess(price);
currencyInfoUpdateNotifierInterface.onTimestampPriceUpdated(price);
if(onTimestampPriceUpdatedListenerList != null)
{
for(int i = 0; i < onTimestampPriceUpdatedListenerList.size(); i++)
{
onTimestampPriceUpdatedListenerList.get(i).onTimeStampPriceUpdated(price);
}
}
}
}, timestamp);
}
public static String getIconUrl(String currencyDetails)
{
String url;
try {
JSONObject jsonObject = new JSONObject(currencyDetails);
url = "https://www.cryptocompare.com" + jsonObject.getString("ImageUrl") + "?width=50";
} catch (NullPointerException e) {
//Log.d(context.getResources().getString(R.string.debug), symbol + " has no icon URL");
url = null;
} catch (JSONException e) {
//Log.d(context.getResources().getString(R.string.debug), "Url parsing error for " + symbol);
url = null;
}
return url;
}
public void updatePrice(android.content.Context context, String toSymbol, final CurrencyCallBack callBack)
public void updatePrice(android.content.Context context, String toSymbol, final CurrencyInfoUpdateNotifierInterface callBack)
{
dataRetriver = new CurrencyDataRetriever(context);
@ -125,12 +119,12 @@ public class Currency implements Parcelable {
setDayFluctuationPercentage(currencyInfo.getDayFluctuationPercentage());
}
callBack.onSuccess(Currency.this);
callBack.onPriceUpdated(currencyInfo);
}
});
}
public void updateHistoryMinutes(android.content.Context context, String toSymbol, final CurrencyCallBack callBack)
public void updateHistoryMinutes(android.content.Context context, String toSymbol)
{
dataRetriver = new CurrencyDataRetriever(context);
@ -139,7 +133,7 @@ public class Currency implements Parcelable {
public void onSuccess(List<CurrencyDataChart> dataChart) {
setHistoryMinutes(dataChart);
callBack.onSuccess(Currency.this);
currencyInfoUpdateNotifierInterface.onHistoryDataUpdated();
}
@Override
@ -196,7 +190,7 @@ public class Currency implements Parcelable {
});
}
public void updateHistoryHours(android.content.Context context, String toSymbol, final CurrencyCallBack callBack)
public void updateHistoryHours(android.content.Context context, String toSymbol)
{
dataRetriver = new CurrencyDataRetriever(context);
dataRetriver.updateHistory(symbol, toSymbol, new CurrencyDataRetriever.DataChartCallBack() {
@ -204,7 +198,7 @@ public class Currency implements Parcelable {
public void onSuccess(List<CurrencyDataChart> dataChart) {
setHistoryHours(dataChart);
callBack.onSuccess(Currency.this);
currencyInfoUpdateNotifierInterface.onHistoryDataUpdated();
}
@Override
@ -212,7 +206,7 @@ public class Currency implements Parcelable {
}, CurrencyDataRetriever.HOURS);
}
public void updateHistoryDays(android.content.Context context, String toSymbol, final CurrencyCallBack callBack)
public void updateHistoryDays(android.content.Context context, String toSymbol)
{
dataRetriver = new CurrencyDataRetriever(context);
dataRetriver.updateHistory(symbol, toSymbol, new CurrencyDataRetriever.DataChartCallBack() {
@ -220,7 +214,7 @@ public class Currency implements Parcelable {
public void onSuccess(List<CurrencyDataChart> dataChart) {
setHistoryDays(dataChart);
callBack.onSuccess(Currency.this);
currencyInfoUpdateNotifierInterface.onHistoryDataUpdated();
}
@Override
@ -228,12 +222,6 @@ public class Currency implements Parcelable {
}, CurrencyDataRetriever.DAYS);
}
public void updateDetails(android.content.Context context, final CurrencyCallBack callBack)
{
dataRetriver = new CurrencyDataRetriever(context);
}
private int getDarkenColor(int color)
{
int transColor;
@ -543,4 +531,19 @@ public class Currency implements Parcelable {
return new Currency[size];
}
};
public interface OnTimestampPriceUpdatedListener
{
void onTimeStampPriceUpdated(String price);
}
public void addOnTimestampPriceUpdatedListener(OnTimestampPriceUpdatedListener onTimestampPriceUpdatedListener)
{
if(onTimestampPriceUpdatedListenerList == null)
{
onTimestampPriceUpdatedListenerList = new ArrayList<>();
}
onTimestampPriceUpdatedListenerList.add(onTimestampPriceUpdatedListener);
}
}

View File

@ -4,18 +4,29 @@ import android.app.Activity;
import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.CardView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
@ -24,10 +35,13 @@ import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.herbron.moodl.Activities.CurrencyDetailsActivity;
import com.herbron.moodl.CurrencyInfoUpdateNotifierInterface;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CryptocompareApiManager;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.DataNotifiers.MoodlboxNotifierInterface;
import com.herbron.moodl.MoodlBox;
import com.herbron.moodl.PlaceholderManager;
import com.herbron.moodl.Utils.PlaceholderUtils;
import com.herbron.moodl.R;
import java.util.ArrayList;
@ -35,25 +49,53 @@ import java.util.List;
import static com.herbron.moodl.MoodlBox.collapseH;
import static com.herbron.moodl.MoodlBox.expandH;
import static com.herbron.moodl.MoodlBox.getIconDominantColor;
import static com.herbron.moodl.MoodlBox.numberConformer;
/**
* Created by Tiji on 12/05/2018.
*/
public class CurrencyCardview extends CardView {
public class CurrencyCardview extends CardView implements CurrencyInfoUpdateNotifierInterface {
private static final int FADE_IN_DURATION = 300;
private Currency currency;
private Activity parentActivity;
private Context context;
private OnClickListener detailsClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(parentActivity, CurrencyDetailsActivity.class);
intent.putExtra(getContext().getString(R.string.currency), currency);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(parentActivity, findViewById(R.id.LineChartView), "chart");
parentActivity.startActivity(intent, activityOptions.toBundle());
}
else {
parentActivity.startActivity(intent);
}
}
};
public CurrencyCardview(@NonNull Context context) {
super(context);
this.context = context;
}
public CurrencyCardview(@NonNull final Context context, final Currency currency, final Activity activity)
{
super (context);
currency.setListener(this);
this.currency = currency;
this.parentActivity = activity;
this.context = context;
LayoutInflater.from(context).inflate(R.layout.cardview_watchlist, this, true);
@ -61,48 +103,9 @@ public class CurrencyCardview extends CardView {
setupCardView();
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View view) {
PreferencesManager preferencesManager = new PreferencesManager(context);
setOnClickListeners();
if (view.findViewById(R.id.collapsableLayout).getVisibility() == View.VISIBLE) {
collapseH(view.findViewById(R.id.collapsableLayout));
} else {
view.findViewById(R.id.linearLayoutSubLayout).setVisibility(View.GONE);
view.findViewById(R.id.progressBarLinechartWatchlist).setVisibility(View.VISIBLE);
expandH(view.findViewById(R.id.collapsableLayout));
if (currency.getHistoryMinutes() == null) {
currency.updateHistoryMinutes(context, preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
@Override
public void onSuccess(Currency currency) {
if(currency.getHistoryMinutes() != null)
{
setupLineChart(currency);
view.findViewById(R.id.progressBarLinechartWatchlist).setVisibility(View.GONE);
view.findViewById(R.id.linearLayoutSubLayout).setVisibility(View.VISIBLE);
}
else
{
view.findViewById(R.id.progressBarLinechartWatchlist).setVisibility(View.GONE);
view.findViewById(R.id.linearLayoutSubLayout).setVisibility(View.VISIBLE);
view.findViewById(R.id.linearLayoutSubLayout).findViewById(R.id.detailsArrow).setVisibility(View.GONE);
}
}
});
}
else
{
expandH(view.findViewById(R.id.collapsableLayout));
view.findViewById(R.id.progressBarLinechartWatchlist).setVisibility(View.GONE);
view.findViewById(R.id.linearLayoutSubLayout).setVisibility(View.VISIBLE);
}
}
}
});
updateCardViewInfos(currency);
updateCardviewInfos();
findViewById(R.id.deleteCardWatchlist).setOnClickListener(new OnClickListener() {
@Override
@ -113,34 +116,20 @@ public class CurrencyCardview extends CardView {
}
});
findViewById(R.id.LineChartView).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(activity, CurrencyDetailsActivity.class);
intent.putExtra("currency", currency);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
updateColor();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(activity, findViewById(R.id.LineChartView), "chart");
activity.startActivity(intent, activityOptions.toBundle());
}
else
{
activity.startActivity(intent);
}
}
});
updateColor(currency);
startIconUpdater();
}
public CurrencyCardview(@NonNull final Context context, final Currency currency, float totalValue, boolean isBalanceHidden)
public CurrencyCardview(@NonNull final Context context, final Currency currency, Activity activity, boolean isBalanceHidden)
{
super(context);
currency.setListener(this);
this.currency = currency;
this.parentActivity = activity;
this.context = context;
LayoutInflater.from(context).inflate(R.layout.cardview_currency, this, true);
@ -148,6 +137,74 @@ public class CurrencyCardview extends CardView {
setupCardView();
setOnClickListeners();
updateCardviewInfos();
updateColor();
startIconUpdater();
}
private void startIconUpdater()
{
IconDownloader iconDownloader = new IconDownloader();
iconDownloader.execute(context, currency);
iconDownloader.setOnBitmapDownloadedListener(new IconDownloader.OnBitmapDownloadedListener() {
@Override
public void onDownloaded(Bitmap icon) {
currency.setIcon(icon);
currency.setChartColor(getIconDominantColor(context, icon));
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
updateCurrencyColorRelatedLayouts();
}
});
}
});
}
private void updateCurrencyColorRelatedLayouts()
{
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new AccelerateInterpolator());
fadeIn.setDuration(FADE_IN_DURATION);
ImageView currencyIconImageView = findViewById(R.id.currencyIcon);
currencyIconImageView.setImageBitmap(currency.getIcon());
currencyIconImageView.startAnimation(fadeIn);
Drawable arrowDrawable = ((ImageView) findViewById(R.id.detailsArrow)).getDrawable();
arrowDrawable.mutate();
arrowDrawable.setColorFilter(new PorterDuffColorFilter(currency.getChartColor(), PorterDuff.Mode.SRC_IN));
arrowDrawable.invalidateSelf();
Drawable progressDrawable = ((ProgressBar) findViewById(R.id.progressBarLinechart)).getIndeterminateDrawable();
progressDrawable.mutate();
progressDrawable.setColorFilter(new PorterDuffColorFilter(currency.getChartColor(), PorterDuff.Mode.SRC_IN));
progressDrawable.invalidateSelf();
if(findViewById(R.id.currencyPortfolioDominance) != null)
{
Drawable progressBarDrawable = ((ProgressBar) findViewById(R.id.currencyPortfolioDominance)).getProgressDrawable();
progressBarDrawable.mutate();
progressBarDrawable.setColorFilter(new PorterDuffColorFilter(currency.getChartColor(), PorterDuff.Mode.SRC_IN));
progressBarDrawable.invalidateSelf();
}
LineChart lineChart = findViewById(R.id.LineChartView);
if(currency.getHistoryMinutes() != null)
{
lineChart.setData(generateData());
lineChart.invalidate();
}
}
private void setOnClickListeners()
{
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View view) {
@ -156,52 +213,26 @@ public class CurrencyCardview extends CardView {
if (view.findViewById(R.id.collapsableLayout).getVisibility() == View.VISIBLE) {
collapseH(view.findViewById(R.id.collapsableLayout));
} else {
view.findViewById(R.id.linearLayoutSubLayout).setVisibility(View.GONE);
view.findViewById(R.id.progressBarLinechartSummary).setVisibility(View.VISIBLE);
view.findViewById(R.id.linearLayoutSubCharts).setVisibility(View.GONE);
view.findViewById(R.id.progressBarLinechart).setVisibility(View.VISIBLE);
expandH(view.findViewById(R.id.collapsableLayout));
if (currency.getHistoryMinutes() == null) {
currency.updateHistoryMinutes(context, preferencesManager.getDefaultCurrency(), new Currency.CurrencyCallBack() {
@Override
public void onSuccess(Currency currency) {
if(currency.getHistoryMinutes() != null)
{
setupLineChart(currency);
view.findViewById(R.id.progressBarLinechartSummary).setVisibility(View.GONE);
view.findViewById(R.id.linearLayoutSubLayout).setVisibility(View.VISIBLE);
}
else
{
view.findViewById(R.id.progressBarLinechartSummary).setVisibility(View.GONE);
view.findViewById(R.id.linearLayoutSubLayout).setVisibility(View.VISIBLE);
view.findViewById(R.id.linearLayoutSubLayout).findViewById(R.id.detailsArrow).setVisibility(View.GONE);
}
}
});
currency.updateHistoryMinutes(context, preferencesManager.getDefaultCurrency());
}
else
{
expandH(view.findViewById(R.id.collapsableLayout));
view.findViewById(R.id.progressBarLinechartSummary).setVisibility(View.GONE);
view.findViewById(R.id.linearLayoutSubLayout).setVisibility(View.VISIBLE);
view.findViewById(R.id.progressBarLinechart).setVisibility(View.GONE);
view.findViewById(R.id.linearLayoutSubCharts).setVisibility(View.VISIBLE);
}
}
}
});
updateCardViewInfos(currency, totalValue, isBalanceHidden);
findViewById(R.id.linearLayoutSubCharts).setOnClickListener(detailsClickListener);
findViewById(R.id.LineChartView).setOnClickListener(detailsClickListener);
findViewById(R.id.LineChartView).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(context.getApplicationContext(), CurrencyDetailsActivity.class);
intent.putExtra(getContext().getString(R.string.currency), currency);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.getApplicationContext().startActivity(intent);
}
});
updateColor(currency);
}
public Currency getCurrency()
@ -211,8 +242,9 @@ public class CurrencyCardview extends CardView {
private void setupCardView()
{
ViewGroup.MarginLayoutParams layoutParams = new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.WRAP_CONTENT);
layoutParams.setMargins((int) MoodlBox.convertDpToPx(10, getResources()), 0, (int) MoodlBox.convertDpToPx(10, getResources()), (int) MoodlBox.convertDpToPx(10, getResources()));
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.MarginLayoutParams.MATCH_PARENT, LinearLayout.MarginLayoutParams.WRAP_CONTENT);
int margin = (int) MoodlBox.convertDpToPx(10, getResources());
layoutParams.setMargins(margin, margin, margin, 0);
setLayoutParams(layoutParams);
@ -241,76 +273,36 @@ public class CurrencyCardview extends CardView {
lineChart.getLegend().setEnabled(false);
lineChart.getXAxis().setEnabled(false);
lineChart.setViewPortOffsets(0, 0, 0, 0);
lineChart.setData(generateData(currency));
lineChart.setData(generateData());
}
private void updateCardViewInfos(Currency currency)
private void updateCardviewInfos()
{
((TextView) findViewById(R.id.currencyFluctuationTextView))
.setText(PlaceholderManager.getValueParenthesisString(numberConformer(currency.getDayFluctuation()), getContext()));
.setText(PlaceholderUtils.getValueParenthesisString(numberConformer(currency.getDayFluctuation()), getContext()));
((TextView) findViewById(R.id.currencyValueTextView))
.setText(PlaceholderManager.getValueString(numberConformer(currency.getValue()), getContext()));
.setText(PlaceholderUtils.getValueString(numberConformer(currency.getValue()), getContext()));
((ImageView) findViewById(R.id.currencyIcon))
.setImageBitmap(currency.getIcon());
((TextView) findViewById(R.id.currencyNameTextView))
.setText(currency.getName());
((TextView) findViewById(R.id.currencySymbolTextView))
.setText(PlaceholderManager.getSymbolString(currency.getSymbol(), getContext()));
.setText(PlaceholderUtils.getSymbolString(currency.getSymbol(), getContext()));
((TextView) findViewById(R.id.currencyFluctuationPercentageTextView))
.setText(PlaceholderManager.getPercentageString(numberConformer(currency.getDayFluctuationPercentage()), getContext()));
Drawable arrowDrawable = ((ImageView) findViewById(R.id.detailsArrow)).getDrawable();
arrowDrawable.mutate();
arrowDrawable.setColorFilter(new PorterDuffColorFilter(currency.getChartColor(), PorterDuff.Mode.SRC_IN));
arrowDrawable.invalidateSelf();
Drawable progressDrawable = ((ProgressBar) findViewById(R.id.progressBarLinechartWatchlist)).getIndeterminateDrawable();
progressDrawable.mutate();
progressDrawable.setColorFilter(new PorterDuffColorFilter(currency.getChartColor(), PorterDuff.Mode.SRC_IN));
progressDrawable.invalidateSelf();
.setText(PlaceholderUtils.getPercentageString(numberConformer(currency.getDayFluctuationPercentage()), getContext()));
}
private void updateCardViewInfos(Currency currency, float totalValue, boolean isBalanceHidden)
public void updateOwnedValues(float totalValue, boolean isBalanceHidden)
{
double value = currency.getValue() * currency.getBalance();
double percentage = value / totalValue * 100;
((TextView) findViewById(R.id.currencyValueOwnedTextView))
.setText(PlaceholderManager.getValueParenthesisString(numberConformer(currency.getValue() * currency.getBalance()), getContext()));
((TextView) findViewById(R.id.currencyFluctuationTextView))
.setText(PlaceholderManager.getValueParenthesisString(numberConformer(currency.getDayFluctuation()), getContext()));
((TextView) findViewById(R.id.currencyValueTextView))
.setText(PlaceholderManager.getValueString(numberConformer(currency.getValue()), getContext()));
((ImageView) findViewById(R.id.currencyIcon))
.setImageBitmap(currency.getIcon());
((TextView) findViewById(R.id.currencyNameTextView))
.setText(currency.getName());
((TextView) findViewById(R.id.currencySymbolTextView))
.setText(PlaceholderManager.getSymbolString(currency.getSymbol(), getContext()));
.setText(PlaceholderUtils.getValueParenthesisString(numberConformer(currency.getValue() * currency.getBalance()), getContext()));
((TextView) findViewById(R.id.currencyOwnedTextView))
.setText(PlaceholderManager.getBalanceString(numberConformer(currency.getBalance()), currency.getSymbol(), getContext()));
((TextView) findViewById(R.id.currencyFluctuationPercentageTextView))
.setText(PlaceholderManager.getPercentageString(numberConformer(currency.getDayFluctuationPercentage()), getContext()));
Drawable arrowDrawable = ((ImageView) findViewById(R.id.detailsArrow)).getDrawable();
arrowDrawable.mutate();
arrowDrawable.setColorFilter(new PorterDuffColorFilter(currency.getChartColor(), PorterDuff.Mode.SRC_IN));
arrowDrawable.invalidateSelf();
Drawable progressDrawable = ((ProgressBar) findViewById(R.id.progressBarLinechartSummary)).getIndeterminateDrawable();
progressDrawable.mutate();
progressDrawable.setColorFilter(new PorterDuffColorFilter(currency.getChartColor(), PorterDuff.Mode.SRC_IN));
progressDrawable.invalidateSelf();
Drawable progressBarDrawable = ((ProgressBar) findViewById(R.id.currencyPortfolioDominance)).getProgressDrawable();
progressBarDrawable.mutate();
progressBarDrawable.setColorFilter(new PorterDuffColorFilter(currency.getChartColor(), PorterDuff.Mode.SRC_IN));
progressBarDrawable.invalidateSelf();
.setText(PlaceholderUtils.getBalanceString(numberConformer(currency.getBalance()), currency.getSymbol(), getContext()));
((ProgressBar) findViewById(R.id.currencyPortfolioDominance)).setProgress((int) Math.round(percentage));
((TextView) findViewById(R.id.percentageOwnedTextView)).setText(PlaceholderManager.getPercentageString(numberConformer(percentage), getContext()));
((TextView) findViewById(R.id.percentageOwnedTextView)).setText(PlaceholderUtils.getPercentageString(numberConformer(percentage), getContext()));
if(isBalanceHidden)
{
@ -326,7 +318,7 @@ public class CurrencyCardview extends CardView {
}
}
private LineData generateData(Currency currency)
private LineData generateData()
{
LineDataSet dataSet;
List<CurrencyDataChart> dataChartList = currency.getHistoryMinutes();
@ -340,19 +332,20 @@ public class CurrencyCardview extends CardView {
dataSet = new LineDataSet(values, "");
dataSet.setDrawIcons(false);
dataSet.setColor(currency.getChartColor());
dataSet.setFillColor(getColorWithAplha(currency.getChartColor(), 0.5f));
dataSet.setLineWidth(1);
dataSet.setDrawFilled(true);
dataSet.setFillColor(getColorWithAplha(currency.getChartColor(), 0.5f));
dataSet.setFormLineWidth(1);
dataSet.setFormSize(15);
dataSet.setDrawCircles(false);
dataSet.setDrawValues(false);
dataSet.setHighlightEnabled(false);
dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
return new LineData(dataSet);
}
private void updateColor(Currency currency)
private void updateColor()
{
if(currency.getDayFluctuationPercentage() >= 0)
{
@ -382,4 +375,71 @@ public class CurrencyCardview extends CardView {
return transColor ;
}
@Override
public void onTimestampPriceUpdated(String price) {
}
@Override
public void onHistoryDataUpdated() {
View progressView = findViewById(R.id.progressBarLinechart);
progressView.setVisibility(View.GONE);
findViewById(R.id.linearLayoutSubCharts).setVisibility(View.VISIBLE);
if(currency.getHistoryMinutes() != null)
{
setupLineChart(currency);
}
}
@Override
public void onPriceUpdated(Currency currency) {
}
private static class IconDownloader extends AsyncTask<Object, Integer, Void> implements MoodlboxNotifierInterface
{
private Bitmap icon = null;
private OnBitmapDownloadedListener onBitmapDownloadedListener;
public Bitmap getIcon()
{
return icon;
}
public void setOnBitmapDownloadedListener(OnBitmapDownloadedListener onBitmapDownloadedListener) {
this.onBitmapDownloadedListener = onBitmapDownloadedListener;
}
@Override
protected Void doInBackground(Object... objects) {
Context context = (Context) objects[0];
Currency currency = (Currency) objects[1];
CryptocompareApiManager cryptocompareApiManager = CryptocompareApiManager.getInstance(context);
String iconUrl = MoodlBox.getIconUrl(currency.getSymbol(), cryptocompareApiManager);
if(iconUrl != null)
{
MoodlBox.getBitmapFromURL(iconUrl, currency.getSymbol(), context.getResources(), context, this);
}
return null;
}
@Override
public void onBitmapDownloaded(Bitmap bitmap) {
icon = bitmap;
onBitmapDownloadedListener.onDownloaded(bitmap);
}
public interface OnBitmapDownloadedListener {
void onDownloaded(Bitmap icon);
}
}
}

View File

@ -10,6 +10,7 @@ import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.herbron.moodl.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -267,35 +268,25 @@ public class CurrencyDataRetriever {
{
List<CurrencyDataChart> dataChart = new ArrayList<>();
if(response.length() > 250)
{
response = response.substring(response.indexOf("Data\":[{") + 7, response.lastIndexOf("}],\"TimeTo"));
String[] tab = response.split(Pattern.quote("},{"));
for(int i = 0; i < tab.length; i++)
try {
JSONObject mainJsonObject = new JSONObject(response);
if(mainJsonObject.getString("Response").equals("Success"))
{
JSONArray dataJsonArray = mainJsonObject.getJSONArray("Data");
if(i == 0)
for(int i = 0; i < dataJsonArray.length(); i++)
{
tab[i] = tab[i] + "}";
}
else
{
tab[i] = "{" + tab[i] + "}";
}
try {
JSONObject jsonObject = new JSONObject(tab[i]);
dataChart.add(parseJSON(jsonObject));
} catch (JSONException e) {
Log.d(context.getResources().getString(R.string.debug_volley), "API Request error: " + e + " index: " + i);
JSONObject timeJsonObject = dataJsonArray.getJSONObject(i);
dataChart.add(parseJSON(timeJsonObject));
}
}
}
else
{
dataChart = null;
else
{
dataChart = null;
}
} catch (JSONException e) {
Log.d("moodl", "API Request error : " + e);
}
return dataChart;

View File

@ -1,175 +0,0 @@
package com.herbron.moodl.DataManagers.CurrencyData;
import android.content.Context;
import android.os.StrictMode;
import android.util.Log;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.herbron.moodl.DataManagers.BalanceManager;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.regex.Pattern;
/**
* Created by Tiji on 11/04/2018.
*/
public class CurrencyDetailsList {
final private static String DETAILURL = "https://min-api.cryptocompare.com/data/all/coinlist";
private RequestQueue requestQueue;
private LinkedHashMap<String, String> coinInfosHashmap;
private static CurrencyDetailsList INSTANCE;
private boolean upToDate;
private CurrencyDetailsList(Context context)
{
requestQueue = Volley.newRequestQueue(context);
}
public static synchronized CurrencyDetailsList getInstance(Context context)
{
if(INSTANCE == null)
{
INSTANCE = new CurrencyDetailsList(context);
}
return INSTANCE;
}
public void update(final BalanceManager.IconCallBack callBack)
{
StringRequest strRequest = new StringRequest(Request.Method.GET, DETAILURL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response.length() > 0) {
processDetailResult(response, callBack);
}
upToDate = true;
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
upToDate = true;
}
});
requestQueue.add(strRequest);
}
public boolean isUpToDate()
{
return upToDate;
}
private void processDetailResult(String response, final BalanceManager.IconCallBack callBack)
{
response = response.substring(response.indexOf("\"Data\"") + 7, response.lastIndexOf("},\"Type\":100}"));
String[] tab = response.split(Pattern.quote("},"));
coinInfosHashmap = new LinkedHashMap<>();
for(int i = 0; i < tab.length; i++)
{
tab[i] = tab[i].substring(tab[i].indexOf("\":{")+2, tab[i].length()) + "}";
try {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
JSONObject jsonObject = new JSONObject(tab[i]);
switch (jsonObject.getString("Symbol"))
{
case "IOT":
coinInfosHashmap.put("MIOTA", tab[i]);
break;
case "XRB":
coinInfosHashmap.put("NANO", tab[i]);
break;
default:
coinInfosHashmap.put(jsonObject.getString("Symbol"), tab[i]);
break;
}
} catch (JSONException e) {
Log.d("moodl", "ImageUrl not found.");
}
}
sortDetails();
callBack.onSuccess();
}
private void sortDetails()
{
LinkedHashMap<String, String> sortedHashmap = new LinkedHashMap<>();
List<String> listInfos = new ArrayList<>(coinInfosHashmap.values());
List<String> listSymbols = new ArrayList<>(coinInfosHashmap.keySet());
for(int i = 0; i < coinInfosHashmap.keySet().size(); i++)
{
try {
JSONObject jsonObject = new JSONObject(listInfos.get(i));
int index = jsonObject.getInt("SortOrder");
listInfos.add(index, listInfos.get(i));
listSymbols.add(index, listSymbols.get(i));
} catch (JSONException e) {
e.printStackTrace();
}
}
for(int i = 0; i < listInfos.size(); i++)
{
sortedHashmap.put(listSymbols.get(i), listInfos.get(i));
}
coinInfosHashmap = sortedHashmap;
}
public LinkedHashMap<String, String> getCoinInfosHashmap() {
return coinInfosHashmap;
}
public List<String> getCurrenciesName()
{
List<String> currenciesName = new ArrayList<>();
for (String symbol : coinInfosHashmap.keySet())
{
try {
JSONObject jsonObject = new JSONObject(coinInfosHashmap.get(symbol));
currenciesName.add(jsonObject.getString("CoinName"));
} catch (JSONException e) {
e.printStackTrace();
}
}
return currenciesName;
}
public Currency getCurrencyDetailsFromSymbol(String symbol)
{
//Currency currency = new Currency();
return null;
}
public List<String> getCurrenciesSymbol()
{
return new ArrayList<>(coinInfosHashmap.keySet());
}
}

View File

@ -1,197 +0,0 @@
package com.herbron.moodl.DataManagers.CurrencyData;
import android.content.Context;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.herbron.moodl.Activities.HomeActivityFragments.Overview;
import com.herbron.moodl.DataManagers.BalanceManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Created by Guitoune on 22/04/2018.
*/
public class CurrencyTickerList {
final private static String LISTINGURL = "https://api.coinmarketcap.com/v2/listings/";
final private static String TICKERLISTURL1 = "https://api.coinmarketcap.com/v2/ticker/?start=";
private RequestQueue requestQueue;
private List<Currency> currencyTickerList;
private static CurrencyTickerList INSTANCE;
private boolean upToDate;
private CurrencyTickerList(Context context)
{
requestQueue = Volley.newRequestQueue(context);
}
public static synchronized CurrencyTickerList getInstance(Context context)
{
if(INSTANCE == null)
{
INSTANCE = new CurrencyTickerList(context);
}
return INSTANCE;
}
public boolean isUpToDate()
{
return upToDate;
}
public void getCurrenciesFrom(int indexFrom, final String toSymbol, Overview.UpdateCallBack callBack)
{
String requetsString = TICKERLISTURL1 + indexFrom + "&limit=50&convert=" + toSymbol;
StringRequest strRequest = new StringRequest(Request.Method.GET, requetsString,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response.length() > 0)
{
processTickersResult(response, toSymbol, callBack);
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(strRequest);
}
public void updateListing(final BalanceManager.IconCallBack callBack)
{
currencyTickerList = new ArrayList<>();
StringRequest strRequest = new StringRequest(Request.Method.GET, LISTINGURL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response.length() > 0) {
processTickerListResult(response, callBack);
}
upToDate = true;
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
upToDate = true;
}
});
requestQueue.add(strRequest);
}
public int getTickerIdForSymbol(String symbol)
{
int tickerId = 0;
int i = 0;
while(!currencyTickerList.get(i).getSymbol().equals(symbol) && currencyTickerList.size() > i+1)
{
i++;
}
if(currencyTickerList.get(i).getSymbol().equals(symbol))
{
tickerId = currencyTickerList.get(i).getTickerId();
}
return tickerId;
}
private void processTickersResult(String response, String toSymbol, Overview.UpdateCallBack callBack)
{
List<Currency> currencyList = new ArrayList<>();
try {
JSONObject masterJsonObject = new JSONObject(response);
if(masterJsonObject.keys().hasNext())
{
JSONObject currencyJsonObject = masterJsonObject.getJSONObject(masterJsonObject.keys().next());
Iterator<?> keys = currencyJsonObject.keys();
while(keys.hasNext())
{
String key = keys.next().toString();
JSONObject subCurrencyJsonObject = currencyJsonObject.getJSONObject(key);
Currency newCurrency = new Currency(subCurrencyJsonObject.getString("name"), subCurrencyJsonObject.getString("symbol"), subCurrencyJsonObject.getInt("id"));
newCurrency.setRank(subCurrencyJsonObject.getInt("rank"));
JSONObject quoteJsonObject = subCurrencyJsonObject.getJSONObject("quotes");
JSONObject symJsonObject = quoteJsonObject.getJSONObject(toSymbol);
newCurrency.setValue(symJsonObject.getDouble("price"));
newCurrency.setDayFluctuationPercentage((float) symJsonObject.getDouble("percent_change_24h"));
newCurrency.setDayFluctuation(newCurrency.getDayFluctuationPercentage() * newCurrency.getValue() / 100);
currencyList.add(newCurrency);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
callBack.onSuccess(currencyList);
}
public void processTickerListResult(String response, BalanceManager.IconCallBack callBack)
{
try {
JSONObject dataJsonObject = new JSONObject(response);
JSONArray dataJsonArray = dataJsonObject.getJSONArray("data");
for(int i = 0; i < dataJsonArray.length(); i++)
{
JSONObject currencyJsonObject = dataJsonArray.getJSONObject(i);
currencyTickerList.add(new Currency(currencyJsonObject.getString("name"), currencyJsonObject.getString("symbol"), currencyJsonObject.getInt("id")));
}
} catch (JSONException e) {
e.printStackTrace();
}
/*response = response.substring(16, response.length() - 2);
String[] strTable = response.split(Pattern.quote("},"));
for(int i = 0; i < strTable.length; i++)
{
strTable[i] += "}";
Log.d("moodl", "TICKER " + i + " " + strTable[i]);
try {
JSONObject jsonObject = new JSONObject(strTable[i]);
Log.d("moodl", "TICKER JSON " + i + " " + jsonObject);
switch (jsonObject.getString("symbol"))
{
case "MIOTA":
coinTickersHashmap.put("IOT", strTable[i]);
break;
case "NANO":
coinTickersHashmap.put("XRB", strTable[i]);
break;
default:
coinTickersHashmap.put(jsonObject.getString("symbol"), strTable[i]);
break;
}
} catch (JSONException e) {
e.printStackTrace();
}
}*/
callBack.onSuccess();
}
}

View File

@ -10,18 +10,33 @@ public class Transaction {
private String symbol;
private double amount;
private long timestamp;
private double purchasedPrice;
private double price;
private double fees;
private boolean isMined;
private String feeCurrency;
private String feeFormat;
private String note;
private String symPair;
private String source;
private String destination;
private String type;
private boolean isDeducted;
public Transaction(int transactionId, String symbol, double amount, long timestamp, double purchasedPrice, double fees)
public Transaction(int transactionId, String symbol, String symPair, double amount, long timestamp, double purchasedPrice, double fees, String note, String feeCurrency, String source, String destination, String type, String feeFormat, boolean isDeducted)
{
this.transactionId = transactionId;
this.symbol = symbol;
this.symPair = symPair;
this.amount = amount;
this.timestamp = timestamp;
this.purchasedPrice = purchasedPrice;
this.price = purchasedPrice;
this.fees = fees;
this.note = note;
this.feeCurrency = feeCurrency;
this.source = source;
this.destination = destination;
this.type = type;
this.feeFormat = feeFormat;
this.isDeducted = isDeducted;
}
public int getTransactionId() {
@ -53,14 +68,14 @@ public class Transaction {
this.amount = amount;
}
public void setPurchasedPrice(double purchasedPrice)
public void setPrice(double purchasedPrice)
{
this.purchasedPrice = purchasedPrice;
this.price = purchasedPrice;
}
public double getPurchasedPrice()
public double getPrice()
{
return purchasedPrice;
return price;
}
public double getFees() {
@ -70,4 +85,72 @@ public class Transaction {
public void setFees(double fees) {
this.fees = fees;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public String getSymPair() {
return symPair;
}
public void setSymPair(String symPair) {
this.symPair = symPair;
}
public String getFeeCurrency() {
return feeCurrency;
}
public void setFeeCurrency(String feeCurrency) {
this.feeCurrency = feeCurrency;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFeeFormat() {
return feeFormat;
}
public void setFeeFormat(String feeFormat) {
this.feeFormat = feeFormat;
}
public boolean isDeducted() {
return isDeducted;
}
public void setDeducted(boolean deducted) {
isDeducted = deducted;
}
}

View File

@ -0,0 +1,91 @@
package com.herbron.moodl.DataManagers;
import android.content.Context;
import android.util.Log;
import com.herbron.moodl.R;
import android.util.Base64;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class DataCrypter {
private static Key aesKey;
public static void updateKey(String key)
{
try {
byte[] keyByte = key.getBytes("UTF-8");
byte[] finalKey = new byte[32];
System.arraycopy(keyByte, 0, finalKey, 0, keyByte.length);
aesKey = new SecretKeySpec(finalKey, "AES");
} catch (UnsupportedEncodingException e) {
Log.d("moodl", "Error while creating encryption key " + e.getMessage());
}
}
public static String encrypt(Context context, String data)
{
String encryptedData = null;
try {
IvParameterSpec ivParameterSpec = new IvParameterSpec(context.getString(R.string.ivKey).getBytes("UTF-8"));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, aesKey, ivParameterSpec);
byte[] encryptedBytes = cipher.doFinal(data.getBytes("UTF-8"));
encryptedData = Base64.encodeToString(encryptedBytes, Base64.DEFAULT);
} catch (NoSuchPaddingException | NoSuchAlgorithmException
| InvalidKeyException | BadPaddingException
| IllegalBlockSizeException | UnsupportedEncodingException
| InvalidAlgorithmParameterException e) {
Log.d("moodl", "Error while encrypting data " + e.getMessage());
}
return encryptedData;
}
public static String decrypt(Context context, String data)
{
String decryptedData = null;
try {
IvParameterSpec ivParameterSpec = new IvParameterSpec(context.getString(R.string.ivKey).getBytes("UTF-8"));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, aesKey, ivParameterSpec);
byte[] decryptedBytes = cipher.doFinal(data.getBytes("UTF-8"));
//byte[] dataBytes = Base64.decode(data, Base64.DEFAULT);
decryptedData = new String(decryptedBytes, StandardCharsets.UTF_8);
} catch(NoSuchPaddingException | NoSuchAlgorithmException
| InvalidKeyException | UnsupportedEncodingException
| InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return decryptedData;
}
}

View File

@ -3,15 +3,30 @@ package com.herbron.moodl.DataManagers;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import com.herbron.moodl.Activities.RecordTransactionFragments.TransferFragment;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.CurrencyData.Transaction;
import com.herbron.moodl.DataManagers.ExchangeManager.BinanceManager;
import com.herbron.moodl.DataManagers.ExchangeManager.Exchange;
import com.herbron.moodl.DataManagers.ExchangeManager.HitBtcManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static com.herbron.moodl.Utils.TransferUtils.isBalanceRelated;
/**
* Created by Guitoune on 14/01/2018.
@ -19,33 +34,45 @@ import java.util.List;
public class DatabaseManager extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 6;
private static final int DATABASE_VERSION = 17;
private static final String DATABASE_NAME = "Currencies.db";
private static final String DATABASE_NAME = "mdn.db";
private static final String TABLE_MANUAL_CURRENCIES = "ManualCurrencies";
private static final String TABLE_EXCHANGE_KEYS = "ExchangeKeys";
private static final String TABLE_WATCHLIST = "Watchlist";
public static final String TABLE_MANUAL_TRANSACTIONS = "ManualTransactions";
public static final String TABLE_EXCHANGE_KEYS = "ExchangeKeys";
public static final String TABLE_WATCHLIST = "Watchlist";
private static final String KEY_CURRENCY_ID = "idCurrency";
private static final String KEY_CURRENCY_SYMBOL = "symbol";
private static final String KEY_CURRENCY_NAME = "name";
private static final String KEY_CURRENCY_BALANCE = "balance";
private static final String KEY_CURRENCY_DATE = "addDate";
private static final String KEY_CURRENCY_PURCHASED_PRICE = "purchasedPrice";
private static final String KEY_CURRENCY_IS_MINED = "isMined";
private static final String KEY_CURRENCY_FEES = "fees";
private static final String KEY_TRANSACTION_ID = "transactionId";
private static final String KEY_TRANSACTION_SYMBOL = "symbol";
private static final String KEY_TRANSACTION_AMOUNT = "amount";
private static final String KEY_TRANSACTION_PAIR = "symPair";
private static final String KEY_TRANSACTION_DATE = "transactionDate";
private static final String KEY_TRANSACTION_PURCHASE_PRICE = "purchasePrice";
private static final String KEY_TRANSACTION_SOURCE = "source";
private static final String KEY_TRANSACTION_DESTINATION = "destination";
private static final String KEY_TRANSACTION_FEES = "fees";
private static final String KEY_TRANSACTION_FEE_CURRENCY = "feeCurrency";
private static final String KEY_TRANSACTION_FEE_FORMAT = "feeFormat";
private static final String KEY_TRANSACTION_NOTES = "notes";
private static final String KEY_TRANSACTION_TYPE = "transactionType";
private static final String KEY_TRANSACTION_DEDUCT = "deductHoldings";
private static final String KEY_EXCHANGE_ID = "idExchange";
private static final String KEY_EXCHANGE_NAME = "name";
private static final String KEY_EXCHANGE_TYPE = "type";
private static final String KEY_EXCHANGE_DESCRIPTION = "description";
private static final String KEY_EXCHANGE_PUBLIC_KEY = "publicKey";
private static final String KEY_EXCHANGE_SECRET_KEY = "secretKey";
private static final String KEY_EXCHANGE_IS_ENABLED = "enabled";
private static final String KEY_WATCHLIST_ID = "idWatchlist";
private static final String KEY_WATCHLIST_SYMBOL = "symbol";
private static final String KEY_WATCHLIST_NAME = "name";
private static final String KEY_WATCHLIST_POSITION = "position";
public static final int BINANCE_TYPE = 0;
public static final int HITBTC_TYPE = 1;
public DatabaseManager(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
@ -54,22 +81,31 @@ public class DatabaseManager extends SQLiteOpenHelper{
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_MANUAL_CURRENCIES + "("
+ KEY_CURRENCY_ID + " INTEGER PRIMARY KEY,"
+ KEY_CURRENCY_SYMBOL + " VARCHAR(4),"
+ KEY_CURRENCY_NAME + " VARCHAR(45),"
+ KEY_CURRENCY_BALANCE + " TEXT,"
+ KEY_CURRENCY_DATE + " TEXT,"
+ KEY_CURRENCY_PURCHASED_PRICE + " REAL,"
+ KEY_CURRENCY_IS_MINED + " INTEGER,"
+ KEY_CURRENCY_FEES + " REAL"
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_MANUAL_TRANSACTIONS + "("
+ KEY_TRANSACTION_ID + " INTEGER PRIMARY KEY,"
+ KEY_TRANSACTION_SYMBOL + " VARCHAR(4),"
+ KEY_TRANSACTION_AMOUNT + " TEXT,"
+ KEY_TRANSACTION_DATE + " TEXT,"
+ KEY_TRANSACTION_PURCHASE_PRICE + " REAL,"
+ KEY_TRANSACTION_NOTES + " TEXT,"
+ KEY_TRANSACTION_PAIR + " VARCHAR(4),"
+ KEY_TRANSACTION_FEE_CURRENCY + " VARCHAR(4),"
+ KEY_TRANSACTION_FEES + " REAL,"
+ KEY_TRANSACTION_FEE_FORMAT + " VARCHAR(1),"
+ KEY_TRANSACTION_SOURCE + " TEXT,"
+ KEY_TRANSACTION_DESTINATION + " TEXT,"
+ KEY_TRANSACTION_TYPE + " VARCHAR(1),"
+ KEY_TRANSACTION_DEDUCT + " INTEGER"
+ ");");
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_EXCHANGE_KEYS + "("
+ KEY_EXCHANGE_ID + " INTEGER PRIMARY KEY,"
+ KEY_EXCHANGE_NAME + " TEXT,"
+ KEY_EXCHANGE_TYPE + " INTEGER,"
+ KEY_EXCHANGE_DESCRIPTION + " TEXT,"
+ KEY_EXCHANGE_PUBLIC_KEY + " TEXT,"
+ KEY_EXCHANGE_SECRET_KEY + " TEXT"
+ KEY_EXCHANGE_SECRET_KEY + " TEXT,"
+ KEY_EXCHANGE_IS_ENABLED + " INTEGER"
+ ");");
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_WATCHLIST + "("
@ -85,7 +121,7 @@ public class DatabaseManager extends SQLiteOpenHelper{
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE IF EXISTS " + TABLE_MANUAL_CURRENCIES);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_MANUAL_TRANSACTIONS);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_EXCHANGE_KEYS);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_WATCHLIST);
@ -123,6 +159,51 @@ public class DatabaseManager extends SQLiteOpenHelper{
return false;
}
public void updateTransactionWithId(int transactionId, double amount, Date date, double purchasedPrice, double fees, String note, String symbolFrom, String feeCurrency, String destination, String source, String type, String feeFormat, boolean deductFromHoldings)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(KEY_TRANSACTION_AMOUNT, amount);
cv.put(KEY_TRANSACTION_DATE, date.getTime());
cv.put(KEY_TRANSACTION_PURCHASE_PRICE, purchasedPrice);
cv.put(KEY_TRANSACTION_FEES, fees);
cv.put(KEY_TRANSACTION_NOTES, note);
cv.put(KEY_TRANSACTION_PAIR, symbolFrom);
cv.put(KEY_TRANSACTION_FEE_CURRENCY, feeCurrency);
cv.put(KEY_TRANSACTION_SOURCE, source);
cv.put(KEY_TRANSACTION_DESTINATION, destination);
cv.put(KEY_TRANSACTION_TYPE, type);
cv.put(KEY_TRANSACTION_FEE_FORMAT, feeFormat);
cv.put(KEY_TRANSACTION_DEDUCT, deductFromHoldings ? 1 : 0);
db.update(TABLE_MANUAL_TRANSACTIONS, cv, KEY_TRANSACTION_ID + "=" + transactionId, null);
}
public void addTransaction(String symbol, Double amount, Date date, double purchasePrice, double fees, String note, String symbolFrom, String feeCurrency, String destination, String source, String type, String feeFormat, boolean deductFromHoldings)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TRANSACTION_SYMBOL, symbol);
values.put(KEY_TRANSACTION_AMOUNT, amount);
values.put(KEY_TRANSACTION_DATE, date.getTime());
values.put(KEY_TRANSACTION_PURCHASE_PRICE, purchasePrice);
values.put(KEY_TRANSACTION_FEES, fees);
values.put(KEY_TRANSACTION_NOTES, note);
values.put(KEY_TRANSACTION_PAIR, symbolFrom);
values.put(KEY_TRANSACTION_FEE_CURRENCY, feeCurrency);
values.put(KEY_TRANSACTION_SOURCE, source);
values.put(KEY_TRANSACTION_DESTINATION, destination);
values.put(KEY_TRANSACTION_TYPE, type);
values.put(KEY_TRANSACTION_FEE_FORMAT, feeFormat);
values.put(KEY_TRANSACTION_DEDUCT, deductFromHoldings ? 1 : 0);
db.insert(TABLE_MANUAL_TRANSACTIONS, null, values);
db.close();
}
public void updateWatchlistPosition(String symbol, int position)
{
SQLiteDatabase db = this.getWritableDatabase();
@ -131,7 +212,6 @@ public class DatabaseManager extends SQLiteOpenHelper{
cv.put(KEY_WATCHLIST_POSITION, position);
db.update(TABLE_WATCHLIST, cv, KEY_WATCHLIST_SYMBOL + "='" + symbol + "'", null);
}
private int getWatchlistRowCount(SQLiteDatabase db)
@ -144,11 +224,283 @@ public class DatabaseManager extends SQLiteOpenHelper{
return result.getInt(0);
}
public int deleteCurrencyFromWatchlist(String symbol)
public int getDisabledExchangeAccountsNumber()
{
SQLiteDatabase db = this.getWritableDatabase();
String countQuerry = "SELECT COUNT() FROM " + TABLE_EXCHANGE_KEYS + " WHERE " + KEY_EXCHANGE_IS_ENABLED + "=0";
Cursor result = db.rawQuery(countQuerry, null);
result.moveToFirst();
return result.getInt(0);
}
public void deleteExchangeAccountFromId(int id)
{
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(TABLE_WATCHLIST, KEY_WATCHLIST_SYMBOL + " = '" + symbol + "'", null);
db.delete(TABLE_EXCHANGE_KEYS, KEY_EXCHANGE_ID + " = " + id, null);
db.close();
}
public void deleteCurrencyFromWatchlist(String symbol)
{
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_WATCHLIST, KEY_WATCHLIST_SYMBOL + " = '" + symbol + "'", null);
db.close();
}
public void disableExchangeAccount(int id)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(KEY_EXCHANGE_IS_ENABLED, 0);
db.update(TABLE_EXCHANGE_KEYS, cv, KEY_EXCHANGE_ID + "='" + id + "'", null);
}
public Exchange getExchangeFromId(int exchangeId)
{
String selectQuerry = "SELECT * FROM " + TABLE_EXCHANGE_KEYS + " WHERE " + KEY_EXCHANGE_ID + " = " + exchangeId;
SQLiteDatabase db = this.getWritableDatabase();
Cursor result = db.rawQuery(selectQuerry, null);
Exchange selectedExchange = null;
if(result.moveToFirst())
{
selectedExchange = new Exchange(result.getInt(result.getColumnIndex(KEY_EXCHANGE_ID))
, result.getString(result.getColumnIndex(KEY_EXCHANGE_NAME))
, result.getInt(result.getColumnIndex(KEY_EXCHANGE_TYPE))
, result.getString(result.getColumnIndex(KEY_EXCHANGE_DESCRIPTION))
, result.getString(result.getColumnIndex(KEY_EXCHANGE_PUBLIC_KEY))
, result.getString(result.getColumnIndex(KEY_EXCHANGE_SECRET_KEY))
, (result.getInt(result.getColumnIndex(KEY_EXCHANGE_IS_ENABLED)) == 1));
}
return selectedExchange;
}
public ArrayList<Exchange> getExchanges()
{
String selectQuerry = "SELECT * FROM " + TABLE_EXCHANGE_KEYS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor result = db.rawQuery(selectQuerry, null);
ArrayList<Exchange> exchanges = new ArrayList<>();
while(result.moveToNext())
{
exchanges.add(new Exchange(result.getInt(result.getColumnIndex(KEY_EXCHANGE_ID))
, result.getString(result.getColumnIndex(KEY_EXCHANGE_NAME))
, result.getInt(result.getColumnIndex(KEY_EXCHANGE_TYPE))
, result.getString(result.getColumnIndex(KEY_EXCHANGE_DESCRIPTION))
, result.getString(result.getColumnIndex(KEY_EXCHANGE_PUBLIC_KEY))
, result.getString(result.getColumnIndex(KEY_EXCHANGE_SECRET_KEY))
, (result.getInt(result.getColumnIndex(KEY_EXCHANGE_IS_ENABLED)) == 1)));
}
return exchanges;
}
public void addExchange(String name, int type, String description, String publicKey, String privateKey)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_EXCHANGE_NAME, name);
values.put(KEY_EXCHANGE_TYPE, type);
values.put(KEY_EXCHANGE_DESCRIPTION, description);
values.put(KEY_EXCHANGE_PUBLIC_KEY, publicKey);
values.put(KEY_EXCHANGE_SECRET_KEY, privateKey);
values.put(KEY_EXCHANGE_IS_ENABLED, 1);
db.insert(TABLE_EXCHANGE_KEYS, null, values);
db.close();
}
public JSONArray getDatabaseBackup(Context context, String table, boolean encryptData)
{
String selectQuerry = "SELECT * FROM " + table;
SQLiteDatabase db = this.getWritableDatabase();
Cursor result = db.rawQuery(selectQuerry, null);
JSONArray backupArray = new JSONArray();
while(result.moveToNext())
{
JSONObject backupObject = new JSONObject();
for(int i = 0; i < result.getColumnCount(); i++)
{
try {
if(result.getString(i) != null)
{
if(encryptData)
{
backupObject.put(result.getColumnName(i), DataCrypter.encrypt(context, result.getString(i)));
}
else
{
backupObject.put(result.getColumnName(i), result.getString(i));
}
}
else
{
backupObject.put(result.getColumnName(i), "");
}
} catch (JSONException e) {
Log.d("moodl", "Error while creating a json backup");
}
}
backupArray.put(backupObject);
}
result.close();
db.close();
return backupArray;
}
public void wipeData(String table)
{
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DELETE FROM "+ table);
}
public void addRawData(Context context, JSONObject rawValues, String table, boolean decrypt)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
while(rawValues.keys().hasNext())
{
String key = rawValues.keys().next();
try {
if(decrypt)
{
values.put(key, DataCrypter.decrypt(context, rawValues.getString(key)));
}
else
{
values.put(key, rawValues.getString(key));
}
} catch (JSONException e) {
Log.d("moodl", "Error while inserting " + key + " " + e.getMessage());
}
}
db.insert(table, null, values);
db.close();
}
public void addRowApiKeys(JSONObject rawValues, Context context, boolean decrypt)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
try {
if(decrypt)
{
values.put(KEY_EXCHANGE_NAME, DataCrypter.decrypt(context, rawValues.getString(KEY_EXCHANGE_NAME)));
values.put(KEY_EXCHANGE_TYPE, DataCrypter.decrypt(context, rawValues.getString(KEY_EXCHANGE_TYPE)));
values.put(KEY_EXCHANGE_DESCRIPTION, DataCrypter.decrypt(context, rawValues.getString(KEY_EXCHANGE_DESCRIPTION)));
values.put(KEY_EXCHANGE_PUBLIC_KEY, DataCrypter.decrypt(context, rawValues.getString(KEY_EXCHANGE_PUBLIC_KEY)));
values.put(KEY_EXCHANGE_SECRET_KEY, DataCrypter.decrypt(context, rawValues.getString(KEY_EXCHANGE_SECRET_KEY)));
values.put(KEY_EXCHANGE_IS_ENABLED, DataCrypter.decrypt(context, rawValues.getString(KEY_EXCHANGE_IS_ENABLED)));
}
else
{
values.put(KEY_EXCHANGE_NAME, rawValues.getString(KEY_EXCHANGE_NAME));
values.put(KEY_EXCHANGE_TYPE, rawValues.getString(KEY_EXCHANGE_TYPE));
values.put(KEY_EXCHANGE_DESCRIPTION, rawValues.getString(KEY_EXCHANGE_DESCRIPTION));
values.put(KEY_EXCHANGE_PUBLIC_KEY, rawValues.getString(KEY_EXCHANGE_PUBLIC_KEY));
values.put(KEY_EXCHANGE_SECRET_KEY, rawValues.getString(KEY_EXCHANGE_SECRET_KEY));
values.put(KEY_EXCHANGE_IS_ENABLED, rawValues.getString(KEY_EXCHANGE_IS_ENABLED));
}
} catch (JSONException e) {
Log.d("moodl", "Error while inserting api key " + e.getMessage());
}
db.insert(TABLE_EXCHANGE_KEYS, null, values);
db.close();
}
public void addRowWatchlist(JSONObject rawValues, Context context, boolean decrypt)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
try {
if(decrypt)
{
values.put(KEY_WATCHLIST_SYMBOL, DataCrypter.decrypt(context, rawValues.getString(KEY_WATCHLIST_SYMBOL)));
values.put(KEY_WATCHLIST_NAME, DataCrypter.decrypt(context, rawValues.getString(KEY_WATCHLIST_NAME)));
values.put(KEY_WATCHLIST_POSITION, DataCrypter.decrypt(context, rawValues.getString(KEY_WATCHLIST_POSITION)));
}
else
{
values.put(KEY_WATCHLIST_SYMBOL, rawValues.getString(KEY_WATCHLIST_SYMBOL));
values.put(KEY_WATCHLIST_NAME, rawValues.getString(KEY_WATCHLIST_NAME));
values.put(KEY_WATCHLIST_POSITION, rawValues.getString(KEY_WATCHLIST_POSITION));
}
} catch (JSONException e) {
Log.d("moodl", "Error while inserting watchlist " + e.getMessage());
}
db.insert(TABLE_WATCHLIST, null, values);
db.close();
}
public void addRowTransaction(JSONObject rawValues, Context context, boolean decrypt)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
try {
if(decrypt)
{
values.put(KEY_TRANSACTION_SYMBOL, DataCrypter.decrypt(context, rawValues.getString(KEY_TRANSACTION_SYMBOL)));
values.put(KEY_TRANSACTION_AMOUNT, DataCrypter.decrypt(context, rawValues.getString(KEY_TRANSACTION_AMOUNT)));
values.put(KEY_TRANSACTION_DATE, DataCrypter.decrypt(context, rawValues.getString(KEY_TRANSACTION_DATE)));
values.put(KEY_TRANSACTION_PURCHASE_PRICE, DataCrypter.decrypt(context, rawValues.getString(KEY_TRANSACTION_PURCHASE_PRICE)));
values.put(KEY_TRANSACTION_FEES, DataCrypter.decrypt(context, rawValues.getString(KEY_TRANSACTION_FEES)));
values.put(KEY_TRANSACTION_NOTES, DataCrypter.decrypt(context, rawValues.getString(KEY_TRANSACTION_NOTES)));
values.put(KEY_TRANSACTION_PAIR, DataCrypter.decrypt(context, rawValues.getString(KEY_TRANSACTION_PAIR)));
values.put(KEY_TRANSACTION_FEE_CURRENCY, DataCrypter.decrypt(context, rawValues.getString(KEY_TRANSACTION_FEE_CURRENCY)));
values.put(KEY_TRANSACTION_SOURCE, DataCrypter.decrypt(context, rawValues.getString(KEY_TRANSACTION_SOURCE)));
values.put(KEY_TRANSACTION_DESTINATION, DataCrypter.decrypt(context, rawValues.getString(KEY_TRANSACTION_DESTINATION)));
values.put(KEY_TRANSACTION_TYPE, DataCrypter.decrypt(context, rawValues.getString(KEY_TRANSACTION_TYPE)));
values.put(KEY_TRANSACTION_FEE_FORMAT, DataCrypter.decrypt(context, rawValues.getString(KEY_TRANSACTION_FEE_FORMAT)));
values.put(KEY_TRANSACTION_DEDUCT, DataCrypter.decrypt(context, rawValues.getString(KEY_TRANSACTION_DEDUCT)));
}
else
{
values.put(KEY_TRANSACTION_SYMBOL, rawValues.getString(KEY_TRANSACTION_SYMBOL));
values.put(KEY_TRANSACTION_AMOUNT, rawValues.getString(KEY_TRANSACTION_AMOUNT));
values.put(KEY_TRANSACTION_DATE, rawValues.getString(KEY_TRANSACTION_DATE));
values.put(KEY_TRANSACTION_PURCHASE_PRICE, rawValues.getDouble(KEY_TRANSACTION_PURCHASE_PRICE));
values.put(KEY_TRANSACTION_FEES, rawValues.getDouble(KEY_TRANSACTION_FEES));
values.put(KEY_TRANSACTION_NOTES, rawValues.getString(KEY_TRANSACTION_NOTES));
values.put(KEY_TRANSACTION_PAIR, rawValues.getString(KEY_TRANSACTION_PAIR));
values.put(KEY_TRANSACTION_FEE_CURRENCY, rawValues.getString(KEY_TRANSACTION_FEE_CURRENCY));
values.put(KEY_TRANSACTION_SOURCE, rawValues.getString(KEY_TRANSACTION_SOURCE));
values.put(KEY_TRANSACTION_DESTINATION, rawValues.getString(KEY_TRANSACTION_DESTINATION));
values.put(KEY_TRANSACTION_TYPE, rawValues.getString(KEY_TRANSACTION_TYPE));
values.put(KEY_TRANSACTION_FEE_FORMAT, rawValues.getString(KEY_TRANSACTION_FEE_FORMAT));
values.put(KEY_TRANSACTION_DEDUCT, rawValues.getInt(KEY_TRANSACTION_DEDUCT));
}
} catch (JSONException e) {
Log.d("moodl", "Error while inserting transaction " + e.getMessage());
}
db.insert(TABLE_MANUAL_TRANSACTIONS, null, values);
db.close();
}
public List<Currency> getAllCurrenciesFromWatchlist()
@ -161,30 +513,70 @@ public class DatabaseManager extends SQLiteOpenHelper{
while(resultList.moveToNext())
{
currencyList.add(new Currency(resultList.getString(2), resultList.getString(1)));
currencyList.add(new Currency(resultList.getString(resultList.getColumnIndex(KEY_WATCHLIST_NAME)), resultList.getString(resultList.getColumnIndex(KEY_WATCHLIST_SYMBOL))));
}
resultList.close();
db.close();
return currencyList;
}
public void addCurrencyToManualCurrency(String symbol, double balance, Date date, double purchasedPrice, double fees)
public List<HitBtcManager> getHitBtcAccounts(Context context)
{
String searchQuerry = "SELECT * FROM " + TABLE_EXCHANGE_KEYS + " WHERE " + KEY_EXCHANGE_TYPE + " = " + HITBTC_TYPE + " AND " + KEY_EXCHANGE_IS_ENABLED + " = 1";
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
Cursor resultList = db.rawQuery(searchQuerry, null);
values.put(KEY_CURRENCY_SYMBOL, symbol);
values.put(KEY_CURRENCY_BALANCE, balance);
values.put(KEY_CURRENCY_DATE, date.getTime());
values.put(KEY_CURRENCY_PURCHASED_PRICE, purchasedPrice);
values.put(KEY_CURRENCY_FEES, fees);
List<HitBtcManager> accountList = new ArrayList<>();
db.insert(TABLE_MANUAL_CURRENCIES, null, values);
while(resultList.moveToNext())
{
Exchange exchange = new Exchange(resultList.getInt(resultList.getColumnIndex(KEY_EXCHANGE_ID))
, resultList.getString(resultList.getColumnIndex(KEY_EXCHANGE_NAME))
, resultList.getInt(resultList.getColumnIndex(KEY_EXCHANGE_TYPE))
, resultList.getString(resultList.getColumnIndex(KEY_EXCHANGE_DESCRIPTION))
, resultList.getString(resultList.getColumnIndex(KEY_EXCHANGE_PUBLIC_KEY))
, resultList.getString(resultList.getColumnIndex(KEY_EXCHANGE_SECRET_KEY))
, (resultList.getInt(resultList.getColumnIndex(KEY_EXCHANGE_IS_ENABLED)) == 1));
accountList.add(new HitBtcManager(context, exchange));
}
resultList.close();
db.close();
return accountList;
}
public List<Currency> getAllCurrenciesFromManualCurrency()
public List<BinanceManager> getBinanceAccounts()
{
String searchQuerry = "SELECT * FROM " + TABLE_MANUAL_CURRENCIES;
String searchQuerry = "SELECT * FROM " + TABLE_EXCHANGE_KEYS + " WHERE " + KEY_EXCHANGE_TYPE + " = " + BINANCE_TYPE + " AND " + KEY_EXCHANGE_IS_ENABLED + " = 1";
SQLiteDatabase db = this.getWritableDatabase();
Cursor resultList = db.rawQuery(searchQuerry, null);
List<BinanceManager> accountList = new ArrayList<>();
while(resultList.moveToNext())
{
Exchange exchange = new Exchange(resultList.getInt(resultList.getColumnIndex(KEY_EXCHANGE_ID))
, resultList.getString(resultList.getColumnIndex(KEY_EXCHANGE_NAME))
, resultList.getInt(resultList.getColumnIndex(KEY_EXCHANGE_TYPE))
, resultList.getString(resultList.getColumnIndex(KEY_EXCHANGE_DESCRIPTION))
, resultList.getString(resultList.getColumnIndex(KEY_EXCHANGE_PUBLIC_KEY))
, resultList.getString(resultList.getColumnIndex(KEY_EXCHANGE_SECRET_KEY))
, (resultList.getInt(resultList.getColumnIndex(KEY_EXCHANGE_IS_ENABLED)) == 1));
accountList.add(new BinanceManager(exchange));
}
resultList.close();
db.close();
return accountList;
}
public List<Currency> getAllCurrenciesFromTransactions()
{
String searchQuerry = "SELECT * FROM " + TABLE_MANUAL_TRANSACTIONS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor resultatList = db.rawQuery(searchQuerry, null);
@ -192,7 +584,103 @@ public class DatabaseManager extends SQLiteOpenHelper{
while(resultatList.moveToNext())
{
currencyList.add(new Currency(resultatList.getString(1), resultatList.getDouble(3) - resultatList.getDouble(7)));
String symbol = resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL));
String feeSym = resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_FEE_CURRENCY));
String type = resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_TYPE));
if(type != null && !type.equals(""))
{
switch (type)
{
case "b":
if(symbol.equals(feeSym))
{
currencyList.add(new Currency(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL))
, resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_AMOUNT)) - resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_FEES))));
}
else
{
currencyList.add(new Currency(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL))
, resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_AMOUNT))));
}
if(resultatList.getInt(resultatList.getColumnIndex(KEY_TRANSACTION_DEDUCT)) == 1)
{
currencyList.add(new Currency(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_PAIR))
, -(resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_PURCHASE_PRICE))
* resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_AMOUNT))
+ resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_FEES)))));
}
break;
case "s":
if(symbol.equals(feeSym))
{
currencyList.add(new Currency(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL))
, -resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_AMOUNT)) - resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_FEES))));
}
else
{
currencyList.add(new Currency(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL))
, -resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_AMOUNT))));
}
if(resultatList.getInt(resultatList.getColumnIndex(KEY_TRANSACTION_DEDUCT)) == 1)
{
currencyList.add(new Currency(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_PAIR))
, resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_PURCHASE_PRICE))
* resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_AMOUNT))
- resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_FEES))));
}
break;
case "t":
if(isBalanceRelated(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SOURCE))) && isBalanceRelated(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_DESTINATION))))
{
if(!resultatList.isNull(resultatList.getColumnIndex(KEY_TRANSACTION_DEDUCT)))
{
if(resultatList.getInt(resultatList.getColumnIndex(KEY_TRANSACTION_DEDUCT)) == 1)
{
currencyList.add(new Currency(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL))
, -resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_AMOUNT))));
}
else
{
currencyList.add(new Currency(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL))
, -resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_FEES))));
}
}
}
else
{
if(isBalanceRelated(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SOURCE))))
{
currencyList.add(new Currency(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL))
, -resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_AMOUNT))));
}
else
{
if(isBalanceRelated(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_DESTINATION))))
{
currencyList.add(new Currency(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL))
, resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_AMOUNT))));
}
}
}
break;
}
}
else
{
if(symbol.equals(feeSym))
{
currencyList.add(new Currency(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL))
, resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_AMOUNT)) - resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_FEES))));
}
else
{
currencyList.add(new Currency(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL))
, resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_AMOUNT))));
}
}
}
resultatList.close();
@ -202,23 +690,9 @@ public class DatabaseManager extends SQLiteOpenHelper{
return currencyList;
}
public void updateTransactionWithId(int transactionId, double amount, Date time, double purchasedPrice, double fees)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(KEY_CURRENCY_BALANCE, amount);
cv.put(KEY_CURRENCY_DATE, time.getTime());
cv.put(KEY_CURRENCY_PURCHASED_PRICE, purchasedPrice);
cv.put(KEY_CURRENCY_FEES, fees);
db.update(TABLE_MANUAL_CURRENCIES, cv, KEY_CURRENCY_ID + "=" + transactionId, null);
}
public Transaction getCurrencyTransactionById(int id)
{
String searchQuerry = "SELECT * FROM " + TABLE_MANUAL_CURRENCIES + " WHERE " + KEY_CURRENCY_ID + "='" + id + "'";
String searchQuerry = "SELECT * FROM " + TABLE_MANUAL_TRANSACTIONS + " WHERE " + KEY_TRANSACTION_ID + "='" + id + "'";
SQLiteDatabase db = this.getWritableDatabase();
Cursor resultatList = db.rawQuery(searchQuerry, null);
@ -226,7 +700,20 @@ public class DatabaseManager extends SQLiteOpenHelper{
if(resultatList.moveToFirst())
{
transaction = new Transaction(resultatList.getInt(0), resultatList.getString(1), resultatList.getDouble(3), resultatList.getLong(4), resultatList.getLong(5), resultatList.getDouble(7));
transaction = new Transaction(resultatList.getInt(resultatList.getColumnIndex(KEY_TRANSACTION_ID))
, resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL))
, resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_PAIR))
, resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_AMOUNT))
, resultatList.getLong(resultatList.getColumnIndex(KEY_TRANSACTION_DATE))
, resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_PURCHASE_PRICE))
, resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_FEES))
, resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_NOTES))
, resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_FEE_CURRENCY))
, resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SOURCE))
, resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_DESTINATION))
, resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_TYPE))
, resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_FEE_FORMAT))
, resultatList.getInt(resultatList.getColumnIndex(KEY_TRANSACTION_DEDUCT)) == 1);
}
resultatList.close();
@ -238,7 +725,8 @@ public class DatabaseManager extends SQLiteOpenHelper{
public ArrayList<Transaction> getCurrencyTransactionsForSymbol(String symbol)
{
String searchQuerry = "SELECT * FROM " + TABLE_MANUAL_CURRENCIES + " WHERE " + KEY_CURRENCY_SYMBOL + "='" + symbol.toUpperCase() + "'";
String searchQuerry = "SELECT * FROM " + TABLE_MANUAL_TRANSACTIONS + " WHERE " + KEY_TRANSACTION_SYMBOL + "='" + symbol.toUpperCase()
+ "' OR " + KEY_TRANSACTION_PAIR + "='" + symbol.toUpperCase() + "' AND " + KEY_TRANSACTION_DEDUCT + "=1";
SQLiteDatabase db = this.getWritableDatabase();
Cursor resultatList = db.rawQuery(searchQuerry, null);
@ -246,7 +734,49 @@ public class DatabaseManager extends SQLiteOpenHelper{
while (resultatList.moveToNext())
{
transactionList.add(new Transaction(resultatList.getInt(0), resultatList.getString(1), resultatList.getDouble(3), resultatList.getLong(4), resultatList.getLong(5), resultatList.getDouble(7)));
String type = "t";
String pair = resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_PAIR));
String sym = resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL));
if(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SYMBOL)).equals(symbol.toUpperCase()))
{
type = resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_TYPE));
}
else
{
if(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_TYPE)).equals("s"))
{
type = "b";
pair = sym;
sym = resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_PAIR));
}
else
{
if(resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_TYPE)).equals("b"))
{
type = "s";
pair = sym;
sym = resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_PAIR));
}
}
}
transactionList.add(new Transaction(resultatList.getInt(resultatList.getColumnIndex(KEY_TRANSACTION_ID))
, sym
, pair
, resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_AMOUNT))
, resultatList.getLong(resultatList.getColumnIndex(KEY_TRANSACTION_DATE))
, resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_PURCHASE_PRICE))
, resultatList.getDouble(resultatList.getColumnIndex(KEY_TRANSACTION_FEES))
, resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_NOTES))
, resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_FEE_CURRENCY))
, resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_SOURCE))
, resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_DESTINATION))
, type
, resultatList.getString(resultatList.getColumnIndex(KEY_TRANSACTION_FEE_FORMAT))
, resultatList.getInt(resultatList.getColumnIndex(KEY_TRANSACTION_DEDUCT)) == 1));
}
resultatList.close();
@ -260,7 +790,7 @@ public class DatabaseManager extends SQLiteOpenHelper{
{
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_MANUAL_CURRENCIES, KEY_CURRENCY_ID + "=" + id, null);
db.delete(TABLE_MANUAL_TRANSACTIONS, KEY_TRANSACTION_ID + "=" + id, null);
db.close();
}

View File

@ -6,6 +6,7 @@ import com.binance.api.client.domain.account.Account;
import com.binance.api.client.domain.account.AssetBalance;
import com.binance.api.client.domain.account.Trade;
import com.binance.api.client.exception.BinanceApiException;
import com.herbron.moodl.DataNotifiers.BinanceUpdateNotifierInterface;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import java.util.ArrayList;
@ -15,23 +16,31 @@ import java.util.List;
* Created by Guitoune on 26/02/2018.
*/
public class BinanceManager {
private String publicKey;
private String privateKey;
public class BinanceManager extends Exchange {
private List<Currency> balance;
private ArrayList<com.herbron.moodl.DataManagers.CurrencyData.Trade> trades;
private List<String> pairSymbolList;
private static List<String> pairSymbolList;
public BinanceManager(String publicKey, String privateKey)
private List<BinanceUpdateNotifierInterface> binanceUpdateNotifierInterfaceList;
public BinanceManager(Exchange exchange)
{
this.publicKey = publicKey;
this.privateKey = privateKey;
super(exchange.id, exchange.name, exchange.type, exchange.description, exchange.publicKey, exchange.privateKey, exchange.isEnabled);
createPairSymbolList();
}
public void addListener(BinanceUpdateNotifierInterface binanceUpdateNotifierInterface)
{
if(binanceUpdateNotifierInterfaceList == null)
{
binanceUpdateNotifierInterfaceList = new ArrayList<>();
}
binanceUpdateNotifierInterfaceList.add(binanceUpdateNotifierInterface);
}
private void createPairSymbolList()
{
pairSymbolList = new ArrayList<>();
@ -42,9 +51,10 @@ public class BinanceManager {
pairSymbolList.add("USDT");
}
public void updateBalance(BinanceCallBack callBack)
public void updateBalance()
{
BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(publicKey, privateKey);
BinanceApiRestClient client = factory.newRestClient();
try {
@ -57,21 +67,30 @@ public class BinanceManager {
{
if(Double.parseDouble(assets.get(i).getFree()) > 0 || Double.parseDouble(assets.get(i).getLocked()) > 0)
{
balance.add(new Currency(assets.get(i).getAsset(), Double.parseDouble(assets.get(i).getFree()) + Double.parseDouble(assets.get(i).getLocked())));
//balance.add(new Currency(assets.get(i).getAsset(), Double.parseDouble(assets.get(i).getFree()) + Double.parseDouble(assets.get(i).getLocked())));
if(!assets.get(i).getAsset().equals("VEN"))
{
balance.add(new Currency(assets.get(i).getAsset(), Double.parseDouble(assets.get(i).getFree()) + Double.parseDouble(assets.get(i).getLocked())));
}
}
}
callBack.onSuccess();
for(BinanceUpdateNotifierInterface binanceUpdateNotifierInterface : binanceUpdateNotifierInterfaceList)
{
binanceUpdateNotifierInterface.onBinanceBalanceUpdateSuccess();
}
} catch (BinanceApiException e) {
callBack.onError(e.getMessage());
for(BinanceUpdateNotifierInterface binanceUpdateNotifierInterface : binanceUpdateNotifierInterfaceList)
{
binanceUpdateNotifierInterface.onBinanceBalanceUpdateError(id, e.getMessage());
}
}
}
public void updateTrades(BinanceCallBack callBack, String symbol)
public void updateTrades(String symbol)
{
trades = new ArrayList<>();
for(int i = 0; i < pairSymbolList.size(); i++)
{
if(!pairSymbolList.get(i).equals(symbol))
@ -80,7 +99,10 @@ public class BinanceManager {
}
}
callBack.onSuccess();
for(BinanceUpdateNotifierInterface binanceUpdateNotifierInterface : binanceUpdateNotifierInterfaceList)
{
binanceUpdateNotifierInterface.onBinanceTradesUpdated(trades);
}
}
public void updateTrades(BinanceCallBack callBack, String symbol, long fromId)
@ -98,6 +120,12 @@ public class BinanceManager {
callBack.onSuccess();
}
public void updateTransactions(String symbol)
{
BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance(publicKey, privateKey);
BinanceApiRestClient client = factory.newRestClient();
}
public List<com.herbron.moodl.DataManagers.CurrencyData.Trade> updateTrades(String symbol, String pairSymbol)
{

View File

@ -0,0 +1,96 @@
package com.herbron.moodl.DataManagers.ExchangeManager;
import com.herbron.moodl.DataManagers.InfoAPIManagers.Pair;
import java.util.ArrayList;
import java.util.List;
public class Exchange {
protected int id;
protected String name;
protected int type;
protected String description;
protected String publicKey;
protected String privateKey;
protected boolean isEnabled;
private List<Pair> pairs;
public Exchange(int id, String name, int type, String description, String publicKey, String privateKey, boolean isEnabled)
{
this.id = id;
this.name = name;
this.type = type;
this.description = description;
this.publicKey = publicKey;
this.privateKey = privateKey;
this.isEnabled = isEnabled;
}
public Exchange(String name, List<Pair> pairs)
{
this.name = name;
this.pairs = pairs;
}
public Exchange(Exchange exchange)
{
this.name = exchange.name;
this.pairs = exchange.pairs;
}
public List<Pair> getPairs()
{
return pairs;
}
public boolean isEnabled()
{
return isEnabled;
}
public String getPublicKey()
{
return publicKey;
}
public String getPrivateKey()
{
return privateKey;
}
public int getType()
{
return type;
}
public String getName()
{
return name;
}
public String getDescription()
{
return description;
}
public int getId()
{
return id;
}
public List<Pair> getPairsFor(String symbol)
{
List<Pair> compatiblePairs = new ArrayList<>();
for(Pair pair : pairs)
{
if(pair.contains(symbol))
{
compatiblePairs.add(pair);
}
}
return compatiblePairs;
}
}

View File

@ -11,6 +11,7 @@ import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataNotifiers.HitBTCUpdateNotifierInterface;
import com.herbron.moodl.R;
import org.json.JSONArray;
@ -26,10 +27,8 @@ import java.util.Map;
* Created by Guitoune on 26/02/2018.
*/
public class HitBtcManager {
public class HitBtcManager extends Exchange {
private String publicKey;
private String privateKey;
final private String hitBalanceUrl = "https://api.hitbtc.com/api/2/account/balance";
final private String hitTradingBalanceUrl = "https://api.hitbtc.com/api/2/trading/balance";
final private String tradeHistoryUrl = "https://api.hitbtc.com/api/2/history/trades?";
@ -41,13 +40,24 @@ public class HitBtcManager {
private List<Currency> balance;
private android.content.Context context;
public HitBtcManager(android.content.Context context, String publicKey, String privateKey)
private List<HitBTCUpdateNotifierInterface> hitBTCUpdateNotifierInterfaceList;
public HitBtcManager(android.content.Context context, Exchange exchange)
{
super(exchange.id, exchange.name, exchange.type, exchange.description, exchange.publicKey, exchange.privateKey, exchange.isEnabled);
this.context = context;
requestQueue = Volley.newRequestQueue(context);
}
this.publicKey = publicKey;
this.privateKey = privateKey;
public void addListener(HitBTCUpdateNotifierInterface hitBTCUpdateNotifierInterface)
{
if(hitBTCUpdateNotifierInterfaceList == null)
{
hitBTCUpdateNotifierInterfaceList = new ArrayList<>();
}
hitBTCUpdateNotifierInterfaceList.add(hitBTCUpdateNotifierInterface);
}
private void createPairSymbolList()
@ -60,11 +70,6 @@ public class HitBtcManager {
pairSymbolList.add("USDT");
}
public void updateTrades(final HitBtcCallBack callBack, String symbol, String pairSymbol)
{
}
private void mergeBalanceSymbols()
{
List<Currency> mergedBalance = new ArrayList<>();
@ -91,7 +96,7 @@ public class HitBtcManager {
balance = mergedBalance;
}
public void updateGlobalBalance(final HitBtcCallBack masterCallBack)
public void updateGlobalBalance()
{
isTradingBalanceUpdated = false;
isBalanceUpdated = false;
@ -106,13 +111,20 @@ public class HitBtcManager {
if(isTradingBalanceUpdated)
{
mergeBalanceSymbols();
masterCallBack.onSuccess();
for(HitBTCUpdateNotifierInterface hitBTCUpdateNotifierInterface : hitBTCUpdateNotifierInterfaceList)
{
hitBTCUpdateNotifierInterface.onHitBTCBalanceUpdateSuccess();
}
}
}
@Override
public void onError(String error) {
masterCallBack.onError(error);
for(HitBTCUpdateNotifierInterface hitBTCUpdateNotifierInterface : hitBTCUpdateNotifierInterfaceList)
{
hitBTCUpdateNotifierInterface.onHitBTCBalanceUpdateError(id, error);
}
}
});
@ -124,13 +136,20 @@ public class HitBtcManager {
if(isBalanceUpdated)
{
mergeBalanceSymbols();
masterCallBack.onSuccess();
for(HitBTCUpdateNotifierInterface hitBTCUpdateNotifierInterface : hitBTCUpdateNotifierInterfaceList)
{
hitBTCUpdateNotifierInterface.onHitBTCBalanceUpdateSuccess();
}
}
}
@Override
public void onError(String error) {
masterCallBack.onError(error);
for(HitBTCUpdateNotifierInterface hitBTCUpdateNotifierInterface : hitBTCUpdateNotifierInterfaceList)
{
hitBTCUpdateNotifierInterface.onHitBTCBalanceUpdateError(id, error);
}
}
});
}

View File

@ -0,0 +1,357 @@
package com.herbron.moodl.DataManagers.InfoAPIManagers;
import android.content.Context;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.herbron.moodl.DataNotifiers.CoinmarketcapNotifierInterface;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Created by Guitoune on 22/04/2018.
*/
public class CoinmarketCapAPIManager {
final private static String LISTINGURL = "https://api.coinmarketcap.com/v2/listings/";
final private static String TICKERLISTURL1 = "https://api.coinmarketcap.com/v2/ticker/?start=";
private static final String topCurrenciesUrl = "https://api.coinmarketcap.com/v2/ticker/?limit=9&convert=";
private static final String marketCapUrl = "https://api.coinmarketcap.com/v2/global/?convert=";
private RequestQueue requestQueue;
private List<Currency> currencyTickerList;
private static CoinmarketCapAPIManager INSTANCE;
private boolean upToDate;
private List<Currency> topCurrencies;
private long marketCap;
private long dayVolume;
private String active_crypto;
private String active_markets;
private List<CoinmarketcapNotifierInterface> coinmarketcapNotifierInterfaceList;
private CoinmarketCapAPIManager(Context context)
{
requestQueue = Volley.newRequestQueue(context);
}
public static synchronized CoinmarketCapAPIManager getInstance(Context context)
{
if(INSTANCE == null)
{
INSTANCE = new CoinmarketCapAPIManager(context);
}
return INSTANCE;
}
public void addListener(CoinmarketcapNotifierInterface coinmarketcapNotifierInterface)
{
if(coinmarketcapNotifierInterfaceList == null)
{
coinmarketcapNotifierInterfaceList = new ArrayList<>();
}
coinmarketcapNotifierInterfaceList.add(coinmarketcapNotifierInterface);
}
public boolean isUpToDate()
{
if(currencyTickerList == null)
{
upToDate = false;
}
return upToDate;
}
public void getCurrenciesFrom(int indexFrom, final String toSymbol)
{
String requetsString = TICKERLISTURL1 + indexFrom + "&limit=50&convert=" + toSymbol;
StringRequest strRequest = new StringRequest(Request.Method.GET, requetsString,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response.length() > 0)
{
processTickersResult(response, toSymbol);
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(strRequest);
}
public void updateListing()
{
currencyTickerList = new ArrayList<>();
StringRequest strRequest = new StringRequest(Request.Method.GET, LISTINGURL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response.length() > 0) {
processTickerListResult(response);
}
upToDate = true;
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
upToDate = true;
}
});
requestQueue.add(strRequest);
}
public int getTickerIdForSymbol(String symbol)
{
int tickerId = 0;
int i = 0;
while(!currencyTickerList.get(i).getSymbol().equals(symbol) && currencyTickerList.size() > i+1)
{
i++;
}
if(currencyTickerList.get(i).getSymbol().equals(symbol))
{
tickerId = currencyTickerList.get(i).getTickerId();
}
return tickerId;
}
private void processTickersResult(String response, String toSymbol)
{
List<Currency> currencyList = new ArrayList<>();
try {
JSONObject masterJsonObject = new JSONObject(response);
if(masterJsonObject.keys().hasNext())
{
JSONObject currencyJsonObject = masterJsonObject.getJSONObject(masterJsonObject.keys().next());
Iterator<?> keys = currencyJsonObject.keys();
while(keys.hasNext())
{
String key = keys.next().toString();
JSONObject subCurrencyJsonObject = currencyJsonObject.getJSONObject(key);
Currency newCurrency = new Currency(subCurrencyJsonObject.getString("name"), subCurrencyJsonObject.getString("symbol"), subCurrencyJsonObject.getInt("id"));
newCurrency.setRank(subCurrencyJsonObject.getInt("rank"));
JSONObject quoteJsonObject = subCurrencyJsonObject.getJSONObject("quotes");
JSONObject symJsonObject = quoteJsonObject.getJSONObject(toSymbol);
newCurrency.setValue(symJsonObject.getDouble("price"));
newCurrency.setDayFluctuationPercentage((float) symJsonObject.getDouble("percent_change_24h"));
newCurrency.setDayFluctuation(newCurrency.getDayFluctuationPercentage() * newCurrency.getValue() / 100);
currencyList.add(newCurrency);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
for(CoinmarketcapNotifierInterface coinmarketcapNotifierInterface : coinmarketcapNotifierInterfaceList)
{
coinmarketcapNotifierInterface.onCurrenciesRetrieved(currencyList);
}
}
private void processTickerListResult(String response)
{
try {
JSONObject dataJsonObject = new JSONObject(response);
JSONArray dataJsonArray = dataJsonObject.getJSONArray("data");
for(int i = 0; i < dataJsonArray.length(); i++)
{
JSONObject currencyJsonObject = dataJsonArray.getJSONObject(i);
currencyTickerList.add(new Currency(currencyJsonObject.getString("name"), currencyJsonObject.getString("symbol"), currencyJsonObject.getInt("id")));
}
} catch (JSONException e) {
e.printStackTrace();
}
for(CoinmarketcapNotifierInterface coinmarketcapNotifierInterface : coinmarketcapNotifierInterfaceList)
{
coinmarketcapNotifierInterface.onListingUpdated();
}
}
public List<Currency> getTotalListing()
{
return currencyTickerList;
}
public void updateTopCurrencies(final String toSymbol)
{
String requestString = topCurrenciesUrl + toSymbol;
topCurrencies = new ArrayList<>();
StringRequest strRequest = new StringRequest(Request.Method.GET, requestString,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response.length() > 0) {
processTopCurrencies(response, toSymbol);
}
for(CoinmarketcapNotifierInterface coinmarketcapNotifierInterface : coinmarketcapNotifierInterfaceList)
{
coinmarketcapNotifierInterface.onTopCurrenciesUpdated();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(strRequest);
}
public void updateMarketCap(final String toSymbol)
{
String requestString = marketCapUrl + toSymbol;
StringRequest strRequest = new StringRequest(Request.Method.GET, requestString,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response.length() > 0) {
processMarketCapData(response, toSymbol);
}
for(CoinmarketcapNotifierInterface coinmarketcapNotifierInterface : coinmarketcapNotifierInterfaceList)
{
coinmarketcapNotifierInterface.onMarketCapUpdated();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(strRequest);
}
private void processMarketCapData(String response, String toSymbol)
{
try {
JSONObject jsonObject = new JSONObject(response);
JSONObject dataJsonObject = jsonObject.getJSONObject("data");
JSONObject quotesJsonObject = dataJsonObject.getJSONObject("quotes");
JSONObject valuesJsonObject = quotesJsonObject.getJSONObject(toSymbol);
active_crypto = dataJsonObject.getString("active_cryptocurrencies");
active_markets = dataJsonObject.getString("active_markets");
marketCap = valuesJsonObject.getLong("total_market_cap");
dayVolume = valuesJsonObject.getLong("total_volume_24h");
} catch (JSONException e) {
e.printStackTrace();
}
}
public String getActive_crypto()
{
return active_crypto;
}
public String getActive_markets()
{
return active_markets;
}
public List<Currency> getTopCurrencies()
{
return topCurrencies;
}
public long getDayVolume()
{
return dayVolume;
}
private void processTopCurrencies(String response, String toSymbol)
{
try {
JSONObject masterJsonObject = new JSONObject(response);
if(masterJsonObject.keys().hasNext())
{
JSONObject currencyJsonObject = masterJsonObject.getJSONObject(masterJsonObject.keys().next());
Iterator<?> keys = currencyJsonObject.keys();
while(keys.hasNext())
{
String key = keys.next().toString();
JSONObject subCurrencyJsonObject = currencyJsonObject.getJSONObject(key);
Currency newCurrency = new Currency(subCurrencyJsonObject.getString("name"), subCurrencyJsonObject.getString("symbol"), subCurrencyJsonObject.getInt("id"));
JSONObject quoteJsonObject = subCurrencyJsonObject.getJSONObject("quotes");
JSONObject symJsonObject = quoteJsonObject.getJSONObject(toSymbol);
newCurrency.setMarketCapitalization(symJsonObject.getDouble("market_cap"));
newCurrency.setVolume24h(symJsonObject.getDouble("volume_24h"));
topCurrencies.add(newCurrency);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public Currency getCurrencyFromSymbol(String symbol)
{
Currency returnedCurrency = null;
int index = 0;
do {
if(symbol.equals(topCurrencies.get(index).getSymbol()))
{
returnedCurrency = topCurrencies.get(index);
}
index++;
} while(index < topCurrencies.size() && returnedCurrency == null);
return returnedCurrency;
}
public long getMarketCap()
{
return marketCap;
}
}

View File

@ -0,0 +1,313 @@
package com.herbron.moodl.DataManagers.InfoAPIManagers;
import android.content.Context;
import android.os.StrictMode;
import android.util.Log;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.herbron.moodl.DataNotifiers.CryptocompareNotifierInterface;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import com.herbron.moodl.DataManagers.ExchangeManager.Exchange;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.regex.Pattern;
/**
* Created by Tiji on 11/04/2018.
*/
public class CryptocompareApiManager {
final private static String DETAILURL = "https://min-api.cryptocompare.com/data/all/coinlist";
final private static String EXCHANGEURL = "https://min-api.cryptocompare.com/data/all/exchanges";
private RequestQueue requestQueue;
private LinkedHashMap<String, String> coinInfosHashmap;
private List<Exchange> exchangeList;
private static CryptocompareApiManager INSTANCE;
private boolean exchangesUpToDate;
private boolean detailsUpToDate;
private List<CryptocompareNotifierInterface> cryptocompareNotifierInterfaceList;
private CryptocompareApiManager(Context context)
{
requestQueue = Volley.newRequestQueue(context);
}
public static synchronized CryptocompareApiManager getInstance(Context context)
{
if(INSTANCE == null)
{
INSTANCE = new CryptocompareApiManager(context);
}
return INSTANCE;
}
public void addListener(CryptocompareNotifierInterface cryptocompareNotifierInterface)
{
if(cryptocompareNotifierInterfaceList == null)
{
cryptocompareNotifierInterfaceList = new ArrayList<>();
}
cryptocompareNotifierInterfaceList.add(cryptocompareNotifierInterface);
}
public void updateExchangeList()
{
StringRequest stringRequest = new StringRequest(Request.Method.GET, EXCHANGEURL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
processExchangeResult(response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(stringRequest);
}
public void updateDetails()
{
StringRequest strRequest = new StringRequest(Request.Method.GET, DETAILURL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response.length() > 0) {
processDetailResult(response);
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(strRequest);
}
public boolean isExchangesUpToDate()
{
if(exchangeList == null)
{
exchangesUpToDate = false;
}
return exchangesUpToDate;
}
public boolean isDetailsUpToDate()
{
if(coinInfosHashmap == null)
{
detailsUpToDate = false;
}
return detailsUpToDate;
}
private void processExchangeResult(String response)
{
exchangeList = new ArrayList<>();
try {
JSONObject mainJsonObject = new JSONObject(response);
Iterator<String> exchangeIterator = mainJsonObject.keys();
while(exchangeIterator.hasNext())
{
String exchangeKey = exchangeIterator.next();
JSONObject exchangeJsonObject = mainJsonObject.getJSONObject(exchangeKey);
Iterator<String> pairIterator = exchangeJsonObject.keys();
List<Pair> pairList = new ArrayList<>();
while(pairIterator.hasNext())
{
String pairKey = pairIterator.next();
JSONArray pairJsonArray = exchangeJsonObject.getJSONArray(pairKey);
for(int i = 0; i < pairJsonArray.length(); i++)
{
pairList.add(new Pair(pairKey, pairJsonArray.get(i).toString()));
}
}
exchangeList.add(new Exchange(exchangeKey, pairList));
}
for(CryptocompareNotifierInterface cryptocompareNotifierInterface : cryptocompareNotifierInterfaceList)
{
cryptocompareNotifierInterface.onExchangesUpdated();
}
} catch (JSONException e) {
Log.d("moodl", "Error while processing exchange result");
}
}
public List<Exchange> getExchangeList(String symbol)
{
List<Exchange> compatibleExchanges = new ArrayList<>();
for(Exchange exchange : exchangeList)
{
int i = 0;
boolean isSymbolTraded = false;
while(i < exchange.getPairs().size() && !isSymbolTraded)
{
if(exchange.getPairs().get(i).contains(symbol))
{
compatibleExchanges.add(exchange);
isSymbolTraded = true;
}
i++;
}
}
return compatibleExchanges;
}
private void processDetailResult(String response)
{
response = response.substring(response.indexOf("\"Data\"") + 7, response.lastIndexOf("},\"BaseImageUrl\""));
String[] tab = response.split(Pattern.quote("},"));
coinInfosHashmap = new LinkedHashMap<>();
for(int i = 0; i < tab.length; i++)
{
tab[i] = tab[i].substring(tab[i].indexOf("\":{")+2, tab[i].length()) + "}";
try {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
JSONObject jsonObject = new JSONObject(tab[i]);
switch (jsonObject.getString("Symbol"))
{
case "IOT":
coinInfosHashmap.put("MIOTA", tab[i]);
break;
case "XRB":
coinInfosHashmap.put("NANO", tab[i]);
break;
default:
coinInfosHashmap.put(jsonObject.getString("Symbol"), tab[i]);
break;
}
} catch (JSONException e) {
Log.d("moodl", "ImageUrl not found.");
}
}
sortDetails();
detailsUpToDate = true;
for(CryptocompareNotifierInterface cryptocompareNotifierInterface : cryptocompareNotifierInterfaceList)
{
cryptocompareNotifierInterface.onDetailsUpdated();
}
}
private void sortDetails()
{
LinkedHashMap<String, String> sortedHashmap = new LinkedHashMap<>();
List<String> listInfos = new ArrayList<>(coinInfosHashmap.values());
List<String> listSymbols = new ArrayList<>(coinInfosHashmap.keySet());
for(int i = 0; i < coinInfosHashmap.keySet().size(); i++)
{
try {
JSONObject jsonObject = new JSONObject(listInfos.get(i));
int index = jsonObject.getInt("SortOrder");
listInfos.add(index, listInfos.get(i));
listSymbols.add(index, listSymbols.get(i));
} catch (JSONException e) {
e.printStackTrace();
}
}
for(int i = 0; i < listInfos.size(); i++)
{
sortedHashmap.put(listSymbols.get(i), listInfos.get(i));
}
coinInfosHashmap = sortedHashmap;
}
public LinkedHashMap<String, String> getCoinInfosHashmap() {
return coinInfosHashmap;
}
public List<String> getCurrenciesName()
{
List<String> currenciesName = new ArrayList<>();
for (String symbol : coinInfosHashmap.keySet())
{
try {
JSONObject jsonObject = new JSONObject(coinInfosHashmap.get(symbol));
currenciesName.add(jsonObject.getString("CoinName"));
} catch (JSONException e) {
e.printStackTrace();
}
}
return currenciesName;
}
public List<Currency> getCurrenciesDenomination()
{
List<Currency> currencies = new ArrayList<>();
for(String symbol : coinInfosHashmap.keySet())
{
try {
JSONObject jsonObject = new JSONObject(coinInfosHashmap.get(symbol));
currencies.add(new Currency(jsonObject.getString("CoinName"), symbol));
} catch (JSONException e) {
e.printStackTrace();
}
}
return currencies;
}
public Currency getCurrencyDetailsFromSymbol(String symbol)
{
//Currency currency = new Currency();
return null;
}
public List<String> getCurrenciesSymbol()
{
return new ArrayList<>(coinInfosHashmap.keySet());
}
}

View File

@ -0,0 +1,41 @@
package com.herbron.moodl.DataManagers.InfoAPIManagers;
public class Pair {
private String from;
private String to;
public Pair(String from, String to)
{
this.from = from;
this.to = to;
}
public Pair(Pair pair)
{
this.from = pair.from;
this.to = pair.to;
}
public boolean contains(String symbol)
{
symbol = symbol.toUpperCase();
return symbol.equals(from) || symbol.equals(to);
}
public String getFrom()
{
return from;
}
public String getTo()
{
return to;
}
@Override
public String toString() {
return from + "/" + to;
}
}

View File

@ -1,182 +0,0 @@
package com.herbron.moodl.DataManagers;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Created by Guitoune on 02/03/2018.
*/
public class MarketCapManager {
private static final String topCurrenciesUrl = "https://api.coinmarketcap.com/v2/ticker/?limit=9&convert=";
private static final String marketCapUrl = "https://api.coinmarketcap.com/v2/global/?convert=";
private RequestQueue requestQueue;
private List<Currency> topCurrencies;
private long marketCap;
private long dayVolume;
private String active_crypto;
private String active_markets;
public MarketCapManager(android.content.Context context)
{
requestQueue = Volley.newRequestQueue(context);
}
public void updateTopCurrencies(final VolleyCallBack callBack, final String toSymbol)
{
String requestString = topCurrenciesUrl + toSymbol;
topCurrencies = new ArrayList<>();
StringRequest strRequest = new StringRequest(Request.Method.GET, requestString,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response.length() > 0) {
processTopCurrencies(response, toSymbol);
}
callBack.onSuccess();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(strRequest);
}
public void updateMarketCap(final VolleyCallBack callBack, final String toSymbol)
{
String requestString = marketCapUrl + toSymbol;
StringRequest strRequest = new StringRequest(Request.Method.GET, requestString,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response.length() > 0) {
processMarketCapData(response, toSymbol);
}
callBack.onSuccess();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(strRequest);
}
private void processMarketCapData(String response, String toSymbol)
{
try {
JSONObject jsonObject = new JSONObject(response);
JSONObject dataJsonObject = jsonObject.getJSONObject("data");
JSONObject quotesJsonObject = dataJsonObject.getJSONObject("quotes");
JSONObject valuesJsonObject = quotesJsonObject.getJSONObject(toSymbol);
active_crypto = dataJsonObject.getString("active_cryptocurrencies");
active_markets = dataJsonObject.getString("active_markets");
marketCap = valuesJsonObject.getLong("total_market_cap");
dayVolume = valuesJsonObject.getLong("total_volume_24h");
} catch (JSONException e) {
e.printStackTrace();
}
}
public String getActive_crypto()
{
return active_crypto;
}
public String getActive_markets()
{
return active_markets;
}
public List<Currency> getTopCurrencies()
{
return topCurrencies;
}
public long getDayVolume()
{
return dayVolume;
}
private void processTopCurrencies(String response, String toSymbol)
{
try {
JSONObject masterJsonObject = new JSONObject(response);
if(masterJsonObject.keys().hasNext())
{
JSONObject currencyJsonObject = masterJsonObject.getJSONObject(masterJsonObject.keys().next());
Iterator<?> keys = currencyJsonObject.keys();
while(keys.hasNext())
{
String key = keys.next().toString();
JSONObject subCurrencyJsonObject = currencyJsonObject.getJSONObject(key);
Currency newCurrency = new Currency(subCurrencyJsonObject.getString("name"), subCurrencyJsonObject.getString("symbol"), subCurrencyJsonObject.getInt("id"));
JSONObject quoteJsonObject = subCurrencyJsonObject.getJSONObject("quotes");
JSONObject symJsonObject = quoteJsonObject.getJSONObject(toSymbol);
newCurrency.setMarketCapitalization(symJsonObject.getDouble("market_cap"));
newCurrency.setVolume24h(symJsonObject.getDouble("volume_24h"));
topCurrencies.add(newCurrency);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public Currency getCurrencyFromSymbol(String symbol)
{
Currency returnedCurrency = null;
int index = 0;
do {
if(symbol.equals(topCurrencies.get(index).getSymbol()))
{
returnedCurrency = topCurrencies.get(index);
}
index++;
} while(index < topCurrencies.size() && returnedCurrency == null);
return returnedCurrency;
}
public long getMarketCap()
{
return marketCap;
}
public interface VolleyCallBack
{
void onSuccess();
}
}

View File

@ -9,43 +9,11 @@ import android.preference.PreferenceManager;
public class PreferencesManager {
private static int fragmentUpdated = 0;
private static final String currencyListFile = "CustomCurrencies";
private static final String preferencesFile = "Preferences";
private SharedPreferences settingPreferences;
private SharedPreferences currencyList;
private SharedPreferences preferencesList;
public PreferencesManager(android.content.Context context)
{
settingPreferences = PreferenceManager.getDefaultSharedPreferences(context);
currencyList = context.getSharedPreferences(currencyListFile, 0);
preferencesList = context.getSharedPreferences(preferencesFile, 0);
}
public void setDetailOption(boolean isExtended)
{
SharedPreferences.Editor editor = preferencesList.edit();
editor.putBoolean("DetailOption", isExtended);
editor.apply();
}
public boolean getDetailOption()
{
return preferencesList.getBoolean("DetailOption", true);
}
public boolean mustRefreshDefaultCurrency()
{
fragmentUpdated++;
if(fragmentUpdated == 3)
{
disableRefreshDefaultCurrency();
fragmentUpdated = 0;
}
return settingPreferences.getBoolean("refresh_default_currency", false);
}
public float getMinimumAmount()
@ -65,33 +33,11 @@ public class PreferencesManager {
return ret;
}
private void disableRefreshDefaultCurrency()
{
SharedPreferences.Editor editor = settingPreferences.edit();
editor.putBoolean("refresh_default_currency", false);
editor.apply();
}
public String getDefaultCurrency()
{
return settingPreferences.getString("default_currency", "USD");
}
public String getHitBTCPublicKey()
{
return settingPreferences.getString("hitbtc_publickey", null);
}
public String getHitBTCPrivateKey()
{
return settingPreferences.getString("hitbtc_privatekey", null);
}
public boolean isHitBTCActivated()
{
return settingPreferences.getBoolean("enable_hitbtc", false);
}
public boolean switchBalanceHiddenState()
{
SharedPreferences.Editor editor = settingPreferences.edit();
@ -113,16 +59,6 @@ public class PreferencesManager {
editor.apply();
}
public String getBinancePublicKey()
{
return settingPreferences.getString("binance_publickey", null);
}
public String getBinancePrivateKey()
{
return settingPreferences.getString("binance_privatekey", null);
}
public boolean isBinanceActivated()
{
return settingPreferences.getBoolean("enable_binance", false);

View File

@ -0,0 +1,12 @@
package com.herbron.moodl.DataNotifiers;
/**
* Created by Administrator on 17/06/2018.
*/
public interface BalanceUpdateNotifierInterface {
void onBalanceDataUpdated();
void onBalanceError(String error);
}

View File

@ -0,0 +1,14 @@
package com.herbron.moodl.DataNotifiers;
import com.herbron.moodl.DataManagers.CurrencyData.Trade;
import java.util.List;
public interface BinanceUpdateNotifierInterface {
void onBinanceTradesUpdated(List<Trade> trades);
void onBinanceBalanceUpdateSuccess();
void onBinanceBalanceUpdateError(int accountId, String error);
}

View File

@ -0,0 +1,16 @@
package com.herbron.moodl.DataNotifiers;
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
import java.util.List;
public interface CoinmarketcapNotifierInterface {
void onCurrenciesRetrieved(List<Currency> currencyList);
void onTopCurrenciesUpdated();
void onMarketCapUpdated();
void onListingUpdated();
}

View File

@ -0,0 +1,9 @@
package com.herbron.moodl.DataNotifiers;
public interface CryptocompareNotifierInterface {
void onDetailsUpdated();
void onExchangesUpdated();
}

View File

@ -0,0 +1,9 @@
package com.herbron.moodl.DataNotifiers;
public interface HitBTCUpdateNotifierInterface {
void onHitBTCBalanceUpdateSuccess();
void onHitBTCBalanceUpdateError(int accountId, String error);
}

View File

@ -0,0 +1,9 @@
package com.herbron.moodl.DataNotifiers;
import android.graphics.Bitmap;
public interface MoodlboxNotifierInterface {
void onBitmapDownloaded(Bitmap bitmap);
}

View File

@ -4,9 +4,9 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import com.herbron.moodl.Activities.DetailsActivityFragments.Home;
import com.herbron.moodl.Activities.DetailsActivityFragments.Informations;
import com.herbron.moodl.Activities.DetailsActivityFragments.Transactions;
import com.herbron.moodl.Activities.DetailsActivityFragments.ChartsFragment;
import com.herbron.moodl.Activities.DetailsActivityFragments.InformationFragment;
import com.herbron.moodl.Activities.DetailsActivityFragments.TransactionsFragment;
/**
* Created by Tiji on 13/05/2018.
@ -27,11 +27,11 @@ public class DetailsActivityPagerAdapter extends FragmentStatePagerAdapter {
switch (position)
{
case 0:
return new Home();
return new ChartsFragment();
case 1:
return new Informations();
return new InformationFragment();
case 2:
return new Transactions();
return new TransactionsFragment();
default:
return null;
}

View File

@ -35,7 +35,8 @@ public class FingerprintDialogFragment extends DialogFragment{
@Override
public void onClick(View view) {
dismiss();
getActivity().finish();
getActivity().getFragmentManager().popBackStack();
//getActivity().finish();
}
});

View File

@ -8,6 +8,8 @@ import android.os.CancellationSignal;
import android.os.Handler;
import android.support.v4.app.ActivityCompat;
import com.herbron.moodl.R;
/**
* Created by Guitoune on 28/02/2018.
*/
@ -39,7 +41,7 @@ public class FingerprintHandler extends FingerprintManager.AuthenticationCallbac
{
if(dialogFragment.isVisible())
{
dialogFragment.wrongFingerprint("Error");
dialogFragment.wrongFingerprint(context.getString(R.string.error));
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
@ -57,7 +59,7 @@ public class FingerprintHandler extends FingerprintManager.AuthenticationCallbac
{
if(dialogFragment.isVisible())
{
dialogFragment.wrongFingerprint("Wrong fingerprint");
dialogFragment.wrongFingerprint(context.getString(R.string.wrong_fingerprint));
new Handler().postDelayed(new Runnable() {
@Override
public void run() {

View File

@ -1,44 +0,0 @@
package com.herbron.moodl;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import com.herbron.moodl.Activities.HomeActivityFragments.MarketCapitalization;
import com.herbron.moodl.Activities.HomeActivityFragments.Summary;
import com.herbron.moodl.Activities.HomeActivityFragments.Watchlist;
/**
* Created by Tiji on 13/04/2018.
*/
public class HomeActivityPagerAdapter extends FragmentStatePagerAdapter {
private int numOfTabs;
public HomeActivityPagerAdapter(FragmentManager fm, int numOfTabs)
{
super(fm);
this.numOfTabs = numOfTabs;
}
@Override
public Fragment getItem(int position) {
switch (position)
{
case 0:
return new Watchlist();
case 1:
return new Summary();
case 2:
return new MarketCapitalization();
default:
return null;
}
}
@Override
public int getCount() {
return numOfTabs;
}
}

View File

@ -1,65 +0,0 @@
package com.herbron.moodl.LayoutManagers;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.herbron.moodl.DataManagers.CurrencyData.Trade;
import com.herbron.moodl.R;
import java.util.ArrayList;
import static com.herbron.moodl.MoodlBox.getDateFromTimestamp;
/**
* Created by Guitoune on 24/04/2018.
*/
public class TradeListAdapter extends ArrayAdapter<Trade> {
private Context context;
public TradeListAdapter(Context context, ArrayList<Trade> trades)
{
super(context, android.R.layout.simple_list_item_1, trades);
this.context = context;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Trade trade = getItem(position);
if(convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom_trade_row, parent, false);
}
TextView amountTxtView = convertView.findViewById(R.id.amountPurchased);
TextView purchasedPrice = convertView.findViewById(R.id.purchasedPrice);
TextView tradePair = convertView.findViewById(R.id.pair);
TextView dateTxtView = convertView.findViewById(R.id.tradeDate);
View tradeIndicator = convertView.findViewById(R.id.tradeIndicator);
amountTxtView.setText(String.valueOf(trade.getQty()));
purchasedPrice.setText(trade.getPrice());
dateTxtView.setText(getDateFromTimestamp(trade.getTime()));
tradePair.setText(trade.getSymbol() + "/" + trade.getPairSymbol());
if(trade.isBuyer())
{
tradeIndicator.setBackgroundColor(context.getColor(R.color.green));
}
else
{
tradeIndicator.setBackgroundColor(context.getColor(R.color.red));
}
return convertView;
}
}

View File

@ -1,138 +0,0 @@
package com.herbron.moodl.LayoutManagers;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.daimajia.swipe.SwipeLayout;
import com.herbron.moodl.Activities.RecordTransactionActivity;
import com.herbron.moodl.DataManagers.CurrencyData.Transaction;
import com.herbron.moodl.DataManagers.DatabaseManager;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.R;
import java.util.ArrayList;
import static com.herbron.moodl.MoodlBox.collapseH;
import static com.herbron.moodl.MoodlBox.getDateFromTimestamp;
import static com.herbron.moodl.MoodlBox.numberConformer;
import static java.lang.Math.abs;
/**
* Created by Guitoune on 24/04/2018.
*/
public class TransactionListAdapter extends ArrayAdapter<Transaction> {
private Context context;
public TransactionListAdapter(Context context, ArrayList<Transaction> transactions)
{
super(context, android.R.layout.simple_list_item_1, transactions);
this.context = context;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
final Transaction transaction = getItem(position);
if(convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom_transaction_row, parent, false);
}
TextView amountTxtView = convertView.findViewById(R.id.amountPurchased);
TextView valueTxtView = convertView.findViewById(R.id.puchasedValue);
TextView dateTxtView = convertView.findViewById(R.id.purchaseDate);
amountTxtView.setText(String.valueOf(transaction.getAmount()));
valueTxtView.setText(numberConformer(transaction.getPurchasedPrice() * transaction.getAmount()));
dateTxtView.setText(getDateFromTimestamp(transaction.getTimestamp()));
LinearLayout deleteLayout = convertView.findViewById(R.id.deleteTransactionLayout);
deleteLayout.setTag(transaction.getTransactionId());
deleteLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
PreferencesManager preferencesManager = new PreferencesManager(context);
DatabaseManager databaseManager = new DatabaseManager(context);
preferencesManager.setMustUpdateSummary(true);
databaseManager.deleteTransactionFromId(Integer.parseInt(view.getTag().toString()));
collapseH((View) view.getParent().getParent().getParent());
}
});
LinearLayout editLayout = convertView.findViewById(R.id.editTransactionLayout);
editLayout.setTag(transaction.getTransactionId());
editLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String name = ((Activity) context).getTitle().toString();
name = name.substring(1, name.indexOf("|") - 1);
Intent intent = new Intent(context, RecordTransactionActivity.class);
intent.putExtra("coin", name);
intent.putExtra("symbol", transaction.getSymbol());
intent.putExtra("transactionId", transaction.getTransactionId());
context.startActivity(intent);
}
});
setupSwipeView(convertView);
return convertView;
}
private void setupSwipeView(View view)
{
SwipeLayout swipeLayout = view.findViewById(R.id.swipeLayout);
//set show mode.
swipeLayout.setShowMode(SwipeLayout.ShowMode.LayDown);
//add drag edge.(If the BottomView has 'layout_gravity' attribute, this line is unnecessary)
swipeLayout.addDrag(SwipeLayout.DragEdge.Left, view.findViewById(R.id.bottom_wrapper));
swipeLayout.addSwipeListener(new SwipeLayout.SwipeListener() {
@Override
public void onClose(SwipeLayout layout) {
//when the SurfaceView totally cover the BottomView.
}
@Override
public void onUpdate(SwipeLayout layout, int leftOffset, int topOffset) {
//you are swiping.
}
@Override
public void onStartOpen(SwipeLayout layout) {
}
@Override
public void onOpen(SwipeLayout layout) {
//when the BottomView totally show.
}
@Override
public void onStartClose(SwipeLayout layout) {
}
@Override
public void onHandRelease(SwipeLayout layout, float xvel, float yvel) {
//when user's hand released.
}
});
}
}

View File

@ -4,16 +4,18 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v7.graphics.Palette;
import android.support.v7.widget.CardView;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import com.herbron.moodl.Activities.HomeActivity;
import com.herbron.moodl.DataManagers.CurrencyData.CurrencyDetailsList;
import com.herbron.moodl.DataManagers.InfoAPIManagers.CryptocompareApiManager;
import com.herbron.moodl.DataNotifiers.MoodlboxNotifierInterface;
import org.json.JSONException;
import org.json.JSONObject;
@ -206,40 +208,55 @@ public class MoodlBox {
}
}
public static void getBitmapFromURL(String src, String symbol, Resources resources, Context context, HomeActivity.IconCallBack callBack)
public static void getBitmapFromURL(String src, String symbol, Resources resources, Context context, MoodlboxNotifierInterface callBack)
{
String size = src.substring(src.lastIndexOf("=") + 1, src.length());
String filepath = context.getCacheDir() + "/" + symbol + "x" + size + ".png";
Bitmap result;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
result = BitmapFactory.decodeFile(filepath, options);
if(result == null)
if(src != null)
{
try {
java.net.URL url = new java.net.URL(src);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
result = BitmapFactory.decodeStream(input);
String size = src.substring(src.lastIndexOf("=") + 1, src.length());
String filepath = context.getCacheDir() + "/" + symbol + "x" + size + ".png";
FileOutputStream out = new FileOutputStream(filepath);
result.compress(Bitmap.CompressFormat.PNG, 100, out);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
} catch (IOException e) {
Log.d("moodl", "Error while downloading " + symbol + " icon > " + e.getMessage());
result = BitmapFactory.decodeResource(resources,
R.mipmap.ic_launcher_moodl);
result = Bitmap.createScaledBitmap(result, Integer.valueOf(size), Integer.valueOf(size), false);
result = BitmapFactory.decodeFile(filepath, options);
if(result == null)
{
try {
java.net.URL url = new java.net.URL(src);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
result = BitmapFactory.decodeStream(input);
FileOutputStream out = new FileOutputStream(filepath);
result.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (IOException e) {
Log.d("moodl", "Error while downloading " + symbol + " icon > " + e.getMessage());
Drawable defautlDrawable = resources.getDrawable(R.drawable.ic_panorama_fish_eye_24dp);
result = Bitmap.createBitmap(defautlDrawable.getIntrinsicWidth(), defautlDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
defautlDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
defautlDrawable.draw(canvas);
}
}
}
else
{
Log.d("moodl", "No URL for " + symbol);
Drawable defautlDrawable = resources.getDrawable(R.drawable.ic_panorama_fish_eye_24dp);
result = Bitmap.createBitmap(defautlDrawable.getIntrinsicWidth(), defautlDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
defautlDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
defautlDrawable.draw(canvas);
}
callBack.onSuccess(result);
callBack.onBitmapDownloaded(result);
}
public static int getColor(int id, Context context)
@ -274,9 +291,9 @@ public class MoodlBox {
return drawable;
}
public static String getIconUrl(String symbol, CurrencyDetailsList currencyDetailsList)
public static String getIconUrl(String symbol, CryptocompareApiManager cryptocompareApiManager)
{
return getIconUrl(symbol, 50, currencyDetailsList);
return getIconUrl(symbol, 50, cryptocompareApiManager);
}
public static float convertDpToPx(float dp, Resources resources)
@ -284,12 +301,12 @@ public class MoodlBox {
return dp * resources.getDisplayMetrics().density;
}
public static String getIconUrl(String symbol, int size, CurrencyDetailsList currencyDetailsList)
public static String getIconUrl(String symbol, int size, CryptocompareApiManager cryptocompareApiManager)
{
String url;
try {
JSONObject jsonObject = new JSONObject(currencyDetailsList.getCoinInfosHashmap().get(symbol));
JSONObject jsonObject = new JSONObject(cryptocompareApiManager.getCoinInfosHashmap().get(symbol));
url = "https://www.cryptocompare.com" + jsonObject.getString("ImageUrl") + "?width=" + size;
} catch (JSONException | NullPointerException e) {
url = null;
@ -297,4 +314,18 @@ public class MoodlBox {
return url;
}
public static int getIconDominantColor(Context context, Bitmap icon)
{
if(icon != null)
{
Palette.Builder builder = Palette.from(icon);
return builder.generate().getDominantColor(getColor(R.color.default_color, context));
}
else
{
return getColor(R.color.default_color, context);
}
}
}

View File

@ -1,12 +1,18 @@
package com.herbron.moodl;
package com.herbron.moodl.Utils;
import android.content.Context;
import com.herbron.moodl.DataManagers.PreferencesManager;
import com.herbron.moodl.R;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Tiji on 19/04/2018.
*/
public class PlaceholderManager {
public class PlaceholderUtils {
public static String getValueString(String value, android.content.Context context)
{
@ -32,7 +38,37 @@ public class PlaceholderManager {
return formattedString;
}
public static String getValuePercentageString(String value, String percentage, android.content.Context context)
public static List<String> getFeeOptionsForSymbol(String symbol, Context context)
{
List<String> options = new ArrayList<>();
options.add(context.getResources().getString(R.string.fixedFee, symbol));
options.add(context.getResources().getString(R.string.percentageFee, symbol));
return options;
}
public static String getPairString(String pair1, String pair2, Context context)
{
return context.getResources().getString(R.string.pairPlaceholder, pair1, pair2);
}
public static String getDenomination(String coinName, String coinSymbol, Context context)
{
return context.getResources().getString(R.string.denomincationPlaceholder, coinName, coinSymbol);
}
public static String getEditTransactionString(String coinName, Context context)
{
return context.getResources().getString(R.string.edit_transaction, coinName);
}
public static String getEmitedPercentageString(String percentage, Context context)
{
return context.getResources().getString(R.string.emitedPlaceholder, percentage);
}
public static String getValuePercentageString(String value, String percentage, Context context)
{
PreferencesManager preferencesManager = new PreferencesManager(context);
String formattedString = null;
@ -147,4 +183,24 @@ public class PlaceholderManager {
{
return context.getResources().getString(R.string.timestampPlaceholder, date);
}
public static String getToString(String to, android.content.Context context)
{
return context.getResources().getString(R.string.toPlaceholder, to);
}
public static String getFromString(String from, android.content.Context context)
{
return context.getResources().getString(R.string.fromPlaceholder, from);
}
public static String getFromToString(String from, String to, android.content.Context context)
{
return context.getResources().getString(R.string.fromToPlaceholder, from, to);
}
public static String getToPairString(String from, String to, Context context)
{
return context.getResources().getString(R.string.toPairPlaceholder, from, to);
}
}

View File

@ -0,0 +1,42 @@
package com.herbron.moodl.Utils;
import android.content.Context;
import com.herbron.moodl.Activities.RecordTransactionFragments.TransferFragment;
import com.herbron.moodl.R;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class TransferUtils {
public static boolean isBalanceRelated(String str)
{
Set<String> set = new HashSet<>(Arrays.asList(TransferFragment.EXCHANGE_CODE, TransferFragment.WALLET_CODE));
return set.contains(str);
}
public static String getLabelFor(Context context, String str)
{
switch (str)
{
case "stra:e":
return context.getResources().getStringArray(R.array.from_transfer_options_string_array)[0].toLowerCase();
case "stra:mw":
return context.getResources().getStringArray(R.array.from_transfer_options_string_array)[1].toLowerCase();
case "stra:m":
return context.getResources().getStringArray(R.array.from_transfer_options_string_array)[2].toLowerCase();
case "stra:smew":
return context.getResources().getStringArray(R.array.from_transfer_options_string_array)[3].toLowerCase();
case "stra:a":
return context.getResources().getStringArray(R.array.from_transfer_options_string_array)[4].toLowerCase();
case "stra:unk":
return context.getResources().getStringArray(R.array.from_transfer_options_string_array)[5].toLowerCase();
case "stra:fo":
return context.getResources().getStringArray(R.array.from_transfer_options_string_array)[6].toLowerCase();
}
return null;
}
}

View File

@ -0,0 +1,10 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false"
android:fillAfter="true">
<translate
android:fromXDelta="0%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="200%"
android:duration="400" />
</set>

View File

@ -0,0 +1,10 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false"
android:fillAfter="true">
<translate
android:fromXDelta="0%" android:toXDelta="0%"
android:fromYDelta="200%" android:toYDelta="0%"
android:duration="400"/>
</set>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/separationColor">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<solid android:color="@color/separationColor" />
<corners android:radius="2dp" />
</shape>
</item>
<item android:id="@android:id/background">
<shape android:shape="rectangle">
<solid android:color="@color/transparent"/>
<corners android:radius="2dp"/>
<stroke
android:color="@color/separationColor"
android:width="2dp"
android:dashGap="4dp"
android:dashWidth="9dp"/>
</shape>
</item>
</ripple>

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true">
<layer-list>
<item>
<shape android:shape="rectangle">
<solid android:color="@color/hardWhite"/>
<corners
android:topLeftRadius="5dp"
android:topRightRadius="5dp"/>
<padding
android:left="3dp"
android:right="3dp"
android:top="3dp"
android:bottom="3dp"/>
</shape>
</item>
<item
android:gravity="center_vertical|right"
android:drawable="@drawable/ic_arrow_drop_down_white_24dp"/>
</layer-list>
</item>
<item android:state_enabled="false">
<layer-list>
<item>
<shape android:shape="rectangle">
<solid android:color="@color/softWhite"/>
<corners
android:topLeftRadius="5dp"
android:topRightRadius="5dp"/>
<padding
android:left="3dp"
android:right="3dp"
android:top="3dp"
android:bottom="3dp"/>
</shape>
</item>
<item
android:gravity="center_vertical|right"
android:drawable="@drawable/ic_arrow_drop_down_white_24dp"/>
</layer-list>
</item>
</selector>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/separationColor"/>
<corners android:radius="5dp"/>
<padding
android:left="3dp"
android:right="3dp"
android:top="3dp"
android:bottom="3dp"/>
</shape>
</item>
</selector>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<item android:id="@android:id/background">
<shape android:shape="rectangle">
<solid android:color="@color/transparent"/>
<corners android:radius="2dp"/>

View File

@ -0,0 +1,27 @@
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:name="check"
android:pathData="M 9 16.17 L 4.83 12 L 3.41 13.41 L 9 19 L 21 7 L 19.59 5.59 Z"
android:fillColor="#FFFFFFFF"/>
</vector>
</aapt:attr>
<target android:name="check">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="pathData"
android:duration="200"
android:valueFrom="M 3.41 13.41 L 6.205 16.205 L 9 19 L 21 7 L 19.59 5.59 L 9 16.17 L 4.83 12 L 3.41 13.41 M 18.216 5.784 L 18.216 5.784 L 18.216 5.784 L 18.216 5.784 L 18.216 5.784 C 18.216 5.784 18.216 5.784 18.216 5.784 L 18.216 5.784 C 18.216 5.784 18.216 5.784 18.216 5.784"
android:valueTo="M 3 17.25 L 3 21 L 6.75 21 L 17.81 9.94 L 14.06 6.19 L 8.53 11.72 L 3 17.25 L 3 17.25 M 20.71 7.04 L 20.71 7.04 L 18.88 8.87 L 15.13 5.12 L 16.96 3.29 C 17.35 2.9 17.98 2.9 18.37 3.29 L 20.71 5.63 C 21.1 6.02 21.1 6.65 20.71 7.04"
android:valueType="pathType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
</animated-vector>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/softWhite"/>
<corners
android:topLeftRadius="5dp"
android:topRightRadius="5dp"/>
<padding
android:left="3dp"
android:right="3dp"
android:top="3dp"
android:bottom="3dp"/>
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,28 @@
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:name="edit"
android:pathData="M 3 17.25 L 3 21 L 6.75 21 L 17.81 9.94 L 14.06 6.19 L 3 17.25 Z M 20.71 7.04 C 21.1 6.65 21.1 6.02 20.71 5.63 L 18.37 3.29 C 17.98 2.9 17.35 2.9 16.96 3.29 L 15.13 5.12 L 18.88 8.87 L 20.71 7.04 Z"
android:fillColor="#FFFFFFFF"/>
</vector>
</aapt:attr>
<target android:name="edit">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="pathData"
android:duration="200"
android:valueFrom="M 3 17.25 L 3 17.25 L 3 21 L 6.75 21 L 17.81 9.94 L 14.06 6.19 L 3 17.25 M 20.71 5.63 L 18.37 3.29 C 17.98 2.9 17.35 2.9 16.96 3.29 L 15.13 5.12 L 18.88 8.87 L 20.71 7.04 L 20.71 7.04 C 21.1 6.65 21.1 6.02 20.71 5.63"
android:valueTo="M 9 16.17 L 4.83 12 L 3.41 13.41 L 9 19 L 21 7 L 19.59 5.59 L 9 16.17 M 18.216 5.784 L 18.216 5.784 C 18.216 5.784 18.216 5.784 18.216 5.784 L 18.216 5.784 L 18.216 5.784 L 18.216 5.784 L 18.216 5.784 C 18.216 5.784 18.216 5.784 18.216 5.784"
android:valueType="pathType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
</animated-vector>

View File

@ -0,0 +1,13 @@
<vector android:height="24dp" android:viewportHeight="2000"
android:viewportWidth="2000" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#f3ba2e"
android:pathData="M953,1986c-13,-7 -149,-139 -303,-294 -199,-201 -280,-289 -280,-304 0,-16 39,-61 120,-143l121,-121 194,195 195,196 195,-196 194,-195 127,127c69,69 124,133 122,140 -1,8 -139,148 -304,312 -321,317 -321,316 -381,283z" android:strokeColor="#00000000"/>
<path android:fillColor="#f3ba2e"
android:pathData="M117,1157c-51,-51 -98,-103 -105,-115 -14,-26 -16,-82 -2,-82 6,0 10,-5 10,-11 0,-15 185,-199 201,-199 18,0 254,232 254,250 0,18 -236,250 -254,250 -7,0 -54,-42 -104,-93z" android:strokeColor="#00000000"/>
<path android:fillColor="#f3ba2e"
android:pathData="M867,1132c-64,-64 -117,-124 -117,-132 0,-20 231,-250 250,-250 20,0 250,231 250,250 0,20 -231,250 -250,250 -9,0 -68,-53 -133,-118z" android:strokeColor="#00000000"/>
<path android:fillColor="#f3ba2e"
android:pathData="M1638,1125l-127,-125 125,-123c70,-67 132,-122 139,-122 8,0 56,41 107,92 157,154 157,151 0,306 -51,51 -98,93 -105,94 -7,2 -69,-53 -139,-122z" android:strokeColor="#00000000"/>
<path android:fillColor="#f3ba2e"
android:pathData="M490,755c-81,-82 -120,-127 -120,-143 0,-15 82,-105 283,-307 156,-157 289,-285 295,-285 7,0 12,-4 12,-10 0,-5 20,-10 45,-10 25,0 44,3 43,8 -1,4 131,137 293,297 161,160 295,296 297,304 2,7 -53,71 -122,140l-127,127 -194,-195 -195,-196 -195,196 -194,195 -121,-121z" android:strokeColor="#00000000"/>
</vector>

View File

@ -0,0 +1,23 @@
<vector android:height="24dp" android:viewportHeight="1950"
android:viewportWidth="1950" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#0072a0"
android:pathData="M656,1510l-208,-370 -224,-127c-124,-70 -223,-131 -221,-137 2,-5 160,-107 351,-226l348,-216 251,32c139,18 252,32 253,31 1,-1 13,-21 27,-43 21,-34 46,-52 131,-97 102,-54 107,-56 223,-66 192,-18 172,-9 270,-128 48,-58 89,-100 91,-93 2,6 -4,61 -13,121l-18,109 -151,87c-145,83 -154,91 -228,179l-78,93 95,157c52,87 93,159 91,161 -2,2 -98,-31 -189,-66l-28,-11 25,43 25,42 72,5 72,5 53,200c29,110 54,201 54,202 0,1 -21,5 -46,9l-46,7 36,20c20,12 36,23 36,26 -1,9 -271,176 -289,179 -10,1 -91,-77 -201,-192 -102,-107 -188,-192 -191,-188 -4,4 -35,126 -69,272 -81,348 -81,350 -89,350 -4,0 -101,-166 -215,-370z" android:strokeColor="#00000000"/>
<path android:fillColor="#008ebf"
android:pathData="M1231,1225c-101,-228 -187,-415 -191,-415 -4,0 -53,77 -110,171l-103,171 -191,-7 -191,-7 -223,-126c-122,-69 -221,-130 -219,-136 2,-5 160,-107 351,-226l348,-216 251,32c139,18 252,32 253,31 1,-1 13,-21 27,-43 21,-34 46,-52 131,-97 102,-54 107,-56 223,-66 192,-18 172,-9 270,-128 48,-58 89,-100 91,-93 2,6 -4,61 -13,121l-18,109 -151,87c-145,83 -154,91 -228,179l-78,93 95,157c52,87 93,159 91,161 -2,2 -16,-1 -32,-8 -16,-6 -64,-24 -107,-39l-77,-29 25,42 24,42 72,5 72,5 53,200c29,110 54,201 54,202 0,1 -24,5 -52,9 -58,8 -63,11 -193,157l-70,77 -184,-415z" android:strokeColor="#00000000"/>
<path android:fillColor="#57bbe6"
android:pathData="M1420,1263c0,-197 -4,-364 -8,-370 -4,-7 -83,-31 -175,-53l-167,-40 -225,0c-124,0 -225,3 -225,6 0,3 45,80 100,170 55,90 100,166 100,168 0,3 -33,3 -72,0 -40,-2 -127,-6 -193,-7l-120,-4 -218,-123c-119,-68 -216,-128 -214,-134 2,-5 160,-107 351,-226l348,-216 251,32c139,18 252,32 253,31 1,-1 13,-21 27,-43 21,-34 46,-52 131,-97 102,-54 107,-56 223,-66 192,-18 172,-9 270,-128 48,-58 89,-100 91,-93 2,6 -4,61 -13,121l-18,109 -151,87c-145,83 -154,91 -228,179l-78,93 95,157c52,87 93,159 91,161 -2,2 -98,-31 -189,-66l-28,-11 25,43 25,42 72,5 72,5 53,200c29,110 51,201 49,203 -1,2 -28,6 -58,9l-56,6 -91,103c-51,57 -94,104 -96,104 -2,0 -4,-161 -4,-357z" android:strokeColor="#00000000"/>
<path android:fillColor="#15a6db"
android:pathData="M1421,1270c0,-195 3,-350 5,-345 2,6 46,116 98,245l93,235 -48,55c-26,30 -70,80 -98,110l-50,55 0,-355z" android:strokeColor="#00000000"/>
<path android:fillColor="#15a6db"
android:pathData="M1625,1233c-49,-81 -103,-169 -119,-195l-28,-49 72,3 73,3 49,184c26,102 47,188 46,193 -2,4 -43,-58 -93,-139z" android:strokeColor="#00000000"/>
<path android:fillColor="#15a6db"
android:pathData="M779,1146c-2,-2 -78,-5 -169,-7 -174,-3 -171,-2 -265,-60 -16,-11 -41,-24 -55,-31 -14,-7 -28,-17 -32,-23 -4,-5 -8,-6 -8,-2 0,5 -12,-1 -26,-12 -15,-12 -31,-21 -36,-21 -5,0 -33,-15 -61,-34 -29,-18 -69,-41 -90,-51 -21,-10 -36,-19 -34,-21 4,-4 610,-85 612,-81 15,21 205,339 205,342 0,6 -35,7 -41,1z" android:strokeColor="#00000000"/>
<path android:fillColor="#15a6db"
android:pathData="M1524,937c-79,-30 -109,-46 -106,-56 3,-8 0,-11 -6,-7 -8,5 -309,-61 -359,-79 -8,-3 17,-54 68,-140 45,-75 80,-137 78,-139 -2,-2 -132,59 -288,135 -157,76 -287,137 -289,134 -3,-2 15,-82 39,-178l43,-173 250,32c189,25 253,30 259,21 4,-7 15,-25 23,-40 8,-16 19,-27 24,-25 4,2 49,54 98,116 68,85 92,108 96,95 3,-10 8,-89 12,-176 4,-86 10,-157 14,-157 16,0 217,-20 254,-25l40,-6 -20,23 -19,23 22,-19c12,-10 21,-21 20,-25 -1,-3 36,-53 83,-110 46,-57 86,-98 88,-91 3,7 -4,61 -13,121l-18,109 -147,85c-81,47 -151,85 -155,85 -4,0 -1,-8 6,-17 13,-16 12,-17 -4,-4 -9,7 -16,19 -15,25 2,6 -30,50 -70,98l-72,87 84,140c102,169 109,181 99,180 -4,0 -58,-19 -119,-42z" android:strokeColor="#00000000"/>
<path android:fillColor="#7bcff4"
android:pathData="M1625,1233c-49,-81 -103,-169 -119,-195l-28,-49 73,3 72,3 48,185c27,102 48,188 46,192 -1,4 -42,-58 -92,-139z" android:strokeColor="#00000000"/>
<path android:fillColor="#7bcff4"
android:pathData="M1528,938c-124,-46 -118,-34 -92,-182 8,-48 13,-90 11,-92 -2,-2 -91,25 -197,61 -107,36 -198,65 -202,65 -3,0 30,-61 74,-136 44,-74 79,-136 77,-138 -2,-2 -132,59 -288,135 -157,76 -287,137 -289,134 -3,-2 15,-82 39,-178l43,-173 216,28c118,15 232,30 252,33 36,5 39,3 58,-36 12,-22 25,-39 30,-37 4,2 49,54 98,116 68,85 92,108 96,95 3,-10 8,-89 12,-176 4,-86 10,-157 14,-157 18,0 229,-21 258,-26 27,-4 48,-24 119,-110 47,-57 88,-102 91,-100 10,10 -30,234 -42,230 -6,-2 -39,-8 -73,-12l-62,-9 -83,96c-46,53 -83,100 -83,106 0,6 -33,49 -73,97l-73,86 85,140c102,170 109,182 99,181 -4,0 -56,-19 -115,-41z" android:strokeColor="#00000000"/>
<path android:fillColor="#8cdbff"
android:pathData="M1531,939c-58,-21 -107,-41 -109,-44 -3,-2 3,-57 13,-121 14,-93 20,-113 30,-102 9,10 156,252 182,301 7,11 -6,8 -116,-34z" android:strokeColor="#00000000"/>
</vector>

View File

@ -1,7 +1,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<gradient
android:type="linear"
android:startColor="@color/colorPrimary"
android:endColor="@color/colorPrimaryDark"
android:startColor="@color/colorPrimaryDark"
android:endColor="@color/colorPrimary"
android:angle="0"/>
</shape>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#010101" android:pathData="M20,12l-1.41,-1.41L13,16.17V4h-2v12.17l-5.58,-5.59L4,12l8,8 8,-8z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="@color/separationColor"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M7,10l5,5 5,-5z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M7,10l5,5 5,-5z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="@color/separationColor"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M7,14l5,-5 5,5z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M7,14l5,-5 5,5z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M4,12l1.41,1.41L11,7.83V20h2V7.83l5.58,5.59L20,12l-8,-8 -8,8z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="@color/error"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@color/colorPrimary"
android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
</vector>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/summary_background"/>
<corners android:topLeftRadius="10dp"
android:topRightRadius="10dp"/>
</shape>
</item>
</selector>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:angle="-90"
android:centerY="2%"
android:startColor="@color/increaseCandle"
android:centerColor="@color/white"
android:endColor="@color/white"
android:type="linear"/>
</shape>
</item>
</selector>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:angle="-90"
android:centerY="2%"
android:startColor="@color/decreaseCandle"
android:centerColor="@color/white"
android:endColor="@color/white"
android:type="linear"/>
</shape>
</item>
</selector>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:angle="-90"
android:centerY="2%"
android:startColor="@color/blue"
android:centerColor="@color/white"
android:endColor="@color/white"
android:type="linear"/>
</shape>
</item>
</selector>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/increaseCandle"/>
<corners
android:topLeftRadius="5dp"
android:topRightRadius="5dp"/>
<padding
android:left="3dp"
android:right="3dp"
android:top="3dp"
android:bottom="3dp"/>
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/decreaseCandle"/>
<corners
android:topLeftRadius="5dp"
android:topRightRadius="5dp"/>
<padding
android:left="3dp"
android:right="3dp"
android:top="3dp"
android:bottom="3dp"/>
</shape>
</item>
</layer-list>

Some files were not shown because too many files have changed in this diff Show More