diff --git a/src/Command.elm b/src/Command.elm index f512716..532471d 100644 --- a/src/Command.elm +++ b/src/Command.elm @@ -472,27 +472,27 @@ unfavouriteStatus client statusId = Cmd.none -follow : Maybe Client -> Int -> Cmd Msg -follow client id = +follow : Maybe Client -> Account -> Cmd Msg +follow client account = case client of Just client -> - HttpBuilder.post (ApiUrl.follow id) + HttpBuilder.post (ApiUrl.follow account.id) |> withClient client |> withBodyDecoder relationshipDecoder - |> send (MastodonEvent << AccountFollowed) + |> send (MastodonEvent << (AccountFollowed account)) Nothing -> Cmd.none -unfollow : Maybe Client -> Int -> Cmd Msg -unfollow client id = +unfollow : Maybe Client -> Account -> Cmd Msg +unfollow client account = case client of Just client -> - HttpBuilder.post (ApiUrl.unfollow id) + HttpBuilder.post (ApiUrl.unfollow account.id) |> withClient client |> withBodyDecoder relationshipDecoder - |> send (MastodonEvent << AccountUnfollowed) + |> send (MastodonEvent << (AccountUnfollowed account)) Nothing -> Cmd.none diff --git a/src/Types.elm b/src/Types.elm index 5d3224f..2af2142 100644 --- a/src/Types.elm +++ b/src/Types.elm @@ -42,14 +42,14 @@ type alias MastodonResult a = type MastodonMsg = AccessToken (MastodonResult AccessTokenResult) - | AccountFollowed (MastodonResult Relationship) + | AccountFollowed Account (MastodonResult Relationship) | AccountFollowers Bool (MastodonResult (List Account)) | AccountFollowing Bool (MastodonResult (List Account)) | AccountReceived (MastodonResult Account) | AccountRelationship (MastodonResult (List Relationship)) | AccountRelationships (MastodonResult (List Relationship)) | AccountTimeline Bool (MastodonResult (List Status)) - | AccountUnfollowed (MastodonResult Relationship) + | AccountUnfollowed Account (MastodonResult Relationship) | AppRegistered (MastodonResult AppRegistration) | AutoSearch (MastodonResult (List Account)) | ContextLoaded Status (MastodonResult Context) @@ -85,7 +85,7 @@ type Msg | DeleteStatus Int | DraftEvent DraftMsg | FilterNotifications NotificationFilter - | FollowAccount Int + | FollowAccount Account | LoadAccount Int | LogoutClient Client | TimelineLoadNext String String @@ -101,7 +101,7 @@ type Msg | SubmitDraft | SwitchClient Client | Tick Time - | UnfollowAccount Int + | UnfollowAccount Account | UrlChange Navigation.Location | UnreblogStatus Status | ViewAccountFollowing Account diff --git a/src/Update/Main.elm b/src/Update/Main.elm index 8e55836..6a6fc64 100644 --- a/src/Update/Main.elm +++ b/src/Update/Main.elm @@ -135,11 +135,11 @@ update msg model = CloseThread -> { model | currentView = LocalTimelineView } ! [] - FollowAccount id -> - model ! [ Command.follow (List.head model.clients) id ] + FollowAccount account -> + model ! [ Command.follow (List.head model.clients) account ] - UnfollowAccount id -> - model ! [ Command.unfollow (List.head model.clients) id ] + UnfollowAccount account -> + model ! [ Command.unfollow (List.head model.clients) account ] DeleteStatus id -> model ! [ Command.deleteStatus (List.head model.clients) id ] diff --git a/src/Update/Mastodon.elm b/src/Update/Mastodon.elm index 2e81754..67d39fc 100644 --- a/src/Update/Mastodon.elm +++ b/src/Update/Mastodon.elm @@ -47,7 +47,7 @@ update msg model = Err error -> { model | errors = addErrorNotification (errorText error) model } ! [] - AccountFollowed result -> + AccountFollowed _ result -> case result of Ok { decoded } -> processFollowEvent decoded True model ! [] @@ -55,10 +55,10 @@ update msg model = Err error -> { model | errors = addErrorNotification (errorText error) model } ! [] - AccountUnfollowed result -> + AccountUnfollowed account result -> case result of Ok { decoded } -> - processFollowEvent decoded False model ! [] + processUnfollowEvent account decoded model ! [] Err error -> { model | errors = addErrorNotification (errorText error) model } ! [] @@ -328,3 +328,19 @@ processFollowEvent relationship flag model = | accountRelationships = accountRelationships , accountRelationship = accountRelationship } + + +processUnfollowEvent : Account -> Relationship -> Model -> Model +processUnfollowEvent account relationship model = + let + newModel = + processFollowEvent relationship False model + in + case model.currentUser of + Just currentUser -> + { newModel + | homeTimeline = Update.Timeline.cleanUnfollow account currentUser model.homeTimeline + } + + Nothing -> + newModel diff --git a/src/Update/Timeline.elm b/src/Update/Timeline.elm index 5b0573a..d2ecd40 100644 --- a/src/Update/Timeline.elm +++ b/src/Update/Timeline.elm @@ -1,6 +1,7 @@ module Update.Timeline exposing - ( deleteStatusFromAllTimelines + ( cleanUnfollow + , deleteStatusFromAllTimelines , deleteStatus , empty , markAsLoading @@ -17,6 +18,30 @@ import Mastodon.Model exposing (..) import Types exposing (..) +type alias CurrentUser = + Account + + +{-| Remove statuses from a given account when they're not a direct mention to +the current user. This is typically used after an account has been unfollowed. +-} +cleanUnfollow : Account -> CurrentUser -> Timeline Status -> Timeline Status +cleanUnfollow account currentUser timeline = + let + keep status = + if Mastodon.Helper.sameAccount account status.account then + case List.head status.mentions of + Just mention -> + mention.id == currentUser.id && mention.acct == currentUser.acct + + Nothing -> + False + else + True + in + { timeline | entries = List.filter keep timeline.entries } + + deleteStatusFromCurrentView : Int -> Model -> CurrentView deleteStatusFromCurrentView id model = -- Note: account timeline is already cleaned in deleteStatusFromAllTimelines diff --git a/src/View/Account.elm b/src/View/Account.elm index ec1f1df..f6c6776 100644 --- a/src/View/Account.elm +++ b/src/View/Account.elm @@ -58,13 +58,13 @@ followButton currentUser relationship account = Just relationship -> if relationship.following then - ( UnfollowAccount account.id + ( UnfollowAccount account , "btn btn-default btn-primary" , "eye-close" , "Unfollow" ) else - ( FollowAccount account.id + ( FollowAccount account , "btn btn-default" , "eye-open" , "Follow" diff --git a/tests/Fixtures.elm b/tests/Fixtures.elm index 69158fa..8d8e640 100644 --- a/tests/Fixtures.elm +++ b/tests/Fixtures.elm @@ -75,6 +75,31 @@ accountPloum = } +statusNico : Status +statusNico = + { account = accountNico + , application = Nothing + , content = "

hello

" + , created_at = "2017-04-24T20:12:20.922Z" + , favourited = Nothing + , favourites_count = 0 + , id = 737931 + , in_reply_to_account_id = Nothing + , in_reply_to_id = Nothing + , media_attachments = [] + , mentions = [] + , reblog = Nothing + , reblogged = Nothing + , reblogs_count = 0 + , sensitive = Just False + , spoiler_text = "" + , tags = [] + , uri = "tag:mamot.fr,2017-04-24:objectId=737932:objectType=Status" + , url = Just "https://mamot.fr/@n1k0/737931" + , visibility = "public" + } + + statusNicoToVjousse : Status statusNicoToVjousse = { account = accountNico diff --git a/tests/Main.elm b/tests/Main.elm index 6a023e0..18531a7 100644 --- a/tests/Main.elm +++ b/tests/Main.elm @@ -2,6 +2,7 @@ port module Main exposing (..) import MastodonTest.HelperTest import MastodonTest.HttpTest +import UpdateTest.TimelineTest import Test import Test.Runner.Node exposing (run, TestProgram) import Json.Encode exposing (Value) @@ -13,6 +14,7 @@ main = Test.concat [ MastodonTest.HelperTest.all , MastodonTest.HttpTest.all + , UpdateTest.TimelineTest.all ] diff --git a/tests/UpdateTest/TimelineTest.elm b/tests/UpdateTest/TimelineTest.elm new file mode 100644 index 0000000..1fa11fb --- /dev/null +++ b/tests/UpdateTest/TimelineTest.elm @@ -0,0 +1,39 @@ +module UpdateTest.TimelineTest exposing (..) + +import Test exposing (..) +import Update.Timeline +import Expect +import Fixtures + + +all : Test +all = + describe "Update.Timeline tests" + [ describe "removeAccountStatuses" + [ test "Remove account statuses" <| + \() -> + let + timeline = + { id = "foo" + , entries = + [ Fixtures.statusNico -- discard + , Fixtures.statusNicoToVjousse + , Fixtures.statusNicoToVjousseAgain + , Fixtures.statusPloumToVjousse + , Fixtures.statusReblogged + ] + , links = { prev = Nothing, next = Nothing } + , loading = False + } + in + timeline + |> Update.Timeline.removeAccountStatuses Fixtures.accountNico Fixtures.accountVjousse + |> .entries + |> Expect.equal + [ Fixtures.statusNicoToVjousse + , Fixtures.statusNicoToVjousseAgain + , Fixtures.statusPloumToVjousse + , Fixtures.statusReblogged + ] + ] + ] diff --git a/tests/elm-package.json b/tests/elm-package.json index f59b3a0..5387fd6 100644 --- a/tests/elm-package.json +++ b/tests/elm-package.json @@ -28,7 +28,8 @@ "elm-lang/websocket": "1.0.2 <= v < 2.0.0", "evancz/url-parser": "2.0.1 <= v < 3.0.0", "jinjor/elm-html-parser": "1.1.5 <= v < 2.0.0", - "lukewestby/elm-http-builder": "5.1.0 <= v < 6.0.0" + "lukewestby/elm-http-builder": "5.1.0 <= v < 6.0.0", + "thebritican/elm-autocomplete": "4.0.3 <= v < 5.0.0" }, "elm-version": "0.18.0 <= v < 0.19.0" }