Skip to content

Commit

Permalink
Merge pull request #5179 from wikimedia/yirCard_design
Browse files Browse the repository at this point in the history
Year-in-review Feed card.
  • Loading branch information
cooltey authored Jan 16, 2025
2 parents 69b29d1 + a1586a3 commit 5f31853
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import android.app.Activity
import android.content.Context
import android.view.MenuItem
import android.view.View
import android.widget.Checkable
import android.widget.CompoundButton
import android.widget.TextView
import androidx.fragment.app.Fragment
import kotlinx.serialization.SerialName
Expand Down Expand Up @@ -37,11 +37,11 @@ class BreadCrumbLogEvent(
if (context is SettingsActivity) {
return
}
val viewReadableName = BreadCrumbViewUtil.getReadableNameForView(view)
val str = "$viewReadableName." + when (view) {
is Checkable -> if (!view.isChecked) "on" else "off"
else -> "click"
var viewReadableName = BreadCrumbViewUtil.getReadableNameForView(view)
if (view.tag is String && (view.tag as String).isNotEmpty()) {
viewReadableName += "." + view.tag as String
}
val str = "$viewReadableName." + if (view is CompoundButton) { if (!view.isChecked) "on" else "off" } else "click"
EventPlatformClient.submit(BreadCrumbLogEvent(BreadCrumbViewUtil.getReadableScreenName(context), str))
}

Expand All @@ -61,6 +61,11 @@ class BreadCrumbLogEvent(
"show" + invokeSource?.let { ".from." + it.value }.orEmpty()))
}

fun logImpression(context: Context, name: String) {
EventPlatformClient.submit(BreadCrumbLogEvent(BreadCrumbViewUtil.getReadableScreenName(context),
"impression.$name"))
}

