From 03f4b26e2a4a62ff67e6779de52c716738ac87b1 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Wed, 5 Sep 2018 21:03:08 +0200 Subject: [PATCH 01/33] Raise gradle version. --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 1535c90..c01ba83 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' + classpath 'com.android.tools.build:gradle:3.1.4' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.6.2' } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a9609a0..0948dc9 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Nov 29 19:03:06 EET 2017 +#Wed Sep 05 21:01:23 CEST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip From 602d8758087b1209a3540c83ca7b84b44dfda85f Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Wed, 5 Sep 2018 21:07:22 +0200 Subject: [PATCH 02/33] Update all dependencies. --- app/build.gradle | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index c13be0b..6077004 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,12 +15,12 @@ repositories { } android { - compileSdkVersion 26 - buildToolsVersion '26.0.2' + compileSdkVersion 27 + buildToolsVersion '27.0.3' defaultConfig { applicationId 'com.blogspot.e_kanivets.moneytracker' minSdkVersion 17 - targetSdkVersion 26 + targetSdkVersion 27 versionCode 23 versionName '1.8.7' } @@ -65,22 +65,22 @@ dependencies { transitive = true } - compile 'com.android.support:support-v4:26.1.0' - compile 'com.android.support:appcompat-v7:26.1.0' - compile 'com.android.support:design:26.1.0' + compile 'com.android.support:support-v4:27.1.1' + compile 'com.android.support:appcompat-v7:27.1.1' + compile 'com.android.support:design:27.1.1' compile 'com.jakewharton:butterknife:8.5.1' // View annotation bindings annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1' // ButterKnife compiler - compile 'com.google.dagger:dagger:2.0.1' // Dependency injection tool + compile 'com.google.dagger:dagger:2.11' // Dependency injection tool compile 'com.github.PhilJay:MPAndroidChart:v2.2.4' // Charts compile 'com.jakewharton.timber:timber:4.1.2' // Advanced logging tool - compile 'com.android.support.constraint:constraint-layout:1.0.2' + compile 'com.android.support.constraint:constraint-layout:1.1.3' compile 'com.dropbox.core:dropbox-core-sdk:3.0.5' // Dropbox Core API testCompile 'junit:junit:4.12' - testCompile 'org.mockito:mockito-core:2.0.43-beta' + testCompile 'org.mockito:mockito-core:2.8.9' androidTestCompile 'com.crittercism.dexmaker:dexmaker:1.4' androidTestCompile 'com.crittercism.dexmaker:dexmaker-dx:1.4' androidTestCompile 'com.crittercism.dexmaker:dexmaker-mockito:1.4' - annotationProcessor 'com.google.dagger:dagger-compiler:2.0.1' + annotationProcessor 'com.google.dagger:dagger-compiler:2.11' provided 'org.glassfish:javax.annotation:10.0-b28' } From 857ff386dffd97dbaa345a49af22ad1b7256f7aa Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Wed, 5 Sep 2018 21:25:45 +0200 Subject: [PATCH 03/33] #95. Kotlinify EditAccountActivity. --- app/build.gradle | 4 + .../activity/account/AccountsActivity.java | 42 ++---- .../activity/account/EditAccountActivity.java | 139 ------------------ .../activity/account/EditAccountActivity.kt | 132 +++++++++++++++++ .../main/res/layout/activity_edit_account.xml | 8 +- build.gradle | 4 +- 6 files changed, 158 insertions(+), 171 deletions(-) delete mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/EditAccountActivity.java create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/EditAccountActivity.kt diff --git a/app/build.gradle b/app/build.gradle index 6077004..87e4167 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,10 +8,13 @@ buildscript { } } apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' apply plugin: 'io.fabric' repositories { maven { url 'https://maven.fabric.io/public' } + mavenCentral() } android { @@ -83,4 +86,5 @@ dependencies { androidTestCompile 'com.crittercism.dexmaker:dexmaker-mockito:1.4' annotationProcessor 'com.google.dagger:dagger-compiler:2.11' provided 'org.glassfish:javax.annotation:10.0-b28' + compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/AccountsActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/AccountsActivity.java index 6f5e624..9b18836 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/AccountsActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/AccountsActivity.java @@ -10,6 +10,7 @@ import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity; import com.blogspot.e_kanivets.moneytracker.adapter.AccountAdapter; import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController; +import com.blogspot.e_kanivets.moneytracker.entity.data.Account; import com.blogspot.e_kanivets.moneytracker.ui.presenter.AccountsSummaryPresenter; import com.blogspot.e_kanivets.moneytracker.util.AnswersProxy; @@ -20,36 +21,30 @@ import butterknife.OnItemClick; public class AccountsActivity extends BaseBackActivity { - @SuppressWarnings("unused") - private static final String TAG = "AccountsActivity"; + @SuppressWarnings("unused") private static final String TAG = "AccountsActivity"; private static final int REQUEST_ADD_ACCOUNT = 1; private static final int REQUEST_TRANSFER = 2; private static final int REQUEST_EDIT_ACCOUNT = 3; - @Inject - AccountController accountController; + @Inject AccountController accountController; private AccountsSummaryPresenter summaryPresenter; - @BindView(R.id.list_view) - ListView listView; + @BindView(R.id.list_view) ListView listView; - @Override - protected int getContentViewId() { + @Override protected int getContentViewId() { return R.layout.activity_accounts; } - @Override - protected boolean initData() { + @Override protected boolean initData() { boolean result = super.initData(); getAppComponent().inject(AccountsActivity.this); summaryPresenter = new AccountsSummaryPresenter(AccountsActivity.this); return result; } - @Override - protected void initViews() { + @Override protected void initViews() { super.initViews(); listView.addHeaderView(summaryPresenter.create()); @@ -58,14 +53,12 @@ protected void initViews() { update(); } - @Override - public boolean onCreateOptionsMenu(Menu menu) { + @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_accounts, menu); return true; } - @Override - public boolean onOptionsItemSelected(MenuItem item) { + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_transfer: makeTransfer(); @@ -76,28 +69,23 @@ public boolean onOptionsItemSelected(MenuItem item) { } } - @OnItemClick(R.id.list_view) - public void onAccountClick(int position) { - Intent intent = new Intent(this, EditAccountActivity.class); - intent.putExtra(EditAccountActivity.KEY_ACCOUNT, accountController.readAll().get(position - 1)); - startActivityForResult(intent, REQUEST_EDIT_ACCOUNT); + @OnItemClick(R.id.list_view) public void onAccountClick(int position) { + Account account = accountController.readAll().get(position - 1); + startActivityForResult(EditAccountActivity.Companion.newIntent(this, account), REQUEST_EDIT_ACCOUNT); } public void makeTransfer() { AnswersProxy.get().logButton("Add Transfer"); - startActivityForResult(new Intent(AccountsActivity.this, TransferActivity.class), - REQUEST_TRANSFER); + startActivityForResult(new Intent(AccountsActivity.this, TransferActivity.class), REQUEST_TRANSFER); } - @OnClick(R.id.btn_add_account) - public void addAccount() { + @OnClick(R.id.btn_add_account) public void addAccount() { AnswersProxy.get().logButton("Add Account"); Intent intent = new Intent(AccountsActivity.this, AddAccountActivity.class); startActivityForResult(intent, REQUEST_ADD_ACCOUNT); } - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == AppCompatActivity.RESULT_OK) { diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/EditAccountActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/EditAccountActivity.java deleted file mode 100644 index 2860d54..0000000 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/EditAccountActivity.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.blogspot.e_kanivets.moneytracker.activity.account; - -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.support.design.widget.TextInputLayout; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.EditText; - -import com.blogspot.e_kanivets.moneytracker.R; -import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity; -import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController; -import com.blogspot.e_kanivets.moneytracker.entity.data.Account; - -import javax.inject.Inject; - -import butterknife.BindView; -import butterknife.OnClick; - -public class EditAccountActivity extends BaseBackActivity { - - public static final String KEY_ACCOUNT = "key_account"; - - @Inject - AccountController accountController; - - private Account account; - - @BindView(R.id.til_title) - TextInputLayout tilTitle; - @BindView(R.id.et_title) - EditText etTitle; - @BindView(R.id.et_goal) - EditText etGoal; - @BindView(R.id.view_color) - View viewColor; - - @Override - protected int getContentViewId() { - return R.layout.activity_edit_account; - } - - @Override - protected boolean initData() { - getAppComponent().inject(EditAccountActivity.this); - account = getIntent().getParcelableExtra(KEY_ACCOUNT); - return account != null && super.initData(); - } - - @Override - protected void initViews() { - super.initViews(); - - etTitle.setText(account.getTitle()); - etGoal.setText(Double.toString(account.getGoal())); - viewColor.setBackgroundColor(account.getColor()); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - if (account.isArchived()) { - getMenuInflater().inflate(R.menu.menu_archived_account, menu); - } else { - getMenuInflater().inflate(R.menu.menu_account, menu); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.action_archive: - archive(); - return true; - - case R.id.action_restore: - restore(); - return true; - - case R.id.action_delete: - delete(); - return true; - - default: - return super.onOptionsItemSelected(item); - } - } - - @OnClick(R.id.fabDone) - void done() { - String title = etTitle.getText().toString().trim(); - - if (title.isEmpty()) { - tilTitle.setError(getString(R.string.field_cant_be_empty)); - } else { - Account newAccount = new Account(account.getId(), title, account.getCurSum(), - account.getCurrency(), account.getGoal(), account.isArchived(), account.getColor()); - boolean updated = accountController.update(newAccount) != null; - if (updated) { - setResult(RESULT_OK); - finish(); - } - } - } - - private void archive() { - if (account.equals(accountController.readDefaultAccount())) { - showToast(R.string.cant_archive_default_account); - } else { - accountController.archive(account); - setResult(RESULT_OK); - finish(); - } - } - - private void restore() { - accountController.restore(account); - setResult(RESULT_OK); - finish(); - } - - private void delete() { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.delete_account_title); - builder.setMessage(R.string.delete_account_message); - builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - accountController.delete(account); - setResult(RESULT_OK); - finish(); - } - }); - builder.setNegativeButton(android.R.string.cancel, null); - builder.show(); - } - -} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/EditAccountActivity.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/EditAccountActivity.kt new file mode 100644 index 0000000..59f1247 --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/EditAccountActivity.kt @@ -0,0 +1,132 @@ +package com.blogspot.e_kanivets.moneytracker.activity.account + +import android.app.Activity +import android.app.AlertDialog +import android.content.Context +import android.content.Intent +import android.view.Menu +import android.view.MenuItem + +import com.blogspot.e_kanivets.moneytracker.R +import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity +import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController +import com.blogspot.e_kanivets.moneytracker.entity.data.Account +import kotlinx.android.synthetic.main.activity_edit_account.* + +import javax.inject.Inject + +class EditAccountActivity : BaseBackActivity() { + + @Inject + internal lateinit var accountController: AccountController + + private lateinit var account: Account + + override fun getContentViewId(): Int { + return R.layout.activity_edit_account + } + + override fun initData(): Boolean { + appComponent.inject(this@EditAccountActivity) + val accountFromParcel: Account? = intent.getParcelableExtra(KEY_ACCOUNT) + + return if (accountFromParcel == null) false + else { + account = accountFromParcel + super.initData() + } + } + + override fun initViews() { + super.initViews() + + etTitle.setText(account.title) + etGoal.setText(account.goal.toString()) + viewColor.setBackgroundColor(account.color) + + fabDone.setOnClickListener { done() } + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + if (account.isArchived) { + menuInflater.inflate(R.menu.menu_archived_account, menu) + } else { + menuInflater.inflate(R.menu.menu_account, menu) + } + return true + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + return when (item.itemId) { + R.id.action_archive -> archive() + R.id.action_restore -> restore() + R.id.action_delete -> delete() + else -> super.onOptionsItemSelected(item) + } + } + + private fun done() { + val title = etTitle.text.toString().trim { it <= ' ' } + + if (title.isEmpty()) { + tilTitle.error = getString(R.string.field_cant_be_empty) + } else { + val newAccount = Account( + account.id, title, account.curSum.toDouble(), + account.currency, account.goal, account.isArchived, account.color + ) + val updated = accountController.update(newAccount) != null + if (updated) { + setResult(Activity.RESULT_OK) + finish() + } + } + } + + private fun archive(): Boolean { + if (account == accountController.readDefaultAccount()) { + showToast(R.string.cant_archive_default_account) + } else { + accountController.archive(account) + setResult(Activity.RESULT_OK) + finish() + } + + return true + } + + private fun restore(): Boolean { + accountController.restore(account) + setResult(Activity.RESULT_OK) + finish() + + return true + } + + private fun delete(): Boolean { + val builder = AlertDialog.Builder(this) + builder.setTitle(R.string.delete_account_title) + builder.setMessage(R.string.delete_account_message) + builder.setPositiveButton(android.R.string.ok) { _, _ -> + accountController.delete(account) + setResult(Activity.RESULT_OK) + finish() + } + builder.setNegativeButton(android.R.string.cancel, null) + builder.show() + + return true + } + + companion object { + + const val KEY_ACCOUNT = "key_account" + + fun newIntent(context: Context, account: Account): Intent { + val intent = Intent(context, EditAccountActivity::class.java) + intent.putExtra(KEY_ACCOUNT, account) + return intent + } + } + +} diff --git a/app/src/main/res/layout/activity_edit_account.xml b/app/src/main/res/layout/activity_edit_account.xml index 2d7da6c..370e430 100644 --- a/app/src/main/res/layout/activity_edit_account.xml +++ b/app/src/main/res/layout/activity_edit_account.xml @@ -30,12 +30,12 @@ app:layout_behavior="@string/appbar_scrolling_view_behavior"> Date: Wed, 5 Sep 2018 21:27:57 +0200 Subject: [PATCH 04/33] #95. Move EditAccountActivity to activity.account.edit package. --- app/src/main/AndroidManifest.xml | 2 +- .../moneytracker/activity/account/AccountsActivity.java | 1 + .../activity/account/{ => edit}/EditAccountActivity.kt | 6 ++---- .../blogspot/e_kanivets/moneytracker/di/AppComponent.java | 2 +- app/src/main/res/layout/activity_edit_account.xml | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) rename app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/{ => edit}/EditAccountActivity.kt (95%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2776004..0b50798 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -87,7 +87,7 @@ android:screenOrientation="portrait" android:theme="@style/Theme.Default" /> + tools:context="com.blogspot.e_kanivets.moneytracker.activity.account.edit.EditAccountActivity"> Date: Wed, 5 Sep 2018 21:49:33 +0200 Subject: [PATCH 05/33] #95. Partly move logic from EditAccountActivity to EditAccountFragment. --- .../account/edit/EditAccountActivity.kt | 32 ++--- .../edit/fragment/EditAccountFragment.kt | 60 +++++++++ .../main/res/layout/activity_edit_account.xml | 121 +++++------------- .../main/res/layout/fragment_edit_account.xml | 79 ++++++++++++ 4 files changed, 182 insertions(+), 110 deletions(-) create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt create mode 100644 app/src/main/res/layout/fragment_edit_account.xml diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt index 489ddf7..6dbf773 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt @@ -38,11 +38,7 @@ class EditAccountActivity : BaseBackActivity() { override fun initViews() { super.initViews() - etTitle.setText(account.title) - etGoal.setText(account.goal.toString()) - viewColor.setBackgroundColor(account.color) - - fabDone.setOnClickListener { done() } + fabDone.setOnClickListener { /*done()*/ } } override fun onCreateOptionsMenu(menu: Menu): Boolean { @@ -63,21 +59,15 @@ class EditAccountActivity : BaseBackActivity() { } } - private fun done() { - val title = etTitle.text.toString().trim { it <= ' ' } - - if (title.isEmpty()) { - tilTitle.error = getString(R.string.field_cant_be_empty) - } else { - val newAccount = Account( - account.id, title, account.curSum.toDouble(), - account.currency, account.goal, account.isArchived, account.color - ) - val updated = accountController.update(newAccount) != null - if (updated) { - setResult(Activity.RESULT_OK) - finish() - } + private fun done(title: String) { + val newAccount = Account( + account.id, title, account.curSum.toDouble(), + account.currency, account.goal, account.isArchived, account.color + ) + val updated = accountController.update(newAccount) != null + if (updated) { + setResult(Activity.RESULT_OK) + finish() } } @@ -118,7 +108,7 @@ class EditAccountActivity : BaseBackActivity() { companion object { - const val KEY_ACCOUNT = "key_account" + private const val KEY_ACCOUNT = "key_account" fun newIntent(context: Context, account: Account): Intent { val intent = Intent(context, EditAccountActivity::class.java) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt new file mode 100644 index 0000000..a4df59c --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt @@ -0,0 +1,60 @@ +package com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment + +import android.os.Bundle +import android.support.v4.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.blogspot.e_kanivets.moneytracker.R +import com.blogspot.e_kanivets.moneytracker.entity.data.Account +import kotlinx.android.synthetic.main.fragment_edit_account.* + +class EditAccountFragment() : Fragment() { + + private lateinit var account: Account + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + arguments?.let { arguments -> account = arguments.getParcelable(KEY_ACCOUNT) } + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + val rootView = inflater.inflate(R.layout.fragment_edit_account, container, false) + initViews() + return rootView + } + + fun initViews() { + etTitle.setText(account.title) + etGoal.setText(account.goal.toString()) + viewColor.setBackgroundColor(account.color) + } + + private fun done() { + val title = etTitle.text.toString().trim { it <= ' ' } + + if (title.isEmpty()) { + tilTitle.error = getString(R.string.field_cant_be_empty) + } else { + val newAccount = Account( + account.id, title, account.curSum.toDouble(), + account.currency, account.goal, account.isArchived, account.color + ) + } + } + + companion object { + + private const val KEY_ACCOUNT = "key_account" + + fun newInstance(account: Account): EditAccountFragment { + val fragment = EditAccountFragment() + val arguments = Bundle() + arguments.putParcelable(KEY_ACCOUNT, account) + fragment.arguments = arguments + return fragment + } + + } + +} diff --git a/app/src/main/res/layout/activity_edit_account.xml b/app/src/main/res/layout/activity_edit_account.xml index cf0977e..e96d428 100644 --- a/app/src/main/res/layout/activity_edit_account.xml +++ b/app/src/main/res/layout/activity_edit_account.xml @@ -6,97 +6,40 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" - tools:context="com.blogspot.e_kanivets.moneytracker.activity.account.edit.EditAccountActivity"> + tools:context="com.blogspot.e_kanivets.moneytracker.activity.account.edit.EditAccountActivity" + > - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_height="?attr/actionBarSize" + android:background="?attr/colorPrimary" + app:popupTheme="@style/AppTheme.PopupOverlay" + /> + + + + + + diff --git a/app/src/main/res/layout/fragment_edit_account.xml b/app/src/main/res/layout/fragment_edit_account.xml new file mode 100644 index 0000000..c09d09a --- /dev/null +++ b/app/src/main/res/layout/fragment_edit_account.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From ababa1eb13f548c8538d9b644ddf3ac6f1a8f249 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Thu, 6 Sep 2018 08:10:04 +0200 Subject: [PATCH 06/33] #95. Completely move all logic to EditAccountFragment. --- .../account/edit/EditAccountActivity.kt | 21 ++--------- .../EditAccountFragmentPagerAdapter.kt | 21 +++++++++++ .../edit/fragment/EditAccountFragment.kt | 36 ++++++++++++------- .../activity/base/BaseFragment.kt | 33 +++++++++++++++++ .../moneytracker/di/AppComponent.java | 3 ++ 5 files changed, 83 insertions(+), 31 deletions(-) create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/base/BaseFragment.kt diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt index 6dbf773..2571b9b 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt @@ -8,6 +8,7 @@ import android.view.Menu import android.view.MenuItem import com.blogspot.e_kanivets.moneytracker.R +import com.blogspot.e_kanivets.moneytracker.activity.account.edit.adapter.EditAccountFragmentPagerAdapter import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController import com.blogspot.e_kanivets.moneytracker.entity.data.Account @@ -38,15 +39,11 @@ class EditAccountActivity : BaseBackActivity() { override fun initViews() { super.initViews() - fabDone.setOnClickListener { /*done()*/ } + viewPager.adapter = EditAccountFragmentPagerAdapter(supportFragmentManager, account) } override fun onCreateOptionsMenu(menu: Menu): Boolean { - if (account.isArchived) { - menuInflater.inflate(R.menu.menu_archived_account, menu) - } else { - menuInflater.inflate(R.menu.menu_account, menu) - } + menuInflater.inflate(if (account.isArchived) R.menu.menu_archived_account else R.menu.menu_account, menu) return true } @@ -59,18 +56,6 @@ class EditAccountActivity : BaseBackActivity() { } } - private fun done(title: String) { - val newAccount = Account( - account.id, title, account.curSum.toDouble(), - account.currency, account.goal, account.isArchived, account.color - ) - val updated = accountController.update(newAccount) != null - if (updated) { - setResult(Activity.RESULT_OK) - finish() - } - } - private fun archive(): Boolean { if (account == accountController.readDefaultAccount()) { showToast(R.string.cant_archive_default_account) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt new file mode 100644 index 0000000..0839836 --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt @@ -0,0 +1,21 @@ +package com.blogspot.e_kanivets.moneytracker.activity.account.edit.adapter + +import android.support.v4.app.Fragment +import android.support.v4.app.FragmentManager +import android.support.v4.app.FragmentPagerAdapter +import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.EditAccountFragment +import com.blogspot.e_kanivets.moneytracker.entity.data.Account + +class EditAccountFragmentPagerAdapter(fragmentManager: FragmentManager, private val account: Account) : + FragmentPagerAdapter(fragmentManager) { + + override fun getItem(position: Int): Fragment { + return when (position) { + 0 -> EditAccountFragment.newInstance(account) + else -> Fragment() + } + } + + override fun getCount(): Int = 1 + +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt index a4df59c..a33586a 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt @@ -1,33 +1,38 @@ package com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment +import android.app.Activity import android.os.Bundle -import android.support.v4.app.Fragment -import android.view.LayoutInflater +import android.support.design.widget.FloatingActionButton import android.view.View -import android.view.ViewGroup import com.blogspot.e_kanivets.moneytracker.R +import com.blogspot.e_kanivets.moneytracker.R.layout +import com.blogspot.e_kanivets.moneytracker.activity.base.BaseFragment +import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController import com.blogspot.e_kanivets.moneytracker.entity.data.Account import kotlinx.android.synthetic.main.fragment_edit_account.* +import javax.inject.Inject -class EditAccountFragment() : Fragment() { +class EditAccountFragment : BaseFragment() { + + @Inject + internal lateinit var accountController: AccountController private lateinit var account: Account - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - arguments?.let { arguments -> account = arguments.getParcelable(KEY_ACCOUNT) } - } + override val contentViewId: Int = layout.fragment_edit_account - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - val rootView = inflater.inflate(R.layout.fragment_edit_account, container, false) - initViews() - return rootView + override fun initData() { + appComponent.inject(this@EditAccountFragment) + arguments?.let { arguments -> account = arguments.getParcelable(KEY_ACCOUNT) } } - fun initViews() { + override fun initViews(view: View) { etTitle.setText(account.title) etGoal.setText(account.goal.toString()) viewColor.setBackgroundColor(account.color) + + val fabDone = view.rootView.findViewById(R.id.fabDone) + fabDone.setOnClickListener { done() } } private fun done() { @@ -40,6 +45,11 @@ class EditAccountFragment() : Fragment() { account.id, title, account.curSum.toDouble(), account.currency, account.goal, account.isArchived, account.color ) + val updated = accountController.update(newAccount) != null + if (updated) { + activity?.setResult(Activity.RESULT_OK) + activity?.finish() + } } } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/base/BaseFragment.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/base/BaseFragment.kt new file mode 100644 index 0000000..d3d5a73 --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/base/BaseFragment.kt @@ -0,0 +1,33 @@ +package com.blogspot.e_kanivets.moneytracker.activity.base + +import android.os.Bundle +import android.support.v4.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.blogspot.e_kanivets.moneytracker.MtApp +import com.blogspot.e_kanivets.moneytracker.di.AppComponent + +abstract class BaseFragment : Fragment() { + + protected val appComponent: AppComponent = MtApp.get().appComponent + + protected abstract val contentViewId: Int + + protected abstract fun initData() + + protected abstract fun initViews(view: View) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + initData() + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = + inflater.inflate(contentViewId, container, false) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initViews(view) + } +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java index 8e6d754..75db9c2 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java @@ -1,6 +1,7 @@ package com.blogspot.e_kanivets.moneytracker.di; import com.blogspot.e_kanivets.moneytracker.activity.account.edit.EditAccountActivity; +import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.EditAccountFragment; import com.blogspot.e_kanivets.moneytracker.activity.charts.ChartsActivity; import com.blogspot.e_kanivets.moneytracker.activity.external.BackupActivity; import com.blogspot.e_kanivets.moneytracker.activity.external.ImportExportActivity; @@ -81,4 +82,6 @@ public interface AppComponent { void inject(MonthSummaryAdapter monthSummaryAdapter); void inject(EditAccountActivity editAccountActivity); + + void inject(EditAccountFragment editAccountFragment); } From bc6c4c050a80eb456e8a3ff9408956b1efd67c7b Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Thu, 6 Sep 2018 21:10:00 +0200 Subject: [PATCH 07/33] #95. Ongoing refactoring. --- .../moneytracker/activity/record/MainActivity.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/MainActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/MainActivity.java index 57dc083..3a155f8 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/MainActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/MainActivity.java @@ -94,14 +94,12 @@ protected void initViews() { setTitle(R.string.title_records); - tvDefaultAccountTitle = (TextView) navigationView.getHeaderView(0).findViewById(R.id.tv_default_account_title); - tvDefaultAccountSum = (TextView) navigationView.getHeaderView(0).findViewById(R.id.tv_default_account_sum); - tvCurrency = (TextView) navigationView.getHeaderView(0).findViewById(R.id.tv_currency); + tvDefaultAccountTitle = navigationView.getHeaderView(0).findViewById(R.id.tv_default_account_title); + tvDefaultAccountSum = navigationView.getHeaderView(0).findViewById(R.id.tv_default_account_sum); + tvCurrency = navigationView.getHeaderView(0).findViewById(R.id.tv_currency); if (preferenceController.checkRateDialog()) showAppRateDialog(); - //registerForContextMenu(listView); - View summaryView = summaryPresenter.create(true); listView.addHeaderView(summaryView); summaryView.setOnClickListener(new View.OnClickListener() { From b49d2b12c773b1690ef93682bfae8d43f800f268 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Thu, 6 Sep 2018 21:23:42 +0200 Subject: [PATCH 08/33] #95. Add AccountRecordFragment. --- .../EditAccountFragmentPagerAdapter.kt | 4 +- .../edit/fragment/AccountRecordsFragment.kt | 44 +++++++++++++++++++ .../moneytracker/di/AppComponent.java | 3 ++ .../res/layout/fragment_account_records.xml | 13 ++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountRecordsFragment.kt create mode 100644 app/src/main/res/layout/fragment_account_records.xml diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt index 0839836..9ba3fc5 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt @@ -3,6 +3,7 @@ package com.blogspot.e_kanivets.moneytracker.activity.account.edit.adapter import android.support.v4.app.Fragment import android.support.v4.app.FragmentManager import android.support.v4.app.FragmentPagerAdapter +import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.AccountRecordsFragment import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.EditAccountFragment import com.blogspot.e_kanivets.moneytracker.entity.data.Account @@ -12,10 +13,11 @@ class EditAccountFragmentPagerAdapter(fragmentManager: FragmentManager, private override fun getItem(position: Int): Fragment { return when (position) { 0 -> EditAccountFragment.newInstance(account) + 1 -> AccountRecordsFragment.newInstance(account) else -> Fragment() } } - override fun getCount(): Int = 1 + override fun getCount(): Int = 2 } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountRecordsFragment.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountRecordsFragment.kt new file mode 100644 index 0000000..8c065c6 --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountRecordsFragment.kt @@ -0,0 +1,44 @@ +package com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment + +import android.os.Bundle +import android.view.View +import com.blogspot.e_kanivets.moneytracker.R +import com.blogspot.e_kanivets.moneytracker.activity.base.BaseFragment +import com.blogspot.e_kanivets.moneytracker.adapter.RecordAdapter +import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController +import com.blogspot.e_kanivets.moneytracker.entity.data.Account +import kotlinx.android.synthetic.main.fragment_account_records.* +import javax.inject.Inject + +class AccountRecordsFragment : BaseFragment() { + + @Inject + internal lateinit var accountController: AccountController + + private lateinit var account: Account + + override val contentViewId: Int = R.layout.fragment_account_records + + override fun initData() { + appComponent.inject(this@AccountRecordsFragment) + arguments?.let { arguments -> account = arguments.getParcelable(AccountRecordsFragment.KEY_ACCOUNT) } + } + + override fun initViews(view: View) { + listView.adapter = RecordAdapter(activity, listOf()) + } + + companion object { + + private const val KEY_ACCOUNT = "key_account" + + fun newInstance(account: Account): AccountRecordsFragment { + val fragment = AccountRecordsFragment() + val arguments = Bundle() + arguments.putParcelable(KEY_ACCOUNT, account) + fragment.arguments = arguments + return fragment + } + + } +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java index 75db9c2..9178884 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java @@ -1,6 +1,7 @@ package com.blogspot.e_kanivets.moneytracker.di; import com.blogspot.e_kanivets.moneytracker.activity.account.edit.EditAccountActivity; +import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.AccountRecordsFragment; import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.EditAccountFragment; import com.blogspot.e_kanivets.moneytracker.activity.charts.ChartsActivity; import com.blogspot.e_kanivets.moneytracker.activity.external.BackupActivity; @@ -84,4 +85,6 @@ public interface AppComponent { void inject(EditAccountActivity editAccountActivity); void inject(EditAccountFragment editAccountFragment); + + void inject(AccountRecordsFragment accountRecordsFragment); } diff --git a/app/src/main/res/layout/fragment_account_records.xml b/app/src/main/res/layout/fragment_account_records.xml new file mode 100644 index 0000000..f4e5e9d --- /dev/null +++ b/app/src/main/res/layout/fragment_account_records.xml @@ -0,0 +1,13 @@ + + + + + + From 05c19ab7adae50b12c6f92888d12344e393a830d Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Thu, 6 Sep 2018 21:47:52 +0200 Subject: [PATCH 09/33] #95. Display account records. --- .../edit/fragment/AccountRecordsFragment.kt | 6 +- .../controller/data/RecordController.java | 84 +++++++++---------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountRecordsFragment.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountRecordsFragment.kt index 8c065c6..e01a262 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountRecordsFragment.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountRecordsFragment.kt @@ -5,7 +5,7 @@ import android.view.View import com.blogspot.e_kanivets.moneytracker.R import com.blogspot.e_kanivets.moneytracker.activity.base.BaseFragment import com.blogspot.e_kanivets.moneytracker.adapter.RecordAdapter -import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController +import com.blogspot.e_kanivets.moneytracker.controller.data.RecordController import com.blogspot.e_kanivets.moneytracker.entity.data.Account import kotlinx.android.synthetic.main.fragment_account_records.* import javax.inject.Inject @@ -13,7 +13,7 @@ import javax.inject.Inject class AccountRecordsFragment : BaseFragment() { @Inject - internal lateinit var accountController: AccountController + internal lateinit var recordController: RecordController private lateinit var account: Account @@ -25,7 +25,7 @@ class AccountRecordsFragment : BaseFragment() { } override fun initViews(view: View) { - listView.adapter = RecordAdapter(activity, listOf()) + listView.adapter = RecordAdapter(activity, recordController.getRecordsForAccount(account)) } companion object { diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordController.java index a17b984..5bd47d0 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordController.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordController.java @@ -27,30 +27,27 @@ public class RecordController extends BaseController { private final AccountController accountController; public RecordController(IRepo recordRepo, CategoryController categoryController, - AccountController accountController) { + AccountController accountController) { super(recordRepo); this.categoryController = categoryController; this.accountController = accountController; } - @Override - @SuppressWarnings("SimplifiableIfStatement") - public Record create(@Nullable Record record) { + @Override @SuppressWarnings("SimplifiableIfStatement") public Record create(@Nullable Record record) { if (record == null) return null; record = validateRecord(record); Record createdRecord = repo.create(record); - if (createdRecord == null) return null; - else { + if (createdRecord == null) { + return null; + } else { accountController.recordAdded(createdRecord); return createdRecord; } } - @Override - @SuppressWarnings("SimplifiableIfStatement") - public Record update(@Nullable Record record) { + @Override @SuppressWarnings("SimplifiableIfStatement") public Record update(@Nullable Record record) { if (record == null) return null; record = validateRecord(record); @@ -58,44 +55,42 @@ record = validateRecord(record); Record oldRecord = read(record.getId()); Record updatedRecord = repo.update(record); - if (updatedRecord == null) return null; - else { + if (updatedRecord == null) { + return null; + } else { accountController.recordUpdated(oldRecord, updatedRecord); return updatedRecord; } } - @Override - @SuppressWarnings("SimplifiableIfStatement") - public boolean delete(@Nullable Record record) { - if (repo.delete(record)) return accountController.recordDeleted(record); - else return false; + @Override @SuppressWarnings("SimplifiableIfStatement") public boolean delete(@Nullable Record record) { + if (repo.delete(record)) { + return accountController.recordDeleted(record); + } else { + return false; + } } - @Nullable - @Override - public Record read(long id) { - List list = readWithCondition("id=?", new String[]{Long.toString(id)}); + @Nullable @Override public Record read(long id) { + List list = readWithCondition("id=?", new String[] { Long.toString(id) }); - if (list.size() == 1) return list.get(0); - else return null; + if (list.size() == 1) { + return list.get(0); + } else { + return null; + } } - @NonNull - @Override - public List readAll() { + @NonNull @Override public List readAll() { return readWithCondition(null, null); } - @NonNull - @Override - public List readWithCondition(String condition, String[] args) { + @NonNull @Override public List readWithCondition(String condition, String[] args) { List recordList = super.readWithCondition(condition, args); // Sort record list by time field from smallest to biggest Collections.sort(recordList, new Comparator() { - @Override - public int compare(Record lhs, Record rhs) { + @Override public int compare(Record lhs, Record rhs) { return lhs.getTime() < rhs.getTime() ? -1 : (lhs.getTime() == rhs.getTime() ? 0 : 1); } }); @@ -104,16 +99,14 @@ public int compare(Record lhs, Record rhs) { List completedRecordList = new ArrayList<>(); for (Record record : recordList) { Category category = null; - if (record.getCategory() != null) - category = categoryController.read(record.getCategory().getId()); + if (record.getCategory() != null) category = categoryController.read(record.getCategory().getId()); Account account = null; - if (record.getAccount() != null) - account = accountController.read(record.getAccount().getId()); + if (record.getAccount() != null) account = accountController.read(record.getAccount().getId()); - completedRecordList.add(new Record(record.getId(), record.getTime(), record.getType(), - record.getTitle(), category, record.getPrice(), account, record.getCurrency(), - record.getDecimals())); + completedRecordList.add( + new Record(record.getId(), record.getTime(), record.getType(), record.getTitle(), category, + record.getPrice(), account, record.getCurrency(), record.getDecimals())); } return completedRecordList; @@ -121,8 +114,16 @@ public int compare(Record lhs, Record rhs) { public List getRecordsForPeriod(Period period) { String condition = DbHelper.TIME_COLUMN + " BETWEEN ? AND ?"; - String[] args = new String[]{Long.toString(period.getFirst().getTime()), - Long.toString(period.getLast().getTime())}; + String[] args = new String[] { + Long.toString(period.getFirst().getTime()), Long.toString(period.getLast().getTime()) + }; + + return readWithCondition(condition, args); + } + + public List getRecordsForAccount(Account account) { + String condition = DbHelper.ACCOUNT_ID_COLUMN + "=?"; + String[] args = new String[] { Long.toString(account.getId()) }; return readWithCondition(condition, args); } @@ -132,8 +133,7 @@ private Record validateRecord(@NonNull Record record) { Category category = categoryController.readOrCreate(record.getCategory().getName()); - return new Record(record.getId(), record.getTime(), record.getType(), record.getTitle(), - category, record.getPrice(), record.getAccount(), record.getCurrency(), - record.getDecimals()); + return new Record(record.getId(), record.getTime(), record.getType(), record.getTitle(), category, + record.getPrice(), record.getAccount(), record.getCurrency(), record.getDecimals()); } } \ No newline at end of file From bd7615d93161dad45b160abfc58d1478ce37530f Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Thu, 6 Sep 2018 21:53:42 +0200 Subject: [PATCH 10/33] #95. Rename FragmentAccountRecords to FragmentAccountOperations. --- .../adapter/EditAccountFragmentPagerAdapter.kt | 4 ++-- ...rdsFragment.kt => AccountOperationsFragment.kt} | 14 +++++++------- .../e_kanivets/moneytracker/di/AppComponent.java | 4 ++-- ...records.xml => fragment_account_operations.xml} | 0 4 files changed, 11 insertions(+), 11 deletions(-) rename app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/{AccountRecordsFragment.kt => AccountOperationsFragment.kt} (76%) rename app/src/main/res/layout/{fragment_account_records.xml => fragment_account_operations.xml} (100%) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt index 9ba3fc5..73cb183 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt @@ -3,7 +3,7 @@ package com.blogspot.e_kanivets.moneytracker.activity.account.edit.adapter import android.support.v4.app.Fragment import android.support.v4.app.FragmentManager import android.support.v4.app.FragmentPagerAdapter -import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.AccountRecordsFragment +import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.AccountOperationsFragment import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.EditAccountFragment import com.blogspot.e_kanivets.moneytracker.entity.data.Account @@ -13,7 +13,7 @@ class EditAccountFragmentPagerAdapter(fragmentManager: FragmentManager, private override fun getItem(position: Int): Fragment { return when (position) { 0 -> EditAccountFragment.newInstance(account) - 1 -> AccountRecordsFragment.newInstance(account) + 1 -> AccountOperationsFragment.newInstance(account) else -> Fragment() } } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountRecordsFragment.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountOperationsFragment.kt similarity index 76% rename from app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountRecordsFragment.kt rename to app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountOperationsFragment.kt index e01a262..d9d6d4f 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountRecordsFragment.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountOperationsFragment.kt @@ -7,21 +7,21 @@ import com.blogspot.e_kanivets.moneytracker.activity.base.BaseFragment import com.blogspot.e_kanivets.moneytracker.adapter.RecordAdapter import com.blogspot.e_kanivets.moneytracker.controller.data.RecordController import com.blogspot.e_kanivets.moneytracker.entity.data.Account -import kotlinx.android.synthetic.main.fragment_account_records.* +import kotlinx.android.synthetic.main.fragment_account_operations.* import javax.inject.Inject -class AccountRecordsFragment : BaseFragment() { +class AccountOperationsFragment : BaseFragment() { @Inject internal lateinit var recordController: RecordController private lateinit var account: Account - override val contentViewId: Int = R.layout.fragment_account_records + override val contentViewId: Int = R.layout.fragment_account_operations override fun initData() { - appComponent.inject(this@AccountRecordsFragment) - arguments?.let { arguments -> account = arguments.getParcelable(AccountRecordsFragment.KEY_ACCOUNT) } + appComponent.inject(this@AccountOperationsFragment) + arguments?.let { arguments -> account = arguments.getParcelable(AccountOperationsFragment.KEY_ACCOUNT) } } override fun initViews(view: View) { @@ -32,8 +32,8 @@ class AccountRecordsFragment : BaseFragment() { private const val KEY_ACCOUNT = "key_account" - fun newInstance(account: Account): AccountRecordsFragment { - val fragment = AccountRecordsFragment() + fun newInstance(account: Account): AccountOperationsFragment { + val fragment = AccountOperationsFragment() val arguments = Bundle() arguments.putParcelable(KEY_ACCOUNT, account) fragment.arguments = arguments diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java index 9178884..1f0b100 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java @@ -1,7 +1,7 @@ package com.blogspot.e_kanivets.moneytracker.di; import com.blogspot.e_kanivets.moneytracker.activity.account.edit.EditAccountActivity; -import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.AccountRecordsFragment; +import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.AccountOperationsFragment; import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.EditAccountFragment; import com.blogspot.e_kanivets.moneytracker.activity.charts.ChartsActivity; import com.blogspot.e_kanivets.moneytracker.activity.external.BackupActivity; @@ -86,5 +86,5 @@ public interface AppComponent { void inject(EditAccountFragment editAccountFragment); - void inject(AccountRecordsFragment accountRecordsFragment); + void inject(AccountOperationsFragment accountRecordsFragment); } diff --git a/app/src/main/res/layout/fragment_account_records.xml b/app/src/main/res/layout/fragment_account_operations.xml similarity index 100% rename from app/src/main/res/layout/fragment_account_records.xml rename to app/src/main/res/layout/fragment_account_operations.xml From 85e09ab11d95d75d884e16db7bd44a45c15e20b3 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Mon, 10 Sep 2018 21:03:11 +0200 Subject: [PATCH 11/33] #95. Kotlinify TransferController. --- .../controller/data/TransferController.java | 40 ------------------- .../controller/data/TransferController.kt | 27 +++++++++++++ 2 files changed, 27 insertions(+), 40 deletions(-) delete mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/TransferController.java create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/TransferController.kt diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/TransferController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/TransferController.java deleted file mode 100644 index 765a5f8..0000000 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/TransferController.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.blogspot.e_kanivets.moneytracker.controller.data; - -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -import com.blogspot.e_kanivets.moneytracker.controller.base.BaseController; -import com.blogspot.e_kanivets.moneytracker.entity.data.Transfer; -import com.blogspot.e_kanivets.moneytracker.repo.base.IRepo; - -/** - * Controller class to encapsulate transfer handling logic. - * Created on 2/17/16. - * - * @author Evgenii Kanivets - */ -public class TransferController extends BaseController { - @SuppressWarnings("unused") - private static final String TAG = "TransferController"; - - @NonNull - private AccountController accountController; - - public TransferController(@NonNull IRepo transferRepo, - @NonNull AccountController accountController) { - super(transferRepo); - this.accountController = accountController; - } - - @Override - @SuppressWarnings("SimplifiableIfStatement") - public Transfer create(@Nullable Transfer transfer) { - Transfer createdTransfer = repo.create(transfer); - - if (createdTransfer == null) return null; - else { - accountController.transferDone(createdTransfer); - return createdTransfer; - } - } -} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/TransferController.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/TransferController.kt new file mode 100644 index 0000000..552740a --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/TransferController.kt @@ -0,0 +1,27 @@ +package com.blogspot.e_kanivets.moneytracker.controller.data + +import com.blogspot.e_kanivets.moneytracker.controller.base.BaseController +import com.blogspot.e_kanivets.moneytracker.entity.data.Transfer +import com.blogspot.e_kanivets.moneytracker.repo.base.IRepo + +/** + * Controller class to encapsulate transfer handling logic. + * Created on 2/17/16. + * + * @author Evgenii Kanivets + */ +class TransferController( + transferRepo: IRepo, + private val accountController: AccountController +) : BaseController(transferRepo) { + + override fun create(transfer: Transfer?): Transfer? { + val createdTransfer = repo.create(transfer) + + return if (createdTransfer == null) null else { + accountController.transferDone(createdTransfer) + createdTransfer + } + } + +} From 710f433329bd830046fa880810bd494f4d0affef Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Mon, 10 Sep 2018 21:26:59 +0200 Subject: [PATCH 12/33] #95. Display transfers as records in account operations. --- .../fragment/AccountOperationsFragment.kt | 34 ++++++++++++++++++- .../controller/data/TransferController.kt | 9 +++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountOperationsFragment.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountOperationsFragment.kt index d9d6d4f..6a2a25a 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountOperationsFragment.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountOperationsFragment.kt @@ -6,7 +6,11 @@ import com.blogspot.e_kanivets.moneytracker.R import com.blogspot.e_kanivets.moneytracker.activity.base.BaseFragment import com.blogspot.e_kanivets.moneytracker.adapter.RecordAdapter import com.blogspot.e_kanivets.moneytracker.controller.data.RecordController +import com.blogspot.e_kanivets.moneytracker.controller.data.TransferController import com.blogspot.e_kanivets.moneytracker.entity.data.Account +import com.blogspot.e_kanivets.moneytracker.entity.data.Category +import com.blogspot.e_kanivets.moneytracker.entity.data.Record +import com.blogspot.e_kanivets.moneytracker.entity.data.Transfer import kotlinx.android.synthetic.main.fragment_account_operations.* import javax.inject.Inject @@ -14,6 +18,8 @@ class AccountOperationsFragment : BaseFragment() { @Inject internal lateinit var recordController: RecordController + @Inject + internal lateinit var transferController: TransferController private lateinit var account: Account @@ -25,7 +31,33 @@ class AccountOperationsFragment : BaseFragment() { } override fun initViews(view: View) { - listView.adapter = RecordAdapter(activity, recordController.getRecordsForAccount(account)) + listView.adapter = RecordAdapter(activity, getRecords()) + } + + private fun getRecords(): List { + val accountRecords = recordController.getRecordsForAccount(account) + val accountTransfers = transferController.getTransfersForAccount(account) + + accountRecords += calculateRecordsFromTransfers(accountTransfers) + accountRecords.sortByDescending { it.time } + + return accountRecords + } + + private fun calculateRecordsFromTransfers(transfers: List): List { + val records = mutableListOf() + + transfers.forEach { + val type = if (it.fromAccountId == account.id) Record.TYPE_EXPENSE else Record.TYPE_INCOME + val title = "Transfer ${if (type == Record.TYPE_EXPENSE) "to" else "from"}" + val category = Category("transfer") + val price = if (type == Record.TYPE_EXPENSE) it.fromAmount else it.toAmount + val decimals = if (type == Record.TYPE_EXPENSE) it.fromDecimals else it.toDecimals + + records += Record(it.id, it.time, type, title, category, price, account, account.currency, decimals) + } + + return records.toList() } companion object { diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/TransferController.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/TransferController.kt index 552740a..457901e 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/TransferController.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/TransferController.kt @@ -1,7 +1,9 @@ package com.blogspot.e_kanivets.moneytracker.controller.data import com.blogspot.e_kanivets.moneytracker.controller.base.BaseController +import com.blogspot.e_kanivets.moneytracker.entity.data.Account import com.blogspot.e_kanivets.moneytracker.entity.data.Transfer +import com.blogspot.e_kanivets.moneytracker.repo.DbHelper import com.blogspot.e_kanivets.moneytracker.repo.base.IRepo /** @@ -24,4 +26,11 @@ class TransferController( } } + fun getTransfersForAccount(account: Account): List { + val condition = "${DbHelper.FROM_ACCOUNT_ID_COLUMN}=? OR ${DbHelper.TO_ACCOUNT_ID_COLUMN}=?" + val args = arrayOf(account.id.toString(), account.id.toString()) + + return readWithCondition(condition, args) + } + } From 3c75b2c29bb070bcc74f81a2da7580aecadc141f Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Mon, 10 Sep 2018 21:44:05 +0200 Subject: [PATCH 13/33] #95. Refactor AccountOperationsFragment. --- .../edit/fragment/AccountOperationsFragment.kt | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountOperationsFragment.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountOperationsFragment.kt index 6a2a25a..2d189d7 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountOperationsFragment.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/AccountOperationsFragment.kt @@ -5,6 +5,7 @@ import android.view.View import com.blogspot.e_kanivets.moneytracker.R import com.blogspot.e_kanivets.moneytracker.activity.base.BaseFragment import com.blogspot.e_kanivets.moneytracker.adapter.RecordAdapter +import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController import com.blogspot.e_kanivets.moneytracker.controller.data.RecordController import com.blogspot.e_kanivets.moneytracker.controller.data.TransferController import com.blogspot.e_kanivets.moneytracker.entity.data.Account @@ -16,6 +17,8 @@ import javax.inject.Inject class AccountOperationsFragment : BaseFragment() { + @Inject + internal lateinit var accountController: AccountController @Inject internal lateinit var recordController: RecordController @Inject @@ -38,19 +41,19 @@ class AccountOperationsFragment : BaseFragment() { val accountRecords = recordController.getRecordsForAccount(account) val accountTransfers = transferController.getTransfersForAccount(account) - accountRecords += calculateRecordsFromTransfers(accountTransfers) + accountRecords += obtainRecordsFromTransfers(accountTransfers) accountRecords.sortByDescending { it.time } return accountRecords } - private fun calculateRecordsFromTransfers(transfers: List): List { + private fun obtainRecordsFromTransfers(transfers: List): List { val records = mutableListOf() transfers.forEach { val type = if (it.fromAccountId == account.id) Record.TYPE_EXPENSE else Record.TYPE_INCOME - val title = "Transfer ${if (type == Record.TYPE_EXPENSE) "to" else "from"}" - val category = Category("transfer") + val title = constructRecordTitle(type, it) + val category = Category(getString(R.string.transfer).toLowerCase()) val price = if (type == Record.TYPE_EXPENSE) it.fromAmount else it.toAmount val decimals = if (type == Record.TYPE_EXPENSE) it.fromDecimals else it.toDecimals @@ -60,6 +63,13 @@ class AccountOperationsFragment : BaseFragment() { return records.toList() } + private fun constructRecordTitle(type: Int, transfer: Transfer): String { + val titlePrefix = getString(if (type == Record.TYPE_EXPENSE) R.string.to else R.string.from) + val oppositeAccountId = if (type == Record.TYPE_EXPENSE) transfer.toAccountId else transfer.fromAccountId + val oppositeAccountTitle = "$titlePrefix ${accountController.read(oppositeAccountId)?.title}" + return "${getString(R.string.transfer)} $oppositeAccountTitle".toLowerCase() + } + companion object { private const val KEY_ACCOUNT = "key_account" From 7cc5dae90e8a27e53812d8cb3d8570ee082c956d Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Mon, 10 Sep 2018 21:57:49 +0200 Subject: [PATCH 14/33] #95. Add tabs to EditAccountActivity. --- .../activity/account/edit/EditAccountActivity.kt | 1 + .../edit/adapter/EditAccountFragmentPagerAdapter.kt | 8 ++++++++ app/src/main/res/layout/activity_edit_account.xml | 9 +++++++++ 3 files changed, 18 insertions(+) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt index 2571b9b..e30bc1f 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt @@ -39,6 +39,7 @@ class EditAccountActivity : BaseBackActivity() { override fun initViews() { super.initViews() + tabLayout.setupWithViewPager(viewPager) viewPager.adapter = EditAccountFragmentPagerAdapter(supportFragmentManager, account) } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt index 73cb183..809d23f 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt @@ -18,6 +18,14 @@ class EditAccountFragmentPagerAdapter(fragmentManager: FragmentManager, private } } + override fun getPageTitle(position: Int): CharSequence? { + return when (position) { + 0 -> "Information" + 1 -> "Operations" + else -> "" + } + } + override fun getCount(): Int = 2 } diff --git a/app/src/main/res/layout/activity_edit_account.xml b/app/src/main/res/layout/activity_edit_account.xml index e96d428..4a73f71 100644 --- a/app/src/main/res/layout/activity_edit_account.xml +++ b/app/src/main/res/layout/activity_edit_account.xml @@ -23,6 +23,15 @@ app:popupTheme="@style/AppTheme.PopupOverlay" /> + + Date: Mon, 10 Sep 2018 22:07:02 +0200 Subject: [PATCH 15/33] #95. Add localization. --- .../account/edit/EditAccountActivity.kt | 10 ++- .../EditAccountFragmentPagerAdapter.kt | 31 --------- .../activity/charts/ChartsActivity.java | 64 ++++--------------- .../adapter/GeneralViewPagerAdapter.kt | 29 +++++++++ app/src/main/res/values-ru/strings.xml | 4 ++ app/src/main/res/values-uk/strings.xml | 4 ++ app/src/main/res/values-zh/strings.xml | 4 ++ app/src/main/res/values/strings.xml | 4 ++ 8 files changed, 65 insertions(+), 85 deletions(-) delete mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/GeneralViewPagerAdapter.kt diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt index e30bc1f..2cf8a42 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt @@ -8,8 +8,10 @@ import android.view.Menu import android.view.MenuItem import com.blogspot.e_kanivets.moneytracker.R -import com.blogspot.e_kanivets.moneytracker.activity.account.edit.adapter.EditAccountFragmentPagerAdapter +import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.AccountOperationsFragment +import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.EditAccountFragment import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity +import com.blogspot.e_kanivets.moneytracker.adapter.GeneralViewPagerAdapter import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController import com.blogspot.e_kanivets.moneytracker.entity.data.Account import kotlinx.android.synthetic.main.activity_edit_account.* @@ -40,7 +42,11 @@ class EditAccountActivity : BaseBackActivity() { super.initViews() tabLayout.setupWithViewPager(viewPager) - viewPager.adapter = EditAccountFragmentPagerAdapter(supportFragmentManager, account) + + val adapter = GeneralViewPagerAdapter(supportFragmentManager) + adapter.addFragment(EditAccountFragment.newInstance(account), getString(R.string.information)) + adapter.addFragment(AccountOperationsFragment.newInstance(account), getString(R.string.operations)) + viewPager.adapter = adapter } override fun onCreateOptionsMenu(menu: Menu): Boolean { diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt deleted file mode 100644 index 809d23f..0000000 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/adapter/EditAccountFragmentPagerAdapter.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.blogspot.e_kanivets.moneytracker.activity.account.edit.adapter - -import android.support.v4.app.Fragment -import android.support.v4.app.FragmentManager -import android.support.v4.app.FragmentPagerAdapter -import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.AccountOperationsFragment -import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.EditAccountFragment -import com.blogspot.e_kanivets.moneytracker.entity.data.Account - -class EditAccountFragmentPagerAdapter(fragmentManager: FragmentManager, private val account: Account) : - FragmentPagerAdapter(fragmentManager) { - - override fun getItem(position: Int): Fragment { - return when (position) { - 0 -> EditAccountFragment.newInstance(account) - 1 -> AccountOperationsFragment.newInstance(account) - else -> Fragment() - } - } - - override fun getPageTitle(position: Int): CharSequence? { - return when (position) { - 0 -> "Information" - 1 -> "Operations" - else -> "" - } - } - - override fun getCount(): Int = 2 - -} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/charts/ChartsActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/charts/ChartsActivity.java index 918cb11..16b6136 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/charts/ChartsActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/charts/ChartsActivity.java @@ -1,16 +1,14 @@ package com.blogspot.e_kanivets.moneytracker.activity.charts; -import android.graphics.Color; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import com.blogspot.e_kanivets.moneytracker.R; import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity; import com.blogspot.e_kanivets.moneytracker.activity.charts.fragment.GraphFragment; import com.blogspot.e_kanivets.moneytracker.activity.charts.fragment.SummaryFragment; +import com.blogspot.e_kanivets.moneytracker.adapter.GeneralViewPagerAdapter; import com.blogspot.e_kanivets.moneytracker.controller.CurrencyController; import com.blogspot.e_kanivets.moneytracker.controller.data.ExchangeRateController; import com.blogspot.e_kanivets.moneytracker.controller.data.RecordController; @@ -18,7 +16,6 @@ import com.blogspot.e_kanivets.moneytracker.report.ReportMaker; import com.blogspot.e_kanivets.moneytracker.report.chart.IMonthReport; -import java.util.ArrayList; import java.util.List; import javax.inject.Inject; @@ -27,32 +24,24 @@ public class ChartsActivity extends BaseBackActivity { - @Inject - RecordController recordController; - @Inject - ExchangeRateController exchangeRateController; - @Inject - CurrencyController currencyController; + @Inject RecordController recordController; + @Inject ExchangeRateController exchangeRateController; + @Inject CurrencyController currencyController; - @BindView(R.id.tabs) - TabLayout tabLayout; - @BindView(R.id.view_pager) - ViewPager viewPager; + @BindView(R.id.tabs) TabLayout tabLayout; + @BindView(R.id.view_pager) ViewPager viewPager; - @Override - protected int getContentViewId() { + @Override protected int getContentViewId() { return R.layout.activity_charts; } - @Override - protected boolean initData() { + @Override protected boolean initData() { boolean result = super.initData(); getAppComponent().inject(ChartsActivity.this); return result; } - @Override - protected void initViews() { + @Override protected void initViews() { super.initViews(); setupViewPager(viewPager); @@ -85,38 +74,9 @@ private void setupViewPager(ViewPager viewPager) { graphFragment = GraphFragment.newInstance(monthReport); } - ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); - adapter.addFragment(SummaryFragment.newInstance(monthReport), "Summary"); - adapter.addFragment(graphFragment, "Graph"); + GeneralViewPagerAdapter adapter = new GeneralViewPagerAdapter(getSupportFragmentManager()); + adapter.addFragment(SummaryFragment.newInstance(monthReport), getString(R.string.summary)); + adapter.addFragment(graphFragment, getString(R.string.graph)); viewPager.setAdapter(adapter); } - - class ViewPagerAdapter extends FragmentPagerAdapter { - private final List mFragmentList = new ArrayList<>(); - private final List mFragmentTitleList = new ArrayList<>(); - - ViewPagerAdapter(FragmentManager manager) { - super(manager); - } - - @Override - public Fragment getItem(int position) { - return mFragmentList.get(position); - } - - @Override - public int getCount() { - return mFragmentList.size(); - } - - void addFragment(Fragment fragment, String title) { - mFragmentList.add(fragment); - mFragmentTitleList.add(title); - } - - @Override - public CharSequence getPageTitle(int position) { - return mFragmentTitleList.get(position); - } - } } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/GeneralViewPagerAdapter.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/GeneralViewPagerAdapter.kt new file mode 100644 index 0000000..68325c7 --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/GeneralViewPagerAdapter.kt @@ -0,0 +1,29 @@ +package com.blogspot.e_kanivets.moneytracker.adapter + +import android.support.v4.app.Fragment +import android.support.v4.app.FragmentManager +import android.support.v4.app.FragmentPagerAdapter +import java.util.ArrayList + +class GeneralViewPagerAdapter(manager: FragmentManager) : FragmentPagerAdapter(manager) { + private val fragmentList = ArrayList() + private val fragmentTitleList = ArrayList() + + override fun getItem(position: Int): Fragment { + return fragmentList[position] + } + + override fun getCount(): Int { + return fragmentList.size + } + + fun addFragment(fragment: Fragment, title: String) { + fragmentList.add(fragment) + fragmentTitleList.add(title) + } + + override fun getPageTitle(position: Int): CharSequence? { + return fragmentTitleList[position] + } + +} diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 7bb319a..ff1375e 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -123,4 +123,8 @@ Нельзя архивировать счет по умолчанию. Удалить счет Вы уверены, что хотите удалить этот счет ? Вы не сможете восстановить его после удаления. + + График + Информация + Операции diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 2398fdd..c721c4a 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -123,4 +123,8 @@ Неможливо архівувати рахунок за замовчанням. Видалити рахунок Ви впевнені, що хочете видалити цей рахунок? Ви не зможете відновити його після видалення. + + Графік + Інформація + Операції diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index c98ea3a..ea66930 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -112,4 +112,8 @@ 您无法获得默认帐户。 删除帐户 你确定要删除这个帐户吗? 以后不能恢复。 + + 圖形 + 信息 + 操作 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4552453..3250acf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -133,5 +133,9 @@ Delete account Are you sure about deleting this account? It can\'t be restored after. + Graph + Information + Operations + From 6b4b778239e0e489c2c00b91862ec9933568cb08 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Tue, 11 Sep 2018 17:33:18 +0200 Subject: [PATCH 16/33] #95. Hide FAB when going to Operations tab. --- .../account/edit/EditAccountActivity.kt | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt index 2cf8a42..3f10199 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/EditAccountActivity.kt @@ -4,9 +4,9 @@ import android.app.Activity import android.app.AlertDialog import android.content.Context import android.content.Intent +import android.support.v4.view.ViewPager.OnPageChangeListener import android.view.Menu import android.view.MenuItem - import com.blogspot.e_kanivets.moneytracker.R import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.AccountOperationsFragment import com.blogspot.e_kanivets.moneytracker.activity.account.edit.fragment.EditAccountFragment @@ -14,8 +14,9 @@ import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity import com.blogspot.e_kanivets.moneytracker.adapter.GeneralViewPagerAdapter import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController import com.blogspot.e_kanivets.moneytracker.entity.data.Account -import kotlinx.android.synthetic.main.activity_edit_account.* - +import kotlinx.android.synthetic.main.activity_edit_account.fabDone +import kotlinx.android.synthetic.main.activity_edit_account.tabLayout +import kotlinx.android.synthetic.main.activity_edit_account.viewPager import javax.inject.Inject class EditAccountActivity : BaseBackActivity() { @@ -47,6 +48,17 @@ class EditAccountActivity : BaseBackActivity() { adapter.addFragment(EditAccountFragment.newInstance(account), getString(R.string.information)) adapter.addFragment(AccountOperationsFragment.newInstance(account), getString(R.string.operations)) viewPager.adapter = adapter + + viewPager.addOnPageChangeListener(object : OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) {} + + override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} + + override fun onPageSelected(position: Int) { + if (position == 0) fabDone.show() else fabDone.hide() + } + + }) } override fun onCreateOptionsMenu(menu: Menu): Boolean { From b622cbdc08412e9f7b69a4fe0bf9e84a0240dca3 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Tue, 11 Sep 2018 17:34:56 +0200 Subject: [PATCH 17/33] #95. Updated .travis.yml. --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1337593..69a752b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,17 +3,17 @@ jdk: oraclejdk8 android: components: # The BuildTools version used by your project - - build-tools-26.0.2 + - build-tools-27.0.3 # The SDK version used to compile your project - android-21 - - android-26 + - android-27 # Additional components - extra-google-google_play_services - extra-google-m2repository - extra-android-m2repository - - addon-google_apis-google-26 + - addon-google_apis-google-27 # Specify at least one system image, # if you need to run emulator(s) during your tests From 3e76c153a048dd1563ebf1a9df72b0d39dbb9e18 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Tue, 11 Sep 2018 21:54:59 +0200 Subject: [PATCH 18/33] #150. Add 'Delete' button to backup item view. --- .../activity/external/BackupActivity.java | 65 +++++++------------ .../moneytracker/adapter/BackupAdapter.kt | 41 ++++++++++++ app/src/main/res/layout/view_backup_item.xml | 26 ++++++++ 3 files changed, 90 insertions(+), 42 deletions(-) create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/BackupAdapter.kt create mode 100644 app/src/main/res/layout/view_backup_item.xml diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java index 8ea8e97..5afbefd 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java @@ -4,12 +4,12 @@ import android.support.annotation.NonNull; import android.support.v7.app.AlertDialog; import android.view.View; -import android.widget.ArrayAdapter; import android.widget.ListView; import com.blogspot.e_kanivets.moneytracker.MtApp; import com.blogspot.e_kanivets.moneytracker.R; import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity; +import com.blogspot.e_kanivets.moneytracker.adapter.BackupAdapter; import com.blogspot.e_kanivets.moneytracker.controller.BackupController; import com.blogspot.e_kanivets.moneytracker.controller.PreferenceController; import com.blogspot.e_kanivets.moneytracker.util.AnswersProxy; @@ -29,30 +29,25 @@ public class BackupActivity extends BaseBackActivity { private static final String APP_KEY = "5lqugcckdy9y6lj"; - @Inject - PreferenceController preferenceController; - @Inject - BackupController backupController; + @Inject PreferenceController preferenceController; + @Inject BackupController backupController; private DbxClientV2 dbClient; - @BindView(R.id.btn_backup_now) - View btnBackupNow; - @BindView(R.id.list_view) - ListView listView; + @BindView(R.id.btn_backup_now) View btnBackupNow; + @BindView(R.id.list_view) ListView listView; - @Override - protected int getContentViewId() { + @Override protected int getContentViewId() { return R.layout.activity_backup; } - @Override - protected boolean initData() { + @Override protected boolean initData() { getAppComponent().inject(BackupActivity.this); String accessToken = preferenceController.readDropboxAccessToken(); - if (accessToken == null) Auth.startOAuth2Authentication(BackupActivity.this, APP_KEY); - else { + if (accessToken == null) { + Auth.startOAuth2Authentication(BackupActivity.this, APP_KEY); + } else { DbxRequestConfig config = new DbxRequestConfig("open_money_tracker"); dbClient = new DbxClientV2(config, accessToken); fetchBackups(); @@ -61,14 +56,12 @@ protected boolean initData() { return super.initData(); } - @Override - protected void initViews() { + @Override protected void initViews() { super.initViews(); btnBackupNow.setEnabled(preferenceController.readDropboxAccessToken() != null); } - @Override - protected void onResume() { + @Override protected void onResume() { super.onResume(); if (Auth.getOAuth2Token() != null) { @@ -84,13 +77,11 @@ protected void onResume() { } } - @OnClick(R.id.btn_backup_now) - public void backupNow() { + @OnClick(R.id.btn_backup_now) public void backupNow() { AnswersProxy.get().logButton("Make Backup"); startProgress(getString(R.string.making_backup)); backupController.makeBackup(dbClient, new BackupController.OnBackupListener() { - @Override - public void onBackupSuccess() { + @Override public void onBackupSuccess() { AnswersProxy.get().logEvent("Backup success"); Timber.d("Backup success."); if (isFinishing()) return; @@ -99,8 +90,7 @@ public void onBackupSuccess() { fetchBackups(); } - @Override - public void onBackupFailure(String reason) { + @Override public void onBackupFailure(String reason) { AnswersProxy.get().logEvent("Backup failure"); Timber.d("Backup failure."); if (isFinishing()) return; @@ -113,8 +103,7 @@ public void onBackupFailure(String reason) { }); } - @OnItemClick(R.id.list_view) - public void restoreBackupClicked(int position) { + @OnItemClick(R.id.list_view) public void restoreBackupClicked(int position) { AnswersProxy.get().logButton("Restore backup"); final String backupName = listView.getAdapter().getItem(position).toString(); @@ -122,8 +111,7 @@ public void restoreBackupClicked(int position) { builder.setTitle(getString(R.string.warning)); builder.setMessage(getString(R.string.want_erase_and_restore, backupName)); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { + @Override public void onClick(DialogInterface dialog, int which) { restoreBackup(backupName); } }); @@ -134,8 +122,7 @@ public void onClick(DialogInterface dialog, int which) { private void restoreBackup(final String backupName) { startProgress(getString(R.string.restoring_backup)); backupController.restoreBackup(dbClient, backupName, new BackupController.OnRestoreBackupListener() { - @Override - public void onRestoreSuccess() { + @Override public void onRestoreSuccess() { AnswersProxy.get().logEvent("Restore Success"); Timber.d("Restore success."); if (isFinishing()) return; @@ -146,8 +133,7 @@ public void onRestoreSuccess() { builder.setTitle(getString(R.string.backup_is_restored)); builder.setMessage(getString(R.string.backup_restored, backupName)); builder.setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { + @Override public void onDismiss(DialogInterface dialog) { MtApp.get().buildAppComponent(); setResult(RESULT_OK); finish(); @@ -157,8 +143,7 @@ public void onDismiss(DialogInterface dialog) { builder.show(); } - @Override - public void onRestoreFailure(String reason) { + @Override public void onRestoreFailure(String reason) { AnswersProxy.get().logEvent("Restore Failure"); Timber.d("Restore failure."); if (isFinishing()) return; @@ -166,8 +151,7 @@ public void onRestoreFailure(String reason) { stopProgress(); showToast(R.string.failed_restore_backup); - if (BackupController.OnRestoreBackupListener.ERROR_AUTHENTICATION.equals(reason)) - logout(); + if (BackupController.OnRestoreBackupListener.ERROR_AUTHENTICATION.equals(reason)) logout(); } }); } @@ -175,14 +159,11 @@ public void onRestoreFailure(String reason) { private void fetchBackups() { startProgress(getString(R.string.fetching_backups)); backupController.fetchBackups(dbClient, new BackupController.OnFetchBackupListListener() { - @Override - public void onBackupsFetched(@NonNull List backupList) { + @Override public void onBackupsFetched(@NonNull List backupList) { if (isFinishing()) return; stopProgress(); - ArrayAdapter adapter = new ArrayAdapter<>(BackupActivity.this, - android.R.layout.simple_list_item_1, backupList); - listView.setAdapter(adapter); + listView.setAdapter(new BackupAdapter(BackupActivity.this, backupList)); } }); } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/BackupAdapter.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/BackupAdapter.kt new file mode 100644 index 0000000..e6a53ae --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/BackupAdapter.kt @@ -0,0 +1,41 @@ +package com.blogspot.e_kanivets.moneytracker.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.BaseAdapter +import com.blogspot.e_kanivets.moneytracker.R +import kotlinx.android.synthetic.main.view_backup_item.view.tvTitle + +class BackupAdapter(private val context: Context, private val backups: List) : BaseAdapter() { + + override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { + var view = convertView + val viewHolder: ViewHolder? + + if (view == null) { + val layoutInflater = LayoutInflater.from(context) + + view = layoutInflater.inflate(R.layout.view_backup_item, parent, false) + viewHolder = ViewHolder(view) + + view.tag = viewHolder + } else { + viewHolder = view.tag as ViewHolder + } + + viewHolder.view.tvTitle.text = getItem(position) + + return view!! + } + + override fun getItem(position: Int): String = backups[position] + + override fun getItemId(position: Int): Long = position.toLong() + + override fun getCount(): Int = backups.size + + private data class ViewHolder(val view: View) + +} diff --git a/app/src/main/res/layout/view_backup_item.xml b/app/src/main/res/layout/view_backup_item.xml new file mode 100644 index 0000000..d3fa3f3 --- /dev/null +++ b/app/src/main/res/layout/view_backup_item.xml @@ -0,0 +1,26 @@ + + + + + + + + From 01e5fb293098509eb3d885b81418915dced84b97 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Wed, 12 Sep 2018 16:54:15 +0200 Subject: [PATCH 19/33] #150. Implement delete backup listener. --- .../activity/external/BackupActivity.java | 25 +- .../moneytracker/adapter/BackupAdapter.kt | 12 +- app/src/main/res/layout/view_backup_item.xml | 4 +- app/src/main/res/values/colors.xml | 37 +-- app/src/main/res/values/strings.xml | 260 +++++++++--------- 5 files changed, 187 insertions(+), 151 deletions(-) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java index 5afbefd..131998b 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java @@ -24,9 +24,10 @@ import butterknife.BindView; import butterknife.OnClick; import butterknife.OnItemClick; +import org.jetbrains.annotations.NotNull; import timber.log.Timber; -public class BackupActivity extends BaseBackActivity { +public class BackupActivity extends BaseBackActivity implements BackupAdapter.OnBackupListener { private static final String APP_KEY = "5lqugcckdy9y6lj"; @Inject PreferenceController preferenceController; @@ -77,6 +78,19 @@ public class BackupActivity extends BaseBackActivity { } } + @Override public void onBackupDelete(@NotNull final String backupName) { + AlertDialog.Builder builder = new AlertDialog.Builder(BackupActivity.this); + builder.setTitle(getString(R.string.delete_backup_title)); + builder.setMessage(getString(R.string.delete_backup_message, backupName)); + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override public void onClick(DialogInterface dialog, int which) { + deleteBackup(backupName); + } + }); + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + } + @OnClick(R.id.btn_backup_now) public void backupNow() { AnswersProxy.get().logButton("Make Backup"); startProgress(getString(R.string.making_backup)); @@ -163,11 +177,18 @@ private void fetchBackups() { if (isFinishing()) return; stopProgress(); - listView.setAdapter(new BackupAdapter(BackupActivity.this, backupList)); + + BackupAdapter backupAdapter = new BackupAdapter(BackupActivity.this, backupList); + backupAdapter.setOnBackupListener(BackupActivity.this); + listView.setAdapter(backupAdapter); } }); } + private void deleteBackup(String backupName) { + + } + private void logout() { preferenceController.writeDropboxAccessToken(null); Auth.startOAuth2Authentication(BackupActivity.this, APP_KEY); diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/BackupAdapter.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/BackupAdapter.kt index e6a53ae..1b8e85d 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/BackupAdapter.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/adapter/BackupAdapter.kt @@ -6,10 +6,13 @@ import android.view.View import android.view.ViewGroup import android.widget.BaseAdapter import com.blogspot.e_kanivets.moneytracker.R +import kotlinx.android.synthetic.main.view_backup_item.view.ivDelete import kotlinx.android.synthetic.main.view_backup_item.view.tvTitle class BackupAdapter(private val context: Context, private val backups: List) : BaseAdapter() { + var onBackupListener: OnBackupListener? = null + override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { var view = convertView val viewHolder: ViewHolder? @@ -25,7 +28,10 @@ class BackupAdapter(private val context: Context, private val backups: List diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f6aaa2c..43efe77 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,28 +1,29 @@ - #ffffff - #E0E0E0 + #ffffff + #E0E0E0 - #f1f8e9 - #8bc34a - #689f38 - #33691e + #f1f8e9 + #8bc34a + #689f38 + #33691e - #ffebee - #f44336 - #d32f2f - #b71c1c + #ffebee + #f44336 + #d32f2f + #b71c1c - #f6f6f6 + #f6f6f6 + #8A000000 - #ffbd21 - #ff8a00 + #ffbd21 + #ff8a00 - #ffffffff - #de000000 - #8A000000 + #ffffffff + #de000000 + #8A000000 - #ffffff + #ffffff - #20000000 + #20000000 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3250acf..c94a4e2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,80 +1,80 @@ - Money Tracker - Title - Category - Price - Add income - Add expense - Add - Report - CHANGE THE DATE - TOTAL - Total income - Total expense - Delete - Day - Week - Month - Year - All time - Do you like MoneyTracker? - Rate it on Google Play! - Maybe Later - No, Thank You - Yes! - - Records - Accounts - Add income - Add expense - Add account - - Open navigation drawer - Close navigation drawer - - Export - Add account - Initial sum - Account - Transfer - From - To - Exchange rates - Add exchange rate - " -> " - Account was removed - - Short summary - Custom - Summary - Currency - Error! Specify exchange rates. - Amount - Settings - Settings - Default account - pref_default_account - pref_default_currency - %1$s - %2$s - Default currency - - Results - Incomes - Expenses - - pref_display_precision - Display precision - 9.99$ = 10$ - 9.99$ = 9$ - 9.99$ = 9.99$ - - Import/Export - Import - %1$s records has been imported - Help - To import records into application:\n + Money Tracker + Title + Category + Price + Add income + Add expense + Add + Report + CHANGE THE DATE + TOTAL + Total income + Total expense + Delete + Day + Week + Month + Year + All time + Do you like MoneyTracker? + Rate it on Google Play! + Maybe Later + No, Thank You + Yes! + + Records + Accounts + Add income + Add expense + Add account + + Open navigation drawer + Close navigation drawer + + Export + Add account + Initial sum + Account + Transfer + From + To + Exchange rates + Add exchange rate + " -> " + Account was removed + + Short summary + Custom + Summary + Currency + Error! Specify exchange rates. + Amount + Settings + Settings + Default account + pref_default_account + pref_default_currency + %1$s - %2$s + Default currency + + Results + Incomes + Expenses + + pref_display_precision + Display precision + 9.99$ = 10$ + 9.99$ = 9$ + 9.99$ = 9.99$ + + Import/Export + Import + %1$s records has been imported + Help + To import records into application:\n 1. Create CSV file in format - \n time;title;category;price;currency.\n 2. Copy its content to text field.\n @@ -83,59 +83,61 @@ Note: time - timestamp value in milliseconds; currency - 3 symbols code of currency.\n Example: 1466948795712;metro;transport;-20.0;UAH - / - Bank sells - Convert to - Bank buys - Convert from - - Date - Time - - Backup/Restore - Failed to create backup. - Failed to restore backup. - Chosen backup file %1$s has been restored successfully. - Backup is restored - Warning - Do you really want to erase all current data and restore backup file %1$s? Be sure to backup current data. - Backup now - - Edit income - Edit expense - - Importing records… - Making backup… - Restoring backup… - Fetching backups… - - pref_about - Version %1$s (Android %2$s) - About - Open Money Tracker (OMT) is an accounting application. You can manage your incomes and expenses in easy way. Accounts and currency exchange rates are also available.\n\nTo help us make OMT better, please report bugs to the 4PDA forum; new feature ideas are very welcome too. Find answers or start a discussion on forum.\n\nOMT is open source software, so everyone is encouraged to become a contributor. Non-developers can also help. For instance, you can help translate OMT, provide screenshots or blog about OMT.\n\nOMT is released under the GNU-GPL v3 license and source code is available on GitHub.\n\nDeveloper profile on LinkedIn. - - Field can\'t be empty. - You can\'t be so rich or so poor. - You can\'t be so rich. - None - It\'s too much for transfer. - It\'s too much for exchange. - Can\'t convert between same currencies. - Can\'t create a record in future. - At least one account is needed. - - Edit Account - Color - Goal - Restore - Archive - You can\'t archive a default account. - Delete account - Are you sure about deleting this account? It can\'t be restored after. - - Graph - Information - Operations - - + / + Bank sells + Convert to + Bank buys + Convert from + + Date + Time + + Backup/Restore + Failed to create backup. + Failed to restore backup. + Chosen backup file %1$s has been restored successfully. + Backup is restored + Warning + Do you really want to erase all current data and restore backup file %1$s? Be sure to backup current data. + Backup now + + Edit income + Edit expense + + Importing records… + Making backup… + Restoring backup… + Fetching backups… + + pref_about + Version %1$s (Android %2$s) + About + Open Money Tracker (OMT) is an accounting application. You can manage your incomes and expenses in easy way. Accounts and currency exchange rates are also available.\n\nTo help us make OMT better, please report bugs to the 4PDA forum; new feature ideas are very welcome too. Find answers or start a discussion on forum.\n\nOMT is open source software, so everyone is encouraged to become a contributor. Non-developers can also help. For instance, you can help translate OMT, provide screenshots or blog about OMT.\n\nOMT is released under the GNU-GPL v3 license and source code is available on GitHub.\n\nDeveloper profile on LinkedIn. + + Field can\'t be empty. + You can\'t be so rich or so poor. + You can\'t be so rich. + None + It\'s too much for transfer. + It\'s too much for exchange. + Can\'t convert between same currencies. + Can\'t create a record in future. + At least one account is needed. + + Edit Account + Color + Goal + Restore + Archive + You can\'t archive a default account. + Delete account + Are you sure about deleting this account? It can\'t be restored after. + + Graph + Information + Operations + + + Delete backup + Are you sure about deleting this backup file %1$s? It can\'t be restored after. From b4af9951eceb7cd079aa4040724c40c6811aebff Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Wed, 12 Sep 2018 17:01:59 +0200 Subject: [PATCH 20/33] #150. Extract async tasks from BackupController. --- .../activity/external/BackupActivity.java | 2 +- .../controller/BackupController.java | 273 ------------------ .../controller/backup/BackupController.java | 147 ++++++++++ .../backup/tasks/DropboxBackupAsyncTask.java | 56 ++++ .../DropboxFetchBackupListAsyncTask.java | 51 ++++ .../tasks/DropboxRestoreBackupAsyncTask.java | 52 ++++ .../di/module/ControllerModule.java | 2 +- 7 files changed, 308 insertions(+), 275 deletions(-) delete mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/BackupController.java create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.java create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxBackupAsyncTask.java create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxFetchBackupListAsyncTask.java create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxRestoreBackupAsyncTask.java diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java index 131998b..71a9a05 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java @@ -10,7 +10,7 @@ import com.blogspot.e_kanivets.moneytracker.R; import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity; import com.blogspot.e_kanivets.moneytracker.adapter.BackupAdapter; -import com.blogspot.e_kanivets.moneytracker.controller.BackupController; +import com.blogspot.e_kanivets.moneytracker.controller.backup.BackupController; import com.blogspot.e_kanivets.moneytracker.controller.PreferenceController; import com.blogspot.e_kanivets.moneytracker.util.AnswersProxy; import com.dropbox.core.DbxRequestConfig; diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/BackupController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/BackupController.java deleted file mode 100644 index 9364329..0000000 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/BackupController.java +++ /dev/null @@ -1,273 +0,0 @@ -package com.blogspot.e_kanivets.moneytracker.controller; - -import android.os.AsyncTask; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -import com.dropbox.core.DbxException; -import com.dropbox.core.v2.DbxClientV2; -import com.dropbox.core.v2.files.FileMetadata; -import com.dropbox.core.v2.files.Metadata; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Controller class to encapsulate backup logic. - * Created on 8/10/16. - * - * @author Evgenii Kanivets - */ -public class BackupController { - private FormatController formatController; - private String filesDir; - - public BackupController(FormatController formatController, String filesDir) { - this.formatController = formatController; - this.filesDir = filesDir; - } - - public void makeBackup(@NonNull DbxClientV2 dbClient, - @Nullable OnBackupListener listener) { - FileInputStream fileInputStream = readAppDb(); - long fileLength = readAppDbFileLength(); - if (fileInputStream == null) return; - - DropboxBackupAsyncTask asyncTask = new DropboxBackupAsyncTask(dbClient, - formatController.formatDateAndTime(System.currentTimeMillis()), - fileInputStream, fileLength, listener); - asyncTask.execute(); - } - - public void restoreBackup(@NonNull DbxClientV2 dbClient, @NonNull String backupName, - @Nullable final OnRestoreBackupListener listener) { - final File file = new File(getRestoreFileName()); - FileOutputStream outputStream = null; - try { - outputStream = new FileOutputStream(file); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - - if (outputStream == null) { - if (listener != null) listener.onRestoreFailure(null); - } else { - final FileOutputStream finalOutputStream = outputStream; - DropboxRestoreBackupAsyncTask asyncTask = new DropboxRestoreBackupAsyncTask(dbClient, - backupName, outputStream, new OnRestoreBackupListener() { - @Override - public void onRestoreSuccess() { - try { - finalOutputStream.close(); - } catch (IOException e) { - if (listener != null) listener.onRestoreFailure(null); - e.printStackTrace(); - } - - if (file.exists() && file.length() != 0) { - boolean renamed = file.renameTo(new File(getAppDbFileName())); - if (listener != null) { - if (renamed) listener.onRestoreSuccess(); - else listener.onRestoreFailure(null); - } - } - } - - @Override - public void onRestoreFailure(String reason) { - if (listener != null) listener.onRestoreFailure(reason); - } - }); - asyncTask.execute(); - } - } - - public void fetchBackups(@NonNull DbxClientV2 dbClient, - @Nullable OnFetchBackupListListener listener) { - DropboxFetchBackupListAsyncTask asyncTask = new DropboxFetchBackupListAsyncTask(dbClient, listener); - asyncTask.execute(); - } - - @Nullable - private FileInputStream readAppDb() { - File dbFile = new File(getAppDbFileName()); - FileInputStream fis = null; - - try { - fis = new FileInputStream(dbFile); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - - return fis; - } - - private long readAppDbFileLength() { - File dbFile = new File(getAppDbFileName()); - - if (dbFile.exists()) return dbFile.length(); - else return 0; - } - - @NonNull - private String getAppDbFileName() { - return filesDir + "/databases/database"; - } - - @NonNull - private String getRestoreFileName() { - return getAppDbFileName() + ".restore"; - } - - private static class DropboxBackupAsyncTask extends AsyncTask { - private DbxClientV2 dbClient; - private String fileName; - private FileInputStream fileInputStream; - private long fileLength; - - @Nullable - private OnBackupListener listener; - - public DropboxBackupAsyncTask(@NonNull DbxClientV2 dbClient, String fileName, - FileInputStream fileInputStream, long fileLength, - @Nullable OnBackupListener listener) { - this.dbClient = dbClient; - this.fileName = fileName; - this.fileInputStream = fileInputStream; - this.fileLength = fileLength; - this.listener = listener; - } - - @Override - protected String doInBackground(Void... params) { - FileMetadata info = null; - - try { - info = dbClient.files().upload("/" + fileName).uploadAndFinish(fileInputStream); - } catch (DbxException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - if (info == null) return null; - else return OnBackupListener.SUCCESS; - } - - @Override - protected void onPostExecute(String result) { - super.onPostExecute(result); - if (listener == null) return; - - if (OnBackupListener.SUCCESS.equals(result)) listener.onBackupSuccess(); - else listener.onBackupFailure(result); - } - } - - private static class DropboxFetchBackupListAsyncTask extends AsyncTask, List> { - private DbxClientV2 dbClient; - - @Nullable - private OnFetchBackupListListener listener; - - public DropboxFetchBackupListAsyncTask(DbxClientV2 dbClient, - @Nullable OnFetchBackupListListener listener) { - this.dbClient = dbClient; - this.listener = listener; - } - - @Override - protected List doInBackground(Void... params) { - List entryList = new ArrayList<>(); - List backupList = new ArrayList<>(); - - try { - entryList = dbClient.files().listFolder("").getEntries(); - } catch (DbxException e) { - e.printStackTrace(); - } - - for (Metadata entry : entryList) { - backupList.add(entry.getName()); - } - - return backupList; - } - - @Override - protected void onPostExecute(List backupList) { - super.onPostExecute(backupList); - if (listener == null) return; - - Collections.reverse(backupList); - listener.onBackupsFetched(backupList); - } - } - - private static class DropboxRestoreBackupAsyncTask extends AsyncTask { - private DbxClientV2 dbClient; - private String backupName; - private FileOutputStream outputStream; - - @Nullable - private OnRestoreBackupListener listener; - - public DropboxRestoreBackupAsyncTask(DbxClientV2 dbClient, String backupName, - FileOutputStream outputStream, - @Nullable OnRestoreBackupListener listener) { - this.dbClient = dbClient; - this.backupName = backupName; - this.outputStream = outputStream; - this.listener = listener; - } - - @Override - protected String doInBackground(Void... params) { - FileMetadata info = null; - try { - info = dbClient.files().download("/" + backupName).download(outputStream); - } catch (DbxException | IOException e) { - e.printStackTrace(); - } - - if (info == null) return null; - else return OnBackupListener.SUCCESS; - } - - @Override - protected void onPostExecute(String result) { - super.onPostExecute(result); - if (listener == null) return; - - if (OnBackupListener.SUCCESS.equals(result)) listener.onRestoreSuccess(); - else listener.onRestoreFailure(result); - } - } - - public interface OnBackupListener { - String SUCCESS = "success"; - String ERROR_AUTHENTICATION = "error_authentication"; - - void onBackupSuccess(); - - void onBackupFailure(String reason); - } - - public interface OnFetchBackupListListener { - void onBackupsFetched(@NonNull List backupList); - } - - public interface OnRestoreBackupListener { - String ERROR_AUTHENTICATION = "error_authentication"; - - void onRestoreSuccess(); - - void onRestoreFailure(String reason); - } -} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.java new file mode 100644 index 0000000..bb5d67a --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.java @@ -0,0 +1,147 @@ +package com.blogspot.e_kanivets.moneytracker.controller.backup; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.blogspot.e_kanivets.moneytracker.controller.FormatController; +import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxBackupAsyncTask; +import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxFetchBackupListAsyncTask; +import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxRestoreBackupAsyncTask; +import com.dropbox.core.v2.DbxClientV2; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; + +/** + * Controller class to encapsulate backup logic. + * Created on 8/10/16. + * + * @author Evgenii Kanivets + */ +public class BackupController { + + private FormatController formatController; + private String filesDir; + + public BackupController(FormatController formatController, String filesDir) { + this.formatController = formatController; + this.filesDir = filesDir; + } + + public void makeBackup(@NonNull DbxClientV2 dbClient, + @Nullable OnBackupListener listener) { + FileInputStream fileInputStream = readAppDb(); + long fileLength = readAppDbFileLength(); + if (fileInputStream == null) return; + + DropboxBackupAsyncTask asyncTask = new DropboxBackupAsyncTask(dbClient, + formatController.formatDateAndTime(System.currentTimeMillis()), + fileInputStream, fileLength, listener); + asyncTask.execute(); + } + + public void restoreBackup(@NonNull DbxClientV2 dbClient, @NonNull String backupName, + @Nullable final OnRestoreBackupListener listener) { + final File file = new File(getRestoreFileName()); + FileOutputStream outputStream = null; + try { + outputStream = new FileOutputStream(file); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + if (outputStream == null) { + if (listener != null) listener.onRestoreFailure(null); + } else { + final FileOutputStream finalOutputStream = outputStream; + DropboxRestoreBackupAsyncTask asyncTask = new DropboxRestoreBackupAsyncTask(dbClient, + backupName, outputStream, new OnRestoreBackupListener() { + @Override + public void onRestoreSuccess() { + try { + finalOutputStream.close(); + } catch (IOException e) { + if (listener != null) listener.onRestoreFailure(null); + e.printStackTrace(); + } + + if (file.exists() && file.length() != 0) { + boolean renamed = file.renameTo(new File(getAppDbFileName())); + if (listener != null) { + if (renamed) listener.onRestoreSuccess(); + else listener.onRestoreFailure(null); + } + } + } + + @Override + public void onRestoreFailure(String reason) { + if (listener != null) listener.onRestoreFailure(reason); + } + }); + asyncTask.execute(); + } + } + + public void fetchBackups(@NonNull DbxClientV2 dbClient, + @Nullable OnFetchBackupListListener listener) { + DropboxFetchBackupListAsyncTask asyncTask = new DropboxFetchBackupListAsyncTask(dbClient, listener); + asyncTask.execute(); + } + + @Nullable + private FileInputStream readAppDb() { + File dbFile = new File(getAppDbFileName()); + FileInputStream fis = null; + + try { + fis = new FileInputStream(dbFile); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + return fis; + } + + private long readAppDbFileLength() { + File dbFile = new File(getAppDbFileName()); + + if (dbFile.exists()) return dbFile.length(); + else return 0; + } + + @NonNull + private String getAppDbFileName() { + return filesDir + "/databases/database"; + } + + @NonNull + private String getRestoreFileName() { + return getAppDbFileName() + ".restore"; + } + + public interface OnBackupListener { + String SUCCESS = "success"; + String ERROR_AUTHENTICATION = "error_authentication"; + + void onBackupSuccess(); + + void onBackupFailure(String reason); + } + + public interface OnFetchBackupListListener { + void onBackupsFetched(@NonNull List backupList); + } + + public interface OnRestoreBackupListener { + String ERROR_AUTHENTICATION = "error_authentication"; + + void onRestoreSuccess(); + + void onRestoreFailure(String reason); + } +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxBackupAsyncTask.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxBackupAsyncTask.java new file mode 100644 index 0000000..f764dc0 --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxBackupAsyncTask.java @@ -0,0 +1,56 @@ +package com.blogspot.e_kanivets.moneytracker.controller.backup.tasks; + +import android.os.AsyncTask; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import com.blogspot.e_kanivets.moneytracker.controller.backup.BackupController; +import com.dropbox.core.DbxException; +import com.dropbox.core.v2.DbxClientV2; +import com.dropbox.core.v2.files.FileMetadata; +import java.io.FileInputStream; +import java.io.IOException; + +public class DropboxBackupAsyncTask extends AsyncTask { + private DbxClientV2 dbClient; + private String fileName; + private FileInputStream fileInputStream; + private long fileLength; + + @Nullable + private BackupController.OnBackupListener listener; + + public DropboxBackupAsyncTask(@NonNull DbxClientV2 dbClient, String fileName, + FileInputStream fileInputStream, long fileLength, + @Nullable BackupController.OnBackupListener listener) { + this.dbClient = dbClient; + this.fileName = fileName; + this.fileInputStream = fileInputStream; + this.fileLength = fileLength; + this.listener = listener; + } + + @Override + protected String doInBackground(Void... params) { + FileMetadata info = null; + + try { + info = dbClient.files().upload("/" + fileName).uploadAndFinish(fileInputStream); + } catch (DbxException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + if (info == null) return null; + else return BackupController.OnBackupListener.SUCCESS; + } + + @Override + protected void onPostExecute(String result) { + super.onPostExecute(result); + if (listener == null) return; + + if (BackupController.OnBackupListener.SUCCESS.equals(result)) listener.onBackupSuccess(); + else listener.onBackupFailure(result); + } +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxFetchBackupListAsyncTask.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxFetchBackupListAsyncTask.java new file mode 100644 index 0000000..cfc0354 --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxFetchBackupListAsyncTask.java @@ -0,0 +1,51 @@ +package com.blogspot.e_kanivets.moneytracker.controller.backup.tasks; + +import android.os.AsyncTask; +import android.support.annotation.Nullable; +import com.blogspot.e_kanivets.moneytracker.controller.backup.BackupController; +import com.dropbox.core.DbxException; +import com.dropbox.core.v2.DbxClientV2; +import com.dropbox.core.v2.files.Metadata; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class DropboxFetchBackupListAsyncTask extends AsyncTask, List> { + private DbxClientV2 dbClient; + + @Nullable + private BackupController.OnFetchBackupListListener listener; + + public DropboxFetchBackupListAsyncTask(DbxClientV2 dbClient, + @Nullable BackupController.OnFetchBackupListListener listener) { + this.dbClient = dbClient; + this.listener = listener; + } + + @Override + protected List doInBackground(Void... params) { + List entryList = new ArrayList<>(); + List backupList = new ArrayList<>(); + + try { + entryList = dbClient.files().listFolder("").getEntries(); + } catch (DbxException e) { + e.printStackTrace(); + } + + for (Metadata entry : entryList) { + backupList.add(entry.getName()); + } + + return backupList; + } + + @Override + protected void onPostExecute(List backupList) { + super.onPostExecute(backupList); + if (listener == null) return; + + Collections.reverse(backupList); + listener.onBackupsFetched(backupList); + } +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxRestoreBackupAsyncTask.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxRestoreBackupAsyncTask.java new file mode 100644 index 0000000..b65c092 --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxRestoreBackupAsyncTask.java @@ -0,0 +1,52 @@ +package com.blogspot.e_kanivets.moneytracker.controller.backup.tasks; + +import android.os.AsyncTask; +import android.support.annotation.Nullable; +import com.blogspot.e_kanivets.moneytracker.controller.backup.BackupController; +import com.dropbox.core.DbxException; +import com.dropbox.core.v2.DbxClientV2; +import com.dropbox.core.v2.files.FileMetadata; +import java.io.FileOutputStream; +import java.io.IOException; + +public class DropboxRestoreBackupAsyncTask extends AsyncTask { + private DbxClientV2 dbClient; + private String backupName; + private FileOutputStream outputStream; + + @Nullable private BackupController.OnRestoreBackupListener listener; + + public DropboxRestoreBackupAsyncTask(DbxClientV2 dbClient, String backupName, FileOutputStream outputStream, + @Nullable BackupController.OnRestoreBackupListener listener) { + this.dbClient = dbClient; + this.backupName = backupName; + this.outputStream = outputStream; + this.listener = listener; + } + + @Override protected String doInBackground(Void... params) { + FileMetadata info = null; + try { + info = dbClient.files().download("/" + backupName).download(outputStream); + } catch (DbxException | IOException e) { + e.printStackTrace(); + } + + if (info == null) { + return null; + } else { + return BackupController.OnBackupListener.SUCCESS; + } + } + + @Override protected void onPostExecute(String result) { + super.onPostExecute(result); + if (listener == null) return; + + if (BackupController.OnBackupListener.SUCCESS.equals(result)) { + listener.onRestoreSuccess(); + } else { + listener.onRestoreFailure(result); + } + } +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java index af86465..3ec446f 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java @@ -3,7 +3,7 @@ import android.content.Context; import android.support.annotation.NonNull; -import com.blogspot.e_kanivets.moneytracker.controller.BackupController; +import com.blogspot.e_kanivets.moneytracker.controller.backup.BackupController; import com.blogspot.e_kanivets.moneytracker.controller.external.ExportController; import com.blogspot.e_kanivets.moneytracker.controller.FormatController; import com.blogspot.e_kanivets.moneytracker.controller.PeriodController; From 64cae2dc54e8bf095a8228a68aa91086fb90aa5b Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Wed, 12 Sep 2018 17:33:01 +0200 Subject: [PATCH 21/33] #150. Refactore BackupListener. --- .../controller/backup/BackupController.java | 94 ++----------------- .../backup/tasks/DropboxBackupAsyncTask.java | 51 ++++++---- .../tasks/DropboxRestoreBackupAsyncTask.java | 48 ++++++++-- 3 files changed, 85 insertions(+), 108 deletions(-) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.java index bb5d67a..42efa7f 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.java @@ -9,11 +9,6 @@ import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxRestoreBackupAsyncTask; import com.dropbox.core.v2.DbxClientV2; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; import java.util.List; /** @@ -32,98 +27,29 @@ public BackupController(FormatController formatController, String filesDir) { this.filesDir = filesDir; } - public void makeBackup(@NonNull DbxClientV2 dbClient, - @Nullable OnBackupListener listener) { - FileInputStream fileInputStream = readAppDb(); - long fileLength = readAppDbFileLength(); - if (fileInputStream == null) return; - - DropboxBackupAsyncTask asyncTask = new DropboxBackupAsyncTask(dbClient, - formatController.formatDateAndTime(System.currentTimeMillis()), - fileInputStream, fileLength, listener); + public void makeBackup(@NonNull DbxClientV2 dbClient, @Nullable OnBackupListener listener) { + DropboxBackupAsyncTask asyncTask = + new DropboxBackupAsyncTask(dbClient, formatController.formatDateAndTime(System.currentTimeMillis()), + getAppDbFileName(), listener); asyncTask.execute(); } public void restoreBackup(@NonNull DbxClientV2 dbClient, @NonNull String backupName, - @Nullable final OnRestoreBackupListener listener) { - final File file = new File(getRestoreFileName()); - FileOutputStream outputStream = null; - try { - outputStream = new FileOutputStream(file); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - - if (outputStream == null) { - if (listener != null) listener.onRestoreFailure(null); - } else { - final FileOutputStream finalOutputStream = outputStream; - DropboxRestoreBackupAsyncTask asyncTask = new DropboxRestoreBackupAsyncTask(dbClient, - backupName, outputStream, new OnRestoreBackupListener() { - @Override - public void onRestoreSuccess() { - try { - finalOutputStream.close(); - } catch (IOException e) { - if (listener != null) listener.onRestoreFailure(null); - e.printStackTrace(); - } - - if (file.exists() && file.length() != 0) { - boolean renamed = file.renameTo(new File(getAppDbFileName())); - if (listener != null) { - if (renamed) listener.onRestoreSuccess(); - else listener.onRestoreFailure(null); - } - } - } - - @Override - public void onRestoreFailure(String reason) { - if (listener != null) listener.onRestoreFailure(reason); - } - }); - asyncTask.execute(); - } + @Nullable final OnRestoreBackupListener listener) { + DropboxRestoreBackupAsyncTask asyncTask = + new DropboxRestoreBackupAsyncTask(dbClient, getAppDbFileName(), backupName, listener); + asyncTask.execute(); } - public void fetchBackups(@NonNull DbxClientV2 dbClient, - @Nullable OnFetchBackupListListener listener) { + public void fetchBackups(@NonNull DbxClientV2 dbClient, @Nullable OnFetchBackupListListener listener) { DropboxFetchBackupListAsyncTask asyncTask = new DropboxFetchBackupListAsyncTask(dbClient, listener); asyncTask.execute(); } - @Nullable - private FileInputStream readAppDb() { - File dbFile = new File(getAppDbFileName()); - FileInputStream fis = null; - - try { - fis = new FileInputStream(dbFile); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - - return fis; - } - - private long readAppDbFileLength() { - File dbFile = new File(getAppDbFileName()); - - if (dbFile.exists()) return dbFile.length(); - else return 0; - } - - @NonNull - private String getAppDbFileName() { + @NonNull private String getAppDbFileName() { return filesDir + "/databases/database"; } - @NonNull - private String getRestoreFileName() { - return getAppDbFileName() + ".restore"; - } - public interface OnBackupListener { String SUCCESS = "success"; String ERROR_AUTHENTICATION = "error_authentication"; diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxBackupAsyncTask.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxBackupAsyncTask.java index f764dc0..9174807 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxBackupAsyncTask.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxBackupAsyncTask.java @@ -7,30 +7,31 @@ import com.dropbox.core.DbxException; import com.dropbox.core.v2.DbxClientV2; import com.dropbox.core.v2.files.FileMetadata; +import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; public class DropboxBackupAsyncTask extends AsyncTask { + private DbxClientV2 dbClient; + private String appDbFileName; private String fileName; - private FileInputStream fileInputStream; - private long fileLength; - @Nullable - private BackupController.OnBackupListener listener; + @Nullable private BackupController.OnBackupListener listener; - public DropboxBackupAsyncTask(@NonNull DbxClientV2 dbClient, String fileName, - FileInputStream fileInputStream, long fileLength, + public DropboxBackupAsyncTask(@NonNull DbxClientV2 dbClient, String fileName, String appDbFileName, @Nullable BackupController.OnBackupListener listener) { this.dbClient = dbClient; this.fileName = fileName; - this.fileInputStream = fileInputStream; - this.fileLength = fileLength; + this.appDbFileName = appDbFileName; this.listener = listener; } - @Override - protected String doInBackground(Void... params) { + @Override protected String doInBackground(Void... params) { + FileInputStream fileInputStream = readAppDb(); + if (fileInputStream == null) return null; + FileMetadata info = null; try { @@ -41,16 +42,34 @@ protected String doInBackground(Void... params) { e.printStackTrace(); } - if (info == null) return null; - else return BackupController.OnBackupListener.SUCCESS; + if (info == null) { + return null; + } else { + return BackupController.OnBackupListener.SUCCESS; + } } - @Override - protected void onPostExecute(String result) { + @Override protected void onPostExecute(String result) { super.onPostExecute(result); if (listener == null) return; - if (BackupController.OnBackupListener.SUCCESS.equals(result)) listener.onBackupSuccess(); - else listener.onBackupFailure(result); + if (BackupController.OnBackupListener.SUCCESS.equals(result)) { + listener.onBackupSuccess(); + } else { + listener.onBackupFailure(result); + } + } + + @Nullable private FileInputStream readAppDb() { + File dbFile = new File(appDbFileName); + FileInputStream fis = null; + + try { + fis = new FileInputStream(dbFile); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + return fis; } } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxRestoreBackupAsyncTask.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxRestoreBackupAsyncTask.java index b65c092..a3e108a 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxRestoreBackupAsyncTask.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxRestoreBackupAsyncTask.java @@ -1,41 +1,69 @@ package com.blogspot.e_kanivets.moneytracker.controller.backup.tasks; import android.os.AsyncTask; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.blogspot.e_kanivets.moneytracker.controller.backup.BackupController; import com.dropbox.core.DbxException; import com.dropbox.core.v2.DbxClientV2; import com.dropbox.core.v2.files.FileMetadata; +import java.io.File; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class DropboxRestoreBackupAsyncTask extends AsyncTask { + private DbxClientV2 dbClient; + private String appDbFileName; private String backupName; - private FileOutputStream outputStream; @Nullable private BackupController.OnRestoreBackupListener listener; - public DropboxRestoreBackupAsyncTask(DbxClientV2 dbClient, String backupName, FileOutputStream outputStream, + public DropboxRestoreBackupAsyncTask(DbxClientV2 dbClient, String appDbFileName, String backupName, @Nullable BackupController.OnRestoreBackupListener listener) { this.dbClient = dbClient; + this.appDbFileName = appDbFileName; this.backupName = backupName; - this.outputStream = outputStream; this.listener = listener; } @Override protected String doInBackground(Void... params) { - FileMetadata info = null; + final File file = new File(getRestoreFileName()); + FileOutputStream outputStream = null; try { - info = dbClient.files().download("/" + backupName).download(outputStream); - } catch (DbxException | IOException e) { + outputStream = new FileOutputStream(file); + } catch (FileNotFoundException e) { e.printStackTrace(); } - if (info == null) { + if (outputStream == null) { return null; } else { - return BackupController.OnBackupListener.SUCCESS; + FileMetadata info = null; + try { + info = dbClient.files().download("/" + backupName).download(outputStream); + } catch (DbxException | IOException e) { + e.printStackTrace(); + } + + if (info == null) { + return null; + } else { + try { + outputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + + if (file.exists() && file.length() != 0) { + boolean renamed = file.renameTo(new File(appDbFileName)); + return renamed ? BackupController.OnBackupListener.SUCCESS : null; + } else { + return null; + } + } } } @@ -49,4 +77,8 @@ public DropboxRestoreBackupAsyncTask(DbxClientV2 dbClient, String backupName, Fi listener.onRestoreFailure(result); } } + + @NonNull private String getRestoreFileName() { + return appDbFileName + ".restore"; + } } From e9c945e7183d2d7ed99691a1bda5cc1beee5703e Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Wed, 12 Sep 2018 17:44:06 +0200 Subject: [PATCH 22/33] #150. Consolidate OnBackupListener. --- .../activity/external/BackupActivity.java | 128 +++++++++--------- .../controller/backup/BackupController.java | 73 ---------- .../controller/backup/BackupController.kt | 55 ++++++++ .../DropboxFetchBackupListAsyncTask.java | 4 +- .../tasks/DropboxRestoreBackupAsyncTask.java | 6 +- 5 files changed, 125 insertions(+), 141 deletions(-) delete mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.java create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.kt diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java index 71a9a05..04afc5f 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java @@ -27,7 +27,8 @@ import org.jetbrains.annotations.NotNull; import timber.log.Timber; -public class BackupActivity extends BaseBackActivity implements BackupAdapter.OnBackupListener { +public class BackupActivity extends BaseBackActivity + implements BackupAdapter.OnBackupListener, BackupController.OnBackupListener { private static final String APP_KEY = "5lqugcckdy9y6lj"; @Inject PreferenceController preferenceController; @@ -51,6 +52,7 @@ public class BackupActivity extends BaseBackActivity implements BackupAdapter.On } else { DbxRequestConfig config = new DbxRequestConfig("open_money_tracker"); dbClient = new DbxClientV2(config, accessToken); + backupController.setOnBackupListener(this); fetchBackups(); } @@ -91,30 +93,72 @@ public class BackupActivity extends BaseBackActivity implements BackupAdapter.On builder.show(); } - @OnClick(R.id.btn_backup_now) public void backupNow() { - AnswersProxy.get().logButton("Make Backup"); - startProgress(getString(R.string.making_backup)); - backupController.makeBackup(dbClient, new BackupController.OnBackupListener() { - @Override public void onBackupSuccess() { - AnswersProxy.get().logEvent("Backup success"); - Timber.d("Backup success."); - if (isFinishing()) return; + @Override public void onBackupsFetched(@NonNull List backupList) { + if (isFinishing()) return; - stopProgress(); - fetchBackups(); - } + stopProgress(); + + BackupAdapter backupAdapter = new BackupAdapter(BackupActivity.this, backupList); + backupAdapter.setOnBackupListener(BackupActivity.this); + listView.setAdapter(backupAdapter); + } + + @Override public void onBackupSuccess() { + AnswersProxy.get().logEvent("Backup success"); + Timber.d("Backup success."); + if (isFinishing()) return; + + stopProgress(); + fetchBackups(); + } + + @Override public void onBackupFailure(String reason) { + AnswersProxy.get().logEvent("Backup failure"); + Timber.d("Backup failure."); + if (isFinishing()) return; + + stopProgress(); + showToast(R.string.failed_create_backup); + + if (BackupController.OnBackupListener.ERROR_AUTHENTICATION.equals(reason)) logout(); + } - @Override public void onBackupFailure(String reason) { - AnswersProxy.get().logEvent("Backup failure"); - Timber.d("Backup failure."); - if (isFinishing()) return; + @Override public void onRestoreSuccess(@NonNull String backupName) { + AnswersProxy.get().logEvent("Restore Success"); + Timber.d("Restore success."); + if (isFinishing()) return; - stopProgress(); - showToast(R.string.failed_create_backup); + stopProgress(); - if (BackupController.OnBackupListener.ERROR_AUTHENTICATION.equals(reason)) logout(); + AlertDialog.Builder builder = new AlertDialog.Builder(BackupActivity.this); + builder.setTitle(getString(R.string.backup_is_restored)); + builder.setMessage(getString(R.string.backup_restored, backupName)); + builder.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override public void onDismiss(DialogInterface dialog) { + MtApp.get().buildAppComponent(); + setResult(RESULT_OK); + finish(); } }); + builder.setPositiveButton(android.R.string.ok, null); + builder.show(); + } + + @Override public void onRestoreFailure(String reason) { + AnswersProxy.get().logEvent("Restore Failure"); + Timber.d("Restore failure."); + if (isFinishing()) return; + + stopProgress(); + showToast(R.string.failed_restore_backup); + + if (BackupController.OnBackupListener.ERROR_AUTHENTICATION.equals(reason)) logout(); + } + + @OnClick(R.id.btn_backup_now) public void backupNow() { + AnswersProxy.get().logButton("Make Backup"); + startProgress(getString(R.string.making_backup)); + backupController.makeBackup(dbClient); } @OnItemClick(R.id.list_view) public void restoreBackupClicked(int position) { @@ -135,54 +179,12 @@ public class BackupActivity extends BaseBackActivity implements BackupAdapter.On private void restoreBackup(final String backupName) { startProgress(getString(R.string.restoring_backup)); - backupController.restoreBackup(dbClient, backupName, new BackupController.OnRestoreBackupListener() { - @Override public void onRestoreSuccess() { - AnswersProxy.get().logEvent("Restore Success"); - Timber.d("Restore success."); - if (isFinishing()) return; - - stopProgress(); - - AlertDialog.Builder builder = new AlertDialog.Builder(BackupActivity.this); - builder.setTitle(getString(R.string.backup_is_restored)); - builder.setMessage(getString(R.string.backup_restored, backupName)); - builder.setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override public void onDismiss(DialogInterface dialog) { - MtApp.get().buildAppComponent(); - setResult(RESULT_OK); - finish(); - } - }); - builder.setPositiveButton(android.R.string.ok, null); - builder.show(); - } - - @Override public void onRestoreFailure(String reason) { - AnswersProxy.get().logEvent("Restore Failure"); - Timber.d("Restore failure."); - if (isFinishing()) return; - - stopProgress(); - showToast(R.string.failed_restore_backup); - - if (BackupController.OnRestoreBackupListener.ERROR_AUTHENTICATION.equals(reason)) logout(); - } - }); + backupController.restoreBackup(dbClient, backupName); } private void fetchBackups() { startProgress(getString(R.string.fetching_backups)); - backupController.fetchBackups(dbClient, new BackupController.OnFetchBackupListListener() { - @Override public void onBackupsFetched(@NonNull List backupList) { - if (isFinishing()) return; - - stopProgress(); - - BackupAdapter backupAdapter = new BackupAdapter(BackupActivity.this, backupList); - backupAdapter.setOnBackupListener(BackupActivity.this); - listView.setAdapter(backupAdapter); - } - }); + backupController.fetchBackups(dbClient); } private void deleteBackup(String backupName) { diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.java deleted file mode 100644 index 42efa7f..0000000 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.blogspot.e_kanivets.moneytracker.controller.backup; - -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -import com.blogspot.e_kanivets.moneytracker.controller.FormatController; -import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxBackupAsyncTask; -import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxFetchBackupListAsyncTask; -import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxRestoreBackupAsyncTask; -import com.dropbox.core.v2.DbxClientV2; - -import java.util.List; - -/** - * Controller class to encapsulate backup logic. - * Created on 8/10/16. - * - * @author Evgenii Kanivets - */ -public class BackupController { - - private FormatController formatController; - private String filesDir; - - public BackupController(FormatController formatController, String filesDir) { - this.formatController = formatController; - this.filesDir = filesDir; - } - - public void makeBackup(@NonNull DbxClientV2 dbClient, @Nullable OnBackupListener listener) { - DropboxBackupAsyncTask asyncTask = - new DropboxBackupAsyncTask(dbClient, formatController.formatDateAndTime(System.currentTimeMillis()), - getAppDbFileName(), listener); - asyncTask.execute(); - } - - public void restoreBackup(@NonNull DbxClientV2 dbClient, @NonNull String backupName, - @Nullable final OnRestoreBackupListener listener) { - DropboxRestoreBackupAsyncTask asyncTask = - new DropboxRestoreBackupAsyncTask(dbClient, getAppDbFileName(), backupName, listener); - asyncTask.execute(); - } - - public void fetchBackups(@NonNull DbxClientV2 dbClient, @Nullable OnFetchBackupListListener listener) { - DropboxFetchBackupListAsyncTask asyncTask = new DropboxFetchBackupListAsyncTask(dbClient, listener); - asyncTask.execute(); - } - - @NonNull private String getAppDbFileName() { - return filesDir + "/databases/database"; - } - - public interface OnBackupListener { - String SUCCESS = "success"; - String ERROR_AUTHENTICATION = "error_authentication"; - - void onBackupSuccess(); - - void onBackupFailure(String reason); - } - - public interface OnFetchBackupListListener { - void onBackupsFetched(@NonNull List backupList); - } - - public interface OnRestoreBackupListener { - String ERROR_AUTHENTICATION = "error_authentication"; - - void onRestoreSuccess(); - - void onRestoreFailure(String reason); - } -} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.kt new file mode 100644 index 0000000..23f65ac --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.kt @@ -0,0 +1,55 @@ +package com.blogspot.e_kanivets.moneytracker.controller.backup + +import com.blogspot.e_kanivets.moneytracker.controller.FormatController +import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxBackupAsyncTask +import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxFetchBackupListAsyncTask +import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxRestoreBackupAsyncTask +import com.dropbox.core.v2.DbxClientV2 + +/** + * Controller class to encapsulate backup logic. + * Created on 8/10/16. + * + * @author Evgenii Kanivets + */ +class BackupController(private val formatController: FormatController, filesDir: String) { + + var onBackupListener: OnBackupListener? = null + + private val appDbFileName: String = "$filesDir/databases/database" + + fun makeBackup(dbClient: DbxClientV2) { + val fileName = formatController.formatDateAndTime(System.currentTimeMillis()) + val asyncTask = DropboxBackupAsyncTask(dbClient, fileName, appDbFileName, onBackupListener) + asyncTask.execute() + } + + fun restoreBackup(dbClient: DbxClientV2, backupName: String) { + val asyncTask = DropboxRestoreBackupAsyncTask(dbClient, appDbFileName, backupName, onBackupListener) + asyncTask.execute() + } + + fun fetchBackups(dbClient: DbxClientV2) { + val asyncTask = DropboxFetchBackupListAsyncTask(dbClient, onBackupListener) + asyncTask.execute() + } + + interface OnBackupListener { + + fun onBackupsFetched(backupList: List) + + fun onBackupSuccess() + + fun onBackupFailure(reason: String?) + + fun onRestoreSuccess(backupName: String) + + fun onRestoreFailure(reason: String?) + + companion object { + const val SUCCESS = "success" + const val ERROR_AUTHENTICATION = "error_authentication" + } + } + +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxFetchBackupListAsyncTask.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxFetchBackupListAsyncTask.java index cfc0354..1d35451 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxFetchBackupListAsyncTask.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxFetchBackupListAsyncTask.java @@ -14,10 +14,10 @@ public class DropboxFetchBackupListAsyncTask extends AsyncTask Date: Sat, 15 Sep 2018 21:06:54 +0200 Subject: [PATCH 23/33] #150. Implement Dropbox backup removal. --- .../activity/external/BackupActivity.java | 26 ++++++++-- .../controller/backup/BackupController.kt | 18 ++++--- .../tasks/DropboxRemoveBackupAsyncTask.java | 51 +++++++++++++++++++ 3 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxRemoveBackupAsyncTask.java diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java index 04afc5f..1f6e1ab 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java @@ -25,6 +25,7 @@ import butterknife.OnClick; import butterknife.OnItemClick; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import timber.log.Timber; public class BackupActivity extends BaseBackActivity @@ -86,7 +87,7 @@ public class BackupActivity extends BaseBackActivity builder.setMessage(getString(R.string.delete_backup_message, backupName)); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - deleteBackup(backupName); + removeBackup(backupName); } }); builder.setNegativeButton(android.R.string.cancel, null); @@ -155,6 +156,24 @@ public class BackupActivity extends BaseBackActivity if (BackupController.OnBackupListener.ERROR_AUTHENTICATION.equals(reason)) logout(); } + @Override public void onRemoveSuccess() { + AnswersProxy.get().logEvent("Remove Success"); + Timber.d("Remove success."); + if (isFinishing()) return; + + stopProgress(); + fetchBackups(); + } + + @Override public void onRemoveFailure(@Nullable String reason) { + AnswersProxy.get().logEvent("Remove Failure"); + Timber.d("Remove failure."); + if (isFinishing()) return; + + stopProgress(); + showToast(reason); + } + @OnClick(R.id.btn_backup_now) public void backupNow() { AnswersProxy.get().logButton("Make Backup"); startProgress(getString(R.string.making_backup)); @@ -187,8 +206,9 @@ private void fetchBackups() { backupController.fetchBackups(dbClient); } - private void deleteBackup(String backupName) { - + private void removeBackup(String backupName) { + startProgress(""); + backupController.removeBackup(dbClient, backupName); } private void logout() { diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.kt index 23f65ac..a9ffb3c 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/BackupController.kt @@ -3,6 +3,7 @@ package com.blogspot.e_kanivets.moneytracker.controller.backup import com.blogspot.e_kanivets.moneytracker.controller.FormatController import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxBackupAsyncTask import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxFetchBackupListAsyncTask +import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxRemoveBackupAsyncTask import com.blogspot.e_kanivets.moneytracker.controller.backup.tasks.DropboxRestoreBackupAsyncTask import com.dropbox.core.v2.DbxClientV2 @@ -20,18 +21,19 @@ class BackupController(private val formatController: FormatController, filesDir: fun makeBackup(dbClient: DbxClientV2) { val fileName = formatController.formatDateAndTime(System.currentTimeMillis()) - val asyncTask = DropboxBackupAsyncTask(dbClient, fileName, appDbFileName, onBackupListener) - asyncTask.execute() + DropboxBackupAsyncTask(dbClient, fileName, appDbFileName, onBackupListener).execute() } fun restoreBackup(dbClient: DbxClientV2, backupName: String) { - val asyncTask = DropboxRestoreBackupAsyncTask(dbClient, appDbFileName, backupName, onBackupListener) - asyncTask.execute() + DropboxRestoreBackupAsyncTask(dbClient, appDbFileName, backupName, onBackupListener).execute() } fun fetchBackups(dbClient: DbxClientV2) { - val asyncTask = DropboxFetchBackupListAsyncTask(dbClient, onBackupListener) - asyncTask.execute() + DropboxFetchBackupListAsyncTask(dbClient, onBackupListener).execute() + } + + fun removeBackup(dbClient: DbxClientV2, backupName: String) { + DropboxRemoveBackupAsyncTask(dbClient, backupName, onBackupListener).execute() } interface OnBackupListener { @@ -46,6 +48,10 @@ class BackupController(private val formatController: FormatController, filesDir: fun onRestoreFailure(reason: String?) + fun onRemoveSuccess() + + fun onRemoveFailure(reason: String?) + companion object { const val SUCCESS = "success" const val ERROR_AUTHENTICATION = "error_authentication" diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxRemoveBackupAsyncTask.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxRemoveBackupAsyncTask.java new file mode 100644 index 0000000..db42e7a --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/backup/tasks/DropboxRemoveBackupAsyncTask.java @@ -0,0 +1,51 @@ +package com.blogspot.e_kanivets.moneytracker.controller.backup.tasks; + +import android.os.AsyncTask; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import com.blogspot.e_kanivets.moneytracker.controller.backup.BackupController; +import com.dropbox.core.DbxException; +import com.dropbox.core.v2.DbxClientV2; +import com.dropbox.core.v2.files.DeleteResult; +import com.dropbox.core.v2.files.FileMetadata; +import com.dropbox.core.v2.files.Metadata; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +public class DropboxRemoveBackupAsyncTask extends AsyncTask { + + private DbxClientV2 dbClient; + private String backupName; + + @Nullable private BackupController.OnBackupListener listener; + + public DropboxRemoveBackupAsyncTask(DbxClientV2 dbClient, String backupName, + @Nullable BackupController.OnBackupListener listener) { + this.dbClient = dbClient; + this.backupName = backupName; + this.listener = listener; + } + + @Override protected String doInBackground(Void... params) { + try { + Metadata metadata = dbClient.files().deleteV2("/" + backupName).getMetadata(); + return metadata == null ? null : BackupController.OnBackupListener.SUCCESS; + } catch (DbxException e) { + e.printStackTrace(); + return e.getMessage(); + } + } + + @Override protected void onPostExecute(String result) { + super.onPostExecute(result); + if (listener == null) return; + + if (BackupController.OnBackupListener.SUCCESS.equals(result)) { + listener.onRemoveSuccess(); + } else { + listener.onRemoveFailure(result); + } + } +} From 3bb5ab2eccbf1512f31989c055933b1352c723b8 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Sat, 15 Sep 2018 21:18:19 +0200 Subject: [PATCH 24/33] Add 'Removing backup' message. --- .../activity/external/BackupActivity.java | 2 +- app/src/main/res/values-ru/strings.xml | 237 +++++++++--------- app/src/main/res/values-uk/strings.xml | 1 + app/src/main/res/values-zh/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 5 files changed, 123 insertions(+), 119 deletions(-) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java index 1f6e1ab..ca078be 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/BackupActivity.java @@ -207,7 +207,7 @@ private void fetchBackups() { } private void removeBackup(String backupName) { - startProgress(""); + startProgress(getString(R.string.removing_backup)); backupController.removeBackup(dbClient, backupName); } diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ff1375e..1cd0249 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -1,73 +1,73 @@ - Money Tracker - - Название - Категория - Цена - Добавить доход - Добавить расход - Добавить - - Отчет - ИЗМЕНИТЬ ДАТУ - СУММА - Суммарный доход - Суммарный расход - Удалить - - День - Неделя - Месяц - Год - За все время - - Вам нравится MoneyTracker? - Оцените его на Google Play! - Может быть позже - Нет, спасибо - Да! - - Записи - Счета - Добавить доход - Добавить расход - Добавить счет - - Экспорт - Добавить счет - Начальная сумма - Счет - Перевод - Со счета - На счет - Курсы обмена - Добавить курс обмена - Счет был удален - - Краткий отчет - Другой - Сводка - Валюта - Ошибка! Укажите курсы обмена. - Количество - Настройки - Настройки - Счет по умолчанию - Валюта по умолчанию - - Итоги - Доходы - Расходы - - Точность отображения - - Импорт/Экспорт - Импорт - %1$s записей было импортировано - Справка - Для импорта записей в приложение:\n + Money Tracker + + Название + Категория + Цена + Добавить доход + Добавить расход + Добавить + + Отчет + ИЗМЕНИТЬ ДАТУ + СУММА + Суммарный доход + Суммарный расход + Удалить + + День + Неделя + Месяц + Год + За все время + + Вам нравится MoneyTracker? + Оцените его на Google Play! + Может быть позже + Нет, спасибо + Да! + + Записи + Счета + Добавить доход + Добавить расход + Добавить счет + + Экспорт + Добавить счет + Начальная сумма + Счет + Перевод + Со счета + На счет + Курсы обмена + Добавить курс обмена + Счет был удален + + Краткий отчет + Другой + Сводка + Валюта + Ошибка! Укажите курсы обмена. + Количество + Настройки + Настройки + Счет по умолчанию + Валюта по умолчанию + + Итоги + Доходы + Расходы + + Точность отображения + + Импорт/Экспорт + Импорт + %1$s записей было импортировано + Справка + Для импорта записей в приложение:\n 1. Создайте CSV файл в формате - \n время;заголовок;категория;цена;валюта.\n 2. Скопируйте его контент в текстовое поле.\n @@ -76,55 +76,56 @@ Важно: время - метка времени в миллисекундах; валюта - 3-х символьный код валюты.\n Пример: 1466948795712;метро;транспорт;-20.0;UAH - Банк продает - Конвертировать в - Банк покупает - Конвертировать из - - Дата - Время - - Бэкап/Восстановление - Не удалось создать бэкап. - Не удалось восстановить бэкап. - Выбранный бэкап %1$s был успешно восстановлен. - Бэкап восстановлен - Предупреждение - Вы действительно хотите удалить все текущие данные и восстановить бэкап %1$s? Пожалуйста, сделайте бэкап текущих данных. - Сделать бэкап - - Редактировать доход - Редактировать расход - - Импортирование записей… - Создание бэкапа… - Восстановление бэкапа… - Загрузка бэкапов… - - Версия %1$s (Android %2$s) - О приложении - Open Money Tracker (OMT) это приложения для ведения личных финансов. Вы легко можете управлять доходами и расходами. Также доступны счета и курсы обмена.\n\nДля того чтобы помочь сделать OMT лучше, пишите о багах на форуме 4PDA; идеи новых функций также приветствуются. Ищите ответы или начинайте обсуждение на форуме.\n\nOMT это проект с открытым исходным кодом, так что каждый может помочь с его разработкой. Не-разработчики также могут помочь. Например, вы можете помочь с переводом, предоставить скриншоты или написать статью в блоге о OMT.\n\nOMT выпущен под GNU-GPL v3 лицензией и исходный код доступен на GitHub.\n\nПрофиль разработчика на LinkedIn. - - Поле не может быть пустым. - Вы не можете быть настолько богаты или бедны. - Вы не можете быть настолько богаты. - Нет - Слишком много для перевода. - Слишком много для обмена. - Нельзя конвертировать валюту в саму себя. - Нельзя создать запись в будущем. - Необходим, по крайней мере, один счет. - - Редактировать счет - Цвет - Цель - Восстановить - Архивировать - Нельзя архивировать счет по умолчанию. - Удалить счет - Вы уверены, что хотите удалить этот счет ? Вы не сможете восстановить его после удаления. - - График - Информация - Операции + Банк продает + Конвертировать в + Банк покупает + Конвертировать из + + Дата + Время + + Бэкап/Восстановление + Не удалось создать бэкап. + Не удалось восстановить бэкап. + Выбранный бэкап %1$s был успешно восстановлен. + Бэкап восстановлен + Предупреждение + Вы действительно хотите удалить все текущие данные и восстановить бэкап %1$s? Пожалуйста, сделайте бэкап текущих данных. + Сделать бэкап + + Редактировать доход + Редактировать расход + + Импортирование записей… + Создание бэкапа… + Восстановление бэкапа… + Загрузка бэкапов… + Удаление бэкапа… + + Версия %1$s (Android %2$s) + О приложении + Open Money Tracker (OMT) это приложения для ведения личных финансов. Вы легко можете управлять доходами и расходами. Также доступны счета и курсы обмена.\n\nДля того чтобы помочь сделать OMT лучше, пишите о багах на форуме 4PDA; идеи новых функций также приветствуются. Ищите ответы или начинайте обсуждение на форуме.\n\nOMT это проект с открытым исходным кодом, так что каждый может помочь с его разработкой. Не-разработчики также могут помочь. Например, вы можете помочь с переводом, предоставить скриншоты или написать статью в блоге о OMT.\n\nOMT выпущен под GNU-GPL v3 лицензией и исходный код доступен на GitHub.\n\nПрофиль разработчика на LinkedIn. + + Поле не может быть пустым. + Вы не можете быть настолько богаты или бедны. + Вы не можете быть настолько богаты. + Нет + Слишком много для перевода. + Слишком много для обмена. + Нельзя конвертировать валюту в саму себя. + Нельзя создать запись в будущем. + Необходим, по крайней мере, один счет. + + Редактировать счет + Цвет + Цель + Восстановить + Архивировать + Нельзя архивировать счет по умолчанию. + Удалить счет + Вы уверены, что хотите удалить этот счет ? Вы не сможете восстановить его после удаления. + + График + Информация + Операции diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index c721c4a..e82b208 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -100,6 +100,7 @@ Створення бекапу… Відновлення бекапу… Завантаження бекапів… + Видалення бекапу… Версія %1$s (Android %2$s) Про додаток diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index ea66930..c3c2d59 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -89,6 +89,7 @@ 生成备份…… 恢复备份中…… 正在获得备份…… + 刪除備份…… 版本 %1$s (安卓 %2$s) 关于 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c94a4e2..55a87a7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -108,6 +108,7 @@ Making backup… Restoring backup… Fetching backups… + Removing backup… pref_about Version %1$s (Android %2$s) From 24fbc63e6e7748f9addccdbd1d15ac4a2d3c5a0b Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Sun, 16 Sep 2018 08:16:29 +0200 Subject: [PATCH 25/33] #134. Add account goal to EditAccountFragment. --- .../edit/fragment/EditAccountFragment.kt | 20 +++-- .../util/validator/EditAccountValidator.java | 76 +++++++++++++++++++ .../main/res/layout/fragment_edit_account.xml | 3 +- 3 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/EditAccountValidator.java diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt index a33586a..c383b65 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt @@ -7,8 +7,11 @@ import android.view.View import com.blogspot.e_kanivets.moneytracker.R import com.blogspot.e_kanivets.moneytracker.R.layout import com.blogspot.e_kanivets.moneytracker.activity.base.BaseFragment +import com.blogspot.e_kanivets.moneytracker.controller.FormatController import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController import com.blogspot.e_kanivets.moneytracker.entity.data.Account +import com.blogspot.e_kanivets.moneytracker.util.validator.EditAccountValidator +import com.blogspot.e_kanivets.moneytracker.util.validator.IValidator import kotlinx.android.synthetic.main.fragment_edit_account.* import javax.inject.Inject @@ -16,6 +19,10 @@ class EditAccountFragment : BaseFragment() { @Inject internal lateinit var accountController: AccountController + @Inject + internal lateinit var formatController: FormatController + + private lateinit var accountValidator: IValidator private lateinit var account: Account @@ -28,22 +35,23 @@ class EditAccountFragment : BaseFragment() { override fun initViews(view: View) { etTitle.setText(account.title) - etGoal.setText(account.goal.toString()) + etGoal.setText(formatController.formatPrecisionNone(account.goal)) viewColor.setBackgroundColor(account.color) val fabDone = view.rootView.findViewById(R.id.fabDone) fabDone.setOnClickListener { done() } + + accountValidator = EditAccountValidator(context!!, view) } private fun done() { - val title = etTitle.text.toString().trim { it <= ' ' } + if (accountValidator.validate()) { + val title = etTitle.text.toString().trim { it <= ' ' } + val goal = etGoal.text.toString().toDouble() - if (title.isEmpty()) { - tilTitle.error = getString(R.string.field_cant_be_empty) - } else { val newAccount = Account( account.id, title, account.curSum.toDouble(), - account.currency, account.goal, account.isArchived, account.color + account.currency, goal, account.isArchived, account.color ) val updated = accountController.update(newAccount) != null if (updated) { diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/EditAccountValidator.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/EditAccountValidator.java new file mode 100644 index 0000000..43f39f4 --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/EditAccountValidator.java @@ -0,0 +1,76 @@ +package com.blogspot.e_kanivets.moneytracker.util.validator; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.design.widget.TextInputLayout; +import android.view.View; +import android.widget.EditText; +import butterknife.BindView; +import butterknife.ButterKnife; +import com.blogspot.e_kanivets.moneytracker.R; +import com.blogspot.e_kanivets.moneytracker.entity.data.Account; + +/** + * Util class for EditAccount validation. + * Created on 16.09.2018. + * + * @author Evgenii Kanivets + */ + +public class EditAccountValidator implements IValidator { + + @NonNull + private final Context context; + + @BindView(R.id.tilTitle) + TextInputLayout tilTitle; + @BindView(R.id.etTitle) + EditText etTitle; + @BindView(R.id.tilGoal) + TextInputLayout tilGoal; + @BindView(R.id.etGoal) + EditText etGoal; + + public EditAccountValidator(@NonNull Context context, @NonNull View view) { + this.context = context; + ButterKnife.bind(this, view); + initTextWatchers(); + } + + @Override + public boolean validate() { + String title = etTitle.getText().toString().trim(); + double goal = Double.MAX_VALUE; + + try { + goal = Double.parseDouble(etGoal.getText().toString().trim()); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + + boolean valid = true; + + if (title.isEmpty()) { + tilTitle.setError(context.getString(R.string.field_cant_be_empty)); + valid = false; + } + + if (goal == Double.MAX_VALUE) { + tilGoal.setError(context.getString(R.string.field_cant_be_empty)); + goal = 0; + valid = false; + } + + if (Math.abs(goal) > MAX_ABS_VALUE) { + tilGoal.setError(context.getString(R.string.too_rich_or_poor)); + valid = false; + } + + return valid; + } + + private void initTextWatchers() { + etTitle.addTextChangedListener(new ClearErrorTextWatcher(tilTitle)); + etGoal.addTextChangedListener(new ClearErrorTextWatcher(tilGoal)); + } +} diff --git a/app/src/main/res/layout/fragment_edit_account.xml b/app/src/main/res/layout/fragment_edit_account.xml index c09d09a..b45d7ce 100644 --- a/app/src/main/res/layout/fragment_edit_account.xml +++ b/app/src/main/res/layout/fragment_edit_account.xml @@ -27,10 +27,9 @@ Date: Sun, 16 Sep 2018 08:32:20 +0200 Subject: [PATCH 26/33] #134. Formatting. --- .../edit/fragment/EditAccountFragment.kt | 3 +++ .../util/validator/EditAccountValidator.java | 18 ++++++------------ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt index c383b65..9d0fc17 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/account/edit/fragment/EditAccountFragment.kt @@ -10,6 +10,7 @@ import com.blogspot.e_kanivets.moneytracker.activity.base.BaseFragment import com.blogspot.e_kanivets.moneytracker.controller.FormatController import com.blogspot.e_kanivets.moneytracker.controller.data.AccountController import com.blogspot.e_kanivets.moneytracker.entity.data.Account +import com.blogspot.e_kanivets.moneytracker.util.AnswersProxy import com.blogspot.e_kanivets.moneytracker.util.validator.EditAccountValidator import com.blogspot.e_kanivets.moneytracker.util.validator.IValidator import kotlinx.android.synthetic.main.fragment_edit_account.* @@ -45,6 +46,7 @@ class EditAccountFragment : BaseFragment() { } private fun done() { + AnswersProxy.get().logButton("Edit Account") if (accountValidator.validate()) { val title = etTitle.text.toString().trim { it <= ' ' } val goal = etGoal.text.toString().toDouble() @@ -55,6 +57,7 @@ class EditAccountFragment : BaseFragment() { ) val updated = accountController.update(newAccount) != null if (updated) { + AnswersProxy.get().logEvent("Edit Account") activity?.setResult(Activity.RESULT_OK) activity?.finish() } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/EditAccountValidator.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/EditAccountValidator.java index 43f39f4..fc2596a 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/EditAccountValidator.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/util/validator/EditAccountValidator.java @@ -19,17 +19,12 @@ public class EditAccountValidator implements IValidator { - @NonNull - private final Context context; + @NonNull private final Context context; - @BindView(R.id.tilTitle) - TextInputLayout tilTitle; - @BindView(R.id.etTitle) - EditText etTitle; - @BindView(R.id.tilGoal) - TextInputLayout tilGoal; - @BindView(R.id.etGoal) - EditText etGoal; + @BindView(R.id.tilTitle) TextInputLayout tilTitle; + @BindView(R.id.etTitle) EditText etTitle; + @BindView(R.id.tilGoal) TextInputLayout tilGoal; + @BindView(R.id.etGoal) EditText etGoal; public EditAccountValidator(@NonNull Context context, @NonNull View view) { this.context = context; @@ -37,8 +32,7 @@ public EditAccountValidator(@NonNull Context context, @NonNull View view) { initTextWatchers(); } - @Override - public boolean validate() { + @Override public boolean validate() { String title = etTitle.getText().toString().trim(); double goal = Double.MAX_VALUE; From 9fb0339dc771054252c1660716c485dffe42dc32 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Sun, 16 Sep 2018 09:00:13 +0200 Subject: [PATCH 27/33] #153. Add 'NON susbstitution currency' setting. --- .../activity/SettingsActivity.java | 89 ++++++++++--------- .../controller/CurrencyController.java | 22 +++-- .../controller/PreferenceController.java | 37 ++++---- app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values-uk/strings.xml | 1 + app/src/main/res/values-zh/strings.xml | 1 + app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/preferences.xml | 46 +++++----- 8 files changed, 109 insertions(+), 90 deletions(-) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/SettingsActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/SettingsActivity.java index d8d8c50..53de442 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/SettingsActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/SettingsActivity.java @@ -22,34 +22,25 @@ import javax.inject.Inject; public class SettingsActivity extends BaseBackActivity { - @SuppressWarnings("unused") - private static final String TAG = "SettingsActivity"; + @SuppressWarnings("unused") private static final String TAG = "SettingsActivity"; - @Override - protected int getContentViewId() { + @Override protected int getContentViewId() { return R.layout.activity_settings; } - @Override - protected void initViews() { + @Override protected void initViews() { super.initViews(); // Display the fragment as the main content. - getFragmentManager().beginTransaction() - .replace(R.id.content, new SettingsFragment()) - .commit(); + getFragmentManager().beginTransaction().replace(R.id.content, new SettingsFragment()).commit(); } public static class SettingsFragment extends PreferenceFragment { - @Inject - AccountController accountController; - @Inject - CurrencyController currencyController; - @Inject - PreferenceController preferenceController; - - @Override - public void onCreate(Bundle savedInstanceState) { + @Inject AccountController accountController; + @Inject CurrencyController currencyController; + @Inject PreferenceController preferenceController; + + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MtApp.get().getAppComponent().inject(SettingsFragment.this); @@ -59,18 +50,14 @@ public void onCreate(Bundle savedInstanceState) { setupDefaultAccountPref(); setupDefaultCurrencyPref(); + setupNonSubstitutionCurrencyPref(); setupDisplayPrecision(); setupAboutPref(); } - private void setupAboutPref() { - Preference preference = findPreference(getString(R.string.pref_about)); - preference.setSummary(getString(R.string.about_summary, BuildConfig.VERSION_NAME, - Build.VERSION.RELEASE)); - } - private void setupDefaultAccountPref() { - ListPreference defaultAccountPref = (ListPreference) findPreference(getString(R.string.pref_default_account)); + ListPreference defaultAccountPref = + (ListPreference) findPreference(getString(R.string.pref_default_account)); defaultAccountPref.setOnPreferenceChangeListener(preferenceChangeListener); List accountList = accountController.readActiveAccounts(); @@ -87,9 +74,9 @@ private void setupDefaultAccountPref() { } } - @SuppressWarnings("ToArrayCallWithZeroLengthArrayArgument") - private void setupDefaultCurrencyPref() { - ListPreference defaultCurrencyPref = (ListPreference) findPreference(getString(R.string.pref_default_currency)); + @SuppressWarnings("ToArrayCallWithZeroLengthArrayArgument") private void setupDefaultCurrencyPref() { + ListPreference defaultCurrencyPref = + (ListPreference) findPreference(getString(R.string.pref_default_currency)); defaultCurrencyPref.setOnPreferenceChangeListener(preferenceChangeListener); List currencyList = currencyController.readAll(); @@ -101,9 +88,23 @@ private void setupDefaultCurrencyPref() { defaultCurrencyPref.setSummary(defaultCurrency); } - @SuppressWarnings("ToArrayCallWithZeroLengthArrayArgument") - private void setupDisplayPrecision() { - ListPreference displayPrecisionPref = (ListPreference) findPreference(getString(R.string.pref_display_precision)); + @SuppressWarnings("ToArrayCallWithZeroLengthArrayArgument") private void setupNonSubstitutionCurrencyPref() { + ListPreference nonSubstitutionCurrencyPref = + (ListPreference) findPreference(getString(R.string.pref_non_substitution_currency)); + nonSubstitutionCurrencyPref.setOnPreferenceChangeListener(preferenceChangeListener); + + List currencyList = currencyController.readAll(); + nonSubstitutionCurrencyPref.setEntries(currencyList.toArray(new String[0])); + nonSubstitutionCurrencyPref.setEntryValues(currencyList.toArray(new String[0])); + + String nonSubstitutionCurrency = currencyController.readNonSubstitutionCurrency(); + nonSubstitutionCurrencyPref.setDefaultValue(nonSubstitutionCurrency); + nonSubstitutionCurrencyPref.setSummary(nonSubstitutionCurrency); + } + + @SuppressWarnings("ToArrayCallWithZeroLengthArrayArgument") private void setupDisplayPrecision() { + ListPreference displayPrecisionPref = + (ListPreference) findPreference(getString(R.string.pref_display_precision)); displayPrecisionPref.setOnPreferenceChangeListener(preferenceChangeListener); List precisionListValues = new ArrayList<>(); @@ -124,6 +125,11 @@ private void setupDisplayPrecision() { } } + private void setupAboutPref() { + Preference preference = findPreference(getString(R.string.pref_about)); + preference.setSummary(getString(R.string.about_summary, BuildConfig.VERSION_NAME, Build.VERSION.RELEASE)); + } + @SuppressWarnings("ToArrayCallWithZeroLengthArrayArgument") private String[] getEntries(List accountList) { List result = new ArrayList<>(); @@ -146,16 +152,15 @@ private String[] getEntryValues(List accountList) { return result.toArray(new String[0]); } - private Preference.OnPreferenceChangeListener preferenceChangeListener - = new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - // Previously we could set summary to default value, - // but now it's needed to display selected entry - preference.setSummary("%s"); - getActivity().setResult(RESULT_OK); - return true; - } - }; + private Preference.OnPreferenceChangeListener preferenceChangeListener = + new Preference.OnPreferenceChangeListener() { + @Override public boolean onPreferenceChange(Preference preference, Object newValue) { + // Previously we could set summary to default value, + // but now it's needed to display selected entry + preference.setSummary("%s"); + getActivity().setResult(RESULT_OK); + return true; + } + }; } } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/CurrencyController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/CurrencyController.java index adbae7a..12ef3f9 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/CurrencyController.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/CurrencyController.java @@ -25,8 +25,7 @@ public class CurrencyController { private AccountController accountController; private PreferenceController preferenceController; - @NonNull - private List currencyList; + @NonNull private List currencyList; public CurrencyController(AccountController accountController, PreferenceController preferenceController) { this.accountController = accountController; @@ -34,13 +33,11 @@ public CurrencyController(AccountController accountController, PreferenceControl currencyList = fetchCurrencies(); } - @NonNull - public List readAll() { + @NonNull public List readAll() { return currencyList; } - @NonNull - public String readDefaultCurrency() { + @NonNull public String readDefaultCurrency() { // First of all read from Prefs String currency = preferenceController.readDefaultCurrency(); @@ -54,8 +51,17 @@ public String readDefaultCurrency() { return currency; } - @NonNull - private List fetchCurrencies() { + @NonNull public String readNonSubstitutionCurrency() { + // First of all read from Prefs + String currency = preferenceController.readNonSubstitutionCurrency(); + + // If don't have default currency, use NON + if (currency == null) currency = DbHelper.DEFAULT_ACCOUNT_CURRENCY; + + return currency; + } + + @NonNull private List fetchCurrencies() { Set toret = new HashSet<>(); Locale[] locs = Locale.getAvailableLocales(); diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/PreferenceController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/PreferenceController.java index 477e5e9..7cf9676 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/PreferenceController.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/PreferenceController.java @@ -33,8 +33,7 @@ public class PreferenceController { private static final int RATE_PERIOD = 5; - @NonNull - private Context context; + @NonNull private Context context; public PreferenceController(@NonNull Context context) { this.context = context; @@ -113,22 +112,27 @@ public long readDefaultAccountId() { return Long.parseLong(preferences.getString(defaultAccountPref, "-1")); } - @Nullable - public String readDefaultCurrency() { + @Nullable public String readDefaultCurrency() { String defaultCurrencyPref = context.getString(R.string.pref_default_currency); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); return preferences.getString(defaultCurrencyPref, null); } - @NonNull - public String readDisplayPrecision() { + @NonNull public String readDisplayPrecision() { String displayPrecisionPref = context.getString(R.string.pref_display_precision); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); return preferences.getString(displayPrecisionPref, FormatController.PRECISION_MATH); } + @Nullable public String readNonSubstitutionCurrency() { + String nonSubstitutionCurrencyPref = context.getString(R.string.pref_non_substitution_currency); + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + + return preferences.getString(nonSubstitutionCurrencyPref, null); + } + public long readFirstTs() { return getDefaultPrefs().getLong(KEY_FIRST_TS, -1); } @@ -137,28 +141,23 @@ public long readLastTs() { return getDefaultPrefs().getLong(KEY_LAST_TS, -1); } - @Nullable - public String readPeriodType() { + @Nullable public String readPeriodType() { return getDefaultPrefs().getString(KEY_PERIOD_TYPE, null); } - @Nullable - public String readDropboxAccessToken() { + @Nullable public String readDropboxAccessToken() { return getDefaultPrefs().getString(KEY_DROPBOX_ACCESS_TOKEN, null); } - @NonNull - public Set readFilteredCategories() { + @NonNull public Set readFilteredCategories() { // http://stackoverflow.com/questions/14034803/misbehavior-when-trying-to-store-a-string-set-using-sharedpreferences/14034804#14034804 return new HashSet<>(getDefaultPrefs().getStringSet(KEY_FILTERED_CATEGORIES, new HashSet())); } - @NonNull - public Map readRecordTitleCategoryPairs() { + @NonNull public Map readRecordTitleCategoryPairs() { Map map = new TreeMap<>(); - Set set = getDefaultPrefs().getStringSet(KEY_RECORD_TITLE_CATEGORY_PAIRS, - new HashSet()); + Set set = getDefaultPrefs().getStringSet(KEY_RECORD_TITLE_CATEGORY_PAIRS, new HashSet()); for (String entry : set) { String[] words = entry.split(";"); if (words.length == 2) { @@ -169,13 +168,11 @@ public Map readRecordTitleCategoryPairs() { return map; } - @NonNull - private SharedPreferences getDefaultPrefs() { + @NonNull private SharedPreferences getDefaultPrefs() { return context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE); } - @NonNull - private SharedPreferences.Editor getEditor() { + @NonNull private SharedPreferences.Editor getEditor() { return getDefaultPrefs().edit(); } } diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 1cd0249..4995132 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -56,6 +56,7 @@ Настройки Счет по умолчанию Валюта по умолчанию + Замена валюты NON Итоги Доходы diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index e82b208..d828602 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -56,6 +56,7 @@ Налаштування Рахунок за замовчуванням Валюта за замовчуванням + Замiна валюти NON Підсумки Доходи diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index c3c2d59..a8fc9f1 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -52,6 +52,7 @@ 设置 默认账户 默认货币 + NON 替代貨幣 表格 收入 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 55a87a7..7d479d0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -58,7 +58,9 @@ pref_default_account pref_default_currency %1$s - %2$s + pref_non_substitution_currency Default currency + NON substitution currency Results Incomes diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 041c89a..cf1ac3a 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -1,26 +1,32 @@ - + - + - + + + + + + + - - - From 18980598054c9bb8fd70cbe8b054e3497207299b Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Mon, 17 Sep 2018 19:54:56 +0200 Subject: [PATCH 28/33] #153. Substitute NON currency in RecordController. --- .../controller/data/RecordController.java | 13 +++- .../di/module/ControllerModule.java | 75 ++++++------------- 2 files changed, 32 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordController.java index 5bd47d0..e6e3006 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordController.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordController.java @@ -3,6 +3,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import com.blogspot.e_kanivets.moneytracker.controller.CurrencyController; import com.blogspot.e_kanivets.moneytracker.repo.DbHelper; import com.blogspot.e_kanivets.moneytracker.controller.base.BaseController; import com.blogspot.e_kanivets.moneytracker.entity.data.Account; @@ -23,14 +24,17 @@ * @author Evgenii Kanivets */ public class RecordController extends BaseController { + private final CategoryController categoryController; private final AccountController accountController; + private final CurrencyController currencyController; public RecordController(IRepo recordRepo, CategoryController categoryController, - AccountController accountController) { + AccountController accountController, CurrencyController currencyController) { super(recordRepo); this.categoryController = categoryController; this.accountController = accountController; + this.currencyController = currencyController; } @Override @SuppressWarnings("SimplifiableIfStatement") public Record create(@Nullable Record record) { @@ -104,9 +108,14 @@ record = validateRecord(record); Account account = null; if (record.getAccount() != null) account = accountController.read(record.getAccount().getId()); + String currency = record.getCurrency(); + if (DbHelper.DEFAULT_ACCOUNT_CURRENCY.equals(currency)) { + currency = currencyController.readNonSubstitutionCurrency(); + } + completedRecordList.add( new Record(record.getId(), record.getTime(), record.getType(), record.getTitle(), category, - record.getPrice(), account, record.getCurrency(), record.getDecimals())); + record.getPrice(), account, currency, record.getDecimals())); } return completedRecordList; diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java index 3ec446f..d65b999 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java @@ -33,102 +33,69 @@ * * @author Evgenii Kanivets */ -@Module -public class ControllerModule { +@Module public class ControllerModule { private Context context; public ControllerModule(Context context) { this.context = context; } - @Provides - @NonNull - @Singleton - public AccountController providesAccountController(IRepo accountRepo, - PreferenceController preferenceController) { + @Provides @NonNull @Singleton public AccountController providesAccountController(IRepo accountRepo, + PreferenceController preferenceController) { return new AccountController(accountRepo, preferenceController); } - @Provides - @NonNull - @Singleton - public CategoryController providesCategoryController(IRepo categoryRepo, - PreferenceController preferenceController) { + @Provides @NonNull @Singleton public CategoryController providesCategoryController(IRepo categoryRepo, + PreferenceController preferenceController) { return new CategoryController(categoryRepo, preferenceController); } - @Provides - @NonNull - @Singleton + @Provides @NonNull @Singleton public ExchangeRateController providesExchangeRateController(IRepo exchangeRateRepo) { return new ExchangeRateController(exchangeRateRepo); } - @Provides - @NonNull - @Singleton - public RecordController providesRecordController(IRepo recordRepo, - CategoryController categoryController, - AccountController accountController) { - return new RecordController(recordRepo, categoryController, accountController); + @Provides @NonNull @Singleton + public RecordController providesRecordController(IRepo recordRepo, CategoryController categoryController, + AccountController accountController, CurrencyController currencyController) { + return new RecordController(recordRepo, categoryController, accountController, currencyController); } - @Provides - @NonNull - @Singleton - public TransferController providesTransferController(IRepo transferRepo, - AccountController accountController) { + @Provides @NonNull @Singleton public TransferController providesTransferController(IRepo transferRepo, + AccountController accountController) { return new TransferController(transferRepo, accountController); } - @Provides - @NonNull - @Singleton + @Provides @NonNull @Singleton public CurrencyController providesCurrencyController(AccountController accountController, - PreferenceController preferenceController) { + PreferenceController preferenceController) { return new CurrencyController(accountController, preferenceController); } - @Provides - @NonNull - @Singleton - public PreferenceController providesPreferenceController() { + @Provides @NonNull @Singleton public PreferenceController providesPreferenceController() { return new PreferenceController(context); } - @Provides - @NonNull - @Singleton + @Provides @NonNull @Singleton public PeriodController providesPeriodController(PreferenceController preferenceController) { return new PeriodController(preferenceController); } - @Provides - @NonNull - @Singleton + @Provides @NonNull @Singleton public FormatController providesFormatController(PreferenceController preferenceController) { return new FormatController(preferenceController); } - @Provides - @NonNull - @Singleton - public ExportController providesExportController(RecordController recordController, - CategoryController categoryController) { + @Provides @NonNull @Singleton public ExportController providesExportController(RecordController recordController, + CategoryController categoryController) { return new ExportController(recordController, categoryController); } - @Provides - @NonNull - @Singleton - public ImportController providesImportController(RecordController recordController) { + @Provides @NonNull @Singleton public ImportController providesImportController(RecordController recordController) { return new ImportController(recordController); } - @Provides - @NonNull - @Singleton - public BackupController providesBackupController(FormatController formatController) { + @Provides @NonNull @Singleton public BackupController providesBackupController(FormatController formatController) { return new BackupController(formatController, context.getApplicationInfo().dataDir); } } From 80153679476c101f63edde07affd06a975d00cc0 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Mon, 17 Sep 2018 20:41:54 +0200 Subject: [PATCH 29/33] #153. Substitute NON currency in AccountController. --- .../activity/SettingsActivity.java | 2 +- .../controller/CurrencyController.java | 10 ---- .../controller/PreferenceController.java | 3 +- .../controller/data/AccountController.java | 60 ++++++++++++++----- .../controller/data/RecordController.java | 10 ++-- .../di/module/ControllerModule.java | 4 +- 6 files changed, 56 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/SettingsActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/SettingsActivity.java index 53de442..eac0415 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/SettingsActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/SettingsActivity.java @@ -97,7 +97,7 @@ private void setupDefaultAccountPref() { nonSubstitutionCurrencyPref.setEntries(currencyList.toArray(new String[0])); nonSubstitutionCurrencyPref.setEntryValues(currencyList.toArray(new String[0])); - String nonSubstitutionCurrency = currencyController.readNonSubstitutionCurrency(); + String nonSubstitutionCurrency = preferenceController.readNonSubstitutionCurrency(); nonSubstitutionCurrencyPref.setDefaultValue(nonSubstitutionCurrency); nonSubstitutionCurrencyPref.setSummary(nonSubstitutionCurrency); } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/CurrencyController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/CurrencyController.java index 12ef3f9..e21f92d 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/CurrencyController.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/CurrencyController.java @@ -51,16 +51,6 @@ public CurrencyController(AccountController accountController, PreferenceControl return currency; } - @NonNull public String readNonSubstitutionCurrency() { - // First of all read from Prefs - String currency = preferenceController.readNonSubstitutionCurrency(); - - // If don't have default currency, use NON - if (currency == null) currency = DbHelper.DEFAULT_ACCOUNT_CURRENCY; - - return currency; - } - @NonNull private List fetchCurrencies() { Set toret = new HashSet<>(); Locale[] locs = Locale.getAvailableLocales(); diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/PreferenceController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/PreferenceController.java index 7cf9676..16d9d14 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/PreferenceController.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/PreferenceController.java @@ -8,6 +8,7 @@ import com.blogspot.e_kanivets.moneytracker.R; +import com.blogspot.e_kanivets.moneytracker.repo.DbHelper; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -130,7 +131,7 @@ public long readDefaultAccountId() { String nonSubstitutionCurrencyPref = context.getString(R.string.pref_non_substitution_currency); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); - return preferences.getString(nonSubstitutionCurrencyPref, null); + return preferences.getString(nonSubstitutionCurrencyPref, DbHelper.DEFAULT_ACCOUNT_CURRENCY); } public long readFirstTs() { diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/AccountController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/AccountController.java index 75cf0db..f383cd7 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/AccountController.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/AccountController.java @@ -8,6 +8,7 @@ import com.blogspot.e_kanivets.moneytracker.entity.data.Account; import com.blogspot.e_kanivets.moneytracker.entity.data.Record; import com.blogspot.e_kanivets.moneytracker.entity.data.Transfer; +import com.blogspot.e_kanivets.moneytracker.repo.DbHelper; import com.blogspot.e_kanivets.moneytracker.repo.base.IRepo; import java.util.ArrayList; @@ -20,8 +21,7 @@ * @author Evgenii Kanivets */ public class AccountController extends BaseController { - @SuppressWarnings("unused") - private static final String TAG = "AccountController"; + @SuppressWarnings("unused") private static final String TAG = "AccountController"; private final PreferenceController preferenceController; @@ -30,8 +30,22 @@ public AccountController(IRepo accountRepo, PreferenceController prefer this.preferenceController = preferenceController; } - @NonNull - public List readActiveAccounts() { + @Nullable @Override public Account read(long id) { + return substituteCurrency(super.read(id)); + } + + @NonNull @Override public List readAll() { + List accountList = super.readAll(); + + List result = new ArrayList<>(); + for (Account account : accountList) { + result.add(substituteCurrency(account)); + } + + return result; + } + + @NonNull public List readActiveAccounts() { List result = new ArrayList<>(); for (Account account : readAll()) { @@ -43,8 +57,7 @@ public List readActiveAccounts() { return result; } - @NonNull - public List readArchivedAccounts() { + @NonNull public List readArchivedAccounts() { List result = new ArrayList<>(); for (Account account : readAll()) { @@ -128,15 +141,18 @@ public boolean transferDone(@Nullable Transfer transfer) { return true; } - @Nullable - public Account readDefaultAccount() { + @Nullable public Account readDefaultAccount() { long defaultAccountId = preferenceController.readDefaultAccountId(); - if (defaultAccountId == -1) return getFirstAccount(); - else { + if (defaultAccountId == -1) { + return getFirstAccount(); + } else { Account account = read(defaultAccountId); - if (account == null) return getFirstAccount(); - else return account; + if (account == null) { + return getFirstAccount(); + } else { + return account; + } } } @@ -162,7 +178,23 @@ public boolean restore(@Nullable Account account) { private Account getFirstAccount() { List accountList = readAll(); - if (accountList.size() == 0) return null; - else return accountList.get(0); + if (accountList.size() == 0) { + return null; + } else { + return accountList.get(0); + } + } + + private Account substituteCurrency(Account account) { + if (account == null) { + return null; + } else { + String currency = account.getCurrency(); + if (DbHelper.DEFAULT_ACCOUNT_CURRENCY.equals(currency)) { + currency = preferenceController.readNonSubstitutionCurrency(); + } + return new Account(account.getId(), account.getTitle(), account.getCurSum(), currency, + account.getDecimals(), account.getGoal(), account.isArchived(), account.getColor()); + } } } \ No newline at end of file diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordController.java index e6e3006..c15d524 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordController.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordController.java @@ -3,7 +3,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import com.blogspot.e_kanivets.moneytracker.controller.CurrencyController; +import com.blogspot.e_kanivets.moneytracker.controller.PreferenceController; import com.blogspot.e_kanivets.moneytracker.repo.DbHelper; import com.blogspot.e_kanivets.moneytracker.controller.base.BaseController; import com.blogspot.e_kanivets.moneytracker.entity.data.Account; @@ -27,14 +27,14 @@ public class RecordController extends BaseController { private final CategoryController categoryController; private final AccountController accountController; - private final CurrencyController currencyController; + private final PreferenceController preferenceController; public RecordController(IRepo recordRepo, CategoryController categoryController, - AccountController accountController, CurrencyController currencyController) { + AccountController accountController, PreferenceController preferenceController) { super(recordRepo); this.categoryController = categoryController; this.accountController = accountController; - this.currencyController = currencyController; + this.preferenceController = preferenceController; } @Override @SuppressWarnings("SimplifiableIfStatement") public Record create(@Nullable Record record) { @@ -110,7 +110,7 @@ record = validateRecord(record); String currency = record.getCurrency(); if (DbHelper.DEFAULT_ACCOUNT_CURRENCY.equals(currency)) { - currency = currencyController.readNonSubstitutionCurrency(); + currency = preferenceController.readNonSubstitutionCurrency(); } completedRecordList.add( diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java index d65b999..05297ff 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java @@ -57,8 +57,8 @@ public ExchangeRateController providesExchangeRateController(IRepo @Provides @NonNull @Singleton public RecordController providesRecordController(IRepo recordRepo, CategoryController categoryController, - AccountController accountController, CurrencyController currencyController) { - return new RecordController(recordRepo, categoryController, accountController, currencyController); + AccountController accountController, PreferenceController preferenceController) { + return new RecordController(recordRepo, categoryController, accountController, preferenceController); } @Provides @NonNull @Singleton public TransferController providesTransferController(IRepo transferRepo, From b6924c70625e982e7db5238f571f64b2163559f1 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Mon, 17 Sep 2018 20:51:46 +0200 Subject: [PATCH 30/33] #153. Fine tune CurrencyController. --- .../moneytracker/controller/CurrencyController.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/CurrencyController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/CurrencyController.java index e21f92d..706d2e8 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/CurrencyController.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/CurrencyController.java @@ -63,13 +63,15 @@ public CurrencyController(AccountController accountController, PreferenceControl } } - List currencyList = new ArrayList<>(); + List currencySet = new ArrayList<>(); for (Currency currency : toret) { - currencyList.add(currency.getCurrencyCode()); + currencySet.add(currency.getCurrencyCode()); } - currencyList.add(DbHelper.DEFAULT_ACCOUNT_CURRENCY); - currencyList.add("BYN"); // New belorussian ruble + currencySet.add(DbHelper.DEFAULT_ACCOUNT_CURRENCY); + currencySet.add("BYN"); // New belorussian ruble + + currencyList = new ArrayList<>(currencySet); Collections.sort(currencyList); From 1dd6dd43da8750227cc3b226f8956ae42d0e0673 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Mon, 17 Sep 2018 20:55:20 +0200 Subject: [PATCH 31/33] #153. Fix RecordControllerTest. --- .../moneytracker/controller/data/RecordControllerTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/test/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordControllerTest.java b/app/src/test/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordControllerTest.java index 274299f..0e14b27 100644 --- a/app/src/test/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordControllerTest.java +++ b/app/src/test/java/com/blogspot/e_kanivets/moneytracker/controller/data/RecordControllerTest.java @@ -3,6 +3,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import com.blogspot.e_kanivets.moneytracker.controller.PreferenceController; import com.blogspot.e_kanivets.moneytracker.entity.Period; import com.blogspot.e_kanivets.moneytracker.entity.data.Account; import com.blogspot.e_kanivets.moneytracker.entity.data.Category; @@ -34,6 +35,7 @@ public class RecordControllerTest { private RecordController recordController; private CategoryController categoryMock; private AccountController accountMock; + private PreferenceController preferenceMock; private TestRepo repo; @Before @@ -41,8 +43,9 @@ public void setUp() throws Exception { repo = new TestRepo(); categoryMock = Mockito.mock(CategoryController.class); accountMock = Mockito.mock(AccountController.class); + preferenceMock = Mockito.mock(PreferenceController.class); - recordController = new RecordController(repo, categoryMock, accountMock); + recordController = new RecordController(repo, categoryMock, accountMock, preferenceMock); } @After From 69e21862e899a74184131d58b23198fda907bad7 Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Mon, 17 Sep 2018 21:10:02 +0200 Subject: [PATCH 32/33] #155. Fix record layout. --- app/src/main/res/layout/view_record.xml | 166 +++++++++++++----------- 1 file changed, 88 insertions(+), 78 deletions(-) diff --git a/app/src/main/res/layout/view_record.xml b/app/src/main/res/layout/view_record.xml index f62fadb..4da9721 100644 --- a/app/src/main/res/layout/view_record.xml +++ b/app/src/main/res/layout/view_record.xml @@ -2,97 +2,107 @@ + android:background="@color/white" + > + + + android:layout_height="wrap_content" + android:layout_weight="1" + android:orientation="vertical" + > + + - + + - - - - - - - - - - + android:background="@android:color/transparent" + android:gravity="start" + android:paddingBottom="5dp" + android:text="New Text" + android:theme="@style/Text_Body2" + /> - - - + android:layout_gravity="center_vertical|top" + android:layout_marginStart="2dp" + android:layout_weight="1" + android:background="@android:color/transparent" + android:gravity="start" + android:paddingBottom="5dp" + android:text="New Text" + android:theme="@style/Text_Body1" + /> + + + + - + - + - + + + \ No newline at end of file From 6e9450a7839cf160b0af1d91caa8ca3cfee527ef Mon Sep 17 00:00:00 2001 From: Evgenii Kanivets Date: Mon, 17 Sep 2018 21:28:44 +0200 Subject: [PATCH 33/33] Fix tests. --- .../moneytracker/controller/data/AccountControllerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/test/java/com/blogspot/e_kanivets/moneytracker/controller/data/AccountControllerTest.java b/app/src/test/java/com/blogspot/e_kanivets/moneytracker/controller/data/AccountControllerTest.java index 6a38f35..7e8d9af 100644 --- a/app/src/test/java/com/blogspot/e_kanivets/moneytracker/controller/data/AccountControllerTest.java +++ b/app/src/test/java/com/blogspot/e_kanivets/moneytracker/controller/data/AccountControllerTest.java @@ -174,11 +174,11 @@ public void testTransferDone() throws Exception { public void testReadDefaultAccount() throws Exception { assertNull(accountController.readDefaultAccount()); - Account account1 = new Account(1, "a1", 100, "NON", 0, 0, false, 0); + Account account1 = new Account(1, "a1", 100, "UAH", 0, 0, false, 0); repo.create(account1); assertEquals(account1, accountController.readDefaultAccount()); - Account account2 = new Account(2, "a2", 0, "NON", 0, 0, false, 0); + Account account2 = new Account(2, "a2", 0, "UAH", 0, 0, false, 0); repo.create(account2); assertEquals(account1, accountController.readDefaultAccount());