eslint: react-refresh, react-hooks
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Martti Malmi 2024-01-04 11:54:58 +02:00
parent b143520901
commit 2a2c713486
22 changed files with 62 additions and 27 deletions

View File

@ -1,7 +1,12 @@
module.exports = {
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:react/recommended"],
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
],
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint", "formatjs"],
plugins: ["@typescript-eslint", "formatjs", "react-refresh"],
rules: {
"formatjs/enforce-id": [
"error",
@ -10,6 +15,8 @@ module.exports = {
},
],
"react/react-in-jsx-scope": "off",
"react-hooks/exhaustive-deps": "off",
"react-refresh/only-export-components": "warn",
},
root: true,
ignorePatterns: ["build/", "*.test.ts", "*.js"],

View File

@ -100,6 +100,8 @@
"eslint": "^8.48.0",
"eslint-plugin-formatjs": "^4.11.3",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"postcss": "^8.4.31",
"postcss-preset-env": "^9.2.0",
"prettier": "2.8.3",

View File

@ -29,4 +29,6 @@ const AsyncButton = React.forwardRef<HTMLButtonElement, AsyncButtonProps>((props
);
});
AsyncButton.displayName = "AsyncButton";
export default AsyncButton;

View File

@ -24,7 +24,7 @@ export default function ZapstrEmbed({ ev }: { ev: NostrEvent }) {
<audio src={media?.[1] ?? ""} controls={true} />
<div>
{refPersons.map(a => (
<ProfileImage pubkey={a[1]} subHeader={<>{a[2] ?? ""}</>} className="" defaultNip=" " />
<ProfileImage key={a[1]} pubkey={a[1]} subHeader={<>{a[2] ?? ""}</>} className="" defaultNip=" " />
))}
</div>
</div>

View File

@ -345,7 +345,7 @@ export function NoteCreator() {
{Object.keys(relays.item || {})
.filter(el => relays.item[el].write)
.map((r, i, a) => (
<div className="p flex justify-between note-creator-relay">
<div className="p flex justify-between note-creator-relay" key={r}>
<div>{r}</div>
<div>
<input
@ -406,8 +406,8 @@ export function NoteCreator() {
</h4>
<FormattedMessage defaultMessage="Zaps on this note will be split to the following users." id="LwYmVi" />
<div className="flex flex-col g8">
{[...(note.zapSplits ?? [])].map((v, i, arr) => (
<div className="flex items-center g8">
{[...(note.zapSplits ?? [])].map((v: ZapTarget, i, arr) => (
<div className="flex items-center g8" key={`${v.name}-${v.value}`}>
<div className="flex flex-col flex-4 g4">
<h4>
<FormattedMessage defaultMessage="Recipient" id="8Rkoyb" />

View File

@ -5,7 +5,7 @@ export default function FileUploadProgress({ progress }: { progress: Array<Uploa
return (
<div className="flex flex-col g8">
{progress.map(p => (
<div className="flex flex-col g2" id={p.id}>
<div key={p.id} className="flex flex-col g2" id={p.id}>
{p.file.name}
<Progress value={p.progress} status={p.stage} />
</div>

View File

@ -1,5 +1,5 @@
import "./Thread.css";
import { useMemo, useState, ReactNode, useContext } from "react";
import { useMemo, useState, ReactNode, useContext, Fragment } from "react";
import { useIntl } from "react-intl";
import { useNavigate, useParams } from "react-router-dom";
import { TaggedNostrEvent, u256, NostrPrefix, EventExt, parseNostrLink, NostrLink } from "@snort/system";
@ -41,7 +41,7 @@ const Subthread = ({ active, notes, related, chains, onNavigate }: SubthreadProp
const isLastSubthread = idx === notes.length - 1;
const replies = getReplies(a.id, chains);
return (
<>
<Fragment key={a.id}>
<div className={`subthread-container ${replies.length > 0 ? "subthread-multi" : ""}`}>
<Divider />
<Note
@ -65,7 +65,7 @@ const Subthread = ({ active, notes, related, chains, onNavigate }: SubthreadProp
onNavigate={onNavigate}
/>
)}
</>
</Fragment>
);
};
@ -138,6 +138,7 @@ const TierTwo = ({ active, isLastSubthread, notes, related, chains, onNavigate }
const lastReply = idx === rest.length - 1;
return (
<ThreadNote
key={r.id}
active={active}
onNavigate={onNavigate}
note={r}

View File

@ -111,7 +111,7 @@ export function TimelineRenderer(props: TimelineRendererProps) {
<>
<div className="card latest-notes" onClick={() => props.showLatest(false)} ref={ref}>
{props.latest.slice(0, 3).map(p => {
return <ProfileImage pubkey={p} showUsername={false} link={""} showFollowDistance={false} />;
return <ProfileImage key={p} pubkey={p} showUsername={false} link={""} showFollowDistance={false} />;
})}
<FormattedMessage
defaultMessage="{n} new {n, plural, =1 {note} other {notes}}"
@ -128,6 +128,7 @@ export function TimelineRenderer(props: TimelineRendererProps) {
{props.latest.slice(0, 3).map(p => {
return (
<ProfileImage
key={p}
pubkey={p}
showProfileCard={false}
showUsername={false}

View File

@ -27,7 +27,7 @@ export function ReBroadcaster({ onClose, ev }: { onClose: () => void; ev: Tagged
{Object.keys(relays.item || {})
.filter(el => relays.item[el].write)
.map((r, i, a) => (
<div className="card flex justify-between">
<div key={r} className="card flex justify-between">
<div>{r}</div>
<div>
<input

View File

@ -165,6 +165,7 @@ export default function SendSats(props: SendSatsProps) {
<div className="flex g4 f-wrap">
{props.targets.map(v => (
<ProfileImage
key={v.value}
pubkey={v.value}
showUsername={false}
showFollowDistance={false}

View File

@ -93,7 +93,7 @@ export function HashTagHeader({ tag, events, className }: { tag: string; events?
</div>
<div className="flex items-center">
{pubkeys.slice(0, 5).map(a => (
<ProfileImage pubkey={a} showUsername={false} showFollowDistance={false} size={40} />
<ProfileImage key={a} pubkey={a} showUsername={false} showFollowDistance={false} size={40} />
))}
{pubkeys.length > 5 && (
<span>

View File

@ -173,7 +173,7 @@ export default function ZapPoolPage() {
<FormattedMessage defaultMessage="Relays" id="RoOyAh" />
</h3>
{relayConnections.map(a => (
<div>
<div key={a.address}>
<h4>{getRelayName(a.address)}</h4>
<ZapPoolTarget
target={
@ -191,7 +191,7 @@ export default function ZapPoolPage() {
<FormattedMessage defaultMessage="File hosts" id="XICsE8" />
</h3>
{UploaderServices.map(a => (
<div>
<div key={a.name}>
<h4>{a.name}</h4>
<ZapPoolTarget
target={
@ -209,7 +209,7 @@ export default function ZapPoolPage() {
<FormattedMessage defaultMessage="Data Providers" id="ELbg9p" />
</h3>
{DataProviders.map(a => (
<div>
<div key={a.name}>
<h4>{a.name}</h4>
<ZapPoolTarget
target={

View File

@ -25,7 +25,7 @@ function OnboardingLayout() {
<Icon name="translate" />
<select value={lang} onChange={e => setOverride(e.target.value)} className="capitalize">
{AllLanguageCodes.sort().map(a => (
<option value={a}>
<option key={a} value={a}>
{new Intl.DisplayNames([a], {
type: "language",
}).of(a)}

View File

@ -33,7 +33,7 @@ export default function ExportKeys() {
{hexToMnemonic(generatedEntropy ?? "")
.split(" ")
.map((a, i) => (
<div className="flex items-center word">
<div key={a} className="flex items-center word">
<div>{i + 1}</div>
<div>{a}</div>
</div>

View File

@ -80,7 +80,7 @@ export default function ModerationSettingsPage() {
</button>
</div>
{appData.mutedWords.map(v => (
<div className="p br b flex items-center justify-between">
<div key={v} className="p br b flex items-center justify-between">
<div>{v}</div>
<button type="button" onClick={() => removeMutedWord(v)}>
<FormattedMessage defaultMessage="Delete" id="K3r6DQ" />

View File

@ -59,7 +59,7 @@ const PreferencesPage = () => {
}
style={{ textTransform: "capitalize" }}>
{AllLanguageCodes.sort().map(a => (
<option value={a}>
<option key={a} value={a}>
{new Intl.DisplayNames([a], {
type: "language",
}).of(a)}

View File

@ -75,7 +75,7 @@ const RelayInfo = () => {
</h4>
<div className="grow">
{stats.info.supported_nips.map(a => (
<a target="_blank" rel="noreferrer" href={`https://nips.be/${a}`} className="pill">
<a key={a} target="_blank" rel="noreferrer" href={`https://nips.be/${a}`} className="pill">
NIP-{a.toString().padStart(2, "0")}
</a>
))}

View File

@ -148,7 +148,7 @@ export function CloseRelays() {
?.filter(a => !relayUrls.includes(unwrap(sanitizeRelayUrl(a.url))) && !a.is_paid)
.sort((a, b) => (a.distance > b.distance ? 1 : -1))
.map(a => (
<div className="bg-dark p br flex flex-col g8">
<div key={a.url} className="bg-dark p br flex flex-col g8">
<div className="flex justify-between items-center">
<div className="bold">{getRelayName(a.url)}</div>
<AsyncButton

View File

@ -62,6 +62,7 @@ export function FollowsRelayHealth({
<div>
{missingRelays.map(a => (
<ProfilePreview
key={a}
pubkey={a}
options={{
about: false,
@ -80,7 +81,7 @@ export function FollowsRelayHealth({
.sort((a, b) => (a.count > b.count ? -1 : 1))
.slice(0, 10)
.map(a => (
<div className="flex justify-between">
<div key={a.relay} className="flex justify-between">
<div>{getRelayName(a.relay)}</div>
<div>
{a.count} (<FormattedNumber style="percent" value={a.count / uniqueFollows.length} />)

View File

@ -141,7 +141,7 @@ export function PruneFollowList() {
.sort(([, a], [, b]) => (a > b ? -1 : 1))
.map(([k, v]) => {
return (
<div className="flex justify-between">
<div key={k} className="flex justify-between">
<ProfileImage pubkey={k} />
<div className="flex flex-col gap-1">
<FormattedMessage

View File

@ -91,7 +91,7 @@ export function SubscribePage() {
{Plans.map(a => {
const lower = Plans.filter(b => b.id < a.id);
return (
<div className={classNames("p flex flex-col g8", { disabled: a.disabled })}>
<div key={a.id} className={classNames("p flex flex-col g8", { disabled: a.disabled })}>
<div className="grow">
<h2>{mapPlanName(a.id)}</h2>
<p>
@ -108,10 +108,10 @@ export function SubscribePage() {
</p>
<ul className="list-disc">
{a.unlocks.map(b => (
<li>{mapFeatureName(b)} </li>
<li key={`unlocks-${b}`}>{mapFeatureName(b)} </li>
))}
{lower.map(b => (
<li>
<li key={`lower-${b}`}>
<FormattedMessage
defaultMessage="Everything in {plan}"
id="l+ikU1"

View File

@ -2964,6 +2964,8 @@ __metadata:
eslint: ^8.48.0
eslint-plugin-formatjs: ^4.11.3
eslint-plugin-react: ^7.33.2
eslint-plugin-react-hooks: ^4.6.0
eslint-plugin-react-refresh: ^0.4.5
fuse.js: ^7.0.0
highlight.js: ^11.8.0
light-bolt11-decoder: ^2.1.0
@ -5904,6 +5906,24 @@ __metadata:
languageName: node
linkType: hard
"eslint-plugin-react-hooks@npm:^4.6.0":
version: 4.6.0
resolution: "eslint-plugin-react-hooks@npm:4.6.0"
peerDependencies:
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
checksum: 23001801f14c1d16bf0a837ca7970d9dd94e7b560384b41db378b49b6e32dc43d6e2790de1bd737a652a86f81a08d6a91f402525061b47719328f586a57e86c3
languageName: node
linkType: hard
"eslint-plugin-react-refresh@npm:^0.4.5":
version: 0.4.5
resolution: "eslint-plugin-react-refresh@npm:0.4.5"
peerDependencies:
eslint: ">=7"
checksum: 953e665f6aaf097291a2bb07fde05466338aecd169bcd6faa708b50166912e3a757f45a45252cf7738b5e0d986224d363cc227864e98c979fe9978770b2b9f42
languageName: node
linkType: hard
"eslint-plugin-react@npm:^7.33.2":
version: 7.33.2
resolution: "eslint-plugin-react@npm:7.33.2"