diff --git a/app/src/main/java/com/futo/circles/extensions/FragmentExtensions.kt b/app/src/main/java/com/futo/circles/extensions/FragmentExtensions.kt index a6defc9a77151790de5bb218e627ed980bf32f25..fed2da5457840e8965b48b233afa1d71d75e24b2 100644 --- a/app/src/main/java/com/futo/circles/extensions/FragmentExtensions.kt +++ b/app/src/main/java/com/futo/circles/extensions/FragmentExtensions.kt @@ -15,26 +15,37 @@ import com.google.android.material.snackbar.Snackbar @SuppressLint("InflateParams") -fun Fragment.showError(message: String) { - view?.let { - val snack: Snackbar = Snackbar.make(it, message, Snackbar.LENGTH_LONG) - val customSnackView = layoutInflater.inflate(R.layout.error_snack_bar_view, null) - snack.view.setBackgroundColor(Color.TRANSPARENT) - - val snackLayout = snack.view as Snackbar.SnackbarLayout - snackLayout.setPadding(0, 0, 0, 0) - - customSnackView.findViewById<TextView>(R.id.tvErrorMessage).also { textView -> - textView.text = message - } - snackLayout.addView(customSnackView, 0) - - val layoutParams = (snack.view.layoutParams as? FrameLayout.LayoutParams)?.also { params -> - params.gravity = Gravity.TOP - } - snack.view.layoutParams = layoutParams - snack.show() +private fun Fragment.showBar(message: String, isError: Boolean, showOnActivity: Boolean) { + val parentView = if (showOnActivity) activity?.findViewById(android.R.id.content) else view + parentView ?: return + + val snack: Snackbar = Snackbar.make(parentView, message, Snackbar.LENGTH_LONG) + snack.view.setBackgroundColor(Color.TRANSPARENT) + + val snackLayout = snack.view as Snackbar.SnackbarLayout + snackLayout.setPadding(0, 0, 0, 0) + + val customSnackView = layoutInflater.inflate( + if (isError) R.layout.error_snack_bar_view else R.layout.success_snack_bar_view, + null + ).apply { + findViewById<TextView>(R.id.tvMessage)?.text = message + } + snackLayout.addView(customSnackView, 0) + + val layoutParams = (snack.view.layoutParams as? FrameLayout.LayoutParams)?.also { params -> + params.gravity = Gravity.TOP } + snack.view.layoutParams = layoutParams + snack.show() +} + +fun Fragment.showError(message: String, showOnActivity: Boolean = false) { + showBar(message, true, showOnActivity) +} + +fun Fragment.showSuccess(message: String, showOnActivity: Boolean = false) { + showBar(message, false, showOnActivity) } fun Fragment.setEnabledViews(enabled: Boolean) { diff --git a/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersDialogFragment.kt b/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersDialogFragment.kt index d3d8587d8b4ce97bd17d2f668518920cdf221391..37bfee48e6b6f03ff3ba5f54c7852ba62ec330d8 100644 --- a/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersDialogFragment.kt +++ b/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersDialogFragment.kt @@ -6,9 +6,7 @@ import androidx.navigation.fragment.navArgs import com.futo.circles.R import com.futo.circles.base.BaseFullscreenDialogFragment import com.futo.circles.databinding.InviteMembersDialogFragmentBinding -import com.futo.circles.extensions.getQueryTextChangeStateFlow -import com.futo.circles.extensions.observeData -import com.futo.circles.extensions.setVisibility +import com.futo.circles.extensions.* import com.futo.circles.feature.group_invite.list.search.InviteMembersSearchListAdapter import com.futo.circles.feature.group_invite.list.selected.SelectedUsersListAdapter import org.koin.androidx.viewmodel.ext.android.viewModel @@ -39,6 +37,10 @@ class InviteMembersDialogFragment : binding.toolbar.setNavigationOnClickListener { activity?.onBackPressed() } setupLists() setupObservers() + binding.btnInvite.setOnClickWithLoading { + viewModel.invite() + setLoadingState(true) + } } private fun setupLists() { @@ -58,6 +60,20 @@ class InviteMembersDialogFragment : viewModel.selectedUsersLiveData.observeData(this) { items -> selectedUsersListAdapter.submitList(items) binding.selectedUserDivider.setVisibility(items.isNotEmpty()) + binding.btnInvite.setButtonEnabled(items.isNotEmpty()) } + viewModel.inviteResultLiveData.observeResponse(this, + success = { + showSuccess(getString(R.string.invitation_sent), true) + activity?.onBackPressed() + }, + error = { message -> showError(message) }, + onRequestInvoked = { setLoadingState(false) } + ) + } + + private fun setLoadingState(isLoading: Boolean) { + setEnabledViews(!isLoading) + binding.btnInvite.setIsLoading(isLoading) } } \ No newline at end of file diff --git a/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersViewModel.kt b/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersViewModel.kt index 2597b2fbf30970da59281f997170fede8ba5ad57..fe1dd81067300d827053b86a6b14681d8fc858de 100644 --- a/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersViewModel.kt +++ b/app/src/main/java/com/futo/circles/feature/group_invite/InviteMembersViewModel.kt @@ -3,6 +3,8 @@ package com.futo.circles.feature.group_invite import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.asLiveData +import com.futo.circles.extensions.Response +import com.futo.circles.extensions.launchBg import com.futo.circles.extensions.launchUi import com.futo.circles.feature.group_invite.data_source.InviteMembersDataSource import com.futo.circles.model.CirclesUser @@ -19,6 +21,8 @@ class InviteMembersViewModel( val selectedUsersLiveData = dataSource.selectedUsersFlow.asLiveData() + val inviteResultLiveData = MutableLiveData<Response<Unit>>() + fun initSearchListener(queryFlow: StateFlow<String>) { launchUi { queryFlow @@ -33,4 +37,8 @@ class InviteMembersViewModel( dataSource.toggleUserSelect(user) } + fun invite() { + launchBg { inviteResultLiveData.postValue(dataSource.inviteUsers(this)) } + } + } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_error.xml b/app/src/main/res/drawable/ic_error.xml new file mode 100644 index 0000000000000000000000000000000000000000..3c9a4b352cc10706ed0cbf98a341f400fd127bb4 --- /dev/null +++ b/app/src/main/res/drawable/ic_error.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#FFFFFF" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/> +</vector> diff --git a/app/src/main/res/layout/error_snack_bar_view.xml b/app/src/main/res/layout/error_snack_bar_view.xml index 06992b481512a1c4b1ac36150dba58e9e6052069..45d2e09863adae0b65fc8daf009360d937303e6f 100644 --- a/app/src/main/res/layout/error_snack_bar_view.xml +++ b/app/src/main/res/layout/error_snack_bar_view.xml @@ -2,6 +2,7 @@ <androidx.cardview.widget.CardView 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/tooltipCard" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="16dp" @@ -14,16 +15,16 @@ android:padding="8dp"> <ImageView - android:id="@+id/ivError" + android:id="@+id/ivIcon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:src="@android:drawable/stat_notify_error" + android:src="@drawable/ic_error" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView - android:id="@+id/tvErrorMessage" + android:id="@+id/tvMessage" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" @@ -32,10 +33,11 @@ android:textColor="@color/white" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toEndOf="@id/ivError" + app:layout_constraintStart_toEndOf="@id/ivIcon" app:layout_constraintTop_toTopOf="parent" tools:text="asdasdasdasdadsaasdsadasdasdasdasasdasdasdasdasasdsdasddasdasdasdasdadssdasdadsasdadasddas" /> </androidx.constraintlayout.widget.ConstraintLayout> -</androidx.cardview.widget.CardView> \ No newline at end of file +</androidx.cardview.widget.CardView> + diff --git a/app/src/main/res/layout/success_snack_bar_view.xml b/app/src/main/res/layout/success_snack_bar_view.xml new file mode 100644 index 0000000000000000000000000000000000000000..d1d1e6aa95ee28e25751dac9bb500cacc181474f --- /dev/null +++ b/app/src/main/res/layout/success_snack_bar_view.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.cardview.widget.CardView 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/tooltipCard" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="16dp" + app:cardBackgroundColor="@color/blue" + app:cardCornerRadius="8dp"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:padding="8dp"> + + <ImageView + android:id="@+id/ivIcon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/ic_check_circle" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:tint="@color/white" /> + + <TextView + android:id="@+id/tvMessage" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:ellipsize="end" + android:maxLines="2" + android:textColor="@color/white" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/ivIcon" + app:layout_constraintTop_toTopOf="parent" + tools:text="asdasdasdasdadsaasdsadasdasdasdasasdasdasdasdasasdsdasddasdasdasdasdadssdasdadsasdadasddas" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + +</androidx.cardview.widget.CardView> + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ab747ba9be90434b066818129f5748931212a33f..29d3e5f9225f7a4e2a81106a7caf528eaaf697dc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -33,6 +33,7 @@ <string name="suggestion">Suggestions</string> <string name="no_results">No results</string> <string name="invite">Invite</string> + <string name="invitation_sent">Invitation sent</string> <plurals name="member_plurals"> <item quantity="one">%d member</item>