diff --git a/crates/app/src/public/css/utility.css b/crates/app/src/public/css/utility.css
index 4b0460f..f5f834f 100644
--- a/crates/app/src/public/css/utility.css
+++ b/crates/app/src/public/css/utility.css
@@ -35,7 +35,7 @@
justify-content: right;
}
-.justify-start {
+.justify_start {
justify-content: flex-start !important;
}
diff --git a/crates/app/src/public/html/body.lisp b/crates/app/src/public/html/body.lisp
index 89b6d53..705b14c 100644
--- a/crates/app/src/public/html/body.lisp
+++ b/crates/app/src/public/html/body.lisp
@@ -169,21 +169,20 @@
("id" "littleweb")
(div
("class" "inner flex flex_col gap_2")
-
(a
- ("class" "button w_full lowered justify-start")
+ ("class" "button w_full lowered justify_start")
("href" "/net")
(icon (text "globe"))
(str (text "littleweb:label.browser")))
(a
- ("class" "button w_full lowered justify-start")
+ ("class" "button w_full lowered justify_start")
("href" "/services")
(icon (text "panel-top"))
(str (text "littleweb:label.my_services")))
(a
- ("class" "button w_full lowered justify-start")
+ ("class" "button w_full lowered justify_start")
("href" "/domains")
(icon (text "panel-top"))
(str (text "littleweb:label.my_domains")))
diff --git a/crates/app/src/public/html/chats/app.lisp b/crates/app/src/public/html/chats/app.lisp
index 8d0b3d4..e64dc0b 100644
--- a/crates/app/src/public/html/chats/app.lisp
+++ b/crates/app/src/public/html/chats/app.lisp
@@ -73,7 +73,7 @@
(text "{%- endif %}"))
(text "{% if can_manage_channels -%}")
(a
- ("class" "button w_full justify-start lowered")
+ ("class" "button w_full justify_start lowered")
("href" "/community/{{ selected_community }}/manage#/channels")
(text "{{ icon \"plus\" }}")
(span
diff --git a/crates/app/src/public/html/chats/channels.lisp b/crates/app/src/public/html/chats/channels.lisp
index 2e12b18..fb61be0 100644
--- a/crates/app/src/public/html/chats/channels.lisp
+++ b/crates/app/src/public/html/chats/channels.lisp
@@ -7,7 +7,7 @@
(div
("class" "flex flex_row gap_1")
(a
- ("class" "w_full justify-start button {% if selected_channel == channel.id -%}lowered{% else %}camo{%- endif %}")
+ ("class" "w_full justify_start button {% if selected_channel == channel.id -%}lowered{% else %}camo{%- endif %}")
("href" "/chats/{{ selected_community }}/{{ channel.id }}")
("data-turbo" "{{ selected_community == '0' }}")
(text "{{ icon \"rss\" }}")
diff --git a/crates/app/src/public/html/components.lisp b/crates/app/src/public/html/components.lisp
index 3753516..f88a872 100644
--- a/crates/app/src/public/html/components.lisp
+++ b/crates/app/src/public/html/components.lisp
@@ -1863,14 +1863,14 @@
; option a
(button
- ("class" "hover_left_bar raised justify-start w_full poll_option")
+ ("class" "hover_left_bar raised justify_start w_full poll_option")
("onclick" "trigger('me::vote', ['{{ post.id }}', 'A'])")
(icon (text "tally-1"))
(text "{{ poll[0].option_a }}"))
; option b
(button
- ("class" "hover_left_bar raised justify-start w_full poll_option")
+ ("class" "hover_left_bar raised justify_start w_full poll_option")
("onclick" "trigger('me::vote', ['{{ post.id }}', 'B'])")
(icon (text "tally-2"))
(text "{{ poll[0].option_b }}"))
@@ -1878,7 +1878,7 @@
; option c
(text "{% if poll[0].option_c -%}")
(button
- ("class" "hover_left_bar raised justify-start w_full poll_option")
+ ("class" "hover_left_bar raised justify_start w_full poll_option")
("onclick" "trigger('me::vote', ['{{ post.id }}', 'C'])")
(icon (text "tally-3"))
(text "{{ poll[0].option_c }}"))
@@ -1887,7 +1887,7 @@
; option d
(text "{% if poll[0].option_d -%}")
(button
- ("class" "hover_left_bar raised justify-start w_full poll_option")
+ ("class" "hover_left_bar raised justify_start w_full poll_option")
("onclick" "trigger('me::vote', ['{{ post.id }}', 'D'])")
(icon (text "tally-4"))
(text "{{ poll[0].option_d }}"))
@@ -2181,7 +2181,7 @@
("class" "flex flex_row gap_1")
(a
("href" "/journals/{{ journal.id }}/0?view={{ view_mode }}")
- ("class" "button justify-start lowered w_full")
+ ("class" "button justify_start lowered w_full")
(icon (text "notebook"))
(text "{{ journal.title }}"))
@@ -2207,7 +2207,7 @@
(div
("class" "flex flex_row gap_1")
(button
- ("class" "justify-start lowered w_full")
+ ("class" "justify_start lowered w_full")
(icon (text "arrow-down"))
(text "{{ journal.title }}"))
@@ -2257,7 +2257,7 @@
; create note
(text "{% if user and user.id == journal.owner -%}")
(button
- ("class" "lowered justify-start w_full")
+ ("class" "lowered justify_start w_full")
("onclick" "create_note()")
(icon (text "plus"))
(str (text "journals:action.create_note")))
@@ -2271,7 +2271,7 @@
(text "{% macro notes_list_dir_listing(dir, dirs, notes, owner, journal, view_mode=false) -%}")
(details
(summary
- ("class" "button w_full justify-start raised w_full")
+ ("class" "button w_full justify_start raised w_full")
(icon (text "folder"))
(text "{{ dir[2] }}"))
@@ -2299,7 +2299,7 @@
("ui_ident" "{% if selected_note == note.id -%} active_note {%- else -%} inactive_note {%- endif %}")
(a
("href" "{% if owner -%} /@{{ owner.username }}/{{ journal.title }}/{{ note.title }} {%- else -%} /journals/{{ journal.id }}/{{ note.id }} {%- endif %}")
- ("class" "button justify-start w_full {% if selected_note == note.id -%} lowered {%- else -%} raised {%- endif %}")
+ ("class" "button justify_start w_full {% if selected_note == note.id -%} lowered {%- else -%} raised {%- endif %}")
(icon (text "file-text"))
(text "{{ note.title }}"))
@@ -2380,7 +2380,7 @@
(div
("class" "flex flex_row gap_1")
(button
- ("class" "justify-start lowered w_full")
+ ("class" "justify_start lowered w_full")
(icon (text "folder-open"))
(text "{{ dir[2] }}"))
@@ -2423,7 +2423,7 @@
(text "{% macro note_mover_dirs_listing(dir, dirs) -%}")
(button
("onclick" "move_note_dir(window.NOTE_MOVER_NOTE_ID, '{{ dir[0] }}'); document.getElementById('note_mover_dialog').close()")
- ("class" "justify-start lowered w_full")
+ ("class" "justify_start lowered w_full")
(icon (text "folder-open"))
(text "{{ dir[2] }}"))
diff --git a/crates/app/src/public/html/economy/wallet.lisp b/crates/app/src/public/html/economy/wallet.lisp
index ddeb428..0fb5b92 100644
--- a/crates/app/src/public/html/economy/wallet.lisp
+++ b/crates/app/src/public/html/economy/wallet.lisp
@@ -14,9 +14,9 @@
(span (str (text "general:link.wallet")))))
(div
("class" "card lowered flex flex_col gap_4")
- (a
+ (button
("class" "card button raised")
- ("href" "/wallet/buy")
+ ("onclick" "document.getElementById('buy_dialog').showModal()")
(b (text "Coin balance"))
(h3
("class" "flex gap_2 items_center")
@@ -63,4 +63,54 @@
(icon (text "external-link")))
(text "{%- endif %}")))
(text "{%- endfor %}")))))))
+
+(dialog
+ ("id" "buy_dialog")
+ (div
+ ("class" "inner flex flex_col gap_2")
+ (p (text "All coin purchases are one-time and will not recur."))
+ (p (text "If you do not receive your coins within a minute of purchase, please contact support."))
+
+ (button
+ ("class" "lowered w_full justify_start")
+ ("onclick" "checkout('Coins100')")
+ (text "100 coins ({{ config.stripe.price_texts.coins_100 }})"))
+
+ (button
+ ("class" "w_full justify_start")
+ ("onclick" "checkout('Coins400')")
+ (text "400 coins ({{ config.stripe.price_texts.coins_400 }})"))
+
+ (hr ("class" "margin"))
+ (div
+ ("class" "flex gap_2 justify_between")
+ (div null?)
+ (button
+ ("class" "lowered red")
+ ("type" "button")
+ ("onclick", "document.getElementById('buy_dialog').close()")
+ (icon (text "x"))
+ (str (text "dialog:action.cancel"))))))
+
+(script
+ (text "globalThis.checkout = (product) => {
+ document.getElementById('buy_dialog').close();
+ fetch(\"/api/v1/service_hooks/stripe/checkout\", {
+ method: \"POST\",
+ headers: {
+ \"Content-Type\": \"application/json\",
+ },
+ body: JSON.stringify({
+ product,
+ }),
+ })
+ .then((res) => res.json())
+ .then((res) => {
+ trigger(\"atto::toast\", [res.ok ? \"success\" : \"error\", res.message]);
+
+ if (res.ok) {
+ window.location.href = res.payload;
+ }
+ });
+ }"))
(text "{% endblock %}")
diff --git a/crates/app/src/public/html/journals/app.lisp b/crates/app/src/public/html/journals/app.lisp
index 246e930..48e9e12 100644
--- a/crates/app/src/public/html/journals/app.lisp
+++ b/crates/app/src/public/html/journals/app.lisp
@@ -121,7 +121,7 @@
(div
("class" "flex flex_col gap_2 w_full")
(button
- ("class" "lowered justify-start w_full")
+ ("class" "lowered justify_start w_full")
("onclick" "create_journal()")
(icon (text "plus"))
(str (text "journals:action.create_journal")))
@@ -207,7 +207,7 @@
(details
("class" "w_full")
(summary
- ("class" "button lowered w_full justify-start")
+ ("class" "button lowered w_full justify_start")
(icon (text "settings"))
(str (text "general:action.manage")))
@@ -261,7 +261,7 @@
(details
("class" "w_full")
(summary
- ("class" "button lowered w_full justify-start")
+ ("class" "button lowered w_full justify_start")
(icon (text "folders"))
(str (text "journals:label.directories")))
diff --git a/crates/app/src/public/html/profile/base.lisp b/crates/app/src/public/html/profile/base.lisp
index aab9c70..c1788b3 100644
--- a/crates/app/src/public/html/profile/base.lisp
+++ b/crates/app/src/public/html/profile/base.lisp
@@ -64,7 +64,7 @@
("id" "username")
("class" "username flex items_center gap_2 flex_wrap w_full")
(span
- ("class" "name shorter")
+ ("class" "name")
(text "{{ components::username(user=profile) }}"))
(text "{% if profile.is_verified -%}")
(span
@@ -84,6 +84,12 @@
("style" "color: var(--color-primary);")
("class" "flex items_center")
(text "{{ icon \"id-card-lanyard\" }}"))
+ (text "{%- endif %} {% if profile.checkouts|length > 0 -%}")
+ (span
+ ("title" "Donator")
+ ("style" "color: var(--color-primary);")
+ ("class" "flex items_center")
+ (text "{{ icon \"hand-heart\" }}"))
(text "{%- endif %} {% if profile.permissions|has_staff_badge -%}")
(span
("title" "Staff")
diff --git a/crates/app/src/public/html/profile/posts.lisp b/crates/app/src/public/html/profile/posts.lisp
index 2632319..e01660b 100644
--- a/crates/app/src/public/html/profile/posts.lisp
+++ b/crates/app/src/public/html/profile/posts.lisp
@@ -32,7 +32,7 @@
("class" "card w_full flex flex_col gap_2")
("ui_ident" "io_data_load")
; pinned
- (text "{% if pinned|length > 0 -%}")
+ (text "{% if pinned and pinned|length > 0 -%}")
(text "{% for post in pinned %} {% if post[2].read_access == \"Everybody\" -%} {% if post[0].context.repost and post[0].context.repost.reposting -%} {{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true, can_manage_post=is_self) }} {% else %} {{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], can_manage_post=is_self, poll=post[5]) }} {%- endif %} {%- endif %} {% endfor %}")
(div ("class" "squig"))
(text "{%- endif %}")
diff --git a/crates/app/src/public/html/profile/responses.lisp b/crates/app/src/public/html/profile/responses.lisp
index 67ccd80..925d271 100644
--- a/crates/app/src/public/html/profile/responses.lisp
+++ b/crates/app/src/public/html/profile/responses.lisp
@@ -32,7 +32,7 @@
("class" "card w_full flex flex_col gap_2")
("ui_ident" "io_data_load")
; pinned
- (text "{% if pinned|length > 0 -%}")
+ (text "{% if pinned and pinned|length > 0 -%}")
(text "{% for post in pinned %} {% if post[2].read_access == \"Everybody\" -%} {% if post[0].context.repost and post[0].context.repost.reposting -%} {{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true, can_manage_post=is_self) }} {% else %} {{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], can_manage_post=is_self, poll=post[5]) }} {%- endif %} {%- endif %} {% endfor %}")
(div ("class" "squig"))
(text "{%- endif %}")
diff --git a/crates/app/src/public/html/stacks/add_user.lisp b/crates/app/src/public/html/stacks/add_user.lisp
index 7318cfc..5ae6f90 100644
--- a/crates/app/src/public/html/stacks/add_user.lisp
+++ b/crates/app/src/public/html/stacks/add_user.lisp
@@ -16,7 +16,7 @@
(span (text "Select a stack to add this user to:"))
(text "{% for stack in stacks %}")
(button
- ("class" "justify-start lowered w_full")
+ ("class" "justify_start lowered w_full")
("onclick" "choose_stack('{{ stack.id }}')")
(icon (text "layers"))
(text "{{ stack.name }}"))
diff --git a/crates/app/src/public/js/me.js b/crates/app/src/public/js/me.js
index e1f7def..708baf4 100644
--- a/crates/app/src/public/js/me.js
+++ b/crates/app/src/public/js/me.js
@@ -726,7 +726,7 @@
element.innerHTML = "";
for (const token of Object.entries($.LOGIN_ACCOUNT_TOKENS)) {
element.innerHTML += `
-