1
0
Fork 0
tooty/src/Update/Mastodon.elm

334 lines
12 KiB
Elm

module Update.Mastodon exposing (update)
import Command
import Navigation
import Mastodon.Helper
import Mastodon.Model exposing (..)
import Task
import Types exposing (..)
import Update.Draft
import Update.Error exposing (..)
import Update.Timeline
errorText : Error -> String
errorText error =
case error of
MastodonError statusCode statusMsg errorMsg ->
"HTTP " ++ (toString statusCode) ++ " " ++ statusMsg ++ ": " ++ errorMsg
ServerError statusCode statusMsg errorMsg ->
"HTTP " ++ (toString statusCode) ++ " " ++ statusMsg ++ ": " ++ errorMsg
TimeoutError ->
"Request timed out."
NetworkError ->
"Unreachable host."
update : MastodonMsg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
AccessToken result ->
case result of
Ok { decoded } ->
let
client =
Client decoded.server decoded.accessToken Nothing
in
{ model | clients = client :: model.clients }
! [ Command.loadTimelines <| Just client
, Command.saveClients <| client :: model.clients
, Navigation.modifyUrl model.location.pathname
, Navigation.reload
]
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AccountFollowed result ->
case result of
Ok { decoded } ->
processFollowEvent decoded True model ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AccountUnfollowed result ->
case result of
Ok { decoded } ->
processFollowEvent decoded False model ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AppRegistered result ->
case result of
Ok { decoded } ->
{ model | registration = Just decoded }
! [ Command.saveRegistration decoded
, Command.navigateToAuthUrl decoded
]
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
ContextLoaded status result ->
case result of
Ok { decoded } ->
{ model | currentView = ThreadView (Thread status decoded) }
! [ Command.scrollToThreadStatus <| toString status.id ]
Err error ->
{ model
| currentView = LocalTimelineView
, errors = addErrorNotification (errorText error) model
}
! []
CurrentUser result ->
case result of
Ok { decoded } ->
let
updatedClients =
case model.clients of
client :: xs ->
({ client | account = Just decoded }) :: xs
_ ->
model.clients
in
{ model | currentUser = Just decoded, clients = updatedClients }
! [ Command.saveClients updatedClients ]
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
FavoriteAdded result ->
case result of
Ok _ ->
model ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
FavoriteRemoved result ->
case result of
Ok _ ->
model ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
LocalTimeline append result ->
case result of
Ok { decoded, links } ->
{ model | localTimeline = Update.Timeline.update append decoded links model.localTimeline } ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
Notifications append result ->
case result of
Ok { decoded, links } ->
let
aggregated =
Mastodon.Helper.aggregateNotifications decoded
in
{ model | notifications = Update.Timeline.update append aggregated links model.notifications } ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
GlobalTimeline append result ->
case result of
Ok { decoded, links } ->
{ model | globalTimeline = Update.Timeline.update append decoded links model.globalTimeline } ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
FavoriteTimeline append result ->
case result of
Ok { decoded, links } ->
{ model | favoriteTimeline = Update.Timeline.update append decoded links model.favoriteTimeline } ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
Reblogged result ->
case result of
Ok _ ->
model ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
StatusPosted _ ->
-- FIXME: here we should rather send a ClearDraft command, and update the
-- ClearDraft message handler to update DOM status
let
draft =
Update.Draft.empty
in
{ model | draft = draft }
! [ Command.scrollColumnToTop "home-timeline"
, Command.updateDomStatus draft.status
]
StatusDeleted result ->
case result of
Ok { decoded } ->
Update.Timeline.deleteStatusFromAllTimelines decoded model ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
Unreblogged result ->
case result of
Ok _ ->
model ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AccountReceived result ->
case result of
Ok { decoded } ->
{ model
| currentView = AccountView decoded
, accountRelationships = []
}
! [ Command.loadAccountTimeline
(List.head model.clients)
decoded.id
model.accountTimeline.links.next
]
Err error ->
{ model
| currentView = LocalTimelineView
, errors = addErrorNotification (errorText error) model
}
! []
AccountTimeline append result ->
case result of
Ok { decoded, links } ->
{ model | accountTimeline = Update.Timeline.update append decoded links model.accountTimeline } ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AccountFollowers append result ->
case result of
Ok { decoded, links } ->
{ model | accountFollowers = Update.Timeline.update append decoded links model.accountFollowers }
! [ Command.loadRelationships (List.head model.clients) <| List.map .id decoded ]
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AccountFollowing append result ->
case result of
Ok { decoded, links } ->
{ model | accountFollowing = Update.Timeline.update append decoded links model.accountFollowing }
! [ Command.loadRelationships (List.head model.clients) <| List.map .id decoded ]
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AccountRelationship result ->
case result of
Ok { decoded } ->
case decoded of
[ relationship ] ->
{ model | accountRelationship = Just relationship } ! []
_ ->
model ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AccountRelationships result ->
case result of
Ok { decoded } ->
{ model
| accountRelationships = List.concat [ model.accountRelationships, decoded ]
}
! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
HomeTimeline append result ->
case result of
Ok { decoded, links } ->
{ model | homeTimeline = Update.Timeline.update append decoded links model.homeTimeline } ! []
Err error ->
{ model | errors = addErrorNotification (errorText error) model } ! []
AutoSearch result ->
let
draft =
model.draft
in
case result of
Ok { decoded } ->
{ model
| draft =
{ draft
| showAutoMenu =
Update.Draft.showAutoMenu
decoded
draft.autoAtPosition
draft.autoQuery
, autoAccounts = decoded
}
}
-- Force selection of the first item after each
-- Successfull request
! [ Task.perform identity (Task.succeed ((DraftEvent << ResetAutocomplete) True)) ]
Err error ->
{ model
| draft = { draft | showAutoMenu = False }
, errors = addErrorNotification (errorText error) model
}
! []
{-| Update viewed account relationships as well as the relationship with the
current connected user, both according to the "following" status provided.
-}
processFollowEvent : Relationship -> Bool -> Model -> Model
processFollowEvent relationship flag model =
let
updateRelationship r =
if r.id == relationship.id then
{ r | following = flag }
else
r
accountRelationships =
model.accountRelationships |> List.map updateRelationship
accountRelationship =
case model.accountRelationship of
Just accountRelationship ->
if accountRelationship.id == relationship.id then
Just { relationship | following = flag }
else
model.accountRelationship
Nothing ->
Nothing
in
{ model
| accountRelationships = accountRelationships
, accountRelationship = accountRelationship
}