Skip to content

Commit 2865df0

Browse files
authored
Merge pull request #268 from dozro/sonarqube/maintainability-2026-03-14
[internal] Fix maintainability and reliability issues raised by SonarQube
2 parents d5ced10 + 5b1245c commit 2865df0

37 files changed

Lines changed: 188 additions & 179 deletions

src/app/components/DeviceVerificationSetup.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ function makeUIAAction<T>(
7070
type SetupVerificationProps = {
7171
onComplete: (recoveryKey: string) => void;
7272
};
73-
function SetupVerification({ onComplete }: SetupVerificationProps) {
73+
function SetupVerification({ onComplete }: Readonly<SetupVerificationProps>) {
7474
const mx = useMatrixClient();
7575
const alive = useAlive();
7676

@@ -227,7 +227,7 @@ function SetupVerification({ onComplete }: SetupVerificationProps) {
227227
type RecoveryKeyDisplayProps = {
228228
recoveryKey: string;
229229
};
230-
function RecoveryKeyDisplay({ recoveryKey }: RecoveryKeyDisplayProps) {
230+
function RecoveryKeyDisplay({ recoveryKey }: Readonly<RecoveryKeyDisplayProps>) {
231231
const [show, setShow] = useState(false);
232232

233233
const handleCopy = () => {
@@ -241,7 +241,7 @@ function RecoveryKeyDisplay({ recoveryKey }: RecoveryKeyDisplayProps) {
241241
FileSaver.saveAs(blob, 'recovery-key.txt');
242242
};
243243

244-
const safeToDisplayKey = show ? recoveryKey : recoveryKey.replace(/[^\s]/g, '*');
244+
const safeToDisplayKey = show ? recoveryKey : recoveryKey.replaceAll(/[^\s]/g, '*');
245245

246246
return (
247247
<Box direction="Column" gap="400">

src/app/components/Pdf-viewer/PdfViewer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export const PdfViewer = as<'div', PdfViewerProps>(
8585
if (docState.status !== AsyncStatus.Success) return;
8686
const jumpInput = evt.currentTarget.jumpInput as HTMLInputElement;
8787
if (!jumpInput) return;
88-
const jumpTo = parseInt(jumpInput.value, 10);
88+
const jumpTo = Number.parseInt(jumpInput.value, 10);
8989
setPageNo(Math.max(1, Math.min(docState.data.numPages, jumpTo)));
9090
setJumpAnchor(undefined);
9191
};

src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,10 @@ export function EmoticonAutocomplete({
5757

5858
const [emojiThreshold] = useSetting(settingsAtom, 'emojiSuggestThreshold');
5959

60-
const searchList = useMemo(() => {
61-
const list: Array<EmoticonSearchItem> = [];
62-
return list.concat(
63-
imagePacks.flatMap((pack) => pack.getImages(ImageUsage.Emoticon)),
64-
emojis
65-
);
66-
}, [imagePacks]);
60+
const searchList = useMemo<Array<EmoticonSearchItem>>(
61+
() => [...imagePacks.flatMap((pack) => pack.getImages(ImageUsage.Emoticon)), ...emojis],
62+
[imagePacks]
63+
);
6764

6865
const [result, search, resetSearch] = useAsyncSearch(
6966
searchList,

src/app/components/editor/input.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ const parseHeadingNode = (
322322

323323
const headingMatch = node.name.match(/^h([123456])$/);
324324
const [, g1AsLevel] = headingMatch ?? ['h3', '3'];
325-
const level = parseInt(g1AsLevel, 10);
325+
const level = Number.parseInt(g1AsLevel, 10);
326326

327327
const mdSequence = node.attribs['data-md'];
328328
if (mdSequence !== undefined) {
@@ -334,7 +334,7 @@ const parseHeadingNode = (
334334

335335
return {
336336
type: BlockType.Heading,
337-
level: (level <= 3 ? level : 3) as HeadingLevel,
337+
level: Math.min(level, 3) as HeadingLevel,
338338
children,
339339
};
340340
};

src/app/components/editor/output.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,13 @@ export const toMatrixCustomHTML = (
128128

129129
return `${parsedMarkdown}${toMatrixCustomHTML(n, { ...opts, allowBlockMarkdown: false })}`;
130130
};
131-
if (Array.isArray(node)) return node.map(parseNode).join('');
131+
if (Array.isArray(node))
132+
return node.map((element, index, array) => parseNode(element, index, array)).join('');
132133
if (Text.isText(node)) return textToCustomHtml(node, opts);
133134

134-
const children = node.children.map(parseNode).join('');
135+
const children = node.children
136+
.map((element, index, array) => parseNode(element, index, array))
137+
.join('');
135138
return elementToCustomHtml(node, children);
136139
};
137140

@@ -193,14 +196,14 @@ export const toPlainText = (node: Descendant | Descendant[], isMarkdown: boolean
193196
* @returns boolean
194197
*/
195198
export const customHtmlEqualsPlainText = (customHtml: string, plain: string): boolean =>
196-
customHtml.replace(/<br\/>/g, '\n') === sanitizeText(plain);
199+
customHtml.replaceAll('<br/>', '\n') === sanitizeText(plain);
197200

198-
export const trimCustomHtml = (customHtml: string) => customHtml.replace(/<br\/>$/g, '').trim();
201+
export const trimCustomHtml = (customHtml: string) => customHtml.replaceAll(/<br\/>$/g, '').trim();
199202

200203
export const trimCommand = (cmdName: string, str: string) => {
201204
const cmdRegX = new RegExp(`^(\\s+)?(\\/${sanitizeForRegex(cmdName)})([^\\S\n]+)?`);
202205

203-
const match = str.match(cmdRegX);
206+
const match = new RegExp(cmdRegX).exec(str);
204207
if (!match) return str;
205208
return str.slice(match[0].length);
206209
};

src/app/components/emoji-board/EmojiBoard.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ function EmojiSidebar({
179179
packs,
180180
saveStickerEmojiBandwidth,
181181
onScrollToGroup,
182-
}: EmojiSidebarProps) {
182+
}: Readonly<EmojiSidebarProps>) {
183183
const mx = useMatrixClient();
184184
const useAuthentication = useMediaAuthentication();
185185

@@ -264,7 +264,7 @@ function StickerSidebar({
264264
packs,
265265
saveStickerEmojiBandwidth,
266266
onScrollToGroup,
267-
}: StickerSidebarProps) {
267+
}: Readonly<StickerSidebarProps>) {
268268
const mx = useMatrixClient();
269269
const useAuthentication = useMediaAuthentication();
270270

@@ -316,7 +316,7 @@ function EmojiGroupHolder({
316316
previewAtom,
317317
onGroupItemClick,
318318
children,
319-
}: EmojiGroupHolderProps) {
319+
}: Readonly<EmojiGroupHolderProps>) {
320320
const setPreviewData = useSetAtom(previewAtom);
321321

322322
const handleEmojiPreview = useCallback(
@@ -397,7 +397,7 @@ export function EmojiBoard({
397397
onStickerSelect,
398398
allowTextCustomEmoji,
399399
addToRecentEmoji = true,
400-
}: EmojiBoardProps) {
400+
}: Readonly<EmojiBoardProps>) {
401401
const mx = useMatrixClient();
402402
const [saveStickerEmojiBandwidth] = useSetting(settingsAtom, 'saveStickerEmojiBandwidth');
403403

@@ -589,7 +589,7 @@ export function EmojiBoard({
589589
id={SEARCH_GROUP_ID}
590590
label={searchedItems.length ? 'Search Results' : 'No Results found'}
591591
>
592-
{searchedItems.map(renderItem)}
592+
{searchedItems.map((element, index) => renderItem(element, index))}
593593
</EmojiGroup>
594594
)}
595595
<div

src/app/components/event-history/EventHistory.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export const EventHistory = as<'div', EventHistoryProps>(
121121
[room, setReplyDraft]
122122
);
123123

124-
function MenuOptions({ mEvent }: { mEvent: MatrixEvent }) {
124+
function MenuOptions({ mEvent }: Readonly<{ mEvent: MatrixEvent }>) {
125125
const setModal = useSetAtom(modalAtom);
126126
return (
127127
<Menu className={css.MenuOptions}>
@@ -177,7 +177,10 @@ export const EventHistory = as<'div', EventHistoryProps>(
177177
);
178178
}
179179

180-
function EventItem({ mEvent, EventContent }: { mEvent: MatrixEvent; EventContent: IContent }) {
180+
function EventItem({
181+
mEvent,
182+
EventContent,
183+
}: Readonly<{ mEvent: MatrixEvent; EventContent: IContent }>) {
181184
const [isHovered, setIsHovered] = useState(false);
182185
return (
183186
<Box

src/app/components/message/RenderBody.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function RenderBody({
1919
highlightRegex,
2020
htmlReactParserOptions,
2121
linkifyOpts,
22-
}: RenderBodyProps) {
22+
}: Readonly<RenderBodyProps>) {
2323
if (body === '') return <MessageEmptyContent />;
2424
if (customBody) {
2525
if (customBody === '') return <MessageEmptyContent />;

src/app/components/message/Reply.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ export const ThreadIndicator = as<'div'>(({ ...props }, ref) => (
6868

6969
type ReplyProps = {
7070
room: Room;
71-
timelineSet?: EventTimelineSet | undefined;
71+
timelineSet?: EventTimelineSet;
7272
replyEventId: string;
73-
threadRootId?: string | undefined;
74-
onClick?: MouseEventHandler | undefined;
73+
threadRootId?: string;
74+
onClick?: MouseEventHandler;
7575
};
7676

7777
export const Reply = as<'div', ReplyProps>(
@@ -119,18 +119,18 @@ export const Reply = as<'div', ReplyProps>(
119119

120120
if (format === 'org.matrix.custom.html' && formattedBody) {
121121
const strippedHtml = trimReplyFromFormattedBody(formattedBody)
122-
.replace(/<br\s*\/?>/gi, ' ')
123-
.replace(/<\/p>\s*<p[^>]*>/gi, ' ')
124-
.replace(/<\/?p[^>]*>/gi, '')
125-
.replace(/(?:\r\n|\r|\n)/g, ' ');
122+
.replaceAll(/<br\s*\/?>/gi, ' ')
123+
.replaceAll(/<\/p>\s*<p[^>]*>/gi, ' ')
124+
.replaceAll(/<\/?p[^>]*>/gi, '')
125+
.replaceAll(/(?:\r\n|\r|\n)/g, ' ');
126126
const parserOpts = getReactCustomHtmlParser(mx, room.roomId, {
127127
linkifyOpts: LINKIFY_OPTS,
128128
useAuthentication,
129129
nicknames,
130130
});
131131
bodyJSX = parse(strippedHtml, parserOpts) as JSX.Element;
132132
} else if (body) {
133-
const strippedBody = trimReplyFromBody(body).replace(/(?:\r\n|\r|\n)/g, ' ');
133+
const strippedBody = trimReplyFromBody(body).replaceAll(/(?:\r\n|\r|\n)/g, ' ');
134134
bodyJSX = scaleSystemEmoji(strippedBody);
135135
}
136136

src/app/components/time-date/DatePicker.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
3333
const currentDate = dateFor(selectedYear, selectedMonth, selectedDay);
3434
const time = value - currentDate;
3535

36-
const newDate = dateFor(year, month, mDays < selectedDay ? mDays : selectedDay);
36+
const newDate = dateFor(year, month, Math.min(mDays, selectedDay));
3737

3838
const newValue = newDate + time;
3939
handleSubmit(newValue);
@@ -60,7 +60,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
6060
<Menu className={css.PickerMenu} ref={ref}>
6161
<Box direction="Row" gap="200" className={css.PickerContainer}>
6262
<PickerColumn title="Day">
63-
{Array.from(Array(daysInMonth(selectedMonth, selectedYear)).keys())
63+
{Array.from(new Array(daysInMonth(selectedMonth, selectedYear)).keys())
6464
.map((i) => i + 1)
6565
.map((day) => (
6666
<Chip
@@ -81,7 +81,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
8181
))}
8282
</PickerColumn>
8383
<PickerColumn title="Month">
84-
{Array.from(Array(12).keys())
84+
{Array.from(new Array(12).keys())
8585
.map((i) => i + 1)
8686
.map((month) => (
8787
<Chip
@@ -106,7 +106,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
106106
))}
107107
</PickerColumn>
108108
<PickerColumn title="Year">
109-
{Array.from(Array(yearsRange).keys())
109+
{Array.from(new Array(yearsRange).keys())
110110
.map((i) => minYear + i)
111111
.map((year) => (
112112
<Chip

0 commit comments

Comments
 (0)