mirror of
https://github.com/LemmyNet/joinlemmy-site.git
synced 2024-11-21 11:51:17 +00:00
Fixing eslint.
This commit is contained in:
parent
5f98a6e9e3
commit
e8dfff4da7
19 changed files with 1212 additions and 126 deletions
|
@ -1,4 +0,0 @@
|
|||
generate_translations.js
|
||||
webpack.config.js
|
||||
tailwind.config.js
|
||||
src/api_tests
|
|
@ -1,41 +0,0 @@
|
|||
{
|
||||
"root": true,
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"project": "./tsconfig.json",
|
||||
"warnOnUnsupportedTypeScriptVersion": false
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-explicit-any": 0,
|
||||
"@typescript-eslint/explicit-module-boundary-types": 0,
|
||||
"arrow-body-style": 0,
|
||||
"curly": 0,
|
||||
"eol-last": 0,
|
||||
"eqeqeq": 0,
|
||||
"func-style": 0,
|
||||
"import/no-duplicates": 0,
|
||||
"max-statements": 0,
|
||||
"max-params": 0,
|
||||
"new-cap": 0,
|
||||
"no-console": 0,
|
||||
"no-duplicate-imports": 0,
|
||||
"no-extra-parens": 0,
|
||||
"no-return-assign": 0,
|
||||
"no-throw-literal": 0,
|
||||
"no-trailing-spaces": 0,
|
||||
"no-unused-expressions": 0,
|
||||
"no-useless-constructor": 0,
|
||||
"no-useless-escape": 0,
|
||||
"no-var": 0,
|
||||
"prefer-const": 0,
|
||||
"prefer-rest-params": 0,
|
||||
"quote-props": 0,
|
||||
"unicorn/filename-case": 0
|
||||
}
|
||||
}
|
10
Dockerfile
10
Dockerfile
|
@ -1,5 +1,5 @@
|
|||
# Build the git includes for the docs
|
||||
FROM alpine:3 as docs_include
|
||||
FROM alpine:3 AS docs_include
|
||||
RUN apk add --no-cache git bash curl
|
||||
WORKDIR /app
|
||||
COPY lemmy-docs ./lemmy-docs
|
||||
|
@ -7,7 +7,7 @@ WORKDIR /app/lemmy-docs
|
|||
RUN ./update-includes.sh
|
||||
|
||||
# Build the docs
|
||||
FROM alpine:3 as docs
|
||||
FROM alpine:3 AS docs
|
||||
WORKDIR /app
|
||||
RUN wget -O mdbook.tar.gz https://github.com/rust-lang/mdBook/releases/download/v0.4.30/mdbook-v0.4.30-x86_64-unknown-linux-musl.tar.gz
|
||||
RUN tar -xzf mdbook.tar.gz
|
||||
|
@ -15,7 +15,7 @@ COPY lemmy-docs ./lemmy-docs
|
|||
RUN ./mdbook build lemmy-docs -d ../docs
|
||||
|
||||
# Build the typedoc API docs
|
||||
FROM node:alpine as api
|
||||
FROM node:alpine AS api
|
||||
WORKDIR /app
|
||||
COPY lemmy-js-client lemmy-js-client
|
||||
WORKDIR /app/lemmy-js-client
|
||||
|
@ -24,7 +24,7 @@ RUN pnpm i
|
|||
RUN pnpm run docs
|
||||
|
||||
# Build the isomorphic app
|
||||
FROM node:alpine as builder
|
||||
FROM node:alpine AS builder
|
||||
RUN apk update && apk add python3 build-base gcc wget git curl --no-cache
|
||||
RUN curl -sf https://gobinaries.com/tj/node-prune | sh
|
||||
RUN corepack enable pnpm
|
||||
|
@ -63,7 +63,7 @@ RUN rm -rf ./node_modules/import-sort-parser-typescript
|
|||
RUN rm -rf ./node_modules/typescript
|
||||
RUN rm -rf ./node_modules/npm
|
||||
|
||||
FROM node:alpine as runner
|
||||
FROM node:alpine AS runner
|
||||
COPY --from=builder /app/dist /app/dist
|
||||
COPY --from=builder /app/node_modules /app/node_modules
|
||||
|
||||
|
|
98
eslint.config.mjs
Normal file
98
eslint.config.mjs
Normal file
|
@ -0,0 +1,98 @@
|
|||
import pluginJs from "@eslint/js";
|
||||
import tseslint from "typescript-eslint";
|
||||
import prettier from "eslint-plugin-prettier/recommended";
|
||||
import jsxa11y from "eslint-plugin-jsx-a11y";
|
||||
import inferno from "eslint-plugin-inferno";
|
||||
|
||||
export default [
|
||||
pluginJs.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
prettier,
|
||||
{
|
||||
plugins: {
|
||||
inferno: inferno,
|
||||
rules: inferno.configs.recommended,
|
||||
},
|
||||
},
|
||||
{
|
||||
plugins: {
|
||||
"jsx-a11y": jsxa11y,
|
||||
},
|
||||
rules: jsxa11y.configs.recommended.rules,
|
||||
},
|
||||
{
|
||||
languageOptions: {
|
||||
parser: tseslint.parser,
|
||||
},
|
||||
},
|
||||
// For some reason this has to be in its own block
|
||||
{
|
||||
ignores: [
|
||||
"crawl.mjs",
|
||||
"generate_rss_feed.mjs",
|
||||
"generate_translations.mjs",
|
||||
"lemmy-js-client",
|
||||
"webpack.config.js",
|
||||
"tailwind.config.js",
|
||||
"src/shared/build-config.js",
|
||||
"src/api_tests",
|
||||
"**/*.png",
|
||||
"**/*.css",
|
||||
"**/*.scss",
|
||||
"**/*.svg",
|
||||
"dist/*",
|
||||
".yalc/*",
|
||||
],
|
||||
},
|
||||
{
|
||||
files: ["src/**/*.js", "src/**/*.mjs", "src/**/*.ts", "src/**/*.tsx"],
|
||||
rules: {
|
||||
"@typescript-eslint/ban-ts-comment": 0,
|
||||
"@typescript-eslint/no-explicit-any": 0,
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{ argsIgnorePattern: "^_" },
|
||||
],
|
||||
"explicit-module-boundary-types": 0,
|
||||
"no-empty-function": 0,
|
||||
"no-non-null-assertion": 0,
|
||||
"arrow-body-style": 0,
|
||||
curly: 0,
|
||||
"eol-last": 0,
|
||||
eqeqeq: "error",
|
||||
"func-style": 0,
|
||||
"import/no-duplicates": 0,
|
||||
"max-statements": 0,
|
||||
"max-params": 0,
|
||||
"new-cap": 0,
|
||||
"no-console": 0,
|
||||
"no-duplicate-imports": 0,
|
||||
"no-extra-parens": 0,
|
||||
"no-return-assign": 0,
|
||||
"no-throw-literal": 0,
|
||||
"no-trailing-spaces": 0,
|
||||
"no-unused-expressions": 0,
|
||||
"no-useless-constructor": 0,
|
||||
"no-useless-escape": 0,
|
||||
"no-var": 0,
|
||||
"prefer-const": "error",
|
||||
"prefer-rest-params": 0,
|
||||
"prettier/prettier": "error",
|
||||
"quote-props": 0,
|
||||
"unicorn/filename-case": 0,
|
||||
"jsx-a11y/media-has-caption": 0,
|
||||
"jsx-a11y/label-has-associated-control": 0,
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
patterns: [
|
||||
{
|
||||
group: ["assets/*", "client/*", "server/*", "shared/*"],
|
||||
message: "Use relative import instead.",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
15
package.json
15
package.json
|
@ -11,10 +11,13 @@
|
|||
"clean": "rimraf dist",
|
||||
"crawl": "node crawl.mjs",
|
||||
"update-donations": "node update_donations.mjs",
|
||||
"lint": "node generate_translations.mjs && tsc --noEmit && eslint --report-unused-disable-directives --ext .js,.ts,.tsx src && prettier --check \"src/**/*.{ts,tsx,js,css,scss}\"",
|
||||
"prebuild:dev": "pnpm clean && node generate_translations.mjs && pnpm tailwind && pnpm generate_rss_feed",
|
||||
"prebuild:prod": "pnpm clean && node generate_translations.mjs && pnpm tailwind && pnpm generate_rss_feed",
|
||||
"lint": "pnpm translations:generate && tsc --noEmit && pnpm eslint --report-unused-disable-directives && pnpm prettier --check \"src/**/*.{ts,tsx,js,mjs,css,scss}\"",
|
||||
"prebuild:dev": "pnpm clean && pnpm translations:generate && pnpm tailwind && pnpm generate_rss_feed",
|
||||
"prebuild:prod": "pnpm clean && pnpm translations:generate && pnpm tailwind && pnpm generate_rss_feed",
|
||||
"generate_rss_feed": "node generate_rss_feed.mjs",
|
||||
"translations:generate": "node generate_translations.mjs",
|
||||
"translations:init": "git submodule init && pnpm translations:update",
|
||||
"translations:update": "git submodule update --remote --recursive",
|
||||
"tailwind": "tailwindcss -i ./src/style.css -o ./dist/styles/styles.css --minify",
|
||||
"prepare": "husky",
|
||||
"start": "pnpm build:dev --watch & tailwind --watch"
|
||||
|
@ -27,7 +30,7 @@
|
|||
"@babel/preset-env": "7.25.8",
|
||||
"@babel/preset-typescript": "^7.23.2",
|
||||
"@babel/runtime": "^7.23.2",
|
||||
"@glidejs/glide": "3.6.2",
|
||||
"@glidejs/glide": "3.5.2",
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"babel-loader": "^9.1.3",
|
||||
"babel-plugin-inferno": "^6.7.0",
|
||||
|
@ -73,6 +76,9 @@
|
|||
"@typescript-eslint/parser": "^8.0.0",
|
||||
"css-loader": "^7.0.0",
|
||||
"eslint": "^9.0.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-inferno": "^7.34.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.0",
|
||||
"eslint-plugin-prettier": "^5.0.1",
|
||||
"husky": "^9.0.6",
|
||||
"lint-staged": "^15.0.2",
|
||||
|
@ -84,6 +90,7 @@
|
|||
"style-loader": "^4.0.0",
|
||||
"terser": "^5.24.0",
|
||||
"typescript": "^5.2.2",
|
||||
"typescript-eslint": "^8.9.0",
|
||||
"webpack-dev-server": "5.1.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
1026
pnpm-lock.yaml
1026
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -7,7 +7,7 @@ import { getLanguageFromCookie, i18n } from "../shared/i18next";
|
|||
// If query param is set, server updates cookie automatically,
|
||||
// so no need to check the query here
|
||||
const languageCookie = getLanguageFromCookie(document.cookie);
|
||||
if (languageCookie != null) {
|
||||
if (languageCookie !== undefined) {
|
||||
i18n.changeLanguage(languageCookie);
|
||||
} else {
|
||||
i18n.changeLanguage(navigator.language);
|
||||
|
|
|
@ -35,7 +35,7 @@ server.use(
|
|||
server.use("/feed.xml", express.static(path.resolve("./dist/feed.xml")));
|
||||
|
||||
function erudaInit(): string {
|
||||
if (process.env["NODE_ENV"] == "development") {
|
||||
if (process.env["NODE_ENV"] === "development") {
|
||||
return `
|
||||
<script src="//cdn.jsdelivr.net/npm/eruda"></script>
|
||||
<script>eruda.init();</script>
|
||||
|
@ -49,12 +49,12 @@ function setLanguage(req: Request, res: Response): string {
|
|||
// Setting the language for non-js browsers
|
||||
const cookieLang = getLanguageFromCookie(req.headers.cookie);
|
||||
let language: string;
|
||||
if (req.query["lang"] != null) {
|
||||
if (req.query["lang"] !== undefined) {
|
||||
language = req.query["lang"].toString();
|
||||
res.cookie("lang", language, {
|
||||
expires: new Date(Date.now() + 60 * 60 * 24 * 7),
|
||||
});
|
||||
} else if (cookieLang != null) {
|
||||
} else if (cookieLang !== undefined) {
|
||||
language = cookieLang;
|
||||
} else {
|
||||
language = req.headers["accept-language"]
|
||||
|
|
|
@ -37,6 +37,7 @@ const AppDetailsTitle = ({ app }: AppDetailsCardProps) => (
|
|||
<img
|
||||
src={app.icon || "/static/assets/images/lemmy.svg"}
|
||||
className="rounded-xl w-7 h-7"
|
||||
alt=""
|
||||
/>
|
||||
<a href={app.link} className={`card-title text-2xl ${TEXT_GRADIENT}`}>
|
||||
{app.name}
|
||||
|
@ -68,9 +69,10 @@ const AppDetailsCard = ({ app }: AppDetailsCardProps) => (
|
|||
<img
|
||||
src={app.banner || "/static/assets/images/lemmy.svg"}
|
||||
className="rounded-xl max-h-96 mb-2"
|
||||
alt=""
|
||||
/>
|
||||
<p className="text-sm text-gray-300 mb-2">{app.description}</p>
|
||||
{app.sourceType == SourceType.Closed && (
|
||||
{app.sourceType === SourceType.Closed && (
|
||||
<div className="alert alert-warning">
|
||||
<Icon icon="alert-octagon" />
|
||||
<span>{i18n.t("closed_source_warning")}</span>
|
||||
|
@ -209,7 +211,7 @@ export class Apps extends Component<any, State> {
|
|||
}
|
||||
|
||||
function handlePlatformChange(i: Apps, event: any) {
|
||||
let platform: Platform = (event.target.value as Platform) ?? Platform.All;
|
||||
const platform: Platform = (event.target.value as Platform) ?? Platform.All;
|
||||
i.setState({
|
||||
platform,
|
||||
});
|
||||
|
|
|
@ -39,7 +39,7 @@ const QrModal = ({ name, imgData }) => (
|
|||
</button>
|
||||
</form>
|
||||
<div className="container mx-auto">
|
||||
<img className="w-auto" src={imgData} />
|
||||
<img className="w-auto" src={imgData} alt="" />
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
|
@ -56,7 +56,7 @@ export class Crypto extends Component<any, State> {
|
|||
}
|
||||
|
||||
async componentDidMount() {
|
||||
let cryptoQr = new Map<string, string>();
|
||||
const cryptoQr = new Map<string, string>();
|
||||
for (const c of CRYPTOS) {
|
||||
cryptoQr.set(c.name, await QRCode.toDataURL(c.address));
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ const GoldSponsorCards = ({ title, sponsors, color }: GoldSponsorCardsProps) =>
|
|||
<div className="flex flex-wrap flex-row justify-center">
|
||||
{s.avatar && (
|
||||
<div className="avatar w-auto h-8">
|
||||
<img src={s.avatar} className="rounded" />
|
||||
<img src={s.avatar} className="rounded" alt="" />
|
||||
</div>
|
||||
)}
|
||||
<span className="text-xs">{s.name}</span>
|
||||
|
@ -268,13 +268,13 @@ export class Donate extends Component<any, any> {
|
|||
}
|
||||
|
||||
function convertTranslators(): Translation[] {
|
||||
let trans: Translation[] = [];
|
||||
const trans: Translation[] = [];
|
||||
for (const [key, value] of Object.entries(translators)) {
|
||||
let split = key.split("_");
|
||||
let lang = split[0];
|
||||
let country = split[1] !== undefined ? split[1].toUpperCase() : undefined;
|
||||
const split = key.split("_");
|
||||
const lang = split[0];
|
||||
const country = split[1] !== undefined ? split[1].toUpperCase() : undefined;
|
||||
|
||||
let t: Translation = {
|
||||
const t: Translation = {
|
||||
lang,
|
||||
country,
|
||||
translators: value,
|
||||
|
|
|
@ -48,7 +48,7 @@ export class InstancePicker extends Component<Props, State> {
|
|||
</button>
|
||||
</form>
|
||||
<div className="container mx-auto">
|
||||
{this.state.activeStep == Step.Interest && (
|
||||
{this.state.activeStep === Step.Interest && (
|
||||
<>
|
||||
<p className="text-2xl font-bold text-center pb-4">
|
||||
{i18n.t("what_topic")}
|
||||
|
@ -67,7 +67,7 @@ export class InstancePicker extends Component<Props, State> {
|
|||
</div>
|
||||
</>
|
||||
)}
|
||||
{this.state.activeStep == Step.Language && (
|
||||
{this.state.activeStep === Step.Language && (
|
||||
<>
|
||||
<p className="text-2xl font-bold text-center pb-4">
|
||||
{i18n.t("what_language")}
|
||||
|
@ -94,21 +94,25 @@ export class InstancePicker extends Component<Props, State> {
|
|||
)}
|
||||
|
||||
<ul className="steps steps-vertical lg:steps-horizontal w-full">
|
||||
<li
|
||||
onClick={linkEvent(this, handleResetInterests)}
|
||||
className={classNames("step text-gray-300", {
|
||||
"step-primary": this.state.activeStep == Step.Interest,
|
||||
})}
|
||||
>
|
||||
{i18n.t("interests")}
|
||||
<li>
|
||||
<button
|
||||
onClick={linkEvent(this, handleResetInterests)}
|
||||
className={classNames("step text-gray-300", {
|
||||
"step-primary": this.state.activeStep === Step.Interest,
|
||||
})}
|
||||
>
|
||||
{i18n.t("interests")}
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
onClick={linkEvent(this, handleResetInterests)}
|
||||
className={classNames("step text-gray-300", {
|
||||
"step-primary": this.state.activeStep == Step.Language,
|
||||
})}
|
||||
>
|
||||
{i18n.t("languages")}
|
||||
<li>
|
||||
<button
|
||||
onClick={linkEvent(this, handleResetInterests)}
|
||||
className={classNames("step text-gray-300", {
|
||||
"step-primary": this.state.activeStep === Step.Language,
|
||||
})}
|
||||
>
|
||||
{i18n.t("languages")}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -120,7 +124,7 @@ export class InstancePicker extends Component<Props, State> {
|
|||
|
||||
function handleTopicChange(i: InstancePicker, event: any) {
|
||||
i.setState({
|
||||
topic: TOPICS.find(c => c.name == event.target.value) ?? ALL_TOPIC,
|
||||
topic: TOPICS.find(c => c.name === event.target.value) ?? ALL_TOPIC,
|
||||
activeStep: Step.Language,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -194,7 +194,7 @@ const imgError =
|
|||
|
||||
const InstanceIcon = ({ domain, icon }) => (
|
||||
<a className="rounded-xl bg-neutral-800 p-4" href={buildUrl(domain)}>
|
||||
<img className="w-24 h-24" src={icon} onError={imgError} />
|
||||
<img className="w-24 h-24" src={icon} onError={imgError} alt="" />
|
||||
</a>
|
||||
);
|
||||
|
||||
|
@ -257,11 +257,11 @@ export const StatsBadges = ({ users, comments, monthlyUsers }) => (
|
|||
);
|
||||
|
||||
function registrationModeToString(registrationMode: string): string {
|
||||
if (registrationMode == "Open") {
|
||||
if (registrationMode === "Open") {
|
||||
return i18n.t("registrations_open");
|
||||
} else if (registrationMode == "Closed") {
|
||||
} else if (registrationMode === "Closed") {
|
||||
return i18n.t("registrations_closed");
|
||||
} else if (registrationMode == "RequireApplication") {
|
||||
} else if (registrationMode === "RequireApplication") {
|
||||
return i18n.t("requires_application");
|
||||
} else {
|
||||
return i18n.t("registrations_open");
|
||||
|
@ -293,10 +293,13 @@ export const DetailsModal = ({
|
|||
<img
|
||||
src={banner}
|
||||
className="object-cover w-full h-48 rounded-xl mb-3"
|
||||
alt=""
|
||||
/>
|
||||
)}
|
||||
<div className="flex flex-row flex-wrap gap-4 mb-3 items-center">
|
||||
{icon && <img className="w-8 h-8" src={icon} onError={imgError} />}
|
||||
{icon && (
|
||||
<img className="w-8 h-8" src={icon} onError={imgError} alt="" />
|
||||
)}
|
||||
<StatsBadges
|
||||
users={users}
|
||||
comments={comments}
|
||||
|
@ -375,11 +378,11 @@ interface Props {
|
|||
}
|
||||
|
||||
function getSortFromQuery(sort?: string): Sort {
|
||||
return SORTS.find(s => s.name == sort) ?? RANDOM_SORT;
|
||||
return SORTS.find(s => s.name === sort) ?? RANDOM_SORT;
|
||||
}
|
||||
|
||||
function getTopicFromQuery(topic?: string): Topic {
|
||||
return TOPICS.find(c => c.name == topic) ?? ALL_TOPIC;
|
||||
return TOPICS.find(c => c.name === topic) ?? ALL_TOPIC;
|
||||
}
|
||||
|
||||
function getInstancesQueryParams() {
|
||||
|
@ -459,9 +462,9 @@ export class Instances extends Component<Props, State> {
|
|||
instances = instances.filter(i => !this.isOpenInstance(i));
|
||||
|
||||
// Sort
|
||||
if (this.state.sort == RANDOM_SORT) {
|
||||
if (this.state.sort === RANDOM_SORT) {
|
||||
instances = sortRandom(instances);
|
||||
} else if (this.state.sort == MOST_ACTIVE_SORT) {
|
||||
} else if (this.state.sort === MOST_ACTIVE_SORT) {
|
||||
instances = sortActive(instances);
|
||||
} else {
|
||||
instances = sortActive(instances).reverse();
|
||||
|
@ -570,14 +573,14 @@ export class Instances extends Component<Props, State> {
|
|||
|
||||
function handleSortChange(i: Instances, event: any) {
|
||||
i.setState({
|
||||
sort: SORTS.find(s => s.name == event.target.value) ?? RANDOM_SORT,
|
||||
sort: SORTS.find(s => s.name === event.target.value) ?? RANDOM_SORT,
|
||||
});
|
||||
i.buildInstanceList();
|
||||
}
|
||||
|
||||
function handleTopicChange(i: Instances, event: any) {
|
||||
i.setState({
|
||||
topic: TOPICS.find(c => c.name == event.target.value) ?? ALL_TOPIC,
|
||||
topic: TOPICS.find(c => c.name === event.target.value) ?? ALL_TOPIC,
|
||||
});
|
||||
i.buildInstanceList();
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ const CarouselBlock = () => (
|
|||
"border-primary/[.15]": i & 1,
|
||||
"border-secondary/[.15]": !(i & 1),
|
||||
})}
|
||||
alt=""
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
|
@ -116,7 +117,11 @@ const FollowCommunitiesBlock = ({ i }: MainProps) => (
|
|||
const FeatureCard = ({ pic, title, subtitle, classes }) => (
|
||||
<div className={`card ${CARD_GRADIENT} shadow-xl ${classes}`}>
|
||||
<div className="p-4">
|
||||
<img src={pic} className="rounded-xl w-full object-fill min-h-[300px]" />
|
||||
<img
|
||||
src={pic}
|
||||
className="rounded-xl w-full object-fill min-h-[300px]"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<div className="card-body pt-0">
|
||||
<h2 className="card-title text-secondary">{title}</h2>
|
||||
|
@ -500,6 +505,7 @@ export class Main extends Component<Props, State> {
|
|||
<img
|
||||
src="/static/assets/images/world_background.svg"
|
||||
className="bg-top bg-no-repeat bg-contain opacity-20 absolute"
|
||||
alt=""
|
||||
/>
|
||||
<div className="container mx-auto px-4">
|
||||
<TitleBlock i={this} />
|
||||
|
|
|
@ -72,7 +72,11 @@ export const Navbar = ({ footer = false }) => (
|
|||
>
|
||||
<div className="navbar-start">
|
||||
<Link className="btn btn-ghost normal-case text-xl" to="/">
|
||||
<img src="/static/assets/images/lemmy.svg" className="h-12 w-12" />
|
||||
<img
|
||||
src="/static/assets/images/lemmy.svg"
|
||||
className="h-12 w-12"
|
||||
alt=""
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="navbar-center hidden lg:flex">
|
||||
|
@ -111,13 +115,10 @@ export const Navbar = ({ footer = false }) => (
|
|||
"dropdown-top": footer,
|
||||
})}
|
||||
>
|
||||
<label tabIndex={0} className="btn btn-ghost lg:hidden">
|
||||
<label className="btn btn-ghost lg:hidden">
|
||||
<Icon icon="align-right" size={IconSize.Large} />
|
||||
</label>
|
||||
<ul
|
||||
tabIndex={0}
|
||||
className="menu menu-sm dropdown-content z-[1] p-2 shadow bg-neutral-800 rounded-box w-52 items-center mt-3 "
|
||||
>
|
||||
<ul className="menu menu-sm dropdown-content z-[1] p-2 shadow bg-neutral-800 rounded-box w-52 items-center mt-3 ">
|
||||
<NavLinks />
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -22,7 +22,7 @@ export class NewsItem extends Component<any, any> {
|
|||
}
|
||||
|
||||
get markdown(): string {
|
||||
return news_md.find(v => v.title == this.title)?.markdown ?? "";
|
||||
return news_md.find(v => v.title === this.title)?.markdown ?? "";
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -18,7 +18,7 @@ interface NewsInfo {
|
|||
|
||||
function buildNewsInfoArray(): Array<NewsInfo> {
|
||||
return news_reversed.map(n => {
|
||||
let split = n.title.split(" - ");
|
||||
const split = n.title.split(" - ");
|
||||
|
||||
return {
|
||||
dateStr: split[0],
|
||||
|
@ -48,7 +48,11 @@ const TitleBlock = () => (
|
|||
<div className="pt-16 text-center text-4xl font-bold mb-8">
|
||||
{title}
|
||||
<a href="/feed.xml" className="ml-4 inline-block">
|
||||
<img src="/static/assets/images/rss.svg" width={24} />
|
||||
<img
|
||||
src="/static/assets/images/rss.svg"
|
||||
width={24}
|
||||
alt={i18n.t("rss_feeds")}
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -72,17 +72,11 @@ export const i18n = i18next as i18nTyped;
|
|||
export { resources };
|
||||
|
||||
// https://gist.github.com/hunan-rostomyan/28e8702c1cecff41f7fe64345b76f2ca
|
||||
export function getLanguageFromCookie(cookies?: string): string | null {
|
||||
if (cookies == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getLanguageFromCookie(cookies?: string): string | undefined {
|
||||
const key = "lang=";
|
||||
return (
|
||||
cookies
|
||||
.split(";")
|
||||
.map(c => c.trim())
|
||||
.filter(cookie => cookie.substring(0, key.length) === key)
|
||||
.map(cookie => cookie.substring(key.length))[0] || null
|
||||
);
|
||||
return cookies
|
||||
?.split(";")
|
||||
.map(c => c.trim())
|
||||
.filter(cookie => cookie.substring(0, key.length) === key)
|
||||
.map(cookie => cookie.substring(key.length))[0];
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import markdown_it_ruby from "markdown-it-ruby";
|
|||
import markdown_it_sub from "markdown-it-sub";
|
||||
import markdown_it_sup from "markdown-it-sup";
|
||||
|
||||
let SHORTNUM_SI_FORMAT = new Intl.NumberFormat("en-US", {
|
||||
const SHORTNUM_SI_FORMAT = new Intl.NumberFormat("en-US", {
|
||||
maximumFractionDigits: 1,
|
||||
//@ts-ignore
|
||||
notation: "compact",
|
||||
|
|
Loading…
Reference in a new issue