common/app/model/pressedContent.scala (195 lines of code) (raw):
package model.pressed
import com.gu.commercial.branding.Branding
import com.gu.facia.api.utils.BoostLevel
import com.gu.facia.api.{models => fapi}
import common.Edition
import model.{ContentFormat, Pillar}
import views.support.ContentOldAgeDescriber
sealed trait PressedContent {
def properties: PressedProperties
def header: PressedCardHeader
def card: PressedCard
def discussion: PressedDiscussionSettings
def display: PressedDisplaySettings
def maybePillar: Option[Pillar] = Pillar(properties.maybeContent)
lazy val participatesInDeduplication: Boolean = properties.embedType.isEmpty
def format: ContentFormat
def withoutTrailText: PressedContent
def withoutCommercial: PressedContent
def withBoostLevel(level: Option[BoostLevel]): PressedContent
def withCard(card: PressedCard): PressedContent
protected def propertiesWithoutCommercial(properties: PressedProperties): PressedProperties =
properties.copy(
maybeContent = properties.maybeContent.map(storyWithoutCommercial),
)
private def storyWithoutCommercial(story: PressedStory): PressedStory =
story.copy(
tags = story.tags.copy(
tags = story.tags.tags.map(tag =>
tag.copy(
properties = tag.properties.copy(commercial = None),
),
),
),
)
def isPaidFor: Boolean = properties.isPaidFor
def branding(edition: Edition): Option[Branding] =
for {
brandings <- properties.editionBrandings
editionBranding <- brandings find (_.edition == edition)
branding <- editionBranding.branding
} yield branding
def isActionCard: Boolean =
properties.maybeContent.exists { c =>
c.tags.tags.exists(_.id == "tone/callout")
}
// For DCR
def ageWarning: Option[String] = {
properties.maybeContent
.filter(c => c.tags.tags.exists(_.id == "tone/news"))
.map(ContentOldAgeDescriber.apply)
.filterNot(_ == "")
}
}
object PressedContent {
def make(content: fapi.FaciaContent, suppressImages: Boolean): PressedContent =
content match {
case curatedContent: fapi.CuratedContent => CuratedContent.make(curatedContent, suppressImages)
case supportingCuratedContent: fapi.SupportingCuratedContent =>
SupportingCuratedContent.make(supportingCuratedContent)
case linkSnap: fapi.LinkSnap => LinkSnap.make(linkSnap)
case latestSnap: fapi.LatestSnap => LatestSnap.make(latestSnap)
}
}
final case class CuratedContent(
override val properties: PressedProperties,
override val header: PressedCardHeader,
override val card: PressedCard,
override val discussion: PressedDiscussionSettings,
override val display: PressedDisplaySettings,
override val format: ContentFormat,
enriched: Option[
EnrichedContent,
], // This is currently an option, as we introduce the new field. It can then become a value type.
supportingContent: List[PressedContent],
cardStyle: CardStyle,
) extends PressedContent {
override def withoutTrailText: PressedContent = copy(card = card.withoutTrailText)
override def withoutCommercial: PressedContent = copy(
properties = propertiesWithoutCommercial(properties),
supportingContent = supportingContent.map(_.withoutCommercial),
)
override def withBoostLevel(level: Option[BoostLevel]): PressedContent = copy(
display = display.copy(boostLevel = level),
)
override def withCard(card: PressedCard): PressedContent = copy(
card = card,
)
}
object CuratedContent {
def make(content: fapi.CuratedContent, suppressImages: Boolean): CuratedContent = {
CuratedContent(
properties = PressedProperties.make(content),
header = PressedCardHeader.make(content),
card = PressedCard.make(content),
discussion = PressedDiscussionSettings.make(content),
display = PressedDisplaySettings.make(content, Some(suppressImages)),
format = ContentFormat.fromFapiContentFormat(content.format),
supportingContent = content.supportingContent.map((sc) => PressedContent.make(sc, false)),
cardStyle = CardStyle.make(content.cardStyle),
enriched = Some(EnrichedContent.empty),
)
}
}
final case class SupportingCuratedContent(
override val properties: PressedProperties,
override val header: PressedCardHeader,
override val card: PressedCard,
override val discussion: PressedDiscussionSettings,
override val display: PressedDisplaySettings,
override val format: ContentFormat,
cardStyle: CardStyle,
) extends PressedContent {
override def withoutTrailText: PressedContent = copy(card = card.withoutTrailText)
override def withoutCommercial: PressedContent = copy(properties = propertiesWithoutCommercial(properties))
override def withBoostLevel(level: Option[BoostLevel]): PressedContent = copy(
display = display.copy(boostLevel = level),
)
override def withCard(card: PressedCard): PressedContent = copy(
card = card,
)
}
object SupportingCuratedContent {
def make(content: fapi.SupportingCuratedContent): SupportingCuratedContent = {
SupportingCuratedContent(
properties = PressedProperties.make(content),
header = PressedCardHeader.make(content),
card = PressedCard.make(content),
discussion = PressedDiscussionSettings.make(content),
display = PressedDisplaySettings.make(content, None),
format = ContentFormat.fromFapiContentFormat(content.format),
cardStyle = CardStyle.make(content.cardStyle),
)
}
}
final case class LinkSnap(
override val properties: PressedProperties,
override val header: PressedCardHeader,
override val card: PressedCard,
override val discussion: PressedDiscussionSettings,
override val display: PressedDisplaySettings,
override val format: ContentFormat,
enriched: Option[
EnrichedContent,
], // This is currently an option, as we introduce the new field. It can then become a value type.
) extends PressedContent {
override def withoutTrailText: PressedContent = copy(card = card.withoutTrailText)
override def withoutCommercial: PressedContent = copy(properties = propertiesWithoutCommercial(properties))
override def withBoostLevel(level: Option[BoostLevel]): PressedContent = copy(
display = display.copy(boostLevel = level),
)
override def withCard(card: PressedCard): PressedContent = copy(
card = card,
)
}
object LinkSnap {
def make(content: fapi.LinkSnap): LinkSnap = {
LinkSnap(
properties = PressedProperties.make(content),
header = PressedCardHeader.make(content),
card = PressedCard.make(content),
discussion = PressedDiscussionSettings.make(content),
display = PressedDisplaySettings.make(content, None),
enriched = Some(EnrichedContent.empty),
format = ContentFormat.defaultContentFormat,
)
}
}
final case class LatestSnap(
override val properties: PressedProperties,
override val header: PressedCardHeader,
override val card: PressedCard,
override val discussion: PressedDiscussionSettings,
override val display: PressedDisplaySettings,
override val format: ContentFormat,
) extends PressedContent {
override def withoutTrailText: PressedContent = copy(card = card.withoutTrailText)
override def withoutCommercial: PressedContent = copy(properties = propertiesWithoutCommercial(properties))
override def withBoostLevel(level: Option[BoostLevel]): PressedContent = copy(
display = display.copy(boostLevel = level),
)
override def withCard(card: PressedCard): PressedContent = copy(
card = card,
)
}
object LatestSnap {
def make(content: fapi.LatestSnap): LatestSnap = {
LatestSnap(
properties = PressedProperties.make(content),
header = PressedCardHeader.make(content),
card = PressedCard.make(content),
discussion = PressedDiscussionSettings.make(content),
display = PressedDisplaySettings.make(content, None),
format = ContentFormat.fromFapiContentFormat(content.format),
)
}
}