mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-26 18:00:31 +00:00
Add user bios (#1043)
* Add user bios * Version v0.7.35 * Add domain name change instructions to docs. (#1044) * Add domain name change instructions to docs. * Changing docker execs to docker-compose execs * Set maxLength to user bio and render as md * Fix bio updating after SaveUserSetting Co-authored-by: Dessalines <tyhou13@gmx.com> Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
This commit is contained in:
parent
e31f74c3ad
commit
1acb51105a
6 changed files with 57 additions and 6 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -16,5 +16,6 @@ ui/src/translations
|
|||
|
||||
# ide config
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
target
|
||||
|
|
|
@ -97,6 +97,7 @@ pub struct SaveUserSettings {
|
|||
lang: String,
|
||||
avatar: Option<String>,
|
||||
email: Option<String>,
|
||||
bio: Option<String>,
|
||||
matrix_user_id: Option<String>,
|
||||
new_password: Option<String>,
|
||||
new_password_verify: Option<String>,
|
||||
|
@ -557,6 +558,17 @@ impl Perform for Oper<SaveUserSettings> {
|
|||
None => read_user.email,
|
||||
};
|
||||
|
||||
let bio = match &data.bio {
|
||||
Some(bio) => {
|
||||
if bio.chars().count() <= 300 {
|
||||
Some(bio.to_owned())
|
||||
} else {
|
||||
return Err(APIError::err("bio_length_overflow").into());
|
||||
}
|
||||
}
|
||||
None => read_user.bio,
|
||||
};
|
||||
|
||||
let avatar = match &data.avatar {
|
||||
Some(avatar) => Some(avatar.to_owned()),
|
||||
None => read_user.avatar,
|
||||
|
@ -613,7 +625,7 @@ impl Perform for Oper<SaveUserSettings> {
|
|||
show_avatars: data.show_avatars,
|
||||
send_notifications_to_email: data.send_notifications_to_email,
|
||||
actor_id: read_user.actor_id,
|
||||
bio: read_user.bio,
|
||||
bio,
|
||||
local: read_user.local,
|
||||
private_key: read_user.private_key,
|
||||
public_key: read_user.public_key,
|
||||
|
|
3
ui/src/components/markdown-textarea.tsx
vendored
3
ui/src/components/markdown-textarea.tsx
vendored
|
@ -21,6 +21,7 @@ interface MarkdownTextAreaProps {
|
|||
replyType?: boolean;
|
||||
focus?: boolean;
|
||||
disabled?: boolean;
|
||||
maxLength?: number;
|
||||
onSubmit?(msg: { val: string; formId: string }): any;
|
||||
onContentChange?(val: string): any;
|
||||
onReplyCancel?(): any;
|
||||
|
@ -121,7 +122,7 @@ export class MarkdownTextArea extends Component<
|
|||
required
|
||||
disabled={this.props.disabled}
|
||||
rows={2}
|
||||
maxLength={10000}
|
||||
maxLength={this.props.maxLength || 10000}
|
||||
/>
|
||||
{this.state.previewMode && (
|
||||
<div
|
||||
|
|
40
ui/src/components/user.tsx
vendored
40
ui/src/components/user.tsx
vendored
|
@ -31,6 +31,7 @@ import {
|
|||
toast,
|
||||
setupTippy,
|
||||
getLanguage,
|
||||
mdToHtml,
|
||||
} from '../utils';
|
||||
import { UserListing } from './user-listing';
|
||||
import { SortSelect } from './sort-select';
|
||||
|
@ -39,6 +40,7 @@ import { MomentTime } from './moment-time';
|
|||
import { i18n } from '../i18next';
|
||||
import moment from 'moment';
|
||||
import { UserDetails } from './user-details';
|
||||
import { MarkdownTextArea } from './markdown-textarea';
|
||||
|
||||
interface UserState {
|
||||
user: UserView;
|
||||
|
@ -109,6 +111,7 @@ export class User extends Component<any, UserState> {
|
|||
show_avatars: null,
|
||||
send_notifications_to_email: null,
|
||||
auth: null,
|
||||
bio: null,
|
||||
},
|
||||
userSettingsLoading: null,
|
||||
deleteAccountLoading: null,
|
||||
|
@ -149,7 +152,13 @@ export class User extends Component<any, UserState> {
|
|||
this.handleUserSettingsListingTypeChange = this.handleUserSettingsListingTypeChange.bind(
|
||||
this
|
||||
);
|
||||
this.handleUserSettingsListingTypeChange = this.handleUserSettingsListingTypeChange.bind(
|
||||
this
|
||||
);
|
||||
this.handlePageChange = this.handlePageChange.bind(this);
|
||||
this.handleUserSettingsBioChange = this.handleUserSettingsBioChange.bind(
|
||||
this
|
||||
);
|
||||
|
||||
this.state.user_id = Number(this.props.match.params.id) || null;
|
||||
this.state.username = this.props.match.params.username;
|
||||
|
@ -375,6 +384,12 @@ export class User extends Component<any, UserState> {
|
|||
)}
|
||||
</ul>
|
||||
</h5>
|
||||
<div className="d-flex align-items-center mb-2">
|
||||
<div
|
||||
className="md-div"
|
||||
dangerouslySetInnerHTML={mdToHtml(user.bio)}
|
||||
/>
|
||||
</div>
|
||||
<div className="d-flex align-items-center mb-2">
|
||||
<svg class="icon">
|
||||
<use xlinkHref="#icon-cake"></use>
|
||||
|
@ -570,6 +585,18 @@ export class User extends Component<any, UserState> {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-lg-3 col-form-label" htmlFor="user-bio">
|
||||
{i18n.t('bio')}
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<MarkdownTextArea
|
||||
initialContent={this.state.userSettingsForm.bio}
|
||||
onContentChange={this.handleUserSettingsBioChange}
|
||||
maxLength={300}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-lg-5 col-form-label">
|
||||
<a
|
||||
|
@ -900,6 +927,11 @@ export class User extends Component<any, UserState> {
|
|||
i.setState(i.state);
|
||||
}
|
||||
|
||||
handleUserSettingsBioChange(val: string) {
|
||||
this.state.userSettingsForm.bio = val;
|
||||
this.setState(this.state);
|
||||
}
|
||||
|
||||
handleUserSettingsMatrixUserIdChange(i: User, event: any) {
|
||||
i.state.userSettingsForm.matrix_user_id = event.target.value;
|
||||
if (
|
||||
|
@ -1057,6 +1089,7 @@ export class User extends Component<any, UserState> {
|
|||
this.state.userSettingsForm.lang = UserService.Instance.user.lang;
|
||||
this.state.userSettingsForm.avatar = UserService.Instance.user.avatar;
|
||||
this.state.userSettingsForm.email = this.state.user.email;
|
||||
this.state.userSettingsForm.bio = this.state.user.bio;
|
||||
this.state.userSettingsForm.send_notifications_to_email = this.state.user.send_notifications_to_email;
|
||||
this.state.userSettingsForm.show_avatars =
|
||||
UserService.Instance.user.show_avatars;
|
||||
|
@ -1068,9 +1101,10 @@ export class User extends Component<any, UserState> {
|
|||
} else if (res.op == UserOperation.SaveUserSettings) {
|
||||
const data = res.data as LoginResponse;
|
||||
UserService.Instance.login(data);
|
||||
this.setState({
|
||||
userSettingsLoading: false,
|
||||
});
|
||||
this.state.user.bio = this.state.userSettingsForm.bio;
|
||||
this.state.userSettingsLoading = false;
|
||||
this.setState(this.state);
|
||||
|
||||
window.scrollTo(0, 0);
|
||||
} else if (res.op == UserOperation.DeleteAccount) {
|
||||
this.setState({
|
||||
|
|
1
ui/src/interfaces.ts
vendored
1
ui/src/interfaces.ts
vendored
|
@ -597,6 +597,7 @@ export interface UserSettingsForm {
|
|||
lang: string;
|
||||
avatar?: string;
|
||||
email?: string;
|
||||
bio?: string;
|
||||
matrix_user_id?: string;
|
||||
new_password?: string;
|
||||
new_password_verify?: string;
|
||||
|
|
4
ui/translations/en.json
vendored
4
ui/translations/en.json
vendored
|
@ -228,6 +228,7 @@
|
|||
"landing_0":
|
||||
"Lemmy is a <1>link aggregator</1> / reddit alternative, intended to work in the <2>fediverse</2>.<3></3>It's self-hostable, has live-updating comment threads, and is tiny (<4>~80kB</4>). Federation into the ActivityPub network is on the roadmap. <5></5>This is a <6>very early beta version</6>, and a lot of features are currently broken or missing. <7></7>Suggest new features or report bugs <8>here.</8><9></9>Made with <10>Rust</10>, <11>Actix</11>, <12>Inferno</12>, <13>Typescript</13>. <14></14> <15>Thank you to our contributors: </15> dessalines, Nutomic, asonix, zacanger, and iav.",
|
||||
"not_logged_in": "Not logged in.",
|
||||
"bio_length_overflow": "User bio cannot exceed 300 characters!",
|
||||
"logged_in": "Logged in.",
|
||||
"must_login": "You must <1>log in or register</1> to comment.",
|
||||
"site_saved": "Site Saved.",
|
||||
|
@ -284,5 +285,6 @@
|
|||
"cake_day_info": "It's {{ creator_name }}'s cake day today!",
|
||||
"invalid_post_title": "Invalid post title",
|
||||
"invalid_url": "Invalid URL.",
|
||||
"play_captcha_audio": "Play Captcha Audio"
|
||||
"play_captcha_audio": "Play Captcha Audio",
|
||||
"bio": "Bio"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue