diff of 442d9b810f5406c431b9f55a356e6c857bfa7284
442d9b810f5406c431b9f55a356e6c857bfa7284
diff --git a/elm-frontti/src/Ajax_cmds.elm b/elm-frontti/src/Ajax_cmds.elm
index 75d976b..016e786 100644
--- a/elm-frontti/src/Ajax_cmds.elm
+++ b/elm-frontti/src/Ajax_cmds.elm
@@ -112,3 +112,14 @@ loadPostVersion post_id_int version_id_int =
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
+ }
diff --git a/elm-frontti/src/Article.elm b/elm-frontti/src/Article.elm
index 565c4b4..86b6c12 100644
--- a/elm-frontti/src/Article.elm
+++ b/elm-frontti/src/Article.elm
@@ -46,6 +46,8 @@ type alias Article =
, versions: Maybe (List Int)
, version : Maybe Int
, created_at: Maybe Time.Posix
+ , hidden : Bool
+ , unlisted : Bool
}
-- encoder
@@ -62,6 +64,8 @@ encode article =
, ( "id", (maybe int) article.id)
, ( "version", (maybe int) article.version)
, ( "created_at", (maybe iso8601) article.created_at)
+ , ( "hidden", bool article.hidden)
+ , ( "unlisted", bool article.unlisted)
]
@@ -77,7 +81,9 @@ idDecoder = Decode.maybe ( 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
+creator_Decoder = Decode.field "creator" creatorDecoder
+hiddenDecoder = Decode.field "hidden" Decode.bool
+unlistedDecoder = Decode.field "unlisted" Decode.bool
-- |> == clojure's ->>
articleDecoder : Decoder Article
@@ -92,6 +98,8 @@ articleDecoder =
|> decodeApply versionsDecoder
|> decodeApply versionDecoder
|> decodeApply created_atDecoder
+ |> decodeApply hiddenDecoder
+ |> decodeApply unlistedDecoder
type alias Title =
{ title : String
diff --git a/elm-frontti/src/Main.elm b/elm-frontti/src/Main.elm
index 4dc3561..8b647ce 100644
--- a/elm-frontti/src/Main.elm
+++ b/elm-frontti/src/Main.elm
@@ -62,8 +62,7 @@ main =
subscriptions : Model -> Sub Msg
subscriptions _ = Sub.batch
[ tags ReceivedTag
- , aceStateUpdate AceStateUpdate
- , fromLocalStorage PostFromLocalStorage]
+ , aceStateUpdate AceStateUpdate]
initialModel url key viewstate = Model viewstate Nothing False False [] Nothing LoggedOut key url Nothing Time.utc Nothing
@@ -100,11 +99,6 @@ viewStatePerUrl url =
, getSettings
, getTitles
, loadTaggedPosts tags_])
- RouteParser.NewPost ->
- (PostEditor, [ getSettings
- , getTitles
- , getSession
- , loadPostFromLocalStorage ()])
RouteParser.PostVersion post_id version_id -> (Loading, [ getSession
, getSettings
@@ -130,9 +124,10 @@ port alert : String -> Cmd msg
port tags : (String -> msg) -> Sub msg
port aceStateUpdate : (String -> msg) -> Sub msg
-port savePostToLocalStorage: String -> Cmd msg
-port loadPostFromLocalStorage: () -> Cmd msg
-port fromLocalStorage: (String -> msg) -> Sub msg
+toggleHidden article =
+ { article | hidden = not article.hidden}
+toggleUnlisted article =
+ { article | unlisted = not article.unlisted}
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
@@ -203,11 +198,7 @@ update msg model =
Ok user ->
if model.view_state == PostEditor then
({ model | loginState = LoggedIn user
- , postEditorSettings = Just (PostEditorSettings
- (Maybe.withDefault
- (Article.Article (C.Creator user.username user.nickname user.img_location) [""] "" Nothing "New post" Nothing (Just []) Nothing Nothing)
- model.postFromLocalStorage)
- "" False)}
+ , postEditorSettings = Nothing}
, Cmd.none)
else
({model | loginState = LoggedIn user}, Cmd.none)
@@ -264,7 +255,7 @@ update msg model =
article = { old_article | tags = tag :: settings.article.tags} in
({ model | postEditorSettings = Just
{ settings | article = article}}
- , savePostToLocalStorage (Json.Encode.encode 0 (Article.encode article)))
+ , Cmd.none)
Nothing -> (model, alert "ReceivedTag called even though postEditorSettings is nil")
DropTag tag ->
case model.postEditorSettings of
@@ -273,7 +264,7 @@ update msg model =
article = { old_article | tags = List.filter ((/=) settings.selected_tag) old_article.tags} in
({ model | postEditorSettings = Just
{ settings | article = article}}
- , savePostToLocalStorage (Json.Encode.encode 0 (Article.encode article)))
+ , Cmd.none)
Nothing -> (model, alert "DropTag called even though postEditorSettings is nil")
HttpIgnoreResponse result ->
(model, Cmd.none)
@@ -294,7 +285,7 @@ update msg model =
({ model | postEditorSettings = Just
{ settings | article =
{ article | content = content}}}
- , savePostToLocalStorage (Json.Encode.encode 0 (Article.encode article)))
+ , Cmd.none)
Nothing -> (model, alert "AceStateUpdate called even though postEditorSettings is nil")
ChangeTitle new_title ->
@@ -304,7 +295,7 @@ update msg model =
({ model | postEditorSettings = Just
{ settings | article =
{ article | title = new_title}}}
- , savePostToLocalStorage (Json.Encode.encode 0 (Article.encode article)))
+ , Cmd.none)
Nothing -> (model, alert "ChangeTitle called even though postEditorSettings is nil")
HttpManagerGetListOfImages _ -> (model, getListOfImages True)
GetListOfImages -> ( { model | showImageModal = True }
@@ -416,27 +407,29 @@ update msg model =
, Cmd.none)
Err err ->
(model , alert ("Error loading post version " ++ Debug.toString err))
- PostFromLocalStorage post_json ->
- case (Decode.decodeString Article.articleDecoder post_json) of
- Ok saved_article ->
- ({ model | postFromLocalStorage = Just saved_article}
- , Cmd.none)
- Err err ->
+ GenNewPost ->
+ ( model
+ , generateNewPost)
+ NewPostGenerated new_post_id ->
+ case new_post_id of
+ Ok id ->
( model
- , alert ("json decoding failed" ++ Debug.toString err))
- ClearLocalStorage ->
- case model.loginState of
- LoggedIn user ->
- ({ model | postEditorSettings = Just (PostEditorSettings
- (Maybe.withDefault
- (Article.Article (C.Creator user.username user.nickname user.img_location) [""] "" Nothing "New post" Nothing (Just []) Nothing Nothing)
- model.postFromLocalStorage)
- "" False)}
- , clearPostFromLS ())
- _ -> (model, Cmd.none)
-
-
-
+ , 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)
doGoHome_ model other_cmds =
(model, Cmd.batch (List.append [ getSettings
diff --git a/elm-frontti/src/Message.elm b/elm-frontti/src/Message.elm
index 1dfee98..81a2c0b 100644
--- a/elm-frontti/src/Message.elm
+++ b/elm-frontti/src/Message.elm
@@ -119,8 +119,10 @@ type Msg
| GotTaggedPosts (Result Http.Error (List Article.Article))
| ToggleArticlePreview
| GotOldPost (Result Http.Error Article.Article)
- | PostFromLocalStorage String
- | ClearLocalStorage
+ | GenNewPost
+ | NewPostGenerated (Result Http.Error Int)
+ | ToggleArticleUnlisted
+ | ToggleArticleHidden
diff --git a/elm-frontti/src/PostEditor.elm b/elm-frontti/src/PostEditor.elm
index 2364142..af3f1d3 100644
--- a/elm-frontti/src/PostEditor.elm
+++ b/elm-frontti/src/PostEditor.elm
@@ -36,7 +36,7 @@ hijack msg =
optionize tag = option [value tag] [text tag]
-tagView post selectedTag = div [class "tagview"]
+tagView post selectedTag = div [class "tagview editor-grouper"]
[ select [ multiple True
, class "tag-select"
, id "tag-select"
@@ -48,12 +48,6 @@ tagView post selectedTag = div [class "tagview"]
, murja_button [ onClick (DropTag selectedTag)
, attribute "data-testid" "remove-tag"]
[text "Remove selected tag"]]
-
-third_column = div [class "tagview" ]
- [ murja_button [ onClick ClearLocalStorage
- , attribute "data-testid" "clear-editor" ]
- [ text "Clear post in the editor" ] ]
-
editor params =
node "ace-editor"
( params
@@ -66,35 +60,46 @@ filesDecoder =
D.at ["target","files"] (D.list File.decoder)
postEditor post tag showImageModal loadedImages draggingImages editorSettings app_settings tz loginState
- = [ div [ id "editor-buttons"]
- [ 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"]
- , label [for "show-preview-cb"]
- [text "Show article preview"]
- , input [ type_ "checkbox"
- , id "show-preview-cb"
- , checked editorSettings.show_preview
- , onClick ToggleArticlePreview] []]
-
- , tagView post tag
- , third_column
+ = [ 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
+ , 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] []
+ , label [for "show-preview-cb"]
+ [text "Show article preview"]
+ , input [ type_ "checkbox"
+ , id "show-preview-cb"
+ , checked editorSettings.show_preview
+ , onClick ToggleArticlePreview] []]]
, if showImageModal then imageSelector loadedImages else div [] []
- , div [ attribute "data-testid" "article-id" ] [ text ("Article: " ++ (Maybe.withDefault "No id" (Maybe.map String.fromInt post.id)))]
-
, if editorSettings.show_preview then
case loginState of
LoggedIn user ->
diff --git a/elm-frontti/src/RouteParser.elm b/elm-frontti/src/RouteParser.elm
index f60d76e..0a0dbb4 100644
--- a/elm-frontti/src/RouteParser.elm
+++ b/elm-frontti/src/RouteParser.elm
@@ -7,7 +7,6 @@ import String exposing (fromInt)
type Route
= Page Int
| Post Int
- | NewPost
| PostAdmin
| MediaManager
| PostEditor Int
@@ -25,7 +24,6 @@ routeParser =
, map Post (s "blog" </> (s "post" </> int))
, map PostEditor (s "blog" </> (s "post" </> (s "edit" </> int)))
, map MediaManager (s "blog" </> (s "mediamanager"))
- , map NewPost (s "blog" </> (s "new_post"))
, map TaggedPosts (s "blog" </> (s "tags" </> string))
, map PostAdmin (s "blog" </> (s "postadmin"))]
diff --git a/elm-frontti/src/Topbar.elm b/elm-frontti/src/Topbar.elm
index fc70da6..af39075 100644
--- a/elm-frontti/src/Topbar.elm
+++ b/elm-frontti/src/Topbar.elm
@@ -18,8 +18,13 @@ topbar state =
LoggedIn user ->
div [class "left-sidebar"] [ span [] [text ("Welcome, " ++ user.nickname)]
, User.user_avatar user
- , ul [] [ li [] [ murja_button [ onClick GoHome, attribute "data-testid" "home"] [text "Home"]]
- , li [] [ murja_button [ onClick (PushUrl "/blog/postadmin"), attribute "data-testid" "manage-posts-btn" ] [text "Manage posts"]]
- , li [] [ murja_button [ onClick (PushUrl "/blog/mediamanager")] [text "Manage media"]]
- , li [] [ murja_button [ onClick (PushUrl "/blog/new_post"), attribute "data-testid" "new-post-btn" ] [text "New post!"]]]]
+ , ul [] [ li [] [ murja_button [ onClick GoHome, attribute "data-testid" "home"]
+ [text "Home"]]
+ , li [] [ murja_button [ onClick (PushUrl "/blog/postadmin"), attribute "data-testid" "manage-posts-btn" ]
+ [text "Manage posts"]]
+ , li [] [ murja_button [ onClick (PushUrl "/blog/mediamanager")]
+ [text "Manage media"]]
+ , li [] [ murja_button [ onClick GenNewPost
+ , attribute "data-testid" "new-post-btn" ]
+ [text "New post!"]]]]
_ -> div [] []
diff --git a/playwright-tests/tests/basic-tests.spec.ts b/playwright-tests/tests/basic-tests.spec.ts
index 9a01b8f..3401a17 100644
--- a/playwright-tests/tests/basic-tests.spec.ts
+++ b/playwright-tests/tests/basic-tests.spec.ts
@@ -18,10 +18,8 @@ const password = 'p4ssw0rd';
async function postPost(page, title, post, tag, append_img = false) {
await page.getByTestId('new-post-btn').click();
- await page.getByTestId('clear-editor').click();
console.log(`Posting post with title ${title}, tag ${tag}`);
- await expect(page.getByTestId('article-id')).toContainText('Article: No id');
await page.locator('#editor-post-title').fill(title);
@@ -70,6 +68,9 @@ async function postPost(page, title, post, tag, append_img = false) {
await expect(page.locator('#editor-post-content')).toContainText('<img');
}
+
+ await page.locator("#hidden").setChecked(false);
+
// save the post
await page.locator('#editor-post-save').click();
@@ -119,13 +120,14 @@ test('basic testing', async ({ page, browser }) => {
await expect(page.locator('.post')).toBeVisible();
await expect(page.locator('.post')).toContainText(post);
await expect(page.locator('.tag')).toHaveText(tag);
- /*
+
// edit the post
for(let x = 0; x < 10; x++) {
- console.log('x: ' + x);
- await page.getByTestId('edit-post-btn').click();
-
- await expect(page.getByTestId('article-id')).not.toContainText('Article: No id');
+ const hidden = x % 2 == 0;
+ await page.goto('http://localhost:3010/blog/postadmin');
+ await expect(page.getByTestId('manager-edit-post-btn')).toBeVisible();
+
+ await page.getByTestId('manager-edit-post-btn').click();
await expect(page.locator('#editor-post-content')).toBeVisible();
@@ -135,24 +137,27 @@ test('basic testing', async ({ page, browser }) => {
console.log('success');
});
+ await page.locator("#hidden").setChecked(hidden);
+
await page.locator('#editor-post-save').click();
await page.goto('http://localhost:3010');
- await expect(page.locator('.post')).toContainText("edited article");
- await expect(page.locator('.post')).not.toContainText(post);
+ if (hidden) {
+ await expect(page.locator('.post')).toBeHidden()
+ } else {
+ await expect(page.locator('.post')).toContainText("edited article");
+ await expect(page.locator('.post')).not.toContainText(post);
+ }
}
- await expect(page.locator('.meta')).toContainText('1, 2, 3, 4, 5, 6, 7, 8, 9, 10');*/
+ await expect(page.locator('.meta')).toContainText('2, 4, 6, 8, 10');
// hide the post
await page.getByTestId('edit-post-btn').click();
await expect(page.locator('#editor-post-content')).toBeVisible();
-
- tag = 'hidden';
- await page.locator('#new-tag-btn').click();
- await page.locator('#tag-select').selectOption('hidden');
+ await page.locator("#hidden").setChecked(false);
await page.locator('#editor-post-save').click();
await page.goto('http://localhost:3010');
@@ -163,9 +168,7 @@ test('basic testing', async ({ page, browser }) => {
await expect(page.getByTestId('manager-edit-post-btn')).toBeVisible();
await page.getByTestId('manager-edit-post-btn').click();
- await page.locator('#tag-select').selectOption('hidden');
-
- await page.getByTestId('remove-tag').click();
+ await page.locator("#hidden").setChecked(false);
await page.locator('#editor-post-title').fill('Latest test post');
await page.locator('#editor-post-save').click();
@@ -184,12 +187,12 @@ test('basic testing', async ({ page, browser }) => {
const new_ctx = await browser.newContext();
// Create a new page inside context.
- /* const anon_page = await new_ctx.newPage();
+ const anon_page = await new_ctx.newPage();
await anon_page.goto('http://localhost:3010');
- await expect(anon_page.locator('.meta')).toContainText('1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13');
-
- await anon_page.close(); */
+ await expect(anon_page.locator('.meta')).toContainText('2, 4, 6, 8, 10, 12, 13, 14');
+
+ await anon_page.close();
// make sure editor saves
await page.getByText('Edit this post').click();
@@ -213,7 +216,7 @@ test('basic testing', async ({ page, browser }) => {
// make sure the basic post view opens
await page.getByRole('link', { name: 'really badly edited test post' }).click();
// await expect(page.getByText('LOADING')).toBeHidden();
- await expect(page.getByText('jeejee')).toBeVisible();
+ await expect(page.getByText('jeejee')).toBeVisible();
await expect(page.getByText('random content')).toBeHidden();
// test images
diff --git a/resources/css/murja.css b/resources/css/murja.css
index ea04e21..6e5bac7 100644
--- a/resources/css/murja.css
+++ b/resources/css/murja.css
@@ -6,6 +6,17 @@ html, body {
flex: 1 1;
}
+.editor-grouper {
+
+}
+
+.editor-top {
+ flex: auto;
+ flex-direction: row;
+ display: flex;
+ justify-content: space-around;
+}
+
.tagview {
display: table;
}
diff --git a/resources/js/murja-helper.js b/resources/js/murja-helper.js
index 5b9660d..902cc54 100644
--- a/resources/js/murja-helper.js
+++ b/resources/js/murja-helper.js
@@ -33,7 +33,7 @@ app.ports.addImgToAce.subscribe(img_id => {
editor.insert('<img src="/api/pictures/' + img_id +'" />');
} else alert("Didn't find ace editor");
-})
+});
Object.defineProperty(HTMLElement.prototype, "dangerouslySetInnerHTML", {
get () {
@@ -42,21 +42,4 @@ Object.defineProperty(HTMLElement.prototype, "dangerouslySetInnerHTML", {
set (value) {
this.innerHTML = value
}
-})
-
-app.ports.savePostToLocalStorage.subscribe( v => {
- localStorage.setItem("post", v)
-});
-
-app.ports.loadPostFromLocalStorage.subscribe( () => {
- const post = localStorage.getItem("post");
- if (post)
- app.ports.fromLocalStorage.send(post);
-});
-
-app.ports.clearPostFromLS.subscribe( () => {
- if (window.confirm("Are you sure to clear the editor?")) {
- localStorage.removeItem("post");
- location.reload();
- }
});