PunimTag Web Application - Major Feature Release #1

Open
tanyar09 wants to merge 106 commits from dev into master
4 changed files with 48 additions and 5 deletions
Showing only changes of commit 36b84fc355 - Show all commits

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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[]>