add: ability to convert existing communities into forums
This commit is contained in:
parent
3958d5eaef
commit
2407e6b213
8 changed files with 125 additions and 24 deletions
|
@ -5,22 +5,26 @@
|
||||||
--hue: 16;
|
--hue: 16;
|
||||||
--sat: 6%;
|
--sat: 6%;
|
||||||
--lit: 0%;
|
--lit: 0%;
|
||||||
--color-surface: hsl(var(--hue), var(--sat), calc(97% - var(--lit)));
|
--color-surface: hsl(var(--hue), var(--sat), calc(94% - var(--lit)));
|
||||||
--color-lowered: hsl(var(--hue), var(--sat), calc(94% - var(--lit)));
|
--color-lowered: hsl(var(--hue), var(--sat), calc(90% - var(--lit)));
|
||||||
--color-raised: hsl(var(--hue), var(--sat), calc(99% - var(--lit)));
|
--color-raised: hsl(var(--hue), var(--sat), calc(97% - var(--lit)));
|
||||||
--color-super-lowered: hsl(var(--hue), var(--sat), calc(85% - var(--lit)));
|
--color-super-lowered: hsl(var(--hue), var(--sat), calc(85% - var(--lit)));
|
||||||
--color-super-raised: hsl(var(--hue), var(--sat), calc(100% - var(--lit)));
|
--color-super-raised: hsl(var(--hue), var(--sat), calc(99% - var(--lit)));
|
||||||
--color-text: hsl(0, 0%, 0%);
|
--color-text: hsl(0, 0%, 9%);
|
||||||
--color-text-raised: var(--color-text);
|
--color-text-raised: var(--color-text);
|
||||||
--color-text-lowered: var(--color-text);
|
--color-text-lowered: var(--color-text);
|
||||||
|
|
||||||
--color-primary: hsl(330, 18%, 26%);
|
--color-primary: hsl(330, 18%, 26%);
|
||||||
--color-primary-lowered: hsl(330, 18%, 21%);
|
--color-primary-lowered: hsl(330, 18%, 21%);
|
||||||
--color-text-primary: hsl(0, 0%, 100%);
|
--color-text-primary: hsl(0, 0%, 91%);
|
||||||
|
|
||||||
--color-secondary: hsl(6, 18%, 66%);
|
--color-secondary: hsl(277, 27%, 70%);
|
||||||
--color-secondary-lowered: hsl(6, 18%, 61%);
|
--color-secondary-lowered: hsl(277, 27%, 65%);
|
||||||
--color-text-secondary: hsl(0, 0%, 0%);
|
--color-text-secondary: hsl(0, 0%, 9%);
|
||||||
|
|
||||||
|
--color-accent: hsl(237, 27%, 28%);
|
||||||
|
--color-accent-lowered: hsl(237, 27%, 23%);
|
||||||
|
--color-text-accent: hsl(0, 0%, 91%);
|
||||||
|
|
||||||
--color-link: #2949b2;
|
--color-link: #2949b2;
|
||||||
--color-shadow: rgba(0, 0, 0, 0.08);
|
--color-shadow: rgba(0, 0, 0, 0.08);
|
||||||
|
@ -54,15 +58,19 @@
|
||||||
--color-raised: hsl(var(--hue), var(--sat), calc(2% + var(--lit)));
|
--color-raised: hsl(var(--hue), var(--sat), calc(2% + var(--lit)));
|
||||||
--color-super-lowered: hsl(var(--hue), var(--sat), calc(12% + var(--lit)));
|
--color-super-lowered: hsl(var(--hue), var(--sat), calc(12% + var(--lit)));
|
||||||
--color-super-raised: hsl(var(--hue), var(--sat), calc(4% + var(--lit)));
|
--color-super-raised: hsl(var(--hue), var(--sat), calc(4% + var(--lit)));
|
||||||
--color-text: hsl(0, 0%, 95%);
|
--color-text: hsl(0, 0%, 91%);
|
||||||
|
|
||||||
--color-primary: hsl(331, 18%, 74%);
|
--color-primary: hsl(331, 18%, 74%);
|
||||||
--color-primary-lowered: hsl(331, 18%, 69%);
|
--color-primary-lowered: hsl(331, 18%, 69%);
|
||||||
--color-text-primary: hsl(0, 0%, 0%);
|
--color-text-primary: hsl(0, 0%, 9%);
|
||||||
|
|
||||||
--color-secondary: hsl(6, 18%, 34%);
|
--color-secondary: hsl(277, 27%, 30%);
|
||||||
--color-secondary-lowered: hsl(6, 18%, 29%);
|
--color-secondary-lowered: hsl(277, 27%, 25%);
|
||||||
--color-text-secondary: hsl(0, 0%, 100%);
|
--color-text-secondary: hsl(0, 0%, 91%);
|
||||||
|
|
||||||
|
--color-accent: hsl(237, 27%, 72%);
|
||||||
|
--color-accent-lowered: hsl(237, 27%, 67%);
|
||||||
|
--color-text-accent: hsl(0, 0%, 9%);
|
||||||
|
|
||||||
--color-link: #93c5fd;
|
--color-link: #93c5fd;
|
||||||
--color-red: hsl(0, 94%, 82%);
|
--color-red: hsl(0, 94%, 82%);
|
||||||
|
|
|
@ -370,7 +370,17 @@ button.secondary,
|
||||||
.button.secondary {
|
.button.secondary {
|
||||||
background: var(--color-secondary);
|
background: var(--color-secondary);
|
||||||
color: var(--color-text-secondary);
|
color: var(--color-text-secondary);
|
||||||
font-weight: 500;
|
}
|
||||||
|
|
||||||
|
button.accent:hover,
|
||||||
|
.button.accent:hover {
|
||||||
|
background: var(--color-accent-lowered);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.accent,
|
||||||
|
.button.accent {
|
||||||
|
background: var(--color-accent);
|
||||||
|
color: var(--color-text-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
button.secondary:hover,
|
button.secondary:hover,
|
||||||
|
@ -861,18 +871,19 @@ dialog {
|
||||||
display: none;
|
display: none;
|
||||||
background: var(--color-surface);
|
background: var(--color-surface);
|
||||||
border: solid 1px var(--color-super-lowered) !important;
|
border: solid 1px var(--color-super-lowered) !important;
|
||||||
border-radius: var(--radius);
|
border-radius: calc(var(--radius) * 2);
|
||||||
max-width: 100%;
|
max-width: 95%;
|
||||||
border-style: none;
|
border-style: none;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
animation: popin ease-in-out 1 0.1s forwards running;
|
animation: popin ease-in-out 1 0.15s forwards running;
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog .inner {
|
dialog .inner {
|
||||||
padding: var(--pad-4);
|
padding: var(--pad-4);
|
||||||
width: 25rem;
|
width: 25rem;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog .inner hr:not(.flipped):last-of-type {
|
dialog .inner hr:not(.flipped):last-of-type {
|
||||||
|
@ -891,6 +902,11 @@ dialog[open] {
|
||||||
dialog::backdrop {
|
dialog::backdrop {
|
||||||
background: hsla(0, 0%, 0%, 50%);
|
background: hsla(0, 0%, 0%, 50%);
|
||||||
backdrop-filter: blur(5px);
|
backdrop-filter: blur(5px);
|
||||||
|
animation: fadein ease-in-out 1 0.1s forwards running;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog:is(.dark *)::backdrop {
|
||||||
|
background: hsla(0, 0%, 100%, 15%);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dropdown */
|
/* dropdown */
|
||||||
|
@ -905,7 +921,7 @@ dialog::backdrop {
|
||||||
background: var(--color-raised);
|
background: var(--color-raised);
|
||||||
/* border: solid 1px var(--color-super-lowered); */
|
/* border: solid 1px var(--color-super-lowered); */
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
border-radius: var(--radius);
|
border-radius: calc(var(--radius) * 2);
|
||||||
top: calc(100% + 5px);
|
top: calc(100% + 5px);
|
||||||
right: 0;
|
right: 0;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
|
|
|
@ -311,7 +311,7 @@
|
||||||
(div ("id" "tokens") ("style" "display: contents"))
|
(div ("id" "tokens") ("style" "display: contents"))
|
||||||
|
|
||||||
(div
|
(div
|
||||||
("class" "flex justify_between")
|
("class" "flex justify_right gap_2")
|
||||||
(a
|
(a
|
||||||
("href" "/auth/login")
|
("href" "/auth/login")
|
||||||
("class" "button")
|
("class" "button")
|
||||||
|
@ -323,7 +323,8 @@
|
||||||
("class" "lowered")
|
("class" "lowered")
|
||||||
("onclick" "document.getElementById('tokens_dialog').close()")
|
("onclick" "document.getElementById('tokens_dialog').close()")
|
||||||
("type" "button")
|
("type" "button")
|
||||||
(icon (text "check")))))))
|
(icon (text "check"))
|
||||||
|
(str (text "dialog:action.okay")))))))
|
||||||
|
|
||||||
; user scripts
|
; user scripts
|
||||||
(text "{%- endif %} {% if user and use_user_theme -%} {{ components::theme(user=user, theme_preference=user.settings.theme_preference) }}
|
(text "{%- endif %} {% if user and use_user_theme -%} {{ components::theme(user=user, theme_preference=user.settings.theme_preference) }}
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
("name" "is_forum")
|
("name" "is_forum")
|
||||||
("class" "w_content"))
|
("class" "w_content"))
|
||||||
(span
|
(span
|
||||||
(text "Is forum")))
|
(text "Make this a forum community")))
|
||||||
(button
|
(button
|
||||||
(text "{{ text \"communities:action.create\" }}"))))
|
(text "{{ text \"communities:action.create\" }}"))))
|
||||||
(text "{% if list|length >= 4 -%} {{ components::supporter_ad(body=\"Become a supporter to create up to 10 communities!\") }} {%- endif %} {%- endif %}")
|
(text "{% if list|length >= 4 -%} {{ components::supporter_ad(body=\"Become a supporter to create up to 10 communities!\") }} {%- endif %} {%- endif %}")
|
||||||
|
|
|
@ -37,14 +37,14 @@
|
||||||
(text "{{ icon \"rss\" }}")
|
(text "{{ icon \"rss\" }}")
|
||||||
(span
|
(span
|
||||||
(text "{{ text \"communities:tab.channels\" }}")))
|
(text "{{ text \"communities:tab.channels\" }}")))
|
||||||
(text "{%- endif %} {% if community.is_forum -%}")
|
(text "{%- endif %}")
|
||||||
(a
|
(a
|
||||||
("href" "#/topics")
|
("href" "#/topics")
|
||||||
("data-tab-button" "topics")
|
("data-tab-button" "topics")
|
||||||
(icon (text "list"))
|
(icon (text "list"))
|
||||||
(span
|
(span
|
||||||
(str (text "communities:tab.topics"))))
|
(str (text "communities:tab.topics"))))
|
||||||
(text "{%- endif %} {% if can_manage_emojis -%}")
|
(text "{% if can_manage_emojis -%}")
|
||||||
(a
|
(a
|
||||||
("href" "#/emojis")
|
("href" "#/emojis")
|
||||||
("data-tab-button" "emojis")
|
("data-tab-button" "emojis")
|
||||||
|
@ -825,6 +825,42 @@
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
}"))
|
}"))
|
||||||
|
(text "{% else %}")
|
||||||
|
(div
|
||||||
|
("class" "card lowered w_full hidden flex flex_col gap_2")
|
||||||
|
("data-tab" "topics")
|
||||||
|
(p (text "You can only manage topics for forum communities. You can convert this community into a forum, but you will not be able to go back."))
|
||||||
|
(p (text "This will permanently change your community. Currently existing posts will no longer be visible on the community."))
|
||||||
|
(button
|
||||||
|
("onclick" "convert_to_forum()")
|
||||||
|
(icon (text "circle-fading-arrow-up"))
|
||||||
|
(text "Switch to forum")))
|
||||||
|
|
||||||
|
(script
|
||||||
|
(text "globalThis.convert_to_forum = async () => {
|
||||||
|
if (
|
||||||
|
!(await trigger(\"atto::confirm\", [
|
||||||
|
\"Are you sure you would like to do this? It cannot be undone.\",
|
||||||
|
]))
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(\"/api/v1/communities/{{ community.id }}/is_forum\", {
|
||||||
|
method: \"POST\",
|
||||||
|
})
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((res) => {
|
||||||
|
trigger(\"atto::toast\", [
|
||||||
|
res.ok ? \"success\" : \"error\",
|
||||||
|
res.message,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (res.ok) {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}"))
|
||||||
(text "{%- endif %}"))
|
(text "{%- endif %}"))
|
||||||
|
|
||||||
(script
|
(script
|
||||||
|
|
|
@ -264,6 +264,41 @@ pub async fn update_owner_request(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn update_is_forum_request(
|
||||||
|
jar: CookieJar,
|
||||||
|
Extension(data): Extension<State>,
|
||||||
|
Path(id): Path<usize>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let data = &(data.read().await).0;
|
||||||
|
let user = match get_user_from_token!(jar, data, oauth::AppScope::CommunityManage) {
|
||||||
|
Some(ua) => ua,
|
||||||
|
None => return Json(Error::NotAllowed.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut community = match data.get_community_by_id_no_void(id).await {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(e) => return Json(e.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
community.context.enable_titles = true;
|
||||||
|
community.context.require_titles = true;
|
||||||
|
|
||||||
|
match data.update_community_is_forum(id, &user, 1).await {
|
||||||
|
Ok(_) => match data
|
||||||
|
.update_community_context(id, &user, community.context)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(_) => Json(ApiReturn {
|
||||||
|
ok: true,
|
||||||
|
message: "Community updated".to_string(),
|
||||||
|
payload: (),
|
||||||
|
}),
|
||||||
|
Err(e) => Json(e.into()),
|
||||||
|
},
|
||||||
|
Err(e) => Json(e.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_membership(
|
pub async fn get_membership(
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
Extension(data): Extension<State>,
|
Extension(data): Extension<State>,
|
||||||
|
|
|
@ -95,6 +95,10 @@ pub fn routes() -> Router {
|
||||||
"/communities/{id}/context",
|
"/communities/{id}/context",
|
||||||
post(communities::communities::update_context_request),
|
post(communities::communities::update_context_request),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/communities/{id}/is_forum",
|
||||||
|
post(communities::communities::update_is_forum_request),
|
||||||
|
)
|
||||||
.route(
|
.route(
|
||||||
"/communities/{id}/access/read",
|
"/communities/{id}/access/read",
|
||||||
post(communities::communities::update_read_access_request),
|
post(communities::communities::update_read_access_request),
|
||||||
|
|
|
@ -556,6 +556,7 @@ impl DataManager {
|
||||||
auto_method!(update_community_write_access(CommunityWriteAccess)@get_community_by_id_no_void:FinePermission::MANAGE_COMMUNITIES; -> "UPDATE communities SET write_access = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_community);
|
auto_method!(update_community_write_access(CommunityWriteAccess)@get_community_by_id_no_void:FinePermission::MANAGE_COMMUNITIES; -> "UPDATE communities SET write_access = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_community);
|
||||||
auto_method!(update_community_join_access(CommunityJoinAccess)@get_community_by_id_no_void:FinePermission::MANAGE_COMMUNITIES; -> "UPDATE communities SET join_access = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_community);
|
auto_method!(update_community_join_access(CommunityJoinAccess)@get_community_by_id_no_void:FinePermission::MANAGE_COMMUNITIES; -> "UPDATE communities SET join_access = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_community);
|
||||||
auto_method!(update_community_topics(HashMap<usize, ForumTopic>)@get_community_by_id_no_void:FinePermission::MANAGE_COMMUNITIES; -> "UPDATE communities SET topics = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_community);
|
auto_method!(update_community_topics(HashMap<usize, ForumTopic>)@get_community_by_id_no_void:FinePermission::MANAGE_COMMUNITIES; -> "UPDATE communities SET topics = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_community);
|
||||||
|
auto_method!(update_community_is_forum(i32)@get_community_by_id_no_void:FinePermission::MANAGE_COMMUNITIES; -> "UPDATE communities SET is_forum = $1 WHERE id = $2" --cache-key-tmpl=cache_clear_community);
|
||||||
|
|
||||||
auto_method!(incr_community_likes()@get_community_by_id_no_void -> "UPDATE communities SET likes = likes + 1 WHERE id = $1" --cache-key-tmpl=cache_clear_community --incr);
|
auto_method!(incr_community_likes()@get_community_by_id_no_void -> "UPDATE communities SET likes = likes + 1 WHERE id = $1" --cache-key-tmpl=cache_clear_community --incr);
|
||||||
auto_method!(incr_community_dislikes()@get_community_by_id_no_void -> "UPDATE communities SET dislikes = dislikes + 1 WHERE id = $1" --cache-key-tmpl=cache_clear_community --incr);
|
auto_method!(incr_community_dislikes()@get_community_by_id_no_void -> "UPDATE communities SET dislikes = dislikes + 1 WHERE id = $1" --cache-key-tmpl=cache_clear_community --incr);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue