diff --git a/app/src/main/java/com/example/tampopo_client/Tampopo.java b/app/src/main/java/com/example/tampopo_client/Tampopo.java index 895975a..c5edc9b 100644 --- a/app/src/main/java/com/example/tampopo_client/Tampopo.java +++ b/app/src/main/java/com/example/tampopo_client/Tampopo.java @@ -1,6 +1,7 @@ package com.example.tampopo_client; import android.app.Application; +import android.content.SharedPreferences; public class Tampopo extends Application { //いらないので下記2つをコメントアウトしました @@ -16,6 +17,7 @@ private String nickname; private String icon; + public String getToken() {return token;} public void setToken(String token) { @@ -30,6 +32,14 @@ this.userId = userId; } + public String getMailaddress() { return mailaddress; } + + public void setMailaddress(String mailaddress) { + this.mailaddress = mailaddress; + } + + + public String getPassword() { return password; } @@ -53,15 +63,16 @@ this.chatFriendId = ChatFriendId; } - public String getMailaddress() { return mailaddress; } - - public void setMailaddress(String mailaddress) {this.mailaddress = mailaddress; } public String getNickname() { return nickname; } - public void setNickname(String nickname) {this.nickname = nickname; } + public void setNickname(String nickname) { + this.nickname = nickname; + } public String getIcon() { return icon; } - public void setIcon(String icon) {this.icon = icon; } + public void setIcon(String icon) { + this.icon = icon; + } } diff --git a/app/src/main/java/com/example/tampopo_client/models/User.java b/app/src/main/java/com/example/tampopo_client/models/User.java index 706145d..6533361 100644 --- a/app/src/main/java/com/example/tampopo_client/models/User.java +++ b/app/src/main/java/com/example/tampopo_client/models/User.java @@ -55,4 +55,7 @@ public void setToken(String token){ this.token = token; } + + public void setPassword(String body) { + } } diff --git a/app/src/main/java/com/example/tampopo_client/resources/UserResource.java b/app/src/main/java/com/example/tampopo_client/resources/UserResource.java index 5e9f426..c582de0 100644 --- a/app/src/main/java/com/example/tampopo_client/resources/UserResource.java +++ b/app/src/main/java/com/example/tampopo_client/resources/UserResource.java @@ -74,7 +74,8 @@ @PUT("users/{user-id}/password") Call updatePassword( @Path("user-id") String userId, - @Field("new-password") String newPassword + @Field("new-password") String newPassword, + @Field("token") String token //市井 ); //単一アカウントのemailの取得 diff --git a/app/src/main/java/com/example/tampopo_client/viewmodels/UserViewModel.java b/app/src/main/java/com/example/tampopo_client/viewmodels/UserViewModel.java index 15936e6..84ddf44 100644 --- a/app/src/main/java/com/example/tampopo_client/viewmodels/UserViewModel.java +++ b/app/src/main/java/com/example/tampopo_client/viewmodels/UserViewModel.java @@ -1,5 +1,7 @@ package com.example.tampopo_client.viewmodels; +import android.util.Log; + import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; @@ -42,12 +44,13 @@ public class UserViewModel extends ViewModel { private final Retrofit retrofit; - private final UserResource userResource; - private final MutableLiveData user = new MutableLiveData<>(); + private static UserResource userResource; + private static final MutableLiveData user = new MutableLiveData<>(); private final MutableLiveData token = new MutableLiveData<>(); private final MutableLiveData icon = new MutableLiveData<>(); private final MutableLiveDataloading = new MutableLiveData<>(false); - private final MutableLiveData error = new MutableLiveData<>(); + private static final MutableLiveData error = new MutableLiveData<>(); + //コンストラクタ public UserViewModel(){ @@ -63,7 +66,7 @@ public LiveData getToken() { return token; } public LiveData getIcon() { return icon; } public LiveDataisLoading() { return loading;} - public LiveData getError() { return error; } + public static LiveData getError() { return error; } //新規登録 enqueueで非同期処理、Callbackで成功失敗の処理、LiveDataに反映 //サーバーから返ってきた型と合わせないとFailureに流れる @@ -134,7 +137,9 @@ if (response.isSuccessful()) { System.out.println(response.code()); - return response.body(); + String iconUrl = response.body(); + icon.postValue(iconUrl); + return iconUrl; } else { System.out.println(response.code()); return null; @@ -158,6 +163,26 @@ // }); } + //アイコン(非同期) + public void getIconAsync(String id) { + Call call = userResource.getIcon(id); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + String iconUrl = response.body(); + icon.postValue(iconUrl); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + Log.e("UserViewModel", "Error"); + } + }); + } + + public void updateIcon(String id, String newIcon, String token) { Call call = userResource.updateIcon(id, newIcon, token); call.enqueue(new Callback() { @@ -177,5 +202,94 @@ }); } + //ニックネームの変更(市井) + public void updateName(String userId, String newName, String tokenValue) { + loading.setValue(true); + + userResource.updateName(userId, newName, tokenValue).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + loading.setValue(false); + if (response.isSuccessful()) { + // LiveData に更新 + User currentUser = user.getValue(); + if (currentUser != null) { + currentUser.setName(response.body()); + user.setValue(currentUser); + } + } else { + error.setValue("ニックネーム変更失敗: " + response.code()); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + loading.setValue(false); + error.setValue("通信エラー: " + t.getMessage()); + } + }); + } + //パスワードの変更(市井) + public void updatePassword(String userId, String newPassword ,String tokenValue) { + loading.setValue(true); + + userResource.updatePassword(userId, newPassword ,tokenValue).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + loading.setValue(false); + if (response.isSuccessful()) { + // LiveData に更新 + User currentUser = user.getValue(); + if (currentUser != null) { + currentUser.setPassword(newPassword); + user.setValue(currentUser); + } + } else { + error.setValue("パスワード変更失敗: " + response.code()); + } + } + + + @Override + public void onFailure(Call call, Throwable t) { + loading.setValue(false); + error.setValue("通信エラー: " + t.getMessage()); + } + }); + } + + + //emailの変更(市井) + public void updateEmail(String userId, String newEmale, String tokenValue) { + loading.setValue(true); + + userResource.updateEmail(userId, newEmale, tokenValue).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + loading.setValue(false); + if (response.isSuccessful()) { + // LiveData に更新 + User currentUser = user.getValue(); + if (currentUser != null) { + currentUser.setEmail(newEmale); + user.setValue(currentUser); + } + } else { + error.setValue("メールアドレス変更失敗: " + response.code()); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + loading.setValue(false); + error.setValue("通信エラー: " + t.getMessage()); + } + }); + } + + + + //viewModelのところでを呼び出すがフレンド系は西村さんの方で管理する + } diff --git a/app/src/main/java/com/example/tampopo_client/views/AccountActivity.java b/app/src/main/java/com/example/tampopo_client/views/AccountActivity.java index 90ed189..a757838 100644 --- a/app/src/main/java/com/example/tampopo_client/views/AccountActivity.java +++ b/app/src/main/java/com/example/tampopo_client/views/AccountActivity.java @@ -6,18 +6,24 @@ import android.widget.Button; import android.widget.EditText; import android.widget.ImageButton; +import android.widget.Toast; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; +import androidx.lifecycle.ViewModelProvider; +import androidx.lifecycle.Observer; import com.example.tampopo_client.R; import com.example.tampopo_client.Tampopo; +import com.example.tampopo_client.viewmodels.UserViewModel; public class AccountActivity extends AppCompatActivity { + private UserViewModel userViewModel; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -29,6 +35,8 @@ return insets; }); + // ViewModel初期化 + userViewModel = new ViewModelProvider(this).get(UserViewModel.class); //アカウント編集画面から設定画面への遷移 ImageButton buttonReturn = (ImageButton)findViewById(R.id.buttonReturn); @@ -40,67 +48,72 @@ }); //もともとのメールアドレスを表示 - EditText mailbuttonInput = (EditText) findViewById(R.id.mailbutton); + EditText mailbuttonInput = findViewById(R.id.mailbutton); mailbuttonInput.setText(((Tampopo) AccountActivity.this.getApplication()).getMailaddress()); - //決定ボタンを押したときにパスワードとメールアドレスを保存 - Button dicisionbutton = (Button) findViewById(R.id.dicisionbutton); - dicisionbutton.setOnClickListener(new View.OnClickListener() { + // 決定ボタン + Button dicisionbutton = findViewById(R.id.dicisionbutton); + dicisionbutton.setOnClickListener(v -> { - private Object getApplication; + Tampopo app = (Tampopo) getApplication(); - public void onClick(View v) { - //現在のパスワード - EditText beforepasswordbuttonInput = (EditText) findViewById(R.id.beforepasswordbutton); - String beforepasswordbutton = beforepasswordbuttonInput.getText().toString(); + // 現在の(保存されている)パスワード + String currentStoredPassword = app.getPassword() == null ? "" : app.getPassword(); - //パスワード変更 - EditText afterpasswordbutton1Input = (EditText) findViewById(R.id.afterpasswordbutton1); - String afterpasswordbutton1 = afterpasswordbutton1Input.getText().toString(); + // 入力値を取得 + String beforePassword = ((EditText) findViewById(R.id.beforepasswordbutton)).getText().toString(); + String afterPassword1 = ((EditText) findViewById(R.id.afterpasswordbutton1)).getText().toString(); + String afterPassword2 = ((EditText) findViewById(R.id.afterpasswordbutton2)).getText().toString(); + String mailAddress = ((EditText) findViewById(R.id.mailbutton)).getText().toString(); - EditText afterpasswordbutton2Input = (EditText) findViewById(R.id.afterpasswordbutton2); - String afterpasswordbutton2 = afterpasswordbutton1Input.getText().toString(); - ((Tampopo) AccountActivity.this.getApplication()).setPassword(afterpasswordbutton2); + boolean passwordChanged = false; + boolean emailChanged = false; - //メールアドレス登録 - EditText mailbuttonInput = (EditText) findViewById(R.id.mailbutton); - String mailbutton = mailbuttonInput.getText().toString(); - ((Tampopo) AccountActivity.this.getApplication()).setMailaddress(mailbutton); + // パスワード変更チェック + if (!afterPassword1.isEmpty() || !afterPassword2.isEmpty() || !beforePassword.isEmpty()) { - //もし前のパスワードが合っていなかったはじくようにする + // 現在のパスワード確認 + if (!beforePassword.equals(currentStoredPassword)) { + Toast.makeText(this, "現在のパスワードが違います。", Toast.LENGTH_SHORT).show(); + return; + } + // 新しいパスワード2回一致チェック + if (!afterPassword1.equals(afterPassword2)) { + Toast.makeText(this, "新しいパスワードが一致しません。", Toast.LENGTH_SHORT).show(); + return; + } - //決定を押したら設定画面に遷移 - Intent intent = new Intent(AccountActivity.this, SettingActivity.class); - startActivity(intent); + // 新旧同一チェック + if (afterPassword1.equals(currentStoredPassword)) { + Toast.makeText(this, "新しいパスワードは現在のパスワードと同じです。", Toast.LENGTH_SHORT).show(); + return; + } + + // 更新実行 + app.setPassword(afterPassword2); + userViewModel.updatePassword(app.getUserId(), afterPassword2, app.getToken()); + passwordChanged = true; } + + // メールアドレス変更チェック + if (!mailAddress.equals(app.getMailaddress())) { + app.setMailaddress(mailAddress); + userViewModel.updateEmail(app.getUserId(), mailAddress, app.getToken()); + emailChanged = true; + } + + // 結果表示 + if (!passwordChanged && !emailChanged) { + Toast.makeText(this, "変更がありません。", Toast.LENGTH_SHORT).show(); + return; + } + + Toast.makeText(this, "アカウント情報を更新しました。", Toast.LENGTH_SHORT).show(); + + // 設定画面に戻る + Intent intent = new Intent(AccountActivity.this, SettingActivity.class); + startActivity(intent); }); - -// //もし前のパスワードが合っていなかったはじくようにする -// -// -// //決定を押したら設定画面に遷移 -// dicisionbutton.setOnClickListener(new View.OnClickListener() { -// -// private Object getApplication; -// -// public void onClick(View v) { -// -// Intent intent = new Intent(AccountActivity.this, SettingActivity.class); -// startActivity(intent); -// -// -// } -// }); - } - @Override - protected void onStart() { - super.onStart(); - - //もともとのメールアドレスを表示 - EditText mailbuttonInput = (EditText) findViewById(R.id.mailbutton); - mailbuttonInput.setText(((Tampopo) AccountActivity.this.getApplication()).getMailaddress()); - - } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/tampopo_client/views/LoginActivity.java b/app/src/main/java/com/example/tampopo_client/views/LoginActivity.java index 52837ad..5c7ced7 100644 --- a/app/src/main/java/com/example/tampopo_client/views/LoginActivity.java +++ b/app/src/main/java/com/example/tampopo_client/views/LoginActivity.java @@ -46,7 +46,14 @@ @Override public void onChanged(String token) { if (token != null){ - ((Tampopo) LoginActivity.this.getApplication()).setToken(token); + Tampopo app = (Tampopo) LoginActivity.this.getApplication(); + app.setToken(token); + + EditText passwordInput = findViewById(R.id.PasswordText); + String enteredPassword = passwordInput.getText().toString(); + app.setPassword(enteredPassword); + + Intent intent = new Intent(LoginActivity.this, MainActivity.class); startActivity(intent); } diff --git a/app/src/main/java/com/example/tampopo_client/views/LogoutActivity.java b/app/src/main/java/com/example/tampopo_client/views/LogoutActivity.java index 35b0561..f62b98c 100644 --- a/app/src/main/java/com/example/tampopo_client/views/LogoutActivity.java +++ b/app/src/main/java/com/example/tampopo_client/views/LogoutActivity.java @@ -40,7 +40,7 @@ Button logoutbutton = (Button) findViewById(R.id.logoutbutton); logoutbutton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - Intent intent = new Intent(LogoutActivity.this, SettingActivity.class); + Intent intent = new Intent(LogoutActivity.this, LaunchActivity.class); startActivity(intent); } }); diff --git a/app/src/main/java/com/example/tampopo_client/views/ProfileActivity.java b/app/src/main/java/com/example/tampopo_client/views/ProfileActivity.java index 075b7ff..b94a61b 100644 --- a/app/src/main/java/com/example/tampopo_client/views/ProfileActivity.java +++ b/app/src/main/java/com/example/tampopo_client/views/ProfileActivity.java @@ -1,23 +1,69 @@ package com.example.tampopo_client.views; + import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageButton; +import android.widget.ImageView; import androidx.activity.EdgeToEdge; +import androidx.activity.result.ActivityResultCallback; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; +import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProvider; +import com.bumptech.glide.Glide; import com.example.tampopo_client.R; import com.example.tampopo_client.Tampopo; +import com.example.tampopo_client.viewmodels.UserViewModel; +import com.google.android.material.imageview.ShapeableImageView; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.security.AccessController; +import java.util.Base64; public class ProfileActivity extends AppCompatActivity { + private UserViewModel userViewModel; + Tampopo app; + private String changeIconUrl; + private boolean iconFlag; + ShapeableImageView iconView; + + private ActivityResultLauncher launcher = registerForActivityResult(new ActivityResultContracts.OpenDocument(), new ActivityResultCallback() { + @Override + public void onActivityResult(Uri uri) { + if(uri == null)return; + ShapeableImageView changeIconButton = findViewById(R.id.changeIcon); + changeIconButton.setImageURI(uri); + try { + InputStream inputStream = getApplicationContext().getContentResolver().openInputStream(uri); + Bitmap bitmap = BitmapFactory.decodeStream(new BufferedInputStream(inputStream)); + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); + byte[] byteArray = stream.toByteArray(); + changeIconUrl = Base64.getEncoder().encodeToString(byteArray); + iconFlag = true; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + }); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -29,9 +75,19 @@ return insets; }); + // ViewModel初期化 + userViewModel = new ViewModelProvider(this).get(UserViewModel.class); + + app = (Tampopo) getApplication(); + String uid = app.getUserId(); + + ShapeableImageView iconView = findViewById(R.id.myicon); + ShapeableImageView changeIconView = findViewById(R.id.changeIcon); + + //プロフィール編集画面から設定画面への遷移 - ImageButton buttonReturn = (ImageButton)findViewById(R.id.buttonReturn); + ImageButton buttonReturn = (ImageButton) findViewById(R.id.buttonReturn); buttonReturn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Intent intent = new Intent(ProfileActivity.this, SettingActivity.class); @@ -39,51 +95,65 @@ } }); - //もともとのidとニックネームを表示 + + //もともとのidとニックネームとアイコンを表示 + userViewModel.getIconAsync(uid); + userViewModel.getIcon().observe(this, new Observer() { + @Override + public void onChanged(String iconUrl) { + Glide.with(ProfileActivity.this).load(iconUrl).into(iconView); + } + }); + EditText nicknameInput = (EditText) findViewById(R.id.nicknamebutton); nicknameInput.setText(((Tampopo) ProfileActivity.this.getApplication()).getNickname()); - EditText useridInput = (EditText) findViewById(R.id.idbutton); + EditText useridInput = findViewById(R.id.idbutton); useridInput.setText(((Tampopo) ProfileActivity.this.getApplication()).getUserId()); + //IDを変更できないようにする + useridInput.setEnabled(false); - //決定ボタンを押したときにidとニックネームを保存 + //アイコンを押したときの変更 + iconView.setOnClickListener(new View.OnClickListener(){ + public void onClick(View v) { + launcher.launch(new String[] {"image/*"}); + } + + }); + + //決定ボタン Button dicisionbutton = findViewById(R.id.dicisionbutton); + //決定ボタンを押したときにidとニックネームとアイコンを保存 dicisionbutton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { + + EditText usernicknameInput = findViewById(R.id.nicknamebutton); String usernickname = usernicknameInput.getText().toString(); EditText useridInput = findViewById(R.id.idbutton); String userid = useridInput.getText().toString(); - // Application(Tampopo)に保存(→SharedPreferencesにも自動保存される) - Tampopo app = (Tampopo) getApplication(); + // Application(Tampopo)に保存 + app.setNickname(usernickname); app.setUserId(userid); + userViewModel.updateName(app.getUserId(), usernickname, app.getToken()); + if(iconFlag){ + Bitmap iconBitmap = ((BitmapDrawable) changeIconView.getDrawable()).getBitmap(); + userViewModel.updateIcon(app.getUserId(),changeIconUrl,app.getToken()); + app.setIcon(changeIconUrl); + } + // 設定画面に戻る Intent intent = new Intent(ProfileActivity.this, SettingActivity.class); startActivity(intent); } }); - //決定を押したら設定画面に遷移 -// dicisionbutton.setOnClickListener(new View.OnClickListener() { -// -// private Object getApplication; -// -// public void onClick(View v) { -// -// //決定を押したら設定画面に遷移 -// Intent intent = new Intent(ProfileActivity.this, SettingActivity.class); -// startActivity(intent); -// -// -// } -// }); - } @@ -92,15 +162,13 @@ super.onStart(); //もともとのidとニックネームを表示 - EditText nicknameInput = (EditText) findViewById(R.id.nicknamebutton); + EditText nicknameInput = findViewById(R.id.nicknamebutton); nicknameInput.setText(((Tampopo) ProfileActivity.this.getApplication()).getNickname()); - EditText useridInput = (EditText) findViewById(R.id.idbutton); + EditText useridInput = findViewById(R.id.idbutton); useridInput.setText(((Tampopo) ProfileActivity.this.getApplication()).getUserId()); } - - } diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index 4e5056c..fc779ad 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -7,6 +7,26 @@ android:layout_height="match_parent" tools:context=".views.ProfileActivity"> + +