diff --git a/package.json b/package.json
index 0c7c027..42981fc 100644
--- a/package.json
+++ b/package.json
@@ -37,9 +37,11 @@
"autoprefixer": "^10.1.0",
"bible-reference-rcl": "1.4.0-beta",
"core-js": "^3.8.3",
+ "deep-diff": "^1.0.2",
"deep-equal": "^2.0.5",
"gitea-react-toolkit": "2.4.0",
"localforage": "^1.9.0",
+ "lodash.clonedeep": "^4.5.0",
"markdown-translatable": "2.0.3",
"next": "12",
"postcss": "^8.2.1",
@@ -58,7 +60,7 @@
"translation-helps-rcl": "3.6.0-beta",
"use-deep-compare-effect": "^1.3.1",
"word-aligner": "^1.0.0",
- "word-aligner-rcl": "1.0.4"
+ "word-aligner-rcl": "file:.yalc/word-aligner-rcl"
},
"devDependencies": {
"@cypress/code-coverage": "^3.9.11",
diff --git a/src/components/WordAlignerArea.js b/src/components/WordAlignerArea.js
new file mode 100644
index 0000000..9e04ea4
--- /dev/null
+++ b/src/components/WordAlignerArea.js
@@ -0,0 +1,100 @@
+import React, {useEffect, useState} from 'react'
+import PropTypes from 'prop-types'
+import DialogTitle from '@mui/material/DialogTitle'
+import { RxLink2, RxLinkBreak2 } from 'react-icons/rx'
+import { AlignmentHelpers, WordAligner } from 'word-aligner-rcl'
+
+// popup dialog for user to align verse
+export default function WordAlignerArea({
+ aligned,
+ alignmentIconStyle,
+ contextId,
+ lexiconCache,
+ loadLexiconEntry,
+ onChange,
+ showPopover,
+ sourceLanguage,
+ sourceLanguageFont,
+ sourceFontSizePercent,
+ targetLanguage,
+ targetLanguageFont,
+ targetFontSizePercent,
+ title,
+ translate,
+ verseAlignments,
+ targetWords,
+ style,
+}) {
+ const [aligned_, setAligned] = useState(aligned)
+ const [alignmentChange, setAlignmentChange] = useState(null)
+
+ useEffect(() => {
+ console.log('WordAlignerArea: initialized')
+ }, [])
+
+ useEffect(() => {
+ if (aligned !== aligned_) {
+ console.log('WordAlignerArea: set alignment to', aligned)
+ setAligned(aligned)
+ }
+ }, [aligned])
+
+
+ function onAlignmentChange(results) {
+ // const onAlignmentsChange = alignerStatus?.actions?.onAlignmentsChange
+ // const alignmentComplete = onAlignmentsChange?.(results)
+ const alignmentComplete = AlignmentHelpers.areAlgnmentsComplete(results.targetWords, results.verseAlignments);
+ setAlignmentChange(results) // save the most recent change
+ setAligned(alignmentComplete) // update alignment complete status
+ }
+
+ return (
+ <>
+
+
+ {`Aligning: ${title}`}
+ {aligned_? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ >
+ )
+}
+
+WordAlignerArea.propTypes = {
+ aligned: PropTypes.bool,
+ contextId: PropTypes.object.isRequired,
+ lexiconCache: PropTypes.object,
+ loadLexiconEntry: PropTypes.func.isRequired,
+ onChange: PropTypes.func,
+ showPopover: PropTypes.func.isRequired,
+ sourceLanguage: PropTypes.string.isRequired,
+ sourceLanguageFont: PropTypes.string,
+ sourceFontSizePercent: PropTypes.number,
+ targetLanguageFont: PropTypes.string,
+ targetFontSizePercent: PropTypes.number,
+ translate: PropTypes.func.isRequired,
+ title: PropTypes.string,
+ verseAlignments: PropTypes.array.isRequired,
+ targetWords: PropTypes.array.isRequired,
+};
+
diff --git a/src/components/WordAlignerDialog.js b/src/components/WordAlignerDialog.js
index 7111b8a..dc36869 100644
--- a/src/components/WordAlignerDialog.js
+++ b/src/components/WordAlignerDialog.js
@@ -6,6 +6,8 @@ import React, {
useState,
} from 'react'
import PropTypes from 'prop-types'
+import cloneDeep from 'lodash.clonedeep'
+import * as isEqual from 'deep-equal'
import Dialog from '@mui/material/Dialog'
import DialogTitle from '@mui/material/DialogTitle'
import { RxLink2, RxLinkBreak2 } from 'react-icons/rx'
@@ -21,6 +23,7 @@ import {
import { useBoundsUpdater } from 'translation-helps-rcl'
import PopoverComponent from './PopoverComponent'
import { StoreContext } from '@context/StoreContext'
+import WordAlignerArea from './WordAlignerArea';
const alignmentIconStyle = { marginLeft:'50px' }
@@ -31,10 +34,11 @@ export default function WordAlignerDialog({
translate,
getLexiconData,
}) {
- const [alignerData, setAlignerData] = useState(null)
+ const [currentAlignerData, setCurrentAlignerData] = useState(null)
const [alignmentChange, setAlignmentChange] = useState(null)
const [aligned, setAligned] = useState(false)
const [lexiconData, setLexiconData] = useState(null)
+ const [dialogState, setDialogState] = useState({})
const [showResetWarning, setShowResetWarning] = useState(false)
const dialogRef = useRef(null) // for keeping track of aligner dialog position
@@ -52,9 +56,9 @@ export default function WordAlignerDialog({
} = useBoundsUpdater({ // keeps track of drag bounds
workspaceRef: mainScreenRef,
cardRef: dialogRef,
- open: !!alignerData,
+ open: !!currentAlignerData,
displayState: {
- alignerData
+ alignerData: currentAlignerData
},
})
@@ -74,16 +78,49 @@ export default function WordAlignerDialog({
}
useEffect(() => {
- setAlignerData(alignerData_)
+ // see if alignment data has changed
+ const alignments = alignerData_?.alignments || null;
+ const wordBank = alignerData_?.wordBank || null;
+ const show = alignerData_?.showDialog;
+ const verseAlignments_ = dialogState?.verseAlignments || null;
+ const targetWords_ = dialogState?.targetWords || null;
+ const changedTW = !isEqual(wordBank, targetWords_);
+ if (changedTW) {
+ // const differences = diff(wordBank, targetWords_);
+ console.log("targetWords differences")
+ }
+ const changedVA = !isEqual(alignments, verseAlignments_);
+ if (changedVA) {
+ // const differences = diff(verseAlignments, verseAlignments_);
+ console.log("verseAlignments differences")
+ }
+ const showDialog = !!(alignments && wordBank);
+ const changedShow = (!show !== !showDialog)
+
+ if (changedTW || changedVA || changedShow) {
+ const verseAlignments = cloneDeep(alignments);
+ const targetWords = cloneDeep(wordBank);
+ setDialogState({
+ verseAlignments,
+ targetWords,
+ showDialog,
+ })
+ }
+
+ setCurrentAlignerData(cloneDeep(alignerData_))
}, [alignerData_])
+ useEffect(() => {
+ console.log('WordAlignerDialog: initialized')
+ }, [])
+
useEffect(() => { // monitor changes in alignment dialog position and open state
- if (alignerData &&
+ if (currentAlignerData &&
dialogRef?.current?.clientWidth &&
dialogRef?.current?.clientHeight) {
doUpdateBounds()
}
- }, [dialogRef?.current, alignerData])
+ }, [dialogRef?.current, currentAlignerData])
/**
* called on every alignment change. We save this new alignment state so that it can be applied if user clicks accept.
@@ -91,10 +128,10 @@ export default function WordAlignerDialog({
* @param {object} results
*/
function onAlignmentChange(results) {
- const onAlignmentsChange = alignerStatus?.actions?.onAlignmentsChange
- const alignmentComplete = onAlignmentsChange?.(results)
- setAlignmentChange(results) // save the most recent change
- setAligned(alignmentComplete) // update alignment complete status
+ // const onAlignmentsChange = alignerStatus?.actions?.onAlignmentsChange
+ // const alignmentComplete = onAlignmentsChange?.(results)
+ // setAlignmentChange(results) // save the most recent change
+ setAligned(false) // update alignment complete status
}
function showPopover(PopoverTitle, wordDetails, positionCoord, rawData) {
@@ -108,13 +145,13 @@ export default function WordAlignerDialog({
})
}
- const errorMessage = alignerData?.errorMessage
+ const errorMessage = currentAlignerData?.errorMessage
useEffect(() => { // set initial aligned state
- if (alignerData) {
+ if (currentAlignerData) {
setAligned(!!alignerStatus?.state?.aligned)
}
- }, [alignerData, alignerStatus])
+ }, [currentAlignerData, alignerStatus])
const {
projectId,
@@ -135,17 +172,26 @@ export default function WordAlignerDialog({
setAlignmentChange(null)
}
+ function setShowDialog(show) {
+ const _dialogState = {
+ ...dialogState,
+ showDialog: !!show,
+ }
+ setDialogState(_dialogState)
+ }
+
/**
* reset all the alignments
*/
function doReset() {
console.log('WordAlignerDialog() - reset Alignments Clicked')
- setShowResetWarning(false)
- const alignmentData_ = AlignmentHelpers.resetAlignments(alignerData?.alignments, alignerData?.wordBank)
+ setShowDialog(false) // momentarily hide the dialog
+ const alignmentData_ = AlignmentHelpers.resetAlignments(dialogState?.verseAlignments, dialogState?.targetWords)
- setAlignerData({ // this causes word aligner to redraw with empty alignments
- alignments: alignmentData_.verseAlignments,
- wordBank: alignmentData_.targetWords,
+ setDialogState({ // this causes word aligner to redraw with empty alignments
+ verseAlignments: alignmentData_.verseAlignments,
+ targetWords: alignmentData_.targetWords,
+ showDialog: true,
})
const latestChange = alignmentChange || {}
@@ -157,7 +203,9 @@ export default function WordAlignerDialog({
setAlignmentChange(alignmentChange_) // clear the last alignment changes in case user next does save
}
- const enableResetWarning = useMemo( () => (showResetWarning && !!alignerData), [showResetWarning && !!alignerData])
+ const showDialog = !!dialogState?.showDialog;
+ const haveAlignerData = !!(dialogState?.verseAlignments && dialogState?.targetWords)
+ const enableResetWarning = useMemo( () => (showDialog && haveAlignerData), [showDialog, haveAlignerData])
return (
<>
@@ -165,43 +213,28 @@ export default function WordAlignerDialog({
fullWidth={true}
maxWidth={'lg'}
onClose={() => {}}
- open={!!alignerData}
+ open={!!showDialog}
PaperComponent={PaperComponent}
bounds={bounds}
aria-labelledby="draggable-aligner-dialog-title"
>
-
-
- {`Aligning: ${title}`}
- {aligned? (
-
- ) : (
-
- )}
-
-
-
- {(!errorMessage && alignerData?.alignments) ?
-
- : // if error, then show message
-
- { errorMessage || '' }
-
- }
-
+
+