Fix up post, profile and community forms. Fixes #409 (#423)

This commit is contained in:
Dessalines 2021-09-18 16:40:59 -04:00 committed by GitHub
parent ba07aa3126
commit 8f132f67fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 154 additions and 132 deletions

View file

@ -20,6 +20,7 @@ import { i18n } from "../../i18next";
import { UserService, WebSocketService } from "../../services"; import { UserService, WebSocketService } from "../../services";
import { import {
authField, authField,
donateLemmyUrl,
fetchLimit, fetchLimit,
getLanguage, getLanguage,
isBrowser, isBrowser,
@ -28,7 +29,6 @@ import {
numToSI, numToSI,
setTheme, setTheme,
showAvatars, showAvatars,
supportLemmyUrl,
toast, toast,
wsClient, wsClient,
wsJsonToRes, wsJsonToRes,
@ -241,7 +241,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
<a <a
className="nav-link" className="nav-link"
title={i18n.t("support_lemmy")} title={i18n.t("support_lemmy")}
href={supportLemmyUrl} href={donateLemmyUrl}
> >
<Icon icon="heart" classes="small" /> <Icon icon="heart" classes="small" />
</a> </a>

View file

@ -36,7 +36,7 @@ export class ImageUploadForm extends Component<
<form class="d-inline"> <form class="d-inline">
<label <label
htmlFor={this.id} htmlFor={this.id}
class="pointer ml-4 text-muted small font-weight-bold" class="pointer text-muted small font-weight-bold"
> >
{!this.props.imageSrc ? ( {!this.props.imageSrc ? (
<span class="btn btn-secondary">{this.props.uploadTitle}</span> <span class="btn btn-secondary">{this.props.uploadTitle}</span>

View file

@ -121,16 +121,19 @@ export class CommunityForm extends Component<
<form onSubmit={linkEvent(this, this.handleCreateCommunitySubmit)}> <form onSubmit={linkEvent(this, this.handleCreateCommunitySubmit)}>
{!this.props.community_view && ( {!this.props.community_view && (
<div class="form-group row"> <div class="form-group row">
<label class="col-12 col-form-label" htmlFor="community-name"> <label
class="col-12 col-sm-2 col-form-label"
htmlFor="community-name"
>
{i18n.t("name")} {i18n.t("name")}
<span <span
class="pointer unselectable ml-2 text-muted" class="position-absolute pointer unselectable ml-2 text-muted"
data-tippy-content={i18n.t("name_explain")} data-tippy-content={i18n.t("name_explain")}
> >
<Icon icon="help-circle" classes="icon-inline" /> <Icon icon="help-circle" classes="icon-inline" />
</span> </span>
</label> </label>
<div class="col-12"> <div class="col-12 col-sm-10">
<input <input
type="text" type="text"
id="community-name" id="community-name"
@ -146,16 +149,19 @@ export class CommunityForm extends Component<
</div> </div>
)} )}
<div class="form-group row"> <div class="form-group row">
<label class="col-12 col-form-label" htmlFor="community-title"> <label
class="col-12 col-sm-2 col-form-label"
htmlFor="community-title"
>
{i18n.t("display_name")} {i18n.t("display_name")}
<span <span
class="pointer unselectable ml-2 text-muted" class="position-absolute pointer unselectable ml-2 text-muted"
data-tippy-content={i18n.t("display_name_explain")} data-tippy-content={i18n.t("display_name_explain")}
> >
<Icon icon="help-circle" classes="icon-inline" /> <Icon icon="help-circle" classes="icon-inline" />
</span> </span>
</label> </label>
<div class="col-12"> <div class="col-12 col-sm-10">
<input <input
type="text" type="text"
id="community-title" id="community-title"
@ -168,30 +174,34 @@ export class CommunityForm extends Component<
/> />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group row">
<label>{i18n.t("icon")}</label> <label class="col-12 col-sm-2">{i18n.t("icon")}</label>
<ImageUploadForm <div class="col-12 col-sm-10">
uploadTitle={i18n.t("upload_icon")} <ImageUploadForm
imageSrc={this.state.communityForm.icon} uploadTitle={i18n.t("upload_icon")}
onUpload={this.handleIconUpload} imageSrc={this.state.communityForm.icon}
onRemove={this.handleIconRemove} onUpload={this.handleIconUpload}
rounded onRemove={this.handleIconRemove}
/> rounded
</div> />
<div class="form-group"> </div>
<label>{i18n.t("banner")}</label>
<ImageUploadForm
uploadTitle={i18n.t("upload_banner")}
imageSrc={this.state.communityForm.banner}
onUpload={this.handleBannerUpload}
onRemove={this.handleBannerRemove}
/>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-12 col-form-label" htmlFor={this.id}> <label class="col-12 col-sm-2">{i18n.t("banner")}</label>
<div class="col-12 col-sm-10">
<ImageUploadForm
uploadTitle={i18n.t("upload_banner")}
imageSrc={this.state.communityForm.banner}
onUpload={this.handleBannerUpload}
onRemove={this.handleBannerRemove}
/>
</div>
</div>
<div class="form-group row">
<label class="col-12 col-sm-2 col-form-label" htmlFor={this.id}>
{i18n.t("sidebar")} {i18n.t("sidebar")}
</label> </label>
<div class="col-12"> <div class="col-12 col-sm-10">
<MarkdownTextArea <MarkdownTextArea
initialContent={this.state.communityForm.description} initialContent={this.state.communityForm.description}
onContentChange={this.handleCommunityDescriptionChange} onContentChange={this.handleCommunityDescriptionChange}
@ -201,18 +211,18 @@ export class CommunityForm extends Component<
{this.props.enableNsfw && ( {this.props.enableNsfw && (
<div class="form-group row"> <div class="form-group row">
<div class="col-12"> <legend class="col-form-label col-sm-2 pt-0">
{i18n.t("nsfw")}
</legend>
<div class="col-10">
<div class="form-check"> <div class="form-check">
<input <input
class="form-check-input" class="form-check-input position-static"
id="community-nsfw" id="community-nsfw"
type="checkbox" type="checkbox"
checked={this.state.communityForm.nsfw} checked={this.state.communityForm.nsfw}
onChange={linkEvent(this, this.handleCommunityNsfwChange)} onChange={linkEvent(this, this.handleCommunityNsfwChange)}
/> />
<label class="form-check-label" htmlFor="community-nsfw">
{i18n.t("nsfw")}
</label>
</div> </div>
</div> </div>
</div> </div>

View file

@ -227,10 +227,10 @@ export class Settings extends Component<any, SettingsState> {
<h5>{i18n.t("change_password")}</h5> <h5>{i18n.t("change_password")}</h5>
<form onSubmit={linkEvent(this, this.handleChangePasswordSubmit)}> <form onSubmit={linkEvent(this, this.handleChangePasswordSubmit)}>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-5 col-form-label" htmlFor="user-password"> <label class="col-sm-5 col-form-label" htmlFor="user-password">
{i18n.t("new_password")} {i18n.t("new_password")}
</label> </label>
<div class="col-lg-7"> <div class="col-sm-7">
<input <input
type="password" type="password"
id="user-password" id="user-password"
@ -244,12 +244,12 @@ export class Settings extends Component<any, SettingsState> {
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label <label
class="col-lg-5 col-form-label" class="col-sm-5 col-form-label"
htmlFor="user-verify-password" htmlFor="user-verify-password"
> >
{i18n.t("verify_password")} {i18n.t("verify_password")}
</label> </label>
<div class="col-lg-7"> <div class="col-sm-7">
<input <input
type="password" type="password"
id="user-verify-password" id="user-verify-password"
@ -262,10 +262,10 @@ export class Settings extends Component<any, SettingsState> {
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-5 col-form-label" htmlFor="user-old-password"> <label class="col-sm-5 col-form-label" htmlFor="user-old-password">
{i18n.t("old_password")} {i18n.t("old_password")}
</label> </label>
<div class="col-lg-7"> <div class="col-sm-7">
<input <input
type="password" type="password"
id="user-old-password" id="user-old-password"
@ -417,10 +417,10 @@ export class Settings extends Component<any, SettingsState> {
<h5>{i18n.t("settings")}</h5> <h5>{i18n.t("settings")}</h5>
<form onSubmit={linkEvent(this, this.handleSaveSettingsSubmit)}> <form onSubmit={linkEvent(this, this.handleSaveSettingsSubmit)}>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-5 col-form-label" htmlFor="display-name"> <label class="col-sm-5 col-form-label" htmlFor="display-name">
{i18n.t("display_name")} {i18n.t("display_name")}
</label> </label>
<div class="col-lg-7"> <div class="col-sm-7">
<input <input
id="display-name" id="display-name"
type="text" type="text"
@ -434,10 +434,10 @@ export class Settings extends Component<any, SettingsState> {
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-3 col-form-label" htmlFor="user-bio"> <label class="col-sm-3 col-form-label" htmlFor="user-bio">
{i18n.t("bio")} {i18n.t("bio")}
</label> </label>
<div class="col-lg-9"> <div class="col-sm-9">
<MarkdownTextArea <MarkdownTextArea
initialContent={this.state.saveUserSettingsForm.bio} initialContent={this.state.saveUserSettingsForm.bio}
onContentChange={this.handleBioChange} onContentChange={this.handleBioChange}
@ -447,10 +447,10 @@ export class Settings extends Component<any, SettingsState> {
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-3 col-form-label" htmlFor="user-email"> <label class="col-sm-3 col-form-label" htmlFor="user-email">
{i18n.t("email")} {i18n.t("email")}
</label> </label>
<div class="col-lg-9"> <div class="col-sm-9">
<input <input
type="email" type="email"
id="user-email" id="user-email"
@ -463,12 +463,12 @@ export class Settings extends Component<any, SettingsState> {
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-5 col-form-label" htmlFor="matrix-user-id"> <label class="col-sm-5 col-form-label" htmlFor="matrix-user-id">
<a href={elementUrl} rel="noopener"> <a href={elementUrl} rel="noopener">
{i18n.t("matrix_user_id")} {i18n.t("matrix_user_id")}
</a> </a>
</label> </label>
<div class="col-lg-7"> <div class="col-sm-7">
<input <input
id="matrix-user-id" id="matrix-user-id"
type="text" type="text"
@ -480,90 +480,102 @@ export class Settings extends Component<any, SettingsState> {
/> />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group row">
<label>{i18n.t("avatar")}</label> <label class="col-sm-3">{i18n.t("avatar")}</label>
<ImageUploadForm <div class="col-sm-9">
uploadTitle={i18n.t("upload_avatar")} <ImageUploadForm
imageSrc={this.state.saveUserSettingsForm.avatar} uploadTitle={i18n.t("upload_avatar")}
onUpload={this.handleAvatarUpload} imageSrc={this.state.saveUserSettingsForm.avatar}
onRemove={this.handleAvatarRemove} onUpload={this.handleAvatarUpload}
rounded onRemove={this.handleAvatarRemove}
/> rounded
/>
</div>
</div> </div>
<div class="form-group"> <div class="form-group row">
<label>{i18n.t("banner")}</label> <label class="col-sm-3">{i18n.t("banner")}</label>
<ImageUploadForm <div class="col-sm-9">
uploadTitle={i18n.t("upload_banner")} <ImageUploadForm
imageSrc={this.state.saveUserSettingsForm.banner} uploadTitle={i18n.t("upload_banner")}
onUpload={this.handleBannerUpload} imageSrc={this.state.saveUserSettingsForm.banner}
onRemove={this.handleBannerRemove} onUpload={this.handleBannerUpload}
/> onRemove={this.handleBannerRemove}
/>
</div>
</div> </div>
<div class="form-group"> <div class="form-group row">
<label htmlFor="user-language">{i18n.t("language")}</label> <label class="col-sm-3" htmlFor="user-language">
<select {i18n.t("language")}
id="user-language" </label>
value={this.state.saveUserSettingsForm.lang} <div class="col-sm-9">
onChange={linkEvent(this, this.handleLangChange)} <select
class="ml-2 custom-select w-auto" id="user-language"
> value={this.state.saveUserSettingsForm.lang}
<option disabled aria-hidden="true"> onChange={linkEvent(this, this.handleLangChange)}
{i18n.t("language")} class="custom-select w-auto"
</option> >
<option value="browser">{i18n.t("browser_default")}</option> <option disabled aria-hidden="true">
<option disabled aria-hidden="true"> {i18n.t("language")}
</option>
{languages.sort().map(lang => (
<option value={lang.code}>
{ISO6391.getNativeName(lang.code) || lang.code}
</option> </option>
))} <option value="browser">{i18n.t("browser_default")}</option>
</select> <option disabled aria-hidden="true">
</option>
{languages.sort().map(lang => (
<option value={lang.code}>
{ISO6391.getNativeName(lang.code) || lang.code}
</option>
))}
</select>
</div>
</div> </div>
<div class="form-group"> <div class="form-group row">
<label htmlFor="user-theme">{i18n.t("theme")}</label> <label class="col-sm-3" htmlFor="user-theme">
<select {i18n.t("theme")}
id="user-theme"
value={this.state.saveUserSettingsForm.theme}
onChange={linkEvent(this, this.handleThemeChange)}
class="ml-2 custom-select w-auto"
>
<option disabled aria-hidden="true">
{i18n.t("theme")}
</option>
<option value="browser">{i18n.t("browser_default")}</option>
{themes.map(theme => (
<option value={theme}>{theme}</option>
))}
</select>
</div>
<form className="form-group">
<label>
<div class="mr-2">{i18n.t("type")}</div>
</label> </label>
<ListingTypeSelect <div class="col-sm-9">
type_={ <select
Object.values(ListingType)[ id="user-theme"
this.state.saveUserSettingsForm.default_listing_type value={this.state.saveUserSettingsForm.theme}
] onChange={linkEvent(this, this.handleThemeChange)}
} class="custom-select w-auto"
showLocal={showLocal(this.isoData)} >
onChange={this.handleListingTypeChange} <option disabled aria-hidden="true">
/> {i18n.t("theme")}
</option>
<option value="browser">{i18n.t("browser_default")}</option>
{themes.map(theme => (
<option value={theme}>{theme}</option>
))}
</select>
</div>
</div>
<form className="form-group row">
<label class="col-sm-3">{i18n.t("type")}</label>
<div class="col-sm-9">
<ListingTypeSelect
type_={
Object.values(ListingType)[
this.state.saveUserSettingsForm.default_listing_type
]
}
showLocal={showLocal(this.isoData)}
onChange={this.handleListingTypeChange}
/>
</div>
</form> </form>
<form className="form-group"> <form className="form-group row">
<label> <label class="col-sm-3">{i18n.t("sort_type")}</label>
<div class="mr-2">{i18n.t("sort_type")}</div> <div class="col-sm-9">
</label> <SortSelect
<SortSelect sort={
sort={ Object.values(SortType)[
Object.values(SortType)[ this.state.saveUserSettingsForm.default_sort_type
this.state.saveUserSettingsForm.default_sort_type ]
] }
} onChange={this.handleSortTypeChange}
onChange={this.handleSortTypeChange} />
/> </div>
</form> </form>
{this.state.siteRes.site_view.site.enable_nsfw && ( {this.state.siteRes.site_view.site.enable_nsfw && (
<div class="form-group"> <div class="form-group">

View file

@ -310,18 +310,18 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
)} )}
{this.props.enableNsfw && ( {this.props.enableNsfw && (
<div class="form-group row"> <div class="form-group row">
<legend class="col-form-label col-sm-2 pt-0">
{i18n.t("nsfw")}
</legend>
<div class="col-sm-10"> <div class="col-sm-10">
<div class="form-check"> <div class="form-check">
<input <input
class="form-check-input" class="form-check-input position-static"
id="post-nsfw" id="post-nsfw"
type="checkbox" type="checkbox"
checked={this.state.postForm.nsfw} checked={this.state.postForm.nsfw}
onChange={linkEvent(this, this.handlePostNsfwChange)} onChange={linkEvent(this, this.handlePostNsfwChange)}
/> />
<label class="form-check-label" htmlFor="post-nsfw">
{i18n.t("nsfw")}
</label>
</div> </div>
</div> </div>
</div> </div>

View file

@ -92,13 +92,13 @@ export const favIconPngUrl = "/static/assets/icons/apple-touch-icon.png";
// export const defaultFavIcon = `${window.location.protocol}//${window.location.host}${favIconPngUrl}`; // export const defaultFavIcon = `${window.location.protocol}//${window.location.host}${favIconPngUrl}`;
export const repoUrl = "https://github.com/LemmyNet"; export const repoUrl = "https://github.com/LemmyNet";
export const joinLemmyUrl = "https://join-lemmy.org"; export const joinLemmyUrl = "https://join-lemmy.org";
export const supportLemmyUrl = `${joinLemmyUrl}/support`; export const donateLemmyUrl = `${joinLemmyUrl}/donate`;
export const docsUrl = `${joinLemmyUrl}/docs/en/index.html`; export const docsUrl = `${joinLemmyUrl}/docs/en/index.html`;
export const helpGuideUrl = `${joinLemmyUrl}/docs/en/about/guide.html`; // TODO find a way to redirect to the non-en folder export const helpGuideUrl = `${joinLemmyUrl}/docs/en/about/guide.html`; // TODO find a way to redirect to the non-en folder
export const markdownHelpUrl = `${helpGuideUrl}#markdown-guide`; export const markdownHelpUrl = `${helpGuideUrl}#markdown-guide`;
export const sortingHelpUrl = `${helpGuideUrl}#sorting`; export const sortingHelpUrl = `${helpGuideUrl}#sorting`;
export const archiveUrl = "https://archive.is"; export const archiveUrl = "https://archive.is";
export const elementUrl = "https://element.io/"; export const elementUrl = "https://element.io";
export const postRefetchSeconds: number = 60 * 1000; export const postRefetchSeconds: number = 60 * 1000;
export const fetchLimit = 20; export const fetchLimit = 20;