diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a15ba51..62c087e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,6 +17,12 @@ android:theme="@style/Theme.TaskTracker" android:usesCleartextTraffic="true" tools:targetApi="31"> + + diff --git a/app/src/main/java/com/example/tasktracker/Activities/LoginActivity.java b/app/src/main/java/com/example/tasktracker/Activities/LoginActivity.java index cef1e11..0b49400 100644 --- a/app/src/main/java/com/example/tasktracker/Activities/LoginActivity.java +++ b/app/src/main/java/com/example/tasktracker/Activities/LoginActivity.java @@ -2,14 +2,13 @@ package com.example.tasktracker.Activities; import android.annotation.SuppressLint; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Bundle; import android.util.Log; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; -import com.example.tasktracker.Answers.LoginAnswer; +import com.example.tasktracker.Answers.StatusAnswer; import com.example.tasktracker.Api.ApiFactory; import com.example.tasktracker.PublicKeyNames; import com.example.tasktracker.R; @@ -84,9 +83,9 @@ public class LoginActivity extends AppCompatActivity { private void SingIn() { Disposable disposable = ApiFactory.getApiService().singin(login, password) - .subscribeOn(Schedulers.io()).subscribe(new Consumer() { + .subscribeOn(Schedulers.io()).subscribe(new Consumer() { @Override - public void accept(LoginAnswer loginAnswer) throws Throwable { + public void accept(StatusAnswer loginAnswer) throws Throwable { if(loginAnswer.getStatus().equals("big")) { Snackbar.make(binding.getRoot(), R.string.snackbar_InvalidLogin, Snackbar.LENGTH_SHORT).show(); return; @@ -116,9 +115,9 @@ public class LoginActivity extends AppCompatActivity { } private void SingUp() { Disposable disposable = ApiFactory.getApiService().singup(login, password) - .subscribeOn(Schedulers.io()).subscribe(new Consumer() { + .subscribeOn(Schedulers.io()).subscribe(new Consumer() { @Override - public void accept(LoginAnswer loginAnswer) throws Throwable { + public void accept(StatusAnswer loginAnswer) throws Throwable { if(loginAnswer.getStatus().equals("big")) { Snackbar.make(binding.getRoot(), R.string.snackbar_BigLoginPassword, Snackbar.LENGTH_SHORT).show(); return; diff --git a/app/src/main/java/com/example/tasktracker/Activities/MainMenu.java b/app/src/main/java/com/example/tasktracker/Activities/MainMenu.java index 83bb7d7..a5acb34 100644 --- a/app/src/main/java/com/example/tasktracker/Activities/MainMenu.java +++ b/app/src/main/java/com/example/tasktracker/Activities/MainMenu.java @@ -1,5 +1,8 @@ package com.example.tasktracker.Activities; +import static android.view.View.INVISIBLE; +import static android.view.View.VISIBLE; + import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; @@ -115,19 +118,6 @@ public class MainMenu extends AppCompatActivity { } }); - binding.buttonSingOut.setOnClickListener(v -> { - getSharedPreferences(PublicKeyNames.TOKEN_LIST, MODE_PRIVATE). - edit(). - remove(PublicKeyNames.LOGIN_KEY). - remove(PublicKeyNames.PASSWORD_KEY). - apply(); - - @SuppressLint("UnsafeIntentLaunch") - Intent intent = new Intent(this, LoginActivity.class); - startActivity(intent); - finish(); - }); - viewModel.getOnLoad().observe(this, new Observer>() { @Override public void onChanged(List tasks) { @@ -148,6 +138,22 @@ public class MainMenu extends AppCompatActivity { } public void Offline() { + binding.buttonSettings.setVisibility(INVISIBLE); + binding.buttonLogOut.setVisibility(VISIBLE); + + binding.buttonLogOut.setOnClickListener(v -> { + getSharedPreferences(PublicKeyNames.TOKEN_LIST, MODE_PRIVATE). + edit(). + remove(PublicKeyNames.LOGIN_KEY). + remove(PublicKeyNames.PASSWORD_KEY). + apply(); + + @SuppressLint("UnsafeIntentLaunch") + Intent intent = new Intent(this, LoginActivity.class); + startActivity(intent); + finish(); + }); + ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) { @Override @@ -181,6 +187,11 @@ public class MainMenu extends AppCompatActivity { } private void Online() { + binding.buttonSettings.setOnClickListener(v->{ + Intent intent = SettingsActivity.getIntent(this, login); + startActivity(intent); + }); + viewModel.onFail().observe(this, new Observer() { @Override public void onChanged(String s) { diff --git a/app/src/main/java/com/example/tasktracker/Activities/SettingsActivity.java b/app/src/main/java/com/example/tasktracker/Activities/SettingsActivity.java new file mode 100644 index 0000000..d8f9f52 --- /dev/null +++ b/app/src/main/java/com/example/tasktracker/Activities/SettingsActivity.java @@ -0,0 +1,103 @@ +package com.example.tasktracker.Activities; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; + +import androidx.appcompat.app.AppCompatActivity; + +import com.example.tasktracker.Answers.StatusAnswer; +import com.example.tasktracker.Api.ApiFactory; +import com.example.tasktracker.PublicKeyNames; +import com.example.tasktracker.R; +import com.example.tasktracker.databinding.ActivitySettingsBinding; +import com.google.android.material.snackbar.Snackbar; + +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.functions.Consumer; +import io.reactivex.rxjava3.schedulers.Schedulers; + +public class SettingsActivity extends AppCompatActivity { + private ActivitySettingsBinding binding; + private CompositeDisposable compositeDisposable; + + private String login; + + public static Intent getIntent(Context context, String login) { + Intent intent = new Intent(context, SettingsActivity.class); + intent.putExtra(PublicKeyNames.LOGIN_KEY, login); + return intent; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + binding = ActivitySettingsBinding.inflate(getLayoutInflater()); + super.onCreate(savedInstanceState); + setContentView(binding.getRoot()); + + login = getIntent().getStringExtra(PublicKeyNames.LOGIN_KEY); + + binding.login.setText(login); + + binding.buttonBack.setOnClickListener(v->{ + finish(); + }); + binding.buttonLogOut.setOnClickListener(v->{ + getSharedPreferences(PublicKeyNames.TOKEN_LIST, MODE_PRIVATE) + .edit() + .remove(PublicKeyNames.LOGIN_KEY) + .remove(PublicKeyNames.PASSWORD_KEY) + .apply(); + Intent intent = new Intent(SettingsActivity.this, LoginActivity.class); + startActivity(intent); + finish(); + }); + compositeDisposable = new CompositeDisposable(); + + binding.buttonChangePassword.setOnClickListener(v->{ + String oldPassword = binding.fieldOldPassword.getText().toString(); + String newPassword = binding.fieldNewPassword.getText().toString(); + String retryPassword = binding.fieldRetreyPassword.getText().toString(); + + if(!retryPassword.equals(newPassword)) { + Snackbar.make(binding.getRoot(), R.string.snackbar_PasswordsNotEquals, Snackbar.LENGTH_LONG).show(); + return; + } + + Disposable disposable = ApiFactory.getApiService().changePassword(oldPassword, login, newPassword) + .subscribeOn(Schedulers.io()) + .subscribe(new Consumer() { + @Override + public void accept(StatusAnswer statusAnswer) throws Throwable { + if (statusAnswer.getStatus().equals("ok")) { + getSharedPreferences(PublicKeyNames.TOKEN_LIST, MODE_PRIVATE) + .edit() + .remove(PublicKeyNames.LOGIN_KEY) + .remove(PublicKeyNames.PASSWORD_KEY) + .apply(); + Intent intent = new Intent(SettingsActivity.this, LoginActivity.class); + startActivity(intent); + finish(); + } + else { + Snackbar.make(binding.getRoot(), R.string.snackbar_InvalidPassword, Snackbar.LENGTH_SHORT).show(); + } + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Throwable { + Snackbar.make(binding.getRoot(), R.string.snackbar_InternetError, Snackbar.LENGTH_SHORT).show(); + } + }); + compositeDisposable.add(disposable); + }); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + compositeDisposable.dispose(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/tasktracker/Answers/LoginAnswer.java b/app/src/main/java/com/example/tasktracker/Answers/StatusAnswer.java similarity index 82% rename from app/src/main/java/com/example/tasktracker/Answers/LoginAnswer.java rename to app/src/main/java/com/example/tasktracker/Answers/StatusAnswer.java index 934c2f8..0ff85ae 100644 --- a/app/src/main/java/com/example/tasktracker/Answers/LoginAnswer.java +++ b/app/src/main/java/com/example/tasktracker/Answers/StatusAnswer.java @@ -4,7 +4,7 @@ import com.google.gson.annotations.SerializedName; import java.io.Serializable; -public class LoginAnswer implements Serializable { +public class StatusAnswer implements Serializable { @SerializedName("status") private String status; diff --git a/app/src/main/java/com/example/tasktracker/Api/ApiService.java b/app/src/main/java/com/example/tasktracker/Api/ApiService.java index 4de7b0a..44d06cc 100644 --- a/app/src/main/java/com/example/tasktracker/Api/ApiService.java +++ b/app/src/main/java/com/example/tasktracker/Api/ApiService.java @@ -1,6 +1,6 @@ package com.example.tasktracker.Api; -import com.example.tasktracker.Answers.LoginAnswer; +import com.example.tasktracker.Answers.StatusAnswer; import com.example.tasktracker.Answers.Task; import java.util.ArrayList; @@ -14,10 +14,10 @@ import retrofit2.http.Query; public interface ApiService { @GET("singin") - Single singin(@Query("login") String login, @Query("password") String password); + Single singin(@Query("login") String login, @Query("password") String password); @POST("singup") - Single singup(@Query("login") String login, @Query("password") String password); + Single singup(@Query("login") String login, @Query("password") String password); @GET("user/task") Single getTask(@Query("login") String login, @Query("password") String password, @Query("id") long id); @@ -33,4 +33,7 @@ public interface ApiService { @POST("user/task/remove") Call removeTask(@Query("login") String login, @Query("password") String password, @Query("id") long ID); + + @POST("user/ChangePassword") + Single changePassword(@Query("oldPassword") String oldPassword, @Query("login") String login, @Query("newPassword") String newPassword); } diff --git a/app/src/main/res/drawable/setting.png b/app/src/main/res/drawable/setting.png new file mode 100644 index 0000000..bfbf326 Binary files /dev/null and b/app/src/main/res/drawable/setting.png differ diff --git a/app/src/main/res/layout/activity_main_menu.xml b/app/src/main/res/layout/activity_main_menu.xml index 5b47b68..2edc006 100644 --- a/app/src/main/res/layout/activity_main_menu.xml +++ b/app/src/main/res/layout/activity_main_menu.xml @@ -29,12 +29,22 @@ app:layout_constraintTop_toBottomOf="@id/findLine"/> + + + + + + + + + + + + + + +