From 5dd9fa01cb671ea9699120cfd4280e562411f5e5 Mon Sep 17 00:00:00 2001 From: trisua Date: Fri, 27 Jun 2025 13:10:04 -0400 Subject: [PATCH] add: 8 achievements add: larger text setting fix: small infinite timeline bugs --- Cargo.lock | 8 +- crates/app/Cargo.toml | 2 +- crates/app/src/public/html/body.lisp | 12 ++ crates/app/src/public/html/profile/posts.lisp | 3 +- .../app/src/public/html/profile/settings.lisp | 26 ++-- crates/app/src/public/js/atto.js | 134 ++++++++++-------- crates/app/src/routes/api/v1/auth/profile.rs | 4 +- crates/app/src/routes/api/v1/auth/social.rs | 10 +- .../src/routes/api/v1/communities/posts.rs | 10 +- .../routes/api/v1/communities/questions.rs | 13 +- crates/app/src/routes/api/v1/journals.rs | 4 +- crates/app/src/routes/pages/misc.rs | 16 ++- crates/core/Cargo.toml | 2 +- crates/core/src/database/auth.rs | 5 +- crates/core/src/database/reactions.rs | 31 +++- crates/core/src/database/userfollows.rs | 17 ++- crates/core/src/model/auth.rs | 63 +++++--- crates/l10n/Cargo.toml | 2 +- crates/shared/Cargo.toml | 2 +- 19 files changed, 241 insertions(+), 123 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a11c634..ce61c71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3231,7 +3231,7 @@ dependencies = [ [[package]] name = "tetratto" -version = "9.0.0" +version = "10.0.0" dependencies = [ "ammonia", "async-stripe", @@ -3262,7 +3262,7 @@ dependencies = [ [[package]] name = "tetratto-core" -version = "9.0.0" +version = "10.0.0" dependencies = [ "async-recursion", "base16ct", @@ -3284,7 +3284,7 @@ dependencies = [ [[package]] name = "tetratto-l10n" -version = "9.0.0" +version = "10.0.0" dependencies = [ "pathbufd", "serde", @@ -3293,7 +3293,7 @@ dependencies = [ [[package]] name = "tetratto-shared" -version = "9.0.0" +version = "10.0.0" dependencies = [ "ammonia", "chrono", diff --git a/crates/app/Cargo.toml b/crates/app/Cargo.toml index e29dcb9..3c66674 100644 --- a/crates/app/Cargo.toml +++ b/crates/app/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tetratto" -version = "9.0.0" +version = "10.0.0" edition = "2024" [dependencies] diff --git a/crates/app/src/public/html/body.lisp b/crates/app/src/public/html/body.lisp index 82e5fe9..227a8f1 100644 --- a/crates/app/src/public/html/body.lisp +++ b/crates/app/src/public/html/body.lisp @@ -1,5 +1,17 @@ (div ("id" "toast_zone")) +; large text +(text "{% if user and user.settings.large_text -%}") +(style + (text "button, a, p, span, b, strone, em, i, pre, code { + font-size: 18px !important; + } + + nav .icon { + font-size: 15px !important; + }")) +(text "{%- endif %}") + ; templates (template ("id" "loading_skeleton") diff --git a/crates/app/src/public/html/profile/posts.lisp b/crates/app/src/public/html/profile/posts.lisp index 6c417a6..6120fea 100644 --- a/crates/app/src/public/html/profile/posts.lisp +++ b/crates/app/src/public/html/profile/posts.lisp @@ -49,6 +49,7 @@ (text "setTimeout(async () => { await trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?user_id={{ profile.id }}&tag={{ tag }}&page=\", Number.parseInt(\"{{ page }}\") - 1, \"{{ paged }}\" === \"true\"]); (await ns(\"ui\")).IO_DATA_DISABLE_RELOAD = true; - }, 500);")) + console.log(\"created profile timeline\"); + }, 1000);")) (text "{% endblock %}") diff --git a/crates/app/src/public/html/profile/settings.lisp b/crates/app/src/public/html/profile/settings.lisp index 2b12aa0..f2280e6 100644 --- a/crates/app/src/public/html/profile/settings.lisp +++ b/crates/app/src/public/html/profile/settings.lisp @@ -1407,6 +1407,22 @@ embed_html: 'Muted phrases should all be on new lines.', }], + [[], \"Accessibility\", \"title\"], + [ + [\"large_text\", \"Increase UI text size\"], + \"{{ profile.settings.large_text }}\", + \"checkbox\", + ], + [ + [\"paged_timelines\", \"Make timelines paged instead of infinitely scrolled\"], + \"{{ profile.settings.paged_timelines }}\", + \"checkbox\", + ], + [ + [\"auto_clear_notifs\", \"Automatically clear all notifications when you open the notifications page\"], + \"{{ profile.settings.auto_clear_notifs }}\", + \"checkbox\", + ], ], settings, { @@ -1531,16 +1547,6 @@ \"Hides dislikes on all posts. Users will also no longer be able to dislike your posts.\", \"text\", ], - [ - [\"paged_timelines\", \"Make timelines paged instead of infinitely scrolled\"], - \"{{ profile.settings.paged_timelines }}\", - \"checkbox\", - ], - [ - [\"auto_clear_notifs\", \"Automatically clear all notifications when you open the notifications page\"], - \"{{ profile.settings.auto_clear_notifs }}\", - \"checkbox\", - ], [[], \"Fun\", \"title\"], [ [\"disable_gpa_fun\", \"Disable GPA\"], diff --git a/crates/app/src/public/js/atto.js b/crates/app/src/public/js/atto.js index 0bd8d62..350b7a3 100644 --- a/crates/app/src/public/js/atto.js +++ b/crates/app/src/public/js/atto.js @@ -1151,82 +1151,90 @@ ${option.input_element_type === "textarea" ? `${option.value}` : ""} }); // intersection observer infinite scrolling - const obs = (await ns("ui")).IO_DATA_OBSERVER; - if (obs) { - console.log("get lost old observer"); - obs.disconnect(); - } + self.IO_DATA_OBSERVER = null; - self.IO_DATA_OBSERVER = new IntersectionObserver( - async (entries) => { - for (const entry of entries) { - if (!entry.isIntersecting) { - continue; - } - - await self.io_load_data(); - break; + self.define( + "io_data_load", + async (_, tmpl, page, paginated_mode = false) => { + // remove old + const obs = self.IO_DATA_OBSERVER; + if (obs) { + console.log("get lost old observer"); + obs.disconnect(); + self.IO_DATA_OBSERVER = null; } - }, - { - root: document.body, - rootMargin: "0px", - threshold: 1, - }, - ); - self.define("io_data_load", (_, tmpl, page, paginated_mode = false) => { - self.IO_DATA_MARKER = document.querySelector( - "[ui_ident=io_data_marker]", - ); + self.IO_DATA_OBSERVER = new IntersectionObserver( + async (entries) => { + for (const entry of entries) { + if (!entry.isIntersecting) { + continue; + } - self.IO_DATA_ELEMENT = document.querySelector( - "[ui_ident=io_data_load]", - ); - - self.IO_HTML_TMPL = document.getElementById("loading_skeleton"); - - if (!self.IO_DATA_ELEMENT || !self.IO_DATA_MARKER) { - console.warn( - "ui::io_data_load called, but required elements don't exist", + await self.io_load_data(); + break; + } + }, + { + root: document.body, + rootMargin: "0px", + threshold: 1, + }, ); - return; - } + // ... + self.IO_DATA_MARKER = document.querySelector( + "[ui_ident=io_data_marker]", + ); - self.IO_DATA_TMPL = tmpl; - self.IO_DATA_PAGE = page; - self.IO_DATA_SEEN_IDS = []; - self.IO_DATA_WAITING = false; - self.IO_HAS_LOADED_AT_LEAST_ONCE = false; - self.IO_DATA_DISCONNECTED = false; - self.IO_DATA_DISABLE_RELOAD = false; + self.IO_DATA_ELEMENT = document.querySelector( + "[ui_ident=io_data_load]", + ); - if (!paginated_mode) { - self.IO_DATA_OBSERVER.observe(self.IO_DATA_MARKER); - } else { - // immediately load first page - self.IO_DATA_TMPL = self.IO_DATA_TMPL.replace("&page=", ""); - self.IO_DATA_TMPL += `&paginated=true&page=`; - self.io_load_data(); - } + self.IO_HTML_TMPL = document.getElementById("loading_skeleton"); + + if (!self.IO_DATA_ELEMENT || !self.IO_DATA_MARKER) { + console.warn( + "ui::io_data_load called, but required elements don't exist", + ); - setTimeout(() => { - if (self.IO_DATA_DISABLE_RELOAD) { - console.log("missing data reload disabled"); return; } - if (!self.IO_HAS_LOADED_AT_LEAST_ONCE) { - // reload - self.IO_DATA_OBSERVER.disconnect(); - console.log("timeline load fail :("); - window.location.reload(); - } - }, 1500); + self.IO_DATA_TMPL = tmpl; + self.IO_DATA_PAGE = page; + self.IO_DATA_SEEN_IDS = []; + self.IO_DATA_WAITING = false; + self.IO_HAS_LOADED_AT_LEAST_ONCE = false; + self.IO_DATA_DISCONNECTED = false; + self.IO_DATA_DISABLE_RELOAD = false; - self.IO_PAGINATED = paginated_mode; - }); + if (!paginated_mode) { + self.IO_DATA_OBSERVER.observe(self.IO_DATA_MARKER); + } else { + // immediately load first page + self.IO_DATA_TMPL = self.IO_DATA_TMPL.replace("&page=", ""); + self.IO_DATA_TMPL += `&paginated=true&page=`; + self.io_load_data(); + } + + setTimeout(() => { + if (self.IO_DATA_DISABLE_RELOAD) { + console.log("missing data reload disabled"); + return; + } + + if (!self.IO_HAS_LOADED_AT_LEAST_ONCE) { + // reload + self.IO_DATA_OBSERVER.disconnect(); + console.log("timeline load fail :("); + window.location.reload(); + } + }, 1500); + + self.IO_PAGINATED = paginated_mode; + }, + ); self.define("io_load_data", async () => { if (self.IO_DATA_WAITING) { diff --git a/crates/app/src/routes/api/v1/auth/profile.rs b/crates/app/src/routes/api/v1/auth/profile.rs index baf2f54..0d2bc49 100644 --- a/crates/app/src/routes/api/v1/auth/profile.rs +++ b/crates/app/src/routes/api/v1/auth/profile.rs @@ -116,7 +116,7 @@ pub async fn update_user_settings_request( Json(mut req): Json, ) -> impl IntoResponse { let data = &(data.read().await).0; - let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageProfile) { + let mut user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageProfile) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; @@ -153,7 +153,7 @@ pub async fn update_user_settings_request( // award achievement if let Err(e) = data - .add_achievement(&user, AchievementName::EditSettings.into()) + .add_achievement(&mut user, AchievementName::EditSettings.into()) .await { return Json(e.into()); diff --git a/crates/app/src/routes/api/v1/auth/social.rs b/crates/app/src/routes/api/v1/auth/social.rs index a507e49..53aff80 100644 --- a/crates/app/src/routes/api/v1/auth/social.rs +++ b/crates/app/src/routes/api/v1/auth/social.rs @@ -22,7 +22,7 @@ pub async fn follow_request( Extension(data): Extension, ) -> impl IntoResponse { let data = &(data.read().await).0; - let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageFollowing) { + let mut user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageFollowing) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; @@ -40,7 +40,7 @@ pub async fn follow_request( } else { // create match data - .create_userfollow(UserFollow::new(user.id, id), false) + .create_userfollow(UserFollow::new(user.id, id), &user, false) .await { Ok(r) => { @@ -59,13 +59,15 @@ pub async fn follow_request( return Json(e.into()); }; + // award achievement if let Err(e) = data - .add_achievement(&user, AchievementName::FollowUser.into()) + .add_achievement(&mut user, AchievementName::FollowUser.into()) .await { return Json(e.into()); } + // ... Json(ApiReturn { ok: true, message: "User followed".to_string(), @@ -123,7 +125,7 @@ pub async fn accept_follow_request( // create follow match data - .create_userfollow(UserFollow::new(id, user.id), true) + .create_userfollow(UserFollow::new(id, user.id), &user, true) .await { Ok(_) => { diff --git a/crates/app/src/routes/api/v1/communities/posts.rs b/crates/app/src/routes/api/v1/communities/posts.rs index e1fb89e..fee1ba8 100644 --- a/crates/app/src/routes/api/v1/communities/posts.rs +++ b/crates/app/src/routes/api/v1/communities/posts.rs @@ -37,7 +37,7 @@ pub async fn create_request( JsonMultipart(images, req): JsonMultipart, ) -> impl IntoResponse { let data = &(data.read().await).0; - let user = match get_user_from_token!(jar, data, oauth::AppScope::UserCreatePosts) { + let mut user = match get_user_from_token!(jar, data, oauth::AppScope::UserCreatePosts) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; @@ -181,7 +181,7 @@ pub async fn create_request( // achievements if let Err(e) = data - .add_achievement(&user, AchievementName::CreatePost.into()) + .add_achievement(&mut user, AchievementName::CreatePost.into()) .await { return Json(e.into()); @@ -189,7 +189,7 @@ pub async fn create_request( if user.post_count >= 49 { if let Err(e) = data - .add_achievement(&user, AchievementName::Create50Posts.into()) + .add_achievement(&mut user, AchievementName::Create50Posts.into()) .await { return Json(e.into()); @@ -198,7 +198,7 @@ pub async fn create_request( if user.post_count >= 99 { if let Err(e) = data - .add_achievement(&user, AchievementName::Create100Posts.into()) + .add_achievement(&mut user, AchievementName::Create100Posts.into()) .await { return Json(e.into()); @@ -207,7 +207,7 @@ pub async fn create_request( if user.post_count >= 999 { if let Err(e) = data - .add_achievement(&user, AchievementName::Create1000Posts.into()) + .add_achievement(&mut user, AchievementName::Create1000Posts.into()) .await { return Json(e.into()); diff --git a/crates/app/src/routes/api/v1/communities/questions.rs b/crates/app/src/routes/api/v1/communities/questions.rs index c469512..ec24c08 100644 --- a/crates/app/src/routes/api/v1/communities/questions.rs +++ b/crates/app/src/routes/api/v1/communities/questions.rs @@ -52,12 +52,23 @@ pub async fn create_request( // award achievement if let Some(ref user) = user { + let mut user = user.clone(); + if let Err(e) = data - .add_achievement(user, AchievementName::CreateQuestion.into()) + .add_achievement(&mut user, AchievementName::CreateQuestion.into()) .await { return Json(e.into()); } + + if drawings.len() > 0 { + if let Err(e) = data + .add_achievement(&mut user, AchievementName::CreateDrawing.into()) + .await + { + return Json(e.into()); + } + } } // ... diff --git a/crates/app/src/routes/api/v1/journals.rs b/crates/app/src/routes/api/v1/journals.rs index e2f9404..95ae3da 100644 --- a/crates/app/src/routes/api/v1/journals.rs +++ b/crates/app/src/routes/api/v1/journals.rs @@ -98,7 +98,7 @@ pub async fn create_request( Json(props): Json, ) -> impl IntoResponse { let data = &(data.read().await).0; - let user = match get_user_from_token!(jar, data, oauth::AppScope::UserCreateJournals) { + let mut user = match get_user_from_token!(jar, data, oauth::AppScope::UserCreateJournals) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; @@ -110,7 +110,7 @@ pub async fn create_request( Ok(x) => { // award achievement if let Err(e) = data - .add_achievement(&user, AchievementName::CreateJournal.into()) + .add_achievement(&mut user, AchievementName::CreateJournal.into()) .await { return Json(e.into()); diff --git a/crates/app/src/routes/pages/misc.rs b/crates/app/src/routes/pages/misc.rs index 44f54aa..3b99c5d 100644 --- a/crates/app/src/routes/pages/misc.rs +++ b/crates/app/src/routes/pages/misc.rs @@ -10,7 +10,10 @@ use axum::{ use axum_extra::extract::CookieJar; use serde::Deserialize; use tetratto_core::model::{ - auth::DefaultTimelineChoice, permissions::FinePermission, requests::ActionType, Error, + auth::{AchievementName, DefaultTimelineChoice}, + permissions::FinePermission, + requests::ActionType, + Error, }; use std::fs::read_to_string; use pathbufd::PathBufD; @@ -447,7 +450,7 @@ pub async fn achievements_request( Extension(data): Extension, ) -> impl IntoResponse { let data = data.read().await; - let user = match get_user_from_token!(jar, data.0) { + let mut user = match get_user_from_token!(jar, data.0) { Some(ua) => ua, None => { return Err(Html( @@ -458,6 +461,15 @@ pub async fn achievements_request( let achievements = data.0.fill_achievements(user.achievements.clone()); + // award achievement + if let Err(e) = data + .0 + .add_achievement(&mut user, AchievementName::OpenAchievements.into()) + .await + { + return Err(Html(render_error(e, &jar, &data, &None).await)); + } + // ... let lang = get_lang!(jar, data.0); let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await; diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index b2fd135..afcecb0 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tetratto-core" -version = "9.0.0" +version = "10.0.0" edition = "2024" [dependencies] diff --git a/crates/core/src/database/auth.rs b/crates/core/src/database/auth.rs index 4baeef0..a34b634 100644 --- a/crates/core/src/database/auth.rs +++ b/crates/core/src/database/auth.rs @@ -712,7 +712,7 @@ impl DataManager { /// Add an achievement to a user. /// /// Still returns `Ok` if the user already has the achievement. - pub async fn add_achievement(&self, user: &User, achievement: Achievement) -> Result<()> { + pub async fn add_achievement(&self, user: &mut User, achievement: Achievement) -> Result<()> { if user .achievements .iter() @@ -734,9 +734,8 @@ impl DataManager { .await?; // add achievement - let mut user = user.clone(); user.achievements.push(achievement); - self.update_user_achievements(user.id, user.achievements) + self.update_user_achievements(user.id, user.achievements.to_owned()) .await?; Ok(()) diff --git a/crates/core/src/database/reactions.rs b/crates/core/src/database/reactions.rs index 347548f..4d15190 100644 --- a/crates/core/src/database/reactions.rs +++ b/crates/core/src/database/reactions.rs @@ -1,9 +1,9 @@ use oiseau::cache::Cache; use crate::model::{ - Error, Result, - auth::{Notification, User}, + auth::{AchievementName, Notification, User}, permissions::FinePermission, reactions::{AssetType, Reaction}, + Error, Result, }; use crate::{auto_method, DataManager}; @@ -148,6 +148,33 @@ impl DataManager { { return Err(Error::NotAllowed); } + + // achievements + if user.id != post.owner { + let mut owner = self.get_user_by_id(post.owner).await?; + self.add_achievement(&mut owner, AchievementName::Get1Like.into()) + .await?; + + if post.likes >= 9 { + self.add_achievement(&mut owner, AchievementName::Get10Likes.into()) + .await?; + } + + if post.likes >= 49 { + self.add_achievement(&mut owner, AchievementName::Get50Likes.into()) + .await?; + } + + if post.likes >= 99 { + self.add_achievement(&mut owner, AchievementName::Get100Likes.into()) + .await?; + } + + if post.dislikes >= 24 { + self.add_achievement(&mut owner, AchievementName::Get25Dislikes.into()) + .await?; + } + } } else if data.asset_type == AssetType::Question { let question = self.get_question_by_id(data.asset).await?; diff --git a/crates/core/src/database/userfollows.rs b/crates/core/src/database/userfollows.rs index 09504c0..3409443 100644 --- a/crates/core/src/database/userfollows.rs +++ b/crates/core/src/database/userfollows.rs @@ -1,5 +1,5 @@ use oiseau::cache::Cache; -use crate::model::auth::FollowResult; +use crate::model::auth::{AchievementName, FollowResult}; use crate::model::requests::{ActionRequest, ActionType}; use crate::model::{Error, Result, auth::User, auth::UserFollow, permissions::FinePermission}; use crate::{auto_method, DataManager}; @@ -238,9 +238,14 @@ impl DataManager { /// # Arguments /// * `data` - a mock [`UserFollow`] object to insert /// * `force` - if we should skip the request stage - pub async fn create_userfollow(&self, data: UserFollow, force: bool) -> Result { + pub async fn create_userfollow( + &self, + data: UserFollow, + initiator: &User, + force: bool, + ) -> Result { if !force { - let other_user = self.get_user_by_id(data.receiver).await?; + let mut other_user = self.get_user_by_id(data.receiver).await?; if other_user.settings.private_profile { // send follow request instead @@ -254,6 +259,12 @@ impl DataManager { return Ok(FollowResult::Requested); } + + // check if we're staff + if initiator.permissions.check(FinePermission::STAFF_BADGE) { + self.add_achievement(&mut other_user, AchievementName::FollowedByStaff.into()) + .await?; + } } // ... diff --git a/crates/core/src/model/auth.rs b/crates/core/src/model/auth.rs index 4617770..11f015f 100644 --- a/crates/core/src/model/auth.rs +++ b/crates/core/src/model/auth.rs @@ -258,6 +258,9 @@ pub struct UserSettings { /// Automatically clear all notifications when notifications are viewed. #[serde(default)] pub auto_clear_notifs: bool, + /// Increase the text size of buttons and paragraphs. + #[serde(default)] + pub large_text: bool, } fn mime_avif() -> String { @@ -475,26 +478,26 @@ pub struct ExternalConnectionData { } /// The total number of achievements needed to 100% Tetratto! -pub const ACHIEVEMENTS: usize = 8; +pub const ACHIEVEMENTS: usize = 16; #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub enum AchievementName { - /// Create your first post. CreatePost, - /// Follow somebody. FollowUser, - /// Create your 50th post. Create50Posts, - /// Create your 100th post. Create100Posts, - /// Create your 1000th post. Create1000Posts, - /// Ask your first question. CreateQuestion, - /// Edit your settings. EditSettings, - /// Create your first journal. CreateJournal, + FollowedByStaff, + CreateDrawing, + OpenAchievements, + Get1Like, + Get10Likes, + Get50Likes, + Get100Likes, + Get25Dislikes, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] @@ -515,6 +518,14 @@ impl AchievementName { Self::CreateQuestion => "Big questions...", Self::EditSettings => "Just how I like it!", Self::CreateJournal => "Dear diary...", + Self::FollowedByStaff => "Big Shrimpin'", + Self::CreateDrawing => "Modern art", + Self::OpenAchievements => "Welcome!", + Self::Get1Like => "Baby steps!", + Self::Get10Likes => "WOW! 10 LIKES!", + Self::Get50Likes => "banger post follow for more", + Self::Get100Likes => "everyone liked that", + Self::Get25Dislikes => "Sorry...", } } @@ -528,19 +539,37 @@ impl AchievementName { Self::CreateQuestion => "Ask your first question!", Self::EditSettings => "Edit your settings.", Self::CreateJournal => "Create your first journal.", + Self::FollowedByStaff => "Get followed by a staff member!", + Self::CreateDrawing => "Include a drawing in a question.", + Self::OpenAchievements => "Open the achievements page.", + Self::Get1Like => "Get 1 like on a post! Good job!", + Self::Get10Likes => "Get 10 likes on one post.", + Self::Get50Likes => "Get 50 likes on one post.", + Self::Get100Likes => "Get 100 likes on one post.", + Self::Get25Dislikes => "Get 25 dislikes on one post... :(", } } pub fn rarity(&self) -> AchievementRarity { + // i don't want to write that long ass type name everywhere + use AchievementRarity::*; match self { - Self::CreatePost => AchievementRarity::Common, - Self::FollowUser => AchievementRarity::Common, - Self::Create50Posts => AchievementRarity::Uncommon, - Self::Create100Posts => AchievementRarity::Uncommon, - Self::Create1000Posts => AchievementRarity::Rare, - Self::CreateQuestion => AchievementRarity::Common, - Self::EditSettings => AchievementRarity::Common, - Self::CreateJournal => AchievementRarity::Uncommon, + Self::CreatePost => Common, + Self::FollowUser => Common, + Self::Create50Posts => Uncommon, + Self::Create100Posts => Uncommon, + Self::Create1000Posts => Rare, + Self::CreateQuestion => Common, + Self::EditSettings => Common, + Self::CreateJournal => Uncommon, + Self::FollowedByStaff => Rare, + Self::CreateDrawing => Common, + Self::OpenAchievements => Common, + Self::Get1Like => Common, + Self::Get10Likes => Common, + Self::Get50Likes => Uncommon, + Self::Get100Likes => Rare, + Self::Get25Dislikes => Uncommon, } } } diff --git a/crates/l10n/Cargo.toml b/crates/l10n/Cargo.toml index c50b714..1b3e5e1 100644 --- a/crates/l10n/Cargo.toml +++ b/crates/l10n/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tetratto-l10n" -version = "9.0.0" +version = "10.0.0" edition = "2024" authors.workspace = true repository.workspace = true diff --git a/crates/shared/Cargo.toml b/crates/shared/Cargo.toml index 8d48901..5fd4230 100644 --- a/crates/shared/Cargo.toml +++ b/crates/shared/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tetratto-shared" -version = "9.0.0" +version = "10.0.0" edition = "2024" authors.workspace = true repository.workspace = true