parent
017f07d45d
commit
57f7f0cc7c
@ -92,12 +92,29 @@ body {
|
|||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.username {
|
.status .username,
|
||||||
|
.current-user .username {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-left: 65px;
|
margin-left: 65px;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.follow-entry {
|
||||||
|
min-height: 38px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.follow-entry .avatar {
|
||||||
|
width: 38px;
|
||||||
|
height: 38px;
|
||||||
|
}
|
||||||
|
.follow-entry .username {
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 97%;
|
||||||
|
margin-left: 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
.acct {
|
.acct {
|
||||||
font-size: 97%;
|
font-size: 97%;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
@ -334,6 +351,17 @@ body {
|
|||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.account-infos a {
|
||||||
|
color: #c8c8c8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-infos a:hover,
|
||||||
|
.account-infos a:focus,
|
||||||
|
.account-infos a:active {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
/* Viewer */
|
/* Viewer */
|
||||||
|
|
||||||
.viewer {
|
.viewer {
|
||||||
|
231
src/Command.elm
Normal file
231
src/Command.elm
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
module Command
|
||||||
|
exposing
|
||||||
|
( initCommands
|
||||||
|
, navigateToAuthUrl
|
||||||
|
, registerApp
|
||||||
|
, saveClient
|
||||||
|
, saveRegistration
|
||||||
|
, loadNotifications
|
||||||
|
, loadUserAccount
|
||||||
|
, loadAccount
|
||||||
|
, loadAccountInfo
|
||||||
|
, loadThread
|
||||||
|
, loadTimelines
|
||||||
|
, postStatus
|
||||||
|
, deleteStatus
|
||||||
|
, reblogStatus
|
||||||
|
, unreblogStatus
|
||||||
|
, favouriteStatus
|
||||||
|
, unfavouriteStatus
|
||||||
|
)
|
||||||
|
|
||||||
|
import Json.Encode as Encode
|
||||||
|
import Mastodon.Model exposing (..)
|
||||||
|
import Mastodon.Encoder
|
||||||
|
import Mastodon.Http
|
||||||
|
import Navigation
|
||||||
|
import Ports
|
||||||
|
import Types exposing (..)
|
||||||
|
|
||||||
|
|
||||||
|
initCommands : Maybe AppRegistration -> Maybe Client -> Maybe String -> Cmd Msg
|
||||||
|
initCommands registration client authCode =
|
||||||
|
Cmd.batch <|
|
||||||
|
case authCode of
|
||||||
|
Just authCode ->
|
||||||
|
case registration of
|
||||||
|
Just registration ->
|
||||||
|
[ Mastodon.Http.getAccessToken registration authCode
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << AccessToken)
|
||||||
|
]
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
[ loadUserAccount client, loadTimelines client ]
|
||||||
|
|
||||||
|
|
||||||
|
navigateToAuthUrl : AppRegistration -> Cmd Msg
|
||||||
|
navigateToAuthUrl registration =
|
||||||
|
Navigation.load <| Mastodon.Http.getAuthorizationUrl registration
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
in
|
||||||
|
Mastodon.Http.register
|
||||||
|
cleanServer
|
||||||
|
"tooty"
|
||||||
|
appUrl
|
||||||
|
"read write follow"
|
||||||
|
"https://github.com/n1k0/tooty"
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << AppRegistered)
|
||||||
|
|
||||||
|
|
||||||
|
saveClient : Client -> Cmd Msg
|
||||||
|
saveClient client =
|
||||||
|
Mastodon.Encoder.clientEncoder client
|
||||||
|
|> Encode.encode 0
|
||||||
|
|> Ports.saveClient
|
||||||
|
|
||||||
|
|
||||||
|
saveRegistration : AppRegistration -> Cmd Msg
|
||||||
|
saveRegistration registration =
|
||||||
|
Mastodon.Encoder.registrationEncoder registration
|
||||||
|
|> Encode.encode 0
|
||||||
|
|> Ports.saveRegistration
|
||||||
|
|
||||||
|
|
||||||
|
loadNotifications : Maybe Client -> Cmd Msg
|
||||||
|
loadNotifications client =
|
||||||
|
case client of
|
||||||
|
Just client ->
|
||||||
|
Mastodon.Http.fetchNotifications client
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << Notifications)
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Cmd.none
|
||||||
|
|
||||||
|
|
||||||
|
loadUserAccount : Maybe Client -> Cmd Msg
|
||||||
|
loadUserAccount client =
|
||||||
|
case client of
|
||||||
|
Just client ->
|
||||||
|
Mastodon.Http.userAccount client
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << CurrentUser)
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Cmd.none
|
||||||
|
|
||||||
|
|
||||||
|
loadAccount : Maybe Client -> Int -> Cmd Msg
|
||||||
|
loadAccount client accountId =
|
||||||
|
case client of
|
||||||
|
Just client ->
|
||||||
|
Mastodon.Http.fetchAccount client accountId
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << AccountReceived)
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Cmd.none
|
||||||
|
|
||||||
|
|
||||||
|
loadAccountInfo : Maybe Client -> Int -> Cmd Msg
|
||||||
|
loadAccountInfo client accountId =
|
||||||
|
case client of
|
||||||
|
Just client ->
|
||||||
|
Cmd.batch
|
||||||
|
[ Mastodon.Http.fetchAccountTimeline client accountId
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << AccountTimeline)
|
||||||
|
, Mastodon.Http.fetchAccountFollowers client accountId
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << AccountFollowers)
|
||||||
|
, Mastodon.Http.fetchAccountFollowing client accountId
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << AccountFollowing)
|
||||||
|
]
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Cmd.none
|
||||||
|
|
||||||
|
|
||||||
|
loadThread : Maybe Client -> Status -> Cmd Msg
|
||||||
|
loadThread client status =
|
||||||
|
case client of
|
||||||
|
Just client ->
|
||||||
|
Mastodon.Http.context client status.id
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << (ContextLoaded status))
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Cmd.none
|
||||||
|
|
||||||
|
|
||||||
|
loadTimelines : Maybe Client -> Cmd Msg
|
||||||
|
loadTimelines client =
|
||||||
|
case client of
|
||||||
|
Just client ->
|
||||||
|
Cmd.batch
|
||||||
|
[ 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
|
||||||
|
]
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Cmd.none
|
||||||
|
|
||||||
|
|
||||||
|
postStatus : Maybe Client -> StatusRequestBody -> Cmd Msg
|
||||||
|
postStatus client draft =
|
||||||
|
case client of
|
||||||
|
Just client ->
|
||||||
|
Mastodon.Http.postStatus client draft
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << StatusPosted)
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Cmd.none
|
||||||
|
|
||||||
|
|
||||||
|
deleteStatus : Maybe Client -> Int -> Cmd Msg
|
||||||
|
deleteStatus client id =
|
||||||
|
case client of
|
||||||
|
Just client ->
|
||||||
|
Mastodon.Http.deleteStatus client id
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << StatusDeleted)
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Cmd.none
|
||||||
|
|
||||||
|
|
||||||
|
reblogStatus : Maybe Client -> Int -> Cmd Msg
|
||||||
|
reblogStatus client statusId =
|
||||||
|
case client of
|
||||||
|
Just client ->
|
||||||
|
Mastodon.Http.reblog client statusId
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << Reblogged)
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Cmd.none
|
||||||
|
|
||||||
|
|
||||||
|
unreblogStatus : Maybe Client -> Int -> Cmd Msg
|
||||||
|
unreblogStatus client statusId =
|
||||||
|
case client of
|
||||||
|
Just client ->
|
||||||
|
Mastodon.Http.unreblog client statusId
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << Unreblogged)
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Cmd.none
|
||||||
|
|
||||||
|
|
||||||
|
favouriteStatus : Maybe Client -> Int -> Cmd Msg
|
||||||
|
favouriteStatus client statusId =
|
||||||
|
case client of
|
||||||
|
Just client ->
|
||||||
|
Mastodon.Http.favourite client statusId
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << FavoriteAdded)
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Cmd.none
|
||||||
|
|
||||||
|
|
||||||
|
unfavouriteStatus : Maybe Client -> Int -> Cmd Msg
|
||||||
|
unfavouriteStatus client statusId =
|
||||||
|
case client of
|
||||||
|
Just client ->
|
||||||
|
Mastodon.Http.unfavourite client statusId
|
||||||
|
|> Mastodon.Http.send (MastodonEvent << FavoriteRemoved)
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Cmd.none
|
@ -2,7 +2,8 @@ module Main exposing (..)
|
|||||||
|
|
||||||
import Navigation
|
import Navigation
|
||||||
import View exposing (view)
|
import View exposing (view)
|
||||||
import Model exposing (Flags, Model, Msg(..), init, update, subscriptions)
|
import Model exposing (..)
|
||||||
|
import Types exposing (..)
|
||||||
|
|
||||||
|
|
||||||
main : Program Flags Model Msg
|
main : Program Flags Model Msg
|
||||||
|
@ -6,6 +6,8 @@ module Mastodon.ApiUrl
|
|||||||
, userAccount
|
, userAccount
|
||||||
, account
|
, account
|
||||||
, accountTimeline
|
, accountTimeline
|
||||||
|
, followers
|
||||||
|
, following
|
||||||
, status
|
, status
|
||||||
, homeTimeline
|
, homeTimeline
|
||||||
, publicTimeline
|
, publicTimeline
|
||||||
@ -54,6 +56,16 @@ userAccount server =
|
|||||||
server ++ accounts ++ "verify_credentials"
|
server ++ accounts ++ "verify_credentials"
|
||||||
|
|
||||||
|
|
||||||
|
followers : Int -> String
|
||||||
|
followers id =
|
||||||
|
(account id) ++ "/followers"
|
||||||
|
|
||||||
|
|
||||||
|
following : Int -> String
|
||||||
|
following id =
|
||||||
|
(account id) ++ "/following"
|
||||||
|
|
||||||
|
|
||||||
homeTimeline : String
|
homeTimeline : String
|
||||||
homeTimeline =
|
homeTimeline =
|
||||||
"/api/v1/timelines/home"
|
"/api/v1/timelines/home"
|
||||||
|
@ -11,6 +11,8 @@ module Mastodon.Http
|
|||||||
, getAccessToken
|
, getAccessToken
|
||||||
, fetchAccount
|
, fetchAccount
|
||||||
, fetchAccountTimeline
|
, fetchAccountTimeline
|
||||||
|
, fetchAccountFollowers
|
||||||
|
, fetchAccountFollowing
|
||||||
, fetchLocalTimeline
|
, fetchLocalTimeline
|
||||||
, fetchNotifications
|
, fetchNotifications
|
||||||
, fetchGlobalTimeline
|
, fetchGlobalTimeline
|
||||||
@ -134,6 +136,16 @@ fetchNotifications client =
|
|||||||
fetch client (ApiUrl.notifications) <| Decode.list notificationDecoder
|
fetch client (ApiUrl.notifications) <| Decode.list notificationDecoder
|
||||||
|
|
||||||
|
|
||||||
|
fetchAccountFollowers : Client -> Int -> Request (List Account)
|
||||||
|
fetchAccountFollowers client accountId =
|
||||||
|
fetch client (ApiUrl.followers accountId) <| Decode.list accountDecoder
|
||||||
|
|
||||||
|
|
||||||
|
fetchAccountFollowing : Client -> Int -> Request (List Account)
|
||||||
|
fetchAccountFollowing client accountId =
|
||||||
|
fetch client (ApiUrl.following accountId) <| Decode.list accountDecoder
|
||||||
|
|
||||||
|
|
||||||
userAccount : Client -> Request Account
|
userAccount : Client -> Request Account
|
||||||
userAccount client =
|
userAccount client =
|
||||||
HttpBuilder.get (ApiUrl.userAccount client.server)
|
HttpBuilder.get (ApiUrl.userAccount client.server)
|
||||||
|
422
src/Model.elm
422
src/Model.elm
@ -1,17 +1,15 @@
|
|||||||
module Model exposing (..)
|
module Model exposing (..)
|
||||||
|
|
||||||
|
import Command
|
||||||
import Dom
|
import Dom
|
||||||
import Json.Encode as Encode
|
import Dom.Scroll
|
||||||
import Navigation
|
import Navigation
|
||||||
import Mastodon.Decoder
|
import Mastodon.Decoder
|
||||||
import Mastodon.Encoder
|
|
||||||
import Mastodon.Helper
|
import Mastodon.Helper
|
||||||
import Mastodon.Http
|
import Mastodon.Model exposing (..)
|
||||||
import Mastodon.Model
|
|
||||||
import Mastodon.WebSocket
|
import Mastodon.WebSocket
|
||||||
import Ports
|
|
||||||
import Task
|
import Task
|
||||||
import Dom.Scroll
|
import Types exposing (..)
|
||||||
|
|
||||||
|
|
||||||
maxBuffer : Int
|
maxBuffer : Int
|
||||||
@ -20,124 +18,6 @@ maxBuffer =
|
|||||||
100
|
100
|
||||||
|
|
||||||
|
|
||||||
type alias Flags =
|
|
||||||
{ client : Maybe Mastodon.Model.Client
|
|
||||||
, registration : Maybe Mastodon.Model.AppRegistration
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type DraftMsg
|
|
||||||
= ClearDraft
|
|
||||||
| UpdateSensitive Bool
|
|
||||||
| UpdateSpoiler String
|
|
||||||
| UpdateStatus String
|
|
||||||
| UpdateVisibility String
|
|
||||||
| UpdateReplyTo Mastodon.Model.Status
|
|
||||||
| ToggleSpoiler Bool
|
|
||||||
|
|
||||||
|
|
||||||
type ViewerMsg
|
|
||||||
= CloseViewer
|
|
||||||
| OpenViewer (List Mastodon.Model.Attachment) Mastodon.Model.Attachment
|
|
||||||
|
|
||||||
|
|
||||||
type MastodonMsg
|
|
||||||
= 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)
|
|
||||||
| 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)
|
|
||||||
| StatusDeleted (Result Mastodon.Model.Error Int)
|
|
||||||
| StatusPosted (Result Mastodon.Model.Error Mastodon.Model.Status)
|
|
||||||
| Unreblogged (Result Mastodon.Model.Error Mastodon.Model.Status)
|
|
||||||
| Account (Result Mastodon.Model.Error Mastodon.Model.Account)
|
|
||||||
| AccountTimeline (Result Mastodon.Model.Error (List Mastodon.Model.Status))
|
|
||||||
| 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 ())
|
|
||||||
| DeleteStatus Int
|
|
||||||
| DraftEvent DraftMsg
|
|
||||||
| LoadAccount Int
|
|
||||||
| MastodonEvent MastodonMsg
|
|
||||||
| NoOp
|
|
||||||
| OpenThread Mastodon.Model.Status
|
|
||||||
| Reblog Int
|
|
||||||
| Register
|
|
||||||
| RemoveFavorite Int
|
|
||||||
| ServerChange String
|
|
||||||
| SubmitDraft
|
|
||||||
| UrlChange Navigation.Location
|
|
||||||
| UseGlobalTimeline Bool
|
|
||||||
| Unreblog Int
|
|
||||||
| ViewerEvent ViewerMsg
|
|
||||||
| WebSocketEvent WebSocketMsg
|
|
||||||
| ScrollColumn String
|
|
||||||
|
|
||||||
|
|
||||||
type alias Draft =
|
|
||||||
{ status : String
|
|
||||||
, 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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias Viewer =
|
|
||||||
{ attachments : List Mastodon.Model.Attachment
|
|
||||||
, attachment : Mastodon.Model.Attachment
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type CurrentView
|
|
||||||
= -- Basically, what we should be displaying in the fourth column
|
|
||||||
AccountView Mastodon.Model.Account
|
|
||||||
| ThreadView Thread
|
|
||||||
| LocalTimelineView
|
|
||||||
| GlobalTimelineView
|
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
|
||||||
{ server : String
|
|
||||||
, 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
|
|
||||||
, accountTimeline : List Mastodon.Model.Status
|
|
||||||
, notifications : List Mastodon.Model.NotificationAggregate
|
|
||||||
, draft : Draft
|
|
||||||
, errors : List String
|
|
||||||
, location : Navigation.Location
|
|
||||||
, useGlobalTimeline : Bool
|
|
||||||
, viewer : Maybe Viewer
|
|
||||||
, currentUser : Maybe Mastodon.Model.Account
|
|
||||||
, currentView : CurrentView
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extractAuthCode : Navigation.Location -> Maybe String
|
extractAuthCode : Navigation.Location -> Maybe String
|
||||||
extractAuthCode { search } =
|
extractAuthCode { search } =
|
||||||
case (String.split "?code=" search) of
|
case (String.split "?code=" search) of
|
||||||
@ -171,6 +51,8 @@ init flags location =
|
|||||||
, localTimeline = []
|
, localTimeline = []
|
||||||
, globalTimeline = []
|
, globalTimeline = []
|
||||||
, accountTimeline = []
|
, accountTimeline = []
|
||||||
|
, accountFollowers = []
|
||||||
|
, accountFollowing = []
|
||||||
, notifications = []
|
, notifications = []
|
||||||
, draft = defaultDraft
|
, draft = defaultDraft
|
||||||
, errors = []
|
, errors = []
|
||||||
@ -180,100 +62,7 @@ init flags location =
|
|||||||
, currentView = LocalTimelineView
|
, currentView = LocalTimelineView
|
||||||
, currentUser = Nothing
|
, currentUser = Nothing
|
||||||
}
|
}
|
||||||
! [ initCommands flags.registration flags.client authCode ]
|
! [ Command.initCommands flags.registration flags.client authCode ]
|
||||||
|
|
||||||
|
|
||||||
initCommands : Maybe Mastodon.Model.AppRegistration -> Maybe Mastodon.Model.Client -> Maybe String -> Cmd Msg
|
|
||||||
initCommands registration client authCode =
|
|
||||||
Cmd.batch <|
|
|
||||||
case authCode of
|
|
||||||
Just authCode ->
|
|
||||||
case registration of
|
|
||||||
Just registration ->
|
|
||||||
[ Mastodon.Http.getAccessToken registration authCode
|
|
||||||
|> Mastodon.Http.send (MastodonEvent << AccessToken)
|
|
||||||
]
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
[ loadUserAccount client, loadTimelines client ]
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
in
|
|
||||||
Mastodon.Http.register
|
|
||||||
cleanServer
|
|
||||||
"tooty"
|
|
||||||
appUrl
|
|
||||||
"read write follow"
|
|
||||||
"https://github.com/n1k0/tooty"
|
|
||||||
|> Mastodon.Http.send (MastodonEvent << AppRegistered)
|
|
||||||
|
|
||||||
|
|
||||||
saveClient : Mastodon.Model.Client -> Cmd Msg
|
|
||||||
saveClient client =
|
|
||||||
Mastodon.Encoder.clientEncoder client
|
|
||||||
|> Encode.encode 0
|
|
||||||
|> Ports.saveClient
|
|
||||||
|
|
||||||
|
|
||||||
saveRegistration : Mastodon.Model.AppRegistration -> Cmd Msg
|
|
||||||
saveRegistration registration =
|
|
||||||
Mastodon.Encoder.registrationEncoder registration
|
|
||||||
|> Encode.encode 0
|
|
||||||
|> Ports.saveRegistration
|
|
||||||
|
|
||||||
|
|
||||||
loadNotifications : Maybe Mastodon.Model.Client -> Cmd Msg
|
|
||||||
loadNotifications client =
|
|
||||||
case client of
|
|
||||||
Just client ->
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
loadTimelines : Maybe Mastodon.Model.Client -> Cmd Msg
|
|
||||||
loadTimelines client =
|
|
||||||
case client of
|
|
||||||
Just client ->
|
|
||||||
Cmd.batch
|
|
||||||
[ 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
|
|
||||||
]
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
Cmd.none
|
|
||||||
|
|
||||||
|
|
||||||
preferredTimeline : Model -> CurrentView
|
preferredTimeline : Model -> CurrentView
|
||||||
@ -289,35 +78,23 @@ truncate entries =
|
|||||||
List.take maxBuffer entries
|
List.take maxBuffer entries
|
||||||
|
|
||||||
|
|
||||||
postStatus : Mastodon.Model.Client -> Mastodon.Model.StatusRequestBody -> Cmd Msg
|
errorText : Error -> String
|
||||||
postStatus client draft =
|
|
||||||
Mastodon.Http.postStatus client draft
|
|
||||||
|> Mastodon.Http.send (MastodonEvent << StatusPosted)
|
|
||||||
|
|
||||||
|
|
||||||
deleteStatus : Mastodon.Model.Client -> Int -> Cmd Msg
|
|
||||||
deleteStatus client id =
|
|
||||||
Mastodon.Http.deleteStatus client id
|
|
||||||
|> Mastodon.Http.send (MastodonEvent << StatusDeleted)
|
|
||||||
|
|
||||||
|
|
||||||
errorText : Mastodon.Model.Error -> String
|
|
||||||
errorText error =
|
errorText error =
|
||||||
case error of
|
case error of
|
||||||
Mastodon.Model.MastodonError statusCode statusMsg errorMsg ->
|
MastodonError statusCode statusMsg errorMsg ->
|
||||||
"HTTP " ++ (toString statusCode) ++ " " ++ statusMsg ++ ": " ++ errorMsg
|
"HTTP " ++ (toString statusCode) ++ " " ++ statusMsg ++ ": " ++ errorMsg
|
||||||
|
|
||||||
Mastodon.Model.ServerError statusCode statusMsg errorMsg ->
|
ServerError statusCode statusMsg errorMsg ->
|
||||||
"HTTP " ++ (toString statusCode) ++ " " ++ statusMsg ++ ": " ++ errorMsg
|
"HTTP " ++ (toString statusCode) ++ " " ++ statusMsg ++ ": " ++ errorMsg
|
||||||
|
|
||||||
Mastodon.Model.TimeoutError ->
|
TimeoutError ->
|
||||||
"Request timed out."
|
"Request timed out."
|
||||||
|
|
||||||
Mastodon.Model.NetworkError ->
|
NetworkError ->
|
||||||
"Unreachable host."
|
"Unreachable host."
|
||||||
|
|
||||||
|
|
||||||
toStatusRequestBody : Draft -> Mastodon.Model.StatusRequestBody
|
toStatusRequestBody : Draft -> StatusRequestBody
|
||||||
toStatusRequestBody draft =
|
toStatusRequestBody draft =
|
||||||
{ status = draft.status
|
{ status = draft.status
|
||||||
, in_reply_to_id =
|
, in_reply_to_id =
|
||||||
@ -333,7 +110,7 @@ toStatusRequestBody draft =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
updateTimelinesWithBoolFlag : Int -> Bool -> (Mastodon.Model.Status -> Mastodon.Model.Status) -> Model -> Model
|
updateTimelinesWithBoolFlag : Int -> Bool -> (Status -> Status) -> Model -> Model
|
||||||
updateTimelinesWithBoolFlag statusId flag statusUpdater model =
|
updateTimelinesWithBoolFlag statusId flag statusUpdater model =
|
||||||
let
|
let
|
||||||
update flag status =
|
update flag status =
|
||||||
@ -351,15 +128,17 @@ updateTimelinesWithBoolFlag statusId flag statusUpdater model =
|
|||||||
|
|
||||||
processFavourite : Int -> Bool -> Model -> Model
|
processFavourite : Int -> Bool -> Model -> Model
|
||||||
processFavourite statusId flag model =
|
processFavourite statusId flag model =
|
||||||
|
-- TODO: update notifications too
|
||||||
updateTimelinesWithBoolFlag statusId flag (\s -> { s | favourited = Just flag }) model
|
updateTimelinesWithBoolFlag statusId flag (\s -> { s | favourited = Just flag }) model
|
||||||
|
|
||||||
|
|
||||||
processReblog : Int -> Bool -> Model -> Model
|
processReblog : Int -> Bool -> Model -> Model
|
||||||
processReblog statusId flag model =
|
processReblog statusId flag model =
|
||||||
|
-- TODO: update notifications too
|
||||||
updateTimelinesWithBoolFlag statusId flag (\s -> { s | reblogged = Just flag }) model
|
updateTimelinesWithBoolFlag statusId flag (\s -> { s | reblogged = Just flag }) model
|
||||||
|
|
||||||
|
|
||||||
deleteStatusFromTimeline : Int -> List Mastodon.Model.Status -> List Mastodon.Model.Status
|
deleteStatusFromTimeline : Int -> List Status -> List Status
|
||||||
deleteStatusFromTimeline statusId timeline =
|
deleteStatusFromTimeline statusId timeline =
|
||||||
timeline
|
timeline
|
||||||
|> List.filter
|
|> List.filter
|
||||||
@ -371,7 +150,7 @@ deleteStatusFromTimeline statusId timeline =
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
updateDraft : DraftMsg -> Mastodon.Model.Account -> Draft -> ( Draft, Cmd Msg )
|
updateDraft : DraftMsg -> Account -> Draft -> ( Draft, Cmd Msg )
|
||||||
updateDraft draftMsg currentUser draft =
|
updateDraft draftMsg currentUser draft =
|
||||||
case draftMsg of
|
case draftMsg of
|
||||||
ClearDraft ->
|
ClearDraft ->
|
||||||
@ -432,12 +211,12 @@ processMastodonEvent msg model =
|
|||||||
Ok { server, accessToken } ->
|
Ok { server, accessToken } ->
|
||||||
let
|
let
|
||||||
client =
|
client =
|
||||||
Mastodon.Model.Client server accessToken
|
Client server accessToken
|
||||||
in
|
in
|
||||||
{ model | client = Just client }
|
{ model | client = Just client }
|
||||||
! [ loadTimelines <| Just client
|
! [ Command.loadTimelines <| Just client
|
||||||
, Navigation.modifyUrl model.location.pathname
|
, Navigation.modifyUrl model.location.pathname
|
||||||
, saveClient client
|
, Command.saveClient client
|
||||||
]
|
]
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
@ -447,8 +226,8 @@ processMastodonEvent msg model =
|
|||||||
case result of
|
case result of
|
||||||
Ok registration ->
|
Ok registration ->
|
||||||
{ model | registration = Just registration }
|
{ model | registration = Just registration }
|
||||||
! [ saveRegistration registration
|
! [ Command.saveRegistration registration
|
||||||
, Navigation.load <| Mastodon.Http.getAuthorizationUrl registration
|
, Command.navigateToAuthUrl registration
|
||||||
]
|
]
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
@ -457,11 +236,7 @@ processMastodonEvent msg model =
|
|||||||
ContextLoaded status result ->
|
ContextLoaded status result ->
|
||||||
case result of
|
case result of
|
||||||
Ok context ->
|
Ok context ->
|
||||||
let
|
{ model | currentView = ThreadView (Thread status context) } ! []
|
||||||
thread =
|
|
||||||
Thread status context
|
|
||||||
in
|
|
||||||
{ model | currentView = ThreadView thread } ! []
|
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
{ model
|
{ model
|
||||||
@ -481,7 +256,7 @@ processMastodonEvent msg model =
|
|||||||
FavoriteAdded result ->
|
FavoriteAdded result ->
|
||||||
case result of
|
case result of
|
||||||
Ok status ->
|
Ok status ->
|
||||||
processFavourite status.id True model ! [ loadNotifications model.client ]
|
model ! [ Command.loadNotifications model.client ]
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
{ model | errors = (errorText error) :: model.errors } ! []
|
{ model | errors = (errorText error) :: model.errors } ! []
|
||||||
@ -489,7 +264,7 @@ processMastodonEvent msg model =
|
|||||||
FavoriteRemoved result ->
|
FavoriteRemoved result ->
|
||||||
case result of
|
case result of
|
||||||
Ok status ->
|
Ok status ->
|
||||||
processFavourite status.id False model ! [ loadNotifications model.client ]
|
model ! [ Command.loadNotifications model.client ]
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
{ model | errors = (errorText error) :: model.errors } ! []
|
{ model | errors = (errorText error) :: model.errors } ! []
|
||||||
@ -500,7 +275,7 @@ processMastodonEvent msg model =
|
|||||||
{ model | localTimeline = localTimeline } ! []
|
{ model | localTimeline = localTimeline } ! []
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
{ model | localTimeline = [], errors = (errorText error) :: model.errors } ! []
|
{ model | errors = (errorText error) :: model.errors } ! []
|
||||||
|
|
||||||
Notifications result ->
|
Notifications result ->
|
||||||
case result of
|
case result of
|
||||||
@ -508,7 +283,7 @@ processMastodonEvent msg model =
|
|||||||
{ model | notifications = Mastodon.Helper.aggregateNotifications notifications } ! []
|
{ model | notifications = Mastodon.Helper.aggregateNotifications notifications } ! []
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
{ model | notifications = [], errors = (errorText error) :: model.errors } ! []
|
{ model | errors = (errorText error) :: model.errors } ! []
|
||||||
|
|
||||||
GlobalTimeline result ->
|
GlobalTimeline result ->
|
||||||
case result of
|
case result of
|
||||||
@ -516,12 +291,12 @@ processMastodonEvent msg model =
|
|||||||
{ model | globalTimeline = globalTimeline } ! []
|
{ model | globalTimeline = globalTimeline } ! []
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
{ model | globalTimeline = [], errors = (errorText error) :: model.errors } ! []
|
{ model | errors = (errorText error) :: model.errors } ! []
|
||||||
|
|
||||||
Reblogged result ->
|
Reblogged result ->
|
||||||
case result of
|
case result of
|
||||||
Ok status ->
|
Ok status ->
|
||||||
model ! [ loadNotifications model.client ]
|
model ! [ Command.loadNotifications model.client ]
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
{ model | errors = (errorText error) :: model.errors } ! []
|
{ model | errors = (errorText error) :: model.errors } ! []
|
||||||
@ -545,15 +320,16 @@ processMastodonEvent msg model =
|
|||||||
Unreblogged result ->
|
Unreblogged result ->
|
||||||
case result of
|
case result of
|
||||||
Ok status ->
|
Ok status ->
|
||||||
model ! [ loadNotifications model.client ]
|
model ! [ Command.loadNotifications model.client ]
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
{ model | errors = (errorText error) :: model.errors } ! []
|
{ model | errors = (errorText error) :: model.errors } ! []
|
||||||
|
|
||||||
Account result ->
|
AccountReceived result ->
|
||||||
case result of
|
case result of
|
||||||
Ok account ->
|
Ok account ->
|
||||||
{ model | currentView = AccountView account } ! []
|
{ model | currentView = AccountView account }
|
||||||
|
! [ Command.loadAccountInfo model.client account.id ]
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
{ model
|
{ model
|
||||||
@ -570,13 +346,29 @@ processMastodonEvent msg model =
|
|||||||
Err error ->
|
Err error ->
|
||||||
{ model | errors = (errorText error) :: model.errors } ! []
|
{ model | errors = (errorText error) :: model.errors } ! []
|
||||||
|
|
||||||
|
AccountFollowers result ->
|
||||||
|
case result of
|
||||||
|
Ok statuses ->
|
||||||
|
{ model | accountFollowers = statuses } ! []
|
||||||
|
|
||||||
|
Err error ->
|
||||||
|
{ model | errors = (errorText error) :: model.errors } ! []
|
||||||
|
|
||||||
|
AccountFollowing result ->
|
||||||
|
case result of
|
||||||
|
Ok statuses ->
|
||||||
|
{ model | accountFollowing = statuses } ! []
|
||||||
|
|
||||||
|
Err error ->
|
||||||
|
{ model | errors = (errorText error) :: model.errors } ! []
|
||||||
|
|
||||||
UserTimeline result ->
|
UserTimeline result ->
|
||||||
case result of
|
case result of
|
||||||
Ok userTimeline ->
|
Ok userTimeline ->
|
||||||
{ model | userTimeline = userTimeline } ! []
|
{ model | userTimeline = userTimeline } ! []
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
{ model | userTimeline = [], errors = (errorText error) :: model.errors } ! []
|
{ model | errors = (errorText error) :: model.errors } ! []
|
||||||
|
|
||||||
|
|
||||||
processWebSocketMsg : WebSocketMsg -> Model -> ( Model, Cmd Msg )
|
processWebSocketMsg : WebSocketMsg -> Model -> ( Model, Cmd Msg )
|
||||||
@ -672,9 +464,6 @@ update msg model =
|
|||||||
NoOp ->
|
NoOp ->
|
||||||
model ! []
|
model ! []
|
||||||
|
|
||||||
DomResult result ->
|
|
||||||
model ! []
|
|
||||||
|
|
||||||
MastodonEvent msg ->
|
MastodonEvent msg ->
|
||||||
let
|
let
|
||||||
( newModel, commands ) =
|
( newModel, commands ) =
|
||||||
@ -696,76 +485,28 @@ update msg model =
|
|||||||
model ! []
|
model ! []
|
||||||
|
|
||||||
Register ->
|
Register ->
|
||||||
model ! [ registerApp model ]
|
model ! [ Command.registerApp model ]
|
||||||
|
|
||||||
OpenThread status ->
|
OpenThread status ->
|
||||||
case model.client of
|
model ! [ Command.loadThread model.client status ]
|
||||||
Just client ->
|
|
||||||
model
|
|
||||||
! [ Mastodon.Http.context client status.id
|
|
||||||
|> Mastodon.Http.send (MastodonEvent << (ContextLoaded status))
|
|
||||||
]
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
model ! []
|
|
||||||
|
|
||||||
CloseThread ->
|
CloseThread ->
|
||||||
{ model | currentView = preferredTimeline model } ! []
|
{ model | currentView = preferredTimeline model } ! []
|
||||||
|
|
||||||
DeleteStatus id ->
|
DeleteStatus id ->
|
||||||
case model.client of
|
model ! [ Command.deleteStatus model.client id ]
|
||||||
Just client ->
|
|
||||||
model ! [ deleteStatus client id ]
|
|
||||||
|
|
||||||
Nothing ->
|
ReblogStatus id ->
|
||||||
model ! []
|
processReblog id True model ! [ Command.reblogStatus model.client id ]
|
||||||
|
|
||||||
Reblog id ->
|
UnreblogStatus id ->
|
||||||
-- Note: The case of reblogging is specific as it seems the server
|
processReblog id False model ! [ Command.unreblogStatus model.client id ]
|
||||||
-- 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
|
|
||||||
! [ Mastodon.Http.reblog client id
|
|
||||||
|> Mastodon.Http.send (MastodonEvent << Reblogged)
|
|
||||||
]
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
model ! []
|
|
||||||
|
|
||||||
Unreblog id ->
|
|
||||||
case model.client of
|
|
||||||
Just client ->
|
|
||||||
processReblog id False model
|
|
||||||
! [ Mastodon.Http.unfavourite client id
|
|
||||||
|> Mastodon.Http.send (MastodonEvent << Unreblogged)
|
|
||||||
]
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
model ! []
|
|
||||||
|
|
||||||
AddFavorite id ->
|
AddFavorite id ->
|
||||||
model
|
processFavourite id True model ! [ Command.favouriteStatus model.client id ]
|
||||||
! case model.client of
|
|
||||||
Just client ->
|
|
||||||
[ Mastodon.Http.favourite client id
|
|
||||||
|> Mastodon.Http.send (MastodonEvent << FavoriteAdded)
|
|
||||||
]
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
RemoveFavorite id ->
|
RemoveFavorite id ->
|
||||||
model
|
processFavourite id False model ! [ Command.unfavouriteStatus model.client id ]
|
||||||
! case model.client of
|
|
||||||
Just client ->
|
|
||||||
[ Mastodon.Http.unfavourite client id
|
|
||||||
|> Mastodon.Http.send (MastodonEvent << FavoriteRemoved)
|
|
||||||
]
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
DraftEvent draftMsg ->
|
DraftEvent draftMsg ->
|
||||||
case model.currentUser of
|
case model.currentUser of
|
||||||
@ -787,31 +528,20 @@ update msg model =
|
|||||||
{ model | viewer = viewer } ! [ commands ]
|
{ model | viewer = viewer } ! [ commands ]
|
||||||
|
|
||||||
SubmitDraft ->
|
SubmitDraft ->
|
||||||
model
|
model ! [ Command.postStatus model.client <| toStatusRequestBody model.draft ]
|
||||||
! case model.client of
|
|
||||||
Just client ->
|
|
||||||
[ postStatus client <| toStatusRequestBody model.draft ]
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
LoadAccount accountId ->
|
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
|
|
||||||
-}
|
|
||||||
{ model | currentView = preferredTimeline model }
|
{ model | currentView = preferredTimeline model }
|
||||||
! case model.client of
|
! [ Command.loadAccount model.client accountId ]
|
||||||
Just client ->
|
|
||||||
[ Mastodon.Http.fetchAccount client accountId
|
|
||||||
|> Mastodon.Http.send (MastodonEvent << Account)
|
|
||||||
, Mastodon.Http.fetchAccountTimeline client accountId
|
|
||||||
|> Mastodon.Http.send (MastodonEvent << AccountTimeline)
|
|
||||||
]
|
|
||||||
|
|
||||||
Nothing ->
|
ViewAccountFollowers account ->
|
||||||
[]
|
{ model | currentView = AccountFollowersView account model.accountFollowers } ! []
|
||||||
|
|
||||||
|
ViewAccountFollowing account ->
|
||||||
|
{ model | currentView = AccountFollowingView account model.accountFollowing } ! []
|
||||||
|
|
||||||
|
ViewAccountStatuses account ->
|
||||||
|
{ model | currentView = AccountView account } ! []
|
||||||
|
|
||||||
UseGlobalTimeline flag ->
|
UseGlobalTimeline flag ->
|
||||||
let
|
let
|
||||||
@ -820,11 +550,17 @@ update msg model =
|
|||||||
in
|
in
|
||||||
{ model | currentView = preferredTimeline newModel } ! []
|
{ model | currentView = preferredTimeline newModel } ! []
|
||||||
|
|
||||||
ClearOpenedAccount ->
|
CloseAccount ->
|
||||||
{ model | currentView = preferredTimeline model } ! []
|
{ model
|
||||||
|
| currentView = preferredTimeline model
|
||||||
|
, accountTimeline = []
|
||||||
|
, accountFollowing = []
|
||||||
|
, accountFollowers = []
|
||||||
|
}
|
||||||
|
! []
|
||||||
|
|
||||||
ScrollColumn context ->
|
ScrollColumn context ->
|
||||||
model ! [ Task.attempt DomResult <| Dom.Scroll.toTop context ]
|
model ! [ Task.attempt (always NoOp) <| Dom.Scroll.toTop context ]
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
subscriptions : Model -> Sub Msg
|
||||||
|
138
src/Types.elm
Normal file
138
src/Types.elm
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
module Types exposing (..)
|
||||||
|
|
||||||
|
import Mastodon.Model exposing (..)
|
||||||
|
import Navigation
|
||||||
|
|
||||||
|
|
||||||
|
type alias Flags =
|
||||||
|
{ client : Maybe Client
|
||||||
|
, registration : Maybe AppRegistration
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type DraftMsg
|
||||||
|
= ClearDraft
|
||||||
|
| UpdateSensitive Bool
|
||||||
|
| UpdateSpoiler String
|
||||||
|
| UpdateStatus String
|
||||||
|
| UpdateVisibility String
|
||||||
|
| UpdateReplyTo Status
|
||||||
|
| ToggleSpoiler Bool
|
||||||
|
|
||||||
|
|
||||||
|
type ViewerMsg
|
||||||
|
= CloseViewer
|
||||||
|
| OpenViewer (List Attachment) Attachment
|
||||||
|
|
||||||
|
|
||||||
|
type MastodonMsg
|
||||||
|
= AccessToken (Result Error AccessTokenResult)
|
||||||
|
| AccountFollowers (Result Error (List Account))
|
||||||
|
| AccountFollowing (Result Error (List Account))
|
||||||
|
| AccountReceived (Result Error Account)
|
||||||
|
| AccountTimeline (Result Error (List Status))
|
||||||
|
| AppRegistered (Result Error AppRegistration)
|
||||||
|
| ContextLoaded Status (Result Error Context)
|
||||||
|
| CurrentUser (Result Error Account)
|
||||||
|
| FavoriteAdded (Result Error Status)
|
||||||
|
| FavoriteRemoved (Result Error Status)
|
||||||
|
| GlobalTimeline (Result Error (List Status))
|
||||||
|
| LocalTimeline (Result Error (List Status))
|
||||||
|
| Notifications (Result Error (List Notification))
|
||||||
|
| Reblogged (Result Error Status)
|
||||||
|
| StatusDeleted (Result Error Int)
|
||||||
|
| StatusPosted (Result Error Status)
|
||||||
|
| Unreblogged (Result Error Status)
|
||||||
|
| UserTimeline (Result Error (List Status))
|
||||||
|
|
||||||
|
|
||||||
|
type WebSocketMsg
|
||||||
|
= NewWebsocketGlobalMessage String
|
||||||
|
| NewWebsocketLocalMessage String
|
||||||
|
| NewWebsocketUserMessage String
|
||||||
|
|
||||||
|
|
||||||
|
type Msg
|
||||||
|
= AddFavorite Int
|
||||||
|
| CloseAccount
|
||||||
|
| CloseThread
|
||||||
|
| DeleteStatus Int
|
||||||
|
| DraftEvent DraftMsg
|
||||||
|
| LoadAccount Int
|
||||||
|
| MastodonEvent MastodonMsg
|
||||||
|
| NoOp
|
||||||
|
| OpenThread Status
|
||||||
|
| ReblogStatus Int
|
||||||
|
| Register
|
||||||
|
| RemoveFavorite Int
|
||||||
|
| ScrollColumn String
|
||||||
|
| ServerChange String
|
||||||
|
| SubmitDraft
|
||||||
|
| UrlChange Navigation.Location
|
||||||
|
| UseGlobalTimeline Bool
|
||||||
|
| UnreblogStatus Int
|
||||||
|
| ViewAccountFollowing Account
|
||||||
|
| ViewAccountFollowers Account
|
||||||
|
| ViewAccountStatuses Account
|
||||||
|
| ViewerEvent ViewerMsg
|
||||||
|
| WebSocketEvent WebSocketMsg
|
||||||
|
|
||||||
|
|
||||||
|
type alias AccountViewInfo =
|
||||||
|
{ account : Account
|
||||||
|
, timeline : List Status
|
||||||
|
, folowers : List Account
|
||||||
|
, following : List Account
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type alias Draft =
|
||||||
|
{ status : String
|
||||||
|
, in_reply_to : Maybe Status
|
||||||
|
, spoiler_text : Maybe String
|
||||||
|
, sensitive : Bool
|
||||||
|
, visibility : String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type alias Thread =
|
||||||
|
{ status : Status
|
||||||
|
, context : Context
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type alias Viewer =
|
||||||
|
{ attachments : List Attachment
|
||||||
|
, attachment : Attachment
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type CurrentView
|
||||||
|
= -- Basically, what we should be displaying in the fourth column
|
||||||
|
AccountFollowersView Account (List Account)
|
||||||
|
| AccountFollowingView Account (List Account)
|
||||||
|
| AccountView Account
|
||||||
|
| GlobalTimelineView
|
||||||
|
| LocalTimelineView
|
||||||
|
| ThreadView Thread
|
||||||
|
|
||||||
|
|
||||||
|
type alias Model =
|
||||||
|
{ server : String
|
||||||
|
, registration : Maybe AppRegistration
|
||||||
|
, client : Maybe Client
|
||||||
|
, userTimeline : List Status
|
||||||
|
, localTimeline : List Status
|
||||||
|
, globalTimeline : List Status
|
||||||
|
, accountTimeline : List Status
|
||||||
|
, accountFollowers : List Account
|
||||||
|
, accountFollowing : List Account
|
||||||
|
, notifications : List NotificationAggregate
|
||||||
|
, draft : Draft
|
||||||
|
, errors : List String
|
||||||
|
, location : Navigation.Location
|
||||||
|
, useGlobalTimeline : Bool
|
||||||
|
, viewer : Maybe Viewer
|
||||||
|
, currentUser : Maybe Account
|
||||||
|
, currentView : CurrentView
|
||||||
|
}
|
206
src/View.elm
206
src/View.elm
@ -6,8 +6,8 @@ import Html.Attributes exposing (..)
|
|||||||
import Html.Events exposing (..)
|
import Html.Events exposing (..)
|
||||||
import List.Extra exposing (elemIndex, getAt)
|
import List.Extra exposing (elemIndex, getAt)
|
||||||
import Mastodon.Helper
|
import Mastodon.Helper
|
||||||
import Mastodon.Model
|
import Mastodon.Model exposing (..)
|
||||||
import Model exposing (..)
|
import Types exposing (..)
|
||||||
import ViewHelper exposing (..)
|
import ViewHelper exposing (..)
|
||||||
import Date
|
import Date
|
||||||
import Date.Extra.Config.Config_en_au as DateEn
|
import Date.Extra.Config.Config_en_au as DateEn
|
||||||
@ -66,7 +66,7 @@ icon name =
|
|||||||
i [ class <| "glyphicon glyphicon-" ++ name ] []
|
i [ class <| "glyphicon glyphicon-" ++ name ] []
|
||||||
|
|
||||||
|
|
||||||
accountLink : Mastodon.Model.Account -> Html Msg
|
accountLink : Account -> Html Msg
|
||||||
accountLink account =
|
accountLink account =
|
||||||
a
|
a
|
||||||
[ href account.url
|
[ href account.url
|
||||||
@ -75,7 +75,7 @@ accountLink account =
|
|||||||
[ text <| "@" ++ account.username ]
|
[ text <| "@" ++ account.username ]
|
||||||
|
|
||||||
|
|
||||||
accountAvatarLink : Mastodon.Model.Account -> Html Msg
|
accountAvatarLink : Account -> Html Msg
|
||||||
accountAvatarLink account =
|
accountAvatarLink account =
|
||||||
a
|
a
|
||||||
[ href account.url
|
[ href account.url
|
||||||
@ -85,12 +85,7 @@ accountAvatarLink account =
|
|||||||
[ img [ class "avatar", src account.avatar ] [] ]
|
[ img [ class "avatar", src account.avatar ] [] ]
|
||||||
|
|
||||||
|
|
||||||
attachmentPreview :
|
attachmentPreview : String -> Maybe Bool -> List Attachment -> Attachment -> Html Msg
|
||||||
String
|
|
||||||
-> Maybe Bool
|
|
||||||
-> List Mastodon.Model.Attachment
|
|
||||||
-> Mastodon.Model.Attachment
|
|
||||||
-> Html Msg
|
|
||||||
attachmentPreview context sensitive attachments ({ url, preview_url } as attachment) =
|
attachmentPreview context sensitive attachments ({ url, preview_url } as attachment) =
|
||||||
let
|
let
|
||||||
nsfw =
|
nsfw =
|
||||||
@ -133,7 +128,7 @@ attachmentPreview context sensitive attachments ({ url, preview_url } as attachm
|
|||||||
[ media ]
|
[ media ]
|
||||||
|
|
||||||
|
|
||||||
attachmentListView : String -> Mastodon.Model.Status -> Html Msg
|
attachmentListView : String -> Status -> Html Msg
|
||||||
attachmentListView context { media_attachments, sensitive } =
|
attachmentListView context { media_attachments, sensitive } =
|
||||||
case media_attachments of
|
case media_attachments of
|
||||||
[] ->
|
[] ->
|
||||||
@ -144,7 +139,7 @@ attachmentListView context { media_attachments, sensitive } =
|
|||||||
List.map (attachmentPreview context sensitive attachments) attachments
|
List.map (attachmentPreview context sensitive attachments) attachments
|
||||||
|
|
||||||
|
|
||||||
statusContentView : String -> Mastodon.Model.Status -> Html Msg
|
statusContentView : String -> Status -> Html Msg
|
||||||
statusContentView context status =
|
statusContentView context status =
|
||||||
case status.spoiler_text of
|
case status.spoiler_text of
|
||||||
"" ->
|
"" ->
|
||||||
@ -170,7 +165,7 @@ statusContentView context status =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
statusView : String -> Mastodon.Model.Status -> Html Msg
|
statusView : String -> Status -> Html Msg
|
||||||
statusView context ({ account, content, media_attachments, reblog, mentions } as status) =
|
statusView context ({ account, content, media_attachments, reblog, mentions } as status) =
|
||||||
let
|
let
|
||||||
accountLinkAttributes =
|
accountLinkAttributes =
|
||||||
@ -183,7 +178,7 @@ statusView context ({ account, content, media_attachments, reblog, mentions } as
|
|||||||
]
|
]
|
||||||
in
|
in
|
||||||
case reblog of
|
case reblog of
|
||||||
Just (Mastodon.Model.Reblog reblog) ->
|
Just (Reblog reblog) ->
|
||||||
div [ class "reblog" ]
|
div [ class "reblog" ]
|
||||||
[ p [ class "status-info" ]
|
[ p [ class "status-info" ]
|
||||||
[ icon "fire"
|
[ icon "fire"
|
||||||
@ -207,58 +202,94 @@ statusView context ({ account, content, media_attachments, reblog, mentions } as
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
accountTimelineView :
|
followView : Account -> Html Msg
|
||||||
Mastodon.Model.Account
|
followView account =
|
||||||
-> List Mastodon.Model.Status
|
div [ class "follow-entry" ]
|
||||||
-> String
|
[ accountAvatarLink account
|
||||||
-> String
|
, div [ class "username" ]
|
||||||
-> Html Msg
|
[ strong []
|
||||||
accountTimelineView account statuses label iconName =
|
[ text <|
|
||||||
div [ class "col-md-3 column" ]
|
if account.display_name /= "" then
|
||||||
[ div [ class "panel panel-default" ]
|
account.display_name
|
||||||
[ closeablePanelheading iconName label ClearOpenedAccount
|
else
|
||||||
, div [ class "timeline" ]
|
account.username
|
||||||
[ div
|
|
||||||
[ class "account-detail"
|
|
||||||
, style [ ( "background-image", "url('" ++ account.header ++ "')" ) ]
|
|
||||||
]
|
|
||||||
[ div [ class "opacity-layer" ]
|
|
||||||
[ img [ src account.avatar ] []
|
|
||||||
, span [ class "account-display-name" ] [ text account.display_name ]
|
|
||||||
, span [ class "account-username" ] [ text ("@" ++ account.username) ]
|
|
||||||
, span [ class "account-note" ] (formatContent account.note [])
|
|
||||||
]
|
|
||||||
]
|
|
||||||
, div [ class "row account-infos" ]
|
|
||||||
[ div [ class "col-md-4" ]
|
|
||||||
[ text "Statuses"
|
|
||||||
, br [] []
|
|
||||||
, text <| toString account.statuses_count
|
|
||||||
]
|
|
||||||
, div [ class "col-md-4" ]
|
|
||||||
[ text "Following"
|
|
||||||
, br [] []
|
|
||||||
, text <| toString account.following_count
|
|
||||||
]
|
|
||||||
, div [ class "col-md-4" ]
|
|
||||||
[ text "Followers"
|
|
||||||
, br [] []
|
|
||||||
, text <| toString account.followers_count
|
|
||||||
]
|
|
||||||
]
|
|
||||||
, ul [ class "list-group" ] <|
|
|
||||||
List.map
|
|
||||||
(\s ->
|
|
||||||
li [ class "list-group-item status" ]
|
|
||||||
[ statusView "account" s ]
|
|
||||||
)
|
|
||||||
statuses
|
|
||||||
]
|
]
|
||||||
|
, br [] []
|
||||||
|
, text <| "@" ++ account.acct
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
statusActionsView : Mastodon.Model.Status -> Mastodon.Model.Account -> Html Msg
|
accountCounterLink : String -> Int -> (Account -> Msg) -> Account -> Html Msg
|
||||||
|
accountCounterLink label count tagger account =
|
||||||
|
a
|
||||||
|
[ href ""
|
||||||
|
, class "col-md-4"
|
||||||
|
, onClickWithPreventAndStop <| tagger account
|
||||||
|
]
|
||||||
|
[ text label
|
||||||
|
, br [] []
|
||||||
|
, text <| toString count
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
accountView : String -> String -> Account -> Html Msg -> Html Msg
|
||||||
|
accountView label iconName account panelContent =
|
||||||
|
let
|
||||||
|
{ statuses_count, following_count, followers_count } =
|
||||||
|
account
|
||||||
|
in
|
||||||
|
div [ class "col-md-3 column" ]
|
||||||
|
[ div [ class "panel panel-default" ]
|
||||||
|
[ closeablePanelheading iconName label CloseAccount
|
||||||
|
, div [ class "timeline" ]
|
||||||
|
[ div
|
||||||
|
[ class "account-detail"
|
||||||
|
, style [ ( "background-image", "url('" ++ account.header ++ "')" ) ]
|
||||||
|
]
|
||||||
|
[ div [ class "opacity-layer" ]
|
||||||
|
[ img [ src account.avatar ] []
|
||||||
|
, span [ class "account-display-name" ] [ text account.display_name ]
|
||||||
|
, span [ class "account-username" ] [ text ("@" ++ account.username) ]
|
||||||
|
, span [ class "account-note" ] (formatContent account.note [])
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, div [ class "row account-infos" ]
|
||||||
|
[ accountCounterLink "Statuses" statuses_count ViewAccountStatuses account
|
||||||
|
, accountCounterLink "Following" following_count ViewAccountFollowing account
|
||||||
|
, accountCounterLink "Followers" followers_count ViewAccountFollowers account
|
||||||
|
]
|
||||||
|
, panelContent
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
accountTimelineView : String -> List Status -> Account -> Html Msg
|
||||||
|
accountTimelineView label statuses account =
|
||||||
|
accountView label "user" account <|
|
||||||
|
ul [ class "list-group" ] <|
|
||||||
|
List.map
|
||||||
|
(\s ->
|
||||||
|
li [ class "list-group-item status" ]
|
||||||
|
[ statusView "account" s ]
|
||||||
|
)
|
||||||
|
statuses
|
||||||
|
|
||||||
|
|
||||||
|
accountFollowView : String -> List Account -> Account -> Html Msg
|
||||||
|
accountFollowView label accounts account =
|
||||||
|
accountView label "user" account <|
|
||||||
|
ul [ class "list-group" ] <|
|
||||||
|
List.map
|
||||||
|
(\account ->
|
||||||
|
li [ class "list-group-item status" ]
|
||||||
|
[ followView account ]
|
||||||
|
)
|
||||||
|
accounts
|
||||||
|
|
||||||
|
|
||||||
|
statusActionsView : Status -> Account -> Html Msg
|
||||||
statusActionsView status currentUser =
|
statusActionsView status currentUser =
|
||||||
let
|
let
|
||||||
sourceStatus =
|
sourceStatus =
|
||||||
@ -270,10 +301,10 @@ statusActionsView status currentUser =
|
|||||||
( reblogClasses, reblogEvent ) =
|
( reblogClasses, reblogEvent ) =
|
||||||
case status.reblogged of
|
case status.reblogged of
|
||||||
Just True ->
|
Just True ->
|
||||||
( baseBtnClasses ++ " reblogged", Unreblog sourceStatus.id )
|
( baseBtnClasses ++ " reblogged", UnreblogStatus sourceStatus.id )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( baseBtnClasses, Reblog sourceStatus.id )
|
( baseBtnClasses, ReblogStatus sourceStatus.id )
|
||||||
|
|
||||||
( favClasses, favEvent ) =
|
( favClasses, favEvent ) =
|
||||||
case status.favourited of
|
case status.favourited of
|
||||||
@ -322,7 +353,7 @@ statusActionsView status currentUser =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
statusEntryView : String -> String -> Mastodon.Model.Account -> Mastodon.Model.Status -> Html Msg
|
statusEntryView : String -> String -> Account -> Status -> Html Msg
|
||||||
statusEntryView context className currentUser status =
|
statusEntryView context className currentUser status =
|
||||||
let
|
let
|
||||||
nsfwClass =
|
nsfwClass =
|
||||||
@ -339,13 +370,7 @@ statusEntryView context className currentUser status =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
timelineView :
|
timelineView : String -> String -> String -> Account -> List Status -> Html Msg
|
||||||
String
|
|
||||||
-> String
|
|
||||||
-> String
|
|
||||||
-> Mastodon.Model.Account
|
|
||||||
-> List Mastodon.Model.Status
|
|
||||||
-> Html Msg
|
|
||||||
timelineView label iconName context currentUser statuses =
|
timelineView label iconName context currentUser statuses =
|
||||||
div [ class "col-md-3 column" ]
|
div [ class "col-md-3 column" ]
|
||||||
[ div [ class "panel panel-default" ]
|
[ div [ class "panel panel-default" ]
|
||||||
@ -358,7 +383,7 @@ timelineView label iconName context currentUser statuses =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
notificationHeading : List Mastodon.Model.Account -> String -> String -> Html Msg
|
notificationHeading : List Account -> String -> String -> Html Msg
|
||||||
notificationHeading accounts str iconType =
|
notificationHeading accounts str iconType =
|
||||||
div [ class "status-info" ]
|
div [ class "status-info" ]
|
||||||
[ div [ class "avatars" ] <| List.map accountAvatarLink accounts
|
[ div [ class "avatars" ] <| List.map accountAvatarLink accounts
|
||||||
@ -371,12 +396,7 @@ notificationHeading accounts str iconType =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
notificationStatusView :
|
notificationStatusView : String -> Account -> Status -> NotificationAggregate -> Html Msg
|
||||||
String
|
|
||||||
-> Mastodon.Model.Account
|
|
||||||
-> Mastodon.Model.Status
|
|
||||||
-> Mastodon.Model.NotificationAggregate
|
|
||||||
-> Html Msg
|
|
||||||
notificationStatusView context currentUser status { type_, accounts } =
|
notificationStatusView context currentUser status { type_, accounts } =
|
||||||
div [ class <| "notification " ++ type_ ]
|
div [ class <| "notification " ++ type_ ]
|
||||||
[ case type_ of
|
[ case type_ of
|
||||||
@ -393,7 +413,7 @@ notificationStatusView context currentUser status { type_, accounts } =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
notificationFollowView : Mastodon.Model.Account -> Mastodon.Model.NotificationAggregate -> Html Msg
|
notificationFollowView : Account -> NotificationAggregate -> Html Msg
|
||||||
notificationFollowView currentUser { accounts } =
|
notificationFollowView currentUser { accounts } =
|
||||||
let
|
let
|
||||||
profileView account =
|
profileView account =
|
||||||
@ -414,10 +434,7 @@ notificationFollowView currentUser { accounts } =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
notificationEntryView :
|
notificationEntryView : Account -> NotificationAggregate -> Html Msg
|
||||||
Mastodon.Model.Account
|
|
||||||
-> Mastodon.Model.NotificationAggregate
|
|
||||||
-> Html Msg
|
|
||||||
notificationEntryView currentUser notification =
|
notificationEntryView currentUser notification =
|
||||||
li [ class "list-group-item" ]
|
li [ class "list-group-item" ]
|
||||||
[ case notification.status of
|
[ case notification.status of
|
||||||
@ -429,7 +446,7 @@ notificationEntryView currentUser notification =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
notificationListView : Mastodon.Model.Account -> List Mastodon.Model.NotificationAggregate -> Html Msg
|
notificationListView : Account -> List NotificationAggregate -> Html Msg
|
||||||
notificationListView currentUser notifications =
|
notificationListView currentUser notifications =
|
||||||
div [ class "col-md-3 column" ]
|
div [ class "col-md-3 column" ]
|
||||||
[ div [ class "panel panel-default" ]
|
[ div [ class "panel panel-default" ]
|
||||||
@ -465,7 +482,7 @@ draftReplyToView draft =
|
|||||||
text ""
|
text ""
|
||||||
|
|
||||||
|
|
||||||
currentUserView : Maybe Mastodon.Model.Account -> Html Msg
|
currentUserView : Maybe Account -> Html Msg
|
||||||
currentUserView currentUser =
|
currentUserView currentUser =
|
||||||
case currentUser of
|
case currentUser of
|
||||||
Just currentUser ->
|
Just currentUser ->
|
||||||
@ -594,7 +611,7 @@ draftView { draft, currentUser } =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
threadView : Mastodon.Model.Account -> Thread -> Html Msg
|
threadView : Account -> Thread -> Html Msg
|
||||||
threadView currentUser thread =
|
threadView currentUser thread =
|
||||||
let
|
let
|
||||||
statuses =
|
statuses =
|
||||||
@ -663,7 +680,7 @@ homepageView model =
|
|||||||
model.userTimeline
|
model.userTimeline
|
||||||
, notificationListView currentUser model.notifications
|
, notificationListView currentUser model.notifications
|
||||||
, case model.currentView of
|
, case model.currentView of
|
||||||
Model.LocalTimelineView ->
|
LocalTimelineView ->
|
||||||
timelineView
|
timelineView
|
||||||
"Local timeline"
|
"Local timeline"
|
||||||
"th-large"
|
"th-large"
|
||||||
@ -671,7 +688,7 @@ homepageView model =
|
|||||||
currentUser
|
currentUser
|
||||||
model.localTimeline
|
model.localTimeline
|
||||||
|
|
||||||
Model.GlobalTimelineView ->
|
GlobalTimelineView ->
|
||||||
timelineView
|
timelineView
|
||||||
"Global timeline"
|
"Global timeline"
|
||||||
"globe"
|
"globe"
|
||||||
@ -679,11 +696,16 @@ homepageView model =
|
|||||||
currentUser
|
currentUser
|
||||||
model.globalTimeline
|
model.globalTimeline
|
||||||
|
|
||||||
Model.AccountView account ->
|
AccountView account ->
|
||||||
-- Todo: Load the user timeline
|
accountTimelineView "Account" model.accountTimeline account
|
||||||
accountTimelineView account model.accountTimeline "Account" "user"
|
|
||||||
|
|
||||||
Model.ThreadView thread ->
|
AccountFollowersView account followers ->
|
||||||
|
accountFollowView "Account followers" model.accountFollowers account
|
||||||
|
|
||||||
|
AccountFollowingView account following ->
|
||||||
|
accountFollowView "Account following" model.accountFollowing account
|
||||||
|
|
||||||
|
ThreadView thread ->
|
||||||
threadView currentUser thread
|
threadView currentUser thread
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import HtmlParser
|
|||||||
import Json.Decode as Decode
|
import Json.Decode as Decode
|
||||||
import String.Extra exposing (replace)
|
import String.Extra exposing (replace)
|
||||||
import Mastodon.Model
|
import Mastodon.Model
|
||||||
import Model exposing (Msg(LoadAccount))
|
import Types exposing (..)
|
||||||
|
|
||||||
|
|
||||||
-- Custom Events
|
-- Custom Events
|
||||||
@ -83,7 +83,7 @@ createLinkNode attrs children mentions =
|
|||||||
Nothing ->
|
Nothing ->
|
||||||
Html.node "a"
|
Html.node "a"
|
||||||
((List.map toAttribute attrs)
|
((List.map toAttribute attrs)
|
||||||
++ [ onClickWithStop Model.NoOp, target "_blank" ]
|
++ [ onClickWithStop NoOp, target "_blank" ]
|
||||||
)
|
)
|
||||||
(toVirtualDom mentions children)
|
(toVirtualDom mentions children)
|
||||||
|
|
||||||
@ -91,10 +91,8 @@ createLinkNode attrs children mentions =
|
|||||||
getHrefLink : List ( String, String ) -> Maybe String
|
getHrefLink : List ( String, String ) -> Maybe String
|
||||||
getHrefLink attrs =
|
getHrefLink attrs =
|
||||||
attrs
|
attrs
|
||||||
|> List.filter
|
|> List.filter (\( name, value ) -> (name == "href"))
|
||||||
(\( name, value ) -> (name == "href"))
|
|> List.map (\( name, value ) -> value)
|
||||||
|> List.map
|
|
||||||
(\( name, value ) -> value)
|
|
||||||
|> List.head
|
|> List.head
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user