(text "{% extends \"root.html\" %} {% block head %}")
(text "{% if journal -%}") (title (text "{{ journal.title }}")) (text "{% else %}") (title (text "Journals - {{ config.name }}")) (text "{%- endif %}")
(link ("rel" "stylesheet") ("data-turbo-temporary" "true") ("href" "/css/chats.css?v=tetratto-{{ random_cache_breaker }}"))

(text "{% if view_mode and journal and is_editor -%} {% if note -%}")
; redirect to note
(meta ("http-equiv" "refresh") ("content" "0; url=/@{{ user.username }}/{{ journal.title }}/{{ note.title }}"))
(text "{% else %}")
; redirect to journal homepage
(meta ("http-equiv" "refresh") ("content" "0; url=/@{{ user.username }}/{{ journal.title }}"))
(text "{%- endif %} {%- endif %}")
(text "{% endblock %} {% block body %} {{ macros::nav(selected=\"journals\") }}")
(text "{% if not view_mode -%}")
(nav
    ("class" "chats_nav")
    (button
        ("class" "flex gap-2 items-center active")
        ("onclick" "toggle_sidebars(event)")
        (text "{{ icon \"panel-left\" }} {% if community -%}")
        (b
            ("class" "name shorter")
            (text "{% if community.context.display_name -%} {{ community.context.display_name }} {% else %} {{ community.title }} {%- endif %}"))
        (text "{% else %}")
        (b
            (text "{{ text \"journals:label.my_journals\" }}"))
        (text "{%- endif %}")))
