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 { id :: Url , 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 ] , "id" A..= collection.id , "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 ] , "id" A..= collection.id , "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 ]