diff --git a/modules/api/src/main/ModTimeline.scala b/modules/api/src/main/ModTimeline.scala index 3df79f37ef16..8bd184caee5c 100644 --- a/modules/api/src/main/ModTimeline.scala +++ b/modules/api/src/main/ModTimeline.scala @@ -26,8 +26,10 @@ case class ModTimeline( lazy val all: List[Event] = val reportEvents: List[Event] = reports.flatMap: r => r.done.map(ReportClose(r, _)).toList ::: reportAtoms(r) - val appealMsgs: List[Event] = appeal.so(_.msgs.toList) - val playBans: List[Event] = playbanRecord.so(_.bans.toList).toNel.map(PlayBans(_)).toList + val appealMsgs: List[Event] = appeal.so: a => + a.msgs.toList.takeWhile: msg => + a.mutedSince.fold(true)(mutedAt => msg.at.isBefore(mutedAt)) + val playBans: List[Event] = playbanRecord.so(_.bans.toList).toNel.map(PlayBans(_)).toList val concat: List[Event] = modLog ::: appealMsgs ::: notes ::: reportEvents ::: playBans ::: flaggedPublicLines // latest first diff --git a/modules/appeal/src/main/Appeal.scala b/modules/appeal/src/main/Appeal.scala index a97a7c5122f3..66a075d5a176 100644 --- a/modules/appeal/src/main/Appeal.scala +++ b/modules/appeal/src/main/Appeal.scala @@ -8,8 +8,8 @@ import lila.ui.Icon case class Appeal( @Key("_id") id: AppealId, - msgs: Vector[AppealMsg], - status: Appeal.Status, // from the moderators POV + msgs: Vector[AppealMsg], // chronological order, oldest first + status: Appeal.Status, // from the moderators POV createdAt: Instant, updatedAt: Instant, // date of first player message without a mod reply @@ -50,6 +50,9 @@ case class Appeal( def read = copy(status = Appeal.Status.Read) def toggleMute = if isMuted then read else copy(status = Appeal.Status.Muted) + lazy val mutedSince: Option[Instant] = isMuted.so: + msgs.reverse.takeWhile(m => !isByMod(m)).lastOption.map(_.at) + def isByMod(msg: AppealMsg) = msg.by != id object Appeal: