tycho-components 0.41.1 → 0.41.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/features/Comments/CommentUtils.d.ts +3 -1
- package/dist/features/Comments/CommentUtils.js +28 -1
- package/dist/features/Comments/Comments.js +26 -16
- package/dist/features/PageRender/PageRenderView.d.ts +2 -1
- package/dist/features/PageRender/PageRenderView.js +46 -2
- package/package.json +1 -1
|
@@ -10,7 +10,9 @@ declare const CommentUtils: {
|
|
|
10
10
|
persistDrawerWidth: (width: number) => void;
|
|
11
11
|
persistDrawerHeight: (height: number) => void;
|
|
12
12
|
readStoredDockPosition: () => DockPosition;
|
|
13
|
-
persistDockPosition: (position:
|
|
13
|
+
persistDockPosition: (position: DockPosition) => void;
|
|
14
|
+
readStoredLastDocked: () => DockedPosition;
|
|
15
|
+
persistLastDocked: (position: DockedPosition) => void;
|
|
14
16
|
getUndockedPopupSize: () => {
|
|
15
17
|
width: number;
|
|
16
18
|
height: number;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const DRAWER_WIDTH_STORAGE_KEY = 'tycho-comments-drawer-width';
|
|
2
2
|
const DRAWER_HEIGHT_STORAGE_KEY = 'tycho-comments-drawer-height';
|
|
3
3
|
const DOCK_POSITION_STORAGE_KEY = 'tycho-comments-dock-position';
|
|
4
|
+
const LAST_DOCKED_STORAGE_KEY = 'tycho-comments-last-docked';
|
|
4
5
|
const DRAWER_MIN_WIDTH = 320;
|
|
5
6
|
const DRAWER_MIN_HEIGHT = 200;
|
|
6
7
|
const POPUP_NAME = 'tycho-comments';
|
|
@@ -87,7 +88,7 @@ const persistDrawerHeight = (height) => {
|
|
|
87
88
|
const readStoredDockPosition = () => {
|
|
88
89
|
try {
|
|
89
90
|
const stored = localStorage.getItem(DOCK_POSITION_STORAGE_KEY);
|
|
90
|
-
if (isDockPosition(stored)
|
|
91
|
+
if (isDockPosition(stored)) {
|
|
91
92
|
return stored;
|
|
92
93
|
}
|
|
93
94
|
}
|
|
@@ -104,6 +105,30 @@ const persistDockPosition = (position) => {
|
|
|
104
105
|
// ignore storage access errors
|
|
105
106
|
}
|
|
106
107
|
};
|
|
108
|
+
const readStoredLastDocked = () => {
|
|
109
|
+
try {
|
|
110
|
+
const stored = localStorage.getItem(LAST_DOCKED_STORAGE_KEY);
|
|
111
|
+
if (stored === 'left' || stored === 'right' || stored === 'bottom') {
|
|
112
|
+
return stored;
|
|
113
|
+
}
|
|
114
|
+
const dock = localStorage.getItem(DOCK_POSITION_STORAGE_KEY);
|
|
115
|
+
if (dock === 'left' || dock === 'right' || dock === 'bottom') {
|
|
116
|
+
return dock;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// ignore storage access errors
|
|
121
|
+
}
|
|
122
|
+
return 'right';
|
|
123
|
+
};
|
|
124
|
+
const persistLastDocked = (position) => {
|
|
125
|
+
try {
|
|
126
|
+
localStorage.setItem(LAST_DOCKED_STORAGE_KEY, position);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// ignore storage access errors
|
|
130
|
+
}
|
|
131
|
+
};
|
|
107
132
|
const getUndockedPopupSize = () => {
|
|
108
133
|
if (typeof window === 'undefined') {
|
|
109
134
|
return { width: POPUP_MIN_WIDTH, height: POPUP_MIN_HEIGHT };
|
|
@@ -168,6 +193,8 @@ const CommentUtils = {
|
|
|
168
193
|
persistDrawerHeight,
|
|
169
194
|
readStoredDockPosition,
|
|
170
195
|
persistDockPosition,
|
|
196
|
+
readStoredLastDocked,
|
|
197
|
+
persistLastDocked,
|
|
171
198
|
getUndockedPopupSize,
|
|
172
199
|
copyStylesToPopup,
|
|
173
200
|
openCommentsPopup,
|
|
@@ -41,12 +41,11 @@ export default function Comments({ uid, keywords, references, mode, onClose, onC
|
|
|
41
41
|
const popupRef = useRef(null);
|
|
42
42
|
const popupPollRef = useRef(null);
|
|
43
43
|
const ignorePopupCloseRef = useRef(false);
|
|
44
|
+
const popupCloseHandledRef = useRef(false);
|
|
45
|
+
const restoredUndockRef = useRef(false);
|
|
44
46
|
const lastDockedRef = useRef(null);
|
|
45
47
|
if (lastDockedRef.current === null) {
|
|
46
|
-
|
|
47
|
-
lastDockedRef.current = CommentUtils.isDockedPosition(initial)
|
|
48
|
-
? initial
|
|
49
|
-
: 'right';
|
|
48
|
+
lastDockedRef.current = CommentUtils.readStoredLastDocked();
|
|
50
49
|
}
|
|
51
50
|
const load = async () => {
|
|
52
51
|
try {
|
|
@@ -70,22 +69,21 @@ export default function Comments({ uid, keywords, references, mode, onClose, onC
|
|
|
70
69
|
popupPollRef.current = null;
|
|
71
70
|
}
|
|
72
71
|
}, []);
|
|
73
|
-
const
|
|
72
|
+
const handlePopupClosed = useCallback(() => {
|
|
74
73
|
clearPopupPoll();
|
|
75
74
|
popupRef.current = null;
|
|
76
75
|
setExternalContainer(null);
|
|
77
76
|
if (ignorePopupCloseRef.current) {
|
|
78
77
|
ignorePopupCloseRef.current = false;
|
|
78
|
+
popupCloseHandledRef.current = true;
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
});
|
|
88
|
-
}, [clearPopupPoll]);
|
|
81
|
+
if (popupCloseHandledRef.current)
|
|
82
|
+
return;
|
|
83
|
+
popupCloseHandledRef.current = true;
|
|
84
|
+
// Do not redock — keep undocked so the main Drawer stays closed.
|
|
85
|
+
onClose();
|
|
86
|
+
}, [clearPopupPoll, onClose]);
|
|
89
87
|
const closePopup = useCallback(() => {
|
|
90
88
|
clearPopupPoll();
|
|
91
89
|
const popup = popupRef.current;
|
|
@@ -105,6 +103,7 @@ export default function Comments({ uid, keywords, references, mode, onClose, onC
|
|
|
105
103
|
if (existing && !existing.closed) {
|
|
106
104
|
existing.focus();
|
|
107
105
|
setDockPosition('undocked');
|
|
106
|
+
CommentUtils.persistDockPosition('undocked');
|
|
108
107
|
return;
|
|
109
108
|
}
|
|
110
109
|
const opened = CommentUtils.openCommentsPopup();
|
|
@@ -112,22 +111,25 @@ export default function Comments({ uid, keywords, references, mode, onClose, onC
|
|
|
112
111
|
return;
|
|
113
112
|
const { popup, container } = opened;
|
|
114
113
|
ignorePopupCloseRef.current = false;
|
|
114
|
+
popupCloseHandledRef.current = false;
|
|
115
115
|
popupRef.current = popup;
|
|
116
116
|
setExternalContainer(container);
|
|
117
117
|
setDockPosition('undocked');
|
|
118
|
+
CommentUtils.persistDockPosition('undocked');
|
|
118
119
|
popup.addEventListener('beforeunload', () => {
|
|
119
|
-
|
|
120
|
+
handlePopupClosed();
|
|
120
121
|
});
|
|
121
122
|
clearPopupPoll();
|
|
122
123
|
popupPollRef.current = window.setInterval(() => {
|
|
123
124
|
if (!popupRef.current || popupRef.current.closed) {
|
|
124
|
-
|
|
125
|
+
handlePopupClosed();
|
|
125
126
|
}
|
|
126
127
|
}, 500);
|
|
127
|
-
}, [clearPopupPoll,
|
|
128
|
+
}, [clearPopupPoll, handlePopupClosed]);
|
|
128
129
|
const setDockedPosition = useCallback((position) => {
|
|
129
130
|
lastDockedRef.current = position;
|
|
130
131
|
CommentUtils.persistDockPosition(position);
|
|
132
|
+
CommentUtils.persistLastDocked(position);
|
|
131
133
|
closePopup();
|
|
132
134
|
setDockPosition(position);
|
|
133
135
|
}, [closePopup]);
|
|
@@ -176,6 +178,14 @@ export default function Comments({ uid, keywords, references, mode, onClose, onC
|
|
|
176
178
|
useEffect(() => {
|
|
177
179
|
load();
|
|
178
180
|
}, []);
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
if (restoredUndockRef.current)
|
|
183
|
+
return;
|
|
184
|
+
if (CommentUtils.readStoredDockPosition() !== 'undocked')
|
|
185
|
+
return;
|
|
186
|
+
restoredUndockRef.current = true;
|
|
187
|
+
openUndockedWindow();
|
|
188
|
+
}, [openUndockedWindow]);
|
|
179
189
|
useEffect(() => {
|
|
180
190
|
if (!openAddComment || !comments)
|
|
181
191
|
return;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import './style.scss';
|
|
2
|
-
import { PageRenderViewProps } from './types';
|
|
2
|
+
import { CollapsedPageRenderElement, PageRenderViewProps } from './types';
|
|
3
3
|
export default function PageRenderView({ elements, selectedTier, corpus, displayTags, showLineNumbers, highlightSentenceUid, activeTokenKey, selectedTokenKeys, tokenSelectionKey, getDisplayValue, getTokenStyle, getTokenClassName, isTokenEdited, getParticipantName, getParticipantColor, onTokenClick, onTokenHover, onParticipantHover, wrapToken, renderTokenSuffix, }: PageRenderViewProps): import("react").JSX.Element;
|
|
4
|
+
export declare function findPunctuationAfterCollapsedJunction(items: CollapsedPageRenderElement[], junctionIndex: number): number | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment } from 'react';
|
|
2
3
|
import cx from 'classnames';
|
|
3
4
|
import './style.scss';
|
|
4
5
|
import collapseElementsForTier from './collapseElementsForTier';
|
|
@@ -6,8 +7,51 @@ import isTokenRefVisible, { tokenRefToToken } from './tokenUtils';
|
|
|
6
7
|
import { PageRenderElementType, } from './types';
|
|
7
8
|
export default function PageRenderView({ elements, selectedTier, corpus, displayTags = false, showLineNumbers = true, highlightSentenceUid, activeTokenKey, selectedTokenKeys, tokenSelectionKey, getDisplayValue, getTokenStyle, getTokenClassName, isTokenEdited, getParticipantName, getParticipantColor, onTokenClick, onTokenHover, onParticipantHover, wrapToken, renderTokenSuffix, }) {
|
|
8
9
|
const collapsed = collapseElementsForTier(elements, selectedTier, corpus);
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
const punctuationBeforeBreak = new Map();
|
|
11
|
+
const punctuationIndexes = new Set();
|
|
12
|
+
collapsed.forEach((item, index) => {
|
|
13
|
+
const punctuationIndex = findPunctuationAfterCollapsedJunction(collapsed, index);
|
|
14
|
+
if (punctuationIndex === undefined)
|
|
15
|
+
return;
|
|
16
|
+
punctuationBeforeBreak.set(index, punctuationIndex);
|
|
17
|
+
punctuationIndexes.add(punctuationIndex);
|
|
18
|
+
});
|
|
19
|
+
const renderItem = (item) => (_jsx(PageRenderElementItem, { item: item, highlight: highlightSentenceUid != null &&
|
|
20
|
+
sentenceUidForItem(item) === highlightSentenceUid, showLineNumbers: showLineNumbers, displayTags: displayTags, activeTokenKey: activeTokenKey, selectedTokenKeys: selectedTokenKeys, tokenSelectionKey: tokenSelectionKey, getDisplayValue: getDisplayValue, getTokenStyle: getTokenStyle, getTokenClassName: getTokenClassName, isTokenEdited: isTokenEdited, getParticipantName: getParticipantName, getParticipantColor: getParticipantColor, onTokenClick: onTokenClick, onTokenHover: onTokenHover, onParticipantHover: onParticipantHover, wrapToken: wrapToken, renderTokenSuffix: renderTokenSuffix }, item.key));
|
|
21
|
+
return (_jsx("div", { className: "page-render-elements", children: collapsed.map((item, index) => {
|
|
22
|
+
if (punctuationIndexes.has(index))
|
|
23
|
+
return null;
|
|
24
|
+
const punctuationIndex = punctuationBeforeBreak.get(index);
|
|
25
|
+
return (_jsxs(Fragment, { children: [renderItem(item), punctuationIndex !== undefined &&
|
|
26
|
+
renderItem(collapsed[punctuationIndex])] }, item.key));
|
|
27
|
+
}) }));
|
|
28
|
+
}
|
|
29
|
+
export function findPunctuationAfterCollapsedJunction(items, junctionIndex) {
|
|
30
|
+
const junction = items[junctionIndex];
|
|
31
|
+
if (junction?.kind !== 'collapsedJunction')
|
|
32
|
+
return undefined;
|
|
33
|
+
let hasLineBreak = false;
|
|
34
|
+
for (let index = junctionIndex + 1; index < items.length; index += 1) {
|
|
35
|
+
const item = items[index];
|
|
36
|
+
if (item.kind === 'single') {
|
|
37
|
+
if (item.element.type === PageRenderElementType.LINE_BREAK) {
|
|
38
|
+
hasLineBreak = true;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (item.element.type === PageRenderElementType.LINE_NUMBER) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (hasLineBreak &&
|
|
45
|
+
item.element.type === PageRenderElementType.TOKEN &&
|
|
46
|
+
item.element.token?.t === 'PUNC' &&
|
|
47
|
+
item.element.token.uid === junction.token.uid &&
|
|
48
|
+
item.element.token.p > junction.token.p) {
|
|
49
|
+
return index;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
11
55
|
}
|
|
12
56
|
function sentenceUidForItem(item) {
|
|
13
57
|
if (item.kind === 'collapsedJunction')
|