forked from Cutlery/immich
		
	Compare commits
	
		
			15 Commits
		
	
	
		
			main
			...
			fix/edit-f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8fd54e3994 | ||
|  | ad9aafd484 | ||
|  | 8eca25007e | ||
|  | 86b200e870 | ||
|  | 5dcc4ddfc6 | ||
|  | 6b10994bd2 | ||
|  | 12ede06411 | ||
|  | 121e9f1f1c | ||
|  | c263607515 | ||
|  | 4cb2e16549 | ||
|  | 0f8fb8d38b | ||
|  | 107157b856 | ||
|  | 87cbcc02c3 | ||
|  | 62531a75eb | ||
|  | 29c7663caa | 
| @ -21,7 +21,7 @@ | |||||||
| 
 | 
 | ||||||
|   export let peopleWithFaces: AssetFaceResponseDto[]; |   export let peopleWithFaces: AssetFaceResponseDto[]; | ||||||
|   export let allPeople: PersonResponseDto[]; |   export let allPeople: PersonResponseDto[]; | ||||||
|   export let editedPersonIndex: number; |   export let editedPerson: PersonResponseDto; | ||||||
|   export let assetType: AssetTypeEnum; |   export let assetType: AssetTypeEnum; | ||||||
|   export let assetId: string; |   export let assetId: string; | ||||||
| 
 | 
 | ||||||
| @ -106,7 +106,7 @@ | |||||||
| 
 | 
 | ||||||
