PunimTag Web Application - Major Feature Release #1
@ -97,6 +97,12 @@ jobs:
|
||||
container:
|
||||
image: python:3.12-slim
|
||||
steps:
|
||||
- name: Install Node.js for checkout action
|
||||
run: |
|
||||
apt-get update && apt-get install -y curl
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
||||
apt-get install -y nodejs
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@ -147,6 +153,12 @@ jobs:
|
||||
DATABASE_URL_AUTH: postgresql+psycopg2://postgres:postgres@postgres:5432/punimtag_auth_test
|
||||
REDIS_URL: redis://redis:6379/0
|
||||
steps:
|
||||
- name: Install Node.js for checkout action
|
||||
run: |
|
||||
apt-get update && apt-get install -y curl
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
||||
apt-get install -y nodejs
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ export default function PhotoViewer({ photos, initialIndex, onClose }: PhotoView
|
||||
// Slideshow state
|
||||
const [isPlaying, setIsPlaying] = useState(false)
|
||||
const [slideshowInterval, setSlideshowInterval] = useState(3) // seconds
|
||||
const slideshowTimerRef = useRef<NodeJS.Timeout | null>(null)
|
||||
const slideshowTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||
|
||||
// Favorite state
|
||||
const [isFavorite, setIsFavorite] = useState(false)
|
||||
|
||||
@ -547,6 +547,33 @@ export default function Modify() {
|
||||
})
|
||||
}
|
||||
|
||||
const confirmUnmatchFace = async () => {
|
||||
if (!unmatchConfirmDialog || !selectedPersonId || !unmatchConfirmDialog.faceId) return
|
||||
|
||||
try {
|
||||
setBusy(true)
|
||||
setError(null)
|
||||
setUnmatchConfirmDialog(null)
|
||||
|
||||
// Unmatch the single face
|
||||
await facesApi.batchUnmatch({ face_ids: [unmatchConfirmDialog.faceId] })
|
||||
|
||||
// Reload people list to update face counts
|
||||
const peopleRes = await peopleApi.listWithFaces(lastNameFilter || undefined)
|
||||
setPeople(peopleRes.items)
|
||||
|
||||
// Reload faces
|
||||
await loadPersonFaces(selectedPersonId)
|
||||
|
||||
setSuccess('Successfully unlinked face')
|
||||
setTimeout(() => setSuccess(null), 3000)
|
||||
} catch (err: any) {
|
||||
setError(err.response?.data?.detail || err.message || 'Failed to unmatch face')
|
||||
} finally {
|
||||
setBusy(false)
|
||||
}
|
||||
}
|
||||
|
||||
const confirmBulkUnmatchFaces = async () => {
|
||||
if (!unmatchConfirmDialog || !selectedPersonId || selectedFaces.size === 0) return
|
||||
|
||||
|
||||
@ -414,7 +414,9 @@ export default function Tags() {
|
||||
}
|
||||
}
|
||||
|
||||
// Save pending changes
|
||||
// Save pending changes (currently unused, kept for future use)
|
||||
// @ts-expect-error - Intentionally unused, kept for future use
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const _saveChanges = async () => {
|
||||
const pendingPhotoIds = new Set([
|
||||
...Object.keys(pendingTagChanges).map(Number),
|
||||
@ -483,7 +485,9 @@ export default function Tags() {
|
||||
}
|
||||
}
|
||||
|
||||
// Get pending changes count
|
||||
// Get pending changes count (currently unused, kept for future use)
|
||||
// @ts-expect-error - Intentionally unused, kept for future use
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const _pendingChangesCount = useMemo(() => {
|
||||
const additions = Object.values(pendingTagChanges).reduce((sum, ids) => sum + ids.length, 0)
|
||||
const removals = Object.values(pendingTagRemovals).reduce((sum, ids) => sum + ids.length, 0)
|
||||
@ -1549,7 +1553,7 @@ function PhotoTagDialog({
|
||||
|
||||
// Bulk Tag Dialog Component
|
||||
function BulkTagDialog({
|
||||
folderPath,
|
||||
folderPath: _folderPath,
|
||||
folder,
|
||||
tags,
|
||||
pendingTagChanges,
|
||||
@ -1559,7 +1563,7 @@ function BulkTagDialog({
|
||||
onRemoveTag,
|
||||
getPhotoTags,
|
||||
}: {
|
||||
folderPath: string // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
folderPath: string
|
||||
folder: FolderGroup | undefined
|
||||
tags: TagResponse[]
|
||||
pendingTagChanges: Record<number, number[]>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user