mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-11-01 10:09:56 +00:00
Merge branch 'main' into feat/create-post-file-upload-a11y
This commit is contained in:
commit
78e1ab994e
7 changed files with 43 additions and 53 deletions
|
@ -21,10 +21,6 @@
|
||||||
"@typescript-eslint/explicit-module-boundary-types": 0,
|
"@typescript-eslint/explicit-module-boundary-types": 0,
|
||||||
"@typescript-eslint/no-empty-function": 0,
|
"@typescript-eslint/no-empty-function": 0,
|
||||||
"arrow-body-style": 0,
|
"arrow-body-style": 0,
|
||||||
"jsx-a11y/anchor-is-valid": 1,
|
|
||||||
"jsx-a11y/aria-role": 1,
|
|
||||||
"jsx-a11y/click-events-have-key-events": 1,
|
|
||||||
"jsx-a11y/no-static-element-interactions": 1,
|
|
||||||
"curly": 0,
|
"curly": 0,
|
||||||
"eol-last": 0,
|
"eol-last": 0,
|
||||||
"eqeqeq": 0,
|
"eqeqeq": 0,
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
margin-top: -6.5px;
|
margin-top: -6.5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-title a:visited {
|
.post-title a:visited:not(:hover) {
|
||||||
color: var(--bs-gray) !important;
|
color: var(--bs-gray) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,22 +11,21 @@ export default async (req: Request, res: Response) => {
|
||||||
const theme = req.params.name;
|
const theme = req.params.name;
|
||||||
|
|
||||||
if (!theme.endsWith(".css")) {
|
if (!theme.endsWith(".css")) {
|
||||||
res.statusCode = 400;
|
return res.status(400).send("Theme must be a css file");
|
||||||
res.send("Theme must be a css file");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const customTheme = path.resolve(extraThemesFolder, theme);
|
const customTheme = path.resolve(extraThemesFolder, theme);
|
||||||
|
|
||||||
if (existsSync(customTheme)) {
|
if (existsSync(customTheme)) {
|
||||||
res.sendFile(customTheme);
|
return res.sendFile(customTheme);
|
||||||
} else {
|
} else {
|
||||||
const internalTheme = path.resolve(`./dist/assets/css/themes/${theme}`);
|
const internalTheme = path.resolve(`./dist/assets/css/themes/${theme}`);
|
||||||
|
|
||||||
// If the theme doesn't exist, just send litely
|
// If the theme doesn't exist, just send litely
|
||||||
if (existsSync(internalTheme)) {
|
if (existsSync(internalTheme)) {
|
||||||
res.sendFile(internalTheme);
|
return res.sendFile(internalTheme);
|
||||||
} else {
|
} else {
|
||||||
res.sendFile(path.resolve("./dist/assets/css/themes/litely.css"));
|
return res.sendFile(path.resolve("./dist/assets/css/themes/litely.css"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,7 @@ import type { NextFunction, Response } from "express";
|
||||||
export default function ({ res, next }: { res: Response; next: NextFunction }) {
|
export default function ({ res, next }: { res: Response; next: NextFunction }) {
|
||||||
res.setHeader(
|
res.setHeader(
|
||||||
"Content-Security-Policy",
|
"Content-Security-Policy",
|
||||||
`default-src 'self'; manifest-src *; connect-src *; img-src * data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; form-action 'self'; base-uri 'self'; frame-src *; media-src *`
|
`default-src 'self'; manifest-src *; connect-src *; img-src * data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; form-action 'self'; base-uri 'self'; frame-src *; media-src * data:`
|
||||||
);
|
);
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { Component, linkEvent } from "inferno";
|
import { Component } from "inferno";
|
||||||
import { Post } from "lemmy-js-client";
|
import { Post } from "lemmy-js-client";
|
||||||
import * as sanitizeHtml from "sanitize-html";
|
import * as sanitizeHtml from "sanitize-html";
|
||||||
import { relTags } from "../../config";
|
import { relTags } from "../../config";
|
||||||
import { I18NextService } from "../../services";
|
|
||||||
import { Icon } from "../common/icon";
|
import { Icon } from "../common/icon";
|
||||||
|
|
||||||
interface MetadataCardProps {
|
interface MetadataCardProps {
|
||||||
|
@ -17,10 +16,6 @@ export class MetadataCard extends Component<
|
||||||
MetadataCardProps,
|
MetadataCardProps,
|
||||||
MetadataCardState
|
MetadataCardState
|
||||||
> {
|
> {
|
||||||
state: MetadataCardState = {
|
|
||||||
expanded: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +24,7 @@ export class MetadataCard extends Component<
|
||||||
const post = this.props.post;
|
const post = this.props.post;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!this.state.expanded && post.embed_title && post.url && (
|
{post.embed_title && post.url && (
|
||||||
<div className="post-metadata-card card border-secondary mt-3 mb-2">
|
<div className="post-metadata-card card border-secondary mt-3 mb-2">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
|
@ -61,34 +56,12 @@ export class MetadataCard extends Component<
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{post.embed_video_url && (
|
|
||||||
<button
|
|
||||||
className="mt-2 btn btn-secondary text-monospace"
|
|
||||||
onClick={linkEvent(this, this.handleIframeExpand)}
|
|
||||||
>
|
|
||||||
{I18NextService.i18n.t("expand_here")}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{this.state.expanded && post.embed_video_url && (
|
|
||||||
<div className="ratio ratio-16x9">
|
|
||||||
<iframe
|
|
||||||
allowFullScreen
|
|
||||||
className="post-metadata-iframe"
|
|
||||||
src={post.embed_video_url}
|
|
||||||
title={post.embed_title}
|
|
||||||
></iframe>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleIframeExpand(i: MetadataCard) {
|
|
||||||
i.setState({ expanded: !i.state.expanded });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,6 +262,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
const { post } = this.postView;
|
const { post } = this.postView;
|
||||||
const { url } = post;
|
const { url } = post;
|
||||||
|
|
||||||
|
// if direct video link
|
||||||
if (url && isVideo(url)) {
|
if (url && isVideo(url)) {
|
||||||
return (
|
return (
|
||||||
<div className="embed-responsive mt-3">
|
<div className="embed-responsive mt-3">
|
||||||
|
@ -272,6 +273,20 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if embedded video link
|
||||||
|
if (url && post.embed_video_url) {
|
||||||
|
return (
|
||||||
|
<div className="ratio ratio-16x9">
|
||||||
|
<iframe
|
||||||
|
allowFullScreen
|
||||||
|
className="post-metadata-iframe"
|
||||||
|
src={post.embed_video_url}
|
||||||
|
title={post.embed_title}
|
||||||
|
></iframe>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,7 +353,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
} else if (url) {
|
} else if (url) {
|
||||||
if (!this.props.hideImage && isVideo(url)) {
|
if ((!this.props.hideImage && isVideo(url)) || post.embed_video_url) {
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
className="text-body"
|
className="text-body"
|
||||||
|
@ -382,7 +397,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
const post_view = this.postView;
|
const post_view = this.postView;
|
||||||
return (
|
return (
|
||||||
<span className="small">
|
<span className="small">
|
||||||
<PersonListing person={post_view.creator} />
|
<PersonListing person={post_view.creator} muted={true} />
|
||||||
{this.creatorIsMod_ && (
|
{this.creatorIsMod_ && (
|
||||||
<span className="mx-1 badge text-bg-light">
|
<span className="mx-1 badge text-bg-light">
|
||||||
{I18NextService.i18n.t("mod")}
|
{I18NextService.i18n.t("mod")}
|
||||||
|
@ -429,8 +444,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
<Link
|
<Link
|
||||||
className={`d-inline ${
|
className={`d-inline ${
|
||||||
!post.featured_community && !post.featured_local
|
!post.featured_community && !post.featured_local
|
||||||
? "text-body"
|
? "link-dark"
|
||||||
: "text-primary"
|
: "link-primary"
|
||||||
}`}
|
}`}
|
||||||
to={`/post/${post.id}`}
|
to={`/post/${post.id}`}
|
||||||
title={I18NextService.i18n.t("comments")}
|
title={I18NextService.i18n.t("comments")}
|
||||||
|
@ -455,8 +470,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
<a
|
<a
|
||||||
className={
|
className={
|
||||||
!post.featured_community && !post.featured_local
|
!post.featured_community && !post.featured_local
|
||||||
? "text-body"
|
? "link-dark"
|
||||||
: "text-primary"
|
: "link-primary"
|
||||||
}
|
}
|
||||||
href={url}
|
href={url}
|
||||||
title={url}
|
title={url}
|
||||||
|
@ -539,10 +554,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
const url = post.url;
|
const url = post.url;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<p className="d-flex text-muted align-items-center gap-1 small m-0">
|
<p className="small m-0">
|
||||||
{url && !(hostname(url) === getExternalHost()) && (
|
{url && !(hostname(url) === getExternalHost()) && (
|
||||||
<a
|
<a
|
||||||
className="text-muted fst-italic"
|
className="fst-italic link-dark link-opacity-75 link-opacity-100-hover"
|
||||||
href={url}
|
href={url}
|
||||||
title={url}
|
title={url}
|
||||||
rel={relTags}
|
rel={relTags}
|
||||||
|
@ -726,9 +741,12 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
<Icon icon="message-square" classes="me-1" inline />
|
<Icon icon="message-square" classes="me-1" inline />
|
||||||
{post_view.counts.comments}
|
{post_view.counts.comments}
|
||||||
{this.unreadCount && (
|
{this.unreadCount && (
|
||||||
<span className="text-muted fst-italic">
|
<>
|
||||||
|
{" "}
|
||||||
|
<span className="fst-italic">
|
||||||
({this.unreadCount} {I18NextService.i18n.t("new")})
|
({this.unreadCount} {I18NextService.i18n.t("new")})
|
||||||
</span>
|
</span>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
|
|
@ -332,7 +332,9 @@ export class Search extends Component<any, SearchState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
if (!this.state.isIsomorphic) {
|
if (
|
||||||
|
!(this.state.isIsomorphic || this.props.history.location.state?.searched)
|
||||||
|
) {
|
||||||
const promises = [this.fetchCommunities()];
|
const promises = [this.fetchCommunities()];
|
||||||
if (this.state.searchText) {
|
if (this.state.searchText) {
|
||||||
promises.push(this.search());
|
promises.push(this.search());
|
||||||
|
@ -1095,7 +1097,9 @@ export class Search extends Component<any, SearchState> {
|
||||||
sort: sort ?? urlSort,
|
sort: sort ?? urlSort,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.props.history.push(`/search${getQueryString(queryParams)}`);
|
this.props.history.push(`/search${getQueryString(queryParams)}`, {
|
||||||
|
searched: true,
|
||||||
|
});
|
||||||
|
|
||||||
await this.search();
|
await this.search();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue