diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b1a2f41..7ec1c97 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -44,6 +44,7 @@ implementation(libs.retrofit2.retrofit) implementation(libs.converter.jackson) implementation(libs.navigation.runtime.android) + implementation (libs.material.v1100) testImplementation(libs.junit) androidTestImplementation(libs.ext.junit) androidTestImplementation(libs.espresso.core) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cbab318..ec9f1f7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,8 +1,10 @@ + > getActivities(@Path("user_id") String userId, @Query("filter") String filter); + + @POST("users/{user_id}/activities") + @FormUrlEncoded + Call addActivity(@Path("user_id") String userId, @Field("token") String token, @Field("new-activity") String newActivity); // FIXME: We need to rename new-activity to new_activity + + @GET("users/{user_id}/activities/{activity_id}") + Call getActivity(@Path("user_id") String userId, @Path("activity_id") String activityId); + + @DELETE("users/{user_id}/activities/{activity_id}") + Call deleteActivity(@Path("user_id") String userId, @Path("activity_id") String activityId, @Query("token") String token); + + @GET("users/{user_id}/activities/{activity_id}/text") + Call getText(@Path("user_id") String userId, @Path("activity_id") String activityId); + + @GET("users/{user_id}/activities/{activity_id}/updated-time") + Call getUpdatedTime(@Path("user_id") String userId, @Path("activity_id") String activityId); + + @GET("users/{user_id}/activities/last-updated-time") + Call getLastUpdatedTime(@Path("user_id") String userId, @Path("activity_id") String activityId); +} 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 new file mode 100644 index 0000000..7db852b --- /dev/null +++ b/app/src/main/java/com/example/tampopo_client/resources/UserResource.java @@ -0,0 +1,130 @@ +package com.example.tampopo_client.resources; +import com.example.tampopo_client.models.User; +import com.example.tampopo_client.models.FriendPair; +import java.util.List; + +import retrofit2.Call; +import retrofit2.http.DELETE; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.POST; +import retrofit2.http.PUT; +import retrofit2.http.Path; +import retrofit2.http.Query; + +public interface UserResource { + + + // 全ユーザ取得 + @GET("users") + Call> getUsers(); + + // 新規アカウントを作る + @FormUrlEncoded + @POST("users") + Call createUser( + @Field("user-id") String userId, + @Field("password") String password + ); + + + // 単一アカウントの情報を返す + @GET("users/{user-id}") + Call getUser(@Path("user-id") String userId); + + // ユーザ削除 + @DELETE("users/{user-id}") + Call deleteUser( + @Path("user-id") String userId, + @Query("token") String token + ); + + + //ログイン + @FormUrlEncoded + @POST("users/{user-id}/login") + Call login( + @Path("user-id") String userId, + @Field("password") String password + ); + + //アカウントのニックネームの取得 + @GET("users/{user-id}/name") + Call getName(@Path("user-id") String userId); + + //ニックネームの変更 + @FormUrlEncoded + @PUT("users/{user-id}/name") + Call updateName( + @Path("user-id") String userId, + @Field("new-name") String newName, + @Field("token") String token + ); + + // 単一アカウントのパスワードの取得 + @GET("users/{user-id}/password") + Call getPassword( + @Path("user-id") String userId, + @Query("token") String token + ); + + //指定されたIDのパスワードを変更する + @FormUrlEncoded + @PUT("users/{user-id}/password") + Call updatePassword( + @Path("user-id") String userId, + @Field("new-password") String newPassword + ); + + //単一アカウントのemailの取得 + @GET("users/{user-id}/email") + Call getEmail(@Path("user-id") String userId); + + //指定されたIDのemailを変更する + @FormUrlEncoded + @PUT("users/{user-id}/email") + Call updateEmail( + @Path("user-id") String userId, + @Field("new-email") String newEmail, + @Field("token") String token + ); + + //指定されたIDのアイコンを返す + @GET("users/{user-id}/icon") + Call getIcon(@Path("user-id") String userId); + + //アイコンを変更する + @FormUrlEncoded + @PUT("users/{user-id}/icon") + Call updateIcon( + @Path("user-id") String userId, + @Field("new-icon") String newIcon, + @Field("token") String token + ); + + //フレンド関連だがuserに置いておく + //フレンド相手の情報の取得 + @GET("users/{user-id}/friends") + Call> getFriends( + @Path("user-id") String userId, + @Query("token") String token + ); + + //自分のペアのpid一覧(JSON)の取得 + @GET("users/{user-id}/friends/{pair-id}") + Call getFriendPair( + @Path("user-id") String userId, + @Path("pair-id") int pairId, + @Query("token") String token + ); + + //ペアの削除 + @DELETE("users/{user-id}/friends/{pair-id}") + Call deleteFriendPair( + @Path("user-id") String userId, + @Path("pair-id") int pairId, + @Query("token") String token + ); + +} diff --git a/app/src/main/java/com/example/tampopo_client/viewmodels/ActivityViewModel.java b/app/src/main/java/com/example/tampopo_client/viewmodels/ActivityViewModel.java new file mode 100644 index 0000000..5a2e999 --- /dev/null +++ b/app/src/main/java/com/example/tampopo_client/viewmodels/ActivityViewModel.java @@ -0,0 +1,84 @@ +package com.example.tampopo_client.viewmodels; + +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +import com.example.tampopo_client.models.Activity; +import com.example.tampopo_client.resources.ActivitiesResource; + +import java.util.ArrayList; +import java.util.List; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.converter.jackson.JacksonConverterFactory; + +/** + * アクティビティを扱うためのViewModel + * + * @author Shohei Yamagiwa + * @implNote Repositoryは作成せずに、すべてViewModelで処理する + */ +public class ActivityViewModel extends ViewModel { + private final ActivitiesResource activitiesResource; + + private final MutableLiveData> activitiesLiveData; + + public ActivityViewModel() { + final Retrofit retrofit = new Retrofit.Builder() + .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/tampopo/") + .addConverterFactory(JacksonConverterFactory.create()) + .build(); + activitiesResource = retrofit.create(ActivitiesResource.class); + + activitiesLiveData = new MutableLiveData<>(List.of()); + } + + public void createActivity(String userId, String token, String newActivity) { + Call createActivityCall = activitiesResource.addActivity(userId, token, newActivity); + createActivityCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + String createdActivityId = response.body(); + + // TODO: 仮作成なので改善必須 + Call getActivityCall = activitiesResource.getActivity(userId, createdActivityId); + getActivityCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + List activities = activitiesLiveData.getValue(); + if (activities == null) { + activities = new ArrayList<>(); + } + Activity createdActivity = response.body(); + activities.add(createdActivity); + activitiesLiveData.postValue(activities); + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.e(ActivityViewModel.class.getSimpleName(), "An error has occurred.", t); + } + }); + } else { + Log.e(ActivityViewModel.class.getSimpleName(), response.code() + " " + response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.e(ActivityViewModel.class.getSimpleName(), "An error has occurred.", t); + } + }); + } + + public MutableLiveData> getActivitiesLiveData() { + return activitiesLiveData; + } +} diff --git a/app/src/main/java/com/example/tampopo_client/viewmodels/FriendReceivedRequestViewModel.java b/app/src/main/java/com/example/tampopo_client/viewmodels/FriendReceivedRequestViewModel.java index fb1c277..596ddc4 100644 --- a/app/src/main/java/com/example/tampopo_client/viewmodels/FriendReceivedRequestViewModel.java +++ b/app/src/main/java/com/example/tampopo_client/viewmodels/FriendReceivedRequestViewModel.java @@ -8,6 +8,9 @@ import java.util.List; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.jackson.JacksonConverterFactory; @@ -17,24 +20,77 @@ //APIの窓口 private final FriendRequestsResource friendRequestsResource; //自分が受け取った申請 - private final MutableLiveData> receivedRequests ; + private final MutableLiveData> receivedRequests; //通信結果の状態 - private final MutableLiveData operationResult ; + private final MutableLiveData operationResult; public FriendReceivedRequestViewModel() { this.retrofit = new Retrofit.Builder() - .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/tampopo-server/") + .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/tampopo/") .addConverterFactory(JacksonConverterFactory.create()) .build(); this.friendRequestsResource = retrofit.create(FriendRequestsResource.class); this.receivedRequests = new MutableLiveData<>(); this.operationResult = new MutableLiveData<>(); } + //viewがobserve出来るように public MutableLiveData> getSentRequestsLiveData() { return receivedRequests; } + //サーバーから受け取ったFriendReceivedRequestのデータを格納してキャッシュしていくぞ + public void loadReceivedRequests(String token) { + //tokenを渡して、受信フレンド申請一覧を取得するHTTPリクエスト(Webのサーバーに対して何かをお願いするメッセージ」)を作る準備をしている + Call> call = friendRequestsResource.getFriendRequests(token); + //call.enqueueでサーバーへ送信(何を?) + call.enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.isSuccessful()) { + //通信が成功したらLiveDataへのキャッシュ + receivedRequests.setValue(response.body()); + operationResult.setValue("Success"); + System.out.println("Success SetValue" + response.body()); + } else { + operationResult.setValue("Error: " + response.code()); + System.out.println("response error"); + } + } + @Override + public void onFailure(Call> call, Throwable t) { + operationResult.setValue("Network error: " + t.getMessage()); + System.out.println("ネットワークエラー: " + t); + } + }); + } + // フレンドリクエスト削除メソッド + public void deleteFriendRequest(String friendRequestId, String token) { + Call call = friendRequestsResource.deleteFriendRequest(friendRequestId, token); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + operationResult.setValue("Friend request deleted successfully."); + loadReceivedRequests(token); // 削除後、一覧を更新 + System.out.println("Deleted friend request ID: " + friendRequestId); + } else { + operationResult.setValue("Error deleting request: " + response.code()); + System.out.println("Error deleting request: " + response.code()); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + operationResult.setValue("Network error: " + t.getMessage()); + System.out.println("Network error: " + t); + } + }); + } } + + + diff --git a/app/src/main/java/com/example/tampopo_client/viewmodels/FriendSentRequestViewModel.java b/app/src/main/java/com/example/tampopo_client/viewmodels/FriendSentRequestViewModel.java index 6676003..c9a99ea 100644 --- a/app/src/main/java/com/example/tampopo_client/viewmodels/FriendSentRequestViewModel.java +++ b/app/src/main/java/com/example/tampopo_client/viewmodels/FriendSentRequestViewModel.java @@ -6,44 +6,107 @@ import com.example.tampopo_client.models.FriendRequest; import com.example.tampopo_client.resources.FriendRequestsResource; - import java.util.List; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.jackson.JacksonConverterFactory; public class FriendSentRequestViewModel extends ViewModel { - //サーバー(API)と通信するためのツール + // サーバー(API)と通信するためのツール private final Retrofit retrofit; + // APIの窓口 private final FriendRequestsResource friendRequestsResource; - //自分が送った申請 - private final MutableLiveData> sentRequests ; - //変数がfinalやから一回しか代入できません - //sentRequestで呼び出される、viewモデルの下のコンストラクターがアンドロイドがで呼び出される - // 処理の進行中 - private final MutableLiveData operationResult ; + // 自分が送ったフレンド申請一覧 + private final MutableLiveData> sentRequests; + // 処理の進行状況や結果を表示するためのステータスメッセージ + private final MutableLiveData operationResult; + // コンストラクタ(ViewModel生成時に呼び出される) public FriendSentRequestViewModel() { - this.retrofit = new Retrofit.Builder() - .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/tampopo-server/") + .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/tampopo/") .addConverterFactory(JacksonConverterFactory.create()) .build(); this.friendRequestsResource = retrofit.create(FriendRequestsResource.class); this.sentRequests = new MutableLiveData<>(); this.operationResult = new MutableLiveData<>(); - } - //viewがobserve出来るように - public MutableLiveData> getSentRequestsLiveData() { - return sentRequests; - } -//Mutable Livedataの宣言 + // Viewがobserveできるようにgetterを用意 + public MutableLiveData> getSentRequestsLiveData() { + return sentRequests; + } + + public MutableLiveData getOperationResult() { + return operationResult; + } + + // サーバーから送信済みフレンドリクエスト一覧を取得してキャッシュに保存 + public void loadSentRequests(String token) { + Call> call = friendRequestsResource.getFriendRequests(token); + + call.enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.isSuccessful()) { + sentRequests.setValue(response.body()); + operationResult.setValue("Success"); + System.out.println("Success SetValue: " + response.body()); + } else { + operationResult.setValue("Error: " + response.code()); + System.out.println("Response error: " + response.code()); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + operationResult.setValue("Network error: " + t.getMessage()); + System.out.println("Network error: " + t); + } + }); + } + + // サーバーにフレンド申請を送信するメソッド + public void sendFriendRequest(String senderId, String receiverId, String token) { + Call call = friendRequestsResource.postFriendRequest(token, senderId, receiverId); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + //Retrofitでサーバーにリクエストを送った後、その結果が帰ってくる。成功 + operationResult.setValue("Friend request sent successfully."); + + // 成功時に送信済みリストを更新 + loadSentRequests(token); + + System.out.println("Friend request sent: " + response.body()); + } else { + operationResult.setValue("Error sending request: " + response.code()); + System.out.println("Error sending request: " + response.code()); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + operationResult.setValue("Network error: " + t.getMessage()); + System.out.println("Network error: " + t); + } + }); + } +} + + + + + @@ -123,4 +186,4 @@ // } //} -} + diff --git a/app/src/main/java/com/example/tampopo_client/viewmodels/FriendViewModel.java b/app/src/main/java/com/example/tampopo_client/viewmodels/FriendViewModel.java index b85f756..a4e6274 100644 --- a/app/src/main/java/com/example/tampopo_client/viewmodels/FriendViewModel.java +++ b/app/src/main/java/com/example/tampopo_client/viewmodels/FriendViewModel.java @@ -1,22 +1,87 @@ package com.example.tampopo_client.viewmodels; +import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import com.example.tampopo_client.models.FriendPair; import com.example.tampopo_client.resources.FriendsResource; +import com.example.tampopo_client.resources.UserResource; +import java.util.List; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.jackson.JacksonConverterFactory; +import retrofit2.http.Field; public class FriendViewModel extends ViewModel { private final Retrofit retrofit; + private final UserResource usersResource; private final FriendsResource friendsResource; + private final MutableLiveData> friendIdsLiveData; + private final MutableLiveData friendPair; public FriendViewModel(){ this.retrofit = new Retrofit.Builder() - .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/tampopo-server/") + .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/tampopo/") .addConverterFactory(JacksonConverterFactory.create()) .build(); + this.usersResource = retrofit.create(UserResource.class); this.friendsResource = retrofit.create(FriendsResource.class); + this.friendIdsLiveData = new MutableLiveData<>(); + this.friendPair = new MutableLiveData<>(); + } + + public MutableLiveData> getFriendIdsLiveData(){ + return this.friendIdsLiveData; + } + public MutableLiveData getFriendPair(){ + return this.friendPair; + } + + public void loadFriends(String userId, String token){ + Call> call = usersResource.getFriends(userId, token); + + call.enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if(response.isSuccessful()){ + List friendIds = response.body(); + friendIdsLiveData.setValue(friendIds); + System.out.println(response.code()); + }else{ + System.out.println(response.code()); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + System.out.println("NetWorkError" + t); + } + }); + } + + public void addFriend(String token, String user0Id, String user1Id){ + Call call = friendsResource.createFriend(token, user0Id, user1Id); + + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if(response.isSuccessful()){ + friendPair.setValue(response.body()); + System.out.println(response.code()); + }else{ + System.out.println(response.code()); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + System.out.println("NetWorkError" + t); + } + }); } } 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 new file mode 100644 index 0000000..f16fdf6 --- /dev/null +++ b/app/src/main/java/com/example/tampopo_client/viewmodels/UserViewModel.java @@ -0,0 +1,106 @@ +package com.example.tampopo_client.viewmodels; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +import com.example.tampopo_client.models.User; +import com.example.tampopo_client.resources.UserResource; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.converter.jackson.JacksonConverterFactory; + +/*userだけなのでサーバーから情報を取ってくることは名前の変更 +viewModelはviewからrequestをもらってmodelに流す +88行目にviewからviewmodelをとる +viewmodelのインスタンスは1個しかなし +128 観測するという宣言をする +observeは2つ引数をもち、一つ目は固定、2つ目は 無名クラスで長い new observerとあるがこれはインスタンスを作っているわけではないここでしかない使わないローカルなクラス +observerの子クラスである。 observerの無名子クラスと生成するのとインスタンスを作成する 画面の変更をlistenしている + +viewModel側  +viewModelからsetValueで値を変えていく +updateUserName、updateEmail、login、createUserもある。それらを書いていく。viewから必要なものを出していく + +viewとviewModels +イベントパターン +1.画面を表示するごとに値を取る +2.ボタンを押した際の通信をする +3.画面の途中で更新する + +view側がviewModelを使うための方法 +1.最初にUserViewModel userViewModelで宣言 88行目 userViewModelのインスタンスを作る + +*/ + +public class UserViewModel extends ViewModel { + + private final Retrofit retrofit; + private final UserResource userResource; + private final MutableLiveData user = new MutableLiveData<>(); + private final MutableLiveData token = new MutableLiveData<>(); + private final MutableLiveDataloading = new MutableLiveData<>(false); + private final MutableLiveData error = new MutableLiveData<>(); + + //コンストラクタ + public UserViewModel(){ + this.retrofit = new Retrofit.Builder() + .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/tampopo/") + .addConverterFactory(JacksonConverterFactory.create()) + .build(); + this.userResource = retrofit.create(UserResource.class); + } + + public LiveData getUser() { return user; } + public LiveData getToken() { return token; } + public LiveDataisLoading() { return loading;} + public LiveData getError() { return error; } + + //新規登録 enqueueで非同期処理、Callbackで成功失敗の処理、LiveDataに反映 + //サーバーから返ってきた型と合わせないとFailureに流れる + //tokenはログイン処理後に発行されるため削除しました。 + public void createUser(String id, String password) { + loading.setValue(true); + userResource.createUser(id, password).enqueue(new Callback() { + @Override public void onResponse(Call c, Response res) { + loading.setValue(false); + if (res.isSuccessful()) { + User u = res.body(); + user.setValue(u); + } else { + error.setValue("登録失敗: " + res.code()); + } + } + @Override public void onFailure(Call c, Throwable t) { + loading.setValue(false); + error.setValue("エラー: " + t.getMessage()); + } + }); + } + + //ログイン + public void login(String id, String password) { + loading.setValue(true); + userResource.login(id, password).enqueue(new Callback() { + @Override public void onResponse(Call c, Response res) { + loading.setValue(false); + if (res.isSuccessful()) { + userResource.getUser(id); + token.setValue(res.body()); + + } else { + error.setValue("ログイン失敗: " + res.code()); + } + } + @Override public void onFailure(Call c, Throwable t) { + loading.setValue(false); + error.setValue("エラー: " + t.getMessage()); + } + }); + } + + //viewModelのところでを呼び出すがフレンド系は西村さんの方で管理する +} diff --git a/app/src/main/java/com/example/tampopo_client/views/FriendListFragment.java b/app/src/main/java/com/example/tampopo_client/views/FriendListFragment.java index b616b19..203ab3b 100644 --- a/app/src/main/java/com/example/tampopo_client/views/FriendListFragment.java +++ b/app/src/main/java/com/example/tampopo_client/views/FriendListFragment.java @@ -13,7 +13,7 @@ import android.view.ViewGroup; import com.example.tampopo_client.R; -import com.example.tampopo_client.views.placeholder.PlaceholderContent; +import com.example.tampopo_client.views.placeholder.FriendContent; /** * A fragment representing a list of Items. @@ -65,7 +65,7 @@ } else { recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount)); } - recyclerView.setAdapter(new MyFriendRecyclerViewAdapter(PlaceholderContent.ITEMS)); + recyclerView.setAdapter(new MyFriendRecyclerViewAdapter(FriendContent.ITEMS)); } return view; } diff --git a/app/src/main/java/com/example/tampopo_client/views/FriendReceivedFragment.java b/app/src/main/java/com/example/tampopo_client/views/FriendReceivedFragment.java index b320d46..abe19ae 100644 --- a/app/src/main/java/com/example/tampopo_client/views/FriendReceivedFragment.java +++ b/app/src/main/java/com/example/tampopo_client/views/FriendReceivedFragment.java @@ -13,7 +13,7 @@ import android.view.ViewGroup; import com.example.tampopo_client.R; -import com.example.tampopo_client.views.placeholder.PlaceholderContent; +import com.example.tampopo_client.views.placeholder.FriendRequestContent; /** * A fragment representing a list of Items. @@ -65,7 +65,7 @@ } else { recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount)); } - recyclerView.setAdapter(new MyFriendRequestRecyclerViewAdapter(PlaceholderContent.ITEMS)); + recyclerView.setAdapter(new MyFriendRequestRecyclerViewAdapter(FriendRequestContent.ITEMS)); } return view; } diff --git a/app/src/main/java/com/example/tampopo_client/views/LaunchActivity.java b/app/src/main/java/com/example/tampopo_client/views/LaunchActivity.java index d36fa48..c3076d4 100644 --- a/app/src/main/java/com/example/tampopo_client/views/LaunchActivity.java +++ b/app/src/main/java/com/example/tampopo_client/views/LaunchActivity.java @@ -10,8 +10,12 @@ import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; +import androidx.lifecycle.ViewModelProvider; import com.example.tampopo_client.R; +import com.example.tampopo_client.viewmodels.UserViewModel; + +import retrofit2.Retrofit; public class LaunchActivity extends AppCompatActivity { 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 a72efcb..64a5c94 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 @@ -1,16 +1,26 @@ package com.example.tampopo_client.views; +import android.content.Intent; import android.os.Bundle; - +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.EditText; +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 com.example.tampopo_client.R; +import com.example.tampopo_client.Tampopo; +import com.example.tampopo_client.viewmodels.UserViewModel; public class LoginActivity extends AppCompatActivity { + UserViewModel userViewModel; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -21,5 +31,46 @@ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); + userViewModel = new ViewModelProvider(this).get(UserViewModel.class); + + userViewModel.getError().observe(this, + msg -> { + if (msg != null) { + Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); + } + }); + + Button button_login = (Button) findViewById(R.id.loginbutton); + button_login.setOnClickListener(new OnClickListener() { + + private Object getApplication; + + public void onClick(View v) { + EditText useridInput = (EditText) findViewById(R.id.userIDText); + String userid = useridInput.getText().toString(); + EditText passwordInput = (EditText) findViewById(R.id.PasswordText); + String password = passwordInput.getText().toString(); + userViewModel.login(userid, password); + + userViewModel.getToken().getValue(); + //TODO:上記のトークンを使ってTampopoクラスにセットするコードを書く + //((Tampopo)this.getApplication).setToken(token); + + + Intent intent = new Intent(LoginActivity.this, MainActivity.class); + startActivity(intent); + + } + }); + + Button button_createaccount = (Button) findViewById(R.id.createaccountbutton); + button_createaccount.setOnClickListener(new OnClickListener() { + + public void onClick(View v) { + Intent intent = new Intent(LoginActivity.this, RegisterActivity.class); + startActivity(intent); + } + }); + } } \ No newline at end of file diff --git a/app/src/main/java/com/example/tampopo_client/views/MainActivity.java b/app/src/main/java/com/example/tampopo_client/views/MainActivity.java index c253be2..21e3aae 100644 --- a/app/src/main/java/com/example/tampopo_client/views/MainActivity.java +++ b/app/src/main/java/com/example/tampopo_client/views/MainActivity.java @@ -1,12 +1,20 @@ package com.example.tampopo_client.views; import android.content.Intent; +import android.graphics.Color; import android.os.Bundle; import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.ArrayAdapter; import android.widget.Button; +import android.widget.EditText; +import android.widget.GridView; import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.TextView; import androidx.activity.EdgeToEdge; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; @@ -16,6 +24,14 @@ public class MainActivity extends AppCompatActivity { + private EditText editMessage; + private ImageButton sendButton; + private GridView wordGroup; + private LinearLayout messageList; + //アクティビティの選択肢 + private String[] words = {"ひまnow","あそぼ!","そろそろ会いたない〜?", "勉強なう", "電話しよ~", "お風呂入ってくる~","今暇だよー!","いそがしい~!!"}; + private Button openDialogButton; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -54,5 +70,78 @@ // } // }); + messageList = findViewById(R.id.messageList); + + // ボタンを押すとダイアログ表示(トリガー用) + openDialogButton = findViewById(R.id.openDialogButton); + openDialogButton.setOnClickListener(v -> showInputDialog()); + + } + private void showInputDialog() { + // カスタムビュー読み込み + View dialogView = getLayoutInflater().inflate(R.layout.main_dialog, null); + EditText editTextInput = dialogView.findViewById(R.id.editTextInput); + GridView wordGrid = dialogView.findViewById(R.id.wordGrid); + ImageButton sendButton = dialogView.findViewById(R.id.sendButton); + + // 語群セット + ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, words); + wordGrid.setAdapter(adapter); + + // 語群クリックで入力欄にセット + wordGrid.setOnItemClickListener((parent, view, position, id) -> { + editTextInput.setText(words[position]); + // 入力欄にフォーカス&キーボード表示 + editTextInput.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); + imm.showSoftInput(editTextInput, InputMethodManager.SHOW_IMPLICIT); + }); + + // ダイアログ生成 + AlertDialog dialog = new AlertDialog.Builder(this) + .setView(dialogView) + .create(); + + // 送信ボタン処理 + sendButton.setOnClickListener(v -> { + String message = editTextInput.getText().toString().trim(); + int length = message.length(); + if (!message.isEmpty()) { + if(length > 20){ + openDialogButton.setTextSize(7); + }else if(length > 10){ + openDialogButton.setTextSize(10); + }else{ + openDialogButton.setTextSize(12); + } + openDialogButton.setMaxLines(10); + openDialogButton.setLineSpacing(4.0f,1.2f); + openDialogButton.setText(message); + editTextInput.setText(""); + dialog.dismiss(); // ダイアログを閉じる + }else{ + openDialogButton.setText(""); + } + }); + + dialog.show(); + } + + private void addMessageToHome(String message) { + TextView textView = new TextView(this); + textView.setText(message); + textView.setPadding(10, 10, 10, 10); + textView.setBackgroundColor(Color.parseColor("#E0E0E0")); + int length = message.length(); + if(length > 10){ + textView.setTextSize(5); + }else if(length > 7){ + textView.setTextSize(8); + }else{ + textView.setTextSize(10); + } + textView.setMaxLines(10); + textView.setLineSpacing(4.0f,1.2f); + messageList.addView(textView); } } \ No newline at end of file diff --git a/app/src/main/java/com/example/tampopo_client/views/MyFriendRecyclerViewAdapter.java b/app/src/main/java/com/example/tampopo_client/views/MyFriendRecyclerViewAdapter.java index 5ee7ffe..1bdcbeb 100644 --- a/app/src/main/java/com/example/tampopo_client/views/MyFriendRecyclerViewAdapter.java +++ b/app/src/main/java/com/example/tampopo_client/views/MyFriendRecyclerViewAdapter.java @@ -1,26 +1,25 @@ package com.example.tampopo_client.views; -import androidx.recyclerview.widget.RecyclerView; - import android.view.LayoutInflater; -import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import com.example.tampopo_client.views.placeholder.PlaceholderContent.PlaceholderItem; import com.example.tampopo_client.databinding.FragmentFriendListBinding; +import com.example.tampopo_client.views.placeholder.FriendContent; import java.util.List; +import androidx.recyclerview.widget.RecyclerView; + /** - * {@link RecyclerView.Adapter} that can display a {@link PlaceholderItem}. + * {@link RecyclerView.Adapter} that can display a {@link FriendContent.FriendItem}. * TODO: Replace the implementation with code for your data type. */ public class MyFriendRecyclerViewAdapter extends RecyclerView.Adapter { - private final List mValues; + private final List mValues; - public MyFriendRecyclerViewAdapter(List items) { + public MyFriendRecyclerViewAdapter(List items) { mValues = items; } @@ -34,7 +33,7 @@ @Override public void onBindViewHolder(final ViewHolder holder, int position) { holder.mItem = mValues.get(position); - holder.mIdView.setText(mValues.get(position).id); + //holder.mIdView.setText(mValues.get(position).id); holder.mContentView.setText(mValues.get(position).content); } @@ -44,13 +43,13 @@ } public class ViewHolder extends RecyclerView.ViewHolder { - public final TextView mIdView; + //public final TextView mIdView; public final TextView mContentView; - public PlaceholderItem mItem; + public FriendContent.FriendItem mItem; public ViewHolder(FragmentFriendListBinding binding) { super(binding.getRoot()); - mIdView = binding.itemNumber; + //mIdView = binding.itemNumber; mContentView = binding.content; } diff --git a/app/src/main/java/com/example/tampopo_client/views/MyFriendRequestRecyclerViewAdapter.java b/app/src/main/java/com/example/tampopo_client/views/MyFriendRequestRecyclerViewAdapter.java index 09d6193..9640389 100644 --- a/app/src/main/java/com/example/tampopo_client/views/MyFriendRequestRecyclerViewAdapter.java +++ b/app/src/main/java/com/example/tampopo_client/views/MyFriendRequestRecyclerViewAdapter.java @@ -3,24 +3,23 @@ import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; -import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import com.example.tampopo_client.views.placeholder.PlaceholderContent.PlaceholderItem; +import com.example.tampopo_client.views.placeholder.FriendRequestContent.FriendRequestItem; import com.example.tampopo_client.databinding.FragmentFriendReceivedBinding; import java.util.List; /** - * {@link RecyclerView.Adapter} that can display a {@link PlaceholderItem}. + * {@link RecyclerView.Adapter} that can display a {@link FriendRequestItem}. * TODO: Replace the implementation with code for your data type. */ public class MyFriendRequestRecyclerViewAdapter extends RecyclerView.Adapter { - private final List mValues; + private final List mValues; - public MyFriendRequestRecyclerViewAdapter(List items) { + public MyFriendRequestRecyclerViewAdapter(List items) { mValues = items; } @@ -34,7 +33,7 @@ @Override public void onBindViewHolder(final ViewHolder holder, int position) { holder.mItem = mValues.get(position); - holder.mIdView.setText(mValues.get(position).id); + //holder.mIdView.setText(mValues.get(position).id); holder.mContentView.setText(mValues.get(position).content); } @@ -44,13 +43,13 @@ } public class ViewHolder extends RecyclerView.ViewHolder { - public final TextView mIdView; + //public final TextView mIdView; public final TextView mContentView; - public PlaceholderItem mItem; + public FriendRequestItem mItem; public ViewHolder(FragmentFriendReceivedBinding binding) { super(binding.getRoot()); - mIdView = binding.itemNumber; + //mIdView = binding.itemNumber; mContentView = binding.content; } diff --git a/app/src/main/java/com/example/tampopo_client/views/RegisterActivity.java b/app/src/main/java/com/example/tampopo_client/views/RegisterActivity.java index 4ba2800..625e438 100644 --- a/app/src/main/java/com/example/tampopo_client/views/RegisterActivity.java +++ b/app/src/main/java/com/example/tampopo_client/views/RegisterActivity.java @@ -4,16 +4,23 @@ import android.os.Bundle; import android.view.View; import android.widget.Button; +import android.widget.EditText; +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 com.example.tampopo_client.R; +import com.example.tampopo_client.Tampopo; +import com.example.tampopo_client.viewmodels.UserViewModel; public class RegisterActivity extends AppCompatActivity { + private Tampopo tampopo; + UserViewModel userViewModel; @Override protected void onCreate(Bundle savedInstanceState) { @@ -25,19 +32,55 @@ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); - Button button_register = (Button) findViewById(R.id.Registerbutton); - button_register.setOnClickListener(new View.OnClickListener() { + + //Tampopoの取得 + tampopo = (Tampopo) this.getApplication(); + //ViewModel の取得 + userViewModel = new ViewModelProvider(this).get(UserViewModel.class); + + //入力欄の取得 + EditText userIdEditText = findViewById(R.id.editTextUserId); + EditText passwordEditText = findViewById(R.id.editTextPassword); + + + //登録 + Button registerButton = (Button) findViewById(R.id.Registerbutton); + registerButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - Intent intent = new Intent(RegisterActivity.this,LoginActivity.class); - startActivity(intent); + String userId = userIdEditText.getText().toString().trim(); + String password = passwordEditText.getText().toString().trim(); + + //空文字チェック + if (userId.isEmpty() || password.isEmpty()) { + Toast.makeText(RegisterActivity.this, "IDとパスワードを入力してください", Toast.LENGTH_SHORT).show(); + return; + } + + //通信 + userViewModel.createUser(userId, password); + + + //アカウントの確認、問題なければ通信 + if (userViewModel.getUser().getValue() != null) { + userViewModel.login(userId, password); + tampopo.setUserId(userId); + tampopo.setPassword(password); + Intent intent = new Intent(RegisterActivity.this, MainActivity.class); + startActivity(intent); + } else { + Toast.makeText(RegisterActivity.this, "アカウント作成に失敗しました", Toast.LENGTH_SHORT).show(); + } + } }); - button_register = (Button) findViewById(R.id.Loginbutton2); - button_register.setOnClickListener(new View.OnClickListener() { + + //ログイン画面へ + Button loginButton = findViewById(R.id.Loginbutton2); + loginButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - Intent intent = new Intent(RegisterActivity.this,LoginActivity.class); + Intent intent = new Intent(RegisterActivity.this, LoginActivity.class); startActivity(intent); } }); diff --git a/app/src/main/java/com/example/tampopo_client/views/placeholder/FriendContent.java b/app/src/main/java/com/example/tampopo_client/views/placeholder/FriendContent.java new file mode 100644 index 0000000..4521cdc --- /dev/null +++ b/app/src/main/java/com/example/tampopo_client/views/placeholder/FriendContent.java @@ -0,0 +1,81 @@ +package com.example.tampopo_client.views.placeholder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Helper class for providing sample content for user interfaces created by + * Android template wizards. + *

