From 231c74da0350fb5c021411651070230c1ce4c3b7 Mon Sep 17 00:00:00 2001 From: pulkit-mac Date: Sun, 14 Apr 2019 13:52:19 +0530 Subject: [PATCH] feat: Add Event Feedbacks --- app/build.gradle | 5 ++- .../fossasia/openevent/general/di/Modules.kt | 11 +++++- .../general/event/EventDetailsFragment.kt | 18 +++++++++ .../general/event/EventDetailsViewModel.kt | 17 ++++++++- .../openevent/general/event/EventService.kt | 9 ++++- .../general/event/feedback/Feedback.kt | 17 +++++++++ .../general/event/feedback/FeedbackApi.kt | 16 ++++++++ .../event/feedback/FeedbackRecyclerAdapter.kt | 32 ++++++++++++++++ .../event/feedback/FeedbackViewHolder.kt | 14 +++++++ app/src/main/res/layout/content_event.xml | 38 ++++++++++++++++++- app/src/main/res/layout/item_feedback.xml | 24 ++++++++++++ app/src/main/res/values/strings.xml | 1 + 12 files changed, 195 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/org/fossasia/openevent/general/event/feedback/Feedback.kt create mode 100644 app/src/main/java/org/fossasia/openevent/general/event/feedback/FeedbackApi.kt create mode 100644 app/src/main/java/org/fossasia/openevent/general/event/feedback/FeedbackRecyclerAdapter.kt create mode 100644 app/src/main/java/org/fossasia/openevent/general/event/feedback/FeedbackViewHolder.kt create mode 100644 app/src/main/res/layout/item_feedback.xml diff --git a/app/build.gradle b/app/build.gradle index a593ed5010..5c81a5b499 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -36,11 +36,12 @@ android { shrinkResources true minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - buildConfigField "String", "DEFAULT_BASE_URL", '"https://api.eventyay.com/v1/"' + buildConfigField "String", "DEFAULT_BASE_URL", '"https://open-event-api-dev.herokuapp.com/v1/"' + buildConfigField "String", "MAPBOX_KEY", '"'+MAPBOX_KEY+'"' } debug { - buildConfigField "String", "DEFAULT_BASE_URL", '"https://open-event-api-dev.herokuapp.com/v1/"' + buildConfigField "String", "DEFAULT_BASE_URL", '"https://api.eventyay.com/v1/"' buildConfigField "String", "MAPBOX_KEY", '"'+MAPBOX_KEY+'"' } } diff --git a/app/src/main/java/org/fossasia/openevent/general/di/Modules.kt b/app/src/main/java/org/fossasia/openevent/general/di/Modules.kt index 33917ef164..44a31f701d 100644 --- a/app/src/main/java/org/fossasia/openevent/general/di/Modules.kt +++ b/app/src/main/java/org/fossasia/openevent/general/di/Modules.kt @@ -40,6 +40,8 @@ import org.fossasia.openevent.general.common.EventsDiffCallback import org.fossasia.openevent.general.data.Resource import org.fossasia.openevent.general.event.EventsListAdapter import org.fossasia.openevent.general.event.EventsViewModel +import org.fossasia.openevent.general.event.feedback.Feedback +import org.fossasia.openevent.general.event.feedback.FeedbackApi import org.fossasia.openevent.general.event.location.EventLocation import org.fossasia.openevent.general.event.location.EventLocationApi import org.fossasia.openevent.general.event.topic.EventTopic @@ -132,11 +134,15 @@ val apiModule = module { val retrofit: Retrofit = get() retrofit.create(EventLocationApi::class.java) } + single { + val retrofit: Retrofit = get() + retrofit.create(FeedbackApi::class.java) + } factory { AuthHolder(get()) } factory { AuthService(get(), get(), get()) } - factory { EventService(get(), get(), get(), get(), get(), get()) } + factory { EventService(get(), get(), get(), get(), get(), get(), get()) } factory { TicketService(get(), get()) } factory { SocialLinksService(get(), get()) } factory { AttendeeService(get(), get(), get()) } @@ -204,7 +210,8 @@ val networkModule = module { SignUp::class.java, Ticket::class.java, SocialLink::class.java, EventId::class.java, EventTopic::class.java, Attendee::class.java, TicketId::class.java, Order::class.java, AttendeeId::class.java, Charge::class.java, Paypal::class.java, ConfirmOrder::class.java, - CustomForm::class.java, EventLocation::class.java, EventType::class.java)) + CustomForm::class.java, EventLocation::class.java, EventType::class.java, + Feedback::class.java)) .addConverterFactory(JacksonConverterFactory.create(objectMapper)) .baseUrl(baseUrl) .build() diff --git a/app/src/main/java/org/fossasia/openevent/general/event/EventDetailsFragment.kt b/app/src/main/java/org/fossasia/openevent/general/event/EventDetailsFragment.kt index 27c026a358..20e05c0a05 100644 --- a/app/src/main/java/org/fossasia/openevent/general/event/EventDetailsFragment.kt +++ b/app/src/main/java/org/fossasia/openevent/general/event/EventDetailsFragment.kt @@ -18,6 +18,7 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.navigation.Navigation.findNavController import androidx.navigation.fragment.navArgs +import androidx.recyclerview.widget.LinearLayoutManager import com.squareup.picasso.Callback import com.squareup.picasso.Picasso import kotlinx.android.synthetic.main.content_event.aboutEventContainer @@ -36,6 +37,8 @@ import kotlinx.android.synthetic.main.content_event.view.eventTimingLinearLayout import kotlinx.android.synthetic.main.content_event.view.imageMap import kotlinx.android.synthetic.main.content_event.view.locationUnderMap import kotlinx.android.synthetic.main.content_event.view.eventImage +import kotlinx.android.synthetic.main.content_event.view.feedbackContainer +import kotlinx.android.synthetic.main.content_event.view.feedbackRv import kotlinx.android.synthetic.main.content_event.view.organizerLogoIcon import kotlinx.android.synthetic.main.content_event.view.nestedContentEventScroll import kotlinx.android.synthetic.main.content_event.view.organizerName @@ -51,6 +54,7 @@ import org.fossasia.openevent.general.CircleTransform import org.fossasia.openevent.general.R import org.fossasia.openevent.general.about.AboutEventFragmentArgs import org.fossasia.openevent.general.event.EventUtils.loadMapUrl +import org.fossasia.openevent.general.event.feedback.FeedbackRecyclerAdapter import org.fossasia.openevent.general.event.topic.SimilarEventsFragment import org.fossasia.openevent.general.social.SocialLinksFragment import org.fossasia.openevent.general.ticket.TicketsFragmentArgs @@ -73,6 +77,7 @@ const val EVENT_LOCATION = "eventLocation" class EventDetailsFragment : Fragment() { private val eventViewModel by viewModel() private val safeArgs: EventDetailsFragmentArgs by navArgs() + private val feedbackAdapter = FeedbackRecyclerAdapter() private lateinit var rootView: View private var eventTopicId: Long? = null @@ -107,6 +112,7 @@ class EventDetailsFragment : Fragment() { showEventErrorScreen(false) setHasOptionsMenu(true) }) + eventViewModel.loadEventFeedback(safeArgs.eventId) } override fun onCreateView( @@ -118,6 +124,9 @@ class EventDetailsFragment : Fragment() { setToolbar(activity) setHasOptionsMenu(true) + rootView.feedbackRv.layoutManager = LinearLayoutManager(context) + rootView.feedbackRv.adapter = feedbackAdapter + rootView.buttonTickets.setOnClickListener { loadTicketFragment() } @@ -128,6 +137,15 @@ class EventDetailsFragment : Fragment() { showEventErrorScreen(true) }) + eventViewModel.eventFeedback.observe(viewLifecycleOwner, Observer { + feedbackAdapter.addAll(it) + if (it.isEmpty()) { + rootView.feedbackContainer.visibility = View.GONE + } else { + rootView.feedbackContainer.visibility = View.VISIBLE + } + }) + eventViewModel.loadEvent(safeArgs.eventId) rootView.retry.setOnClickListener { eventViewModel.loadEvent(safeArgs.eventId) diff --git a/app/src/main/java/org/fossasia/openevent/general/event/EventDetailsViewModel.kt b/app/src/main/java/org/fossasia/openevent/general/event/EventDetailsViewModel.kt index 244b84f5dd..78064df2d3 100644 --- a/app/src/main/java/org/fossasia/openevent/general/event/EventDetailsViewModel.kt +++ b/app/src/main/java/org/fossasia/openevent/general/event/EventDetailsViewModel.kt @@ -12,6 +12,7 @@ import org.fossasia.openevent.general.R import org.fossasia.openevent.general.auth.User import org.fossasia.openevent.general.common.SingleLiveEvent import org.fossasia.openevent.general.data.Resource +import org.fossasia.openevent.general.event.feedback.Feedback import timber.log.Timber class EventDetailsViewModel(private val eventService: EventService, private val resource: Resource) : ViewModel() { @@ -26,6 +27,20 @@ class EventDetailsViewModel(private val eventService: EventService, private val val error: LiveData = mutableError private val mutableEvent = MutableLiveData() val event: LiveData = mutableEvent + private val mutableEventFeedback = MutableLiveData>() + val eventFeedback: LiveData> = mutableEventFeedback + + fun loadEventFeedback(id: Long) { + compositeDisposable.add(eventService.getEventFeedback(id) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + mutableEventFeedback.value = it + }, { + Timber.e(it, "Error fetching events feedback") + }) + ) + } fun loadEvent(id: Long) { if (id.equals(-1)) { @@ -52,7 +67,7 @@ class EventDetailsViewModel(private val eventService: EventService, private val // location handling val BASE_URL = "https://api.mapbox.com/v4/mapbox.emerald/pin-l-marker+673ab7" val LOCATION = "(" + event.longitude + "," + event.latitude + ")/" + event.longitude + "," + event.latitude - return BASE_URL + LOCATION + ",15/900x500.png?access_token=" + MAPBOX_KEY + return "$BASE_URL$LOCATION,15/900x500.png?access_token=$MAPBOX_KEY" } fun setFavorite(eventId: Long, favorite: Boolean) { diff --git a/app/src/main/java/org/fossasia/openevent/general/event/EventService.kt b/app/src/main/java/org/fossasia/openevent/general/event/EventService.kt index 379f514fb9..8554d7af2e 100644 --- a/app/src/main/java/org/fossasia/openevent/general/event/EventService.kt +++ b/app/src/main/java/org/fossasia/openevent/general/event/EventService.kt @@ -3,6 +3,8 @@ package org.fossasia.openevent.general.event import io.reactivex.Completable import io.reactivex.Flowable import io.reactivex.Single +import org.fossasia.openevent.general.event.feedback.Feedback +import org.fossasia.openevent.general.event.feedback.FeedbackApi import org.fossasia.openevent.general.event.location.EventLocation import org.fossasia.openevent.general.event.location.EventLocationApi import org.fossasia.openevent.general.event.topic.EventTopic @@ -19,7 +21,8 @@ class EventService( private val eventTopicApi: EventTopicApi, private val eventTopicsDao: EventTopicsDao, private val eventTypesApi: EventTypesApi, - private val eventLocationApi: EventLocationApi + private val eventLocationApi: EventLocationApi, + private val eventFeedbackApi: FeedbackApi ) { fun getEvents(): Flowable> { @@ -59,6 +62,10 @@ class EventService( return eventTypesApi.getEventTypes() } + fun getEventFeedback(id: Long): Single> { + return eventFeedbackApi.getEventFeedback(id) + } + fun getSearchEvents(eventName: String): Single> { return eventApi.searchEvents("name", eventName).flatMap { apiList -> var eventIds = apiList.map { it.id }.toList() diff --git a/app/src/main/java/org/fossasia/openevent/general/event/feedback/Feedback.kt b/app/src/main/java/org/fossasia/openevent/general/event/feedback/Feedback.kt new file mode 100644 index 0000000000..ebeb1a9d38 --- /dev/null +++ b/app/src/main/java/org/fossasia/openevent/general/event/feedback/Feedback.kt @@ -0,0 +1,17 @@ +package org.fossasia.openevent.general.event.feedback + +import com.fasterxml.jackson.annotation.JsonProperty +import com.github.jasminb.jsonapi.LongIdHandler +import com.github.jasminb.jsonapi.annotations.Id +import com.github.jasminb.jsonapi.annotations.Type + +@Type("feedback") +data class Feedback( + @Id(LongIdHandler::class) + val id: Long, + val rating: String?, + val comment: String?, + @JsonProperty("deleted-at") + val deletedAt: String? + +) diff --git a/app/src/main/java/org/fossasia/openevent/general/event/feedback/FeedbackApi.kt b/app/src/main/java/org/fossasia/openevent/general/event/feedback/FeedbackApi.kt new file mode 100644 index 0000000000..8714c0f631 --- /dev/null +++ b/app/src/main/java/org/fossasia/openevent/general/event/feedback/FeedbackApi.kt @@ -0,0 +1,16 @@ +package org.fossasia.openevent.general.event.feedback + +import io.reactivex.Single +import retrofit2.http.GET +import retrofit2.http.Path +import retrofit2.http.Query + +interface FeedbackApi { + + @GET("events/{eventId}/feedbacks") + fun getEventFeedback( + @Path("eventId") eventId: Long, + @Query("sort") sort: String = "rating", + @Query("filter") eventName: String = "[]" + ): Single> +} diff --git a/app/src/main/java/org/fossasia/openevent/general/event/feedback/FeedbackRecyclerAdapter.kt b/app/src/main/java/org/fossasia/openevent/general/event/feedback/FeedbackRecyclerAdapter.kt new file mode 100644 index 0000000000..510a376c22 --- /dev/null +++ b/app/src/main/java/org/fossasia/openevent/general/event/feedback/FeedbackRecyclerAdapter.kt @@ -0,0 +1,32 @@ +package org.fossasia.openevent.general.event.feedback + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import org.fossasia.openevent.general.R + +class FeedbackRecyclerAdapter : RecyclerView.Adapter() { + val feedbackList = ArrayList() + + fun addAll(feedbackList: List) { + if (feedbackList.isNotEmpty()) + this.feedbackList.clear() + this.feedbackList.addAll(feedbackList) + notifyDataSetChanged() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FeedbackViewHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.item_feedback, parent, false) + return FeedbackViewHolder(view) + } + + override fun onBindViewHolder(holder: FeedbackViewHolder, position: Int) { + val feedback = feedbackList[position] + + holder.bind(feedback) + } + + override fun getItemCount(): Int { + return feedbackList.size + } +} diff --git a/app/src/main/java/org/fossasia/openevent/general/event/feedback/FeedbackViewHolder.kt b/app/src/main/java/org/fossasia/openevent/general/event/feedback/FeedbackViewHolder.kt new file mode 100644 index 0000000000..b557a1f3eb --- /dev/null +++ b/app/src/main/java/org/fossasia/openevent/general/event/feedback/FeedbackViewHolder.kt @@ -0,0 +1,14 @@ +package org.fossasia.openevent.general.event.feedback + +import android.view.View +import androidx.recyclerview.widget.RecyclerView +import kotlinx.android.synthetic.main.item_feedback.view.commentTv +import kotlinx.android.synthetic.main.item_feedback.view.ratingBar + +class FeedbackViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + + fun bind(feedback: Feedback) { + itemView.commentTv.text = feedback.comment + itemView.ratingBar.rating = feedback.rating?.toFloat() ?: 0f + } +} diff --git a/app/src/main/res/layout/content_event.xml b/app/src/main/res/layout/content_event.xml index af97c8bc18..a2772bbaf6 100644 --- a/app/src/main/res/layout/content_event.xml +++ b/app/src/main/res/layout/content_event.xml @@ -371,6 +371,42 @@ android:paddingRight="@dimen/padding_large" android:paddingTop="@dimen/padding_small" /> + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bc0f4317f8..521023c1c0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -300,5 +300,6 @@ And I\'m up for savedType What Sounds good? + Feedback