Improve reply prefix computation. (#103)
This commit is contained in:
parent
44f8caa1ea
commit
017f07d45d
@ -1,21 +1,15 @@
|
|||||||
module Mastodon.Helper
|
module Mastodon.Helper
|
||||||
exposing
|
exposing
|
||||||
( accountMentioned
|
( extractReblog
|
||||||
, extractReblog
|
|
||||||
, aggregateNotifications
|
, aggregateNotifications
|
||||||
, addNotificationToAggregates
|
, addNotificationToAggregates
|
||||||
|
, getReplyPrefix
|
||||||
, notificationToAggregate
|
, notificationToAggregate
|
||||||
, sameAccount
|
, sameAccount
|
||||||
)
|
)
|
||||||
|
|
||||||
import List.Extra exposing (groupWhile, uniqueBy)
|
import List.Extra exposing (groupWhile, uniqueBy)
|
||||||
import Mastodon.Model
|
import Mastodon.Model exposing (..)
|
||||||
exposing
|
|
||||||
( Notification
|
|
||||||
, NotificationAggregate
|
|
||||||
, Reblog(..)
|
|
||||||
, Status
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
extractReblog : Status -> Status
|
extractReblog : Status -> Status
|
||||||
@ -28,6 +22,33 @@ extractReblog status =
|
|||||||
status
|
status
|
||||||
|
|
||||||
|
|
||||||
|
getReplyPrefix : Account -> Status -> String
|
||||||
|
getReplyPrefix replier status =
|
||||||
|
-- Note: the Mastodon API doesn't consistently return mentions in the order
|
||||||
|
-- they appear in the status text, we do nothing about that.
|
||||||
|
let
|
||||||
|
posters =
|
||||||
|
case status.reblog of
|
||||||
|
Just (Mastodon.Model.Reblog reblog) ->
|
||||||
|
[ reblog.account, status.account ] |> List.map toMention
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
(toMention status.account) :: status.mentions
|
||||||
|
|
||||||
|
finalPosters =
|
||||||
|
posters
|
||||||
|
|> uniqueBy .acct
|
||||||
|
|> List.filter (\m -> m /= (toMention replier))
|
||||||
|
|> List.map (\m -> "@" ++ m.acct)
|
||||||
|
in
|
||||||
|
(String.join " " finalPosters) ++ " "
|
||||||
|
|
||||||
|
|
||||||
|
toMention : Account -> Mention
|
||||||
|
toMention { id, url, username, acct } =
|
||||||
|
Mention id url username acct
|
||||||
|
|
||||||
|
|
||||||
notificationToAggregate : Notification -> NotificationAggregate
|
notificationToAggregate : Notification -> NotificationAggregate
|
||||||
notificationToAggregate notification =
|
notificationToAggregate notification =
|
||||||
NotificationAggregate
|
NotificationAggregate
|
||||||
@ -143,11 +164,7 @@ aggregateNotifications notifications =
|
|||||||
|> List.reverse
|
|> List.reverse
|
||||||
|
|
||||||
|
|
||||||
accountMentioned : Mastodon.Model.Account -> Mastodon.Model.Mention -> Bool
|
|
||||||
accountMentioned { acct, username } mention =
|
|
||||||
acct == mention.acct && username == mention.username
|
|
||||||
|
|
||||||
|
|
||||||
sameAccount : Mastodon.Model.Account -> Mastodon.Model.Account -> Bool
|
sameAccount : Mastodon.Model.Account -> Mastodon.Model.Account -> Bool
|
||||||
sameAccount { acct, username } account =
|
sameAccount { id, acct, username } account =
|
||||||
acct == account.acct && username == account.username
|
-- Note: different instances can share the same id for different accounts.
|
||||||
|
id == account.id && acct == account.acct && username == account.username
|
||||||
|
@ -400,22 +400,9 @@ updateDraft draftMsg currentUser draft =
|
|||||||
{ draft | visibility = visibility } ! []
|
{ draft | visibility = visibility } ! []
|
||||||
|
|
||||||
UpdateReplyTo status ->
|
UpdateReplyTo status ->
|
||||||
let
|
|
||||||
mentions =
|
|
||||||
status.mentions
|
|
||||||
|> List.filter (\m -> not (Mastodon.Helper.accountMentioned currentUser m))
|
|
||||||
|> List.map (\m -> "@" ++ m.acct)
|
|
||||||
|> String.join " "
|
|
||||||
|
|
||||||
newStatus =
|
|
||||||
if Mastodon.Helper.sameAccount status.account currentUser then
|
|
||||||
mentions
|
|
||||||
else
|
|
||||||
"@" ++ status.account.acct ++ " " ++ mentions
|
|
||||||
in
|
|
||||||
{ draft
|
{ draft
|
||||||
| in_reply_to = Just status
|
| in_reply_to = Just status
|
||||||
, status = (String.trim newStatus) ++ " "
|
, status = Mastodon.Helper.getReplyPrefix currentUser status
|
||||||
, sensitive = Maybe.withDefault False status.sensitive
|
, sensitive = Maybe.withDefault False status.sensitive
|
||||||
, spoiler_text =
|
, spoiler_text =
|
||||||
if status.spoiler_text == "" then
|
if status.spoiler_text == "" then
|
||||||
|
20
src/View.elm
20
src/View.elm
@ -261,7 +261,7 @@ accountTimelineView account statuses label iconName =
|
|||||||
statusActionsView : Mastodon.Model.Status -> Mastodon.Model.Account -> Html Msg
|
statusActionsView : Mastodon.Model.Status -> Mastodon.Model.Account -> Html Msg
|
||||||
statusActionsView status currentUser =
|
statusActionsView status currentUser =
|
||||||
let
|
let
|
||||||
targetStatus =
|
sourceStatus =
|
||||||
Mastodon.Helper.extractReblog status
|
Mastodon.Helper.extractReblog status
|
||||||
|
|
||||||
baseBtnClasses =
|
baseBtnClasses =
|
||||||
@ -270,18 +270,18 @@ statusActionsView status currentUser =
|
|||||||
( reblogClasses, reblogEvent ) =
|
( reblogClasses, reblogEvent ) =
|
||||||
case status.reblogged of
|
case status.reblogged of
|
||||||
Just True ->
|
Just True ->
|
||||||
( baseBtnClasses ++ " reblogged", Unreblog targetStatus.id )
|
( baseBtnClasses ++ " reblogged", Unreblog sourceStatus.id )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( baseBtnClasses, Reblog targetStatus.id )
|
( baseBtnClasses, Reblog sourceStatus.id )
|
||||||
|
|
||||||
( favClasses, favEvent ) =
|
( favClasses, favEvent ) =
|
||||||
case status.favourited of
|
case status.favourited of
|
||||||
Just True ->
|
Just True ->
|
||||||
( baseBtnClasses ++ " favourited", RemoveFavorite targetStatus.id )
|
( baseBtnClasses ++ " favourited", RemoveFavorite sourceStatus.id )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( baseBtnClasses, AddFavorite targetStatus.id )
|
( baseBtnClasses, AddFavorite sourceStatus.id )
|
||||||
|
|
||||||
statusDate =
|
statusDate =
|
||||||
Date.fromString status.created_at
|
Date.fromString status.created_at
|
||||||
@ -294,24 +294,24 @@ statusActionsView status currentUser =
|
|||||||
[ a
|
[ a
|
||||||
[ class baseBtnClasses
|
[ class baseBtnClasses
|
||||||
, onClickWithPreventAndStop <|
|
, onClickWithPreventAndStop <|
|
||||||
DraftEvent (UpdateReplyTo targetStatus)
|
DraftEvent (UpdateReplyTo status)
|
||||||
]
|
]
|
||||||
[ icon "share-alt" ]
|
[ icon "share-alt" ]
|
||||||
, a
|
, a
|
||||||
[ class reblogClasses
|
[ class reblogClasses
|
||||||
, onClickWithPreventAndStop reblogEvent
|
, onClickWithPreventAndStop reblogEvent
|
||||||
]
|
]
|
||||||
[ icon "fire", text (toString status.reblogs_count) ]
|
[ icon "fire", text (toString sourceStatus.reblogs_count) ]
|
||||||
, a
|
, a
|
||||||
[ class favClasses
|
[ class favClasses
|
||||||
, onClickWithPreventAndStop favEvent
|
, onClickWithPreventAndStop favEvent
|
||||||
]
|
]
|
||||||
[ icon "star", text (toString status.favourites_count) ]
|
[ icon "star", text (toString sourceStatus.favourites_count) ]
|
||||||
, if Mastodon.Helper.sameAccount status.account currentUser then
|
, if Mastodon.Helper.sameAccount sourceStatus.account currentUser then
|
||||||
a
|
a
|
||||||
[ class <| baseBtnClasses ++ " btn-delete"
|
[ class <| baseBtnClasses ++ " btn-delete"
|
||||||
, href ""
|
, href ""
|
||||||
, onClickWithPreventAndStop <| DeleteStatus status.id
|
, onClickWithPreventAndStop <| DeleteStatus sourceStatus.id
|
||||||
]
|
]
|
||||||
[ icon "trash" ]
|
[ icon "trash" ]
|
||||||
else
|
else
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
module Fixtures exposing (..)
|
module Fixtures exposing (..)
|
||||||
|
|
||||||
import Mastodon.Model exposing (Account, Notification, NotificationAggregate, Status)
|
import Mastodon.Model exposing (..)
|
||||||
|
|
||||||
|
|
||||||
accountSkro : Account
|
accountSkro : Account
|
||||||
@ -135,6 +135,60 @@ statusNicoToVjousseAgain =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
statusPloumToVjousse : Status
|
||||||
|
statusPloumToVjousse =
|
||||||
|
{ account = accountPloum
|
||||||
|
, content = "<p>hey @vjousse</p>"
|
||||||
|
, created_at = "2017-04-25T07:41:23.492Z"
|
||||||
|
, favourited = Nothing
|
||||||
|
, favourites_count = 0
|
||||||
|
, id = 752169
|
||||||
|
, in_reply_to_account_id = Nothing
|
||||||
|
, in_reply_to_id = Nothing
|
||||||
|
, media_attachments = []
|
||||||
|
, mentions =
|
||||||
|
[ { id = 26303
|
||||||
|
, url = "https://mamot.fr/@vjousse"
|
||||||
|
, username = "vjousse"
|
||||||
|
, acct = "vjousse"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
, reblog = Nothing
|
||||||
|
, reblogged = Nothing
|
||||||
|
, reblogs_count = 0
|
||||||
|
, sensitive = Just False
|
||||||
|
, spoiler_text = ""
|
||||||
|
, tags = []
|
||||||
|
, uri = "tag:mamot.fr,2017-04-25:objectId=752169:objectType=Status"
|
||||||
|
, url = "https://mamot.fr/@n1k0/752169"
|
||||||
|
, visibility = "public"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
statusReblogged : Status
|
||||||
|
statusReblogged =
|
||||||
|
{ account = accountVjousse
|
||||||
|
, content = "<p>fake post</p>"
|
||||||
|
, created_at = "2017-04-24T20:16:20.922Z"
|
||||||
|
, favourited = Nothing
|
||||||
|
, favourites_count = 0
|
||||||
|
, id = 737932
|
||||||
|
, in_reply_to_account_id = Nothing
|
||||||
|
, in_reply_to_id = Nothing
|
||||||
|
, media_attachments = []
|
||||||
|
, mentions = []
|
||||||
|
, reblog = Just (Reblog statusPloumToVjousse)
|
||||||
|
, reblogged = Nothing
|
||||||
|
, reblogs_count = 0
|
||||||
|
, sensitive = Just False
|
||||||
|
, spoiler_text = ""
|
||||||
|
, tags = []
|
||||||
|
, uri = "tag:mamot.fr,2017-04-24:objectId=737932:objectType=Status"
|
||||||
|
, url = "https://mamot.fr/@n1k0/737932"
|
||||||
|
, visibility = "public"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
notificationNicoMentionVjousse : Notification
|
notificationNicoMentionVjousse : Notification
|
||||||
notificationNicoMentionVjousse =
|
notificationNicoMentionVjousse =
|
||||||
{ id = 224284
|
{ id = 224284
|
||||||
|
@ -2,18 +2,41 @@ module MastodonTest.HelperTest exposing (..)
|
|||||||
|
|
||||||
import Test exposing (..)
|
import Test exposing (..)
|
||||||
import Expect
|
import Expect
|
||||||
import Mastodon.Helper
|
import Mastodon.Helper exposing (..)
|
||||||
import Fixtures
|
import Fixtures
|
||||||
|
|
||||||
|
|
||||||
all : Test
|
all : Test
|
||||||
all =
|
all =
|
||||||
describe "Notification test suite"
|
describe "Mastodon.Helper tests"
|
||||||
|
[ describe "Reply tests"
|
||||||
|
[ test "Simple reply" <|
|
||||||
|
\() ->
|
||||||
|
Fixtures.statusNicoToVjousse
|
||||||
|
|> getReplyPrefix Fixtures.accountVjousse
|
||||||
|
|> Expect.equal "@n1k0 "
|
||||||
|
, test "Keeping replying to a previous post mentioning a user" <|
|
||||||
|
\() ->
|
||||||
|
Fixtures.statusNicoToVjousse
|
||||||
|
|> getReplyPrefix Fixtures.accountNico
|
||||||
|
|> Expect.equal "@vjousse "
|
||||||
|
, test "Replying to original poster and reblogger" <|
|
||||||
|
\() ->
|
||||||
|
Fixtures.statusReblogged
|
||||||
|
|> getReplyPrefix Fixtures.accountNico
|
||||||
|
|> Expect.equal "@ploum @vjousse "
|
||||||
|
, test "Exclude replier from generated reply prefix" <|
|
||||||
|
\() ->
|
||||||
|
Fixtures.statusNicoToVjousse
|
||||||
|
|> getReplyPrefix Fixtures.accountNico
|
||||||
|
|> Expect.equal "@vjousse "
|
||||||
|
]
|
||||||
|
, describe "Notification test suite"
|
||||||
[ describe "Aggegate test"
|
[ describe "Aggegate test"
|
||||||
[ test "Aggregate Notifications" <|
|
[ test "Aggregate Notifications" <|
|
||||||
\() ->
|
\() ->
|
||||||
Fixtures.notifications
|
Fixtures.notifications
|
||||||
|> Mastodon.Helper.aggregateNotifications
|
|> aggregateNotifications
|
||||||
|> Expect.equal
|
|> Expect.equal
|
||||||
[ { type_ = "mention"
|
[ { type_ = "mention"
|
||||||
, status = Just Fixtures.statusNicoToVjousse
|
, status = Just Fixtures.statusNicoToVjousse
|
||||||
@ -29,14 +52,14 @@ all =
|
|||||||
, test "Dedupes aggregated accounts" <|
|
, test "Dedupes aggregated accounts" <|
|
||||||
\() ->
|
\() ->
|
||||||
Fixtures.duplicateAccountNotifications
|
Fixtures.duplicateAccountNotifications
|
||||||
|> Mastodon.Helper.aggregateNotifications
|
|> aggregateNotifications
|
||||||
|> List.map (.accounts >> List.length)
|
|> List.map (.accounts >> List.length)
|
||||||
|> Expect.equal [ 1 ]
|
|> Expect.equal [ 1 ]
|
||||||
, test "Add follows notification to aggregate" <|
|
, test "Add follows notification to aggregate" <|
|
||||||
\() ->
|
\() ->
|
||||||
Fixtures.notifications
|
Fixtures.notifications
|
||||||
|> Mastodon.Helper.aggregateNotifications
|
|> aggregateNotifications
|
||||||
|> (Mastodon.Helper.addNotificationToAggregates Fixtures.notificationPloumFollowsVjousse)
|
|> (addNotificationToAggregates Fixtures.notificationPloumFollowsVjousse)
|
||||||
|> Expect.equal
|
|> Expect.equal
|
||||||
[ { type_ = "mention"
|
[ { type_ = "mention"
|
||||||
, status = Just Fixtures.statusNicoToVjousse
|
, status = Just Fixtures.statusNicoToVjousse
|
||||||
@ -52,8 +75,8 @@ all =
|
|||||||
, test "Add mention notification to aggregate" <|
|
, test "Add mention notification to aggregate" <|
|
||||||
\() ->
|
\() ->
|
||||||
Fixtures.notifications
|
Fixtures.notifications
|
||||||
|> Mastodon.Helper.aggregateNotifications
|
|> aggregateNotifications
|
||||||
|> (Mastodon.Helper.addNotificationToAggregates Fixtures.notificationNicoMentionVjousse)
|
|> (addNotificationToAggregates Fixtures.notificationNicoMentionVjousse)
|
||||||
|> Expect.equal
|
|> Expect.equal
|
||||||
[ { type_ = "mention"
|
[ { type_ = "mention"
|
||||||
, status = Just Fixtures.statusNicoToVjousse
|
, status = Just Fixtures.statusNicoToVjousse
|
||||||
@ -69,8 +92,8 @@ all =
|
|||||||
, test "Add new mention notification to aggregate" <|
|
, test "Add new mention notification to aggregate" <|
|
||||||
\() ->
|
\() ->
|
||||||
Fixtures.notifications
|
Fixtures.notifications
|
||||||
|> Mastodon.Helper.aggregateNotifications
|
|> aggregateNotifications
|
||||||
|> (Mastodon.Helper.addNotificationToAggregates Fixtures.notificationNicoMentionVjousseAgain)
|
|> (addNotificationToAggregates Fixtures.notificationNicoMentionVjousseAgain)
|
||||||
|> Expect.equal
|
|> Expect.equal
|
||||||
[ { type_ = "mention"
|
[ { type_ = "mention"
|
||||||
, status = Just Fixtures.statusNicoToVjousseAgain
|
, status = Just Fixtures.statusNicoToVjousseAgain
|
||||||
@ -90,3 +113,4 @@ all =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user