+ * TODO: Replace all uses of this class before publishing your app. + */ +public class FriendContent { + + /** + * An array of sample (placeholder) items. + */ + + public static final List ITEMS = new ArrayList(); + + /** + * A map of sample (placeholder) items, by ID. + */ + public static final Map ITEM_MAP = new HashMap(); + + private static final int COUNT = 30; + + static { + // Add some sample items. + for (int i = 1; i <= COUNT; i++) { + addItem(createPlaceholderItem(i)); + } + } + + + private static void addItem(FriendItem item) { + + ITEMS.add(item); + ITEM_MAP.put(item.id, item); + } + + + private static FriendItem createPlaceholderItem(int position) { + return new FriendItem(String.valueOf(position), "ユーザー名 " , makeDetails(position)); + + } + + private static String makeDetails(int position) { + StringBuilder builder = new StringBuilder(); + builder.append("Details about Item: ").append(position); + for (int i = 0; i < position; i++) { + builder.append("\nMore details information here."); + } + return builder.toString(); + } + + /** + * A placeholder item representing a piece of content. + */ + + public static class FriendItem { + + public final String id; + public final String content; + public final String details; + + + public FriendItem(String id, String content, String details) { + + this.id = id; + this.content = content; + this.details = details; + } + + @Override + public String toString() { + return content; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/tampopo_client/views/placeholder/FriendRequestContent.java b/app/src/main/java/com/example/tampopo_client/views/placeholder/FriendRequestContent.java new file mode 100644 index 0000000..cd141e8 --- /dev/null +++ b/app/src/main/java/com/example/tampopo_client/views/placeholder/FriendRequestContent.java @@ -0,0 +1,64 @@ +package com.example.tampopo_client.views.placeholder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class FriendRequestContent { + + //FriendRequestを格納するリスト + public static final List ITEMS = new ArrayList(); + + //各アイテムにアクセスするためのID付きマップ*/ + public static final Map ITEM_MAP = new HashMap(); + + private static final int COUNT = 30; //データ30個作成 + + //アイテムを初期化時に追加する + static { + // Add some sample items. + for (int i = 1; i <= COUNT; i++) { + addItem(createPlaceholderItem(i)); + } + } + + //アイテムをリストとマップの両方に登録するメソッド + private static void addItem(FriendRequestItem item) { + ITEMS.add(item); + ITEM_MAP.put(item.id, item); + } + + //位置(1,2,...)に応じたFriendRequestItem を生成するメソッド + private static FriendRequestItem createPlaceholderItem(int position) { + return new FriendRequestItem(String.valueOf(position), "ユーザー名 ", makeDetails(position)); + } + + //詳細説明用の文字列を作るメソッド。position に応じて「詳細情報」がたくさん増える + private static String makeDetails(int position) { + StringBuilder builder = new StringBuilder(); + builder.append("Details about Item: ").append(position); + for (int i = 0; i < position; i++) { + builder.append("\nMore details information here."); + } + return builder.toString(); + } + + //FriendRequestを表す1件のデータ + public static class FriendRequestItem { + public final String id; //アイテムのID + public final String content; //表示される名前 + public final String details; //詳細説明 + + public FriendRequestItem(String id, String content, String details) { + this.id = id; + this.content = content; + this.details = details; + } + + @Override + public String toString() { + return content; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/tampopo_client/views/placeholder/PlaceholderContent.java b/app/src/main/java/com/example/tampopo_client/views/placeholder/PlaceholderContent.java deleted file mode 100644 index 00871a5..0000000 --- a/app/src/main/java/com/example/tampopo_client/views/placeholder/PlaceholderContent.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.example.tampopo_client.views.placeholder; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Helper class for providing sample content for user interfaces created by - * Android template wizards. - *

- * TODO: Replace all uses of this class before publishing your app. - */ -public class PlaceholderContent { - - /** - * An array of sample (placeholder) items. - */ - public static final List ITEMS = new ArrayList(); - - /** - * A map of sample (placeholder) items, by ID. - */ - public static final Map ITEM_MAP = new HashMap(); - - private static final int COUNT = 25; - - static { - // Add some sample items. - for (int i = 1; i <= COUNT; i++) { - addItem(createPlaceholderItem(i)); - } - } - - private static void addItem(PlaceholderItem item) { - ITEMS.add(item); - ITEM_MAP.put(item.id, item); - } - - private static PlaceholderItem createPlaceholderItem(int position) { - return new PlaceholderItem(String.valueOf(position), "Item " + position, makeDetails(position)); - } - - private static String makeDetails(int position) { - StringBuilder builder = new StringBuilder(); - builder.append("Details about Item: ").append(position); - for (int i = 0; i < position; i++) { - builder.append("\nMore details information here."); - } - return builder.toString(); - } - - /** - * A placeholder item representing a piece of content. - */ - public static class PlaceholderItem { - public final String id; - public final String content; - public final String details; - - public PlaceholderItem(String id, String content, String details) { - this.id = id; - this.content = content; - this.details = details; - } - - @Override - public String toString() { - return content; - } - } -} \ No newline at end of file diff --git a/app/src/main/res/drawable/comment.png b/app/src/main/res/drawable/comment.png new file mode 100644 index 0000000..963fbb5 --- /dev/null +++ b/app/src/main/res/drawable/comment.png Binary files differ diff --git a/app/src/main/res/drawable/eye.png b/app/src/main/res/drawable/eye.png new file mode 100644 index 0000000..0cb343f --- /dev/null +++ b/app/src/main/res/drawable/eye.png Binary files differ diff --git a/app/src/main/res/layout/activity_launch.xml b/app/src/main/res/layout/activity_launch.xml index 7ccbd4b..cc3237c 100644 --- a/app/src/main/res/layout/activity_launch.xml +++ b/app/src/main/res/layout/activity_launch.xml @@ -23,7 +23,7 @@