Skip to content

Commit

Permalink
#460 Make the Resource Viewer editable as a proof-of-concept Scriptur…
Browse files Browse the repository at this point in the history
…e editor
  • Loading branch information
FoolRunning committed Oct 16, 2023
1 parent 851ecbc commit d86f4e2
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ launchSettings.json

# Test development user appdata files
dev-appdata/
c-sharp/**/*.BAK
37 changes: 37 additions & 0 deletions c-sharp/NetworkObjects/UsfmDataProvider.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Xml;
using System.Xml.XPath;
using Paranext.DataProvider.JsonUtils;
using Paranext.DataProvider.MessageHandlers;
using Paranext.DataProvider.MessageTransports;
Expand Down Expand Up @@ -43,6 +44,7 @@ protected override ResponseToRequest HandleRequest(string functionName, JsonArra
"getBookNames" => GetBookNames(),
"getChapter" => GetChapter(args[0]!.ToJsonString()),
"getChapterUsx" => GetChapterUsx(args[0]!.ToJsonString()),
"setChapterUsx" => SetChapterUsx(args[0]!.ToJsonString(), args[1]!.ToString()),
"getVerse" => GetVerse(args[0]!.ToJsonString()),
_ => ResponseToRequest.Failed($"Unexpected function: {functionName}")
};
Expand Down Expand Up @@ -73,6 +75,13 @@ private ResponseToRequest GetChapterUsx(string args)
: ResponseToRequest.Failed(errorMsg);
}

private ResponseToRequest SetChapterUsx(string argVref, string argNewUsx)
{
return VerseRefConverter.TryCreateVerseRef(argVref, out var verseRef, out string errorMsg)
? SetUsx(verseRef, argNewUsx)
: ResponseToRequest.Failed(errorMsg);
}

private ResponseToRequest GetVerse(string args)
{
return VerseRefConverter.TryCreateVerseRef(args, out var verseRef, out string errorMsg)
Expand All @@ -87,6 +96,34 @@ public string GetUsx(VerseRef vref)
return contents;
}

public ResponseToRequest SetUsx(VerseRef vref, string newUsx)
{
try
{
XmlDocument doc = new() { PreserveWhitespace = true };
doc.LoadXml(newUsx);
if (doc.FirstChild?.Name != "usx")
return ResponseToRequest.Failed("Invalid USX");

UsxFragmenter.FindFragments(
_scrText!.ScrStylesheet(vref.BookNum),
doc.CreateNavigator(),
XPathExpression.Compile("*[false()]"),
out string usfm
);

usfm = UsfmToken.NormalizeUsfm(_scrText, vref.BookNum, usfm);
_scrText.PutText(vref.BookNum, vref.ChapterNum, false, usfm, null);
SendDataUpdateEvent("*");
}
catch (Exception e)
{
return ResponseToRequest.Failed(e.Message);
}

return ResponseToRequest.Succeeded();
}

private XmlDocument GetUsxForChapter(int bookNum, int chapterNum)
{
return ConvertUsfmToUsx(GetUsfmForChapter(bookNum, chapterNum), bookNum);
Expand Down
1 change: 1 addition & 0 deletions c-sharp/ParatextUtils/ParatextGlobals.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public static void Initialize(string dataFolderPath)
ICUDllLocator.Initialize(false, false);

// Now tell Paratext.Data to use the specified folder
dataFolderPath = Path.GetFullPath(dataFolderPath); // Make sure path is rooted
ParatextData.Initialize(dataFolderPath, false);
s_initialized = true;
}
Expand Down
20 changes: 15 additions & 5 deletions extensions/src/resource-viewer/resource-viewer.web-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ const usxEditorCharMap = Object.fromEntries(

interface ScriptureTextPanelUsxProps {
usx: string;
onChanged?: (newUsx: string) => void;
}

const defaultScrRef: ScriptureReference = {
Expand All @@ -135,16 +136,17 @@ const defaultScrRef: ScriptureReference = {
* Scripture text panel that displays a read only version of a usx editor that displays the current
* chapter
*/
function ScriptureTextPanelUsxEditor({ usx }: ScriptureTextPanelUsxProps) {
function ScriptureTextPanelUsxEditor({ usx, onChanged }: ScriptureTextPanelUsxProps) {
return (
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
<div className="text-panel">
<UsxEditor
usx={usx}
paraMap={usxEditorParaMap}
charMap={usxEditorCharMap}
onUsxChanged={() => {
/* Read only */
onUsxChanged={(newUsx) => {
// TODO: Check if the project is editable
if (onChanged) onChanged(newUsx);
}}
/>
</div>
Expand All @@ -155,11 +157,19 @@ globalThis.webViewComponent = function ResourceViewer(): JSX.Element {
logger.info('Preparing to display the Resource Viewer');

const [scrRef] = useSetting('platform.verseRef', defaultScrRef);
const [usx, , isLoading] = useData.ChapterUsx<UsfmProviderDataTypes, 'ChapterUsx'>(
const [usx, setUsx, isLoading] = useData.ChapterUsx<UsfmProviderDataTypes, 'ChapterUsx'>(
'usfm',
useMemo(() => new VerseRef(scrRef.bookNum, scrRef.chapterNum, scrRef.verseNum), [scrRef]),
'Loading Scripture...',
);

return <div>{isLoading ? 'Loading' : <ScriptureTextPanelUsxEditor usx={usx ?? '<usx/>'} />}</div>;
return (
<div>
{isLoading ? (
'Loading'
) : (
<ScriptureTextPanelUsxEditor usx={usx ?? '<usx/>'} onChanged={setUsx} />
)}
</div>
);
};
2 changes: 1 addition & 1 deletion extensions/src/usfm-data-provider/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ declare module 'usfm-data-provider' {
export type UsfmProviderDataTypes = {
BookNames: DataProviderDataType<boolean, string[], never>;
Chapter: DataProviderDataType<VerseRef, string | undefined, never>;
ChapterUsx: DataProviderDataType<VerseRef, string | undefined, never>;
ChapterUsx: DataProviderDataType<VerseRef, string | undefined, string>;
Verse: DataProviderDataType<VerseRef, string | undefined, never>;
};

Expand Down

0 comments on commit d86f4e2

Please sign in to comment.