Add websocket for local and global timeline (#66)
* Connect to the websocket API * Enable user timeline update through websockets * Update elm-html-parser to latest * Listem to local and global timelines * Subscribe to global timeline only if it's displayed * Some review changes * Add elm-test and test notification aggregates * Add new follow notification * Fex addNotificationToAggregates * Add test * Clarify logic * Update local and global timelines using WS I've renamed the "public" timeline to "global", and removed the HTTP reload of the user timeline when posting a Toot. We only rely on websockets now.
This commit is contained in:
parent
c72a9281df
commit
00ffcecf1d
@ -30,7 +30,7 @@ module Mastodon
|
|||||||
, fetchAccount
|
, fetchAccount
|
||||||
, fetchLocalTimeline
|
, fetchLocalTimeline
|
||||||
, fetchNotifications
|
, fetchNotifications
|
||||||
, fetchPublicTimeline
|
, fetchGlobalTimeline
|
||||||
, fetchUserTimeline
|
, fetchUserTimeline
|
||||||
, postStatus
|
, postStatus
|
||||||
, send
|
, send
|
||||||
@ -662,8 +662,8 @@ fetchLocalTimeline client =
|
|||||||
fetch client "/api/v1/timelines/public?local=true" <| Decode.list statusDecoder
|
fetch client "/api/v1/timelines/public?local=true" <| Decode.list statusDecoder
|
||||||
|
|
||||||
|
|
||||||
fetchPublicTimeline : Client -> Request (List Status)
|
fetchGlobalTimeline : Client -> Request (List Status)
|
||||||
fetchPublicTimeline client =
|
fetchGlobalTimeline client =
|
||||||
fetch client "/api/v1/timelines/public" <| Decode.list statusDecoder
|
fetch client "/api/v1/timelines/public" <| Decode.list statusDecoder
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ type MastodonMsg
|
|||||||
| FavoriteRemoved (Result Mastodon.Error Mastodon.Status)
|
| FavoriteRemoved (Result Mastodon.Error Mastodon.Status)
|
||||||
| LocalTimeline (Result Mastodon.Error (List Mastodon.Status))
|
| LocalTimeline (Result Mastodon.Error (List Mastodon.Status))
|
||||||
| Notifications (Result Mastodon.Error (List Mastodon.Notification))
|
| Notifications (Result Mastodon.Error (List Mastodon.Notification))
|
||||||
| PublicTimeline (Result Mastodon.Error (List Mastodon.Status))
|
| GlobalTimeline (Result Mastodon.Error (List Mastodon.Status))
|
||||||
| Reblogged (Result Mastodon.Error Mastodon.Status)
|
| Reblogged (Result Mastodon.Error Mastodon.Status)
|
||||||
| StatusPosted (Result Mastodon.Error Mastodon.Status)
|
| StatusPosted (Result Mastodon.Error Mastodon.Status)
|
||||||
| Unreblogged (Result Mastodon.Error Mastodon.Status)
|
| Unreblogged (Result Mastodon.Error Mastodon.Status)
|
||||||
@ -92,7 +92,7 @@ type alias Model =
|
|||||||
, client : Maybe Mastodon.Client
|
, client : Maybe Mastodon.Client
|
||||||
, userTimeline : List Mastodon.Status
|
, userTimeline : List Mastodon.Status
|
||||||
, localTimeline : List Mastodon.Status
|
, localTimeline : List Mastodon.Status
|
||||||
, publicTimeline : List Mastodon.Status
|
, globalTimeline : List Mastodon.Status
|
||||||
, notifications : List Mastodon.NotificationAggregate
|
, notifications : List Mastodon.NotificationAggregate
|
||||||
, draft : Draft
|
, draft : Draft
|
||||||
, account : Maybe Mastodon.Account
|
, account : Maybe Mastodon.Account
|
||||||
@ -134,7 +134,7 @@ init flags location =
|
|||||||
, client = flags.client
|
, client = flags.client
|
||||||
, userTimeline = []
|
, userTimeline = []
|
||||||
, localTimeline = []
|
, localTimeline = []
|
||||||
, publicTimeline = []
|
, globalTimeline = []
|
||||||
, notifications = []
|
, notifications = []
|
||||||
, draft = defaultDraft
|
, draft = defaultDraft
|
||||||
, account = Nothing
|
, account = Nothing
|
||||||
@ -217,7 +217,7 @@ loadTimelines client =
|
|||||||
Cmd.batch
|
Cmd.batch
|
||||||
[ Mastodon.fetchUserTimeline client |> Mastodon.send (MastodonEvent << UserTimeline)
|
[ Mastodon.fetchUserTimeline client |> Mastodon.send (MastodonEvent << UserTimeline)
|
||||||
, Mastodon.fetchLocalTimeline client |> Mastodon.send (MastodonEvent << LocalTimeline)
|
, Mastodon.fetchLocalTimeline client |> Mastodon.send (MastodonEvent << LocalTimeline)
|
||||||
, Mastodon.fetchPublicTimeline client |> Mastodon.send (MastodonEvent << PublicTimeline)
|
, Mastodon.fetchGlobalTimeline client |> Mastodon.send (MastodonEvent << GlobalTimeline)
|
||||||
, loadNotifications <| Just client
|
, loadNotifications <| Just client
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ updateTimelinesWithBoolFlag statusId flag statusUpdater model =
|
|||||||
{ model
|
{ model
|
||||||
| userTimeline = List.map (update flag) model.userTimeline
|
| userTimeline = List.map (update flag) model.userTimeline
|
||||||
, localTimeline = List.map (update flag) model.localTimeline
|
, localTimeline = List.map (update flag) model.localTimeline
|
||||||
, publicTimeline = List.map (update flag) model.publicTimeline
|
, globalTimeline = List.map (update flag) model.globalTimeline
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -417,13 +417,13 @@ processMastodonEvent msg model =
|
|||||||
Err error ->
|
Err error ->
|
||||||
{ model | notifications = [], errors = (errorText error) :: model.errors } ! []
|
{ model | notifications = [], errors = (errorText error) :: model.errors } ! []
|
||||||
|
|
||||||
PublicTimeline result ->
|
GlobalTimeline result ->
|
||||||
case result of
|
case result of
|
||||||
Ok publicTimeline ->
|
Ok globalTimeline ->
|
||||||
{ model | publicTimeline = publicTimeline } ! []
|
{ model | globalTimeline = globalTimeline } ! []
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
{ model | publicTimeline = [], errors = (errorText error) :: model.errors } ! []
|
{ model | globalTimeline = [], errors = (errorText error) :: model.errors } ! []
|
||||||
|
|
||||||
Reblogged result ->
|
Reblogged result ->
|
||||||
case result of
|
case result of
|
||||||
@ -434,7 +434,7 @@ processMastodonEvent msg model =
|
|||||||
{ model | errors = (errorText error) :: model.errors } ! []
|
{ model | errors = (errorText error) :: model.errors } ! []
|
||||||
|
|
||||||
StatusPosted _ ->
|
StatusPosted _ ->
|
||||||
{ model | draft = defaultDraft } ! [ loadTimelines model.client ]
|
{ model | draft = defaultDraft } ! []
|
||||||
|
|
||||||
Unreblogged result ->
|
Unreblogged result ->
|
||||||
case result of
|
case result of
|
||||||
@ -601,11 +601,35 @@ update msg model =
|
|||||||
{ model | errors = (logError "StatusResult" error message) :: model.errors } ! []
|
{ model | errors = (logError "StatusResult" error message) :: model.errors } ! []
|
||||||
|
|
||||||
NewWebsocketLocalMessage message ->
|
NewWebsocketLocalMessage message ->
|
||||||
-- @TODO
|
case (Mastodon.decodeWebSocketMessage message) of
|
||||||
|
Mastodon.EventError error ->
|
||||||
|
{ model | errors = error :: model.errors } ! []
|
||||||
|
|
||||||
|
Mastodon.StatusResult result ->
|
||||||
|
case result of
|
||||||
|
Ok status ->
|
||||||
|
{ model | localTimeline = status :: model.localTimeline } ! []
|
||||||
|
|
||||||
|
Err error ->
|
||||||
|
{ model | errors = error :: model.errors } ! []
|
||||||
|
|
||||||
|
_ ->
|
||||||
model ! []
|
model ! []
|
||||||
|
|
||||||
NewWebsocketGlobalMessage message ->
|
NewWebsocketGlobalMessage message ->
|
||||||
-- @TODO
|
case (Mastodon.decodeWebSocketMessage message) of
|
||||||
|
Mastodon.EventError error ->
|
||||||
|
{ model | errors = error :: model.errors } ! []
|
||||||
|
|
||||||
|
Mastodon.StatusResult result ->
|
||||||
|
case result of
|
||||||
|
Ok status ->
|
||||||
|
{ model | globalTimeline = status :: model.globalTimeline } ! []
|
||||||
|
|
||||||
|
Err error ->
|
||||||
|
{ model | errors = error :: model.errors } ! []
|
||||||
|
|
||||||
|
_ ->
|
||||||
model ! []
|
model ! []
|
||||||
|
|
||||||
|
|
||||||
|
@ -153,7 +153,6 @@ statusView context ({ account, content, media_attachments, reblog, mentions } as
|
|||||||
let
|
let
|
||||||
accountLinkAttributes =
|
accountLinkAttributes =
|
||||||
[ href account.url
|
[ href account.url
|
||||||
|
|
||||||
-- When clicking on a status, we should not let the browser
|
-- When clicking on a status, we should not let the browser
|
||||||
-- redirect to a new page. That's why we're preventing the default
|
-- redirect to a new page. That's why we're preventing the default
|
||||||
-- behavior here
|
-- behavior here
|
||||||
@ -575,7 +574,7 @@ homepageView model =
|
|||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
if model.useGlobalTimeline then
|
if model.useGlobalTimeline then
|
||||||
timelineView "Global timeline" "globe" "global" model.publicTimeline
|
timelineView "Global timeline" "globe" "global" model.globalTimeline
|
||||||
else
|
else
|
||||||
timelineView "Local timeline" "th-large" "local" model.localTimeline
|
timelineView "Local timeline" "th-large" "local" model.localTimeline
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user