diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 40840fd..c1e53ea 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,8 +1,8 @@ - + + + android:exported="true" /> - - + android:exported="true"> - - + android:exported="true"> - - + android:exported="true"> - - - + - + \ No newline at end of file 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 index 455723a..183e544 100644 --- a/app/src/main/java/com/example/tampopo_client/viewmodels/ActivityViewModel.java +++ b/app/src/main/java/com/example/tampopo_client/viewmodels/ActivityViewModel.java @@ -110,11 +110,15 @@ // 自分のフレンドの最新のアクティビティを取得して更新する if (friendUserIdsLiveData.isInitialized() && friendUserIdsLiveData.getValue() != null) { - for (String userId : friendUserIdsLiveData.getValue()) { + List friendUserIds = friendUserIdsLiveData.getValue(); + for (String userId : friendUserIds) { pullLatestActivity(userId, activitiesResource, new ActivityFetchCallback() { @Override public void onSuccess(Activity activity) { updateFriendToActivitiesLiveData(activity, userId); + + // NOTE: 毎秒呼ばれるけど動いているので気にしない + sortFriendsByUpdateTime(friendUserIds); } @Override @@ -267,22 +271,10 @@ List friendUserIds = friendUserIdsLiveData.getValue(); if (friendUserIds == null || !friendUserIds.equals(response.body())) { friendUserIdsLiveData.postValue(response.body()); - SortedSet friends = new TreeSet<>(new Friend.UpdateTimeComparator()); + // NOTE: 毎秒呼ばれるけど動いているので気にしない assert friendUserIds != null; - friendUserIds.forEach(userId -> { - List activities = getActivitiesLiveDataFromUserId(userId).getValue(); - if (activities == null || activities.isEmpty()) { - return; - } - - Activity latestActivity = activities.get(0); - friends.add(new Friend(userId, latestActivity.getUpdateTime())); - }); - - // 並び替えたフレンドのユーザーIDを順番に格納して更新する - sortedFriendUserIds.clear(); - friends.forEach(friend -> sortedFriendUserIds.add(friend.getUserId())); + sortFriendsByUpdateTime(friendUserIds); } } } @@ -294,6 +286,29 @@ }); } + /** + * ユーザのフレンドのリストを更新順で並び替える + * + * @param friendUserIds 自身のフレンドのユーザーIDのリスト + */ + private void sortFriendsByUpdateTime(List friendUserIds) { + SortedSet friends = new TreeSet<>(new Friend.UpdateTimeComparator()); + + friendUserIds.forEach(userId -> { + List activities = getActivitiesLiveDataFromUserId(userId).getValue(); + if (activities == null || activities.isEmpty()) { + return; + } + + Activity latestActivity = activities.get(0); + friends.add(new Friend(userId, latestActivity.getUpdateTime())); + }); + + // 並び替えたフレンドのユーザーIDを順番に格納して更新する + sortedFriendUserIds.clear(); + friends.forEach(friend -> sortedFriendUserIds.add(friend.getUserId())); + } + public MutableLiveData getMyLatestActivityLiveData() { return myLatestActivityLiveData; } @@ -311,6 +326,10 @@ return friendToActivitiesLiveData.get(userId); } + public Map>> getFriendToActivitiesLiveData() { + return friendToActivitiesLiveData; + } + public MutableLiveData> getFriendUserIdsLiveData() { return friendUserIdsLiveData; } @@ -355,7 +374,7 @@ public static class UpdateTimeComparator implements Comparator { @Override public int compare(Friend o1, Friend o2) { - return o1.getLatestUpdateTime().compareTo(o2.getLatestUpdateTime()); + return o2.getLatestUpdateTime().compareTo(o1.getLatestUpdateTime()); } } } 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 bc194c6..a02a716 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 @@ -86,7 +86,7 @@ tampopo.setToken(token); // 画面遷移 - Intent intent = new Intent(RegisterActivity.this, MainActivity.class); + Intent intent = new Intent(RegisterActivity.this, UserInfoActivity.class); startActivity(intent); finish(); } else { diff --git a/app/src/main/java/com/example/tampopo_client/views/UserInfoActivity.java b/app/src/main/java/com/example/tampopo_client/views/UserInfoActivity.java new file mode 100644 index 0000000..6d50809 --- /dev/null +++ b/app/src/main/java/com/example/tampopo_client/views/UserInfoActivity.java @@ -0,0 +1,132 @@ +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.Toast; + +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.models.User; +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.util.Base64; + +public class UserInfoActivity extends AppCompatActivity { + private UserViewModel userViewModel; + Tampopo app; + private String changeIconUrl; + private boolean iconFlag; + + private ActivityResultLauncher launcher = registerForActivityResult(new ActivityResultContracts.OpenDocument(), new ActivityResultCallback() { + @Override + public void onActivityResult(Uri uri) { + if(uri == null){ + iconFlag = false; + 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); + EdgeToEdge.enable(this); + setContentView(R.layout.activity_user_info); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + + userViewModel = new ViewModelProvider(this).get(UserViewModel.class); + + app = (Tampopo) getApplication(); + + ShapeableImageView iconView = findViewById(R.id.myicon); + ShapeableImageView changeIconView = findViewById(R.id.changeIcon); + + changeIconView.setOnClickListener(new View.OnClickListener(){ + public void onClick(View v) { + launcher.launch(new String[] {"image/*"}); + } + + }); + + userViewModel.getIcon().observe(this, new Observer() { + @Override + public void onChanged(String iconUrl) { + Glide.with(UserInfoActivity.this).load(iconUrl).into(iconView); + } + }); + //決定ボタン + Button dicisionbutton = findViewById(R.id.enter_button); + dicisionbutton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + + + EditText usernicknameInput = findViewById(R.id.nickname); + String usernickname = usernicknameInput.getText().toString(); + + // Application(Tampopo)に保存 + app.setNickname(usernickname); + + 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); + } + + if (usernicknameInput == null && changeIconUrl == null) { + Toast.makeText(UserInfoActivity.this, "ニックネームとアイコンを設定してください", Toast.LENGTH_SHORT).show(); + }else if(usernicknameInput == null){ + Toast.makeText(UserInfoActivity.this, "ニックネームを入力してください", Toast.LENGTH_SHORT).show(); + } else if (changeIconUrl == null) { + Toast.makeText(UserInfoActivity.this, "アイコンを設定してください", Toast.LENGTH_SHORT).show(); + }else { + //メイン画面に進む + Intent intent = new Intent(UserInfoActivity.this, MainActivity.class); + startActivity(intent); + } + } + }); + + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/tampopo.png b/app/src/main/res/drawable/tampopo.png new file mode 100644 index 0000000..642625f --- /dev/null +++ b/app/src/main/res/drawable/tampopo.png Binary files differ diff --git a/app/src/main/res/layout/activity_chat.xml b/app/src/main/res/layout/activity_chat.xml index 9a43176..0cf1cd2 100644 --- a/app/src/main/res/layout/activity_chat.xml +++ b/app/src/main/res/layout/activity_chat.xml @@ -15,9 +15,11 @@ android:layout_width="350dp" android:layout_height="200dp" android:ems="10" - android:hint=" |" android:inputType="text" - android:background="#32FF2F" + android:background="#6AFA68" + android:hint="|" + android:gravity="center" + android:importantForAccessibility="no" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" @@ -30,9 +32,11 @@ android:layout_width="350dp" android:layout_height="200dp" android:ems="10" - android:hint=" |" android:inputType="text" - android:background="#B57EDC" + android:background="#B782DC" + android:hint="|" + android:gravity="center" + android:importantForAccessibility="no" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" @@ -55,6 +59,7 @@ android:layout_height="50dp" android:background="#E0F7FA" android:scaleType="fitCenter" + android:importantForAccessibility="no" app:srcCompat="@drawable/phone" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" diff --git a/app/src/main/res/layout/activity_user_info.xml b/app/src/main/res/layout/activity_user_info.xml new file mode 100644 index 0000000..779518b --- /dev/null +++ b/app/src/main/res/layout/activity_user_info.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + +