diff --git a/src/Command.elm b/src/Command.elm index fba5c45..cf970b7 100644 --- a/src/Command.elm +++ b/src/Command.elm @@ -10,6 +10,7 @@ module Command , loadAccount , loadAccountFollowers , loadAccountFollowing + , loadAccountPins , loadHomeTimeline , loadLocalTimeline , loadGlobalTimeline @@ -186,6 +187,20 @@ loadAccount client accountId = Cmd.none +loadAccountPins : Maybe Client -> String -> Maybe String -> Cmd Msg +loadAccountPins client accountId url = + case client of + Just client -> + HttpBuilder.get (Maybe.withDefault (ApiUrl.accountTimeline accountId) url) + |> withClient client + |> withBodyDecoder (Decode.list statusDecoder) + |> withQueryParams [ ( "pinned", "true" ) ] + |> send (MastodonEvent << AccountPins (url /= Nothing)) + + Nothing -> + Cmd.none + + loadAccountFollowers : Maybe Client -> String -> Maybe String -> Cmd Msg loadAccountFollowers client accountId url = case client of diff --git a/src/Mastodon/Decoder.elm b/src/Mastodon/Decoder.elm index bea2b97..7eeb467 100644 --- a/src/Mastodon/Decoder.elm +++ b/src/Mastodon/Decoder.elm @@ -253,6 +253,7 @@ statusDecoder = |> Pipe.required "uri" Decode.string |> Pipe.required "url" (Decode.nullable Decode.string) |> Pipe.required "visibility" Decode.string + |> Pipe.optional "pinned" Decode.bool False -- Not a real value, used to show pinned indicator webSocketEventDecoder : Decode.Decoder WebSocketMessage diff --git a/src/Mastodon/Model.elm b/src/Mastodon/Model.elm index 0d38a32..bb69707 100644 --- a/src/Mastodon/Model.elm +++ b/src/Mastodon/Model.elm @@ -260,6 +260,7 @@ type alias Status = , uri : String , url : Maybe String , visibility : String + , pinned : Bool -- Not a real value, used to show pinned indicator } diff --git a/src/Types.elm b/src/Types.elm index e0ae6a8..9476eb4 100644 --- a/src/Types.elm +++ b/src/Types.elm @@ -50,6 +50,7 @@ type MastodonMsg | AccountFollowing Bool (MastodonResult (List Account)) | AccountBlocked Account (MastodonResult Relationship) | AccountMuted Account (MastodonResult Relationship) + | AccountPins Bool (MastodonResult (List Status)) | AccountReceived (MastodonResult Account) | AccountRelationship (MastodonResult (List Relationship)) | AccountRelationships (MastodonResult (List Relationship)) @@ -135,6 +136,7 @@ type Msg type alias AccountInfo = { account : Maybe Account + , pins : List Status , timeline : Timeline Status , followers : Timeline Account , following : Timeline Account diff --git a/src/Update/AccountInfo.elm b/src/Update/AccountInfo.elm index 6903e4a..0de9023 100644 --- a/src/Update/AccountInfo.elm +++ b/src/Update/AccountInfo.elm @@ -7,6 +7,7 @@ import Update.Timeline empty : AccountInfo empty = { account = Nothing + , pins = [] , timeline = Update.Timeline.empty "account-timeline" , followers = Update.Timeline.empty "account-followers" , following = Update.Timeline.empty "account-following" diff --git a/src/Update/Mastodon.elm b/src/Update/Mastodon.elm index 12a8c00..abd0d3c 100644 --- a/src/Update/Mastodon.elm +++ b/src/Update/Mastodon.elm @@ -275,6 +275,20 @@ update msg ({ accountInfo, search } as model) = Err error -> { model | errors = addErrorNotification (errorText error) model } ! [] + AccountPins append result -> + case result of + Ok { decoded, links } -> + { model + | accountInfo = + { accountInfo + | pins = decoded + } + } + ! [] + + Err error -> + { model | errors = addErrorNotification (errorText error) model } ! [] + AccountTimeline append result -> case result of Ok { decoded, links } -> diff --git a/src/Update/Route.elm b/src/Update/Route.elm index a441e48..9b303b3 100644 --- a/src/Update/Route.elm +++ b/src/Update/Route.elm @@ -96,6 +96,7 @@ update ({ accountInfo } as model) = , accountInfo = Update.AccountInfo.empty } ! [ Command.loadAccount (List.head model.clients) accountId + , Command.loadAccountPins (List.head model.clients) accountId Nothing , Command.loadAccountTimeline (List.head model.clients) accountId Nothing ] diff --git a/src/View/Account.elm b/src/View/Account.elm index 51e16b9..c2df6c0 100644 --- a/src/View/Account.elm +++ b/src/View/Account.elm @@ -175,8 +175,8 @@ accountFollowView view currentUser accountInfo = text "" -accountTimelineView : CurrentUser -> AccountInfo -> Html Msg -accountTimelineView currentUser accountInfo = +accountTimelineView : CurrentUser -> AccountInfo -> Bool -> Html Msg +accountTimelineView currentUser accountInfo pins = let keyedEntry status = ( extractStatusId status.id @@ -185,11 +185,17 @@ accountTimelineView currentUser accountInfo = entries = List.map keyedEntry accountInfo.timeline.entries + + setPin status = + { status | pinned = True } + + pins = + List.map keyedEntry (List.map setPin accountInfo.pins) in case accountInfo.account of Just account -> Keyed.ul [ id accountInfo.timeline.id, class "list-group" ] <| - (entries ++ [ ( "load-more", Common.loadMoreBtn accountInfo.timeline ) ]) + List.append pins (entries ++ [ ( "load-more", Common.loadMoreBtn accountInfo.timeline ) ]) Nothing -> text "" @@ -341,10 +347,10 @@ accountView subView currentUser accountInfo = , counterLinks subView account , case subView of AccountStatusesView -> - accountTimelineView currentUser accountInfo + accountTimelineView currentUser accountInfo True AccountStatusesRepliesView -> - accountTimelineView currentUser accountInfo + accountTimelineView currentUser accountInfo False _ -> accountFollowView subView currentUser accountInfo diff --git a/src/View/Status.elm b/src/View/Status.elm index 06d5fb1..caf689e 100644 --- a/src/View/Status.elm +++ b/src/View/Status.elm @@ -205,10 +205,19 @@ statusEntryView context className currentUser status = statusView : String -> Status -> Html Msg -statusView context ({ account, content, media_attachments, reblog, mentions } as status) = +statusView context ({ account, content, media_attachments, reblog, mentions, pinned } as status) = let accountLinkAttributes = [ href <| "#account/" ++ account.id ] + + pin = + if pinned then + p [ class "status-info" ] + [ Common.icon "pushpin" + , text " Pinned status" + ] + else + text "" in case reblog of Just (Reblog reblog) -> @@ -224,7 +233,8 @@ statusView context ({ account, content, media_attachments, reblog, mentions } as Nothing -> div [ class "status" ] - [ Common.accountAvatarLink False account + [ pin + , Common.accountAvatarLink False account , div [ class "username" ] [ a accountLinkAttributes [ text (if account.display_name=="" then account.username else account.display_name)