|   const handleCreatePerson = async () => { |   const handleCreatePerson = async () => { | ||||||
|     const timeout = setTimeout(() => (isShowLoadingNewPerson = true), timeBeforeShowLoadingSpinner); |     const timeout = setTimeout(() => (isShowLoadingNewPerson = true), timeBeforeShowLoadingSpinner); | ||||||
|     const personToUpdate = peopleWithFaces.find((person) => person.id === peopleWithFaces[editedPersonIndex].id); |     const personToUpdate = peopleWithFaces.find((face) => face.person?.id === editedPerson.id); | ||||||
| 
 | 
 | ||||||
|     const newFeaturePhoto = personToUpdate ? await zoomImageToBase64(personToUpdate) : null; |     const newFeaturePhoto = personToUpdate ? await zoomImageToBase64(personToUpdate) : null; | ||||||
| 
 | 
 | ||||||
| @ -229,7 +229,7 @@ | |||||||
|     <div class="immich-scrollbar mt-4 flex flex-wrap gap-2 overflow-y-auto"> |     <div class="immich-scrollbar mt-4 flex flex-wrap gap-2 overflow-y-auto"> | ||||||
|       {#if searchName == ''} |       {#if searchName == ''} | ||||||
|         {#each allPeople as person (person.id)} |         {#each allPeople as person (person.id)} | ||||||
|           {#if person.id !== peopleWithFaces[editedPersonIndex].person?.id} |           {#if person.id !== editedPerson.id} | ||||||
|             <div class="w-fit"> |             <div class="w-fit"> | ||||||
|               <button class="w-[90px]" on:click={() => dispatch('reassign', person)}> |               <button class="w-[90px]" on:click={() => dispatch('reassign', person)}> | ||||||
|                 <div class="relative"> |                 <div class="relative"> | ||||||
| @ -255,7 +255,7 @@ | |||||||
|         {/each} |         {/each} | ||||||
|       {:else} |       {:else} | ||||||
|         {#each searchedPeople as person (person.id)} |         {#each searchedPeople as person (person.id)} | ||||||
|           {#if person.id !== peopleWithFaces[editedPersonIndex].person?.id} |           {#if person.id !== editedPerson.id} | ||||||
|             <div class="w-fit"> |             <div class="w-fit"> | ||||||
|               <button class="w-[90px]" on:click={() => dispatch('reassign', person)}> |               <button class="w-[90px]" on:click={() => dispatch('reassign', person)}> | ||||||
|                 <div class="relative"> |                 <div class="relative"> | ||||||
|  | |||||||
| @ -28,14 +28,14 @@ | |||||||
|   export let assetType: AssetTypeEnum; |   export let assetType: AssetTypeEnum; | ||||||
| 
 | 
 | ||||||
|   // keep track of the changes |   // keep track of the changes | ||||||
|   let numberOfPersonToCreate: string[] = []; |   let peopleToCreate: string[] = []; | ||||||
|   let numberOfAssetFaceGenerated: string[] = []; |   let assetFaceGenerated: string[] = []; | ||||||
| 
 | 
 | ||||||
|   // faces |   // faces | ||||||
|   let peopleWithFaces: AssetFaceResponseDto[] = []; |   let peopleWithFaces: AssetFaceResponseDto[] = []; | ||||||
|   let selectedPersonToReassign: (PersonResponseDto | null)[]; |   let selectedPersonToReassign: Record<string, PersonResponseDto> = {}; | ||||||
|   let selectedPersonToCreate: (string | null)[]; |   let selectedPersonToCreate: Record<string, string> = {}; | ||||||
|   let editedPersonIndex: number; |   let editedPerson: PersonResponseDto; | ||||||
| 
 | 
 | ||||||
|   // loading spinners |   // loading spinners | ||||||
|   let isShowLoadingDone = false; |   let isShowLoadingDone = false; | ||||||
| @ -49,6 +49,8 @@ | |||||||
|   let loaderLoadingDoneTimeout: ReturnType<typeof setTimeout>; |   let loaderLoadingDoneTimeout: ReturnType<typeof setTimeout>; | ||||||
|   let automaticRefreshTimeout: ReturnType<typeof setTimeout>; |   let automaticRefreshTimeout: ReturnType<typeof setTimeout>; | ||||||
| 
 | 
 | ||||||
|  |   const thumbnailWidth = '90px'; | ||||||
|  | 
 | ||||||
|   const dispatch = createEventDispatcher<{ |   const dispatch = createEventDispatcher<{ | ||||||
|     close: void; |     close: void; | ||||||
|     refresh: void; |     refresh: void; | ||||||
| @ -60,8 +62,6 @@ | |||||||
|       const { people } = await getAllPeople({ withHidden: true }); |       const { people } = await getAllPeople({ withHidden: true }); | ||||||
|       allPeople = people; |       allPeople = people; | ||||||
|       peopleWithFaces = await getFaces({ id: assetId }); |       peopleWithFaces = await getFaces({ id: assetId }); | ||||||
|       selectedPersonToCreate = Array.from({ length: peopleWithFaces.length }); |  | ||||||
|       selectedPersonToReassign = Array.from({ length: peopleWithFaces.length }); |  | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|       handleError(error, "Can't get faces"); |       handleError(error, "Can't get faces"); | ||||||
|     } finally { |     } finally { | ||||||
| @ -71,12 +71,12 @@ | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   const onPersonThumbnail = (personId: string) => { |   const onPersonThumbnail = (personId: string) => { | ||||||
|     numberOfAssetFaceGenerated.push(personId); |     assetFaceGenerated.push(personId); | ||||||
|     if ( |     if ( | ||||||
|       isEqual(numberOfAssetFaceGenerated, numberOfPersonToCreate) && |       isEqual(assetFaceGenerated, peopleToCreate) && | ||||||
|       loaderLoadingDoneTimeout && |       loaderLoadingDoneTimeout && | ||||||
|       automaticRefreshTimeout && |       automaticRefreshTimeout && | ||||||
|       selectedPersonToCreate.filter((person) => person !== null).length === numberOfPersonToCreate.length |       Object.keys(selectedPersonToCreate).length === peopleToCreate.length | ||||||
|     ) { |     ) { | ||||||
|       clearTimeout(loaderLoadingDoneTimeout); |       clearTimeout(loaderLoadingDoneTimeout); | ||||||
|       clearTimeout(automaticRefreshTimeout); |       clearTimeout(automaticRefreshTimeout); | ||||||
| @ -97,36 +97,41 @@ | |||||||
|     dispatch('close'); |     dispatch('close'); | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const handleReset = (index: number) => { |   const handleReset = (id: string) => { | ||||||
|     if (selectedPersonToReassign[index]) { |     if (selectedPersonToReassign[id]) { | ||||||
|       selectedPersonToReassign[index] = null; |       delete selectedPersonToReassign[id]; | ||||||
|  | 
 | ||||||
|  |       // trigger reactivity | ||||||
|  |       selectedPersonToReassign = selectedPersonToReassign; | ||||||
|     } |     } | ||||||
|     if (selectedPersonToCreate[index]) { |     if (selectedPersonToCreate[id]) { | ||||||
|       selectedPersonToCreate[index] = null; |       delete selectedPersonToCreate[id]; | ||||||
|  | 
 | ||||||
|  |       // trigger reactivity | ||||||
|  |       selectedPersonToCreate = selectedPersonToCreate; | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const handleEditFaces = async () => { |   const handleEditFaces = async () => { | ||||||
|     loaderLoadingDoneTimeout = setTimeout(() => (isShowLoadingDone = true), timeBeforeShowLoadingSpinner); |     loaderLoadingDoneTimeout = setTimeout(() => (isShowLoadingDone = true), timeBeforeShowLoadingSpinner); | ||||||
|     const numberOfChanges = |     const numberOfChanges = Object.keys(selectedPersonToCreate).length + Object.keys(selectedPersonToReassign).length; | ||||||
|       selectedPersonToCreate.filter((person) => person !== null).length + | 
 | ||||||
|       selectedPersonToReassign.filter((person) => person !== null).length; |  | ||||||
|     if (numberOfChanges > 0) { |     if (numberOfChanges > 0) { | ||||||
|       try { |       try { | ||||||
|         for (const [index, peopleWithFace] of peopleWithFaces.entries()) { |         for (const personWithFace of peopleWithFaces) { | ||||||
|           const personId = selectedPersonToReassign[index]?.id; |           const personId = selectedPersonToReassign[personWithFace.id]?.id; | ||||||
| 
 | 
 | ||||||
|           if (personId) { |           if (personId) { | ||||||
|             await reassignFacesById({ |             await reassignFacesById({ | ||||||
|               id: personId, |               id: personId, | ||||||
|               faceDto: { id: peopleWithFace.id }, |               faceDto: { id: personWithFace.id }, | ||||||
|             }); |             }); | ||||||
|           } else if (selectedPersonToCreate[index]) { |           } else if (selectedPersonToCreate[personWithFace.id]) { | ||||||
|             const data = await createPerson({ personCreateDto: {} }); |             const data = await createPerson({ personCreateDto: {} }); | ||||||
|             numberOfPersonToCreate.push(data.id); |             peopleToCreate.push(data.id); | ||||||
|             await reassignFacesById({ |             await reassignFacesById({ | ||||||
|               id: data.id, |               id: data.id, | ||||||
|               faceDto: { id: peopleWithFace.id }, |               faceDto: { id: personWithFace.id }, | ||||||
|             }); |             }); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
| @ -141,7 +146,7 @@ | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     isShowLoadingDone = false; |     isShowLoadingDone = false; | ||||||
|     if (numberOfPersonToCreate.length === 0) { |     if (peopleToCreate.length === 0) { | ||||||
|       clearTimeout(loaderLoadingDoneTimeout); |       clearTimeout(loaderLoadingDoneTimeout); | ||||||
|       dispatch('refresh'); |       dispatch('refresh'); | ||||||
|     } else { |     } else { | ||||||
| @ -150,23 +155,26 @@ | |||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const handleCreatePerson = (newFeaturePhoto: string | null) => { |   const handleCreatePerson = (newFeaturePhoto: string | null) => { | ||||||
|     const personToUpdate = peopleWithFaces.find((person) => person.id === peopleWithFaces[editedPersonIndex].id); |     const personToUpdate = peopleWithFaces.find((face) => face.person?.id === editedPerson.id); | ||||||
|     if (newFeaturePhoto && personToUpdate) { |     if (newFeaturePhoto && personToUpdate) { | ||||||
|       selectedPersonToCreate[peopleWithFaces.indexOf(personToUpdate)] = newFeaturePhoto; |       selectedPersonToCreate[personToUpdate.id] = newFeaturePhoto; | ||||||
|     } |     } | ||||||
|     showSeletecFaces = false; |     showSeletecFaces = false; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const handleReassignFace = (person: PersonResponseDto | null) => { |   const handleReassignFace = (person: PersonResponseDto | null) => { | ||||||
|     if (person) { |     const personToUpdate = peopleWithFaces.find((face) => face.person?.id === editedPerson.id); | ||||||
|       selectedPersonToReassign[editedPersonIndex] = person; |     if (person && personToUpdate) { | ||||||
|  |       selectedPersonToReassign[personToUpdate.id] = person; | ||||||
|       showSeletecFaces = false; |       showSeletecFaces = false; | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const handlePersonPicker = (index: number) => { |   const handlePersonPicker = (person: PersonResponseDto | null) => { | ||||||
|     editedPersonIndex = index; |     if (person) { | ||||||
|     showSeletecFaces = true; |       editedPerson = person; | ||||||
|  |       showSeletecFaces = true; | ||||||
|  |     } | ||||||
|   }; |   }; | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| @ -217,35 +225,48 @@ | |||||||
|                 on:mouseleave={() => ($boundingBoxesArray = [])} |                 on:mouseleave={() => ($boundingBoxesArray = [])} | ||||||
|               > |               > | ||||||
|                 <div class="relative"> |                 <div class="relative"> | ||||||
|                   <ImageThumbnail |                   {#if selectedPersonToCreate[face.id]} | ||||||
|                     curve |                     <ImageThumbnail | ||||||
|                     shadow |                       curve | ||||||
|                     url={selectedPersonToCreate[index] || |                       shadow | ||||||
|                       getPeopleThumbnailUrl(selectedPersonToReassign[index]?.id || face.person.id)} |                       url={selectedPersonToCreate[face.id]} | ||||||
|                     altText={selectedPersonToReassign[index] |                       altText={selectedPersonToCreate[face.id]} | ||||||
|                       ? selectedPersonToReassign[index]?.name |                       title={'New person'} | ||||||
|                       : selectedPersonToCreate[index] |                       widthStyle={thumbnailWidth} | ||||||
|                         ? 'New person' |                       heightStyle={thumbnailWidth} | ||||||
|                         : getPersonNameWithHiddenValue(face.person?.name, face.person?.isHidden)} |                     /> | ||||||
|                     title={selectedPersonToReassign[index] |                   {:else if selectedPersonToReassign[face.id]} | ||||||
|                       ? selectedPersonToReassign[index]?.name |                     <ImageThumbnail | ||||||
|                       : selectedPersonToCreate[index] |                       curve | ||||||
|                         ? 'New person' |                       shadow | ||||||
|                         : getPersonNameWithHiddenValue(face.person?.name, face.person?.isHidden)} |                       url={getPeopleThumbnailUrl(selectedPersonToReassign[face.id].id)} | ||||||
|                     widthStyle="90px" |                       altText={selectedPersonToReassign[face.id]?.name || selectedPersonToReassign[face.id].id} | ||||||
|                     heightStyle="90px" |                       title={getPersonNameWithHiddenValue( | ||||||
|                     thumbhash={null} |                         selectedPersonToReassign[face.id].name, | ||||||
|                     hidden={selectedPersonToReassign[index] |                         face.person?.isHidden, | ||||||
|                       ? selectedPersonToReassign[index]?.isHidden |                       )} | ||||||
|                       : selectedPersonToCreate[index] |                       widthStyle={thumbnailWidth} | ||||||
|                         ? false |                       heightStyle={thumbnailWidth} | ||||||
|                         : face.person?.isHidden} |                       hidden={selectedPersonToReassign[face.id].isHidden} | ||||||
|                   /> |                     /> | ||||||
|  |                   {:else} | ||||||
|  |                     <ImageThumbnail | ||||||
|  |                       curve | ||||||
|  |                       shadow | ||||||
|  |                       url={getPeopleThumbnailUrl(face.person.id)} | ||||||
|  |                       altText={face.person.name || face.person.id} | ||||||
|  |                       title={getPersonNameWithHiddenValue(face.person.name, face.person.isHidden)} | ||||||
|  |                       widthStyle={thumbnailWidth} | ||||||
|  |                       heightStyle={thumbnailWidth} | ||||||
|  |                       hidden={face.person.isHidden} | ||||||
|  |                     /> | ||||||
|  |                   {/if} | ||||||
|                 </div> |                 </div> | ||||||
|                 {#if !selectedPersonToCreate[index]} | 
 | ||||||
|  |                 {#if !selectedPersonToCreate[face.id]} | ||||||
|                   <p class="relative mt-1 truncate font-medium" title={face.person?.name}> |                   <p class="relative mt-1 truncate font-medium" title={face.person?.name}> | ||||||
|                     {#if selectedPersonToReassign[index]?.id} |                     {#if selectedPersonToReassign[face.id]?.id} | ||||||
|                       {selectedPersonToReassign[index]?.name} |                       {selectedPersonToReassign[face.id]?.name} | ||||||
|                     {:else} |                     {:else} | ||||||
|                       {face.person?.name} |                       {face.person?.name} | ||||||
|                     {/if} |                     {/if} | ||||||
| @ -253,8 +274,8 @@ | |||||||
|                 {/if} |                 {/if} | ||||||
| 
 | 
 | ||||||
|                 <div class="absolute -right-[5px] -top-[5px] h-[20px] w-[20px] rounded-full bg-blue-700"> |                 <div class="absolute -right-[5px] -top-[5px] h-[20px] w-[20px] rounded-full bg-blue-700"> | ||||||
|                   {#if selectedPersonToCreate[index] || selectedPersonToReassign[index]} |                   {#if selectedPersonToCreate[face.id] || selectedPersonToReassign[face.id]} | ||||||
|                     <button on:click={() => handleReset(index)} class="flex h-full w-full"> |                     <button on:click={() => handleReset(face.id)} class="flex h-full w-full"> | ||||||
|                       <div class="absolute left-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] transform"> |                       <div class="absolute left-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] transform"> | ||||||
|                         <div> |                         <div> | ||||||
|                           <Icon path={mdiRestart} size={18} /> |                           <Icon path={mdiRestart} size={18} /> | ||||||
| @ -262,7 +283,7 @@ | |||||||
|                       </div> |                       </div> | ||||||
|                     </button> |                     </button> | ||||||
|                   {:else} |                   {:else} | ||||||
|                     <button on:click={() => handlePersonPicker(index)} class="flex h-full w-full"> |                     <button on:click={() => handlePersonPicker(face.person)} class="flex h-full w-full"> | ||||||
|                       <div |                       <div | ||||||
|                         class="absolute left-1/2 top-1/2 h-[2px] w-[14px] translate-x-[-50%] translate-y-[-50%] transform bg-white" |                         class="absolute left-1/2 top-1/2 h-[2px] w-[14px] translate-x-[-50%] translate-y-[-50%] transform bg-white" | ||||||
|                       /> |                       /> | ||||||
| @ -282,7 +303,7 @@ | |||||||
|   <AssignFaceSidePanel |   <AssignFaceSidePanel | ||||||
|     {peopleWithFaces} |     {peopleWithFaces} | ||||||
|     {allPeople} |     {allPeople} | ||||||
|     {editedPersonIndex} |     {editedPerson} | ||||||
|     {assetType} |     {assetType} | ||||||
|     {assetId} |     {assetId} | ||||||
|     on:close={() => (showSeletecFaces = false)} |     on:close={() => (showSeletecFaces = false)} | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user