Skip to content
This repository was archived by the owner on Feb 17, 2020. It is now read-only.

Commit f9d5696

Browse files
authored
Merge pull request #526 from squanchy-dev/show_event_room_in_schedule
Show event room in schedule
2 parents fb7663c + 1ee717c commit f9d5696

35 files changed

Lines changed: 215 additions & 109 deletions

app/src/debug/java/net/squanchy/support/debug/DebugActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class DebugActivity : AppCompatActivity() {
8383
}
8484

8585
private fun createPlace(): Option<Place> = Option(
86-
Place("1", "That room over there", Option.empty())
86+
Place("1", "That room over there", Option.empty(), -1)
8787
)
8888

8989
private fun createTalkSpeakers(): List<Speaker> {

app/src/main/java/net/squanchy/favorites/FavoritesPageView.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class FavoritesPageView @JvmOverloads constructor(
3333
private val disposable = CompositeDisposable()
3434

3535
init {
36-
with(favoritesComponent(unwrapToActivityContext(context))) {
36+
with(favoritesComponent(context.unwrapToActivityContext())) {
3737
favoritesService = favoritesService()
3838
navigator = navigator()
3939
analytics = analytics()
@@ -126,7 +126,7 @@ class FavoritesPageView @JvmOverloads constructor(
126126
// ⚠️ HACK this is DIRTY and HORRIBLE but it's the only way we can ship this
127127
// without rewriting the whole data layer. Sorry. I swear, we know it sucks
128128
// and we want to fix this ASAP.
129-
val activity: HomeActivity = unwrapToActivityContext(context) as HomeActivity
129+
val activity: HomeActivity = context.unwrapToActivityContext() as HomeActivity
130130
activity.requestSignIn()
131131
}
132132

app/src/main/java/net/squanchy/favorites/view/FavoritesViewHolders.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.view.View
55
import android.widget.TextView
66
import net.squanchy.schedule.domain.view.Event
77
import net.squanchy.schedule.view.EventItemView
8+
import net.squanchy.schedule.view.OnEventClickListener
89
import org.joda.time.LocalDate
910

1011
fun favoriteItemViewHolderFor(itemView: View) = when (itemView) {
@@ -17,9 +18,9 @@ sealed class FavoritesViewHolder<T : View>(itemView: T) : RecyclerView.ViewHolde
1718

1819
class EventViewHolder(itemView: EventItemView) : FavoritesViewHolder<EventItemView>(itemView) {
1920

20-
fun updateWith(event: Event, listener: (Event) -> Unit) {
21-
(itemView as EventItemView).updateWith(event)
22-
itemView.setOnClickListener { listener(event) }
21+
fun updateWith(event: Event, listener: OnEventClickListener?) {
22+
(itemView as EventItemView).updateWith(event, false) // TODO import the feature flag here as well
23+
itemView.setOnClickListener { listener?.invoke(event) }
2324
}
2425
}
2526

app/src/main/java/net/squanchy/imageloader/ImageLoaderComponent.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import android.support.v7.app.AppCompatActivity
44
import dagger.Component
55
import net.squanchy.injection.ActivityContextModule
66

7-
fun imageLoaderComponent(activity: AppCompatActivity) =
7+
fun imageLoaderComponent(activity: AppCompatActivity): ImageLoaderComponent =
88
DaggerImageLoaderComponent.builder()
99
.activityContextModule(ActivityContextModule(activity))
1010
.imageLoaderModule(ImageLoaderModule())

app/src/main/java/net/squanchy/injection/ApplicationComponent.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import android.app.Application
44
import dagger.Component
55
import net.squanchy.analytics.Analytics
66
import net.squanchy.analytics.AnalyticsModule
7+
import net.squanchy.remoteconfig.FeatureFlags
78
import net.squanchy.remoteconfig.RemoteConfig
89
import net.squanchy.remoteconfig.RemoteConfigModule
910
import net.squanchy.schedule.tracksfilter.TracksFilter
@@ -65,6 +66,8 @@ interface ApplicationComponent {
6566

6667
fun remoteConfig(): RemoteConfig
6768

69+
fun featureFlags(): FeatureFlags
70+
6871
fun application(): Application
6972

7073
fun algoliaSearchEngine(): AlgoliaSearchEngine
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package net.squanchy.remoteconfig
2+
3+
class FeatureFlags(private val remoteConfig: RemoteConfig) {
4+
5+
val showEventRoomInSchedule
6+
get() = isFeatureEnabled(Feature.ShowEventRoomInSchedule)
7+
8+
private fun isFeatureEnabled(feature: Feature) = remoteConfig.getBoolean(feature.remoteConfigFlagName)
9+
10+
private sealed class Feature {
11+
abstract val remoteConfigFlagName: String
12+
13+
object ShowEventRoomInSchedule : Feature() {
14+
15+
override val remoteConfigFlagName = "show_event_room_in_schedule"
16+
}
17+
}
18+
}

app/src/main/java/net/squanchy/remoteconfig/RemoteConfig.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ class RemoteConfig(
1414
private val cacheExpiryInSeconds: Long
1515
get() = if (debugMode) EXPIRY_IMMEDIATELY else EXPIRY_ONE_HOUR
1616

17+
fun getBoolean(key: String): Single<Boolean> =
18+
getConfigValue { firebaseRemoteConfig.getBoolean(key) }
19+
1720
private fun <T> getConfigValue(action: () -> T): Single<T> {
1821
return fetchAndActivate(cacheExpiryInSeconds)
1922
.andThen(Single.fromCallable { action() })
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
package net.squanchy.remoteconfig
22

33
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
4-
5-
import net.squanchy.BuildConfig
6-
import net.squanchy.R
7-
84
import dagger.Module
95
import dagger.Provides
6+
import net.squanchy.BuildConfig
7+
import net.squanchy.R
108

119
@Module
1210
class RemoteConfigModule {
1311

1412
@Provides
15-
internal fun firebaseRemoteConfig() = FirebaseRemoteConfig.getInstance()
13+
fun firebaseRemoteConfig() = FirebaseRemoteConfig.getInstance()
1614

1715
@Provides
18-
internal fun remoteConfig(firebaseRemoteConfig: FirebaseRemoteConfig): RemoteConfig {
16+
fun remoteConfig(firebaseRemoteConfig: FirebaseRemoteConfig): RemoteConfig {
1917
return RemoteConfigBuilder(firebaseRemoteConfig)
2018
.withDebugMode(BuildConfig.DEBUG)
2119
.withDefaults(R.xml.remote_config_defaults)
2220
.build()
2321
}
22+
23+
@Provides
24+
fun featureFlags(remoteConfig: RemoteConfig) = FeatureFlags(remoteConfig)
2425
}

app/src/main/java/net/squanchy/schedule/ScheduleComponent.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import net.squanchy.injection.ApplicationComponent
99
import net.squanchy.injection.applicationComponent
1010
import net.squanchy.navigation.NavigationModule
1111
import net.squanchy.navigation.Navigator
12+
import net.squanchy.remoteconfig.FeatureFlags
1213
import net.squanchy.schedule.tracksfilter.TracksFilter
1314
import net.squanchy.service.repository.TracksRepository
1415
import net.squanchy.support.injection.CurrentTimeModule
@@ -23,7 +24,10 @@ internal fun scheduleComponent(activity: AppCompatActivity): ScheduleComponent =
2324
.build()
2425

2526
@ActivityLifecycle
26-
@Component(modules = [ScheduleModule::class, NavigationModule::class, CurrentTimeModule::class], dependencies = [ApplicationComponent::class])
27+
@Component(
28+
modules = [ScheduleModule::class, NavigationModule::class, CurrentTimeModule::class],
29+
dependencies = [ApplicationComponent::class]
30+
)
2731
internal interface ScheduleComponent {
2832

2933
fun scheduleService(): ScheduleService
@@ -37,4 +41,6 @@ internal interface ScheduleComponent {
3741
fun tracksRepository(): TracksRepository
3842

3943
fun tracksFilter(): TracksFilter
44+
45+
fun featureFlags(): FeatureFlags
4046
}

app/src/main/java/net/squanchy/schedule/SchedulePageView.kt

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,18 @@ import android.support.design.widget.CoordinatorLayout
55
import android.support.design.widget.TabLayout
66
import android.text.Spanned
77
import android.util.AttributeSet
8-
import android.view.View
8+
import androidx.view.isVisible
9+
import io.reactivex.Observable
910
import io.reactivex.android.schedulers.AndroidSchedulers
1011
import io.reactivex.disposables.CompositeDisposable
12+
import io.reactivex.functions.BiFunction
1113
import kotlinx.android.synthetic.main.view_page_schedule.view.*
1214
import net.squanchy.R
1315
import net.squanchy.analytics.Analytics
1416
import net.squanchy.analytics.ContentType
1517
import net.squanchy.home.Loadable
1618
import net.squanchy.navigation.Navigator
19+
import net.squanchy.remoteconfig.FeatureFlags
1720
import net.squanchy.schedule.domain.view.Event
1821
import net.squanchy.schedule.domain.view.Schedule
1922
import net.squanchy.schedule.view.ScheduleViewPagerAdapter
@@ -35,16 +38,18 @@ class SchedulePageView @JvmOverloads constructor(
3538
private val navigate: Navigator
3639
private val analytics: Analytics
3740
private val currentTime: CurrentTime
41+
private val featureFlags: FeatureFlags
3842
private var subscriptions = CompositeDisposable()
3943

4044
init {
41-
val activity = unwrapToActivityContext(getContext())
45+
val activity = context.unwrapToActivityContext()
4246
val component = scheduleComponent(activity)
4347
service = component.scheduleService()
4448
navigate = component.navigator()
4549
analytics = component.analytics()
4650
viewPagerAdapter = ScheduleViewPagerAdapter(activity)
4751
currentTime = component.currentTime()
52+
featureFlags = component.featureFlags()
4853
}
4954

5055
override fun onFinishInflate() {
@@ -80,15 +85,17 @@ class SchedulePageView @JvmOverloads constructor(
8085

8186
override fun startLoading() {
8287
subscriptions.add(
83-
service.schedule()
88+
Observable.combineLatest(service.schedule(), featureFlags.showEventRoomInSchedule.toObservable(), combineInPair())
8489
.observeOn(AndroidSchedulers.mainThread())
8590
.subscribe(
86-
{ updateWith(it, ::onEventClicked) },
87-
{ Timber.e(it) }
91+
{ updateWith(it.first, it.second, ::onEventClicked) },
92+
Timber::e
8893
)
8994
)
9095
}
9196

97+
private fun combineInPair(): BiFunction<Schedule, Boolean, Pair<Schedule, Boolean>> = BiFunction(::Pair)
98+
9299
private fun onEventClicked(event: Event) {
93100
analytics.trackItemSelected(ContentType.SCHEDULE_ITEM, event.id)
94101
navigate.toEventDetails(event.id)
@@ -115,27 +122,27 @@ class SchedulePageView @JvmOverloads constructor(
115122
}
116123
}
117124

118-
private fun hasTypefaceSpan(text: CharSequence?) = if (text !is Spanned) false else text.hasTypefaceSpan()
125+
private fun hasTypefaceSpan(text: CharSequence?) = (text as? Spanned)?.hasTypefaceSpan() ?: false
119126

120-
fun updateWith(schedule: Schedule, onEventClicked: (Event) -> Unit) {
121-
progressbar.visibility = View.GONE
127+
fun updateWith(schedule: Schedule, showRoom: Boolean, onEventClicked: (Event) -> Unit) {
128+
progressbar.isVisible = false
122129

123130
if (schedule.isEmpty) {
124-
viewpager.visibility = GONE
125-
tabstrip.visibility = GONE
126-
emptyView.visibility = VISIBLE
131+
viewpager.isVisible = false
132+
tabstrip.isVisible = false
133+
emptyView.isVisible = true
127134
return
128135
}
129136

130-
viewpager.visibility = VISIBLE
131-
tabstrip.visibility = VISIBLE
132-
emptyView.visibility = GONE
137+
viewpager.isVisible = true
138+
tabstrip.isVisible = true
139+
emptyView.isVisible = false
133140

134-
viewPagerAdapter.updateWith(schedule.pages, onEventClicked)
141+
viewPagerAdapter.updateWith(schedule.pages, showRoom, onEventClicked)
135142
if (viewpager.adapter == null) {
136143
viewpager.adapter = viewPagerAdapter
137144
}
138145

139-
progressbar.visibility = View.GONE
146+
progressbar.isVisible = false
140147
}
141148
}

0 commit comments

Comments
 (0)