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 ade8bd4ee4..441e559ac8 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 @@ -203,7 +203,7 @@ val viewModelModule = module { viewModel { ProfileViewModel(get(), get()) } viewModel { SignUpViewModel(get(), get(), get()) } viewModel { EventDetailsViewModel(get(), get(), get(), get(), get(), get(), get(), get()) } - viewModel { SessionViewModel(get(), get()) } + viewModel { SessionViewModel(get(), get(), get()) } viewModel { SearchViewModel(get(), get(), get(), get()) } viewModel { AttendeeViewModel(get(), get(), get(), get(), get(), get(), get()) } viewModel { SearchLocationViewModel(get(), get()) } 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 d71bedc2c1..3d63b504d7 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 @@ -80,9 +80,6 @@ import org.fossasia.openevent.general.utils.Utils.setToolbar import org.jetbrains.anko.design.longSnackbar import org.jetbrains.anko.design.snackbar -const val EVENT_ID = "eventId" -const val EVENT_TOPIC_ID = "eventTopicId" -const val EVENT_LOCATION = "eventLocation" const val EVENT_DETAIL_FRAGMENT = "eventDetailFragment;" class EventDetailsFragment : Fragment() { diff --git a/app/src/main/java/org/fossasia/openevent/general/sessions/SessionFragment.kt b/app/src/main/java/org/fossasia/openevent/general/sessions/SessionFragment.kt index 2613bf2401..6de3b57e19 100644 --- a/app/src/main/java/org/fossasia/openevent/general/sessions/SessionFragment.kt +++ b/app/src/main/java/org/fossasia/openevent/general/sessions/SessionFragment.kt @@ -13,6 +13,9 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.navigation.fragment.navArgs import com.squareup.picasso.Picasso +import androidx.navigation.Navigation.findNavController +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.LinearLayoutManager.HORIZONTAL import kotlinx.android.synthetic.main.fragment_session.view.progressBar import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailTrack import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailAbstract @@ -34,7 +37,12 @@ import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailAbstrac import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailTrackContainer import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailSignUpButton import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailTrackIcon +import kotlinx.android.synthetic.main.fragment_session.view.speakersUnderSessionRecycler +import kotlinx.android.synthetic.main.fragment_session.view.speakersProgressBar +import kotlinx.android.synthetic.main.fragment_session.view.sessionDetailSpeakersContainer import org.fossasia.openevent.general.R +import org.fossasia.openevent.general.common.SpeakerClickListener +import org.fossasia.openevent.general.speakers.SpeakerRecyclerAdapter import org.fossasia.openevent.general.event.EventUtils import org.fossasia.openevent.general.utils.Utils import org.fossasia.openevent.general.utils.Utils.setToolbar @@ -47,6 +55,7 @@ const val LINE_COUNT_ABSTRACT = 3 class SessionFragment : Fragment() { private lateinit var rootView: View private val sessionViewModel by viewModel() + private val speakersAdapter = SpeakerRecyclerAdapter() private val safeArgs: SessionFragmentArgs by navArgs() override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -59,6 +68,9 @@ class SessionFragment : Fragment() { .nonNull() .observe(viewLifecycleOwner, Observer { rootView.snackbar(it) + if (it == getString(R.string.error_fetching_speakers_for_session)) { + rootView.sessionDetailSpeakersContainer.visibility = View.GONE + } }) sessionViewModel.session @@ -74,11 +86,48 @@ class SessionFragment : Fragment() { rootView.sessionDetailContainer.visibility = if (it) View.GONE else View.VISIBLE }) + sessionViewModel.speakersUnderSession + .nonNull() + .observe(viewLifecycleOwner, Observer { + speakersAdapter.addAll(it) + if (it.isEmpty()) + rootView.sessionDetailSpeakersContainer.visibility = View.GONE + else + rootView.speakersProgressBar.visibility = View.GONE + }) + sessionViewModel.loadSession(safeArgs.sessionId) + val currentSpeakers = sessionViewModel.speakersUnderSession.value + if (currentSpeakers == null) + sessionViewModel.loadSpeakersUnderSession(safeArgs.sessionId) + else { + speakersAdapter.addAll(currentSpeakers) + if (currentSpeakers.isEmpty()) + rootView.sessionDetailSpeakersContainer.visibility = View.GONE + else + rootView.speakersProgressBar.visibility = View.GONE + } + + val layoutManager = LinearLayoutManager(context) + layoutManager.orientation = HORIZONTAL + rootView.speakersUnderSessionRecycler.layoutManager = layoutManager + rootView.speakersUnderSessionRecycler.adapter = speakersAdapter return rootView } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val speakerClickListener = object : SpeakerClickListener { + override fun onClick(speakerId: Long) { + findNavController(rootView).navigate(SessionFragmentDirections.actionSessionToSpeaker(speakerId)) + } + } + speakersAdapter.apply { + onSpeakerClick = speakerClickListener + } + } + override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { android.R.id.home -> { diff --git a/app/src/main/java/org/fossasia/openevent/general/sessions/SessionViewModel.kt b/app/src/main/java/org/fossasia/openevent/general/sessions/SessionViewModel.kt index c476b1b658..e98a730989 100644 --- a/app/src/main/java/org/fossasia/openevent/general/sessions/SessionViewModel.kt +++ b/app/src/main/java/org/fossasia/openevent/general/sessions/SessionViewModel.kt @@ -3,17 +3,20 @@ package org.fossasia.openevent.general.sessions import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import io.reactivex.android.schedulers.AndroidSchedulers import org.fossasia.openevent.general.BuildConfig.MAPBOX_KEY import io.reactivex.disposables.CompositeDisposable -import io.reactivex.schedulers.Schedulers +import io.reactivex.rxkotlin.plusAssign import org.fossasia.openevent.general.R import org.fossasia.openevent.general.common.SingleLiveEvent import org.fossasia.openevent.general.data.Resource +import org.fossasia.openevent.general.speakers.Speaker +import org.fossasia.openevent.general.speakers.SpeakerService +import org.fossasia.openevent.general.utils.extensions.withDefaultSchedulers import timber.log.Timber class SessionViewModel( private val sessionService: SessionService, + private val speakerService: SpeakerService, private val resource: Resource ) : ViewModel() { private val compositeDisposable = CompositeDisposable() @@ -24,6 +27,8 @@ class SessionViewModel( val progress: LiveData = mutableProgress private val mutableError = SingleLiveEvent() val error: LiveData = mutableError + private val mutableSpeakers = MutableLiveData>() + val speakersUnderSession: LiveData> = mutableSpeakers fun loadSession(id: Long) { if (id == -1L) { @@ -31,9 +36,8 @@ class SessionViewModel( return } - compositeDisposable.add(sessionService.fetchSession(id) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) + compositeDisposable += sessionService.fetchSession(id) + .withDefaultSchedulers() .doOnSubscribe { mutableProgress.value = true } .subscribe({ mutableSession.value = it @@ -43,7 +47,22 @@ class SessionViewModel( mutableError.value = resource.getString(R.string.error_fetching_event_section_message, resource.getString(R.string.session)) }) - ) + } + + fun loadSpeakersUnderSession(id: Long) { + if (id == -1L) { + mutableError.value = resource.getString(R.string.error_fetching_speakers_for_session) + return + } + + compositeDisposable += speakerService.fetchSpeakerForSession(id) + .withDefaultSchedulers() + .subscribe({ + mutableSpeakers.value = it + }, { + Timber.e(it, "Error fetching speakers for session $id") + mutableError.value = resource.getString(R.string.error_fetching_speakers_for_session) + }) } fun loadMap(latitude: String, longitude: String): String { diff --git a/app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerApi.kt b/app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerApi.kt index 72d16c5f89..fc4ac2a893 100644 --- a/app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerApi.kt +++ b/app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerApi.kt @@ -9,6 +9,9 @@ interface SpeakerApi { @GET("events/{id}/speakers") fun getSpeakerForEvent(@Path("id") id: Long): Single> + @GET("sessions/{sessionId}/speakers") + fun getSpeakersForSession(@Path("sessionId") id: Long): Single> + @GET("speakers/{speaker_id}") fun getSpeakerWithId(@Path("speaker_id") id: Long): Single } diff --git a/app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerService.kt b/app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerService.kt index b63a97c8a8..b7aab6f37b 100644 --- a/app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerService.kt +++ b/app/src/main/java/org/fossasia/openevent/general/speakers/SpeakerService.kt @@ -24,6 +24,12 @@ class SpeakerService( return speakerWithEventDao.getSpeakerWithEventId(id) } + fun fetchSpeakerForSession(sessionId: Long): Single> = + speakerApi.getSpeakersForSession(sessionId) + .doOnSuccess { + speakerDao.insertSpeakers(it) + } + fun fetchSpeaker(id: Long): Flowable { return speakerDao.getSpeaker(id) } diff --git a/app/src/main/res/layout/fragment_session.xml b/app/src/main/res/layout/fragment_session.xml index 897f041c33..d745bed64f 100644 --- a/app/src/main/res/layout/fragment_session.xml +++ b/app/src/main/res/layout/fragment_session.xml @@ -220,6 +220,36 @@ android:background="@color/grey" /> + + + + + + + + Error fetching event Error fetching events + Error fetching speakers under this session Error Error fetching favorite events Failed to list Orders under a user