fedi/src/Fedi/Activity.hs
2024-12-17 10:46:59 +02:00

135 lines
3.3 KiB
Haskell

module Fedi.Activity where
import Data.Aeson qualified as A
import Data.Text qualified as T
import Fedi.Types
import Fedi.Actor
import Data.Time (UTCTime)
data Activity
= Create
{ id :: ActivityUrl
, actor :: ActorId
, object :: Object
}
activityUrl :: Activity -> ActivityUrl
activityUrl = \case
create@Create{} -> create.id
type ActivityUrl = Url
data Object
= NoteObject Note
objectUrl :: Object -> Url
objectUrl = \case
NoteObject note -> note.id
data Note
= Note
{ id :: NoteId
, published :: UTCTime
, actor :: ActorId
, content :: T.Text
, name :: Maybe String
, url :: Maybe Url
, replies :: Collection Unordered Note
}
type NoteId = Url
type Followers = [Actor]
type Following = [Actor]
type Inbox = Collection Ordered Activity
type Outbox = Collection Unordered Activity
type OutboxPage = OrderedCollectionPage Activity
data Ordered
data Unordered
data OrderedCollectionPage a
= OrderedCollectionPage
{ id :: Url
, partOf :: Url
, orderedItems :: [a]
}
data Collection order a
= Collection
{ summary :: String
, items :: [a]
, first :: Maybe Url
, last :: Maybe Url
}
instance A.ToJSON Note where
toJSON note =
A.object $
[ "type" A..= ("Note" :: String)
, "id" A..= note.id
, "published" A..= note.published
, "attributedTo" A..= note.actor
, "content" A..= note.content
, "name" A..= note.name
, "replies" A..= note.replies
]
<> [ "name" A..= name | Just name <- [note.name] ]
<> [ "url" A..= url | Just url <- [note.url] ]
instance A.ToJSON Object where
toJSON = \case
NoteObject note -> A.toJSON note
instance A.ToJSON Activity where
toJSON = \case
create@Create{} ->
A.object
[ "@context" A..=
[ "https://www.w3.org/ns/activitystreams" :: String
]
, "type" A..= ("Create" :: String)
, "id" A..= create.id
, "actor" A..= create.actor
, "object" A..= create.object
]
instance A.ToJSON a => A.ToJSON (Collection Ordered a) where
toJSON collection =
A.object
[ "@context" A..=
[ "https://www.w3.org/ns/activitystreams" :: String
]
, "type" A..= ("OrderedCollection" :: String)
, "summary" A..= collection.summary
, "totalItems" A..= length collection.items
, "orderedItems" A..= collection.items
, "first" A..= collection.first
, "last" A..= collection.last
]
instance A.ToJSON a => A.ToJSON (Collection Unordered a) where
toJSON collection =
A.object
[ "@context" A..=
[ "https://www.w3.org/ns/activitystreams" :: String
]
, "type" A..= ("Collection" :: String)
, "summary" A..= collection.summary
, "totalItems" A..= length collection.items
, "items" A..= collection.items
, "first" A..= collection.first
, "last" A..= collection.last
]
instance A.ToJSON a => A.ToJSON (OrderedCollectionPage a) where
toJSON collection =
A.object
[ "@context" A..=
[ "https://www.w3.org/ns/activitystreams" :: String
]
, "type" A..= ("OrderedCollectionPage" :: String)
, "partOf" A..= collection.partOf
, "orderedItems" A..= collection.orderedItems
]