diff --git a/app/src/main/java/com/futo/circles/core/Constants.kt b/app/src/main/java/com/futo/circles/core/Constants.kt index a97f05ec1baacf0342e277a9a28173ee5ed7d530..8bd7c5d8a85c5d9fa0e40826dd6e62147808ed24 100644 --- a/app/src/main/java/com/futo/circles/core/Constants.kt +++ b/app/src/main/java/com/futo/circles/core/Constants.kt @@ -6,3 +6,5 @@ const val REGISTRATION_TOKEN_KEY = "org.matrix.msc3231.login.registration_token" const val TERMS_URL_EXTENSION = "_matrix/consent" const val VALIDATION_TOKEN_SUBMIT_URL_PREFIX = "_matrix/identity/api/v1/validate/email/submitToken" + +const val DEFAULT_USER_PREFIX = "@notices:" diff --git a/app/src/main/java/com/futo/circles/di/DataSourceModule.kt b/app/src/main/java/com/futo/circles/di/DataSourceModule.kt index 8a6de5f86619f7925d8748fa52855a030c6b1500..6252295b29e0ab71bfe3ee87882db70c75e810d5 100644 --- a/app/src/main/java/com/futo/circles/di/DataSourceModule.kt +++ b/app/src/main/java/com/futo/circles/di/DataSourceModule.kt @@ -11,6 +11,8 @@ import com.futo.circles.feature.circles.accept_invite.AcceptCircleInviteDataSour import com.futo.circles.feature.circles.following.FollowingDataSource import com.futo.circles.feature.groups.GroupsDataSource import com.futo.circles.feature.log_in.LoginDataSource +import com.futo.circles.feature.people.PeopleDataSource +import com.futo.circles.feature.people.UserOptionsDataSource import com.futo.circles.feature.photos.PhotosDataSource import com.futo.circles.feature.photos.preview.GalleryImageDataSource import com.futo.circles.feature.photos.save.SelectGalleryDataSource @@ -88,4 +90,6 @@ val dataSourceModule = module { factory { (deviceId: String) -> RemoveSessionDataSource(deviceId, get(), get()) } factory { (roomId: String, eventId: String) -> GalleryImageDataSource(roomId, eventId) } factory { SelectGalleryDataSource(get(), get()) } + factory { PeopleDataSource() } + factory { UserOptionsDataSource() } } \ No newline at end of file diff --git a/app/src/main/java/com/futo/circles/di/UiModule.kt b/app/src/main/java/com/futo/circles/di/UiModule.kt index 13063e6ab1b1063f1b9ccd1c7386c2ecb1462b35..c8e64032fa132873ef7969bde844ca6fbf574b5f 100644 --- a/app/src/main/java/com/futo/circles/di/UiModule.kt +++ b/app/src/main/java/com/futo/circles/di/UiModule.kt @@ -5,6 +5,7 @@ import com.futo.circles.feature.circles.accept_invite.AcceptCircleInviteViewMode import com.futo.circles.feature.circles.following.FollowingViewModel import com.futo.circles.feature.groups.GroupsViewModel import com.futo.circles.feature.log_in.LogInViewModel +import com.futo.circles.feature.people.PeopleViewModel import com.futo.circles.feature.photos.PhotosViewModel import com.futo.circles.feature.photos.gallery.GalleryViewModel import com.futo.circles.feature.photos.preview.GalleryImageViewModel @@ -40,10 +41,11 @@ val uiModule = module { viewModel { LogInViewModel(get()) } viewModel { GroupsViewModel(get()) } viewModel { CirclesViewModel(get()) } + viewModel { PeopleViewModel(get(), get()) } viewModel { PhotosViewModel(get()) } viewModel { (roomId: String, type: CircleRoomTypeArg) -> TimelineViewModel( - get { parametersOf(roomId, type) }, get { parametersOf(roomId) }, get(), get() + get { parametersOf(roomId, type) }, get { parametersOf(roomId) }, get(), get(), get() ) } viewModel { (roomId: String) -> InviteMembersViewModel(get { parametersOf(roomId) }) } diff --git a/app/src/main/java/com/futo/circles/feature/people/PeopleDataSource.kt b/app/src/main/java/com/futo/circles/feature/people/PeopleDataSource.kt new file mode 100644 index 0000000000000000000000000000000000000000..6d61d0018b583e6b21a973d3ffa6b8e59b1f9e97 --- /dev/null +++ b/app/src/main/java/com/futo/circles/feature/people/PeopleDataSource.kt @@ -0,0 +1,52 @@ +package com.futo.circles.feature.people + +import androidx.lifecycle.asFlow +import com.futo.circles.core.DEFAULT_USER_PREFIX +import com.futo.circles.mapping.toPeopleUserListItem +import com.futo.circles.model.PeopleHeaderItem +import com.futo.circles.model.PeopleListItem +import com.futo.circles.provider.MatrixSessionProvider +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.* +import org.matrix.android.sdk.api.session.user.model.User + +class PeopleDataSource { + + private val session = MatrixSessionProvider.currentSession + + private val excludeUserIds = mutableListOf( + session?.myUserId ?: "", + DEFAULT_USER_PREFIX + session?.myUserId?.substringAfter(":") + ).toSet() + + fun getPeopleList() = combine(getKnownUsersFlow(), getIgnoredUserFlow()) + { knowUsers, ignoredUsers -> + buildList(knowUsers, ignoredUsers) + }.flowOn(Dispatchers.IO).distinctUntilChanged() + + private fun getKnownUsersFlow() = session?.userService()?.getUsersLive()?.asFlow() + ?.map { list -> list.filterNot { user -> excludeUserIds.contains(user.userId) } } + ?: flowOf() + + private fun getIgnoredUserFlow() = + session?.userService()?.getIgnoredUsersLive()?.asFlow() ?: flowOf() + + private fun buildList(knowUsers: List<User>, ignoredUsers: List<User>): List<PeopleListItem> { + val filteredKnownUsers = knowUsers.filterNot { knowUser -> + ignoredUsers.firstOrNull { ignoredUser -> + ignoredUser.userId == knowUser.userId + } != null + }.map { it.toPeopleUserListItem(false) } + + val list = mutableListOf<PeopleListItem>() + if (filteredKnownUsers.isNotEmpty()) { + list.add(PeopleHeaderItem.knownUsersHeader) + list.addAll(filteredKnownUsers) + } + if (ignoredUsers.isNotEmpty()) { + list.add(PeopleHeaderItem.ignoredUsers) + list.addAll(ignoredUsers.map { it.toPeopleUserListItem(true) }) + } + return list + } +} \ No newline at end of file diff --git a/app/src/main/java/com/futo/circles/feature/people/PeopleFragment.kt b/app/src/main/java/com/futo/circles/feature/people/PeopleFragment.kt index fa5969c9917a3f7d227e2ca5e3479741e20a745a..81ba11d13f20f84f5f62b3043a0f7d9466197da8 100644 --- a/app/src/main/java/com/futo/circles/feature/people/PeopleFragment.kt +++ b/app/src/main/java/com/futo/circles/feature/people/PeopleFragment.kt @@ -1,6 +1,68 @@ package com.futo.circles.feature.people +import android.os.Bundle +import android.view.View import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.DividerItemDecoration +import by.kirich1409.viewbindingdelegate.viewBinding import com.futo.circles.R +import com.futo.circles.databinding.PeopleFragmentBinding +import com.futo.circles.extensions.observeData +import com.futo.circles.extensions.observeResponse +import com.futo.circles.extensions.showDialog +import com.futo.circles.feature.people.list.PeopleAdapter +import com.futo.circles.model.PeopleUserListItem +import org.koin.androidx.viewmodel.ext.android.viewModel -class PeopleFragment:Fragment(R.layout.people_fragment) \ No newline at end of file +class PeopleFragment : Fragment(R.layout.people_fragment) { + + private val viewModel by viewModel<PeopleViewModel>() + private val binding by viewBinding(PeopleFragmentBinding::bind) + + private val peopleAdapter by lazy { + PeopleAdapter( + onUserClicked = { user -> navigateToUserPage(user) }, + onIgnore = { user, ignore -> handleIgnoreClicked(user, ignore) }, + ) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupViews() + setupObservers() + } + + private fun setupViews() { + binding.rvUsers.apply { + adapter = peopleAdapter + addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL)) + } + } + + private fun setupObservers() { + viewModel.peopleLiveData.observeData(this) { items -> + peopleAdapter.submitList(items) + } + viewModel.ignoreUserLiveData.observeResponse(this) + } + + private fun navigateToUserPage(user: PeopleUserListItem) { + + } + + private fun handleIgnoreClicked(user: PeopleUserListItem, ignore: Boolean) { + if (ignore) showIgnoreConfirmation(user.id) + else viewModel.unIgnoreUser(user.id) + } + + private fun showIgnoreConfirmation(userId: String) { + showDialog( + titleResIdRes = R.string.ignore, + messageResId = R.string.ignore_user_message, + positiveButtonRes = R.string.ignore, + negativeButtonVisible = true, + positiveAction = { viewModel.ignoreUser(userId) } + ) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/futo/circles/feature/people/PeopleViewModel.kt b/app/src/main/java/com/futo/circles/feature/people/PeopleViewModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..670585c4d931189d97c460bde5a3699bf3d95627 --- /dev/null +++ b/app/src/main/java/com/futo/circles/feature/people/PeopleViewModel.kt @@ -0,0 +1,28 @@ +package com.futo.circles.feature.people + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.asLiveData +import com.futo.circles.core.SingleEventLiveData +import com.futo.circles.extensions.Response +import com.futo.circles.extensions.launchBg + +class PeopleViewModel( + peopleDataSource: PeopleDataSource, + private val userOptionsDataSource: UserOptionsDataSource +) : ViewModel() { + + val peopleLiveData = peopleDataSource.getPeopleList().asLiveData() + val ignoreUserLiveData = SingleEventLiveData<Response<Unit?>>() + + fun unIgnoreUser(id: String) { + launchBg { + ignoreUserLiveData.postValue(userOptionsDataSource.unIgnoreSender(id)) + } + } + + fun ignoreUser(id: String) { + launchBg { + ignoreUserLiveData.postValue(userOptionsDataSource.ignoreSender(id)) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/futo/circles/feature/people/UserOptionsDataSource.kt b/app/src/main/java/com/futo/circles/feature/people/UserOptionsDataSource.kt new file mode 100644 index 0000000000000000000000000000000000000000..fd10ee9a42ebf4aef135dfccea11611931e28b69 --- /dev/null +++ b/app/src/main/java/com/futo/circles/feature/people/UserOptionsDataSource.kt @@ -0,0 +1,17 @@ +package com.futo.circles.feature.people + +import com.futo.circles.extensions.createResult +import com.futo.circles.provider.MatrixSessionProvider + +class UserOptionsDataSource { + + private val session = MatrixSessionProvider.currentSession + + suspend fun ignoreSender(userId: String) = createResult { + session?.userService()?.ignoreUserIds(listOf(userId)) + } + + suspend fun unIgnoreSender(userId: String) = createResult { + session?.userService()?.unIgnoreUserIds(listOf(userId)) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/futo/circles/feature/people/list/PeopleAdapter.kt b/app/src/main/java/com/futo/circles/feature/people/list/PeopleAdapter.kt new file mode 100644 index 0000000000000000000000000000000000000000..5e966723c16797fb42874286f361aa09c6da6baa --- /dev/null +++ b/app/src/main/java/com/futo/circles/feature/people/list/PeopleAdapter.kt @@ -0,0 +1,40 @@ +package com.futo.circles.feature.people.list + +import android.view.ViewGroup +import com.futo.circles.core.list.BaseRvAdapter +import com.futo.circles.model.PeopleHeaderItem +import com.futo.circles.model.PeopleListItem +import com.futo.circles.model.PeopleUserListItem + +private enum class PeopleListViewType { Header, User } + +class PeopleAdapter( + private val onUserClicked: (PeopleUserListItem) -> Unit, + private val onIgnore: (PeopleUserListItem, Boolean) -> Unit, +) : BaseRvAdapter<PeopleListItem, PeopleViewHolder>( + DefaultIdEntityCallback() +) { + + override fun getItemViewType(position: Int): Int = when (getItem(position)) { + is PeopleHeaderItem -> PeopleListViewType.Header.ordinal + is PeopleUserListItem -> PeopleListViewType.User.ordinal + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PeopleViewHolder { + return when (PeopleListViewType.values()[viewType]) { + PeopleListViewType.Header -> PeopleHeaderViewHolder(parent) + PeopleListViewType.User -> PeopleUserViewHolder( + parent, + onUserClicked = { position -> onUserClicked(getItem(position) as PeopleUserListItem) }, + onIgnore = { position, ignore -> + onIgnore(getItem(position) as PeopleUserListItem, ignore) + }, + ) + } + } + + override fun onBindViewHolder(holder: PeopleViewHolder, position: Int) { + holder.bind(getItem(position)) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/futo/circles/feature/people/list/PeopleViewHolder.kt b/app/src/main/java/com/futo/circles/feature/people/list/PeopleViewHolder.kt new file mode 100644 index 0000000000000000000000000000000000000000..405321c7a5dc4aff7bf5590fc327faad6a266a53 --- /dev/null +++ b/app/src/main/java/com/futo/circles/feature/people/list/PeopleViewHolder.kt @@ -0,0 +1,63 @@ +package com.futo.circles.feature.people.list + +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.futo.circles.core.list.ViewBindingHolder +import com.futo.circles.core.list.context +import com.futo.circles.databinding.InviteHeaderListItemBinding +import com.futo.circles.databinding.PeopleListItemBinding +import com.futo.circles.extensions.loadProfileIcon +import com.futo.circles.extensions.onClick +import com.futo.circles.extensions.setIsVisible +import com.futo.circles.model.PeopleHeaderItem +import com.futo.circles.model.PeopleListItem +import com.futo.circles.model.PeopleUserListItem + +abstract class PeopleViewHolder(view: View) : RecyclerView.ViewHolder(view) { + abstract fun bind(data: PeopleListItem) +} + +class PeopleUserViewHolder( + parent: ViewGroup, + private val onUserClicked: (Int) -> Unit, + private val onIgnore: (Int, Boolean) -> Unit +) : PeopleViewHolder(inflate(parent, PeopleListItemBinding::inflate)) { + + private companion object : ViewBindingHolder + + private val binding = baseBinding as PeopleListItemBinding + + init { + onClick(itemView) { position -> onUserClicked(position) } + onClick(binding.btnIgnore) { position -> onIgnore(position, true) } + onClick(binding.btnUnignore) { position -> onIgnore(position, false) } + } + + override fun bind(data: PeopleListItem) { + if (data !is PeopleUserListItem) return + + with(binding) { + userItem.tvUserName.text = data.user.name + userItem.tvUserId.text = data.id + userItem.ivUserImage.loadProfileIcon(data.user.avatarUrl, data.user.name) + btnIgnore.setIsVisible(!data.isIgnored) + btnUnignore.setIsVisible(data.isIgnored) + } + } +} + +class PeopleHeaderViewHolder( + parent: ViewGroup, +) : PeopleViewHolder(inflate(parent, InviteHeaderListItemBinding::inflate)) { + + private companion object : ViewBindingHolder + + private val binding = baseBinding as InviteHeaderListItemBinding + + override fun bind(data: PeopleListItem) { + if (data !is PeopleHeaderItem) return + + binding.tvHeader.text = context.getString(data.titleRes) + } +} diff --git a/app/src/main/java/com/futo/circles/feature/room/select_users/SelectUsersDataSource.kt b/app/src/main/java/com/futo/circles/feature/room/select_users/SelectUsersDataSource.kt index cbc7b06c41e5c2ab8d19eb87b52c25e9d3e849d2..c0648e6277c41ee394508798164e8b58bcee7fbf 100644 --- a/app/src/main/java/com/futo/circles/feature/room/select_users/SelectUsersDataSource.kt +++ b/app/src/main/java/com/futo/circles/feature/room/select_users/SelectUsersDataSource.kt @@ -1,6 +1,7 @@ package com.futo.circles.feature.room.select_users import androidx.lifecycle.asFlow +import com.futo.circles.core.DEFAULT_USER_PREFIX import com.futo.circles.mapping.toUserListItem import com.futo.circles.model.HeaderItem import com.futo.circles.model.InviteMemberListItem @@ -93,6 +94,5 @@ class SelectUsersDataSource(roomId: String?) { private companion object { private const val MAX_SUGGESTION_COUNT = 30 - private const val DEFAULT_USER_PREFIX = "@notices:" } } \ No newline at end of file diff --git a/app/src/main/java/com/futo/circles/feature/timeline/TimelineViewModel.kt b/app/src/main/java/com/futo/circles/feature/timeline/TimelineViewModel.kt index ea426ff7cbc8278d6cc82bef00b079a8501ee0bb..afbc959ca1966be5f4403fe51631d75cff2e71fc 100644 --- a/app/src/main/java/com/futo/circles/feature/timeline/TimelineViewModel.kt +++ b/app/src/main/java/com/futo/circles/feature/timeline/TimelineViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.asLiveData import com.futo.circles.core.SingleEventLiveData import com.futo.circles.extensions.Response import com.futo.circles.extensions.launchBg +import com.futo.circles.feature.people.UserOptionsDataSource import com.futo.circles.feature.room.LeaveRoomDataSource import com.futo.circles.feature.timeline.data_source.SendMessageDataSource import com.futo.circles.feature.timeline.post.share.ShareableContent @@ -18,7 +19,8 @@ class TimelineViewModel( private val timelineDataSource: TimelineDataSource, private val leaveRoomDataSource: LeaveRoomDataSource, private val sendMessageDataSource: SendMessageDataSource, - private val postOptionsDataSource: PostOptionsDataSource + private val postOptionsDataSource: PostOptionsDataSource, + private val userOptionsDataSource: UserOptionsDataSource ) : BaseTimelineViewModel(timelineDataSource) { val timelineEventsLiveData = timelineDataSource.timelineEventsLiveData @@ -48,7 +50,7 @@ class TimelineViewModel( fun ignoreSender(senderId: String) { launchBg { - ignoreUserLiveData.postValue(postOptionsDataSource.ignoreSender(senderId)) + ignoreUserLiveData.postValue(userOptionsDataSource.ignoreSender(senderId)) } } diff --git a/app/src/main/java/com/futo/circles/feature/timeline/post/PostOptionsDataSource.kt b/app/src/main/java/com/futo/circles/feature/timeline/post/PostOptionsDataSource.kt index 7c9657220a07b8ce1229eee1af9c7187eebb0440..8c3a2f9f6e32d5416f26c5304b3405ee66310c50 100644 --- a/app/src/main/java/com/futo/circles/feature/timeline/post/PostOptionsDataSource.kt +++ b/app/src/main/java/com/futo/circles/feature/timeline/post/PostOptionsDataSource.kt @@ -53,8 +53,4 @@ class PostOptionsDataSource( val b = Glide.with(context).asBitmap().load(imageContent).submit().get() b.saveImageToDeviceGallery(context) } - - suspend fun ignoreSender(userId: String) = createResult { - session?.userService()?.ignoreUserIds(listOf(userId)) - } } \ No newline at end of file diff --git a/app/src/main/java/com/futo/circles/mapping/MatrixUserMapping.kt b/app/src/main/java/com/futo/circles/mapping/MatrixUserMapping.kt index 20d19c899b8bc08dc3489f1ab9f41fa567d1127d..0bf37fd2d88a242cdc40fee85825c85a99a8c1dc 100644 --- a/app/src/main/java/com/futo/circles/mapping/MatrixUserMapping.kt +++ b/app/src/main/java/com/futo/circles/mapping/MatrixUserMapping.kt @@ -1,6 +1,7 @@ package com.futo.circles.mapping import com.futo.circles.model.CirclesUserSummary +import com.futo.circles.model.PeopleUserListItem import com.futo.circles.model.UserListItem import org.matrix.android.sdk.api.session.user.model.User @@ -11,4 +12,13 @@ fun User.toUserListItem(isSelected: Boolean) = UserListItem( avatarUrl = avatarUrl ?: "" ), isSelected = isSelected +) + +fun User.toPeopleUserListItem(isIgnored: Boolean) = PeopleUserListItem( + user = CirclesUserSummary( + id = userId, + name = displayName ?: userId, + avatarUrl = avatarUrl ?: "" + ), + isIgnored = isIgnored ) \ No newline at end of file diff --git a/app/src/main/java/com/futo/circles/model/PeopleListItem.kt b/app/src/main/java/com/futo/circles/model/PeopleListItem.kt new file mode 100644 index 0000000000000000000000000000000000000000..7963e7834b7616b6031b8ca2d729c7c761f46ec9 --- /dev/null +++ b/app/src/main/java/com/futo/circles/model/PeopleListItem.kt @@ -0,0 +1,24 @@ +package com.futo.circles.model + +import com.futo.circles.R +import com.futo.circles.core.list.IdEntity + +sealed class PeopleListItem : IdEntity<String> + +data class PeopleHeaderItem( + val titleRes: Int +) : PeopleListItem() { + override val id: String = titleRes.toString() + + companion object { + val knownUsersHeader = PeopleHeaderItem(R.string.known_users) + val ignoredUsers = PeopleHeaderItem(R.string.ignored_users) + } +} + +data class PeopleUserListItem( + val user: CirclesUserSummary, + val isIgnored: Boolean = false +) : PeopleListItem() { + override val id: String = user.id +} \ No newline at end of file diff --git a/app/src/main/res/layout/people_fragment.xml b/app/src/main/res/layout/people_fragment.xml index 77d9ef65f8c7c6bf54bdef7d54d1646b86417404..f8723fa1629336ac142d34a61d806fc392d62e40 100644 --- a/app/src/main/res/layout/people_fragment.xml +++ b/app/src/main/res/layout/people_fragment.xml @@ -1,6 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> -</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/rvUsers" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> + +</FrameLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/people_list_item.xml b/app/src/main/res/layout/people_list_item.xml new file mode 100644 index 0000000000000000000000000000000000000000..ebf51fef1d0360bfdc3daebef764865c6ab367e4 --- /dev/null +++ b/app/src/main/res/layout/people_list_item.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingVertical="4dp" + android:background="?selectableItemBackground" + android:clickable="true" + android:focusable="true"> + + <include + android:id="@+id/userItem" + layout="@layout/user_list_item" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginEnd="100dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <com.google.android.material.button.MaterialButton + android:id="@+id/btnIgnore" + style="@style/AccentButtonStyle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="8dp" + android:padding="0dp" + android:text="@string/ignore" + android:textSize="14sp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + tools:visibility="visible" /> + + <com.google.android.material.button.MaterialButton + android:id="@+id/btnUnignore" + style="@style/NegativeButtonStyle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="8dp" + android:padding="0dp" + android:text="@string/unignore" + android:textSize="14sp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml index 51875bde0fb56b27fef4062a2ccd20201af85785..1dc5fe4611bc8654236d4f4e5dad72d6357b662a 100644 --- a/app/src/main/res/menu/bottom_nav_menu.xml +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -7,7 +7,7 @@ android:title="@string/circles" /> <item - android:id="@+id/peopleFragment" + android:id="@+id/people_nav_graph" android:icon="@drawable/ic_round_contacts" android:title="@string/people" /> diff --git a/app/src/main/res/navigation/nav_graph_bottom_menu.xml b/app/src/main/res/navigation/nav_graph_bottom_menu.xml index cc8fdb1fa7ff2d123ef677f307a68c2409e0b17b..c97aa184a61b2e59a7e9eda42ad2dd830105b27d 100644 --- a/app/src/main/res/navigation/nav_graph_bottom_menu.xml +++ b/app/src/main/res/navigation/nav_graph_bottom_menu.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav_graph_bottom_menu" app:startDestination="@id/circles_nav_graph"> @@ -11,11 +10,7 @@ <include app:graph="@navigation/photos_nav_graph" /> - <fragment - android:id="@+id/peopleFragment" - android:name="com.futo.circles.feature.people.PeopleFragment" - android:label="@string/my_people" - tools:layout="@layout/people_fragment" /> + <include app:graph="@navigation/people_nav_graph" /> <include app:graph="@navigation/settings_nav_graph" /> diff --git a/app/src/main/res/navigation/people_nav_graph.xml b/app/src/main/res/navigation/people_nav_graph.xml new file mode 100644 index 0000000000000000000000000000000000000000..87252aa3f7d7fe0c9495a1254b741d327047bd89 --- /dev/null +++ b/app/src/main/res/navigation/people_nav_graph.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<navigation xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/people_nav_graph" + app:startDestination="@id/peopleFragment"> + + <fragment + android:id="@+id/peopleFragment" + android:name="com.futo.circles.feature.people.PeopleFragment" + android:label="@string/my_people" + tools:layout="@layout/people_fragment" /> +</navigation> \ 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 a3022f2768cb7a61632737935ecfc25735fa8895..8daddeb6c4a48c2bae02cf84e5cc7c9857a10b6a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -29,6 +29,7 @@ <string name="invite_to_format">Invite to %s</string> <string name="search_by_name_or_id">Search by name or id</string> <string name="known_users">Known users</string> + <string name="ignored_users">Ignored users</string> <string name="suggestion">Suggestions</string> <string name="no_results">No results</string> <string name="invite">Invite</string> @@ -218,6 +219,7 @@ <string name="device">Device</string> <string name="choose_gallery">Choose gallery</string> <string name="pick_image">Pick image</string> + <string name="unignore">Unignore</string> <string-array name="report_categories">