Fix #97: Allow deleting a toot. (#102)

This commit is contained in:
Nicolas Perriault 2017-04-29 09:20:26 +02:00 committed by GitHub
parent d32f12bf20
commit 44f8caa1ea
6 changed files with 199 additions and 94 deletions

View File

@ -4,43 +4,6 @@ body {
overflow: hidden;
}
::-webkit-scrollbar {
width: 10px;
height: 8px
}
::-webkit-scrollbar-thumb {
background: #444;
border: 0px none #ffffff;
border-radius: 50px;
}
::-webkit-scrollbar-thumb:hover {
background: #777;
}
::-webkit-scrollbar-thumb:active {
background: #777;
}
::-webkit-scrollbar-track {
border: 0px none #ffffff;
border-radius: 0;
background: rgba(0,0,0,0.1);
}
::-webkit-scrollbar-track:hover {
background: #2a2e31;
}
::-webkit-scrollbar-track:active {
background: #2a2e31;
}
::-webkit-scrollbar-corner {
background: transparent;
}
.timeline {
overflow-y: auto;
overflow-x: hidden;
@ -193,6 +156,10 @@ body {
color: #d56344;
}
.btn-delete .glyphicon {
font-size: 80%;
}
/* Attachments */
.attachments {
@ -441,3 +408,42 @@ body {
width: 100%;
}
}
/* Scrollbars */
::-webkit-scrollbar {
width: 10px;
height: 8px
}
::-webkit-scrollbar-thumb {
background: #444;
border: 0px none #ffffff;
border-radius: 50px;
}
::-webkit-scrollbar-thumb:hover {
background: #777;
}
::-webkit-scrollbar-thumb:active {
background: #777;
}
::-webkit-scrollbar-track {
border: 0px none #ffffff;
border-radius: 0;
background: rgba(0,0,0,0.1);
}
::-webkit-scrollbar-track:hover {
background: #2a2e31;
}
::-webkit-scrollbar-track:active {
background: #2a2e31;
}
::-webkit-scrollbar-corner {
background: transparent;
}

View File

@ -6,6 +6,7 @@ module Mastodon.ApiUrl
, userAccount
, account
, accountTimeline
, status
, homeTimeline
, publicTimeline
, notifications
@ -97,6 +98,11 @@ reblog server id =
statuses server ++ "/" ++ (toString id) ++ "/reblog"
status : Server -> Int -> String
status server id =
statuses server ++ "/" ++ (toString id)
unreblog : Server -> Int -> String
unreblog server id =
statuses server ++ "/" ++ (toString id) ++ "/unreblog"

View File

@ -1,9 +1,11 @@
module Mastodon.Helper
exposing
( extractReblog
( accountMentioned
, extractReblog
, aggregateNotifications
, addNotificationToAggregates
, notificationToAggregate
, sameAccount
)
import List.Extra exposing (groupWhile, uniqueBy)
@ -139,3 +141,13 @@ aggregateNotifications notifications =
|> List.concat
|> List.sortBy .created_at
|> List.reverse
accountMentioned : Mastodon.Model.Account -> Mastodon.Model.Mention -> Bool
accountMentioned { acct, username } mention =
acct == mention.acct && username == mention.username
sameAccount : Mastodon.Model.Account -> Mastodon.Model.Account -> Bool
sameAccount { acct, username } account =
acct == account.acct && username == account.username

View File

@ -16,6 +16,7 @@ module Mastodon.Http
, fetchGlobalTimeline
, fetchUserTimeline
, postStatus
, deleteStatus
, userAccount
, send
)
@ -148,6 +149,13 @@ postStatus client statusRequestBody =
|> HttpBuilder.withJsonBody (statusRequestBodyEncoder statusRequestBody)
deleteStatus : Client -> Int -> Request Int
deleteStatus client id =
HttpBuilder.delete (ApiUrl.status client.server id)
|> HttpBuilder.withExpect (Http.expectJson <| Decode.succeed id)
|> HttpBuilder.withHeader "Authorization" ("Bearer " ++ client.token)
context : Client -> Int -> Request Context
context client id =
HttpBuilder.get (ApiUrl.context client.server id)

View File

@ -52,6 +52,7 @@ type MastodonMsg
| 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)
@ -70,6 +71,7 @@ type Msg
| ClearOpenedAccount
| CloseThread
| DomResult (Result Dom.Error ())
| DeleteStatus Int
| DraftEvent DraftMsg
| LoadAccount Int
| MastodonEvent MastodonMsg
@ -287,22 +289,18 @@ truncate entries =
List.take maxBuffer entries
accountMentioned : Mastodon.Model.Account -> Mastodon.Model.Mention -> Bool
accountMentioned { acct, username } mention =
acct == mention.acct && username == mention.username
sameAccount : Mastodon.Model.Account -> Mastodon.Model.Account -> Bool
sameAccount { acct, username } account =
acct == account.acct && username == account.username
postStatus : Mastodon.Model.Client -> Mastodon.Model.StatusRequestBody -> Cmd Msg
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 =
case error of
@ -405,12 +403,12 @@ updateDraft draftMsg currentUser draft =
let
mentions =
status.mentions
|> List.filter (\m -> not (accountMentioned currentUser m))
|> List.filter (\m -> not (Mastodon.Helper.accountMentioned currentUser m))
|> List.map (\m -> "@" ++ m.acct)
|> String.join " "
newStatus =
if sameAccount status.account currentUser then
if Mastodon.Helper.sameAccount status.account currentUser then
mentions
else
"@" ++ status.account.acct ++ " " ++ mentions
@ -544,6 +542,19 @@ processMastodonEvent msg model =
StatusPosted _ ->
{ model | draft = defaultDraft } ! []
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 ->
@ -714,6 +725,14 @@ update msg model =
CloseThread ->
{ model | currentView = preferredTimeline model } ! []
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

