diff options
author | Sam Wilkins <samwilkins333@gmail.com> | 2019-09-14 21:00:37 -0400 |
---|---|---|
committer | Sam Wilkins <samwilkins333@gmail.com> | 2019-09-14 21:00:37 -0400 |
commit | c2f749238e9db63b81c3bec08a14dd6006ab876f (patch) | |
tree | 021211ba6c070c307344deee6199c4eba9ef4833 | |
parent | 037098aca0993bee6f986b592c17aa54a7225905 (diff) |
sharing routine for docs and final formatting fixes
-rw-r--r-- | src/Utils.ts | 4 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 9 | ||||
-rw-r--r-- | src/new_fields/RichTextUtils.ts | 153 | ||||
-rw-r--r-- | src/server/credentials/google_docs_token.json | 2 |
5 files changed, 108 insertions, 62 deletions
diff --git a/src/Utils.ts b/src/Utils.ts index 60f18eac2..a842f5a20 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -42,6 +42,10 @@ export class Utils { return this.prepend(`/files/${filename}`); } + public static shareUrl(documentId: string): string { + return this.prepend(`/doc/${documentId}?sharing=true`); + } + public static CorsProxy(url: string): string { return this.prepend(RouteStore.corsProxy + "/") + encodeURIComponent(url); } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index f19243bd6..12771d11e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -50,7 +50,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo return ( <> <line key="linkLine" className="collectionfreeformlinkview-linkLine" - style={{ strokeWidth: `${5}` }} + style={{ strokeWidth: `${3}` }} x1={`${x1}`} y1={`${y1}`} x2={`${x2}`} y2={`${y2}`} /> {/* <circle key="linkCircle" className="collectionfreeformlinkview-linkCircle" diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 23f615f32..fc5b27220 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -749,11 +749,10 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe let targetContext = await Cast(proto.targetContext, Doc); let jumpToDoc = await Cast(linkDoc.anchor2, Doc); if (jumpToDoc) { - if (DocumentManager.Instance.getDocumentView(jumpToDoc)) { - - DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, undefined, undefined, NumCast((jumpToDoc === linkDoc.anchor2 ? linkDoc.anchor2Page : linkDoc.anchor1Page))); - return; - } + // if (DocumentManager.Instance.getDocumentView(jumpToDoc)) { + DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, undefined, document => this.props.addDocTab(document, undefined, location ? location : "onRight"), NumCast((jumpToDoc === linkDoc.anchor2 ? linkDoc.anchor2Page : linkDoc.anchor1Page))); + return; + // } } if (targetContext) { DocumentManager.Instance.jumpToDocument(targetContext, ctrlKey, false, document => this.props.addDocTab(document, undefined, location ? location : "inTab")); diff --git a/src/new_fields/RichTextUtils.ts b/src/new_fields/RichTextUtils.ts index 84744db2f..555c41b67 100644 --- a/src/new_fields/RichTextUtils.ts +++ b/src/new_fields/RichTextUtils.ts @@ -4,7 +4,7 @@ import { RichTextField } from "./RichTextField"; import { docs_v1 } from "googleapis"; import { GoogleApiClientUtils } from "../client/apis/google_docs/GoogleApiClientUtils"; import { FormattedTextBox } from "../client/views/nodes/FormattedTextBox"; -import { Opt } from "./Doc"; +import { Opt, Doc } from "./Doc"; import Color = require('color'); import { sinkListItem } from "prosemirror-schema-list"; import { Utils, PostToServer } from "../Utils"; @@ -12,6 +12,11 @@ import { RouteStore } from "../server/RouteStore"; import { Docs } from "../client/documents/Documents"; import { schema } from "../client/util/RichTextSchema"; import { GooglePhotos } from "../client/apis/google_docs/GooglePhotosClientUtils"; +import { SchemaHeaderField } from "./SchemaHeaderField"; +import { DocServer } from "../client/DocServer"; +import { Cast } from "./Types"; +import { Id } from "./FieldSymbols"; +import { DocumentView } from "../client/views/nodes/DocumentView"; export namespace RichTextUtils { @@ -91,9 +96,15 @@ export namespace RichTextUtils { export namespace GoogleDocs { export const Export = async (state: EditorState): Promise<GoogleApiClientUtils.Docs.Content> => { - const nodes: Node<any>[] = []; + const nodes: (Node<any> | null)[] = []; let text = ToPlainText(state); - state.doc.content.forEach(node => node.content.forEach(child => nodes.push(child))); + state.doc.content.forEach(node => { + if (!node.childCount) { + nodes.push(null); + } else { + node.content.forEach(child => nodes.push(child)); + } + }); const requests = await marksToStyle(nodes); return { text, requests }; }; @@ -223,30 +234,11 @@ export namespace RichTextUtils { const StyleToMark = new Map<keyof docs_v1.Schema$TextStyle, keyof typeof schema.marks>([ ["bold", "strong"], ["italic", "em"], - ["foregroundColor", "pFontColor"] - ]); - - const MarkToStyle = new Map<keyof typeof schema.marks, keyof docs_v1.Schema$TextStyle>([ - ["strong", "bold"], - ["em", "italic"], - ["pFontColor", "foregroundColor"], - ["timesNewRoman", "weightedFontFamily"], - ["georgia", "weightedFontFamily"], - ["comicSans", "weightedFontFamily"], - ["tahoma", "weightedFontFamily"], - ["impact", "weightedFontFamily"] + ["foregroundColor", "pFontColor"], + ["fontSize", "pFontSize"] ]); - const FontFamilyMapping = new Map<string, string>([ - ["timesNewRoman", "Times New Roman"], - ["arial", "Arial"], - ["georgia", "Georgia"], - ["comicSans", "Comic Sans MS"], - ["tahoma", "Tahoma"], - ["impact", "Impact"] - ]); - - const styleToMarks = (schema: any, textStyle?: docs_v1.Schema$TextStyle): Opt<Mark[]> => { + const styleToMarks = (schema: any, textStyle?: docs_v1.Schema$TextStyle) => { if (!textStyle) { return undefined; } @@ -263,20 +255,53 @@ export namespace RichTextUtils { let object = value.color.rgbColor; attributes.color = Color.rgb(["red", "green", "blue"].map(color => object[color] * 255 || 0)).hex(); } + if (value.magnitude) { + attributes.fontSize = value.magnitude; + } - let mark = schema.mark(schema.marks[converted], attributes); + let mapped = schema.marks[converted]; + if (!mapped) { + alert(`No mapping found for ${converted}!`); + return; + } + + let mark = schema.mark(mapped, attributes); mark && marks.push(mark); } }); return marks; }; + const MarkToStyle = new Map<keyof typeof schema.marks, keyof docs_v1.Schema$TextStyle>([ + ["strong", "bold"], + ["em", "italic"], + ["pFontColor", "foregroundColor"], + ["timesNewRoman", "weightedFontFamily"], + ["georgia", "weightedFontFamily"], + ["comicSans", "weightedFontFamily"], + ["tahoma", "weightedFontFamily"], + ["impact", "weightedFontFamily"] + ]); + + const FontFamilyMapping = new Map<string, string>([ + ["timesNewRoman", "Times New Roman"], + ["arial", "Arial"], + ["georgia", "Georgia"], + ["comicSans", "Comic Sans MS"], + ["tahoma", "Tahoma"], + ["impact", "Impact"] + ]); + const ignored = ["user_mark"]; - const marksToStyle = async (nodes: Node<any>[]): Promise<docs_v1.Schema$Request[]> => { + const marksToStyle = async (nodes: (Node<any> | null)[]): Promise<docs_v1.Schema$Request[]> => { let requests: docs_v1.Schema$Request[] = []; let position = 1; for (let node of nodes) { + if (node === null) { + position += 2; + continue; + } const { marks, attrs, nodeSize } = node; const textStyle: docs_v1.Schema$TextStyle = {}; const information: LinkInformation = { @@ -284,37 +309,55 @@ export namespace RichTextUtils { endIndex: position + nodeSize, textStyle }; - if (marks.length) { - let mark: Mark<any>; - const markMap = BuildMarkMap(marks); - Object.keys(schema.marks).map(markName => { - if (!ignored.includes(markName) && (mark = markMap[markName])) { - const converted = MarkToStyle.get(markName) || markName as keyof docs_v1.Schema$TextStyle; - let value: any = true; - if (converted) { - const { attrs } = mark; - switch (converted) { - case "link": - value = { url: attrs.href }; - textStyle.foregroundColor = fromRgb.blue; - textStyle.bold = true; - break; - case "fontSize": - value = attrs.fontSize; - break; - case "foregroundColor": - value = fromHex(attrs.color); - break; - case "weightedFontFamily": - value = { fontFamily: FontFamilyMapping.get(markName) }; + let mark: Mark<any>; + const markMap = BuildMarkMap(marks); + for (let markName of Object.keys(schema.marks)) { + if (ignored.includes(markName) || !(mark = markMap[markName])) { + continue; + } + let converted = MarkToStyle.get(markName) || markName as keyof docs_v1.Schema$TextStyle; + let value: any = true; + if (!converted) { + continue; + } + const { attrs } = mark; + switch (converted) { + case "link": + let url = attrs.href; + const delimiter = "/doc/"; + const alreadyShared = "?sharing=true"; + if (new RegExp(window.location.origin + delimiter).test(url) && !url.endsWith(alreadyShared)) { + const linkDoc = await DocServer.GetRefField(url.split(delimiter)[1]); + if (linkDoc instanceof Doc) { + const target = (await Cast(linkDoc.anchor2, Doc))!; + const exported = Doc.MakeAlias(target); + DocumentView.makeCustomViewClicked(exported); + target && (url = Utils.shareUrl(exported[Id])); + linkDoc.anchor2 = exported; } - textStyle[converted] = value; } - } - }); - if (Object.keys(textStyle).length) { - requests.push(EncodeStyleUpdate(information)); + value = { url }; + textStyle.foregroundColor = fromRgb.blue; + textStyle.bold = true; + break; + case "fontSize": + value = attrs.fontSize; + break; + case "foregroundColor": + value = fromHex(attrs.color); + break; + case "weightedFontFamily": + value = { fontFamily: FontFamilyMapping.get(markName) }; + } + let matches: RegExpExecArray | null; + if ((matches = /p(\d+)/g.exec(markName)) !== null) { + converted = "fontSize"; + value = { magnitude: parseInt(matches[1]), unit: "PT" }; } + textStyle[converted] = value; + } + if (Object.keys(textStyle).length) { + requests.push(EncodeStyleUpdate(information)); } if (node.type.name === "image") { requests.push(await EncodeImage({ diff --git a/src/server/credentials/google_docs_token.json b/src/server/credentials/google_docs_token.json index 330d27141..265c07c69 100644 --- a/src/server/credentials/google_docs_token.json +++ b/src/server/credentials/google_docs_token.json @@ -1 +1 @@ -{"access_token":"ya29.GlyEBxgqsCRjX9SAJGGss3EtfrPgwSjeMsfsuwJqTk7o4GRrBpwU0eQXXBNgPdAPRSrJzuVgAqWxap9kKrtkpf2tuHxk7Ml9Jblj48tU0BN2X0lMh66S2EIRhLnQnw","refresh_token":"1/HTv_xFHszu2Nf3iiFrUTaeKzC_Vp2-6bpIB06xW_WHI","scope":"https://www.googleapis.com/auth/presentations.readonly https://www.googleapis.com/auth/documents.readonly https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/documents https://www.googleapis.com/auth/photoslibrary https://www.googleapis.com/auth/photoslibrary.appendonly https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/presentations https://www.googleapis.com/auth/photoslibrary.sharing","token_type":"Bearer","expiry_date":1568501067486}
\ No newline at end of file +{"access_token":"ya29.ImCEByJgpv8e3CNTi-EwwqOtXUB1sNsOyOxM4WEyTybrQzCKc80SkjQZgb9gFCChbA7fFsdvewVAS_SiohfFziPOV4-YffeO417NS2CQf1cksmCQQBWxmL3i7qvQgz4VkdI","refresh_token":"1/HTv_xFHszu2Nf3iiFrUTaeKzC_Vp2-6bpIB06xW_WHI","scope":"https://www.googleapis.com/auth/presentations.readonly https://www.googleapis.com/auth/documents.readonly https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/documents https://www.googleapis.com/auth/photoslibrary https://www.googleapis.com/auth/photoslibrary.appendonly https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/presentations https://www.googleapis.com/auth/photoslibrary.sharing","token_type":"Bearer","expiry_date":1568509688650}
\ No newline at end of file |