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

Commit eaa7a16

Browse files
authored
Merge branch 'develop' into fab-hearth-avd
2 parents ebba337 + 4e4d009 commit eaa7a16

57 files changed

Lines changed: 722 additions & 482 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class DebugActivity : AppCompatActivity() {
7575
experienceLevel = Option(ExperienceLevel.ADVANCED),
7676
speakers = createTalkSpeakers(),
7777
type = Event.Type.TALK,
78-
favorited = true,
78+
favorite = true,
7979
description = Option.empty(),
8080
track = Option(createTrack()),
8181
timeZone = DateTimeZone.forID("Europe/Rome")

app/src/main/java/net/squanchy/analytics/Analytics.kt

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@ class Analytics internal constructor(
4646
}
4747

4848
private fun trackItemSelectedOnFirebaseAnalytics(contentType: ContentType, itemId: String) {
49-
val params = Bundle()
50-
params.putString(FirebaseAnalytics.Param.CONTENT_TYPE, contentType.rawContentType)
51-
params.putString(FirebaseAnalytics.Param.ITEM_ID, itemId)
49+
val params = Bundle().apply {
50+
putString(FirebaseAnalytics.Param.CONTENT_TYPE, contentType.rawContentType)
51+
putString(FirebaseAnalytics.Param.ITEM_ID, itemId)
52+
}
5253
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, params)
5354
}
5455

@@ -81,12 +82,26 @@ class Analytics internal constructor(
8182

8283
fun trackNotificationsEnabled() {
8384
firebaseAnalytics.setUserProperty("notifications_status", "enabled")
85+
firebaseAnalytics.logEvent("notifications_status_changed", flagEnabled(TRUE))
8486
}
8587

8688
fun trackNotificationsDisabled() {
8789
firebaseAnalytics.setUserProperty("notifications_status", "disabled")
90+
firebaseAnalytics.logEvent("notifications_status_changed", flagEnabled(FALSE))
91+
}
92+
93+
fun trackFavoritesInScheduleEnabled() {
94+
firebaseAnalytics.setUserProperty("favorites_in_schedule", "enable")
95+
firebaseAnalytics.logEvent("favorites_in_schedule_changed", flagEnabled(TRUE))
96+
}
97+
98+
fun trackFavoritesInScheduleDisabled() {
99+
firebaseAnalytics.setUserProperty("favorites_in_schedule", "disabled")
100+
firebaseAnalytics.logEvent("favorites_in_schedule_changed", flagEnabled(FALSE))
88101
}
89102

103+
private fun flagEnabled(value: String) = Bundle().apply { putString("enabled", value) }
104+
90105
fun trackUserNotLoggedIn() {
91106
setUserLoginProperty(LoginStatus.NOT_LOGGED_IN)
92107
}
@@ -105,9 +120,15 @@ class Analytics internal constructor(
105120
}
106121

107122
fun trackWifiConfigurationEvent(isSuccess: Boolean, wifiConfigOrigin: WifiConfigOrigin) {
108-
val params = Bundle()
109-
params.putString("origin", wifiConfigOrigin.rawOrigin)
110-
params.putBoolean("success", isSuccess)
123+
val params = Bundle().apply {
124+
putString("origin", wifiConfigOrigin.rawOrigin)
125+
putBoolean("success", isSuccess)
126+
}
111127
firebaseAnalytics.logEvent("wifi_config", params)
112128
}
129+
130+
companion object {
131+
private const val TRUE = "true"
132+
private const val FALSE = "false"
133+
}
113134
}

app/src/main/java/net/squanchy/eventdetails/EventDetailsService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ internal class EventDetailsService(
3333
}
3434