(text "{%- endif %}")
(div
    ("class" "flex")
    ; journals/notes listing
    (text "{% if not view_mode -%}")
    ; this isn't shown if we're in view mode
    (div
        ("class" "sidebar flex flex-col gap-2 justify-between")
        ("id" "notes_list")
        (div
            ("class" "flex flex-col gap-2 w-full")
            (button
                ("class" "lowered justify-start w-full")
                ("onclick" "create_journal()")
                (icon (text "plus"))
                (str (text "journals:action.create_journal")))

            (text "{% for journal in journals %}")
            (text "{{ components::journal_listing(journal=journal, notes=notes, selected_note=selected_note, selected_journal=selected_journal, view_mode=view_mode) }}")
            (text "{% endfor %}")))
    (text "{%- endif %}")
    ; editor
    (div
        ("class" "w-full padded_section")
        ("id" "editor")
        ("style" "padding: var(--pad-4)")
        (main
            ("class" "flex flex-col gap-2")
            ; the journal/note header is always shown
            (text "{% if journal -%}")
            (div
                ("class" "mobile_nav w-full flex items-center justify-between gap-2")
                (div
                    ("class" "flex gap-2 items-center")
                    (a
                        ("class" "flex items-center")
                        ("href" "/api/v1/auth/user/find/{{ journal.owner }}")
                        (text "{{ components::avatar(username=journal.owner, selector_type=\"id\", size=\"18px\") }}"))

                    (a
                        ("class" "flush")
                        ("href" "{% if view_mode -%} /@{{ owner.username }}/{{ journal.title }}/index {%- else -%} /journals/{{ journal.id }}/0 {%- endif %}")
                        (b (text "{{ journal.title }}")))

                    (text "{% if note -%}")
                    (span (text "/"))
                    (b (text "{{ note.title }}"))
                    (text "{%- endif %}"))

                (text "{% if user and user.id == journal.owner -%}")
                (div
                    ("class" "pillmenu")
                    (a
                        ("class" "{% if not view_mode -%}active{%- endif %}")
                        ("href" "/journals/{{ journal.id }}/{% if note -%} {{ note.id }} {%- else -%} 0 {%- endif %}")
                        ("data-turbo" "false")
                        (icon (text "pencil")))
                    (a
                        ("class" "{% if view_mode -%}active{%- endif %}")
                        ("href" "/@{{ user.username }}/{{ journal.title }}/{% if note -%} {{ note.title }} {%- else -%} index {%- endif %}")
                        (icon (text "eye"))))
                (text "{%- endif %}"))
            (text "{%- endif %}")

            ; we're going to put some help panes in here if something is 0
            ; ...people got confused on the chats page because they somehow couldn't figure out how to open the sidebar
            (text "{% if selected_journal == 0 -%}")
            ; no journal selected
            (div
                ("class" "card w-full flex flex-col gap-2")
                (h3 (str (text "journals:label.welcome")))
                (span (str (text "journals:label.select_a_journal")))
                (button
                    ("onclick" "create_journal()")
                    (icon (text "plus"))
                    (str (text "journals:action.create_journal"))))
            (text "{% elif selected_note == 0 -%}")
            ; journal selected, but no note is selected
            (text "{% if not view_mode -%}")
            ; we're the journal owner and we're not in view mode
            (div
                ("class" "card w-full flex flex-col gap-2")
                (h3 (text "{{ journal.title }}"))
                (span (str (text "journals:label.select_a_note")))
                (button
                    ("onclick" "create_note()")
                    (icon (text "plus"))
                    (str (text "journals:action.create_note"))))

            ; we'll also let users edit the journal's settings here i guess
            (details
                ("class" "w-full")
                (summary
                    ("class" "button lowered w-full justify-start")
                    (icon (text "settings"))
                    (str (text "general:action.manage")))

                (div
                    ("class" "card flex flex-col gap-2 lowered")
                    (div
                        ("class" "card-nest")
                        (div
                            ("class" "card small")
                            (b
                                (text "Privacy")))
                        (div
                            ("class" "card")
                            (select
                                ("onchange" "change_journal_privacy(event)")
                                (option
                                    ("value" "Private")
                                    ("selected" "{% if journal.privacy == 'Private' -%}true{% else %}false{%- endif %}")
                                    (text "Private"))
                                (option
                                    ("value" "Public")
                                    ("selected" "{% if journal.privacy == 'Public' -%}true{% else %}false{%- endif %}")
                                    (text "Public")))))

                    (div
                        ("class" "card-nest")
                        (div
                            ("class" "card small")
                            (label
                                ("for" "title")
                                (b (str (text "communities:label.title")))))

                        (form
                            ("class" "card flex flex-col gap-2")
                            ("onsubmit" "change_journal_title(event)")
                            (div
                                ("class" "flex flex-col gap-1")
                                (input
                                    ("type" "text")
                                    ("name" "title")
                                    ("id" "title")
                                    ("placeholder" "title")
                                    ("required" "")
                                    ("minlength" "2")))
                            (button
                                ("class" "primary")
                                (text "{{ icon \"check\" }}")
                                (span
                                    (text "{{ text \"general:action.save\" }}")))))))
            (text "{% else %}")
            ; we're in view mode; just show journal listing and notes as journal homepage
            (div
                ("class" "card flex flex-col gap-2")
                (text "{{ components::journal_listing(journal=journal, notes=notes, selected_note=selected_note, selected_journal=selected_journal, view_mode=view_mode, owner=owner) }}"))
            (text "{%- endif %}")
            (text "{% else %}")
            ; journal AND note selected
            (text "{% if not view_mode -%}")
            ; not view mode; show editor
            ; import codemirror
            (script ("src" "https://unpkg.com/codemirror@5.39.2/lib/codemirror.js") ("data-turbo-temporary" "true"))
            (script ("src" "https://unpkg.com/codemirror@5.39.2/addon/display/placeholder.js") ("data-turbo-temporary" "true"))
            (script ("src" "https://unpkg.com/codemirror@5.39.2/mode/markdown/markdown.js") ("data-turbo-temporary" "true"))
            (link ("rel" "stylesheet") ("href" "https://unpkg.com/codemirror@5.39.2/lib/codemirror.css") ("data-turbo-temporary" "true"))

            ; tab bar
            (div
                ("class" "pillmenu")
                (a
                    ("href" "#/editor")
                    ("data-tab-button" "editor")
                    ("data-turbo" "false")
                    ("class" "active")
                    (str (text "journals:label.editor")))

                (a
                    ("href" "#/preview")
                    ("data-tab-button" "preview")
                    ("data-turbo" "false")
                    (str (text "journals:label.preview_pane"))))

            ; tabs
            (div
                ("data-tab" "editor")
                ("class" "flex flex-col gap-2 card")
                ("style" "animation: fadein ease-in-out 1 0.5s forwards running")
                ("id" "editor_tab"))

            (div
                ("data-tab" "preview")
                ("class" "flex flex-col gap-2 card hidden")
                ("style" "animation: fadein ease-in-out 1 0.5s forwards running")
                ("id" "preview_tab"))

            (button
                ("onclick" "change_note_content('{{ note.id }}')")
                (icon (text "check"))
                (str (text "general:action.save")))

            ; init codemirror
            (script ("id" "editor_content") ("type" "text/markdown") (text "{{ note.content|remove_script_tags|safe }}"))
            (script
                (text "setTimeout(() => {
                    globalThis.editor = CodeMirror(document.getElementById(\"editor_tab\"), {
                        value: document.getElementById(\"editor_content\").innerHTML,
                        mode: \"markdown\",
                        lineWrapping: true,
                        autoCloseBrackets: true,
                        autofocus: true,
                        viewportMargin: Number.POSITIVE_INFINITY,
                        inputStyle: \"contenteditable\",
                        highlightFormatting: false,
                        fencedCodeBlockHighlighting: false,
                        xml: false,
                        smartIndent: false,
                        placeholder: `# {{ note.title }}`,
                        extraKeys: {
                            Home: \"goLineLeft\",
                            End: \"goLineRight\",
                            Enter: (cm) => {
                                cm.replaceSelection(\"\\n\");
                            },
                        },
                    });

                    document.querySelector(\"[data-tab-button=editor]\").addEventListener(\"click\", async (e) => {
                        e.preventDefault();
                        trigger(\"atto::hooks::tabs:switch\", [\"editor\"]);
                    });

                    document.querySelector(\"[data-tab-button=preview]\").addEventListener(\"click\", async (e) => {
                        e.preventDefault();
                        const res = await (
                            await fetch(\"/api/v1/notes/preview\", {
                                method: \"POST\",
                                headers: {
                                    \"Content-Type\": \"application/json\",
                                },
                                body: JSON.stringify({
                                    content: globalThis.editor.getValue(),
                                }),
                            })
                        ).text();

                        document.getElementById(\"preview_tab\").innerHTML = res;
                        trigger(\"atto::hooks::tabs:switch\", [\"preview\"]);
                    });
                }, 150);"))
            (text "{% else %}")
            ; we're just viewing this note
            (div
                ("class" "flex flex-col gap-2 card")
                (text "{{ note.content|markdown|safe }}"))

            (div
                ("class" "flex w-full justify-between gap-2")
                (span (text "Last updated: ") (span ("class" "date") (text "{{ note.edited }}")))
                (text "{% if user and user.id == owner.id -%}")
                (button
                    ("class" "small")
                    ("onclick" "{% if journal.privacy == \"Public\" -%}
                        trigger('atto::copy_text', ['{{ config.host }}/@{{ owner.username }}/{{ journal.title }}/{{ note.title }}'])
                    {%- else -%}
                        prompt_make_public();
                        trigger('atto::copy_text', ['{{ config.host }}/@{{ owner.username }}/{{ journal.title }}/{{ note.title }}'])
                    {%- endif %}")
                    (icon (text "share"))
                    (str (text "general:label.share")))

                (script
                    (text "globalThis.prompt_make_public = async () => {
                        if (
                            !(await trigger(\"atto::confirm\", [
                                \"Would you like to make this journal public? This is required for others to view this note.\",
                            ]))
                        ) {
                            return;
                        }

                        change_journal_privacy({ target: { selectedOptions: [{ value: \"Public\" }] }, preventDefault: () => {} });
                    }"))
                (text "{%- endif %}"))
            (text "{%- endif %}")
            (text "{%- endif %}")))
    (style
        (text "nav::after {
            width: 100%;
            left: 0;
        }"))
    (script
        (text "window.JOURNAL_PROPS = {
            selected_journal: \"{{ selected_journal }}\",
            selected_note: \"{{ selected_note }}\",
        };

        // journals/notes
        globalThis.create_journal = async () => {
            const title = await trigger(\"atto::prompt\", [\"Journal title:\"]);

            if (!title) {
                return;
            }

            fetch(\"/api/v1/journals\", {
                method: \"POST\",
                headers: {
                    \"Content-Type\": \"application/json\",
                },
                body: JSON.stringify({
                    title,
                }),
            })
                .then((res) => res.json())
                .then((res) => {
                    trigger(\"atto::toast\", [
                        res.ok ? \"success\" : \"error\",
                        res.message,
                    ]);

                    if (res.ok) {
                        setTimeout(() => {
                            window.location.href = `/journals/${res.payload}/0`;
                        }, 100);
                    }
                });
        }

        globalThis.create_note = async () => {
            const title = await trigger(\"atto::prompt\", [\"Note title:\"]);

            if (!title) {
                return;
            }

            fetch(\"/api/v1/notes\", {
                method: \"POST\",
                headers: {
                    \"Content-Type\": \"application/json\",
                },
                body: JSON.stringify({
                    title,
                    content: `# ${title}`,
                    journal: \"{{ selected_journal }}\",
                }),
            })
                .then((res) => res.json())
                .then((res) => {
                    trigger(\"atto::toast\", [
                        res.ok ? \"success\" : \"error\",
                        res.message,
                    ]);

                    if (res.ok) {
                        setTimeout(() => {
                            window.location.href = `/journals/{{ selected_journal }}/${res.payload}`;
                        }, 100);
                    }
                });
        }

        globalThis.delete_journal = async (id) => {
            if (
                !(await trigger(\"atto::confirm\", [
                    \"Are you sure you would like to do this?\",
                ]))
            ) {
                return;
            }

            fetch(`/api/v1/journals/${id}`, {
                method: \"DELETE\",
            })
                .then((res) => res.json())
                .then((res) => {
                    trigger(\"atto::toast\", [
                        res.ok ? \"success\" : \"error\",
                        res.message,
                    ]);

                    if (res.ok) {
                        setTimeout(() => {
                            window.location.href = \"/journals\";
                        }, 100);
                    }
                });
        }

        globalThis.delete_note = async (id) => {
            if (
                !(await trigger(\"atto::confirm\", [
                    \"Are you sure you would like to do this?\",
                ]))
            ) {
                return;
            }

            fetch(`/api/v1/notes/${id}`, {
                method: \"DELETE\",
            })
                .then((res) => res.json())
                .then((res) => {
                    trigger(\"atto::toast\", [
                        res.ok ? \"success\" : \"error\",
                        res.message,
                    ]);

                    if (res.ok) {
                        setTimeout(() => {
                            window.location.href = \"/journals/{{ selected_journal }}/0\";
                        }, 100);
                    }
                });
        }

        globalThis.change_journal_title = async (e) => {
            e.preventDefault();
            fetch(\"/api/v1/journals/{{ selected_journal }}/title\", {
                method: \"POST\",
                headers: {
                    \"Content-Type\": \"application/json\",
                },
                body: JSON.stringify({
                    title: e.target.title.value,
                }),
            })
                .then((res) => res.json())
                .then((res) => {
                    trigger(\"atto::toast\", [
                        res.ok ? \"success\" : \"error\",
                        res.message,
                    ]);

                    if (res.ok) {
                        e.reset();
                    }
                });
        }

        globalThis.change_journal_privacy = async (e) => {
            e.preventDefault();
            const selected = e.target.selectedOptions[0];
            fetch(\"/api/v1/journals/{% if journal -%} {{ journal.id }} {%- else -%} {{ selected_journal }} {%- endif %}/privacy\", {
                method: \"POST\",
                headers: {
                    \"Content-Type\": \"application/json\",
                },
                body: JSON.stringify({
                    privacy: selected.value,
                }),
            })
                .then((res) => res.json())
                .then((res) => {
                    trigger(\"atto::toast\", [
                        res.ok ? \"success\" : \"error\",
                        res.message,
                    ]);
                });
        }

        globalThis.change_note_title = async (id) => {
            const title = await trigger(\"atto::prompt\", [\"New note title:\"]);

            if (!title) {
                return;
            }

            fetch(`/api/v1/notes/${id}/title`, {
                method: \"POST\",
                headers: {
                    \"Content-Type\": \"application/json\",
                },
                body: JSON.stringify({
                    title,
                }),
            })
                .then((res) => res.json())
                .then((res) => {
                    trigger(\"atto::toast\", [
                        res.ok ? \"success\" : \"error\",
                        res.message,
                    ]);

                    if (res.ok) {
                        e.reset();
                    }
                });
        }

        globalThis.change_note_content = async (id) => {
            fetch(`/api/v1/notes/${id}/content`, {
                method: \"POST\",
                headers: {
                    \"Content-Type\": \"application/json\",
                },
                body: JSON.stringify({
                    content: globalThis.editor.getValue(),
                }),
            })
                .then((res) => res.json())
                .then((res) => {
                    trigger(\"atto::toast\", [
                        res.ok ? \"success\" : \"error\",
                        res.message,
                    ]);
                });
        }

        // sidebars
        window.SIDEBARS_OPEN = false;
        if (new URLSearchParams(window.location.search).get(\"nav\") === \"true\") {
            window.SIDEBARS_OPEN = true;
        }

        if (
            window.SIDEBARS_OPEN &&
            !document.body.classList.contains(\"sidebars_shown\")
        ) {
            toggle_sidebars();
            window.SIDEBARS_OPEN = true;
        }

        for (const anchor of document.querySelectorAll(\"[data-turbo=false]\")) {
            anchor.href += `?nav=${window.SIDEBARS_OPEN}`;
        }

        function toggle_sidebars() {
            window.SIDEBARS_OPEN = !window.SIDEBARS_OPEN;

            for (const anchor of document.querySelectorAll(
                \"[data-turbo=false]\",
            )) {
                anchor.href = anchor.href.replace(
                    `?nav=${!window.SIDEBARS_OPEN}`,
                    `?nav=${window.SIDEBARS_OPEN}`,
                );
            }

            const notes_list = document.getElementById(\"notes_list\");

            if (document.body.classList.contains(\"sidebars_shown\")) {
                // hide
                document.body.classList.remove(\"sidebars_shown\");
                notes_list.style.left = \"-200%\";
            } else {
                // show
                document.body.classList.add(\"sidebars_shown\");
                notes_list.style.left = \"0\";
            }
        }")))
(text "{% endblock %}")