Skip to content

Commit a12b674

Browse files
anhanh11001iamareebjamal
authored andcommitted
feat: Add speakers under session (#1788)
Detail: - Set up recycler/adapter to fetch speakers under session Fixes: #1786
1 parent 4bea92c commit a12b674

File tree

9 files changed

+122
-10
lines changed

9 files changed

+122
-10
lines changed

app/src/main/java/org/fossasia/openevent/general/di/Modules.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ val viewModelModule = module {
203203
viewModel { ProfileViewModel(get(), get()) }
204204
viewModel { SignUpViewModel(get(), get(), get()) }
205205
viewModel { EventDetailsViewModel(get(), get(), get(), get(), get(), get(), get(), get()) }
206-
viewModel { SessionViewModel(get(), get()) }
206+
viewModel { SessionViewModel(get(), get(), get()) }
207207
viewModel { SearchViewModel(get(), get(), get(), get()) }
208208
viewModel { AttendeeViewModel(get(), get(), get(), get(), get(), get(), get()) }
209209
viewModel { SearchLocationViewModel(get(), get()) }

app/src/main/java/org/fossasia/openevent/general/event/EventDetailsFragment.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,6 @@ import org.fossasia.openevent.general.utils.Utils.setToolbar
8080
import org.jetbrains.anko.design.longSnackbar
8181
import org.jetbrains.anko.design.snackbar
8282

83-
const val EVENT_ID = "eventId"
84-
const val EVENT_TOPIC_ID = "eventTopicId"
85-
const val EVENT_LOCATION = "eventLocation"
8683
const val EVENT_DETAIL_FRAGMENT = "eventDetailFragment;"
8784

8885
class EventDetailsFragment : Fragment() {

app/src/main/java/org/fossasia/openevent/general/sessions/SessionFragment.kt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ import androidx.fragment.app.Fragment
1313
import androidx.lifecycle.Observer
1414
import androidx.navigation.fragment.navArgs
1515
import com.squareup.picasso.Picasso
16+
import androidx.navigation.Navigation.findNavController
17+
import androidx.recyclerview.widget.LinearLayoutManager
18+
import androidx.recyclerview.widget.LinearLayoutManager.HORIZONTAL
1619
import kotlinx.android.synthetic.main.fragment_session.view.progressBar
1720
import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailTrack
1821
import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailAbstract
@@ -34,7 +37,12 @@ import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailAbstrac
3437
import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailTrackContainer
3538
import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailSignUpButton
3639
import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailTrackIcon
40+
import kotlinx.android.synthetic.main.fragment_session.view.speakersUnderSessionRecycler
41+
import kotlinx.android.synthetic.main.fragment_session.view.speakersProgressBar
42+
import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailSpeakersContainer
3743
import org.fossasia.openevent.general.R
44+
import org.fossasia.openevent.general.common.SpeakerClickListener
45+
import org.fossasia.openevent.general.speakers.SpeakerRecyclerAdapter
3846
import org.fossasia.openevent.general.event.EventUtils
3947
import org.fossasia.openevent.general.utils.Utils
4048
import org.fossasia.openevent.general.utils.Utils.setToolbar
@@ -47,6 +55,7 @@ const val LINE_COUNT_ABSTRACT = 3
4755
class SessionFragment : Fragment() {
4856
private lateinit var rootView: View
4957
private val sessionViewModel by viewModel<SessionViewModel>()
58+
private val speakersAdapter = SpeakerRecyclerAdapter()
5059
private val safeArgs: SessionFragmentArgs by navArgs()
5160

5261
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@@ -59,6 +68,9 @@ class SessionFragment : Fragment() {
5968
.nonNull()
6069
.observe(viewLifecycleOwner, Observer {
6170
rootView.snackbar(it)
71+
if (it == getString(R.string.error_fetching_speakers_for_session)) {
72+
rootView.sessionDetailSpeakersContainer.visibility = View.GONE
73+
}
6274
})
6375

6476
sessionViewModel.session
@@ -74,11 +86,48 @@ class SessionFragment : Fragment() {
7486
rootView.sessionDetailContainer.visibility = if (it) View.GONE else View.VISIBLE
7587
})
7688

89+
sessionViewModel.speakersUnderSession
90+
.nonNull()
91+
.observe(viewLifecycleOwner, Observer {
92+
speakersAdapter.addAll(it)
93+
if (it.isEmpty())
94+
rootView.sessionDetailSpeakersContainer.visibility = View.GONE
95+
else
96+
rootView.speakersProgressBar.visibility = View.GONE
97+
})
98+
7799
sessionViewModel.loadSession(safeArgs.sessionId)
100+
val currentSpeakers = sessionViewModel.speakersUnderSession.value
101+
if (currentSpeakers == null)
102+
sessionViewModel.loadSpeakersUnderSession(safeArgs.sessionId)
103+
else {
104+
speakersAdapter.addAll(currentSpeakers)
105+
if (currentSpeakers.isEmpty())
106+
rootView.sessionDetailSpeakersContainer.visibility = View.GONE
107+
else
108+
rootView.speakersProgressBar.visibility = View.GONE
109+
}
110+
111+
val layoutManager = LinearLayoutManager(context)
112+
layoutManager.orientation = HORIZONTAL
113+
rootView.speakersUnderSessionRecycler.layoutManager = layoutManager
114+
rootView.speakersUnderSessionRecycler.adapter = speakersAdapter
78115

79116
return rootView
80117
}
81118

119+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
120+
super.onViewCreated(view, savedInstanceState)
121+
val speakerClickListener = object : SpeakerClickListener {
122+
override fun onClick(speakerId: Long) {
123+
findNavController(rootView).navigate(SessionFragmentDirections.actionSessionToSpeaker(speakerId))
124+
}
125+
}
126+
speakersAdapter.apply {
127+
onSpeakerClick = speakerClickListener
128+
}
129+
}
130+
82131
override fun onOptionsItemSelected(item: MenuItem): Boolean {
83132
return when (item.itemId) {
84133
android.R.id.home -> {

app/src/main/java/org/fossasia/openevent/general/sessions/SessionViewModel.kt

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@ package org.fossasia.openevent.general.sessions
33
import androidx.lifecycle.LiveData
44
import androidx.lifecycle.MutableLiveData
55
import androidx.lifecycle.ViewModel
6-
import io.reactivex.android.schedulers.AndroidSchedulers
76
import org.fossasia.openevent.general.BuildConfig.MAPBOX_KEY
87
import io.reactivex.disposables.CompositeDisposable
9-
import io.reactivex.schedulers.Schedulers
8+
import io.reactivex.rxkotlin.plusAssign
109
import org.fossasia.openevent.general.R
1110
import org.fossasia.openevent.general.common.SingleLiveEvent
1211
import org.fossasia.openevent.general.data.Resource
12+
import org.fossasia.openevent.general.speakers.Speaker
13+
import org.fossasia.openevent.general.speakers.SpeakerService
14+
import org.fossasia.openevent.general.utils.extensions.withDefaultSchedulers
1315
import timber.log.Timber
1416

1517
class SessionViewModel(
1618
private val sessionService: SessionService,
19+
private val speakerService: SpeakerService,
1720
private val resource: Resource
1821
) : ViewModel() {
1922
private val compositeDisposable = CompositeDisposable()
@@ -24,16 +27,17 @@ class SessionViewModel(
2427
val progress: LiveData<Boolean> = mutableProgress
2528
private val mutableError = SingleLiveEvent<String>()
2629
val error: LiveData<String> = mutableError
30+
private val mutableSpeakers = MutableLiveData<List<Speaker>>()
31+
val speakersUnderSession: LiveData<List<Speaker>> = mutableSpeakers
2732

2833
fun loadSession(id: Long) {
2934
if (id == -1L) {
3035
mutableError.value = resource.getString(R.string.error_fetching_event_message)
3136
return
3237
}
3338

34-
compositeDisposable.add(sessionService.fetchSession(id)
35-
.subscribeOn(Schedulers.io())
36-
.observeOn(AndroidSchedulers.mainThread())
39+
compositeDisposable += sessionService.fetchSession(id)
40+
.withDefaultSchedulers()
3741
.doOnSubscribe { mutableProgress.value = true }
3842
.subscribe({
3943
mutableSession.value = it
@@ -43,7 +47,22 @@ class SessionViewModel(
4347
mutableError.value = resource.getString(R.string.error_fetching_event_section_message,
4448
resource.getString(R.string.session))
4549
})
46-
)
50+
}
51+
52+
fun loadSpeakersUnderSession(id: Long) {
53+
if (id == -1L) {
54+
mutableError.value = resource.getString(R.string.error_fetching_speakers_for_session)
55+
return
56+
}
57+
58+
compositeDisposable += speakerService.fetchSpeakerForSession(id)
59+
.withDefaultSchedulers()
60+
.subscribe({
61+
mutableSpeakers.value = it
62+
}, {
63+
Timber.e(it, "Error fetching speakers for session $id")
64+
mutableError.value = resource.getString(R.string.error_fetching_speakers_for_session)
65+
})
4766
}
4867

4968
fun loadMap(latitude: String, longitude: String): String {

app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerApi.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ interface SpeakerApi {
99
@GET("events/{id}/speakers")
1010
fun getSpeakerForEvent(@Path("id") id: Long): Single<List<Speaker>>
1111

12+
@GET("sessions/{sessionId}/speakers")
13+
fun getSpeakersForSession(@Path("sessionId") id: Long): Single<List<Speaker>>
14+
1215
@GET("speakers/{speaker_id}")
1316
fun getSpeakerWithId(@Path("speaker_id") id: Long): Single<Speaker>
1417
}

app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerService.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ class SpeakerService(
2424
return speakerWithEventDao.getSpeakerWithEventId(id)
2525
}
2626

27+
fun fetchSpeakerForSession(sessionId: Long): Single<List<Speaker>> =
28+
speakerApi.getSpeakersForSession(sessionId)
29+
.doOnSuccess {
30+
speakerDao.insertSpeakers(it)
31+
}
32+
2733
fun fetchSpeaker(id: Long): Flowable<Speaker> {
2834
return speakerDao.getSpeaker(id)
2935
}

app/src/main/res/layout/fragment_session.xml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,36 @@
220220
android:background="@color/grey" />
221221
</LinearLayout>
222222

223+
<LinearLayout
224+
android:id="@+id/sessionDetailSpeakersContainer"
225+
android:orientation="vertical"
226+
android:layout_width="match_parent"
227+
android:layout_height="wrap_content"
228+
android:animateLayoutChanges="true">
229+
<TextView
230+
android:layout_width="match_parent"
231+
android:layout_height="wrap_content"
232+
android:text="@string/speakers"
233+
android:textColor="@color/dark_grey"
234+
android:textSize="@dimen/event_details_headers"
235+
android:layout_marginBottom="@dimen/layout_margin_medium"/>
236+
<ProgressBar
237+
android:id="@+id/speakersProgressBar"
238+
android:layout_width="wrap_content"
239+
android:layout_height="wrap_content"
240+
android:layout_gravity="center"/>
241+
<androidx.recyclerview.widget.RecyclerView
242+
android:id="@+id/speakersUnderSessionRecycler"
243+
android:layout_width="match_parent"
244+
android:layout_height="wrap_content"/>
245+
<View
246+
android:layout_width="match_parent"
247+
android:layout_height="@dimen/event_details_divider"
248+
android:layout_marginTop="@dimen/layout_margin_large"
249+
android:layout_marginBottom="@dimen/layout_margin_large"
250+
android:background="@color/grey" />
251+
</LinearLayout>
252+
223253
<androidx.appcompat.widget.AppCompatButton
224254
android:id="@+id/sessionDetailSignUpButton"
225255
android:layout_width="match_parent"

app/src/main/res/navigation/navigation_graph.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,13 @@
251251
android:name="org.fossasia.openevent.general.sessions.SessionFragment"
252252
android:label="SessionFragment"
253253
tools:layout="@layout/fragment_session">
254+
<action
255+
android:id="@+id/action_session_to_speaker"
256+
app:destination="@id/speakerFragment"
257+
app:popEnterAnim="@anim/slide_in_left"
258+
app:popExitAnim="@anim/slide_out_right"
259+
app:enterAnim="@anim/slide_in_right"
260+
app:exitAnim="@anim/slide_out_left"/>
254261
<argument
255262
android:name="sessionId"
256263
app:argType="long"

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@
290290
<!--about event fragment-->
291291
<string name="error_fetching_event_message">Error fetching event</string>
292292
<string name="error_fetching_events_message">Error fetching events</string>
293+
<string name="error_fetching_speakers_for_session">Error fetching speakers under this session</string>
293294
<string name="error">Error</string>
294295
<string name="fetch_favorite_events_error_message">Error fetching favorite events</string>
295296
<string name="list_orders_fail_message">Failed to list Orders under a user</string>

0 commit comments

Comments
 (0)