mirror of
https://github.com/LemmyNet/joinlemmy-site.git
synced 2024-11-21 20:01:16 +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
|
# 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
|
RUN apk add --no-cache git bash curl
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY lemmy-docs ./lemmy-docs
|
COPY lemmy-docs ./lemmy-docs
|
||||||
|
@ -7,7 +7,7 @@ WORKDIR /app/lemmy-docs
|
||||||
RUN ./update-includes.sh
|
RUN ./update-includes.sh
|
||||||
|
|
||||||
# Build the docs
|
# Build the docs
|
||||||
FROM alpine:3 as docs
|
FROM alpine:3 AS docs
|
||||||
WORKDIR /app
|
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 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
|
RUN tar -xzf mdbook.tar.gz
|
||||||
|
@ -15,7 +15,7 @@ COPY lemmy-docs ./lemmy-docs
|
||||||
RUN ./mdbook build lemmy-docs -d ../docs
|
RUN ./mdbook build lemmy-docs -d ../docs
|
||||||
|
|
||||||
# Build the typedoc API docs
|
# Build the typedoc API docs
|
||||||
FROM node:alpine as api
|
FROM node:alpine AS api
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY lemmy-js-client lemmy-js-client
|
COPY lemmy-js-client lemmy-js-client
|
||||||
WORKDIR /app/lemmy-js-client
|
WORKDIR /app/lemmy-js-client
|
||||||
|
@ -24,7 +24,7 @@ RUN pnpm i
|
||||||
RUN pnpm run docs
|
RUN pnpm run docs
|
||||||
|
|
||||||
# Build the isomorphic app
|
# 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 apk update && apk add python3 build-base gcc wget git curl --no-cache
|
||||||
RUN curl -sf https://gobinaries.com/tj/node-prune | sh
|
RUN curl -sf https://gobinaries.com/tj/node-prune | sh
|
||||||
RUN corepack enable pnpm
|
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/typescript
|
||||||
RUN rm -rf ./node_modules/npm
|
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/dist /app/dist
|
||||||
COPY --from=builder /app/node_modules /app/node_modules
|
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",
|
"clean": "rimraf dist",
|
||||||
"crawl": "node crawl.mjs",
|
"crawl": "node crawl.mjs",
|
||||||
"update-donations": "node update_donations.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}\"",
|
"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 && node generate_translations.mjs && pnpm tailwind && pnpm generate_rss_feed",
|
"prebuild:dev": "pnpm clean && pnpm translations:generate && pnpm tailwind && pnpm generate_rss_feed",
|
||||||
"prebuild:prod": "pnpm clean && node generate_translations.mjs && 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",
|
"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",
|
"tailwind": "tailwindcss -i ./src/style.css -o ./dist/styles/styles.css --minify",
|
||||||
"prepare": "husky",
|
"prepare": "husky",
|
||||||
"start": "pnpm build:dev --watch & tailwind --watch"
|
"start": "pnpm build:dev --watch & tailwind --watch"
|
||||||
|
@ -27,7 +30,7 @@
|
||||||
"@babel/preset-env": "7.25.8",
|
"@babel/preset-env": "7.25.8",
|
||||||
"@babel/preset-typescript": "^7.23.2",
|
"@babel/preset-typescript": "^7.23.2",
|
||||||
"@babel/runtime": "^7.23.2",
|
"@babel/runtime": "^7.23.2",
|
||||||
"@glidejs/glide": "3.6.2",
|
"@glidejs/glide": "3.5.2",
|
||||||
"@tailwindcss/typography": "^0.5.10",
|
"@tailwindcss/typography": "^0.5.10",
|
||||||
"babel-loader": "^9.1.3",
|
"babel-loader": "^9.1.3",
|
||||||
"babel-plugin-inferno": "^6.7.0",
|
"babel-plugin-inferno": "^6.7.0",
|
||||||
|
@ -73,6 +76,9 @@
|
||||||
"@typescript-eslint/parser": "^8.0.0",
|
"@typescript-eslint/parser": "^8.0.0",
|
||||||
"css-loader": "^7.0.0",
|
"css-loader": "^7.0.0",
|
||||||
"eslint": "^9.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",
|
"eslint-plugin-prettier": "^5.0.1",
|
||||||
"husky": "^9.0.6",
|
"husky": "^9.0.6",
|
||||||
"lint-staged": "^15.0.2",
|
"lint-staged": "^15.0.2",
|
||||||
|
@ -84,6 +90,7 @@
|
||||||
"style-loader": "^4.0.0",
|
"style-loader": "^4.0.0",
|
||||||
"terser": "^5.24.0",
|
"terser": "^5.24.0",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
|
"typescript-eslint": "^8.9.0",
|
||||||
"webpack-dev-server": "5.1.0"
|
"webpack-dev-server": "5.1.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"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,
|
// If query param is set, server updates cookie automatically,
|
||||||
// so no need to check the query here
|
// so no need to check the query here
|
||||||
const languageCookie = getLanguageFromCookie(document.cookie);
|
const languageCookie = getLanguageFromCookie(document.cookie);
|
||||||
if (languageCookie != null) {
|
if (languageCookie !== undefined) {
|
||||||
i18n.changeLanguage(languageCookie);
|
i18n.changeLanguage(languageCookie);
|
||||||
} else {
|
} else {
|
||||||
i18n.changeLanguage(navigator.language);
|
i18n.changeLanguage(navigator.language);
|
||||||
|
|
|
@ -35,7 +35,7 @@ server.use(
|
||||||
server.use("/feed.xml", express.static(path.resolve("./dist/feed.xml")));
|
server.use("/feed.xml", express.static(path.resolve("./dist/feed.xml")));
|
||||||
|
|
||||||
function erudaInit(): string {
|
function erudaInit(): string {
|
||||||
if (process.env["NODE_ENV"] == "development") {
|
if (process.env["NODE_ENV"] === "development") {
|
||||||
return `
|
return `
|
||||||
<script src="//cdn.jsdelivr.net/npm/eruda"></script>
|
<script src="//cdn.jsdelivr.net/npm/eruda"></script>
|
||||||
<script>eruda.init();</script>
|
<script>eruda.init();</script>
|
||||||
|
@ -49,12 +49,12 @@ function setLanguage(req: Request, res: Response): string {
|
||||||
// Setting the language for non-js browsers
|
// Setting the language for non-js browsers
|
||||||
const cookieLang = getLanguageFromCookie(req.headers.cookie);
|
const cookieLang = getLanguageFromCookie(req.headers.cookie);
|
||||||
let language: string;
|
let language: string;
|
||||||
if (req.query["lang"] != null) {
|
if (req.query["lang"] !== undefined) {
|
||||||
language = req.query["lang"].toString();
|
language = req.query["lang"].toString();
|
||||||
res.cookie("lang", language, {
|
res.cookie("lang", language, {
|
||||||
expires: new Date(Date.now() + 60 * 60 * 24 * 7),
|
expires: new Date(Date.now() + 60 * 60 * 24 * 7),
|
||||||
});
|
});
|
||||||
} else if (cookieLang != null) {
|
} else if (cookieLang !== undefined) {
|
||||||
language = cookieLang;
|
language = cookieLang;
|
||||||
} else {
|
} else {
|
||||||
language = req.headers["accept-language"]
|
language = req.headers["accept-language"]
|
||||||
|
|
|
@ -37,6 +37,7 @@ const AppDetailsTitle = ({ app }: AppDetailsCardProps) => (
|
||||||
<img
|
<img
|
||||||
src={app.icon || "/static/assets/images/lemmy.svg"}
|
src={app.icon || "/static/assets/images/lemmy.svg"}
|
||||||
className="rounded-xl w-7 h-7"
|
className="rounded-xl w-7 h-7"
|
||||||
|
alt=""
|
||||||
/>
|
/>
|
||||||
<a href={app.link} className={`card-title text-2xl ${TEXT_GRADIENT}`}>
|
<a href={app.link} className={`card-title text-2xl ${TEXT_GRADIENT}`}>
|
||||||
{app.name}
|
{app.name}
|
||||||
|
@ -68,9 +69,10 @@ const AppDetailsCard = ({ app }: AppDetailsCardProps) => (
|
||||||
<img
|
<img
|
||||||
src={app.banner || "/static/assets/images/lemmy.svg"}
|
src={app.banner || "/static/assets/images/lemmy.svg"}
|
||||||
className="rounded-xl max-h-96 mb-2"
|
className="rounded-xl max-h-96 mb-2"
|
||||||
|
alt=""
|
||||||
/>
|
/>
|
||||||
<p className="text-sm text-gray-300 mb-2">{app.description}</p>
|
<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">
|
<div className="alert alert-warning">
|
||||||
<Icon icon="alert-octagon" />
|
<Icon icon="alert-octagon" />
|
||||||
<span>{i18n.t("closed_source_warning")}</span>
|
<span>{i18n.t("closed_source_warning")}</span>
|
||||||
|
@ -209,7 +211,7 @@ export class Apps extends Component<any, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePlatformChange(i: Apps, event: any) {
|
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({
|
i.setState({
|
||||||
platform,
|
platform,
|
||||||
});
|
});
|
||||||
|
|
|
@ -39,7 +39,7 @@ const QrModal = ({ name, imgData }) => (
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<div className="container mx-auto">
|
<div className="container mx-auto">
|
||||||
<img className="w-auto" src={imgData} />
|
<img className="w-auto" src={imgData} alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
@ -56,7 +56,7 @@ export class Crypto extends Component<any, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
let cryptoQr = new Map<string, string>();
|
const cryptoQr = new Map<string, string>();
|
||||||
for (const c of CRYPTOS) {
|
for (const c of CRYPTOS) {
|
||||||
cryptoQr.set(c.name, await QRCode.toDataURL(c.address));
|
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">
|
<div className="flex flex-wrap flex-row justify-center">
|
||||||
{s.avatar && (
|
{s.avatar && (
|
||||||
<div className="avatar w-auto h-8">
|
<div className="avatar w-auto h-8">
|
||||||
<img src={s.avatar} className="rounded" />
|
<img src={s.avatar} className="rounded" alt="" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<span className="text-xs">{s.name}</span>
|
<span className="text-xs">{s.name}</span>
|
||||||
|
@ -268,13 +268,13 @@ export class Donate extends Component<any, any> {
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertTranslators(): Translation[] {
|
function convertTranslators(): Translation[] {
|
||||||
let trans: Translation[] = [];
|
const trans: Translation[] = [];
|
||||||
for (const [key, value] of Object.entries(translators)) {
|
for (const [key, value] of Object.entries(translators)) {
|
||||||
let split = key.split("_");
|
const split = key.split("_");
|
||||||
let lang = split[0];
|
const lang = split[0];
|
||||||
let country = split[1] !== undefined ? split[1].toUpperCase() : undefined;
|
const country = split[1] !== undefined ? split[1].toUpperCase() : undefined;
|
||||||
|
|
||||||
let t: Translation = {
|
const t: Translation = {
|
||||||
lang,
|
lang,
|
||||||
country,
|
country,
|
||||||
translators: value,
|
translators: value,
|
||||||
|
|
|
@ -48,7 +48,7 @@ export class InstancePicker extends Component<Props, State> {
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<div className="container mx-auto">
|
<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">
|
<p className="text-2xl font-bold text-center pb-4">
|
||||||
{i18n.t("what_topic")}
|
{i18n.t("what_topic")}
|
||||||
|
@ -67,7 +67,7 @@ export class InstancePicker extends Component<Props, State> {
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{this.state.activeStep == Step.Language && (
|
{this.state.activeStep === Step.Language && (
|
||||||
<>
|
<>
|
||||||
<p className="text-2xl font-bold text-center pb-4">
|
<p className="text-2xl font-bold text-center pb-4">
|
||||||
{i18n.t("what_language")}
|
{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">
|
<ul className="steps steps-vertical lg:steps-horizontal w-full">
|
||||||
<li
|
<li>
|
||||||
|
<button
|
||||||
onClick={linkEvent(this, handleResetInterests)}
|
onClick={linkEvent(this, handleResetInterests)}
|
||||||
className={classNames("step text-gray-300", {
|
className={classNames("step text-gray-300", {
|
||||||
"step-primary": this.state.activeStep == Step.Interest,
|
"step-primary": this.state.activeStep === Step.Interest,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{i18n.t("interests")}
|
{i18n.t("interests")}
|
||||||
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li>
|
||||||
|
<button
|
||||||
onClick={linkEvent(this, handleResetInterests)}
|
onClick={linkEvent(this, handleResetInterests)}
|
||||||
className={classNames("step text-gray-300", {
|
className={classNames("step text-gray-300", {
|
||||||
"step-primary": this.state.activeStep == Step.Language,
|
"step-primary": this.state.activeStep === Step.Language,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{i18n.t("languages")}
|
{i18n.t("languages")}
|
||||||
|
</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -120,7 +124,7 @@ export class InstancePicker extends Component<Props, State> {
|
||||||
|
|
||||||
function handleTopicChange(i: InstancePicker, event: any) {
|
function handleTopicChange(i: InstancePicker, event: any) {
|
||||||
i.setState({
|
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,
|
activeStep: Step.Language,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,7 +194,7 @@ const imgError =
|
||||||
|
|
||||||
const InstanceIcon = ({ domain, icon }) => (
|
const InstanceIcon = ({ domain, icon }) => (
|
||||||
<a className="rounded-xl bg-neutral-800 p-4" href={buildUrl(domain)}>
|
<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>
|
</a>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -257,11 +257,11 @@ export const StatsBadges = ({ users, comments, monthlyUsers }) => (
|
||||||
);
|
);
|
||||||
|
|
||||||
function registrationModeToString(registrationMode: string): string {
|
function registrationModeToString(registrationMode: string): string {
|
||||||
if (registrationMode == "Open") {
|
if (registrationMode === "Open") {
|
||||||
return i18n.t("registrations_open");
|
return i18n.t("registrations_open");
|
||||||
} else if (registrationMode == "Closed") {
|
} else if (registrationMode === "Closed") {
|
||||||
return i18n.t("registrations_closed");
|
return i18n.t("registrations_closed");
|
||||||
} else if (registrationMode == "RequireApplication") {
|
} else if (registrationMode === "RequireApplication") {
|
||||||
return i18n.t("requires_application");
|
return i18n.t("requires_application");
|
||||||
} else {
|
} else {
|
||||||
return i18n.t("registrations_open");
|
return i18n.t("registrations_open");
|
||||||
|
@ -293,10 +293,13 @@ export const DetailsModal = ({
|
||||||
<img
|
<img
|
||||||
src={banner}
|
src={banner}
|
||||||
className="object-cover w-full h-48 rounded-xl mb-3"
|
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">
|
<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
|
<StatsBadges
|
||||||
users={users}
|
users={users}
|
||||||
comments={comments}
|
comments={comments}
|
||||||
|
@ -375,11 +378,11 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSortFromQuery(sort?: string): Sort {
|
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 {
|
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() {
|
function getInstancesQueryParams() {
|
||||||
|
@ -459,9 +462,9 @@ export class Instances extends Component<Props, State> {
|
||||||
instances = instances.filter(i => !this.isOpenInstance(i));
|
instances = instances.filter(i => !this.isOpenInstance(i));
|
||||||
|
|
||||||
// Sort
|
// Sort
|
||||||
if (this.state.sort == RANDOM_SORT) {
|
if (this.state.sort === RANDOM_SORT) {
|
||||||
instances = sortRandom(instances);
|
instances = sortRandom(instances);
|
||||||
} else if (this.state.sort == MOST_ACTIVE_SORT) {
|
} else if (this.state.sort === MOST_ACTIVE_SORT) {
|
||||||
instances = sortActive(instances);
|
instances = sortActive(instances);
|
||||||
} else {
|
} else {
|
||||||
instances = sortActive(instances).reverse();
|
instances = sortActive(instances).reverse();
|
||||||
|
@ -570,14 +573,14 @@ export class Instances extends Component<Props, State> {
|
||||||
|
|
||||||
function handleSortChange(i: Instances, event: any) {
|
function handleSortChange(i: Instances, event: any) {
|
||||||
i.setState({
|
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();
|
i.buildInstanceList();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTopicChange(i: Instances, event: any) {
|
function handleTopicChange(i: Instances, event: any) {
|
||||||
i.setState({
|
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();
|
i.buildInstanceList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ const CarouselBlock = () => (
|
||||||
"border-primary/[.15]": i & 1,
|
"border-primary/[.15]": i & 1,
|
||||||
"border-secondary/[.15]": !(i & 1),
|
"border-secondary/[.15]": !(i & 1),
|
||||||
})}
|
})}
|
||||||
|
alt=""
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -116,7 +117,11 @@ const FollowCommunitiesBlock = ({ i }: MainProps) => (
|
||||||
const FeatureCard = ({ pic, title, subtitle, classes }) => (
|
const FeatureCard = ({ pic, title, subtitle, classes }) => (
|
||||||
<div className={`card ${CARD_GRADIENT} shadow-xl ${classes}`}>
|
<div className={`card ${CARD_GRADIENT} shadow-xl ${classes}`}>
|
||||||
<div className="p-4">
|
<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>
|
||||||
<div className="card-body pt-0">
|
<div className="card-body pt-0">
|
||||||
<h2 className="card-title text-secondary">{title}</h2>
|
<h2 className="card-title text-secondary">{title}</h2>
|
||||||
|
@ -500,6 +505,7 @@ export class Main extends Component<Props, State> {
|
||||||
<img
|
<img
|
||||||
src="/static/assets/images/world_background.svg"
|
src="/static/assets/images/world_background.svg"
|
||||||
className="bg-top bg-no-repeat bg-contain opacity-20 absolute"
|
className="bg-top bg-no-repeat bg-contain opacity-20 absolute"
|
||||||
|
alt=""
|
||||||
/>
|
/>
|
||||||
<div className="container mx-auto px-4">
|
<div className="container mx-auto px-4">
|
||||||
<TitleBlock i={this} />
|
<TitleBlock i={this} />
|
||||||
|
|
|
@ -72,7 +72,11 @@ export const Navbar = ({ footer = false }) => (
|
||||||
>
|
>
|
||||||
<div className="navbar-start">
|
<div className="navbar-start">
|
||||||
<Link className="btn btn-ghost normal-case text-xl" to="/">
|
<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>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="navbar-center hidden lg:flex">
|
<div className="navbar-center hidden lg:flex">
|
||||||
|
@ -111,13 +115,10 @@ export const Navbar = ({ footer = false }) => (
|
||||||
"dropdown-top": footer,
|
"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} />
|
<Icon icon="align-right" size={IconSize.Large} />
|
||||||
</label>
|
</label>
|
||||||
<ul
|
<ul className="menu menu-sm dropdown-content z-[1] p-2 shadow bg-neutral-800 rounded-box w-52 items-center mt-3 ">
|
||||||
tabIndex={0}
|
|
||||||
className="menu menu-sm dropdown-content z-[1] p-2 shadow bg-neutral-800 rounded-box w-52 items-center mt-3 "
|
|
||||||
>
|
|
||||||
<NavLinks />
|
<NavLinks />
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,7 +22,7 @@ export class NewsItem extends Component<any, any> {
|
||||||
}
|
}
|
||||||
|
|
||||||
get markdown(): string {
|
get markdown(): string {
|
||||||
return news_md.find(v => v.title == this.title)?.markdown ?? "";
|
return news_md.find(v => v.title === this.title)?.markdown ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -18,7 +18,7 @@ interface NewsInfo {
|
||||||
|
|
||||||
function buildNewsInfoArray(): Array<NewsInfo> {
|
function buildNewsInfoArray(): Array<NewsInfo> {
|
||||||
return news_reversed.map(n => {
|
return news_reversed.map(n => {
|
||||||
let split = n.title.split(" - ");
|
const split = n.title.split(" - ");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dateStr: split[0],
|
dateStr: split[0],
|
||||||
|
@ -48,7 +48,11 @@ const TitleBlock = () => (
|
||||||
<div className="pt-16 text-center text-4xl font-bold mb-8">
|
<div className="pt-16 text-center text-4xl font-bold mb-8">
|
||||||
{title}
|
{title}
|
||||||
<a href="/feed.xml" className="ml-4 inline-block">
|
<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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -72,17 +72,11 @@ export const i18n = i18next as i18nTyped;
|
||||||
export { resources };
|
export { resources };
|
||||||
|
|
||||||
// https://gist.github.com/hunan-rostomyan/28e8702c1cecff41f7fe64345b76f2ca
|
// https://gist.github.com/hunan-rostomyan/28e8702c1cecff41f7fe64345b76f2ca
|
||||||
export function getLanguageFromCookie(cookies?: string): string | null {
|
export function getLanguageFromCookie(cookies?: string): string | undefined {
|
||||||
if (cookies == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const key = "lang=";
|
const key = "lang=";
|
||||||
return (
|
return cookies
|
||||||
cookies
|
?.split(";")
|
||||||
.split(";")
|
|
||||||
.map(c => c.trim())
|
.map(c => c.trim())
|
||||||
.filter(cookie => cookie.substring(0, key.length) === key)
|
.filter(cookie => cookie.substring(0, key.length) === key)
|
||||||
.map(cookie => cookie.substring(key.length))[0] || null
|
.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_sub from "markdown-it-sub";
|
||||||
import markdown_it_sup from "markdown-it-sup";
|
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,
|
maximumFractionDigits: 1,
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
notation: "compact",
|
notation: "compact",
|
||||||
|
|
Loading…
Reference in a new issue