Skip to content

Commit

Permalink
feat: Add Event Feedbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
aggarwalpulkit596 committed Apr 14, 2019
1 parent 3d3a586 commit 231c74d
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 7 deletions.
5 changes: 3 additions & 2 deletions app/build.gradle
Expand Up @@ -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+'"'
}
}
Expand Down
11 changes: 9 additions & 2 deletions app/src/main/java/org/fossasia/openevent/general/di/Modules.kt
Expand Up @@ -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
Expand Down Expand Up @@ -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()) }
Expand Down Expand Up @@ -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()
Expand Down
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -73,6 +77,7 @@ const val EVENT_LOCATION = "eventLocation"
class EventDetailsFragment : Fragment() {
private val eventViewModel by viewModel<EventDetailsViewModel>()
private val safeArgs: EventDetailsFragmentArgs by navArgs()
private val feedbackAdapter = FeedbackRecyclerAdapter()

private lateinit var rootView: View
private var eventTopicId: Long? = null
Expand Down Expand Up @@ -107,6 +112,7 @@ class EventDetailsFragment : Fragment() {
showEventErrorScreen(false)
setHasOptionsMenu(true)
})
eventViewModel.loadEventFeedback(safeArgs.eventId)
}

override fun onCreateView(
Expand All @@ -118,6 +124,9 @@ class EventDetailsFragment : Fragment() {
setToolbar(activity)
setHasOptionsMenu(true)

rootView.feedbackRv.layoutManager = LinearLayoutManager(context)
rootView.feedbackRv.adapter = feedbackAdapter

rootView.buttonTickets.setOnClickListener {
loadTicketFragment()
}
Expand All @@ -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)
Expand Down
Expand Up @@ -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() {
Expand All @@ -26,6 +27,20 @@ class EventDetailsViewModel(private val eventService: EventService, private val
val error: LiveData<String> = mutableError
private val mutableEvent = MutableLiveData<Event>()
val event: LiveData<Event> = mutableEvent
private val mutableEventFeedback = MutableLiveData<List<Feedback>>()
val eventFeedback: LiveData<List<Feedback>> = 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)) {
Expand All @@ -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) {
Expand Down
Expand Up @@ -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
Expand All @@ -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<List<Event>> {
Expand Down Expand Up @@ -59,6 +62,10 @@ class EventService(
return eventTypesApi.getEventTypes()
}

fun getEventFeedback(id: Long): Single<List<Feedback>> {
return eventFeedbackApi.getEventFeedback(id)
}

fun getSearchEvents(eventName: String): Single<List<Event>> {
return eventApi.searchEvents("name", eventName).flatMap { apiList ->
var eventIds = apiList.map { it.id }.toList()
Expand Down
@@ -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?

)
@@ -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<List<Feedback>>
}
@@ -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<FeedbackViewHolder>() {
val feedbackList = ArrayList<Feedback>()

fun addAll(feedbackList: List<Feedback>) {
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
}
}
@@ -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
}
}
38 changes: 37 additions & 1 deletion app/src/main/res/layout/content_event.xml
Expand Up @@ -371,6 +371,42 @@
android:paddingRight="@dimen/padding_large"
android:paddingTop="@dimen/padding_small" />
</LinearLayout>
<LinearLayout
android:id="@+id/feedbackContainer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_margin_large"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/organizerContainer"
tools:visibility="visible">

<View
android:layout_width="match_parent"
android:layout_height="@dimen/event_details_divider"
android:layout_marginLeft="@dimen/layout_margin_large"
android:layout_marginRight="@dimen/layout_margin_large"
android:layout_marginBottom="@dimen/layout_margin_extra_large"
android:background="@color/grey" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/layout_margin_large"
android:layout_marginRight="@dimen/layout_margin_large"
android:layout_marginBottom="@dimen/layout_margin_large"
android:text="@string/feedback"
android:textColor="@color/dark_grey"
android:textSize="@dimen/event_details_headers" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/feedbackRv"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>


<LinearLayout
android:id="@+id/similarEventsContainer"
Expand All @@ -381,7 +417,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/organizerContainer"
app:layout_constraintTop_toBottomOf="@id/feedbackContainer"
tools:visibility="visible">

<FrameLayout
Expand Down
24 changes: 24 additions & 0 deletions app/src/main/res/layout/item_feedback.xml
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_marginStart="@dimen/layout_margin_large"
android:layout_marginTop="@dimen/layout_margin_small"
android:layout_marginBottom="@dimen/layout_margin_small"
android:layout_marginEnd="@dimen/layout_margin_large"
android:layout_height="wrap_content">
<RatingBar
android:id="@+id/ratingBar"
android:numStars="5"
style="@style/Widget.AppCompat.RatingBar.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<TextView
android:id="@+id/commentTv"
android:layout_marginTop="@dimen/layout_margin_small"
android:textColor="@color/black"
android:layout_width="match_parent"
android:layout_height="wrap_content" />


</LinearLayout>
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Expand Up @@ -300,5 +300,6 @@
<string name="and_i_m_up_for">And I\'m up for</string>
<string name="savedType">savedType</string>
<string name="what_type">What Sounds good?</string>
<string name="feedback">Feedback</string>

</resources>

0 comments on commit 231c74d

Please sign in to comment.