mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
fix sonar warnings
This commit is contained in:
@@ -10,7 +10,7 @@ export interface ErrorsAlertProps {
|
||||
messages: string[]
|
||||
}
|
||||
|
||||
export function Alert(props: ErrorsAlertProps) {
|
||||
export function Alert(props: Readonly<ErrorsAlertProps>) {
|
||||
let title: React.ReactNode
|
||||
let color: string
|
||||
let icon: React.ReactNode
|
||||
|
||||
@@ -44,7 +44,7 @@ export function ImageWithPlaceholderWhileLoading({
|
||||
title,
|
||||
width,
|
||||
style,
|
||||
}: ImageWithPlaceholderWhileLoadingProps) {
|
||||
}: Readonly<ImageWithPlaceholderWhileLoadingProps>) {
|
||||
const { classes } = useStyles({
|
||||
placeholderWidth,
|
||||
placeholderHeight,
|
||||
|
||||
@@ -5,6 +5,6 @@ export interface LogoProps {
|
||||
size: number
|
||||
}
|
||||
|
||||
export function Logo(props: LogoProps) {
|
||||
export function Logo(props: Readonly<LogoProps>) {
|
||||
return <Image src={logo} w={props.size} />
|
||||
}
|
||||
|
||||
@@ -4,7 +4,11 @@ import dayjs from "dayjs"
|
||||
import { Constants } from "@/app/constants"
|
||||
import { useNow } from "@/hooks/useNow"
|
||||
|
||||
export function RelativeDate(props: { date: Date | number | undefined }) {
|
||||
export function RelativeDate(
|
||||
props: Readonly<{
|
||||
date: Date | number | undefined
|
||||
}>
|
||||
) {
|
||||
const now = useNow(60 * 1000)
|
||||
|
||||
if (!props.date) return <Trans>N/A</Trans>
|
||||
|
||||
@@ -13,7 +13,7 @@ interface UserEditProps {
|
||||
onSave: () => void
|
||||
}
|
||||
|
||||
export function UserEdit(props: UserEditProps) {
|
||||
export function UserEdit(props: Readonly<UserEditProps>) {
|
||||
const form = useForm<AdminSaveUserRequest>({
|
||||
initialValues: props.user ?? {
|
||||
name: "",
|
||||
|
||||
@@ -11,7 +11,7 @@ interface CodeEditorProps {
|
||||
onChange: (value: string | undefined) => void
|
||||
}
|
||||
|
||||
export function CodeEditor(props: CodeEditorProps) {
|
||||
export function CodeEditor(props: Readonly<CodeEditorProps>) {
|
||||
const mobile = useMobile()
|
||||
|
||||
return mobile ? (
|
||||
|
||||
@@ -30,7 +30,7 @@ interface RichCodeEditorProps {
|
||||
onChange: (value: string | undefined) => void
|
||||
}
|
||||
|
||||
function RichCodeEditor(props: RichCodeEditorProps) {
|
||||
function RichCodeEditor(props: Readonly<RichCodeEditorProps>) {
|
||||
const colorScheme = useColorScheme()
|
||||
const editorTheme = colorScheme === "dark" ? "vs-dark" : "light"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TypographyStylesProvider } from "@mantine/core"
|
||||
import { Typography } from "@mantine/core"
|
||||
import type { ReactNode } from "react"
|
||||
import { tss } from "@/tss"
|
||||
|
||||
@@ -20,5 +20,5 @@ const useStyles = tss.create(() => ({
|
||||
|
||||
export const BasicHtmlStyles = (props: { children: ReactNode }) => {
|
||||
const { classes } = useStyles()
|
||||
return <TypographyStylesProvider className={classes.content}>{props.children}</TypographyStylesProvider>
|
||||
return <Typography className={classes.content}>{props.children}</Typography>
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import { BasicHtmlStyles } from "@/components/content/BasicHtmlStyles"
|
||||
import { ImageWithPlaceholderWhileLoading } from "@/components/ImageWithPlaceholderWhileLoading"
|
||||
|
||||
export function Enclosure(props: { enclosureType: string; enclosureUrl: string }) {
|
||||
export function Enclosure(
|
||||
props: Readonly<{
|
||||
enclosureType: string
|
||||
enclosureUrl: string
|
||||
}>
|
||||
) {
|
||||
const hasVideo = props.enclosureType.startsWith("video")
|
||||
const hasAudio = props.enclosureType.startsWith("audio")
|
||||
const hasImage = props.enclosureType.startsWith("image")
|
||||
|
||||
@@ -96,7 +96,7 @@ const useStyles = tss
|
||||
}
|
||||
})
|
||||
|
||||
export function FeedEntry(props: FeedEntryProps) {
|
||||
export function FeedEntry(props: Readonly<FeedEntryProps>) {
|
||||
const viewMode = useAppSelector(state => state.user.localSettings.viewMode)
|
||||
const fontSizePercentage = useAppSelector(state => state.user.localSettings.fontSizePercentage)
|
||||
const { classes, cx } = useStyles({
|
||||
|
||||
@@ -9,7 +9,7 @@ export interface FeedEntryBodyProps {
|
||||
entry: Entry
|
||||
}
|
||||
|
||||
export function FeedEntryBody(props: FeedEntryBodyProps) {
|
||||
export function FeedEntryBody(props: Readonly<FeedEntryBodyProps>) {
|
||||
const search = useAppSelector(state => state.entries.search)
|
||||
return (
|
||||
<Box>
|
||||
|
||||
@@ -27,7 +27,7 @@ const useStyles = tss.create(({ theme, colorScheme }) => ({
|
||||
},
|
||||
}))
|
||||
|
||||
export function FeedEntryContextMenu(props: FeedEntryContextMenuProps) {
|
||||
export function FeedEntryContextMenu(props: Readonly<FeedEntryContextMenuProps>) {
|
||||
const colorScheme = useColorScheme()
|
||||
const { classes } = useStyles()
|
||||
const sourceType = useAppSelector(state => state.entries.source.type)
|
||||
|
||||
@@ -14,7 +14,7 @@ interface FeedEntryFooterProps {
|
||||
entry: Entry
|
||||
}
|
||||
|
||||
export function FeedEntryFooter(props: FeedEntryFooterProps) {
|
||||
export function FeedEntryFooter(props: Readonly<FeedEntryFooterProps>) {
|
||||
const tags = useAppSelector(state => state.user.tags)
|
||||
const mobile = useMobile()
|
||||
const { spacing } = useActionButton()
|
||||
|
||||
@@ -5,7 +5,7 @@ export interface FeedFaviconProps {
|
||||
size?: number
|
||||
}
|
||||
|
||||
export function FeedFavicon({ url, size = 18 }: FeedFaviconProps) {
|
||||
export function FeedFavicon({ url, size = 18 }: Readonly<FeedFaviconProps>) {
|
||||
return (
|
||||
<ImageWithPlaceholderWhileLoading
|
||||
src={url}
|
||||
|
||||
@@ -12,7 +12,7 @@ export interface MediaProps {
|
||||
description?: string
|
||||
}
|
||||
|
||||
export function Media(props: MediaProps) {
|
||||
export function Media(props: Readonly<MediaProps>) {
|
||||
const width = props.thumbnailWidth
|
||||
const height = props.thumbnailHeight
|
||||
const placeholderSize = calculatePlaceholderSize({
|
||||
|
||||
@@ -22,7 +22,15 @@ const useStyles = tss
|
||||
},
|
||||
}))
|
||||
|
||||
function ShareButton({ icon, color, onClick }: { icon: IconType; color: Color; onClick: () => void }) {
|
||||
function ShareButton({
|
||||
icon,
|
||||
color,
|
||||
onClick,
|
||||
}: Readonly<{
|
||||
icon: IconType
|
||||
color: Color
|
||||
onClick: () => void
|
||||
}>) {
|
||||
const { classes } = useStyles({
|
||||
color,
|
||||
})
|
||||
@@ -36,7 +44,15 @@ function ShareButton({ icon, color, onClick }: { icon: IconType; color: Color; o
|
||||
)
|
||||
}
|
||||
|
||||
function SiteShareButton({ url, icon, color }: { icon: IconType; color: Color; url: string }) {
|
||||
function SiteShareButton({
|
||||
url,
|
||||
icon,
|
||||
color,
|
||||
}: Readonly<{
|
||||
icon: IconType
|
||||
color: Color
|
||||
url: string
|
||||
}>) {
|
||||
const onClick = () => {
|
||||
window.open(url, "", "menubar=no,toolbar=no,resizable=yes,scrollbars=yes,width=800,height=600")
|
||||
}
|
||||
@@ -44,7 +60,11 @@ function SiteShareButton({ url, icon, color }: { icon: IconType; color: Color; u
|
||||
return <ShareButton icon={icon} color={color} onClick={onClick} />
|
||||
}
|
||||
|
||||
function CopyUrlButton({ url }: { url: string }) {
|
||||
function CopyUrlButton({
|
||||
url,
|
||||
}: Readonly<{
|
||||
url: string
|
||||
}>) {
|
||||
return (
|
||||
<CopyButton value={url}>
|
||||
{({ copied, copy }) => <ShareButton icon={copied ? TbCheck : TbCopy} color="#000" onClick={copy} />}
|
||||
@@ -52,7 +72,13 @@ function CopyUrlButton({ url }: { url: string }) {
|
||||
)
|
||||
}
|
||||
|
||||
function BrowserNativeShareButton({ url, description }: { url: string; description: string }) {
|
||||
function BrowserNativeShareButton({
|
||||
url,
|
||||
description,
|
||||
}: Readonly<{
|
||||
url: string
|
||||
description: string
|
||||
}>) {
|
||||
const mobile = useMobile()
|
||||
const { isBrowserExtensionPopup } = useBrowserExtension()
|
||||
const onClick = () => {
|
||||
@@ -71,7 +97,12 @@ function BrowserNativeShareButton({ url, description }: { url: string; descripti
|
||||
)
|
||||
}
|
||||
|
||||
export function ShareButtons(props: { url: string; description: string }) {
|
||||
export function ShareButtons(
|
||||
props: Readonly<{
|
||||
url: string
|
||||
description: string
|
||||
}>
|
||||
) {
|
||||
const sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings)
|
||||
const enabledSharingSites = (Object.keys(Constants.sharing) as Array<keyof SharingSettings>).filter(site => sharingSettings?.[site])
|
||||
const url = encodeURIComponent(props.url)
|
||||
|
||||
@@ -39,9 +39,8 @@ export function Subscribe() {
|
||||
},
|
||||
})
|
||||
const subscribe = useAsyncCallback(client.feed.subscribe, {
|
||||
onSuccess: async sub => {
|
||||
await dispatch(reloadTree())
|
||||
dispatch(redirectToFeed(sub.data))
|
||||
onSuccess: sub => {
|
||||
dispatch(reloadTree()).then(() => dispatch(redirectToFeed(sub.data)))
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ const useStyles = tss
|
||||
},
|
||||
}))
|
||||
|
||||
export function FeedEntryCompactHeader(props: FeedEntryHeaderProps) {
|
||||
export function FeedEntryCompactHeader(props: Readonly<FeedEntryHeaderProps>) {
|
||||
const { classes } = useStyles({
|
||||
read: props.entry.read,
|
||||
})
|
||||
|
||||
@@ -24,7 +24,7 @@ const useStyles = tss
|
||||
},
|
||||
}))
|
||||
|
||||
export function FeedEntryHeader(props: FeedEntryHeaderProps) {
|
||||
export function FeedEntryHeader(props: Readonly<FeedEntryHeaderProps>) {
|
||||
const { classes } = useStyles({
|
||||
read: props.entry.read,
|
||||
})
|
||||
|
||||
@@ -6,7 +6,7 @@ export interface FeedEntryTitleProps {
|
||||
entry: Entry
|
||||
}
|
||||
|
||||
export function FeedEntryTitle(props: FeedEntryTitleProps) {
|
||||
export function FeedEntryTitle(props: Readonly<FeedEntryTitleProps>) {
|
||||
const search = useAppSelector(state => state.entries.search)
|
||||
const keywords = search?.split(" ")
|
||||
return (
|
||||
|
||||
@@ -6,7 +6,11 @@ import { markEntry } from "@/app/entries/thunks"
|
||||
import { useAppDispatch } from "@/app/store"
|
||||
import type { Entry } from "@/app/types"
|
||||
|
||||
export function OpenExternalLink(props: { entry: Entry }) {
|
||||
export function OpenExternalLink(
|
||||
props: Readonly<{
|
||||
entry: Entry
|
||||
}>
|
||||
) {
|
||||
const dispatch = useAppDispatch()
|
||||
const onClick = (e: React.MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
|
||||
@@ -6,7 +6,11 @@ import { starEntry } from "@/app/entries/thunks"
|
||||
import { useAppDispatch } from "@/app/store"
|
||||
import type { Entry } from "@/app/types"
|
||||
|
||||
export function Star(props: { entry: Entry }) {
|
||||
export function Star(
|
||||
props: Readonly<{
|
||||
entry: Entry
|
||||
}>
|
||||
) {
|
||||
const dispatch = useAppDispatch()
|
||||
const onClick = (e: React.MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
|
||||
@@ -94,7 +94,7 @@ const viewModeData: ViewModeControlItem[] = [
|
||||
},
|
||||
]
|
||||
|
||||
export function ProfileMenu(props: ProfileMenuProps) {
|
||||
export function ProfileMenu(props: Readonly<ProfileMenuProps>) {
|
||||
const [opened, setOpened] = useState(false)
|
||||
const now = useNow()
|
||||
const profile = useAppSelector(state => state.user.profile)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { NumberFormatter } from "@mantine/core"
|
||||
import type { MetricGauge } from "@/app/types"
|
||||
|
||||
interface MeterProps {
|
||||
interface GaugeProps {
|
||||
gauge: MetricGauge
|
||||
}
|
||||
|
||||
export function Gauge(props: MeterProps) {
|
||||
export function Gauge(props: Readonly<GaugeProps>) {
|
||||
return <NumberFormatter value={props.gauge.value} thousandSeparator />
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ interface MeterProps {
|
||||
meter: MetricMeter
|
||||
}
|
||||
|
||||
export function Meter(props: MeterProps) {
|
||||
export function Meter(props: Readonly<MeterProps>) {
|
||||
return (
|
||||
<Box>
|
||||
<Box>Mean: {props.meter.mean_rate.toFixed(2)}</Box>
|
||||
|
||||
@@ -7,7 +7,7 @@ interface MetricAccordionItemProps {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export function MetricAccordionItem({ metricKey, name, headerValue, children }: MetricAccordionItemProps) {
|
||||
export function MetricAccordionItem({ metricKey, name, headerValue, children }: Readonly<MetricAccordionItemProps>) {
|
||||
return (
|
||||
<Accordion.Item value={metricKey} key={metricKey}>
|
||||
<Accordion.Control>
|
||||
|
||||
@@ -5,7 +5,7 @@ interface MetricTimerProps {
|
||||
timer: MetricTimer
|
||||
}
|
||||
|
||||
export function Timer(props: MetricTimerProps) {
|
||||
export function Timer(props: Readonly<MetricTimerProps>) {
|
||||
return (
|
||||
<Box>
|
||||
<Box>Mean: {props.timer.mean_rate.toFixed(2)}</Box>
|
||||
|
||||
@@ -2,7 +2,11 @@ import { Box } from "@mantine/core"
|
||||
import type React from "react"
|
||||
import { useMobile } from "@/hooks/useMobile"
|
||||
|
||||
export function OnDesktop(props: { children: React.ReactNode }) {
|
||||
export function OnDesktop(
|
||||
props: Readonly<{
|
||||
children: React.ReactNode
|
||||
}>
|
||||
) {
|
||||
const mobile = useMobile()
|
||||
return <Box>{!mobile && props.children}</Box>
|
||||
}
|
||||
|
||||
@@ -2,7 +2,11 @@ import { Box } from "@mantine/core"
|
||||
import type React from "react"
|
||||
import { useMobile } from "@/hooks/useMobile"
|
||||
|
||||
export function OnMobile(props: { children: React.ReactNode }) {
|
||||
export function OnMobile(
|
||||
props: Readonly<{
|
||||
children: React.ReactNode
|
||||
}>
|
||||
) {
|
||||
const mobile = useMobile()
|
||||
return <Box>{mobile && props.children}</Box>
|
||||
}
|
||||
|
||||
@@ -52,7 +52,9 @@ export function ProfileSettings() {
|
||||
),
|
||||
labels: { confirm: <Trans>Confirm</Trans>, cancel: <Trans>Cancel</Trans> },
|
||||
confirmProps: { color: "red" },
|
||||
onConfirm: async () => await deleteProfile.execute(),
|
||||
onConfirm: () => {
|
||||
deleteProfile.execute()
|
||||
},
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -59,7 +59,7 @@ const useStyles = tss
|
||||
}
|
||||
})
|
||||
|
||||
export function TreeNode(props: TreeNodeProps) {
|
||||
export function TreeNode(props: Readonly<TreeNodeProps>) {
|
||||
const { classes } = useStyles({
|
||||
selected: props.selected,
|
||||
hasError: props.hasError,
|
||||
|
||||
@@ -14,7 +14,7 @@ export interface TreeSearchProps {
|
||||
feeds: Subscription[]
|
||||
}
|
||||
|
||||
export function TreeSearch(props: TreeSearchProps) {
|
||||
export function TreeSearch(props: Readonly<TreeSearchProps>) {
|
||||
const dispatch = useAppDispatch()
|
||||
const { _ } = useLingui()
|
||||
|
||||
|
||||
@@ -10,7 +10,12 @@ const useStyles = tss.create(() => ({
|
||||
},
|
||||
}))
|
||||
|
||||
export function UnreadCount(props: { unreadCount: number; showIndicator: boolean }) {
|
||||
export function UnreadCount(
|
||||
props: Readonly<{
|
||||
unreadCount: number
|
||||
showIndicator: boolean
|
||||
}>
|
||||
) {
|
||||
const { classes } = useStyles()
|
||||
|
||||
if (props.unreadCount <= 0) return null
|
||||
|
||||
Reference in New Issue
Block a user