142 lines
4.9 KiB
Elm
142 lines
4.9 KiB
Elm
|
module Mastodon.Helper
|
||
|
exposing
|
||
|
( extractReblog
|
||
|
, aggregateNotifications
|
||
|
, addNotificationToAggregates
|
||
|
, notificationToAggregate
|
||
|
)
|
||
|
|
||
|
import List.Extra exposing (groupWhile)
|
||
|
import Mastodon.Model
|
||
|
exposing
|
||
|
( Notification
|
||
|
, NotificationAggregate
|
||
|
, Reblog(..)
|
||
|
, Status
|
||
|
)
|
||
|
|
||
|
|
||
|
extractReblog : Status -> Status
|
||
|
extractReblog status =
|
||
|
case status.reblog of
|
||
|
Just (Reblog reblog) ->
|
||
|
reblog
|
||
|
|
||
|
Nothing ->
|
||
|
status
|
||
|
|
||
|
|
||
|
notificationToAggregate : Notification -> NotificationAggregate
|
||
|
notificationToAggregate notification =
|
||
|
NotificationAggregate
|
||
|
notification.type_
|
||
|
notification.status
|
||
|
[ notification.account ]
|
||
|
notification.created_at
|
||
|
|
||
|
|
||
|
addNotificationToAggregates : Notification -> List NotificationAggregate -> List NotificationAggregate
|
||
|
addNotificationToAggregates notification aggregates =
|
||
|
let
|
||
|
addNewAccountToSameStatus : NotificationAggregate -> Notification -> NotificationAggregate
|
||
|
addNewAccountToSameStatus aggregate notification =
|
||
|
case ( aggregate.status, notification.status ) of
|
||
|
( Just aggregateStatus, Just notificationStatus ) ->
|
||
|
if aggregateStatus.id == notificationStatus.id then
|
||
|
{ aggregate | accounts = notification.account :: aggregate.accounts }
|
||
|
else
|
||
|
aggregate
|
||
|
|
||
|
( _, _ ) ->
|
||
|
aggregate
|
||
|
|
||
|
{-
|
||
|
Let's try to find an already existing aggregate, matching the notification
|
||
|
we are trying to add.
|
||
|
If we find any aggregate, we modify it inplace. If not, we return the
|
||
|
aggregates unmodified
|
||
|
-}
|
||
|
newAggregates =
|
||
|
aggregates
|
||
|
|> List.map
|
||
|
(\aggregate ->
|
||
|
case ( aggregate.type_, notification.type_ ) of
|
||
|
{-
|
||
|
Notification and aggregate are of the follow type.
|
||
|
Add the new following account.
|
||
|
-}
|
||
|
( "follow", "follow" ) ->
|
||
|
{ aggregate | accounts = notification.account :: aggregate.accounts }
|
||
|
|
||
|
{-
|
||
|
Notification is of type follow, but current aggregate
|
||
|
is of another type. Let's continue then.
|
||
|
-}
|
||
|
( _, "follow" ) ->
|
||
|
aggregate
|
||
|
|
||
|
{-
|
||
|
If both types are the same check if we should
|
||
|
add the new account.
|
||
|
-}
|
||
|
( aggregateType, notificationType ) ->
|
||
|
if aggregateType == notificationType then
|
||
|
addNewAccountToSameStatus aggregate notification
|
||
|
else
|
||
|
aggregate
|
||
|
)
|
||
|
in
|
||
|
{-
|
||
|
If we did no modification to the old aggregates it's
|
||
|
because we didn't found any match. So me have to create
|
||
|
a new aggregate
|
||
|
-}
|
||
|
if newAggregates == aggregates then
|
||
|
notificationToAggregate (notification) :: aggregates
|
||
|
else
|
||
|
newAggregates
|
||
|
|
||
|
|
||
|
aggregateNotifications : List Notification -> List NotificationAggregate
|
||
|
aggregateNotifications notifications =
|
||
|
let
|
||
|
only type_ notifications =
|
||
|
List.filter (\n -> n.type_ == type_) notifications
|
||
|
|
||
|
sameStatus n1 n2 =
|
||
|
case ( n1.status, n2.status ) of
|
||
|
( Just r1, Just r2 ) ->
|
||
|
r1.id == r2.id
|
||
|
|
||
|
_ ->
|
||
|
False
|
||
|
|
||
|
extractAggregate statusGroup =
|
||
|
let
|
||
|
accounts =
|
||
|
List.map .account statusGroup
|
||
|
in
|
||
|
case statusGroup of
|
||
|
notification :: _ ->
|
||
|
[ NotificationAggregate
|
||
|
notification.type_
|
||
|
notification.status
|
||
|
accounts
|
||
|
notification.created_at
|
||
|
]
|
||
|
|
||
|
[] ->
|
||
|
[]
|
||
|
|
||
|
aggregate statusGroups =
|
||
|
List.map extractAggregate statusGroups |> List.concat
|
||
|
in
|
||
|
[ notifications |> only "reblog" |> groupWhile sameStatus |> aggregate
|
||
|
, notifications |> only "favourite" |> groupWhile sameStatus |> aggregate
|
||
|
, notifications |> only "mention" |> groupWhile sameStatus |> aggregate
|
||
|
, notifications |> only "follow" |> groupWhile (\_ _ -> True) |> aggregate
|
||
|
]
|
||
|
|> List.concat
|
||
|
|> List.sortBy .created_at
|
||
|
|> List.reverse
|