refactor: move isValidUrl to global util, prop/scope cleaning

This commit is contained in:
NamesMT 2025-05-02 05:10:35 +00:00
parent 8ea74f77dd
commit 03974e82b2
3 changed files with 36 additions and 37 deletions

8
src/utils/url.ts Normal file
View file

@ -0,0 +1,8 @@
export const isValidUrl = (urlString: string): boolean => {
try {
new URL(urlString)
return true
} catch (e) {
return false
}
}

View file

@ -1,4 +1,4 @@
import React from "react"
import React, { useCallback, useMemo } from "react"
import { Button } from "@/components/ui/button"
import {
DropdownMenu,
@ -10,18 +10,40 @@ import { MoreVertical, ExternalLink, Download } from "lucide-react"
import { InstallMarketplaceItemOptions, MarketplaceItem } from "../../../../../src/services/marketplace/types"
import { vscode } from "@/utils/vscode"
import { useAppTranslation } from "@/i18n/TranslationContext"
import { isValidUrl } from "@roo/utils/url"
interface MarketplaceItemActionsMenuProps {
item: MarketplaceItem
handleOpenSourceUrl: () => void
}
export const MarketplaceItemActionsMenu: React.FC<MarketplaceItemActionsMenuProps> = ({
item,
handleOpenSourceUrl,
}) => {
const { t } = useAppTranslation()
const itemSourceUrl = useMemo(() => {
if (item.sourceUrl && isValidUrl(item.sourceUrl)) {
return item.sourceUrl
}
let url = item.repoUrl
if (item.defaultBranch) {
url = `${url}/tree/${item.defaultBranch}`
if (item.path) {
const normalizedPath = item.path.replace(/\\/g, "/").replace(/^\/+/, "")
url = `${url}/${normalizedPath}`
}
}
return url
}, [item.sourceUrl, item.repoUrl, item.defaultBranch, item.path])
const handleOpenSourceUrl = useCallback(() => {
vscode.postMessage({
type: "openExternal",
url: itemSourceUrl,
})
}, [itemSourceUrl])
const handleInstall = (options?: InstallMarketplaceItemOptions) => {
vscode.postMessage({
type: "installMarketplaceItem",

View file

@ -1,4 +1,4 @@
import React, { useMemo, useCallback } from "react"
import React, { useMemo } from "react"
import { MarketplaceItem } from "../../../../../src/services/marketplace/types"
import { vscode } from "@/utils/vscode"
import { groupItemsByType, GroupedItems } from "../utils/grouping"
@ -7,6 +7,7 @@ import { TypeGroup } from "./TypeGroup"
import { ViewState } from "../MarketplaceViewStateManager"
import { useAppTranslation } from "@/i18n/TranslationContext"
import { MarketplaceItemActionsMenu } from "./MarketplaceItemActionsMenu"
import { isValidUrl } from "@roo/utils/url"
interface MarketplaceItemCardProps {
item: MarketplaceItem
@ -24,14 +25,6 @@ export const MarketplaceItemCard: React.FC<MarketplaceItemCardProps> = ({
setActiveTab,
}) => {
const { t } = useAppTranslation()
const isValidUrl = (urlString: string): boolean => {
try {
new URL(urlString)
return true
} catch (e) {
return false
}
}
const typeLabel = useMemo(() => {
switch (item.type) {
@ -63,30 +56,6 @@ export const MarketplaceItemCard: React.FC<MarketplaceItemCardProps> = ({
}
}, [item.type])
// Memoize URL calculation
const itemSourceUrl = useMemo(() => {
if (item.sourceUrl && isValidUrl(item.sourceUrl)) {
return item.sourceUrl
}
let url = item.repoUrl
if (item.defaultBranch) {
url = `${url}/tree/${item.defaultBranch}`
if (item.path) {
const normalizedPath = item.path.replace(/\\/g, "/").replace(/^\/+/, "")
url = `${url}/${normalizedPath}`
}
}
return url
}, [item.sourceUrl, item.repoUrl, item.defaultBranch, item.path])
const handleOpenSourceUrl = useCallback(() => {
vscode.postMessage({
type: "openExternal",
url: itemSourceUrl,
})
}, [itemSourceUrl])
// Group items by type
const groupedItems = useMemo(() => {
if (!item.items?.length) {
@ -194,7 +163,7 @@ export const MarketplaceItemCard: React.FC<MarketplaceItemCardProps> = ({
)}
</div>
<MarketplaceItemActionsMenu item={item} handleOpenSourceUrl={handleOpenSourceUrl} />
<MarketplaceItemActionsMenu item={item} />
</div>
{item.type === "package" && (