2023-09-04 11:26:18 -05:00

123 lines
5.5 KiB
TypeScript

'use client'
import React, { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { DocumentTextIcon, LanguageIcon, LinkIcon, MagnifyingGlassMinusIcon, MagnifyingGlassPlusIcon, SquaresPlusIcon } from '@heroicons/react/24/outline'
import { useProject } from '../../../context/Project/provider'
import { entities } from '../../../wailsjs/wailsjs/go/models'
import LanguageSelect from '../../utils/LanguageSelect'
import ToolToggleButton from './ToolToggleButton'
import processImageArea from '../../../useCases/processImageArea'
import { pushNotification } from '../../../redux/features/notifications/notificationQueueSlice'
import { RootState } from '../../../redux/store'
import { maxScale, scaleStep, setAreAreasVisible, setAreLinkAreaContextsVisible, setAreProcessedWordsVisible, setAreTranslatedWordsVisible, setScale } from '../../../redux/features/stage/stageSlice'
const ToolingOverlay = () => {
const dispatch = useDispatch()
const {
scale,
areAreasVisible,
areLinkAreaContextsVisible,
areProcessedWordsVisible,
areTranslatedWordsVisible,
} = useSelector((state: RootState) => state.stage)
const { getSelectedDocument, selectedAreaId, requestUpdateArea, requestUpdateDocument, updateDocuments } = useProject()
const selectedDocument = getSelectedDocument()
const [selectedArea, setSelectedArea] = useState<entities.Area | undefined>()
useEffect(() => {
setSelectedArea(selectedDocument?.areas.find(a => a.id == selectedAreaId))
}, [selectedAreaId, selectedDocument, selectedArea])
const handleAreaProcessLanguageSelect = async (selectedLanguage: entities.Language) => {
if (!selectedArea) return
let successfullyUpdatedLanguageOnArea = false
try {
successfullyUpdatedLanguageOnArea = await requestUpdateArea({ ...selectedArea, ...{ language: selectedLanguage } })
} catch (err) {
dispatch(pushNotification({ message: 'Error updating area language', level: 'error' }))
return
}
const selectedDocumentId = getSelectedDocument()?.id
if (!successfullyUpdatedLanguageOnArea || !selectedDocumentId) {
dispatch(pushNotification({ message: 'Did not successfully update area language', level: 'warning' }))
return
}
try {
await processImageArea(selectedDocumentId, selectedArea.id)
await updateDocuments()
dispatch(pushNotification({ message: 'Finished processing area', level: 'info' }))
} catch (err) {
dispatch(pushNotification({ message: 'Error processing area', level: 'error' }))
}
}
const handleDocumentProcessLanguageSelect = async (selectedLanguage: entities.Language) => {
if (!selectedDocument) return
const currentDocument = selectedDocument
currentDocument.defaultLanguage = selectedLanguage
await requestUpdateDocument(currentDocument)
await updateDocuments()
}
const renderLanguageSelect = () => {
const defaultLanguage = selectedArea?.language.displayName ? selectedArea?.language : selectedDocument?.defaultLanguage
const onSelect = selectedArea ? handleAreaProcessLanguageSelect : handleDocumentProcessLanguageSelect
return <LanguageSelect
styles={{ fontSize: '16px', borderRadius: '2px' }}
defaultLanguage={defaultLanguage}
onSelect={onSelect}
/>
}
return <>
{/* Top buttons */}
<div className='absolute flex justify-between align-top top-2 p-2 drop-shadow-2xl pointer-events-none shadow-slate-100' style={{ width: 'calc(100% - 0.5rem)' }}>
<div className='align-top pointer-events-auto w-1/3'>
<h1 className="text-lg font-medium text-gray-900 block mr-2 drop-shadow-2xl shadow-slate-100 drop truncate">
{selectedArea?.name
? `${selectedDocument?.name} / ${selectedArea?.name}`
: selectedDocument?.name
}
</h1>
{ renderLanguageSelect() }
{/* <LanguageSelect styles={{ fontSize: '16px', borderRadius: '2px' }} defaultLanguage={selectedArea?.language.displayName ? selectedArea?.language : selectedDocument?.defaultLanguage} /> */}
</div>
<div className='flex mt-4 justify-evenly align-top pointer-events-auto'>
<MagnifyingGlassMinusIcon className='w-4 h-4' />
<input
id="zoomRange" type="range" min={scaleStep} max={maxScale} step={scaleStep}
value={scale} className="w-[calc(100%-50px)] h-2 bg-indigo-200 rounded-lg appearance-none cursor-pointer p-0"
onChange={(e) => { dispatch(setScale(e.currentTarget.valueAsNumber)) }}
/>
<MagnifyingGlassPlusIcon className='w-4 h-4' />
</div>
</div>
{/* Right Buttons */}
<div className='absolute bottom-6 right-3 pointer-events-none'>
{areAreasVisible
? <>
<ToolToggleButton icon={LinkIcon} hint='Link Area Contexts' isActive={areLinkAreaContextsVisible} onClick={() => dispatch(setAreLinkAreaContextsVisible(!areLinkAreaContextsVisible))} />
<ToolToggleButton icon={LanguageIcon} hint='Toggle Translations' isActive={areTranslatedWordsVisible} onClick={() => dispatch(setAreTranslatedWordsVisible(!areTranslatedWordsVisible))} />
<ToolToggleButton icon={DocumentTextIcon} hint='Toggle Processed' isActive={areProcessedWordsVisible} onClick={() => dispatch(setAreProcessedWordsVisible(!areProcessedWordsVisible))} />
</>
: <></>
}
<ToolToggleButton icon={SquaresPlusIcon} hint='Toggle Areas' isActive={areAreasVisible} onClick={() => dispatch(setAreAreasVisible(!areAreasVisible))} />
</div>
</>
}
export default ToolingOverlay