View File

@ -85,7 +85,12 @@ accountAvatarLink account =
[ img [ class "avatar", src account.avatar ] [] ]
attachmentPreview : String -> Maybe Bool -> List Mastodon.Model.Attachment -> Mastodon.Model.Attachment -> Html Msg
attachmentPreview :
String
-> Maybe Bool
-> List Mastodon.Model.Attachment
-> Mastodon.Model.Attachment
-> Html Msg
attachmentPreview context sensitive attachments ({ url, preview_url } as attachment) =
let
nsfw =
@ -202,13 +207,21 @@ statusView context ({ account, content, media_attachments, reblog, mentions } as
]
accountTimelineView : Mastodon.Model.Account -> List Mastodon.Model.Status -> String -> String -> Html Msg
accountTimelineView :
Mastodon.Model.Account
-> List Mastodon.Model.Status
-> String
-> String
-> Html Msg
accountTimelineView account statuses label iconName =
div [ class "col-md-3 column" ]
[ div [ class "panel panel-default" ]
[ closeablePanelheading iconName label ClearOpenedAccount
, div [ class "timeline" ]
[ div [ class "account-detail", style [ ( "background-image", "url('" ++ account.header ++ "')" ) ] ]
[ 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 ]
@ -245,8 +258,8 @@ accountTimelineView account statuses label iconName =
]
statusActionsView : Mastodon.Model.Status -> Html Msg
statusActionsView status =
statusActionsView : Mastodon.Model.Status -> Mastodon.Model.Account -> Html Msg
statusActionsView status currentUser =
let
targetStatus =
Mastodon.Helper.extractReblog status
@ -294,17 +307,23 @@ statusActionsView status =
, onClickWithPreventAndStop favEvent
]
[ icon "star", text (toString status.favourites_count) ]
, if Mastodon.Helper.sameAccount status.account currentUser then
a
[ class <| baseBtnClasses ++ " btn-delete"
, href ""
, onClickWithPreventAndStop <| DeleteStatus status.id
]
[ icon "trash" ]
else
text ""
, a
[ class baseBtnClasses
, href status.url
, onClickWithPreventAndStop <| OpenThread status
]
[ class baseBtnClasses, href status.url, target "_blank" ]
[ icon "time", formatDate ]
]
statusEntryView : String -> String -> Mastodon.Model.Status -> Html Msg
statusEntryView context className status =
statusEntryView : String -> String -> Mastodon.Model.Account -> Mastodon.Model.Status -> Html Msg
statusEntryView context className currentUser status =
let
nsfwClass =
case status.sensitive of
@ -316,19 +335,25 @@ statusEntryView context className status =
in
li [ class <| "list-group-item " ++ className ++ " " ++ nsfwClass ]
[ statusView context status
, statusActionsView status
, statusActionsView status currentUser
]
timelineView : String -> String -> String -> List Mastodon.Model.Status -> Html Msg
timelineView label iconName context statuses =
timelineView :
String
-> String
-> String
-> Mastodon.Model.Account
-> List Mastodon.Model.Status
-> Html Msg
timelineView label iconName context currentUser statuses =
div [ class "col-md-3 column" ]
[ div [ class "panel panel-default" ]
[ a
[ href "", onClickWithPreventAndStop <| ScrollColumn context ]
[ div [ class "panel-heading" ] [ icon iconName, text label ] ]
, ul [ id context, class "list-group timeline" ] <|
List.map (statusEntryView context "") statuses
List.map (statusEntryView context "" currentUser) statuses
]
]
@ -346,8 +371,13 @@ notificationHeading accounts str iconType =
]
notificationStatusView : String -> Mastodon.Model.Status -> Mastodon.Model.NotificationAggregate -> Html Msg
notificationStatusView context status { type_, accounts } =
notificationStatusView :
String
-> Mastodon.Model.Account
-> Mastodon.Model.Status
-> Mastodon.Model.NotificationAggregate
-> Html Msg
notificationStatusView context currentUser status { type_, accounts } =
div [ class <| "notification " ++ type_ ]
[ case type_ of
"reblog" ->
@ -359,12 +389,12 @@ notificationStatusView context status { type_, accounts } =
_ ->
text ""
, statusView context status
, statusActionsView status
, statusActionsView status currentUser
]
notificationFollowView : Mastodon.Model.NotificationAggregate -> Html Msg
notificationFollowView { accounts } =
notificationFollowView : Mastodon.Model.Account -> Mastodon.Model.NotificationAggregate -> Html Msg
notificationFollowView currentUser { accounts } =
let
profileView account =
div [ class "status follow-profile" ]
@ -384,27 +414,30 @@ notificationFollowView { accounts } =
]
notificationEntryView : Mastodon.Model.NotificationAggregate -> Html Msg
notificationEntryView notification =
notificationEntryView :
Mastodon.Model.Account
-> Mastodon.Model.NotificationAggregate
-> Html Msg
notificationEntryView currentUser notification =
li [ class "list-group-item" ]
[ case notification.status of
Just status ->
notificationStatusView "notification" status notification
notificationStatusView "notification" currentUser status notification
Nothing ->
notificationFollowView notification
notificationFollowView currentUser notification
]
notificationListView : List Mastodon.Model.NotificationAggregate -> Html Msg
notificationListView notifications =
notificationListView : Mastodon.Model.Account -> List Mastodon.Model.NotificationAggregate -> Html Msg
notificationListView currentUser notifications =
div [ class "col-md-3 column" ]
[ div [ class "panel panel-default" ]
[ a
[ href "", onClickWithPreventAndStop <| ScrollColumn "notifications" ]
[ div [ class "panel-heading" ] [ icon "bell", text "Notifications" ] ]
, ul [ id "notifications", class "list-group timeline" ] <|
List.map notificationEntryView notifications
List.map (notificationEntryView currentUser) notifications
]
]
@ -561,8 +594,8 @@ draftView { draft, currentUser } =
]
threadView : Thread -> Html Msg
threadView thread =
threadView : Mastodon.Model.Account -> Thread -> Html Msg
threadView currentUser thread =
let
statuses =
List.concat
@ -578,6 +611,7 @@ threadView thread =
else
""
)
currentUser
status
in
div [ class "col-md-3 column" ]
@ -614,24 +648,44 @@ sidebarView model =
homepageView : Model -> Html Msg
homepageView model =
div [ class "row" ]
[ sidebarView model
, timelineView "Home timeline" "home" "home" model.userTimeline
, notificationListView model.notifications
, case model.currentView of
Model.LocalTimelineView ->
timelineView "Local timeline" "th-large" "local" model.localTimeline
case model.currentUser of
Nothing ->
text ""
Model.GlobalTimelineView ->
timelineView "Global timeline" "globe" "global" model.globalTimeline
Just currentUser ->
div [ class "row" ]
[ sidebarView model
, timelineView
"Home timeline"
"home"
"home"
currentUser
model.userTimeline
, notificationListView currentUser model.notifications
, case model.currentView of
Model.LocalTimelineView ->
timelineView
"Local timeline"
"th-large"
"local"
currentUser
model.localTimeline
Model.AccountView account ->
-- Todo: Load the user timeline
accountTimelineView account model.accountTimeline "Account" "user"
Model.GlobalTimelineView ->
timelineView
"Global timeline"
"globe"
"global"
currentUser
model.globalTimeline
Model.ThreadView thread ->
threadView thread
]
Model.AccountView account ->
-- Todo: Load the user timeline
accountTimelineView account model.accountTimeline "Account" "user"
Model.ThreadView thread ->
threadView currentUser thread
]
authView : Model -> Html Msg