1- import { useEffect , useRef } from 'react' ;
1+ import { useCallback , useEffect , useRef } from 'react' ;
2+ import { toast } from 'react-toastify' ;
23import { ImageFile , Panel , ExifOverlay } from '../components/ui/AppProperties' ;
34import { KEYBIND_DEFINITIONS , normalizeCombo } from '../utils/keyboardUtils' ;
45import { useEditorStore } from '../store/useEditorStore' ;
@@ -36,6 +37,19 @@ export const useKeyboardShortcuts = ({
3637 sortedListRef . current = sortedImageList ;
3738 } , [ sortedImageList ] ) ;
3839
40+ const handleCopyImagePaths = useCallback ( async ( paths : Array < string > ) => {
41+ const physicalPaths = [ ...new Set ( paths . map ( ( path ) => path . split ( '?vc=' ) [ 0 ] ) ) ] ;
42+ if ( physicalPaths . length === 0 ) {
43+ return ;
44+ }
45+ try {
46+ await navigator . clipboard . writeText ( physicalPaths . join ( '\n' ) ) ;
47+ } catch ( err ) {
48+ console . error ( 'Failed to copy image path to clipboard' , err ) ;
49+ toast . error ( `Failed to copy path: ${ err } ` ) ;
50+ }
51+ } , [ ] ) ;
52+
3953 useEffect ( ( ) => {
4054 const getStoreState = ( ) => ( {
4155 editor : useEditorStore . getState ( ) ,
@@ -56,6 +70,21 @@ export const useKeyboardShortcuts = ({
5670 }
5771 }
5872
73+ const getImagePathsForCopy = ( s : any ) : Array < string > => {
74+ if ( s . editor . selectedImage ) {
75+ return [ s . editor . selectedImage . path ] ;
76+ }
77+ const { libraryActivePath, multiSelectedPaths } = s . library ;
78+ if ( multiSelectedPaths . length > 0 ) {
79+ const listOrder = new Map ( sortedListRef . current . map ( ( image : ImageFile , index : number ) => [ image . path , index ] ) ) ;
80+ return [ ...multiSelectedPaths ] . sort (
81+ ( a : string , b : string ) =>
82+ ( listOrder . get ( a ) ?? Number . MAX_SAFE_INTEGER ) - ( listOrder . get ( b ) ?? Number . MAX_SAFE_INTEGER ) ,
83+ ) ;
84+ }
85+ return libraryActivePath ? [ libraryActivePath ] : [ ] ;
86+ } ;
87+
5988 const actions : Record < string , any > = {
6089 open_image : {
6190 shouldFire : ( s : any ) => ! s . editor . selectedImage && s . library . libraryActivePath !== null ,
@@ -78,6 +107,13 @@ export const useKeyboardShortcuts = ({
78107 handlePasteAdjustments ( ) ;
79108 } ,
80109 } ,
110+ copy_image_path : {
111+ shouldFire : ( s : any ) => getImagePathsForCopy ( s ) . length > 0 ,
112+ execute : ( e : any , s : any ) => {
113+ e . preventDefault ( ) ;
114+ handleCopyImagePaths ( getImagePathsForCopy ( s ) ) ;
115+ } ,
116+ } ,
81117 copy_files : {
82118 shouldFire : ( s : any ) => s . library . multiSelectedPaths . length > 0 ,
83119 execute : ( e : any , s : any ) => {
@@ -590,6 +626,7 @@ export const useKeyboardShortcuts = ({
590626 handleZoomChange ,
591627 handleRotate ,
592628 handleCopyAdjustments ,
629+ handleCopyImagePaths ,
593630 handlePasteAdjustments ,
594631 handleRate ,
595632 handleSetColorLabel ,
0 commit comments