"eslint": "^7.30.0",
"eslint-plugin-prettier": "^3.4.0",
"husky": "^7.0.1",
+ "import-sort-style-module": "^6.0.0",
"iso-639-1": "^2.1.9",
"lemmy-js-client": "0.11.0",
"lint-staged": "^11.0.1",
"node-fetch": "^2.6.1",
"node-sass": "^6.0.1",
"prettier": "^2.3.2",
+ "prettier-plugin-import-sort": "^0.0.7",
+ "prettier-plugin-organize-imports": "^2.2.0",
+ "prettier-plugin-packagejson": "^2.2.11",
"rimraf": "^3.0.2",
"run-node-webpack-plugin": "^1.3.0",
"sass-loader": "^12.1.0",
"package.json": [
"sortpack"
]
+ },
+ "importSort": {
+ ".js, .jsx, .ts, .tsx": {
+ "style": "module",
+ "parser": "typescript"
+ }
}
}
import { hydrate } from "inferno-hydrate";
import { BrowserRouter } from "inferno-router";
-import { initializeSite } from "../shared/initialize";
-import { App } from "../shared/components/app";
+import { App } from "../shared/components/app/app";
+import { initializeSite } from "../shared/utils";
const site = window.isoData.site_res;
initializeSite(site);
-import serialize from "serialize-javascript";
import express from "express";
-import { StaticRouter } from "inferno-router";
+import { IncomingHttpHeaders } from "http";
+import { Helmet } from "inferno-helmet";
+import { matchPath, StaticRouter } from "inferno-router";
import { renderToString } from "inferno-server";
-import { matchPath } from "inferno-router";
+import IsomorphicCookie from "isomorphic-cookie";
+import { GetSite, GetSiteResponse, LemmyHttp } from "lemmy-js-client";
import path from "path";
-import { App } from "../shared/components/app";
+import process from "process";
+import serialize from "serialize-javascript";
+import { App } from "../shared/components/app/app";
+import { SYMBOLS } from "../shared/components/common/symbols";
+import { httpBaseInternal } from "../shared/env";
import {
ILemmyConfig,
InitialFetchRequest,
IsoData,
} from "../shared/interfaces";
import { routes } from "../shared/routes";
-import IsomorphicCookie from "isomorphic-cookie";
-import { GetSite, GetSiteResponse, LemmyHttp } from "lemmy-js-client";
-import process from "process";
-import { Helmet } from "inferno-helmet";
-import { SYMBOLS } from "../shared/components/symbols";
-import { initializeSite } from "../shared/initialize";
-import { httpBaseInternal } from "../shared/env";
-import { IncomingHttpHeaders } from "http";
-import { setOptionalAuth } from "../shared/utils";
+import { initializeSite, setOptionalAuth } from "../shared/utils";
const server = express();
const [hostname, port] = process.env["LEMMY_UI_HOST"]
import { Component } from "inferno";
-import { Route, Switch } from "inferno-router";
-import { Provider } from "inferno-i18next";
import { Helmet } from "inferno-helmet";
-import { i18n } from "../i18next";
-import { routes } from "../routes";
-import { Navbar } from "./navbar";
+import { Provider } from "inferno-i18next";
+import { Route, Switch } from "inferno-router";
+import { GetSiteResponse } from "lemmy-js-client";
+import { i18n } from "../../i18next";
+import { routes } from "../../routes";
+import { favIconPngUrl, favIconUrl } from "../../utils";
import { Footer } from "./footer";
+import { Navbar } from "./navbar";
import { NoMatch } from "./no-match";
-import { Theme } from "./theme";
-import { GetSiteResponse } from "lemmy-js-client";
import "./styles.scss";
-import { favIconPngUrl, favIconUrl } from "../utils";
+import { Theme } from "./theme";
export interface AppProps {
siteRes: GetSiteResponse;
import { Component } from "inferno";
import { Link } from "inferno-router";
-import { i18n } from "../i18next";
-import { repoUrl, joinLemmyUrl, docsUrl } from "../utils";
import { GetSiteResponse } from "lemmy-js-client";
-import { VERSION } from "../version";
+import { i18n } from "../../i18next";
+import { docsUrl, joinLemmyUrl, repoUrl } from "../../utils";
+import { VERSION } from "../../version";
interface FooterProps {
site: GetSiteResponse;
-import { Component, linkEvent, createRef, RefObject } from "inferno";
+import { Component, createRef, linkEvent, RefObject } from "inferno";
import { Link } from "inferno-router";
-import { Subscription } from "rxjs";
-import { WebSocketService, UserService } from "../services";
import {
- UserOperation,
- GetReplies,
- GetRepliesResponse,
+ CommentResponse,
+ CommentView,
GetPersonMentions,
GetPersonMentionsResponse,
GetPrivateMessages,
- PrivateMessagesResponse,
- SortType,
+ GetReplies,
+ GetRepliesResponse,
GetSiteResponse,
- CommentView,
- CommentResponse,
PrivateMessageResponse,
+ PrivateMessagesResponse,
PrivateMessageView,
+ SortType,
+ UserOperation,
} from "lemmy-js-client";
+import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
+import { UserService, WebSocketService } from "../../services";
import {
- wsJsonToRes,
- showAvatars,
+ authField,
fetchLimit,
- toast,
- setTheme,
getLanguage,
+ isBrowser,
notifyComment,
notifyPrivateMessage,
- isBrowser,
- wsSubscribe,
+ setTheme,
+ showAvatars,
supportLemmyUrl,
- wsUserOp,
+ toast,
wsClient,
- authField,
-} from "../utils";
-import { i18n } from "../i18next";
-import { PictrsImage } from "./pictrs-image";
-import { Icon } from "./icon";
+ wsJsonToRes,
+ wsSubscribe,
+ wsUserOp,
+} from "../../utils";
+import { Icon } from "../common/icon";
+import { PictrsImage } from "../common/pictrs-image";
interface NavbarProps {
site_res: GetSiteResponse;
import { I18nKeys } from "i18next";
import { Component } from "inferno";
-import { i18n } from "../i18next";
+import { i18n } from "../../i18next";
export class NoMatch extends Component<any, any> {
private errCode = new URLSearchParams(this.props.location.search).get(
--- /dev/null
+// Custom css
+@import "../../../../node_modules/tributejs/dist/tribute.css";
+@import "../../../../node_modules/toastify-js/src/toastify.css";
+@import "../../../../node_modules/choices.js/src/styles/choices.scss";
+@import "../../../../node_modules/tippy.js/dist/tippy.css";
+@import "../../../assets/css/main.css";
-import { LocalUserSettingsView } from "lemmy-js-client";
-import { Helmet } from "inferno-helmet";
import { Component } from "inferno";
+import { Helmet } from "inferno-helmet";
+import { LocalUserSettingsView } from "lemmy-js-client";
interface Props {
localUserView: LocalUserSettingsView | undefined;
import { Component } from "inferno";
+import { T } from "inferno-i18next";
import { Link } from "inferno-router";
-import { Subscription } from "rxjs";
import {
+ CommentResponse,
CreateComment,
EditComment,
UserOperation,
- CommentResponse,
} from "lemmy-js-client";
-import { CommentNode as CommentNodeI } from "../interfaces";
+import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
+import { CommentNode as CommentNodeI } from "../../interfaces";
+import { UserService, WebSocketService } from "../../services";
import {
authField,
capitalizeFirstLetter,
wsJsonToRes,
wsSubscribe,
wsUserOp,
-} from "../utils";
-import { WebSocketService, UserService } from "../services";
-import { i18n } from "../i18next";
-import { T } from "inferno-i18next";
-import { MarkdownTextArea } from "./markdown-textarea";
-import { Icon } from "./icon";
+} from "../../utils";
+import { Icon } from "../common/icon";
+import { MarkdownTextArea } from "../common/markdown-textarea";
interface CommentFormProps {
postId?: number;
import { Component, linkEvent } from "inferno";
import { Link } from "inferno-router";
import {
+ AddAdmin,
+ AddModToCommunity,
+ BanFromCommunity,
+ BanPerson,
+ CommentView,
+ CommunityModeratorView,
CreateCommentLike,
DeleteComment,
- RemoveComment,
MarkCommentAsRead,
MarkPersonMentionAsRead,
- SaveComment,
- BanFromCommunity,
- BanPerson,
- CommunityModeratorView,
+ PersonMentionView,
PersonViewSafe,
- AddModToCommunity,
- AddAdmin,
+ RemoveComment,
+ SaveComment,
TransferCommunity,
TransferSite,
- CommentView,
- PersonMentionView,
} from "lemmy-js-client";
-import { CommentNode as CommentNodeI, BanType } from "../interfaces";
-import { WebSocketService, UserService } from "../services";
+import moment from "moment";
+import { i18n } from "../../i18next";
+import { BanType, CommentNode as CommentNodeI } from "../../interfaces";
+import { UserService, WebSocketService } from "../../services";
import {
- mdToHtml,
- getUnixTime,
+ authField,
canMod,
+ colorList,
+ getUnixTime,
isMod,
+ mdToHtml,
setupTippy,
- colorList,
- wsClient,
- authField,
showScores,
-} from "../utils";
-import moment from "moment";
-import { MomentTime } from "./moment-time";
+ wsClient,
+} from "../../utils";
+import { Icon, Spinner } from "../common/icon";
+import { MomentTime } from "../common/moment-time";
+import { CommunityLink } from "../community/community-link";
+import { PersonListing } from "../person/person-listing";
import { CommentForm } from "./comment-form";
import { CommentNodes } from "./comment-nodes";
-import { PersonListing } from "./person-listing";
-import { CommunityLink } from "./community-link";
-import { Icon, Spinner } from "./icon";
-import { i18n } from "../i18next";
interface CommentNodeState {
showReply: boolean;
import { Component } from "inferno";
-import { CommentNode as CommentNodeI } from "../interfaces";
import { CommunityModeratorView, PersonViewSafe } from "lemmy-js-client";
+import { CommentNode as CommentNodeI } from "../../interfaces";
import { CommentNode } from "./comment-node";
interface CommentNodesProps {
import { Component, linkEvent } from "inferno";
-import { DataType } from "../interfaces";
-
-import { i18n } from "../i18next";
+import { i18n } from "../../i18next";
+import { DataType } from "../../interfaces";
interface DataTypeSelectProps {
type_: DataType;
import { Component } from "inferno";
import { Helmet } from "inferno-helmet";
-import { httpExternalPath } from "../env";
-import { md } from "../utils";
+import { httpExternalPath } from "../../env";
+import { md } from "../../utils";
interface HtmlTagsProps {
title: string;
import { Component, linkEvent } from "inferno";
-import { pictrsUri } from "../env";
-import { UserService } from "../services";
-import { toast, randomStr } from "../utils";
-import { i18n } from "../i18next";
+import { pictrsUri } from "../../env";
+import { i18n } from "../../i18next";
+import { UserService } from "../../services";
+import { randomStr, toast } from "../../utils";
import { Icon } from "./icon";
interface ImageUploadFormProps {
import { Component, linkEvent } from "inferno";
import { ListingType } from "lemmy-js-client";
-import { UserService } from "../services";
-import { randomStr } from "../utils";
-import { i18n } from "../i18next";
+import { i18n } from "../../i18next";
+import { UserService } from "../../services";
+import { randomStr } from "../../utils";
interface ListingTypeSelectProps {
type_: ListingType;
+import autosize from "autosize";
import { Component, linkEvent } from "inferno";
import { Prompt } from "inferno-router";
+import { pictrsUri } from "../../env";
+import { i18n } from "../../i18next";
+import { UserService } from "../../services";
import {
- mdToHtml,
- randomStr,
+ isBrowser,
markdownHelpUrl,
- toast,
- setupTribute,
+ mdToHtml,
pictrsDeleteToast,
+ randomStr,
setupTippy,
- isBrowser,
-} from "../utils";
-import { UserService } from "../services";
-import autosize from "autosize";
-import { i18n } from "../i18next";
-import { pictrsUri } from "../env";
+ setupTribute,
+ toast,
+} from "../../utils";
import { Icon, Spinner } from "./icon";
interface MarkdownTextAreaProps {
handleInsertCode(i: MarkdownTextArea, event: any) {
event.preventDefault();
- if (i.getSelectedText().split(/\r*\n/).length > 1){
+ if (i.getSelectedText().split(/\r*\n/).length > 1) {
i.simpleSurroundBeforeAfter("```\n", "\n```");
} else {
- i.simpleSurround('`');
+ i.simpleSurround("`");
}
}
let textarea: any = document.getElementById(this.id);
let start: number = textarea.selectionStart;
let end: number = textarea.selectionEnd;
- return start !== end ? this.state.content.substring(start, end) : '';
+ return start !== end ? this.state.content.substring(start, end) : "";
}
}
import { Component } from "inferno";
import moment from "moment";
-import { getMomentLanguage, capitalizeFirstLetter } from "../utils";
-import { i18n } from "../i18next";
+import { i18n } from "../../i18next";
+import { capitalizeFirstLetter, getMomentLanguage } from "../../utils";
import { Icon } from "./icon";
interface MomentTimeProps {
import { Component, linkEvent } from "inferno";
-import { i18n } from "../i18next";
+import { i18n } from "../../i18next";
interface PaginatorProps {
page: number;
import { Component, linkEvent } from "inferno";
import { SortType } from "lemmy-js-client";
-import { sortingHelpUrl, randomStr } from "../utils";
+import { i18n } from "../../i18next";
+import { randomStr, sortingHelpUrl } from "../../utils";
import { Icon } from "./icon";
-import { i18n } from "../i18next";
interface SortSelectProps {
sort: SortType;
import { Component, linkEvent } from "inferno";
-import { HtmlTags } from "./html-tags";
-import { Subscription } from "rxjs";
import {
- UserOperation,
- CommunityView,
- ListCommunitiesResponse,
CommunityResponse,
+ CommunityView,
FollowCommunity,
ListCommunities,
- SortType,
+ ListCommunitiesResponse,
ListingType,
SiteView,
+ SortType,
+ UserOperation,
} from "lemmy-js-client";
-import { WebSocketService } from "../services";
+import { Subscription } from "rxjs";
+import { InitialFetchRequest } from "shared/interfaces";
+import { i18n } from "../../i18next";
+import { WebSocketService } from "../../services";
import {
- wsJsonToRes,
- toast,
+ authField,
getPageFromProps,
isBrowser,
setIsoData,
+ setOptionalAuth,
+ toast,
+ wsClient,
+ wsJsonToRes,
wsSubscribe,
wsUserOp,
- wsClient,
- authField,
- setOptionalAuth,
-} from "../utils";
+} from "../../utils";
+import { HtmlTags } from "../common/html-tags";
+import { Spinner } from "../common/icon";
+import { Paginator } from "../common/paginator";
import { CommunityLink } from "./community-link";
-import { Paginator } from "./paginator";
-import { Spinner } from "./icon";
-import { i18n } from "../i18next";
-import { InitialFetchRequest } from "shared/interfaces";
const communityLimit = 100;
</td>
<td class="text-right">
{cv.subscribed ? (
- <span
- class="pointer btn-link"
- role="button"
+ <button
+ class="btn btn-link d-inline-block"
onClick={linkEvent(
cv.community.id,
this.handleUnsubscribe
)}
>
{i18n.t("unsubscribe")}
- </span>
+ </button>
) : (
- <span
- class="pointer btn-link"
- role="button"
+ <button
+ class="btn btn-link d-inline-block"
onClick={linkEvent(
cv.community.id,
this.handleSubscribe
)}
>
{i18n.t("subscribe")}
- </span>
+ </button>
)}
</td>
</tr>
import { Component, linkEvent } from "inferno";
import { Prompt } from "inferno-router";
-import { Subscription } from "rxjs";
import {
- EditCommunity,
- CreateCommunity,
- UserOperation,
CommunityResponse,
CommunityView,
+ CreateCommunity,
+ EditCommunity,
+ UserOperation,
} from "lemmy-js-client";
-import { WebSocketService } from "../services";
+import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
+import { WebSocketService } from "../../services";
import {
- wsJsonToRes,
+ authField,
capitalizeFirstLetter,
- toast,
randomStr,
+ toast,
+ wsClient,
+ wsJsonToRes,
wsSubscribe,
wsUserOp,
- wsClient,
- authField,
-} from "../utils";
-import { i18n } from "../i18next";
-
-import { MarkdownTextArea } from "./markdown-textarea";
-import { ImageUploadForm } from "./image-upload-form";
-import { Icon, Spinner } from "./icon";
+} from "../../utils";
+import { Icon, Spinner } from "../common/icon";
+import { ImageUploadForm } from "../common/image-upload-form";
+import { MarkdownTextArea } from "../common/markdown-textarea";
interface CommunityFormProps {
community_view?: CommunityView; // If a community is given, that means this is an edit
this.state = this.emptyState;
- this.handleCommunityDescriptionChange = this.handleCommunityDescriptionChange.bind(
- this
- );
+ this.handleCommunityDescriptionChange =
+ this.handleCommunityDescriptionChange.bind(this);
this.handleIconUpload = this.handleIconUpload.bind(this);
this.handleIconRemove = this.handleIconRemove.bind(this);
import { Component } from "inferno";
import { Link } from "inferno-router";
import { CommunitySafe } from "lemmy-js-client";
-import { hostname, showAvatars } from "../utils";
-import { PictrsImage } from "./pictrs-image";
+import { hostname, showAvatars } from "../../utils";
+import { PictrsImage } from "../common/pictrs-image";
interface CommunityLinkProps {
// TODO figure this out better
import { Component } from "inferno";
-import { Subscription } from "rxjs";
-import { DataType, InitialFetchRequest } from "../interfaces";
import {
- UserOperation,
- GetCommunityResponse,
- CommunityResponse,
- SortType,
- PostView,
- GetPosts,
- GetCommunity,
- ListingType,
- GetPostsResponse,
- PostResponse,
AddModToCommunityResponse,
BanFromCommunityResponse,
+ CommentResponse,
CommentView,
+ CommunityResponse,
GetComments,
GetCommentsResponse,
- CommentResponse,
+ GetCommunity,
+ GetCommunityResponse,
+ GetPosts,
+ GetPostsResponse,
GetSiteResponse,
+ ListingType,
+ PostResponse,
+ PostView,
+ SortType,
+ UserOperation,
} from "lemmy-js-client";
-import { UserService, WebSocketService } from "../services";
-import { PostListings } from "./post-listings";
-import { CommentNodes } from "./comment-nodes";
-import { HtmlTags } from "./html-tags";
-import { SortSelect } from "./sort-select";
-import { DataTypeSelect } from "./data-type-select";
-import { Sidebar } from "./sidebar";
-import { CommunityLink } from "./community-link";
-import { BannerIconHeader } from "./banner-icon-header";
-import { Icon, Spinner } from "./icon";
-import { Paginator } from "./paginator";
+import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
+import { DataType, InitialFetchRequest } from "../../interfaces";
+import { UserService, WebSocketService } from "../../services";
import {
- wsJsonToRes,
- fetchLimit,
- toast,
- getPageFromProps,
- getSortTypeFromProps,
- getDataTypeFromProps,
- editCommentRes,
- saveCommentRes,
+ authField,
+ commentsToFlatNodes,
+ communityRSSUrl,
createCommentLikeRes,
createPostLikeFindRes,
+ editCommentRes,
editPostFindRes,
- commentsToFlatNodes,
- setupTippy,
+ fetchLimit,
+ getDataTypeFromProps,
+ getPageFromProps,
+ getSortTypeFromProps,
notifyPost,
+ restoreScrollPosition,
+ saveCommentRes,
+ saveScrollPosition,
setIsoData,
+ setOptionalAuth,
+ setupTippy,
+ toast,
+ wsClient,
+ wsJsonToRes,
wsSubscribe,
- communityRSSUrl,
wsUserOp,
- wsClient,
- authField,
- setOptionalAuth,
- saveScrollPosition,
- restoreScrollPosition,
-} from "../utils";
-import { i18n } from "../i18next";
+} from "../../utils";
+import { CommentNodes } from "../comment/comment-nodes";
+import { BannerIconHeader } from "../common/banner-icon-header";
+import { DataTypeSelect } from "../common/data-type-select";
+import { HtmlTags } from "../common/html-tags";
+import { Icon, Spinner } from "../common/icon";
+import { Paginator } from "../common/paginator";
+import { SortSelect } from "../common/sort-select";
+import { Sidebar } from "../community/sidebar";
+import { PostListings } from "../post/post-listings";
+import { CommunityLink } from "./community-link";
interface State {
communityRes: GetCommunityResponse;
import { Component } from "inferno";
+import { CommunityView, SiteView } from "lemmy-js-client";
import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
+import { UserService } from "../../services";
+import { isBrowser, setIsoData, toast, wsSubscribe } from "../../utils";
+import { HtmlTags } from "../common/html-tags";
+import { Spinner } from "../common/icon";
import { CommunityForm } from "./community-form";
-import { HtmlTags } from "./html-tags";
-import { Spinner } from "./icon";
-import { CommunityView, SiteView } from "lemmy-js-client";
-import { setIsoData, toast, wsSubscribe, isBrowser } from "../utils";
-import { UserService } from "../services";
-import { i18n } from "../i18next";
interface CreateCommunityState {
site_view: SiteView;
import { Component, linkEvent } from "inferno";
import { Link } from "inferno-router";
import {
- CommunityView,
+ AddModToCommunity,
CommunityModeratorView,
- FollowCommunity,
+ CommunityView,
DeleteCommunity,
- RemoveCommunity,
+ FollowCommunity,
PersonViewSafe,
- AddModToCommunity,
+ RemoveCommunity,
} from "lemmy-js-client";
-import { WebSocketService, UserService } from "../services";
-import { mdToHtml, getUnixTime, wsClient, authField } from "../utils";
-import { CommunityForm } from "./community-form";
-import { PersonListing } from "./person-listing";
-import { CommunityLink } from "./community-link";
-import { BannerIconHeader } from "./banner-icon-header";
-import { Icon } from "./icon";
-import { i18n } from "../i18next";
+import { i18n } from "../../i18next";
+import { UserService, WebSocketService } from "../../services";
+import { authField, getUnixTime, mdToHtml, wsClient } from "../../utils";
+import { BannerIconHeader } from "../common/banner-icon-header";
+import { Icon } from "../common/icon";
+import { CommunityForm } from "../community/community-form";
+import { CommunityLink } from "../community/community-link";
+import { PersonListing } from "../person/person-listing";
interface SidebarProps {
community_view: CommunityView;
{this.canMod && (
<>
<li className="list-inline-item-action">
- <span
- role="button"
- class="pointer"
+ <button
+ class="btn btn-link text-muted d-inline-block"
onClick={linkEvent(this, this.handleEditClick)}
data-tippy-content={i18n.t("edit")}
aria-label={i18n.t("edit")}
>
<Icon icon="edit" classes="icon-inline" />
- </span>
+ </button>
</li>
{!this.amTopMod &&
(!this.state.showConfirmLeaveModTeam ? (
<li className="list-inline-item-action">
- <span
- class="pointer"
- role="button"
+ <button
+ class="btn btn-link text-muted d-inline-block"
onClick={linkEvent(
this,
this.handleShowConfirmLeaveModTeamClick
)}
>
{i18n.t("leave_mod_team")}
- </span>
+ </button>
</li>
) : (
<>
{i18n.t("are_you_sure")}
</li>
<li className="list-inline-item-action">
- <span
- class="pointer"
- role="button"
+ <button
+ class="btn btn-link text-muted d-inline-block"
onClick={linkEvent(this, this.handleLeaveModTeamClick)}
>
{i18n.t("yes")}
- </span>
+ </button>
</li>
<li className="list-inline-item-action">
- <span
- class="pointer"
- role="button"
+ <button
+ class="btn btn-link text-muted d-inline-block"
onClick={linkEvent(
this,
this.handleCancelLeaveModTeamClick
)}
>
{i18n.t("no")}
- </span>
+ </button>
</li>
</>
))}
{this.amTopMod && (
<li className="list-inline-item-action">
- <span
- class="pointer"
+ <button
+ class="btn btn-link text-muted d-inline-block"
onClick={linkEvent(this, this.handleDeleteClick)}
data-tippy-content={
!community_view.community.deleted
community_view.community.deleted && "text-danger"
}`}
/>
- </span>
+ </button>
</li>
)}
</>
{this.canAdmin && (
<li className="list-inline-item">
{!this.props.community_view.community.removed ? (
- <span
- class="pointer"
- role="button"
+ <button
+ class="btn btn-link text-muted d-inline-block"
onClick={linkEvent(this, this.handleModRemoveShow)}
>
{i18n.t("remove")}
- </span>
+ </button>
) : (
- <span
- class="pointer"
- role="button"
+ <button
+ class="btn btn-link text-muted d-inline-block"
onClick={linkEvent(this, this.handleModRemoveSubmit)}
>
{i18n.t("restore")}
- </span>
+ </button>
)}
</li>
)}
+import autosize from "autosize";
import { Component, linkEvent } from "inferno";
-import { Subscription } from "rxjs";
import {
- UserOperation,
- SiteResponse,
+ GetSiteConfig,
+ GetSiteConfigResponse,
GetSiteResponse,
SaveSiteConfig,
- GetSiteConfigResponse,
- GetSiteConfig,
+ SiteResponse,
+ UserOperation,
} from "lemmy-js-client";
-import { WebSocketService } from "../services";
+import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
+import { InitialFetchRequest } from "../../interfaces";
+import { WebSocketService } from "../../services";
import {
- wsJsonToRes,
+ authField,
capitalizeFirstLetter,
- toast,
+ isBrowser,
randomStr,
setIsoData,
+ toast,
+ wsClient,
+ wsJsonToRes,
wsSubscribe,
- isBrowser,
wsUserOp,
- wsClient,
- authField,
-} from "../utils";
-import autosize from "autosize";
+} from "../../utils";
+import { HtmlTags } from "../common/html-tags";
+import { Spinner } from "../common/icon";
+import { PersonListing } from "../person/person-listing";
import { SiteForm } from "./site-form";
-import { PersonListing } from "./person-listing";
-import { HtmlTags } from "./html-tags";
-import { Spinner } from "./icon";
-import { i18n } from "../i18next";
-import { InitialFetchRequest } from "shared/interfaces";
interface AdminSettingsState {
siteRes: GetSiteResponse;
import { Component, linkEvent } from "inferno";
+import { T } from "inferno-i18next";
import { Link } from "inferno-router";
-import { Subscription } from "rxjs";
import {
- UserOperation,
+ AddAdminResponse,
+ BanPersonResponse,
+ CommentResponse,
+ CommentView,
CommunityFollowerView,
+ CommunityView,
+ GetComments,
+ GetCommentsResponse,
GetFollowedCommunitiesResponse,
+ GetPosts,
+ GetPostsResponse,
+ GetSiteResponse,
ListCommunities,
ListCommunitiesResponse,
- CommunityView,
- SortType,
- GetSiteResponse,
ListingType,
- SiteResponse,
- GetPostsResponse,
PostResponse,
PostView,
- GetPosts,
- CommentView,
- GetComments,
- GetCommentsResponse,
- CommentResponse,
- AddAdminResponse,
- BanPersonResponse,
+ SiteResponse,
+ SortType,
+ UserOperation,
} from "lemmy-js-client";
-import { DataType, InitialFetchRequest } from "../interfaces";
-import { WebSocketService, UserService } from "../services";
-import { PostListings } from "./post-listings";
-import { CommentNodes } from "./comment-nodes";
-import { SortSelect } from "./sort-select";
-import { ListingTypeSelect } from "./listing-type-select";
-import { DataTypeSelect } from "./data-type-select";
-import { SiteForm } from "./site-form";
-import { PersonListing } from "./person-listing";
-import { CommunityLink } from "./community-link";
-import { BannerIconHeader } from "./banner-icon-header";
-import { Icon, Spinner } from "./icon";
+import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
+import { DataType, InitialFetchRequest } from "../../interfaces";
+import { UserService, WebSocketService } from "../../services";
import {
- wsJsonToRes,
- mdToHtml,
+ authField,
+ commentsToFlatNodes,
+ createCommentLikeRes,
+ createPostLikeFindRes,
+ editCommentRes,
+ editPostFindRes,
fetchLimit,
- toast,
+ getDataTypeFromProps,
getListingTypeFromProps,
getPageFromProps,
getSortTypeFromProps,
- getDataTypeFromProps,
- editCommentRes,
- saveCommentRes,
- createCommentLikeRes,
- createPostLikeFindRes,
- editPostFindRes,
- commentsToFlatNodes,
- setupTippy,
+ mdToHtml,
notifyPost,
+ restoreScrollPosition,
+ saveCommentRes,
+ saveScrollPosition,
setIsoData,
- wsSubscribe,
- wsUserOp,
setOptionalAuth,
- wsClient,
- authField,
- saveScrollPosition,
- restoreScrollPosition,
+ setupTippy,
showLocal,
-} from "../utils";
-import { i18n } from "../i18next";
-import { T } from "inferno-i18next";
-import { HtmlTags } from "./html-tags";
-import { Paginator } from "./paginator";
+ toast,
+ wsClient,
+ wsJsonToRes,
+ wsSubscribe,
+ wsUserOp,
+} from "../../utils";
+import { CommentNodes } from "../comment/comment-nodes";
+import { BannerIconHeader } from "../common/banner-icon-header";
+import { DataTypeSelect } from "../common/data-type-select";
+import { HtmlTags } from "../common/html-tags";
+import { Icon, Spinner } from "../common/icon";
+import { ListingTypeSelect } from "../common/listing-type-select";
+import { Paginator } from "../common/paginator";
+import { SortSelect } from "../common/sort-select";
+import { CommunityLink } from "../community/community-link";
+import { PersonListing } from "../person/person-listing";
+import { PostListings } from "../post/post-listings";
+import { SiteForm } from "./site-form";
-interface MainState {
+interface HomeState {
subscribedCommunities: CommunityFollowerView[];
trendingCommunities: CommunityView[];
siteRes: GetSiteResponse;
page: number;
}
-interface MainProps {
+interface HomeProps {
listingType: ListingType;
dataType: DataType;
sort: SortType;
page?: number;
}
-export class Main extends Component<any, MainState> {
+export class Home extends Component<any, HomeState> {
private isoData = setIsoData(this.context);
private subscription: Subscription;
- private emptyState: MainState = {
+ private emptyState: HomeState = {
subscribedCommunities: [],
trendingCommunities: [],
siteRes: this.isoData.site_res,
window.isoData.path = undefined;
}
- static getDerivedStateFromProps(props: any): MainProps {
+ static getDerivedStateFromProps(props: any): HomeProps {
return {
listingType: getListingTypeFromProps(props),
dataType: getDataTypeFromProps(props),
return promises;
}
- componentDidUpdate(_: any, lastState: MainState) {
+ componentDidUpdate(_: any, lastState: HomeState) {
if (
lastState.listingType !== this.state.listingType ||
lastState.dataType !== this.state.dataType ||
this.canAdmin && (
<ul class="list-inline mb-1 text-muted font-weight-bold">
<li className="list-inline-item-action">
- <span
- class="pointer"
- role="button"
+ <button
+ class="btn btn-link d-inline-block text-muted"
onClick={linkEvent(this, this.handleEditClick)}
aria-label={i18n.t("edit")}
data-tippy-content={i18n.t("edit")}
>
<Icon icon="edit" classes="icon-inline" />
- </span>
+ </button>
</li>
</ul>
)
);
}
- handleEditClick(i: Main) {
+ handleEditClick(i: Home) {
i.state.showEditSite = true;
i.setState(i.state);
}
import { Component } from "inferno";
import { GetSiteResponse } from "lemmy-js-client";
-import { setIsoData } from "../utils";
-import { i18n } from "../i18next";
-import { HtmlTags } from "./html-tags";
+import { i18n } from "../../i18next";
+import { setIsoData } from "../../utils";
+import { HtmlTags } from "../common/html-tags";
interface InstancesState {
siteRes: GetSiteResponse;
--- /dev/null
+import { Component, linkEvent } from "inferno";
+import { T } from "inferno-i18next";
+import {
+ GetCaptchaResponse,
+ GetSiteResponse,
+ Login as LoginForm,
+ LoginResponse,
+ PasswordReset,
+ Register,
+ SiteView,
+ UserOperation,
+} from "lemmy-js-client";
+import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
+import { UserService, WebSocketService } from "../../services";
+import {
+ authField,
+ isBrowser,
+ joinLemmyUrl,
+ setIsoData,
+ toast,
+ validEmail,
+ wsClient,
+ wsJsonToRes,
+ wsSubscribe,
+ wsUserOp,
+} from "../../utils";
+import { HtmlTags } from "../common/html-tags";
+import { Icon, Spinner } from "../common/icon";
+
+interface State {
+ loginForm: LoginForm;
+ registerForm: Register;
+ loginLoading: boolean;
+ registerLoading: boolean;
+ captcha: GetCaptchaResponse;
+ captchaPlaying: boolean;
+ site_view: SiteView;
+}
+
+export class Login extends Component<any, State> {
+ private isoData = setIsoData(this.context);
+ private subscription: Subscription;
+
+ emptyState: State = {
+ loginForm: {
+ username_or_email: undefined,
+ password: undefined,
+ },
+ registerForm: {
+ username: undefined,
+ password: undefined,
+ password_verify: undefined,
+ show_nsfw: false,
+ captcha_uuid: undefined,
+ captcha_answer: undefined,
+ },
+ loginLoading: false,
+ registerLoading: false,
+ captcha: undefined,
+ captchaPlaying: false,
+ site_view: this.isoData.site_res.site_view,
+ };
+
+ constructor(props: any, context: any) {
+ super(props, context);
+
+ this.state = this.emptyState;
+
+ this.parseMessage = this.parseMessage.bind(this);
+ this.subscription = wsSubscribe(this.parseMessage);
+
+ if (isBrowser()) {
+ WebSocketService.Instance.send(wsClient.getCaptcha());
+ }
+ }
+
+ componentWillUnmount() {
+ if (isBrowser()) {
+ this.subscription.unsubscribe();
+ }
+ }
+
+ get documentTitle(): string {
+ return `${i18n.t("login")} - ${this.state.site_view.site.name}`;
+ }
+
+ get isLemmyMl(): boolean {
+ return isBrowser() && window.location.hostname == "lemmy.ml";
+ }
+
+ render() {
+ return (
+ <div class="container">
+ <HtmlTags
+ title={this.documentTitle}
+ path={this.context.router.route.match.url}
+ />
+ <div class="row">
+ <div class="col-12 col-lg-6 mb-4">{this.loginForm()}</div>
+ <div class="col-12 col-lg-6">{this.registerForm()}</div>
+ </div>
+ </div>
+ );
+ }
+
+ loginForm() {
+ return (
+ <div>
+ <form onSubmit={linkEvent(this, this.handleLoginSubmit)}>
+ <h5>{i18n.t("login")}</h5>
+ <div class="form-group row">
+ <label
+ class="col-sm-2 col-form-label"
+ htmlFor="login-email-or-username"
+ >
+ {i18n.t("email_or_username")}
+ </label>
+ <div class="col-sm-10">
+ <input
+ type="text"
+ class="form-control"
+ id="login-email-or-username"
+ value={this.state.loginForm.username_or_email}
+ onInput={linkEvent(this, this.handleLoginUsernameChange)}
+ autoComplete="email"
+ required
+ minLength={3}
+ />
+ </div>
+ </div>
+ <div class="form-group row">
+ <label class="col-sm-2 col-form-label" htmlFor="login-password">
+ {i18n.t("password")}
+ </label>
+ <div class="col-sm-10">
+ <input
+ type="password"
+ id="login-password"
+ value={this.state.loginForm.password}
+ onInput={linkEvent(this, this.handleLoginPasswordChange)}
+ class="form-control"
+ autoComplete="current-password"
+ required
+ maxLength={60}
+ />
+ <button
+ type="button"
+ onClick={linkEvent(this, this.handlePasswordReset)}
+ className="btn p-0 btn-link d-inline-block float-right text-muted small font-weight-bold pointer-events not-allowed"
+ disabled={!validEmail(this.state.loginForm.username_or_email)}
+ title={i18n.t("no_password_reset")}
+ >
+ {i18n.t("forgot_password")}
+ </button>
+ </div>
+ </div>
+ <div class="form-group row">
+ <div class="col-sm-10">
+ <button type="submit" class="btn btn-secondary">
+ {this.state.loginLoading ? <Spinner /> : i18n.t("login")}
+ </button>
+ </div>
+ </div>
+ </form>
+ </div>
+ );
+ }
+
+ registerForm() {
+ return (
+ <form onSubmit={linkEvent(this, this.handleRegisterSubmit)}>
+ <h5>{i18n.t("sign_up")}</h5>
+
+ <div class="form-group row">
+ <label class="col-sm-2 col-form-label" htmlFor="register-username">
+ {i18n.t("username")}
+ </label>
+
+ <div class="col-sm-10">
+ <input
+ type="text"
+ id="register-username"
+ class="form-control"
+ value={this.state.registerForm.username}
+ onInput={linkEvent(this, this.handleRegisterUsernameChange)}
+ required
+ minLength={3}
+ maxLength={20}
+ pattern="[a-zA-Z0-9_]+"
+ />
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label class="col-sm-2 col-form-label" htmlFor="register-email">
+ {i18n.t("email")}
+ </label>
+ <div class="col-sm-10">
+ <input
+ type="email"
+ id="register-email"
+ class="form-control"
+ placeholder={i18n.t("optional")}
+ value={this.state.registerForm.email}
+ autoComplete="email"
+ onInput={linkEvent(this, this.handleRegisterEmailChange)}
+ minLength={3}
+ />
+ {!validEmail(this.state.registerForm.email) && (
+ <div class="mt-2 mb-0 alert alert-light" role="alert">
+ <Icon icon="alert-triangle" classes="icon-inline mr-2" />
+ {i18n.t("no_password_reset")}
+ </div>
+ )}
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label class="col-sm-2 col-form-label" htmlFor="register-password">
+ {i18n.t("password")}
+ </label>
+ <div class="col-sm-10">
+ <input
+ type="password"
+ id="register-password"
+ value={this.state.registerForm.password}
+ autoComplete="new-password"
+ onInput={linkEvent(this, this.handleRegisterPasswordChange)}
+ maxLength={60}
+ class="form-control"
+ required
+ />
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label
+ class="col-sm-2 col-form-label"
+ htmlFor="register-verify-password"
+ >
+ {i18n.t("verify_password")}
+ </label>
+ <div class="col-sm-10">
+ <input
+ type="password"
+ id="register-verify-password"
+ value={this.state.registerForm.password_verify}
+ autoComplete="new-password"
+ onInput={linkEvent(this, this.handleRegisterPasswordVerifyChange)}
+ maxLength={60}
+ class="form-control"
+ required
+ />
+ </div>
+ </div>
+
+ {this.state.captcha && (
+ <div class="form-group row">
+ <label class="col-sm-2" htmlFor="register-captcha">
+ <span class="mr-2">{i18n.t("enter_code")}</span>
+ <button
+ type="button"
+ class="btn btn-secondary"
+ onClick={linkEvent(this, this.handleRegenCaptcha)}
+ aria-label={i18n.t("captcha")}
+ >
+ <Icon icon="refresh-cw" classes="icon-refresh-cw" />
+ </button>
+ </label>
+ {this.showCaptcha()}
+ <div class="col-sm-6">
+ <input
+ type="text"
+ class="form-control"
+ id="register-captcha"
+ value={this.state.registerForm.captcha_answer}
+ onInput={linkEvent(
+ this,
+ this.handleRegisterCaptchaAnswerChange
+ )}
+ required
+ />
+ </div>
+ </div>
+ )}
+ {this.state.site_view.site.enable_nsfw && (
+ <div class="form-group row">
+ <div class="col-sm-10">
+ <div class="form-check">
+ <input
+ class="form-check-input"
+ id="register-show-nsfw"
+ type="checkbox"
+ checked={this.state.registerForm.show_nsfw}
+ onChange={linkEvent(this, this.handleRegisterShowNsfwChange)}
+ />
+ <label class="form-check-label" htmlFor="register-show-nsfw">
+ {i18n.t("show_nsfw")}
+ </label>
+ </div>
+ </div>
+ </div>
+ )}
+ {this.isLemmyMl && (
+ <div class="mt-2 mb-0 alert alert-light" role="alert">
+ <T i18nKey="lemmy_ml_registration_message">
+ #<a href={joinLemmyUrl}>#</a>
+ </T>
+ </div>
+ )}
+ <div class="form-group row">
+ <div class="col-sm-10">
+ <button type="submit" class="btn btn-secondary">
+ {this.state.registerLoading ? <Spinner /> : i18n.t("sign_up")}
+ </button>
+ </div>
+ </div>
+ </form>
+ );
+ }
+
+ showCaptcha() {
+ return (
+ <div class="col-sm-4">
+ {this.state.captcha.ok && (
+ <>
+ <img
+ class="rounded-top img-fluid"
+ src={this.captchaPngSrc()}
+ style="border-bottom-right-radius: 0; border-bottom-left-radius: 0;"
+ alt={i18n.t("captcha")}
+ />
+ {this.state.captcha.ok.wav && (
+ <button
+ class="rounded-bottom btn btn-sm btn-secondary btn-block"
+ style="border-top-right-radius: 0; border-top-left-radius: 0;"
+ title={i18n.t("play_captcha_audio")}
+ onClick={linkEvent(this, this.handleCaptchaPlay)}
+ type="button"
+ disabled={this.state.captchaPlaying}
+ >
+ <Icon icon="play" classes="icon-play" />
+ </button>
+ )}
+ </>
+ )}
+ </div>
+ );
+ }
+
+ handleLoginSubmit(i: Login, event: any) {
+ event.preventDefault();
+ i.state.loginLoading = true;
+ i.setState(i.state);
+ WebSocketService.Instance.send(wsClient.login(i.state.loginForm));
+ }
+
+ handleLoginUsernameChange(i: Login, event: any) {
+ i.state.loginForm.username_or_email = event.target.value;
+ i.setState(i.state);
+ }
+
+ handleLoginPasswordChange(i: Login, event: any) {
+ i.state.loginForm.password = event.target.value;
+ i.setState(i.state);
+ }
+
+ handleRegisterSubmit(i: Login, event: any) {
+ event.preventDefault();
+ i.state.registerLoading = true;
+ i.setState(i.state);
+ WebSocketService.Instance.send(wsClient.register(i.state.registerForm));
+ }
+
+ handleRegisterUsernameChange(i: Login, event: any) {
+ i.state.registerForm.username = event.target.value;
+ i.setState(i.state);
+ }
+
+ handleRegisterEmailChange(i: Login, event: any) {
+ i.state.registerForm.email = event.target.value;
+ if (i.state.registerForm.email == "") {
+ i.state.registerForm.email = undefined;
+ }
+ i.setState(i.state);
+ }
+
+ handleRegisterPasswordChange(i: Login, event: any) {
+ i.state.registerForm.password = event.target.value;
+ i.setState(i.state);
+ }
+
+ handleRegisterPasswordVerifyChange(i: Login, event: any) {
+ i.state.registerForm.password_verify = event.target.value;
+ i.setState(i.state);
+ }
+
+ handleRegisterShowNsfwChange(i: Login, event: any) {
+ i.state.registerForm.show_nsfw = event.target.checked;
+ i.setState(i.state);
+ }
+
+ handleRegisterCaptchaAnswerChange(i: Login, event: any) {
+ i.state.registerForm.captcha_answer = event.target.value;
+ i.setState(i.state);
+ }
+
+ handleRegenCaptcha(_i: Login, event: any) {
+ event.preventDefault();
+ WebSocketService.Instance.send(wsClient.getCaptcha());
+ }
+
+ handlePasswordReset(i: Login, event: any) {
+ event.preventDefault();
+ let resetForm: PasswordReset = {
+ email: i.state.loginForm.username_or_email,
+ };
+ WebSocketService.Instance.send(wsClient.passwordReset(resetForm));
+ }
+
+ handleCaptchaPlay(i: Login, event: any) {
+ event.preventDefault();
+ let snd = new Audio("data:audio/wav;base64," + i.state.captcha.ok.wav);
+ snd.play();
+ i.state.captchaPlaying = true;
+ i.setState(i.state);
+ snd.addEventListener("ended", () => {
+ snd.currentTime = 0;
+ i.state.captchaPlaying = false;
+ i.setState(this.state);
+ });
+ }
+
+ captchaPngSrc() {
+ return `data:image/png;base64,${this.state.captcha.ok.png}`;
+ }
+
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
+ console.log(msg);
+ if (msg.error) {
+ toast(i18n.t(msg.error), "danger");
+ this.state = this.emptyState;
+ this.state.registerForm.captcha_answer = undefined;
+ // Refetch another captcha
+ WebSocketService.Instance.send(wsClient.getCaptcha());
+ this.setState(this.state);
+ return;
+ } else {
+ if (op == UserOperation.Login) {
+ let data = wsJsonToRes<LoginResponse>(msg).data;
+ this.state = this.emptyState;
+ this.setState(this.state);
+ UserService.Instance.login(data);
+ WebSocketService.Instance.send(
+ wsClient.userJoin({
+ auth: authField(),
+ })
+ );
+ toast(i18n.t("logged_in"));
+ this.props.history.push("/");
+ } else if (op == UserOperation.Register) {
+ let data = wsJsonToRes<LoginResponse>(msg).data;
+ this.state = this.emptyState;
+ this.setState(this.state);
+ UserService.Instance.login(data);
+ WebSocketService.Instance.send(
+ wsClient.userJoin({
+ auth: authField(),
+ })
+ );
+ this.props.history.push("/communities");
+ } else if (op == UserOperation.GetCaptcha) {
+ let data = wsJsonToRes<GetCaptchaResponse>(msg).data;
+ if (data.ok) {
+ this.state.captcha = data;
+ this.state.registerForm.captcha_uuid = data.ok.uuid;
+ this.setState(this.state);
+ }
+ } else if (op == UserOperation.PasswordReset) {
+ toast(i18n.t("reset_password_mail_sent"));
+ } else if (op == UserOperation.GetSite) {
+ let data = wsJsonToRes<GetSiteResponse>(msg).data;
+ this.state.site_view = data.site_view;
+ this.setState(this.state);
+ }
+ }
+ }
+}
import { Component, linkEvent } from "inferno";
-import { Subscription } from "rxjs";
import {
- UserOperation,
LoginResponse,
PasswordChange as PasswordChangeForm,
SiteView,
+ UserOperation,
} from "lemmy-js-client";
-import { WebSocketService, UserService } from "../services";
+import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
+import { UserService, WebSocketService } from "../../services";
import {
- wsJsonToRes,
capitalizeFirstLetter,
- toast,
- setIsoData,
isBrowser,
+ setIsoData,
+ toast,
+ wsClient,
+ wsJsonToRes,
wsSubscribe,
wsUserOp,
- wsClient,
-} from "../utils";
-import { i18n } from "../i18next";
-import { HtmlTags } from "./html-tags";
-import { Spinner } from "./icon";
+} from "../../utils";
+import { HtmlTags } from "../common/html-tags";
+import { Spinner } from "../common/icon";
interface State {
passwordChangeForm: PasswordChangeForm;
import { Component, linkEvent } from "inferno";
import { Helmet } from "inferno-helmet";
+import { LoginResponse, Register, UserOperation } from "lemmy-js-client";
import { Subscription } from "rxjs";
-import { retryWhen, delay, take } from "rxjs/operators";
-import { Register, LoginResponse, UserOperation } from "lemmy-js-client";
-import { WebSocketService, UserService } from "../services";
-import { wsUserOp, wsJsonToRes, toast, wsClient } from "../utils";
+import { delay, retryWhen, take } from "rxjs/operators";
+import { i18n } from "../../i18next";
+import { UserService, WebSocketService } from "../../services";
+import { toast, wsClient, wsJsonToRes, wsUserOp } from "../../utils";
+import { Spinner } from "../common/icon";
import { SiteForm } from "./site-form";
-import { Spinner } from "./icon";
-import { i18n } from "../i18next";
interface State {
userForm: Register;
import { Component, linkEvent } from "inferno";
import { Prompt } from "inferno-router";
-import { MarkdownTextArea } from "./markdown-textarea";
-import { Spinner } from "./icon";
-import { ImageUploadForm } from "./image-upload-form";
-import { Site, EditSite, CreateSite } from "lemmy-js-client";
-import { WebSocketService } from "../services";
+import { CreateSite, EditSite, Site } from "lemmy-js-client";
+import { i18n } from "../../i18next";
+import { WebSocketService } from "../../services";
import {
authField,
capitalizeFirstLetter,
randomStr,
wsClient,
-} from "../utils";
-import { i18n } from "../i18next";
+} from "../../utils";
+import { Spinner } from "../common/icon";
+import { ImageUploadForm } from "../common/image-upload-form";
+import { MarkdownTextArea } from "../common/markdown-textarea";
interface SiteFormProps {
site?: Site; // If a site is given, that means this is an edit
enable_downvotes: this.props.site.enable_downvotes,
open_registration: this.props.site.open_registration,
enable_nsfw: this.props.site.enable_nsfw,
- community_creation_admin_only: this.props.site
- .community_creation_admin_only,
+ community_creation_admin_only:
+ this.props.site.community_creation_admin_only,
icon: this.props.site.icon,
banner: this.props.site.banner,
auth: authField(),
import { Component, linkEvent } from "inferno";
-import { Subscription } from "rxjs";
+import { T } from "inferno-i18next";
import {
+ GetCaptchaResponse,
+ GetSiteResponse,
Login as LoginForm,
- Register,
LoginResponse,
- UserOperation,
PasswordReset,
- GetSiteResponse,
- GetCaptchaResponse,
+ Register,
SiteView,
+ UserOperation,
} from "lemmy-js-client";
-import { WebSocketService, UserService } from "../services";
+import { Subscription } from "rxjs";
+import { i18n } from "../i18next";
+import { UserService, WebSocketService } from "../services";
import {
- wsJsonToRes,
- validEmail,
- toast,
- wsSubscribe,
+ authField,
isBrowser,
+ joinLemmyUrl,
setIsoData,
- wsUserOp,
+ toast,
+ validEmail,
wsClient,
- authField,
- joinLemmyUrl,
+ wsJsonToRes,
+ wsSubscribe,
+ wsUserOp,
} from "../utils";
-import { i18n } from "../i18next";
-import { HtmlTags } from "./html-tags";
-import { Icon, Spinner } from "./icon";
-import { T } from "inferno-i18next";
+import { HtmlTags } from "./common/html-tags";
+import { Icon, Spinner } from "./common/icon";
interface State {
loginForm: LoginForm;
import { Component } from "inferno";
import { Link } from "inferno-router";
-import { Subscription } from "rxjs";
import {
- UserOperation,
+ CommunityModeratorView,
+ GetCommunity,
+ GetCommunityResponse,
GetModlog,
GetModlogResponse,
- SiteView,
- ModRemovePostView,
+ ModAddCommunityView,
+ ModAddView,
+ ModBanFromCommunityView,
+ ModBanView,
ModLockPostView,
- ModStickyPostView,
ModRemoveCommentView,
ModRemoveCommunityView,
- ModBanFromCommunityView,
- ModBanView,
- ModAddCommunityView,
- ModAddView,
- GetCommunity,
- GetCommunityResponse,
- CommunityModeratorView,
+ ModRemovePostView,
+ ModStickyPostView,
+ SiteView,
+ UserOperation,
} from "lemmy-js-client";
-import { WebSocketService, UserService } from "../services";
+import moment from "moment";
+import { Subscription } from "rxjs";
+import { i18n } from "../i18next";
+import { InitialFetchRequest } from "../interfaces";
+import { UserService, WebSocketService } from "../services";
import {
- wsJsonToRes,
fetchLimit,
- toast,
+ isBrowser,
setIsoData,
+ toast,
+ wsClient,
+ wsJsonToRes,
wsSubscribe,
- isBrowser,
wsUserOp,
- wsClient,
} from "../utils";
-import { MomentTime } from "./moment-time";
-import { HtmlTags } from "./html-tags";
-import moment from "moment";
-import { i18n } from "../i18next";
-import { InitialFetchRequest } from "shared/interfaces";
-import { PersonListing } from "./person-listing";
-import { CommunityLink } from "./community-link";
-import { Spinner } from "./icon";
-import { Paginator } from "./paginator";
+import { HtmlTags } from "./common/html-tags";
+import { Spinner } from "./common/icon";
+import { MomentTime } from "./common/moment-time";
+import { Paginator } from "./common/paginator";
+import { CommunityLink } from "./community/community-link";
+import { PersonListing } from "./person/person-listing";
enum ModlogEnum {
ModRemovePost,
import { Component } from "inferno";
-import { i18n } from "../i18next";
-import { Icon } from "./icon";
+import { i18n } from "../../i18next";
+import { Icon } from "../common/icon";
interface CakeDayProps {
creatorName: string;
import { Component, linkEvent } from "inferno";
-import { Subscription } from "rxjs";
import {
- UserOperation,
+ CommentResponse,
CommentView,
- SortType,
- GetReplies,
- GetRepliesResponse,
GetPersonMentions,
GetPersonMentionsResponse,
- PersonMentionResponse,
- CommentResponse,
- PrivateMessageView,
GetPrivateMessages,
- PrivateMessagesResponse,
+ GetReplies,
+ GetRepliesResponse,
+ PersonMentionResponse,
+ PersonMentionView,
PrivateMessageResponse,
+ PrivateMessagesResponse,
+ PrivateMessageView,
SiteView,
- PersonMentionView,
+ SortType,
+ UserOperation,
} from "lemmy-js-client";
-import { WebSocketService, UserService } from "../services";
+import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
+import { InitialFetchRequest } from "../../interfaces";
+import { UserService, WebSocketService } from "../../services";
import {
- wsJsonToRes,
- fetchLimit,
- toast,
+ authField,
+ commentsToFlatNodes,
+ createCommentLikeRes,
editCommentRes,
+ fetchLimit,
+ isBrowser,
saveCommentRes,
- createCommentLikeRes,
- commentsToFlatNodes,
- setupTippy,
setIsoData,
+ setupTippy,
+ toast,
+ wsClient,
+ wsJsonToRes,
wsSubscribe,
- isBrowser,
wsUserOp,
- wsClient,
- authField,
-} from "../utils";
-import { CommentNodes } from "./comment-nodes";
-import { PrivateMessage } from "./private-message";
-import { HtmlTags } from "./html-tags";
-import { Paginator } from "./paginator";
-import { SortSelect } from "./sort-select";
-import { Icon, Spinner } from "./icon";
-import { i18n } from "../i18next";
-import { InitialFetchRequest } from "shared/interfaces";
+} from "../../utils";
+import { CommentNodes } from "../comment/comment-nodes";
+import { HtmlTags } from "../common/html-tags";
+import { Icon, Spinner } from "../common/icon";
+import { Paginator } from "../common/paginator";
+import { SortSelect } from "../common/sort-select";
+import { PrivateMessage } from "../private_message/private-message";
enum UnreadOrAll {
Unread,
title={this.documentTitle}
path={this.context.router.route.match.url}
/>
- <h5 class="mb-1">
+ <h5 class="mb-2">
{i18n.t("inbox")}
<small>
<a
this.state.messages.length >
0 &&
this.state.unreadOrAll == UnreadOrAll.Unread && (
- <ul class="list-inline mb-1 text-muted small font-weight-bold">
- <li className="list-inline-item">
- <span
- class="pointer"
- role="button"
- onClick={linkEvent(this, this.markAllAsRead)}
- >
- {i18n.t("mark_all_as_read")}
- </span>
- </li>
- </ul>
+ <button
+ class="btn btn-secondary mb-2"
+ onClick={linkEvent(this, this.markAllAsRead)}
+ >
+ {i18n.t("mark_all_as_read")}
+ </button>
)}
{this.selects()}
{this.state.messageType == MessageType.All && this.all()}
import { Component } from "inferno";
import {
- PostView,
CommentView,
- SortType,
GetPersonDetailsResponse,
PersonViewSafe,
+ PostView,
+ SortType,
} from "lemmy-js-client";
-import { PersonDetailsView } from "../interfaces";
-import { commentsToFlatNodes, setupTippy } from "../utils";
-import { PostListing } from "./post-listing";
-import { CommentNodes } from "./comment-nodes";
-import { Paginator } from "./paginator";
+import { PersonDetailsView } from "../../interfaces";
+import { commentsToFlatNodes, setupTippy } from "../../utils";
+import { CommentNodes } from "../comment/comment-nodes";
+import { Paginator } from "../common/paginator";
+import { PostListing } from "../post/post-listing";
interface PersonDetailsProps {
personRes: GetPersonDetailsResponse;
import { Component } from "inferno";
import { Link } from "inferno-router";
import { PersonSafe } from "lemmy-js-client";
-import { showAvatars, hostname, isCakeDay } from "../utils";
+import { hostname, isCakeDay, showAvatars } from "../../utils";
+import { PictrsImage } from "../common/pictrs-image";
import { CakeDay } from "./cake-day";
-import { PictrsImage } from "./pictrs-image";
interface PersonListingProps {
person: PersonSafe;
import { Component, linkEvent } from "inferno";
import { Link } from "inferno-router";
-import { Subscription } from "rxjs";
import ISO6391 from "iso-639-1";
import {
- UserOperation,
- SortType,
- ListingType,
- SaveUserSettings,
- LoginResponse,
- DeleteAccount,
- GetSiteResponse,
- GetPersonDetailsResponse,
AddAdminResponse,
- GetPersonDetails,
- CommentResponse,
- PostResponse,
BanPersonResponse,
ChangePassword,
+ CommentResponse,
+ DeleteAccount,
+ GetPersonDetails,
+ GetPersonDetailsResponse,
+ GetSiteResponse,
+ ListingType,
+ LoginResponse,
+ PostResponse,
+ SaveUserSettings,
+ SortType,
+ UserOperation,
} from "lemmy-js-client";
-import { InitialFetchRequest, PersonDetailsView } from "../interfaces";
-import { WebSocketService, UserService } from "../services";
+import moment from "moment";
+import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
+import { InitialFetchRequest, PersonDetailsView } from "../../interfaces";
+import { UserService, WebSocketService } from "../../services";
import {
- wsJsonToRes,
- fetchLimit,
- routeSortTypeToEnum,
+ authField,
capitalizeFirstLetter,
- themes,
- setTheme,
- languages,
- toast,
- setupTippy,
- getLanguage,
- mdToHtml,
+ createCommentLikeRes,
+ createPostLikeFindRes,
+ editCommentRes,
+ editPostFindRes,
elementUrl,
- setIsoData,
+ fetchLimit,
getIdFromProps,
+ getLanguage,
getUsernameFromProps,
- wsSubscribe,
- createCommentLikeRes,
- editCommentRes,
- saveCommentRes,
- createPostLikeFindRes,
+ languages,
+ mdToHtml,
previewLines,
- editPostFindRes,
- wsUserOp,
- wsClient,
- authField,
- setOptionalAuth,
- saveScrollPosition,
restoreScrollPosition,
+ routeSortTypeToEnum,
+ saveCommentRes,
+ saveScrollPosition,
+ setIsoData,
+ setOptionalAuth,
+ setTheme,
+ setupTippy,
showLocal,
-} from "../utils";
-import { PersonListing } from "./person-listing";
-import { HtmlTags } from "./html-tags";
-import { SortSelect } from "./sort-select";
-import { ListingTypeSelect } from "./listing-type-select";
-import { MomentTime } from "./moment-time";
-import { i18n } from "../i18next";
-import moment from "moment";
+ themes,
+ toast,
+ wsClient,
+ wsJsonToRes,
+ wsSubscribe,
+ wsUserOp,
+} from "../../utils";
+import { BannerIconHeader } from "../common/banner-icon-header";
+import { HtmlTags } from "../common/html-tags";
+import { Icon, Spinner } from "../common/icon";
+import { ImageUploadForm } from "../common/image-upload-form";
+import { ListingTypeSelect } from "../common/listing-type-select";
+import { MarkdownTextArea } from "../common/markdown-textarea";
+import { MomentTime } from "../common/moment-time";
+import { SortSelect } from "../common/sort-select";
+import { CommunityLink } from "../community/community-link";
import { PersonDetails } from "./person-details";
-import { MarkdownTextArea } from "./markdown-textarea";
-import { Icon, Spinner } from "./icon";
-import { ImageUploadForm } from "./image-upload-form";
-import { BannerIconHeader } from "./banner-icon-header";
-import { CommunityLink } from "./community-link";
+import { PersonListing } from "./person-listing";
interface PersonState {
personRes: GetPersonDetailsResponse;
import { Component } from "inferno";
+import {
+ CommunityView,
+ GetCommunity,
+ GetCommunityResponse,
+ ListCommunities,
+ ListCommunitiesResponse,
+ ListingType,
+ PostView,
+ SiteView,
+ SortType,
+ UserOperation,
+} from "lemmy-js-client";
import { Subscription } from "rxjs";
-import { PostForm } from "./post-form";
-import { HtmlTags } from "./html-tags";
-import { Spinner } from "./icon";
+import { InitialFetchRequest, PostFormParams } from "shared/interfaces";
+import { i18n } from "../../i18next";
+import { UserService, WebSocketService } from "../../services";
import {
authField,
fetchLimit,
wsJsonToRes,
wsSubscribe,
wsUserOp,
-} from "../utils";
-import { UserService, WebSocketService } from "../services";
-import {
- UserOperation,
- ListCommunitiesResponse,
- CommunityView,
- SiteView,
- ListCommunities,
- SortType,
- ListingType,
- PostView,
- GetCommunity,
- GetCommunityResponse,
-} from "lemmy-js-client";
-import { i18n } from "../i18next";
-import { InitialFetchRequest, PostFormParams } from "shared/interfaces";
+} from "../../utils";
+import { HtmlTags } from "../common/html-tags";
+import { Spinner } from "../common/icon";
+import { PostForm } from "./post-form";
interface CreatePostState {
site_view: SiteView;
import { Component, linkEvent } from "inferno";
import { Post } from "lemmy-js-client";
-import { i18n } from "../i18next";
-import { Icon } from "./icon";
+import { i18n } from "../../i18next";
+import { Icon } from "../common/icon";
interface FramelyCardProps {
post: Post;
+import autosize from "autosize";
import { Component, linkEvent } from "inferno";
import { Prompt } from "inferno-router";
-import { PostListings } from "./post-listings";
-import { MarkdownTextArea } from "./markdown-textarea";
-import { Icon, Spinner } from "./icon";
-import { Subscription } from "rxjs";
import {
+ CommunityView,
CreatePost,
EditPost,
- PostView,
+ ListingType,
PostResponse,
- UserOperation,
- CommunityView,
- SortType,
+ PostView,
Search,
- SearchType,
SearchResponse,
- ListingType,
+ SearchType,
+ SortType,
+ UserOperation,
} from "lemmy-js-client";
-import { WebSocketService, UserService } from "../services";
-import { PostFormParams } from "../interfaces";
+import { Subscription } from "rxjs";
+import { pictrsUri } from "../../env";
+import { i18n } from "../../i18next";
+import { PostFormParams } from "../../interfaces";
+import { UserService, WebSocketService } from "../../services";
import {
- wsJsonToRes,
- getPageTitle,
- validURL,
- capitalizeFirstLetter,
archiveUrl,
+ authField,
+ capitalizeFirstLetter,
+ choicesConfig,
+ communitySelectName,
+ communityToChoice,
debounce,
+ fetchCommunities,
+ getPageTitle,
+ isBrowser,
isImage,
- toast,
- setupTippy,
pictrsDeleteToast,
+ setupTippy,
+ toast,
validTitle,
+ validURL,
+ wsClient,
+ wsJsonToRes,
wsSubscribe,
- isBrowser,
wsUserOp,
- wsClient,
- authField,
- communityToChoice,
- fetchCommunities,
- choicesConfig,
- communitySelectName,
-} from "../utils";
-import autosize from "autosize";
+} from "../../utils";
+import { Icon, Spinner } from "../common/icon";
+import { MarkdownTextArea } from "../common/markdown-textarea";
+import { PostListings } from "./post-listings";
-var Choices;
+var Choices: any;
if (isBrowser()) {
Choices = require("choices.js");
}
-import { i18n } from "../i18next";
-import { pictrsUri } from "../env";
-
const MAX_POST_TITLE_LENGTH = 200;
interface PostFormProps {
import { Component, linkEvent } from "inferno";
import { Link } from "inferno-router";
-import { WebSocketService, UserService } from "../services";
import {
- PostView,
+ AddAdmin,
+ AddModToCommunity,
+ BanFromCommunity,
+ BanPerson,
+ CommunityModeratorView,
CreatePostLike,
DeletePost,
- RemovePost,
LockPost,
- StickyPost,
- SavePost,
PersonViewSafe,
- BanFromCommunity,
- BanPerson,
- AddModToCommunity,
- AddAdmin,
- TransferSite,
+ PostView,
+ RemovePost,
+ SavePost,
+ StickyPost,
TransferCommunity,
- CommunityModeratorView,
+ TransferSite,
} from "lemmy-js-client";
-import { BanType } from "../interfaces";
-import { MomentTime } from "./moment-time";
-import { PostForm } from "./post-form";
-import { IFramelyCard } from "./iframely-card";
-import { PersonListing } from "./person-listing";
-import { CommunityLink } from "./community-link";
-import { PictrsImage } from "./pictrs-image";
-import { Icon } from "./icon";
+import { externalHost } from "../../env";
+import { i18n } from "../../i18next";
+import { BanType } from "../../interfaces";
+import { UserService, WebSocketService } from "../../services";
import {
- md,
- mdToHtml,
+ authField,
canMod,
- isMod,
- isImage,
- isVideo,
getUnixTime,
- setupTippy,
hostname,
+ isImage,
+ isMod,
+ isVideo,
+ md,
+ mdToHtml,
previewLines,
- wsClient,
- authField,
+ setupTippy,
showScores,
-} from "../utils";
-import { i18n } from "../i18next";
-import { externalHost } from "../env";
+ wsClient,
+} from "../../utils";
+import { Icon } from "../common/icon";
+import { MomentTime } from "../common/moment-time";
+import { PictrsImage } from "../common/pictrs-image";
+import { CommunityLink } from "../community/community-link";
+import { PersonListing } from "../person/person-listing";
+import { IFramelyCard } from "./iframely-card";
+import { PostForm } from "./post-form";
interface PostListingState {
showEdit: boolean;
)}
{(isImage(post.url) || post.thumbnail_url) &&
(!this.state.imageExpanded ? (
- <span
- class="text-monospace unselectable pointer ml-2 text-muted small"
+ <button
+ class="btn btn-link text-monospace text-muted small d-inline-block ml-2"
data-tippy-content={i18n.t("expand_here")}
onClick={linkEvent(this, this.handleImageExpandClick)}
>
<Icon icon="plus-square" classes="icon-inline" />
- </span>
+ </button>
) : (
<span>
- <span
- class="text-monospace unselectable pointer ml-2 text-muted small"
+ <button
+ class="btn btn-link text-monospace text-muted small d-inline-block ml-2"
onClick={linkEvent(this, this.handleImageExpandClick)}
>
<Icon icon="minus-square" classes="icon-inline" />
- </span>
+ </button>
<div>
- <span
- class="pointer"
+ <button
+ class="btn btn-link d-inline-block"
onClick={linkEvent(this, this.handleImageExpandClick)}
>
<PictrsImage src={this.getImageSrc()} />
- </span>
+ </button>
</div>
</span>
))}
import { Component } from "inferno";
+import { T } from "inferno-i18next";
import { Link } from "inferno-router";
import { PostView } from "lemmy-js-client";
+import { i18n } from "../../i18next";
import { PostListing } from "./post-listing";
-import { i18n } from "../i18next";
-import { T } from "inferno-i18next";
interface PostListingsProps {
posts: PostView[];
+import autosize from "autosize";
import { Component, linkEvent } from "inferno";
-import { HtmlTags } from "./html-tags";
-import { Spinner } from "./icon";
-import { Subscription } from "rxjs";
import {
- UserOperation,
- PostView,
- GetPostResponse,
- PostResponse,
- MarkCommentAsRead,
- CommentResponse,
- CommunityResponse,
+ AddAdminResponse,
+ AddModToCommunityResponse,
BanFromCommunityResponse,
BanPersonResponse,
- AddModToCommunityResponse,
- AddAdminResponse,
- SearchType,
- SortType,
- Search,
+ CommentResponse,
+ CommunityResponse,
+ GetCommunityResponse,
GetPost,
- SearchResponse,
+ GetPostResponse,
GetSiteResponse,
- GetCommunityResponse,
ListingType,
+ MarkCommentAsRead,
+ PostResponse,
+ PostView,
+ Search,
+ SearchResponse,
+ SearchType,
+ SortType,
+ UserOperation,
} from "lemmy-js-client";
+import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
import {
+ CommentNode as CommentNodeI,
CommentSortType,
CommentViewType,
InitialFetchRequest,
- CommentNode as CommentNodeI,
-} from "../interfaces";
-import { WebSocketService, UserService } from "../services";
+} from "../../interfaces";
+import { UserService, WebSocketService } from "../../services";
import {
- wsJsonToRes,
- toast,
- editCommentRes,
- saveCommentRes,
+ authField,
+ buildCommentsTree,
+ commentsToFlatNodes,
createCommentLikeRes,
createPostLikeRes,
- commentsToFlatNodes,
- setupTippy,
- setIsoData,
- getIdFromProps,
+ editCommentRes,
getCommentIdFromProps,
- wsSubscribe,
+ getIdFromProps,
+ insertCommentIntoTree,
isBrowser,
- previewLines,
isImage,
- wsUserOp,
- wsClient,
- authField,
- setOptionalAuth,
- saveScrollPosition,
+ previewLines,
restoreScrollPosition,
- buildCommentsTree,
- insertCommentIntoTree,
-} from "../utils";
+ saveCommentRes,
+ saveScrollPosition,
+ setIsoData,
+ setOptionalAuth,
+ setupTippy,
+ toast,
+ wsClient,
+ wsJsonToRes,
+ wsSubscribe,
+ wsUserOp,
+} from "../../utils";
+import { CommentForm } from "../comment/comment-form";
+import { CommentNodes } from "../comment/comment-nodes";
+import { HtmlTags } from "../common/html-tags";
+import { Spinner } from "../common/icon";
+import { Sidebar } from "../community/sidebar";
import { PostListing } from "./post-listing";
-import { Sidebar } from "./sidebar";
-import { CommentForm } from "./comment-form";
-import { CommentNodes } from "./comment-nodes";
-import autosize from "autosize";
-import { i18n } from "../i18next";
interface PostState {
postRes: GetPostResponse;
import { Component } from "inferno";
-import { Subscription } from "rxjs";
-import { PrivateMessageForm } from "./private-message-form";
-import { HtmlTags } from "./html-tags";
-import { Spinner } from "./icon";
-import { UserService, WebSocketService } from "../services";
import {
- SiteView,
- UserOperation,
+ GetPersonDetails,
GetPersonDetailsResponse,
PersonViewSafe,
+ SiteView,
SortType,
- GetPersonDetails,
+ UserOperation,
} from "lemmy-js-client";
+import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
+import { InitialFetchRequest } from "../../interfaces";
+import { UserService, WebSocketService } from "../../services";
import {
authField,
getRecipientIdFromProps,
wsJsonToRes,
wsSubscribe,
wsUserOp,
-} from "../utils";
-import { i18n } from "../i18next";
-import { InitialFetchRequest } from "shared/interfaces";
+} from "../../utils";
+import { HtmlTags } from "../common/html-tags";
+import { Spinner } from "../common/icon";
+import { PrivateMessageForm } from "./private-message-form";
interface CreatePrivateMessageState {
site_view: SiteView;
import { Component, linkEvent } from "inferno";
+import { T } from "inferno-i18next";
import { Prompt } from "inferno-router";
-import { Subscription } from "rxjs";
import {
CreatePrivateMessage,
EditPrivateMessage,
- PrivateMessageView,
- PrivateMessageResponse,
PersonSafe,
+ PrivateMessageResponse,
+ PrivateMessageView,
UserOperation,
} from "lemmy-js-client";
-import { WebSocketService } from "../services";
+import { Subscription } from "rxjs";
+import { i18n } from "../../i18next";
+import { WebSocketService } from "../../services";
import {
+ authField,
capitalizeFirstLetter,
- wsJsonToRes,
- toast,
+ isBrowser,
setupTippy,
+ toast,
+ wsClient,
+ wsJsonToRes,
wsSubscribe,
- isBrowser,
wsUserOp,
- wsClient,
- authField,
-} from "../utils";
-import { PersonListing } from "./person-listing";
-import { MarkdownTextArea } from "./markdown-textarea";
-import { Icon, Spinner } from "./icon";
-import { i18n } from "../i18next";
-import { T } from "inferno-i18next";
+} from "../../utils";
+import { Icon, Spinner } from "../common/icon";
+import { MarkdownTextArea } from "../common/markdown-textarea";
+import { PersonListing } from "../person/person-listing";
interface PrivateMessageFormProps {
recipient: PersonSafe;
// Its an edit
if (this.props.privateMessage) {
- this.state.privateMessageForm.content = this.props.privateMessage.private_message.content;
+ this.state.privateMessageForm.content =
+ this.props.privateMessage.private_message.content;
}
}
<div class="form-group row">
<label class="col-sm-2 col-form-label">
{i18n.t("message")}
- <span
+ <button
+ class="btn btn-link text-warning d-inline-block"
onClick={linkEvent(this, this.handleShowDisclaimer)}
- role="button"
- class="ml-2 pointer text-danger"
data-tippy-content={i18n.t("private_message_disclaimer")}
aria-label={i18n.t("private_message_disclaimer")}
>
<Icon icon="alert-triangle" classes="icon-inline" />
- </span>
+ </button>
</label>
<div class="col-sm-10">
<MarkdownTextArea
import { Component, linkEvent } from "inferno";
import {
- PrivateMessageView,
DeletePrivateMessage,
MarkPrivateMessageAsRead,
PersonSafe,
+ PrivateMessageView,
} from "lemmy-js-client";
-import { WebSocketService, UserService } from "../services";
-import { authField, mdToHtml, toast, wsClient } from "../utils";
-import { MomentTime } from "./moment-time";
+import { i18n } from "../../i18next";
+import { UserService, WebSocketService } from "../../services";
+import { authField, mdToHtml, toast, wsClient } from "../../utils";
+import { Icon } from "../common/icon";
+import { MomentTime } from "../common/moment-time";
+import { PersonListing } from "../person/person-listing";
import { PrivateMessageForm } from "./private-message-form";
-import { PersonListing } from "./person-listing";
-import { Icon } from "./icon";
-import { i18n } from "../i18next";
interface PrivateMessageState {
showReply: boolean;
this.state = this.emptyState;
this.handleReplyCancel = this.handleReplyCancel.bind(this);
- this.handlePrivateMessageCreate = this.handlePrivateMessageCreate.bind(
- this
- );
+ this.handlePrivateMessageCreate =
+ this.handlePrivateMessageCreate.bind(this);
this.handlePrivateMessageEdit = this.handlePrivateMessageEdit.bind(this);
}
import { Component, linkEvent } from "inferno";
-import { Subscription } from "rxjs";
import {
- UserOperation,
- PostView,
+ CommentResponse,
CommentView,
CommunityView,
+ GetCommunity,
+ GetPersonDetails,
+ ListCommunities,
+ ListCommunitiesResponse,
+ ListingType,
PersonViewSafe,
- SortType,
+ PostResponse,
+ PostView,
Search as SearchForm,
SearchResponse,
SearchType,
- PostResponse,
- CommentResponse,
Site,
- ListingType,
- ListCommunities,
- ListCommunitiesResponse,
- GetCommunity,
- GetPersonDetails,
+ SortType,
+ UserOperation,
} from "lemmy-js-client";
+import { Subscription } from "rxjs";
+import { InitialFetchRequest } from "shared/interfaces";
+import { i18n } from "../i18next";
import { WebSocketService } from "../services";
import {
- wsJsonToRes,
- fetchLimit,
- routeSearchTypeToEnum,
- routeSortTypeToEnum,
- toast,
- createCommentLikeRes,
- createPostLikeFindRes,
- commentsToFlatNodes,
- setIsoData,
- wsSubscribe,
- wsUserOp,
- wsClient,
authField,
- setOptionalAuth,
- saveScrollPosition,
- restoreScrollPosition,
- routeListingTypeToEnum,
- showLocal,
- isBrowser,
+ capitalizeFirstLetter,
choicesConfig,
+ commentsToFlatNodes,
+ communitySelectName,
+ communityToChoice,
+ createCommentLikeRes,
+ createPostLikeFindRes,
debounce,
fetchCommunities,
- communityToChoice,
+ fetchLimit,
fetchUsers,
- personToChoice,
- capitalizeFirstLetter,
- communitySelectName,
+ isBrowser,
personSelectName,
+ personToChoice,
+ restoreScrollPosition,
+ routeListingTypeToEnum,
+ routeSearchTypeToEnum,
+ routeSortTypeToEnum,
+ saveScrollPosition,
+ setIsoData,
+ setOptionalAuth,
+ showLocal,
+ toast,
+ wsClient,
+ wsJsonToRes,
+ wsSubscribe,
+ wsUserOp,
} from "../utils";
-import { PostListing } from "./post-listing";
-import { HtmlTags } from "./html-tags";
-import { Spinner } from "./icon";
-import { PersonListing } from "./person-listing";
-import { CommunityLink } from "./community-link";
-import { SortSelect } from "./sort-select";
-import { ListingTypeSelect } from "./listing-type-select";
-import { CommentNodes } from "./comment-nodes";
-import { Paginator } from "./paginator";
-import { i18n } from "../i18next";
-import { InitialFetchRequest } from "shared/interfaces";
-
-var Choices;
+import { CommentNodes } from "./comment/comment-nodes";
+import { HtmlTags } from "./common/html-tags";
+import { Spinner } from "./common/icon";
+import { ListingTypeSelect } from "./common/listing-type-select";
+import { Paginator } from "./common/paginator";
+import { SortSelect } from "./common/sort-select";
+import { CommunityLink } from "./community/community-link";
+import { PersonListing } from "./person/person-listing";
+import { PostListing } from "./post/post-listing";
+
+var Choices: any;
if (isBrowser()) {
Choices = require("choices.js");
}
+++ /dev/null
-// Custom css
-@import "../../../node_modules/tributejs/dist/tribute.css";
-@import "../../../node_modules/toastify-js/src/toastify.css";
-@import "../../../node_modules/choices.js/src/styles/choices.scss";
-@import "../../../node_modules/tippy.js/dist/tippy.css";
-@import "../../assets/css/main.css";
import i18next, { i18nTyped } from "i18next";
-import { getLanguage } from "./utils";
-import { en } from "./translations/en";
+import { ar } from "./translations/ar";
+import { bg } from "./translations/bg";
+import { ca } from "./translations/ca";
+import { da } from "./translations/da";
+import { de } from "./translations/de";
import { el } from "./translations/el";
-import { eu } from "./translations/eu";
+import { en } from "./translations/en";
import { eo } from "./translations/eo";
import { es } from "./translations/es";
-import { de } from "./translations/de";
-import { fr } from "./translations/fr";
-import { sv } from "./translations/sv";
-import { ru } from "./translations/ru";
-import { zh } from "./translations/zh";
-import { nl } from "./translations/nl";
-import { it } from "./translations/it";
-import { fi } from "./translations/fi";
-import { ca } from "./translations/ca";
+import { eu } from "./translations/eu";
import { fa } from "./translations/fa";
+import { fi } from "./translations/fi";
+import { fr } from "./translations/fr";
+import { ga } from "./translations/ga";
+import { gl } from "./translations/gl";
import { hi } from "./translations/hi";
-import { pl } from "./translations/pl";
-import { pt_BR } from "./translations/pt_BR";
+import { hr } from "./translations/hr";
+import { hu } from "./translations/hu";
+import { id } from "./translations/id";
+import { it } from "./translations/it";
import { ja } from "./translations/ja";
import { ka } from "./translations/ka";
-import { gl } from "./translations/gl";
-import { tr } from "./translations/tr";
-import { hu } from "./translations/hu";
-import { uk } from "./translations/uk";
-import { sq } from "./translations/sq";
import { km } from "./translations/km";
-import { ga } from "./translations/ga";
-import { sr_Latn } from "./translations/sr_Latn";
-import { da } from "./translations/da";
-import { oc } from "./translations/oc";
-import { hr } from "./translations/hr";
-import { th } from "./translations/th";
-import { bg } from "./translations/bg";
-import { ar } from "./translations/ar";
import { ko } from "./translations/ko";
-import { id } from "./translations/id";
import { nb_NO } from "./translations/nb_NO";
+import { nl } from "./translations/nl";
+import { oc } from "./translations/oc";
+import { pl } from "./translations/pl";
+import { pt_BR } from "./translations/pt_BR";
+import { ru } from "./translations/ru";
+import { sq } from "./translations/sq";
+import { sr_Latn } from "./translations/sr_Latn";
+import { sv } from "./translations/sv";
+import { th } from "./translations/th";
+import { tr } from "./translations/tr";
+import { uk } from "./translations/uk";
+import { zh } from "./translations/zh";
import { zh_Hant } from "./translations/zh_Hant";
+import { getLanguage } from "./utils";
// https://github.com/nimbusec-oss/inferno-i18next/blob/master/tests/T.test.js#L66
const resources = {
+++ /dev/null
-import { GetSiteResponse } from "lemmy-js-client";
-import { UserService } from "./services";
-import { i18n } from "./i18next";
-import { getLanguage } from "./utils";
-
-export function initializeSite(site: GetSiteResponse) {
- UserService.Instance.localUserView = site.my_user;
- i18n.changeLanguage(getLanguage());
-}
import { IRouteProps } from "inferno-router/dist/Route";
-import { Main } from "./components/main";
-import { Login } from "./components/login";
-import { CreatePost } from "./components/create-post";
-import { CreateCommunity } from "./components/create-community";
-import { CreatePrivateMessage } from "./components/create-private-message";
-import { PasswordChange } from "./components/password_change";
-import { Post } from "./components/post";
-import { Community } from "./components/community";
-import { Communities } from "./components/communities";
-import { Person } from "./components/person";
+import { Communities } from "./components/community/communities";
+import { Community } from "./components/community/community";
+import { CreateCommunity } from "./components/community/create-community";
+import { AdminSettings } from "./components/home/admin-settings";
+import { Home } from "./components/home/home";
+import { Instances } from "./components/home/instances";
+import { Login } from "./components/home/login";
+import { PasswordChange } from "./components/home/password_change";
+import { Setup } from "./components/home/setup";
import { Modlog } from "./components/modlog";
-import { Setup } from "./components/setup";
-import { AdminSettings } from "./components/admin-settings";
-import { Inbox } from "./components/inbox";
+import { Inbox } from "./components/person/inbox";
+import { Person } from "./components/person/person";
+import { CreatePost } from "./components/post/create-post";
+import { Post } from "./components/post/post";
+import { CreatePrivateMessage } from "./components/private_message/create-private-message";
import { Search } from "./components/search";
-import { Instances } from "./components/instances";
import { InitialFetchRequest } from "./interfaces";
interface IRoutePropsWithFetch extends IRouteProps {
{
path: `/`,
exact: true,
- component: Main,
- fetchInitialData: req => Main.fetchInitialData(req),
+ component: Home,
+ fetchInitialData: req => Home.fetchInitialData(req),
},
{
path: `/home/data_type/:data_type/listing_type/:listing_type/sort/:sort/page/:page`,
- component: Main,
- fetchInitialData: req => Main.fetchInitialData(req),
+ component: Home,
+ fetchInitialData: req => Home.fetchInitialData(req),
},
{
path: `/login`,
// import Cookies from 'js-cookie';
import IsomorphicCookie from "isomorphic-cookie";
-import { LocalUserSettingsView, LoginResponse } from "lemmy-js-client";
import jwt_decode from "jwt-decode";
-import { Subject, BehaviorSubject } from "rxjs";
+import { LocalUserSettingsView, LoginResponse } from "lemmy-js-client";
+import { BehaviorSubject, Subject } from "rxjs";
interface Claims {
sub: number;
-import { wsUri } from "../env";
import { PersonViewSafe, WebSocketJsonResponse } from "lemmy-js-client";
-import { isBrowser } from "../utils";
-import { Observable } from "rxjs";
-import { share } from "rxjs/operators";
import {
- Options as WSOptions,
default as ReconnectingWebSocket,
+ Options as WSOptions,
} from "reconnecting-websocket";
+import { Observable } from "rxjs";
+import { share } from "rxjs/operators";
+import { wsUri } from "../env";
+import { isBrowser } from "../utils";
export class WebSocketService {
private static _instance: WebSocketService;
-import "moment/locale/es";
+import emojiShortName from "emoji-short-name";
+import {
+ CommentView,
+ CommunityView,
+ GetSiteResponse,
+ LemmyHttp,
+ LemmyWebsocket,
+ ListingType,
+ LocalUserSettingsView,
+ PersonViewSafe,
+ PostView,
+ PrivateMessageView,
+ Search,
+ SearchResponse,
+ SearchType,
+ SortType,
+ UserOperation,
+ WebSocketJsonResponse,
+ WebSocketResponse,
+} from "lemmy-js-client";
+import markdown_it from "markdown-it";
+import markdown_it_container from "markdown-it-container";
+import markdown_it_sub from "markdown-it-sub";
+import markdown_it_sup from "markdown-it-sup";
+import moment from "moment";
+import "moment/locale/bg";
+import "moment/locale/ca";
+import "moment/locale/da";
+import "moment/locale/de";
import "moment/locale/el";
-import "moment/locale/eu";
import "moment/locale/eo";
-import "moment/locale/de";
-import "moment/locale/zh-cn";
+import "moment/locale/es";
+import "moment/locale/eu";
+import "moment/locale/fa";
+import "moment/locale/fi";
import "moment/locale/fr";
-import "moment/locale/sv";
-import "moment/locale/ru";
-import "moment/locale/nl";
+import "moment/locale/ga";
+import "moment/locale/gl";
+import "moment/locale/hi";
+import "moment/locale/hr";
+import "moment/locale/hu";
+import "moment/locale/id";
import "moment/locale/it";
-import "moment/locale/fi";
-import "moment/locale/ca";
-import "moment/locale/fa";
-import "moment/locale/pl";
-import "moment/locale/pt-br";
import "moment/locale/ja";
import "moment/locale/ka";
-import "moment/locale/hi";
-import "moment/locale/gl";
-import "moment/locale/tr";
-import "moment/locale/hu";
-import "moment/locale/uk";
-import "moment/locale/sq";
import "moment/locale/km";
-import "moment/locale/ga";
-import "moment/locale/sr";
import "moment/locale/ko";
-import "moment/locale/da";
-import "moment/locale/hr";
-import "moment/locale/bg";
-import "moment/locale/id";
import "moment/locale/nb";
-
-import {
- UserOperation,
- CommentView,
- LocalUserSettingsView,
- SortType,
- ListingType,
- SearchType,
- WebSocketResponse,
- WebSocketJsonResponse,
- Search,
- SearchResponse,
- PostView,
- PrivateMessageView,
- LemmyWebsocket,
- PersonViewSafe,
- CommunityView,
- LemmyHttp,
-} from "lemmy-js-client";
-
+import "moment/locale/nl";
+import "moment/locale/pl";
+import "moment/locale/pt-br";
+import "moment/locale/ru";
+import "moment/locale/sq";
+import "moment/locale/sr";
+import "moment/locale/sv";
+import "moment/locale/tr";
+import "moment/locale/uk";
+import "moment/locale/zh-cn";
+import { Subscription } from "rxjs";
+import { delay, retryWhen, take } from "rxjs/operators";
+import tippy from "tippy.js";
+import Toastify from "toastify-js";
+import { httpBase } from "./env";
+import { i18n } from "./i18next";
import {
+ CommentNode as CommentNodeI,
CommentSortType,
DataType,
IsoData,
- CommentNode as CommentNodeI,
} from "./interfaces";
import { UserService, WebSocketService } from "./services";
+
var Tribute: any;
if (isBrowser()) {
Tribute = require("tributejs");
}
-import markdown_it from "markdown-it";
-import markdown_it_sub from "markdown-it-sub";
-import markdown_it_sup from "markdown-it-sup";
-import markdown_it_container from "markdown-it-container";
-import emojiShortName from "emoji-short-name";
-import Toastify from "toastify-js";
-import tippy from "tippy.js";
-import moment from "moment";
-import { Subscription } from "rxjs";
-import { retryWhen, delay, take } from "rxjs/operators";
-import { i18n } from "./i18next";
-import { httpBase } from "./env";
export const wsClient = new LemmyWebsocket();
? pvs.person.name
: `${hostname(pvs.person.actor_id)}/${pvs.person.name}`;
}
+
+export function initializeSite(site: GetSiteResponse) {
+ UserService.Instance.localUserView = site.my_user;
+ i18n.changeLanguage(getLanguage());
+}
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08"
integrity sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==
-"@babel/core@^7.14.6":
+"@babel/core@^7.14.6", "@babel/core@^7.2.2":
version "7.14.6"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.6.tgz#e0814ec1a950032ff16c13a2721de39a8416fcab"
integrity sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==
chalk "^2.0.0"
js-tokens "^4.0.0"
+"@babel/parser@^7.0.0-beta.54", "@babel/parser@^7.14.5", "@babel/parser@^7.14.6", "@babel/parser@^7.14.7":
+ version "7.14.7"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595"
+ integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==
+
"@babel/parser@^7.12.13":
version "7.12.15"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.15.tgz#2b20de7f0b4b332d9b119dd9c33409c538b8aacf"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.13.tgz#42f03862f4aed50461e543270916b47dd501f0df"
integrity sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==
-"@babel/parser@^7.14.5", "@babel/parser@^7.14.6", "@babel/parser@^7.14.7":
- version "7.14.7"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595"
- integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==
-
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz#4b467302e1548ed3b1be43beae2cc9cf45e0bb7e"
"@babel/parser" "^7.14.5"
"@babel/types" "^7.14.5"
-"@babel/traverse@^7.13.0":
- version "7.13.13"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.13.tgz#39aa9c21aab69f74d948a486dd28a2dbdbf5114d"
- integrity sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==
- dependencies:
- "@babel/code-frame" "^7.12.13"
- "@babel/generator" "^7.13.9"
- "@babel/helper-function-name" "^7.12.13"
- "@babel/helper-split-export-declaration" "^7.12.13"
- "@babel/parser" "^7.13.13"
- "@babel/types" "^7.13.13"
- debug "^4.1.0"
- globals "^11.1.0"
-
-"@babel/traverse@^7.14.5":
+"@babel/traverse@^7.0.0-beta.54", "@babel/traverse@^7.14.5":
version "7.14.7"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.7.tgz#64007c9774cfdc3abd23b0780bc18a3ce3631753"
integrity sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==
debug "^4.1.0"
globals "^11.1.0"
+"@babel/traverse@^7.13.0":
+ version "7.13.13"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.13.tgz#39aa9c21aab69f74d948a486dd28a2dbdbf5114d"
+ integrity sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==
+ dependencies:
+ "@babel/code-frame" "^7.12.13"
+ "@babel/generator" "^7.13.9"
+ "@babel/helper-function-name" "^7.12.13"
+ "@babel/helper-split-export-declaration" "^7.12.13"
+ "@babel/parser" "^7.13.13"
+ "@babel/types" "^7.13.13"
+ debug "^4.1.0"
+ globals "^11.1.0"
+
"@babel/types@^7", "@babel/types@^7.4.4":
version "7.11.5"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d"
lodash "^4.17.19"
to-fast-properties "^2.0.0"
+"@babel/types@^7.0.0-beta.54", "@babel/types@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff"
+ integrity sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.14.5"
+ to-fast-properties "^2.0.0"
+
"@babel/types@^7.10.4":
version "7.11.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d"
lodash "^4.17.19"
to-fast-properties "^2.0.0"
-"@babel/types@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff"
- integrity sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==
- dependencies:
- "@babel/helper-validator-identifier" "^7.14.5"
- to-fast-properties "^2.0.0"
-
"@discoveryjs/json-ext@^0.5.0":
version "0.5.2"
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752"
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
+builtin-modules@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887"
+ integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==
+
builtins@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88"
resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.1.tgz#ef15f2670db3f1992557e2d965abc459e6e358d4"
integrity sha512-5twvci5b9eRBw2wCfPtN0GmlR2/gadZqyFpPhOK6CvMFoFgA+USnZ6Jpu1lhG9h85pQ3Ouil3PfXWRD4EUaRiQ==
+caller-callsite@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134"
+ integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=
+ dependencies:
+ callsites "^2.0.0"
+
+caller-path@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4"
+ integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=
+ dependencies:
+ caller-callsite "^2.0.0"
+
+callsites@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
+ integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=
+
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
+cosmiconfig@^5.0.5:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
+ integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==
+ dependencies:
+ import-fresh "^2.0.0"
+ is-directory "^0.3.1"
+ js-yaml "^3.13.1"
+ parse-json "^4.0.0"
+
cosmiconfig@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
+detect-indent@^6.0.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6"
+ integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==
+
detect-indent@~5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50=
+detect-newline@3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
+ integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==
+
detect-newline@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03"
integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
+fast-glob@^3.0.3:
+ version "3.2.7"
+ resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1"
+ integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==
+ dependencies:
+ "@nodelib/fs.stat" "^2.0.2"
+ "@nodelib/fs.walk" "^1.2.3"
+ glob-parent "^5.1.2"
+ merge2 "^1.3.0"
+ micromatch "^4.0.4"
+
fast-glob@^3.1.1:
version "3.2.4"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3"
make-dir "^3.0.2"
pkg-dir "^4.1.0"
+find-line-column@^0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/find-line-column/-/find-line-column-0.5.2.tgz#db00238ff868551a182e74a103416d295a98c8ca"
+ integrity sha1-2wAjj/hoVRoYLnShA0FtKVqYyMo=
+
find-npm-prefix@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz#8d8ce2c78b3b4b9e66c8acc6a37c231eb841cfdf"
integrity sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA==
+find-root@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
+ integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
+
find-up@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
dependencies:
assert-plus "^1.0.0"
+git-hooks-list@1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/git-hooks-list/-/git-hooks-list-1.0.3.tgz#be5baaf78203ce342f2f844a9d2b03dba1b45156"
+ integrity sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ==
+
glob-parent@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae"
dependencies:
type-fest "^0.20.2"
+globby@10.0.0:
+ version "10.0.0"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.0.tgz#abfcd0630037ae174a88590132c2f6804e291072"
+ integrity sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw==
+ dependencies:
+ "@types/glob" "^7.1.1"
+ array-union "^2.1.0"
+ dir-glob "^3.0.1"
+ fast-glob "^3.0.3"
+ glob "^7.1.3"
+ ignore "^5.1.1"
+ merge2 "^1.2.3"
+ slash "^3.0.0"
+
globby@^11.0.3:
version "11.0.3"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
-ignore@^5.1.4:
+ignore@^5.1.1, ignore@^5.1.4:
version "5.1.8"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
+import-fresh@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546"
+ integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY=
+ dependencies:
+ caller-path "^2.0.0"
+ resolve-from "^3.0.0"
+
import-fresh@^3.0.0, import-fresh@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66"
pkg-dir "^4.2.0"
resolve-cwd "^3.0.0"
+import-sort-config@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/import-sort-config/-/import-sort-config-6.0.0.tgz#7313775b761eb479ab2d383945ecb15c008763b8"
+ integrity sha512-FJpF2F3+30JXqH1rJKeajxoSCHCueai3/0ntDN4y3GJL5pjnLDt/VjCy5FzjH7u0NHnllL/zVEf1wfmsVxJlPQ==
+ dependencies:
+ cosmiconfig "^5.0.5"
+ find-root "^1.0.0"
+ minimatch "^3.0.4"
+ resolve-from "^4.0.0"
+
+import-sort-parser-babylon@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/import-sort-parser-babylon/-/import-sort-parser-babylon-6.0.0.tgz#e1a4c28e0794ad7d9ff36cd045559d8ca8c38be7"
+ integrity sha512-NyShTiNhTh4Vy7kJUVe6CuvOaQAzzfSIT72wtp3CzGjz8bHjNj59DCAjncuviicmDOgVAgmLuSh1WMcLYAMWGg==
+ dependencies:
+ "@babel/core" "^7.2.2"
+ "@babel/parser" "^7.0.0-beta.54"
+ "@babel/traverse" "^7.0.0-beta.54"
+ "@babel/types" "^7.0.0-beta.54"
+ find-line-column "^0.5.2"
+
+import-sort-parser-typescript@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/import-sort-parser-typescript/-/import-sort-parser-typescript-6.0.0.tgz#98e73cef9e077d073e798722ed59e215b51c17e2"
+ integrity sha512-pgxnr3I156DonupQriNsgDb2zJN9TxrqCCIN1rwT/6SDO1rkJb+a0fjqshCjlgacTSA92oPAp1eAwmQUeZi3dw==
+ dependencies:
+ typescript "^3.2.4"
+
+import-sort-parser@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/import-sort-parser/-/import-sort-parser-6.0.0.tgz#0d901f264d98ed7caaae71f66128a686f828f2f4"
+ integrity sha512-H5L+d6HnqHvThB0GmAA3/43Sv74oCwL0iMk3/ixOv0LRJ69rCyHXeG/+UadMHrD2FefEmgPIWboEPAG7gsQrkA==
+
+import-sort-style-module@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/import-sort-style-module/-/import-sort-style-module-6.0.0.tgz#3149df4785bae804ed32630634ed49e405fa7cad"
+ integrity sha512-Oxd256EVt6TAgawhIDuKnNHWumzHMHFWhVncBBvlHVnx69B4GP/Gu4Xo+gjxtqSEKEvam5ajUkNvnsXLDMDjKg==
+
+import-sort-style@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/import-sort-style/-/import-sort-style-6.0.0.tgz#088523f056e5064c34a6426f4733674d81b42e6a"
+ integrity sha512-z0H5PKs7YoDeKxNYXv2AA1mjjZFY07fjeNCXUdTM3ymJtWeeEoTm8CQkFm2l+KPZoMczIvdwzJpWkkOamBnsPw==
+
+import-sort@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/import-sort/-/import-sort-6.0.0.tgz#48ba2a7b53f2566ca1dd004327ea271321ad64ff"
+ integrity sha512-XUwSQMGAGmcW/wfshFE0gXgb1NPF6ibbQD6wDr3KRDykZf/lZj0jf58Bwa02xNb8EE59oz7etFe9OHnJocUW5Q==
+ dependencies:
+ detect-newline "^2.1.0"
+ import-sort-parser "^6.0.0"
+ import-sort-style "^6.0.0"
+ is-builtin-module "^3.0.0"
+ resolve "^1.8.1"
+
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
dependencies:
builtin-modules "^1.0.0"
+is-builtin-module@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.1.0.tgz#6fdb24313b1c03b75f8b9711c0feb8c30b903b00"
+ integrity sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==
+ dependencies:
+ builtin-modules "^3.0.0"
+
is-callable@^1.1.4, is-callable@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb"
is-data-descriptor "^1.0.0"
kind-of "^6.0.2"
+is-directory@^0.3.1:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
+ integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=
+
is-extendable@^0.1.0, is-extendable@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
dependencies:
path-is-inside "^1.0.2"
+is-plain-obj@2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
+ integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
+
is-plain-obj@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
-json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.2:
+json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
-merge2@^1.3.0:
+merge2@^1.2.3, merge2@^1.3.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
dependencies:
error-ex "^1.2.0"
+parse-json@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
+ integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=
+ dependencies:
+ error-ex "^1.3.1"
+ json-parse-better-errors "^1.0.1"
+
parse-json@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646"
dependencies:
fast-diff "^1.1.2"
+prettier-plugin-import-sort@^0.0.7:
+ version "0.0.7"
+ resolved "https://registry.yarnpkg.com/prettier-plugin-import-sort/-/prettier-plugin-import-sort-0.0.7.tgz#b13dcc4de98940b99066a9e34606a955d109b546"
+ integrity sha512-O0KlUSq+lwvh+UiN3wZDT6wWkf7TNxTVv2/XXE5KqpRNbFJq3nRg2ftzBYFFO8QGpdWIrOB0uCTCtFjIxmVKQw==
+ dependencies:
+ import-sort "^6.0.0"
+ import-sort-config "^6.0.0"
+ import-sort-parser-babylon "^6.0.0"
+ import-sort-parser-typescript "^6.0.0"
+
+prettier-plugin-organize-imports@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-2.2.0.tgz#dcdd5222416a90bd819734f131fea4a22b1c613a"
+ integrity sha512-2WM3moc/cAPCCsSneYhaL4+mMws0Bypbxz+98wuRyaA7GMokhOECVkQCG7l2hcH+9/4d5NsgZs9yktfwDy4r7A==
+
+prettier-plugin-packagejson@^2.2.11:
+ version "2.2.11"
+ resolved "https://registry.yarnpkg.com/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.2.11.tgz#640b6301da3a58c489889b3d315255e18153daf0"
+ integrity sha512-oJCBCEkHIKScEv6qNQC47S39NXlevbzwvoJE3gflmBB8/3BEsC6ZRi+hwFVajw32b4tDI9hFXPIzmVd/T8Rm9w==
+ dependencies:
+ sort-package-json "1.50.0"
+
prettier@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d"
dependencies:
path-parse "^1.0.6"
-resolve@^1.14.2, resolve@^1.20.0:
+resolve@^1.14.2, resolve@^1.20.0, resolve@^1.8.1:
version "1.20.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
ip "1.1.5"
smart-buffer "^4.1.0"
+sort-object-keys@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/sort-object-keys/-/sort-object-keys-1.1.3.tgz#bff833fe85cab147b34742e45863453c1e190b45"
+ integrity sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==
+
+sort-package-json@1.50.0:
+ version "1.50.0"
+ resolved "https://registry.yarnpkg.com/sort-package-json/-/sort-package-json-1.50.0.tgz#19fc109fe23bd157bd03c8e572fa3251a52467d8"
+ integrity sha512-qZpqhMU9XTntebgAgc4hv/D6Fzhh7kFnwvV6a7+q8y8J5JoaDqPYQnvXPf7BBqG95tdE8X6JVNo7/jDzcbdfUg==
+ dependencies:
+ detect-indent "^6.0.0"
+ detect-newline "3.1.0"
+ git-hooks-list "1.0.3"
+ globby "10.0.0"
+ is-plain-obj "2.1.0"
+ sort-object-keys "^1.1.3"
+
sorted-object@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
+typescript@^3.2.4:
+ version "3.9.10"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8"
+ integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==
+
typescript@^4.3.5:
version "4.3.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4"