mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-11-25 22:01:13 +00:00
Merge branch 'main' into comment-border-tweak
This commit is contained in:
commit
96e216975a
19 changed files with 433 additions and 296 deletions
|
@ -2,7 +2,7 @@ import { initializeSite, setupDateFns } from "@utils/app";
|
|||
import { hydrate } from "inferno-hydrate";
|
||||
import { Router } from "inferno-router";
|
||||
import { App } from "../shared/components/app/app";
|
||||
import { HistoryService } from "../shared/services";
|
||||
import { HistoryService, UserService } from "../shared/services";
|
||||
|
||||
import "bootstrap/js/dist/collapse";
|
||||
import "bootstrap/js/dist/dropdown";
|
||||
|
@ -14,7 +14,7 @@ async function startClient() {
|
|||
|
||||
const wrapper = (
|
||||
<Router history={HistoryService.history}>
|
||||
<App />
|
||||
<App user={UserService.Instance.myUserInfo} />
|
||||
</Router>
|
||||
);
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ export default async (req: Request, res: Response) => {
|
|||
|
||||
const wrapper = (
|
||||
<StaticRouter location={url} context={isoData}>
|
||||
<App />
|
||||
<App user={site?.my_user} />
|
||||
</StaticRouter>
|
||||
);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import { dataBsTheme } from "@utils/browser";
|
|||
import { Component, RefObject, createRef, linkEvent } from "inferno";
|
||||
import { Provider } from "inferno-i18next-dess";
|
||||
import { Route, Switch } from "inferno-router";
|
||||
import { MyUserInfo } from "lemmy-js-client";
|
||||
import { IsoDataOptionalSite } from "../../interfaces";
|
||||
import { routes } from "../../routes";
|
||||
import { FirstLoadService, I18NextService, UserService } from "../../services";
|
||||
|
@ -14,10 +15,14 @@ import { Navbar } from "./navbar";
|
|||
import "./styles.scss";
|
||||
import { Theme } from "./theme";
|
||||
|
||||
export class App extends Component<any, any> {
|
||||
interface AppProps {
|
||||
user?: MyUserInfo;
|
||||
}
|
||||
|
||||
export class App extends Component<AppProps, any> {
|
||||
private isoData: IsoDataOptionalSite = setIsoData(this.context);
|
||||
private readonly mainContentRef: RefObject<HTMLElement>;
|
||||
constructor(props: any, context: any) {
|
||||
constructor(props: AppProps, context: any) {
|
||||
super(props, context);
|
||||
this.mainContentRef = createRef();
|
||||
}
|
||||
|
@ -29,10 +34,6 @@ export class App extends Component<any, any> {
|
|||
|
||||
user = UserService.Instance.myUserInfo;
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({ bsTheme: dataBsTheme(this.user) });
|
||||
}
|
||||
|
||||
render() {
|
||||
const siteRes = this.isoData.site_res;
|
||||
const siteView = siteRes?.site_view;
|
||||
|
@ -43,7 +44,7 @@ export class App extends Component<any, any> {
|
|||
<div
|
||||
id="app"
|
||||
className="lemmy-site"
|
||||
data-bs-theme={this.state?.bsTheme}
|
||||
data-bs-theme={dataBsTheme(this.props.user)}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { randomStr } from "@utils/helpers";
|
||||
import classNames from "classnames";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { DataType } from "../../interfaces";
|
||||
import { I18NextService } from "../../services";
|
||||
|
@ -15,6 +17,8 @@ export class DataTypeSelect extends Component<
|
|||
DataTypeSelectProps,
|
||||
DataTypeSelectState
|
||||
> {
|
||||
private id = `listing-type-input-${randomStr()}`;
|
||||
|
||||
state: DataTypeSelectState = {
|
||||
type_: this.props.type_,
|
||||
};
|
||||
|
@ -31,33 +35,41 @@ export class DataTypeSelect extends Component<
|
|||
|
||||
render() {
|
||||
return (
|
||||
<div className="data-type-select btn-group btn-group-toggle flex-wrap">
|
||||
<div
|
||||
className="data-type-select btn-group btn-group-toggle flex-wrap"
|
||||
role="group"
|
||||
>
|
||||
<input
|
||||
id={`${this.id}-posts`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={DataType.Post}
|
||||
checked={this.state.type_ === DataType.Post}
|
||||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
/>
|
||||
<label
|
||||
className={`pointer btn btn-outline-secondary
|
||||
${this.state.type_ == DataType.Post && "active"}
|
||||
`}
|
||||
htmlFor={`${this.id}-posts`}
|
||||
className={classNames("pointer btn btn-outline-secondary", {
|
||||
active: this.state.type_ === DataType.Post,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={DataType.Post}
|
||||
checked={this.state.type_ == DataType.Post}
|
||||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("posts")}
|
||||
</label>
|
||||
|
||||
<input
|
||||
id={`${this.id}-comments`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={DataType.Comment}
|
||||
checked={this.state.type_ === DataType.Comment}
|
||||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
/>
|
||||
<label
|
||||
className={`pointer btn btn-outline-secondary ${
|
||||
this.state.type_ == DataType.Comment && "active"
|
||||
}`}
|
||||
htmlFor={`${this.id}-comments`}
|
||||
className={classNames("pointer btn btn-outline-secondary", {
|
||||
active: this.state.type_ === DataType.Comment,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={DataType.Comment}
|
||||
checked={this.state.type_ == DataType.Comment}
|
||||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("comments")}
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { randomStr } from "@utils/helpers";
|
||||
import classNames from "classnames";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { ListingType } from "lemmy-js-client";
|
||||
import { I18NextService, UserService } from "../../services";
|
||||
|
@ -38,60 +39,72 @@ export class ListingTypeSelect extends Component<
|
|||
|
||||
render() {
|
||||
return (
|
||||
<div className="listing-type-select btn-group btn-group-toggle flex-wrap">
|
||||
<div
|
||||
className="listing-type-select btn-group btn-group-toggle flex-wrap"
|
||||
role="group"
|
||||
>
|
||||
{this.props.showSubscribed && (
|
||||
<label
|
||||
title={I18NextService.i18n.t("subscribed_description")}
|
||||
className={`btn btn-outline-secondary
|
||||
${this.state.type_ == "Subscribed" && "active"}
|
||||
${!UserService.Instance.myUserInfo ? "disabled" : "pointer"}
|
||||
`}
|
||||
>
|
||||
<>
|
||||
<input
|
||||
id={`${this.id}-subscribed`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={"Subscribed"}
|
||||
checked={this.state.type_ == "Subscribed"}
|
||||
checked={this.state.type_ === "Subscribed"}
|
||||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
disabled={!UserService.Instance.myUserInfo}
|
||||
/>
|
||||
{I18NextService.i18n.t("subscribed")}
|
||||
</label>
|
||||
<label
|
||||
htmlFor={`${this.id}-subscribed`}
|
||||
title={I18NextService.i18n.t("subscribed_description")}
|
||||
className={classNames("btn btn-outline-secondary", {
|
||||
active: this.state.type_ === "Subscribed",
|
||||
disabled: !UserService.Instance.myUserInfo,
|
||||
pointer: UserService.Instance.myUserInfo,
|
||||
})}
|
||||
>
|
||||
{I18NextService.i18n.t("subscribed")}
|
||||
</label>
|
||||
</>
|
||||
)}
|
||||
{this.props.showLocal && (
|
||||
<label
|
||||
title={I18NextService.i18n.t("local_description")}
|
||||
className={`pointer btn btn-outline-secondary ${
|
||||
this.state.type_ == "Local" && "active"
|
||||
}`}
|
||||
>
|
||||
<>
|
||||
<input
|
||||
id={`${this.id}-local`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={"Local"}
|
||||
checked={this.state.type_ == "Local"}
|
||||
checked={this.state.type_ === "Local"}
|
||||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("local")}
|
||||
</label>
|
||||
<label
|
||||
htmlFor={`${this.id}-local`}
|
||||
title={I18NextService.i18n.t("local_description")}
|
||||
className={classNames("pointer btn btn-outline-secondary", {
|
||||
active: this.state.type_ === "Local",
|
||||
})}
|
||||
>
|
||||
{I18NextService.i18n.t("local")}
|
||||
</label>
|
||||
</>
|
||||
)}
|
||||
<input
|
||||
id={`${this.id}-all`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={"All"}
|
||||
checked={this.state.type_ === "All"}
|
||||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
/>
|
||||
<label
|
||||
title={I18NextService.i18n.t("all_description")}
|
||||
className={`pointer btn btn-outline-secondary ${
|
||||
(this.state.type_ == "All" && "active") ||
|
||||
(!this.props.showLocal && this.state.type_ == "Local" && "active")
|
||||
}`}
|
||||
htmlFor={`${this.id}-all`}
|
||||
className={classNames("pointer btn btn-outline-secondary", {
|
||||
active:
|
||||
this.state.type_ === "All" ||
|
||||
(!this.props.showLocal && this.state.type_) === "Local",
|
||||
})}
|
||||
>
|
||||
<input
|
||||
id={`${this.id}-all`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={"All"}
|
||||
checked={this.state.type_ == "All"}
|
||||
onChange={linkEvent(this, this.handleTypeChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("all")}
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -53,7 +53,7 @@ export class UserBadges extends Component<UserBadgesProps> {
|
|||
{getRoleLabelPill({
|
||||
label: I18NextService.i18n.t("banned"),
|
||||
tooltip: I18NextService.i18n.t("banned"),
|
||||
classes: "text-bg-danger",
|
||||
classes: "text-danger border border-danger",
|
||||
shrink: false,
|
||||
})}
|
||||
</span>
|
||||
|
@ -63,7 +63,7 @@ export class UserBadges extends Component<UserBadgesProps> {
|
|||
{getRoleLabelPill({
|
||||
label: I18NextService.i18n.t("deleted"),
|
||||
tooltip: I18NextService.i18n.t("deleted"),
|
||||
classes: "text-bg-danger",
|
||||
classes: "text-danger border border-danger",
|
||||
shrink: false,
|
||||
})}
|
||||
</span>
|
||||
|
@ -74,7 +74,7 @@ export class UserBadges extends Component<UserBadgesProps> {
|
|||
{getRoleLabelPill({
|
||||
label: I18NextService.i18n.t("op").toUpperCase(),
|
||||
tooltip: I18NextService.i18n.t("creator"),
|
||||
classes: "text-bg-info",
|
||||
classes: "text-info border border-info",
|
||||
shrink: false,
|
||||
})}
|
||||
</span>
|
||||
|
@ -84,7 +84,7 @@ export class UserBadges extends Component<UserBadgesProps> {
|
|||
{getRoleLabelPill({
|
||||
label: I18NextService.i18n.t("mod"),
|
||||
tooltip: I18NextService.i18n.t("mod"),
|
||||
classes: "text-bg-primary",
|
||||
classes: "text-primary border border-primary",
|
||||
})}
|
||||
</span>
|
||||
)}
|
||||
|
@ -93,7 +93,7 @@ export class UserBadges extends Component<UserBadgesProps> {
|
|||
{getRoleLabelPill({
|
||||
label: I18NextService.i18n.t("admin"),
|
||||
tooltip: I18NextService.i18n.t("admin"),
|
||||
classes: "text-bg-danger",
|
||||
classes: "text-danger border border-danger",
|
||||
})}
|
||||
</span>
|
||||
)}
|
||||
|
|
|
@ -114,7 +114,7 @@ interface HomeState {
|
|||
}
|
||||
|
||||
interface HomeProps {
|
||||
listingType: ListingType;
|
||||
listingType?: ListingType;
|
||||
dataType: DataType;
|
||||
sort: SortType;
|
||||
page: number;
|
||||
|
@ -163,12 +163,12 @@ function getDataTypeFromQuery(type?: string): DataType {
|
|||
return type ? DataType[type] : DataType.Post;
|
||||
}
|
||||
|
||||
function getListingTypeFromQuery(type?: string): ListingType {
|
||||
function getListingTypeFromQuery(type?: string): ListingType | undefined {
|
||||
const myListingType =
|
||||
UserService.Instance.myUserInfo?.local_user_view?.local_user
|
||||
?.default_listing_type;
|
||||
|
||||
return (type ? (type as ListingType) : myListingType) ?? "Local";
|
||||
return type ? (type as ListingType) : myListingType;
|
||||
}
|
||||
|
||||
function getSortTypeFromQuery(type?: string): SortType {
|
||||
|
@ -311,11 +311,12 @@ export class Home extends Component<any, HomeState> {
|
|||
client,
|
||||
auth,
|
||||
query: { dataType: urlDataType, listingType, page: urlPage, sort: urlSort },
|
||||
site,
|
||||
}: InitialFetchRequest<QueryParams<HomeProps>>): Promise<HomeData> {
|
||||
const dataType = getDataTypeFromQuery(urlDataType);
|
||||
|
||||
// TODO figure out auth default_listingType, default_sort_type
|
||||
const type_ = getListingTypeFromQuery(listingType);
|
||||
const type_ =
|
||||
getListingTypeFromQuery(listingType) ??
|
||||
site.site_view.local_site.default_post_listing_type;
|
||||
const sort = getSortTypeFromQuery(urlSort);
|
||||
|
||||
const page = urlPage ? Number(urlPage) : 1;
|
||||
|
@ -761,7 +762,10 @@ export class Home extends Component<any, HomeState> {
|
|||
</div>
|
||||
<div className="col-auto">
|
||||
<ListingTypeSelect
|
||||
type_={listingType}
|
||||
type_={
|
||||
listingType ??
|
||||
this.state.siteRes.site_view.local_site.default_post_listing_type
|
||||
}
|
||||
showLocal={showLocal(this.isoData)}
|
||||
showSubscribed
|
||||
onChange={this.handleListingTypeChange}
|
||||
|
@ -770,7 +774,12 @@ export class Home extends Component<any, HomeState> {
|
|||
<div className="col-auto">
|
||||
<SortSelect sort={sort} onChange={this.handleSortChange} />
|
||||
</div>
|
||||
<div className="col-auto ps-0">{getRss(listingType)}</div>
|
||||
<div className="col-auto ps-0">
|
||||
{getRss(
|
||||
listingType ??
|
||||
this.state.siteRes.site_view.local_site.default_post_listing_type
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -175,7 +175,9 @@ export class Login extends Component<any, State> {
|
|||
}
|
||||
|
||||
case "success": {
|
||||
UserService.Instance.login(loginRes.data);
|
||||
UserService.Instance.login({
|
||||
res: loginRes.data,
|
||||
});
|
||||
const site = await HttpService.client.getSite({
|
||||
auth: myAuth(),
|
||||
});
|
||||
|
|
|
@ -206,7 +206,7 @@ export class Setup extends Component<any, State> {
|
|||
if (i.state.registerRes.state == "success") {
|
||||
const data = i.state.registerRes.data;
|
||||
|
||||
UserService.Instance.login(data);
|
||||
UserService.Instance.login({ res: data });
|
||||
i.setState({ doneRegisteringUser: true });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -469,7 +469,9 @@ export class Signup extends Component<any, State> {
|
|||
|
||||
// Only log them in if a jwt was set
|
||||
if (data.jwt) {
|
||||
UserService.Instance.login(data);
|
||||
UserService.Instance.login({
|
||||
res: data,
|
||||
});
|
||||
|
||||
const site = await HttpService.client.getSite({ auth: myAuth() });
|
||||
|
||||
|
|
|
@ -11,8 +11,9 @@ import {
|
|||
setIsoData,
|
||||
updatePersonBlock,
|
||||
} from "@utils/app";
|
||||
import { capitalizeFirstLetter } from "@utils/helpers";
|
||||
import { capitalizeFirstLetter, randomStr } from "@utils/helpers";
|
||||
import { RouteDataResponse } from "@utils/types";
|
||||
import classNames from "classnames";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import {
|
||||
AddAdmin,
|
||||
|
@ -283,34 +284,41 @@ export class Inbox extends Component<any, InboxState> {
|
|||
}
|
||||
|
||||
unreadOrAllRadios() {
|
||||
const radioId = randomStr();
|
||||
|
||||
return (
|
||||
<div className="btn-group btn-group-toggle flex-wrap">
|
||||
<div className="btn-group btn-group-toggle flex-wrap" role="group">
|
||||
<input
|
||||
id={`${radioId}-unread`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={UnreadOrAll.Unread}
|
||||
checked={this.state.unreadOrAll === UnreadOrAll.Unread}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
|
||||
`}
|
||||
htmlFor={`${radioId}-unread`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.unreadOrAll === UnreadOrAll.Unread,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={UnreadOrAll.Unread}
|
||||
checked={this.state.unreadOrAll == UnreadOrAll.Unread}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("unread")}
|
||||
</label>
|
||||
|
||||
<input
|
||||
id={`${radioId}-all`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={UnreadOrAll.All}
|
||||
checked={this.state.unreadOrAll === UnreadOrAll.All}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${this.state.unreadOrAll == UnreadOrAll.All && "active"}
|
||||
`}
|
||||
htmlFor={`${radioId}-all`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.unreadOrAll === UnreadOrAll.All,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={UnreadOrAll.All}
|
||||
checked={this.state.unreadOrAll == UnreadOrAll.All}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("all")}
|
||||
</label>
|
||||
</div>
|
||||
|
@ -318,62 +326,75 @@ export class Inbox extends Component<any, InboxState> {
|
|||
}
|
||||
|
||||
messageTypeRadios() {
|
||||
const radioId = randomStr();
|
||||
|
||||
return (
|
||||
<div className="btn-group btn-group-toggle flex-wrap">
|
||||
<div className="btn-group btn-group-toggle flex-wrap" role="group">
|
||||
<input
|
||||
id={`${radioId}-all`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.All}
|
||||
checked={this.state.messageType === MessageType.All}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${this.state.messageType == MessageType.All && "active"}
|
||||
`}
|
||||
htmlFor={`${radioId}-all`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.messageType === MessageType.All,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.All}
|
||||
checked={this.state.messageType == MessageType.All}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("all")}
|
||||
</label>
|
||||
|
||||
<input
|
||||
id={`${radioId}-replies`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.Replies}
|
||||
checked={this.state.messageType === MessageType.Replies}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${this.state.messageType == MessageType.Replies && "active"}
|
||||
`}
|
||||
htmlFor={`${radioId}-replies`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.messageType === MessageType.Replies,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.Replies}
|
||||
checked={this.state.messageType == MessageType.Replies}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("replies")}
|
||||
</label>
|
||||
|
||||
<input
|
||||
id={`${radioId}-mentions`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.Mentions}
|
||||
checked={this.state.messageType === MessageType.Mentions}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${this.state.messageType == MessageType.Mentions && "active"}
|
||||
`}
|
||||
htmlFor={`${radioId}-mentions`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.messageType === MessageType.Mentions,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.Mentions}
|
||||
checked={this.state.messageType == MessageType.Mentions}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("mentions")}
|
||||
</label>
|
||||
|
||||
<input
|
||||
id={`${radioId}-messages`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.Messages}
|
||||
checked={this.state.messageType === MessageType.Messages}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${this.state.messageType == MessageType.Messages && "active"}
|
||||
`}
|
||||
htmlFor={`${radioId}-messages`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.messageType === MessageType.Messages,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.Messages}
|
||||
checked={this.state.messageType == MessageType.Messages}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("messages")}
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -135,7 +135,9 @@ export class PasswordChange extends Component<any, State> {
|
|||
|
||||
if (i.state.passwordChangeRes.state === "success") {
|
||||
const data = i.state.passwordChangeRes.data;
|
||||
UserService.Instance.login(data);
|
||||
UserService.Instance.login({
|
||||
res: data,
|
||||
});
|
||||
|
||||
const site = await HttpService.client.getSite({ auth: myAuth() });
|
||||
if (site.state === "success") {
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
getQueryParams,
|
||||
getQueryString,
|
||||
numToSI,
|
||||
randomStr,
|
||||
} from "@utils/helpers";
|
||||
import { canMod, isAdmin, isBanned } from "@utils/roles";
|
||||
import type { QueryParams } from "@utils/types";
|
||||
|
@ -397,7 +398,7 @@ export class Profile extends Component<
|
|||
|
||||
get viewRadios() {
|
||||
return (
|
||||
<div className="btn-group btn-group-toggle flex-wrap mb-2">
|
||||
<div className="btn-group btn-group-toggle flex-wrap mb-2" role="group">
|
||||
{this.getRadio(PersonDetailsView.Overview)}
|
||||
{this.getRadio(PersonDetailsView.Comments)}
|
||||
{this.getRadio(PersonDetailsView.Posts)}
|
||||
|
@ -409,22 +410,27 @@ export class Profile extends Component<
|
|||
getRadio(view: PersonDetailsView) {
|
||||
const { view: urlView } = getProfileQueryParams();
|
||||
const active = view === urlView;
|
||||
const radioId = randomStr();
|
||||
|
||||
return (
|
||||
<label
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active,
|
||||
})}
|
||||
>
|
||||
<>
|
||||
<input
|
||||
id={radioId}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={view}
|
||||
checked={active}
|
||||
onChange={linkEvent(this, this.handleViewChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t(view.toLowerCase() as NoOptionI18nKeys)}
|
||||
</label>
|
||||
<label
|
||||
htmlFor={radioId}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active,
|
||||
})}
|
||||
>
|
||||
{I18NextService.i18n.t(view.toLowerCase() as NoOptionI18nKeys)}
|
||||
</label>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,9 @@ import {
|
|||
myAuthRequired,
|
||||
setIsoData,
|
||||
} from "@utils/app";
|
||||
import { randomStr } from "@utils/helpers";
|
||||
import { RouteDataResponse } from "@utils/types";
|
||||
import classNames from "classnames";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import {
|
||||
ApproveRegistrationApplication,
|
||||
|
@ -125,34 +127,41 @@ export class RegistrationApplications extends Component<
|
|||
}
|
||||
|
||||
unreadOrAllRadios() {
|
||||
const radioId = randomStr();
|
||||
|
||||
return (
|
||||
<div className="btn-group btn-group-toggle flex-wrap mb-2">
|
||||
<div className="btn-group btn-group-toggle flex-wrap mb-2" role="group">
|
||||
<input
|
||||
id={`${radioId}-unread`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={UnreadOrAll.Unread}
|
||||
checked={this.state.unreadOrAll === UnreadOrAll.Unread}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
|
||||
`}
|
||||
htmlFor={`${radioId}-unread`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.unreadOrAll === UnreadOrAll.Unread,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={UnreadOrAll.Unread}
|
||||
checked={this.state.unreadOrAll == UnreadOrAll.Unread}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("unread")}
|
||||
</label>
|
||||
|
||||
<input
|
||||
id={`${radioId}-all`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={UnreadOrAll.All}
|
||||
checked={this.state.unreadOrAll === UnreadOrAll.All}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${this.state.unreadOrAll == UnreadOrAll.All && "active"}
|
||||
`}
|
||||
htmlFor={`${radioId}-all`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.unreadOrAll === UnreadOrAll.All,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={UnreadOrAll.All}
|
||||
checked={this.state.unreadOrAll == UnreadOrAll.All}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("all")}
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -5,8 +5,10 @@ import {
|
|||
myAuthRequired,
|
||||
setIsoData,
|
||||
} from "@utils/app";
|
||||
import { randomStr } from "@utils/helpers";
|
||||
import { amAdmin } from "@utils/roles";
|
||||
import { RouteDataResponse } from "@utils/types";
|
||||
import classNames from "classnames";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import {
|
||||
CommentReportResponse,
|
||||
|
@ -187,34 +189,41 @@ export class Reports extends Component<any, ReportsState> {
|
|||
}
|
||||
|
||||
unreadOrAllRadios() {
|
||||
const radioId = randomStr();
|
||||
|
||||
return (
|
||||
<div className="btn-group btn-group-toggle flex-wrap mb-2">
|
||||
<div className="btn-group btn-group-toggle flex-wrap mb-2" role="group">
|
||||
<input
|
||||
id={`${radioId}-unread`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={UnreadOrAll.Unread}
|
||||
checked={this.state.unreadOrAll === UnreadOrAll.Unread}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
|
||||
`}
|
||||
htmlFor={`${radioId}-unread`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.unreadOrAll === UnreadOrAll.Unread,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={UnreadOrAll.Unread}
|
||||
checked={this.state.unreadOrAll == UnreadOrAll.Unread}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("unread")}
|
||||
</label>
|
||||
|
||||
<input
|
||||
id={`${radioId}-all`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={UnreadOrAll.All}
|
||||
checked={this.state.unreadOrAll === UnreadOrAll.All}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${this.state.unreadOrAll == UnreadOrAll.All && "active"}
|
||||
`}
|
||||
htmlFor={`${radioId}-all`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.unreadOrAll === UnreadOrAll.All,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={UnreadOrAll.All}
|
||||
checked={this.state.unreadOrAll == UnreadOrAll.All}
|
||||
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("all")}
|
||||
</label>
|
||||
</div>
|
||||
|
@ -222,70 +231,83 @@ export class Reports extends Component<any, ReportsState> {
|
|||
}
|
||||
|
||||
messageTypeRadios() {
|
||||
const radioId = randomStr();
|
||||
|
||||
return (
|
||||
<div className="btn-group btn-group-toggle flex-wrap mb-2">
|
||||
<div className="btn-group btn-group-toggle flex-wrap mb-2" role="group">
|
||||
<input
|
||||
id={`${radioId}-all`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.All}
|
||||
checked={this.state.messageType === MessageType.All}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${this.state.messageType == MessageType.All && "active"}
|
||||
`}
|
||||
htmlFor={`${radioId}-all`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.messageType === MessageType.All,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.All}
|
||||
checked={this.state.messageType == MessageType.All}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("all")}
|
||||
</label>
|
||||
|
||||
<input
|
||||
id={`${radioId}-comments`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.CommentReport}
|
||||
checked={this.state.messageType === MessageType.CommentReport}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${this.state.messageType == MessageType.CommentReport && "active"}
|
||||
`}
|
||||
htmlFor={`${radioId}-comments`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.messageType === MessageType.CommentReport,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.CommentReport}
|
||||
checked={this.state.messageType == MessageType.CommentReport}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("comments")}
|
||||
</label>
|
||||
|
||||
<input
|
||||
id={`${radioId}-posts`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.PostReport}
|
||||
checked={this.state.messageType === MessageType.PostReport}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${this.state.messageType == MessageType.PostReport && "active"}
|
||||
`}
|
||||
htmlFor={`${radioId}-posts`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.messageType === MessageType.PostReport,
|
||||
})}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.PostReport}
|
||||
checked={this.state.messageType == MessageType.PostReport}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("posts")}
|
||||
</label>
|
||||
|
||||
{amAdmin() && (
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer
|
||||
${
|
||||
this.state.messageType == MessageType.PrivateMessageReport &&
|
||||
"active"
|
||||
}
|
||||
`}
|
||||
>
|
||||
<>
|
||||
<input
|
||||
id={`${radioId}-messages`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={MessageType.PrivateMessageReport}
|
||||
checked={
|
||||
this.state.messageType == MessageType.PrivateMessageReport
|
||||
this.state.messageType === MessageType.PrivateMessageReport
|
||||
}
|
||||
onChange={linkEvent(this, this.handleMessageTypeChange)}
|
||||
/>
|
||||
{I18NextService.i18n.t("messages")}
|
||||
</label>
|
||||
<label
|
||||
htmlFor={`${radioId}-messages`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active:
|
||||
this.state.messageType === MessageType.PrivateMessageReport,
|
||||
})}
|
||||
>
|
||||
{I18NextService.i18n.t("messages")}
|
||||
</label>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1175,8 +1175,12 @@ export class Settings extends Component<any, SettingsState> {
|
|||
...i.state.saveUserSettingsForm,
|
||||
auth: myAuthRequired(),
|
||||
});
|
||||
|
||||
if (saveRes.state === "success") {
|
||||
UserService.Instance.login(saveRes.data);
|
||||
UserService.Instance.login({
|
||||
res: saveRes.data,
|
||||
showToast: false,
|
||||
});
|
||||
toast(I18NextService.i18n.t("saved"));
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
@ -1198,7 +1202,10 @@ export class Settings extends Component<any, SettingsState> {
|
|||
auth: myAuthRequired(),
|
||||
});
|
||||
if (changePasswordRes.state === "success") {
|
||||
UserService.Instance.login(changePasswordRes.data);
|
||||
UserService.Instance.login({
|
||||
res: changePasswordRes.data,
|
||||
showToast: false,
|
||||
});
|
||||
window.scrollTo(0, 0);
|
||||
toast(I18NextService.i18n.t("password_changed"));
|
||||
}
|
||||
|
|
|
@ -19,10 +19,11 @@ import {
|
|||
restoreScrollPosition,
|
||||
saveScrollPosition,
|
||||
} from "@utils/browser";
|
||||
import { debounce } from "@utils/helpers";
|
||||
import { debounce, randomStr } from "@utils/helpers";
|
||||
import { isImage } from "@utils/media";
|
||||
import { RouteDataResponse } from "@utils/types";
|
||||
import autosize from "autosize";
|
||||
import classNames from "classnames";
|
||||
import { Component, RefObject, createRef, linkEvent } from "inferno";
|
||||
import {
|
||||
AddAdmin,
|
||||
|
@ -430,80 +431,98 @@ export class Post extends Component<any, PostState> {
|
|||
}
|
||||
|
||||
sortRadios() {
|
||||
const radioId =
|
||||
this.state.postRes.state === "success"
|
||||
? this.state.postRes.data.post_view.post.id
|
||||
: randomStr();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="btn-group btn-group-toggle flex-wrap me-3 mb-2">
|
||||
<div
|
||||
className="btn-group btn-group-toggle flex-wrap me-3 mb-2"
|
||||
role="group"
|
||||
>
|
||||
<input
|
||||
id={`${radioId}-hot`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={"Hot"}
|
||||
checked={this.state.commentSort === "Hot"}
|
||||
onChange={linkEvent(this, this.handleCommentSortChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer ${
|
||||
this.state.commentSort === "Hot" && "active"
|
||||
}`}
|
||||
htmlFor={`${radioId}-hot`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.commentSort === "Hot",
|
||||
})}
|
||||
>
|
||||
{I18NextService.i18n.t("hot")}
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={"Hot"}
|
||||
checked={this.state.commentSort === "Hot"}
|
||||
onChange={linkEvent(this, this.handleCommentSortChange)}
|
||||
/>
|
||||
</label>
|
||||
<input
|
||||
id={`${radioId}-top`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={"Top"}
|
||||
checked={this.state.commentSort === "Top"}
|
||||
onChange={linkEvent(this, this.handleCommentSortChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer ${
|
||||
this.state.commentSort === "Top" && "active"
|
||||
}`}
|
||||
htmlFor={`${radioId}-top`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.commentSort === "Top",
|
||||
})}
|
||||
>
|
||||
{I18NextService.i18n.t("top")}
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={"Top"}
|
||||
checked={this.state.commentSort === "Top"}
|
||||
onChange={linkEvent(this, this.handleCommentSortChange)}
|
||||
/>
|
||||
</label>
|
||||
<input
|
||||
id={`${radioId}-new`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={"New"}
|
||||
checked={this.state.commentSort === "New"}
|
||||
onChange={linkEvent(this, this.handleCommentSortChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer ${
|
||||
this.state.commentSort === "New" && "active"
|
||||
}`}
|
||||
htmlFor={`${radioId}-new`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.commentSort === "New",
|
||||
})}
|
||||
>
|
||||
{I18NextService.i18n.t("new")}
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={"New"}
|
||||
checked={this.state.commentSort === "New"}
|
||||
onChange={linkEvent(this, this.handleCommentSortChange)}
|
||||
/>
|
||||
</label>
|
||||
<input
|
||||
id={`${radioId}-old`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={"Old"}
|
||||
checked={this.state.commentSort === "Old"}
|
||||
onChange={linkEvent(this, this.handleCommentSortChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer ${
|
||||
this.state.commentSort === "Old" && "active"
|
||||
}`}
|
||||
htmlFor={`${radioId}-old`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.commentSort === "Old",
|
||||
})}
|
||||
>
|
||||
{I18NextService.i18n.t("old")}
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={"Old"}
|
||||
checked={this.state.commentSort === "Old"}
|
||||
onChange={linkEvent(this, this.handleCommentSortChange)}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div className="btn-group btn-group-toggle flex-wrap mb-2">
|
||||
<div className="btn-group btn-group-toggle flex-wrap mb-2" role="group">
|
||||
<input
|
||||
id={`${radioId}-chat`}
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={CommentViewType.Flat}
|
||||
checked={this.state.commentViewType === CommentViewType.Flat}
|
||||
onChange={linkEvent(this, this.handleCommentViewTypeChange)}
|
||||
/>
|
||||
<label
|
||||
className={`btn btn-outline-secondary pointer ${
|
||||
this.state.commentViewType === CommentViewType.Flat && "active"
|
||||
}`}
|
||||
htmlFor={`${radioId}-chat`}
|
||||
className={classNames("btn btn-outline-secondary pointer", {
|
||||
active: this.state.commentViewType === CommentViewType.Flat,
|
||||
})}
|
||||
>
|
||||
{I18NextService.i18n.t("chat")}
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
value={CommentViewType.Flat}
|
||||
checked={this.state.commentViewType === CommentViewType.Flat}
|
||||
onChange={linkEvent(this, this.handleCommentViewTypeChange)}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
@ -26,12 +26,18 @@ export class UserService {
|
|||
this.#setJwtInfo();
|
||||
}
|
||||
|
||||
public login(res: LoginResponse) {
|
||||
public login({
|
||||
res,
|
||||
showToast = true,
|
||||
}: {
|
||||
res: LoginResponse;
|
||||
showToast?: boolean;
|
||||
}) {
|
||||
const expires = new Date();
|
||||
expires.setDate(expires.getDate() + 365);
|
||||
|
||||
if (isBrowser() && res.jwt) {
|
||||
toast(I18NextService.i18n.t("logged_in"));
|
||||
showToast && toast(I18NextService.i18n.t("logged_in"));
|
||||
setAuthCookie(res.jwt);
|
||||
this.#setJwtInfo();
|
||||
}
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
import { MyUserInfo } from "lemmy-js-client";
|
||||
import isDark from "./is-dark";
|
||||
|
||||
export default function dataBsTheme(user) {
|
||||
export default function dataBsTheme(user?: MyUserInfo) {
|
||||
return (isDark() && user?.local_user_view.local_user.theme === "browser") ||
|
||||
(user &&
|
||||
["darkly", "darkly-red", "darkly-pureblack"].includes(
|
||||
user.local_user_view.local_user.theme
|
||||
))
|
||||
[
|
||||
"darkly",
|
||||
"darkly-red",
|
||||
"darkly-pureblack",
|
||||
"darkly-compact",
|
||||
"i386",
|
||||
"vaporwave-dark",
|
||||
].includes(user.local_user_view.local_user.theme))
|
||||
? "dark"
|
||||
: "light";
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue