1
0
Fork 0
tooty/src/Model.elm

859 lines
27 KiB
Elm
Raw Normal View History

2017-04-20 07:46:18 +00:00
module Model exposing (..)
import Dom
2017-04-20 07:46:18 +00:00
import Json.Encode as Encode
import Navigation
2017-04-27 14:34:27 +00:00
import Mastodon.Decoder
import Mastodon.Encoder
import Mastodon.Helper
import Mastodon.Http
import Mastodon.Model
import Mastodon.WebSocket
2017-04-20 07:46:18 +00:00
import Ports
import Task
import Dom.Scroll
2017-04-20 07:46:18 +00:00
maxBuffer : Int
maxBuffer =
-- Max number of entries to keep in columns
100
2017-04-20 07:46:18 +00:00
type alias Flags =
2017-04-27 14:34:27 +00:00
{ client : Maybe Mastodon.Model.Client
, registration : Maybe Mastodon.Model.AppRegistration
2017-04-20 07:46:18 +00:00
}
2017-04-20 18:30:19 +00:00
type DraftMsg
= ClearDraft
2017-04-20 18:30:19 +00:00
| UpdateSensitive Bool
| UpdateSpoiler String
| UpdateStatus String
2017-04-21 12:03:39 +00:00
| UpdateVisibility String
2017-04-27 14:34:27 +00:00
| UpdateReplyTo Mastodon.Model.Status
| ToggleSpoiler Bool
2017-04-20 18:30:19 +00:00
2017-04-24 19:21:43 +00:00
type ViewerMsg
= CloseViewer
2017-04-27 14:34:27 +00:00
| OpenViewer (List Mastodon.Model.Attachment) Mastodon.Model.Attachment
2017-04-24 19:21:43 +00:00
type MastodonMsg
2017-04-27 14:34:27 +00:00
= AccessToken (Result Mastodon.Model.Error Mastodon.Model.AccessTokenResult)
| AppRegistered (Result Mastodon.Model.Error Mastodon.Model.AppRegistration)
| ContextLoaded Mastodon.Model.Status (Result Mastodon.Model.Error Mastodon.Model.Context)
| CurrentUser (Result Mastodon.Model.Error Mastodon.Model.Account)
2017-04-27 14:34:27 +00:00
| FavoriteAdded (Result Mastodon.Model.Error Mastodon.Model.Status)
| FavoriteRemoved (Result Mastodon.Model.Error Mastodon.Model.Status)
| LocalTimeline (Result Mastodon.Model.Error (List Mastodon.Model.Status))
| Notifications (Result Mastodon.Model.Error (List Mastodon.Model.Notification))
| GlobalTimeline (Result Mastodon.Model.Error (List Mastodon.Model.Status))
| Reblogged (Result Mastodon.Model.Error Mastodon.Model.Status)
2017-04-29 07:20:26 +00:00
| StatusDeleted (Result Mastodon.Model.Error Int)
2017-04-27 14:34:27 +00:00
| StatusPosted (Result Mastodon.Model.Error Mastodon.Model.Status)
| Unreblogged (Result Mastodon.Model.Error Mastodon.Model.Status)
2017-04-27 20:01:51 +00:00
| Account (Result Mastodon.Model.Error Mastodon.Model.Account)
| AccountTimeline (Result Mastodon.Model.Error (List Mastodon.Model.Status))
2017-04-27 14:34:27 +00:00
| UserTimeline (Result Mastodon.Model.Error (List Mastodon.Model.Status))
type WebSocketMsg
= NewWebsocketUserMessage String
| NewWebsocketGlobalMessage String
| NewWebsocketLocalMessage String
type Msg
= AddFavorite Int
| ClearOpenedAccount
| CloseThread
| DomResult (Result Dom.Error ())
2017-04-29 07:20:26 +00:00
| DeleteStatus Int
2017-04-20 18:30:19 +00:00
| DraftEvent DraftMsg
2017-04-27 20:01:51 +00:00
| LoadAccount Int
| MastodonEvent MastodonMsg
| NoOp
| OpenThread Mastodon.Model.Status
| Reblog Int
2017-04-20 07:46:18 +00:00
| Register
| RemoveFavorite Int
2017-04-20 07:46:18 +00:00
| ServerChange String
2017-04-20 18:30:19 +00:00
| SubmitDraft
2017-04-20 07:46:18 +00:00
| UrlChange Navigation.Location
| UseGlobalTimeline Bool
| Unreblog Int
2017-04-24 19:21:43 +00:00
| ViewerEvent ViewerMsg
| WebSocketEvent WebSocketMsg
| ScrollColumn String
2017-04-20 07:46:18 +00:00
type alias Draft =
{ status : String
2017-04-27 14:34:27 +00:00
, in_reply_to : Maybe Mastodon.Model.Status
, spoiler_text : Maybe String
, sensitive : Bool
, visibility : String
}
type alias Thread =
{ status : Mastodon.Model.Status
, context : Mastodon.Model.Context
}
2017-04-24 19:21:43 +00:00
type alias Viewer =
2017-04-27 14:34:27 +00:00
{ attachments : List Mastodon.Model.Attachment
, attachment : Mastodon.Model.Attachment
2017-04-24 19:21:43 +00:00
}
type CurrentView
= -- Basically, what we should be displaying in the fourth column
AccountView Mastodon.Model.Account
| ThreadView Thread
| LocalTimelineView
| GlobalTimelineView
2017-04-20 07:46:18 +00:00
type alias Model =
{ server : String
2017-04-27 14:34:27 +00:00
, registration : Maybe Mastodon.Model.AppRegistration
, client : Maybe Mastodon.Model.Client
, userTimeline : List Mastodon.Model.Status
, localTimeline : List Mastodon.Model.Status
, globalTimeline : List Mastodon.Model.Status
2017-04-27 20:01:51 +00:00
, accountTimeline : List Mastodon.Model.Status
2017-04-27 14:34:27 +00:00
, notifications : List Mastodon.Model.NotificationAggregate
, draft : Draft
2017-04-20 07:46:18 +00:00
, errors : List String
, location : Navigation.Location
, useGlobalTimeline : Bool
2017-04-24 19:21:43 +00:00
, viewer : Maybe Viewer
, currentUser : Maybe Mastodon.Model.Account
, currentView : CurrentView
2017-04-20 07:46:18 +00:00
}
extractAuthCode : Navigation.Location -> Maybe String
extractAuthCode { search } =
case (String.split "?code=" search) of
[ _, authCode ] ->
Just authCode
_ ->
Nothing
defaultDraft : Draft
2017-04-20 18:30:19 +00:00
defaultDraft =
{ status = ""
, in_reply_to = Nothing
2017-04-20 18:30:19 +00:00
, spoiler_text = Nothing
, sensitive = False
, visibility = "public"
}
2017-04-20 07:46:18 +00:00
init : Flags -> Navigation.Location -> ( Model, Cmd Msg )
init flags location =
let
authCode =
extractAuthCode location
in
{ server = ""
, registration = flags.registration
, client = flags.client
, userTimeline = []
, localTimeline = []
, globalTimeline = []
2017-04-27 20:01:51 +00:00
, accountTimeline = []
, notifications = []
2017-04-20 18:30:19 +00:00
, draft = defaultDraft
2017-04-20 07:46:18 +00:00
, errors = []
, location = location
, useGlobalTimeline = False
2017-04-24 19:21:43 +00:00
, viewer = Nothing
, currentView = LocalTimelineView
, currentUser = Nothing
2017-04-20 07:46:18 +00:00
}
! [ initCommands flags.registration flags.client authCode ]
2017-04-27 14:34:27 +00:00
initCommands : Maybe Mastodon.Model.AppRegistration -> Maybe Mastodon.Model.Client -> Maybe String -> Cmd Msg
2017-04-20 07:46:18 +00:00
initCommands registration client authCode =
Cmd.batch <|
case authCode of
Just authCode ->
case registration of
Just registration ->
2017-04-27 14:34:27 +00:00
[ Mastodon.Http.getAccessToken registration authCode
|> Mastodon.Http.send (MastodonEvent << AccessToken)
]
2017-04-20 07:46:18 +00:00
Nothing ->
[]
Nothing ->
[ loadUserAccount client, loadTimelines client ]
2017-04-20 07:46:18 +00:00
registerApp : Model -> Cmd Msg
registerApp { server, location } =
let
appUrl =
location.origin ++ location.pathname
cleanServer =
if String.endsWith "/" server then
String.dropRight 1 server
else
server
2017-04-20 07:46:18 +00:00
in
2017-04-27 14:34:27 +00:00
Mastodon.Http.register
cleanServer
2017-04-20 07:46:18 +00:00
"tooty"
appUrl
"read write follow"
"https://github.com/n1k0/tooty"
2017-04-27 14:34:27 +00:00
|> Mastodon.Http.send (MastodonEvent << AppRegistered)
2017-04-20 07:46:18 +00:00
2017-04-27 14:34:27 +00:00
saveClient : Mastodon.Model.Client -> Cmd Msg
2017-04-20 07:46:18 +00:00
saveClient client =
2017-04-27 14:34:27 +00:00
Mastodon.Encoder.clientEncoder client
2017-04-20 07:46:18 +00:00
|> Encode.encode 0
|> Ports.saveClient
2017-04-27 14:34:27 +00:00
saveRegistration : Mastodon.Model.AppRegistration -> Cmd Msg
2017-04-20 07:46:18 +00:00
saveRegistration registration =
2017-04-27 14:34:27 +00:00
Mastodon.Encoder.registrationEncoder registration
2017-04-20 07:46:18 +00:00
|> Encode.encode 0
|> Ports.saveRegistration
2017-04-27 14:34:27 +00:00
loadNotifications : Maybe Mastodon.Model.Client -> Cmd Msg
loadNotifications client =
case client of
Just client ->
2017-04-27 14:34:27 +00:00
Mastodon.Http.fetchNotifications client
|> Mastodon.Http.send (MastodonEvent << Notifications)
Nothing ->
Cmd.none
loadUserAccount : Maybe Mastodon.Model.Client -> Cmd Msg
loadUserAccount client =
case client of
Just client ->
Mastodon.Http.userAccount client
|> Mastodon.Http.send (MastodonEvent << CurrentUser)
Nothing ->
Cmd.none
2017-04-27 14:34:27 +00:00
loadTimelines : Maybe Mastodon.Model.Client -> Cmd Msg
2017-04-20 07:46:18 +00:00
loadTimelines client =
2017-04-20 18:30:19 +00:00
case client of
Just client ->
Cmd.batch
2017-04-27 14:34:27 +00:00
[ Mastodon.Http.fetchUserTimeline client
|> Mastodon.Http.send (MastodonEvent << UserTimeline)
, Mastodon.Http.fetchLocalTimeline client
|> Mastodon.Http.send (MastodonEvent << LocalTimeline)
, Mastodon.Http.fetchGlobalTimeline client
|> Mastodon.Http.send (MastodonEvent << GlobalTimeline)
, loadNotifications <| Just client
2017-04-20 18:30:19 +00:00
]
Nothing ->
Cmd.none
preferredTimeline : Model -> CurrentView
preferredTimeline model =
if model.useGlobalTimeline then
GlobalTimelineView
else
LocalTimelineView
truncate : List a -> List a
truncate entries =
List.take maxBuffer entries
2017-04-27 14:34:27 +00:00
postStatus : Mastodon.Model.Client -> Mastodon.Model.StatusRequestBody -> Cmd Msg
2017-04-20 18:30:19 +00:00
postStatus client draft =
2017-04-27 14:34:27 +00:00
Mastodon.Http.postStatus client draft
|> Mastodon.Http.send (MastodonEvent << StatusPosted)
2017-04-20 07:46:18 +00:00
2017-04-29 07:20:26 +00:00
deleteStatus : Mastodon.Model.Client -> Int -> Cmd Msg
deleteStatus client id =
Mastodon.Http.deleteStatus client id
|> Mastodon.Http.send (MastodonEvent << StatusDeleted)
2017-04-27 14:34:27 +00:00
errorText : Mastodon.Model.Error -> String
2017-04-20 07:46:18 +00:00
errorText error =
case error of
2017-04-27 14:34:27 +00:00
Mastodon.Model.MastodonError statusCode statusMsg errorMsg ->
2017-04-20 07:46:18 +00:00
"HTTP " ++ (toString statusCode) ++ " " ++ statusMsg ++ ": " ++ errorMsg
2017-04-27 14:34:27 +00:00
Mastodon.Model.ServerError statusCode statusMsg errorMsg ->
2017-04-20 07:46:18 +00:00
"HTTP " ++ (toString statusCode) ++ " " ++ statusMsg ++ ": " ++ errorMsg
2017-04-27 14:34:27 +00:00
Mastodon.Model.TimeoutError ->
2017-04-20 07:46:18 +00:00
"Request timed out."
2017-04-27 14:34:27 +00:00
Mastodon.Model.NetworkError ->
2017-04-20 07:46:18 +00:00
"Unreachable host."
2017-04-27 14:34:27 +00:00
toStatusRequestBody : Draft -> Mastodon.Model.StatusRequestBody
toStatusRequestBody draft =
{ status = draft.status
, in_reply_to_id =
case draft.in_reply_to of
Just status ->
Just status.id
Nothing ->
Nothing
, spoiler_text = draft.spoiler_text
, sensitive = draft.sensitive
, visibility = draft.visibility
}
2017-04-27 14:34:27 +00:00
updateTimelinesWithBoolFlag : Int -> Bool -> (Mastodon.Model.Status -> Mastodon.Model.Status) -> Model -> Model
updateTimelinesWithBoolFlag statusId flag statusUpdater model =
let
update flag status =
2017-04-27 14:34:27 +00:00
if (Mastodon.Helper.extractReblog status).id == statusId then
statusUpdater status
else
status
in
{ model
| userTimeline = List.map (update flag) model.userTimeline
, localTimeline = List.map (update flag) model.localTimeline
, globalTimeline = List.map (update flag) model.globalTimeline
}
processFavourite : Int -> Bool -> Model -> Model
processFavourite statusId flag model =
updateTimelinesWithBoolFlag statusId flag (\s -> { s | favourited = Just flag }) model
processReblog : Int -> Bool -> Model -> Model
processReblog statusId flag model =
updateTimelinesWithBoolFlag statusId flag (\s -> { s | reblogged = Just flag }) model
2017-04-27 14:34:27 +00:00
deleteStatusFromTimeline : Int -> List Mastodon.Model.Status -> List Mastodon.Model.Status
deleteStatusFromTimeline statusId timeline =
timeline
2017-04-27 14:34:27 +00:00
|> List.filter
(\s ->
s.id
/= statusId
&& (Mastodon.Helper.extractReblog s).id
/= statusId
)
updateDraft : DraftMsg -> Mastodon.Model.Account -> Draft -> ( Draft, Cmd Msg )
updateDraft draftMsg currentUser draft =
2017-04-20 18:30:19 +00:00
case draftMsg of
ClearDraft ->
defaultDraft ! []
2017-04-20 18:30:19 +00:00
ToggleSpoiler enabled ->
{ draft
| spoiler_text =
if enabled then
Just ""
else
Nothing
}
! []
2017-04-20 18:30:19 +00:00
UpdateSensitive sensitive ->
{ draft | sensitive = sensitive } ! []
2017-04-20 18:30:19 +00:00
UpdateSpoiler spoiler_text ->
{ draft | spoiler_text = Just spoiler_text } ! []
2017-04-20 18:30:19 +00:00
UpdateStatus status ->
{ draft | status = status } ! []
2017-04-20 18:30:19 +00:00
2017-04-21 12:03:39 +00:00
UpdateVisibility visibility ->
{ draft | visibility = visibility } ! []
UpdateReplyTo status ->
{ draft
| in_reply_to = Just status
, status = Mastodon.Helper.getReplyPrefix currentUser status
, sensitive = Maybe.withDefault False status.sensitive
, spoiler_text =
if status.spoiler_text == "" then
Nothing
else
Just status.spoiler_text
, visibility = status.visibility
}
! [ Dom.focus "status" |> Task.attempt (always NoOp) ]
2017-04-20 18:30:19 +00:00
2017-04-24 19:21:43 +00:00
updateViewer : ViewerMsg -> Maybe Viewer -> ( Maybe Viewer, Cmd Msg )
updateViewer viewerMsg viewer =
case viewerMsg of
CloseViewer ->
Nothing ! []
OpenViewer attachments attachment ->
(Just <| Viewer attachments attachment) ! []
processMastodonEvent : MastodonMsg -> Model -> ( Model, Cmd Msg )
processMastodonEvent msg model =
2017-04-20 07:46:18 +00:00
case msg of
AccessToken result ->
case result of
Ok { server, accessToken } ->
let
client =
2017-04-27 14:34:27 +00:00
Mastodon.Model.Client server accessToken
in
{ model | client = Just client }
! [ loadTimelines <| Just client
, Navigation.modifyUrl model.location.pathname
, saveClient client
]
2017-04-20 07:46:18 +00:00
Err error ->
{ model | errors = (errorText error) :: model.errors } ! []
2017-04-20 07:46:18 +00:00
AppRegistered result ->
case result of
Ok registration ->
{ model | registration = Just registration }
! [ saveRegistration registration
2017-04-27 14:34:27 +00:00
, Navigation.load <| Mastodon.Http.getAuthorizationUrl registration
2017-04-20 07:46:18 +00:00
]
Err error ->
{ model | errors = (errorText error) :: model.errors } ! []
ContextLoaded status result ->
case result of
Ok context ->
let
thread =
Thread status context
in
{ model | currentView = ThreadView thread } ! []
Err error ->
{ model
| currentView = preferredTimeline model
, errors = (errorText error) :: model.errors
}
! []
CurrentUser result ->
case result of
Ok currentUser ->
{ model | currentUser = Just currentUser } ! []
Err error ->
{ model | errors = (errorText error) :: model.errors } ! []
FavoriteAdded result ->
2017-04-20 07:46:18 +00:00
case result of
Ok status ->
processFavourite status.id True model ! [ loadNotifications model.client ]
2017-04-20 07:46:18 +00:00
Err error ->
{ model | errors = (errorText error) :: model.errors } ! []
FavoriteRemoved result ->
case result of
Ok status ->
processFavourite status.id False model ! [ loadNotifications model.client ]
Err error ->
{ model | errors = (errorText error) :: model.errors } ! []
LocalTimeline result ->
case result of
Ok localTimeline ->
{ model | localTimeline = localTimeline } ! []
Err error ->
{ model | localTimeline = [], errors = (errorText error) :: model.errors } ! []
Notifications result ->
case result of
Ok notifications ->
2017-04-27 14:34:27 +00:00
{ model | notifications = Mastodon.Helper.aggregateNotifications notifications } ! []
Err error ->
{ model | notifications = [], errors = (errorText error) :: model.errors } ! []
GlobalTimeline result ->
case result of
Ok globalTimeline ->
{ model | globalTimeline = globalTimeline } ! []
Err error ->
{ model | globalTimeline = [], errors = (errorText error) :: model.errors } ! []
Reblogged result ->
case result of
Ok status ->
model ! [ loadNotifications model.client ]
Err error ->
{ model | errors = (errorText error) :: model.errors } ! []
StatusPosted _ ->
{ model | draft = defaultDraft } ! []
2017-04-29 07:20:26 +00:00
StatusDeleted result ->
case result of
Ok id ->
{ model
| userTimeline = deleteStatusFromTimeline id model.userTimeline
, localTimeline = deleteStatusFromTimeline id model.localTimeline
, globalTimeline = deleteStatusFromTimeline id model.globalTimeline
}
! []
Err error ->
{ model | errors = (errorText error) :: model.errors } ! []
Unreblogged result ->
case result of
Ok status ->
model ! [ loadNotifications model.client ]
Err error ->
{ model | errors = (errorText error) :: model.errors } ! []
2017-04-27 20:01:51 +00:00
Account result ->
case result of
Ok account ->
{ model | currentView = AccountView account } ! []
Err error ->
{ model
| currentView = preferredTimeline model
, errors = (errorText error) :: model.errors
}
! []
2017-04-27 20:01:51 +00:00
AccountTimeline result ->
case result of
Ok statuses ->
{ model | accountTimeline = statuses } ! []
Err error ->
{ model | errors = (errorText error) :: model.errors } ! []
UserTimeline result ->
case result of
Ok userTimeline ->
{ model | userTimeline = userTimeline } ! []
Err error ->
{ model | userTimeline = [], errors = (errorText error) :: model.errors } ! []
processWebSocketMsg : WebSocketMsg -> Model -> ( Model, Cmd Msg )
processWebSocketMsg msg model =
case msg of
NewWebsocketUserMessage message ->
2017-04-27 14:34:27 +00:00
case (Mastodon.Decoder.decodeWebSocketMessage message) of
Mastodon.WebSocket.ErrorEvent error ->
{ model | errors = error :: model.errors } ! []
2017-04-27 14:34:27 +00:00
Mastodon.WebSocket.StatusUpdateEvent result ->
case result of
Ok status ->
{ model | userTimeline = truncate (status :: model.userTimeline) } ! []
Err error ->
{ model | errors = error :: model.errors } ! []
2017-04-27 14:34:27 +00:00
Mastodon.WebSocket.StatusDeleteEvent result ->
case result of
Ok id ->
{ model | userTimeline = deleteStatusFromTimeline id model.userTimeline } ! []
Err error ->
{ model | errors = error :: model.errors } ! []
2017-04-27 14:34:27 +00:00
Mastodon.WebSocket.NotificationEvent result ->
case result of
Ok notification ->
let
notifications =
2017-04-27 14:34:27 +00:00
Mastodon.Helper.addNotificationToAggregates
notification
model.notifications
in
{ model | notifications = truncate notifications } ! []
Err error ->
{ model | errors = error :: model.errors } ! []
NewWebsocketLocalMessage message ->
2017-04-27 14:34:27 +00:00
case (Mastodon.Decoder.decodeWebSocketMessage message) of
Mastodon.WebSocket.ErrorEvent error ->
{ model | errors = error :: model.errors } ! []
2017-04-27 14:34:27 +00:00
Mastodon.WebSocket.StatusUpdateEvent result ->
case result of
Ok status ->
{ model | localTimeline = truncate (status :: model.localTimeline) } ! []
Err error ->
{ model | errors = error :: model.errors } ! []
2017-04-27 14:34:27 +00:00
Mastodon.WebSocket.StatusDeleteEvent result ->
case result of
Ok id ->
{ model | localTimeline = deleteStatusFromTimeline id model.localTimeline } ! []
Err error ->
{ model | errors = error :: model.errors } ! []
_ ->
model ! []
NewWebsocketGlobalMessage message ->
2017-04-27 14:34:27 +00:00
case (Mastodon.Decoder.decodeWebSocketMessage message) of
Mastodon.WebSocket.ErrorEvent error ->
{ model | errors = error :: model.errors } ! []
2017-04-27 14:34:27 +00:00
Mastodon.WebSocket.StatusUpdateEvent result ->
case result of
Ok status ->
{ model | globalTimeline = truncate (status :: model.globalTimeline) } ! []
Err error ->
{ model | errors = error :: model.errors } ! []
2017-04-27 14:34:27 +00:00
Mastodon.WebSocket.StatusDeleteEvent result ->
case result of
Ok id ->
{ model | globalTimeline = deleteStatusFromTimeline id model.globalTimeline } ! []
Err error ->
{ model | errors = error :: model.errors } ! []
_ ->
model ! []
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
model ! []
DomResult result ->
model ! []
MastodonEvent msg ->
let
( newModel, commands ) =
processMastodonEvent msg model
in
newModel ! [ commands ]
WebSocketEvent msg ->
let
( newModel, commands ) =
processWebSocketMsg msg model
in
newModel ! [ commands ]
ServerChange server ->
{ model | server = server } ! []
UrlChange location ->
model ! []
Register ->
model ! [ registerApp model ]
OpenThread status ->
case model.client of
Just client ->
model
! [ Mastodon.Http.context client status.id
|> Mastodon.Http.send (MastodonEvent << (ContextLoaded status))
]
Nothing ->
model ! []
CloseThread ->
{ model | currentView = preferredTimeline model } ! []
2017-04-29 07:20:26 +00:00
DeleteStatus id ->
case model.client of
Just client ->
model ! [ deleteStatus client id ]
Nothing ->
model ! []
Reblog id ->
-- Note: The case of reblogging is specific as it seems the server
-- response takes a lot of time to be received by the client, so we
-- perform optimistic updates here.
case model.client of
Just client ->
processReblog id True model
2017-04-27 14:34:27 +00:00
! [ Mastodon.Http.reblog client id
|> Mastodon.Http.send (MastodonEvent << Reblogged)
]
Nothing ->
model ! []
Unreblog id ->
case model.client of
Just client ->
processReblog id False model
2017-04-27 14:34:27 +00:00
! [ Mastodon.Http.unfavourite client id
|> Mastodon.Http.send (MastodonEvent << Unreblogged)
]
Nothing ->
model ! []
AddFavorite id ->
model
! case model.client of
Just client ->
2017-04-27 14:34:27 +00:00
[ Mastodon.Http.favourite client id
|> Mastodon.Http.send (MastodonEvent << FavoriteAdded)
]
Nothing ->
[]
RemoveFavorite id ->
model
! case model.client of
Just client ->
2017-04-27 14:34:27 +00:00
[ Mastodon.Http.unfavourite client id
|> Mastodon.Http.send (MastodonEvent << FavoriteRemoved)
]
Nothing ->
[]
2017-04-20 18:30:19 +00:00
DraftEvent draftMsg ->
case model.currentUser of
Just user ->
let
( draft, commands ) =
updateDraft draftMsg user model.draft
in
{ model | draft = draft } ! [ commands ]
Nothing ->
model ! []
2017-04-20 18:30:19 +00:00
2017-04-24 19:21:43 +00:00
ViewerEvent viewerMsg ->
let
( viewer, commands ) =
updateViewer viewerMsg model.viewer
in
{ model | viewer = viewer } ! [ commands ]
2017-04-20 18:30:19 +00:00
SubmitDraft ->
model
! case model.client of
Just client ->
[ postStatus client <| toStatusRequestBody model.draft ]
2017-04-20 18:30:19 +00:00
Nothing ->
[]
2017-04-27 20:01:51 +00:00
LoadAccount accountId ->
{-
@TODO
When requesting a user profile, we should load a new "page"
so that the URL in the browser matches the user displayed
-}
2017-04-27 20:01:51 +00:00
{ model | currentView = preferredTimeline model }
! case model.client of
Just client ->
2017-04-27 14:34:27 +00:00
[ Mastodon.Http.fetchAccount client accountId
2017-04-27 20:01:51 +00:00
|> Mastodon.Http.send (MastodonEvent << Account)
, Mastodon.Http.fetchAccountTimeline client accountId
|> Mastodon.Http.send (MastodonEvent << AccountTimeline)
]
Nothing ->
[]
UseGlobalTimeline flag ->
let
newModel =
{ model | useGlobalTimeline = flag }
in
{ model | currentView = preferredTimeline newModel } ! []
ClearOpenedAccount ->
{ model | currentView = preferredTimeline model } ! []
ScrollColumn context ->
model ! [ Task.attempt DomResult <| Dom.Scroll.toTop context ]
2017-04-25 14:27:15 +00:00
subscriptions : Model -> Sub Msg
subscriptions model =
case model.client of
Just client ->
let
subs =
2017-04-27 14:34:27 +00:00
[ Mastodon.WebSocket.subscribeToWebSockets
client
2017-04-27 14:34:27 +00:00
Mastodon.WebSocket.UserStream
NewWebsocketUserMessage
]
++ (if model.useGlobalTimeline then
2017-04-27 14:34:27 +00:00
[ Mastodon.WebSocket.subscribeToWebSockets
client
2017-04-27 14:34:27 +00:00
Mastodon.WebSocket.GlobalPublicStream
NewWebsocketGlobalMessage
]
else
2017-04-27 14:34:27 +00:00
[ Mastodon.WebSocket.subscribeToWebSockets
client
2017-04-27 14:34:27 +00:00
Mastodon.WebSocket.LocalPublicStream
NewWebsocketLocalMessage
]
)
in
Sub.batch <| List.map (Sub.map WebSocketEvent) subs
2017-04-25 14:27:15 +00:00
Nothing ->
Sub.batch []