diff of 32e8cda49a3bf4a5862032472a6c7b01e3048521
32e8cda49a3bf4a5862032472a6c7b01e3048521
diff --git a/elm-frontti/elm.json b/elm-frontti/elm.json
deleted file mode 100644
index c8df00f..0000000
--- a/elm-frontti/elm.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "type": "application",
- "source-directories": [
- "src"
- ],
- "elm-version": "0.19.1",
- "dependencies": {
- "direct": {
- "NoRedInk/elm-json-decode-pipeline": "1.0.0",
- "PanagiotisGeorgiadis/elm-datetime": "1.3.0",
- "TSFoster/elm-uuid": "4.2.0",
- "danhandrea/elm-date-format": "2.0.1",
- "elm/browser": "1.0.2",
- "elm/core": "1.0.5",
- "elm/file": "1.0.5",
- "elm/html": "1.0.0",
- "elm/http": "2.0.0",
- "elm/json": "1.1.3",
- "elm/random": "1.0.0",
- "elm/regex": "1.0.0",
- "elm/time": "1.0.0",
- "elm/url": "1.0.0",
- "elm-community/dict-extra": "2.4.0",
- "elm-community/list-extra": "8.7.0",
- "elm-community/string-extra": "4.0.1",
- "mhoare/elm-stack": "3.1.2",
- "waratuman/json-extra": "1.0.2",
- "waratuman/time-extra": "1.1.0"
- },
- "indirect": {
- "TSFoster/elm-bytes-extra": "1.3.0",
- "TSFoster/elm-md5": "2.0.1",
- "TSFoster/elm-sha1": "2.1.1",
- "danfishgold/base64-bytes": "1.1.0",
- "elm/bytes": "1.0.8",
- "elm/parser": "1.1.0",
- "elm/virtual-dom": "1.0.2",
- "justinmimbs/timezone-data": "2.1.4",
- "rtfeldman/elm-hex": "1.0.0",
- "rtfeldman/elm-iso8601-date-strings": "1.1.3"
- }
- },
- "test-dependencies": {
- "direct": {},
- "indirect": {}
- }
-}
diff --git a/elm-frontti/src/Ajax_cmds.elm b/elm-frontti/src/Ajax_cmds.elm
deleted file mode 100644
index 52492f6..0000000
--- a/elm-frontti/src/Ajax_cmds.elm
+++ /dev/null
@@ -1,220 +0,0 @@
-module Ajax_cmds exposing (..)
-
-import Article
-import User
-import Page
-import Feeds
-import Message exposing (..)
-import Http exposing (..)
-import Image
-import Initial
-import Settings
-import Logs
-import Json.Decode as Json
-
-getSession =
- Http.get
- { url = "/api/login/session"
- , expect = Http.expectJson GotSession User.userDecoder}
-
-getEditablePosts : Cmd Msg
-getEditablePosts =
- Http.get
- { url = "/api/posts/all-titles"
- , expect = Http.expectJson EditableTitlesReceived (Json.list Article.sidebarTitleDecoder) }
-
-getPage page_id =
- Http.get
- { url = "/api/posts/page/" ++ (String.fromInt page_id)
- , expect = Http.expectJson PageReceived Page.pageDecoder}
-
-getPost : Int -> Cmd Msg
-getPost post_id =
- Http.get
- { url = "/api/posts/post/" ++ (String.fromInt post_id)
- , expect = Http.expectJson PostReceived Article.articleDecoder}
-
-getSettings =
- Http.get
- { url = "/api/settings/client-settings"
- , expect = Http.expectJson SettingsReceived Settings.settingsDecoder}
-
-getSettingsAdmin =
- Http.get
- { url = "/api/settings/client-settings"
- , expect = Http.expectJson AdminSettingsReceived Settings.settingsDecoder}
-
-getTitles =
- Http.get
- { url = "/api/posts/titles"
- , expect = Http.expectJson TitlesReceived (Json.list Article.sidebarTitleDecoder)}
-
-postLogin username password =
- Http.post
- { url = "/api/login/login"
- , expect = Http.expectJson LoginSuccess User.userDecoder
- , body = Http.jsonBody <| User.encodeLoggingIn <| User.UserLoggingIn username password}
-
-getPostEditorData post_id =
- Http.get
- { url = "/api/posts/post/" ++ (String.fromInt post_id) ++ "/allow-hidden/true"
- , expect = Http.expectJson EditorPostReceived Article.articleDecoder}
-
-putArticle : Article.Article -> Cmd Msg
-putArticle article =
- Http.request
- { method = "PUT"
- , headers = []
- , url = "/api/posts/post"
- , body = Http.jsonBody <| Article.encode article
- , expect = Http.expectString HttpGoHome
- , timeout = Nothing
- , tracker = Nothing
- }
-
--- returns { :id :name }
-getListOfImages : Bool -> Cmd Msg
-getListOfImages managerCalled = Http.get
- { url = "/api/pictures/list/all"
- , expect = Http.expectJson (GotListOfImages managerCalled) (Json.list Image.imageDecoder)}
-
-
-postPicture handler_msg url pictureFile = Http.post
- { url = url
- , body = Http.multipartBody [ Http.filePart "file" pictureFile ]
- , expect = Http.expectJson handler_msg Image.imageResponseDecoder }
-
-
-deletePictures ids = Http.request
- { url = "/api/pictures"
- , method = "DELETE"
- , headers = []
- , expect = Http.expectString HttpManagerGetListOfImages
- , body = Http.jsonBody <| (Image.list_of_uuids_encode ids)
- , timeout = Nothing
- , tracker = Nothing}
-
-getReferencingPosts id = Http.get
- { url = "/api/pictures/referencing/" ++ id
- , expect = Http.expectJson GotReferencingPosts (Json.list Image.referencingPostDecoder)}
-
-loadTaggedPosts tags = Http.get
- { url = "/api/posts/tagged/" ++ tags
- , expect = Http.expectJson GotTaggedPosts (Json.list Article.articleDecoder)}
-
-loadPostVersion post_id_int version_id_int =
- let post_id = String.fromInt post_id_int
- version_id = String.fromInt version_id_int in
- Http.get
- { url = "/api/posts/post/" ++ post_id ++ "/version/" ++ version_id
- , expect = Http.expectJson GotOldPost Article.articleDecoder}
-
-generateNewPost =
- Http.request
- { method = "POST"
- , headers = []
- , url = "/api/posts/new_post"
- , body = emptyBody
- , expect = Http.expectJson NewPostGenerated Json.int
- , timeout = Nothing
- , tracker = Nothing
- }
-
-saveSettings settings =
- Http.request
- { method = "PUT"
- , headers = []
- , url = "/api/settings/client-settings"
- , body = Http.jsonBody (Settings.encodeSettings settings)
- , expect = Http.expectWhatever SettingsSaved
- , timeout = Nothing
- , tracker = Nothing}
-
-searchPreviouslyPosts search_term =
- Http.post
- { url = "/api/posts/search-previously"
- , body = Http.stringBody "application/json" search_term
- , expect = Http.expectJson PreviouslySearchResult (Json.list Article.previouslyDocDecoder)}
-
-
-loadPreviousArticle post_id =
- Http.get
- { url = "/api/posts/post/" ++ (String.fromInt post_id)
- , expect = Http.expectJson PreviousPostReceived Article.articleDecoder}
-
-getFeeds archived =
- Http.get
- { url = if archived then
- "/api/user/feeds?archived=archived"
- else
- "/api/user/feeds"
- , expect = Http.expectJson FeedsReceived (Json.list Feeds.feedDecoder)}
-
-addFeed newFeed =
- Http.post
- { url = "/api/user/feeds"
- , body = Http.jsonBody (Feeds.newFeedEncoder newFeed)
- , expect = Http.expectWhatever FeedAdded }
-
-markFeedItemRead feed_id item_id =
- Http.post
- { url = "/api/user/feeds/" ++ feed_id ++ "/" ++ item_id ++ "/mark-read"
- , body = Http.emptyBody
- , expect = Http.expectWhatever FeedItemReadResponse}
-
-deleteFeed feed_id =
- Http.request
- { url = "/api/user/feeds/" ++ feed_id
- , method = "DELETE"
- , headers = []
- , expect = Http.expectWhatever FeedDeleted
- , body = Http.emptyBody
- , timeout = Nothing
- , tracker = Nothing}
-
-getFeedMeta =
- Http.get
- { url = "/api/user/feeds/meta"
- , expect = Http.expectJson FeedMetaReceived Feeds.metadataDecoder}
-
-postExcerpt excerpt feed_id =
- Http.post
- { url = " /api/posts/excerpt/" ++ feed_id
- , body = Http.stringBody "text/plain" excerpt
- , expect = Http.expectJson NewPostGenerated Json.int}
-
-getAdminLogs =
- Http.get
- { url = "/api/logs"
- , expect = Http.expectJson GotAdminLogs (Json.list Logs.decoder)}
-
-saveGroups groups =
- Http.post
- { url = "/api/logs/groups"
- , body = Http.jsonBody <| Logs.groupsEncoder groups
- , expect = Http.expectWhatever LogGroupsSaved}
-
-getLogGroups =
- Http.get
- { url = "/api/logs/groups"
- , expect = Http.expectJson GotLogGroups Logs.groupsDecoder}
-
-getTopbarAlarms permissions =
- if List.member "update-settings" permissions then
- Http.get
- { url = "/api/logs/alarm"
- , expect = Http.expectJson GotTopbarLogAlarm Logs.topbarAlarmDecoder}
- else
- Cmd.none
-
-submitUser user oldpasswd newpasswd =
- Http.post
- { url = "/api/user/submit"
- , body = Http.jsonBody (User.encodeEditorUser user oldpasswd newpasswd)
- , expect = Http.expectWhatever UserSubmitResult}
-
-postInitialData data =
- Http.post
- { url = "/api/initial"
- , body = Http.jsonBody <| Initial.initialEncoder data
- , expect = Http.expectWhatever PostInitialSuccess}
diff --git a/elm-frontti/src/Article.elm b/elm-frontti/src/Article.elm
deleted file mode 100644
index 2e67007..0000000
--- a/elm-frontti/src/Article.elm
+++ /dev/null
@@ -1,146 +0,0 @@
-module Article exposing (..)
-
-import Creator exposing (encode)
-
-import DateTime exposing (DateTime)
-import Json.Encode as Json exposing (..)
-import Json.Encode.Extra exposing (..)
-import Json.Decode as Decode exposing (Decoder, succeed)
-import Json.Decode.Pipeline exposing (required)
-import Json.Decode.Extra as Extra
-import Time
-
--- {
--- "tags": [],
--- "creator": {
--- "username": "feuer",
--- "nickname": "Feuer",
--- "img_location": "https://feuerx.net/etc/feuer.jpeg"
--- },
--- "content": "<p>Tämä on testi posti :D</p>\n\n<p>Uusi paragraaaaaaaafffi</p>",
--- "comments": [],
--- "amount-of-comments": 0,
--- "title": "Testi Posti",
--- "id": 1,
--- "versions": [],
--- "version": null,
--- "created_at": "2020-10-16T07:52:59Z",
--- "previosly": [{"id": 666,
--- "title": "Titteli"}]
--- }
-
-import Creator exposing (Creator, creatorDecoder)
-
-decodeApply : Decode.Decoder a -> Decode.Decoder (a -> b) -> Decode.Decoder b
-decodeApply value partial =
- Decode.andThen (\p -> Decode.map p value) partial
-
-type ArticleSource
- = Murja
- | Rss
- String -- <-link
-
-type alias PreviousArticle =
- { id: Int
- , title: String}
-
-type alias Article =
- { creator : Creator
- , tags : List String
- , content : String
- -- TODO make a comment type
- , comments : Maybe (List String)
- -- , amount_of_comments : Int
- , title : String
- , id : Int
- , versions: Maybe (List Int)
- , version : Maybe Int
- , created_at: Maybe Time.Posix
- , hidden : Bool
- , unlisted : Bool
- , previously: List PreviousArticle
- , source: ArticleSource}
-
--- encoder
-
-encodePreviously prev =
- object
- [ ( "id", int prev.id)
- , ( "title", string prev.title)]
-
-encode : Article -> Json.Value
-encode article =
- object
- [ ( "creator", Creator.encode article.creator )
- , ( "tags", list string article.tags)
- , ( "content", string article.content)
- , ( "comments", (list string (case article.comments of
- Just comments -> comments
- Nothing -> [])))
- , ( "title", string article.title)
- , ( "id", int article.id)
- , ( "version", (maybe int) article.version)
- , ( "created_at", (maybe iso8601) article.created_at)
- , ( "hidden", bool article.hidden)
- , ( "unlisted", bool article.unlisted)
- , ( "previously", list encodePreviously article.previously)
- ]
-
-
--- decoder
-
-
-tagsDecoder = Decode.field "tags" (Decode.list Decode.string)
-contentDecoder = Decode.field "content" Decode.string
-commentsDecoder = Decode.maybe (Decode.field "comments" (Decode.list Decode.string))
--- amount_of_commentsDecoder = Decode.field "amount-of-comments" Decode.int
-titleDecoder = Decode.field "title" Decode.string
-idDecoder = Decode.field "id" Decode.int
-versionsDecoder = Decode.maybe (Decode.field "versions" (Decode.list Decode.int))
-versionDecoder = Decode.maybe (Decode.field "version" Decode.int)
-created_atDecoder = Decode.field "created_at" (Decode.maybe Extra.iso8601)
-creator_Decoder = Decode.field "creator" creatorDecoder
-hiddenDecoder = Decode.field "hidden" Decode.bool
-unlistedDecoder = Decode.field "unlisted" Decode.bool
-
-previouslyDocDecoder =
- Decode.succeed PreviousArticle
- |> decodeApply idDecoder
- |> decodeApply titleDecoder
-
-previouslyDecoder = Decode.field "previously" (Decode.list previouslyDocDecoder)
-
--- |> == clojure's ->>
-articleDecoder : Decoder Article
-articleDecoder =
- Decode.succeed Article
- |> decodeApply creator_Decoder
- |> decodeApply tagsDecoder
- |> decodeApply contentDecoder
- |> decodeApply commentsDecoder
- |> decodeApply titleDecoder
- |> decodeApply idDecoder
- |> decodeApply versionsDecoder
- |> decodeApply versionDecoder
- |> decodeApply created_atDecoder
- |> decodeApply hiddenDecoder
- |> decodeApply unlistedDecoder
- |> decodeApply previouslyDecoder
- |> decodeApply (Decode.succeed Murja)
-
-type alias Title =
- { title : String
- , id : Int
- , year : Int
- , month: Int
- , tags: List String
- }
-
-
-sidebarTitleDecoder =
- Decode.succeed Title
- |> decodeApply (Decode.field "Title" Decode.string)
- |> decodeApply (Decode.field "Id" Decode.int)
- |> decodeApply (Decode.field "Year" Decode.int)
- |> decodeApply (Decode.field "Month" Decode.int)
- |> decodeApply (Decode.field "Tags" (Decode.list Decode.string))
diff --git a/elm-frontti/src/Article_view.elm b/elm-frontti/src/Article_view.elm
deleted file mode 100644
index 02f9865..0000000
--- a/elm-frontti/src/Article_view.elm
+++ /dev/null
@@ -1,59 +0,0 @@
-module Article_view exposing (..)
-
-import DateFormat as Df
-import Html exposing (..)
-import Html.Attributes exposing (..)
-import Html.Events exposing (onInput, onClick)
-import User
-import Message exposing (..)
-import Settings
-import Time
-import Article
-
-
-formatDateTime formatString zone posixTime =
- Df.format formatString zone posixTime
-
-articleView settings loginstate zone the_actual_post =
- let versions = Maybe.withDefault [] the_actual_post.versions
- url = case the_actual_post.source of
- Article.Rss link -> link
- Article.Murja -> ("/blog/post/" ++ String.fromInt the_actual_post.id)
- in
- div [class "post"] [ a [ href url ] [ text the_actual_post.title ]
- , div [class "meta"] (List.append [ User.user_avatar the_actual_post.creator
- , p [] [text ("By " ++ the_actual_post.creator.nickname)]
- , case the_actual_post.created_at of
- Just writing_time ->
- p [] [text ("Written at " ++ (formatDateTime settings.time_format zone writing_time))]
- Nothing ->
- p [] [text ("No idea when it's written")]]
- (let post_id = the_actual_post.id in
- (List.map (\version -> a [ href ("/blog/post/" ++ String.fromInt post_id ++ "/version/" ++ String.fromInt version) ] [ text ((String.fromInt version) ++ ", ")]) versions)))
-
- , (let post_id = the_actual_post.id in
- case loginstate of
- LoggedIn _ -> case the_actual_post.source of
- Article.Murja -> a [ href ("/blog/post/edit/" ++ String.fromInt post_id)
- , attribute "data-testid" "edit-post-btn"
- , onClick (OpenPostEditor post_id)] [text "Edit this post"]
- Article.Rss _ -> div [] []
- _ -> div [] [])
-
- , article [ class "content"
- , dangerouslySetInnerHTML the_actual_post.content] []
- , div [ class "previously" ]
- ( the_actual_post.previously
- |> List.map (\prev -> span [] [ a [ href ("/blog/post/" ++ (String.fromInt prev.id))
- , title prev.title]
- [ text settings.previously_label ]
- , text ", "]))
- , let tags = ( the_actual_post.tags
- |> List.filter ((/=) ""))
- in
- if not (List.isEmpty tags) then
- div [ class "tags" ] ( tags
- |> List.map ( \tag -> span [] [ a [ href ("/blog/tags/" ++ tag)
- , class "tag" ] [text tag]
- , text ", "]))
- else div [] []]
diff --git a/elm-frontti/src/Button.elm b/elm-frontti/src/Button.elm
deleted file mode 100644
index 9c64091..0000000
--- a/elm-frontti/src/Button.elm
+++ /dev/null
@@ -1,9 +0,0 @@
-module Button exposing (murja_button)
-
-import Html exposing (..)
-import Html.Attributes exposing (..)
-import Html.Events exposing (..)
-
-murja_button params contents =
- button (List.append params [ class "murja-button" ])
- contents
diff --git a/elm-frontti/src/Creator.elm b/elm-frontti/src/Creator.elm
deleted file mode 100644
index fee57f6..0000000
--- a/elm-frontti/src/Creator.elm
+++ /dev/null
@@ -1,26 +0,0 @@
-module Creator exposing (..)
-
-import Json.Encode as Json exposing (..)
-import Json.Decode as Decode exposing (Decoder, succeed)
-import Json.Decode.Pipeline exposing (required)
-
-type alias Creator =
- { username : String
- , nickname : String
- , img_location : String}
-
-usernameDecoder = Decode.field "username" Decode.string
-nicknameDecoder = Decode.field "nickname" Decode.string
-img_locationDecoder = Decode.field "img_location" Decode.string
-
-creatorDecoder = Decode.map3 Creator usernameDecoder nicknameDecoder img_locationDecoder
-
--- encoder
-
-encode : Creator -> Json.Value
-encode creator =
- object
- [ ( "username", string creator.username)
- , ( "nickname", string creator.nickname)
- , ( "img_location", string creator.img_location)
- ]
diff --git a/elm-frontti/src/Date_utils.elm b/elm-frontti/src/Date_utils.elm
deleted file mode 100644
index 1ae2823..0000000
--- a/elm-frontti/src/Date_utils.elm
+++ /dev/null
@@ -1,8 +0,0 @@
-module Date_utils exposing (int_to_month_string)
-import Array
-
--- import Dict exposing (Dict)
-
-months = Array.fromList ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
-
-int_to_month_string i = Array.get (i - 1) months
diff --git a/elm-frontti/src/FeedManager.elm b/elm-frontti/src/FeedManager.elm
deleted file mode 100644
index 17a2041..0000000
--- a/elm-frontti/src/FeedManager.elm
+++ /dev/null
@@ -1,37 +0,0 @@
-module FeedManager exposing (..)
-
-import Message exposing (..)
-import Html exposing (..)
-import Html.Attributes exposing (..)
-import Html.Events exposing (onInput, onClick)
-import Button exposing (murja_button)
-import Article_view exposing (formatDateTime)
-import Time
-
-feedmanager time_format zone feeds =
- table [ class "feed-manager-container" ]
- ( feeds
- |> List.map (\f ->
- let last_updated = ( f.items
- |> List.map (Time.posixToMillis << .pubdate)
- |> List.maximum) in
- ( last_updated
- , f))
- |> List.sortBy ((\last_updated ->
- case last_updated of
- Just d -> d
- Nothing -> 9999) << Tuple.first)
- |> List.reverse
- |> List.map (\tuple ->
- let (last_updated, f) = tuple in
- tr [ ]
- [ td [] [ text <| f.name ++ " ("
- , a [ href f.url] [ text f.url ]
- , text ")"]
- , td [] [ text <| "Last updated at " ++ ( last_updated
- |> Maybe.map Time.millisToPosix
- |> (Maybe.map <| formatDateTime time_format zone)
- |> Maybe.withDefault "never")]
- , td []
- [ murja_button [ onClick <| DeleteFeed f.id ]
- [ text "Delete feed" ]]]))
diff --git a/elm-frontti/src/FeedView.elm b/elm-frontti/src/FeedView.elm
deleted file mode 100644
index aa3b2a3..0000000
--- a/elm-frontti/src/FeedView.elm
+++ /dev/null
@@ -1,100 +0,0 @@
-module FeedView exposing (..)
-
-import DateFormat as Df
-import Feeds exposing (..)
-import Dict
-import Time
-import Message exposing (..)
-import Html exposing (..)
-import Html.Attributes exposing (..)
-import Html.Events exposing (onInput, onClick, on)
-import Button exposing (murja_button)
-import UUID
-import Article_view exposing (formatDateTime)
-import FeedManager exposing (feedmanager)
-import Tab exposing (TabEntry, tabs)
-import Random
-
-feed_item loginstate settings zone item =
- let time_format = settings.time_format
- article = itemToArticle item in
- li [ class "feed-item" ]
- ( case item.feed_id of
- Just feed_id ->
- [ div [] [ murja_button [ onClick <| SelectExcerpt item.id ] [ text "Write a post about this"]]
- , node "dialog" [ id <| "excerpt-dialog-" ++ (UUID.toString item.id) ]
- (let textarea_id = "excerpt-dialog-" ++ (UUID.toString item.id) ++ "-textarea" in
- [ div [ class "dialog" ]
- [ header [ class "previouslyHeader" ] [ button [ onClick ClosePreviousPostsModel ] [ text "X"]]
- , h3 [] [ text "Select an excerpt"]
- , textarea [ rows 30
- , cols 60
- , id textarea_id ] [ text item.description ]
- , murja_button [ onClick <| CreateExcerptPost textarea_id item.id ] [ text "Create a post" ]]])
- , Article_view.articleView settings loginstate zone article ]
- Nothing ->
- [ text "Unknown feed" ])
-
-correctlySortedFeedItemList loginstate settings zone items =
- ( items
- |> List.sortBy (Time.posixToMillis << .pubdate)
- |> List.reverse
- |> List.map (feed_item loginstate settings zone))
-
--- fs = feeds, elm sucks balls at shadowing
-perFeedView loginstate settings zone fs new_feed_state =
- ul [ class "feed-list" ]
- (List.map (\feed ->
- li [ class "feed" ]
- [ header [] [ text <| feed.name ++ " (" ++ (String.fromInt (List.length feed.items)) ++ ")" ]
- , a [ href feed.url ] [ text feed.url ]
- , ul [ class "feed-items" ]
- (correctlySortedFeedItemList loginstate settings zone <| List.map (\i -> { i | feed_id = Just feed.id}) feed.items)]) fs)
-
-singleFeedView loginstate settings zone fs =
- let final_feed = List.concatMap (\feed -> List.map (\item -> { item | feed_id = Just feed.id}) feed.items) fs in
- div []
- [ header [] [ text <| (String.fromInt (List.length final_feed)) ++ " unread articles" ]
- , ul [ class "feed-items" ]
- (correctlySortedFeedItemList loginstate settings zone final_feed)]
-
-
-readerState_str state =
- case state of
- PerFeed -> "PerFeed"
- SingleFeed -> "SingleFeed"
- FeedManager -> "FeedManager"
-
-feeds feedReaderState loginstate show_archived settings zone fs new_feed metadata =
- let new_feed_state = Maybe.withDefault (NewFeed "" "") new_feed
- in
- div [ id "feeds" ]
- [ label [] [ input [ type_ "checkbox"
- , checked show_archived
- , onClick <| ShowArchivedFeedItems (not show_archived)] []
- , text "Show read items"]
- , tabs "rss-feed-tab" (readerState_str feedReaderState) Nothing
- (Dict.fromList [ ("PerFeed", TabEntry "Group by feed" "" (perFeedView loginstate settings zone fs new_feed_state) Nothing ["*"])
- , ("SingleFeed", TabEntry "Show all in a feed" "" (singleFeedView loginstate settings zone fs) Nothing ["*"])
- , ("FeedManager", TabEntry "Manage feeds" "" (feedmanager settings.time_format zone fs) Nothing ["*"])])
-
- , h3 [] [ text "Add new feed?"]
- , label [ for "name" ] [ text "Feed name" ]
- , input [ id "name"
- , onInput SetFeedName
- , value new_feed_state.name
- , type_ "text"] []
-
- , label [ for "url" ] [ text "Url to feed" ]
- , input [ id "url"
- , onInput SetFeedUrl
- , value new_feed_state.url
- , type_ "text"] []
- , murja_button [ onClick (AddFeed new_feed_state)] [ text "Add a feed"]
- , case metadata of
- Just meta ->
- details [] [ summary [] [ text "Latest feed updates at: "]
- , ul []
- ( meta.last_update_timestamps
- |> List.map (\timestamp -> li [] [ text timestamp]))]
- Nothing -> text "Metadata didn't load"]
diff --git a/elm-frontti/src/Feeds.elm b/elm-frontti/src/Feeds.elm
deleted file mode 100644
index e22506d..0000000
--- a/elm-frontti/src/Feeds.elm
+++ /dev/null
@@ -1,102 +0,0 @@
-module Feeds exposing (..)
-
-import Json.Encode as Json exposing (..)
-import Json.Encode.Extra exposing (..)
-import Json.Decode as Decode exposing (Decoder, succeed)
-import Json.Decode.Pipeline exposing (required)
-import Json.Decode.Extra as Extra
-import Time
-
-import UUID exposing (UUID)
-
-import Article exposing (decodeApply)
-import Creator exposing (Creator)
-
-
-type alias Item =
- { id: UUID
- , fetched: Time.Posix
- , title: String
- , description: String
- , link: String
- , author: String
- , pubdate: Time.Posix
- , is_read: Bool
- -- parent id that's required for ui to function correctly
- , feed_id: Maybe UUID}
-
-type alias Feed =
- { id: UUID
- , name: String
- , url: String
- , creator: Creator
- , items: List Item}
-
-type alias NewFeed =
- { name: String
- , url: String}
-
-type alias FeedMetadata =
- { last_update_timestamps: List String}
-
--- Article conversion
-itemToArticle item =
- let creator = Creator "" item.author "" in
- Article.Article creator [] item.description Nothing item.title -1 Nothing (Just 1) (Just item.pubdate) False False [] (Article.Rss item.link)
-
--- metadata decoder
-
-metadataDecoder = Decode.succeed FeedMetadata
- |> decodeApply (Decode.field "last-update-timestamps" (Decode.list Decode.string))
-
--- feedDecoder
-
-creatorDecoder = Decode.field "creator" Creator.creatorDecoder
-urlDecoder = Decode.field "url" Decode.string
-nameDecoder = (Decode.field "name" Decode.string)
-idDecoder = (Decode.field "id" UUID.jsonDecoder)
-
--- itemDecoder
-fetchedDecoder = Decode.field "fetched" Extra.iso8601
-titleDecoder = Decode.field "title" Decode.string
-descriptionDecoder = Decode.field "description" Decode.string
-linkDecoder = Decode.field "link" Decode.string
-authorDecoder = Decode.field "author" Decode.string
-pubdateDecoder = Decode.field "pubdate" Extra.iso8601
-is_readDecoder = Decode.field "is_read" Decode.bool
-
-itemDecoder =
- Decode.succeed Item
- |> decodeApply idDecoder
- |> decodeApply fetchedDecoder
- |> decodeApply titleDecoder
- |> decodeApply descriptionDecoder
- |> decodeApply linkDecoder
- |> decodeApply authorDecoder
- |> decodeApply pubdateDecoder
- |> decodeApply is_readDecoder
- |> decodeApply (Decode.succeed Nothing)
-
-itemsDecoder =
- Decode.field "items" (Decode.list itemDecoder)
-
-feedDecoder: Decoder Feed
-feedDecoder =
- Decode.succeed Feed
- |> decodeApply idDecoder
- |> decodeApply nameDecoder
- |> decodeApply urlDecoder
- |> decodeApply creatorDecoder
- |> decodeApply itemsDecoder
-
-newFeedDecoder: Decoder NewFeed
-newFeedDecoder =
- Decode.succeed NewFeed
- |> decodeApply nameDecoder
- |> decodeApply urlDecoder
-
-newFeedEncoder o =
- Json.object
- [ ("name", Json.string o.name)
- , ("url", Json.string o.url) ]
-
diff --git a/elm-frontti/src/Image.elm b/elm-frontti/src/Image.elm
deleted file mode 100644
index d11abca..0000000
--- a/elm-frontti/src/Image.elm
+++ /dev/null
@@ -1,49 +0,0 @@
-module Image exposing (..)
-
-import Json.Encode as Json exposing (..)
-import Json.Encode.Extra exposing (..)
-import Json.Decode as Decode exposing (Decoder, succeed)
-import Json.Decode.Pipeline exposing (required)
-import Json.Decode.Extra as Extra
-
-import UUID exposing (UUID)
-
-import Article exposing (decodeApply)
-
-type alias Image =
- { id: UUID
- , name: String }
-
-type alias PostImageResponse =
- { id: UUID }
-
-type alias ReferencingPost =
- { post_id : Int
- , post_title : String
- , media_id : String
- , media_name : String}
-
-encode img =
- object
- [ ("id", UUID.toValue img.id)
- , ("name", string img.name) ]
-
-idDecoder = Decode.field "id" UUID.jsonDecoder
-nameDecoder = Decode.field "name" Decode.string
-
-imageDecoder =
- Decode.succeed Image
- |> decodeApply idDecoder
- |> decodeApply nameDecoder
-imageResponseDecoder = Decode.succeed PostImageResponse
- |> decodeApply idDecoder
-
-list_of_uuids_encode ids = Json.object
- [ ( "ids", Json.list UUID.toValue ids)]
-
-referencingPostDecoder =
- Decode.succeed ReferencingPost
- |> decodeApply (Decode.field "post_id" Decode.int)
- |> decodeApply (Decode.field "post_title" Decode.string)
- |> decodeApply (Decode.field "media_id" Decode.string)
- |> decodeApply (Decode.field "media_name" Decode.string)
diff --git a/elm-frontti/src/ImageSelector.elm b/elm-frontti/src/ImageSelector.elm
deleted file mode 100644
index 1a41159..0000000
--- a/elm-frontti/src/ImageSelector.elm
+++ /dev/null
@@ -1,18 +0,0 @@
-module ImageSelector exposing (..)
-
-import Html exposing (..)
-import Html.Attributes exposing (..)
-import Html.Events exposing (onClick)
-
-import UUID
-
-import Image exposing (Image)
-import Message exposing (..)
-
-image the_actual_img = img [ src ("/api/pictures/" ++ (UUID.toString the_actual_img.id))
- , onClick (SelectedImage the_actual_img.id)] []
-
-imageSelector : List Image -> Html Msg
-imageSelector img_list =
- div [ id "selector-div" ]
- (List.map image img_list)
diff --git a/elm-frontti/src/Initial.elm b/elm-frontti/src/Initial.elm
deleted file mode 100644
index 2494c13..0000000
--- a/elm-frontti/src/Initial.elm
+++ /dev/null
@@ -1,36 +0,0 @@
-module Initial exposing (..)
-
-import Article exposing (decodeApply)
-import Json.Decode as Decode exposing (Decoder, succeed)
-import Json.Encode as Json
-
-type alias Initial =
- { initial : Bool } -- http api can't return bare booleans (as "false"s are interpreted as 404 in the middlewares
-
-type alias InitialFormData =
- { username : String
- , nickname : String
- , password : String
- , domain : String
- , blog_title : String
- , rss_title : String
- , rss_link : String
- , rss_description : Maybe String
- , rss_lang : String
- , rss_email : String}
-
-initialDecoder = succeed Initial
- |> decodeApply (Decode.field "initial" Decode.bool)
-
-initialEncoder i =
- Json.object
- [ ("username", Json.string i.username)
- , ("nickname", Json.string i.nickname)
- , ("password", Json.string i.password)
- , ("domain", Json.string i.domain)
- , ("blog_title", Json.string i.blog_title)
- , ("rss_title", Json.string i.rss_title)
- , ("rss_link", Json.string i.rss_link)
- , ("rss_description", Json.string (Maybe.withDefault i.blog_title i.rss_description))
- , ("rss_lang", Json.string i.rss_lang)
- , ("rss_email", Json.string i.rss_email)]
diff --git a/elm-frontti/src/InitialForm.elm b/elm-frontti/src/InitialForm.elm
deleted file mode 100644
index d7c524f..0000000
--- a/elm-frontti/src/InitialForm.elm
+++ /dev/null
@@ -1,67 +0,0 @@
-module InitialForm exposing (..)
-
-import Html exposing (..)
-import Html.Attributes exposing (..)
-import Html.Events exposing (onInput, onClick)
-
-import Message exposing (..)
-
-initialForm data =
- div []
- [ text "Welcome to your new Murja-blog. There doesn't seem to be any users in the db yet. Please provide the initial user- and rss-settings now. These can all be changed later in the ui."
- , div [ class "initial-form" ]
- [ h1 [] [ text "User settings"]
- , span [] []
- , h2 [] [ text "The initial admin user: " ]
- , span [] []
- , label [] [ text "Username (used when logging in): "
- , input [ type_ "text"
- , value data.username
- , onInput SetInitialUsername ] []]
- , label [] [ text "Nickname (shown in the ui): "
- , input [ type_ "text"
- , value data.nickname
- , onInput SetInitialNickname ] []]
- , label [] [ text "Password: "
- , input [ type_ "password"
- , value data.password
- , onInput SetInitialPassword ] []]
- , span [] []
- , h1 [] [ text "Site settings"]
- , span [] []
- , label [] [ text "Domain (the dns name this site is reached by. This is used in session cookies. This should be left empty on dev.): "
- , input [ type_ "text"
- , value data.domain
- , onInput SetInitialDomain ] []]
- , label [] [ text "Blog's title: "
- , input [ type_ "text"
- , value data.blog_title
- , onInput SetInitialBlog_Title ] []]
-
- -- the stupid grid layout requires a few empty spans to lay h1 out into its own row
- , h1 [] [ text "RSS-feed settings"]
- , span [] []
-
- , label [] [ text "Rss-feed's title: "
- , input [ type_ "text"
- , value data.rss_title
- , onInput SetInitialRss_Title ] []]
- , label [] [ text "Rss-feed's link: "
- , input [ type_ "text"
- , value data.rss_link
- , onInput SetInitialRss_Link ] []]
- , label [] [ text "Rss-feed's description: "
- , input [ type_ "text"
- , value <| Maybe.withDefault data.blog_title data.rss_description
- , onInput SetInitialRss_Description ] []]
- , label [] [ text "Rss-feed's language code: "
- , input [ type_ "text"
- , value data.rss_lang
- , onInput SetInitialRss_Lang ] []]
- , label [] [ text "Rss-feed's listed email contact address: "
- , input [ type_ "text"
- , value data.rss_email
- , onInput SetInitialRss_Email ] []]]
- , button
- [ onClick <| SaveInitialData data ]
- [ text "Start using murja"]]
diff --git a/elm-frontti/src/Logs.elm b/elm-frontti/src/Logs.elm
deleted file mode 100644
index 42a481b..0000000
--- a/elm-frontti/src/Logs.elm
+++ /dev/null
@@ -1,64 +0,0 @@
-module Logs exposing (..)
-
-import Article exposing (decodeApply)
-import Json.Decode as Decode exposing (Decoder, succeed)
-import Json.Encode as Json exposing (..)
-import Regex exposing (Regex)
-
-type alias Log =
- { row : String -- let's keep them as just dumb lines for now and add smarter analytics later...
- }
-
-type alias Group =
- { name: String
- , alarmy: Bool
- , sound_alarm: Bool
- , members: List Log}
-
-type alias ParsedGroup =
- { name: String
- , regex: Regex
- , alarmy: Bool
- , sound_alarm: Bool
- , members: List Log}
-
-regex_to_parsedgroup str =
- case Regex.fromString str of
- Just re -> Just <| ParsedGroup str re False False []
- Nothing -> Nothing
-
-str_to_group str =
- Group str False False []
-
-parsedGroup_to_group pg =
- Group pg.name pg.alarmy pg.members
-
-rowDecoder = Decode.field "row" Decode.string
-decoder = Decode.succeed Log |> decodeApply rowDecoder
-
-groupEncoder group =
- object
- [ ( "name", string group.name)
- , ( "alarmy", bool group.alarmy)]
-
-groupsEncoder groups =
- list groupEncoder groups
-
-nameDecoder = Decode.field "name" Decode.string
-alarmyDecoder = Decode.field "alarmy" Decode.bool
-sound_alarm_decoder = Decode.field "sound-alarm" Decode.bool
-
-groupDecoder = Decode.succeed Group
- |> decodeApply nameDecoder
- |> decodeApply alarmyDecoder
- |> decodeApply sound_alarm_decoder
- |> decodeApply (Decode.succeed [])
-
-groupsDecoder = Decode.list groupDecoder
-
-type alias TopbarAlarm =
- { alarm: Bool }
-
-alarmDecoder = Decode.field "alarm" Decode.bool
-topbarAlarmDecoder = Decode.succeed TopbarAlarm
- |> decodeApply alarmDecoder
diff --git a/elm-frontti/src/Logviewer.elm b/elm-frontti/src/Logviewer.elm
deleted file mode 100644
index 66b2a12..0000000
--- a/elm-frontti/src/Logviewer.elm
+++ /dev/null
@@ -1,76 +0,0 @@
-module Logviewer exposing (..)
-
-import Html exposing (..)
-import Html.Attributes exposing (..)
-import Html.Events exposing (..)
-import Regex
-import List.Extra
-import Logs exposing (..)
-
-import Message exposing (..)
-
-dropMaybe: (List (Maybe a)) -> List a
-dropMaybe lst =
- List.foldr (\val -> (\acc ->
- case val of
- Just a -> a :: acc
- Nothing -> acc)) [] lst
-
-log_to_list log
- = li [] [ text log.row ]
-
-listify group
- = let is_ungrouped = group.name == "Ungrouped"
- in
- details []
- [ summary [ class "loggroup-summary" ] [
- span [ class "loggroup-summary-container" ]
- [ text <| group.name ++ " (" ++ (String.fromInt (List.length group.members)) ++ ")" ++ (if group.sound_alarm then " ALERT! " else "")
- , if not is_ungrouped then
- button [ onClick <| DeleteLogGroup group.name ] [ text "Delete log group" ]
- else div [] []
- , if not is_ungrouped then
- label [] [ input [ type_ "checkbox"
- , checked group.alarmy
- , onClick (SetLogAlarmy group (not group.alarmy))] []
- , text "Alarm"]
- else
- div [] []]]
- , ul []
- (List.map log_to_list group.members)]
-
-parseRegex: Group -> Maybe ParsedGroup
-parseRegex r =
- case Regex.fromString r.name of
- Just rr -> Just (ParsedGroup r.name rr r.alarmy r.sound_alarm r.members)
- Nothing -> Nothing
-
-tab: List Log -> List Group -> String -> Html Msg
-tab logs groups edited_group =
- let regexes = groups
- |> List.map parseRegex
- |> dropMaybe
- grouped = regexes
- |> List.map (\regex ->
- let members = List.filter (\l -> Regex.contains regex.regex l.row) logs
- in
- { regex | members = members})
- |> List.map listify
- last_group = logs
- |> List.filter (\l -> regexes
- |> List.filter (\r -> Regex.contains r.regex l.row)
- |> (==) [])
- |> ParsedGroup "Ungrouped" Regex.never False False
- |> listify
- in
- div []
- [ h3 [] [ text "Add a new group" ]
- , label [] [ text "Grouping regexp "
- , input [ type_ "text"
- , value edited_group
- , onInput EditGroupRegexp] []]
- , button [ type_ "button"
- , onClick <| SaveLogGroup edited_group] [ text "Add group"]
- , h3 [] [ text "Logs: "]
- , div [] grouped
- , last_group]
diff --git a/elm-frontti/src/Main.elm b/elm-frontti/src/Main.elm
deleted file mode 100644
index a672887..0000000
--- a/elm-frontti/src/Main.elm
+++ /dev/null
@@ -1,1172 +0,0 @@
-port module Main exposing (..)
-
-import Browser
-import Html exposing (..)
-import Html.Attributes exposing (..)
-import Html.Events exposing (onInput, onClick)
-
-import Http
-import Regex
-
-import Article
-import Article_view exposing (articleView)
-import Ajax_cmds exposing (..)
-import Creator as C
-import Page as P
-import Settings
-import Message exposing (..)
-import User
-import PostsAdmin
-import PostEditor
-import SettingsEditor
-import Medialist exposing (medialist)
-import Image
-import Logviewer
-import Logs
-import ImageSelector exposing (imageSelector)
-import InitialForm
-
-import DateTime exposing (DateTime)
-import Json.Decode as Decode
-import Json.Encode
-import Time
-import Task
-import Dict.Extra exposing (groupBy)
-import Dict exposing (toList, keys, get)
-import String exposing (fromInt)
-import String.Extra exposing (toSentenceCase)
-import Stack exposing (push, top, pop)
-
-import Browser.Navigation as Nav
-
-import RouteParser
-import Url
-import Date_utils exposing (int_to_month_string)
-
-import UUID
-import File exposing (mime)
-
-import FeedView
-import Feeds exposing (NewFeed)
-import Tab exposing (..)
-import UserEditor
-
--- MAIN
-
-main : Program () Model Msg
-main =
- Browser.application
- { init = init
- , view = view
- , update = update
- , subscriptions = subscriptions
- , onUrlChange = UrlChanged
- , onUrlRequest = LinkClicked
- }
-
--- SUBSCRIPTIONS
-
-
-subscriptions : Model -> Sub Msg
-subscriptions _ = Sub.batch
- [ tags ReceivedTag
- , aceStateUpdate AceStateUpdate
- , excerptCreated ExcerptCreated]
-
-initialModel url key viewstate = Model viewstate Nothing False False [] Nothing LoggedOut key url Nothing Time.utc [] [] Nothing PerFeed Nothing False
-
-viewStatePerUrl : Url.Url -> (ViewState, List (Cmd Msg))
-viewStatePerUrl url =
- case RouteParser.url_to_route url of
- RouteParser.Page page_id -> (Loading, [ getSettings
- , getTitles
- , getSession
- , getPage page_id
- ])
- RouteParser.Post post_id -> (Loading, [ getSettings
- , getTitles
- , getSession
- , getPost post_id])
- RouteParser.Home -> (Loading, [ getSettings
- , getTitles
- , getSession
- , getPage 1
- ])
- RouteParser.PostEditor post_id -> (Loading, [ getSettings
- , getTitles
- , getSession
- , getPostEditorData post_id])
- RouteParser.PostAdmin -> (Loading, [ getSettings
- , getSession
- , getTitles
- , getEditablePosts ])
- RouteParser.MediaManager -> (Loading, [ getSettings
- , getSession
- , getTitles
- , getListOfImages True] )
- RouteParser.TaggedPosts tags_ -> (Loading, [ getSession
- , getSettings
- , getTitles
- , loadTaggedPosts tags_])
-
- RouteParser.PostVersion post_id version_id -> (Loading, [ getSession
- , getSettings
- , getTitles
- , loadPostVersion post_id version_id])
-
- RouteParser.NotFound -> (ShowError ("Couldn't parse url " ++ (Url.toString url)), [Cmd.none])
- RouteParser.SettingsEditor -> (Loading, [ getSession
- , getSettingsAdmin
- , getTitles])
- RouteParser.FeedReader -> (Loading, [ getSession
- , getSettings
- , getFeeds False
- , getFeedMeta ])
- RouteParser.Logs -> ( (Logs [] [] "")
- , [ getSettings
- , getSession
- , getAdminLogs
- , getTitles
- , getLogGroups])
- RouteParser.OwnUserSettings -> ( UserSettings "" "" Nothing
- , [ getSettings
- , getSession
- , getTitles])
- RouteParser.InitialSetup -> ( InitialSetup { username = ""
- , nickname = ""
- , password = ""
- , domain = ""
- , blog_title = ""
- , rss_title = ""
- , rss_link = ""
- , rss_description = Nothing
- , rss_lang = ""
- , rss_email = ""}
- , [ getSettings ])
-
-init _ url key =
- let (viewstate, cmds) = (viewStatePerUrl url)
- model = initialModel url key viewstate
- in
- ( model
- , Cmd.batch (List.append cmds [ Task.perform AdjustTimeZone Time.here]))
-
-
--- UPDATE
-
-
--- PORTS --
-port prompt : String -> Cmd msg
-port showPreviousPostsModal: (() -> Cmd msg)
-port closePreviousPostsModal: (() -> Cmd msg)
-port showPreviousPostPreviewModal: (() -> Cmd msg)
-port tags : (String -> msg) -> Sub msg
-port aceStateUpdate : (String -> msg) -> Sub msg
-port showModal: String -> Cmd msg
-port createExcerpt: (String, String) -> Cmd msg
-port excerptCreated: ((String, String) -> msg) -> Sub msg
-
-toggleHidden article =
- { article | hidden = not article.hidden}
-toggleUnlisted article =
- { article | unlisted = not article.unlisted}
-
-errToString: Http.Error -> String
-errToString err =
- case err of
- Http.BadUrl str -> "Bad url: " ++ str
- Http.Timeout -> "Timeout trying to contact the server. Are you online?"
- Http.NetworkError -> "Network error. Are you online?"
- Http.BadStatus status -> String.fromInt status
- Http.BadBody body -> "Received unparseable response: " ++ body
-
-update : Msg -> Model -> (Model, Cmd Msg)
-update msg model =
- case msg of
- SettingsReceived result ->
- case result of
- Ok new_settings ->
- ({model | settings = Just new_settings}, Cmd.none)
-
- Err http_error ->
- ( model
- , alert ("Error loading settings " ++ Debug.toString http_error))
- PostReceived result ->
- ( {model | view_state = case result of
- Ok post -> PostView post
- Err error -> ShowError ( errToString error)}
- , Cmd.none)
- PageReceived result ->
- ( {model | view_state = case result of
- Ok page -> PageView page
- Err error -> ShowError ( errToString error)}
- , Cmd.none)
- TitlesReceived result ->
- case result of
- Ok decoded_titles ->
- ({ model | titles = decoded_titles}
- , Cmd.none)
- Err error ->
- ( model
- , alert ("Error loading titles " ++ Debug.toString error))
- UrlChanged url ->
- let (view_state, cmds) = viewStatePerUrl url in
- ({model | url = url, view_state = view_state}, Cmd.batch cmds)
- LinkClicked urlRequest ->
- case urlRequest of
- Browser.Internal url ->
- (model, Nav.pushUrl model.key (Url.toString url))
- Browser.External href ->
- (model, Nav.load href)
- LoginFocus ->
- ({model | loginState = LoggingIn "" ""}, Cmd.none)
- ChangeUsername username ->
- case model.loginState of
- LoggingIn old_username password ->
- ({model | loginState = LoggingIn username password}, Cmd.none)
- _ -> (model, Cmd.none)
- ChangePassword password ->
- case model.loginState of
- LoggingIn username old_password ->
- ({model | loginState = LoggingIn username password}, Cmd.none)
- _ -> (model, Cmd.none)
- DoLogIn -> case model.loginState of
- LoggingIn username password ->
- (model, postLogin username password)
- _ -> (model, Cmd.none)
- LoginSuccess result ->
- case result of
- Ok user ->
- ({model | loginState = LoggedIn user}, Cmd.none)
- Err error ->
- ({model | loginState = LoginFailed}, Cmd.none)
- GotSession result ->
- case result of
- Ok user ->
- case model.view_state of
- PostEditor ->
- ({ model | loginState = LoggedIn user
- , postEditorSettings = Nothing}
- , getTopbarAlarms user.permissions)
- UserSettings oldpwd newpwd _ ->
- ( { model
- | loginState = LoggedIn user
- , view_state = UserSettings oldpwd newpwd (Just user)}
- , getTopbarAlarms user.permissions)
- _ ->
- ({model | loginState = LoggedIn user}
- , getTopbarAlarms user.permissions)
- Err error ->
- case error of
- Http.BadStatus status ->
- if status == 401 then
- -- no valid session
- (model, Cmd.none)
- else
- ( model
- , alert ("Error (" ++ String.fromInt status ++ ") when loading session"))
- Http.BadBody err ->
- ( model
- , alert ("Error when loading session: " ++ err))
- _ -> ( model
- , alert ("Error when loading session"))
- EditableTitlesReceived result ->
- ( {model | view_state = case result of
- Ok titles -> PostEditorList titles
- Err error -> ShowError ( errToString error)}
- , Cmd.none)
- OpenPostEditor post_id ->
- (model, getPostEditorData post_id)
- EditorPostReceived result ->
- case result of
- Ok post ->
- ({ model | view_state = PostEditor
- , postEditorSettings = Just (PostEditorSettings post "" False Nothing)}
- , Cmd.none)
- Err error ->
- ( model
- , alert ("Error loading post editor " ++ Debug.toString error))
- PromptTag prompt_message ->
- (model, prompt prompt_message)
- Alert alert_msg ->
- (model, alert alert_msg)
- RunAce content ->
- (model, reallySetupAce content)
- SelectTag tag ->
- case model.postEditorSettings of
- Just settings ->
- ({ model | postEditorSettings = Just
- { settings | selected_tag = tag}}
- , Cmd.none)
- _ -> (model, Cmd.none)
- ReceivedTag tag ->
- case model.postEditorSettings of
- Just settings ->
- let old_article = settings.article
- article = { old_article | tags = tag :: settings.article.tags} in
- ({ model | postEditorSettings = Just
- { settings | article = article}}
- , Cmd.none)
- Nothing -> (model, alert "ReceivedTag called even though postEditorSettings is nil")
- DropTag tag ->
- case model.postEditorSettings of
- Just settings ->
- let old_article = settings.article
- article = { old_article | tags = List.filter ((/=) settings.selected_tag) old_article.tags} in
- ({ model | postEditorSettings = Just
- { settings | article = article}}
- , Cmd.none)
- Nothing -> (model, alert "DropTag called even though postEditorSettings is nil")
- HttpIgnoreResponse result ->
- (model, Cmd.none)
- SavePost article ->
- doGoHome_
- { model | postEditorSettings = Nothing}
- [ putArticle article ]
-
-
- GoHome -> doGoHome model
- HttpGoHome _ -> doGoHome model
-
- AceStateUpdate content ->
- case model.postEditorSettings of
- Just settings ->
- let article = settings.article in
- ({ model | postEditorSettings = Just
- { settings | article =
- { article | content = content}}}
- , Cmd.none)
- Nothing -> (model, alert "AceStateUpdate called even though postEditorSettings is nil")
-
- ChangeTitle new_title ->
- case model.postEditorSettings of
- Just settings ->
- let article = settings.article in
- ({ model | postEditorSettings = Just
- { settings | article =
- { article | title = new_title}}}
- , Cmd.none)
- Nothing -> (model, alert "ChangeTitle called even though postEditorSettings is nil")
- HttpManagerGetListOfImages _ -> (model, getListOfImages True)
- GetListOfImages -> ( { model | showImageModal = True }
- , getListOfImages False)
- GotListOfImages managerCalled result ->
- case result of
-
- Ok images ->
- case managerCalled of
- True ->
- ({ model
- | loadedImages = images
- , view_state = MediaList
- , medialist_state = Just (MediaListState [] Dict.empty)}
- , Cmd.batch (List.map (\image -> getReferencingPosts (UUID.toString image.id)) images))
- False ->
- ({model | showImageModal = True, loadedImages = images}, Cmd.none)
- Err error ->
- ( { model | view_state = ShowError (errToString error) }
- , Cmd.none)
- SelectedImage img_id ->
- ( {model | showImageModal = False, loadedImages = [] }
- , addImgToAce (UUID.toString img_id))
- EditorDragEnter ->
- ( {model | draggingImages = True}
- , Cmd.none)
- EditorDragLeave ->
- ( {model | draggingImages = False}
- , Cmd.none)
- GotFiles sendPicture file files ->
- if String.startsWith "image" (mime file) then
- ( { model | draggingImages = False }
- , sendPicture file)
- else
- ( { model | draggingImages = False }
- , alert ("Got " ++ (mime file) ++ ", expected an image"))
- GotInputFiles files ->
- if List.all (\file -> String.startsWith "image" (mime file)) files then
- ( model
- , Cmd.batch (List.map (\file -> postPicture UploadedImage PostEditor.editor_image_api file) files))
- else
- ( model
- , alert ("Expected images, got " ++ (String.join ", " (List.map mime files))))
- UploadedImage imgResponse ->
- case imgResponse of
- Ok actualResponse ->
- ( model
- , addImgToAce (UUID.toString actualResponse.id ))
- Err err ->
- (model, alert ("Error uploading image " ++ Debug.toString err))
- MarkImageForRemoval img_id ->
- case model.medialist_state of
- Just state ->
- if List.member img_id state.selected_ids_for_removal then
- ({ model | medialist_state = Just {state | selected_ids_for_removal =
- List.filter ((/=) img_id) state.selected_ids_for_removal}}
- , Cmd.none)
- else
- ({ model | medialist_state = Just {state | selected_ids_for_removal = img_id :: state.selected_ids_for_removal}}
- , Cmd.none)
-
- Nothing ->
- ( model
- , alert "Medialist state is uninitialized")
- MarkAllImages ids ->
- case model.medialist_state of
- Just state ->
- ({ model | medialist_state = Just {state | selected_ids_for_removal = ids}}
- , Cmd.none)
- Nothing -> ( model
- , alert "Medialist state is uninitialized")
- RemoveSelectedImages ->
- case model.medialist_state of
- Just state ->
- (model, deletePictures state.selected_ids_for_removal)
- Nothing -> (model, Cmd.none)
- GotReferencingPosts response ->
- case response of
- Ok posts ->
- case model.medialist_state of
- Just state -> ({ model | medialist_state = Just {state | referencing_posts =
- Dict.union state.referencing_posts (groupBy .media_id posts)}}
- , Cmd.none)
- Nothing -> ( model
- , Cmd.none)
- Err err ->
- ( model
- , alert "Error while downloading info about referencing posts, check your devtools' network log")
- PushUrl url ->
- ( model, Nav.pushUrl model.key url )
- AdjustTimeZone zone ->
- ( {model | zone = zone}
- , Cmd.none)
- GotTaggedPosts result ->
- case result of
- Ok posts ->
- ({ model | view_state = TaggedPostsView posts}
- , Cmd.none)
- Err err ->
- ( model , alert ( "Error loading tagged posts " ++ (Debug.toString err)))
- ToggleArticlePreview ->
- ({ model | postEditorSettings = Maybe.map (\settings ->
- {settings | show_preview = not settings.show_preview}) model.postEditorSettings}
- , Cmd.none)
- GotOldPost result ->
- case result of
- Ok post ->
- ({ model | view_state = PostView post}
- , Cmd.none)
- Err err ->
- (model , alert ("Error loading post version " ++ Debug.toString err))
- GenNewPost ->
- ( model
- , generateNewPost)
- NewPostGenerated new_post_id ->
- case new_post_id of
- Ok id ->
- ( model
- , Cmd.batch
- [ ( Nav.pushUrl model.key ("/blog/post/edit/" ++ String.fromInt id))
- , getPostEditorData id])
- Err error ->
- ( model
- , alert ("ERROR: " ++ (Debug.toString error)))
- ToggleArticleHidden ->
- ({ model | postEditorSettings = Maybe.map (\settings ->
- {settings | article = toggleHidden settings.article})
- model.postEditorSettings}
- , Cmd.none)
- ToggleArticleUnlisted ->
- ({ model | postEditorSettings = Maybe.map (\settings ->
- {settings | article = toggleUnlisted settings.article})
- model.postEditorSettings}
- , Cmd.none)
- AdminSettingsReceived result ->
- case result of
- Ok new_settings ->
- ({model
- | settings = Just new_settings
- , view_state = SettingsEditor}, Cmd.none)
-
- Err http_error ->
- ( model
- , alert ("Error loading settings " ++ Debug.toString http_error))
- SetTimeFormat tf ->
- ({ model | settings = Maybe.map (\settings ->
- { settings | time_format = tf})
- model.settings}
- , Cmd.none)
- SetBlogTitle title ->
- ({ model | settings = Maybe.map (\settings ->
- { settings | blog_title = title})
- model.settings}
- , Cmd.none)
- SetPageSize pg_size ->
- case String.toInt pg_size of
- Just page_size ->
- ({ model | settings = Maybe.map (\settings ->
- { settings | recent_post_count = page_size})
- model.settings}
- , Cmd.none)
- Nothing ->
- ( model
- , alert "Page size should be a number")
- SaveSettings ->
- case model.settings of
- Just settings ->
- ( model
- , saveSettings settings)
- Nothing ->
- ( model
- , Cmd.none)
- SettingsSaved result ->
- case result of
- Ok _ ->
- ( model
- , Cmd.none)
-
- Err http_error ->
- ( model
- , alert ("Error saving settings " ++ Debug.toString http_error))
- ShowPreviousPostsModal ->
- ( model
- , showPreviousPostsModal ())
- ClosePreviousPostsModel ->
- ( model
- , closePreviousPostsModal ())
- PreviouslySearchInput search_term ->
- ( model
- , searchPreviouslyPosts search_term)
- PreviouslySearchResult result ->
- case result of
- Ok previously_posts ->
- let article_previouslies = case model.postEditorSettings of
- Just settings -> settings.article.previously
- Nothing -> []
- in
- ({ model |
- searchedPosts = List.filter (\p -> not (List.member p article_previouslies)) previously_posts}
- , Cmd.none)
- Err error ->
- ( model
- , alert (errToString error))
- SelectPreviouslyPost selectedPost ->
- case model.postEditorSettings of
- Just editorSettings ->
- let new_posts = List.filter ((/=) selectedPost) model.searchedPosts
- article = editorSettings.article
- previously = article.previously
- in
- ({ model
- | searchedPosts = new_posts
- , postEditorSettings = Just { editorSettings
- | article = { article
- | previously = selectedPost :: previously}}}
- , Cmd.none)
- Nothing ->
- ( model
- , Cmd.none)
- DropPreviously previous_post ->
- case model.postEditorSettings of
- Just editorSettings ->
- let article = editorSettings.article
- previously = article.previously
- in
- ({ model
- | postEditorSettings = Just
- { editorSettings
- | article =
- { article
- | previously = List.filter ((/=) previous_post) previously}}}
- , Cmd.none)
- Nothing ->
- ( model
- , Cmd.none)
- SetPreviouslyLabel label ->
- ({ model | settings = Maybe.map (\settings ->
- { settings | previously_label = label})
- model.settings}
- , Cmd.none)
- LoadPreviouslyPreview prev_article ->
- ( model
- , loadPreviousArticle prev_article.id )
- PreviousPostReceived result ->
- case result of
- Ok article ->
- let postEditorSettings = model.postEditorSettings
- in
- ({ model
- | postEditorSettings = Maybe.map (\settings ->
- { settings
- | previewing_previously = Just article}) postEditorSettings}
- , showPreviousPostPreviewModal ())
- Err err ->
- ( model
- , alert ("Failed to load a previosly-post with error: " ++ (errToString err)))
- ClosePreviousPostPreviewModal ->
- ( model
- , closePreviousPostsModal ())
- FeedsReceived result ->
- case result of
- Ok fs ->
- let feeds = ( fs
- |> List.sortBy (\f -> ( f.items
- |> List.map (Time.posixToMillis << .pubdate)
- |> List.minimum
- |> Maybe.withDefault 999))
- |> List.reverse)
- in
- case model.view_state of
- Feeds _ archived ->
- ( { model | view_state = Feeds feeds archived}
- , Cmd.none)
- _ ->
- ( { model | view_state = Feeds feeds False}
- , Cmd.none)
- Err error ->
- ( { model | view_state = ShowError (errToString error) }
- , Cmd.none)
- SetFeedName name ->
- let new_feed = (Maybe.withDefault (NewFeed "" "") model.new_feed)
- in
- ({ model
- | new_feed = Just { new_feed
- | name = name}}
- , Cmd.none)
- SetFeedUrl url ->
- let new_feed = (Maybe.withDefault (NewFeed "" "") model.new_feed)
- in
- ({ model
- | new_feed = Just { new_feed
- | url = url}}
- , Cmd.none)
- AddFeed new_feed ->
- ({ model
- | new_feed = Nothing}
- , addFeed new_feed)
- FeedAdded r ->
- case r of
- Ok _ ->
- case model.view_state of
- Feeds _ archived ->
- ( model
- , getFeeds archived)
- _ -> ( model
- , Cmd.none)
- Err error ->
- ( { model | view_state = ShowError (errToString error) }
- , Cmd.none)
- SelectTab tab_id selected_tab ->
- case tab_id of
- "rss-feed-tab" ->
- case (str_to_readerState selected_tab) of
- Just readerstate ->
- ({ model
- | feedReaderState = readerstate}
- , Cmd.none)
- Nothing ->
- ( model
- , alert <| "Unknown selected tab " ++ selected_tab)
- "posteditor-preview-tab" ->
- ({ model |
- postEditorSettings =
- Maybe.map (\settings -> {settings
- | show_preview = selected_tab == "PreviewArticle"})
- model.postEditorSettings}
- , Cmd.none)
- _ -> ( model
- , alert <| "Unknown tab " ++ tab_id)
- ReadFeedItem feed_id item_id is_read ->
- case model.view_state of
- Feeds feeds show_archived ->
- let new_feeds = ( feeds
- |> List.map (\f -> if f.id == feed_id then
- {f | items = ( f.items
- |> List.map (\item ->
- if item.id == item_id then
- {item | is_read = is_read}
- else
- item ))}
- else
- f))
- in
- ({ model | view_state = Feeds new_feeds show_archived}
- , markFeedItemRead (UUID.toString feed_id) (UUID.toString item_id))
- _ -> ( model
- , Cmd.none)
- ShowArchivedFeedItems showArchived ->
- case model.view_state of
- Feeds feeds _ ->
- ({ model
- | view_state = Feeds feeds showArchived}
- , getFeeds showArchived)
- _ -> ( model
- , Cmd.none)
- FeedItemReadResponse result ->
- case result of
- Ok _ -> ( model
- , Cmd.none)
- Err error -> ( { model | view_state = ShowError (errToString error) }
- , Cmd.none)
- DeleteFeed id ->
- ( model
- , deleteFeed <| UUID.toString id)
- FeedDeleted result ->
- case result of
- Ok _ ->
- case model.view_state of
- Feeds _ archived ->
- ( model
- , getFeeds archived)
- _ ->
- ( model
- , Cmd.none)
- Err error -> ( { model | view_state = ShowError (errToString error) }
- , Cmd.none)
-
- FeedMetaReceived result ->
- case result of
- Ok metadata ->
- ({ model
- | feedMetadata = Just metadata}
- , Cmd.none)
- Err error -> ( { model | view_state = ShowError (errToString error) }
- , Cmd.none)
- SelectExcerpt article_uuid ->
- ( model
- , showModal <| "excerpt-dialog-" ++ (UUID.toString article_uuid))
- CreateExcerptPost textarea_id feed_id ->
- ( model
- , createExcerpt (textarea_id, UUID.toString feed_id))
- ExcerptCreated (excerpt, feed_id) ->
- ( model
- , postExcerpt excerpt feed_id)
- GotAdminLogs result ->
- case result of
- Ok logs ->
- case model.view_state of
- Logs _ g str ->
- ({ model | view_state = Logs logs g str}
- , Cmd.none)
- _ ->
- ( model
- , alert "Wrong viewstate again")
- Err error ->
- ( { model | view_state = ShowError (errToString error) }
- , Cmd.none)
- EditGroupRegexp new_regex ->
- ((case model.view_state of
- Logs a b _ ->
- { model | view_state = Logs a b new_regex}
- _ -> model)
- , Cmd.none)
- SaveLogGroup new_potential_regex ->
- case Regex.fromString new_potential_regex of
- Just _ ->
- case model.view_state of
- Logs logs groups asd ->
- let group = Logs.str_to_group new_potential_regex
- new_groups = (group::groups) in
- ({ model | view_state = Logs logs new_groups asd }
- , saveGroups new_groups)
- _ -> ( model
- , Cmd.none)
- Nothing ->
- ( model
- , alert <| "Invalid regex " ++ new_potential_regex)
- DeleteLogGroup group ->
- case model.view_state of
- Logs logs groups current ->
- let new_groups = (List.filter (\g -> g.name /= group) groups)
- new_state = Logs logs new_groups current
- in
- ({ model | view_state = new_state}
- , saveGroups new_groups)
- _ -> ( model
- , Cmd.none)
- SetLogAlarmy group new_alarmy ->
- case model.view_state of
- Logs a groups b ->
- let new_groups = groups
- |> List.map (\g ->
- if g.name == group.name then
- { g | alarmy = new_alarmy}
- else g)
- in
- ({ model
- | view_state = Logs a new_groups b}
- , saveGroups new_groups)
- _ -> ( model
- , Cmd.none)
- LogGroupsSaved result ->
- case result of
- Ok _ ->
- ( model
- , Cmd.none)
- Err err ->
- ( model
- , alert <| "Saving groups failed " ++ (Debug.toString err))
- GotLogGroups result ->
- case result of
- Ok groups ->
- let new_viewstate =
- case model.view_state of
- Logs logs _ str -> Logs logs groups str
- _ -> model.view_state
- in
- ({ model
- | view_state = new_viewstate}
- , case model.view_state of
- Logs _ _ _ -> Cmd.none
- _ -> alert "view state is wrong")
- Err error ->
- ( { model | view_state = ShowError (errToString error) }
- , Cmd.none)
- GotTopbarLogAlarm res ->
- case res of
- Ok alarm ->
- ({ model | ringLogAlarm = alarm.alarm}
- , Cmd.none)
- Err error ->
- ( { model | view_state = ShowError (errToString error) }
- , Cmd.none)
- SetDomain dm ->
- ({ model | settings = Maybe.map (\settings ->
- { settings | domain = dm })
- model.settings}
- , Cmd.none)
- SetUsername usrname ->
- case model.view_state of
- UserSettings oldpwd newpwd usr ->
- ({ model
- | view_state = UserSettings oldpwd newpwd (Maybe.map (\old_usr ->
- {old_usr | username = usrname}) usr)}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SetNickname new_nickname ->
- case model.view_state of
- UserSettings oldpwd newpwd usr ->
- ({ model
- | view_state = UserSettings oldpwd newpwd (Maybe.map (\old_usr ->
- {old_usr | nickname = new_nickname}) usr)}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SetNewpwd newpwd ->
- case model.view_state of
- UserSettings oldpwd _ usr ->
- ({ model
- | view_state = UserSettings oldpwd newpwd usr}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SetOldpwd oldpwd ->
- case model.view_state of
- UserSettings _ newpwd usr ->
- ({ model
- | view_state = UserSettings oldpwd newpwd usr}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SubmitChangedUser oldpasswd newpasswd user ->
- -- TODO implement
- case model.loginState of
- LoggedIn usr ->
- ( model
- , if usr.id == user.id then
- submitUser user oldpasswd newpasswd
- else
- Cmd.none)
- _ -> ( model
- , Cmd.none)
- UserSubmitResult r ->
- case r of
- Ok _ ->
- ( model
- , Cmd.batch [ getSettings
- , getSession
- , getTitles])
- Err error ->
- ( { model | view_state = ShowError (errToString error) }
- , Cmd.none)
- UploadedOwnProfilePic r ->
- case r of
- -- we're not really interested in the return value more than "is it 2xx instead of 4xx or 5xx?", we're just as api-compatible with the posteditor's image upload functionality as possible
- Ok _ ->
- ( model
- , Cmd.batch [ getSettings
- , getSession
- , getTitles])
- Err error ->
- ( { model | view_state = ShowError (errToString error) }
- , Cmd.none)
- SetInitialUsername usrname ->
- case model.view_state of
- InitialSetup formdata ->
- ( { model | view_state
- = InitialSetup { formdata
- | username = usrname }}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SetInitialNickname nckname ->
- case model.view_state of
- InitialSetup formdata ->
- ( { model | view_state
- = InitialSetup { formdata
- | nickname = nckname }}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SetInitialPassword passwd ->
- case model.view_state of
- InitialSetup formdata ->
- ( { model | view_state
- = InitialSetup { formdata
- | password = passwd }}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SetInitialDomain dmain ->
- case model.view_state of
- InitialSetup formdata ->
- ( { model | view_state
- = InitialSetup { formdata
- | domain = dmain }}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SetInitialBlog_Title title ->
- case model.view_state of
- InitialSetup formdata ->
- ( { model | view_state
- = InitialSetup { formdata
- | blog_title = title }}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SetInitialRss_Title title ->
- case model.view_state of
- InitialSetup formdata ->
- ( { model | view_state
- = InitialSetup { formdata
- | rss_title = title }}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SetInitialRss_Link link ->
- case model.view_state of
- InitialSetup formdata ->
- ( { model | view_state
- = InitialSetup { formdata
- | rss_link = link }}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SetInitialRss_Description descr ->
- case model.view_state of
- InitialSetup formdata ->
- ( { model | view_state
- = InitialSetup { formdata
- | rss_description = (if descr == "" then
- Nothing
- else
- Just descr)}}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SetInitialRss_Lang lang ->
- case model.view_state of
- InitialSetup formdata ->
- ( { model | view_state
- = InitialSetup { formdata
- | rss_lang = lang }}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SetInitialRss_Email email ->
- case model.view_state of
- InitialSetup formdata ->
- ( { model | view_state
- = InitialSetup { formdata
- | rss_email = email }}
- , Cmd.none)
- _ -> ( model, Cmd.none)
- SaveInitialData data ->
- ( model
- , postInitialData data )
- PostInitialSuccess res ->
- case res of
- Ok _ ->
- doGoHome model
- Err error ->
- ( { model | view_state = ShowError (errToString error) }
- , Cmd.none)
-
-doGoHome_ model other_cmds =
- (model, Cmd.batch (List.append [ getSettings
- , getTitles
- , getSession
- , getPage 1
- , Nav.pushUrl model.key "/blog/"]
- other_cmds))
-
-doGoHome model = doGoHome_ model []
-
--- VIEW
-
-sidebarHistory : List Article.Title -> Html Msg
-sidebarHistory titles =
- let grouped_by_year = groupBy .year titles in
- div [id "grouper"]
- [ul []
- (List.concat (List.map (\year ->
- case get year grouped_by_year of
- Just per_year ->
- [li [] [details [] [summary [] [text ((fromInt year) ++ " (" ++ (fromInt (List.length per_year)) ++ ")")],
- let grouped_by_month = groupBy .month per_year in
- ul [] (List.concat (List.map (\month ->
- case (int_to_month_string month) of
- Just month_str ->
- let month_titles = titles |> List.filter (\title ->
- title.year == year && title.month == month)
- in
- [li [] [details [] [summary [] [text ((toSentenceCase month_str) ++ " (" ++ (fromInt (List.length month_titles)) ++ ")")]
- , ul [class "title-list"] (month_titles
- |> List.map (\title ->
- [li [class "title-list"]
- [a [href ("/blog/post/" ++ (fromInt title.id))] [text title.title]]])
- |> List.concat)]]]
- Nothing -> [li [] [details [] [summary [] [text ("Couldn't decode month " ++ (String.fromInt month))]]]]
- ) (keys grouped_by_month) |> List.reverse))]]]
-
- Nothing ->
- [li [] [text ("There's no year " ++ (fromInt year) ++ " in titles")]]) (keys grouped_by_year |> List.reverse)))]
-
-
-page_wrapper comp =
- div [class "flex-container"]
- [ div [class "page"]
- comp]
-
-unknown_state = [ div [] [ text "Unknown viewstate in blog_tab"] ]
-
-blog_tab settings model =
- div []
- (case model.view_state of
- Loading ->
- [div [] [text "LOADING"]]
- PostView article ->
- [ articleView settings model.loginState model.zone article ]
- PageView page ->
- let post_elements = (List.map (articleView settings model.loginState model.zone) page.posts) in
- (List.concat [ (if post_elements /= [] then
- post_elements
- else
- [ div [class "post"] [ text <| case model.loginState of
- LoggedIn usr -> "Hi " ++ usr.nickname ++ ", there are no (also: no user) posts in this instance"
- _ -> "There are no (also: no user) posts in this instance"]])
- , [footer [ attribute "data-testid" "page-changer"
- , class "page-changer" ]
- (if page.id > 1 then
- [ a [href ("/blog/page/" ++ fromInt (page.id + 1))] [text "Older posts"]
- , a [href ("/blog/page/" ++ fromInt (page.id - 1)), class "newer-post"] [text "Newer posts"]]
- else
- [a [href ("/blog/page/" ++ fromInt (page.id + 1))] [text "Older posts"]])]])
- ShowError err ->
- [pre [] [text err]]
- TaggedPostsView articles ->
- (List.map (articleView settings model.loginState model.zone) articles)
- Logs logs groups current_group -> [ Logviewer.tab logs groups current_group ]
- -- ignored cases (that should maybe be removed from the enumeration?) that are inlined here to make compiler yell about new unimplemented enumerations
- PostEditorList _ -> unknown_state
- PostEditor -> unknown_state
- MediaList -> unknown_state
- SettingsEditor -> unknown_state
- Feeds _ _ -> unknown_state
- UserSettings oldpasswd newpasswd usr_ -> case usr_ of
- Just usr -> [ UserEditor.editor model.draggingImages oldpasswd newpasswd usr]
- Nothing -> [ div [] [ text "Can't change user settings when there's no user"]]
- InitialSetup data -> [ InitialForm.initialForm data]
- )
-
-rss_tab model settings =
- div []
- (case model.view_state of
- Feeds feeds show_archived -> [ FeedView.feeds model.feedReaderState model.loginState show_archived settings model.zone feeds model.new_feed model.feedMetadata]
- _ -> [ div [] [ text "Unknown viewstate in rss_tab"] ])
-
-postmanager_tab model =
- div []
- (case model.view_state of
- PostEditorList titles -> [ PostsAdmin.view titles ]
- _ -> [ div [] [ text "Unknown viewstate in postmanager_tab"] ])
-
-mediamanager_tab model =
- div []
- (case model.view_state of
- MediaList -> [ medialist model.loadedImages model.medialist_state ]
- _ -> [ div [] [ text "Unknown viewstate in mediamanager_tab"] ])
-
-settings_tab settings model =
- div []
- (case model.view_state of
- SettingsEditor -> [ SettingsEditor.editor settings]
- _ -> [ div [] [ text "Unknown viewstate in settings_tab"] ])
-
-posteditor_tab settings model =
- div [ class "posteditor-tab" ]
- (case model.view_state of
- PostEditor ->
- case model.postEditorSettings of
- Just editorSettings ->
- let post = editorSettings.article
- tag_index = editorSettings.selected_tag in
- PostEditor.postEditor post tag_index model.showImageModal model.loadedImages model.draggingImages editorSettings settings model.zone model.loginState model.searchedPosts
- Nothing -> [ div [] [ text "No post loaded" ]]
- _ -> [ div [] [ text "Unknown viewstate in posteditor_tab" ]])
-
-view : Model -> Browser.Document Msg
-view model =
- case model.settings of
- Nothing ->
- { title = "Error loading murja"
- , body =
- [div [] [text "Couldn't load settings"]]}
- Just settings ->
- { title = settings.blog_title
- , body =
- [ header [] [a [href "/"] [text settings.blog_title ]]
- , div [ class "sidebar-flex" ]
- [ let tabstate = viewstate_to_tabstate model.view_state in
- tabs "topbar" (tabstate_to_str tabstate) (case model.loginState of
- LoggedIn usr -> Just usr
- _ -> Nothing)
- (Dict.fromList [ ("Blog"
- , TabEntry "Home" ""
- (blog_tab settings model)
- (Just GoHome)
- ["*"])
- , ("RssFeeds"
- , TabEntry "RSS Feeds" ""
- (rss_tab model settings)
- (Just (PushUrl "/blog/feeds"))
- ["create-post"] ) -- <- TODO make a real permission for rss
- , ("ManagePosts"
- , TabEntry "Manage posts" ""
- (postmanager_tab model)
- (Just (PushUrl "/blog/postadmin"))
- ["create-post", "delete-post", "edit-post"])
- , ("ManageMedia"
- , TabEntry "Manage media" ""
- (mediamanager_tab model)
- (Just (PushUrl "/blog/mediamanager"))
- ["create-post", "delete-post", "edit-post"])
- , ("SettingsTab"
- , TabEntry "Settings" ""
- (settings_tab settings model)
- (Just (PushUrl "/blog/settings"))
- ["update-settings"])
- , ("SettingLogs"
- , TabEntry ("Logs" ++ (if model.ringLogAlarm then " (!!!!!!)" else ""))
- (if model.ringLogAlarm then " alert " else "")
- (text "in the frontpage these views don't show up anywhere")
- (Just (PushUrl "/blog/logs"))
- ["update-settings"])
- , ("PostEditTab"
- , TabEntry "Post editor" ""
- (posteditor_tab settings model)
- (Just GenNewPost)
- ["create-post", "edit-post"])])
- , div [id "sidebar"] [ UserEditor.loginView model.loginState
- , (sidebarHistory model.titles )
- , (case model.view_state of
- PostEditorList titles -> PostsAdmin.tagList titles
- _ -> div [] [])]]]}
diff --git a/elm-frontti/src/Medialist.elm b/elm-frontti/src/Medialist.elm
deleted file mode 100644
index 90b7c71..0000000
--- a/elm-frontti/src/Medialist.elm
+++ /dev/null
@@ -1,66 +0,0 @@
-module Medialist exposing (..)
-
-import Html exposing (..)
-import Html.Attributes exposing (..)
-import Html.Events exposing (..)
-import Json.Decode as D
-import Dict
-
-
-import Http
-
-import Article
-import Ajax_cmds exposing (..)
-import Creator as C
-import Page as P
-import Message exposing (..)
-import ImageSelector exposing (imageSelector)
-import Image
-
-import UUID
-
-referencing_post_view post = li []
- [ a [ href ("/blog/post/" ++ (String.fromInt post.post_id)) ]
- [ text post.post_title ]]
-
-medialist images medialist_state =
- case medialist_state of
- Just state ->
- div [ class "vertical-flex-container" ]
- (List.append
- [div [class "title-flex-container"]
- [ button [ class "post-admin-title"
- , onClick RemoveSelectedImages ] [ text "Remove selected" ]
- , div [ class "post-admin-title" ] []
- , button [ class "post-admin-title"
- , onClick (MarkAllImages (List.map .id images))] [ text "Select all" ]]]
- (List.map (\image ->
- let checkbox_id = "delete" ++ (UUID.toString image.id)
- in
- div [ class "title-flex-container" ]
- [ details [ ]
- [ summary [ class "post-admin-title" ] [h2 [] [ text image.name ]
- , div [] [ text (UUID.toString image.id)]]
- , ImageSelector.image image]
- , details [ class "post-admin-title"]
- [ summary [ attribute "data-testid" "referencing-post"]
- [ text "Referencing posts" ]
- , case (Dict.get (UUID.toString image.id) state.referencing_posts) of
- Just referencing_posts ->
- if referencing_posts == [] then
- div [] [ text "No referencing posts" ]
- else
- ul []
- (List.map referencing_post_view referencing_posts)
- Nothing -> div [] [ text "No referencing posts" ]]
- , div [ class "post-admin-title" ]
- [ label [for checkbox_id] [text "Choose for deletion"]
- , input [ type_ "checkbox"
- , id checkbox_id
- , checked (List.member image.id state.selected_ids_for_removal)
- , onClick (MarkImageForRemoval image.id)] []]])
- images))
- Nothing ->
- div [] [ text "lol et sit oo initialisoinu medialist_statea" ]
-
-
diff --git a/elm-frontti/src/Message.elm b/elm-frontti/src/Message.elm
deleted file mode 100644
index c46a44d..0000000
--- a/elm-frontti/src/Message.elm
+++ /dev/null
@@ -1,275 +0,0 @@
-port module Message exposing (..)
-
-import Http
-import Html
-import Html.Attributes
-import Json.Encode
-import Browser
-import Time
-import Page as P
-import Article
-import Browser.Navigation as Nav
-import Settings
-import Url
-import Title
-import Feeds
-import Image exposing (Image, ReferencingPost)
-import Logs
-import Initial
-
-import File exposing (File)
-import UUID exposing (UUID)
-import Stack exposing (..)
-import Dict exposing (Dict)
-import Regex
-
-type ViewState
- = PageView P.Page
- | PostView Article.Article
- | Loading
- | ShowError String
- | PostEditorList (List Title.Title) -- list all the posts in db
- | PostEditor
- | MediaList -- list all the image blobs in db
- | TaggedPostsView (List Article.Article)
- | SettingsEditor
- | Feeds (List Feeds.Feed) Bool -- <- show_archived?
- -- v- the second List will be parsed as List Regex later
- | Logs (List Logs.Log) (List Logs.Group) String
- | UserSettings
- -- oldpwd
- String
- -- newpwd
- String
- -- the view's user we're editing instead of the LoginState's user who is logged in here
- (Maybe LoginUser)
- | InitialSetup
- Initial.InitialFormData
-
-
-
--- a simplified version of ViewState type for the main.elm's tabcomponent
-type TabState
- = Blog
- | RssFeeds
- | ManagePosts
- | ManageMedia
- | SettingsTab
- | PostEditTab
-
-viewstate_to_tabstate vs =
- case vs of
- PageView _ -> Blog
- PostView _ -> Blog
- Loading -> Blog
- ShowError _ -> Blog
- PostEditorList _ -> ManagePosts
- PostEditor -> PostEditTab
- MediaList -> ManageMedia
- TaggedPostsView _ -> Blog
- SettingsEditor -> SettingsTab
- Feeds _ _ -> RssFeeds
- Logs _ _ _ -> Blog
- UserSettings _ _ _ -> Blog
- InitialSetup _ -> Blog
-
-tabstate_to_str tb =
- case tb of
- Blog -> "Blog"
- RssFeeds -> "RssFeeds"
- ManagePosts -> "ManagePosts"
- ManageMedia -> "ManageMedia"
- SettingsTab -> "SettingsTab"
- PostEditTab -> "PostEditTab"
-
-str_to_tabstate str =
- case str of
- "Blog" -> Blog
- "RssFeeds" -> RssFeeds
- "ManagePosts" -> ManagePosts
- "ManageMedia" -> ManageMedia
- "SettingsTab" -> SettingsTab
- "PostEditTab" -> PostEditTab
- _ -> Blog
-
-type alias User =
- { username : String
- , nickname : String
- , img_location : String
- }
-
-type LoginState
- = LoggedIn LoginUser
- | LoggingIn String String
- | LoginFailed
- | LoggedOut
-
-
-type alias LoginUser =
- { nickname : String
- , username : String
- , img_location : String
- , primary_group_name : String
- , permissions : List String
- , id: Int --unique and immutable key, needed because UserEditor.editor lets user change all the other values
- }
-
-type alias MediaListState =
- { selected_ids_for_removal : List UUID
- , referencing_posts : Dict String (List ReferencingPost)}
-
-type alias PostEditorSettings =
- { article : Article.Article
- , selected_tag : String
- , show_preview : Bool
- , previewing_previously : Maybe Article.Article}
-
-type FeedReaderState
- = PerFeed
- | SingleFeed
- | FeedManager
-
-str_to_readerState str =
- case str of
- "PerFeed" -> Just PerFeed
- "SingleFeed" -> Just SingleFeed
- "FeedManager" -> Just FeedManager
- _ -> Nothing
-
-type alias Model =
- { view_state : ViewState
- , settings : Maybe Settings.Settings
- , showImageModal : Bool
- , draggingImages : Bool
- , loadedImages : List Image
- , medialist_state : Maybe MediaListState
- , loginState : LoginState
- , key : Nav.Key
- , url : Url.Url
- , postEditorSettings: Maybe PostEditorSettings
- , zone : Time.Zone
- , titles : List Article.Title
- , searchedPosts : List Article.PreviousArticle
- , new_feed: Maybe Feeds.NewFeed
- , feedReaderState: FeedReaderState
- , feedMetadata: Maybe Feeds.FeedMetadata
- , ringLogAlarm: Bool}
-
-type Msg
- = PageReceived (Result Http.Error P.Page)
- | PostReceived (Result Http.Error Article.Article)
- | SettingsReceived (Result Http.Error Settings.Settings)
- | TitlesReceived (Result Http.Error (List Article.Title))
- | EditableTitlesReceived (Result Http.Error (List Article.Title))
- | UrlChanged Url.Url
- | LinkClicked Browser.UrlRequest
- | LoginFocus
- | ChangeUsername String
- | ChangePassword String
- | DoLogIn
- | LoginSuccess (Result Http.Error LoginUser)
- | GotSession (Result Http.Error LoginUser)
- | OpenPostEditor Int
- | EditorPostReceived (Result Http.Error Article.Article)
- | PromptTag String
- | ReceivedTag String
- | AceStateUpdate String
- | SelectTag String
- | Alert String
- | DropTag String
- | SavePost Article.Article
- | HttpIgnoreResponse (Result Http.Error String)
- | HttpGoHome (Result Http.Error String)
- | GoHome
- | ChangeTitle String
- | RunAce String
- | GetListOfImages
- | GotListOfImages Bool (Result Http.Error (List Image.Image))
- | SelectedImage UUID
- | EditorDragEnter
- | EditorDragLeave
- | GotFiles (File.File -> Cmd Msg) File (List File)
- | GotInputFiles (List File)
- | UploadedImage (Result Http.Error Image.PostImageResponse)
- | MarkImageForRemoval UUID
- | MarkAllImages (List UUID)
- | RemoveSelectedImages
- | HttpManagerGetListOfImages (Result Http.Error String)
- | GotReferencingPosts (Result Http.Error (List Image.ReferencingPost))
- | PushUrl String
- | AdjustTimeZone Time.Zone
- | GotTaggedPosts (Result Http.Error (List Article.Article))
- | ToggleArticlePreview
- | GotOldPost (Result Http.Error Article.Article)
- | GenNewPost
- | NewPostGenerated (Result Http.Error Int)
- | ToggleArticleUnlisted
- | ToggleArticleHidden
- | AdminSettingsReceived (Result Http.Error Settings.Settings)
- | SetTimeFormat String
- | SetBlogTitle String
- | SetPageSize String
- | SaveSettings
- | SettingsSaved (Result Http.Error ())
- | ShowPreviousPostsModal
- | ClosePreviousPostsModel
- | PreviouslySearchInput String
- | PreviouslySearchResult (Result Http.Error (List Article.PreviousArticle))
- | SelectPreviouslyPost Article.PreviousArticle
- | DropPreviously Article.PreviousArticle
- | SetPreviouslyLabel String
- | LoadPreviouslyPreview Article.PreviousArticle
- | PreviousPostReceived (Result Http.Error Article.Article)
- | ClosePreviousPostPreviewModal
- | FeedsReceived (Result Http.Error (List Feeds.Feed))
- | SetFeedUrl String
- | SetFeedName String
- | AddFeed Feeds.NewFeed
- | FeedAdded (Result Http.Error ())
- | SelectTab String String
- | ReadFeedItem UUID UUID Bool
- | ShowArchivedFeedItems Bool
- | FeedItemReadResponse (Result Http.Error ())
- | DeleteFeed UUID
- | FeedDeleted (Result Http.Error ())
- | FeedMetaReceived (Result Http.Error Feeds.FeedMetadata)
- | SelectExcerpt UUID
- | CreateExcerptPost String UUID
- | ExcerptCreated (String, String)
- | GotAdminLogs (Result Http.Error (List Logs.Log))
- | EditGroupRegexp String
- | SaveLogGroup String
- | DeleteLogGroup String
- | SetLogAlarmy Logs.ParsedGroup Bool
- | LogGroupsSaved (Result Http.Error ())
- | GotLogGroups (Result Http.Error (List Logs.Group))
- | GotTopbarLogAlarm (Result Http.Error Logs.TopbarAlarm)
- | SetDomain String
- | SetUsername String
- | SetNickname String
- | SetNewpwd String
- | SetOldpwd String
- | SubmitChangedUser String String LoginUser
- | UserSubmitResult (Result Http.Error ())
- | UploadedOwnProfilePic (Result Http.Error Image.PostImageResponse)
- | SetInitialUsername String
- | SetInitialNickname String
- | SetInitialPassword String
- | SetInitialDomain String
- | SetInitialBlog_Title String
- | SetInitialRss_Title String
- | SetInitialRss_Link String
- | SetInitialRss_Description String
- | SetInitialRss_Lang String
- | SetInitialRss_Email String
- | SaveInitialData Initial.InitialFormData
- | PostInitialSuccess (Result Http.Error ())
-
--- ports
-port reallySetupAce : String -> Cmd msg
-port addImgToAce : String -> Cmd msg
-port alert : String -> Cmd msg
-
--- dumb shit that would deserve its own module
-dangerouslySetInnerHTML: String -> Html.Attribute msg
-dangerouslySetInnerHTML = Json.Encode.string >> Html.Attributes.property "dangerouslySetInnerHTML"
diff --git a/elm-frontti/src/Page.elm b/elm-frontti/src/Page.elm
deleted file mode 100644
index c9d51db..0000000
--- a/elm-frontti/src/Page.elm
+++ /dev/null
@@ -1,22 +0,0 @@
-module Page exposing (..)
-
-
-import Http
-import Html exposing (Html, text, pre)
-import Article as A
-
-import Json.Decode as Decode exposing (Decoder, succeed)
-import Json.Decode.Pipeline exposing (required)
-import Json.Decode.Extra as Extra
-
-type alias Page =
- { last_page: Bool
- , id : Int
- , posts: List A.Article}
-
-pageDecoder : Decoder Page
-pageDecoder =
- Decode.map3 Page
- (Decode.field "last-page?" Decode.bool)
- (Decode.field "id" Decode.int)
- (Decode.field "posts" (Decode.list A.articleDecoder))
diff --git a/elm-frontti/src/PostEditor.elm b/elm-frontti/src/PostEditor.elm
deleted file mode 100644
index 7615999..0000000
--- a/elm-frontti/src/PostEditor.elm
+++ /dev/null
@@ -1,161 +0,0 @@
-module PostEditor exposing (..)
-
-import Html exposing (..)
-import Html.Attributes exposing (..)
-import Html.Events exposing (..)
-import Json.Decode as D
-
-
-import Http
-
-import Article_view
-import Ajax_cmds exposing (..)
-import Creator as C
-import Page as P
-import Message exposing (..)
-import ImageSelector exposing (imageSelector)
-import Button exposing (murja_button)
-import Tab exposing (..)
-import Dict exposing (Dict)
-
-import File exposing (File)
-import File.Select as Select
-
--- dropDecoder : D.Decoder Msg
-dropDecoder handler =
- D.at ["dataTransfer","files"] (D.oneOrMore (GotFiles handler) File.decoder )
-
-
-hijackOn : String -> D.Decoder msg -> Attribute msg
-hijackOn event decoder =
- preventDefaultOn event (D.map hijack decoder)
-
-
-hijack : msg -> (msg, Bool)
-hijack msg =
- (msg, True)
-
-
-optionize tag = option [value tag] [text tag]
-
-tagView post selectedTag = div [class "tagview editor-grouper"]
- [ select [ multiple True
- , class "tag-select"
- , id "tag-select"
- , onInput SelectTag
- , attribute "data-tags" (String.join "," post.tags)] (List.map optionize post.tags)
- , murja_button [ onClick (PromptTag "New tag? ")
- , id "new-tag-btn"]
- [ text "Add tag"]
- , murja_button [ onClick (DropTag selectedTag)
- , attribute "data-testid" "remove-tag"]
- [text "Remove selected tag"]]
-
-editor params =
- div [ class "editor-container" ]
- [ node "ace-editor"
- ( params
- ++ [ attribute "theme" "ace/theme/monokai"
- , attribute "mode" "ace/mode/html"])
- []]
-
-filesDecoder : D.Decoder (List File)
-filesDecoder =
- D.at ["target","files"] (D.list File.decoder)
-
-previously_row p
- = li [] [ murja_button [ onClick (LoadPreviouslyPreview p) ] [ text p.title]
- , button [ onClick (DropPreviously p)] [ text "X"]]
-
-previouslyButtons post loadedPosts previewingArticle article_settings =
- let { app_settings, loginState , tz} = article_settings
- in
- div [ class "previously-buttons" ]
- [ murja_button [ onClick ShowPreviousPostsModal ] [ text "Link previous posts"]
- , ul []
- ( post.previously
- |> List.map previously_row)
- , node "dialog" [ id "previewPreviouslyModal" ]
- (case previewingArticle of
- Just article ->
- [ div [ class "dialog" ]
- [ header [ class "previouslyHeader" ] [ button [ onClick ClosePreviousPostPreviewModal ] [ text "X"]]
- , case loginState of
- LoggedIn user ->
- Article_view.articleView app_settings loginState tz article
- _ -> div [] [text "You're not logged in"]]]
- Nothing -> [])
- , node "dialog" [ id "previouslyModal" ]
- [ div [ class "dialog" ]
- [ header [ class "previouslyHeader" ] [ button [ onClick ClosePreviousPostsModel ] [ text "X"]]
- , select [ multiple True
- , class "previouslyPostResult"]
- (List.map (\prev_post ->
- option [ onClick (SelectPreviouslyPost prev_post) ] [ text prev_post.title ]) loadedPosts)
- , input [ type_ "text"
- , placeholder "Search for posts"
- , onInput PreviouslySearchInput] []]]]
-
-postEditor post tag showImageModal loadedImages draggingImages editorSettings app_settings tz loginState searchedPosts
- = [ div [ class "editor-top" ]
- [ div [ id "editor-buttons"
- , class "editor-grouper"]
- [ input [ name "title"
- , id "editor-post-title"
- , value post.title
- , onInput ChangeTitle] []
- , murja_button [ id "editor-post-save"
- , onClick (SavePost post) ] [text "Save version"]
- , label [ for "file-pictures-input"
- , class "murja-button"] [ text "Add pictures from device"]
- , input [ type_ "file"
- , multiple False
- , style "display" "none"
- , id "file-pictures-input"
- , on "change" (D.map GotInputFiles filesDecoder)] []
- , murja_button [ id "image-insert-btn"
- , onClick GetListOfImages]
- [text "Insert image"]]
- , tagView post tag
- , previouslyButtons post searchedPosts editorSettings.previewing_previously
- { app_settings = app_settings
- , loginState = loginState
- , tz = tz }
- , div [ class "editor-grouper" ]
- [ label [ for "hidden"]
- [ text "Hidden article"]
- , input [ type_ "checkbox"
- , id "hidden"
- , checked post.hidden
- , onClick ToggleArticleHidden ] []
- , label [ for "unlisted"]
- [ text "Unlisted article"]
- , input [ type_ "checkbox"
- , id "unlisted"
- , checked post.unlisted
- , onClick ToggleArticleUnlisted] []]]
- , if showImageModal then imageSelector loadedImages else div [] []
- , case loginState of
- LoggedIn user ->
- tabs "posteditor-preview-tab" (if editorSettings.show_preview then
- "PreviewArticle"
- else
- "EditArticle") (Just user)
- (Dict.fromList [ ("EditArticle"
- , TabEntry "Edit article" ""
- (editor [ id "editor-post-content"
- , style "background-color" (if draggingImages then "#880088" else "")
- , hijackOn "dragenter" (D.succeed EditorDragEnter)
- , hijackOn "dragend" (D.succeed EditorDragLeave)
- , hijackOn "dragover" (D.succeed EditorDragEnter)
- , hijackOn "dragleave" (D.succeed EditorDragLeave)
- , hijackOn "drop" (dropDecoder (postPicture UploadedImage editor_image_api))
- , hijackOn "ready" (D.succeed (RunAce post.content))])
- Nothing ["*"])
- , ("PreviewArticle"
- , TabEntry "Preview article" ""
- (Article_view.articleView app_settings loginState tz post)
- Nothing ["*"])])
- _ -> div [] [text "You're not logged in"]]
-
-editor_image_api = "/api/pictures"
diff --git a/elm-frontti/src/PostsAdmin.elm b/elm-frontti/src/PostsAdmin.elm
deleted file mode 100644
index c20d6a5..0000000
--- a/elm-frontti/src/PostsAdmin.elm
+++ /dev/null
@@ -1,53 +0,0 @@
-module PostsAdmin exposing (..)
-
-import Message exposing (..)
-import Set
-
-import Html exposing (..)
-import Html.Attributes exposing (..)
-import Html.Events exposing (..)
-
-import Date_utils exposing (int_to_month_string)
-
-tagListElement allTags tag =
- let count = ( allTags
- |> List.filter ((==) tag)
- |> List.length) in
- a [ href ("/blog/tags/" ++ tag)
- , style "display" "block" ]
- [ text (tag ++ " (" ++ (String.fromInt count) ++ ")")]
-
-tagList titles =
- let allTags = ( titles
- |> List.concatMap (\title -> title.tags))
- tags = ( allTags
- |> Set.fromList
- |> Set.toList
- |> List.filter ((/=) "")) in
- div [] (List.append [h3 [] [text ("Tags in the system (" ++ String.fromInt (List.length tags) ++ "): ")]]
- ( tags
- |> List.map (tagListElement allTags)))
-
-titleView title = case (int_to_month_string title.month) of
- Just month ->
- div [ class "title-flex-container" ]
- [ span [class "post-admin-title" ] [text ( title.title ++ " - " ++ month ++ ", " ++ (String.fromInt title.year))]
- , a [ href ("/blog/post/edit/" ++ String.fromInt title.id)
- , attribute "data-testid" "manager-edit-post-btn"
- , onClick (OpenPostEditor title.id)] [text "Edit"]
- -- this has never been implemented...
- -- , a [href ("/blog/post/remove/" ++ String.fromInt title.id)] [text "Remove"]
- , div [class "post-admin-title" ]
- (List.append [ h3 [] [text "Tags: "]]
- (List.map (\tag -> a [ href ("/blog/tags/" ++ tag)
- , style "display" "block" ]
- [ text tag ]) title.tags))]
- Nothing -> div [] [text ("Parsing month " ++ (String.fromInt title.month) ++ " failed")]
-
-view titles = (div [class "vertical-flex-container"]
- (if titles /= [] then
- (titles
- |> List.map titleView)
- else [ span [] [ text "No posts in murja. Create one by "
- , button [ onClick GenNewPost ] [ text "clicking here" ]]]))
-
diff --git a/elm-frontti/src/RouteParser.elm b/elm-frontti/src/RouteParser.elm
deleted file mode 100644
index b3e0cca..0000000
--- a/elm-frontti/src/RouteParser.elm
+++ /dev/null
@@ -1,42 +0,0 @@
-module RouteParser exposing (..)
-
-import Url
-import Url.Parser exposing (..)
-import String exposing (fromInt)
--- http://localhost:3000/blog/post/edit/21
-type Route
- = Page Int
- | Post Int
- | PostAdmin
- | MediaManager
- | PostEditor Int
- | TaggedPosts String
- | PostVersion Int Int
- | SettingsEditor
- | FeedReader
- | Home
- | Logs
- | NotFound
- | OwnUserSettings
- | InitialSetup
-
-routeParser =
- oneOf
- [ map Page (s "blog" </> (s "page" </> int))
- , map Home Url.Parser.top
- , map Home (s "blog")
- , map PostVersion (s "blog" </> (s "post" </> (int </> (s "version" </> int))))
- , map Post (s "blog" </> (s "post" </> int))
- , map PostEditor (s "blog" </> (s "post" </> (s "edit" </> int)))
- , map MediaManager (s "blog" </> (s "mediamanager"))
- , map SettingsEditor (s "blog" </> (s "settings"))
- , map TaggedPosts (s "blog" </> (s "tags" </> string))
- , map Logs (s "blog" </> (s "logs"))
- , map PostAdmin (s "blog" </> (s "postadmin"))
- , map FeedReader (s "blog" </> (s "feeds"))
- , map OwnUserSettings (s "blog" </> (s "usersettings"))
- , map InitialSetup (s "blog" </> (s "initial-setup"))]
-
-
-url_to_route url =
- Maybe.withDefault NotFound (parse routeParser url)
diff --git a/elm-frontti/src/Settings.elm b/elm-frontti/src/Settings.elm
deleted file mode 100644
index 18c3f8c..0000000
--- a/elm-frontti/src/Settings.elm
+++ /dev/null
@@ -1,29 +0,0 @@
-module Settings exposing (..)
-
-import Json.Decode as Decode exposing (Decoder, succeed)
-import Json.Decode.Pipeline exposing (required)
-import Json.Decode.Extra as Extra
-import Json.Encode as Json exposing (..)
-
-type alias Settings =
- { time_format : String
- , blog_title : String
- , recent_post_count : Int
- , previously_label: String
- , domain: String
- }
-
-settingsDecoder = Decode.map5 Settings
- (Decode.field "time-format" Decode.string)
- (Decode.field "blog-title" Decode.string)
- (Decode.field "recent-post-count" Decode.int)
- (Decode.field "previously_label" Decode.string)
- (Decode.field "domain" Decode.string)
-
-encodeSettings settings =
- object
- [ ( "time-format", string settings.time_format )
- , ( "blog-title", string settings.blog_title)
- , ( "recent-post-count", int settings.recent_post_count)
- , ( "previously_label", string settings.previously_label)
- , ( "domain", string settings.domain)]
diff --git a/elm-frontti/src/SettingsEditor.elm b/elm-frontti/src/SettingsEditor.elm
deleted file mode 100644
index a0be10c..0000000
--- a/elm-frontti/src/SettingsEditor.elm
+++ /dev/null
@@ -1,44 +0,0 @@
-module SettingsEditor exposing (..)
-
-import Html exposing (..)
-import Html.Attributes exposing (..)
-import Html.Events exposing (..)
-import Json.Decode as D
-
-import Message exposing (..)
-
-editor settings =
- div [ class "form-grid" ]
- [ label [ for "time-format"]
- [ text "Time format "]
- , input [ id "time-format"
- , onInput SetTimeFormat
- , value settings.time_format] []
-
- , label [ for "title" ]
- [ text "Title" ]
- , input [ id "title"
- , onInput SetBlogTitle
- , value settings.blog_title] []
-
- , label [ for "page_size" ]
- [ text "Page size (posts)"]
- , input [ id "page_size"
- , onInput SetPageSize
- , value (String.fromInt settings.recent_post_count)
- , type_ "number"] []
-
- , label [ for "previously" ]
- [ text "Previously link label" ]
- , input [ id "previously"
- , onInput SetPreviouslyLabel
- , value settings.previously_label] []
-
- , label [ for "domain" ]
- [ text "Site domain (relevant for cookies)" ]
- , input [ id "domain"
- , onInput SetDomain
- , value settings.domain] []
-
- , button [ onClick SaveSettings ]
- [ text "Save settings"]]
diff --git a/elm-frontti/src/Tab.elm b/elm-frontti/src/Tab.elm
deleted file mode 100644
index e99186e..0000000
--- a/elm-frontti/src/Tab.elm
+++ /dev/null
@@ -1,47 +0,0 @@
-module Tab exposing (..)
-
-import Dict exposing (Dict)
-import Set exposing (Set)
-import Html exposing (..)
-import Html.Attributes exposing (..)
-import Html.Events exposing (..)
-import Message exposing (..)
-
-type alias TabEntry =
- { title: String
- , classes: String
- , component: Html Msg
- , onclick: Maybe Msg
- , permissions: List String}
-
--- tabs: String -> String -> Dict String TabEntry -> Html Msg
-tabs tab_id selected_tab usr tabentries =
- let tab_ids = ( tabentries
- |> Dict.filter (\k -> \entry -> case usr of
- Just user -> (( entry.permissions
- |> Set.fromList
- |> Set.intersect (Set.fromList user.permissions)
- |> Set.isEmpty
- |> not)
- ||
- (List.member "*" entry.permissions))
- Nothing -> (List.member "*" entry.permissions))
- |> Dict.keys)
- selected_tab_component = Dict.get selected_tab tabentries
- in
- div [ class "tabs"
- , id tab_id ]
- [ ul [ class "tab-headers" ]
- ( tab_ids
- |> List.map (\id ->
- let entry_ = Dict.get id tabentries in
- case entry_ of
- Just entry ->
- li [ class <| (if selected_tab == id then "tab-header tab-selected" else "tab-header") ++ " " ++ entry.classes
- , onClick (case entry.onclick of
- Just oc -> oc
- Nothing -> SelectTab tab_id id)] [ text <| entry.title ]
- Nothing -> li [] [ text "Unknown tab" ]))
- , case selected_tab_component of
- Just c -> c.component
- Nothing -> div [] [ text <| "Invalid selected tab key " ++ (Debug.toString selected_tab)]]
diff --git a/elm-frontti/src/Title.elm b/elm-frontti/src/Title.elm
deleted file mode 100644
index b5ffe05..0000000
--- a/elm-frontti/src/Title.elm
+++ /dev/null
@@ -1,8 +0,0 @@
-module Title exposing (..)
-
-type alias Title =
- { title: String
- , id: Int
- , year: Int
- , month: Int
- , tags: List String}
diff --git a/elm-frontti/src/User.elm b/elm-frontti/src/User.elm
deleted file mode 100644
index 5b0ce17..0000000
--- a/elm-frontti/src/User.elm
+++ /dev/null
@@ -1,83 +0,0 @@
-module User exposing (..)
-
-import Html exposing (..)
-import Html.Attributes as A exposing (..)
-import Html.Events exposing (..)
-
-import Message exposing (..)
-import Article exposing (decodeApply)
-import Json.Decode as Decode exposing (Decoder, succeed)
-import Json.Decode.Pipeline exposing (required)
-import Json.Decode.Extra as Extra
-import Json.Encode as Json
-import File exposing (File)
-
-
- -- {
- -- "nickname": "Feuer",
- -- "img_location": "https://feuerx.net/etc/feuer.jpeg",
- -- "userid": 1,
- -- "primary-group-name": "Admins",
- -- "permissions": [
- -- "edit-self",
- -- "comment-post",
- -- "edit-user",
- -- "create-comment",
- -- "edit-post",
- -- "delete-post",
- -- "create-post",
- -- "create-page",
- -- "delete-comment",
- -- "delete-user",
- -- "can-import",
- -- "edit-comment"
- -- ]
-
-
-nicknameDecoder = Decode.field "nickname" Decode.string
-imgDecoder = Decode.field "img_location" Decode.string
-group_name_decoder = Decode.field "primary-group-name" Decode.string
-permissionsDecoder = Decode.field "permissions" (Decode.list Decode.string)
-usernameDecoder = Decode.field "username" Decode.string
-idDecoder = Decode.field "userid" Decode.int
-
--- |> == clojure's ->>
-userDecoder : Decoder LoginUser
-userDecoder =
- Decode.succeed LoginUser
- |> decodeApply nicknameDecoder
- |> decodeApply usernameDecoder
- |> decodeApply imgDecoder
- |> decodeApply group_name_decoder
- |> decodeApply permissionsDecoder
- |> decodeApply idDecoder
-
-stateToText state =
- case state of
- LoggedIn _ -> "LoggedIn"
- LoggingIn _ _ -> "LoggingIn"
- LoggedOut -> "LoggedOut"
- LoginFailed -> "LoginFailed"
-
-user_avatar creator = img [class "user_avatar", src creator.img_location] []
-
-type alias UserLoggingIn =
- { username : String
- , password : String}
-
-encodeLoggingIn user =
- Json.object
- [ ("username", Json.string user.username)
- , ("password", Json.string user.password)]
-
-encodeEditorUser : LoginUser -> String -> String-> Json.Value
-encodeEditorUser usr oldpasswd newpasswd =
- Json.object
- [ ("nickname", Json.string usr.nickname)
- , ("username", Json.string usr.username)
- , ("img_location", Json.string usr.img_location)
- , ("id", Json.int usr.id) -- unique and immutable key, needed because UserEditor.editor lets user change all the other values
- , ("old-password", Json.string oldpasswd)
- , ("new-password", Json.string newpasswd)]
-
-
diff --git a/elm-frontti/src/UserEditor.elm b/elm-frontti/src/UserEditor.elm
deleted file mode 100644
index 4237da8..0000000
--- a/elm-frontti/src/UserEditor.elm
+++ /dev/null
@@ -1,68 +0,0 @@
-module UserEditor exposing (..)
-
-import Html exposing (..)
-import Html.Attributes as A exposing (..)
-import Html.Events exposing (..)
-
-import Message exposing (..)
-import PostEditor exposing (hijackOn, dropDecoder)
-import Ajax_cmds exposing (postPicture)
-
-import Json.Decode as D
-
-editor draggingImages oldpasswd newpasswd user =
- div [] [
- div [ class "vertical-flex-container"
- , hijackOn "dragenter" (D.succeed EditorDragEnter)
- , hijackOn "dragend" (D.succeed EditorDragLeave)
- , hijackOn "dragover" (D.succeed EditorDragEnter)
- , hijackOn "dragleave" (D.succeed EditorDragLeave)
- , hijackOn "drop" (dropDecoder (postPicture UploadedOwnProfilePic "/api/pictures/profile"))
- , style "background-color" (if draggingImages then "#880088" else "")
- ]
- [ h1 [ ] [text <| "User " ++ user.nickname ++ "'s settings" ]
- , img [ src user.img_location
- , class "user_avatar" ] []
- , div [ id "img-helper"] [ text "If you want a new profile picture, drag and drop an image file here" ]
- , label [] [ text "Username: "
- , input [ A.required True
- , value user.username
- , onInput SetUsername
- , type_ "text" ] []]
- , label [] [ text "Nickname: "
- , input [ A.required True
- , value user.nickname
- , onInput SetNickname
- , type_ "text"] []]
- , label [] [ text "New password: "
- , input [ type_ "password"
- , onInput SetNewpwd
- , value newpasswd] []]
- , label [] [ text "Current password: "
- , input [ A.required True
- , type_ "password"
- , value oldpasswd
- , onInput SetOldpwd] []]]
- , button [ onClick (SubmitChangedUser oldpasswd newpasswd user) ] [ text "Submit changes!"]]
-
-loginView loginstate =
- let actual_view = [label [for "username"] [text "Username"],
- input [name "username", id "username", attribute "data-testid" "username-input-field", onInput ChangeUsername, onFocus LoginFocus ] [],
- label [for "password"] [text "Password"],
- input [name "password", attribute "data-testid" "password-input-field", id "password", type_ "password", onInput ChangePassword ] []
- -- , label [] [text ("Loginstate: " ++ stateToText loginstate)]
- ] in
- div [] (case loginstate of
- LoggedIn usr ->
- [p [attribute "data-testid" "welcome-user-label"] [ text "Welcome, "
- , a [ href "/blog/usersettings" ]
- [ text usr.nickname]]]
- LoggingIn username password ->
- (List.concat [actual_view,
- [button [attribute "data-testid" "dologin", onClick DoLogIn] [text "Login!"]]])
- LoggedOut ->
- actual_view
- LoginFailed ->
- (List.concat [actual_view,
- [button [onClick DoLogIn] [text "Login!"],
- div [attribute "data-testid" "loginfailed"] [text "Login failed! Check username and password!"]]]))