@@ -5,7 +5,9 @@ import useDirDetection from '@/hooks/use-dir-detection'
55import { type UseEditFormValues } from '@/components/forms/user-form'
66import { useActiveNextPlan , useGetCurrentAdmin , useRemoveUser , useResetUserDataUsage , useRevokeUserSubscription , UserResponse , UsersResponse } from '@/service/api'
77import { useQueryClient } from '@tanstack/react-query'
8- import { Check , Copy , Cpu , EllipsisVertical , Link2Off , ListStart , Network , Pencil , PieChart , QrCode , RefreshCcw , Trash2 , User , Users } from 'lucide-react'
8+ import { Cat , Check , Copy , Cpu , EllipsisVertical , GlobeLock , Link2Off , ListStart , ListTree , Network , Pencil , PieChart , QrCode , RefreshCcw , Trash2 , User , Users } from 'lucide-react'
9+ import { WireguardIcon , XrayIcon , SingboxIcon , MihomoIcon } from '@/components/icons/format-icons'
10+ import { Code } from 'lucide-react'
911import { FC , useCallback , useEffect , useMemo , useRef , useState , useSyncExternalStore } from 'react'
1012import { useForm } from 'react-hook-form'
1113import { useTranslation } from 'react-i18next'
@@ -31,7 +33,7 @@ type ActionButtonsProps = {
3133export interface SubscribeLink {
3234 protocol : string
3335 link : string
34- icon : string
36+ icon : React . ComponentType < { className ?: string } >
3537}
3638
3739const DOWNLOAD_ONLY_PROTOCOLS = [ 'clash' , 'clash-meta' , 'sing-box' ]
@@ -325,14 +327,14 @@ const ActionButtons: FC<ActionButtonsProps> = ({ user, isModalHost = true, rende
325327 const subURL = user . subscription_url . startsWith ( '/' ) ? window . location . origin + user . subscription_url : user . subscription_url
326328
327329 const links = [
328- { protocol : 'links' , link : `${ subURL } /links` , icon : '🔗' } ,
329- { protocol : 'links (base64)' , link : `${ subURL } /links_base64` , icon : '📝' } ,
330- { protocol : 'xray' , link : `${ subURL } /xray` , icon : '⚡' } ,
331- { protocol : 'wireguard' , link : `${ subURL } /wireguard` , icon : '🛜' } ,
332- { protocol : 'clash' , link : `${ subURL } /clash` , icon : '⚔️' } ,
333- { protocol : 'clash-meta' , link : `${ subURL } /clash_meta` , icon : '🛡️' } ,
334- { protocol : 'outline' , link : `${ subURL } /outline` , icon : '🔒' } ,
335- { protocol : 'sing-box' , link : `${ subURL } /sing_box` , icon : '📦' } ,
330+ { protocol : 'links' , link : `${ subURL } /links` , icon : ListTree } ,
331+ { protocol : 'links (base64)' , link : `${ subURL } /links_base64` , icon : Code } ,
332+ { protocol : 'xray' , link : `${ subURL } /xray` , icon : XrayIcon } ,
333+ { protocol : 'wireguard' , link : `${ subURL } /wireguard` , icon : WireguardIcon } ,
334+ { protocol : 'clash' , link : `${ subURL } /clash` , icon : Cat } ,
335+ { protocol : 'clash-meta' , link : `${ subURL } /clash_meta` , icon : MihomoIcon } ,
336+ { protocol : 'outline' , link : `${ subURL } /outline` , icon : GlobeLock } ,
337+ { protocol : 'sing-box' , link : `${ subURL } /sing_box` , icon : SingboxIcon } ,
336338 ]
337339 setSubscribeLinks ( links )
338340 }
@@ -562,13 +564,13 @@ const ActionButtons: FC<ActionButtonsProps> = ({ user, isModalHost = true, rende
562564 } )
563565 }
564566
565- const handleLinksCopy = async ( link : string , type : string , icon : string ) => {
567+ const handleLinksCopy = async ( link : string , type : string ) => {
566568 try {
567569 const cachedContent = configContentCacheRef . current [ link ]
568570 if ( cachedContent !== undefined ) {
569571 const copiedSuccessfully = await copy ( cachedContent )
570572 if ( copiedSuccessfully ) {
571- toast . success ( `${ icon } ${ type } ${ t ( 'usersTable.copied' , { defaultValue : 'Copied to clipboard' } ) } ` )
573+ toast . success ( `${ type } ${ t ( 'usersTable.copied' , { defaultValue : 'Copied to clipboard' } ) } ` )
572574 } else {
573575 toast . error ( t ( 'copyFailed' , { defaultValue : 'Failed to copy content' } ) )
574576 }
@@ -586,7 +588,7 @@ const ActionButtons: FC<ActionButtonsProps> = ({ user, isModalHost = true, rende
586588 const content = await fetchAndCacheContent ( link )
587589 const copiedSuccessfully = await copy ( content )
588590 if ( copiedSuccessfully ) {
589- toast . success ( `${ icon } ${ type } ${ t ( 'usersTable.copied' , { defaultValue : 'Copied to clipboard' } ) } ` )
591+ toast . success ( `${ type } ${ t ( 'usersTable.copied' , { defaultValue : 'Copied to clipboard' } ) } ` )
590592 } else {
591593 toast . error ( t ( 'copyFailed' , { defaultValue : 'Failed to copy content' } ) )
592594 }
@@ -624,15 +626,15 @@ const ActionButtons: FC<ActionButtonsProps> = ({ user, isModalHost = true, rende
624626 }
625627 }
626628
627- const handleCopyOrDownload = ( link : string , type : string , icon : string ) => {
628- if ( type === 'wireguard' ) {
629- window . open ( link , '_blank' )
630- } else if ( DOWNLOAD_ONLY_PROTOCOLS . includes ( type ) ) {
631- handleConfigDownload ( link , type )
632- } else {
633- handleLinksCopy ( link , type , icon )
629+ const handleCopyOrDownload = ( link : string , type : string ) => {
630+ if ( type === 'wireguard' ) {
631+ window . open ( link , '_blank' )
632+ } else if ( DOWNLOAD_ONLY_PROTOCOLS . includes ( type ) ) {
633+ handleConfigDownload ( link , type )
634+ } else {
635+ handleLinksCopy ( link , type )
636+ }
634637 }
635- }
636638
637639 return (
638640 < div onClick = { renderActions ? ( e => e . stopPropagation ( ) ) : undefined } >
@@ -665,8 +667,8 @@ const handleCopyOrDownload = (link: string, type: string, icon: string) => {
665667 </ DropdownMenuTrigger >
666668 < DropdownMenuContent >
667669 { subscribeLinks . map ( ( item , index ) => (
668- < DropdownMenuItem dir = 'ltr' key = { index } onClick = { ( ) => handleCopyOrDownload ( item . link , item . protocol , item . icon ) } >
669- < span className = "mr-2" > { item . icon } </ span >
670+ < DropdownMenuItem dir = 'ltr' key = { index } onClick = { ( ) => handleCopyOrDownload ( item . link , item . protocol ) } >
671+ < item . icon className = "mr-2 h-4 w-4" / >
670672 { item . protocol }
671673 </ DropdownMenuItem >
672674 ) ) }
0 commit comments