mirror of
https://github.com/LemmyNet/lemmy.git
synced 2025-01-20 13:58:20 +00:00
* Add support for donation dialog (fixes #4856) * more changes * test * remove files * default value for new user last_donation_notification * move disable_donation_dialog to local_site * restore formatting
This commit is contained in:
parent
4120c2fc2f
commit
67b36c6537
14 changed files with 78 additions and 44 deletions
19
crates/api/src/local_user/donation_dialog_shown.rs
Normal file
19
crates/api/src/local_user/donation_dialog_shown.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
use actix_web::web::{Data, Json};
|
||||
use chrono::Utc;
|
||||
use lemmy_api_common::{context::LemmyContext, SuccessResponse};
|
||||
use lemmy_db_schema::source::local_user::{LocalUser, LocalUserUpdateForm};
|
||||
use lemmy_db_views::structs::LocalUserView;
|
||||
use lemmy_utils::error::LemmyResult;
|
||||
|
||||
pub async fn donation_dialog_shown(
|
||||
context: Data<LemmyContext>,
|
||||
local_user_view: LocalUserView,
|
||||
) -> LemmyResult<Json<SuccessResponse>> {
|
||||
let form = LocalUserUpdateForm {
|
||||
last_donation_notification: Some(Utc::now()),
|
||||
..Default::default()
|
||||
};
|
||||
LocalUser::update(&mut context.pool(), local_user_view.local_user.id, &form).await?;
|
||||
|
||||
Ok(Json(SuccessResponse::default()))
|
||||
}
|
|
@ -3,6 +3,7 @@ pub mod ban_person;
|
|||
pub mod block;
|
||||
pub mod change_password;
|
||||
pub mod change_password_after_reset;
|
||||
pub mod donation_dialog_shown;
|
||||
pub mod generate_totp_secret;
|
||||
pub mod get_captcha;
|
||||
pub mod list_banned;
|
||||
|
|
|
@ -238,6 +238,8 @@ pub struct CreateSite {
|
|||
pub comment_upvotes: Option<FederationMode>,
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub comment_downvotes: Option<FederationMode>,
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub disable_donation_dialog: Option<bool>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
|
@ -365,6 +367,10 @@ pub struct EditSite {
|
|||
/// What kind of comment downvotes your site allows.
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub comment_downvotes: Option<FederationMode>,
|
||||
/// If this is true, users will never see the dialog asking to support Lemmy development with
|
||||
/// donations.
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub disable_donation_dialog: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
|
|
|
@ -105,6 +105,7 @@ pub async fn create_site(
|
|||
post_downvotes: data.post_downvotes,
|
||||
comment_upvotes: data.comment_upvotes,
|
||||
comment_downvotes: data.comment_downvotes,
|
||||
disable_donation_dialog: data.disable_donation_dialog,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ pub async fn update_site(
|
|||
post_downvotes: data.post_downvotes,
|
||||
comment_upvotes: data.comment_upvotes,
|
||||
comment_downvotes: data.comment_downvotes,
|
||||
disable_donation_dialog: data.disable_donation_dialog,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ use lemmy_api_common::{
|
|||
};
|
||||
use lemmy_db_schema::{
|
||||
aggregates::structs::PersonAggregates,
|
||||
newtypes::{InstanceId, OAuthProviderId, SiteId},
|
||||
newtypes::{InstanceId, OAuthProviderId},
|
||||
source::{
|
||||
actor_language::SiteLanguage,
|
||||
captcha_answer::{CaptchaAnswer, CheckCaptchaAnswer},
|
||||
|
@ -139,21 +139,11 @@ pub async fn register(
|
|||
email: data.email.as_deref().map(str::to_lowercase),
|
||||
show_nsfw: Some(show_nsfw),
|
||||
accepted_application,
|
||||
default_listing_type: Some(local_site.default_post_listing_type),
|
||||
post_listing_mode: Some(local_site.default_post_listing_mode),
|
||||
interface_language: language_tags.first().cloned(),
|
||||
// If its the initial site setup, they are an admin
|
||||
admin: Some(!local_site.site_setup),
|
||||
..LocalUserInsertForm::new(inserted_person.id, Some(data.password.to_string()))
|
||||
};
|
||||
|
||||
let inserted_local_user = create_local_user(
|
||||
&context,
|
||||
language_tags,
|
||||
&local_user_form,
|
||||
local_site.site_id,
|
||||
)
|
||||
.await?;
|
||||
let inserted_local_user =
|
||||
create_local_user(&context, language_tags, local_user_form, &local_site).await?;
|
||||
|
||||
if local_site.site_setup && require_registration_application {
|
||||
if let Some(answer) = data.answer.clone() {
|
||||
|
@ -369,20 +359,10 @@ pub async fn authenticate_with_oauth(
|
|||
show_nsfw: Some(show_nsfw),
|
||||
accepted_application: Some(!require_registration_application),
|
||||
email_verified: Some(oauth_provider.auto_verify_email),
|
||||
post_listing_mode: Some(local_site.default_post_listing_mode),
|
||||
interface_language: language_tags.first().cloned(),
|
||||
// If its the initial site setup, they are an admin
|
||||
admin: Some(!local_site.site_setup),
|
||||
..LocalUserInsertForm::new(person.id, None)
|
||||
};
|
||||
|
||||
local_user = create_local_user(
|
||||
&context,
|
||||
language_tags,
|
||||
&local_user_form,
|
||||
local_site.site_id,
|
||||
)
|
||||
.await?;
|
||||
local_user = create_local_user(&context, language_tags, local_user_form, &local_site).await?;
|
||||
|
||||
// Create the oauth account
|
||||
let oauth_account_form =
|
||||
|
@ -472,28 +452,33 @@ fn get_language_tags(req: &HttpRequest) -> Vec<String> {
|
|||
async fn create_local_user(
|
||||
context: &Data<LemmyContext>,
|
||||
language_tags: Vec<String>,
|
||||
local_user_form: &LocalUserInsertForm,
|
||||
local_site_id: SiteId,
|
||||
mut local_user_form: LocalUserInsertForm,
|
||||
local_site: &LocalSite,
|
||||
) -> Result<LocalUser, LemmyError> {
|
||||
let all_languages = Language::read_all(&mut context.pool()).await?;
|
||||
// use hashset to avoid duplicates
|
||||
let mut language_ids = HashSet::new();
|
||||
|
||||
// Enable languages from `Accept-Language` header
|
||||
for l in language_tags {
|
||||
if let Some(found) = all_languages.iter().find(|all| all.code == l) {
|
||||
for l in &language_tags {
|
||||
if let Some(found) = all_languages.iter().find(|all| &all.code == l) {
|
||||
language_ids.insert(found.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable site languages. Ignored if all languages are enabled.
|
||||
let discussion_languages = SiteLanguage::read(&mut context.pool(), local_site_id).await?;
|
||||
let discussion_languages = SiteLanguage::read(&mut context.pool(), local_site.site_id).await?;
|
||||
language_ids.extend(discussion_languages);
|
||||
|
||||
let language_ids = language_ids.into_iter().collect();
|
||||
|
||||
local_user_form.default_listing_type = Some(local_site.default_post_listing_type);
|
||||
local_user_form.post_listing_mode = Some(local_site.default_post_listing_mode);
|
||||
// If its the initial site setup, they are an admin
|
||||
local_user_form.admin = Some(!local_site.site_setup);
|
||||
local_user_form.interface_language = language_tags.first().cloned();
|
||||
let inserted_local_user =
|
||||
LocalUser::create(&mut context.pool(), local_user_form, language_ids).await?;
|
||||
LocalUser::create(&mut context.pool(), &local_user_form, language_ids).await?;
|
||||
|
||||
Ok(inserted_local_user)
|
||||
}
|
||||
|
|
|
@ -443,6 +443,7 @@ diesel::table! {
|
|||
post_downvotes -> FederationModeEnum,
|
||||
comment_upvotes -> FederationModeEnum,
|
||||
comment_downvotes -> FederationModeEnum,
|
||||
disable_donation_dialog -> Bool,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,6 +515,7 @@ diesel::table! {
|
|||
collapse_bot_comments -> Bool,
|
||||
default_comment_sort_type -> CommentSortTypeEnum,
|
||||
auto_mark_fetched_posts_as_read -> Bool,
|
||||
last_donation_notification -> Timestamptz,
|
||||
hide_media -> Bool,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,9 @@ pub struct LocalSite {
|
|||
pub comment_upvotes: FederationMode,
|
||||
/// What kind of comment downvotes your site allows.
|
||||
pub comment_downvotes: FederationMode,
|
||||
/// If this is true, users will never see the dialog asking to support Lemmy development with
|
||||
/// donations.
|
||||
pub disable_donation_dialog: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, derive_new::new)]
|
||||
|
@ -142,6 +145,8 @@ pub struct LocalSiteInsertForm {
|
|||
pub comment_upvotes: Option<FederationMode>,
|
||||
#[new(default)]
|
||||
pub comment_downvotes: Option<FederationMode>,
|
||||
#[new(default)]
|
||||
pub disable_donation_dialog: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
|
@ -175,4 +180,5 @@ pub struct LocalSiteUpdateForm {
|
|||
pub post_downvotes: Option<FederationMode>,
|
||||
pub comment_upvotes: Option<FederationMode>,
|
||||
pub comment_downvotes: Option<FederationMode>,
|
||||
pub disable_donation_dialog: Option<bool>,
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::{
|
|||
PostListingMode,
|
||||
PostSortType,
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
#[cfg(feature = "full")]
|
||||
|
@ -70,6 +71,9 @@ pub struct LocalUser {
|
|||
pub default_comment_sort_type: CommentSortType,
|
||||
/// Whether to automatically mark fetched posts as read.
|
||||
pub auto_mark_fetched_posts_as_read: bool,
|
||||
/// The last time a donation request was shown to this user. If this is more than a year ago,
|
||||
/// a new notification request should be shown.
|
||||
pub last_donation_notification: DateTime<Utc>,
|
||||
/// Whether to hide posts containing images/videos
|
||||
pub hide_media: bool,
|
||||
}
|
||||
|
@ -131,6 +135,8 @@ pub struct LocalUserInsertForm {
|
|||
#[new(default)]
|
||||
pub auto_mark_fetched_posts_as_read: Option<bool>,
|
||||
#[new(default)]
|
||||
pub last_donation_notification: Option<DateTime<Utc>>,
|
||||
#[new(default)]
|
||||
pub hide_media: Option<bool>,
|
||||
}
|
||||
|
||||
|
@ -164,5 +170,6 @@ pub struct LocalUserUpdateForm {
|
|||
pub collapse_bot_comments: Option<bool>,
|
||||
pub default_comment_sort_type: Option<CommentSortType>,
|
||||
pub auto_mark_fetched_posts_as_read: Option<bool>,
|
||||
pub last_donation_notification: Option<DateTime<Utc>>,
|
||||
pub hide_media: Option<bool>,
|
||||
}
|
||||
|
|
|
@ -235,15 +235,14 @@ mod tests {
|
|||
password_encrypted: inserted_sara_local_user.password_encrypted,
|
||||
open_links_in_new_tab: inserted_sara_local_user.open_links_in_new_tab,
|
||||
infinite_scroll_enabled: inserted_sara_local_user.infinite_scroll_enabled,
|
||||
admin: false,
|
||||
post_listing_mode: inserted_sara_local_user.post_listing_mode,
|
||||
totp_2fa_enabled: inserted_sara_local_user.totp_2fa_enabled,
|
||||
enable_keyboard_navigation: inserted_sara_local_user.enable_keyboard_navigation,
|
||||
enable_animated_images: inserted_sara_local_user.enable_animated_images,
|
||||
enable_private_messages: inserted_sara_local_user.enable_private_messages,
|
||||
collapse_bot_comments: inserted_sara_local_user.collapse_bot_comments,
|
||||
auto_mark_fetched_posts_as_read: false,
|
||||
hide_media: false,
|
||||
last_donation_notification: inserted_sara_local_user.last_donation_notification,
|
||||
..Default::default()
|
||||
},
|
||||
creator: Person {
|
||||
id: inserted_sara_person.id,
|
||||
|
|
|
@ -12,17 +12,14 @@ use url::Url;
|
|||
#[serde(default)]
|
||||
pub struct Settings {
|
||||
/// settings related to the postgresql database
|
||||
#[default(Default::default())]
|
||||
pub database: DatabaseConfig,
|
||||
/// Pictrs image server configuration.
|
||||
#[default(Some(Default::default()))]
|
||||
pub(crate) pictrs: Option<PictrsConfig>,
|
||||
/// Email sending configuration. All options except login/password are mandatory
|
||||
#[default(None)]
|
||||
#[doku(example = "Some(Default::default())")]
|
||||
pub email: Option<EmailConfig>,
|
||||
/// Parameters for automatic configuration of new instance (only used at first start)
|
||||
#[default(None)]
|
||||
#[doku(example = "Some(Default::default())")]
|
||||
pub setup: Option<SetupConfig>,
|
||||
/// the domain name of your instance (mandatory)
|
||||
|
@ -41,18 +38,14 @@ pub struct Settings {
|
|||
pub tls_enabled: bool,
|
||||
/// Set the URL for opentelemetry exports. If you do not have an opentelemetry collector, do not
|
||||
/// set this option
|
||||
#[default(None)]
|
||||
#[doku(skip)]
|
||||
pub opentelemetry_url: Option<Url>,
|
||||
#[default(Default::default())]
|
||||
pub federation: FederationWorkerConfig,
|
||||
// Prometheus configuration.
|
||||
#[default(None)]
|
||||
#[doku(example = "Some(Default::default())")]
|
||||
pub prometheus: Option<PrometheusConfig>,
|
||||
/// Sets a response Access-Control-Allow-Origin CORS header
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
|
||||
#[default(None)]
|
||||
#[doku(example = "lemmy.tld")]
|
||||
cors_origin: Option<String>,
|
||||
}
|
||||
|
@ -74,7 +67,6 @@ pub struct PictrsConfig {
|
|||
pub url: Url,
|
||||
|
||||
/// Set a custom pictrs API key. ( Required for deleting images )
|
||||
#[default(None)]
|
||||
pub api_key: Option<String>,
|
||||
|
||||
/// Specifies how to handle remote images, so that users don't have to connect directly to remote
|
||||
|
@ -114,7 +106,7 @@ pub struct PictrsConfig {
|
|||
pub image_upload_disabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document, PartialEq)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, Default, Document, PartialEq)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub enum PictrsImageMode {
|
||||
/// Leave images unchanged, don't generate any local thumbnails for post urls. Instead the
|
||||
|
@ -185,7 +177,7 @@ impl EmailConfig {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, SmartDefault, Document)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, Default, Document)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct SetupConfig {
|
||||
/// Username for the admin user
|
||||
|
@ -199,7 +191,6 @@ pub struct SetupConfig {
|
|||
pub site_name: String,
|
||||
/// Email for the admin user (optional, can be omitted and set later through the website)
|
||||
#[doku(example = "user@example.com")]
|
||||
#[default(None)]
|
||||
pub admin_email: Option<String>,
|
||||
}
|
||||
|
||||
|
|
6
migrations/2025-01-10-135505_donation-dialog/down.sql
Normal file
6
migrations/2025-01-10-135505_donation-dialog/down.sql
Normal file
|
@ -0,0 +1,6 @@
|
|||
ALTER TABLE local_user
|
||||
DROP COLUMN last_donation_notification;
|
||||
|
||||
ALTER TABLE local_site
|
||||
DROP COLUMN disable_donation_dialog;
|
||||
|
8
migrations/2025-01-10-135505_donation-dialog/up.sql
Normal file
8
migrations/2025-01-10-135505_donation-dialog/up.sql
Normal file
|
@ -0,0 +1,8 @@
|
|||
-- Generate new column last_donation_notification with default value at random time in the
|
||||
-- past year (so that users dont see it all at the same time after instance upgrade).
|
||||
ALTER TABLE local_user
|
||||
ADD COLUMN last_donation_notification timestamptz NOT NULL DEFAULT (now() - (random() * (interval '12 months')));
|
||||
|
||||
ALTER TABLE local_site
|
||||
ADD COLUMN disable_donation_dialog boolean NOT NULL DEFAULT FALSE;
|
||||
|
|
@ -26,6 +26,7 @@ use lemmy_api::{
|
|||
block::user_block_person,
|
||||
change_password::change_password,
|
||||
change_password_after_reset::change_password_after_reset,
|
||||
donation_dialog_shown::donation_dialog_shown,
|
||||
generate_totp_secret::generate_totp_secret,
|
||||
get_captcha::get_captcha,
|
||||
list_banned::list_banned_users,
|
||||
|
@ -331,6 +332,7 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
|||
.route("/unread_count", get().to(unread_count))
|
||||
.route("/list_logins", get().to(list_logins))
|
||||
.route("/validate_auth", get().to(validate_auth))
|
||||
.route("/donation_dialog_shown", post().to(donation_dialog_shown))
|
||||
.route("/avatar", post().to(upload_user_avatar))
|
||||
.route("/avatar", delete().to(delete_user_avatar))
|
||||
.route("/banner", post().to(upload_user_banner))
|
||||
|
|
Loading…
Reference in a new issue