3535
private fun toggleFavoriteOn(event: Event): Completable {
36-
return if (event.favorited) {
36+
return if (event.favorite) {
3737
removeFavorite(event.id)
3838
} else {
3939
favorite(event.id)

app/src/main/java/net/squanchy/eventdetails/widget/EventDetailsCoordinatorLayout.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package net.squanchy.eventdetails.widget
33
import android.content.Context
44
import android.support.design.widget.CoordinatorLayout
55
import android.util.AttributeSet
6-
import android.view.View
6+
import androidx.view.isVisible
77
import kotlinx.android.synthetic.main.activity_event_details.view.*
88
import net.squanchy.R
99
import net.squanchy.schedule.domain.view.Event
@@ -20,19 +20,19 @@ class EventDetailsCoordinatorLayout @JvmOverloads constructor(
2020
eventDetailsHeaderLayout.updateWith(event, listener)
2121
eventDetailsLayout.updateWith(event)
2222

23-
if (canBeFavorited(event)) {
23+
if (event.canBeFavorited) {
2424
// Updates the FAB image state to trigger an AVD animation.
25-
val stateSet = intArrayOf(android.R.attr.state_checked * if (event.favorited) 1 else -1)
25+
val stateSet = intArrayOf(android.R.attr.state_checked * if (event.favorite) 1 else -1)
2626
favoriteFab.setImageState(stateSet, true)
27-
2827
favoriteFab.setOnClickListener { listener.onFavoriteClick() }
29-
favoriteFab.visibility = View.VISIBLE
28+
favoriteFab.isVisible = true
3029
} else {
31-
favoriteFab.visibility = View.GONE
30+
favoriteFab.isVisible = false
3231
}
3332
}
3433

35-
private fun canBeFavorited(event: Event) = event.type === Type.TALK || event.type === Type.KEYNOTE
34+
private val Event.canBeFavorited
35+
get() = type == Type.TALK || type == Type.KEYNOTE || type == Type.WORKSHOP
3636

3737
internal interface OnEventDetailsClickListener : OnFavoriteClickListener, SpeakerView.OnSpeakerClickListener
3838

app/src/main/java/net/squanchy/eventdetails/widget/EventDetailsHeaderLayout.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ import android.content.Context
44
import android.support.design.widget.AppBarLayout
55
import android.util.AttributeSet
66
import android.view.View
7-
import kotlinx.android.synthetic.main.activity_event_details.view.titleTextView
8-
import kotlinx.android.synthetic.main.activity_event_details.view.speakerDetailsView
7+
import androidx.view.isVisible
8+
import kotlinx.android.synthetic.main.activity_event_details.view.*
99
import net.squanchy.schedule.domain.view.Event
1010
import net.squanchy.support.widget.SpeakerView
1111

1212
class EventDetailsHeaderLayout(context: Context, attrs: AttributeSet) : AppBarLayout(context, attrs) {
1313

1414
internal fun updateWith(event: Event, listener: SpeakerView.OnSpeakerClickListener) {
1515
titleTextView.text = event.title
16-
titleTextView.visibility = View.VISIBLE
16+
titleTextView.isVisible = true
1717

1818
speakerDetailsView.visibility = if (event.speakers.isEmpty()) View.GONE else View.VISIBLE
1919
speakerDetailsView.updateWith(event.speakers, listener)

app/src/main/java/net/squanchy/eventdetails/widget/EventDetailsLayout.kt

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ import android.content.Context
44
import android.content.res.Resources
55
import android.support.annotation.AttrRes
66
import android.support.annotation.ColorInt
7+
import android.support.constraint.ConstraintLayout
78
import android.support.v4.content.ContextCompat
89
import android.text.SpannableStringBuilder
910
import android.text.Spanned
1011
import android.text.style.ForegroundColorSpan
1112
import android.util.AttributeSet
1213
import android.util.TypedValue
1314
import android.view.View
14-
import android.widget.LinearLayout
15+
import androidx.view.isVisible
1516
import arrow.core.Option
1617
import kotlinx.android.synthetic.main.merge_event_details_layout.view.*
1718
import net.squanchy.R
@@ -20,81 +21,76 @@ import net.squanchy.schedule.domain.view.Event
2021
import net.squanchy.schedule.domain.view.Place
2122
import net.squanchy.support.lang.getOrThrow
2223
import net.squanchy.support.text.parseHtml
24+
import org.joda.time.DateTimeZone
25+
import org.joda.time.LocalDateTime
2326
import org.joda.time.format.DateTimeFormat
2427

25-
// TODO flatten this layout as a ConstraintLayout
2628
class EventDetailsLayout @JvmOverloads constructor(
2729
context: Context,
2830
attrs: AttributeSet?,
2931
defStyle: Int = 0
30-
) : LinearLayout(context, attrs, defStyle) {
32+
) : ConstraintLayout(context, attrs, defStyle) {
3133

32-
init {
33-
super.setOrientation(LinearLayout.VERTICAL)
34-
}
35-
36-
override fun setOrientation(orientation: Int) {
37-
throw UnsupportedOperationException("Changing orientation is not supported for EventDetailsLayout")
38-
}
34+
private val dateTimeFormatter = DateTimeFormat.forPattern(WHEN_DATE_TIME_FORMAT)
3935

4036
override fun onFinishInflate() {
4137
super.onFinishInflate()
4238

43-
View.inflate(context, R.layout.merge_event_details_layout, this)
39+
inflate(context, R.layout.merge_event_details_layout, this)
4440
}
4541

4642
fun updateWith(event: Event) {
47-
updateWhen(event)
48-
updateWhere(event)
43+
updateWhen(event.startTime, event.timeZone)
44+
updateWhere(event.place)
4945
updateLevel(event.experienceLevel)
5046
updateDescription(event.description)
5147
}
5248

53-
private fun updateWhen(event: Event) {
54-
val formatter = DateTimeFormat.forPattern(WHEN_DATE_TIME_FORMAT).withZone(event.timeZone)
55-
whenTextView.text = formatter.print(event.startTime.toDateTime())
56-
whenContainer.visibility = View.VISIBLE
49+
private fun updateWhen(startTime: LocalDateTime, timeZone: DateTimeZone) {
50+
val formatter = dateTimeFormatter.withZone(timeZone)
51+
whenValue.text = formatter.print(startTime.toDateTime(timeZone))
52+
whenGroup.isVisible = true
5753
}
5854

59-
private fun updateWhere(event: Event) {
60-
if (event.place.isDefined()) {
61-
whereContainer.visibility = View.VISIBLE
62-
whereTextView.text = placeTextFrom(event.place.getOrThrow())
55+
private fun updateWhere(place: Option<Place>) {
56+
if (place.isDefined()) {
57+
whereGroup.isVisible = true
58+
whereValue.text = place.getOrThrow().toPlaceLabel()
6359
} else {
64-
whereContainer.visibility = View.GONE
60+
whereGroup.isVisible = false
6561
}
6662
}
6763

68-
private fun placeTextFrom(place: Place): CharSequence {
69-
val builder = SpannableStringBuilder(place.name)
70-
if (place.floor.isDefined()) {
71-
val floorLabel = place.floor.getOrThrow()
64+
private fun Place.toPlaceLabel(): CharSequence {
65+
val builder = SpannableStringBuilder(name)
66+
if (floor.isDefined()) {
67+
val floorLabel = floor.getOrThrow()
7268
builder.append(" ")
7369
.append(floorLabel)
7470
.setSpan(
75-
createColorSpan(whereTextView, android.R.attr.textColorSecondary),
76-
builder.length - floorLabel.length,
77-
builder.length,
78-
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
71+
createColorSpan(whereValue, android.R.attr.textColorSecondary),
72+
builder.length - floorLabel.length,
73+
builder.length,
74+
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
7975
)
8076
}
8177
return builder
8278
}
8379

8480
private fun updateLevel(level: Option<ExperienceLevel>) {
8581
if (level.isDefined()) {
86-
levelContainer.visibility = View.VISIBLE
82+
levelGroup.isVisible = true
8783

8884
val experienceLevel = level.getOrThrow()
89-
levelTextView.setText(experienceLevel.labelStringResId)
85+
levelValue.setText(experienceLevel.labelStringResId)
9086
tintCompoundDrawableEnd(experienceLevel)
9187
} else {
92-
levelContainer.visibility = View.GONE
88+
levelGroup.isVisible = false
9389
}
9490
}
9591

9692
private fun tintCompoundDrawableEnd(experienceLevel: ExperienceLevel) {
97-
val compoundDrawables = levelTextView.compoundDrawablesRelative
93+
val compoundDrawables = levelValue.compoundDrawablesRelative
9894
val endCompoundDrawable = compoundDrawables[2]
9995
endCompoundDrawable?.setTint(ContextCompat.getColor(context, experienceLevel.colorResId))
10096
}
@@ -113,12 +109,10 @@ class EventDetailsLayout @JvmOverloads constructor(
113109

114110
private fun updateDescription(description: Option<String>) {
115111
if (description.isDefined()) {
116-
descriptionHeader.visibility = View.VISIBLE
117-
descriptionTextView.visibility = View.VISIBLE
118-
descriptionTextView.text = parseHtml(description.getOrThrow())
112+
descriptionGroup.isVisible = true
113+
descriptionValue.text = description.getOrThrow().parseHtml()
119114
} else {
120-
descriptionHeader.visibility = View.GONE
121-
descriptionTextView.visibility = View.GONE
115+
descriptionGroup.isVisible = false
122116
}
123117
}
124118

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

Lines changed: 3 additions & 0 deletions
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

1314
@ActivityLifecycle
1415
@Component(modules = [FavoritesModule::class, NavigationModule::class], dependencies = [ApplicationComponent::class])
@@ -19,6 +20,8 @@ internal interface FavoritesComponent {
1920
fun navigator(): Navigator
2021

2122
fun analytics(): Analytics
23+
24+
fun featureFlags(): FeatureFlags
2225
}
2326

2427
internal fun favoritesComponent(activity: AppCompatActivity): FavoritesComponent {

0 commit comments

Comments
 (0)