Implement C2S unfollowing, using Undo{Follow}
This commit is contained in:
parent
6a4975a52c
commit
bbe6f159d0
17 changed files with 384 additions and 53 deletions
|
@ -64,6 +64,7 @@
|
||||||
/s/#ShrIdent/outbox/#OutboxItemKeyHashid SharerOutboxItemR GET
|
/s/#ShrIdent/outbox/#OutboxItemKeyHashid SharerOutboxItemR GET
|
||||||
/s/#ShrIdent/followers SharerFollowersR GET
|
/s/#ShrIdent/followers SharerFollowersR GET
|
||||||
/s/#ShrIdent/follow SharerFollowR POST
|
/s/#ShrIdent/follow SharerFollowR POST
|
||||||
|
/s/#ShrIdent/unfollow SharerUnfollowR POST
|
||||||
|
|
||||||
/p PeopleR GET
|
/p PeopleR GET
|
||||||
|
|
||||||
|
@ -93,6 +94,7 @@
|
||||||
/s/#ShrIdent/r/#RpIdent/followers RepoFollowersR GET
|
/s/#ShrIdent/r/#RpIdent/followers RepoFollowersR GET
|
||||||
/s/#ShrIdent/r/#RpIdent/edit RepoEditR GET
|
/s/#ShrIdent/r/#RpIdent/edit RepoEditR GET
|
||||||
/s/#ShrIdent/r/#RpIdent/follow RepoFollowR POST
|
/s/#ShrIdent/r/#RpIdent/follow RepoFollowR POST
|
||||||
|
/s/#ShrIdent/r/#RpIdent/unfollow RepoUnfollowR POST
|
||||||
/s/#ShrIdent/r/#RpIdent/s/+Texts RepoSourceR GET
|
/s/#ShrIdent/r/#RpIdent/s/+Texts RepoSourceR GET
|
||||||
/s/#ShrIdent/r/#RpIdent/c RepoHeadChangesR GET
|
/s/#ShrIdent/r/#RpIdent/c RepoHeadChangesR GET
|
||||||
/s/#ShrIdent/r/#RpIdent/b/#Text RepoBranchR GET
|
/s/#ShrIdent/r/#RpIdent/b/#Text RepoBranchR GET
|
||||||
|
@ -117,6 +119,7 @@
|
||||||
/s/#ShrIdent/p/#PrjIdent/followers ProjectFollowersR GET
|
/s/#ShrIdent/p/#PrjIdent/followers ProjectFollowersR GET
|
||||||
/s/#ShrIdent/p/#PrjIdent/edit ProjectEditR GET
|
/s/#ShrIdent/p/#PrjIdent/edit ProjectEditR GET
|
||||||
/s/#ShrIdent/p/#PrjIdent/follow ProjectFollowR POST
|
/s/#ShrIdent/p/#PrjIdent/follow ProjectFollowR POST
|
||||||
|
/s/#ShrIdent/p/#PrjIdent/unfollow ProjectUnfollowR POST
|
||||||
/s/#ShrIdent/p/#PrjIdent/d ProjectDevsR GET POST
|
/s/#ShrIdent/p/#PrjIdent/d ProjectDevsR GET POST
|
||||||
/s/#ShrIdent/p/#PrjIdent/d/!new ProjectDevNewR GET
|
/s/#ShrIdent/p/#PrjIdent/d/!new ProjectDevNewR GET
|
||||||
/s/#ShrIdent/p/#PrjIdent/d/#ShrIdent ProjectDevR GET DELETE POST
|
/s/#ShrIdent/p/#PrjIdent/d/#ShrIdent ProjectDevR GET DELETE POST
|
||||||
|
@ -153,6 +156,7 @@
|
||||||
/s/#ShrIdent/p/#PrjIdent/t/#Int/assign TicketAssignR GET POST
|
/s/#ShrIdent/p/#PrjIdent/t/#Int/assign TicketAssignR GET POST
|
||||||
/s/#ShrIdent/p/#PrjIdent/t/#Int/unassign TicketUnassignR POST
|
/s/#ShrIdent/p/#PrjIdent/t/#Int/unassign TicketUnassignR POST
|
||||||
/s/#ShrIdent/p/#PrjIdent/t/#Int/follow TicketFollowR POST
|
/s/#ShrIdent/p/#PrjIdent/t/#Int/follow TicketFollowR POST
|
||||||
|
/s/#ShrIdent/p/#PrjIdent/t/#Int/unfollow TicketUnfollowR POST
|
||||||
/s/#ShrIdent/p/#PrjIdent/tcr ClaimRequestsProjectR GET
|
/s/#ShrIdent/p/#PrjIdent/tcr ClaimRequestsProjectR GET
|
||||||
/s/#ShrIdent/p/#PrjIdent/t/#Int/cr ClaimRequestsTicketR GET POST
|
/s/#ShrIdent/p/#PrjIdent/t/#Int/cr ClaimRequestsTicketR GET POST
|
||||||
/s/#ShrIdent/p/#PrjIdent/t/#Int/cr/new ClaimRequestNewR GET
|
/s/#ShrIdent/p/#PrjIdent/t/#Int/cr/new ClaimRequestNewR GET
|
||||||
|
|
|
@ -17,6 +17,7 @@ module Vervis.API
|
||||||
( createNoteC
|
( createNoteC
|
||||||
, followC
|
, followC
|
||||||
, offerTicketC
|
, offerTicketC
|
||||||
|
, undoC
|
||||||
, pushCommitsC
|
, pushCommitsC
|
||||||
, getFollowersCollection
|
, getFollowersCollection
|
||||||
)
|
)
|
||||||
|
@ -99,8 +100,8 @@ import Database.Persist.Local
|
||||||
import Yesod.Persist.Local
|
import Yesod.Persist.Local
|
||||||
|
|
||||||
import Vervis.ActivityPub
|
import Vervis.ActivityPub
|
||||||
|
import Vervis.ActivityPub.Recipient
|
||||||
import Vervis.ActorKey
|
import Vervis.ActorKey
|
||||||
import Vervis.API.Recipient
|
|
||||||
import Vervis.FedURI
|
import Vervis.FedURI
|
||||||
import Vervis.Foundation
|
import Vervis.Foundation
|
||||||
import Vervis.Model
|
import Vervis.Model
|
||||||
|
@ -883,6 +884,85 @@ offerTicketC shrUser summary audience offer@(Offer ticket uTarget) = runExceptT
|
||||||
insert_ $ InboxItemLocal ibid obiid ibiid
|
insert_ $ InboxItemLocal ibid obiid ibiid
|
||||||
return remotes
|
return remotes
|
||||||
|
|
||||||
|
undoC
|
||||||
|
:: ShrIdent
|
||||||
|
-> TextHtml
|
||||||
|
-> Audience URIMode
|
||||||
|
-> Undo URIMode
|
||||||
|
-> Handler (Either Text OutboxItemId)
|
||||||
|
undoC shrUser summary audience undo@(Undo luObject) = runExceptT $ do
|
||||||
|
(localRecips, remoteRecips) <- do
|
||||||
|
mrecips <- parseAudience audience
|
||||||
|
fromMaybeE mrecips "Follow with no recipients"
|
||||||
|
federation <- asksSite $ appFederation . appSettings
|
||||||
|
unless (federation || null remoteRecips) $
|
||||||
|
throwE "Federation disabled, but remote recipients specified"
|
||||||
|
route <-
|
||||||
|
fromMaybeE
|
||||||
|
(decodeRouteLocal luObject)
|
||||||
|
"Undo object isn't a valid route"
|
||||||
|
obiidOriginal <- case route of
|
||||||
|
SharerOutboxItemR shr obikhid
|
||||||
|
| shr == shrUser ->
|
||||||
|
decodeKeyHashidE obikhid "Undo object invalid obikhid"
|
||||||
|
_ -> throwE "Undo object isn't actor's outbox item route"
|
||||||
|
let dont = Authority "dont-do.any-forwarding" Nothing
|
||||||
|
(obiidUndo, doc, remotesHttp) <- runDBExcept $ do
|
||||||
|
Entity _pidAuthor personAuthor <- lift $ getAuthor shrUser
|
||||||
|
obi <- do
|
||||||
|
mobi <- lift $ get obiidOriginal
|
||||||
|
fromMaybeE mobi "Undo object obiid doesn't exist in DB"
|
||||||
|
unless (outboxItemOutbox obi == personOutbox personAuthor) $
|
||||||
|
throwE "Undo object obiid belongs to different actor"
|
||||||
|
lift $ do
|
||||||
|
deleteFollow obiidOriginal
|
||||||
|
deleteFollowRemote obiidOriginal
|
||||||
|
deleteFollowRemoteRequest obiidOriginal
|
||||||
|
let obidAuthor = personOutbox personAuthor
|
||||||
|
(obiidUndo, doc, luUndo) <- insertUndoToOutbox obidAuthor
|
||||||
|
let ibidAuthor = personInbox personAuthor
|
||||||
|
fsidAuthor = personFollowers personAuthor
|
||||||
|
knownRemotes <- deliverLocal shrUser ibidAuthor fsidAuthor obiidUndo localRecips
|
||||||
|
remotesHttp <- deliverRemoteDB' dont obiidUndo remoteRecips knownRemotes
|
||||||
|
return (obiidUndo, doc, remotesHttp)
|
||||||
|
lift $ forkWorker "undoC: Outbox POST handler: async HTTP delivery" $ deliverRemoteHttp dont obiidUndo doc remotesHttp
|
||||||
|
return obiidUndo
|
||||||
|
where
|
||||||
|
getAuthor shr = do
|
||||||
|
sid <- getKeyBy404 $ UniqueSharer shr
|
||||||
|
getBy404 $ UniquePersonIdent sid
|
||||||
|
deleteFollow obiid = do
|
||||||
|
mfid <- getKeyBy $ UniqueFollowFollow obiid
|
||||||
|
traverse_ delete mfid
|
||||||
|
deleteFollowRemote obiid = do
|
||||||
|
mfrid <- getKeyBy $ UniqueFollowRemoteFollow obiid
|
||||||
|
traverse_ delete mfrid
|
||||||
|
deleteFollowRemoteRequest obiid = do
|
||||||
|
mfrrid <- getKeyBy $ UniqueFollowRemoteRequestActivity obiid
|
||||||
|
traverse_ delete mfrrid
|
||||||
|
insertUndoToOutbox obid = do
|
||||||
|
hLocal <- asksSite siteInstanceHost
|
||||||
|
encodeRouteLocal <- getEncodeRouteLocal
|
||||||
|
let activity mluAct = Doc hLocal Activity
|
||||||
|
{ activityId = mluAct
|
||||||
|
, activityActor = encodeRouteLocal $ SharerR shrUser
|
||||||
|
, activitySummary = Just summary
|
||||||
|
, activityAudience = audience
|
||||||
|
, activitySpecific = UndoActivity undo
|
||||||
|
}
|
||||||
|
now <- liftIO getCurrentTime
|
||||||
|
obiid <- insert OutboxItem
|
||||||
|
{ outboxItemOutbox = obid
|
||||||
|
, outboxItemActivity =
|
||||||
|
persistJSONObjectFromDoc $ activity Nothing
|
||||||
|
, outboxItemPublished = now
|
||||||
|
}
|
||||||
|
obikhid <- encodeKeyHashid obiid
|
||||||
|
let luAct = encodeRouteLocal $ SharerOutboxItemR shrUser obikhid
|
||||||
|
doc = activity $ Just luAct
|
||||||
|
update obiid [OutboxItemActivity =. persistJSONObjectFromDoc doc]
|
||||||
|
return (obiid, doc, luAct)
|
||||||
|
|
||||||
pushCommitsC
|
pushCommitsC
|
||||||
:: (Entity Person, Sharer)
|
:: (Entity Person, Sharer)
|
||||||
-> Html
|
-> Html
|
||||||
|
|
|
@ -20,7 +20,6 @@ module Vervis.ActivityPub
|
||||||
, parseParent
|
, parseParent
|
||||||
, runDBExcept
|
, runDBExcept
|
||||||
, getLocalParentMessageId
|
, getLocalParentMessageId
|
||||||
, concatRecipients
|
|
||||||
, getPersonOrGroupId
|
, getPersonOrGroupId
|
||||||
, getTicketTeam
|
, getTicketTeam
|
||||||
, getProjectTeam
|
, getProjectTeam
|
||||||
|
@ -41,6 +40,7 @@ module Vervis.ActivityPub
|
||||||
, deliverRemoteDB'
|
, deliverRemoteDB'
|
||||||
, deliverRemoteHttp
|
, deliverRemoteHttp
|
||||||
, serveCommit
|
, serveCommit
|
||||||
|
, deliverLocal
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ import Yesod.Persist.Core
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import qualified Data.CaseInsensitive as CI
|
import qualified Data.CaseInsensitive as CI
|
||||||
import qualified Data.List.NonEmpty as NE
|
import qualified Data.List.NonEmpty as NE
|
||||||
|
import qualified Data.List as L
|
||||||
import qualified Data.List.Ordered as LO
|
import qualified Data.List.Ordered as LO
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.Lazy as TL
|
import qualified Data.Text.Lazy as TL
|
||||||
|
@ -104,6 +105,7 @@ import Data.List.NonEmpty.Local
|
||||||
import Data.Tuple.Local
|
import Data.Tuple.Local
|
||||||
import Database.Persist.Local
|
import Database.Persist.Local
|
||||||
|
|
||||||
|
import Vervis.ActivityPub.Recipient
|
||||||
import Vervis.FedURI
|
import Vervis.FedURI
|
||||||
import Vervis.Foundation
|
import Vervis.Foundation
|
||||||
import Vervis.Model
|
import Vervis.Model
|
||||||
|
@ -190,9 +192,6 @@ getLocalParentMessageId did shr lmid = do
|
||||||
throwE "Local parent belongs to a different discussion"
|
throwE "Local parent belongs to a different discussion"
|
||||||
return mid
|
return mid
|
||||||
|
|
||||||
concatRecipients :: Audience u -> [ObjURI u]
|
|
||||||
concatRecipients (Audience to bto cc bcc gen _) = concat [to, bto, cc, bcc, gen]
|
|
||||||
|
|
||||||
getPersonOrGroupId :: SharerId -> AppDB (Either PersonId GroupId)
|
getPersonOrGroupId :: SharerId -> AppDB (Either PersonId GroupId)
|
||||||
getPersonOrGroupId sid = do
|
getPersonOrGroupId sid = do
|
||||||
mpid <- getKeyBy $ UniquePersonIdent sid
|
mpid <- getKeyBy $ UniquePersonIdent sid
|
||||||
|
@ -693,3 +692,74 @@ serveCommit shr rp ref patch parents = do
|
||||||
}
|
}
|
||||||
makeAuthor encodeRouteHome (Just sharer) _ =
|
makeAuthor encodeRouteHome (Just sharer) _ =
|
||||||
Right $ encodeRouteHome $ SharerR $ sharerIdent sharer
|
Right $ encodeRouteHome $ SharerR $ sharerIdent sharer
|
||||||
|
|
||||||
|
-- | Given a list of local recipients, which may include actors and
|
||||||
|
-- collections,
|
||||||
|
--
|
||||||
|
-- * Insert activity to inboxes of actors
|
||||||
|
-- * If the author's follower collection is listed, insert activity to the
|
||||||
|
-- local members and return the remote members
|
||||||
|
-- * Ignore other collections
|
||||||
|
deliverLocal
|
||||||
|
:: ShrIdent
|
||||||
|
-> InboxId
|
||||||
|
-> FollowerSetId
|
||||||
|
-> Key OutboxItem
|
||||||
|
-> [(ShrIdent, LocalSharerRelatedSet)]
|
||||||
|
-> AppDB
|
||||||
|
[ ( (InstanceId, Host)
|
||||||
|
, NonEmpty (RemoteActorId, LocalURI, LocalURI, Maybe UTCTime)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
deliverLocal shrAuthor ibidAuthor fsidAuthor obiid recips = do
|
||||||
|
(pidsFollowers, remotesFollowers) <-
|
||||||
|
if authorFollowers shrAuthor recips
|
||||||
|
then getFollowers fsidAuthor
|
||||||
|
else return ([], [])
|
||||||
|
ibidsFollowers <-
|
||||||
|
map (personInbox . entityVal) <$>
|
||||||
|
selectList [PersonId <-. pidsFollowers] [Asc PersonInbox]
|
||||||
|
ibidsSharer <- L.delete ibidAuthor <$> getSharerInboxes recips
|
||||||
|
ibidsOther <- concat <$> traverse getOtherInboxes recips
|
||||||
|
let ibids = LO.union ibidsFollowers ibidsSharer ++ ibidsOther
|
||||||
|
ibiids <- insertMany $ replicate (length ibids) $ InboxItem True
|
||||||
|
insertMany_ $
|
||||||
|
map (\ (ibid, ibiid) -> InboxItemLocal ibid obiid ibiid)
|
||||||
|
(zip ibids ibiids)
|
||||||
|
return remotesFollowers
|
||||||
|
where
|
||||||
|
getSharerInboxes sharers = do
|
||||||
|
let shrs =
|
||||||
|
[shr | (shr, s) <- sharers
|
||||||
|
, localRecipSharer $ localRecipSharerDirect s
|
||||||
|
]
|
||||||
|
sids <- selectKeysList [SharerIdent <-. shrs] []
|
||||||
|
map (personInbox . entityVal) <$> selectList [PersonIdent <-. sids] [Asc PersonInbox]
|
||||||
|
getOtherInboxes (shr, LocalSharerRelatedSet _ projects repos) = do
|
||||||
|
msid <- getKeyBy $ UniqueSharer shr
|
||||||
|
case msid of
|
||||||
|
Nothing -> return []
|
||||||
|
Just sid ->
|
||||||
|
(++)
|
||||||
|
<$> getProjectInboxes sid projects
|
||||||
|
<*> getRepoInboxes sid repos
|
||||||
|
where
|
||||||
|
getProjectInboxes sid projects =
|
||||||
|
let prjs =
|
||||||
|
[prj | (prj, j) <- projects
|
||||||
|
, localRecipProject $ localRecipProjectDirect j
|
||||||
|
]
|
||||||
|
in map (projectInbox . entityVal) <$>
|
||||||
|
selectList [ProjectSharer ==. sid, ProjectIdent <-. prjs] []
|
||||||
|
getRepoInboxes sid repos =
|
||||||
|
let rps =
|
||||||
|
[rp | (rp, r) <- repos
|
||||||
|
, localRecipRepo $ localRecipRepoDirect r
|
||||||
|
]
|
||||||
|
in map (repoInbox . entityVal) <$>
|
||||||
|
selectList [RepoSharer ==. sid, RepoIdent <-. rps] []
|
||||||
|
authorFollowers shr lrset =
|
||||||
|
case lookup shr lrset of
|
||||||
|
Just s
|
||||||
|
| localRecipSharerFollowers $ localRecipSharerDirect s -> True
|
||||||
|
_ -> False
|
||||||
|
|
|
@ -13,14 +13,17 @@
|
||||||
- <http://creativecommons.org/publicdomain/zero/1.0/>.
|
- <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||||
-}
|
-}
|
||||||
|
|
||||||
module Vervis.API.Recipient
|
module Vervis.ActivityPub.Recipient
|
||||||
( LocalActor (..)
|
( LocalActor (..)
|
||||||
, LocalTicketDirectSet (..)
|
, LocalTicketDirectSet (..)
|
||||||
, LocalProjectDirectSet (..)
|
, LocalProjectDirectSet (..)
|
||||||
, LocalProjectRelatedSet (..)
|
, LocalProjectRelatedSet (..)
|
||||||
|
, LocalRepoDirectSet (..)
|
||||||
|
, LocalRepoRelatedSet (..)
|
||||||
, LocalSharerDirectSet (..)
|
, LocalSharerDirectSet (..)
|
||||||
, LocalSharerRelatedSet (..)
|
, LocalSharerRelatedSet (..)
|
||||||
, LocalRecipientSet
|
, LocalRecipientSet
|
||||||
|
, concatRecipients
|
||||||
, parseAudience
|
, parseAudience
|
||||||
, actorRecips
|
, actorRecips
|
||||||
)
|
)
|
||||||
|
@ -49,11 +52,14 @@ import Yesod.MonadSite
|
||||||
|
|
||||||
import Data.List.NonEmpty.Local
|
import Data.List.NonEmpty.Local
|
||||||
|
|
||||||
import Vervis.ActivityPub
|
|
||||||
import Vervis.FedURI
|
import Vervis.FedURI
|
||||||
import Vervis.Foundation
|
import Vervis.Foundation
|
||||||
import Vervis.Model.Ident
|
import Vervis.Model.Ident
|
||||||
|
|
||||||
|
concatRecipients :: Audience u -> [ObjURI u]
|
||||||
|
concatRecipients (Audience to bto cc bcc gen _) =
|
||||||
|
concat [to, bto, cc, bcc, gen]
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Actor and collection-of-persons types
|
-- Actor and collection-of-persons types
|
||||||
--
|
--
|
|
@ -22,11 +22,17 @@ module Vervis.Client
|
||||||
, followTicket
|
, followTicket
|
||||||
, followRepo
|
, followRepo
|
||||||
, offerTicket
|
, offerTicket
|
||||||
|
, undoFollowSharer
|
||||||
|
, undoFollowProject
|
||||||
|
, undoFollowTicket
|
||||||
|
, undoFollowRepo
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
import Control.Monad.Trans.Except
|
import Control.Monad.Trans.Except
|
||||||
|
import Control.Monad.Trans.Reader
|
||||||
import Database.Persist
|
import Database.Persist
|
||||||
|
import Database.Persist.Sql
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Text.Blaze.Html (preEscapedToHtml)
|
import Text.Blaze.Html (preEscapedToHtml)
|
||||||
import Text.Blaze.Html.Renderer.Text
|
import Text.Blaze.Html.Renderer.Text
|
||||||
|
@ -40,6 +46,7 @@ import qualified Data.Text.Lazy as TL
|
||||||
|
|
||||||
import Network.FedURI
|
import Network.FedURI
|
||||||
import Web.ActivityPub hiding (Follow)
|
import Web.ActivityPub hiding (Follow)
|
||||||
|
import Yesod.ActivityPub
|
||||||
import Yesod.FedURI
|
import Yesod.FedURI
|
||||||
import Yesod.Hashids
|
import Yesod.Hashids
|
||||||
import Yesod.MonadSite
|
import Yesod.MonadSite
|
||||||
|
@ -47,8 +54,10 @@ import Yesod.RenderSource
|
||||||
|
|
||||||
import qualified Web.ActivityPub as AP
|
import qualified Web.ActivityPub as AP
|
||||||
|
|
||||||
|
import Control.Monad.Trans.Except.Local
|
||||||
import Database.Persist.Local
|
import Database.Persist.Local
|
||||||
|
|
||||||
|
import Vervis.ActivityPub
|
||||||
import Vervis.FedURI
|
import Vervis.FedURI
|
||||||
import Vervis.Foundation
|
import Vervis.Foundation
|
||||||
import Vervis.Model
|
import Vervis.Model
|
||||||
|
@ -242,3 +251,120 @@ offerTicket shrAuthor (TextHtml title) (TextPandocMarkdown desc) shr prj = runEx
|
||||||
, audienceNonActors = map encodeRouteHome recipsC
|
, audienceNonActors = map encodeRouteHome recipsC
|
||||||
}
|
}
|
||||||
return (summary, audience, offer)
|
return (summary, audience, offer)
|
||||||
|
|
||||||
|
undoFollow
|
||||||
|
:: (MonadUnliftIO m, MonadHandler m, HandlerSite m ~ App, MonadSite m, SiteEnv m ~ App)
|
||||||
|
=> ShrIdent
|
||||||
|
-> PersonId
|
||||||
|
-> ExceptT Text (ReaderT SqlBackend m) FollowerSetId
|
||||||
|
-> Text
|
||||||
|
-> Route App
|
||||||
|
-> Route App
|
||||||
|
-> m (Either Text (TextHtml, Audience URIMode, Undo URIMode))
|
||||||
|
undoFollow shrAuthor pidAuthor getFsid typ objRoute recipRoute = runExceptT $ do
|
||||||
|
encodeRouteLocal <- getEncodeRouteLocal
|
||||||
|
encodeRouteHome <- getEncodeRouteHome
|
||||||
|
obiidFollow <- runDBExcept $ do
|
||||||
|
fsid <- getFsid
|
||||||
|
mf <- lift $ getValBy $ UniqueFollow pidAuthor fsid
|
||||||
|
followFollow <$> fromMaybeE mf ("Not following this " <> typ)
|
||||||
|
obikhidFollow <- encodeKeyHashid obiidFollow
|
||||||
|
summary <- do
|
||||||
|
hLocal <- asksSite siteInstanceHost
|
||||||
|
TextHtml . TL.toStrict . renderHtml <$>
|
||||||
|
withUrlRenderer
|
||||||
|
[hamlet|
|
||||||
|
<p>
|
||||||
|
<a href=@{SharerR shrAuthor}>
|
||||||
|
#{shr2text shrAuthor}
|
||||||
|
\ unfollowed #
|
||||||
|
<a href=@{objRoute}>
|
||||||
|
#{renderAuthority hLocal}#{localUriPath $ encodeRouteLocal objRoute}
|
||||||
|
\.
|
||||||
|
|]
|
||||||
|
let undo = Undo
|
||||||
|
{ undoObject =
|
||||||
|
encodeRouteLocal $ SharerOutboxItemR shrAuthor obikhidFollow
|
||||||
|
}
|
||||||
|
audience = Audience [encodeRouteHome recipRoute] [] [] [] [] []
|
||||||
|
return (summary, audience, undo)
|
||||||
|
|
||||||
|
undoFollowSharer
|
||||||
|
:: (MonadUnliftIO m, MonadHandler m, HandlerSite m ~ App, MonadSite m, SiteEnv m ~ App)
|
||||||
|
=> ShrIdent
|
||||||
|
-> PersonId
|
||||||
|
-> ShrIdent
|
||||||
|
-> m (Either Text (TextHtml, Audience URIMode, Undo URIMode))
|
||||||
|
undoFollowSharer shrAuthor pidAuthor shrFollowee =
|
||||||
|
undoFollow shrAuthor pidAuthor getFsid "sharer" objRoute objRoute
|
||||||
|
where
|
||||||
|
objRoute = SharerR shrFollowee
|
||||||
|
getFsid = do
|
||||||
|
sidFollowee <- do
|
||||||
|
msid <- lift $ getKeyBy $ UniqueSharer shrFollowee
|
||||||
|
fromMaybeE msid "No such local sharer"
|
||||||
|
mp <- lift $ getValBy $ UniquePersonIdent sidFollowee
|
||||||
|
personFollowers <$>
|
||||||
|
fromMaybeE mp "Unfollow target local sharer isn't a person"
|
||||||
|
|
||||||
|
undoFollowProject
|
||||||
|
:: (MonadUnliftIO m, MonadHandler m, HandlerSite m ~ App, MonadSite m, SiteEnv m ~ App)
|
||||||
|
=> ShrIdent
|
||||||
|
-> PersonId
|
||||||
|
-> ShrIdent
|
||||||
|
-> PrjIdent
|
||||||
|
-> m (Either Text (TextHtml, Audience URIMode, Undo URIMode))
|
||||||
|
undoFollowProject shrAuthor pidAuthor shrFollowee prjFollowee =
|
||||||
|
undoFollow shrAuthor pidAuthor getFsid "project" objRoute objRoute
|
||||||
|
where
|
||||||
|
objRoute = ProjectR shrFollowee prjFollowee
|
||||||
|
getFsid = do
|
||||||
|
sidFollowee <- do
|
||||||
|
msid <- lift $ getKeyBy $ UniqueSharer shrFollowee
|
||||||
|
fromMaybeE msid "No such local sharer"
|
||||||
|
mj <- lift $ getValBy $ UniqueProject prjFollowee sidFollowee
|
||||||
|
projectFollowers <$>
|
||||||
|
fromMaybeE mj "Unfollow target no such local project"
|
||||||
|
|
||||||
|
undoFollowTicket
|
||||||
|
:: (MonadUnliftIO m, MonadHandler m, HandlerSite m ~ App, MonadSite m, SiteEnv m ~ App)
|
||||||
|
=> ShrIdent
|
||||||
|
-> PersonId
|
||||||
|
-> ShrIdent
|
||||||
|
-> PrjIdent
|
||||||
|
-> Int
|
||||||
|
-> m (Either Text (TextHtml, Audience URIMode, Undo URIMode))
|
||||||
|
undoFollowTicket shrAuthor pidAuthor shrFollowee prjFollowee numFollowee =
|
||||||
|
undoFollow shrAuthor pidAuthor getFsid "project" objRoute recipRoute
|
||||||
|
where
|
||||||
|
objRoute = TicketR shrFollowee prjFollowee numFollowee
|
||||||
|
recipRoute = ProjectR shrFollowee prjFollowee
|
||||||
|
getFsid = do
|
||||||
|
sid <- do
|
||||||
|
msid <- lift $ getKeyBy $ UniqueSharer shrFollowee
|
||||||
|
fromMaybeE msid "No such local sharer"
|
||||||
|
jid <- do
|
||||||
|
mjid <- lift $ getKeyBy $ UniqueProject prjFollowee sid
|
||||||
|
fromMaybeE mjid "No such local project"
|
||||||
|
mt <- lift $ getValBy $ UniqueTicket jid numFollowee
|
||||||
|
ticketFollowers <$>
|
||||||
|
fromMaybeE mt "Unfollow target no such local ticket"
|
||||||
|
|
||||||
|
undoFollowRepo
|
||||||
|
:: (MonadUnliftIO m, MonadHandler m, HandlerSite m ~ App, MonadSite m, SiteEnv m ~ App)
|
||||||
|
=> ShrIdent
|
||||||
|
-> PersonId
|
||||||
|
-> ShrIdent
|
||||||
|
-> RpIdent
|
||||||
|
-> m (Either Text (TextHtml, Audience URIMode, Undo URIMode))
|
||||||
|
undoFollowRepo shrAuthor pidAuthor shrFollowee rpFollowee =
|
||||||
|
undoFollow shrAuthor pidAuthor getFsid "repo" objRoute objRoute
|
||||||
|
where
|
||||||
|
objRoute = RepoR shrFollowee rpFollowee
|
||||||
|
getFsid = do
|
||||||
|
sidFollowee <- do
|
||||||
|
msid <- lift $ getKeyBy $ UniqueSharer shrFollowee
|
||||||
|
fromMaybeE msid "No such local sharer"
|
||||||
|
mr <- lift $ getValBy $ UniqueRepo rpFollowee sidFollowee
|
||||||
|
repoFollowers <$>
|
||||||
|
fromMaybeE mr "Unfollow target no such local repo"
|
||||||
|
|
|
@ -19,85 +19,54 @@ module Vervis.Federation.Discussion
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
--import Control.Applicative
|
|
||||||
--import Control.Concurrent.MVar
|
|
||||||
--import Control.Concurrent.STM.TVar
|
|
||||||
import Control.Exception hiding (Handler, try)
|
import Control.Exception hiding (Handler, try)
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Control.Monad.Logger.CallStack
|
import Control.Monad.Logger.CallStack
|
||||||
import Control.Monad.Trans.Class
|
import Control.Monad.Trans.Class
|
||||||
import Control.Monad.Trans.Except
|
import Control.Monad.Trans.Except
|
||||||
import Control.Monad.Trans.Maybe
|
import Control.Monad.Trans.Maybe
|
||||||
--import Control.Monad.Trans.Reader
|
|
||||||
--import Crypto.Hash
|
|
||||||
--import Data.Aeson
|
|
||||||
import Data.Bifunctor
|
import Data.Bifunctor
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
--import Data.Either
|
|
||||||
import Data.Foldable
|
import Data.Foldable
|
||||||
import Data.Function
|
import Data.Function
|
||||||
import Data.List (sort, deleteBy, nub, union, unionBy, partition)
|
import Data.List (sort, deleteBy, nub, union, unionBy, partition)
|
||||||
import Data.List.NonEmpty (NonEmpty (..), nonEmpty)
|
import Data.List.NonEmpty (NonEmpty (..), nonEmpty)
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
--import Data.Semigroup
|
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Data.Text.Encoding
|
import Data.Text.Encoding
|
||||||
import Data.Time.Clock
|
import Data.Time.Clock
|
||||||
--import Data.Time.Units
|
|
||||||
import Data.Traversable
|
import Data.Traversable
|
||||||
--import Data.Tuple
|
|
||||||
import Database.Persist
|
import Database.Persist
|
||||||
--import Database.Persist.Sql hiding (deleteBy)
|
|
||||||
--import Network.HTTP.Client
|
|
||||||
--import Network.HTTP.Types.Header
|
|
||||||
--import Network.HTTP.Types.URI
|
|
||||||
--import Network.TLS hiding (SHA256)
|
|
||||||
--import UnliftIO.Exception (try)
|
|
||||||
import Yesod.Core hiding (logError, logWarn, logInfo, logDebug)
|
import Yesod.Core hiding (logError, logWarn, logInfo, logDebug)
|
||||||
import Yesod.Persist.Core
|
import Yesod.Persist.Core
|
||||||
|
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import qualified Data.CaseInsensitive as CI
|
import qualified Data.CaseInsensitive as CI
|
||||||
--import qualified Data.List as L
|
|
||||||
import qualified Data.List.NonEmpty as NE
|
import qualified Data.List.NonEmpty as NE
|
||||||
--import qualified Data.List.Ordered as LO
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Database.Esqueleto as E
|
import qualified Database.Esqueleto as E
|
||||||
--import qualified Network.Wai as W
|
|
||||||
|
|
||||||
--import Data.Time.Interval
|
|
||||||
--import Network.HTTP.Signature hiding (requestHeaders)
|
|
||||||
import Yesod.HttpSignature
|
import Yesod.HttpSignature
|
||||||
|
|
||||||
--import Crypto.PublicVerifKey
|
|
||||||
import Database.Persist.JSON
|
import Database.Persist.JSON
|
||||||
import Network.FedURI
|
import Network.FedURI
|
||||||
import Network.HTTP.Digest
|
import Network.HTTP.Digest
|
||||||
import Web.ActivityPub
|
import Web.ActivityPub
|
||||||
import Yesod.ActivityPub
|
import Yesod.ActivityPub
|
||||||
--import Yesod.Auth.Unverified
|
|
||||||
import Yesod.FedURI
|
import Yesod.FedURI
|
||||||
--import Yesod.Hashids
|
|
||||||
--import Yesod.MonadSite
|
|
||||||
|
|
||||||
import Control.Monad.Trans.Except.Local
|
import Control.Monad.Trans.Except.Local
|
||||||
--import Data.Aeson.Local
|
|
||||||
--import Data.Either.Local
|
|
||||||
--import Data.List.Local
|
|
||||||
--import Data.List.NonEmpty.Local
|
|
||||||
--import Data.Maybe.Local
|
|
||||||
import Data.Tuple.Local
|
import Data.Tuple.Local
|
||||||
import Database.Persist.Local
|
import Database.Persist.Local
|
||||||
import Yesod.Persist.Local
|
import Yesod.Persist.Local
|
||||||
|
|
||||||
import Vervis.ActivityPub
|
import Vervis.ActivityPub
|
||||||
--import Vervis.ActorKey
|
import Vervis.ActivityPub.Recipient
|
||||||
import Vervis.FedURI
|
import Vervis.FedURI
|
||||||
import Vervis.Federation.Auth
|
import Vervis.Federation.Auth
|
||||||
import Vervis.Foundation
|
import Vervis.Foundation
|
||||||
import Vervis.Model
|
import Vervis.Model
|
||||||
import Vervis.Model.Ident
|
import Vervis.Model.Ident
|
||||||
--import Vervis.RemoteActorStore
|
|
||||||
import Vervis.Settings
|
import Vervis.Settings
|
||||||
|
|
||||||
sharerCreateNoteF
|
sharerCreateNoteF
|
||||||
|
|
|
@ -63,6 +63,7 @@ import Database.Persist.Local
|
||||||
import Yesod.Persist.Local
|
import Yesod.Persist.Local
|
||||||
|
|
||||||
import Vervis.ActivityPub
|
import Vervis.ActivityPub
|
||||||
|
import Vervis.ActivityPub.Recipient
|
||||||
import Vervis.FedURI
|
import Vervis.FedURI
|
||||||
import Vervis.Federation.Auth
|
import Vervis.Federation.Auth
|
||||||
import Vervis.Foundation
|
import Vervis.Foundation
|
||||||
|
|
|
@ -300,6 +300,7 @@ instance Yesod App where
|
||||||
(NotificationsR shr , _ ) -> person shr
|
(NotificationsR shr , _ ) -> person shr
|
||||||
(SharerOutboxR shr , True) -> person shr
|
(SharerOutboxR shr , True) -> person shr
|
||||||
(SharerFollowR shr , True) -> personAny
|
(SharerFollowR shr , True) -> personAny
|
||||||
|
(SharerUnfollowR shr , True) -> personAny
|
||||||
|
|
||||||
(GroupsR , True) -> personAny
|
(GroupsR , True) -> personAny
|
||||||
(GroupNewR , _ ) -> personAny
|
(GroupNewR , _ ) -> personAny
|
||||||
|
@ -324,6 +325,7 @@ instance Yesod App where
|
||||||
(RepoR shar _ , True) -> person shar
|
(RepoR shar _ , True) -> person shar
|
||||||
(RepoEditR shr _rp , _ ) -> person shr
|
(RepoEditR shr _rp , _ ) -> person shr
|
||||||
(RepoFollowR _shr _rp , True) -> personAny
|
(RepoFollowR _shr _rp , True) -> personAny
|
||||||
|
(RepoUnfollowR _shr _rp , True) -> personAny
|
||||||
(RepoDevsR shr _rp , _ ) -> person shr
|
(RepoDevsR shr _rp , _ ) -> person shr
|
||||||
(RepoDevNewR shr _rp , _ ) -> person shr
|
(RepoDevNewR shr _rp , _ ) -> person shr
|
||||||
(RepoDevR shr _rp _dev , _ ) -> person shr
|
(RepoDevR shr _rp _dev , _ ) -> person shr
|
||||||
|
@ -333,6 +335,7 @@ instance Yesod App where
|
||||||
(ProjectR shr _prj , True) -> person shr
|
(ProjectR shr _prj , True) -> person shr
|
||||||
(ProjectEditR shr _prj , _ ) -> person shr
|
(ProjectEditR shr _prj , _ ) -> person shr
|
||||||
(ProjectFollowR _shr _prj , _ ) -> personAny
|
(ProjectFollowR _shr _prj , _ ) -> personAny
|
||||||
|
(ProjectUnfollowR _shr _prj , _ ) -> personAny
|
||||||
(ProjectDevsR shr _prj , _ ) -> person shr
|
(ProjectDevsR shr _prj , _ ) -> person shr
|
||||||
(ProjectDevNewR shr _prj , _ ) -> person shr
|
(ProjectDevNewR shr _prj , _ ) -> person shr
|
||||||
(ProjectDevR shr _prj _dev , _ ) -> person shr
|
(ProjectDevR shr _prj _dev , _ ) -> person shr
|
||||||
|
@ -366,6 +369,7 @@ instance Yesod App where
|
||||||
(TicketAssignR s j _ , _ ) -> projOp ProjOpAssignTicket s j
|
(TicketAssignR s j _ , _ ) -> projOp ProjOpAssignTicket s j
|
||||||
(TicketUnassignR s j _ , _ ) -> projOp ProjOpUnassignTicket s j
|
(TicketUnassignR s j _ , _ ) -> projOp ProjOpUnassignTicket s j
|
||||||
(TicketFollowR _ _ _ , True) -> personAny
|
(TicketFollowR _ _ _ , True) -> personAny
|
||||||
|
(TicketUnfollowR _ _ _ , True) -> personAny
|
||||||
(ClaimRequestsTicketR s j _, True) -> projOp ProjOpRequestTicket s j
|
(ClaimRequestsTicketR s j _, True) -> projOp ProjOpRequestTicket s j
|
||||||
(ClaimRequestNewR s j _ , _ ) -> projOp ProjOpRequestTicket s j
|
(ClaimRequestNewR s j _ , _ ) -> projOp ProjOpRequestTicket s j
|
||||||
(TicketDiscussionR _ _ _ , True) -> personAny
|
(TicketDiscussionR _ _ _ , True) -> personAny
|
||||||
|
|
|
@ -16,12 +16,20 @@
|
||||||
module Vervis.Handler.Client
|
module Vervis.Handler.Client
|
||||||
( getPublishR
|
( getPublishR
|
||||||
, postSharerOutboxR
|
, postSharerOutboxR
|
||||||
|
|
||||||
, postSharerFollowR
|
, postSharerFollowR
|
||||||
, postProjectFollowR
|
, postProjectFollowR
|
||||||
, postTicketFollowR
|
, postTicketFollowR
|
||||||
, postRepoFollowR
|
, postRepoFollowR
|
||||||
|
|
||||||
|
, postSharerUnfollowR
|
||||||
|
, postProjectUnfollowR
|
||||||
|
, postTicketUnfollowR
|
||||||
|
, postRepoUnfollowR
|
||||||
|
|
||||||
, getNotificationsR
|
, getNotificationsR
|
||||||
, postNotificationsR
|
, postNotificationsR
|
||||||
|
|
||||||
, postTicketsR
|
, postTicketsR
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
@ -199,11 +207,14 @@ activityWidget shr widget1 enctype1 widget2 enctype2 widget3 enctype3 =
|
||||||
<input type=submit>
|
<input type=submit>
|
||||||
|]
|
|]
|
||||||
|
|
||||||
getUserShrIdent :: Handler ShrIdent
|
getUser :: Handler (ShrIdent, PersonId)
|
||||||
getUserShrIdent = do
|
getUser = do
|
||||||
Entity _ p <- requireVerifiedAuth
|
Entity pid p <- requireVerifiedAuth
|
||||||
s <- runDB $ getJust $ personIdent p
|
s <- runDB $ getJust $ personIdent p
|
||||||
return $ sharerIdent s
|
return (sharerIdent s, pid)
|
||||||
|
|
||||||
|
getUserShrIdent :: Handler ShrIdent
|
||||||
|
getUserShrIdent = fst <$> getUser
|
||||||
|
|
||||||
getPublishR :: Handler Html
|
getPublishR :: Handler Html
|
||||||
getPublishR = do
|
getPublishR = do
|
||||||
|
@ -389,6 +400,57 @@ postRepoFollowR shrObject rpObject = do
|
||||||
setFollowMessage shrAuthor eid
|
setFollowMessage shrAuthor eid
|
||||||
redirect $ RepoR shrObject rpObject
|
redirect $ RepoR shrObject rpObject
|
||||||
|
|
||||||
|
setUnfollowMessage :: ShrIdent -> Either Text OutboxItemId -> Handler ()
|
||||||
|
setUnfollowMessage _ (Left err) = setMessage $ toHtml err
|
||||||
|
setUnfollowMessage shr (Right obiid) = do
|
||||||
|
obikhid <- encodeKeyHashid obiid
|
||||||
|
setMessage =<<
|
||||||
|
withUrlRenderer
|
||||||
|
[hamlet|
|
||||||
|
<a href=@{SharerOutboxItemR shr obikhid}>
|
||||||
|
Unfollow request published!
|
||||||
|
|]
|
||||||
|
|
||||||
|
postSharerUnfollowR :: ShrIdent -> Handler ()
|
||||||
|
postSharerUnfollowR shrFollowee = do
|
||||||
|
(shrAuthor, pidAuthor) <- getUser
|
||||||
|
eid <- runExceptT $ do
|
||||||
|
(summary, audience, undo) <-
|
||||||
|
ExceptT $ undoFollowSharer shrAuthor pidAuthor shrFollowee
|
||||||
|
ExceptT $ undoC shrAuthor summary audience undo
|
||||||
|
setUnfollowMessage shrAuthor eid
|
||||||
|
redirect $ SharerR shrFollowee
|
||||||
|
|
||||||
|
postProjectUnfollowR :: ShrIdent -> PrjIdent -> Handler ()
|
||||||
|
postProjectUnfollowR shrFollowee prjFollowee = do
|
||||||
|
(shrAuthor, pidAuthor) <- getUser
|
||||||
|
eid <- runExceptT $ do
|
||||||
|
(summary, audience, undo) <-
|
||||||
|
ExceptT $ undoFollowProject shrAuthor pidAuthor shrFollowee prjFollowee
|
||||||
|
ExceptT $ undoC shrAuthor summary audience undo
|
||||||
|
setUnfollowMessage shrAuthor eid
|
||||||
|
redirect $ ProjectR shrFollowee prjFollowee
|
||||||
|
|
||||||
|
postTicketUnfollowR :: ShrIdent -> PrjIdent -> Int -> Handler ()
|
||||||
|
postTicketUnfollowR shrFollowee prjFollowee numFollowee = do
|
||||||
|
(shrAuthor, pidAuthor) <- getUser
|
||||||
|
eid <- runExceptT $ do
|
||||||
|
(summary, audience, undo) <-
|
||||||
|
ExceptT $ undoFollowTicket shrAuthor pidAuthor shrFollowee prjFollowee numFollowee
|
||||||
|
ExceptT $ undoC shrAuthor summary audience undo
|
||||||
|
setUnfollowMessage shrAuthor eid
|
||||||
|
redirect $ TicketR shrFollowee prjFollowee numFollowee
|
||||||
|
|
||||||
|
postRepoUnfollowR :: ShrIdent -> RpIdent -> Handler ()
|
||||||
|
postRepoUnfollowR shrFollowee rpFollowee = do
|
||||||
|
(shrAuthor, pidAuthor) <- getUser
|
||||||
|
eid <- runExceptT $ do
|
||||||
|
(summary, audience, undo) <-
|
||||||
|
ExceptT $ undoFollowRepo shrAuthor pidAuthor shrFollowee rpFollowee
|
||||||
|
ExceptT $ undoC shrAuthor summary audience undo
|
||||||
|
setUnfollowMessage shrAuthor eid
|
||||||
|
redirect $ RepoR shrFollowee rpFollowee
|
||||||
|
|
||||||
notificationForm :: Maybe (Maybe (InboxItemId, Bool)) -> Form (Maybe (InboxItemId, Bool))
|
notificationForm :: Maybe (Maybe (InboxItemId, Bool)) -> Form (Maybe (InboxItemId, Bool))
|
||||||
notificationForm defs = renderDivs $ mk
|
notificationForm defs = renderDivs $ mk
|
||||||
<$> aopt hiddenField (name "Inbox Item ID#") (fmap fst <$> defs)
|
<$> aopt hiddenField (name "Inbox Item ID#") (fmap fst <$> defs)
|
||||||
|
|
|
@ -148,4 +148,7 @@ getPerson shr sharer person = do
|
||||||
provideHtmlAndAP personAP $(widgetFile "person")
|
provideHtmlAndAP personAP $(widgetFile "person")
|
||||||
where
|
where
|
||||||
followButton =
|
followButton =
|
||||||
followW (SharerFollowR shr) (return $ personFollowers person)
|
followW
|
||||||
|
(SharerFollowR shr)
|
||||||
|
(SharerUnfollowR shr)
|
||||||
|
(return $ personFollowers person)
|
||||||
|
|
|
@ -163,6 +163,7 @@ getProjectR shar proj = do
|
||||||
followButton =
|
followButton =
|
||||||
followW
|
followW
|
||||||
(ProjectFollowR shar proj)
|
(ProjectFollowR shar proj)
|
||||||
|
(ProjectUnfollowR shar proj)
|
||||||
(return $ projectFollowers project)
|
(return $ projectFollowers project)
|
||||||
provideHtmlAndAP projectAP $(widgetFile "project/one")
|
provideHtmlAndAP projectAP $(widgetFile "project/one")
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,10 @@ getDarcsRepoSource repository user repo dir = do
|
||||||
$(widgetFile "repo/source-darcs")
|
$(widgetFile "repo/source-darcs")
|
||||||
where
|
where
|
||||||
followButton =
|
followButton =
|
||||||
followW (RepoFollowR user repo) (return $ repoFollowers repository)
|
followW
|
||||||
|
(RepoFollowR user repo)
|
||||||
|
(RepoUnfollowR user repo)
|
||||||
|
(return $ repoFollowers repository)
|
||||||
|
|
||||||
getDarcsRepoHeadChanges :: ShrIdent -> RpIdent -> Handler TypedContent
|
getDarcsRepoHeadChanges :: ShrIdent -> RpIdent -> Handler TypedContent
|
||||||
getDarcsRepoHeadChanges shar repo = do
|
getDarcsRepoHeadChanges shar repo = do
|
||||||
|
|
|
@ -113,7 +113,10 @@ getGitRepoSource repository user repo ref dir = do
|
||||||
$(widgetFile "repo/source-git")
|
$(widgetFile "repo/source-git")
|
||||||
where
|
where
|
||||||
followButton =
|
followButton =
|
||||||
followW (RepoFollowR user repo) (return $ repoFollowers repository)
|
followW
|
||||||
|
(RepoFollowR user repo)
|
||||||
|
(RepoUnfollowR user repo)
|
||||||
|
(return $ repoFollowers repository)
|
||||||
|
|
||||||
getGitRepoHeadChanges :: Repo -> ShrIdent -> RpIdent -> Handler TypedContent
|
getGitRepoHeadChanges :: Repo -> ShrIdent -> RpIdent -> Handler TypedContent
|
||||||
getGitRepoHeadChanges repository shar repo =
|
getGitRepoHeadChanges repository shar repo =
|
||||||
|
|
|
@ -295,6 +295,7 @@ getTicketR shar proj num = do
|
||||||
let followButton =
|
let followButton =
|
||||||
followW
|
followW
|
||||||
(TicketFollowR shar proj num)
|
(TicketFollowR shar proj num)
|
||||||
|
(TicketUnfollowR shar proj num)
|
||||||
(return $ ticketFollowers ticket)
|
(return $ ticketFollowers ticket)
|
||||||
in $(widgetFile "ticket/one")
|
in $(widgetFile "ticket/one")
|
||||||
|
|
||||||
|
|
|
@ -59,8 +59,8 @@ sharerLinkFedW (Right (inztance, actor)) =
|
||||||
where
|
where
|
||||||
uActor = ObjURI (instanceHost inztance) (remoteActorIdent actor)
|
uActor = ObjURI (instanceHost inztance) (remoteActorIdent actor)
|
||||||
|
|
||||||
followW :: Route App -> AppDB FollowerSetId -> Widget
|
followW :: Route App -> Route App -> AppDB FollowerSetId -> Widget
|
||||||
followW followRoute getFsid = do
|
followW followRoute unfollowRoute getFsid = do
|
||||||
mpid <- maybeVerifiedAuthId
|
mpid <- maybeVerifiedAuthId
|
||||||
for_ mpid $ \ pid -> do
|
for_ mpid $ \ pid -> do
|
||||||
mfollow <- handlerToWidget $ runDB $ do
|
mfollow <- handlerToWidget $ runDB $ do
|
||||||
|
@ -68,7 +68,4 @@ followW followRoute getFsid = do
|
||||||
getValBy $ UniqueFollow pid fsid
|
getValBy $ UniqueFollow pid fsid
|
||||||
case mfollow of
|
case mfollow of
|
||||||
Nothing -> buttonW POST "Follow" followRoute
|
Nothing -> buttonW POST "Follow" followRoute
|
||||||
Just _ ->
|
Just _ -> buttonW POST "Unfollow" unfollowRoute
|
||||||
[whamlet|
|
|
||||||
<div>[Following]
|
|
||||||
|]
|
|
||||||
|
|
|
@ -1155,6 +1155,7 @@ instance ActivityPub Activity where
|
||||||
activityType (OfferActivity _) = "Offer"
|
activityType (OfferActivity _) = "Offer"
|
||||||
activityType (PushActivity _) = "Push"
|
activityType (PushActivity _) = "Push"
|
||||||
activityType (RejectActivity _) = "Reject"
|
activityType (RejectActivity _) = "Reject"
|
||||||
|
activityType (UndoActivity _) = "Undo"
|
||||||
encodeSpecific h _ (AcceptActivity a) = encodeAccept h a
|
encodeSpecific h _ (AcceptActivity a) = encodeAccept h a
|
||||||
encodeSpecific h u (CreateActivity a) = encodeCreate h u a
|
encodeSpecific h u (CreateActivity a) = encodeCreate h u a
|
||||||
encodeSpecific _ _ (FollowActivity a) = encodeFollow a
|
encodeSpecific _ _ (FollowActivity a) = encodeFollow a
|
||||||
|
|
|
@ -115,9 +115,9 @@ library
|
||||||
|
|
||||||
Vervis.Access
|
Vervis.Access
|
||||||
Vervis.ActivityPub
|
Vervis.ActivityPub
|
||||||
|
Vervis.ActivityPub.Recipient
|
||||||
Vervis.ActorKey
|
Vervis.ActorKey
|
||||||
Vervis.API
|
Vervis.API
|
||||||
Vervis.API.Recipient
|
|
||||||
Vervis.Application
|
Vervis.Application
|
||||||
Vervis.Avatar
|
Vervis.Avatar
|
||||||
Vervis.BinaryBody
|
Vervis.BinaryBody
|
||||||
|
|
Loading…
Reference in a new issue