fun logBackPress(context: Context) {
EventPlatformClient.submit(BreadCrumbLogEvent(BreadCrumbViewUtil.getReadableScreenName(context), "back"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Announcement(val id: String = "",
// for iOS versions, so these need to be serialized manually.
@SerialName("min_version") private val minVersion: JsonElement? = null,
@SerialName("max_version") private val maxVersion: JsonElement? = null,
val imageAspectRatio: Double? = null,
val border: Boolean? = null,
val beta: Boolean? = null,
val placement: String = PLACEMENT_FEED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,12 @@ open class AnnouncementCard(private val announcement: Announcement) : Card() {
fun hasBorder(): Boolean {
return announcement.border == true
}

fun getId(): String {
return announcement.id
}

fun aspectRatio(): Double {
return announcement.imageAspectRatio ?: 0.0
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import android.content.Context
import android.net.Uri
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import androidx.core.content.ContextCompat
import androidx.core.text.method.LinkMovementMethodCompat
import androidx.core.view.updateLayoutParams
import org.wikipedia.R
import org.wikipedia.analytics.eventplatform.BreadCrumbLogEvent
import org.wikipedia.databinding.ViewCardAnnouncementBinding
import org.wikipedia.feed.model.Card
import org.wikipedia.feed.onboarding.YIROnboardingCard
import org.wikipedia.feed.view.DefaultFeedCardView
import org.wikipedia.util.DimenUtil
import org.wikipedia.util.StringUtil
Expand Down Expand Up @@ -44,18 +47,32 @@ class AnnouncementCardView(context: Context) : DefaultFeedCardView<AnnouncementC
} else {
binding.viewAnnouncementCardButtonsContainer.visibility = VISIBLE
binding.viewAnnouncementActionPositive.text = it.actionTitle()
binding.viewAnnouncementActionPositive.tag = it.getId()
binding.viewAnnouncementDialogActionPositive.text = it.actionTitle()
binding.viewAnnouncementDialogActionPositive.tag = it.getId()
}
if (!it.negativeText().isNullOrEmpty()) {
binding.viewAnnouncementActionNegative.text = it.negativeText()
binding.viewAnnouncementActionNegative.tag = it.getId()
binding.viewAnnouncementDialogActionNegative.text = it.negativeText()
binding.viewAnnouncementDialogActionNegative.tag = it.getId()
} else {
binding.viewAnnouncementActionNegative.visibility = GONE
binding.viewAnnouncementDialogActionNegative.visibility = GONE
}
if (it.hasImage()) {
binding.viewAnnouncementHeaderImage.visibility = VISIBLE
binding.viewAnnouncementHeaderImage.loadImage(it.image())
if (it.aspectRatio() != 0.0) {
binding.viewAnnouncementHeaderImage.scaleType = ImageView.ScaleType.FIT_CENTER
binding.viewAnnouncementHeaderImage.post {
binding.viewAnnouncementHeaderImage.updateLayoutParams {
height = (binding.viewAnnouncementHeaderImage.width / it.aspectRatio()).toInt()
}
binding.viewAnnouncementHeaderImage.loadImage(it.image())
}
} else {
binding.viewAnnouncementHeaderImage.loadImage(it.image())
}
} else {
binding.viewAnnouncementHeaderImage.visibility = GONE
}
Expand Down Expand Up @@ -86,6 +103,10 @@ class AnnouncementCardView(context: Context) : DefaultFeedCardView<AnnouncementC
binding.viewAnnouncementContainer.radius = 0f
}
}

if (value is YIROnboardingCard) {
BreadCrumbLogEvent.logImpression(context, "YIR2024")
}
}

private fun onPositiveActionClick() {
Expand Down
4 changes: 1 addition & 3 deletions app/src/main/java/org/wikipedia/feed/model/CardType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,8 @@ enum class CardType constructor(private val code: Int,
return PlacesCardView(ctx)
}
},
// TODO: refactor this item when the new Modern Event Platform is finished.
ARTICLE_ANNOUNCEMENT(96) {
YEAR_IN_REVIEW_ANNOUNCEMENT(96) {
override fun newView(ctx: Context): FeedCardView<*> {
// This is not actually used, since this type of card will not be shown in the feed.
return AnnouncementCardView(ctx)
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class OnboardingClient : FeedClient {

private fun getCards(context: Context): List<Card> {
val cards = ArrayList<Card>()
val card: OnboardingCard
var card: OnboardingCard

// NOTE: When adding new onboarding cards, please add them to the *beginning* of the list.

Expand All @@ -41,6 +41,20 @@ class OnboardingClient : FeedClient {
if (card.shouldShow() && Prefs.exploreFeedVisitCount <= SHOW_CUSTOMIZE_ONBOARDING_CARD_COUNT) {
cards.add(card)
}

card = YIROnboardingCard(
Announcement(id = "yir2024Card",
text = context.getString(R.string.year_in_review_text),
imageUrl = "https://upload.wikimedia.org/wikipedia/commons/2/21/WYiR_Block_1.gif",
action = Announcement.Action(context.getString(R.string.year_in_review_action_positive), "https://wikimediafoundation.org/wikipedia-year-in-review-2024/"),
negativeText = context.getString(R.string.view_announcement_card_negative_action),
imageAspectRatio = 4.0 / 3.0
)
)
if (card.shouldShow()) {
cards.add(card)
}

return cards
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.wikipedia.feed.onboarding

import org.wikipedia.R
import org.wikipedia.WikipediaApp
import org.wikipedia.feed.announcement.Announcement
import org.wikipedia.feed.model.CardType
import org.wikipedia.util.GeoUtil
import java.time.LocalDate

class YIROnboardingCard(announcement: Announcement) : OnboardingCard(announcement) {

override fun type(): CardType {
return CardType.YEAR_IN_REVIEW_ANNOUNCEMENT
}

override fun shouldShow(): Boolean {
return super.shouldShow() &&
WikipediaApp.instance.appOrSystemLanguageCode == "en" &&
LocalDate.now() <= LocalDate.of(2025, 2, 28) &&
!excludedCountries.contains(GeoUtil.geoIPCountry)
}

override fun prefKey(): Int {
return R.string.preference_key_feed_yir_onboarding_card_enabled
}

private val excludedCountries = setOf("RU", "IR", "CN", "HK", "MO", "SA", "CU", "MM", "BY", "EG", "PS", "GN", "PK", "KH", "VN", "SD", "AE", "SY", "JO", "VE", "AF")
}
1 change: 1 addition & 0 deletions app/src/main/res/values/preference_keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
<string name="preference_key_feed_cards_lang_supported">feedCardsLangSupported</string>
<string name="preference_key_feed_cards_lang_disabled">feedCardsLangDisabled</string>
<string name="preference_key_feed_customize_onboarding_card_enabled">feedCustomizeOnboardingCardEnabled</string>
<string name="preference_key_feed_yir_onboarding_card_enabled">feedYirOnboardingCardEnabled</string>
<string name="preference_key_add_articles">addArticles</string>
<string name="preference_key_add_reading_lists">addReadingLists</string>
<string name="preference_key_delete_reading_lists">deleteReadingLists</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings_no_translate.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,7 @@
<string name="diff_link_wikitext">{{{diffLink}}}</string>
<string name="wikiText_replace_url">[[%1$s|%2$s]]</string>

<string name="year_in_review_action_positive">Take me there</string>
<string name="year_in_review_text"><![CDATA[<strong>Wikipedia 2024 Year in Review</strong><br/><br/>Wikipedia is the largest knowledge resource ever assembled in the history of the world, and it’s freely available to everyone everywhere. Here’s a review of 2024 through the lens of Wikipedia.]]></string>

</resources>
4 changes: 4 additions & 0 deletions app/src/main/res/xml/developer_preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,10 @@
android:title="Donation results"
android:dialogMessage="Example: [{&quot;dateTime&quot;:&quot;2024-10-22T00:00:00.000&quot;}]"/>

<org.wikipedia.settings.SwitchPreferenceMultiLine
android:key="@string/preference_key_feed_yir_onboarding_card_enabled"
android:title="Year-in-review Feed Card" />

</PreferenceCategory>

</PreferenceScreen>

0 comments on commit 5f31853

Please sign in to comment.