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)
This commit is contained in:
Tanguy Herbron 2018-07-21 14:56:26 +02:00
parent b53d52daeb
commit 7f1a318a70
15 changed files with 408 additions and 205 deletions

Binary file not shown.

2
.idea/gradle.xml generated
View File

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

View File

@ -129,6 +129,10 @@ public class HomeActivity extends AppCompatActivity implements BalanceUpdateInte
{ {
Switch balanceSwitch = findViewById(R.id.switchHideBalance); Switch balanceSwitch = findViewById(R.id.switchHideBalance);
PreferencesManager preferencesManager = new PreferencesManager(getBaseContext());
balanceSwitch.setChecked(preferencesManager.isBalanceHidden());
balanceSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { balanceSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) { public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

View File

@ -57,6 +57,8 @@ public class Overview extends Fragment {
currencyTickerList = CurrencyTickerList.getInstance(getContext()); currencyTickerList = CurrencyTickerList.getInstance(getContext());
currencyDetailsList = CurrencyDetailsList.getInstance(getContext()); currencyDetailsList = CurrencyDetailsList.getInstance(getContext());
fragmentView.findViewById(R.id.toolbar).bringToFront();
preferenceManager = new PreferencesManager(getContext()); preferenceManager = new PreferencesManager(getContext());
listLayout = fragmentView.findViewById(R.id.linearLayoutOverview); listLayout = fragmentView.findViewById(R.id.linearLayoutOverview);

View File

@ -6,7 +6,6 @@ import android.app.AlertDialog;
import android.app.KeyguardManager; import android.app.KeyguardManager;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
@ -34,7 +33,9 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.ExpandableListView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import com.applandeo.FilePicker; import com.applandeo.FilePicker;
import com.applandeo.listeners.OnSelectFileListener; import com.applandeo.listeners.OnSelectFileListener;
@ -66,10 +67,11 @@ import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.regex.Pattern;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.KeyGenerator; import javax.crypto.KeyGenerator;
@ -421,15 +423,17 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_export_data, null, true); View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_export_data, null, true);
dialogBuilder.setView(dialogView); 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)); File backupDirectory = new File(Environment.getExternalStorageDirectory(), getString(R.string.app_name));
if (!backupDirectory.exists()) { createDefaultBackupDirectory(backupDirectory);
if (!backupDirectory.mkdirs()) {
Log.d("moodl", "Error while creating directory");
}
}
final TextView textViewFilePath = dialogView.findViewById(R.id.textViewFilePath);
textViewFilePath.setText(backupDirectory.getAbsolutePath()); textViewFilePath.setText(backupDirectory.getAbsolutePath());
textViewFilePath.setOnClickListener(new View.OnClickListener() { textViewFilePath.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -447,9 +451,6 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
} }
}); });
final CheckBox enterPasswordCheckbox = dialogView.findViewById(R.id.checkboxEnterPassword);
final TextInputLayout textInputLayoutPassword = dialogView.findViewById(R.id.textInputLayoutPassword);
enterPasswordCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { enterPasswordCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) { public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
@ -476,9 +477,16 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
DatabaseManager databaseManager = new DatabaseManager(getContext()); DatabaseManager databaseManager = new DatabaseManager(getContext());
if(enterPasswordCheckbox.isChecked()) if(enterPasswordCheckbox.isChecked())
{
if(textInputLayoutPassword.getEditText().getText().equals(""))
{
textInputLayoutPassword.setError(getString(R.string.must_be_filled));
}
else
{ {
DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString()); DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString());
} }
}
File backupFile = new File(textViewFilePath.getText() + "/" + fileName); File backupFile = new File(textViewFilePath.getText() + "/" + fileName);
@ -487,15 +495,31 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
try { try {
JSONObject backupJson = new JSONObject(); JSONObject backupJson = new JSONObject();
if(enterPasswordCheckbox.isChecked()) initiateJsonBackup(backupJson, enterPasswordCheckbox.isChecked());
if(backupManualEntriesCheckbox.isChecked())
{ {
backupJson.put("encodeChecker", DataCrypter.encrypt(getContext(), "NaukVerification")); backupJson.put("transactions",
databaseManager.getDatabaseBackup(getContext(),
DatabaseManager.TABLE_MANUAL_CURRENCIES,
enterPasswordCheckbox.isChecked()));
} }
else
if(backupWatchlistCheckbox.isChecked())
{ {
backupJson.put("encodeChecker", "NaukVerification"); backupJson.put("watchlist",
databaseManager.getDatabaseBackup(getContext(),
DatabaseManager.TABLE_WATCHLIST,
enterPasswordCheckbox.isChecked()));
}
if(backupKeysCheckbox.isChecked())
{
backupJson.put("apiKeys",
databaseManager.getDatabaseBackup(getContext(),
DatabaseManager.TABLE_EXCHANGE_KEYS,
enterPasswordCheckbox.isChecked()));
} }
backupJson.put("transactions", databaseManager.getBackupData(getContext(),enterPasswordCheckbox.isChecked()));
printWriter.write(backupJson.toString()); printWriter.write(backupJson.toString());
} catch (JSONException e) { } catch (JSONException e) {
@ -510,6 +534,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
dialog.dismiss(); dialog.dismiss();
} }
}); });
dialogBuilder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { dialogBuilder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) { public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss(); dialog.dismiss();
@ -532,17 +557,78 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_import_data, null, true); View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_import_data, null, true);
dialogBuilder.setView(dialogView); 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)); File backupDirectory = new File(Environment.getExternalStorageDirectory(), getString(R.string.app_name));
if(!backupDirectory.exists()) createDefaultBackupDirectory(backupDirectory);
{
if(!backupDirectory.mkdirs())
{
Log.d("moodl", "Error while creating directory");
}
}
final TextView textViewFilePath = dialogView.findViewById(R.id.textViewFilePath);
textViewFilePath.setText(backupDirectory.getAbsolutePath()); textViewFilePath.setText(backupDirectory.getAbsolutePath());
textViewFilePath.setOnClickListener(new View.OnClickListener() { textViewFilePath.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -559,10 +645,6 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
} }
}); });
final CheckBox enterPasswordCheckbox = dialogView.findViewById(R.id.checkboxEnterPassword);
final CheckBox wipeCheckbox = dialogView.findViewById(R.id.checkboxWipeData);
final TextInputLayout textInputLayoutPassword = dialogView.findViewById(R.id.textInputLayoutPassword);
dialogBuilder.setTitle(getString(R.string.restoreBackup)); dialogBuilder.setTitle(getString(R.string.restoreBackup));
dialogBuilder.setPositiveButton(getString(R.string.confirm), new DialogInterface.OnClickListener() { dialogBuilder.setPositiveButton(getString(R.string.confirm), new DialogInterface.OnClickListener() {
@Override @Override
@ -577,11 +659,6 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString()); DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString());
} }
if(wipeCheckbox.isChecked())
{
databaseManager.wipeTransactions();
}
File backupFile = new File(textViewFilePath.getText().toString()); File backupFile = new File(textViewFilePath.getText().toString());
try { try {
@ -609,6 +686,15 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
} }
if(checker.equals("NaukVerification")) if(checker.equals("NaukVerification"))
{
if(restoreManualEntriesCheckbox.isChecked())
{
if(wipeManualEntriesCheckbox.isChecked())
{
databaseManager.wipeData(DatabaseManager.TABLE_MANUAL_CURRENCIES);
}
if(backupJson.has("transactions"))
{ {
JSONArray transactionsArray = backupJson.getJSONArray("transactions"); JSONArray transactionsArray = backupJson.getJSONArray("transactions");
@ -619,6 +705,28 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
databaseManager.addRowTransaction(transactionObject, getContext(), enterPasswordCheckbox.isChecked()); databaseManager.addRowTransaction(transactionObject, getContext(), 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 transactionObject = watchlistArray.getJSONObject(i);
databaseManager.addRowWatchlist(transactionObject, getContext(), enterPasswordCheckbox.isChecked());
}
}
}
}
else else
{ {
textInputLayoutPassword.setError(getString(R.string.wrong_password)); textInputLayoutPassword.setError(getString(R.string.wrong_password));
@ -653,6 +761,27 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
editTextPreference.setNegativeButtonText(getString(R.string.cancel)); editTextPreference.setNegativeButtonText(getString(R.string.cancel));
} }
private void initiateJsonBackup(JSONObject backupJson, boolean mustEncrypt) throws JSONException
{
if(mustEncrypt)
{
backupJson.put("encodeChecker", DataCrypter.encrypt(getContext(), "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() { private boolean checkPermissions() {
String[] permissions = new String[]{ String[] permissions = new String[]{

View File

@ -24,13 +24,13 @@ import java.util.List;
public class DatabaseManager extends SQLiteOpenHelper{ public class DatabaseManager extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 6; private static final int DATABASE_VERSION = 7;
private static final String DATABASE_NAME = "Currencies.db"; private static final String DATABASE_NAME = "Currencies.db";
private static final String TABLE_MANUAL_CURRENCIES = "ManualCurrencies"; public static final String TABLE_MANUAL_CURRENCIES = "ManualCurrencies";
private static final String TABLE_EXCHANGE_KEYS = "ExchangeKeys"; public static final String TABLE_EXCHANGE_KEYS = "ExchangeKeys";
private static final String TABLE_WATCHLIST = "Watchlist"; public static final String TABLE_WATCHLIST = "Watchlist";
private static final String KEY_CURRENCY_ID = "idCurrency"; private static final String KEY_CURRENCY_ID = "idCurrency";
private static final String KEY_CURRENCY_SYMBOL = "symbol"; private static final String KEY_CURRENCY_SYMBOL = "symbol";
@ -43,6 +43,7 @@ public class DatabaseManager extends SQLiteOpenHelper{
private static final String KEY_EXCHANGE_ID = "idExchange"; private static final String KEY_EXCHANGE_ID = "idExchange";
private static final String KEY_EXCHANGE_NAME = "name"; private static final String KEY_EXCHANGE_NAME = "name";
private static final String KEY_EXCHANGE_DESCRIPTION = "description";
private static final String KEY_EXCHANGE_PUBLIC_KEY = "publicKey"; private static final String KEY_EXCHANGE_PUBLIC_KEY = "publicKey";
private static final String KEY_EXCHANGE_SECRET_KEY = "secretKey"; private static final String KEY_EXCHANGE_SECRET_KEY = "secretKey";
@ -73,6 +74,7 @@ public class DatabaseManager extends SQLiteOpenHelper{
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_EXCHANGE_KEYS + "(" db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_EXCHANGE_KEYS + "("
+ KEY_EXCHANGE_ID + " INTEGER PRIMARY KEY," + KEY_EXCHANGE_ID + " INTEGER PRIMARY KEY,"
+ KEY_EXCHANGE_NAME + " TEXT," + KEY_EXCHANGE_NAME + " TEXT,"
+ KEY_EXCHANGE_DESCRIPTION + " TEXT,"
+ KEY_EXCHANGE_PUBLIC_KEY + " TEXT," + KEY_EXCHANGE_PUBLIC_KEY + " TEXT,"
+ KEY_EXCHANGE_SECRET_KEY + " TEXT" + KEY_EXCHANGE_SECRET_KEY + " TEXT"
+ ");"); + ");");
@ -90,11 +92,12 @@ public class DatabaseManager extends SQLiteOpenHelper{
@Override @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{ {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_MANUAL_CURRENCIES); switch (oldVersion)
db.execSQL("DROP TABLE IF EXISTS " + TABLE_EXCHANGE_KEYS); {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_WATCHLIST); case 6:
db.execSQL("ALTER TABLE " + TABLE_EXCHANGE_KEYS
onCreate(db); + " ADD " + KEY_EXCHANGE_DESCRIPTION+ " VARCHAR");
}
} }
private boolean isCurrencyInWatchlist(String symbol) private boolean isCurrencyInWatchlist(String symbol)
@ -157,17 +160,17 @@ public class DatabaseManager extends SQLiteOpenHelper{
db.close(); db.close();
} }
public JSONArray getBackupData(Context context, boolean encryptData) public JSONArray getDatabaseBackup(Context context, String table, boolean encryptData)
{ {
String selectQuerry = "SELECT * FROM " + TABLE_MANUAL_CURRENCIES; String selectQuerry = "SELECT * FROM " + table;
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
Cursor result = db.rawQuery(selectQuerry, null); Cursor result = db.rawQuery(selectQuerry, null);
JSONArray transactionsArray = new JSONArray(); JSONArray backupArray = new JSONArray();
while(result.moveToNext()) while(result.moveToNext())
{ {
JSONObject transactionJson = new JSONObject(); JSONObject backupObject = new JSONObject();
for(int i = 0; i < result.getColumnCount(); i++) for(int i = 0; i < result.getColumnCount(); i++)
{ {
@ -176,32 +179,58 @@ public class DatabaseManager extends SQLiteOpenHelper{
{ {
if(encryptData) if(encryptData)
{ {
transactionJson.put(result.getColumnName(i), DataCrypter.encrypt(context, result.getString(i))); backupObject.put(result.getColumnName(i), DataCrypter.encrypt(context, result.getString(i)));
} }
else else
{ {
transactionJson.put(result.getColumnName(i), result.getString(i)); backupObject.put(result.getColumnName(i), result.getString(i));
} }
} }
else else
{ {
transactionJson.put(result.getColumnName(i), ""); backupObject.put(result.getColumnName(i), "");
} }
} catch (JSONException e) { } catch (JSONException e) {
Log.d("moodl", "Error while creating a json transaction"); Log.d("moodl", "Error while creating a json backup");
} }
} }
transactionsArray.put(transactionJson); backupArray.put(backupObject);
} }
return transactionsArray; return backupArray;
} }
public void wipeTransactions() public void wipeData(String table)
{ {
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DELETE FROM "+ TABLE_MANUAL_CURRENCIES); db.execSQL("DELETE FROM "+ table);
}
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 transaction");
}
db.insert(TABLE_MANUAL_CURRENCIES, null, values);
db.close();
} }
public void addRowTransaction(JSONObject rawValues, Context context, boolean decrypt) public void addRowTransaction(JSONObject rawValues, Context context, boolean decrypt)

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

@ -13,35 +13,31 @@
android:id="@+id/textViewFilePath" android:id="@+id/textViewFilePath"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Click to select"
android:background="@drawable/background_filepath"/> android:background="@drawable/background_filepath"/>
<CheckBox <CheckBox
android:id="@+id/checkboxWipeData" android:id="@+id/checkboxBackupManualEntries"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/wipe_data" android:text="@string/backup_manual_entries" />
android:enabled="false" />
<CheckBox <CheckBox
android:id="@+id/checkboxRestoreEntries" android:id="@+id/checkboxBackupWatchlist"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/restore_manual_entries" android:text="@string/backup_watchlist" />
android:enabled="false" />
<CheckBox <CheckBox
android:id="@+id/checkboxRestoreKeys" android:id="@+id/checkboxBackupKeys"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/restore_keys" android:text="@string/backup_keys" />
android:enabled="false" />
<CheckBox <CheckBox
android:id="@+id/checkboxEnterPassword" android:id="@+id/checkboxEnterPassword"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/enter_password"/> android:text="@string/enter_password" />
<android.support.design.widget.TextInputLayout <android.support.design.widget.TextInputLayout
android:id="@+id/textInputLayoutPassword" android:id="@+id/textInputLayoutPassword"

View File

@ -13,28 +13,49 @@
android:id="@+id/textViewFilePath" android:id="@+id/textViewFilePath"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="Click to select"
android:background="@drawable/background_filepath"/> android:background="@drawable/background_filepath"/>
<CheckBox
android:id="@+id/checkboxWipeData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wipe_data"/>
<CheckBox <CheckBox
android:id="@+id/checkboxRestoreEntries" android:id="@+id/checkboxRestoreEntries"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/restore_manual_entries" android:text="@string/restore_manual_entries"/>
android:enabled="false" />
<CheckBox
android:id="@+id/checkboxWipeManualEntries"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wipe_manual_entries"
android:layout_marginStart="10dp"
android:visibility="gone"/>
<CheckBox
android:id="@+id/checkboxRestoreWatchlist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/restore_watchlist"/>
<CheckBox
android:id="@+id/checkboxWipeWatchlist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wipe_watchlist"
android:layout_marginStart="10dp"
android:visibility="gone"/>
<CheckBox <CheckBox
android:id="@+id/checkboxRestoreKeys" android:id="@+id/checkboxRestoreKeys"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/restore_keys" android:text="@string/restore_keys"/>
android:enabled="false" />
<CheckBox
android:id="@+id/checkboxWipeAPIKeys"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wipe_api_keys"
android:layout_marginStart="10dp"
android:visibility="gone"/>
<CheckBox <CheckBox
android:id="@+id/checkboxEnterPassword" android:id="@+id/checkboxEnterPassword"

View File

@ -4,16 +4,13 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/gradient_background">
<android.support.v7.widget.Toolbar <android.support.v7.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"> android:background="@drawable/gradient_background"
app:layout_collapseMode="pin"
app:elevation="0dp">
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -45,21 +42,20 @@
</android.support.v7.widget.Toolbar> </android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout <android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swiperefreshmarketcap" android:id="@+id/swiperefreshmarketcap"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" android:layout_marginTop="?attr/actionBarSize"
app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:background="@color/summary_background"> android:background="@drawable/gradient_background">
<LinearLayout android:id="@+id/layoutMarketCap" <LinearLayout android:id="@+id/layoutMarketCap"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:paddingTop="20dp"> android:paddingTop="20dp"
android:background="@drawable/list_background">
<ProgressBar <ProgressBar
android:id="@+id/progressBarMarketCap" android:id="@+id/progressBarMarketCap"

View File

@ -4,15 +4,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/gradient_background">
<android.support.v7.widget.Toolbar <android.support.v7.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:background="@drawable/gradient_background"
app:layout_collapseMode="pin"> app:layout_collapseMode="pin">
<FrameLayout <FrameLayout
@ -45,13 +41,11 @@
</android.support.v7.widget.Toolbar> </android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize" android:layout_marginTop="?attr/actionBarSize"
android:background="@color/summary_background"> android:background="@drawable/gradient_background">
<ListView android:id="@+id/linearLayoutOverview" <ListView android:id="@+id/linearLayoutOverview"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -61,7 +55,8 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:divider="@null" android:divider="@null"
android:dividerHeight="0dp" android:dividerHeight="0dp"
android:clipChildren="false"/> android:clipChildren="false"
android:background="@drawable/list_background"/>
</LinearLayout> </LinearLayout>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>

View File

@ -5,14 +5,16 @@
android:id="@+id/coordinatorLayout" android:id="@+id/coordinatorLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.herbron.moodl.Activities.HomeActivity"> tools:context="com.herbron.moodl.Activities.HomeActivity"
android:background="@drawable/gradient_background">
<android.support.design.widget.AppBarLayout <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar" android:id="@+id/app_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/app_bar_height" android:layout_height="@dimen/app_bar_height"
android:theme="@style/AppTheme.AppBarOverlay" android:theme="@style/AppTheme.AppBarOverlay"
android:background="@drawable/gradient_background"> android:background="@drawable/gradient_background"
app:elevation="0dp">
<android.support.design.widget.CollapsingToolbarLayout <android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout" android:id="@+id/toolbar_layout"
@ -70,13 +72,13 @@
android:id="@+id/swiperefreshsummary" android:id="@+id/swiperefreshsummary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:background="@color/summary_background">
<android.support.v4.widget.NestedScrollView <android.support.v4.widget.NestedScrollView
android:id="@+id/nestedScrollViewLayout" android:id="@+id/nestedScrollViewLayout"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:background="@drawable/list_background">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -4,16 +4,13 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/gradient_background">
<android.support.v7.widget.Toolbar <android.support.v7.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"> android:background="@drawable/gradient_background"
app:layout_collapseMode="pin"
app:elevation="0dp">
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -55,20 +52,19 @@
</android.support.v7.widget.Toolbar> </android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout <android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swiperefreshwatchlist" android:id="@+id/swiperefreshwatchlist"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" android:layout_marginTop="?attr/actionBarSize"
app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:background="@color/summary_background"> android:background="@drawable/gradient_background">
<android.support.v4.widget.NestedScrollView <android.support.v4.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:overScrollMode="never"> android:overScrollMode="never"
android:background="@drawable/list_background">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -131,4 +131,12 @@
<string name="wrong_password">Mauvais mot de passe</string> <string name="wrong_password">Mauvais mot de passe</string>
<string name="error">Erreur</string> <string name="error">Erreur</string>
<string name="wrong_fingerprint">Mauvaise empreinte digitale</string> <string name="wrong_fingerprint">Mauvaise empreinte digitale</string>
<string name="backup_manual_entries">Sauvegarder les entrées manuelles</string>
<string name="backup_watchlist">Sauvegarder la liste suivie</string>
<string name="backup_keys">Sauvegarder les clefs API</string>
<string name="must_be_filled">Ne peut pas être vide</string>
<string name="restore_watchlist">Restaurer la liste suivie</string>
<string name="wipe_manual_entries">Supprimer les entrées manuelles actuelles</string>
<string name="wipe_watchlist">Supprimer la liste suivie actuelle</string>
<string name="wipe_api_keys">Supprimer les clefs API actuelles</string>
</resources> </resources>

View File

@ -151,6 +151,12 @@
<item>1 year</item> <item>1 year</item>
</string-array> </string-array>
<string-array name="wipe_options_string_array">
<item>Manual entries</item>
<item>Watchlist</item>
<item>API keys</item>
</string-array>
<!--Cardview placeholders--> <!--Cardview placeholders-->
<string name="currencySymbolPlaceholder" translatable="false">(%1$s)</string> <string name="currencySymbolPlaceholder" translatable="false">(%1$s)</string>
<string name="currencyBalancePlaceholder" translatable="false">%1$s%2$s</string> <string name="currencyBalancePlaceholder" translatable="false">%1$s%2$s</string>
@ -235,5 +241,13 @@
<string name="wrong_password">Wrong password</string> <string name="wrong_password">Wrong password</string>
<string name="error">Error</string> <string name="error">Error</string>
<string name="wrong_fingerprint">Wrong fingerprint</string> <string name="wrong_fingerprint">Wrong fingerprint</string>
<string name="backup_manual_entries">Backup manual entries</string>
<string name="backup_watchlist">Backup watchlist</string>
<string name="backup_keys">Backup API keys</string>
<string name="must_be_filled">Cannot be blank</string>
<string name="restore_watchlist">Restore watchlist</string>
<string name="wipe_manual_entries">Wipe current entries</string>
<string name="wipe_watchlist">Wipe current watchlist</string>
<string name="wipe_api_keys">Wipe current API keys</string>
</resources> </resources>