lang | done | missing
--- | --- | ---
-de | 100% |
-eo | 86% | number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,theme,are_you_sure,yes,no
-es | 95% | archive_link,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default
-fr | 95% | archive_link,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default
-it | 96% | archive_link,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default
-nl | 88% | preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,theme
-ru | 82% | cross_posts,cross_post,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,recent_comments,theme,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no
-sv | 95% | archive_link,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default
-zh | 80% | cross_posts,cross_post,users,number_of_communities,preview,upload_image,formatting_help,view_source,sticky,unsticky,archive_link,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,recent_comments,nsfw,show_nsfw,theme,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no
+de | 97% | avatar,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw
+eo | 84% | number_of_communities,preview,upload_image,avatar,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,theme,are_you_sure,yes,no
+es | 92% | avatar,archive_link,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw
+fr | 92% | avatar,archive_link,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw
+it | 93% | avatar,archive_link,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw
+nl | 86% | preview,upload_image,avatar,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,theme
+ru | 80% | cross_posts,cross_post,number_of_communities,preview,upload_image,avatar,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,recent_comments,theme,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no
+sv | 92% | avatar,archive_link,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw
+zh | 78% | cross_posts,cross_post,users,number_of_communities,preview,upload_image,avatar,formatting_help,view_source,sticky,unsticky,archive_link,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,replies,mentions,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,recent_comments,nsfw,show_nsfw,theme,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no
If you'd like to update this report, run:
--- /dev/null
+-- the views
+drop view user_mention_view;
+drop view reply_view;
+drop view comment_view;
+drop view user_view;
+
+-- user
+create view user_view as
+select id,
+name,
+fedi_name,
+admin,
+banned,
+published,
+(select count(*) from post p where p.creator_id = u.id) as number_of_posts,
+(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score,
+(select count(*) from comment c where c.creator_id = u.id) as number_of_comments,
+(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score
+from user_ u;
+
+-- post
+-- Recreate the view
+drop view post_view;
+create view post_view as
+with all_post as
+(
+ select
+ p.*,
+ (select u.banned from user_ u where p.creator_id = u.id) as banned,
+ (select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community,
+ (select name from user_ where p.creator_id = user_.id) as creator_name,
+ (select name from community where p.community_id = community.id) as community_name,
+ (select removed from community c where p.community_id = c.id) as community_removed,
+ (select deleted from community c where p.community_id = c.id) as community_deleted,
+ (select nsfw from community c where p.community_id = c.id) as community_nsfw,
+ (select count(*) from comment where comment.post_id = p.id) as number_of_comments,
+ coalesce(sum(pl.score), 0) as score,
+ count (case when pl.score = 1 then 1 else null end) as upvotes,
+ count (case when pl.score = -1 then 1 else null end) as downvotes,
+ hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank
+ from post p
+ left join post_like pl on p.id = pl.post_id
+ group by p.id
+)
+
+select
+ap.*,
+u.id as user_id,
+coalesce(pl.score, 0) as my_vote,
+(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed,
+(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read,
+(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved
+from user_ u
+cross join all_post ap
+left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id
+
+union all
+
+select
+ap.*,
+null as user_id,
+null as my_vote,
+null as subscribed,
+null as read,
+null as saved
+from all_post ap
+;
+
+-- community
+
+drop view community_view;
+create view community_view as
+with all_community as
+(
+ select *,
+ (select name from user_ u where c.creator_id = u.id) as creator_name,
+ (select name from category ct where c.category_id = ct.id) as category_name,
+ (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers,
+ (select count(*) from post p where p.community_id = c.id) as number_of_posts,
+ (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments,
+ hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank
+ from community c
+)
+
+select
+ac.*,
+u.id as user_id,
+(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed
+from user_ u
+cross join all_community ac
+
+union all
+
+select
+ac.*,
+null as user_id,
+null as subscribed
+from all_community ac
+;
+
+-- Reply and comment view
+create view comment_view as
+with all_comment as
+(
+ select
+ c.*,
+ (select community_id from post p where p.id = c.post_id),
+ (select u.banned from user_ u where c.creator_id = u.id) as banned,
+ (select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community,
+ (select name from user_ where c.creator_id = user_.id) as creator_name,
+ coalesce(sum(cl.score), 0) as score,
+ count (case when cl.score = 1 then 1 else null end) as upvotes,
+ count (case when cl.score = -1 then 1 else null end) as downvotes
+ from comment c
+ left join comment_like cl on c.id = cl.comment_id
+ group by c.id
+)
+
+select
+ac.*,
+u.id as user_id,
+coalesce(cl.score, 0) as my_vote,
+(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved
+from user_ u
+cross join all_comment ac
+left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id
+
+union all
+
+select
+ ac.*,
+ null as user_id,
+ null as my_vote,
+ null as saved
+from all_comment ac
+;
+
+create view reply_view as
+with closereply as (
+ select
+ c2.id,
+ c2.creator_id as sender_id,
+ c.creator_id as recipient_id
+ from comment c
+ inner join comment c2 on c.id = c2.parent_id
+ where c2.creator_id != c.creator_id
+ -- Do union where post is null
+ union
+ select
+ c.id,
+ c.creator_id as sender_id,
+ p.creator_id as recipient_id
+ from comment c, post p
+ where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id
+)
+select cv.*,
+closereply.recipient_id
+from comment_view cv, closereply
+where closereply.id = cv.id
+;
+
+-- user mention
+create view user_mention_view as
+select
+ c.id,
+ um.id as user_mention_id,
+ c.creator_id,
+ c.post_id,
+ c.parent_id,
+ c.content,
+ c.removed,
+ um.read,
+ c.published,
+ c.updated,
+ c.deleted,
+ c.community_id,
+ c.banned,
+ c.banned_from_community,
+ c.creator_name,
+ c.score,
+ c.upvotes,
+ c.downvotes,
+ c.user_id,
+ c.my_vote,
+ c.saved,
+ um.recipient_id
+from user_mention um, comment_view c
+where um.comment_id = c.id;
+
+-- community tables
+drop view community_moderator_view;
+drop view community_follower_view;
+drop view community_user_ban_view;
+drop view site_view;
+
+create view community_moderator_view as
+select *,
+(select name from user_ u where cm.user_id = u.id) as user_name,
+(select name from community c where cm.community_id = c.id) as community_name
+from community_moderator cm;
+
+create view community_follower_view as
+select *,
+(select name from user_ u where cf.user_id = u.id) as user_name,
+(select name from community c where cf.community_id = c.id) as community_name
+from community_follower cf;
+
+create view community_user_ban_view as
+select *,
+(select name from user_ u where cm.user_id = u.id) as user_name,
+(select name from community c where cm.community_id = c.id) as community_name
+from community_user_ban cm;
+
+create view site_view as
+select *,
+(select name from user_ u where s.creator_id = u.id) as creator_name,
+(select count(*) from user_) as number_of_users,
+(select count(*) from post) as number_of_posts,
+(select count(*) from comment) as number_of_comments,
+(select count(*) from community) as number_of_communities
+from site s;
+
+alter table user_ rename column avatar to icon;
+alter table user_ alter column icon type bytea using icon::bytea;
--- /dev/null
+-- Rename to avatar
+alter table user_ rename column icon to avatar;
+alter table user_ alter column avatar type text;
+
+-- Rebuild nearly all the views, to include the creator avatars
+
+-- user
+drop view user_view;
+create view user_view as
+select id,
+name,
+avatar,
+fedi_name,
+admin,
+banned,
+published,
+(select count(*) from post p where p.creator_id = u.id) as number_of_posts,
+(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score,
+(select count(*) from comment c where c.creator_id = u.id) as number_of_comments,
+(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score
+from user_ u;
+
+-- post
+-- Recreate the view
+drop view post_view;
+create view post_view as
+with all_post as
+(
+ select
+ p.*,
+ (select u.banned from user_ u where p.creator_id = u.id) as banned,
+ (select cb.id::bool from community_user_ban cb where p.creator_id = cb.user_id and p.community_id = cb.community_id) as banned_from_community,
+ (select name from user_ where p.creator_id = user_.id) as creator_name,
+ (select avatar from user_ where p.creator_id = user_.id) as creator_avatar,
+ (select name from community where p.community_id = community.id) as community_name,
+ (select removed from community c where p.community_id = c.id) as community_removed,
+ (select deleted from community c where p.community_id = c.id) as community_deleted,
+ (select nsfw from community c where p.community_id = c.id) as community_nsfw,
+ (select count(*) from comment where comment.post_id = p.id) as number_of_comments,
+ coalesce(sum(pl.score), 0) as score,
+ count (case when pl.score = 1 then 1 else null end) as upvotes,
+ count (case when pl.score = -1 then 1 else null end) as downvotes,
+ hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank
+ from post p
+ left join post_like pl on p.id = pl.post_id
+ group by p.id
+)
+
+select
+ap.*,
+u.id as user_id,
+coalesce(pl.score, 0) as my_vote,
+(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed,
+(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read,
+(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved
+from user_ u
+cross join all_post ap
+left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id
+
+union all
+
+select
+ap.*,
+null as user_id,
+null as my_vote,
+null as subscribed,
+null as read,
+null as saved
+from all_post ap
+;
+
+
+-- community
+drop view community_view;
+create view community_view as
+with all_community as
+(
+ select *,
+ (select name from user_ u where c.creator_id = u.id) as creator_name,
+ (select avatar from user_ u where c.creator_id = u.id) as creator_avatar,
+ (select name from category ct where c.category_id = ct.id) as category_name,
+ (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers,
+ (select count(*) from post p where p.community_id = c.id) as number_of_posts,
+ (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments,
+ hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank
+ from community c
+)
+
+select
+ac.*,
+u.id as user_id,
+(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed
+from user_ u
+cross join all_community ac
+
+union all
+
+select
+ac.*,
+null as user_id,
+null as subscribed
+from all_community ac
+;
+
+-- reply and comment view
+drop view reply_view;
+drop view user_mention_view;
+drop view comment_view;
+create view comment_view as
+with all_comment as
+(
+ select
+ c.*,
+ (select community_id from post p where p.id = c.post_id),
+ (select u.banned from user_ u where c.creator_id = u.id) as banned,
+ (select cb.id::bool from community_user_ban cb, post p where c.creator_id = cb.user_id and p.id = c.post_id and p.community_id = cb.community_id) as banned_from_community,
+ (select name from user_ where c.creator_id = user_.id) as creator_name,
+ (select avatar from user_ where c.creator_id = user_.id) as creator_avatar,
+ coalesce(sum(cl.score), 0) as score,
+ count (case when cl.score = 1 then 1 else null end) as upvotes,
+ count (case when cl.score = -1 then 1 else null end) as downvotes
+ from comment c
+ left join comment_like cl on c.id = cl.comment_id
+ group by c.id
+)
+
+select
+ac.*,
+u.id as user_id,
+coalesce(cl.score, 0) as my_vote,
+(select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved
+from user_ u
+cross join all_comment ac
+left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id
+
+union all
+
+select
+ ac.*,
+ null as user_id,
+ null as my_vote,
+ null as saved
+from all_comment ac
+;
+
+create view reply_view as
+with closereply as (
+ select
+ c2.id,
+ c2.creator_id as sender_id,
+ c.creator_id as recipient_id
+ from comment c
+ inner join comment c2 on c.id = c2.parent_id
+ where c2.creator_id != c.creator_id
+ -- Do union where post is null
+ union
+ select
+ c.id,
+ c.creator_id as sender_id,
+ p.creator_id as recipient_id
+ from comment c, post p
+ where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id
+)
+select cv.*,
+closereply.recipient_id
+from comment_view cv, closereply
+where closereply.id = cv.id
+;
+
+-- user mention
+create view user_mention_view as
+select
+ c.id,
+ um.id as user_mention_id,
+ c.creator_id,
+ c.post_id,
+ c.parent_id,
+ c.content,
+ c.removed,
+ um.read,
+ c.published,
+ c.updated,
+ c.deleted,
+ c.community_id,
+ c.banned,
+ c.banned_from_community,
+ c.creator_name,
+ c.creator_avatar,
+ c.score,
+ c.upvotes,
+ c.downvotes,
+ c.user_id,
+ c.my_vote,
+ c.saved,
+ um.recipient_id
+from user_mention um, comment_view c
+where um.comment_id = c.id;
+
+-- community views
+drop view community_moderator_view;
+drop view community_follower_view;
+drop view community_user_ban_view;
+drop view site_view;
+
+create view community_moderator_view as
+select *,
+(select name from user_ u where cm.user_id = u.id) as user_name,
+(select avatar from user_ u where cm.user_id = u.id),
+(select name from community c where cm.community_id = c.id) as community_name
+from community_moderator cm;
+
+create view community_follower_view as
+select *,
+(select name from user_ u where cf.user_id = u.id) as user_name,
+(select avatar from user_ u where cf.user_id = u.id),
+(select name from community c where cf.community_id = c.id) as community_name
+from community_follower cf;
+
+create view community_user_ban_view as
+select *,
+(select name from user_ u where cm.user_id = u.id) as user_name,
+(select avatar from user_ u where cm.user_id = u.id),
+(select name from community c where cm.community_id = c.id) as community_name
+from community_user_ban cm;
+
+create view site_view as
+select *,
+(select name from user_ u where s.creator_id = u.id) as creator_name,
+(select avatar from user_ u where s.creator_id = u.id) as creator_avatar,
+(select count(*) from user_) as number_of_users,
+(select count(*) from post) as number_of_posts,
+(select count(*) from comment) as number_of_comments,
+(select count(*) from community) as number_of_communities
+from site s;
default_sort_type: i16,
default_listing_type: i16,
lang: String,
+ avatar: Option<String>,
auth: String,
}
name: data.username.to_owned(),
fedi_name: Settings::get().hostname.to_owned(),
email: data.email.to_owned(),
+ avatar: None,
password_encrypted: data.password.to_owned(),
preferred_username: None,
updated: None,
name: read_user.name,
fedi_name: read_user.fedi_name,
email: read_user.email,
+ avatar: data.avatar.to_owned(),
password_encrypted: read_user.password_encrypted,
preferred_username: read_user.preferred_username,
updated: Some(naive_now()),
data.username.to_owned().unwrap_or("admin".to_string()),
) {
Ok(user) => user.id,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_that_username_or_email"))?
+ Err(_e) => {
+ return Err(APIError::err(
+ &self.op,
+ "couldnt_find_that_username_or_email",
+ ))?
+ }
}
}
};
name: read_user.name,
fedi_name: read_user.fedi_name,
email: read_user.email,
+ avatar: read_user.avatar,
password_encrypted: read_user.password_encrypted,
preferred_username: read_user.preferred_username,
updated: Some(naive_now()),
name: read_user.name,
fedi_name: read_user.fedi_name,
email: read_user.email,
+ avatar: read_user.avatar,
password_encrypted: read_user.password_encrypted,
preferred_username: read_user.preferred_username,
updated: Some(naive_now()),
name: read_user.name,
fedi_name: read_user.fedi_name,
email: read_user.email,
+ avatar: read_user.avatar,
password_encrypted: data.password.to_owned(),
preferred_username: read_user.preferred_username,
updated: Some(naive_now()),
preferred_username: None,
password_encrypted: "here".into(),
email: None,
- icon: None,
+ avatar: None,
published: naive_now(),
admin: false,
banned: false,
preferred_username: None,
password_encrypted: "nope".into(),
email: None,
+ avatar: None,
admin: false,
banned: false,
updated: None,
banned -> Bool,
banned_from_community -> Bool,
creator_name -> Varchar,
+ creator_avatar -> Nullable<Text>,
score -> BigInt,
upvotes -> BigInt,
downvotes -> BigInt,
pub banned: bool,
pub banned_from_community: bool,
pub creator_name: String,
+ pub creator_avatar: Option<String>,
pub score: i64,
pub upvotes: i64,
pub downvotes: i64,
banned -> Bool,
banned_from_community -> Bool,
creator_name -> Varchar,
+ creator_avatar -> Nullable<Text>,
score -> BigInt,
upvotes -> BigInt,
downvotes -> BigInt,
pub banned: bool,
pub banned_from_community: bool,
pub creator_name: String,
+ pub creator_avatar: Option<String>,
pub score: i64,
pub upvotes: i64,
pub downvotes: i64,
preferred_username: None,
password_encrypted: "nope".into(),
email: None,
+ avatar: None,
admin: false,
banned: false,
updated: None,
published: inserted_comment.published,
updated: None,
creator_name: inserted_user.name.to_owned(),
+ creator_avatar: None,
score: 1,
downvotes: 0,
upvotes: 1,
published: inserted_comment.published,
updated: None,
creator_name: inserted_user.name.to_owned(),
+ creator_avatar: None,
score: 1,
downvotes: 0,
upvotes: 1,
preferred_username: None,
password_encrypted: "nope".into(),
email: None,
+ avatar: None,
admin: false,
banned: false,
updated: None,
deleted -> Bool,
nsfw -> Bool,
creator_name -> Varchar,
+ creator_avatar -> Nullable<Text>,
category_name -> Varchar,
number_of_subscribers -> BigInt,
number_of_posts -> BigInt,
user_id -> Int4,
published -> Timestamp,
user_name -> Varchar,
+ avatar -> Nullable<Text>,
community_name -> Varchar,
}
}
user_id -> Int4,
published -> Timestamp,
user_name -> Varchar,
+ avatar -> Nullable<Text>,
community_name -> Varchar,
}
}
user_id -> Int4,
published -> Timestamp,
user_name -> Varchar,
+ avatar -> Nullable<Text>,
community_name -> Varchar,
}
}
pub deleted: bool,
pub nsfw: bool,
pub creator_name: String,
+ pub creator_avatar: Option<String>,
pub category_name: String,
pub number_of_subscribers: i64,
pub number_of_posts: i64,
pub user_id: i32,
pub published: chrono::NaiveDateTime,
pub user_name: String,
+ pub avatar: Option<String>,
pub community_name: String,
}
pub user_id: i32,
pub published: chrono::NaiveDateTime,
pub user_name: String,
+ pub avatar: Option<String>,
pub community_name: String,
}
pub user_id: i32,
pub published: chrono::NaiveDateTime,
pub user_name: String,
+ pub avatar: Option<String>,
pub community_name: String,
}
preferred_username: None,
password_encrypted: "nope".into(),
email: None,
+ avatar: None,
admin: false,
banned: false,
updated: None,
preferred_username: None,
password_encrypted: "nope".into(),
email: None,
+ avatar: None,
admin: false,
banned: false,
updated: None,
preferred_username: None,
password_encrypted: "nope".into(),
email: None,
+ avatar: None,
admin: false,
banned: false,
updated: None,
preferred_username: None,
password_encrypted: "nope".into(),
email: None,
+ avatar: None,
admin: false,
banned: false,
updated: None,
banned_from_community -> Bool,
stickied -> Bool,
creator_name -> Varchar,
+ creator_avatar -> Nullable<Text>,
community_name -> Varchar,
community_removed -> Bool,
community_deleted -> Bool,
pub banned_from_community: bool,
pub stickied: bool,
pub creator_name: String,
+ pub creator_avatar: Option<String>,
pub community_name: String,
pub community_removed: bool,
pub community_deleted: bool,
preferred_username: None,
password_encrypted: "nope".into(),
email: None,
+ avatar: None,
updated: None,
admin: false,
banned: false,
body: None,
creator_id: inserted_user.id,
creator_name: user_name.to_owned(),
+ creator_avatar: None,
banned: false,
banned_from_community: false,
community_id: inserted_community.id,
stickied: false,
creator_id: inserted_user.id,
creator_name: user_name.to_owned(),
+ creator_avatar: None,
banned: false,
banned_from_community: false,
community_id: inserted_community.id,
open_registration -> Bool,
enable_nsfw -> Bool,
creator_name -> Varchar,
+ creator_avatar -> Nullable<Text>,
number_of_users -> BigInt,
number_of_posts -> BigInt,
number_of_comments -> BigInt,
pub open_registration: bool,
pub enable_nsfw: bool,
pub creator_name: String,
+ pub creator_avatar: Option<String>,
pub number_of_users: i64,
pub number_of_posts: i64,
pub number_of_comments: i64,
pub preferred_username: Option<String>,
pub password_encrypted: String,
pub email: Option<String>,
- pub icon: Option<Vec<u8>>,
+ pub avatar: Option<String>,
pub admin: bool,
pub banned: bool,
pub published: chrono::NaiveDateTime,
pub admin: bool,
pub banned: bool,
pub email: Option<String>,
+ pub avatar: Option<String>,
pub updated: Option<chrono::NaiveDateTime>,
pub show_nsfw: bool,
pub theme: String,
pub default_sort_type: i16,
pub default_listing_type: i16,
pub lang: String,
+ pub avatar: Option<String>,
}
impl Claims {
default_sort_type: self.default_sort_type,
default_listing_type: self.default_listing_type,
lang: self.lang.to_owned(),
+ avatar: self.avatar.to_owned(),
};
encode(
&Header::default(),
preferred_username: None,
password_encrypted: "nope".into(),
email: None,
+ avatar: None,
admin: false,
banned: false,
updated: None,
preferred_username: None,
password_encrypted: "nope".into(),
email: None,
- icon: None,
+ avatar: None,
admin: false,
banned: false,
published: inserted_user.published,
preferred_username: None,
password_encrypted: "nope".into(),
email: None,
+ avatar: None,
admin: false,
banned: false,
updated: None,
preferred_username: None,
password_encrypted: "nope".into(),
email: None,
+ avatar: None,
admin: false,
banned: false,
updated: None,
banned -> Bool,
banned_from_community -> Bool,
creator_name -> Varchar,
+ creator_avatar -> Nullable<Text>,
score -> BigInt,
upvotes -> BigInt,
downvotes -> BigInt,
pub banned: bool,
pub banned_from_community: bool,
pub creator_name: String,
+ pub creator_avatar: Option<String>,
pub score: i64,
pub upvotes: i64,
pub downvotes: i64,
UserMentionQueryBuilder {
conn,
query,
- for_user_id: for_user_id,
+ for_user_id,
sort: &SortType::New,
unread_only: false,
page: None,
user_view (id) {
id -> Int4,
name -> Varchar,
+ avatar -> Nullable<Text>,
fedi_name -> Varchar,
admin -> Bool,
banned -> Bool,
pub struct UserView {
pub id: i32,
pub name: String,
+ pub avatar: Option<String>,
pub fedi_name: String,
pub admin: bool,
pub banned: bool,
preferred_username -> Nullable<Varchar>,
password_encrypted -> Text,
email -> Nullable<Text>,
- icon -> Nullable<Bytea>,
+ avatar -> Nullable<Text>,
admin -> Bool,
banned -> Bool,
published -> Timestamp,
--- /dev/null
+fuse.js
+translation_report.ts
-const {
+import {
FuseBox,
Sparky,
EnvPlugin,
CSSPlugin,
WebIndexPlugin,
- QuantumPlugin
-} = require('fuse-box');
+ QuantumPlugin,
+} from 'fuse-box';
// const transformInferno = require('../../dist').default
const transformInferno = require('ts-transform-inferno').default;
const transformClasscat = require('ts-transform-classcat').default;
before: [transformClasscat(), transformInferno()],
},
alias: {
- 'locale': 'moment/locale'
- },
+ locale: 'moment/locale',
+ },
plugins: [
EnvPlugin({ NODE_ENV: isProduction ? 'production' : 'development' }),
CSSPlugin(),
WebIndexPlugin({
title: 'Inferno Typescript FuseBox Example',
template: 'src/index.html',
- path: isProduction ? "/static" : "/"
+ path: isProduction ? '/static' : '/',
}),
isProduction &&
- QuantumPlugin({
- bakeApiIntoBundle: 'app',
- treeshake: true,
- uglify: true,
- }),
+ QuantumPlugin({
+ bakeApiIntoBundle: 'app',
+ treeshake: true,
+ uglify: true,
+ }),
],
});
app = fuse.bundle('app').instructions('>index.tsx');
// Sparky.task('version', _ => setVersion());
Sparky.task('clean', _ => Sparky.src('dist/').clean('dist/'));
Sparky.task('env', _ => (isProduction = true));
-Sparky.task('copy-assets', () => Sparky.src('assets/**/**.*').dest(isProduction ? 'dist/' : 'dist/static'));
+Sparky.task('copy-assets', () =>
+ Sparky.src('assets/**/**.*').dest(isProduction ? 'dist/' : 'dist/static')
+);
Sparky.task('dev', ['clean', 'config', 'copy-assets'], _ => {
fuse.dev();
app.hmr().watch();
BanType,
} from '../interfaces';
import { WebSocketService, UserService } from '../services';
-import { mdToHtml, getUnixTime, canMod, isMod } from '../utils';
+import {
+ mdToHtml,
+ getUnixTime,
+ canMod,
+ isMod,
+ pictshareAvatarThumbnail,
+} from '../utils';
import * as moment from 'moment';
import { MomentTime } from './moment-time';
import { CommentForm } from './comment-form';
className="text-info"
to={`/u/${node.comment.creator_name}`}
>
- {node.comment.creator_name}
+ {node.comment.creator_avatar && (
+ <img
+ height="32"
+ width="32"
+ src={pictshareAvatarThumbnail(node.comment.creator_avatar)}
+ class="rounded-circle mr-1"
+ />
+ )}
+ <span>{node.comment.creator_name}</span>
</Link>
</li>
{this.isMod && (
routeSortTypeToEnum,
routeListingTypeToEnum,
postRefetchSeconds,
+ pictshareAvatarThumbnail,
} from '../utils';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
number_of_posts: null,
number_of_comments: null,
number_of_communities: null,
+ enable_downvotes: null,
+ open_registration: null,
+ enable_nsfw: null,
},
admins: [],
banned: [],
{this.state.site.admins.map(admin => (
<li class="list-inline-item">
<Link class="text-info" to={`/u/${admin.name}`}>
- {admin.name}
+ {admin.avatar && (
+ <img
+ height="32"
+ width="32"
+ src={pictshareAvatarThumbnail(admin.avatar)}
+ class="rounded-circle mr-1"
+ />
+ )}
+ <span>{admin.name}</span>
</Link>
</li>
))}
GetSiteResponse,
Comment,
} from '../interfaces';
-import { msgOp } from '../utils';
+import { msgOp, pictshareAvatarThumbnail } from '../utils';
import { version } from '../version';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
class="nav-link"
to={`/u/${UserService.Instance.user.username}`}
>
- {UserService.Instance.user.username}
+ <span>
+ {UserService.Instance.user.avatar && (
+ <img
+ src={pictshareAvatarThumbnail(
+ UserService.Instance.user.avatar
+ )}
+ height="32"
+ width="32"
+ class="rounded-circle mr-2"
+ />
+ )}
+ {UserService.Instance.user.username}
+ </span>
</Link>
</li>
</>
isImage,
isVideo,
getUnixTime,
+ pictshareAvatarThumbnail,
} from '../utils';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
<li className="list-inline-item">
<span>{i18n.t('by')} </span>
<Link className="text-info" to={`/u/${post.creator_name}`}>
- {post.creator_name}
+ {post.creator_avatar && (
+ <img
+ height="32"
+ width="32"
+ src={pictshareAvatarThumbnail(post.creator_avatar)}
+ class="rounded-circle mr-1"
+ />
+ )}
+ <span>{post.creator_name}</span>
</Link>
{this.isMod && (
<span className="mx-1 badge badge-light">
fetchLimit,
routeSearchTypeToEnum,
routeSortTypeToEnum,
+ pictshareAvatarThumbnail,
} from '../utils';
import { PostListing } from './post-listing';
import { SortSelect } from './sort-select';
<Link
className="text-info"
to={`/u/${(i.data as UserView).name}`}
- >{`/u/${(i.data as UserView).name}`}</Link>
+ >
+ {(i.data as UserView).avatar && (
+ <img
+ height="32"
+ width="32"
+ src={pictshareAvatarThumbnail(
+ (i.data as UserView).avatar
+ )}
+ class="rounded-circle mr-1"
+ />
+ )}
+ <span>{`/u/${(i.data as UserView).name}`}</span>
+ </Link>
</span>
<span>{` - ${
(i.data as UserView).comment_score
UserView,
} from '../interfaces';
import { WebSocketService, UserService } from '../services';
-import { mdToHtml, getUnixTime } from '../utils';
+import { mdToHtml, getUnixTime, pictshareAvatarThumbnail } from '../utils';
import { CommunityForm } from './community-form';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
{this.props.moderators.map(mod => (
<li class="list-inline-item">
<Link class="text-info" to={`/u/${mod.user_name}`}>
- {mod.user_name}
+ {mod.avatar && (
+ <img
+ height="32"
+ width="32"
+ src={pictshareAvatarThumbnail(mod.avatar)}
+ class="rounded-circle mr-1"
+ />
+ )}
+ <span>{mod.user_name}</span>
</Link>
</li>
))}
sort: SortType;
page: number;
loading: boolean;
+ avatarLoading: boolean;
userSettingsForm: UserSettingsForm;
userSettingsLoading: boolean;
deleteAccountLoading: boolean;
number_of_comments: null,
comment_score: null,
banned: null,
+ avatar: null,
},
user_id: null,
username: null,
posts: [],
admins: [],
loading: true,
+ avatarLoading: false,
view: this.getViewFromProps(this.props),
sort: this.getSortTypeFromProps(this.props),
page: this.getPageFromProps(this.props),
default_sort_type: null,
default_listing_type: null,
lang: null,
+ avatar: null,
auth: null,
},
userSettingsLoading: null,
) : (
<div class="row">
<div class="col-12 col-md-8">
- <h5>/u/{this.state.user.name}</h5>
+ <h5>
+ {this.state.user.avatar && (
+ <img
+ height="80"
+ width="80"
+ src={this.state.user.avatar}
+ class="rounded-circle mr-2"
+ />
+ )}
+ <span>/u/{this.state.user.name}</span>
+ </h5>
{this.selects()}
{this.state.view == View.Overview && this.overview()}
{this.state.view == View.Comments && this.comments()}
<T i18nKey="settings">#</T>
</h5>
<form onSubmit={linkEvent(this, this.handleUserSettingsSubmit)}>
+ <div class="form-group">
+ <div class="col-12">
+ <label>
+ <T i18nKey="avatar">#</T>
+ </label>
+ <form class="d-inline">
+ <label
+ htmlFor="file-upload"
+ class="pointer ml-4 text-muted small font-weight-bold"
+ >
+ <img
+ height="80"
+ width="80"
+ src={
+ this.state.userSettingsForm.avatar
+ ? this.state.userSettingsForm.avatar
+ : 'https://via.placeholder.com/300/000?text=Avatar'
+ }
+ class="rounded-circle"
+ />
+ </label>
+ <input
+ id="file-upload"
+ type="file"
+ accept="image/*,video/*"
+ name="file"
+ class="d-none"
+ disabled={!UserService.Instance.user}
+ onChange={linkEvent(this, this.handleImageUpload)}
+ />
+ </form>
+ </div>
+ </div>
<div class="form-group">
<div class="col-12">
<label>
this.setState(this.state);
}
+ handleImageUpload(i: User, event: any) {
+ event.preventDefault();
+ let file = event.target.files[0];
+ const imageUploadUrl = `/pictshare/api/upload.php`;
+ const formData = new FormData();
+ formData.append('file', file);
+
+ i.state.avatarLoading = true;
+ i.setState(i.state);
+
+ fetch(imageUploadUrl, {
+ method: 'POST',
+ body: formData,
+ })
+ .then(res => res.json())
+ .then(res => {
+ let url = `${window.location.origin}/pictshare/${res.url}`;
+ if (res.filetype == 'mp4') {
+ url += '/raw';
+ }
+ i.state.userSettingsForm.avatar = url;
+ console.log(url);
+ i.state.avatarLoading = false;
+ i.setState(i.state);
+ })
+ .catch(error => {
+ i.state.avatarLoading = false;
+ i.setState(i.state);
+ alert(error);
+ });
+ }
+
handleUserSettingsSubmit(i: User, event: any) {
event.preventDefault();
i.state.userSettingsLoading = true;
this.state.userSettingsForm.default_listing_type =
UserService.Instance.user.default_listing_type;
this.state.userSettingsForm.lang = UserService.Instance.user.lang;
+ this.state.userSettingsForm.avatar = UserService.Instance.user.avatar;
}
document.title = `/u/${this.state.user.name} - ${WebSocketService.Instance.site.name}`;
window.scrollTo(0, 0);
default_sort_type: SortType;
default_listing_type: ListingType;
lang: string;
+ avatar?: string;
}
export interface UserView {
id: number;
name: string;
+ avatar?: string;
fedi_name: string;
published: string;
number_of_posts: number;
id: number;
user_id: number;
user_name: string;
+ avatar?: string;
community_id: number;
community_name: string;
published: string;
published: string;
updated?: string;
creator_name: string;
+ creator_avatar?: string;
category_name: string;
number_of_subscribers: number;
number_of_posts: number;
published: string;
updated?: string;
creator_name: string;
+ creator_avatar?: string;
community_name: string;
community_removed: boolean;
community_deleted: boolean;
banned: boolean;
banned_from_community: boolean;
creator_name: string;
+ creator_avatar?: string;
score: number;
upvotes: number;
downvotes: number;
default_sort_type: SortType;
default_listing_type: ListingType;
lang: string;
+ avatar?: string;
auth: string;
}
cancel: 'Cancel',
preview: 'Preview',
upload_image: 'upload image',
+ avatar: 'Avatar',
formatting_help: 'formatting help',
view_source: 'view source',
unlock: 'unlock',
});
return ret;
}
+
+export function pictshareAvatarThumbnail(src: string): string {
+ // sample url: http://localhost:8535/pictshare/gs7xuu.jpg
+ let split = src.split('pictshare');
+ let out = `${split[0]}pictshare/96x96${split[1]}`;
+ return out;
+}
import { it } from './src/translations/it';
let files = [
- {t: de, n: 'de'},
- {t: eo, n: 'eo'},
- {t: es, n: 'es'},
- {t: fr, n: 'fr'},
- {t: it, n: 'it'},
- {t: nl, n: 'nl'},
- {t: ru, n: 'ru'},
- {t: sv, n: 'sv'},
- {t: zh, n: 'zh'},
+ { t: de, n: 'de' },
+ { t: eo, n: 'eo' },
+ { t: es, n: 'es' },
+ { t: fr, n: 'fr' },
+ { t: it, n: 'it' },
+ { t: nl, n: 'nl' },
+ { t: ru, n: 'ru' },
+ { t: sv, n: 'sv' },
+ { t: zh, n: 'zh' },
];
let masterKeys = Object.keys(en.translation);
for (let file of files) {
let keys = Object.keys(file.t.translation);
- let pct: number = (keys.length / masterKeys.length * 100);
+ let pct: number = (keys.length / masterKeys.length) * 100;
let missing = difference(masterKeys, keys);
report += `${file.n} | ${pct.toFixed(0)}% | ${missing} \n`;
}